diff --git a/.github/workflows/css.yml b/.github/workflows/css.yml index 2c1ef36..601c2c8 100644 --- a/.github/workflows/css.yml +++ b/.github/workflows/css.yml @@ -39,4 +39,4 @@ jobs: run: npm ci - name: Build CSS - run: npm run gulp compile + run: npm run build diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 8eb59ee..23311c9 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -39,4 +39,4 @@ jobs: run: npm ci - name: Lint - run: npm run gulp lint + run: npm run lint diff --git a/.htmlvalidate.json b/.htmlvalidate.json new file mode 100644 index 0000000..332aa02 --- /dev/null +++ b/.htmlvalidate.json @@ -0,0 +1,10 @@ +{ + "extends": [ + "html-validate:recommended" + ], + "rules": { + "aria-label-misuse": "off", + "no-redundant-role": "off", + "no-inline-style": "off" + } +} diff --git a/.pa11yci.json b/.pa11yci.json new file mode 100644 index 0000000..8964da1 --- /dev/null +++ b/.pa11yci.json @@ -0,0 +1,28 @@ +{ + "standard": "WCAG2AA", + "level": "warning", + "concurrency": 1, + "defaults": { + "reporters": [ + [ + "pa11y-ci-reporter-html", + { + "destination": "./reports" + } + ] + ], + "wait": 3000, + "runners": [ + "axe" + ], + "timeout": 100000, + "hideElements": "", + "ignore": [ + ], + "defaults": { + "chromeLaunchConfig": { + "executablePath": "/snap/bin/chromium" + } + } + } +} diff --git a/src/favicon.ico b/_site/favicon.ico similarity index 100% rename from src/favicon.ico rename to _site/favicon.ico diff --git a/src/humans.txt b/_site/humans.txt similarity index 100% rename from src/humans.txt rename to _site/humans.txt diff --git a/src/img/hypothenuse.jpg b/_site/img/hypothenuse.jpg similarity index 100% rename from src/img/hypothenuse.jpg rename to _site/img/hypothenuse.jpg diff --git a/src/img/pie-1.jpg b/_site/img/pie-1.jpg similarity index 100% rename from src/img/pie-1.jpg rename to _site/img/pie-1.jpg diff --git a/src/img/pie-2.jpg b/_site/img/pie-2.jpg similarity index 100% rename from src/img/pie-2.jpg rename to _site/img/pie-2.jpg diff --git a/src/img/pie-3.jpg b/_site/img/pie-3.jpg similarity index 100% rename from src/img/pie-3.jpg rename to _site/img/pie-3.jpg diff --git a/src/js/prism.js b/_site/js/prism.js similarity index 100% rename from src/js/prism.js rename to _site/js/prism.js diff --git a/_site/js/script.js b/_site/js/script.js new file mode 100644 index 0000000..3a16328 --- /dev/null +++ b/_site/js/script.js @@ -0,0 +1,32 @@ +(function () { + "use strict"; + + // Toggle switch component + var switches = document.querySelectorAll('[role="switch"]'); + + switches.forEach(function (el) { + el.addEventListener('click', function () { + var checked = this.getAttribute('aria-checked') === 'true' || false; + this.setAttribute('aria-checked', !checked); + + if (this.classList.contains('disable-css')) { + var chart = this.parentNode.nextElementSibling; + chart.classList.toggle('chaarts'); + } + }); + }); + + // Scrollable tables + var regions = document.querySelectorAll('.table-container'); + + if (window.matchMedia('(min-width: 30em)').matches) { + regions.forEach(function (el) { + var width = el.offsetWidth; + var table = el.querySelector('table'); + + if (table.offsetWidth > width) { + el.setAttribute('tabindex', '0'); + } + }); + } +})(document); diff --git a/docs/js/script.min.js b/_site/js/script.min.js similarity index 100% rename from docs/js/script.min.js rename to _site/js/script.min.js diff --git a/_site/scss/print.scss b/_site/scss/print.scss new file mode 100644 index 0000000..c7e3b13 --- /dev/null +++ b/_site/scss/print.scss @@ -0,0 +1,63 @@ +@media print { + body > :not(main), + main > :not(.deck), + *:not(.card)::after, + *:not(.card)::before, { + display: none !important; + } + + html, + body, + body > * { + background: none !important; + } + + /** + * 1. No orphans + * 2. No widows + */ + p, + blockquote, + .deck .card { + orphans: 3; /* 1 */ + widows: 3; /* 2 */ + } + + /* @note Avoid random page break */ + ul, + ol, + blockquote, + .deck .card { + page-break-inside: avoid; + break-inside: avoid; + } + + h1, + h2, + h3, + h4, + h5, + h6, + caption { + page-break-after: avoid; + } + + /** + * @note Display links' target, except for images + */ + a::after { + content: " (" attr(href) ") "; + display: inline-block !important; + } + + /* Hide anchors' target */ + a::after img, + a[href^="#"]::after, + a[href^="javascript"]::after { + content: ""; + } + + abbr::after { + content: " (" attr(title) ") "; + } +} diff --git a/_site/scss/styles.scss b/_site/scss/styles.scss new file mode 100644 index 0000000..926b6b6 --- /dev/null +++ b/_site/scss/styles.scss @@ -0,0 +1,19 @@ +@charset "UTF-8"; + +/* ==================== */ +/* == Vendors +/* ==================== */ +@use "sseeeedd/src/scss/styles"; +@use "vendors/prism"; + +.mb-0 { + margin-bottom: 0 !important; +} + +.pb-0 { + padding-bottom: 0 !important; +} + +.fly-out [rel]::before { + content: "\1F30D\A0"; +} diff --git a/src/scss/vendors/_prism.scss b/_site/scss/vendors/_prism.scss similarity index 91% rename from src/scss/vendors/_prism.scss rename to _site/scss/vendors/_prism.scss index 1c26e62..a99c97d 100644 --- a/src/scss/vendors/_prism.scss +++ b/_site/scss/vendors/_prism.scss @@ -13,7 +13,7 @@ pre[data-line] { padding: .25em; margin-top: 3.15em; background: white; - mix-blend-mode: soft-light; + mix-blend-mode: soft-light; pointer-events: none; line-height: inherit; white-space: pre; @@ -26,5 +26,5 @@ pre[data-line] { left: .5em; min-width: 1ch; color: black; - font-weight: 700; + font-weight: 700; } diff --git a/_site/templates/accueil.njk b/_site/templates/accueil.njk new file mode 100644 index 0000000..31bcde7 --- /dev/null +++ b/_site/templates/accueil.njk @@ -0,0 +1,211 @@ +{% extends "index.njk" %} + +{% block lang %}fr{% endblock %} + +{% block meta %} + chaarts + + + + + + +{% endblock %} + +{% block skiplinks %} +
+ Aller à la navigation + Aller au contenu +
+{% endblock %} + +{% block label %}Navigation principale{% endblock %} + +{% block navigation %} + +{% endblock %} + +{% block main %} +

Graphiques

+ +

+ Les différentes versions de graphiques présentées pour le moment reposent uniquement + sur un balisage sémantique — à base de <table> — + et une tartine de variables CSS portées par les balises. + Aucun JavaScript n’est requis pour l’affichage, et les styles sont + améliorés progressivement selon les capacités de votre navigateur. +

+ +

+ Note : en vertu du caractère expérimental + de ces techniques et d’une fondation solide améliorée progressivement, + je ne précise pas le support navigateur de chaque exemple — mais + il va de soi que ce n’est pas magique, et que seuls les navigateurs modernes répondent à l’appel, + à l’exception notable de Edge + qui ne supporte pas (encore) clip-path. + Les autres navigateurs affichent un tableau correctement stylé, et c’est chouette. +

+ +

L’accessibilité

+ +

+ Un effort conséquent a été porté à l’accessibilité. + Comme évoqué précédement, un balisage sémantique et structuré est un pré-requis + — mais ça ne suffit pas. Les CSS + sont appliqués aussi progressivement que possible, afin de garantir le meilleur affichage + possible des données pour chaque internaute. +

+ +

Tableau accessible

+ +

Piqure de rappel :

+ + + +

+ Pour d’autres astuces utiles, je vous recommande chaleureusement la lecture + du + composant inclusif Data Tables de Heydon Pickering, + qui est une véritable mine d’or. +

+ +

Motifs

+

+ Pour distinguer les différentes zones autrement que par la couleur, un motif + svg + est appliqué en + css + — vous en trouverez quelques-uns sur le site + Hero Patterns : +

+
    +
  1. + afin d’améliorer le mélange avec les couleurs ou dégradés d’arrière-plan, la propriété + background-blend-mode est utilisée avec la valeur hard-light ; +
  2. +
  3. + les tailles et positions du motif dépendent directement de la valeur et de l’échelle du + graphique, + selon le type de graphique ; +
  4. +
  5. + pour ne pas embarquer trop de fichiers externes, on utilise + une technique + proposée par Trys Mudford pour inclure nos + svg + en data URi dans une variable + css chacun ; + ainsi, une liste finie de motifs est utilisée dans le thème, sans jamais répéter le svg. +
  6. +
+ +
+

Qu’encoder ?

+

+ Taylor Hunt + a rédigé un article complet sur l’optimisation des + svg + passés en data URi. En résumé, seuls les chevrons et le + caractère « # » ont besoin d’être encodés dans le + css. + Ne vous fatiguez pas avec les autres caractères, leur encodage nuit sérieusement à la lisibilité. +

+
+ + {% include 'includes/_svg-encoding.njk' %} + +

Respect des préférences

+

+ Afin de respecter autant que possible les préférences des visiteurs, + de nombreux éléments ont été adaptés : +

+
    +
  1. + les dimensions sont en unités relatives (em ou rem selon les cas), + afin de s’ajuster de manière cohérente au corps de texte hérité du navigateur et de pouvoir + être agrandi ou réduit sans perte ; +
  2. +
  3. + les couleurs sont adaptées lorsque le mode de contrastes élevés de Windows est détecté à l’aide + de + -ms-high-contrast: active, inspiré par + + l’article de Greg Whitworth sur le sujet. Je vous conseille d’ailleurs + + l’increvable page Test of System Colors Specified in CSS 2 rédigée + par Ian Graham, éditée en… 2000 ! +
  4. +
  5. + les animations et transitions sont désactivées lorsque le système + expose cette préférence grâce à prefers-reduced-motion: reduce ; +
  6. +
  7. + les effets de survol dont l’état initial consiste à masquer du contenu + sont activés contextuellement dans la requête média @media (hover: hover) { … }. +
  8. +
+ +

display et sémantique

+

+ Adrian Roselli explique que jouer avec le display d’un élément + <table> ou <dl> met en péril sa sémantique. + Cette dernière est donc « verrouillée » à l’aide des rôles + aria + dédiés — comme il l’explique + dans un article + détaillé. +

+

+ C’est pourquoi chaque tableau est précédé d’un interrupteur — basé sur + le composant inclusif + conçu par Heydon Pickering — + dont le seul et unique rôle est de désactiver les styles supplémentaires : +

+ + {% include 'includes/_inclusive-toggle.njk' %} + +

+ Voilà, nous sommes prêts à entrer dans le vif du sujet.
+ Faites chauffer votre inspecteur ! +

+{% endblock %} diff --git a/_site/templates/bar-charts.njk b/_site/templates/bar-charts.njk new file mode 100644 index 0000000..4a7e6b1 --- /dev/null +++ b/_site/templates/bar-charts.njk @@ -0,0 +1,194 @@ +{% extends "index.njk" %} + +{% block meta %} + Bar charts — chaarts + + + + + + +{% endblock %} + +{% block navigation %} + +{% endblock %} + +{% block main %} +

Bar charts

+ +

+ This type of graph is used to represent one-dimensional data + (in our example, a timeline). + It's based on CSS grids and custom properties, + a technique inspired by + an article by Miriam Suzanne on + CSS Tricks + with a slight enhancement to improve accessibility. + Here's how to use it: +

+ +
    +
  1. + On the table itself, the --scale custom property is used to define the maximum value + for the graph, + in order to determine its scale. Concretely, a grid will be generated with: + +
  2. +
  3. + On each cell <td>, a --value custom property + allows to place it on the grid, applied to grid-column-end. + Moreover, thanks to clever calculations based on this value, the background gradient is sized + and positioned to reflect the proportion represented by this value on the given scale + (from green for almost nothing to red for almost everything). +
  4. +
  5. + In each cell, the content must include the value and its unit in a + <span> element, possibly tagged with <abbr> + (and aria-label to complement title) if a title can explicit the unit. + This value is pushed to the right of the grid, and its text serves as a mask for the background + gradient — thanks to S. Shaw's trick to + apply background-clip: text as a progressively enhancement — allowing it to be the + corresponding color at the end of the gradient for the given position. +
  6. +
+ + {% import 'macros/_table-bar.njk' as table %} +
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + {{ table.bar('Time: backend', '4', 'ms', 'Millisecond', 'table') }} + {{ table.bar('Time: Frontend', '96', 'ms', 'Millisecond', 'table') }} + {{ table.bar('Delay: first byte', '102', 'ms', 'Millisecond', 'table') }} + {{ table.bar('Delay: last byte', '129', 'ms', 'Millisecond', 'table') }} + {{ table.bar('Delay: first image', '188', 'ms', 'Millisecond', 'table') }} + {{ table.bar('Delay: first CSS', '194', 'ms', 'Millisecond', 'table') }} + {{ table.bar('Delay: first JS', '326', 'ms', 'Millisecond', 'table') }} + {{ table.bar('DOM Interactive', '836', 'ms', 'Millisecond', 'table') }} + {{ table.bar('DOM loading', '836', 'ms', 'Millisecond', 'table') }} + {{ table.bar('DOM complete', '2561', 'ms', 'Millisecond', 'table') }} + {{ table.bar('HTTP traffic completed', '2980', 'ms', 'Millisecond', 'table') }} + +
Loading time for ffoodd.fr
Cumulative loading time
+
+ +
+ HTML +
{% include 'includes/_bar-markup.njk' %}
+
+
+ css +
{% include 'includes/_bar-styles.njk' %}
+
+ +

Waterfall

+ +

+ The principle is the same for this variant, except for one detail: we also manage + the starting point for each measurement + — which is, very simply, the value of the previous point… + However, all the values must be passed as variables on the parent <table>. +

+ +
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + {{ table.bar('Time: backend', '4', 'ms', 'Millisecond', 'waterfall') }} + {{ table.bar('Time: Frontend', '96', 'ms', 'Millisecond', 'waterfall') }} + {{ table.bar('Delay: first byte', '102', 'ms', 'Millisecond', 'waterfall') }} + {{ table.bar('Delay: last byte', '129', 'ms', 'Millisecond', 'waterfall') }} + {{ table.bar('Delay: first image', '188', 'ms', 'Millisecond', 'waterfall') }} + {{ table.bar('Delay: first CSS', '194', 'ms', 'Millisecond', 'waterfall') }} + {{ table.bar('Delay: first JS', '326', 'ms', 'Millisecond', 'waterfall') }} + {{ table.bar('DOM interactive', '836', 'ms', 'Millisecond', 'waterfall') }} + {{ table.bar('DOM loading', '836', 'ms', 'Millisecond', 'waterfall') }} + {{ table.bar('DOM complete', '2561', 'ms', 'Millisecond', 'waterfall') }} + {{ table.bar('HTTP traffic completed', '2980', 'ms', 'Millisecond', 'waterfall') }} + +
Loading time for ffoodd.fr
Cumulative loading time
+
+ +
+ HTML +
{% include 'includes/_waterfall-markup.njk' %}
+
+
+ css +
{% include 'includes/_waterfall-styles.njk' %}
+
+{% endblock %} diff --git a/_site/templates/barres.njk b/_site/templates/barres.njk new file mode 100644 index 0000000..c076889 --- /dev/null +++ b/_site/templates/barres.njk @@ -0,0 +1,204 @@ +{% extends "accueil.njk" %} + +{% block meta %} + Graphiques en barre — chaarts + + + + + + +{% endblock %} + +{% block navigation %} + +{% endblock %} + +{% block main %} +

Graphique en barre

+ +

+ Ce type de graphique sert à représenter des données à une dimension + (dans notre exemple, une ligne de temps). + Il repose sur les grilles et les variables CSS, + technique inspirée + d’un article de Miriam + Suzanne sur + CSS Tricks + légèrement agrémentée pour en améliorer l’accessibilité. + Pour vous en servir, c’est simple : +

+ +
    +
  1. + Sur le tableau, une variable --scale permet de définir la valeur maximale du + graphique, + afin d’en déterminer l’échelle. Concrètement, une grille va être générée avec : + +
  2. +
  3. + Sur chaque cellule <td>, une variable --value permet de la placer + sur la grille, + appliquée à grid-column-end. + De plus grâce à de savants calculs reposant sur cette valeur, le dégradé en arrière-plan est dimensionné et + positionné de façon à + refléter la proportion représentée par cette valeur sur l’échelle donnée (du vert pour presque rien au rouge pour + presque tout). +
  4. +
  5. + Dans chaque cellule, le contenu doit reprendre la valeur et son unité dans un élément <span>, + éventuellement + balisée avec <abbr> (et aria-label pour suppléer title) si un + intitulé peut être explicité pour l’unité. + Cette valeur est poussée à droite de la grille, et son texte sert de masque pour le dégradé en arrière-plan + — grâce à une astuce de S. + Shaw's pour + appliquer background-clip: text en amélioration progressive — lui permettant d’être de la + couleur correspondante + à la fin du dégradé pour la position donnée. +
  6. +
+ + {% import 'macros/_table-bar.njk' as table %} +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + {{ table.bar('Temps : backend', '4', 'ms', 'Milliseconde', 'table') }} + {{ table.bar('Temps : Frontend', '96', 'ms', 'Milliseconde', 'table') }} + {{ table.bar('Délai : premier octet', '102', 'ms', 'Milliseconde', 'table') }} + {{ table.bar('Délai : dernier octet', '129', 'ms', 'Milliseconde', 'table') }} + {{ table.bar('Délai : première image', '188', 'ms', 'Milliseconde', 'table') }} + {{ table.bar('Délai : premier CSS', '194', 'ms', 'Milliseconde', 'table') }} + {{ table.bar('Délai : premier JS', '326', 'ms', 'Milliseconde', 'table') }} + {{ table.bar('DOM Interactif', '836', 'ms', 'Milliseconde', 'table') }} + {{ table.bar('Chargement du DOM', '836', 'ms', 'Milliseconde', 'table') }} + {{ table.bar('DOM complet', '2561', 'ms', 'Milliseconde', 'table') }} + {{ table.bar('Trafic HTTP terminé', '2980', 'ms', 'Milliseconde', 'table') }} + +
Temps de chargement pour ffoodd.fr
Temps de chargement cumulé
+
+ +
+ Le HTML + +
{% include 'includes/_bar-markup.njk' %}
+
+
+ Le css +
{% include 'includes/_bar-styles.njk' %}
+
+ +

Graphique en chute d’eau

+ +

+ Le principe est le même pour cette variante, à un détail près : + on gère également le point de départ pour chaque mesure + — qui est, très simplement, la valeur du point précédent… + Il faut cependant passer toutes les valeurs en tant que variables sur + le parent <table>. +

+ +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + {{ table.bar('Temps : backend', '4', 'ms', 'Milliseconde', 'waterfall') }} + {{ table.bar('Temps : Frontend', '96', 'ms', 'Milliseconde', 'waterfall') }} + {{ table.bar('Délai : premier octet', '102', 'ms', 'Milliseconde', 'waterfall') }} + {{ table.bar('Délai : dernier octet', '129', 'ms', 'Milliseconde', 'waterfall') }} + {{ table.bar('Délai : première image', '188', 'ms', 'Milliseconde', 'waterfall') }} + {{ table.bar('Délai : premier CSS', '194', 'ms', 'Milliseconde', 'waterfall') }} + {{ table.bar('Délai : premier JS', '326', 'ms', 'Milliseconde', 'waterfall') }} + {{ table.bar('DOM Interactif', '836', 'ms', 'Milliseconde', 'waterfall') }} + {{ table.bar('Chargement du DOM', '836', 'ms', 'Milliseconde', 'waterfall') }} + {{ table.bar('DOM complet', '2561', 'ms', 'Milliseconde', 'waterfall') }} + {{ table.bar('Trafic HTTP terminé', '2980', 'ms', 'Milliseconde', 'waterfall') }} + +
Temps de chargement pour ffoodd.fr
Temps de chargement cumulé
+
+ +
+ Le HTML + +
{% include 'includes/_waterfall-markup.njk' %}
+
+
+ Le css +
{% include 'includes/_waterfall-styles.njk' %}
+
+{% endblock %} diff --git a/_site/templates/camembert.njk b/_site/templates/camembert.njk new file mode 100644 index 0000000..1335826 --- /dev/null +++ b/_site/templates/camembert.njk @@ -0,0 +1,694 @@ +{% extends "accueil.njk" %} + +{% block meta %} + Camemberts — chaarts + + + + + + +{% endblock %} + +{% block navigation %} + +{% endblock %} + +{% block main %} +

Graphique en tarte

+ +

+ Le graphique en tarte sert pour les représentations de proportions en pourcentage. + Il s’appuie sur des variables CSS, un abus outrancier de calc(), + display: table-*, clip-path, mask-image, + transform et un tantinet de SVG + pour distinguer chaque zone. Oui, je sais rigoler. Comment qu’on s’en sert ? +

+ +
    +
  1. + Sur chaque entête <th>, une variable --color + permet d’attribuer, et bien… une couleur. +
  2. +
  3. + Puis chaque cellule <td> doit contenir la valeur et son unité, + ainsi qu’un attribut style pour porter quelques variables : +
      +
    1. + --value correspond à la valeur en pourcentage, + utile pour déterminer l’angle que doit occuper l’élément sur le cercle. + Tous les points du polygon() — servant à tracer la part du fromage + à l’aide de clip-path — dépendent de cette valeur (lire la note + technique après l’exemple pour le détail + des calculs). +
    2. +
    3. + --start permet de définir le point de départ de l’arc + sur le cercle. Il s’agit de la somme des précédentes définitions, et est appliqué + à la fonction rotate() de la propriété transform. +
    4. +
    5. + Et enfin une série de variables booléennes valant chacune 0 ou 1 + — d’après une idée de + Roman Komarov dans son article "Conditions for CSS variables" — + dépendent de la valeur : --lt-25, --gt-25, --lt-50… + Elles permettent de faire basculer les points de leur position d’origine + (50% 50%) à leur position calculée, en s’additionnant ou se soustrayant + à la valeur initiale ; +
    6. +
    +
  4. +
  5. + un pseudo-élément ::before sur chaque cellule <td> est mis en + forme + de savante manière en fonction de toutes nos variables, avec notamment transform, + clip-path et mask-image. + +
  6. +
  7. + un pseudo-élément ::after est utilisé pour simuler une infobulle, récapitulant + l’entête et la valeur de la cellule — l’affichage de propriétés personnalisées dans un pseudo-élément n’est + pas si triviale : + +
  8. +
  9. + Et finalement un motif est appliqué sur l’arrière-plan, afin de mieux + l’associer visuellement avec la légende correspondante. +
  10. +
+ + {% import 'macros/_table-pie.njk' as table %} + +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} + {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} + {{ table.pie('JS', '32', '%', '', '4', '#0172F0') }} + {{ table.pie('Json', '1', '%', '', '36', '#FDC02F') }} + {{ table.pie('Images', '44', '%', '', '37', '#39CA74') }} + {{ table.pie('Webfonts', '17', '%', '', '81', '#FF2D40') }} + {{ table.pie('Autres', '2', '%', '', '98', '#585462') }} + +
Répartition du poids des ressources pour ffoodd.fr +
RessourceProportion
+
+ +
+ Un peu de trigonométrie +
+

+ Dans ce graphique, chaque portion représente un arc de cercle basé sur un angle (une partie de 360 degrés). + Pour définir la forme de cette portion, il faut donc placer un point sur le cercle. +

+

+ Pour ce faire, je divise le cercle en quatre carrés. La position du point sur le cercle peut ainsi + être calculée en utilisant les propriétés du triangle rectangle formé par : +

+
    +
  1. le centre du cercle,
  2. +
  3. le point que nous cherchons à positionner,
  4. +
  5. et le point perpendiculaire au rayon et passant par notre point cible.
  6. +
+

+ Nous connaissons l’hypoténuse de ce triangle — le rayon du cercle —, + et l’angle formé par l’hypoténuse et partant du centre du cercle + (en ramenant la valeur sur 90 degrés, puisque le cercle est divisé en quatre secteurs carrés : + si la valeur est supérieure à 25 : moins 90°, etc.) + — plus un angle droit, bien entendu. +

+

La loi des sinus

+

+ Nous pouvons donc utiliser la loi + des sinus pour mesurer chaque côté, + et ainsi obtenir la position du point sur le cercle. + Cela implique de calculer le sinus… Fort heureusement, + Stereokai a implémenté pour nous + la représentation polynomiale de Taylor/Maclaurin en CSS — que j’ai implémentée sour forme d’un mixin : +

+ {% include 'includes/_sin-mixin.njk' %} +

+ Il ne reste plus qu’à utiliser ces dimensions pour placer les points du polygône. + Un vrai jeu d’enfants ! +

+
+
+
+ Le HTML + +
{% include 'includes/_pie-markup.njk' %}
+
+
+ Le css +
+
+   
+@supports (clip-path: polygon( 50% calc( 50% + ( var(--gt-25, 0) ) ) )) {
+ .chaarts.pie {
+   --radius: 32em;
+   margin: 0 auto;
+   padding-top: calc(var(--radius) - 2rem);
+   position: relative;
+ }
+
+ .chaarts.pie tbody {
+   display: table-row;
+ }
+
+ .chaarts.pie tr {
+   display: table-cell;
+   transition: opacity .3s cubic-bezier(.5, 0, .5, 1);
+ }
+
+ .chaarts.pie [scope="row"] {
+   padding-right: .5rem;
+ }
+
+ .chaarts.pie [scope="row"]::before {
+   background: var(--color, currentColor);
+   content: "";
+   display: inline-block;
+   height: 1rem;
+   transform: translate3d(-.2rem, .1rem, 0);
+   width: 1rem;
+ }
+
+ .chaarts.pie td {
+   --position: calc(var(--start, 0) * .01turn);
+ }
+
+ .chaarts.pie td::after,
+ .chaarts.pie td::before {
+   left: 50%;
+   position: absolute;
+   top: calc(var(--radius) / 2);
+   transform-origin: center center;
+ }
+
+ .chaarts.pie td::before {
+   /* L’inclinaison, pour se placer au bon endroit */
+   --position: calc(var(--start, 0) * .01turn);
+   --zoom: .75;
+   /* L’angle représenté par la valeur : 3.6 = 360deg / 100 */
+   /* Puisque nous utilisons une valeur en pourcentage */
+   --part: calc( var(--value) * 3.6 );
+   /* L’angle « utile » pour le calcul, nécessairement inférieur à 90deg */
+   /* On soustrait donc 90deg (= ¼ × 360deg) par tranche de 25% (= ¼ × 100%, oui oui) */
+   --main-angle: calc( var(--part) - ( 90 * ( var(--gt-25, 0) + var(--gt-50, 0) + var(--gt-75, 0) ) ) );
+   /* L’angle principal, exprimé en radian */
+   --β: calc( var(--main-angle) * 0.01745329251 );
+   /* Le dernier angle en radian, par déduction puisque dans un triangle rectangle */
+   --α: calc( ( 90 - var(--main-angle) ) * 0.01745329251 );
+   /* La magie de Stereokai, pour obtenir le sinus de ces angles */
+   --sin-term-β-1: var(--β);
+   --sin-term-β-2: calc((var(--β) * var(--β) * var(--β)) / 6);
+   --sin-term-β-3: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 120);
+   --sin-term-β-4: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 5040);
+   --sin-term-β-5: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 362880);
+   --sin-β: calc(var(--sin-term-β-1) - var(--sin-term-β-2) + var(--sin-term-β-3) - var(--sin-term-β-4) + var(--sin-term-β-5));
+   --sin-term-α-1: var(--α);
+   --sin-term-α-2: calc((var(--α) * var(--α) * var(--α)) / 6);
+   --sin-term-α-3: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 120);
+   --sin-term-α-4: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 5040);
+   --sin-term-α-5: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 362880);
+   --sin-α: calc(var(--sin-term-α-1) - var(--sin-term-α-2) + var(--sin-term-α-3) - var(--sin-term-α-4) + var(--sin-term-α-5));
+   /* Enfin, la position exprimée en % de l’hypothénuse, et divisée par 2 pour s’inscrire dans ¼ du cercle
+    * soit après simplification, divisé par 50 */
+   --pos-B: calc( var(--sin-β) * 50 );
+   --pos-A: calc( var(--sin-α) * 50 );
+   background-color: var(--color, currentColor) var(--background);
+   --polygon: polygon(
+     50% 50%,
+     50% 0%,
+     100% 0%,
+     calc( 50% + ( var(--pos-B) * 1% * var(--lt-25, 1) ) + ( var(--gt-25, 0) * 50% ) ) calc( 50% - ( var(--pos-A) * 1% * var(--lt-25, 1) ) ),
+     calc( 50% + ( var(--gt-25, 0) * 50% ) )                      calc( 50% + ( var(--gt-25, 0) * 50% ) ),
+     calc( 50% + ( var(--pos-A) * 1% * var(--lt-50, 1) ) + ( var(--gt-50, 0) * 50% ) ) calc( 50% + ( var(--pos-B) * 1% * var(--lt-50, 1) ) + ( var(--gt-50, 0) * 50% ) ),
+     calc( 50% - ( var(--gt-50, 0) * 50% ) )                      calc( 50% + ( var(--gt-50, 0) * 50% ) ),
+     calc( 50% - ( var(--pos-B) * 1% * var(--lt-75, 1) ) - ( var(--gt-75, 0) * 50% ) ) calc( 50% + ( var(--pos-A) * 1% * var(--lt-75, 1) ) ),
+     calc( 50% - ( var(--gt-75, 0) * 50% ) )                      calc( 50% - ( var(--gt-75, 0) * 50% ) ),
+     calc( 50% - ( var(--pos-A) * 1% * var(--gt-75, 0) ) )               calc( 50% - ( var(--pos-B) * 1% * var(--gt-75, 0) ) ),
+     50% 50%
+   );
+   clip-path: var(--polygon);
+   content: '';
+   height: var(--radius);
+   --mask: radial-gradient(
+     circle at center,
+     white 0%,
+     white calc(var(--radius)  / 2),
+     transparent calc(var(--radius)  / 2)
+   );
+   mask-image: var(--mask);
+   transform:
+     translate3d(-50%, -50%, 0)
+     rotate( var(--position) )
+     scale( var(--zoom) );
+   transition: transform .2s cubic-bezier(.5, 0, .5, 1);
+   width: var(--radius);
+ }
+
+ .chaarts.pie tr:hover td::before {
+   --zoom: .8;
+ }
+
+ .chaarts.pie tr:nth-child(2n + 2) *::before {
+   --background: var(--stripes);
+ }
+
+ .chaarts.pie td::after {
+   --arrow: calc(100% - .25rem);
+   --axis: calc( var(--position) - .25turn + var(--value) * .005turn );
+   --away: calc( var(--radius) / 2 - 1rem );
+   --integer: calc(var(--value));
+   background-color: #444;
+   color: white;
+   content: var(--term) "\A0: " counter(value) "\A0%";
+   counter-reset: value var(--integer);
+   opacity: 0;
+   padding: .5rem;
+   pointer-events: none;
+   transform-origin: 50% calc(100% + 10px);
+   transform:
+     translate3d(-50%, -50%, 0)
+     rotate( var(--axis) )
+     translate( var(--away) )
+     rotate( calc( var(--axis) * -1 ) )
+     perspective(1000px)
+     rotate3d(1, 0, 0, 45deg);
+   transition:
+     opacity .2s cubic-bezier(0, .5, .5, 1),
+     transform .2s cubic-bezier(0, .5, .5, 1);
+ }
+
+ .chaarts.pie tbody:hover tr {
+   opacity: .75;
+ }
+
+ .chaarts.pie tbody:hover tr:hover {
+   opacity: 1;
+ }
+
+ .chaarts.pie tbody:hover td::after {
+   opacity: 1;
+   transform:
+     translate3d(-50%, -50%, 0)
+     rotate( var(--axis) )
+     translate( var(--away) )
+     rotate( calc( var(--axis) * -1 ) )
+     perspective(1000px)
+     rotate3d(1, 0, 0, 0deg);
+   transition:
+     opacity .2s cubic-bezier(.5, 0, 1, .5),
+     transform .2s cubic-bezier(.5, 0, 1, .5);
+ }
+
+ @media screen and (-ms-high-contrast: active) {
+   .chaarts.pie tr *::before {
+     background-color: Window;
+   }
+
+   .chaarts.pie tr:nth-of-type(odd) *::before {
+     background-color: WindowText;
+   }
+ }
+}
+  
+
+
+
+ Le calcul tordu +

Les positions du polygone

+

+ L’utilisation de variables pseudo-booléennes rend ce calcul pseudo-algorithmique. + Démarrons par un pré-requis essentiel : le polygone étant un tracé fermé et CSS + n’étant pas magique, les points doivent pré-exister. + Spoiler, il nous faut onze points : +

+
    +
  1. + L’axe initial, du centre vers le milieu en haut : 50% 50% + et 50% 0%. +
  2. +
  3. + Un point pour chaque angle aux extrémités : le premier est fixe, à + 100% 0% (en haut à droite) — puis chacun des autres angles + a deux états, atteint ou non. Quelques détails : +
      +
    • + Par exemple le point en bas à droite concerne + les valeurs entre 25% et 50% : si la valeur est inférieure à 25%, il doit + être au centre (pour ne pas gêner le tracé), et dans le cas contraire être + dans son coin. ce qui s’exprime ainsi : + calc( 50% + ( var(--gt-25, 0) * 50% ) ) calc( 50% + ( var(--gt-25, 0) * 50% ) )
      + Ainsi la valeur calculée sera 50% 50% si --gt-25 vaut 0, + et 100% 100% si --gt-25 vaut 1. +
    • +
    • + De plus, chaque angle a sa coordonnée cible : + 100% 100% pour en bas à droite, 0% 100% pour en bas à gauche, + 0% 0% pour en haut à gauche. Il faut donc tantôt soustraire et + tantôt ajouter 50% à la valeur intitiale 50% 50% + pour basculer sur le bon point. +
    • +
    +
  4. +
  5. + Un point pour chaque position possible par quart de cercle, correspondant à + chaque tranche de 25%. À l’instar des points aux angles, ces points doivent être au centre + s’ils ne sont pas utilisés. C’est là qu’on rigole le plus : +
      +
    • on part de 50%, auxquels on ajoute ou soustrait la suite du calcul ;
    • +
    • + on utilise enfin la position calculée — --pos-A + ou --pos-B selon le cas — qu’on convertit en pourcentages à l’aide de + * 1%, et qu’on rend inerte si la valeur est inférieure à la tranche concernée + grâce à * var(--lt-25, 1), par exemple.
      + + Remarquez le seconde valeur dans var(), qui est la valeur par défaut + si la variable n’est pas définie. Cool, non ? + +
    • +
    • + et finalement lorsque la tranche est dépassée, le point bascule vers + 0% ou 100% selon le cas. +
    • +
    +
  6. +
  7. + Et enfin, on referme le tracé en revenant au centre du cercle, + à 50% 50%. +
  8. +
+

C’est tout !

+

Les positions illustrées

+

+ Ces captures d’écran — effectuées dans + l’éditeur + de formes + des outils de développement de Firefox — + montrent les points du polygone dans les différents cas. Vous pouvez consulter pour chaque valeur citée + le polygone résolu pour clip-path — et constater le basculement des valeurs dynamiques d’une + position à une autre. +

+ +
+ +
+
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} + {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} + {{ table.pie('JS', '32', '%', '', '4', '#0172F0') }} + {{ table.pie('Images', '64', '%', '', '36', '#39CA74') }} + +
Exemple de tarte avec une valeur entre 50 et 75%
RessourceProportion
+
+ +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} + {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} + {{ table.pie('JS', '8', '%', '', '4', '#0172F0') }} + {{ table.pie('Images', '88', '%', '', '12', '#39CA74') }} + +
Exemple de tarte avec une valeur supérieure à 75%
RessourceProportion
+
+
+ +

Donut

+ +

+ Sur l’élément <table>, on ajoute une variable --offset + qui permet de déterminer la dimension du trou du donut, + généré à l’aide de mask-image et radial-gradient(). + + Ana Tudor a réalisé de très nombreux exemples + d’utilisation des mask-* sur CodePen, jetez-y un œil ! +

+ +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} + {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} + {{ table.pie('JS', '32', '%', '', '4', '#0172F0') }} + {{ table.pie('Json', '1', '%', '', '36', '#FDC02F') }} + {{ table.pie('Images', '44', '%', '', '37', '#39CA74') }} + {{ table.pie('Webfonts', '17', '%', '', '81', '#FF2D40') }} + {{ table.pie('Autres', '2', '%', '', '98', '#585462') }} + +
Répartition du poids des ressources pour ffoodd.fr +
RessourceProportion
+
+ +
+ Le css +
{% include 'includes/_donut-styles.njk' %}
+
+ +
+

Dégradé conique

+

+ L’utilisation de conic-gradient() est prometteuse pour ce cas précis. + Vous en trouverez des exemples réalisés par Ana Tudor ou Léa Verou — qui a + carrément rédigé la spécification, + et conçu un polyfill. + Cependant le support limité aux navigateurs + basés sur WebKit est déprimant, et pose tout de même quelques questions + en matière d’accessibilité puisqu’on ne peut pas affecter un motif à chaque couleur du dégradé + conique. +

+
+ +

Polaire

+ +

+ Pour cette déclinaison, on ne change presque rien : seulement la variable --zoom + et son implication dans la mise à l’échelle des portions à l’aide de scale(). +

+ +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} + {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} + {{ table.pie('JS', '32', '%', '', '4', '#0172F0') }} + {{ table.pie('Json', '1', '%', '', '36', '#FDC02F') }} + {{ table.pie('Images', '44', '%', '', '37', '#39CA74') }} + {{ table.pie('Webfonts', '17', '%', '', '81', '#FF2D40') }} + {{ table.pie('Autres', '2', '%', '', '98', '#585462') }} + +
Répartition du poids des ressources pour ffoodd.fr +
RessourceProportion
+
+ +
+ Le css +
{% include 'includes/_polar-styles.njk' %}
+
+{% endblock %} diff --git a/_site/templates/column-charts.njk b/_site/templates/column-charts.njk new file mode 100644 index 0000000..ec00e3c --- /dev/null +++ b/_site/templates/column-charts.njk @@ -0,0 +1,248 @@ +{% extends "accueil.njk" %} + +{% block meta %} + Column charts — chaarts + + + + + + +{% endblock %} + +{% block navigation %} + +{% endblock %} + +{% block main %} +

Column charts

+ +

+ Column chart is used for value distributions. + The structure of the table is quite ordinary, but its formatting is based on + display: grid; and especially display: contents; to + facilitate the placement of the cells — technique inspired by + + Hidde De Vries's article More accessible markup with display: contents, + and clarified by + Ire Aderinokun's post How display: contents works. +

+ +

The basic principle is the same as the bar charts:

+
    +
  1. + the first grid row is the reserved to display value in case it reaches scale's max value, + with a fixed size of 2ex + — have a look to CSS + units rudiments, documented in Every Layout by Andy Bell and Heydon Pickering ; +
  2. +
  3. + the repeat() function applied with the --scale custom property + enables us to handle a dynamic scale; +
  4. +
  5. + <thead>, <tbody> and <tr> containers + are neutralized in the grid structure using display: contents; +
  6. +
  7. + each cell is placed on the grid depending its --value + — its background color also depending on its value; +
  8. +
  9. + and finally its text value — wrapped in a <span> element — + is positioned at the top of the column using the same trick as in the bar chart. +
  10. +
+ +
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Browser market shares in France in January 2019
BrowserChromeFirefoxSafariEdgeIEOthers
Market shares62%15%9%5%6%3%
+
+ +
+ HTML +
{% include 'includes/_column-markup.njk' %}
+
+
+ css +
{% include 'includes/_column-styles.njk' %}
+
+ +

Multiple columns

+ +

+ In order to have two values for each main column, we must also have + two subheadings. Concretely speaking: +

+ +
    +
  1. + we add a second row in <thead>: + +
  2. +
  3. + Styles: + +
  4. +
+ +
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Browser market shares in France in January 2019
BrowserChromeFirefoxSafariEdgeIE
Year2018201920182019201820192018201920182019
Market shares49.6%57%11.74%9.59%21.53%18.78%3.72%3.5%4.46%3.66%
+
+ +
+ HTML +
{% include 'includes/_columns-markup.njk' %}
+
+
+ css +
{% include 'includes/_columns-styles.njk' %}
+
+{% endblock %} diff --git a/_site/templates/courbe.njk b/_site/templates/courbe.njk new file mode 100644 index 0000000..916807e --- /dev/null +++ b/_site/templates/courbe.njk @@ -0,0 +1,354 @@ +{% extends "accueil.njk" %} + +{% block meta %} + Courbes — chaarts + + + + + + +{% endblock %} + +{% block navigation %} + +{% endblock %} + +{% block main %} +

Graphique linéaire

+ +

Graphique de surface

+ +

+ Ce graphique repose sur les variables CSS, les grilles et clip-path. + Cette dernière propriété est la plus importante. +

+ +
    +
  1. + Sur le tableau, les échelles et l’unité sont indiquées : + +
  2. +
  3. + Chaque ligne <tr> dans <tbody> porte une palanquée + de variables, correspondant à toutes les valeurs qu’elle contient. + Dans un pseudo-élément ::before, une position est définie pour chaque valeur + au sein de la fonction polygon() de clip-path. + +
  4. +
  5. + Chaque cellule <td> dans <tbody> porte un pseudo-élément + ::after qui sert à récapituler ses entêtes et valeur dans + une infobulle simulée, et un pseudo-élément ::before pour gérer un calque interactif sur la cellule : + +
  6. +
  7. + Tout le reste n’est que décoration : + +
  8. +
+ + {% import 'macros/_table-line.njk' as table %} + +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + {{ table.line('8', '°C', 'Degré Celsius') }} + {{ table.line('6', '°C', 'Degré Celsius') }} + {{ table.line('9', '°C', 'Degré Celsius') }} + {{ table.line('12', '°C', 'Degré Celsius') }} + {{ table.line('15', '°C', 'Degré Celsius') }} + {{ table.line('21', '°C', 'Degré Celsius') }} + {{ table.line('24', '°C', 'Degré Celsius') }} + {{ table.line('25', '°C', 'Degré Celsius') }} + {{ table.line('22', '°C', 'Degré Celsius') }} + {{ table.line('19', '°C', 'Degré Celsius') }} + {{ table.line('14', '°C', 'Degré Celsius') }} + {{ table.line('9', '°C', 'Degré Celsius') }} + + +
Température mensuelle moyenne en 2017
AnnéeJan.Fév.MarsAvr.MaiJuinJuil.AoûtSep.Oct.Nov.Déc.
2017
+
+ +
+ Le HTML + +
{% include 'includes/_line-markup.njk' %}
+
+
+ Le css +
{% include 'includes/_line-styles.njk' %}
+
+
+ Le calcul tordu +

Le tracé du polygon()

+

+ Pour commencer, il faut bien intégrer que clip-path est un tracé, + au même titre qu’une forme vectorielle. Il doit donc être fermé. + Ainsi le tracé démarre à 0% 100% — en bas à gauche, fait sa vie + de tracé, bascule à 100% 100% et revient boucler à 0% 100%. +

+

Et dans son chemin, chaque point doit être positionné en abscisses et en ordonnées.

+

La position en abscisse

+

+ La première position est simple : on divise 100% par l’échelle + var(--x), et on multiplie par l’index de l’élément. Par exemple : + calc( ( 100% / var(--x) * 1) ). + Pour placer chaque point au milieu de sa colonne, on le décale d’une demi-colonne + — ce que l’on fait en ajoutant au calcul précédent var(--offset), qui correspond + à calc( ( 100% / var(--x) ) / 2 ).
+ La position finale est donc, ici pour le troisième point :
+ calc( ( 100% / var(--x) * 3) + var(--offset) ). +

+

La position en ordonnée

+

+ Dans ce graphique, l’ordonnée est l’axe le plus important. Ainsi pour placer le point, + on commence par calculer le ratio de sa valeur sur l’échelle — formulé + ainsi : var(--1) / var(--y). Et parce que polygon() utilise + des valeurs en pourcentage, on rapporte ce calcul sur 100% : + ( var(--1) / var(--y) * 100% ).
+ Et pour finir, les référentiels du polygone partant d’en haut à gauche, la position + doit être définie en fonction du haut de la boîte. La formule finale ressemble + alors à ça — toujours pour le troisième élément :
+ calc( 100% - ( var(--3) / var(--y) * 100% ) ). +

+
+ +

Graphique à point

+ +

Cette variante diffère finalement assez peu de la précédente mouture :

+ +
    +
  1. + le polygon() est poursuivi pour former une ligne, + en dupliquant chaque point avec un décalage de 4px + — l’épaisseur du trait — et dans l’ordre inverse ; +
  2. +
  3. + le pseudo-élément ::before qui permet d’afficher l’infobulle prend ici la forme d’un + point sur la courbe — positionné à l’aide des mêmes calculs qui servent dans le polygone ; +
  4. +
  5. + et surtout, puisque clip-path est appliqué sur la ligne + <tr> : vous pouvez en mettre plusieurs ! + Il nous faut donc ajouter une combinaison de couleur et motif pour distinguer chaque ligne + et les associer visuellement à leur légende. +
  6. +
+ +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + {{ table.line('8', '°C', 'Degré Celsius') }} + {{ table.line('6', '°C', 'Degré Celsius') }} + {{ table.line('9', '°C', 'Degré Celsius') }} + {{ table.line('12', '°C', 'Degré Celsius') }} + {{ table.line('15', '°C', 'Degré Celsius') }} + {{ table.line('21', '°C', 'Degré Celsius') }} + {{ table.line('24', '°C', 'Degré Celsius') }} + {{ table.line('25', '°C', 'Degré Celsius') }} + {{ table.line('22', '°C', 'Degré Celsius') }} + {{ table.line('19', '°C', 'Degré Celsius') }} + {{ table.line('14', '°C', 'Degré Celsius') }} + {{ table.line('9', '°C', 'Degré Celsius') }} + + + + {{ table.line('10', '°C', 'Degré Celsius') }} + {{ table.line('4', '°C', 'Degré Celsius') }} + {{ table.line('7', '°C', 'Degré Celsius') }} + {{ table.line('13', '°C', 'Degré Celsius') }} + {{ table.line('17', '°C', 'Degré Celsius') }} + {{ table.line('20', '°C', 'Degré Celsius') }} + {{ table.line('22', '°C', 'Degré Celsius') }} + {{ table.line('23', '°C', 'Degré Celsius') }} + {{ table.line('26', '°C', 'Degré Celsius') }} + {{ table.line('17', '°C', 'Degré Celsius') }} + {{ table.line('14', '°C', 'Degré Celsius') }} + {{ table.line('10', '°C', 'Degré Celsius') }} + + +
Température mensuelle moyenne par année
AnnéeJan.Fév.MarsAvr.MaiJuinJuil.AoûtSep.Oct.Nov.Déc.
2017
2018
+
+ +
+ Le css +
{% include 'includes/_lines-styles.njk' %}
+
+ +
+

Note

+

+ Pour jouer d’avantage et vous familiariser avec clip-path, + Bennett Feely a créé + clippy. +

+
+{% endblock %} diff --git a/_site/templates/histogramme.njk b/_site/templates/histogramme.njk new file mode 100644 index 0000000..1dcb1b1 --- /dev/null +++ b/_site/templates/histogramme.njk @@ -0,0 +1,255 @@ +{% extends "accueil.njk" %} + +{% block meta %} + Histogramme — chaarts + + + + + + +{% endblock %} + +{% block navigation %} + +{% endblock %} + +{% block main %} +

Histogramme

+ +

+ L’histogramme sert pour les distributions de valeurs. + La structure du tableau est tout à fait ordinaire, cependant sa mise en forme repose + sur display: grid; et surtout display: contents; pour + faciliter le placement des cellules — technique inspirée par + l’article + de Hidde De Vries More accessible markup with display: contents, + et clarifiée par l’article de + Ire Aderinokun How display: contents works. +

+ +

Le principe de base est le même que le graphique en barre :

+
    +
  1. + la première ligne de la grille est réservée pour afficher la valeur textuelle lorsqu’elle approche du haut de + l’échelle, + avec une taille fixe de 2ex + — jetez un œil rudiments + concernant les unités CSS, documentés dans Every Layout par Andy Bell et Heydon + Pickering ; +
  2. +
  3. + la fonction repeat() appliquée avec la variable --scale + permet de gérer une échelle dynamique ; +
  4. +
  5. + les conteneurs <thead>, <tbody> et <tr> + sont neutralisés dans la gestion de la grille à l’aide de display: contents ; +
  6. +
  7. + chaque cellule est placée sur la grille en fonction de --value + — sa valeur, donc — sa couleur d’arrière-plan dépend également de + sa valeur ; +
  8. +
  9. + et finalement la valeur textuelle — contenue dans un élément + <span> — est positionnée en haut de la colonne + à l’aide de la même astuce que dans le graphique en barre. +
  10. +
+ +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Parts de marché navigateurs en France en janvier 2019
NavigateurChromeFirefoxSafariEdgeIEAutres
Parts de marché62 %15 %9 %5 %6 %3 %
+
+ +
+ Le HTML + +
{% include 'includes/_column-markup.njk' %}
+
+
+ Le css +
{% include 'includes/_column-styles.njk' %}
+
+ +

Colonnes multiples

+ +

+ Pour disposer de deux valeurs pour chaque colonne principale, nous devons également + disposer de deux sous-titres. + Concrètement parlant : +

+ +
    +
  1. + on ajoute une seconde ligne dans l’entête <thead> : + +
  2. +
  3. + Côté styles : + +
  4. +
+ +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parts de marché navigateurs en France en janvier 2019
NavigateurChromeFirefoxSafariEdgeIE
Année2018201920182019201820192018201920182019
Parts de marché49.6 %57 %11.74 %9.59 %21.53 %18.78 %3.72 %3.5 %4.46 %3.66 %
+
+ +
+ Le HTML + +
{% include 'includes/_columns-markup.njk' %}
+
+
+ Le css +
{% include 'includes/_columns-styles.njk' %}
+
+{% endblock %} diff --git a/_site/templates/includes/_bar-markup.njk b/_site/templates/includes/_bar-markup.njk new file mode 100644 index 0000000..5745c53 --- /dev/null +++ b/_site/templates/includes/_bar-markup.njk @@ -0,0 +1,18 @@ +
<table class="chaarts bar" style="--scale: 3000">
+  <caption id="caption-1">[…]</caption>
+  <thead class="sr-only">
+    <tr>
+      <td></td>
+      <th scope="col">[…]</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th scope="row">[…]</th>
+      <td style="--value: 4">
+        <span>[…]</span>
+      </td>
+    </tr>
+    <tr>[…]</tr>
+  </tbody>
+</table>
diff --git a/src/templates/includes/_bar-styles.html b/_site/templates/includes/_bar-styles.njk similarity index 100% rename from src/templates/includes/_bar-styles.html rename to _site/templates/includes/_bar-styles.njk diff --git a/_site/templates/includes/_column-markup.njk b/_site/templates/includes/_column-markup.njk new file mode 100644 index 0000000..1acd590 --- /dev/null +++ b/_site/templates/includes/_column-markup.njk @@ -0,0 +1,17 @@ +
<table class="chaarts column" id="column" style="--y: 7;">
+  <caption id="caption-7">[…]</caption>
+  <thead>
+    <tr>
+      <th scope="row">[…]</th>
+      <th scope="col" style="--value: 62;">Chrome</th>
+      <th scope="col" style="--value: 15;">Firefox</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th scope="row">[…]</th>
+      <td style="--value: 62;"><span>62%</span></td>
+      <td style="--value: 15;"><span>15%</span></td>
+    </tr>
+  </tbody>
+</table>
diff --git a/src/templates/includes/_column-styles.html b/_site/templates/includes/_column-styles.njk similarity index 98% rename from src/templates/includes/_column-styles.html rename to _site/templates/includes/_column-styles.njk index b96f258..1ab2b91 100644 --- a/src/templates/includes/_column-styles.html +++ b/_site/templates/includes/_column-styles.njk @@ -14,7 +14,7 @@ margin: 0; } - .chaarts[class*="column"] tr > * + * { + .chaarts[class*="column"] tr > * + * { text-align: center; } diff --git a/_site/templates/includes/_columns-markup.njk b/_site/templates/includes/_columns-markup.njk new file mode 100644 index 0000000..023213c --- /dev/null +++ b/_site/templates/includes/_columns-markup.njk @@ -0,0 +1,21 @@ +
<table class="chaarts column-multiple" id="column-multiple" style="--y: 11; --span: 2;">
+  <caption id="caption-8">[…]</caption>
+  <thead>
+    <tr>
+      <th scope="row" id="browser">[…]</th>
+      <th scope="col" colspan="2" id="chrome">Chrome</th>
+    </tr>
+    <tr>
+      <th scope="row" id="year">[…]</th>
+      <th scope="col" id="chrome-2018">2018</th>
+      <th scope="col" id="chrome-2019">2019</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <th scope="row" id="parts">[…]</th>
+      <td style="--value: 50;" headers="browser chrome year chrome-2018"><span>49.6%</span></td>
+      <td style="--value: 57;" headers="browser chrome year chrome-2019"><span>57%</span></td>
+    </tr>
+  </tbody>
+</table>
diff --git a/src/templates/includes/_columns-styles.html b/_site/templates/includes/_columns-styles.njk similarity index 100% rename from src/templates/includes/_columns-styles.html rename to _site/templates/includes/_columns-styles.njk diff --git a/src/templates/includes/_donut-styles.html b/_site/templates/includes/_donut-styles.njk similarity index 100% rename from src/templates/includes/_donut-styles.html rename to _site/templates/includes/_donut-styles.njk diff --git a/src/templates/includes/_inclusive-toggle.html b/_site/templates/includes/_inclusive-toggle.njk similarity index 100% rename from src/templates/includes/_inclusive-toggle.html rename to _site/templates/includes/_inclusive-toggle.njk diff --git a/_site/templates/includes/_line-markup.njk b/_site/templates/includes/_line-markup.njk new file mode 100644 index 0000000..99e933c --- /dev/null +++ b/_site/templates/includes/_line-markup.njk @@ -0,0 +1,17 @@ +
<table class="chaarts line" style="--y: 32; --x: 13; --t-1: 'Jan.'; --t-2: 'Feb.'; […]">
+  <caption id="caption-3">[…]</caption>
+  <thead>
+    <tr>
+      <th scope="col">[…]</th>
+      <th scope="col">Jan.</th>
+      <th scope="col">[…]</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr style="--year: '2017'; --1: 8; --2: 6; --3: 9; --4: 12; --5: 15; --6: 21; --7: 24; --8: 25; --9: 22; --10: 19; --11: 14; --12: 9;">
+      <th scope="row">2017</th>
+      <td>8 °C</td>
+      <td>[…]</td>
+    </tr>
+  </tbody>
+</table>
diff --git a/src/templates/includes/_line-styles.html b/_site/templates/includes/_line-styles.njk similarity index 100% rename from src/templates/includes/_line-styles.html rename to _site/templates/includes/_line-styles.njk diff --git a/src/templates/includes/_lines-styles.html b/_site/templates/includes/_lines-styles.njk similarity index 100% rename from src/templates/includes/_lines-styles.html rename to _site/templates/includes/_lines-styles.njk diff --git a/_site/templates/includes/_pie-markup.njk b/_site/templates/includes/_pie-markup.njk new file mode 100644 index 0000000..9b29d2e --- /dev/null +++ b/_site/templates/includes/_pie-markup.njk @@ -0,0 +1,16 @@ +
<table class="chaarts pie">
+  <caption id="caption-5">[…]</caption>
+  <thead class="sr-only">
+    <tr>
+      <th scope="col">[…]</th>
+      <th scope="col">[…]</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr style="--color: #734bf9; --term: 'HTML';">
+      <th scope="row">HTML</th>
+      <td style="--value: 2; --start: 0;">2 %</td>
+    </tr>
+    <tr>[…]</tr>
+  </tbody>
+</table>
diff --git a/src/templates/includes/_pie-styles:44.html b/_site/templates/includes/_pie-styles:44.njk similarity index 100% rename from src/templates/includes/_pie-styles:44.html rename to _site/templates/includes/_pie-styles:44.njk diff --git a/src/templates/includes/_pie-styles:64.html b/_site/templates/includes/_pie-styles:64.njk similarity index 100% rename from src/templates/includes/_pie-styles:64.html rename to _site/templates/includes/_pie-styles:64.njk diff --git a/src/templates/includes/_pie-styles:88.html b/_site/templates/includes/_pie-styles:88.njk similarity index 100% rename from src/templates/includes/_pie-styles:88.html rename to _site/templates/includes/_pie-styles:88.njk diff --git a/src/templates/includes/_polar-styles.html b/_site/templates/includes/_polar-styles.njk similarity index 100% rename from src/templates/includes/_polar-styles.html rename to _site/templates/includes/_polar-styles.njk diff --git a/_site/templates/includes/_radar-markup.njk b/_site/templates/includes/_radar-markup.njk new file mode 100644 index 0000000..ed7d5ab --- /dev/null +++ b/_site/templates/includes/_radar-markup.njk @@ -0,0 +1,15 @@ +
<table class="chaarts radar" id="radar" style="--scale: 20; --step: 5; --items: 7; --1: 14; --2: 11; --3: 13; --4: 16; --5: 10; --6: 12; --7: 4; --8: var(--1);">
+  <caption id="caption-9">[…]</caption>
+  <thead>
+    <tr>
+      <th scope="col">[…]</th>
+      <th scope="col">[…]</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td><span>14</span></td>
+      <td><span>11</span></td>
+    </tr>
+  </tbody>
+</table>
diff --git a/src/templates/includes/_radar-styles.html b/_site/templates/includes/_radar-styles.njk similarity index 98% rename from src/templates/includes/_radar-styles.html rename to _site/templates/includes/_radar-styles.njk index 0b3f02a..7ad64c9 100644 --- a/src/templates/includes/_radar-styles.html +++ b/_site/templates/includes/_radar-styles.njk @@ -47,7 +47,7 @@ rotate( calc(var(--part) * var(--index, 1) * -1) ); } - .chaarts[class*="radar"] tr > *:nth-of-type(2) { + .chaarts[class*="radar"] tr > *:nth-of-type(2) { --index: 2; } diff --git a/_site/templates/includes/_radars-markup.njk b/_site/templates/includes/_radars-markup.njk new file mode 100644 index 0000000..e4cd3e0 --- /dev/null +++ b/_site/templates/includes/_radars-markup.njk @@ -0,0 +1,19 @@ +
<table class="chaarts radar-multiple" id="radar-multiple" style="--scale: 20; --step: 5; --items: 7; --areas: 2;">
+  <caption id="caption-9">[…]</caption>
+  <thead>
+    <tr>
+      <th scope="col">[…]</th>
+      <th scope="col">[…]</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr style="--color: #734bf9; --1: 14; --2: 11; --3: 13; --4: 16; --5: 14; --6: 10; --7: 4; --8: var(--1);">
+      <th scope="row">Gaël</th>
+      <td><span>14</span></td>
+    </tr>
+    <tr style="-color: #e11a81; --1: 18; --2: 10; --3: 11; --4: 16; --5: 10; --6: 12; --7: 11; --8: var(--1);">
+      <th scope="row">Luc</th>
+      <td><span>18</span></td>
+    </tr>
+  </tbody>
+</table>
diff --git a/src/templates/includes/_radars-styles.html b/_site/templates/includes/_radars-styles.njk similarity index 100% rename from src/templates/includes/_radars-styles.html rename to _site/templates/includes/_radars-styles.njk diff --git a/src/templates/includes/_sin-mixin.html b/_site/templates/includes/_sin-mixin.njk similarity index 100% rename from src/templates/includes/_sin-mixin.html rename to _site/templates/includes/_sin-mixin.njk diff --git a/src/templates/includes/_svg-encoding.html b/_site/templates/includes/_svg-encoding.njk similarity index 100% rename from src/templates/includes/_svg-encoding.html rename to _site/templates/includes/_svg-encoding.njk diff --git a/src/templates/includes/_waterfall-markup.html b/_site/templates/includes/_waterfall-markup.njk similarity index 83% rename from src/templates/includes/_waterfall-markup.html rename to _site/templates/includes/_waterfall-markup.njk index 2cc6371..5bf7cda 100644 --- a/src/templates/includes/_waterfall-markup.html +++ b/_site/templates/includes/_waterfall-markup.njk @@ -1,3 +1,3 @@
<table class="chaarts bar waterfall"
- style="--scale: 3000; --1: 4; --2: 96; --3: 102; --4: 129; --5: 188; --6: 194; --7: 326; --8: 836; --9: 836; --10: 2561; --11: 2980;">
-</table>
+ style="--scale: 3000; --1: 4; --2: 96; --3: 102; --4: 129; --5: 188; --6: 194; --7: 326; --8: 836; --9: 836; --10: 2561; --11: 2980;"> +</table> diff --git a/src/templates/includes/_waterfall-styles.html b/_site/templates/includes/_waterfall-styles.njk similarity index 100% rename from src/templates/includes/_waterfall-styles.html rename to _site/templates/includes/_waterfall-styles.njk diff --git a/_site/templates/index.njk b/_site/templates/index.njk new file mode 100644 index 0000000..7e25770 --- /dev/null +++ b/_site/templates/index.njk @@ -0,0 +1,228 @@ + + + + + + + {% block meta %} + chaarts + + + + + + + {% endblock %} + + + + + + + +
+ {% block skiplinks %} +
+ Skip to main navigation + Skip to content +
+ {% endblock %} + + +
+ +
+ {% block main %} +

Chaarts

+ +

+ Every charts in this project relies solely on semantic markup + — <table> based — and a spread of + CSS variables carried by the tags. + No JavaScript required for display, and styles are + progressively enhanced depending on your browser's capabilities. +

+ +

+ Note : by virtue of the experimental + nature of these techniques and a solid foundation enhanced progressively, + I don't mention browser support for each example — but + it goes without saying that this is not magic, and only modern browsers handle this right, + with the notable exception of Edge + which does not (yet) support clip-path. + Other browsers display a properly styled table, and that's nice. +

+ +

Accessibility

+ +

+ A major effort has been made to ensure accessibility. + As mentioned above, semantic and structured markup is a prerequisite + — but it's not enough. CSS + is being applied as gradually as possible, in order to guarantee + the best possible display of data for each user. +

+ +

Accessible table

+ +

Wakeup call :

+ + + +

+ For other useful tips, I warmly recommend reading + + Data Tables Inclusive Component by Heydon Pickering, + which is a real gold mine. +

+ +

Patterns

+

+ To distinguish the different areas other than by colour, an + svg + pattern is applied in + css + — you can find some of them on the + Hero Patterns website: +

+
    +
  1. + in order to improve blending with background colors or gradients, the + background-blend-mode proerty is used with the hard-light value; +
  2. +
  3. + pattern's size and position depends directly on the value and scale of the chart, + depending on the type of chart; +
  4. +
  5. + in order not to embed too many external files, we use a + + technique proposed by Trys Mudford to include each + svg + in data URi in a css variable; + thus, a finite list of patterns is used in the theme, without ever repeating the svg. +
  6. +
+ +
+

What to encode?

+

+ Taylor Hunt + a comprehensive article on optimizing past svg + in URi data. In summary, only the chevrons and the "#" character need to be encoded + in the css. + Don't bother with the other characters, their encoding seriously affects readability. +

+
+ + {% include 'includes/_svg-encoding.njk' %} + +

User preferences

+

+ In order to respect as much as possible the preferences of the visitors, + many elements have been adapted: +

+
    +
  1. + dimensions are in relatives units (em or rem as the case may be), + in order to fit coherently with the body of text inherited from the browser and to be able + to be enlarged or reduced without loss; +
  2. +
  3. + colors are adjusted when Windows High Contrast Mode is detected using + -ms-high-contrast: active, inspired by + + Greg Whitworth article on the topic. I also recommend you + + Test of System Colors Specified in CSS 2 rustproof page written by + Ian Graham, published in… 2000! +
  4. +
  5. + animations and transitions are disabled when the system exposes + this preference through prefers-reduced-motion: reduce ; +
  6. +
  7. + hover effects whose initial state consists in hiding content + are activated contextually in the @media (hover: hover) { … } media query. +
  8. +
+ +

display and semantics

+

+ Adrian Roselli explains that playing with a <table> or <dl> + element's display endangers its semantics. + The latter is therefoore "locked" using dedicated + aria + roles — as he explains + in a detailed article. +

+

+ That's why each table is preceded by a switch — based on + Heydon Pickering + inclusive toggle button — + whose one and only role is to disable additional styles: +

+ + {% include 'includes/_inclusive-toggle.njk' %} + +

+ Well, we're ready to get to the heart of the matter.
+ Warm up your dev tools! +

+ {% endblock %} +
+ +{% block scripts %} + + +{% endblock %} + +{% block modal %} +{% endblock %} + + diff --git a/_site/templates/line-charts.njk b/_site/templates/line-charts.njk new file mode 100644 index 0000000..f32c549 --- /dev/null +++ b/_site/templates/line-charts.njk @@ -0,0 +1,353 @@ +{% extends "index.njk" %} + +{% block meta %} + Line charts — chaarts + + + + + + +{% endblock %} + +{% block navigation %} + +{% endblock %} + +{% block main %} +

Line charts

+ +

Area charts

+ +

+ This chart is based on CSS custom properties, grids and clip-path + — the latter being the most important. +

+ +
    +
  1. + Scales are set on the table: + +
  2. +
  3. + Each line <tr> in <tbody> carries a set of variables, + corresponding to all the values it contains. + In a ::before pseudo-element, a position is defined for each value + within the clip-path polygon() function. + +
  4. +
  5. + Each cell <td> in <tbody> carries an + ::after pseudo-element used to summarize + its headers and value in a simulated tooltip, and a ::before pseudo-element + to manage an interactive layer on the cell: + +
  6. +
  7. + Everything else is just decoration:: + +
  8. +
+ + {% import 'macros/_table-line.njk' as table %} + +
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + {{ table.line('8', '°C', 'Degree Celsius') }} + {{ table.line('6', '°C', 'Degree Celsius') }} + {{ table.line('9', '°C', 'Degree Celsius') }} + {{ table.line('12', '°C', 'Degree Celsius') }} + {{ table.line('15', '°C', 'Degree Celsius') }} + {{ table.line('21', '°C', 'Degree Celsius') }} + {{ table.line('24', '°C', 'Degree Celsius') }} + {{ table.line('25', '°C', 'Degree Celsius') }} + {{ table.line('22', '°C', 'Degree Celsius') }} + {{ table.line('19', '°C', 'Degree Celsius') }} + {{ table.line('14', '°C', 'Degree Celsius') }} + {{ table.line('9', '°C', 'Degree Celsius') }} + + +
Average monthly temperature in 2017
YearJan.Feb.Mar.Apr.MayJuneJulyAug.Sep.Oct.Nov.Dec.
2017
+
+ +
+ HTML +
{% include 'includes/_line-markup.njk' %}
+
+
+ css +
{% include 'includes/_line-styles.njk' %}
+
+
+ The calculation twist +

The polygon() path

+

+ To begin with, you need to understand that clip-path is a path, + just like a vector shape. It must therefore be closed. + So the path starts at 0% 100% — bottom left, does its path life, + toggles to 100% 100% and comes back looping at 0% 100%. +

+

And in its path, each point must be positioned in abscissa and ordinate.

+

The X-axis position

+

+ The first position is simple: divide 100% by the + var(--x) scale, and multiply by the index of the element. + For example: calc( ( 100% / var(--x) * 1) ). + To place each point in the middle of its column, we shift it by half a column + — which we do by adding to the previous calculation var(--offset), + which corresponds to calc( ( 100% / var(--x) ) / 2 ).
+ The final position is therefore, here for the third point:
+ calc( ( 100% / var(--x) * 3) + var(--offset) ). +

+

The Y-axis position

+

+ In this graph, the Y-axis is the most important axis. So to place the point, + we start by calculating the ratio of its value on the scale + — formulated as follows: var(--1) / var(--y). And because + polygon() uses percentage values, we report this calculation on 100%: + ( var(--1) / var(--y) * 100% ).
+ And finally, since the polygon's datums start from the top left, the position + position must be defined according to the top of the box. + The final formula then looks like this — again for the third element: + calc( 100% - ( var(--3) / var(--y) * 100% ) ). +

+
+
+ +

Line chart with dots

+ +

In the end, this variant differs little from the previous version:

+ +
    +
  1. + the polygon() is continued to form a line, + duplicating each point with an offset of 4px + — the line thickness — and in the reverse order; +
  2. +
  3. + the ::before pseudo-element that displays the tooltip takes + here the form of a point on the curve + — positioned using the same calculations that are used in the polygon; +
  4. +
  5. + and especially, since clip-path is applied in the line + <tr>: you can put more than one ! + So we need to add a combination of color and pattern to distinguish each line + and associate them visually with their caption. +
  6. +
+ +
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + {{ table.line('8', '°C', 'Degree Celsius') }} + {{ table.line('6', '°C', 'Degree Celsius') }} + {{ table.line('9', '°C', 'Degree Celsius') }} + {{ table.line('12', '°C', 'Degree Celsius') }} + {{ table.line('15', '°C', 'Degree Celsius') }} + {{ table.line('21', '°C', 'Degree Celsius') }} + {{ table.line('24', '°C', 'Degree Celsius') }} + {{ table.line('25', '°C', 'Degree Celsius') }} + {{ table.line('22', '°C', 'Degree Celsius') }} + {{ table.line('19', '°C', 'Degree Celsius') }} + {{ table.line('14', '°C', 'Degree Celsius') }} + {{ table.line('9', '°C', 'Degree Celsius') }} + + + + {{ table.line('10', '°C', 'Degree Celsius') }} + {{ table.line('4', '°C', 'Degree Celsius') }} + {{ table.line('7', '°C', 'Degree Celsius') }} + {{ table.line('13', '°C', 'Degree Celsius') }} + {{ table.line('17', '°C', 'Degree Celsius') }} + {{ table.line('20', '°C', 'Degree Celsius') }} + {{ table.line('22', '°C', 'Degree Celsius') }} + {{ table.line('23', '°C', 'Degree Celsius') }} + {{ table.line('26', '°C', 'Degree Celsius') }} + {{ table.line('17', '°C', 'Degree Celsius') }} + {{ table.line('14', '°C', 'Degree Celsius') }} + {{ table.line('10', '°C', 'Degree Celsius') }} + + +
Average monthly temperature per year
YearJan.Feb.Feb.Mar.Apr.MayJuneJulyAug.Sep.Oct.Nov.Dec.
2017
2018
+
+ +
+ css +
{% include 'includes/_lines-styles.njk' %}
+
+ +
+

Note

+

+ To play more and familiarize yourself with clip-path, + Bennett Feely created + clippy. +

+
+{% endblock %} diff --git a/_site/templates/macros/_table-bar.njk b/_site/templates/macros/_table-bar.njk new file mode 100644 index 0000000..b2b3213 --- /dev/null +++ b/_site/templates/macros/_table-bar.njk @@ -0,0 +1,8 @@ +{% macro bar(term='', definition='', unit='', title='', variant='') %} + + {{ term }} + + {{ definition }}{% if unit != '' %} {% if title != '' %}{% endif %}{{ unit }}{% if title != '' %}{% endif %}{% endif %} + + +{% endmacro %} diff --git a/_site/templates/macros/_table-line.njk b/_site/templates/macros/_table-line.njk new file mode 100644 index 0000000..8228b73 --- /dev/null +++ b/_site/templates/macros/_table-line.njk @@ -0,0 +1,5 @@ +{% macro line(definition='', unit='', title='') %} + + {{ definition }}{% if unit != '' %} {% if title != '' %}{% endif %}{{ unit }}{% if title != '' %}{% endif %}{% endif %} + +{% endmacro %} diff --git a/_site/templates/macros/_table-pie.njk b/_site/templates/macros/_table-pie.njk new file mode 100644 index 0000000..d7422f5 --- /dev/null +++ b/_site/templates/macros/_table-pie.njk @@ -0,0 +1,17 @@ +{% macro pie(term='', definition='', unit='', title='', start='0', color='') %} + + {{ term }} + {% if definition < 25 %} + {% set style = "" %} + {% elif definition < 50 %} + {% set style = "--lt-25: 0; --gt-25: 1; --lt-50: 1; --gt-50: 0;" %} + {% elif definition < 75 %} + {% set style = "--lt-25: 0; --gt-25: 1; --lt-50: 0; --gt-50: 1; --lt-75: 1; --gt-75: 0;" %} + {% else %} + {% set style = "--lt-25: 0; --gt-25: 1; --lt-50: 0; --gt-50: 1; --lt-75: 0; --gt-75: 1; --lt-100: 1;" %} + {% endif %} + + {{ definition }}{% if unit != '' %} {% if title != '' %}{% endif %}{{ unit }}{% if title != '' %}{% endif %}{% endif %} + + +{% endmacro %} diff --git a/_site/templates/pie-charts.njk b/_site/templates/pie-charts.njk new file mode 100644 index 0000000..858dab2 --- /dev/null +++ b/_site/templates/pie-charts.njk @@ -0,0 +1,686 @@ +{% extends "index.njk" %} + +{% block meta %} + Pie charts — chaarts + + + + + + +{% endblock %} + +{% block navigation %} + +{% endblock %} + +{% block main %} +

Pie charts

+ +

+ The pie chart is used for representations of percentage proportions. + It relies on CSS variables, an outrageous abuse of calc(), + display: table-*, clip-path, mask-image, + transform and a bit of SVG + to distinguish each area. Yes, I know how to laugh. How do we use it? +

+ +
    +
  1. + On each header <th>, a --color + custom property allows you to assign, well… a color. +
  2. +
  3. + Then each cell <td> must contain the value + and its unit, as well as a style attribute to carry some variables: +
      +
    1. + --value is the percentage value, + useful for determining the angle the element should occupy on the circle. + All points of the polygon() — used to draw the pie part thanks to clip-path — + depend on this value (read the technical note after + the example for details of the calculations). +
    2. +
    3. + --start is used to define the starting point + of the arc on the circle. It's the sum of the previous definitions, and is applied + to the rotate() function of the transform poperty. +
    4. +
    5. + And finally a series of pseudo-boolean variables, each worthing 0 or 1 + — according to and idea of + Roman Komarov in "Conditions for CSS variables" — + depend on the value: --lt-25, --gt-25, --lt-50… + They allow to toggle the points from their original position + (50% 50%) to their calculated position, by adding or subtracting from the initial value; +
    6. +
    +
  4. +
  5. + a ::before pseudo-element on each cell <td>is formatted + in a clever way according to all our variables, including transform, + clip-path and mask-image. + +
  6. +
  7. + a ::after pseudo-element is used as a tooltip, to summarize header and value for + each cell + —but the display of custom properties in a pseudo-element is not so trivial: + +
  8. +
  9. + And finally a pattern is applied to the background, + in order to better associate it visually with the corresponding legend. +
  10. +
+ + {% import 'macros/_table-pie.njk' as table %} + +
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} + {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} + {{ table.pie('JS', '32', '%', '', '4', '#0172F0') }} + {{ table.pie('Json', '1', '%', '', '36', '#FDC02F') }} + {{ table.pie('Images', '44', '%', '', '37', '#39CA74') }} + {{ table.pie('Webfonts', '17', '%', '', '81', '#FF2D40') }} + {{ table.pie('Other', '2', '%', '', '98', '#585462') }} + +
+ Distribution of the weight of resources for + ffoodd.fr +
ResourceProportion
+
+ +
+ A bit of trigonometry +
+

+ In this graph, each portion represents an arc of a circle based on an angle (part of 360 degrees). + To define the shape of this portion, a point must be placed on the circle. +

+

+ To do this, I divide the circle into four squares. The position of the point on the circle + can then be calculated using the properties of the right-angled triangle formed by: +

+
    +
  1. the center of the circle,
  2. +
  3. the point we're trying to position,
  4. +
  5. and the point perpendicular to the radius and passing through our target point.
  6. +
+

+ We know the hypotenuse of this triangle — the radius of the circle —, + and the angle formed by the hypotenuse and starting from the center of the circle + (reducing the value to 90 degrees, since the circle is divided into four square sectors: + if the value is greater than 25: minus 90°, etc.) + — plus a right angle, of course. +

+

Law of sines

+

+ We can therefore use the sine law + to measure each side, and thus obtain the position of the point on the circle. + Meaning we need to calculate the sine… Fortunately, + Stereokai implemented + for us + the Taylor/Maclaurin polynomial representation in CSS — which I implemented as a mixin: +

+ {% include 'includes/_sin-mixin.njk' %} +

+ All that remains is to use these dimensions to place the points of the polygon. + It's child's play! +

+
+
+
+ HTML +
{% include 'includes/_pie-markup.njk' %}
+
+
+ css +
+
+	 
+@supports (clip-path: polygon( 50% calc( 50% + ( var(--gt-25, 0) ) ) )) {
+ .chaarts.pie {
+	 --radius: 32em;
+	 margin: 0 auto;
+	 padding-top: calc(var(--radius) - 2rem);
+	 position: relative;
+ }
+
+ .chaarts.pie tbody {
+	 display: table-row;
+ }
+
+ .chaarts.pie tr {
+	 display: table-cell;
+	 transition: opacity .3s cubic-bezier(.5, 0, .5, 1);
+ }
+
+ .chaarts.pie [scope="row"] {
+	 padding-right: .5rem;
+ }
+
+ .chaarts.pie [scope="row"]::before {
+	 background: var(--color, currentColor);
+	 content: "";
+	 display: inline-block;
+	 height: 1rem;
+	 transform: translate3d(-.2rem, .1rem, 0);
+	 width: 1rem;
+ }
+
+ .chaarts.pie td {
+	 --position: calc(var(--start, 0) * .01turn);
+ }
+
+ .chaarts.pie td::after,
+ .chaarts.pie td::before {
+	 left: 50%;
+	 position: absolute;
+	 top: calc(var(--radius) / 2);
+	 transform-origin: center center;
+ }
+
+ .chaarts.pie td::before {
+	 /* The inclination, to be in the right place */
+	 --position: calc(var(--start, 0) * .01turn);
+	 --zoom: .75;
+	 /* The angle represented by the value: 3.6 = 360deg / 100 */
+	 /* Since we're using a percentage value */
+	 --part: calc( var(--value) * 3.6 );
+	 /* The "useful" angle for the calculation, necessarily less than 90deg */
+	 /*  We therefore subtract 90deg (= ¼ × 360deg) per 25% (= ¼ × 100%, indeed) */
+	 --main-angle: calc( var(--part) - ( 90 * ( var(--gt-25, 0) + var(--gt-50, 0) + var(--gt-75, 0) ) ) );
+	 /* Main angle, in radian */
+	 --β: calc( var(--main-angle) * 0.01745329251 );
+	 /* The last angle in radian, by deduction since in a right-angled triangle */
+	 --α: calc( ( 90 - var(--main-angle) ) * 0.01745329251 );
+	 /* The magic of Stereokai, to get the sinus from these angles… */
+	 --sin-term-β-1: var(--β);
+	 --sin-term-β-2: calc((var(--β) * var(--β) * var(--β)) / 6);
+	 --sin-term-β-3: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 120);
+	 --sin-term-β-4: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 5040);
+	 --sin-term-β-5: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 362880);
+	 --sin-β: calc(var(--sin-term-β-1) - var(--sin-term-β-2) + var(--sin-term-β-3) - var(--sin-term-β-4) + var(--sin-term-β-5));
+	 --sin-term-α-1: var(--α);
+	 --sin-term-α-2: calc((var(--α) * var(--α) * var(--α)) / 6);
+	 --sin-term-α-3: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 120);
+	 --sin-term-α-4: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 5040);
+	 --sin-term-α-5: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 362880);
+	 --sin-α: calc(var(--sin-term-α-1) - var(--sin-term-α-2) + var(--sin-term-α-3) - var(--sin-term-α-4) + var(--sin-term-α-5));
+	 /* Finally, the position expressed in %, of the hypothenuse, divided by 2 to fit in ¼ of the circle
+		* or after simplification, divided by 50 */
+	 --pos-B: calc( var(--sin-β) * 50 );
+	 --pos-A: calc( var(--sin-α) * 50 );
+	 background-color: var(--color, currentColor) var(--background);
+	 --polygon: polygon(
+		 50% 50%,
+		 50% 0%,
+		 100% 0%,
+		 calc( 50% + ( var(--pos-B) * 1% * var(--lt-25, 1) ) + ( var(--gt-25, 0) * 50% ) ) calc( 50% - ( var(--pos-A) * 1% * var(--lt-25, 1) ) ),
+		 calc( 50% + ( var(--gt-25, 0) * 50% ) )                      calc( 50% + ( var(--gt-25, 0) * 50% ) ),
+		 calc( 50% + ( var(--pos-A) * 1% * var(--lt-50, 1) ) + ( var(--gt-50, 0) * 50% ) ) calc( 50% + ( var(--pos-B) * 1% * var(--lt-50, 1) ) + ( var(--gt-50, 0) * 50% ) ),
+		 calc( 50% - ( var(--gt-50, 0) * 50% ) )                      calc( 50% + ( var(--gt-50, 0) * 50% ) ),
+		 calc( 50% - ( var(--pos-B) * 1% * var(--lt-75, 1) ) - ( var(--gt-75, 0) * 50% ) ) calc( 50% + ( var(--pos-A) * 1% * var(--lt-75, 1) ) ),
+		 calc( 50% - ( var(--gt-75, 0) * 50% ) )                      calc( 50% - ( var(--gt-75, 0) * 50% ) ),
+		 calc( 50% - ( var(--pos-A) * 1% * var(--gt-75, 0) ) )        calc( 50% - ( var(--pos-B) * 1% * var(--gt-75, 0) ) ),
+		 50% 50%
+	 );
+	 clip-path: var(--polygon);
+	 content: '';
+	 height: var(--radius);
+	 --mask: radial-gradient(
+		 circle at center,
+		 white 0%,
+		 white calc(var(--radius)  / 2),
+		 transparent calc(var(--radius)  / 2)
+	 );
+	 mask-image: var(--mask);
+	 transform:
+		 translate3d(-50%, -50%, 0)
+		 rotate( var(--position) )
+		 scale( var(--zoom) );
+	 transition: transform .2s cubic-bezier(.5, 0, .5, 1);
+	 width: var(--radius);
+ }
+
+ .chaarts.pie tr:hover td::before {
+	 --zoom: .8;
+ }
+
+ .chaarts.pie tr:nth-child(2n + 2) *::before {
+	 --background: var(--stripes);
+ }
+
+ .chaarts.pie td::after {
+	 --arrow: calc(100% - .25rem);
+	 --axis: calc( var(--position) - .25turn + var(--value) * .005turn );
+	 --away: calc( var(--radius) / 2 - 1rem );
+	 --integer: calc(var(--value));
+	 background-color: #444;
+	 color: white;
+	 content: var(--term) "\A0: " counter(value) "\A0%";
+	 counter-reset: value var(--integer);
+	 opacity: 0;
+	 padding: .5rem;
+	 pointer-events: none;
+	 transform-origin: 50% calc(100% + 10px);
+	 transform:
+		 translate3d(-50%, -50%, 0)
+		 rotate( var(--axis) )
+		 translate( var(--away) )
+		 rotate( calc( var(--axis) * -1 ) )
+		 perspective(1000px)
+		 rotate3d(1, 0, 0, 45deg);
+	 transition:
+		 opacity .2s cubic-bezier(0, .5, .5, 1),
+		 transform .2s cubic-bezier(0, .5, .5, 1);
+ }
+
+ .chaarts.pie tbody:hover tr {
+	 opacity: .75;
+ }
+
+ .chaarts.pie tbody:hover tr:hover {
+	 opacity: 1;
+ }
+
+ .chaarts.pie tbody:hover td::after {
+	 opacity: 1;
+	 transform:
+		 translate3d(-50%, -50%, 0)
+		 rotate( var(--axis) )
+		 translate( var(--away) )
+		 rotate( calc( var(--axis) * -1 ) )
+		 perspective(1000px)
+		 rotate3d(1, 0, 0, 0deg);
+	 transition:
+		 opacity .2s cubic-bezier(.5, 0, 1, .5),
+		 transform .2s cubic-bezier(.5, 0, 1, .5);
+ }
+
+ @media screen and (-ms-high-contrast: active) {
+	 .chaarts.pie tr *::before {
+		 background-color: Window;
+	 }
+
+	 .chaarts.pie tr:nth-of-type(odd) *::before {
+		 background-color: WindowText;
+	 }
+ }
+}
+	
+
+
+
+ The calculation twist +

The positions of the polygon

+

+ The use of pseudo-Boolean variables makes this calculation pseudo-algorithmic. + Let's start with an essential pre-requisite: the polygon being a closed shape and CSS + not being magical, points must pre-exist. + Spoiler, we need eleven points: +

+
    +
  1. + The initial axis, from centre upwards: 50% 50% + and 50% 0%. +
  2. +
  3. + One point for each angle at the ends: the first one is fixed, at + 100% 0% (top right) — then each of the other angles has + two states, reached or not reached. Some insights: +
      +
    • + For example, the point at the bottom right concerns values between 25% and 50%: + if the value is less than 25%, it must be in the centre (so as not to interfere + with the drawing), and if not, it must be in its corner: + calc( 50% + ( var(--gt-25, 0) * 50% ) ) calc( 50% + ( var(--gt-25, 0) * 50% ) )
      + Thus the calculated value will be 50% 50% if --gt-25 is 0, + and 100% 100% if --gt-25 is 1. +
    • +
    • + In addition, each angle has its target coordinate: + 100% 100% for bottom right, 0% 100% for bottom left, + 0% 0% for top left. It is therefore necessary to sometimes subtract + and sometimes add to the initial value 50% 50% + to switch to the right point. +
    • +
    +
  4. +
  5. + One point for each possible position per quarter circle, corresponding + to each 25% slice. Like the points at the corners, these points must be in the centre + if they are not used. That's where we laugh the most: +
      +
    • we start from 50%, to which we add or subtract the following calculation;
    • +
    • + then the calculated position is used — --pos-A + or --pos-B as the case may be — which is converted into percentages using + * 1%, and rendered inert if the value is less than the range concerned + using * var(--lt-25, 1), for example.
      + + Notice the second value in var()? + This is the default value if the variable is not defined. Cool, isn't it? + +
    • +
    • + finally when the range is exceeded, the point switches to + 0% or 100% as appropriate. +
    • +
    +
  6. +
  7. + And lastly, we lose the path by going back to the centre of the circle, + at 50% 50%. +
  8. +
+

That's it!

+

The positions illustrated

+

+ These screenshots — taken in + the shape editor of + the + Firefox devtools — + show the points of the polygon in the different cases. + You can see for each cited value the resolved polygon for clip-path + — and see how the dynamic values tilt from one position to another. +

+ +
+ +
+
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} + {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} + {{ table.pie('JS', '32', '%', '', '4', '#0172F0') }} + {{ table.pie('Images', '64', '%', '', '36', '#39CA74') }} + +
Pie chart example with a value between 50 and 75%
ResourceProportion
+
+ +
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} + {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} + {{ table.pie('JS', '8', '%', '', '4', '#0172F0') }} + {{ table.pie('Images', '88', '%', '', '12', '#39CA74') }} + +
Pie chart example with a value greater than 75%
ResourceProportion
+
+
+ +

Donut

+ +

+ On the <table> element, we add an --offset variable + that allows us to determine the size of the hole of the donut, + generated using mask-image and radial-gradient(). + Ana Tudor has made + many examples of using mask-* on CodePen, have a look! +

+ +
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} + {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} + {{ table.pie('JS', '32', '%', '', '4', '#0172F0') }} + {{ table.pie('Json', '1', '%', '', '36', '#FDC02F') }} + {{ table.pie('Images', '44', '%', '', '37', '#39CA74') }} + {{ table.pie('Webfonts', '17', '%', '', '81', '#FF2D40') }} + {{ table.pie('Other', '2', '%', '', '98', '#585462') }} + +
Distribution of the weight of resources for ffoodd.fr +
ResourceProportion
+
+ +
+ css +
{% include 'includes/_donut-styles.njk' %}
+
+ +
+

Conical gradient

+

+ The use of conic-gradient() is promising for this case. + You'll find examples made by Ana Tudor and Léa Verou + — who actually wrote the specification, and designed + a polyfill. + However, current support is limited to WebKit based + browsers + is depressing, and still raises some accessibility issues + since you can't assign a pattern to each color of the conic-gradient(). +

+
+ +

Polar chart

+ +

+ For this variant, wa change almost nothing: only the --zoom variable + and its implication in the scaling of portions using scale(). +

+ +
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} + {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} + {{ table.pie('JS', '32', '%', '', '4', '#0172F0') }} + {{ table.pie('Json', '1', '%', '', '36', '#FDC02F') }} + {{ table.pie('Images', '44', '%', '', '37', '#39CA74') }} + {{ table.pie('Webfonts', '17', '%', '', '81', '#FF2D40') }} + {{ table.pie('Other', '2', '%', '', '98', '#585462') }} + +
Distribution of the weight of resources for ffoodd.fr +
ResourceProportion
+
+ +
+ css +
{% include 'includes/_polar-styles.njk' %}
+
+{% endblock %} diff --git a/_site/templates/radar-charts.njk b/_site/templates/radar-charts.njk new file mode 100644 index 0000000..0a8ab60 --- /dev/null +++ b/_site/templates/radar-charts.njk @@ -0,0 +1,352 @@ +{% extends "index.njk" %} + +{% block meta %} + Radar charts — chaarts + + + + + + +{% endblock %} + +{% block navigation %} + +{% endblock %} + +{% block main %} +

Radar charts

+ +

+ This one's kind of fun. We define some CSS + variables on the table: the scale (and tiers), the number of elements, and the values. +

+ +

+ On the CSS side, it's getting complicated: +

+ + + +

And that's it!

+ +
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Level of interest by domain, out of 20
AccessibilitySEOPerformanceCompatibilitySecurityCode qualityTest
1411131610124
+
+ +
+ HTML +
{% include 'includes/_radar-markup.njk' %}
+
+
+ css +
{% include 'includes/_radar-styles.njk' %}
+
+
+ A Chromium bug +

+ There is currently a bug in Chromium — I filled + an issue on bugs.chromium.org — + when using the border-spacing property on the table: + it prevents Chrome to define the dimensions of the table… + For Chrome user, use the inspector to uncheck this property on the + <table> tag of these examples! +

+

Reduced test case

+
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Level of interest by domain, out of 20
AccessibilitySEOPerformanceCompatibilitySecurityCode qualityTest
1411131610124
+
+
+
+ A Firefox feature +
+ The skew() function deforms the element by tilting it. +
+ Screenshot of the deformation caused by skew() + – props to Patrick Brosset + who made CSS + transform Highlighter happen in Firefox DevTools. +
+
+
+ + +

Overlapping radars

+ +

Very few changes compared to the previous version:

+ +
    +
  1. + the <table> element no longer carries the values, + but has a new --areas custom property to indicate the number of rows in the table; +
  2. +
  3. + however we multiply the number of rows in the body of the table: + +
  4. +
  5. + the rest is relatively common now — if you've gone through the previous examples: +
      +
    1. + a color for each row, presented on the header cells + and serving as a background for the data cells; +
    2. +
    3. + a distinctive hover effect over each row: the values appear + verbatim on hovering, and the hovered row is highlighted. In order not to deprive users + who do not have a good hover pointer, this effect is a progressive enhancement + based on the @media (hover: hover) { … } media query. +
    4. +
    +
  6. + +
+ +
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Level of interest by domain, out of 20
AccessibilitySEOPerformanceCompatibilitySecurityCode qualityTest
Gaël1411131614104
Luc18101116101211
+
+ +
+ HTML +
{% include 'includes/_radars-markup.njk' %}
+
+
+ css +
{% include 'includes/_radars-styles.njk' %}
+
+{% endblock %} diff --git a/_site/templates/radar.njk b/_site/templates/radar.njk new file mode 100644 index 0000000..de49403 --- /dev/null +++ b/_site/templates/radar.njk @@ -0,0 +1,357 @@ +{% extends "accueil.njk" %} + +{% block meta %} + Radar — chaarts + + + + + + +{% endblock %} + +{% block navigation %} + +{% endblock %} + +{% block main %} +

Graphique radar

+ +

+ Celui-ci est plutôt amusant. On définit quelques variables + CSS sur le tableau +  : l’échelle (et les paliers), le nombre d’éléments, et les valeurs. +

+ +

+ Côté CSS, ça se complique : +

+ + + +

Et voilà, c’est tout !

+ +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Niveau d’intérêt par domaine, sur 20
AccessibilitéRéférencementPerformanceCompatibilitéSécuritéQualité de codeTest
1411131610124
+
+ +
+ Le HTML + +
{% include 'includes/_radar-markup.njk' %}
+
+
+ Le css +
{% include 'includes/_radar-styles.njk' %}
+
+
+ Bug dans Chromium +

+ Il y a en ce moment un bug dans Chromium — j’ai saisi + un ticket sur bugs.chromium.org — + lors de l’utilisation de la propriété border-spacing sur le tableau : + cela empêche Chrome de définir les dimensions du tableau… + Pour les utilisateurs de Chrome, utilisez l’inspecteur pour décocher cette propriété + sur la balise <table> de ces exemples ! +

+

Cas de test réduit

+
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Niveau d’intérêt par domaine, sur 20
AccessibilitéRéférencementPerformanceCompatibilitéSécuritéQualité de codeTest
1411131610124
+
+
+
+ Une fonctionnalité Firefox +
+ La fonction skew() déforme l’élément en l’inclinant. +
+ Capture d’écran de la déformation provoquée par skew() + – merci à Patrick Brosset + qui a mis en place la + prévisualisation des transformations CSS dans les outils de développement de Firefox. +
+
+
+ + +

Radars superposés

+ +

Très peu de changements par rapport à la version précédente :

+ +
    +
  1. + l’élément <table> ne porte plus les valeurs, mais dispose d’une nouvelle + variable --areas pour indiquer le nombre de lignes dans le tableau ; +
  2. +
  3. + en revanche on multiplie le nombre de lignes dans le corps du tableau : + +
  4. +
  5. + le reste est relativement commun désormais — si vous avez parcourus les exemples précédents : +
      +
    1. + une couleur pour chaque ligne, présentée sur les cellules d’entête et servant d’arrière-plan aux + cellules de données ; +
    2. +
    3. + un effet distinctif au survol de chaque ligne : les valeurs apparaissent + textuellement au survol, et la ligne survolée est mise en exergue. Afin de ne pas priver les utilisateurs + n’ayant pas de pointeur doué pour le survol, cet effet est une amélioration progressive + basé sur la media query @media (hover: hover) { … }. +
    4. +
    +
  6. + +
+ +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Niveau d’intérêt par domaine, sur 20
AccessibilitéRéférencementPerformanceCompatibilitéSécuritéQualité de codeTest
Gaël1411131614104
Luc18101116101211
+
+ +
+ Le HTML + +
{% include 'includes/_radars-markup.njk' %}
+
+
+ Le css +
{% include 'includes/_radars-styles.njk' %}
+
+{% endblock %} diff --git a/dist/chaarts.css b/dist/chaarts.css new file mode 100644 index 0000000..6b8e821 --- /dev/null +++ b/dist/chaarts.css @@ -0,0 +1,1518 @@ +@charset "UTF-8"; +/* ==================== */ +/* == Abstracts +/* ==================== */ +/* ==================== */ +/* == Convert to +/* ==================== */ +/** + * Using Houdini's @property to ensure --integer is type in Chromium-based browsers + * @link https://developer.mozilla.org/en-US/docs/Web/CSS/@property + * @link https://caniuse.com/mdn-css_at-rules_property + ** Based on: + ** @author Carter Li + ** @link https://css-tricks.com/animating-number-counters/#the-new-school-css-solution + */ +@property --integer { + syntax: ""; + initial-value: 0; + inherits: false; +} +/* ==================== */ +/* == Tables +/* ==================== */ +table { + border-collapse: collapse; + caption-side: top; + font-feature-settings: "tnum"; + margin-bottom: 1.5rem; + width: 100%; + vertical-align: top; +} +table > caption:first-child { + font-style: italic; + margin: 0; + padding: 2.5rem 1rem; +} + +th, +td { + padding: 0.5rem 0.75rem; + text-align: left; +} + +th, +table strong { + color: black; +} + +td { + line-height: 1.25; + max-width: 100%; +} + +tbody { + border: 1px solid dimgray; +} + +thead { + border: 1px solid black; +} + +/* ==================== */ +/* == Charts +/* ==================== */ +/** + * Gives scrollable table some UX hints with shadows + * @author Chen Hui Jing + * @link https://codepen.io/huijing/pen/XBGaNQ + ** Based on: + ** @author Lea Verou + ** @link http://lea.verou.me/2012/04/background-attachment-local/ + */ +.table-container { + background: linear-gradient(to right, rgb(255, 255, 255) 30%, rgba(255, 255, 255, 0)), linear-gradient(to right, rgba(255, 255, 255, 0), rgb(255, 255, 255) 70%) 0 100%, radial-gradient(farthest-side at 0% 50%, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0)), radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0)) 0 100%; + background-repeat: no-repeat; + background-color: white; + background-size: 2.5rem 100%, 2.5rem 100%, 1rem 100%, 1rem 100%; + background-position: 0 0, 100%, 0 0, 100%; + background-attachment: local, local, scroll, scroll; + margin: 2rem 0; + max-width: 100%; + overflow-x: auto; + overflow-y: hidden; +} + +.table-container .fieldset { + display: none !important; + padding: 0 1rem; +} + +[class*=chaarts] [role=presentation] { + display: none; +} +[class*=chaarts] abbr[title] { + border-bottom: 0; + font-size: small; + font-weight: normal; + text-transform: none; +} + +.chaarts { + caption-side: bottom; + empty-cells: hide; + margin: 1.5em auto; + overflow: hidden; + padding: 1em; + /** + * @note Defining a CSS custom property for each inlined SVG pattern + * @author Trys Mudford + * @link https://www.trysmudford.com/blog/using-css-custom-properties/ + * @via Jeremy Keith + * @link https://adactio.com/journal/15075 + */ + --checkers: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3E%3Cg fill='%23ffffff99'%3E%3Cpath fill-rule='evenodd' d='M0 0h4v4H0V0zm4 4h4v4H4V4z'/%3E%3C/g%3E%3C/svg%3E"); + --hexagons: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='24' viewBox='0 0 28 49'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23ffffff99' fill-rule='nonzero'%3E%3Cpath d='M13.99 9.25l13 7.5v15l-13 7.5L1 31.75v-15l12.99-7.5zM3 17.9v12.7l10.99 6.34 11-6.35V17.9l-11-6.34L3 17.9zM0 15l12.98-7.5V0h-2v6.35L0 12.69v2.3zm0 18.5L12.98 41v8h-2v-6.85L0 35.81v-2.3zM15 0v7.5L27.99 15H28v-2.31h-.01L17 6.35V0h-2zm0 49v-8l12.99-7.5H28v2.31h-.01L17 42.15V49h-2z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); + --triangles: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='16' viewBox='0 0 36 72'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23ffffff99'%3E%3Cpath d='M2 6h12L8 18 2 6zm18 36h12l-6 12-6-12z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); + --zig: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='12' viewBox='0 0 20 12'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23ffffff99'%3E%3Cpath d='M9.8 12L0 2.2V.8l10 10 10-10v1.4L10.2 12h-.4zm-4 0L0 6.2V4.8L7.2 12H5.8zm8.4 0L20 6.2V4.8L12.8 12h1.4zM9.8 0l.2.2.2-.2h-.4zm-4 0L10 4.2 14.2 0h-1.4L10 2.8 7.2 0H5.8z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); + --stripes: url("data:image/svg+xml,%3Csvg width='6' height='6' viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff99' fill-rule='evenodd'%3E%3Cpath d='M5 0h1L0 6V5zM6 5v1H5z'/%3E%3C/g%3E%3C/svg%3E"); + --dots: url("data:image/svg+xml,%3Csvg width='10' height='10' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff99' fill-rule='evenodd'%3E%3Ccircle cx='3' cy='3' r='3'/%3E%3Ccircle cx='13' cy='13' r='3'/%3E%3C/g%3E%3C/svg%3E"); +} +.chaarts > caption:first-child { + background: inherit; + font-style: normal; + padding: 1rem 0; +} + +table:not(.chaarts) .sr-only { + clip: auto !important; + clip-path: none !important; + height: auto !important; + overflow: visible !important; + position: static !important; + width: auto !important; + white-space: normal !important; +} + +@media screen and (min-width: 30em) { + .chaarts { + border-collapse: separate; + /** + * @note Trying to improve paint & layout performances + * @link https://developer.mozilla.org/fr/docs/Web/CSS/contain + */ + contain: content; + /* + * @bugfix + * @affected Chromium + * @link https://bugs.chromium.org/p/chromium/issues/detail?id=939728 + */ + } + .chaarts:not([class*=radar]) { + border-spacing: 0; + } + .chaarts th, + .chaarts td { + border: 0; + padding: 0; + } + .chaarts th:empty, + .chaarts td:empty { + display: none !important; + } + /* ==================== */ + /* == Bar Charts + * + * @note Grid charts based on: + * @see https://css-tricks.com/css-charts-grid-custom-properties/ + * @author Miriam Suzanne + * + * @note Grid setup: + * 1. 1st column to display legends, fixed width + * 1. 2nd column is a repeater, creating a subcolumn for each unit in --scale + * 1. 3rd columns with 6ch width to ensure that 6 characters long values has enough space to not overflow
+ * + * @note Clipped value coming from: + * @see https://www.ffoodd.fr/le-web-en-kit/ + * @see http://dabblet.com/gist/08fddf3666c39ebc62ca + * @author Gaël Poupard + /* ==================== */ + @supports (grid-template-columns: repeat(var(--scale, 100), minmax(0, 1fr))) { + .bar-container .fieldset { + display: flex !important; + } + .chaarts.bar caption { + text-align: initial; + text-indent: 13.5rem; + } + .chaarts.bar tr { + display: grid; + grid-auto-rows: 1fr; + grid-row-gap: 0.5rem; + grid-template-columns: minmax(min-content, 12.5em) repeat(var(--scale, 100), minmax(0, 1fr)) 10ch; + transition: opacity 0.2s cubic-bezier(0.5, 0, 0.5, 1); + } + .chaarts.bar tr:nth-child(1n+1) { + --background: var(--checkers); + } + .chaarts.bar tr:nth-child(2n+2) { + --background: var(--hexagons); + } + .chaarts.bar tr:nth-child(3n+3) { + --background: var(--triangles); + } + .chaarts.bar tr:nth-child(4n+4) { + --background: var(--zig); + } + .chaarts.bar tr:nth-child(5n+5) { + --background: var(--stripes); + } + .chaarts.bar tr:nth-child(6n+6) { + --background: var(--dots); + } + .chaarts.bar th { + grid-column: 1/1; + margin: 0.5rem 0 0; + padding: 0 1rem 0 0; + text-align: right; + } + .chaarts.bar td { + --size: calc(var(--scale, 100) * 100%); + --position: calc(var(--value, 0) / var(--scale, 100) * 100%); + background: linear-gradient(to right, #01ac49, #444, mediumblue, rebeccapurple, crimson) var(--position) 0% / var(--size) 100%, var(--background) center/contain; + background-blend-mode: hard-light; + grid-column: 2 / var(--value, 0); + margin: 0.5rem 0 0; + position: relative; + } + .chaarts.bar span { + font-weight: bold; + left: 100%; + line-height: 1.5; + position: absolute; + /** + * @note Progressively enhance background-clipping + * @author S. Shaw + * @link https://twitter.com/shshaw/status/1140637533539377153 + * Support is quite good actually + * @link https://caniuse.com/background-clip-text + */ + } + @supports (background-clip: text) or (-webkit-background-clip: text) { + .chaarts.bar span { + background: inherit; + -webkit-background-clip: text; + background-clip: text; + color: transparent; + } + } + .chaarts.bar:hover tr { + opacity: 0.5; + } + .chaarts.bar:hover tr:hover { + opacity: 1; + } + @media screen and (min-width: 30em) and (-ms-high-contrast: active) { + .chaarts.bar td { + /** + * @note Custom color palette for WHCM + * @note Inspired by Greg Whitworth's post + * @link http://www.gwhitworth.com/blog/2017/04/how-to-use-ms-high-contrast + */ + background-image: linear-gradient(to right, Window, ButtonFace, ButtonShadow, ButtonText, highlight), var(--background); + } + } + .chaarts.bar.waterfall tr:nth-of-type(1) td { + grid-column: var(--0, 2) / var(--value, 2); + } + .chaarts.bar.waterfall tr:nth-of-type(2) td { + grid-column: var(--1, 2) / var(--value, 2); + } + .chaarts.bar.waterfall tr:nth-of-type(3) td { + grid-column: var(--2, 2) / var(--value, 2); + } + .chaarts.bar.waterfall tr:nth-of-type(4) td { + grid-column: var(--3, 2) / var(--value, 2); + } + .chaarts.bar.waterfall tr:nth-of-type(5) td { + grid-column: var(--4, 2) / var(--value, 2); + } + .chaarts.bar.waterfall tr:nth-of-type(6) td { + grid-column: var(--5, 2) / var(--value, 2); + } + .chaarts.bar.waterfall tr:nth-of-type(7) td { + grid-column: var(--6, 2) / var(--value, 2); + } + .chaarts.bar.waterfall tr:nth-of-type(8) td { + grid-column: var(--7, 2) / var(--value, 2); + } + .chaarts.bar.waterfall tr:nth-of-type(9) td { + grid-column: var(--8, 2) / var(--value, 2); + } + .chaarts.bar.waterfall tr:nth-of-type(10) td { + grid-column: var(--9, 2) / var(--value, 2); + } + .chaarts.bar.waterfall tr:nth-of-type(11) td { + grid-column: var(--10, 2) / var(--value, 2); + } + } + /* ==================== */ + /* == Pie Charts + /* ==================== */ + @supports (clip-path: polygon(50% calc(50% + (var(--gt-25, 0))))) { + .pie-container .fieldset { + display: flex !important; + margin-bottom: 0; + } + .chaarts.pie { + --radius: 32em; + margin: 0 auto; + padding-top: calc(var(--radius) - 2rem); + position: relative; + /** + * Using clip-path + calc() + transform + CSS vars + * Using mask-image to make a circle + * + * 1. + * @note Based on Ana Tudor's work + * @link https://css-tricks.com/1-html-element-5-css-properties-magic/ + * @author Ana Tudor + * + * 2. + * @note Using a Roma Komarov's idea about boolean custom properties + * @link https://www.kizu.ru/conditions-for-css-variables/ + * + * 3. + * @note Mask support: + * @link https://caniuse.com/#search=mask + */ + /** + * 1. + * @note Display CSS integers custom properties with a trick using counters + * @author Cassie Evans + * @link https://codepen.io/cassie-codes/pen/22ea69e0f681d45f2f4c2ca5e6acf4ab + * + * 2. + * @note We need to ensure our counter uses an integer, --value might a a floating number + * @author Carter Li + * @link https://css-tricks.com/animating-number-counters/#the-new-school-css-solution + */ + } + .chaarts.pie tbody { + display: table-row; + } + .chaarts.pie tr { + display: table-cell; + transition: opacity 0.3s cubic-bezier(0.5, 0, 0.5, 1); + } + .chaarts.pie [scope=row] { + padding-right: 0.5rem; + } + .chaarts.pie [scope=row]::before { + background: var(--color, currentColor) var(--background); + content: ""; + display: inline-block; + height: 1rem; + transform: translate3d(-0.2rem, 0.1rem, 0); + width: 1rem; + } + .chaarts.pie td { + --position: calc(var(--start, 0) * .01turn); + } + .chaarts.pie td::after, + .chaarts.pie td::before { + left: 50%; + position: absolute; + top: calc(var(--radius) / 2); + transform-origin: center center; + } + .chaarts.pie td::before { + --zoom: .75; + --part: calc(var(--value) * 3.6); + --main-angle: calc(var(--part) - (90 * (var(--gt-25, 0) + var(--gt-50, 0) + var(--gt-75, 0)))); + --β: calc(var(--main-angle) * 0.01745329251); + --α: calc((90 - var(--main-angle)) * 0.01745329251); + --sin-term-β-1: var(--β); + --sin-term-β-2: calc((var(--β) * var(--β) * var(--β)) / 6); + --sin-term-β-3: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 120); + --sin-term-β-4: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 5040); + --sin-term-β-5: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 362880); + --sin-β: calc(var(--sin-term-β-1) - var(--sin-term-β-2) + var(--sin-term-β-3) - var(--sin-term-β-4) + var(--sin-term-β-5)); + --sin-term-α-1: var(--α); + --sin-term-α-2: calc((var(--α) * var(--α) * var(--α)) / 6); + --sin-term-α-3: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 120); + --sin-term-α-4: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 5040); + --sin-term-α-5: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 362880); + --sin-α: calc(var(--sin-term-α-1) - var(--sin-term-α-2) + var(--sin-term-α-3) - var(--sin-term-α-4) + var(--sin-term-α-5)); + --pos-B: calc(var(--sin-β) * 50); + --pos-A: calc(var(--sin-α) * 50); + --polygon: polygon( + 50% 50%, + 50% 0%, + 100% 0%, + calc(50% + (var(--pos-B) * 1% * var(--lt-25, 1)) + (var(--gt-25, 0) * 50%)) calc(50% - (var(--pos-A) * 1% * var(--lt-25, 1))), + calc(50% + (var(--gt-25, 0) * 50%)) calc(50% + (var(--gt-25, 0) * 50%)), + calc(50% + (var(--pos-A) * 1% * var(--lt-50, 1)) + (var(--gt-50, 0) * 50%)) calc(50% + (var(--pos-B) * 1% * var(--lt-50, 1)) + (var(--gt-50, 0) * 50%)), + calc(50% - (var(--gt-50, 0) * 50%)) calc(50% + (var(--gt-50, 0) * 50%)), + calc(50% - (var(--pos-B) * 1% * var(--lt-75, 1)) - (var(--gt-75, 0) * 50%)) calc(50% + (var(--pos-A) * 1% * var(--lt-75, 1))), + calc(50% - (var(--gt-75, 0) * 50%)) calc(50% - (var(--gt-75, 0) * 50%)), + calc(50% - (var(--pos-A) * 1% * var(--gt-75, 0))) calc(50% - (var(--pos-B) * 1% * var(--gt-75, 0))), + 50% 50% + ); + background: var(--color, currentColor) var(--background); + clip-path: var(--polygon); + content: ""; + height: var(--radius); + --mask: radial-gradient( + circle at center, + #fff 0 calc(var(--radius) / 2), + transparent 0 + ); + mask-image: var(--mask); + transform: translate3d(-50%, -50%, 0) rotate(var(--position)) scale(var(--zoom)); + transition: transform 0.2s cubic-bezier(0.5, 0, 0.5, 1); + width: var(--radius); + } + .chaarts.pie tr:hover td::before { + --zoom: .8; + } + .chaarts.pie tr:nth-child(1n+1) { + --background: var(--checkers); + } + .chaarts.pie tr:nth-child(2n+2) { + --background: var(--hexagons); + } + .chaarts.pie tr:nth-child(3n+3) { + --background: var(--triangles); + } + .chaarts.pie tr:nth-child(4n+4) { + --background: var(--zig); + } + .chaarts.pie tr:nth-child(5n+5) { + --background: var(--stripes); + } + .chaarts.pie tr:nth-child(6n+6) { + --background: var(--dots); + } + .chaarts.pie td::after { + --arrow: calc(100% - 0.25rem); + --axis: calc(var(--position) - .25turn + var(--value) * .005turn); + --away: calc(var(--radius) / 2 - 1rem); + --integer: calc(var(--value)); + background-color: #444; + color: white; + content: var(--term) " : " counter(value) " %"; + counter-reset: value var(--integer); + opacity: 0; + padding: 0.5rem; + pointer-events: none; + transform-origin: 50% calc(100% + 10px); + transform: translate3d(-50%, -50%, 0) rotate(var(--axis)) translate(var(--away)) rotate(calc(var(--axis) * -1)) perspective(1000px) rotate3d(1, 0, 0, 45deg); + transition: opacity 0.2s cubic-bezier(0, 0.5, 0.5, 1), transform 0.2s cubic-bezier(0, 0.5, 0.5, 1); + } + .chaarts.pie tbody:hover tr { + opacity: 0.5; + } + .chaarts.pie tbody:hover tr:hover { + opacity: 1; + } + .chaarts.pie tbody:hover tr:hover td::after { + opacity: 1; + transform: translate3d(-50%, -50%, 0) rotate(var(--axis)) translate(var(--away)) rotate(calc(var(--axis) * -1)) perspective(1000px) rotate3d(1, 0, 0, 0deg); + transition: opacity 0.2s cubic-bezier(0.5, 0, 1, 0.5), transform 0.2s cubic-bezier(0.5, 0, 1, 0.5); + } + .chaarts.polar td::before { + --zoom: 50; + transform: translate3d(-50%, -50%, 0) rotate(var(--position)) scale(calc((var(--zoom) + var(--value) / (100 / var(--zoom))) / 100)); + } + .chaarts.polar td::after { + --away: calc((var(--radius) / 2) - ((var(--radius) / 4) * ((100 - var(--value)) / 100)) + 2.5rem); + } + .chaarts.polar tr:hover td::before { + --zoom: 50; + } + .chaarts.donut { + --mask: radial-gradient( + circle at 50% calc(50% - 0.25rem), + transparent 0 var(--offset), + #fff calc(var(--offset) + 1px) 100% + ); + mask-image: var(--mask); + } + .chaarts.donut td::after { + --away: calc(var(--radius) / 2 - 2.5rem); + } + @media screen and (min-width: 30em) and (-ms-high-contrast: active) { + .chaarts.pie tbody tr *::before { + /** + * @note Custom color palette for WHCM + * @note Inspired by Greg Whitworth's post + * @link http://www.gwhitworth.com/blog/2017/04/how-to-use-ms-high-contrast + */ + background-color: Window; + } + .chaarts.pie tbody tr:nth-of-type(odd) *::before { + background-color: WindowText; + } + } + } + /* ==================== */ + /* == Line Charts + * + * @note Grid charts based on + * @see https://css-tricks.com/css-charts-grid-custom-properties/ + * @author Miriam Suzanne + * + * @note Massively using clip-path + * @see Bennett Feely's clippy to understand polygon() syntax + * @link http://bennettfeely.com/clippy/ + */ + @supports (clip-path: polygon(0% calc(100% - var(--1) * 100% / var(--y)))) { + .line-container .fieldset { + display: flex !important; + } + .chaarts.line { + --offset: calc((100% / var(--x)) / 2); + --height: calc(32em - 2rem); + --bottom: calc(100% - var(--height)); + padding: var(--height) 0 1rem; + position: relative; + transition: background 0.3s cubic-bezier(0.5, 0, 0.5, 1), color 0.3s cubic-bezier(0.5, 0, 0.5, 1); + } + .chaarts.line::after { + --scale: calc((100% - (var(--y) * 1px)) / var(--y)); + background: repeating-linear-gradient(to bottom, white 0 var(--scale), rgba(0, 0, 0, 0.25) calc(var(--scale) + 1px)); + bottom: var(--bottom); + content: ""; + position: absolute; + top: 0; + width: 100%; + z-index: 1; + } + .chaarts.line tr::before { + content: ""; + position: absolute; + } + .chaarts.line [scope=row], + .chaarts.line thead th:first-child { + color: var(--color, currentColor); + text-align: left; + } + .chaarts.line [style]::before { + bottom: var(--bottom); + background: linear-gradient(to top, deepskyblue, crimson 75%); + --polygon: polygon( + 0% 100%, + calc((100% / var(--x) * 1)) 100%, + calc((100% / var(--x) * 1)) calc(100% - (var(--1) / var(--y) * 100%)), + calc((100% / var(--x) * 1) + var(--offset)) calc(100% - (var(--1) / var(--y) * 100%)), + calc((100% / var(--x) * 2) + var(--offset)) calc(100% - (var(--2) / var(--y) * 100%)), + calc((100% / var(--x) * 3) + var(--offset)) calc(100% - (var(--3) / var(--y) * 100%)), + calc((100% / var(--x) * 4) + var(--offset)) calc(100% - (var(--4) / var(--y) * 100%)), + calc((100% / var(--x) * 5) + var(--offset)) calc(100% - (var(--5) / var(--y) * 100%)), + calc((100% / var(--x) * 6) + var(--offset)) calc(100% - (var(--6) / var(--y) * 100%)), + calc((100% / var(--x) * 7) + var(--offset)) calc(100% - (var(--7) / var(--y) * 100%)), + calc((100% / var(--x) * 8) + var(--offset)) calc(100% - (var(--8) / var(--y) * 100%)), + calc((100% / var(--x) * 9) + var(--offset)) calc(100% - (var(--9) / var(--y) * 100%)), + calc((100% / var(--x) * 10) + var(--offset)) calc(100% - (var(--10) / var(--y) * 100%)), + calc((100% / var(--x) * 11) + var(--offset)) calc(100% - (var(--11) / var(--y) * 100%)), + calc((100% / var(--x) * 12) + var(--offset)) calc(100% - (var(--12) / var(--y) * 100%)), + 100% calc(100% - (var(--12) / var(--y) * 100%)), + 100% 100%, + 0% 100% + ); + clip-path: var(--polygon); + content: ""; + position: absolute; + top: 0; + width: 100%; + z-index: 2; + } + .chaarts.line th, + .chaarts.line td { + background: white; + font-weight: bold; + text-align: center; + width: calc(100% / var(--x)); + } + .chaarts.line [scope=col]:not(:first-child)::after { + background: white var(--stripes); + background-blend-mode: exclusion; + bottom: 4rem; + content: ""; + height: calc(100% - 4rem); + left: calc(100% / var(--x) * var(--index)); + mix-blend-mode: soft-light; + opacity: 0; + position: absolute; + transition: opacity 0.3s cubic-bezier(0.5, 0, 0.5, 1); + width: inherit; + z-index: 3; + } + .chaarts.line [scope=col]:nth-child(2)::after { + --index: 1; + } + .chaarts.line [scope=col]:nth-child(3)::after { + --index: 2; + } + .chaarts.line [scope=col]:nth-child(4)::after { + --index: 3; + } + .chaarts.line [scope=col]:nth-child(5)::after { + --index: 4; + } + .chaarts.line [scope=col]:nth-child(6)::after { + --index: 5; + } + .chaarts.line [scope=col]:nth-child(7)::after { + --index: 6; + } + .chaarts.line [scope=col]:nth-child(8)::after { + --index: 7; + } + .chaarts.line [scope=col]:nth-child(9)::after { + --index: 8; + } + .chaarts.line [scope=col]:nth-child(10)::after { + --index: 9; + } + .chaarts.line [scope=col]:nth-child(11)::after { + --index: 10; + } + .chaarts.line [scope=col]:nth-child(12)::after { + --index: 11; + } + .chaarts.line [scope=col]:nth-child(13)::after { + --index: 12; + } + .chaarts.line [scope=col]:hover::after { + opacity: 0.75; + } + .chaarts.line td { + --value: var(--1); + --term: var(--t-1); + line-height: 1.5; + /** + * 1. + * @note Using white-space and: + ** `\A` to make a line-break + ** `\A0` for a non-breakable space + * @note Based on CSS Secrets by + * @author Lea Verou + * @link https://lea.verou.me/2012/02/flexible-multiline-definition-lists-with-2-lines-of-css/ + * + * 2. + * @note Display CSS integers custom properties with a trick using counters + * @author Cassie Evans + * @link https://codepen.io/cassie-codes/pen/22ea69e0f681d45f2f4c2ca5e6acf4ab + * + * 3. + * @note We need to ensure our counter uses an integer, --value might a a floating number + * @author Carter Li + * @link https://css-tricks.com/animating-number-counters/#the-new-school-css-solution + */ + } + .chaarts.line td::before { + content: ""; + height: 1.5rem; + position: absolute; + transform: translateX(-50%); + width: inherit; + z-index: 10; + } + .chaarts.line td::after { + --arrow: calc(100% - 0.25rem); + --top: calc(var(--height) - (var(--value) / var(--y) * var(--height))); + --polygon: polygon( + 0% 0%, + 100% 0%, + 100% var(--arrow), + calc(50% - 0.25rem) var(--arrow), + 50% 100%, + calc(50% + 0.25rem) var(--arrow), + 0% var(--arrow) + ); + --integer: calc(var(--value)); + background-color: #444; + clip-path: var(--polygon); + color: white; + content: var(--term) " " var(--year) "\a" counter(value) " " var(--unit); + counter-reset: value var(--integer); + opacity: 0; + padding: 0.5rem; + left: calc(var(--offset) * 3); + pointer-events: none; + position: absolute; + top: var(--top, 0); + transform-origin: 50% calc(100% + 10px); + transform: translate3d(-50%, -125%, 0) perspective(1000px) rotate3d(1, 0, 0, 45deg); + transition: opacity 0.2s cubic-bezier(0, 0.5, 0.5, 1), transform 0.2s cubic-bezier(0, 0.5, 0.5, 1); + white-space: pre; + z-index: 5; + } + .chaarts.line td + td::after { + left: calc(100% / var(--x) * var(--index) + var(--offset)); + } + .chaarts.line td:nth-child(2)::after { + --value: var(--1); + --term: var(--t-1); + --index: 1; + } + .chaarts.line td:nth-child(3)::after { + --value: var(--2); + --term: var(--t-2); + --index: 2; + } + .chaarts.line td:nth-child(4)::after { + --value: var(--3); + --term: var(--t-3); + --index: 3; + } + .chaarts.line td:nth-child(5)::after { + --value: var(--4); + --term: var(--t-4); + --index: 4; + } + .chaarts.line td:nth-child(6)::after { + --value: var(--5); + --term: var(--t-5); + --index: 5; + } + .chaarts.line td:nth-child(7)::after { + --value: var(--6); + --term: var(--t-6); + --index: 6; + } + .chaarts.line td:nth-child(8)::after { + --value: var(--7); + --term: var(--t-7); + --index: 7; + } + .chaarts.line td:nth-child(9)::after { + --value: var(--8); + --term: var(--t-8); + --index: 8; + } + .chaarts.line td:nth-child(10)::after { + --value: var(--9); + --term: var(--t-9); + --index: 9; + } + .chaarts.line td:nth-child(11)::after { + --value: var(--10); + --term: var(--t-10); + --index: 10; + } + .chaarts.line td:nth-child(12)::after { + --value: var(--11); + --term: var(--t-11); + --index: 11; + } + .chaarts.line td:nth-child(13)::after { + --value: var(--12); + --term: var(--t-12); + --index: 12; + } + .chaarts.line td:hover::after { + opacity: 1; + transform: translate3d(-50%, -125%, 0) perspective(1000px) rotate3d(1, 0, 0, 0deg); + transition: opacity 0.2s cubic-bezier(0.5, 0, 1, 0.5), transform 0.2s cubic-bezier(0.5, 0, 1, 0.5); + } + .chaarts.points [style]::before { + background: var(--color, currentColor) var(--background); + --polygon: polygon( + calc((100% / var(--x) * 1) + var(--offset)) calc(100% - (var(--1) / var(--y) * 100%)), + calc((100% / var(--x) * 2) + var(--offset)) calc(100% - (var(--2) / var(--y) * 100%)), + calc((100% / var(--x) * 3) + var(--offset)) calc(100% - (var(--3) / var(--y) * 100%)), + calc((100% / var(--x) * 4) + var(--offset)) calc(100% - (var(--4) / var(--y) * 100%)), + calc((100% / var(--x) * 5) + var(--offset)) calc(100% - (var(--5) / var(--y) * 100%)), + calc((100% / var(--x) * 6) + var(--offset)) calc(100% - (var(--6) / var(--y) * 100%)), + calc((100% / var(--x) * 7) + var(--offset)) calc(100% - (var(--7) / var(--y) * 100%)), + calc((100% / var(--x) * 8) + var(--offset)) calc(100% - (var(--8) / var(--y) * 100%)), + calc((100% / var(--x) * 9) + var(--offset)) calc(100% - (var(--9) / var(--y) * 100%)), + calc((100% / var(--x) * 10) + var(--offset)) calc(100% - (var(--10) / var(--y) * 100%)), + calc((100% / var(--x) * 11) + var(--offset)) calc(100% - (var(--11) / var(--y) * 100%)), + calc((100% / var(--x) * 12) + var(--offset)) calc(100% - (var(--12) / var(--y) * 100%)), + calc((100% / var(--x) * 13) + var(--offset)) calc(100% - (var(--12) / var(--y) * 100%)), + 100% calc(100% - (var(--12) / var(--y) * 100%)), + 100% calc((100% + 0.25rem) - (var(--12) / var(--y) * 100%)), + calc((100% / var(--x) * 13) + var(--offset)) calc((100% + 0.25rem) - (var(--12) / var(--y) * 100%)), + calc((100% / var(--x) * 12) + var(--offset)) calc((100% + 0.25rem) - (var(--12) / var(--y) * 100%)), + calc((100% / var(--x) * 11) + var(--offset)) calc((100% + 0.25rem) - (var(--11) / var(--y) * 100%)), + calc((100% / var(--x) * 10) + var(--offset)) calc((100% + 0.25rem) - (var(--10) / var(--y) * 100%)), + calc((100% / var(--x) * 9) + var(--offset)) calc((100% + 0.25rem) - (var(--9) / var(--y) * 100%)), + calc((100% / var(--x) * 8) + var(--offset)) calc((100% + 0.25rem) - (var(--8) / var(--y) * 100%)), + calc((100% / var(--x) * 7) + var(--offset)) calc((100% + 0.25rem) - (var(--7) / var(--y) * 100%)), + calc((100% / var(--x) * 6) + var(--offset)) calc((100% + 0.25rem) - (var(--6) / var(--y) * 100%)), + calc((100% / var(--x) * 5) + var(--offset)) calc((100% + 0.25rem) - (var(--5) / var(--y) * 100%)), + calc((100% / var(--x) * 4) + var(--offset)) calc((100% + 0.25rem) - (var(--4) / var(--y) * 100%)), + calc((100% / var(--x) * 3) + var(--offset)) calc((100% + 0.25rem) - (var(--3) / var(--y) * 100%)), + calc((100% / var(--x) * 2) + var(--offset)) calc((100% + 0.25rem) - (var(--2) / var(--y) * 100%)), + calc((100% / var(--x) * 1) + var(--offset)) calc((100% + 0.25rem) - (var(--1) / var(--y) * 100%)) + ); + transition: opacity 0.3s cubic-bezier(0.5, 0, 0.5, 1); + } + .chaarts.points [style] th::before { + background: var(--color, currentColor) var(--background); + content: ""; + display: inline-block; + height: 1rem; + transform: translate3d(-0.2rem, 0.1rem, 0); + width: 1rem; + } + .chaarts.points [style] td::before { + --size: 1rem; + --top: calc(var(--height) - (var(--value) / var(--y) * var(--height))); + background: var(--color, currentColor) var(--background); + border: 2px solid white; + border-radius: 50%; + box-shadow: 0 0 0.25rem rgba(0, 0, 0, 0.5); + content: ""; + height: var(--size); + left: calc(var(--offset) * 3); + position: absolute; + top: var(--top, 100); + transform: translate3d(calc(var(--size) / -2), calc(var(--size) / -2), 0); + transition: opacity 0.3s cubic-bezier(0.5, 0, 0.5, 1), transform 0.3s cubic-bezier(0.5, 0, 0.5, 1); + width: var(--size); + z-index: 4; + } + .chaarts.points [style] td + td::before { + left: calc(100% / var(--x) * var(--index) + var(--offset)); + } + .chaarts.points [style] td:nth-of-type(2)::before { + --value: var(--2); + --index: 2; + } + .chaarts.points [style] td:nth-of-type(3)::before { + --value: var(--3); + --index: 3; + } + .chaarts.points [style] td:nth-of-type(4)::before { + --value: var(--4); + --index: 4; + } + .chaarts.points [style] td:nth-of-type(5)::before { + --value: var(--5); + --index: 5; + } + .chaarts.points [style] td:nth-of-type(6)::before { + --value: var(--6); + --index: 6; + } + .chaarts.points [style] td:nth-of-type(7)::before { + --value: var(--7); + --index: 7; + } + .chaarts.points [style] td:nth-of-type(8)::before { + --value: var(--8); + --index: 8; + } + .chaarts.points [style] td:nth-of-type(9)::before { + --value: var(--9); + --index: 9; + } + .chaarts.points [style] td:nth-of-type(10)::before { + --value: var(--10); + --index: 10; + } + .chaarts.points [style] td:nth-of-type(11)::before { + --value: var(--11); + --index: 11; + } + .chaarts.points [style] td:nth-of-type(12)::before { + --value: var(--12); + --index: 12; + } + .chaarts.points [style]:nth-child(1n+1) { + --background: var(--checkers); + } + .chaarts.points [style]:nth-child(2n+2) { + --background: var(--hexagons); + } + .chaarts.points [style]:nth-child(3n+3) { + --background: var(--triangles); + } + .chaarts.points [style]:nth-child(4n+4) { + --background: var(--zig); + } + .chaarts.points [style]:nth-child(5n+5) { + --background: var(--stripes); + } + .chaarts.points [style]:nth-child(6n+6) { + --background: var(--dots); + } + .chaarts.points tbody:hover [style]::before, + .chaarts.points tbody:hover [style] td::before { + opacity: 0.25; + } + .chaarts.points tbody:hover [style]:hover::before, + .chaarts.points tbody:hover [style]:hover td::before { + opacity: 1; + } + .chaarts.points tbody:hover [style]:hover td::before { + transform: translate3d(calc(var(--size) / -2), calc(var(--size) / -2), 0) scale(1.25); + } + .chaarts.points [scope=col]:not(:first-child)::after { + mix-blend-mode: multiply; + } + .chaarts.points [scope=col]:not(:first-child):hover::after { + opacity: 0.5; + } + @media screen and (min-width: 30em) and (-ms-high-contrast: active) { + .chaarts.line [style]::before { + /** + * @note Custom color palette for WHCM + * @note Inspired by Greg Whitworth's post + * @link http://www.gwhitworth.com/blog/2017/04/how-to-use-ms-high-contrast + */ + background: linear-gradient(to top, ButtonHighlight, Highlight 75%); + } + } + } + /* ==================== */ + /* == Column Charts + * + * @note Grid charts based on: + * @see https://css-tricks.com/css-charts-grid-custom-properties/ + * @author Miriam Suzanne + /* ==================== */ + @supports (display: contents) { + .column-container .fieldset { + display: flex !important; + } + .chaarts[class*=column] { + --gap: 0.5rem; + --size: calc(var(--scale, 100) * 100%); + --width: calc(64em / var(--y) - 1rem); + display: grid; + grid-column-gap: var(--gap); + max-height: 64em; + position: relative; + /** + * @note Use display: contents to place table-cells in table's grid + * @link https://hiddedevries.nl/en/blog/2018-04-21-more-accessible-markup-with-display-contents + * @link https://bitsofco.de/how-display-contents-works/ + */ + } + .chaarts[class*=column] td, + .chaarts[class*=column] th { + margin: 0; + } + .chaarts[class*=column] tr > * + * { + text-align: center; + } + .chaarts[class*=column] tr, + .chaarts[class*=column] tbody, + .chaarts[class*=column] thead { + display: contents; + } + .chaarts[class*=column] caption { + grid-column: 1/span var(--y); + grid-row: -1; + } + .chaarts[class*=column] td { + --integer: calc(var(--value)); + grid-row: calc(var(--scale, 100) + 2 - var(--integer)) / -2; + pointer-events: none; + position: relative; + transition: opacity 0.2s cubic-bezier(0.5, 0, 0.5, 1); + } + .chaarts[class*=column] td:nth-of-type(1) { + grid-column: 2; + } + .chaarts[class*=column] td:nth-of-type(2) { + grid-column: 3; + } + .chaarts[class*=column] td:nth-of-type(3) { + grid-column: 4; + } + .chaarts[class*=column] td:nth-of-type(4) { + grid-column: 5; + } + .chaarts[class*=column] td:nth-of-type(5) { + grid-column: 6; + } + .chaarts[class*=column] td:nth-of-type(6) { + grid-column: 7; + } + .chaarts[class*=column] td:nth-of-type(7) { + grid-column: 8; + } + .chaarts[class*=column] td:nth-of-type(8) { + grid-column: 9; + } + .chaarts[class*=column] td:nth-of-type(9) { + grid-column: 10; + } + .chaarts[class*=column] td:nth-of-type(10) { + grid-column: 11; + } + .chaarts[class*=column] span { + font-weight: bold; + bottom: 100%; + left: 0; + line-height: 1.5; + pointer-events: auto; + position: absolute; + right: 0; + /** + * @note Progressively enhance background-clipping + * @author S. Shaw + * @link https://twitter.com/shshaw/status/1140637533539377153 + * Support is quite good actually + * @link https://caniuse.com/background-clip-text + */ + } + @supports (background-clip: text) or (-webkit-background-clip: text) { + .chaarts[class*=column] span { + background: inherit; + -webkit-background-clip: text; + background-clip: text; + color: transparent; + } + } + .chaarts[class*=column].column-single { + grid-auto-columns: 1fr; + grid-template-rows: 2ex repeat(var(--scale, 100), minmax(0, 0.25rem)) minmax(min-content, 2rem); + } + .chaarts[class*=column].column-single tbody th { + grid-row: -6/-3; + grid-column: 1; + line-height: 1; + } + .chaarts[class*=column].column-single thead * { + grid-row: -2; + } + .chaarts[class*=column].column-single td { + --position: calc(var(--integer, 0) / var(--scale, 100) * 100%); + background: linear-gradient(to top, #01ac49, #444, mediumblue, rebeccapurple, crimson) 0% var(--position) / 100% var(--size), var(--background) center/1rem; + background-blend-mode: hard-light; + } + .chaarts[class*=column].column-single [scope=col]::after { + background: whitesmoke var(--stripes); + background-blend-mode: exclusion; + bottom: 4rem; + content: ""; + mix-blend-mode: multiply; + opacity: 0; + position: absolute; + transition: opacity 0.3s cubic-bezier(0.5, 0, 0.5, 1); + top: 1rem; + width: var(--width); + z-index: 0; + } + .chaarts[class*=column].column-single [scope=col]:hover::after { + opacity: 0.5; + } + .chaarts[class*=column].column-single [scope=col]:nth-child(2)::after { + left: calc(1em + (var(--width) * 1) + (var(--gap) * 1)); + } + .chaarts[class*=column].column-single [scope=col]:nth-child(3)::after { + left: calc(1em + (var(--width) * 2) + (var(--gap) * 2)); + } + .chaarts[class*=column].column-single [scope=col]:nth-child(4)::after { + left: calc(1em + (var(--width) * 3) + (var(--gap) * 3)); + } + .chaarts[class*=column].column-single [scope=col]:nth-child(5)::after { + left: calc(1em + (var(--width) * 4) + (var(--gap) * 4)); + } + .chaarts[class*=column].column-single [scope=col]:nth-child(6)::after { + left: calc(1em + (var(--width) * 5) + (var(--gap) * 5)); + } + .chaarts[class*=column].column-single [scope=col]:nth-child(7)::after { + left: calc(1em + (var(--width) * 6) + (var(--gap) * 6)); + } + .chaarts[class*=column].column-single td:nth-of-type(1n + 1) { + --background: var(--checkers); + } + .chaarts[class*=column].column-single td:nth-of-type(2n + 2) { + --background: var(--hexagons); + } + .chaarts[class*=column].column-single td:nth-of-type(3n + 3) { + --background: var(--triangles); + } + .chaarts[class*=column].column-single td:nth-of-type(4n + 4) { + --background: var(--zig); + } + .chaarts[class*=column].column-single td:nth-of-type(5n + 5) { + --background: var(--stripes); + } + .chaarts[class*=column].column-single td:nth-of-type(6n + 6) { + --background: var(--dots); + } + @media screen and (min-width: 30em) and (-ms-high-contrast: active) { + .chaarts[class*=column].column-single td { + /** + * @note Custom color palette for WHCM + * @note Inspired by Greg Whitworth's post + * @link http://www.gwhitworth.com/blog/2017/04/how-to-use-ms-high-contrast + */ + background-image: linear-gradient(to top, Window, ButtonFace, ButtonShadow, ButtonText, highlight), var(--background); + } + } + .chaarts[class*=column].column-multiple { + grid-template-columns: minmax(min-content, 14ch) repeat(calc(var(--y) - 1), 1fr); + grid-template-rows: 2ex repeat(var(--scale, 100), minmax(0, 0.25rem)) repeat(2, minmax(min-content, 2rem)); + /** + * @note Oh boy, if we could use var(--span) in selector… + */ + } + .chaarts[class*=column].column-multiple span { + background-image: none; + } + .chaarts[class*=column].column-multiple tbody th { + grid-row: -10/span 7; + } + .chaarts[class*=column].column-multiple thead tr * { + grid-row: -2; + grid-column: 1; + } + .chaarts[class*=column].column-multiple thead tr *:nth-of-type(2) { + grid-column: calc(4 - var(--span))/span var(--span); + } + .chaarts[class*=column].column-multiple thead tr *:nth-of-type(3) { + grid-column: calc(6 - var(--span))/span var(--span); + } + .chaarts[class*=column].column-multiple thead tr *:nth-of-type(4) { + grid-column: calc(8 - var(--span))/span var(--span); + } + .chaarts[class*=column].column-multiple thead tr *:nth-of-type(5) { + grid-column: calc(10 - var(--span))/span var(--span); + } + .chaarts[class*=column].column-multiple thead tr *:nth-of-type(6) { + grid-column: calc(12 - var(--span))/span var(--span); + } + .chaarts[class*=column].column-multiple thead tr + tr * { + font-weight: normal; + grid-row: -3; + } + .chaarts[class*=column].column-multiple thead tr + tr *:nth-of-type(2) { + grid-column: 2; + } + .chaarts[class*=column].column-multiple thead tr + tr *:nth-of-type(3) { + grid-column: 3; + } + .chaarts[class*=column].column-multiple thead tr + tr *:nth-of-type(4) { + grid-column: 4; + } + .chaarts[class*=column].column-multiple thead tr + tr *:nth-of-type(5) { + grid-column: 5; + } + .chaarts[class*=column].column-multiple thead tr + tr *:nth-of-type(6) { + grid-column: 6; + } + .chaarts[class*=column].column-multiple thead tr + tr *:nth-of-type(7) { + grid-column: 7; + } + .chaarts[class*=column].column-multiple thead tr + tr *:nth-of-type(8) { + grid-column: 8; + } + .chaarts[class*=column].column-multiple thead tr + tr *:nth-of-type(9) { + grid-column: 9; + } + .chaarts[class*=column].column-multiple thead tr + tr *:nth-of-type(10) { + grid-column: 10; + } + .chaarts[class*=column].column-multiple thead tr + tr *:nth-of-type(11) { + grid-column: 11; + } + .chaarts[class*=column].column-multiple tr:first-child [scope=col]:nth-child(even)::after { + background: whitesmoke var(--stripes); + background-blend-mode: exclusion; + bottom: 4rem; + content: ""; + mix-blend-mode: multiply; + opacity: 0.25; + position: absolute; + transition: opacity 0.3s cubic-bezier(0.5, 0, 0.5, 1); + top: calc(1rem + 2ex); + width: calc(var(--width) * 2 + var(--gap) / 2 + 1px); + z-index: 0; + } + .chaarts[class*=column].column-multiple tr:first-child [scope=col]:nth-child(2)::after { + left: calc(14ch + 1em + (((var(--width) * 2) + (var(--gap) / 2) + 1px) * 0) + (var(--gap) * 1)); + } + .chaarts[class*=column].column-multiple tr:first-child [scope=col]:nth-child(4)::after { + left: calc(14ch + 1em + (((var(--width) * 2) + (var(--gap) / 2) + 1px) * 2) + (var(--gap) * 3)); + } + .chaarts[class*=column].column-multiple tr:first-child [scope=col]:nth-child(6)::after { + left: calc(14ch + 1em + (((var(--width) * 2) + (var(--gap) / 2) + 1px) * 4) + (var(--gap) * 5)); + } + .chaarts[class*=column].column-multiple td { + background-color: #e11a81; + background-image: var(--zig); + grid-row-end: -3; + } + .chaarts[class*=column].column-multiple td:nth-of-type(2n + 2) { + background: #0172f0 var(--triangles); + } + @media screen and (min-width: 30em) and (-ms-high-contrast: active) { + .chaarts[class*=column].column-multiple td { + background-color: Window; + } + .chaarts[class*=column].column-multiple td:nth-of-type(2n + 2) { + background-color: Highlight; + } + } + } + /* ==================== */ + /* == Radar Charts + /* ==================== */ + @supports (clip-path: polygon(0% 0%, calc(100% - var(--1) * 100% / var(--scale)) 100%, 100% 100%)) { + .radar-container .fieldset { + display: flex !important; + } + .chaarts[class*=radar] { + --radius: 12.8em; + --unitless-radius: calc(1024 / 16 / 5); + --size: calc(var(--radius) / var(--scale)); + --part: calc(360deg / var(--items)); + --integer: calc(var(--scale)); + background-image: repeating-radial-gradient(circle at 50%, rgba(0, 0, 0, 0.2) 0 2px, transparent 0 calc(var(--size) * var(--step))), repeating-radial-gradient(circle at 50%, rgba(0, 0, 0, 0.1) 0 2px, transparent 0 var(--size)); + border: 2px solid; + border-radius: 50%; + contain: layout; + counter-reset: scale var(--integer); + height: calc(var(--radius) * 2); + margin: 6rem auto 12rem; + overflow: visible; + position: relative; + width: calc(var(--radius) * 2); + /** + * Placing items around a circle based on: + * @link https://stackoverflow.com/questions/12813573/position-icons-into-circle + * @link http://dabblet.com/gist/3866686 + * @author Ana Tudor + * + * @note Negative values for radius helps to start at the top left corner + */ + /** + * This is quite sophisticated, we're mixing multiple techniques + * + * @note Setting items as parts of the circle: + * @link https://tympanus.net/codrops/2013/08/09/building-a-circular-navigation-with-css-transforms/ + * @author Sara Soueidan + * + * @note Because we skew items, clip-path() needs to take skew angle into account + * @note To do so, we need to know skewed width (which is hypothenuse of the resulting triangle) + * @note We only know two angles (skew one + suqare one) and a side (initial width), + * @note So we need to compute the sinus of the opposite angle to get hypothenuse + * @note Thanks god, Stereokai made trigonometry functions in pure CSS: + * + * @note Trigonometry functions based on: + * @link https://gist.github.com/stereokai/7666bfe93929b14c2dced148c79e0e97 + * @author Stereokai + */ + } + .chaarts[class*=radar] caption { + background: none; + bottom: -10rem; + position: absolute; + } + .chaarts[class*=radar] [scope=col] { + --away: calc((var(--radius) * -1) - 50%); + left: 50%; + margin: 0; + padding: 0 1rem; + position: absolute; + top: 50%; + transform: translate3d(-50%, -50%, 0) rotate(calc(var(--part) * var(--index, 1))) translate(var(--away)) rotate(calc(var(--part) * var(--index, 1) * -1)); + } + .chaarts[class*=radar] tr > *:nth-of-type(1) { + --index: 1; + } + .chaarts[class*=radar] tr > *:nth-of-type(2) { + --index: 2; + } + .chaarts[class*=radar] tr > *:nth-of-type(3) { + --index: 3; + } + .chaarts[class*=radar] tr > *:nth-of-type(4) { + --index: 4; + } + .chaarts[class*=radar] tr > *:nth-of-type(5) { + --index: 5; + } + .chaarts[class*=radar] tr > *:nth-of-type(6) { + --index: 6; + } + .chaarts[class*=radar] tr > *:nth-of-type(7) { + --index: 7; + } + .chaarts[class*=radar] td { + --skew: calc(90deg - var(--part)); + border-bottom: 1px solid blueviolet; + height: 50%; + left: 0; + margin: 0; + position: absolute; + top: 0; + transform: rotate(calc(var(--part) * var(--index, 1))) skew(var(--skew)); + transform-origin: 100% 100%; + width: 50%; + } + .chaarts[class*=radar] td:nth-of-type(1) span { + --point: var(--1); + --pos: calc(100% - (var(--2) * 100% / (var(--scale) * var(--ratio)))); + } + .chaarts[class*=radar] td:nth-of-type(2) span { + --point: var(--2); + --pos: calc(100% - (var(--3) * 100% / (var(--scale) * var(--ratio)))); + } + .chaarts[class*=radar] td:nth-of-type(3) span { + --point: var(--3); + --pos: calc(100% - (var(--4) * 100% / (var(--scale) * var(--ratio)))); + } + .chaarts[class*=radar] td:nth-of-type(4) span { + --point: var(--4); + --pos: calc(100% - (var(--5) * 100% / (var(--scale) * var(--ratio)))); + } + .chaarts[class*=radar] td:nth-of-type(5) span { + --point: var(--5); + --pos: calc(100% - (var(--6) * 100% / (var(--scale) * var(--ratio)))); + } + .chaarts[class*=radar] td:nth-of-type(6) span { + --point: var(--6); + --pos: calc(100% - (var(--7) * 100% / (var(--scale) * var(--ratio)))); + } + .chaarts[class*=radar] td:nth-of-type(7) span { + --point: var(--7); + --pos: calc(100% - (var(--8) * 100% / (var(--scale) * var(--ratio)))); + } + .chaarts[class*=radar] td::after, .chaarts[class*=radar] td::before { + display: none; + } + .chaarts[class*=radar] span { + --opposite: calc(180 - (90 + (90 - (360 / var(--items))))); + --angle: calc(var(--opposite) * 0.01745329251); + --sin-term-angle-1: var(--angle); + --sin-term-angle-2: calc((var(--angle) * var(--angle) * var(--angle)) / 6); + --sin-term-angle-3: calc((var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle)) / 120); + --sin-term-angle-4: calc((var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle)) / 5040); + --sin-term-angle-5: calc((var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle)) / 362880); + --sin-angle: calc(var(--sin-term-angle-1) - var(--sin-term-angle-2) + var(--sin-term-angle-3) - var(--sin-term-angle-4) + var(--sin-term-angle-5)); + --hypo: calc(var(--unitless-radius) / var(--sin-angle)); + --ratio: calc(var(--hypo) / var(--unitless-radius)); + --polygon: polygon( + 100% var(--pos), + calc(100% - (var(--point) * 100% / var(--scale))) 100%, + 100% 100% + ); + background: linear-gradient(to top left, blueviolet 10%, DarkBlue 75%); + clip-path: var(--polygon); + filter: drop-shadow(0 0 1rem indigo); + height: 100%; + position: absolute; + width: 100%; + } + /** + * 1. + * @note Display CSS integers custom properties with a trick using counters + * @author Cassie Evans + * @link https://codepen.io/cassie-codes/pen/22ea69e0f681d45f2f4c2ca5e6acf4ab + * + * 2. + * @note We need to ensure our counter uses an integer, --value might a a floating number + * @author Carter Li + * @link https://css-tricks.com/animating-number-counters/#the-new-school-css-solution + */ + .chaarts.radar [scope=col]::after { + color: rebeccapurple; + display: block; + font-size: small; + font-weight: 400; + } + .chaarts.radar [scope=col]:nth-child(1)::after { + --integer: calc(var(--1)); + counter-reset: value var(--integer); + content: counter(value) " / " counter(scale); + } + .chaarts.radar [scope=col]:nth-child(2)::after { + --integer: calc(var(--2)); + counter-reset: value var(--integer); + content: counter(value) " / " counter(scale); + } + .chaarts.radar [scope=col]:nth-child(3)::after { + --integer: calc(var(--3)); + counter-reset: value var(--integer); + content: counter(value) " / " counter(scale); + } + .chaarts.radar [scope=col]:nth-child(4)::after { + --integer: calc(var(--4)); + counter-reset: value var(--integer); + content: counter(value) " / " counter(scale); + } + .chaarts.radar [scope=col]:nth-child(5)::after { + --integer: calc(var(--5)); + counter-reset: value var(--integer); + content: counter(value) " / " counter(scale); + } + .chaarts.radar [scope=col]:nth-child(6)::after { + --integer: calc(var(--6)); + counter-reset: value var(--integer); + content: counter(value) " / " counter(scale); + } + .chaarts.radar [scope=col]:nth-child(7)::after { + --integer: calc(var(--7)); + counter-reset: value var(--integer); + content: counter(value) " / " counter(scale); + } + .chaarts.radar-multiple { + margin-bottom: 12rem; + } + .chaarts.radar-multiple tbody { + columns: var(--areas); + vertical-align: bottom; + } + .chaarts.radar-multiple [scope=row] { + bottom: -8rem; + height: 2rem; + left: 1rem; + position: absolute; + } + .chaarts.radar-multiple [scope=row]::before { + background: var(--color, currentColor); + content: ""; + display: inline-block; + height: 1rem; + margin-right: 0.25rem; + transform: translate3d(0, 0.1rem, 0); + width: 1rem; + } + .chaarts.radar-multiple tr:nth-child(2) [scope=row] { + left: calc(1rem + (100% / var(--areas)) * 1); + } + .chaarts.radar-multiple td { + align-items: flex-end; + border-color: var(--color, currentColor); + display: flex; + justify-content: flex-end; + opacity: 0.5; + pointer-events: none; + z-index: 0; + } + .chaarts.radar-multiple td::after { + color: var(--color, currentColor); + display: block; + font-size: small; + font-weight: 700; + text-indent: -0.5rem; + transform: skew(calc(var(--skew) * -1)) rotate(calc(var(--part) * var(--index, 1) * -1)); + transform-origin: 0 0; + width: 100%; + white-space: nowrap; + } + .chaarts.radar-multiple td:nth-of-type(1)::after { + --integer: calc(var(--1)); + counter-reset: value var(--integer); + content: counter(value); + width: calc(var(--1) * 100% / var(--scale)); + } + .chaarts.radar-multiple td:nth-of-type(2)::after { + --integer: calc(var(--2)); + counter-reset: value var(--integer); + content: counter(value); + width: calc(var(--2) * 100% / var(--scale)); + } + .chaarts.radar-multiple td:nth-of-type(3)::after { + --integer: calc(var(--3)); + counter-reset: value var(--integer); + content: counter(value); + width: calc(var(--3) * 100% / var(--scale)); + } + .chaarts.radar-multiple td:nth-of-type(4)::after { + --integer: calc(var(--4)); + counter-reset: value var(--integer); + content: counter(value); + width: calc(var(--4) * 100% / var(--scale)); + } + .chaarts.radar-multiple td:nth-of-type(5)::after { + --integer: calc(var(--5)); + counter-reset: value var(--integer); + content: counter(value); + width: calc(var(--5) * 100% / var(--scale)); + } + .chaarts.radar-multiple td:nth-of-type(6)::after { + --integer: calc(var(--6)); + counter-reset: value var(--integer); + content: counter(value); + width: calc(var(--6) * 100% / var(--scale)); + } + .chaarts.radar-multiple td:nth-of-type(7)::after { + --integer: calc(var(--7)); + counter-reset: value var(--integer); + content: counter(value); + width: calc(var(--7) * 100% / var(--scale)); + } + .chaarts.radar-multiple span { + background: var(--color, currentColor); + pointer-events: auto; + } + @supports (mask-image: url()) { + .chaarts.radar-multiple span { + --mask: radial-gradient(circle at bottom right, rgba(0, 0, 0, 1), rgba(0, 0, 0, .5)); + mask-image: var(--mask); + } + } + @media screen and (min-width: 30em) and (hover: hover) { + .chaarts.radar-multiple td { + opacity: 0.25; + transition: opacity 0.2s cubic-bezier(0.5, 0, 0.5, 1); + } + .chaarts.radar-multiple td::after { + opacity: 0; + transition: inherit; + } + .chaarts.radar-multiple tr:hover td { + opacity: 1; + z-index: 1; + } + .chaarts.radar-multiple tr:hover td::after { + opacity: inherit; + } + } + } +} + +/*# sourceMappingURL=chaarts.css.map */ diff --git a/dist/chaarts.css.map b/dist/chaarts.css.map new file mode 100644 index 0000000..614f2b6 --- /dev/null +++ b/dist/chaarts.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["../src/chaarts.scss","../src/_chaarts-bar.scss","../src/_chaarts-pie.scss","../src/abstracts/_variables.scss","../src/abstracts/_mixins.scss","../src/_chaarts-line.scss","../src/_chaarts-column.scss","../src/_chaarts-radar.scss"],"names":[],"mappings":";AAAA;AACA;AAAA;AAQA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASA;EACC;EACA;EACA;;AAGD;AACA;AAAA;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;;;AAIF;AAAA;EAEC;EACA;;;AAGD;AAAA;EAEC;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA;EACC;EAIA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAIA;EACC;;AAGD;EACC;EACA;EACA;EACA;;;AAIF;EACC;EACA;EACA;EACA;EACA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAQC;EAAA;EAAA;EAAA;EAAA;EAAA;;AAGD;EACC;EACA;EACA;;;AAIF;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;IACC;AACA;AAAA;AAAA;AAAA;IAIA;AAEA;AAAA;AAAA;AAAA;AAAA;;EAKA;IACC;;EAGD;AAAA;IAEC;IACA;;EAEA;AAAA;IACC;;ACzKJ;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAoBA;IACC;MACC;;IAIA;MACC;MACA;;IAGD;MACC;MACA;MACA;MACA;MACA;;IAKC;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IAKH;MACC;MACA;MACA;MACA;;IAGD;MACC;MACA;MACA;MAQA;MACA;MACA;MACA;;IAGD;MACC;MACA;MACA;MACA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;IAOA;MAbD;QAcE;QACA;QACA;QACA;;;IAKD;MACC;;IAGD;MACC;;IAIF;MACC;AACC;AAAA;AAAA;AAAA;AAAA;QAKA;;;IAaA;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;;AC1HL;AACA;AAAA;EAEA;IACC;MACC;MACA;;IAGD;MACC;MACA;MACA;MACA;AAoCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;IArGA;MACC;;IAGD;MACC;MACA;;IAGD;MACC;;IAEA;MACC;MACA;MACA;MACA,QC0DK;MDzDL;MACA,OCwDK;;IDpDP;MACC;;IAGD;AAAA;MAEC;MACA;MACA;MACA;;IAoBD;MACC;MACA;MACA;MACA;MACA;ME5EF;MACA;MACA;MACA;MACA;MACA;MALA;MACA;MACA;MACA;MACA;MACA;MF0EE;MACA;MACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;MAaA;MACA;MACA;MACA;MACA;AAAA;AAAA;AAAA;AAAA;MAKA;MACA;MACA;MACA;;IAGD;MACC;;IAMA;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IAeF;MACC;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;;IAID;MACC;;IAEA;MACC;;IAGD;MACC;MACA;MACA;;IAOF;MACC;MACA;;IAGD;MACC;;IAGD;MACC;;IAIF;MACC;AAAA;AAAA;AAAA;AAAA;MAKA;;IAEA;MACC;;IAIF;MAEE;AACC;AAAA;AAAA;AAAA;AAAA;QAKA;;MAGD;QACC;;;;AG1MJ;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAUA;IACC;MACC;;IAGD;MACC;MACA;MACA;MACA;MACA;MACA;;IAGA;MACC;MACA;MAKA;MACA;MACA;MACA;MACA;MACA;;IAGD;MACC;MACA;;IAGD;AAAA;MAEC;MACA;;IAGD;MACC;MACA;MACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;MAoBA;MACA;MACA;MACA;MACA;MACA;;IAGD;AAAA;MAEC;MACA;MACA;MACA;;IAIA;MACC;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;;IAIA;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IAIF;MACC;;IAIF;MACC;MACA;MACA;AAWA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;IATA;MACC;MACA;MACA;MACA;MACA;MACA;;IAsBD;MACC;MACA;MACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;MASA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MAEA;MACA;;IAGD;MACC;;IAIA;MACC;MACA;MACA;;IAHD;MACC;MACA;MACA;;IAHD;MACC;MACA;MACA;;IAHD;MACC;MACA;MACA;;IAHD;MACC;MACA;MACA;;IAHD;MACC;MACA;MACA;;IAHD;MACC;MACA;MACA;;IAHD;MACC;MACA;MACA;;IAHD;MACC;MACA;MACA;;IAHD;MACC;MACA;MACA;;IAHD;MACC;MACA;MACA;;IAHD;MACC;MACA;MACA;;IAIF;MACC;MACA;MACA;;IAQD;MACC;MACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;MA8BA;;IAGD;MACC;MACA;MACA;MACA;MACA;MACA;;IAIA;MACC;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MAEA;MACA;;IAGD;MACC;;IAIA;MACC;MACA;;IAFD;MACC;MACA;;IAFD;MACC;MACA;;IAFD;MACC;MACA;;IAFD;MACC;MACA;;IAFD;MACC;MACA;;IAFD;MACC;MACA;;IAFD;MACC;MACA;;IAFD;MACC;MACA;;IAFD;MACC;MACA;;IAFD;MACC;MACA;;IASH;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IAIF;AAAA;MAEC;;IAGD;AAAA;MAEC;;IAGD;MACC;;IAIA;MACC;;IAGD;MACC;;IAKH;MACC;AACC;AAAA;AAAA;AAAA;AAAA;QAKA;;;;ACnUH;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;EAUA;IACC;MACC;;IAGD;MACC;MACA;MACA;MACA;MACA;MACA,YHoEM;MGnEN;AAWA;AAAA;AAAA;AAAA;AAAA;;IATA;AAAA;MAEC;;IAGD;MACC;;IAQD;AAAA;AAAA;MAGC;;IAGD;MACC;MACA;;IAGD;MACC;MACA;MACA;MACA;MACA;;IAGC;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IAKH;MACC;MACA;MACA;MACA;MACA;MACA;MACA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;IAOA;MAhBD;QAiBE;QACA;QACA;QACA;;;IAIF;MACC;MACA;;IAEA;MACC;MACA;MACA;;IAGD;MACC;;IAGD;MACC;MACA;MAQA;;IAIA;MACC;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA,KHlCI;MGmCJ;MACA;;IAGD;MACC;;IAIA;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IAQF;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IAIF;MACC;AACC;AAAA;AAAA;AAAA;AAAA;QAKA;;;IAYH;MACC;MACA;AA4DA;AAAA;AAAA;;IA1DA;MACC;;IAGD;MACC;;IAGD;MACC;MACA;;IAGC;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IAKH;MACC;MACA;;IAGC;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IAMF;MACC;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;;IAIA;MACC;;IADD;MACC;;IADD;MACC;;IAKH;MACC;MACA;MACA;;IAMD;MACC;;IAGD;MACC;QACC;;MAGD;QACC;;;;AClPL;AACA;AAAA;EAKA;IACC;MACC;;IAGD;MACC;MACA;MACA;MACA;MACA;MACA;MAUA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;AAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;IA9BA;MACC;MACA;MACA;;IAWD;MACC;MACA;MACA;MACA;MACA;MACA;MACA;;IAIA;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IADD;MACC;;IAqBF;MACC;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;;IAGC;MACC;MACA;;IAFD;MACC;MACA;;IAFD;MACC;MACA;;IAFD;MACC;MACA;;IAFD;MACC;MACA;;IAFD;MACC;MACA;;IAFD;MACC;MACA;;IAIF;MAEC;;IAIF;MACC;MAEA;MHpHF;MACA;MACA;MACA;MACA;MACA;MGmHE;MAEA;MACA;AAAA;AAAA;AAAA;AAAA;MAKA;MAKA;MACA;MACA;MACA;MACA;;AAIF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IAYC;MACC;MACA;MACA;MACA;;IAIA;MACC;MACA;MACA;;IAHD;MACC;MACA;MACA;;IAHD;MACC;MACA;MACA;;IAHD;MACC;MACA;MACA;;IAHD;MACC;MACA;MACA;;IAHD;MACC;MACA;MACA;;IAHD;MACC;MACA;MACA;;IAKH;MACC;;IAEA;MACC;MACA;;IAGD;MACC;MACA;MACA,MJtFM;MIuFN;;IAEA;MACC;MACA;MACA;MACA,QJ7FK;MI8FL;MACA;MACA,OJhGK;;IIsGN;MACC;;IAIF;MACC;MACA;MACA;MACA;MACA;MACA;MACA;;IAEA;MACC;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;;IAIA;MACC;MACA;MACA;MACA;;IAJD;MACC;MACA;MACA;MACA;;IAJD;MACC;MACA;MACA;MACA;;IAJD;MACC;MACA;MACA;MACA;;IAJD;MACC;MACA;MACA;MACA;;IAJD;MACC;MACA;MACA;MACA;;IAJD;MACC;MACA;MACA;MACA;;IAKH;MACC;MACA;;IAEA;MAJD;QAKE;QACA;;;IAIF;MACC;QACC;QACA;;MAEA;QACC;QACA;;MAIF;QACC;QACA;;MAEA;QACC","file":"chaarts.css"} \ No newline at end of file diff --git a/dist/chaarts.min.css b/dist/chaarts.min.css new file mode 100644 index 0000000..2ae233d --- /dev/null +++ b/dist/chaarts.min.css @@ -0,0 +1,2 @@ +@charset "UTF-8";@property --integer{syntax:"";initial-value:0;inherits:false}table{font-feature-settings:"tnum";border-collapse:collapse;caption-side:top;margin-bottom:1.5rem;vertical-align:top;width:100%}table>caption:first-child{font-style:italic;margin:0;padding:2.5rem 1rem}td,th{padding:.5rem .75rem;text-align:left}table strong,th{color:#000}td{line-height:1.25;max-width:100%}tbody{border:1px solid dimgray}thead{border:1px solid #000}.table-container{background:linear-gradient(90deg,#fff 30%,#fff0),linear-gradient(90deg,#fff0,#fff 70%) 0 100%,radial-gradient(farthest-side at 0 50%,#0003,#0000),radial-gradient(farthest-side at 100% 50%,#0003,#0000) 0 100%;background-attachment:local,local,scroll,scroll;background-color:#fff;background-position:0 0,100%,0 0,100%;background-repeat:no-repeat;background-size:2.5rem 100%,2.5rem 100%,1rem 100%,1rem 100%;margin:2rem 0;max-width:100%;overflow-x:auto;overflow-y:hidden}.table-container .fieldset{display:none!important;padding:0 1rem}[class*=chaarts] [role=presentation]{display:none}[class*=chaarts] abbr[title]{border-bottom:0;font-size:small;font-weight:400;text-transform:none}.chaarts{--checkers:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill-rule='evenodd' d='M0 0h4v4H0V0zm4 4h4v4H4V4z' fill='%23ffffff99'/%3E%3C/svg%3E");--hexagons:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='24' viewBox='0 0 28 49'%3E%3Cpath d='m13.99 9.25 13 7.5v15l-13 7.5L1 31.75v-15l12.99-7.5zM3 17.9v12.7l10.99 6.34 11-6.35V17.9l-11-6.34L3 17.9zM0 15l12.98-7.5V0h-2v6.35L0 12.69v2.3zm0 18.5L12.98 41v8h-2v-6.85L0 35.81v-2.3zM15 0v7.5L27.99 15H28v-2.31h-.01L17 6.35V0h-2zm0 49v-8l12.99-7.5H28v2.31h-.01L17 42.15V49h-2z' fill='%23ffffff99' fill-rule='nonzero'/%3E%3C/svg%3E");--triangles:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='16' viewBox='0 0 36 72'%3E%3Cpath d='M2 6h12L8 18 2 6zm18 36h12l-6 12-6-12z' fill='%23ffffff99' fill-rule='evenodd'/%3E%3C/svg%3E");--zig:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='12'%3E%3Cpath d='M9.8 12 0 2.2V.8l10 10 10-10v1.4L10.2 12h-.4zm-4 0L0 6.2V4.8L7.2 12H5.8zm8.4 0L20 6.2V4.8L12.8 12h1.4zM9.8 0l.2.2.2-.2h-.4zm-4 0L10 4.2 14.2 0h-1.4L10 2.8 7.2 0H5.8z' fill='%23ffffff99' fill-rule='evenodd'/%3E%3C/svg%3E");--stripes:url("data:image/svg+xml;charset=utf-8,%3Csvg width='6' height='6' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5 0h1L0 6V5zm1 5v1H5z' fill='%23ffffff99' fill-rule='evenodd'/%3E%3C/svg%3E");--dots:url("data:image/svg+xml;charset=utf-8,%3Csvg width='10' height='10' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff99' fill-rule='evenodd'%3E%3Ccircle cx='3' cy='3' r='3'/%3E%3Ccircle cx='13' cy='13' r='3'/%3E%3C/g%3E%3C/svg%3E");caption-side:bottom;empty-cells:hide;margin:1.5em auto;overflow:hidden;padding:1em}.chaarts>caption:first-child{background:inherit;font-style:normal;padding:1rem 0}table:not(.chaarts) .sr-only{clip:auto!important;clip-path:none!important;height:auto!important;overflow:visible!important;position:static!important;white-space:normal!important;width:auto!important}@media screen and (min-width:30em){.chaarts{border-collapse:initial;contain:content}.chaarts:not([class*=radar]){border-spacing:0}.chaarts td,.chaarts th{border:0;padding:0}.chaarts td:empty,.chaarts th:empty{display:none!important}@supports (grid-template-columns:repeat(var(--scale,100),minmax(0,1fr))){.bar-container .fieldset{display:flex!important}.chaarts.bar caption{text-align:initial;text-indent:13.5rem}.chaarts.bar tr{grid-row-gap:.5rem;display:grid;grid-auto-rows:1fr;grid-template-columns:minmax(min-content,12.5em) repeat(var(--scale,100),minmax(0,1fr)) 10ch;transition:opacity .2s cubic-bezier(.5,0,.5,1)}.chaarts.bar tr:nth-child(1n+1){--background:var(--checkers)}.chaarts.bar tr:nth-child(2n+2){--background:var(--hexagons)}.chaarts.bar tr:nth-child(3n+3){--background:var(--triangles)}.chaarts.bar tr:nth-child(4n+4){--background:var(--zig)}.chaarts.bar tr:nth-child(5n+5){--background:var(--stripes)}.chaarts.bar tr:nth-child(6n+6){--background:var(--dots)}.chaarts.bar th{grid-column:1/1;margin:.5rem 0 0;padding:0 1rem 0 0;text-align:right}.chaarts.bar td{--size:calc(var(--scale, 100)*100%);--position:calc(var(--value, 0)/var(--scale, 100)*100%);background:linear-gradient(to right,#01ac49,#444,#0000cd,#639,crimson) var(--position) 0 /var(--size) 100%,var(--background) center/contain;background-blend-mode:hard-light;grid-column:2/var(--value,0);margin:.5rem 0 0;position:relative}.chaarts.bar span{font-weight:700;left:100%;line-height:1.5;position:absolute}@supports ((-webkit-background-clip:text) or (background-clip:text)) or (-webkit-background-clip:text){.chaarts.bar span{background:inherit;-webkit-background-clip:text;background-clip:text;color:#0000}}.chaarts.bar:hover tr{opacity:.5}.chaarts.bar:hover tr:hover{opacity:1}@media screen and (min-width:30em) and (-ms-high-contrast:active){.chaarts.bar td{background-image:linear-gradient(to right,Window,ButtonFace,ButtonShadow,ButtonText,highlight),var(--background)}}.chaarts.bar.waterfall tr:first-of-type td{grid-column:var(--0,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(2) td{grid-column:var(--1,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(3) td{grid-column:var(--2,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(4) td{grid-column:var(--3,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(5) td{grid-column:var(--4,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(6) td{grid-column:var(--5,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(7) td{grid-column:var(--6,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(8) td{grid-column:var(--7,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(9) td{grid-column:var(--8,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(10) td{grid-column:var(--9,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(11) td{grid-column:var(--10,2) /var(--value,2)}}@supports (clip-path:polygon(50% calc(50% + (var(--gt-25,0))))){.pie-container .fieldset{display:flex!important;margin-bottom:0}.chaarts.pie{--radius:32em;margin:0 auto;padding-top:calc(var(--radius) - 2rem);position:relative}.chaarts.pie tbody{display:table-row}.chaarts.pie tr{display:table-cell;transition:opacity .3s cubic-bezier(.5,0,.5,1)}.chaarts.pie [scope=row]{padding-right:.5rem}.chaarts.pie [scope=row]:before{background:var(--color,currentColor) var(--background);content:"";display:inline-block;height:1rem;transform:translate3d(-.2rem,.1rem,0);width:1rem}.chaarts.pie td{--position:calc(var(--start, 0)*0.01turn)}.chaarts.pie td:after,.chaarts.pie td:before{left:50%;position:absolute;top:calc(var(--radius)/2);transform-origin:center center}.chaarts.pie td:before{--zoom:.75;--part:calc(var(--value)*3.6);--main-angle:calc(var(--part) - (var(--gt-25, 0) + var(--gt-50, 0) + var(--gt-75, 0))*90);--β:calc(var(--main-angle)*0.01745);--α:calc((90 - var(--main-angle))*0.01745);--sin-term-β-1:var(--β);--sin-term-β-2:calc((var(--β)*var(--β)*var(--β))/6);--sin-term-β-3:calc((var(--β)*var(--β)*var(--β)*var(--β)*var(--β))/120);--sin-term-β-4:calc((var(--β)*var(--β)*var(--β)*var(--β)*var(--β)*var(--β)*var(--β))/5040);--sin-term-β-5:calc((var(--β)*var(--β)*var(--β)*var(--β)*var(--β)*var(--β)*var(--β)*var(--β)*var(--β))/362880);--sin-β:calc(var(--sin-term-β-1) - var(--sin-term-β-2) + var(--sin-term-β-3) - var(--sin-term-β-4) + var(--sin-term-β-5));--sin-term-α-1:var(--α);--sin-term-α-2:calc((var(--α)*var(--α)*var(--α))/6);--sin-term-α-3:calc((var(--α)*var(--α)*var(--α)*var(--α)*var(--α))/120);--sin-term-α-4:calc((var(--α)*var(--α)*var(--α)*var(--α)*var(--α)*var(--α)*var(--α))/5040);--sin-term-α-5:calc((var(--α)*var(--α)*var(--α)*var(--α)*var(--α)*var(--α)*var(--α)*var(--α)*var(--α))/362880);--sin-α:calc(var(--sin-term-α-1) - var(--sin-term-α-2) + var(--sin-term-α-3) - var(--sin-term-α-4) + var(--sin-term-α-5));--pos-B:calc(var(--sin-β)*50);--pos-A:calc(var(--sin-α)*50);--polygon:polygon(50% 50%,50% 0%,100% 0%,calc(50% + var(--pos-B)*1%*var(--lt-25, 1) + var(--gt-25, 0)*50%) calc(50% - var(--pos-A)*1%*var(--lt-25, 1)),calc(50% + var(--gt-25, 0)*50%) calc(50% + var(--gt-25, 0)*50%),calc(50% + var(--pos-A)*1%*var(--lt-50, 1) + var(--gt-50, 0)*50%) calc(50% + var(--pos-B)*1%*var(--lt-50, 1) + var(--gt-50, 0)*50%),calc(50% - var(--gt-50, 0)*50%) calc(50% + var(--gt-50, 0)*50%),calc(50% - var(--pos-B)*1%*var(--lt-75, 1) - var(--gt-75, 0)*50%) calc(50% + var(--pos-A)*1%*var(--lt-75, 1)),calc(50% - var(--gt-75, 0)*50%) calc(50% - var(--gt-75, 0)*50%),calc(50% - var(--pos-A)*1%*var(--gt-75, 0)) calc(50% - var(--pos-B)*1%*var(--gt-75, 0)),50% 50%);--mask:radial-gradient(circle at center,#fff 0 calc(var(--radius)/2),#0000 0);background:var(--color,currentColor) var(--background);clip-path:var(--polygon);content:"";height:var(--radius);-webkit-mask-image:var(--mask);mask-image:var(--mask);transform:translate3d(-50%,-50%,0) rotate(var(--position)) scale(var(--zoom));transition:transform .2s cubic-bezier(.5,0,.5,1);width:var(--radius)}.chaarts.pie tr:hover td:before{--zoom:.8}.chaarts.pie tr:nth-child(1n+1){--background:var(--checkers)}.chaarts.pie tr:nth-child(2n+2){--background:var(--hexagons)}.chaarts.pie tr:nth-child(3n+3){--background:var(--triangles)}.chaarts.pie tr:nth-child(4n+4){--background:var(--zig)}.chaarts.pie tr:nth-child(5n+5){--background:var(--stripes)}.chaarts.pie tr:nth-child(6n+6){--background:var(--dots)}.chaarts.pie td:after{--arrow:calc(100% - 0.25rem);--axis:calc(var(--position) - 0.25turn + var(--value)*0.005turn);--away:calc(var(--radius)/2 - 1rem);--integer:calc(var(--value));background-color:#444;color:#fff;content:var(--term) " : " counter(value) " %";counter-reset:value var(--integer);opacity:0;padding:.5rem;pointer-events:none;transform:translate3d(-50%,-50%,0) rotate(var(--axis)) translate(var(--away)) rotate(calc(var(--axis)*-1)) perspective(1000px) rotateX(45deg);transform-origin:50% calc(100% + 10px);transition:opacity .2s cubic-bezier(0,.5,.5,1),transform .2s cubic-bezier(0,.5,.5,1)}.chaarts.pie tbody:hover tr{opacity:.5}.chaarts.pie tbody:hover tr:hover{opacity:1}.chaarts.pie tbody:hover tr:hover td:after{opacity:1;transform:translate3d(-50%,-50%,0) rotate(var(--axis)) translate(var(--away)) rotate(calc(var(--axis)*-1)) perspective(1000px) rotateX(0deg);transition:opacity .2s cubic-bezier(.5,0,1,.5),transform .2s cubic-bezier(.5,0,1,.5)}.chaarts.polar td:before{--zoom:50;transform:translate3d(-50%,-50%,0) rotate(var(--position)) scale(calc((var(--zoom) + var(--value)/(100/var(--zoom)))/100))}.chaarts.polar td:after{--away:calc(var(--radius)/2 - (var(--radius)/4)*(100 - var(--value))/100 + 2.5rem)}.chaarts.polar tr:hover td:before{--zoom:50}.chaarts.donut{--mask:radial-gradient(circle at 50% calc(50% - 0.25rem),#0000 0 var(--offset),#fff calc(var(--offset) + 1px) 100%);-webkit-mask-image:var(--mask);mask-image:var(--mask)}.chaarts.donut td:after{--away:calc(var(--radius)/2 - 2.5rem)}@media screen and (min-width:30em) and (-ms-high-contrast:active){.chaarts.pie tbody tr :before{background-color:Window}.chaarts.pie tbody tr:nth-of-type(odd) :before{background-color:WindowText}}}@supports (clip-path:polygon(0% calc(100% - var(--1 ) * 100% / var(--y )))){.line-container .fieldset{display:flex!important}.chaarts.line{--offset:calc((100%/var(--x))/2);--height:calc(32em - 2rem);--bottom:calc(100% - var(--height));padding:var(--height) 0 1rem;position:relative;transition:background .3s cubic-bezier(.5,0,.5,1),color .3s cubic-bezier(.5,0,.5,1)}.chaarts.line:after{--scale:calc((100% - var(--y)*1px)/var(--y));background:repeating-linear-gradient(to bottom,#fff 0 var(--scale),#00000040 calc(var(--scale) + 1px));bottom:var(--bottom);top:0;width:100%;z-index:1}.chaarts.line tr:before,.chaarts.line:after{content:"";position:absolute}.chaarts.line [scope=row],.chaarts.line thead th:first-child{color:var(--color,currentColor);text-align:left}.chaarts.line [style]:before{--polygon:polygon(0% 100%,calc(100%/var(--x)*1) 100%,calc(100%/var(--x)*1) calc(100% - var(--1)/var(--y)*100%),calc(100%/var(--x)*1 + var(--offset)) calc(100% - var(--1)/var(--y)*100%),calc(100%/var(--x)*2 + var(--offset)) calc(100% - var(--2)/var(--y)*100%),calc(100%/var(--x)*3 + var(--offset)) calc(100% - var(--3)/var(--y)*100%),calc(100%/var(--x)*4 + var(--offset)) calc(100% - var(--4)/var(--y)*100%),calc(100%/var(--x)*5 + var(--offset)) calc(100% - var(--5)/var(--y)*100%),calc(100%/var(--x)*6 + var(--offset)) calc(100% - var(--6)/var(--y)*100%),calc(100%/var(--x)*7 + var(--offset)) calc(100% - var(--7)/var(--y)*100%),calc(100%/var(--x)*8 + var(--offset)) calc(100% - var(--8)/var(--y)*100%),calc(100%/var(--x)*9 + var(--offset)) calc(100% - var(--9)/var(--y)*100%),calc(100%/var(--x)*10 + var(--offset)) calc(100% - var(--10)/var(--y)*100%),calc(100%/var(--x)*11 + var(--offset)) calc(100% - var(--11)/var(--y)*100%),calc(100%/var(--x)*12 + var(--offset)) calc(100% - var(--12)/var(--y)*100%),100% calc(100% - var(--12)/var(--y)*100%),100% 100%,0% 100%);background:linear-gradient(0deg,#00bfff,crimson 75%);bottom:var(--bottom);clip-path:var(--polygon);content:"";position:absolute;top:0;width:100%;z-index:2}.chaarts.line td,.chaarts.line th{background:#fff;font-weight:700;text-align:center;width:calc(100%/var(--x))}.chaarts.line [scope=col]:not(:first-child):after{background:#fff var(--stripes);background-blend-mode:exclusion;bottom:4rem;content:"";height:calc(100% - 4rem);left:calc(100%/var(--x)*var(--index));mix-blend-mode:soft-light;opacity:0;position:absolute;transition:opacity .3s cubic-bezier(.5,0,.5,1);width:inherit;z-index:3}.chaarts.line [scope=col]:nth-child(2):after{--index:1}.chaarts.line [scope=col]:nth-child(3):after{--index:2}.chaarts.line [scope=col]:nth-child(4):after{--index:3}.chaarts.line [scope=col]:nth-child(5):after{--index:4}.chaarts.line [scope=col]:nth-child(6):after{--index:5}.chaarts.line [scope=col]:nth-child(7):after{--index:6}.chaarts.line [scope=col]:nth-child(8):after{--index:7}.chaarts.line [scope=col]:nth-child(9):after{--index:8}.chaarts.line [scope=col]:nth-child(10):after{--index:9}.chaarts.line [scope=col]:nth-child(11):after{--index:10}.chaarts.line [scope=col]:nth-child(12):after{--index:11}.chaarts.line [scope=col]:nth-child(13):after{--index:12}.chaarts.line [scope=col]:hover:after{opacity:.75}.chaarts.line td{--value:var(--1);--term:var(--t-1);line-height:1.5}.chaarts.line td:before{content:"";height:1.5rem;position:absolute;transform:translateX(-50%);width:inherit;z-index:10}.chaarts.line td:after{--arrow:calc(100% - 0.25rem);--top:calc(var(--height) - var(--value)/var(--y)*var(--height));--polygon:polygon(0% 0%,100% 0%,100% var(--arrow),calc(50% - 0.25rem) var(--arrow),50% 100%,calc(50% + 0.25rem) var(--arrow),0% var(--arrow));--integer:calc(var(--value));background-color:#444;clip-path:var(--polygon);color:#fff;content:var(--term) " " var(--year) "\a" counter(value) " " var(--unit);counter-reset:value var(--integer);left:calc(var(--offset)*3);opacity:0;padding:.5rem;pointer-events:none;position:absolute;top:var(--top,0);transform:translate3d(-50%,-125%,0) perspective(1000px) rotateX(45deg);transform-origin:50% calc(100% + 10px);transition:opacity .2s cubic-bezier(0,.5,.5,1),transform .2s cubic-bezier(0,.5,.5,1);white-space:pre;z-index:5}.chaarts.line td+td:after{left:calc(100%/var(--x)*var(--index) + var(--offset))}.chaarts.line td:nth-child(2):after{--value:var(--1);--term:var(--t-1);--index:1}.chaarts.line td:nth-child(3):after{--value:var(--2);--term:var(--t-2);--index:2}.chaarts.line td:nth-child(4):after{--value:var(--3);--term:var(--t-3);--index:3}.chaarts.line td:nth-child(5):after{--value:var(--4);--term:var(--t-4);--index:4}.chaarts.line td:nth-child(6):after{--value:var(--5);--term:var(--t-5);--index:5}.chaarts.line td:nth-child(7):after{--value:var(--6);--term:var(--t-6);--index:6}.chaarts.line td:nth-child(8):after{--value:var(--7);--term:var(--t-7);--index:7}.chaarts.line td:nth-child(9):after{--value:var(--8);--term:var(--t-8);--index:8}.chaarts.line td:nth-child(10):after{--value:var(--9);--term:var(--t-9);--index:9}.chaarts.line td:nth-child(11):after{--value:var(--10);--term:var(--t-10);--index:10}.chaarts.line td:nth-child(12):after{--value:var(--11);--term:var(--t-11);--index:11}.chaarts.line td:nth-child(13):after{--value:var(--12);--term:var(--t-12);--index:12}.chaarts.line td:hover:after{opacity:1;transform:translate3d(-50%,-125%,0) perspective(1000px) rotateX(0deg);transition:opacity .2s cubic-bezier(.5,0,1,.5),transform .2s cubic-bezier(.5,0,1,.5)}.chaarts.points [style]:before{--polygon:polygon(calc(100%/var(--x)*1 + var(--offset)) calc(100% - var(--1)/var(--y)*100%),calc(100%/var(--x)*2 + var(--offset)) calc(100% - var(--2)/var(--y)*100%),calc(100%/var(--x)*3 + var(--offset)) calc(100% - var(--3)/var(--y)*100%),calc(100%/var(--x)*4 + var(--offset)) calc(100% - var(--4)/var(--y)*100%),calc(100%/var(--x)*5 + var(--offset)) calc(100% - var(--5)/var(--y)*100%),calc(100%/var(--x)*6 + var(--offset)) calc(100% - var(--6)/var(--y)*100%),calc(100%/var(--x)*7 + var(--offset)) calc(100% - var(--7)/var(--y)*100%),calc(100%/var(--x)*8 + var(--offset)) calc(100% - var(--8)/var(--y)*100%),calc(100%/var(--x)*9 + var(--offset)) calc(100% - var(--9)/var(--y)*100%),calc(100%/var(--x)*10 + var(--offset)) calc(100% - var(--10)/var(--y)*100%),calc(100%/var(--x)*11 + var(--offset)) calc(100% - var(--11)/var(--y)*100%),calc(100%/var(--x)*12 + var(--offset)) calc(100% - var(--12)/var(--y)*100%),calc(100%/var(--x)*13 + var(--offset)) calc(100% - var(--12)/var(--y)*100%),100% calc(100% - var(--12)/var(--y)*100%),100% calc(100% + 0.25rem - var(--12)/var(--y)*100%),calc(100%/var(--x)*13 + var(--offset)) calc(100% + 0.25rem - var(--12)/var(--y)*100%),calc(100%/var(--x)*12 + var(--offset)) calc(100% + 0.25rem - var(--12)/var(--y)*100%),calc(100%/var(--x)*11 + var(--offset)) calc(100% + 0.25rem - var(--11)/var(--y)*100%),calc(100%/var(--x)*10 + var(--offset)) calc(100% + 0.25rem - var(--10)/var(--y)*100%),calc(100%/var(--x)*9 + var(--offset)) calc(100% + 0.25rem - var(--9)/var(--y)*100%),calc(100%/var(--x)*8 + var(--offset)) calc(100% + 0.25rem - var(--8)/var(--y)*100%),calc(100%/var(--x)*7 + var(--offset)) calc(100% + 0.25rem - var(--7)/var(--y)*100%),calc(100%/var(--x)*6 + var(--offset)) calc(100% + 0.25rem - var(--6)/var(--y)*100%),calc(100%/var(--x)*5 + var(--offset)) calc(100% + 0.25rem - var(--5)/var(--y)*100%),calc(100%/var(--x)*4 + var(--offset)) calc(100% + 0.25rem - var(--4)/var(--y)*100%),calc(100%/var(--x)*3 + var(--offset)) calc(100% + 0.25rem - var(--3)/var(--y)*100%),calc(100%/var(--x)*2 + var(--offset)) calc(100% + 0.25rem - var(--2)/var(--y)*100%),calc(100%/var(--x)*1 + var(--offset)) calc(100% + 0.25rem - var(--1)/var(--y)*100%));background:var(--color,currentColor) var(--background);transition:opacity .3s cubic-bezier(.5,0,.5,1)}.chaarts.points [style] th:before{background:var(--color,currentColor) var(--background);content:"";display:inline-block;height:1rem;transform:translate3d(-.2rem,.1rem,0);width:1rem}.chaarts.points [style] td:before{--size:1rem;--top:calc(var(--height) - var(--value)/var(--y)*var(--height));background:var(--color,currentColor) var(--background);border:2px solid #fff;border-radius:50%;box-shadow:0 0 .25rem #00000080;content:"";height:var(--size);left:calc(var(--offset)*3);position:absolute;top:var(--top,100);transform:translate3d(calc(var(--size)/-2),calc(var(--size)/-2),0);transition:opacity .3s cubic-bezier(.5,0,.5,1),transform .3s cubic-bezier(.5,0,.5,1);width:var(--size);z-index:4}.chaarts.points [style] td+td:before{left:calc(100%/var(--x)*var(--index) + var(--offset))}.chaarts.points [style] td:nth-of-type(2):before{--value:var(--2);--index:2}.chaarts.points [style] td:nth-of-type(3):before{--value:var(--3);--index:3}.chaarts.points [style] td:nth-of-type(4):before{--value:var(--4);--index:4}.chaarts.points [style] td:nth-of-type(5):before{--value:var(--5);--index:5}.chaarts.points [style] td:nth-of-type(6):before{--value:var(--6);--index:6}.chaarts.points [style] td:nth-of-type(7):before{--value:var(--7);--index:7}.chaarts.points [style] td:nth-of-type(8):before{--value:var(--8);--index:8}.chaarts.points [style] td:nth-of-type(9):before{--value:var(--9);--index:9}.chaarts.points [style] td:nth-of-type(10):before{--value:var(--10);--index:10}.chaarts.points [style] td:nth-of-type(11):before{--value:var(--11);--index:11}.chaarts.points [style] td:nth-of-type(12):before{--value:var(--12);--index:12}.chaarts.points [style]:nth-child(1n+1){--background:var(--checkers)}.chaarts.points [style]:nth-child(2n+2){--background:var(--hexagons)}.chaarts.points [style]:nth-child(3n+3){--background:var(--triangles)}.chaarts.points [style]:nth-child(4n+4){--background:var(--zig)}.chaarts.points [style]:nth-child(5n+5){--background:var(--stripes)}.chaarts.points [style]:nth-child(6n+6){--background:var(--dots)}.chaarts.points tbody:hover [style] td:before,.chaarts.points tbody:hover [style]:before{opacity:.25}.chaarts.points tbody:hover [style]:hover td:before,.chaarts.points tbody:hover [style]:hover:before{opacity:1}.chaarts.points tbody:hover [style]:hover td:before{transform:translate3d(calc(var(--size)/-2),calc(var(--size)/-2),0) scale(1.25)}.chaarts.points [scope=col]:not(:first-child):after{mix-blend-mode:multiply}.chaarts.points [scope=col]:not(:first-child):hover:after{opacity:.5}@media screen and (min-width:30em) and (-ms-high-contrast:active){.chaarts.line [style]:before{background:linear-gradient(0deg,ButtonHighlight,Highlight 75%)}}}@supports (display:contents){.column-container .fieldset{display:flex!important}.chaarts[class*=column]{--gap:0.5rem;--size:calc(var(--scale, 100)*100%);--width:calc(64em/var(--y) - 1rem);grid-column-gap:var(--gap);display:grid;max-height:64em;position:relative}.chaarts[class*=column] td,.chaarts[class*=column] th{margin:0}.chaarts[class*=column] tr>*+*{text-align:center}.chaarts[class*=column] tbody,.chaarts[class*=column] thead,.chaarts[class*=column] tr{display:contents}.chaarts[class*=column] caption{grid-column:1/span var(--y);grid-row:-1}.chaarts[class*=column] td{--integer:calc(var(--value));grid-row:calc(var(--scale, 100) + 2 - var(--integer)) /-2;pointer-events:none;position:relative;transition:opacity .2s cubic-bezier(.5,0,.5,1)}.chaarts[class*=column] td:first-of-type{grid-column:2}.chaarts[class*=column] td:nth-of-type(2){grid-column:3}.chaarts[class*=column] td:nth-of-type(3){grid-column:4}.chaarts[class*=column] td:nth-of-type(4){grid-column:5}.chaarts[class*=column] td:nth-of-type(5){grid-column:6}.chaarts[class*=column] td:nth-of-type(6){grid-column:7}.chaarts[class*=column] td:nth-of-type(7){grid-column:8}.chaarts[class*=column] td:nth-of-type(8){grid-column:9}.chaarts[class*=column] td:nth-of-type(9){grid-column:10}.chaarts[class*=column] td:nth-of-type(10){grid-column:11}.chaarts[class*=column] span{bottom:100%;font-weight:700;left:0;line-height:1.5;pointer-events:auto;position:absolute;right:0}@supports ((-webkit-background-clip:text) or (background-clip:text)) or (-webkit-background-clip:text){.chaarts[class*=column] span{background:inherit;-webkit-background-clip:text;background-clip:text;color:#0000}}.chaarts[class*=column].column-single{grid-auto-columns:1fr;grid-template-rows:2ex repeat(var(--scale,100),minmax(0,.25rem)) minmax(min-content,2rem)}.chaarts[class*=column].column-single tbody th{grid-column:1;grid-row:-6/-3;line-height:1}.chaarts[class*=column].column-single thead *{grid-row:-2}.chaarts[class*=column].column-single td{--position:calc(var(--integer, 0)/var(--scale, 100)*100%);background:linear-gradient(to top,#01ac49,#444,#0000cd,#639,crimson) 0 var(--position) /100% var(--size),var(--background) center/1rem;background-blend-mode:hard-light}.chaarts[class*=column].column-single [scope=col]:after{background:#f5f5f5 var(--stripes);background-blend-mode:exclusion;bottom:4rem;content:"";mix-blend-mode:multiply;opacity:0;position:absolute;top:1rem;transition:opacity .3s cubic-bezier(.5,0,.5,1);width:var(--width);z-index:0}.chaarts[class*=column].column-single [scope=col]:hover:after{opacity:.5}.chaarts[class*=column].column-single [scope=col]:nth-child(2):after{left:calc(1em + var(--width)*1 + var(--gap)*1)}.chaarts[class*=column].column-single [scope=col]:nth-child(3):after{left:calc(1em + var(--width)*2 + var(--gap)*2)}.chaarts[class*=column].column-single [scope=col]:nth-child(4):after{left:calc(1em + var(--width)*3 + var(--gap)*3)}.chaarts[class*=column].column-single [scope=col]:nth-child(5):after{left:calc(1em + var(--width)*4 + var(--gap)*4)}.chaarts[class*=column].column-single [scope=col]:nth-child(6):after{left:calc(1em + var(--width)*5 + var(--gap)*5)}.chaarts[class*=column].column-single [scope=col]:nth-child(7):after{left:calc(1em + var(--width)*6 + var(--gap)*6)}.chaarts[class*=column].column-single td:nth-of-type(1n+1){--background:var(--checkers)}.chaarts[class*=column].column-single td:nth-of-type(2n+2){--background:var(--hexagons)}.chaarts[class*=column].column-single td:nth-of-type(3n+3){--background:var(--triangles)}.chaarts[class*=column].column-single td:nth-of-type(4n+4){--background:var(--zig)}.chaarts[class*=column].column-single td:nth-of-type(5n+5){--background:var(--stripes)}.chaarts[class*=column].column-single td:nth-of-type(6n+6){--background:var(--dots)}@media screen and (min-width:30em) and (-ms-high-contrast:active){.chaarts[class*=column].column-single td{background-image:linear-gradient(to top,Window,ButtonFace,ButtonShadow,ButtonText,highlight),var(--background)}}.chaarts[class*=column].column-multiple{grid-template-columns:minmax(min-content,14ch) repeat(calc(var(--y) - 1),1fr);grid-template-rows:2ex repeat(var(--scale,100),minmax(0,.25rem)) repeat(2,minmax(min-content,2rem))}.chaarts[class*=column].column-multiple span{background-image:none}.chaarts[class*=column].column-multiple tbody th{grid-row:-10/span 7}.chaarts[class*=column].column-multiple thead tr *{grid-column:1;grid-row:-2}.chaarts[class*=column].column-multiple thead tr :nth-of-type(2){grid-column:calc(4 - var(--span))/span var(--span)}.chaarts[class*=column].column-multiple thead tr :nth-of-type(3){grid-column:calc(6 - var(--span))/span var(--span)}.chaarts[class*=column].column-multiple thead tr :nth-of-type(4){grid-column:calc(8 - var(--span))/span var(--span)}.chaarts[class*=column].column-multiple thead tr :nth-of-type(5){grid-column:calc(10 - var(--span))/span var(--span)}.chaarts[class*=column].column-multiple thead tr :nth-of-type(6){grid-column:calc(12 - var(--span))/span var(--span)}.chaarts[class*=column].column-multiple thead tr+tr *{font-weight:400;grid-row:-3}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(2){grid-column:2}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(3){grid-column:3}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(4){grid-column:4}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(5){grid-column:5}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(6){grid-column:6}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(7){grid-column:7}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(8){grid-column:8}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(9){grid-column:9}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(10){grid-column:10}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(11){grid-column:11}.chaarts[class*=column].column-multiple tr:first-child [scope=col]:nth-child(2n):after{background:#f5f5f5 var(--stripes);background-blend-mode:exclusion;bottom:4rem;content:"";mix-blend-mode:multiply;opacity:.25;position:absolute;top:calc(1rem + 2ex);transition:opacity .3s cubic-bezier(.5,0,.5,1);width:calc(var(--width)*2 + var(--gap)/2 + 1px);z-index:0}.chaarts[class*=column].column-multiple tr:first-child [scope=col]:nth-child(2):after{left:calc(14ch + 1em + var(--width)*2*0 + var(--gap)/2*0 + var(--gap)*1)}.chaarts[class*=column].column-multiple tr:first-child [scope=col]:nth-child(4):after{left:calc(14ch + 1em + var(--width)*2*2 + var(--gap)/2*2 + 2px + var(--gap)*3)}.chaarts[class*=column].column-multiple tr:first-child [scope=col]:nth-child(6):after{left:calc(14ch + 1em + var(--width)*2*4 + var(--gap)/2*4 + 4px + var(--gap)*5)}.chaarts[class*=column].column-multiple td{background-color:#e11a81;background-image:var(--zig);grid-row-end:-3}.chaarts[class*=column].column-multiple td:nth-of-type(2n+2){background:#0172f0 var(--triangles)}@media screen and (min-width:30em) and (-ms-high-contrast:active){.chaarts[class*=column].column-multiple td{background-color:Window}.chaarts[class*=column].column-multiple td:nth-of-type(2n+2){background-color:Highlight}}}@supports (clip-path:polygon(0% 0%,calc(100% - var(--1 ) * 100% / var(--scale )) 100%,100% 100%)){.radar-container .fieldset{display:flex!important}.chaarts[class*=radar]{--radius:12.8em;--unitless-radius:12.8;--size:calc(var(--radius)/var(--scale));--part:calc(360deg/var(--items));--integer:calc(var(--scale));background-image:repeating-radial-gradient(circle at 50%,#0003 0 2px,#0000 0 calc(var(--size)*var(--step))),repeating-radial-gradient(circle at 50%,#0000001a 0 2px,#0000 0 var(--size));border:2px solid;border-radius:50%;contain:layout;counter-reset:scale var(--integer);height:calc(var(--radius)*2);margin:6rem auto 12rem;overflow:visible;position:relative;width:calc(var(--radius)*2)}.chaarts[class*=radar] caption{background:none;bottom:-10rem;position:absolute}.chaarts[class*=radar] [scope=col]{--away:calc(var(--radius)*-1 - 50%);left:50%;margin:0;padding:0 1rem;position:absolute;top:50%;transform:translate3d(-50%,-50%,0) rotate(calc(var(--part)*var(--index, 1))) translate(var(--away)) rotate(calc(var(--part)*var(--index, 1)*-1))}.chaarts[class*=radar] tr>:first-of-type{--index:1}.chaarts[class*=radar] tr>:nth-of-type(2){--index:2}.chaarts[class*=radar] tr>:nth-of-type(3){--index:3}.chaarts[class*=radar] tr>:nth-of-type(4){--index:4}.chaarts[class*=radar] tr>:nth-of-type(5){--index:5}.chaarts[class*=radar] tr>:nth-of-type(6){--index:6}.chaarts[class*=radar] tr>:nth-of-type(7){--index:7}.chaarts[class*=radar] td{--skew:calc(90deg - var(--part));border-bottom:1px solid #8a2be2;height:50%;left:0;margin:0;position:absolute;top:0;transform:rotate(calc(var(--part)*var(--index, 1))) skew(var(--skew));transform-origin:100% 100%;width:50%}.chaarts[class*=radar] td:first-of-type span{--point:var(--1);--pos:calc(100% - var(--2)*100%/(var(--scale)*var(--ratio)))}.chaarts[class*=radar] td:nth-of-type(2) span{--point:var(--2);--pos:calc(100% - var(--3)*100%/(var(--scale)*var(--ratio)))}.chaarts[class*=radar] td:nth-of-type(3) span{--point:var(--3);--pos:calc(100% - var(--4)*100%/(var(--scale)*var(--ratio)))}.chaarts[class*=radar] td:nth-of-type(4) span{--point:var(--4);--pos:calc(100% - var(--5)*100%/(var(--scale)*var(--ratio)))}.chaarts[class*=radar] td:nth-of-type(5) span{--point:var(--5);--pos:calc(100% - var(--6)*100%/(var(--scale)*var(--ratio)))}.chaarts[class*=radar] td:nth-of-type(6) span{--point:var(--6);--pos:calc(100% - var(--7)*100%/(var(--scale)*var(--ratio)))}.chaarts[class*=radar] td:nth-of-type(7) span{--point:var(--7);--pos:calc(100% - var(--8)*100%/(var(--scale)*var(--ratio)))}.chaarts[class*=radar] td:after,.chaarts[class*=radar] td:before{display:none}.chaarts[class*=radar] span{--opposite:calc(360/var(--items));--angle:calc(var(--opposite)*0.01745);--sin-term-angle-1:var(--angle);--sin-term-angle-2:calc((var(--angle)*var(--angle)*var(--angle))/6);--sin-term-angle-3:calc((var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle))/120);--sin-term-angle-4:calc((var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle))/5040);--sin-term-angle-5:calc((var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle))/362880);--sin-angle:calc(var(--sin-term-angle-1) - var(--sin-term-angle-2) + var(--sin-term-angle-3) - var(--sin-term-angle-4) + var(--sin-term-angle-5));--hypo:calc(var(--unitless-radius)/var(--sin-angle));--ratio:calc(var(--hypo)/var(--unitless-radius));--polygon:polygon(100% var(--pos),calc(100% - var(--point)*100%/var(--scale)) 100%,100% 100%);background:linear-gradient(to top left,#8a2be2 10%,#00008b 75%);clip-path:var(--polygon);filter:drop-shadow(0 0 1rem indigo);height:100%;position:absolute;width:100%}.chaarts.radar [scope=col]:after{color:#639;display:block;font-size:small;font-weight:400}.chaarts.radar [scope=col]:first-child:after{--integer:calc(var(--1));content:counter(value) " / " counter(scale);counter-reset:value var(--integer)}.chaarts.radar [scope=col]:nth-child(2):after{--integer:calc(var(--2));content:counter(value) " / " counter(scale);counter-reset:value var(--integer)}.chaarts.radar [scope=col]:nth-child(3):after{--integer:calc(var(--3));content:counter(value) " / " counter(scale);counter-reset:value var(--integer)}.chaarts.radar [scope=col]:nth-child(4):after{--integer:calc(var(--4));content:counter(value) " / " counter(scale);counter-reset:value var(--integer)}.chaarts.radar [scope=col]:nth-child(5):after{--integer:calc(var(--5));content:counter(value) " / " counter(scale);counter-reset:value var(--integer)}.chaarts.radar [scope=col]:nth-child(6):after{--integer:calc(var(--6));content:counter(value) " / " counter(scale);counter-reset:value var(--integer)}.chaarts.radar [scope=col]:nth-child(7):after{--integer:calc(var(--7));content:counter(value) " / " counter(scale);counter-reset:value var(--integer)}.chaarts.radar-multiple{margin-bottom:12rem}.chaarts.radar-multiple tbody{columns:var(--areas);vertical-align:bottom}.chaarts.radar-multiple [scope=row]{bottom:-8rem;height:2rem;left:1rem;position:absolute}.chaarts.radar-multiple [scope=row]:before{background:var(--color,currentColor);content:"";display:inline-block;height:1rem;margin-right:.25rem;transform:translate3d(0,.1rem,0);width:1rem}.chaarts.radar-multiple tr:nth-child(2) [scope=row]{left:calc(1rem + (100%/var(--areas))*1)}.chaarts.radar-multiple td{align-items:flex-end;border-color:var(--color,currentColor);display:flex;justify-content:flex-end;opacity:.5;pointer-events:none;z-index:0}.chaarts.radar-multiple td:after{color:var(--color,currentColor);display:block;font-size:small;font-weight:700;text-indent:-.5rem;transform:skew(calc(var(--skew)*-1)) rotate(calc(var(--part)*var(--index, 1)*-1));transform-origin:0 0;white-space:nowrap;width:100%}.chaarts.radar-multiple td:first-of-type:after{--integer:calc(var(--1));content:counter(value);counter-reset:value var(--integer);width:calc(var(--1)*100%/var(--scale))}.chaarts.radar-multiple td:nth-of-type(2):after{--integer:calc(var(--2));content:counter(value);counter-reset:value var(--integer);width:calc(var(--2)*100%/var(--scale))}.chaarts.radar-multiple td:nth-of-type(3):after{--integer:calc(var(--3));content:counter(value);counter-reset:value var(--integer);width:calc(var(--3)*100%/var(--scale))}.chaarts.radar-multiple td:nth-of-type(4):after{--integer:calc(var(--4));content:counter(value);counter-reset:value var(--integer);width:calc(var(--4)*100%/var(--scale))}.chaarts.radar-multiple td:nth-of-type(5):after{--integer:calc(var(--5));content:counter(value);counter-reset:value var(--integer);width:calc(var(--5)*100%/var(--scale))}.chaarts.radar-multiple td:nth-of-type(6):after{--integer:calc(var(--6));content:counter(value);counter-reset:value var(--integer);width:calc(var(--6)*100%/var(--scale))}.chaarts.radar-multiple td:nth-of-type(7):after{--integer:calc(var(--7));content:counter(value);counter-reset:value var(--integer);width:calc(var(--7)*100%/var(--scale))}.chaarts.radar-multiple span{background:var(--color,currentColor);pointer-events:auto}@supports ((-webkit-mask-image:url()) or (mask-image:url())){.chaarts.radar-multiple span{--mask:radial-gradient(circle at bottom right,#000,#00000080);-webkit-mask-image:var(--mask);mask-image:var(--mask)}}@media screen and (min-width:30em) and (hover:hover){.chaarts.radar-multiple td{opacity:.25;transition:opacity .2s cubic-bezier(.5,0,.5,1)}.chaarts.radar-multiple td:after{opacity:0;transition:inherit}.chaarts.radar-multiple tr:hover td{opacity:1;z-index:1}.chaarts.radar-multiple tr:hover td:after{opacity:inherit}}}} +/*# sourceMappingURL=chaarts.min.css.map */ \ No newline at end of file diff --git a/dist/chaarts.min.css.map b/dist/chaarts.min.css.map new file mode 100644 index 0000000..9dd7d73 --- /dev/null +++ b/dist/chaarts.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/chaarts.scss","chaarts.css","../src/_chaarts-bar.scss","../src/_chaarts-pie.scss","../src/abstracts/_variables.scss","../src/abstracts/_mixins.scss","../src/_chaarts-line.scss","../src/_chaarts-column.scss","../src/_chaarts-radar.scss"],"names":[],"mappings":"AAqJA,gBCs1CA,CDt9CA,oBACC,kBAAA,CACA,eAAA,CACA,cCLD,CDWA,MAGC,4BAAA,CAFA,wBAAA,CACA,gBAAA,CAEA,oBAAA,CAEA,kBAAA,CADA,UCLD,CDQC,0BACC,iBAAA,CACA,QAAA,CACA,mBCNF,CDUA,MAEC,oBAAA,CACA,eCPD,CDUA,gBAEC,UCPD,CDUA,GACC,gBAAA,CACA,cCPD,CDUA,MACC,wBCPD,CDUA,MACC,qBCPD,CDqBA,iBACC,+MAAA,CAQA,+CAAA,CAHA,qBAAA,CAEA,qCAAA,CAHA,2BAAA,CAEA,2DAAA,CAGA,aAAA,CACA,cAAA,CACA,eAAA,CACA,iBCVD,CDaA,2BACC,sBAAA,CACA,cCVD,CDcC,qCACC,YCXF,CDcC,6BACC,eAAA,CACA,eAAA,CACA,eAAA,CACA,mBCZF,CDgBA,SAeE,+MAAA,CAAA,geAAA,CAAA,iPAAA,CAAA,uVAAA,CAAA,0MAAA,CAAA,0QAAA,CAdD,mBAAA,CACA,gBAAA,CACA,iBAAA,CACA,eAAA,CACA,WCAD,CDaC,6BACC,kBAAA,CACA,iBAAA,CACA,cCXF,CDeA,6BACC,mBAAA,CACA,wBAAA,CACA,qBAAA,CACA,0BAAA,CACA,yBAAA,CAEA,4BAAA,CADA,oBCXD,CDeA,mCACC,SACC,uBAAA,CAKA,eCPA,CDcA,6BACC,gBCZD,CDeA,wBAEC,QAAA,CACA,SCbD,CDeC,oCACC,sBCZF,CCxIF,yEACC,yBACC,sBD2JE,CCvJF,qBACC,kBAAA,CACA,mBDyJC,CCtJF,gBAGC,kBAAA,CAFA,YAAA,CACA,kBAAA,CAEA,4FAAA,CACA,8CDwJC,CCnJA,gCACC,4BDqJD,CCtJA,gCACC,4BDwJD,CCzJA,gCACC,6BD2JD,CC5JA,gCACC,uBD8JD,CC/JA,gCACC,2BDiKD,CClKA,gCACC,wBDoKD,CC/JF,gBACC,eAAA,CACA,gBAAA,CACA,kBAAA,CACA,gBDiKC,CC9JF,gBACC,mCAAA,CACA,uDAAA,CACA,2IAAA,CAQA,gCAAA,CACA,4BAAA,CACA,gBAAA,CACA,iBDyJC,CCtJF,kBACC,eAAA,CACA,SAAA,CACA,eAAA,CACA,iBD+JC,CCtJD,uGAbD,kBAcE,kBAAA,CACA,4BAAA,CACA,oBAAA,CACA,WDyJE,CACF,CCrJD,sBACC,UDuJA,CCpJD,4BACC,SDsJA,CClJF,kEACC,gBAMC,gHDoJE,CACF,CCxIA,2CACC,sCD0ID,CC3IA,4CACC,sCD6ID,CC9IA,4CACC,sCDgJD,CCjJA,4CACC,sCDmJD,CCpJA,4CACC,sCDsJD,CCvJA,4CACC,sCDyJD,CC1JA,4CACC,sCD4JD,CC7JA,4CACC,sCD+JD,CChKA,4CACC,sCDkKD,CCnKA,6CACC,sCDqKD,CCtKA,6CACC,uCDwKD,CACF,CEhSF,gEACC,yBACC,sBAAA,CACA,eFqSE,CElSH,aACC,aAAA,CACA,aAAA,CACA,sCAAA,CACA,iBFgUE,CE9TF,mBACC,iBFgUC,CE7TF,gBACC,kBAAA,CACA,8CF+TC,CE5TF,yBACC,mBF8TC,CE5TD,gCACC,sDAAA,CACA,UAAA,CACA,oBAAA,CACA,WC0DK,CDzDL,qCAAA,CACA,UF8TA,CE1TF,gBACC,yCF4TC,CEzTF,6CAEC,QAAA,CACA,iBAAA,CACA,yBAAA,CACA,8BF2TC,CEvSF,uBACC,UAAA,CACA,6BAAA,CACA,yFAAA,CACA,mCAAA,CACA,0CAAA,CE5EF,uBAAA,CACA,mDAAA,CACA,uEAAA,CACA,0FAAA,CACA,8GAAA,CACA,yHAAA,CALA,uBAAA,CACA,mDAAA,CACA,uEAAA,CACA,0FAAA,CACA,8GAAA,CACA,yHAAA,CF0EE,6BAAA,CACA,6BAAA,CACA,yqBAAA,CAiBA,6EAAA,CAJA,sDAAA,CACA,wBAAA,CACA,UAAA,CACA,oBAAA,CAMA,8BAAA,CAAA,sBAAA,CACA,6EAAA,CACA,gDAAA,CACA,mBFmTC,CEhTF,gCACC,SFkTC,CE5SD,gCACC,4BF8SA,CE/SD,gCACC,4BFiTA,CElTD,gCACC,6BFoTA,CErTD,gCACC,uBFuTA,CExTD,gCACC,2BF0TA,CE3TD,gCACC,wBF6TA,CE9SF,sBACC,4BAAA,CACA,gEAAA,CACA,mCAAA,CACA,4BAAA,CACA,qBAAA,CACA,UAAA,CACA,6CAAA,CACA,kCAAA,CACA,SAAA,CACA,aAAA,CACA,mBAAA,CAEA,6IAAA,CADA,sCAAA,CAEA,oFFgTC,CE5SF,4BACC,UF8SC,CE5SD,kCACC,SF8SA,CE3SD,2CACC,SAAA,CACA,4IAAA,CACA,oFF6SA,CEtSF,yBACC,SAAA,CACA,0HFwSC,CErSF,wBACC,kFFuSC,CEpSF,kCACC,SFsSC,CElSH,eACC,mHAAA,CAKA,8BAAA,CAAA,sBFoSE,CElSF,wBACC,qCFoSC,CEhSH,kEAEE,8BAMC,uBFiSE,CE9RH,+CACC,2BFgSE,CACF,CACF,CKjeF,4EACC,0BACC,sBL8eE,CK3eH,cACC,gCAAA,CACA,0BAAA,CACA,mCAAA,CACA,4BAAA,CACA,iBAAA,CACA,mFL6eE,CK1eF,oBACC,4CAAA,CACA,sGAAA,CAKA,oBAAA,CAGA,KAAA,CACA,UAAA,CACA,SLweC,CKreF,4CAPC,UAAA,CACA,iBL+eC,CKpeF,6DAEC,+BAAA,CACA,eLseC,CKneF,6BAGC,yiCAAA,CADA,oDAAA,CADA,oBAAA,CAsBA,wBAAA,CACA,UAAA,CACA,iBAAA,CACA,KAAA,CACA,UAAA,CACA,SLqeC,CKleF,kCAEC,eAAA,CACA,eAAA,CACA,iBAAA,CACA,yBLoeC,CKheD,kDACC,8BAAA,CACA,+BAAA,CACA,WAAA,CACA,UAAA,CACA,wBAAA,CACA,qCAAA,CACA,yBAAA,CACA,SAAA,CACA,iBAAA,CACA,8CAAA,CACA,aAAA,CACA,SLkeA,CK9dA,6CACC,SLgeD,CKjeA,6CACC,SLmeD,CKpeA,6CACC,SLseD,CKveA,6CACC,SLyeD,CK1eA,6CACC,SL4eD,CK7eA,6CACC,SL+eD,CKhfA,6CACC,SLkfD,CKnfA,6CACC,SLqfD,CKtfA,8CACC,SLwfD,CKzfA,8CACC,UL2fD,CK5fA,8CACC,UL8fD,CK/fA,8CACC,ULigBD,CK7fD,sCACC,WL+fA,CK3fF,iBACC,gBAAA,CACA,iBAAA,CACA,eLghBC,CK9gBD,wBACC,UAAA,CACA,aAAA,CACA,iBAAA,CACA,0BAAA,CACA,aAAA,CACA,ULghBA,CK1fD,uBACC,4BAAA,CACA,+DAAA,CACA,6IAAA,CASA,4BAAA,CACA,qBAAA,CACA,wBAAA,CACA,UAAA,CACA,uEAAA,CACA,kCAAA,CAGA,0BAAA,CAFA,SAAA,CACA,aAAA,CAEA,mBAAA,CACA,iBAAA,CACA,gBAAA,CAEA,sEAAA,CADA,sCAAA,CAEA,oFAAA,CAEA,eAAA,CACA,SL2fA,CKxfD,0BACC,qDL0fA,CKtfA,oCACC,gBAAA,CACA,iBAAA,CACA,SLwfD,CK3fA,oCACC,gBAAA,CACA,iBAAA,CACA,SL6fD,CKhgBA,oCACC,gBAAA,CACA,iBAAA,CACA,SLkgBD,CKrgBA,oCACC,gBAAA,CACA,iBAAA,CACA,SLugBD,CK1gBA,oCACC,gBAAA,CACA,iBAAA,CACA,SL4gBD,CK/gBA,oCACC,gBAAA,CACA,iBAAA,CACA,SLihBD,CKphBA,oCACC,gBAAA,CACA,iBAAA,CACA,SLshBD,CKzhBA,oCACC,gBAAA,CACA,iBAAA,CACA,SL2hBD,CK9hBA,qCACC,gBAAA,CACA,iBAAA,CACA,SLgiBD,CKniBA,qCACC,iBAAA,CACA,kBAAA,CACA,ULqiBD,CKxiBA,qCACC,iBAAA,CACA,kBAAA,CACA,UL0iBD,CK7iBA,qCACC,iBAAA,CACA,kBAAA,CACA,UL+iBD,CK3iBD,6BACC,SAAA,CACA,qEAAA,CACA,oFL6iBA,CKriBD,+BAEC,soEAAA,CADA,sDAAA,CA+BA,8CLuiBA,CKpiBD,kCACC,sDAAA,CACA,UAAA,CACA,oBAAA,CACA,WAAA,CACA,qCAAA,CACA,ULsiBA,CKliBA,kCACC,WAAA,CACA,+DAAA,CACA,sDAAA,CACA,qBAAA,CACA,iBAAA,CACA,+BAAA,CACA,UAAA,CACA,kBAAA,CACA,0BAAA,CACA,iBAAA,CACA,kBAAA,CACA,kEAAA,CACA,oFAAA,CAEA,iBAAA,CACA,SLmiBD,CKhiBA,qCACC,qDLkiBD,CK9hBC,iDACC,gBAAA,CACA,SLgiBF,CKliBC,iDACC,gBAAA,CACA,SLoiBF,CKtiBC,iDACC,gBAAA,CACA,SLwiBF,CK1iBC,iDACC,gBAAA,CACA,SL4iBF,CK9iBC,iDACC,gBAAA,CACA,SLgjBF,CKljBC,iDACC,gBAAA,CACA,SLojBF,CKtjBC,iDACC,gBAAA,CACA,SLwjBF,CK1jBC,iDACC,gBAAA,CACA,SL4jBF,CK9jBC,kDACC,iBAAA,CACA,ULgkBF,CKlkBC,kDACC,iBAAA,CACA,ULokBF,CKtkBC,kDACC,iBAAA,CACA,ULwkBF,CK/jBD,wCACC,4BLikBA,CKlkBD,wCACC,4BLokBA,CKrkBD,wCACC,6BLukBA,CKxkBD,wCACC,uBL0kBA,CK3kBD,wCACC,2BL6kBA,CK9kBD,wCACC,wBLglBA,CK5kBF,yFAEC,WL8kBC,CK3kBF,qGAEC,SL6kBC,CK1kBF,oDACC,8EL4kBC,CKxkBD,oDACC,uBL0kBA,CKvkBD,0DACC,ULykBA,CKpkBH,kEACC,6BAMC,8DLskBG,CACF,CACF,CMh4BF,6BACC,4BACC,sBNy4BE,CMt4BH,wBACC,YAAA,CACA,mCAAA,CACA,kCAAA,CAEA,0BAAA,CADA,YAAA,CAEA,eHoEM,CGnEN,iBN64BE,CM34BF,sDAEC,QN64BC,CM14BF,+BACC,iBN44BC,CMp4BF,uFAGC,gBNs4BC,CMn4BF,gCACC,2BAAA,CACA,WNq4BC,CMl4BF,2BACC,4BAAA,CACA,yDAAA,CACA,mBAAA,CACA,iBAAA,CACA,8CNo4BC,CMj4BA,yCACC,aNm4BD,CMp4BA,0CACC,aNs4BD,CMv4BA,0CACC,aNy4BD,CM14BA,0CACC,aN44BD,CM74BA,0CACC,aN+4BD,CMh5BA,0CACC,aNk5BD,CMn5BA,0CACC,aNq5BD,CMt5BA,0CACC,aNw5BD,CMz5BA,0CACC,cN25BD,CM55BA,2CACC,cN85BD,CMz5BF,6BAEC,WAAA,CADA,eAAA,CAEA,MAAA,CACA,eAAA,CACA,mBAAA,CACA,iBAAA,CACA,ONk6BC,CMz5BD,uGAhBD,6BAiBE,kBAAA,CACA,4BAAA,CACA,oBAAA,CACA,WN45BE,CACF,CMz5BF,sCACC,qBAAA,CACA,yFN25BC,CMz5BD,+CAEC,aAAA,CADA,cAAA,CAEA,aN25BA,CMx5BD,8CACC,WN05BA,CMv5BD,yCACC,yDAAA,CACA,sIAAA,CAQA,gCNk5BA,CM94BA,wDACC,iCAAA,CACA,+BAAA,CACA,WAAA,CACA,UAAA,CACA,uBAAA,CACA,SAAA,CACA,iBAAA,CAEA,QHlCI,CGiCJ,8CAAA,CAEA,kBAAA,CACA,SNg5BD,CM74BA,8DACC,UN+4BD,CM34BC,qEACC,8CN64BF,CM94BC,qEACC,8CNg5BF,CMj5BC,qEACC,8CNm5BF,CMp5BC,qEACC,8CNs5BF,CMv5BC,qEACC,8CNy5BF,CM15BC,qEACC,8CN45BF,CMp5BA,2DACC,4BNs5BD,CMv5BA,2DACC,4BNy5BD,CM15BA,2DACC,6BN45BD,CM75BA,2DACC,uBN+5BD,CMh6BA,2DACC,2BNk6BD,CMn6BA,2DACC,wBNq6BD,CMj6BD,kEACC,yCAMC,8GNm6BC,CACF,CMx5BF,wCACC,6EAAA,CACA,mGN65BC,CM35BD,6CACC,qBN65BA,CM15BD,iDACC,mBN45BA,CMz5BD,mDAEC,aAAA,CADA,WN45BA,CMx5BC,iEACC,kDN05BF,CM35BC,iEACC,kDN65BF,CM95BC,iEACC,kDNg6BF,CMj6BC,iEACC,mDNm6BF,CMp6BC,iEACC,mDNs6BF,CMj6BD,sDACC,eAAA,CACA,WNm6BA,CMh6BC,oEACC,aNk6BF,CMn6BC,oEACC,aNq6BF,CMt6BC,oEACC,aNw6BF,CMz6BC,oEACC,aN26BF,CM56BC,oEACC,aN86BF,CM/6BC,oEACC,aNi7BF,CMl7BC,oEACC,aNo7BF,CMr7BC,oEACC,aNu7BF,CMx7BC,qEACC,cN07BF,CM37BC,qEACC,cN67BF,CMv7BA,uFACC,iCAAA,CACA,+BAAA,CACA,WAAA,CACA,UAAA,CACA,uBAAA,CACA,WAAA,CACA,iBAAA,CAEA,oBAAA,CADA,8CAAA,CAEA,+CAAA,CACA,SNy7BD,CMr7BC,sFACC,wENu7BF,CMx7BC,sFACC,8EN07BF,CM37BC,sFACC,8EN67BF,CMx7BD,2CACC,wBAAA,CACA,2BAAA,CACA,eN07BA,CMp7BD,6DACC,mCNs7BA,CMn7BD,kEACC,2CACC,uBNq7BC,CMl7BF,6DACC,0BNo7BC,CACF,CACF,COlqCF,kGACC,2BACC,sBPuqCE,COpqCH,uBACC,eAAA,CACA,sBAAA,CACA,uCAAA,CACA,gCAAA,CACA,4BAAA,CACA,wLAAA,CAUA,gBAAA,CACA,iBAAA,CACA,cAAA,CACA,kCAAA,CACA,4BAAA,CACA,sBAAA,CACA,gBAAA,CACA,iBAAA,CACA,2BPsrCE,COprCF,+BACC,eAAA,CACA,aAAA,CACA,iBPsrCC,CO3qCF,mCACC,mCAAA,CACA,QAAA,CACA,QAAA,CACA,cAAA,CACA,iBAAA,CACA,OAAA,CACA,gJP6qCC,COzqCD,yCACC,SP2qCA,CO5qCD,0CACC,SP8qCA,CO/qCD,0CACC,SPirCA,COlrCD,0CACC,SPorCA,COrrCD,0CACC,SPurCA,COxrCD,0CACC,SP0rCA,CO3rCD,0CACC,SP6rCA,COxqCF,0BACC,gCAAA,CACA,+BAAA,CACA,UAAA,CACA,MAAA,CACA,QAAA,CACA,iBAAA,CACA,KAAA,CACA,qEAAA,CACA,0BAAA,CACA,SP0qCC,COvqCA,6CACC,gBAAA,CACA,4DPyqCD,CO3qCA,8CACC,gBAAA,CACA,4DP6qCD,CO/qCA,8CACC,gBAAA,CACA,4DPirCD,COnrCA,8CACC,gBAAA,CACA,4DPqrCD,COvrCA,8CACC,gBAAA,CACA,4DPyrCD,CO3rCA,8CACC,gBAAA,CACA,4DP6rCD,CO/rCA,8CACC,gBAAA,CACA,4DPisCD,CO7rCD,iEAEC,YP8rCA,CO1rCF,4BACC,iCAAA,CAEA,qCAAA,CHpHF,+BAAA,CACA,mEAAA,CACA,+FAAA,CACA,0HAAA,CACA,sJAAA,CACA,iJAAA,CGmHE,oDAAA,CAEA,gDAAA,CACA,6FAAA,CAKA,+DAAA,CAKA,wBAAA,CACA,mCAAA,CACA,WAAA,CACA,iBAAA,CACA,UPyrCC,COzqCF,iCACC,UAAA,CACA,aAAA,CACA,eAAA,CACA,ePsrCC,COlrCD,6CACC,wBAAA,CAEA,2CAAA,CADA,kCPqrCA,COvrCD,8CACC,wBAAA,CAEA,2CAAA,CADA,kCP0rCA,CO5rCD,8CACC,wBAAA,CAEA,2CAAA,CADA,kCP+rCA,COjsCD,8CACC,wBAAA,CAEA,2CAAA,CADA,kCPosCA,COtsCD,8CACC,wBAAA,CAEA,2CAAA,CADA,kCPysCA,CO3sCD,8CACC,wBAAA,CAEA,2CAAA,CADA,kCP8sCA,COhtCD,8CACC,wBAAA,CAEA,2CAAA,CADA,kCPmtCA,CO7sCH,wBACC,mBP+sCE,CO7sCF,8BACC,oBAAA,CACA,qBP+sCC,CO5sCF,oCACC,YAAA,CACA,WAAA,CACA,SJtFM,CIuFN,iBP8sCC,CO5sCD,2CACC,oCAAA,CACA,UAAA,CACA,oBAAA,CACA,WJ7FK,CI8FL,mBAAA,CACA,gCAAA,CACA,UP8sCA,COxsCD,oDACC,uCP0sCA,COtsCF,2BACC,oBAAA,CACA,sCAAA,CACA,YAAA,CACA,wBAAA,CACA,UAAA,CACA,mBAAA,CACA,SPwsCC,COtsCD,iCACC,+BAAA,CACA,aAAA,CACA,eAAA,CACA,eAAA,CACA,kBAAA,CACA,iFAAA,CACA,oBAAA,CAEA,kBAAA,CADA,UPysCA,COpsCA,+CACC,wBAAA,CAEA,sBAAA,CADA,kCAAA,CAEA,sCPssCD,CO1sCA,gDACC,wBAAA,CAEA,sBAAA,CADA,kCAAA,CAEA,sCP4sCD,COhtCA,gDACC,wBAAA,CAEA,sBAAA,CADA,kCAAA,CAEA,sCPktCD,COttCA,gDACC,wBAAA,CAEA,sBAAA,CADA,kCAAA,CAEA,sCPwtCD,CO5tCA,gDACC,wBAAA,CAEA,sBAAA,CADA,kCAAA,CAEA,sCP8tCD,COluCA,gDACC,wBAAA,CAEA,sBAAA,CADA,kCAAA,CAEA,sCPouCD,COxuCA,gDACC,wBAAA,CAEA,sBAAA,CADA,kCAAA,CAEA,sCP0uCD,COruCF,6BACC,oCAAA,CACA,mBPuuCC,COruCD,6DAJD,6BAKE,6DAAA,CACA,8BAAA,CAAA,sBPwuCE,CACF,COruCF,qDACC,2BACC,WAAA,CACA,8CPuuCE,COruCF,iCACC,SAAA,CACA,kBPuuCC,COnuCH,oCACC,SAAA,CACA,SPquCE,COnuCF,0CACC,ePquCC,CACF,CACF,CACF","file":"chaarts.min.css"} \ No newline at end of file diff --git a/docs/accueil.html b/docs/accueil.html index 4ad6ba2..791dadc 100644 --- a/docs/accueil.html +++ b/docs/accueil.html @@ -1,162 +1,164 @@ - - - - - - chaarts - - - - - - - - - - - + + + + + + + chaarts + + + + + + + + + + + - +
- - - - - + + +
- -

Graphiques

- -

- Les différentes versions de graphiques présentées pour le moment reposent uniquement - sur un balisage sémantique — à base de <table> — - et une tartine de variables CSS portées par les balises. - Aucun JavaScript n’est requis pour l’affichage, et les styles sont - améliorés progressivement selon les capacités de votre navigateur. -

- -

- Note : en vertu du caractère expérimental - de ces techniques et d’une fondation solide améliorée progressivement, - je ne précise pas le support navigateur de chaque exemple — mais - il va de soi que ce n’est pas magique, et que seuls les navigateurs modernes répondent à l’appel, - à l’exception notable de Edge - qui ne supporte pas (encore) clip-path. - Les autres navigateurs affichent un tableau correctement stylé, et c’est chouette. -

- -

L’accessibilité

- -

- Un effort conséquent a été porté à l’accessibilité. - Comme évoqué précédement, un balisage sémantique et structuré est un pré-requis - — mais ça ne suffit pas. Les CSS - sont appliqués aussi progressivement que possible, afin de garantir le meilleur affichage - possible des données pour chaque internaute. -

- -

Tableau accessible

- -

Piqure de rappel :

- -
    -
  • un tableau doit démarrer par un <caption> ;
  • -
  • - les cellules d’en-tête <th> doivent porter un attribut scope, - avec une valeur row ou col selon le cas ; -
  • -
  • - et vous aurez généralement besoin de distinguer l’entête du corps grâce à - <thead> et <tbody> ; -
  • -
  • - pour les valeurs disposant d’une unité : si vous vous aventurez à utiliser l’élement - <abbr> pour utiliser sa version abrégée, pensez à doubler l’attribut - title avec l’attribut aria-label — cela en améliorera - considérablement l’intérêt pour de nombreux internautes. -
  • -
- -

- Pour d’autres astuces utiles, je vous recommande chaleureusement la lecture - du - composant inclusif Data Tables de Heydon Pickering, - qui est une véritable mine d’or. -

- -

Motifs

-

- Pour distinguer les différentes zones autrement que par la couleur, un motif - svg - est appliqué en - css - — vous en trouverez quelques-uns sur le site - Hero Patterns : -

-
    -
  1. - afin d’améliorer le mélange avec les couleurs ou dégradés d’arrière-plan, la propriété - background-blend-mode est utilisée avec la valeur hard-light ; -
  2. -
  3. - les tailles et positions du motif dépendent directement de la valeur et de l’échelle du graphique, - selon le type de graphique ; -
  4. -
  5. - pour ne pas embarquer trop de fichiers externes, on utilise - une technique - proposée par Trys Mudford pour inclure nos - svg - en data URi dans une variable - css chacun ; - ainsi, une liste finie de motifs est utilisée dans le thème, sans jamais répéter le svg. -
  6. -
- -
-

Qu’encoder ?

-

- Taylor Hunt - a rédigé un article complet sur l’optimisation des - svg - passés en data URi. En résumé, seuls les chevrons et le - caractère « # » ont besoin d’être encodés dans le - css. - Ne vous fatiguez pas avec les autres caractères, leur encodage nuit sérieusement à la lisibilité. -

-
- -
.chaarts {
+	

Graphiques

+ +

+ Les différentes versions de graphiques présentées pour le moment reposent uniquement + sur un balisage sémantique — à base de <table> — + et une tartine de variables CSS portées par les balises. + Aucun JavaScript n’est requis pour l’affichage, et les styles sont + améliorés progressivement selon les capacités de votre navigateur. +

+ +

+ Note : en vertu du caractère expérimental + de ces techniques et d’une fondation solide améliorée progressivement, + je ne précise pas le support navigateur de chaque exemple — mais + il va de soi que ce n’est pas magique, et que seuls les navigateurs modernes répondent à l’appel, + à l’exception notable de Edge + qui ne supporte pas (encore) clip-path. + Les autres navigateurs affichent un tableau correctement stylé, et c’est chouette. +

+ +

L’accessibilité

+ +

+ Un effort conséquent a été porté à l’accessibilité. + Comme évoqué précédement, un balisage sémantique et structuré est un pré-requis + — mais ça ne suffit pas. Les CSS + sont appliqués aussi progressivement que possible, afin de garantir le meilleur affichage + possible des données pour chaque internaute. +

+ +

Tableau accessible

+ +

Piqure de rappel :

+ +
    +
  • un tableau doit démarrer par un <caption> ;
  • +
  • + les cellules d’en-tête <th> doivent porter un attribut scope, + avec une valeur row ou col selon le cas ; +
  • +
  • + et vous aurez généralement besoin de distinguer l’entête du corps grâce à + <thead> et <tbody> ; +
  • +
  • + pour les valeurs disposant d’une unité : si vous vous aventurez à utiliser l’élement + <abbr> pour utiliser sa version abrégée, pensez à doubler l’attribut + title avec l’attribut aria-label — cela en améliorera + considérablement l’intérêt pour de nombreux internautes. +
  • +
+ +

+ Pour d’autres astuces utiles, je vous recommande chaleureusement la lecture + du + composant inclusif Data Tables de Heydon Pickering, + qui est une véritable mine d’or. +

+ +

Motifs

+

+ Pour distinguer les différentes zones autrement que par la couleur, un motif + svg + est appliqué en + css + — vous en trouverez quelques-uns sur le site + Hero Patterns : +

+
    +
  1. + afin d’améliorer le mélange avec les couleurs ou dégradés d’arrière-plan, la propriété + background-blend-mode est utilisée avec la valeur hard-light ; +
  2. +
  3. + les tailles et positions du motif dépendent directement de la valeur et de l’échelle du + graphique, + selon le type de graphique ; +
  4. +
  5. + pour ne pas embarquer trop de fichiers externes, on utilise + une technique + proposée par Trys Mudford pour inclure nos + svg + en data URi dans une variable + css chacun ; + ainsi, une liste finie de motifs est utilisée dans le thème, sans jamais répéter le svg. +
  6. +
+ +
+

Qu’encoder ?

+

+ Taylor Hunt + a rédigé un article complet sur l’optimisation des + svg + passés en data URi. En résumé, seuls les chevrons et le + caractère « # » ont besoin d’être encodés dans le + css. + Ne vous fatiguez pas avec les autres caractères, leur encodage nuit sérieusement à la lisibilité. +

+
+ +
.chaarts {
   --stripes: url("data:image/svg+xml,%3Csvg width='6' height='6' viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff99' fill-rule='evenodd'%3E%3Cpath d='M5 0h1L0 6V5zM6 5v1H5z'/%3E%3C/g%3E%3C/svg%3E");
 }
 
@@ -173,54 +175,56 @@ 

Qu’encoder ?

background-blend-mode: hard-light; }
- -

Respect des préférences

-

- Afin de respecter autant que possible les préférences des visiteurs, - de nombreux éléments ont été adaptés : -

-
    -
  1. - les dimensions sont en unités relatives (em ou rem selon les cas), - afin de s’ajuster de manière cohérente au corps de texte hérité du navigateur et de pouvoir - être agrandi ou réduit sans perte ; -
  2. -
  3. - les couleurs sont adaptées lorsque le mode de contrastes élevés de Windows est détecté à l’aide de - -ms-high-contrast: active, inspiré par - - l’article de Greg Whitworth sur le sujet. Je vous conseille d’ailleurs - - l’increvable page Test of System Colors Specified in CSS 2 rédigée - par Ian Graham, éditée en… 2000 ! -
  4. -
  5. - les animations et transitions sont désactivées lorsque le système - expose cette préférence grâce à prefers-reduced-motion: reduce ; -
  6. -
  7. - les effets de survol dont l’état initial consiste à masquer du contenu - sont activés contextuellement dans la requête média @media (hover: hover) { … }. -
  8. -
- -

display et sémantique

-

- Adrian Roselli explique que jouer avec le display d’un élément - <table> ou <dl> met en péril sa sémantique. - Cette dernière est donc « verrouillée » à l’aide des rôles - aria - dédiés — comme il l’explique - dans un article détaillé. -

-

- C’est pourquoi chaque tableau est précédé d’un interrupteur — basé sur - le composant inclusif - conçu par Heydon Pickering — - dont le seul et unique rôle est de désactiver les styles supplémentaires : -

- -
document.addEventListener("DOMContentLoaded", function() {
+	

Respect des préférences

+

+ Afin de respecter autant que possible les préférences des visiteurs, + de nombreux éléments ont été adaptés : +

+
    +
  1. + les dimensions sont en unités relatives (em ou rem selon les cas), + afin de s’ajuster de manière cohérente au corps de texte hérité du navigateur et de pouvoir + être agrandi ou réduit sans perte ; +
  2. +
  3. + les couleurs sont adaptées lorsque le mode de contrastes élevés de Windows est détecté à l’aide + de + -ms-high-contrast: active, inspiré par + + l’article de Greg Whitworth sur le sujet. Je vous conseille d’ailleurs + + l’increvable page Test of System Colors Specified in CSS 2 rédigée + par Ian Graham, éditée en… 2000 ! +
  4. +
  5. + les animations et transitions sont désactivées lorsque le système + expose cette préférence grâce à prefers-reduced-motion: reduce ; +
  6. +
  7. + les effets de survol dont l’état initial consiste à masquer du contenu + sont activés contextuellement dans la requête média @media (hover: hover) { … }. +
  8. +
+ +

display et sémantique

+

+ Adrian Roselli explique que jouer avec le display d’un élément + <table> ou <dl> met en péril sa sémantique. + Cette dernière est donc « verrouillée » à l’aide des rôles + aria + dédiés — comme il l’explique + dans un article + détaillé. +

+

+ C’est pourquoi chaque tableau est précédé d’un interrupteur — basé sur + le composant inclusif + conçu par Heydon Pickering — + dont le seul et unique rôle est de désactiver les styles supplémentaires : +

+ +
document.addEventListener("DOMContentLoaded", function() {
   var switches = document.querySelectorAll('[role="switch"]');
 
   Array.prototype.forEach.call(switches, function(el, i) {
@@ -234,21 +238,14 @@ 

display et sémantique

}); });
- -

- Voilà, nous sommes prêts à entrer dans le vif du sujet.
- Faites chauffer votre inspecteur ! -

- +

+ Voilà, nous sommes prêts à entrer dans le vif du sujet.
+ Faites chauffer votre inspecteur ! +

+ + - - - - - - - - - \ No newline at end of file + + diff --git a/docs/bar-charts.html b/docs/bar-charts.html index da97115..1eac56a 100644 --- a/docs/bar-charts.html +++ b/docs/bar-charts.html @@ -1,222 +1,216 @@ - - - - - - Bar charts — chaarts - - - - - - - - - - - + + + + + + + Bar charts — chaarts + + + + + + + + + + + - +
- - - - - + + +
- -

Bar charts

- -

- This type of graph is used to represent one-dimensional data - (in our example, a timeline). - It's based on CSS grids and custom properties, - a technique inspired by - an article by Miriam Suzanne on - CSS Tricks - with a slight enhancement to improve accessibility. - Here's how to use it: -

- -
    -
  1. - On the table itself, the --scale custom property is used to define the maximum value for the graph, - in order to determine its scale. Concretely, a grid will be generated with: - -
  2. -
  3. - On each cell <td>, a --value custom property - allows to place it on the grid, applied to grid-column-end. - Moreover, thanks to clever calculations based on this value, the background gradient is sized - and positioned to reflect the proportion represented by this value on the given scale - (from green for almost nothing to red for almost everything). -
  4. -
  5. - In each cell, the content must include the value and its unit in a - <span> element, possibly tagged with <abbr> - (and aria-label to complement title) if a title can explicit the unit. - This value is pushed to the right of the grid, and its text serves as a mask for the background - gradient — thanks to S. Shaw's trick to - apply background-clip: text as a progressively enhancement — allowing it to be the - corresponding color at the end of the gradient for the given position. -
  6. -
- - -
-
-

- Switch
- Allows you to disable styles on the following table. -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Loading time for ffoodd.fr
Cumulative loading time
Time: backend - ms -
Time: Frontend - 96 ms -
Delay: first byte - 102 ms -
Delay: last byte - 129 ms -
Delay: first image - 188 ms -
Delay: first CSS - 194 ms -
Delay: first JS - 326 ms -
DOM Interactive - 836 ms -
DOM loading - 836 ms -
DOM complete - 2561 ms -
HTTP traffic completed - 2980 ms -
-
- -
- HTML -
<table class="chaarts bar" style="--scale: 3000">
+	

Bar charts

+ +

+ This type of graph is used to represent one-dimensional data + (in our example, a timeline). + It's based on CSS grids and custom properties, + a technique inspired by + an article by Miriam Suzanne on + CSS Tricks + with a slight enhancement to improve accessibility. + Here's how to use it: +

+ +
    +
  1. + On the table itself, the --scale custom property is used to define the maximum value + for the graph, + in order to determine its scale. Concretely, a grid will be generated with: + +
  2. +
  3. + On each cell <td>, a --value custom property + allows to place it on the grid, applied to grid-column-end. + Moreover, thanks to clever calculations based on this value, the background gradient is sized + and positioned to reflect the proportion represented by this value on the given scale + (from green for almost nothing to red for almost everything). +
  4. +
  5. + In each cell, the content must include the value and its unit in a + <span> element, possibly tagged with <abbr> + (and aria-label to complement title) if a title can explicit the unit. + This value is pushed to the right of the grid, and its text serves as a mask for the background + gradient — thanks to S. Shaw's trick to + apply background-clip: text as a progressively enhancement — allowing it to be the + corresponding color at the end of the gradient for the given position. +
  6. +
+ +
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Loading time for ffoodd.fr
Cumulative loading time
Time: backend + ms +
Time: Frontend + 96 ms +
Delay: first byte + 102 ms +
Delay: last byte + 129 ms +
Delay: first image + 188 ms +
Delay: first CSS + 194 ms +
Delay: first JS + 326 ms +
DOM Interactive + 836 ms +
DOM loading + 836 ms +
DOM complete + 2561 ms +
HTTP traffic completed + 2980 ms +
+
+ +
+ HTML +
<table class="chaarts bar" style="--scale: 3000">
   <caption id="caption-1">[…]</caption>
   <thead class="sr-only">
     <tr>
@@ -235,10 +229,10 @@ 

Bar charts

</tbody> </table>
-
-
- css -
@supports (grid-template-columns: repeat( var(--scale, 100), minmax(0, 1fr) )) {
+	
+
+ css +
@supports (grid-template-columns: repeat( var(--scale, 100), minmax(0, 1fr) )) {
   .chaarts.bar caption {
     text-align: initial;
     text-indent: 13.5rem;
@@ -322,154 +316,141 @@ 

Bar charts

} }
-
- -

Waterfall

- -

- The principle is the same for this variant, except for one detail: we also manage - the starting point for each measurement - — which is, very simply, the value of the previous point… - However, all the values must be passed as variables on the parent <table>. -

- -
-
-

- Switch
- Allows you to disable styles on the following table. -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Loading time for ffoodd.fr
Cumulative loading time
Time: backend - ms -
Time: Frontend - 96 ms -
Delay: first byte - 102 ms -
Delay: last byte - 129 ms -
Delay: first image - 188 ms -
Delay: first CSS - 194 ms -
Delay: first JS - 326 ms -
DOM interactive - 836 ms -
DOM loading - 836 ms -
DOM complete - 2561 ms -
HTTP traffic completed - 2980 ms -
-
- -
- HTML -
<table class="chaarts bar waterfall"
+	
+ +

Waterfall

+ +

+ The principle is the same for this variant, except for one detail: we also manage + the starting point for each measurement + — which is, very simply, the value of the previous point… + However, all the values must be passed as variables on the parent <table>. +

+ +
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Loading time for ffoodd.fr
Cumulative loading time
Time: backend + ms +
Time: Frontend + 96 ms +
Delay: first byte + 102 ms +
Delay: last byte + 129 ms +
Delay: first image + 188 ms +
Delay: first CSS + 194 ms +
Delay: first JS + 326 ms +
DOM interactive + 836 ms +
DOM loading + 836 ms +
DOM complete + 2561 ms +
HTTP traffic completed + 2980 ms +
+
+ +
+ HTML +
<table class="chaarts bar waterfall"
  style="--scale: 3000; --1: 4; --2: 96; --3: 102; --4: 129; --5: 188; --6: 194; --7: 326; --8: 836; --9: 836; --10: 2561; --11: 2980;">
 </table>
-
-
- css -
.bar.waterfall tr:nth-of-type(2) td {
+	
+
+ css +
.bar.waterfall tr:nth-of-type(2) td {
   grid-column: var(--1, 0) / var(--value, 0);
 }
-
- +
+ + - - - - - - - - - \ No newline at end of file + + diff --git a/docs/barres.html b/docs/barres.html index 0eaa784..fbbfafe 100644 --- a/docs/barres.html +++ b/docs/barres.html @@ -1,220 +1,224 @@ - - - - - - Graphiques en barre — chaarts - - - - - - - - - - - + + + + + + + Graphiques en barre — chaarts + + + + + + + + + + + - +
- - - - - + + +
- -

Graphique en barre

- -

- Ce type de graphique sert à représenter des données à une dimension - (dans notre exemple, une ligne de temps). - Il repose sur les grilles et les variables CSS, - technique inspirée - d’un article de Miriam Suzanne sur - CSS Tricks - légèrement agrémentée pour en améliorer l’accessibilité. - Pour vous en servir, c’est simple : -

- -
    -
  1. - Sur le tableau, une variable --scale permet de définir la valeur maximale du graphique, - afin d’en déterminer l’échelle. Concrètement, une grille va être générée avec : - -
  2. -
  3. - Sur chaque cellule <td>, une variable --value permet de la placer sur la grille, - appliquée à grid-column-end. - De plus grâce à de savants calculs reposant sur cette valeur, le dégradé en arrière-plan est dimensionné et positionné de façon à - refléter la proportion représentée par cette valeur sur l’échelle donnée (du vert pour presque rien au rouge pour presque tout). -
  4. -
  5. - Dans chaque cellule, le contenu doit reprendre la valeur et son unité dans un élément <span>, éventuellement - balisée avec <abbr> (et aria-label pour suppléer title) si un intitulé peut être explicité pour l’unité. - Cette valeur est poussée à droite de la grille, et son texte sert de masque pour le dégradé en arrière-plan - — grâce à une astuce de S. Shaw's pour - appliquer background-clip: text en amélioration progressive — lui permettant d’être de la couleur correspondante - à la fin du dégradé pour la position donnée. -
  6. -
- - -
-
-

- Interrupteur
- Permet de désactiver les styles sur le tableau suivant. -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Temps de chargement pour ffoodd.fr
Temps de chargement cumulé
Temps : backend - ms -
Temps : Frontend - 96 ms -
Délai : premier octet - 102 ms -
Délai : dernier octet - 129 ms -
Délai : première image - 188 ms -
Délai : premier CSS - 194 ms -
Délai : premier JS - 326 ms -
DOM Interactif - 836 ms -
Chargement du DOM - 836 ms -
DOM complet - 2561 ms -
Trafic HTTP terminé - 2980 ms -
-
- -
- Le HTML -
<table class="chaarts bar" style="--scale: 3000">
+	

Graphique en barre

+ +

+ Ce type de graphique sert à représenter des données à une dimension + (dans notre exemple, une ligne de temps). + Il repose sur les grilles et les variables CSS, + technique inspirée + d’un article de Miriam + Suzanne sur + CSS Tricks + légèrement agrémentée pour en améliorer l’accessibilité. + Pour vous en servir, c’est simple : +

+ +
    +
  1. + Sur le tableau, une variable --scale permet de définir la valeur maximale du + graphique, + afin d’en déterminer l’échelle. Concrètement, une grille va être générée avec : + +
  2. +
  3. + Sur chaque cellule <td>, une variable --value permet de la placer + sur la grille, + appliquée à grid-column-end. + De plus grâce à de savants calculs reposant sur cette valeur, le dégradé en arrière-plan est dimensionné et + positionné de façon à + refléter la proportion représentée par cette valeur sur l’échelle donnée (du vert pour presque rien au rouge pour + presque tout). +
  4. +
  5. + Dans chaque cellule, le contenu doit reprendre la valeur et son unité dans un élément <span>, + éventuellement + balisée avec <abbr> (et aria-label pour suppléer title) si un + intitulé peut être explicité pour l’unité. + Cette valeur est poussée à droite de la grille, et son texte sert de masque pour le dégradé en arrière-plan + — grâce à une astuce de S. + Shaw's pour + appliquer background-clip: text en amélioration progressive — lui permettant d’être de la + couleur correspondante + à la fin du dégradé pour la position donnée. +
  6. +
+ +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Temps de chargement pour ffoodd.fr
Temps de chargement cumulé
Temps : backend + ms +
Temps : Frontend + 96 ms +
Délai : premier octet + 102 ms +
Délai : dernier octet + 129 ms +
Délai : première image + 188 ms +
Délai : premier CSS + 194 ms +
Délai : premier JS + 326 ms +
DOM Interactif + 836 ms +
Chargement du DOM + 836 ms +
DOM complet + 2561 ms +
Trafic HTTP terminé + 2980 ms +
+
+ +
+ Le HTML + +
<table class="chaarts bar" style="--scale: 3000">
   <caption id="caption-1">[…]</caption>
   <thead class="sr-only">
     <tr>
@@ -233,10 +237,10 @@ 

Graphique en barre

</tbody> </table>
-
-
- Le css -
@supports (grid-template-columns: repeat( var(--scale, 100), minmax(0, 1fr) )) {
+	
+
+ Le css +
@supports (grid-template-columns: repeat( var(--scale, 100), minmax(0, 1fr) )) {
   .chaarts.bar caption {
     text-align: initial;
     text-indent: 13.5rem;
@@ -320,155 +324,143 @@ 

Graphique en barre

} }
-
- -

Graphique en chute d’eau

- -

- Le principe est le même pour cette variante, à un détail près : - on gère également le point de départ pour chaque mesure - — qui est, très simplement, la valeur du point précédent… - Il faut cependant passer toutes les valeurs en tant que variables sur - le parent <table>. -

- -
-
-

- Interrupteur
- Permet de désactiver les styles sur le tableau suivant. -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Temps de chargement pour ffoodd.fr
Temps de chargement cumulé
Temps : backend - ms -
Temps : Frontend - 96 ms -
Délai : premier octet - 102 ms -
Délai : dernier octet - 129 ms -
Délai : première image - 188 ms -
Délai : premier CSS - 194 ms -
Délai : premier JS - 326 ms -
DOM Interactif - 836 ms -
Chargement du DOM - 836 ms -
DOM complet - 2561 ms -
Trafic HTTP terminé - 2980 ms -
-
- -
- Le HTML -
<table class="chaarts bar waterfall"
+	
+ +

Graphique en chute d’eau

+ +

+ Le principe est le même pour cette variante, à un détail près : + on gère également le point de départ pour chaque mesure + — qui est, très simplement, la valeur du point précédent… + Il faut cependant passer toutes les valeurs en tant que variables sur + le parent <table>. +

+ +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Temps de chargement pour ffoodd.fr
Temps de chargement cumulé
Temps : backend + ms +
Temps : Frontend + 96 ms +
Délai : premier octet + 102 ms +
Délai : dernier octet + 129 ms +
Délai : première image + 188 ms +
Délai : premier CSS + 194 ms +
Délai : premier JS + 326 ms +
DOM Interactif + 836 ms +
Chargement du DOM + 836 ms +
DOM complet + 2561 ms +
Trafic HTTP terminé + 2980 ms +
+
+ +
+ Le HTML + +
<table class="chaarts bar waterfall"
  style="--scale: 3000; --1: 4; --2: 96; --3: 102; --4: 129; --5: 188; --6: 194; --7: 326; --8: 836; --9: 836; --10: 2561; --11: 2980;">
 </table>
-
-
- Le css -
.bar.waterfall tr:nth-of-type(2) td {
+	
+
+ Le css +
.bar.waterfall tr:nth-of-type(2) td {
   grid-column: var(--1, 0) / var(--value, 0);
 }
-
- +
+ + - - - - - - - - - \ No newline at end of file + + diff --git a/docs/camembert.html b/docs/camembert.html index 8e40f86..e8cda81 100644 --- a/docs/camembert.html +++ b/docs/camembert.html @@ -1,273 +1,255 @@ - - - - - -Camemberts — chaarts - - - - - - - - - - - + + + + + + + Camemberts — chaarts + + + + + + + + + + + - +
- - - - - + + +
- -

Graphique en tarte

- -

- Le graphique en tarte sert pour les représentations de proportions en pourcentage. - Il s’appuie sur des variables CSS, un abus outrancier de calc(), - display: table-*, clip-path, mask-image, - transform et un tantinet de SVG - pour distinguer chaque zone. Oui, je sais rigoler. Comment qu’on s’en sert ? -

- -
    -
  1. - Sur chaque entête <th>, une variable --color - permet d’attribuer, et bien… une couleur. -
  2. -
  3. - Puis chaque cellule <td> doit contenir la valeur et son unité, - ainsi qu’un attribut style pour porter quelques variables : -
      -
    1. - --value correspond à la valeur en pourcentage, - utile pour déterminer l’angle que doit occuper l’élément sur le cercle. - Tous les points du polygon() — servant à tracer la part du fromage - à l’aide de clip-path — dépendent de cette valeur (lire la note technique après l’exemple pour le détail - des calculs). -
    2. -
    3. - --start permet de définir le point de départ de l’arc - sur le cercle. Il s’agit de la somme des précédentes définitions, et est appliqué - à la fonction rotate() de la propriété transform. -
    4. -
    5. - Et enfin une série de variables booléennes valant chacune 0 ou 1 - — d’après une idée de - Roman Komarov dans son article "Conditions for CSS variables" — - dépendent de la valeur : --lt-25, --gt-25, --lt-50… - Elles permettent de faire basculer les points de leur position d’origine - (50% 50%) à leur position calculée, en s’additionnant ou se soustrayant - à la valeur initiale ; -
    6. -
    -
  4. -
  5. - un pseudo-élément ::before sur chaque cellule <td> est mis en forme - de savante manière en fonction de toutes nos variables, avec notamment transform, - clip-path et mask-image. - -
  6. -
  7. - un pseudo-élément ::after est utilisé pour simuler une infobulle, récapitulant - l’entête et la valeur de la cellule — l’affichage de propriétés personnalisées dans un pseudo-élément n’est pas si triviale : - -
  8. -
  9. - Et finalement un motif est appliqué sur l’arrière-plan, afin de mieux - l’associer visuellement avec la légende correspondante. -
  10. -
- - - -
-
-

- Interrupteur
- Permet de désactiver les styles sur le tableau suivant. -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Répartition du poids des ressources pour ffoodd.fr
RessourceProportion
HTML - 2 % -
CSS - 2 % -
JS - 32 % -
Json - 1 % -
Images - 44 % -
Webfonts - 17 % -
Autres - 2 % -
-
- -
- Un peu de trigonométrie -
-

- Dans ce graphique, chaque portion représente un arc de cercle basé sur un angle (une partie de 360 degrés). - Pour définir la forme de cette portion, il faut donc placer un point sur le cercle. -

-

- Pour ce faire, je divise le cercle en quatre carrés. La position du point sur le cercle peut ainsi - être calculée en utilisant les propriétés du triangle rectangle formé par : -

-
    -
  1. le centre du cercle,
  2. -
  3. le point que nous cherchons à positionner,
  4. -
  5. et le point perpendiculaire au rayon et passant par notre point cible.
  6. -
-

- Nous connaissons l’hypoténuse de ce triangle — le rayon du cercle —, - et l’angle formé par l’hypoténuse et partant du centre du cercle - (en ramenant la valeur sur 90 degrés, puisque le cercle est divisé en quatre secteurs carrés : - si la valeur est supérieure à 25 : moins 90°, etc.) - — plus un angle droit, bien entendu. -

-

La loi des sinus

-

- Nous pouvons donc utiliser la loi des sinus pour mesurer chaque côté, - et ainsi obtenir la position du point sur le cercle. - Cela implique de calculer le sinus… Fort heureusement, - Stereokai a implémenté pour nous - la représentation polynomiale de Taylor/Maclaurin en CSS — que j’ai implémentée sour forme d’un mixin : -

-
@mixin sin($angle) {
+	

Graphique en tarte

+ +

+ Le graphique en tarte sert pour les représentations de proportions en pourcentage. + Il s’appuie sur des variables CSS, un abus outrancier de calc(), + display: table-*, clip-path, mask-image, + transform et un tantinet de SVG + pour distinguer chaque zone. Oui, je sais rigoler. Comment qu’on s’en sert ? +

+ +
    +
  1. + Sur chaque entête <th>, une variable --color + permet d’attribuer, et bien… une couleur. +
  2. +
  3. + Puis chaque cellule <td> doit contenir la valeur et son unité, + ainsi qu’un attribut style pour porter quelques variables : +
      +
    1. + --value correspond à la valeur en pourcentage, + utile pour déterminer l’angle que doit occuper l’élément sur le cercle. + Tous les points du polygon() — servant à tracer la part du fromage + à l’aide de clip-path — dépendent de cette valeur (lire la note + technique après l’exemple pour le détail + des calculs). +
    2. +
    3. + --start permet de définir le point de départ de l’arc + sur le cercle. Il s’agit de la somme des précédentes définitions, et est appliqué + à la fonction rotate() de la propriété transform. +
    4. +
    5. + Et enfin une série de variables booléennes valant chacune 0 ou 1 + — d’après une idée de + Roman Komarov dans son article "Conditions for CSS variables" — + dépendent de la valeur : --lt-25, --gt-25, --lt-50… + Elles permettent de faire basculer les points de leur position d’origine + (50% 50%) à leur position calculée, en s’additionnant ou se soustrayant + à la valeur initiale ; +
    6. +
    +
  4. +
  5. + un pseudo-élément ::before sur chaque cellule <td> est mis en + forme + de savante manière en fonction de toutes nos variables, avec notamment transform, + clip-path et mask-image. + +
  6. +
  7. + un pseudo-élément ::after est utilisé pour simuler une infobulle, récapitulant + l’entête et la valeur de la cellule — l’affichage de propriétés personnalisées dans un pseudo-élément n’est + pas si triviale : + +
  8. +
  9. + Et finalement un motif est appliqué sur l’arrière-plan, afin de mieux + l’associer visuellement avec la légende correspondante. +
  10. +
+ + +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Répartition du poids des ressources pour ffoodd.fr +
RessourceProportion
HTML + 2 %
CSS + 2 %
JS + 32 %
Json + 1 %
Images + 44 %
Webfonts + 17 %
Autres + 2 %
+
+ +
+ Un peu de trigonométrie +
+

+ Dans ce graphique, chaque portion représente un arc de cercle basé sur un angle (une partie de 360 degrés). + Pour définir la forme de cette portion, il faut donc placer un point sur le cercle. +

+

+ Pour ce faire, je divise le cercle en quatre carrés. La position du point sur le cercle peut ainsi + être calculée en utilisant les propriétés du triangle rectangle formé par : +

+
    +
  1. le centre du cercle,
  2. +
  3. le point que nous cherchons à positionner,
  4. +
  5. et le point perpendiculaire au rayon et passant par notre point cible.
  6. +
+

+ Nous connaissons l’hypoténuse de ce triangle — le rayon du cercle —, + et l’angle formé par l’hypoténuse et partant du centre du cercle + (en ramenant la valeur sur 90 degrés, puisque le cercle est divisé en quatre secteurs carrés : + si la valeur est supérieure à 25 : moins 90°, etc.) + — plus un angle droit, bien entendu. +

+

La loi des sinus

+

+ Nous pouvons donc utiliser la loi + des sinus pour mesurer chaque côté, + et ainsi obtenir la position du point sur le cercle. + Cela implique de calculer le sinus… Fort heureusement, + Stereokai a implémenté pour nous + la représentation polynomiale de Taylor/Maclaurin en CSS — que j’ai implémentée sour forme d’un mixin : +

+
@mixin sin($angle) {
   --sin-term-#{$angle}-1: var(--#{$angle});
   --sin-term-#{$angle}-2: calc((var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle})) / 6);
   --sin-term-#{$angle}-3: calc((var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle})) / 120);
@@ -275,15 +257,16 @@ 

La loi des sinus

--sin-term-#{$angle}-5: calc((var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle})) / 362880); --sin-#{$angle}: calc(var(--sin-term-#{$angle}-1) - var(--sin-term-#{$angle}-2) + var(--sin-term-#{$angle}-3) - var(--sin-term-#{$angle}-4) + var(--sin-term-#{$angle}-5)); }
- -

- Il ne reste plus qu’à utiliser ces dimensions pour placer les points du polygône. - Un vrai jeu d’enfants ! -

-
-
- Le HTML -
<table class="chaarts pie">
+			

+ Il ne reste plus qu’à utiliser ces dimensions pour placer les points du polygône. + Un vrai jeu d’enfants ! +

+
+
+
+ Le HTML + +
<table class="chaarts pie">
   <caption id="caption-5">[…]</caption>
   <thead class="sr-only">
     <tr>
@@ -300,11 +283,12 @@ 

La loi des sinus

</tbody> </table>
-
-
- Le css -
-
   
+	
+
+ Le css +
+
+   
 @supports (clip-path: polygon( 50% calc( 50% + ( var(--gt-25, 0) ) ) )) {
  .chaarts.pie {
    --radius: 32em;
@@ -476,92 +460,95 @@ 

La loi des sinus

} }
-
-
-
- Le calcul tordu -

Les positions du polygone

-

- L’utilisation de variables pseudo-booléennes rend ce calcul pseudo-algorithmique. - Démarrons par un pré-requis essentiel : le polygone étant un tracé fermé et CSS - n’étant pas magique, les points doivent pré-exister. - Spoiler, il nous faut onze points : -

-
    -
  1. - L’axe initial, du centre vers le milieu en haut : 50% 50% - et 50% 0%. -
  2. -
  3. - Un point pour chaque angle aux extrémités : le premier est fixe, à - 100% 0% (en haut à droite) — puis chacun des autres angles - a deux états, atteint ou non. Quelques détails : -
      -
    • - Par exemple le point en bas à droite concerne - les valeurs entre 25% et 50% : si la valeur est inférieure à 25%, il doit - être au centre (pour ne pas gêner le tracé), et dans le cas contraire être - dans son coin. ce qui s’exprime ainsi : - calc( 50% + ( var(--gt-25, 0) * 50% ) ) calc( 50% + ( var(--gt-25, 0) * 50% ) )
      - Ainsi la valeur calculée sera 50% 50% si --gt-25 vaut 0, - et 100% 100% si --gt-25 vaut 1. -
    • -
    • - De plus, chaque angle a sa coordonnée cible : - 100% 100% pour en bas à droite, 0% 100% pour en bas à gauche, - 0% 0% pour en haut à gauche. Il faut donc tantôt soustraire et - tantôt ajouter 50% à la valeur intitiale 50% 50% - pour basculer sur le bon point. -
    • -
    -
  4. -
  5. - Un point pour chaque position possible par quart de cercle, correspondant à - chaque tranche de 25%. À l’instar des points aux angles, ces points doivent être au centre - s’ils ne sont pas utilisés. C’est là qu’on rigole le plus : -
      -
    • on part de 50%, auxquels on ajoute ou soustrait la suite du calcul ;
    • -
    • - on utilise enfin la position calculée — --pos-A - ou --pos-B selon le cas — qu’on convertit en pourcentages à l’aide de - * 1%, et qu’on rend inerte si la valeur est inférieure à la tranche concernée - grâce à * var(--lt-25, 1), par exemple.
      - - Remarquez le seconde valeur dans var(), qui est la valeur par défaut - si la variable n’est pas définie. Cool, non ? - -
    • -
    • - et finalement lorsque la tranche est dépassée, le point bascule vers - 0% ou 100% selon le cas. -
    • -
    -
  6. -
  7. - Et enfin, on referme le tracé en revenant au centre du cercle, - à 50% 50%. -
  8. -
-

C’est tout !

-

Les positions illustrées

-

- Ces captures d’écran — effectuées dans - l’éditeur de formes - des outils de développement de Firefox — - montrent les points du polygone dans les différents cas. Vous pouvez consulter pour chaque valeur citée - le polygone résolu pour clip-path — et constater le basculement des valeurs dynamiques d’une position à une autre. -

-
    -
  • -
    -
    Exemple de rendu pour 44%
    -
    -
    - Tracé pour clip-path avec une valeur de 44% : six points visibles. -
    Capture d’écran du tracé pour 44%.
    -
    -
    -
    td[style*="--value: 44;"]::before {
    +		
    +
+
+ Le calcul tordu +

Les positions du polygone

+

+ L’utilisation de variables pseudo-booléennes rend ce calcul pseudo-algorithmique. + Démarrons par un pré-requis essentiel : le polygone étant un tracé fermé et CSS + n’étant pas magique, les points doivent pré-exister. + Spoiler, il nous faut onze points : +

+
    +
  1. + L’axe initial, du centre vers le milieu en haut : 50% 50% + et 50% 0%. +
  2. +
  3. + Un point pour chaque angle aux extrémités : le premier est fixe, à + 100% 0% (en haut à droite) — puis chacun des autres angles + a deux états, atteint ou non. Quelques détails : +
      +
    • + Par exemple le point en bas à droite concerne + les valeurs entre 25% et 50% : si la valeur est inférieure à 25%, il doit + être au centre (pour ne pas gêner le tracé), et dans le cas contraire être + dans son coin. ce qui s’exprime ainsi : + calc( 50% + ( var(--gt-25, 0) * 50% ) ) calc( 50% + ( var(--gt-25, 0) * 50% ) )
      + Ainsi la valeur calculée sera 50% 50% si --gt-25 vaut 0, + et 100% 100% si --gt-25 vaut 1. +
    • +
    • + De plus, chaque angle a sa coordonnée cible : + 100% 100% pour en bas à droite, 0% 100% pour en bas à gauche, + 0% 0% pour en haut à gauche. Il faut donc tantôt soustraire et + tantôt ajouter 50% à la valeur intitiale 50% 50% + pour basculer sur le bon point. +
    • +
    +
  4. +
  5. + Un point pour chaque position possible par quart de cercle, correspondant à + chaque tranche de 25%. À l’instar des points aux angles, ces points doivent être au centre + s’ils ne sont pas utilisés. C’est là qu’on rigole le plus : +
      +
    • on part de 50%, auxquels on ajoute ou soustrait la suite du calcul ;
    • +
    • + on utilise enfin la position calculée — --pos-A + ou --pos-B selon le cas — qu’on convertit en pourcentages à l’aide de + * 1%, et qu’on rend inerte si la valeur est inférieure à la tranche concernée + grâce à * var(--lt-25, 1), par exemple.
      + + Remarquez le seconde valeur dans var(), qui est la valeur par défaut + si la variable n’est pas définie. Cool, non ? + +
    • +
    • + et finalement lorsque la tranche est dépassée, le point bascule vers + 0% ou 100% selon le cas. +
    • +
    +
  6. +
  7. + Et enfin, on referme le tracé en revenant au centre du cercle, + à 50% 50%. +
  8. +
+

C’est tout !

+

Les positions illustrées

+

+ Ces captures d’écran — effectuées dans + l’éditeur + de formes + des outils de développement de Firefox — + montrent les points du polygone dans les différents cas. Vous pouvez consulter pour chaque valeur citée + le polygone résolu pour clip-path — et constater le basculement des valeurs dynamiques d’une + position à une autre. +

+
    +
  • +
    +
    Exemple de rendu pour 44%
    +
    +
    + Tracé pour clip-path avec une valeur de 44% : six points visibles. +
    Capture d’écran du tracé pour 44%.
    +
    +
    +
    td[style*="--value: 44;"]::before {
       clip-path: polygon(
         50% 50%,
         50% 0%,
    @@ -576,22 +563,22 @@ 

    Les positions illustrées

    50% 50% ); }
    - -
    Code généré pour 44%.
    -
    -
    -
    -
  • -
  • -
    -
    Exemple de rendu pour 64%
    -
    -
    - Tracé pour clip-path avec une valeur de 64% : sept points visibles. -
    Capture d’écran du tracé pour 64%.
    -
    -
    -
    td[style*="--value: 64;"]::before {
    +							
    Code généré pour 44%.
    +
    +
    +
    +
  • +
  • +
    +
    Exemple de rendu pour 64%
    +
    +
    + Tracé pour clip-path avec une valeur de 64% : sept points visibles. +
    Capture d’écran du tracé pour 64%.
    +
    +
    +
    td[style*="--value: 64;"]::before {
       clip-path: polygon(
         50% 50%,
         50% 0%,
    @@ -606,22 +593,22 @@ 

    Les positions illustrées

    50% 50% ); }
    - -
    Code généré pour 64%.
    -
    -
    -
    -
  • -
  • -
    -
    Exemple de rendu pour 88%
    -
    -
    - Tracé pour clip-path avec une valeur de 88% : neuf points visibles. -
    Capture d’écran du tracé pour 88%.
    -
    -
    -
    td[style*="--value: 88;"]::before {
    +							
    Code généré pour 64%.
    +
    +
    +
    +
  • +
  • +
    +
    Exemple de rendu pour 88%
    +
    +
    + Tracé pour clip-path avec une valeur de 88% : neuf points visibles. +
    Capture d’écran du tracé pour 88%.
    +
    +
    +
    td[style*="--value: 88;"]::before {
       clip-path: polygon(
         50% 50%,
         50% 0%,
    @@ -636,255 +623,203 @@ 

    Les positions illustrées

    50% 50% ); }
    - -
    Code généré pour 88%.
    -
    -
    -
    -
  • -
-
- -
-
-
-

- Interrupteur
- Permet de désactiver les styles sur le tableau suivant. -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Exemple de tarte avec une valeur entre 50 et 75%
RessourceProportion
HTML - 2 % -
CSS - 2 % -
JS - 32 % -
Images - 64 % -
-
- -
-
-

- Interrupteur
- Permet de désactiver les styles sur le tableau suivant. -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Exemple de tarte avec une valeur supérieure à 75%
RessourceProportion
HTML - 2 % -
CSS - 2 % -
JS - 8 % -
Images - 88 % -
-
-
- -

Donut

- -

- Sur l’élément <table>, on ajoute une variable --offset - qui permet de déterminer la dimension du trou du donut, - généré à l’aide de mask-image et radial-gradient(). - - Ana Tudor a réalisé de très nombreux exemples - d’utilisation des mask-* sur CodePen, jetez-y un œil ! -

- -
-
-

- Interrupteur
- Permet de désactiver les styles sur le tableau suivant. -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Répartition du poids des ressources pour ffoodd.fr
RessourceProportion
HTML - 2 % -
CSS - 2 % -
JS - 32 % -
Json - 1 % -
Images - 44 % -
Webfonts - 17 % -
Autres - 2 % -
-
- -
- Le css -
.chaarts.donut {
+							
Code généré pour 88%.
+ +
+ + + +
+ +
+
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Exemple de tarte avec une valeur entre 50 et 75%
RessourceProportion
HTML + 2 %
CSS + 2 %
JS + 32 %
Images + 64 %
+
+ +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Exemple de tarte avec une valeur supérieure à 75%
RessourceProportion
HTML + 2 %
CSS + 2 %
JS + 8 %
Images + 88 %
+
+
+ +

Donut

+ +

+ Sur l’élément <table>, on ajoute une variable --offset + qui permet de déterminer la dimension du trou du donut, + généré à l’aide de mask-image et radial-gradient(). + + Ana Tudor a réalisé de très nombreux exemples + d’utilisation des mask-* sur CodePen, jetez-y un œil ! +

+ +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Répartition du poids des ressources pour ffoodd.fr +
RessourceProportion
HTML + 2 %
CSS + 2 %
JS + 32 %
Json + 1 %
Images + 44 %
Webfonts + 17 %
Autres + 2 %
+
+ +
+ Le css +
.chaarts.donut {
   --mask: radial-gradient(
     circle at 50% calc(50% - .25rem),
     transparent 0 var(--offset),
@@ -897,124 +832,103 @@ 

Donut

--away: calc( var(--radius) / 2 - 2.5rem ); }
-
- -
-

Dégradé conique

-

- L’utilisation de conic-gradient() est prometteuse pour ce cas précis. - Vous en trouverez des exemples réalisés par Ana Tudor ou Léa Verou — qui a carrément rédigé la spécification, - et conçu un polyfill. - Cependant le support limité aux navigateurs basés sur WebKit est déprimant, et pose tout de même quelques questions - en matière d’accessibilité puisqu’on ne peut pas affecter un motif à chaque couleur du dégradé conique. -

-
- -

Polaire

- -

- Pour cette déclinaison, on ne change presque rien : seulement la variable --zoom - et son implication dans la mise à l’échelle des portions à l’aide de scale(). -

- -
-
-

- Interrupteur
- Permet de désactiver les styles sur le tableau suivant. -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Répartition du poids des ressources pour ffoodd.fr
RessourceProportion
HTML - 2 % -
CSS - 2 % -
JS - 32 % -
Json - 1 % -
Images - 44 % -
Webfonts - 17 % -
Autres - 2 % -
-
- -
- Le css -
.chaarts.polar td::before {
+	
+ +
+

Dégradé conique

+

+ L’utilisation de conic-gradient() est prometteuse pour ce cas précis. + Vous en trouverez des exemples réalisés par Ana Tudor ou Léa Verou — qui a + carrément rédigé la spécification, + et conçu un polyfill. + Cependant le support limité aux navigateurs + basés sur WebKit est déprimant, et pose tout de même quelques questions + en matière d’accessibilité puisqu’on ne peut pas affecter un motif à chaque couleur du dégradé + conique. +

+
+ +

Polaire

+ +

+ Pour cette déclinaison, on ne change presque rien : seulement la variable --zoom + et son implication dans la mise à l’échelle des portions à l’aide de scale(). +

+ +
+
+

+ Interrupteur
+ Permet de désactiver les styles sur le tableau suivant. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Répartition du poids des ressources pour ffoodd.fr +
RessourceProportion
HTML + 2 %
CSS + 2 %
JS + 32 %
Json + 1 %
Images + 44 %
Webfonts + 17 %
Autres + 2 %
+
+ +
+ Le css +
.chaarts.polar td::before {
   --zoom: 50;
   transform:
     translate3d( -50%, -50%, 0 )
@@ -1034,17 +948,11 @@ 

Polaire

opacity: .5; }
-
- +
+ + - - - - - - - - - \ No newline at end of file + + diff --git a/docs/column-charts.html b/docs/column-charts.html index c24397f..49b62a5 100644 --- a/docs/column-charts.html +++ b/docs/column-charts.html @@ -1,140 +1,141 @@ - - - - - - Column charts — chaarts - - - - - - - - - - - + + + + + + + Column charts — chaarts + + + + + + + + + + + - +
- - - - - + + +
- -

Column charts

- -

- Column chart is used for value distributions. - The structure of the table is quite ordinary, but its formatting is based on - display: grid; and especially display: contents; to - facilitate the placement of the cells — technique inspired by - - Hidde De Vries's article More accessible markup with display: contents, - and clarified by - Ire Aderinokun's post How display: contents works. -

- -

The basic principle is the same as the bar charts:

-
    -
  1. - the first grid row is the reserved to display value in case it reaches scale's max value, - with a fixed size of 2ex - — have a look to CSS - units rudiments, documented in Every Layout by Andy Bell and Heydon Pickering ; -
  2. -
  3. - the repeat() function applied with the --scale custom property - enables us to handle a dynamic scale; -
  4. -
  5. - <thead>, <tbody> and <tr> containers - are neutralized in the grid structure using display: contents; -
  6. - each cell is placed on the grid depending its --value - — its background color also depending on its value; -
  7. -
  8. - and finally its text value — wrapped in a <span> element — - is positioned at the top of the column using the same trick as in the bar chart. -
  9. -
- -
-
-

- Switch
- Allows you to disable styles on the following table. -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - -
Browser market shares in France in January 2019
BrowserChromeFirefoxSafariEdgeIEOthers
Market shares62%15%9%5%6%3%
-
- -
- HTML -
<table class="chaarts column" id="column" style="--y: 7;">
+	

Column charts

+ +

+ Column chart is used for value distributions. + The structure of the table is quite ordinary, but its formatting is based on + display: grid; and especially display: contents; to + facilitate the placement of the cells — technique inspired by + + Hidde De Vries's article More accessible markup with display: contents, + and clarified by + Ire Aderinokun's post How display: contents works. +

+ +

The basic principle is the same as the bar charts:

+
    +
  1. + the first grid row is the reserved to display value in case it reaches scale's max value, + with a fixed size of 2ex + — have a look to CSS + units rudiments, documented in Every Layout by Andy Bell and Heydon Pickering ; +
  2. +
  3. + the repeat() function applied with the --scale custom property + enables us to handle a dynamic scale; +
  4. +
  5. + <thead>, <tbody> and <tr> containers + are neutralized in the grid structure using display: contents; +
  6. +
  7. + each cell is placed on the grid depending its --value + — its background color also depending on its value; +
  8. +
  9. + and finally its text value — wrapped in a <span> element — + is positioned at the top of the column using the same trick as in the bar chart. +
  10. +
+ +
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Browser market shares in France in January 2019
BrowserChromeFirefoxSafariEdgeIEOthers
Market shares62%15%9%5%6%3%
+
+ +
+ HTML +
<table class="chaarts column" id="column" style="--y: 7;">
   <caption id="caption-7">[…]</caption>
   <thead>
     <tr>
@@ -152,10 +153,10 @@ 

Column charts

</tbody> </table>
-
-
- css -
@supports (display: contents) {
+	
+
+ css +
@supports (display: contents) {
   .chaarts[class*="column"] {
     --gap: .5rem;
     --size: calc(var(--scale, 100) * 100%);
@@ -289,122 +290,124 @@ 

Column charts

} }
-
- -

Multiple columns

- -

- In order to have two values for each main column, we must also have - two subheadings. Concretely speaking: -

- -
    -
  1. - we add a second row in <thead>: -
      -
    • - with two column header cells <th scope="col"> - for each column header cell in the first row; -
    • -
    • - remember to add colspan="2" on the first row's header cell - to match the new table layout; -
    • -
    • - and finally add an identifier to each header cell - to referenced them to the relevant data cells — using the - headers attribute, par exemple pour la première cellule: - headers="browser chrome year chrome-2018" where each value - is a header cell's identifier. -
    • -
    -
  2. -
  3. - Styles: -
      -
    • - the first-level header cells must span two columns of the grid, - as required by their colspan for the table layout. It is - unfortunately impossible to use an attribute value in another - property than content — otherwise we could simply write - grid-column: 2 / span attr(colspan);, and that would be awesome… -
    • -
    • - but no! Thus, a --span custom property is added on <table>, - and must match the colspan attributes values mentionned earlier: - it is therefore used to extend the first level headers to the appropriate number of columns. -
    • -
    • - Colors and patterns are no longer applied according to each value, - but according to each column — in the example, every second element - (since we have two entries per column). - Again, if we could use an attribute value or a custom property - in a selector, that would be great. Imagine - tbody td:nth-of-type(var(--span)n + var(--span)) or even - tbody td:nth-of-type(attr(colspan)n + attr(colspan))! -
    • -
    -
  4. -
- -
-
-

- Switch
- Allows you to disable styles on the following table. -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Browser market shares in France in January 2019
BrowserChromeFirefoxSafariEdgeIE
Year2018201920182019201820192018201920182019
Market shares49.6%57%11.74%9.59%21.53%18.78%3.72%3.5%4.46%3.66%
-
- -
- HTML -
<table class="chaarts column-multiple" id="column-multiple" style="--y: 11; --span: 2;">
+	
+ +

Multiple columns

+ +

+ In order to have two values for each main column, we must also have + two subheadings. Concretely speaking: +

+ +
    +
  1. + we add a second row in <thead>: +
      +
    • + with two column header cells <th scope="col"> + for each column header cell in the first row; +
    • +
    • + remember to add colspan="2" on the first row's header cell + to match the new table layout; +
    • +
    • + and finally add an identifier to each header cell + to referenced them to the relevant data cells — using the + headers attribute, par exemple pour la première cellule: + headers="browser chrome year chrome-2018" where each value + is a header cell's identifier. +
    • +
    +
  2. +
  3. + Styles: +
      +
    • + the first-level header cells must span two columns of the grid, + as required by their colspan for the table layout. It is + unfortunately impossible to use an attribute value in another + property than content — otherwise we could simply write + grid-column: 2 / span attr(colspan);, and that would be awesome… +
    • +
    • + but no! Thus, a --span custom property is added on <table>, + and must match the colspan attributes values mentionned earlier: + it is therefore used to extend the first level headers to the appropriate number of columns. +
    • +
    • + Colors and patterns are no longer applied according to each value, + but according to each column — in the example, every second element + (since we have two entries per column). + Again, if we could use an attribute value or a custom property + in a selector, that would be great. Imagine + tbody td:nth-of-type(var(--span)n + var(--span)) or even + tbody td:nth-of-type(attr(colspan)n + attr(colspan))! +
    • +
    +
  4. +
+ +
+
+

+ Switch
+ Allows you to disable styles on the following table. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Browser market shares in France in January 2019
BrowserChromeFirefoxSafariEdgeIE
Year2018201920182019201820192018201920182019
Market shares49.6%57%11.74%9.59%21.53%18.78%3.72%3.5%4.46%3.66%
+
+ +
+ HTML +
<table class="chaarts column-multiple" id="column-multiple" style="--y: 11; --span: 2;">
   <caption id="caption-8">[…]</caption>
   <thead>
     <tr>
@@ -426,10 +429,10 @@ 

Multiple columns

</tbody> </table>
-
-
- css -
@supports (display: contents) {
+	
+
+ css +
@supports (display: contents) {
   .chaarts.column-multiple {
     grid-template-columns: minmax(min-content, 14ch) repeat(calc(var(--y) - 1), 1fr);
     grid-template-rows: 2ex repeat(var(--scale, 100), minmax(0, .25rem)) repeat(2, minmax(min-content, 2rem));
@@ -500,17 +503,11 @@ 

Multiple columns

} }
-
- +
+ + - - - - - - - - - \ No newline at end of file + + diff --git a/docs/courbe.html b/docs/courbe.html index f70f0de..c377e0f 100644 --- a/docs/courbe.html +++ b/docs/courbe.html @@ -1,267 +1,250 @@ - - - - - - Courbes — chaarts - - - - - - - - - - - + + + + + + + Courbes — chaarts + + + + + + + + + + + - +
- - - - - + + +
- -

Graphique linéaire

- -

Graphique de surface

- -

- Ce graphique repose sur les variables CSS, les grilles et clip-path. - Cette dernière propriété est la plus importante. -

- -
    -
  1. - Sur le tableau, les échelles et l’unité sont indiquées : -
      -
    • - --y définit l’échelle des ordonnées, utilisée - pour indiquer l’échelle en arrière-plan mais aussi placer - les points sur la courbe ; -
    • -
    • - --x correspond à l’échelle des abscisses, exprimée - simplement comme le nombre de colonnes à afficher ; -
    • -
    • --unit permet de définir l’unité à afficher dans l’infobulle simulée.
    • -
    -
  2. -
  3. - Chaque ligne <tr> dans <tbody> porte une palanquée - de variables, correspondant à toutes les valeurs qu’elle contient. - Dans un pseudo-élément ::before, une position est définie pour chaque valeur - au sein de la fonction polygon() de clip-path. -
      -
    • - Étant donné que cette fonction accepte deux valeurs en pourcentage - chaque point, la méthode est relativement simple. - La position en abscisse est le nombre de colonnes (le décalage depuis la gauche, donc) - et la position en ordonnée est le ratio de la valeur sur l’échelle, le tout formulé ainsi : - calc( ( 100% / var(--x) * 1 ) + var(--offset) ) calc( 100% - ( var(--1) / var(--y) * 100% ) ), - où * 1 et var(--1) correspondent à l’index de la valeur dans l’ensemble, - et var(--offset) est la valeur d’une demi-colonne, pour placer le point au milieu - de sa colonne. -
    • -
    • - Vous l’aurez peut-être compris, le principal écueil de ce graphique est qu’il - nécessite de connaître le nombre de points par avance. -
    • -
    • - Puisque clip-path requière encore - un préfixe -webkit- pour Safari, on utilise une variable CSS pour éviter la - duplication du polygon() — astuce - partagée par Michelle Barker dans "7 uses for CSS custom properties". -
    • -
    -
  4. -
  5. - Chaque cellule <td> dans <tbody> porte un pseudo-élément - ::after qui sert à récapituler ses entêtes et valeur dans - une infobulle simulée, et un pseudo-élément ::before pour gérer un calque interactif sur la cellule : - -
  6. -
  7. - Tout le reste n’est que décoration : -
      -
    • - un padding-top important sur le tableau pour - réserver l’espace d’affichage des graphiques — attention : - il est nécessaire d’appliquer border-collapse: separate; sur le tableau - afin que le padding ait un impact ; -
    • -
    • le ::before de chaque ligne est étiré afin d’occuper tout l’espace réservé ;
    • -
    • un arrière-plan dégradé pour représenter la surface pleine du même ::before ;
    • -
    • - un repeating-linear-gradient() pour représenter l’échelle verticale, - en arrière-plan du tableau ; -
    • -
    • - et des interactions au survol pour mettre en exergue la valeur survolée : - sa colonne à l’aide d’un pseudo-élément — positionné à l’aide de de savants calculs — - et mix-blend-mode pour un effet waouh. -
    • -
    -
  8. -
- - - -
-
-

- Interrupteur
- Permet de désactiver les styles sur le tableau suivant. -

- -
- - + un préfixe -webkit- pour Safari, on utilise une variable CSS pour éviter la + duplication du polygon() — astuce + partagée par Michelle Barker dans "7 uses for CSS custom properties". + + + +
  • + Chaque cellule <td> dans <tbody> porte un pseudo-élément + ::after qui sert à récapituler ses entêtes et valeur dans + une infobulle simulée, et un pseudo-élément ::before pour gérer un calque interactif sur la cellule : + +
  • +
  • + Tout le reste n’est que décoration : +
      +
    • + un padding-top important sur le tableau pour + réserver l’espace d’affichage des graphiques — attention : + il est nécessaire d’appliquer border-collapse: separate; sur le tableau + afin que le padding ait un impact ; +
    • +
    • le ::before de chaque ligne est étiré afin d’occuper tout l’espace réservé ;
    • +
    • un arrière-plan dégradé pour représenter la surface pleine du même ::before ;
    • +
    • + un repeating-linear-gradient() pour représenter l’échelle verticale, + en arrière-plan du tableau ; +
    • +
    • + et des interactions au survol pour mettre en exergue la valeur survolée : + sa colonne à l’aide d’un pseudo-élément — positionné à l’aide de de savants calculs — + et mix-blend-mode pour un effet waouh. +
    • +
    +
  • + + + +
    +
    +

    + Interrupteur
    + Permet de désactiver les styles sur le tableau suivant. +

    + +
    + +
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Température mensuelle moyenne en 2017
    AnnéeJan.Fév.MarsAvr.MaiJuinJuil.AoûtSep.Oct.Nov.Déc.
    2017 - 8 °C - - 6 °C - - 9 °C - - 12 °C - - 15 °C - - 21 °C - - 24 °C - - 25 °C - - 22 °C - - 19 °C - - 14 °C - - 9 °C -
    -
    - -
    - Le HTML -
    <table class="chaarts line" style="--y: 32; --x: 13; --t-1: 'Jan.'; --t-2: 'Feb.'; […]">
    +			Température mensuelle moyenne en 2017
    +			
    +			
    +				Année
    +				Jan.
    +				Fév.
    +				Mars
    +				Avr.
    +				Mai
    +				Juin
    +				Juil.
    +				Août
    +				Sep.
    +				Oct.
    +				Nov.
    +				Déc.
    +			
    +			
    +			
    +			
    +				2017
    +					
    +		8 °C	
    +
    +					
    +		6 °C	
    +
    +					
    +		9 °C	
    +
    +					
    +		12 °C	
    +
    +					
    +		15 °C	
    +
    +					
    +		21 °C	
    +
    +					
    +		24 °C	
    +
    +					
    +		25 °C	
    +
    +					
    +		22 °C	
    +
    +					
    +		19 °C	
    +
    +					
    +		14 °C	
    +
    +					
    +		9 °C	
    +
    +			
    +			
    +		
    +	
    + +
    + Le HTML + +
    <table class="chaarts line" style="--y: 32; --x: 13; --t-1: 'Jan.'; --t-2: 'Feb.'; […]">
       <caption id="caption-3">[…]</caption>
       <thead>
         <tr>
    @@ -279,10 +262,10 @@ 

    Graphique de surface

    </tbody> </table>
    -
    -
    - Le css -
    @supports (clip-path: polygon(0% calc( 100% - ( var(--1) * 100% / var(--y) )) )) {
    +	
    +
    + Le css +
    @supports (clip-path: polygon(0% calc( 100% - ( var(--1) * 100% / var(--y) )) )) {
       .chaarts.line {
         --offset: calc( ( 100% / var(--x) ) / 2 );
         --height: calc( 32em - 2rem );
    @@ -463,230 +446,187 @@ 

    Graphique de surface

    } }
    -
    -
    - Le calcul tordu -

    Le tracé du polygon()

    -

    - Pour commencer, il faut bien intégrer que clip-path est un tracé, - au même titre qu’une forme vectorielle. Il doit donc être fermé. - Ainsi le tracé démarre à 0% 100% — en bas à gauche, fait sa vie - de tracé, bascule à 100% 100% et revient boucler à 0% 100%. -

    -

    Et dans son chemin, chaque point doit être positionné en abscisses et en ordonnées.

    -

    La position en abscisse

    -

    - La première position est simple : on divise 100% par l’échelle - var(--x), et on multiplie par l’index de l’élément. Par exemple : - calc( ( 100% / var(--x) * 1) ). - Pour placer chaque point au milieu de sa colonne, on le décale d’une demi-colonne - — ce que l’on fait en ajoutant au calcul précédent var(--offset), qui correspond - à calc( ( 100% / var(--x) ) / 2 ).
    - La position finale est donc, ici pour le troisième point :
    - calc( ( 100% / var(--x) * 3) + var(--offset) ). -

    -

    La position en ordonnée

    -

    - Dans ce graphique, l’ordonnée est l’axe le plus important. Ainsi pour placer le point, - on commence par calculer le ratio de sa valeur sur l’échelle — formulé - ainsi : var(--1) / var(--y). Et parce que polygon() utilise - des valeurs en pourcentage, on rapporte ce calcul sur 100% : - ( var(--1) / var(--y) * 100% ).
    - Et pour finir, les référentiels du polygone partant d’en haut à gauche, la position - doit être définie en fonction du haut de la boîte. La formule finale ressemble - alors à ça — toujours pour le troisième élément :
    - calc( 100% - ( var(--3) / var(--y) * 100% ) ). -

    -
    - -

    Graphique à point

    - -

    Cette variante diffère finalement assez peu de la précédente mouture :

    - -
      -
    1. - le polygon() est poursuivi pour former une ligne, - en dupliquant chaque point avec un décalage de 4px - — l’épaisseur du trait — et dans l’ordre inverse ; -
    2. -
    3. - le pseudo-élément ::before qui permet d’afficher l’infobulle prend ici la forme d’un - point sur la courbe — positionné à l’aide des mêmes calculs qui servent dans le polygone ; -
    4. -
    5. - et surtout, puisque clip-path est appliqué sur la ligne - <tr> : vous pouvez en mettre plusieurs ! - Il nous faut donc ajouter une combinaison de couleur et motif pour distinguer chaque ligne - et les associer visuellement à leur légende. -
    6. -
    - -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - +
    +

    + Interrupteur
    + Permet de désactiver les styles sur le tableau suivant. +

    + +
    + +
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Température mensuelle moyenne par année
    AnnéeJan.Fév.MarsAvr.MaiJuinJuil.AoûtSep.Oct.Nov.Déc.
    2017 - 8 °C - - 6 °C - - 9 °C - - 12 °C - - 15 °C - - 21 °C - - 24 °C - - 25 °C - - 22 °C - - 19 °C - - 14 °C - - 9 °C -
    2018 - 10 °C - - 4 °C - - 7 °C - - 13 °C - - 17 °C - - 20 °C - - 22 °C - - 23 °C - - 26 °C - - 17 °C - - 14 °C - - 10 °C -
    -
    - -
    - Le css -
    @supports (clip-path: polygon(0% calc(100% - (var(--1) * 100% / var(--y))))) {
    +			Température mensuelle moyenne par année
    +			
    +			
    +				Année
    +				Jan.
    +				Fév.
    +				Mars
    +				Avr.
    +				Mai
    +				Juin
    +				Juil.
    +				Août
    +				Sep.
    +				Oct.
    +				Nov.
    +				Déc.
    +			
    +			
    +			
    +			
    +				2017
    +					
    +		8 °C	
    +
    +					
    +		6 °C	
    +
    +					
    +		9 °C	
    +
    +					
    +		12 °C	
    +
    +					
    +		15 °C	
    +
    +					
    +		21 °C	
    +
    +					
    +		24 °C	
    +
    +					
    +		25 °C	
    +
    +					
    +		22 °C	
    +
    +					
    +		19 °C	
    +
    +					
    +		14 °C	
    +
    +					
    +		9 °C	
    +
    +			
    +			
    +				2018
    +					
    +		10 °C	
    +
    +					
    +		4 °C	
    +
    +					
    +		7 °C	
    +
    +					
    +		13 °C	
    +
    +					
    +		17 °C	
    +
    +					
    +		20 °C	
    +
    +					
    +		22 °C	
    +
    +					
    +		23 °C	
    +
    +					
    +		26 °C	
    +
    +					
    +		17 °C	
    +
    +					
    +		14 °C	
    +
    +					
    +		10 °C	
    +
    +			
    +			
    +		
    +	
    + +
    + Le css +
    @supports (clip-path: polygon(0% calc(100% - (var(--1) * 100% / var(--y))))) {
       .chaarts.points [style]::before {
         background: var(--color, currentColor) var(--background);
         --polygon: polygon(
    @@ -786,26 +726,20 @@ 

    Graphique à point

    } }
    -
    - -
    -

    Note

    -

    - Pour jouer d’avantage et vous familiariser avec clip-path, - Bennett Feely a créé - clippy. -

    -
    - +
    + +
    +

    Note

    +

    + Pour jouer d’avantage et vous familiariser avec clip-path, + Bennett Feely a créé + clippy. +

    +
    + + - - - - - - - - - \ No newline at end of file + + diff --git a/docs/css/chaarts.min.css b/docs/css/chaarts.min.css new file mode 100644 index 0000000..2ae233d --- /dev/null +++ b/docs/css/chaarts.min.css @@ -0,0 +1,2 @@ +@charset "UTF-8";@property --integer{syntax:"";initial-value:0;inherits:false}table{font-feature-settings:"tnum";border-collapse:collapse;caption-side:top;margin-bottom:1.5rem;vertical-align:top;width:100%}table>caption:first-child{font-style:italic;margin:0;padding:2.5rem 1rem}td,th{padding:.5rem .75rem;text-align:left}table strong,th{color:#000}td{line-height:1.25;max-width:100%}tbody{border:1px solid dimgray}thead{border:1px solid #000}.table-container{background:linear-gradient(90deg,#fff 30%,#fff0),linear-gradient(90deg,#fff0,#fff 70%) 0 100%,radial-gradient(farthest-side at 0 50%,#0003,#0000),radial-gradient(farthest-side at 100% 50%,#0003,#0000) 0 100%;background-attachment:local,local,scroll,scroll;background-color:#fff;background-position:0 0,100%,0 0,100%;background-repeat:no-repeat;background-size:2.5rem 100%,2.5rem 100%,1rem 100%,1rem 100%;margin:2rem 0;max-width:100%;overflow-x:auto;overflow-y:hidden}.table-container .fieldset{display:none!important;padding:0 1rem}[class*=chaarts] [role=presentation]{display:none}[class*=chaarts] abbr[title]{border-bottom:0;font-size:small;font-weight:400;text-transform:none}.chaarts{--checkers:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill-rule='evenodd' d='M0 0h4v4H0V0zm4 4h4v4H4V4z' fill='%23ffffff99'/%3E%3C/svg%3E");--hexagons:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='24' viewBox='0 0 28 49'%3E%3Cpath d='m13.99 9.25 13 7.5v15l-13 7.5L1 31.75v-15l12.99-7.5zM3 17.9v12.7l10.99 6.34 11-6.35V17.9l-11-6.34L3 17.9zM0 15l12.98-7.5V0h-2v6.35L0 12.69v2.3zm0 18.5L12.98 41v8h-2v-6.85L0 35.81v-2.3zM15 0v7.5L27.99 15H28v-2.31h-.01L17 6.35V0h-2zm0 49v-8l12.99-7.5H28v2.31h-.01L17 42.15V49h-2z' fill='%23ffffff99' fill-rule='nonzero'/%3E%3C/svg%3E");--triangles:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='16' viewBox='0 0 36 72'%3E%3Cpath d='M2 6h12L8 18 2 6zm18 36h12l-6 12-6-12z' fill='%23ffffff99' fill-rule='evenodd'/%3E%3C/svg%3E");--zig:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='12'%3E%3Cpath d='M9.8 12 0 2.2V.8l10 10 10-10v1.4L10.2 12h-.4zm-4 0L0 6.2V4.8L7.2 12H5.8zm8.4 0L20 6.2V4.8L12.8 12h1.4zM9.8 0l.2.2.2-.2h-.4zm-4 0L10 4.2 14.2 0h-1.4L10 2.8 7.2 0H5.8z' fill='%23ffffff99' fill-rule='evenodd'/%3E%3C/svg%3E");--stripes:url("data:image/svg+xml;charset=utf-8,%3Csvg width='6' height='6' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5 0h1L0 6V5zm1 5v1H5z' fill='%23ffffff99' fill-rule='evenodd'/%3E%3C/svg%3E");--dots:url("data:image/svg+xml;charset=utf-8,%3Csvg width='10' height='10' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff99' fill-rule='evenodd'%3E%3Ccircle cx='3' cy='3' r='3'/%3E%3Ccircle cx='13' cy='13' r='3'/%3E%3C/g%3E%3C/svg%3E");caption-side:bottom;empty-cells:hide;margin:1.5em auto;overflow:hidden;padding:1em}.chaarts>caption:first-child{background:inherit;font-style:normal;padding:1rem 0}table:not(.chaarts) .sr-only{clip:auto!important;clip-path:none!important;height:auto!important;overflow:visible!important;position:static!important;white-space:normal!important;width:auto!important}@media screen and (min-width:30em){.chaarts{border-collapse:initial;contain:content}.chaarts:not([class*=radar]){border-spacing:0}.chaarts td,.chaarts th{border:0;padding:0}.chaarts td:empty,.chaarts th:empty{display:none!important}@supports (grid-template-columns:repeat(var(--scale,100),minmax(0,1fr))){.bar-container .fieldset{display:flex!important}.chaarts.bar caption{text-align:initial;text-indent:13.5rem}.chaarts.bar tr{grid-row-gap:.5rem;display:grid;grid-auto-rows:1fr;grid-template-columns:minmax(min-content,12.5em) repeat(var(--scale,100),minmax(0,1fr)) 10ch;transition:opacity .2s cubic-bezier(.5,0,.5,1)}.chaarts.bar tr:nth-child(1n+1){--background:var(--checkers)}.chaarts.bar tr:nth-child(2n+2){--background:var(--hexagons)}.chaarts.bar tr:nth-child(3n+3){--background:var(--triangles)}.chaarts.bar tr:nth-child(4n+4){--background:var(--zig)}.chaarts.bar tr:nth-child(5n+5){--background:var(--stripes)}.chaarts.bar tr:nth-child(6n+6){--background:var(--dots)}.chaarts.bar th{grid-column:1/1;margin:.5rem 0 0;padding:0 1rem 0 0;text-align:right}.chaarts.bar td{--size:calc(var(--scale, 100)*100%);--position:calc(var(--value, 0)/var(--scale, 100)*100%);background:linear-gradient(to right,#01ac49,#444,#0000cd,#639,crimson) var(--position) 0 /var(--size) 100%,var(--background) center/contain;background-blend-mode:hard-light;grid-column:2/var(--value,0);margin:.5rem 0 0;position:relative}.chaarts.bar span{font-weight:700;left:100%;line-height:1.5;position:absolute}@supports ((-webkit-background-clip:text) or (background-clip:text)) or (-webkit-background-clip:text){.chaarts.bar span{background:inherit;-webkit-background-clip:text;background-clip:text;color:#0000}}.chaarts.bar:hover tr{opacity:.5}.chaarts.bar:hover tr:hover{opacity:1}@media screen and (min-width:30em) and (-ms-high-contrast:active){.chaarts.bar td{background-image:linear-gradient(to right,Window,ButtonFace,ButtonShadow,ButtonText,highlight),var(--background)}}.chaarts.bar.waterfall tr:first-of-type td{grid-column:var(--0,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(2) td{grid-column:var(--1,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(3) td{grid-column:var(--2,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(4) td{grid-column:var(--3,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(5) td{grid-column:var(--4,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(6) td{grid-column:var(--5,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(7) td{grid-column:var(--6,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(8) td{grid-column:var(--7,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(9) td{grid-column:var(--8,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(10) td{grid-column:var(--9,2) /var(--value,2)}.chaarts.bar.waterfall tr:nth-of-type(11) td{grid-column:var(--10,2) /var(--value,2)}}@supports (clip-path:polygon(50% calc(50% + (var(--gt-25,0))))){.pie-container .fieldset{display:flex!important;margin-bottom:0}.chaarts.pie{--radius:32em;margin:0 auto;padding-top:calc(var(--radius) - 2rem);position:relative}.chaarts.pie tbody{display:table-row}.chaarts.pie tr{display:table-cell;transition:opacity .3s cubic-bezier(.5,0,.5,1)}.chaarts.pie [scope=row]{padding-right:.5rem}.chaarts.pie [scope=row]:before{background:var(--color,currentColor) var(--background);content:"";display:inline-block;height:1rem;transform:translate3d(-.2rem,.1rem,0);width:1rem}.chaarts.pie td{--position:calc(var(--start, 0)*0.01turn)}.chaarts.pie td:after,.chaarts.pie td:before{left:50%;position:absolute;top:calc(var(--radius)/2);transform-origin:center center}.chaarts.pie td:before{--zoom:.75;--part:calc(var(--value)*3.6);--main-angle:calc(var(--part) - (var(--gt-25, 0) + var(--gt-50, 0) + var(--gt-75, 0))*90);--β:calc(var(--main-angle)*0.01745);--α:calc((90 - var(--main-angle))*0.01745);--sin-term-β-1:var(--β);--sin-term-β-2:calc((var(--β)*var(--β)*var(--β))/6);--sin-term-β-3:calc((var(--β)*var(--β)*var(--β)*var(--β)*var(--β))/120);--sin-term-β-4:calc((var(--β)*var(--β)*var(--β)*var(--β)*var(--β)*var(--β)*var(--β))/5040);--sin-term-β-5:calc((var(--β)*var(--β)*var(--β)*var(--β)*var(--β)*var(--β)*var(--β)*var(--β)*var(--β))/362880);--sin-β:calc(var(--sin-term-β-1) - var(--sin-term-β-2) + var(--sin-term-β-3) - var(--sin-term-β-4) + var(--sin-term-β-5));--sin-term-α-1:var(--α);--sin-term-α-2:calc((var(--α)*var(--α)*var(--α))/6);--sin-term-α-3:calc((var(--α)*var(--α)*var(--α)*var(--α)*var(--α))/120);--sin-term-α-4:calc((var(--α)*var(--α)*var(--α)*var(--α)*var(--α)*var(--α)*var(--α))/5040);--sin-term-α-5:calc((var(--α)*var(--α)*var(--α)*var(--α)*var(--α)*var(--α)*var(--α)*var(--α)*var(--α))/362880);--sin-α:calc(var(--sin-term-α-1) - var(--sin-term-α-2) + var(--sin-term-α-3) - var(--sin-term-α-4) + var(--sin-term-α-5));--pos-B:calc(var(--sin-β)*50);--pos-A:calc(var(--sin-α)*50);--polygon:polygon(50% 50%,50% 0%,100% 0%,calc(50% + var(--pos-B)*1%*var(--lt-25, 1) + var(--gt-25, 0)*50%) calc(50% - var(--pos-A)*1%*var(--lt-25, 1)),calc(50% + var(--gt-25, 0)*50%) calc(50% + var(--gt-25, 0)*50%),calc(50% + var(--pos-A)*1%*var(--lt-50, 1) + var(--gt-50, 0)*50%) calc(50% + var(--pos-B)*1%*var(--lt-50, 1) + var(--gt-50, 0)*50%),calc(50% - var(--gt-50, 0)*50%) calc(50% + var(--gt-50, 0)*50%),calc(50% - var(--pos-B)*1%*var(--lt-75, 1) - var(--gt-75, 0)*50%) calc(50% + var(--pos-A)*1%*var(--lt-75, 1)),calc(50% - var(--gt-75, 0)*50%) calc(50% - var(--gt-75, 0)*50%),calc(50% - var(--pos-A)*1%*var(--gt-75, 0)) calc(50% - var(--pos-B)*1%*var(--gt-75, 0)),50% 50%);--mask:radial-gradient(circle at center,#fff 0 calc(var(--radius)/2),#0000 0);background:var(--color,currentColor) var(--background);clip-path:var(--polygon);content:"";height:var(--radius);-webkit-mask-image:var(--mask);mask-image:var(--mask);transform:translate3d(-50%,-50%,0) rotate(var(--position)) scale(var(--zoom));transition:transform .2s cubic-bezier(.5,0,.5,1);width:var(--radius)}.chaarts.pie tr:hover td:before{--zoom:.8}.chaarts.pie tr:nth-child(1n+1){--background:var(--checkers)}.chaarts.pie tr:nth-child(2n+2){--background:var(--hexagons)}.chaarts.pie tr:nth-child(3n+3){--background:var(--triangles)}.chaarts.pie tr:nth-child(4n+4){--background:var(--zig)}.chaarts.pie tr:nth-child(5n+5){--background:var(--stripes)}.chaarts.pie tr:nth-child(6n+6){--background:var(--dots)}.chaarts.pie td:after{--arrow:calc(100% - 0.25rem);--axis:calc(var(--position) - 0.25turn + var(--value)*0.005turn);--away:calc(var(--radius)/2 - 1rem);--integer:calc(var(--value));background-color:#444;color:#fff;content:var(--term) " : " counter(value) " %";counter-reset:value var(--integer);opacity:0;padding:.5rem;pointer-events:none;transform:translate3d(-50%,-50%,0) rotate(var(--axis)) translate(var(--away)) rotate(calc(var(--axis)*-1)) perspective(1000px) rotateX(45deg);transform-origin:50% calc(100% + 10px);transition:opacity .2s cubic-bezier(0,.5,.5,1),transform .2s cubic-bezier(0,.5,.5,1)}.chaarts.pie tbody:hover tr{opacity:.5}.chaarts.pie tbody:hover tr:hover{opacity:1}.chaarts.pie tbody:hover tr:hover td:after{opacity:1;transform:translate3d(-50%,-50%,0) rotate(var(--axis)) translate(var(--away)) rotate(calc(var(--axis)*-1)) perspective(1000px) rotateX(0deg);transition:opacity .2s cubic-bezier(.5,0,1,.5),transform .2s cubic-bezier(.5,0,1,.5)}.chaarts.polar td:before{--zoom:50;transform:translate3d(-50%,-50%,0) rotate(var(--position)) scale(calc((var(--zoom) + var(--value)/(100/var(--zoom)))/100))}.chaarts.polar td:after{--away:calc(var(--radius)/2 - (var(--radius)/4)*(100 - var(--value))/100 + 2.5rem)}.chaarts.polar tr:hover td:before{--zoom:50}.chaarts.donut{--mask:radial-gradient(circle at 50% calc(50% - 0.25rem),#0000 0 var(--offset),#fff calc(var(--offset) + 1px) 100%);-webkit-mask-image:var(--mask);mask-image:var(--mask)}.chaarts.donut td:after{--away:calc(var(--radius)/2 - 2.5rem)}@media screen and (min-width:30em) and (-ms-high-contrast:active){.chaarts.pie tbody tr :before{background-color:Window}.chaarts.pie tbody tr:nth-of-type(odd) :before{background-color:WindowText}}}@supports (clip-path:polygon(0% calc(100% - var(--1 ) * 100% / var(--y )))){.line-container .fieldset{display:flex!important}.chaarts.line{--offset:calc((100%/var(--x))/2);--height:calc(32em - 2rem);--bottom:calc(100% - var(--height));padding:var(--height) 0 1rem;position:relative;transition:background .3s cubic-bezier(.5,0,.5,1),color .3s cubic-bezier(.5,0,.5,1)}.chaarts.line:after{--scale:calc((100% - var(--y)*1px)/var(--y));background:repeating-linear-gradient(to bottom,#fff 0 var(--scale),#00000040 calc(var(--scale) + 1px));bottom:var(--bottom);top:0;width:100%;z-index:1}.chaarts.line tr:before,.chaarts.line:after{content:"";position:absolute}.chaarts.line [scope=row],.chaarts.line thead th:first-child{color:var(--color,currentColor);text-align:left}.chaarts.line [style]:before{--polygon:polygon(0% 100%,calc(100%/var(--x)*1) 100%,calc(100%/var(--x)*1) calc(100% - var(--1)/var(--y)*100%),calc(100%/var(--x)*1 + var(--offset)) calc(100% - var(--1)/var(--y)*100%),calc(100%/var(--x)*2 + var(--offset)) calc(100% - var(--2)/var(--y)*100%),calc(100%/var(--x)*3 + var(--offset)) calc(100% - var(--3)/var(--y)*100%),calc(100%/var(--x)*4 + var(--offset)) calc(100% - var(--4)/var(--y)*100%),calc(100%/var(--x)*5 + var(--offset)) calc(100% - var(--5)/var(--y)*100%),calc(100%/var(--x)*6 + var(--offset)) calc(100% - var(--6)/var(--y)*100%),calc(100%/var(--x)*7 + var(--offset)) calc(100% - var(--7)/var(--y)*100%),calc(100%/var(--x)*8 + var(--offset)) calc(100% - var(--8)/var(--y)*100%),calc(100%/var(--x)*9 + var(--offset)) calc(100% - var(--9)/var(--y)*100%),calc(100%/var(--x)*10 + var(--offset)) calc(100% - var(--10)/var(--y)*100%),calc(100%/var(--x)*11 + var(--offset)) calc(100% - var(--11)/var(--y)*100%),calc(100%/var(--x)*12 + var(--offset)) calc(100% - var(--12)/var(--y)*100%),100% calc(100% - var(--12)/var(--y)*100%),100% 100%,0% 100%);background:linear-gradient(0deg,#00bfff,crimson 75%);bottom:var(--bottom);clip-path:var(--polygon);content:"";position:absolute;top:0;width:100%;z-index:2}.chaarts.line td,.chaarts.line th{background:#fff;font-weight:700;text-align:center;width:calc(100%/var(--x))}.chaarts.line [scope=col]:not(:first-child):after{background:#fff var(--stripes);background-blend-mode:exclusion;bottom:4rem;content:"";height:calc(100% - 4rem);left:calc(100%/var(--x)*var(--index));mix-blend-mode:soft-light;opacity:0;position:absolute;transition:opacity .3s cubic-bezier(.5,0,.5,1);width:inherit;z-index:3}.chaarts.line [scope=col]:nth-child(2):after{--index:1}.chaarts.line [scope=col]:nth-child(3):after{--index:2}.chaarts.line [scope=col]:nth-child(4):after{--index:3}.chaarts.line [scope=col]:nth-child(5):after{--index:4}.chaarts.line [scope=col]:nth-child(6):after{--index:5}.chaarts.line [scope=col]:nth-child(7):after{--index:6}.chaarts.line [scope=col]:nth-child(8):after{--index:7}.chaarts.line [scope=col]:nth-child(9):after{--index:8}.chaarts.line [scope=col]:nth-child(10):after{--index:9}.chaarts.line [scope=col]:nth-child(11):after{--index:10}.chaarts.line [scope=col]:nth-child(12):after{--index:11}.chaarts.line [scope=col]:nth-child(13):after{--index:12}.chaarts.line [scope=col]:hover:after{opacity:.75}.chaarts.line td{--value:var(--1);--term:var(--t-1);line-height:1.5}.chaarts.line td:before{content:"";height:1.5rem;position:absolute;transform:translateX(-50%);width:inherit;z-index:10}.chaarts.line td:after{--arrow:calc(100% - 0.25rem);--top:calc(var(--height) - var(--value)/var(--y)*var(--height));--polygon:polygon(0% 0%,100% 0%,100% var(--arrow),calc(50% - 0.25rem) var(--arrow),50% 100%,calc(50% + 0.25rem) var(--arrow),0% var(--arrow));--integer:calc(var(--value));background-color:#444;clip-path:var(--polygon);color:#fff;content:var(--term) " " var(--year) "\a" counter(value) " " var(--unit);counter-reset:value var(--integer);left:calc(var(--offset)*3);opacity:0;padding:.5rem;pointer-events:none;position:absolute;top:var(--top,0);transform:translate3d(-50%,-125%,0) perspective(1000px) rotateX(45deg);transform-origin:50% calc(100% + 10px);transition:opacity .2s cubic-bezier(0,.5,.5,1),transform .2s cubic-bezier(0,.5,.5,1);white-space:pre;z-index:5}.chaarts.line td+td:after{left:calc(100%/var(--x)*var(--index) + var(--offset))}.chaarts.line td:nth-child(2):after{--value:var(--1);--term:var(--t-1);--index:1}.chaarts.line td:nth-child(3):after{--value:var(--2);--term:var(--t-2);--index:2}.chaarts.line td:nth-child(4):after{--value:var(--3);--term:var(--t-3);--index:3}.chaarts.line td:nth-child(5):after{--value:var(--4);--term:var(--t-4);--index:4}.chaarts.line td:nth-child(6):after{--value:var(--5);--term:var(--t-5);--index:5}.chaarts.line td:nth-child(7):after{--value:var(--6);--term:var(--t-6);--index:6}.chaarts.line td:nth-child(8):after{--value:var(--7);--term:var(--t-7);--index:7}.chaarts.line td:nth-child(9):after{--value:var(--8);--term:var(--t-8);--index:8}.chaarts.line td:nth-child(10):after{--value:var(--9);--term:var(--t-9);--index:9}.chaarts.line td:nth-child(11):after{--value:var(--10);--term:var(--t-10);--index:10}.chaarts.line td:nth-child(12):after{--value:var(--11);--term:var(--t-11);--index:11}.chaarts.line td:nth-child(13):after{--value:var(--12);--term:var(--t-12);--index:12}.chaarts.line td:hover:after{opacity:1;transform:translate3d(-50%,-125%,0) perspective(1000px) rotateX(0deg);transition:opacity .2s cubic-bezier(.5,0,1,.5),transform .2s cubic-bezier(.5,0,1,.5)}.chaarts.points [style]:before{--polygon:polygon(calc(100%/var(--x)*1 + var(--offset)) calc(100% - var(--1)/var(--y)*100%),calc(100%/var(--x)*2 + var(--offset)) calc(100% - var(--2)/var(--y)*100%),calc(100%/var(--x)*3 + var(--offset)) calc(100% - var(--3)/var(--y)*100%),calc(100%/var(--x)*4 + var(--offset)) calc(100% - var(--4)/var(--y)*100%),calc(100%/var(--x)*5 + var(--offset)) calc(100% - var(--5)/var(--y)*100%),calc(100%/var(--x)*6 + var(--offset)) calc(100% - var(--6)/var(--y)*100%),calc(100%/var(--x)*7 + var(--offset)) calc(100% - var(--7)/var(--y)*100%),calc(100%/var(--x)*8 + var(--offset)) calc(100% - var(--8)/var(--y)*100%),calc(100%/var(--x)*9 + var(--offset)) calc(100% - var(--9)/var(--y)*100%),calc(100%/var(--x)*10 + var(--offset)) calc(100% - var(--10)/var(--y)*100%),calc(100%/var(--x)*11 + var(--offset)) calc(100% - var(--11)/var(--y)*100%),calc(100%/var(--x)*12 + var(--offset)) calc(100% - var(--12)/var(--y)*100%),calc(100%/var(--x)*13 + var(--offset)) calc(100% - var(--12)/var(--y)*100%),100% calc(100% - var(--12)/var(--y)*100%),100% calc(100% + 0.25rem - var(--12)/var(--y)*100%),calc(100%/var(--x)*13 + var(--offset)) calc(100% + 0.25rem - var(--12)/var(--y)*100%),calc(100%/var(--x)*12 + var(--offset)) calc(100% + 0.25rem - var(--12)/var(--y)*100%),calc(100%/var(--x)*11 + var(--offset)) calc(100% + 0.25rem - var(--11)/var(--y)*100%),calc(100%/var(--x)*10 + var(--offset)) calc(100% + 0.25rem - var(--10)/var(--y)*100%),calc(100%/var(--x)*9 + var(--offset)) calc(100% + 0.25rem - var(--9)/var(--y)*100%),calc(100%/var(--x)*8 + var(--offset)) calc(100% + 0.25rem - var(--8)/var(--y)*100%),calc(100%/var(--x)*7 + var(--offset)) calc(100% + 0.25rem - var(--7)/var(--y)*100%),calc(100%/var(--x)*6 + var(--offset)) calc(100% + 0.25rem - var(--6)/var(--y)*100%),calc(100%/var(--x)*5 + var(--offset)) calc(100% + 0.25rem - var(--5)/var(--y)*100%),calc(100%/var(--x)*4 + var(--offset)) calc(100% + 0.25rem - var(--4)/var(--y)*100%),calc(100%/var(--x)*3 + var(--offset)) calc(100% + 0.25rem - var(--3)/var(--y)*100%),calc(100%/var(--x)*2 + var(--offset)) calc(100% + 0.25rem - var(--2)/var(--y)*100%),calc(100%/var(--x)*1 + var(--offset)) calc(100% + 0.25rem - var(--1)/var(--y)*100%));background:var(--color,currentColor) var(--background);transition:opacity .3s cubic-bezier(.5,0,.5,1)}.chaarts.points [style] th:before{background:var(--color,currentColor) var(--background);content:"";display:inline-block;height:1rem;transform:translate3d(-.2rem,.1rem,0);width:1rem}.chaarts.points [style] td:before{--size:1rem;--top:calc(var(--height) - var(--value)/var(--y)*var(--height));background:var(--color,currentColor) var(--background);border:2px solid #fff;border-radius:50%;box-shadow:0 0 .25rem #00000080;content:"";height:var(--size);left:calc(var(--offset)*3);position:absolute;top:var(--top,100);transform:translate3d(calc(var(--size)/-2),calc(var(--size)/-2),0);transition:opacity .3s cubic-bezier(.5,0,.5,1),transform .3s cubic-bezier(.5,0,.5,1);width:var(--size);z-index:4}.chaarts.points [style] td+td:before{left:calc(100%/var(--x)*var(--index) + var(--offset))}.chaarts.points [style] td:nth-of-type(2):before{--value:var(--2);--index:2}.chaarts.points [style] td:nth-of-type(3):before{--value:var(--3);--index:3}.chaarts.points [style] td:nth-of-type(4):before{--value:var(--4);--index:4}.chaarts.points [style] td:nth-of-type(5):before{--value:var(--5);--index:5}.chaarts.points [style] td:nth-of-type(6):before{--value:var(--6);--index:6}.chaarts.points [style] td:nth-of-type(7):before{--value:var(--7);--index:7}.chaarts.points [style] td:nth-of-type(8):before{--value:var(--8);--index:8}.chaarts.points [style] td:nth-of-type(9):before{--value:var(--9);--index:9}.chaarts.points [style] td:nth-of-type(10):before{--value:var(--10);--index:10}.chaarts.points [style] td:nth-of-type(11):before{--value:var(--11);--index:11}.chaarts.points [style] td:nth-of-type(12):before{--value:var(--12);--index:12}.chaarts.points [style]:nth-child(1n+1){--background:var(--checkers)}.chaarts.points [style]:nth-child(2n+2){--background:var(--hexagons)}.chaarts.points [style]:nth-child(3n+3){--background:var(--triangles)}.chaarts.points [style]:nth-child(4n+4){--background:var(--zig)}.chaarts.points [style]:nth-child(5n+5){--background:var(--stripes)}.chaarts.points [style]:nth-child(6n+6){--background:var(--dots)}.chaarts.points tbody:hover [style] td:before,.chaarts.points tbody:hover [style]:before{opacity:.25}.chaarts.points tbody:hover [style]:hover td:before,.chaarts.points tbody:hover [style]:hover:before{opacity:1}.chaarts.points tbody:hover [style]:hover td:before{transform:translate3d(calc(var(--size)/-2),calc(var(--size)/-2),0) scale(1.25)}.chaarts.points [scope=col]:not(:first-child):after{mix-blend-mode:multiply}.chaarts.points [scope=col]:not(:first-child):hover:after{opacity:.5}@media screen and (min-width:30em) and (-ms-high-contrast:active){.chaarts.line [style]:before{background:linear-gradient(0deg,ButtonHighlight,Highlight 75%)}}}@supports (display:contents){.column-container .fieldset{display:flex!important}.chaarts[class*=column]{--gap:0.5rem;--size:calc(var(--scale, 100)*100%);--width:calc(64em/var(--y) - 1rem);grid-column-gap:var(--gap);display:grid;max-height:64em;position:relative}.chaarts[class*=column] td,.chaarts[class*=column] th{margin:0}.chaarts[class*=column] tr>*+*{text-align:center}.chaarts[class*=column] tbody,.chaarts[class*=column] thead,.chaarts[class*=column] tr{display:contents}.chaarts[class*=column] caption{grid-column:1/span var(--y);grid-row:-1}.chaarts[class*=column] td{--integer:calc(var(--value));grid-row:calc(var(--scale, 100) + 2 - var(--integer)) /-2;pointer-events:none;position:relative;transition:opacity .2s cubic-bezier(.5,0,.5,1)}.chaarts[class*=column] td:first-of-type{grid-column:2}.chaarts[class*=column] td:nth-of-type(2){grid-column:3}.chaarts[class*=column] td:nth-of-type(3){grid-column:4}.chaarts[class*=column] td:nth-of-type(4){grid-column:5}.chaarts[class*=column] td:nth-of-type(5){grid-column:6}.chaarts[class*=column] td:nth-of-type(6){grid-column:7}.chaarts[class*=column] td:nth-of-type(7){grid-column:8}.chaarts[class*=column] td:nth-of-type(8){grid-column:9}.chaarts[class*=column] td:nth-of-type(9){grid-column:10}.chaarts[class*=column] td:nth-of-type(10){grid-column:11}.chaarts[class*=column] span{bottom:100%;font-weight:700;left:0;line-height:1.5;pointer-events:auto;position:absolute;right:0}@supports ((-webkit-background-clip:text) or (background-clip:text)) or (-webkit-background-clip:text){.chaarts[class*=column] span{background:inherit;-webkit-background-clip:text;background-clip:text;color:#0000}}.chaarts[class*=column].column-single{grid-auto-columns:1fr;grid-template-rows:2ex repeat(var(--scale,100),minmax(0,.25rem)) minmax(min-content,2rem)}.chaarts[class*=column].column-single tbody th{grid-column:1;grid-row:-6/-3;line-height:1}.chaarts[class*=column].column-single thead *{grid-row:-2}.chaarts[class*=column].column-single td{--position:calc(var(--integer, 0)/var(--scale, 100)*100%);background:linear-gradient(to top,#01ac49,#444,#0000cd,#639,crimson) 0 var(--position) /100% var(--size),var(--background) center/1rem;background-blend-mode:hard-light}.chaarts[class*=column].column-single [scope=col]:after{background:#f5f5f5 var(--stripes);background-blend-mode:exclusion;bottom:4rem;content:"";mix-blend-mode:multiply;opacity:0;position:absolute;top:1rem;transition:opacity .3s cubic-bezier(.5,0,.5,1);width:var(--width);z-index:0}.chaarts[class*=column].column-single [scope=col]:hover:after{opacity:.5}.chaarts[class*=column].column-single [scope=col]:nth-child(2):after{left:calc(1em + var(--width)*1 + var(--gap)*1)}.chaarts[class*=column].column-single [scope=col]:nth-child(3):after{left:calc(1em + var(--width)*2 + var(--gap)*2)}.chaarts[class*=column].column-single [scope=col]:nth-child(4):after{left:calc(1em + var(--width)*3 + var(--gap)*3)}.chaarts[class*=column].column-single [scope=col]:nth-child(5):after{left:calc(1em + var(--width)*4 + var(--gap)*4)}.chaarts[class*=column].column-single [scope=col]:nth-child(6):after{left:calc(1em + var(--width)*5 + var(--gap)*5)}.chaarts[class*=column].column-single [scope=col]:nth-child(7):after{left:calc(1em + var(--width)*6 + var(--gap)*6)}.chaarts[class*=column].column-single td:nth-of-type(1n+1){--background:var(--checkers)}.chaarts[class*=column].column-single td:nth-of-type(2n+2){--background:var(--hexagons)}.chaarts[class*=column].column-single td:nth-of-type(3n+3){--background:var(--triangles)}.chaarts[class*=column].column-single td:nth-of-type(4n+4){--background:var(--zig)}.chaarts[class*=column].column-single td:nth-of-type(5n+5){--background:var(--stripes)}.chaarts[class*=column].column-single td:nth-of-type(6n+6){--background:var(--dots)}@media screen and (min-width:30em) and (-ms-high-contrast:active){.chaarts[class*=column].column-single td{background-image:linear-gradient(to top,Window,ButtonFace,ButtonShadow,ButtonText,highlight),var(--background)}}.chaarts[class*=column].column-multiple{grid-template-columns:minmax(min-content,14ch) repeat(calc(var(--y) - 1),1fr);grid-template-rows:2ex repeat(var(--scale,100),minmax(0,.25rem)) repeat(2,minmax(min-content,2rem))}.chaarts[class*=column].column-multiple span{background-image:none}.chaarts[class*=column].column-multiple tbody th{grid-row:-10/span 7}.chaarts[class*=column].column-multiple thead tr *{grid-column:1;grid-row:-2}.chaarts[class*=column].column-multiple thead tr :nth-of-type(2){grid-column:calc(4 - var(--span))/span var(--span)}.chaarts[class*=column].column-multiple thead tr :nth-of-type(3){grid-column:calc(6 - var(--span))/span var(--span)}.chaarts[class*=column].column-multiple thead tr :nth-of-type(4){grid-column:calc(8 - var(--span))/span var(--span)}.chaarts[class*=column].column-multiple thead tr :nth-of-type(5){grid-column:calc(10 - var(--span))/span var(--span)}.chaarts[class*=column].column-multiple thead tr :nth-of-type(6){grid-column:calc(12 - var(--span))/span var(--span)}.chaarts[class*=column].column-multiple thead tr+tr *{font-weight:400;grid-row:-3}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(2){grid-column:2}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(3){grid-column:3}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(4){grid-column:4}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(5){grid-column:5}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(6){grid-column:6}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(7){grid-column:7}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(8){grid-column:8}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(9){grid-column:9}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(10){grid-column:10}.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(11){grid-column:11}.chaarts[class*=column].column-multiple tr:first-child [scope=col]:nth-child(2n):after{background:#f5f5f5 var(--stripes);background-blend-mode:exclusion;bottom:4rem;content:"";mix-blend-mode:multiply;opacity:.25;position:absolute;top:calc(1rem + 2ex);transition:opacity .3s cubic-bezier(.5,0,.5,1);width:calc(var(--width)*2 + var(--gap)/2 + 1px);z-index:0}.chaarts[class*=column].column-multiple tr:first-child [scope=col]:nth-child(2):after{left:calc(14ch + 1em + var(--width)*2*0 + var(--gap)/2*0 + var(--gap)*1)}.chaarts[class*=column].column-multiple tr:first-child [scope=col]:nth-child(4):after{left:calc(14ch + 1em + var(--width)*2*2 + var(--gap)/2*2 + 2px + var(--gap)*3)}.chaarts[class*=column].column-multiple tr:first-child [scope=col]:nth-child(6):after{left:calc(14ch + 1em + var(--width)*2*4 + var(--gap)/2*4 + 4px + var(--gap)*5)}.chaarts[class*=column].column-multiple td{background-color:#e11a81;background-image:var(--zig);grid-row-end:-3}.chaarts[class*=column].column-multiple td:nth-of-type(2n+2){background:#0172f0 var(--triangles)}@media screen and (min-width:30em) and (-ms-high-contrast:active){.chaarts[class*=column].column-multiple td{background-color:Window}.chaarts[class*=column].column-multiple td:nth-of-type(2n+2){background-color:Highlight}}}@supports (clip-path:polygon(0% 0%,calc(100% - var(--1 ) * 100% / var(--scale )) 100%,100% 100%)){.radar-container .fieldset{display:flex!important}.chaarts[class*=radar]{--radius:12.8em;--unitless-radius:12.8;--size:calc(var(--radius)/var(--scale));--part:calc(360deg/var(--items));--integer:calc(var(--scale));background-image:repeating-radial-gradient(circle at 50%,#0003 0 2px,#0000 0 calc(var(--size)*var(--step))),repeating-radial-gradient(circle at 50%,#0000001a 0 2px,#0000 0 var(--size));border:2px solid;border-radius:50%;contain:layout;counter-reset:scale var(--integer);height:calc(var(--radius)*2);margin:6rem auto 12rem;overflow:visible;position:relative;width:calc(var(--radius)*2)}.chaarts[class*=radar] caption{background:none;bottom:-10rem;position:absolute}.chaarts[class*=radar] [scope=col]{--away:calc(var(--radius)*-1 - 50%);left:50%;margin:0;padding:0 1rem;position:absolute;top:50%;transform:translate3d(-50%,-50%,0) rotate(calc(var(--part)*var(--index, 1))) translate(var(--away)) rotate(calc(var(--part)*var(--index, 1)*-1))}.chaarts[class*=radar] tr>:first-of-type{--index:1}.chaarts[class*=radar] tr>:nth-of-type(2){--index:2}.chaarts[class*=radar] tr>:nth-of-type(3){--index:3}.chaarts[class*=radar] tr>:nth-of-type(4){--index:4}.chaarts[class*=radar] tr>:nth-of-type(5){--index:5}.chaarts[class*=radar] tr>:nth-of-type(6){--index:6}.chaarts[class*=radar] tr>:nth-of-type(7){--index:7}.chaarts[class*=radar] td{--skew:calc(90deg - var(--part));border-bottom:1px solid #8a2be2;height:50%;left:0;margin:0;position:absolute;top:0;transform:rotate(calc(var(--part)*var(--index, 1))) skew(var(--skew));transform-origin:100% 100%;width:50%}.chaarts[class*=radar] td:first-of-type span{--point:var(--1);--pos:calc(100% - var(--2)*100%/(var(--scale)*var(--ratio)))}.chaarts[class*=radar] td:nth-of-type(2) span{--point:var(--2);--pos:calc(100% - var(--3)*100%/(var(--scale)*var(--ratio)))}.chaarts[class*=radar] td:nth-of-type(3) span{--point:var(--3);--pos:calc(100% - var(--4)*100%/(var(--scale)*var(--ratio)))}.chaarts[class*=radar] td:nth-of-type(4) span{--point:var(--4);--pos:calc(100% - var(--5)*100%/(var(--scale)*var(--ratio)))}.chaarts[class*=radar] td:nth-of-type(5) span{--point:var(--5);--pos:calc(100% - var(--6)*100%/(var(--scale)*var(--ratio)))}.chaarts[class*=radar] td:nth-of-type(6) span{--point:var(--6);--pos:calc(100% - var(--7)*100%/(var(--scale)*var(--ratio)))}.chaarts[class*=radar] td:nth-of-type(7) span{--point:var(--7);--pos:calc(100% - var(--8)*100%/(var(--scale)*var(--ratio)))}.chaarts[class*=radar] td:after,.chaarts[class*=radar] td:before{display:none}.chaarts[class*=radar] span{--opposite:calc(360/var(--items));--angle:calc(var(--opposite)*0.01745);--sin-term-angle-1:var(--angle);--sin-term-angle-2:calc((var(--angle)*var(--angle)*var(--angle))/6);--sin-term-angle-3:calc((var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle))/120);--sin-term-angle-4:calc((var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle))/5040);--sin-term-angle-5:calc((var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle)*var(--angle))/362880);--sin-angle:calc(var(--sin-term-angle-1) - var(--sin-term-angle-2) + var(--sin-term-angle-3) - var(--sin-term-angle-4) + var(--sin-term-angle-5));--hypo:calc(var(--unitless-radius)/var(--sin-angle));--ratio:calc(var(--hypo)/var(--unitless-radius));--polygon:polygon(100% var(--pos),calc(100% - var(--point)*100%/var(--scale)) 100%,100% 100%);background:linear-gradient(to top left,#8a2be2 10%,#00008b 75%);clip-path:var(--polygon);filter:drop-shadow(0 0 1rem indigo);height:100%;position:absolute;width:100%}.chaarts.radar [scope=col]:after{color:#639;display:block;font-size:small;font-weight:400}.chaarts.radar [scope=col]:first-child:after{--integer:calc(var(--1));content:counter(value) " / " counter(scale);counter-reset:value var(--integer)}.chaarts.radar [scope=col]:nth-child(2):after{--integer:calc(var(--2));content:counter(value) " / " counter(scale);counter-reset:value var(--integer)}.chaarts.radar [scope=col]:nth-child(3):after{--integer:calc(var(--3));content:counter(value) " / " counter(scale);counter-reset:value var(--integer)}.chaarts.radar [scope=col]:nth-child(4):after{--integer:calc(var(--4));content:counter(value) " / " counter(scale);counter-reset:value var(--integer)}.chaarts.radar [scope=col]:nth-child(5):after{--integer:calc(var(--5));content:counter(value) " / " counter(scale);counter-reset:value var(--integer)}.chaarts.radar [scope=col]:nth-child(6):after{--integer:calc(var(--6));content:counter(value) " / " counter(scale);counter-reset:value var(--integer)}.chaarts.radar [scope=col]:nth-child(7):after{--integer:calc(var(--7));content:counter(value) " / " counter(scale);counter-reset:value var(--integer)}.chaarts.radar-multiple{margin-bottom:12rem}.chaarts.radar-multiple tbody{columns:var(--areas);vertical-align:bottom}.chaarts.radar-multiple [scope=row]{bottom:-8rem;height:2rem;left:1rem;position:absolute}.chaarts.radar-multiple [scope=row]:before{background:var(--color,currentColor);content:"";display:inline-block;height:1rem;margin-right:.25rem;transform:translate3d(0,.1rem,0);width:1rem}.chaarts.radar-multiple tr:nth-child(2) [scope=row]{left:calc(1rem + (100%/var(--areas))*1)}.chaarts.radar-multiple td{align-items:flex-end;border-color:var(--color,currentColor);display:flex;justify-content:flex-end;opacity:.5;pointer-events:none;z-index:0}.chaarts.radar-multiple td:after{color:var(--color,currentColor);display:block;font-size:small;font-weight:700;text-indent:-.5rem;transform:skew(calc(var(--skew)*-1)) rotate(calc(var(--part)*var(--index, 1)*-1));transform-origin:0 0;white-space:nowrap;width:100%}.chaarts.radar-multiple td:first-of-type:after{--integer:calc(var(--1));content:counter(value);counter-reset:value var(--integer);width:calc(var(--1)*100%/var(--scale))}.chaarts.radar-multiple td:nth-of-type(2):after{--integer:calc(var(--2));content:counter(value);counter-reset:value var(--integer);width:calc(var(--2)*100%/var(--scale))}.chaarts.radar-multiple td:nth-of-type(3):after{--integer:calc(var(--3));content:counter(value);counter-reset:value var(--integer);width:calc(var(--3)*100%/var(--scale))}.chaarts.radar-multiple td:nth-of-type(4):after{--integer:calc(var(--4));content:counter(value);counter-reset:value var(--integer);width:calc(var(--4)*100%/var(--scale))}.chaarts.radar-multiple td:nth-of-type(5):after{--integer:calc(var(--5));content:counter(value);counter-reset:value var(--integer);width:calc(var(--5)*100%/var(--scale))}.chaarts.radar-multiple td:nth-of-type(6):after{--integer:calc(var(--6));content:counter(value);counter-reset:value var(--integer);width:calc(var(--6)*100%/var(--scale))}.chaarts.radar-multiple td:nth-of-type(7):after{--integer:calc(var(--7));content:counter(value);counter-reset:value var(--integer);width:calc(var(--7)*100%/var(--scale))}.chaarts.radar-multiple span{background:var(--color,currentColor);pointer-events:auto}@supports ((-webkit-mask-image:url()) or (mask-image:url())){.chaarts.radar-multiple span{--mask:radial-gradient(circle at bottom right,#000,#00000080);-webkit-mask-image:var(--mask);mask-image:var(--mask)}}@media screen and (min-width:30em) and (hover:hover){.chaarts.radar-multiple td{opacity:.25;transition:opacity .2s cubic-bezier(.5,0,.5,1)}.chaarts.radar-multiple td:after{opacity:0;transition:inherit}.chaarts.radar-multiple tr:hover td{opacity:1;z-index:1}.chaarts.radar-multiple tr:hover td:after{opacity:inherit}}}} +/*# sourceMappingURL=chaarts.min.css.map */ \ No newline at end of file diff --git a/docs/css/chaarts.min.css.map b/docs/css/chaarts.min.css.map new file mode 100644 index 0000000..9dd7d73 --- /dev/null +++ b/docs/css/chaarts.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/chaarts.scss","chaarts.css","../src/_chaarts-bar.scss","../src/_chaarts-pie.scss","../src/abstracts/_variables.scss","../src/abstracts/_mixins.scss","../src/_chaarts-line.scss","../src/_chaarts-column.scss","../src/_chaarts-radar.scss"],"names":[],"mappings":"AAqJA,gBCs1CA,CDt9CA,oBACC,kBAAA,CACA,eAAA,CACA,cCLD,CDWA,MAGC,4BAAA,CAFA,wBAAA,CACA,gBAAA,CAEA,oBAAA,CAEA,kBAAA,CADA,UCLD,CDQC,0BACC,iBAAA,CACA,QAAA,CACA,mBCNF,CDUA,MAEC,oBAAA,CACA,eCPD,CDUA,gBAEC,UCPD,CDUA,GACC,gBAAA,CACA,cCPD,CDUA,MACC,wBCPD,CDUA,MACC,qBCPD,CDqBA,iBACC,+MAAA,CAQA,+CAAA,CAHA,qBAAA,CAEA,qCAAA,CAHA,2BAAA,CAEA,2DAAA,CAGA,aAAA,CACA,cAAA,CACA,eAAA,CACA,iBCVD,CDaA,2BACC,sBAAA,CACA,cCVD,CDcC,qCACC,YCXF,CDcC,6BACC,eAAA,CACA,eAAA,CACA,eAAA,CACA,mBCZF,CDgBA,SAeE,+MAAA,CAAA,geAAA,CAAA,iPAAA,CAAA,uVAAA,CAAA,0MAAA,CAAA,0QAAA,CAdD,mBAAA,CACA,gBAAA,CACA,iBAAA,CACA,eAAA,CACA,WCAD,CDaC,6BACC,kBAAA,CACA,iBAAA,CACA,cCXF,CDeA,6BACC,mBAAA,CACA,wBAAA,CACA,qBAAA,CACA,0BAAA,CACA,yBAAA,CAEA,4BAAA,CADA,oBCXD,CDeA,mCACC,SACC,uBAAA,CAKA,eCPA,CDcA,6BACC,gBCZD,CDeA,wBAEC,QAAA,CACA,SCbD,CDeC,oCACC,sBCZF,CCxIF,yEACC,yBACC,sBD2JE,CCvJF,qBACC,kBAAA,CACA,mBDyJC,CCtJF,gBAGC,kBAAA,CAFA,YAAA,CACA,kBAAA,CAEA,4FAAA,CACA,8CDwJC,CCnJA,gCACC,4BDqJD,CCtJA,gCACC,4BDwJD,CCzJA,gCACC,6BD2JD,CC5JA,gCACC,uBD8JD,CC/JA,gCACC,2BDiKD,CClKA,gCACC,wBDoKD,CC/JF,gBACC,eAAA,CACA,gBAAA,CACA,kBAAA,CACA,gBDiKC,CC9JF,gBACC,mCAAA,CACA,uDAAA,CACA,2IAAA,CAQA,gCAAA,CACA,4BAAA,CACA,gBAAA,CACA,iBDyJC,CCtJF,kBACC,eAAA,CACA,SAAA,CACA,eAAA,CACA,iBD+JC,CCtJD,uGAbD,kBAcE,kBAAA,CACA,4BAAA,CACA,oBAAA,CACA,WDyJE,CACF,CCrJD,sBACC,UDuJA,CCpJD,4BACC,SDsJA,CClJF,kEACC,gBAMC,gHDoJE,CACF,CCxIA,2CACC,sCD0ID,CC3IA,4CACC,sCD6ID,CC9IA,4CACC,sCDgJD,CCjJA,4CACC,sCDmJD,CCpJA,4CACC,sCDsJD,CCvJA,4CACC,sCDyJD,CC1JA,4CACC,sCD4JD,CC7JA,4CACC,sCD+JD,CChKA,4CACC,sCDkKD,CCnKA,6CACC,sCDqKD,CCtKA,6CACC,uCDwKD,CACF,CEhSF,gEACC,yBACC,sBAAA,CACA,eFqSE,CElSH,aACC,aAAA,CACA,aAAA,CACA,sCAAA,CACA,iBFgUE,CE9TF,mBACC,iBFgUC,CE7TF,gBACC,kBAAA,CACA,8CF+TC,CE5TF,yBACC,mBF8TC,CE5TD,gCACC,sDAAA,CACA,UAAA,CACA,oBAAA,CACA,WC0DK,CDzDL,qCAAA,CACA,UF8TA,CE1TF,gBACC,yCF4TC,CEzTF,6CAEC,QAAA,CACA,iBAAA,CACA,yBAAA,CACA,8BF2TC,CEvSF,uBACC,UAAA,CACA,6BAAA,CACA,yFAAA,CACA,mCAAA,CACA,0CAAA,CE5EF,uBAAA,CACA,mDAAA,CACA,uEAAA,CACA,0FAAA,CACA,8GAAA,CACA,yHAAA,CALA,uBAAA,CACA,mDAAA,CACA,uEAAA,CACA,0FAAA,CACA,8GAAA,CACA,yHAAA,CF0EE,6BAAA,CACA,6BAAA,CACA,yqBAAA,CAiBA,6EAAA,CAJA,sDAAA,CACA,wBAAA,CACA,UAAA,CACA,oBAAA,CAMA,8BAAA,CAAA,sBAAA,CACA,6EAAA,CACA,gDAAA,CACA,mBFmTC,CEhTF,gCACC,SFkTC,CE5SD,gCACC,4BF8SA,CE/SD,gCACC,4BFiTA,CElTD,gCACC,6BFoTA,CErTD,gCACC,uBFuTA,CExTD,gCACC,2BF0TA,CE3TD,gCACC,wBF6TA,CE9SF,sBACC,4BAAA,CACA,gEAAA,CACA,mCAAA,CACA,4BAAA,CACA,qBAAA,CACA,UAAA,CACA,6CAAA,CACA,kCAAA,CACA,SAAA,CACA,aAAA,CACA,mBAAA,CAEA,6IAAA,CADA,sCAAA,CAEA,oFFgTC,CE5SF,4BACC,UF8SC,CE5SD,kCACC,SF8SA,CE3SD,2CACC,SAAA,CACA,4IAAA,CACA,oFF6SA,CEtSF,yBACC,SAAA,CACA,0HFwSC,CErSF,wBACC,kFFuSC,CEpSF,kCACC,SFsSC,CElSH,eACC,mHAAA,CAKA,8BAAA,CAAA,sBFoSE,CElSF,wBACC,qCFoSC,CEhSH,kEAEE,8BAMC,uBFiSE,CE9RH,+CACC,2BFgSE,CACF,CACF,CKjeF,4EACC,0BACC,sBL8eE,CK3eH,cACC,gCAAA,CACA,0BAAA,CACA,mCAAA,CACA,4BAAA,CACA,iBAAA,CACA,mFL6eE,CK1eF,oBACC,4CAAA,CACA,sGAAA,CAKA,oBAAA,CAGA,KAAA,CACA,UAAA,CACA,SLweC,CKreF,4CAPC,UAAA,CACA,iBL+eC,CKpeF,6DAEC,+BAAA,CACA,eLseC,CKneF,6BAGC,yiCAAA,CADA,oDAAA,CADA,oBAAA,CAsBA,wBAAA,CACA,UAAA,CACA,iBAAA,CACA,KAAA,CACA,UAAA,CACA,SLqeC,CKleF,kCAEC,eAAA,CACA,eAAA,CACA,iBAAA,CACA,yBLoeC,CKheD,kDACC,8BAAA,CACA,+BAAA,CACA,WAAA,CACA,UAAA,CACA,wBAAA,CACA,qCAAA,CACA,yBAAA,CACA,SAAA,CACA,iBAAA,CACA,8CAAA,CACA,aAAA,CACA,SLkeA,CK9dA,6CACC,SLgeD,CKjeA,6CACC,SLmeD,CKpeA,6CACC,SLseD,CKveA,6CACC,SLyeD,CK1eA,6CACC,SL4eD,CK7eA,6CACC,SL+eD,CKhfA,6CACC,SLkfD,CKnfA,6CACC,SLqfD,CKtfA,8CACC,SLwfD,CKzfA,8CACC,UL2fD,CK5fA,8CACC,UL8fD,CK/fA,8CACC,ULigBD,CK7fD,sCACC,WL+fA,CK3fF,iBACC,gBAAA,CACA,iBAAA,CACA,eLghBC,CK9gBD,wBACC,UAAA,CACA,aAAA,CACA,iBAAA,CACA,0BAAA,CACA,aAAA,CACA,ULghBA,CK1fD,uBACC,4BAAA,CACA,+DAAA,CACA,6IAAA,CASA,4BAAA,CACA,qBAAA,CACA,wBAAA,CACA,UAAA,CACA,uEAAA,CACA,kCAAA,CAGA,0BAAA,CAFA,SAAA,CACA,aAAA,CAEA,mBAAA,CACA,iBAAA,CACA,gBAAA,CAEA,sEAAA,CADA,sCAAA,CAEA,oFAAA,CAEA,eAAA,CACA,SL2fA,CKxfD,0BACC,qDL0fA,CKtfA,oCACC,gBAAA,CACA,iBAAA,CACA,SLwfD,CK3fA,oCACC,gBAAA,CACA,iBAAA,CACA,SL6fD,CKhgBA,oCACC,gBAAA,CACA,iBAAA,CACA,SLkgBD,CKrgBA,oCACC,gBAAA,CACA,iBAAA,CACA,SLugBD,CK1gBA,oCACC,gBAAA,CACA,iBAAA,CACA,SL4gBD,CK/gBA,oCACC,gBAAA,CACA,iBAAA,CACA,SLihBD,CKphBA,oCACC,gBAAA,CACA,iBAAA,CACA,SLshBD,CKzhBA,oCACC,gBAAA,CACA,iBAAA,CACA,SL2hBD,CK9hBA,qCACC,gBAAA,CACA,iBAAA,CACA,SLgiBD,CKniBA,qCACC,iBAAA,CACA,kBAAA,CACA,ULqiBD,CKxiBA,qCACC,iBAAA,CACA,kBAAA,CACA,UL0iBD,CK7iBA,qCACC,iBAAA,CACA,kBAAA,CACA,UL+iBD,CK3iBD,6BACC,SAAA,CACA,qEAAA,CACA,oFL6iBA,CKriBD,+BAEC,soEAAA,CADA,sDAAA,CA+BA,8CLuiBA,CKpiBD,kCACC,sDAAA,CACA,UAAA,CACA,oBAAA,CACA,WAAA,CACA,qCAAA,CACA,ULsiBA,CKliBA,kCACC,WAAA,CACA,+DAAA,CACA,sDAAA,CACA,qBAAA,CACA,iBAAA,CACA,+BAAA,CACA,UAAA,CACA,kBAAA,CACA,0BAAA,CACA,iBAAA,CACA,kBAAA,CACA,kEAAA,CACA,oFAAA,CAEA,iBAAA,CACA,SLmiBD,CKhiBA,qCACC,qDLkiBD,CK9hBC,iDACC,gBAAA,CACA,SLgiBF,CKliBC,iDACC,gBAAA,CACA,SLoiBF,CKtiBC,iDACC,gBAAA,CACA,SLwiBF,CK1iBC,iDACC,gBAAA,CACA,SL4iBF,CK9iBC,iDACC,gBAAA,CACA,SLgjBF,CKljBC,iDACC,gBAAA,CACA,SLojBF,CKtjBC,iDACC,gBAAA,CACA,SLwjBF,CK1jBC,iDACC,gBAAA,CACA,SL4jBF,CK9jBC,kDACC,iBAAA,CACA,ULgkBF,CKlkBC,kDACC,iBAAA,CACA,ULokBF,CKtkBC,kDACC,iBAAA,CACA,ULwkBF,CK/jBD,wCACC,4BLikBA,CKlkBD,wCACC,4BLokBA,CKrkBD,wCACC,6BLukBA,CKxkBD,wCACC,uBL0kBA,CK3kBD,wCACC,2BL6kBA,CK9kBD,wCACC,wBLglBA,CK5kBF,yFAEC,WL8kBC,CK3kBF,qGAEC,SL6kBC,CK1kBF,oDACC,8EL4kBC,CKxkBD,oDACC,uBL0kBA,CKvkBD,0DACC,ULykBA,CKpkBH,kEACC,6BAMC,8DLskBG,CACF,CACF,CMh4BF,6BACC,4BACC,sBNy4BE,CMt4BH,wBACC,YAAA,CACA,mCAAA,CACA,kCAAA,CAEA,0BAAA,CADA,YAAA,CAEA,eHoEM,CGnEN,iBN64BE,CM34BF,sDAEC,QN64BC,CM14BF,+BACC,iBN44BC,CMp4BF,uFAGC,gBNs4BC,CMn4BF,gCACC,2BAAA,CACA,WNq4BC,CMl4BF,2BACC,4BAAA,CACA,yDAAA,CACA,mBAAA,CACA,iBAAA,CACA,8CNo4BC,CMj4BA,yCACC,aNm4BD,CMp4BA,0CACC,aNs4BD,CMv4BA,0CACC,aNy4BD,CM14BA,0CACC,aN44BD,CM74BA,0CACC,aN+4BD,CMh5BA,0CACC,aNk5BD,CMn5BA,0CACC,aNq5BD,CMt5BA,0CACC,aNw5BD,CMz5BA,0CACC,cN25BD,CM55BA,2CACC,cN85BD,CMz5BF,6BAEC,WAAA,CADA,eAAA,CAEA,MAAA,CACA,eAAA,CACA,mBAAA,CACA,iBAAA,CACA,ONk6BC,CMz5BD,uGAhBD,6BAiBE,kBAAA,CACA,4BAAA,CACA,oBAAA,CACA,WN45BE,CACF,CMz5BF,sCACC,qBAAA,CACA,yFN25BC,CMz5BD,+CAEC,aAAA,CADA,cAAA,CAEA,aN25BA,CMx5BD,8CACC,WN05BA,CMv5BD,yCACC,yDAAA,CACA,sIAAA,CAQA,gCNk5BA,CM94BA,wDACC,iCAAA,CACA,+BAAA,CACA,WAAA,CACA,UAAA,CACA,uBAAA,CACA,SAAA,CACA,iBAAA,CAEA,QHlCI,CGiCJ,8CAAA,CAEA,kBAAA,CACA,SNg5BD,CM74BA,8DACC,UN+4BD,CM34BC,qEACC,8CN64BF,CM94BC,qEACC,8CNg5BF,CMj5BC,qEACC,8CNm5BF,CMp5BC,qEACC,8CNs5BF,CMv5BC,qEACC,8CNy5BF,CM15BC,qEACC,8CN45BF,CMp5BA,2DACC,4BNs5BD,CMv5BA,2DACC,4BNy5BD,CM15BA,2DACC,6BN45BD,CM75BA,2DACC,uBN+5BD,CMh6BA,2DACC,2BNk6BD,CMn6BA,2DACC,wBNq6BD,CMj6BD,kEACC,yCAMC,8GNm6BC,CACF,CMx5BF,wCACC,6EAAA,CACA,mGN65BC,CM35BD,6CACC,qBN65BA,CM15BD,iDACC,mBN45BA,CMz5BD,mDAEC,aAAA,CADA,WN45BA,CMx5BC,iEACC,kDN05BF,CM35BC,iEACC,kDN65BF,CM95BC,iEACC,kDNg6BF,CMj6BC,iEACC,mDNm6BF,CMp6BC,iEACC,mDNs6BF,CMj6BD,sDACC,eAAA,CACA,WNm6BA,CMh6BC,oEACC,aNk6BF,CMn6BC,oEACC,aNq6BF,CMt6BC,oEACC,aNw6BF,CMz6BC,oEACC,aN26BF,CM56BC,oEACC,aN86BF,CM/6BC,oEACC,aNi7BF,CMl7BC,oEACC,aNo7BF,CMr7BC,oEACC,aNu7BF,CMx7BC,qEACC,cN07BF,CM37BC,qEACC,cN67BF,CMv7BA,uFACC,iCAAA,CACA,+BAAA,CACA,WAAA,CACA,UAAA,CACA,uBAAA,CACA,WAAA,CACA,iBAAA,CAEA,oBAAA,CADA,8CAAA,CAEA,+CAAA,CACA,SNy7BD,CMr7BC,sFACC,wENu7BF,CMx7BC,sFACC,8EN07BF,CM37BC,sFACC,8EN67BF,CMx7BD,2CACC,wBAAA,CACA,2BAAA,CACA,eN07BA,CMp7BD,6DACC,mCNs7BA,CMn7BD,kEACC,2CACC,uBNq7BC,CMl7BF,6DACC,0BNo7BC,CACF,CACF,COlqCF,kGACC,2BACC,sBPuqCE,COpqCH,uBACC,eAAA,CACA,sBAAA,CACA,uCAAA,CACA,gCAAA,CACA,4BAAA,CACA,wLAAA,CAUA,gBAAA,CACA,iBAAA,CACA,cAAA,CACA,kCAAA,CACA,4BAAA,CACA,sBAAA,CACA,gBAAA,CACA,iBAAA,CACA,2BPsrCE,COprCF,+BACC,eAAA,CACA,aAAA,CACA,iBPsrCC,CO3qCF,mCACC,mCAAA,CACA,QAAA,CACA,QAAA,CACA,cAAA,CACA,iBAAA,CACA,OAAA,CACA,gJP6qCC,COzqCD,yCACC,SP2qCA,CO5qCD,0CACC,SP8qCA,CO/qCD,0CACC,SPirCA,COlrCD,0CACC,SPorCA,COrrCD,0CACC,SPurCA,COxrCD,0CACC,SP0rCA,CO3rCD,0CACC,SP6rCA,COxqCF,0BACC,gCAAA,CACA,+BAAA,CACA,UAAA,CACA,MAAA,CACA,QAAA,CACA,iBAAA,CACA,KAAA,CACA,qEAAA,CACA,0BAAA,CACA,SP0qCC,COvqCA,6CACC,gBAAA,CACA,4DPyqCD,CO3qCA,8CACC,gBAAA,CACA,4DP6qCD,CO/qCA,8CACC,gBAAA,CACA,4DPirCD,COnrCA,8CACC,gBAAA,CACA,4DPqrCD,COvrCA,8CACC,gBAAA,CACA,4DPyrCD,CO3rCA,8CACC,gBAAA,CACA,4DP6rCD,CO/rCA,8CACC,gBAAA,CACA,4DPisCD,CO7rCD,iEAEC,YP8rCA,CO1rCF,4BACC,iCAAA,CAEA,qCAAA,CHpHF,+BAAA,CACA,mEAAA,CACA,+FAAA,CACA,0HAAA,CACA,sJAAA,CACA,iJAAA,CGmHE,oDAAA,CAEA,gDAAA,CACA,6FAAA,CAKA,+DAAA,CAKA,wBAAA,CACA,mCAAA,CACA,WAAA,CACA,iBAAA,CACA,UPyrCC,COzqCF,iCACC,UAAA,CACA,aAAA,CACA,eAAA,CACA,ePsrCC,COlrCD,6CACC,wBAAA,CAEA,2CAAA,CADA,kCPqrCA,COvrCD,8CACC,wBAAA,CAEA,2CAAA,CADA,kCP0rCA,CO5rCD,8CACC,wBAAA,CAEA,2CAAA,CADA,kCP+rCA,COjsCD,8CACC,wBAAA,CAEA,2CAAA,CADA,kCPosCA,COtsCD,8CACC,wBAAA,CAEA,2CAAA,CADA,kCPysCA,CO3sCD,8CACC,wBAAA,CAEA,2CAAA,CADA,kCP8sCA,COhtCD,8CACC,wBAAA,CAEA,2CAAA,CADA,kCPmtCA,CO7sCH,wBACC,mBP+sCE,CO7sCF,8BACC,oBAAA,CACA,qBP+sCC,CO5sCF,oCACC,YAAA,CACA,WAAA,CACA,SJtFM,CIuFN,iBP8sCC,CO5sCD,2CACC,oCAAA,CACA,UAAA,CACA,oBAAA,CACA,WJ7FK,CI8FL,mBAAA,CACA,gCAAA,CACA,UP8sCA,COxsCD,oDACC,uCP0sCA,COtsCF,2BACC,oBAAA,CACA,sCAAA,CACA,YAAA,CACA,wBAAA,CACA,UAAA,CACA,mBAAA,CACA,SPwsCC,COtsCD,iCACC,+BAAA,CACA,aAAA,CACA,eAAA,CACA,eAAA,CACA,kBAAA,CACA,iFAAA,CACA,oBAAA,CAEA,kBAAA,CADA,UPysCA,COpsCA,+CACC,wBAAA,CAEA,sBAAA,CADA,kCAAA,CAEA,sCPssCD,CO1sCA,gDACC,wBAAA,CAEA,sBAAA,CADA,kCAAA,CAEA,sCP4sCD,COhtCA,gDACC,wBAAA,CAEA,sBAAA,CADA,kCAAA,CAEA,sCPktCD,COttCA,gDACC,wBAAA,CAEA,sBAAA,CADA,kCAAA,CAEA,sCPwtCD,CO5tCA,gDACC,wBAAA,CAEA,sBAAA,CADA,kCAAA,CAEA,sCP8tCD,COluCA,gDACC,wBAAA,CAEA,sBAAA,CADA,kCAAA,CAEA,sCPouCD,COxuCA,gDACC,wBAAA,CAEA,sBAAA,CADA,kCAAA,CAEA,sCP0uCD,COruCF,6BACC,oCAAA,CACA,mBPuuCC,COruCD,6DAJD,6BAKE,6DAAA,CACA,8BAAA,CAAA,sBPwuCE,CACF,COruCF,qDACC,2BACC,WAAA,CACA,8CPuuCE,COruCF,iCACC,SAAA,CACA,kBPuuCC,COnuCH,oCACC,SAAA,CACA,SPquCE,COnuCF,0CACC,ePquCC,CACF,CACF,CACF","file":"chaarts.min.css"} \ No newline at end of file diff --git a/docs/css/print.min.css b/docs/css/print.min.css deleted file mode 100644 index 04c8ab8..0000000 --- a/docs/css/print.min.css +++ /dev/null @@ -1 +0,0 @@ -@media print{:not(.card)::after,:not(.card)::before,body>:not(main),main>:not(.deck){display:none!important}body,body>*,html{background:0 0!important}.deck .card,blockquote,p{orphans:3;widows:3}.deck .card,blockquote,ol,ul{page-break-inside:avoid;-moz-column-break-inside:avoid;break-inside:avoid}caption,h1,h2,h3,h4,h5,h6{page-break-after:avoid}a::after{content:" (" attr(href) ") ";display:inline-block!important}a::after img,a[href^="#"]::after,a[href^=javascript]::after{content:""}abbr::after{content:" (" attr(title) ") "}} \ No newline at end of file diff --git a/docs/css/styles.min.css b/docs/css/styles.min.css index b7d9c89..c13ddbd 100644 --- a/docs/css/styles.min.css +++ b/docs/css/styles.min.css @@ -1,89 +1,2 @@ -@charset "UTF-8";html{color-scheme:light dark;--neutral: 0, 0%;--treshold: 60%;--hue: 240;--analog: calc(var(--hue) + 30);--right: 150;--wrong: calc(var(--right) + 180);--light-scale: 1.61803398875;--lightness: 30%;--brighter: calc(var(--lightness) * var(--light-scale));--darker: calc(var(--lightness) / var(--light-scale));--switch: calc((var(--lightness) - var(--treshold)) * -100);--secondary: var(--hue), 100%, var(--lightness);--secondary-light: var(--hue), 100%, var(--brighter);--secondary-dark: var(--hue), 100%, var(--darker);--accent: var(--analog), 50%, var(--lightness);--accent-light: var(--analog), 50%, var(--brighter);--accent-dark: var(--analog), 50%, var(--darker);--alert: var(--wrong), 100%, var(--lightness);--alert-light: var(--wrong), 100%, var(--brighter);--alert-dark: var(--wrong), 100%, var(--darker);--success: var(--right), 100%, var(--lightness);--success-light: var(--right), 100%, var(--brighter);--success-dark: var(--right), 100%, var(--darker);--contrast: var(--neutral), var(--switch);--contrast-inverse: var(--neutral), calc(var(--switch) * -1);--muted: var(--neutral), var(--lightness);--muted-light: var(--neutral), var(--brighter);--muted-dark: var(--neutral), var(--darker);--background: var(--neutral), 96%;--enter: cubic-bezier(0, .5, .5, 1);--exit: cubic-bezier(.5, 0, 1, .5);--move: cubic-bezier(.5, 0, .5, 1);--external: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M91.875 62H85v23H15V15h23V0H0v100h100V62z'/%3E%3Cpath d='M54 0v.627l17.787 17.85L52.701 38H38v24h24V49.799l20.773-20.337L99.374 46H100V0z'/%3E%3C/svg%3E");--unsafe: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 47 59.5'%3E%3Cpath d='m 44,26.5 h -3.5 v -10 C 40.5,7.402 33.098,0 24,0 H 23 C 14.801,0 7.943,5.874 6.694,13.966 c -0.295,1.91 1.015,3.698 2.925,3.993 1.916,0.297 3.699,-1.016 3.993,-2.925 C 14.319,10.454 18.355,7 23,7 h 1 c 5.238,0 9.5,4.262 9.5,9.5 v 10 H 3 c -1.657,0 -3,1.343 -3,3 v 27 c 0,1.657 1.343,3 3,3 h 41 c 1.657,0 3,-1.343 3,-3 v -27 c 0,-1.657 -1.343,-3 -3,-3 z'/%3E%3C/svg%3E");--anchor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 85 85.2'%3E%3Cpath d='M56.7 51.7l9.1 9c-2.3 5.5-8.1 9.7-17.3 11.2v-45c6.1-2.3 8-7.1 8-12.7C56.5 6.4 50.2 0 42.4 0s-14 6.3-14 14.2c0 5.6 1.9 10.4 8 12.7v45c-9.1-1.5-15-5.7-17.3-11.2l9.2-9H0v27.8l9.8-9.8c6.2 9.2 18.5 15.5 32.7 15.5 14.2 0 26.5-6.3 32.7-15.5l9.8 9.8V51.7zM42.5 19c-2.6 0-4.7-2.1-4.7-4.7s2.1-4.7 4.7-4.7 4.7 2.1 4.7 4.7-2.1 4.7-4.7 4.7z'/%3E%3C/svg%3E");--select: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 59 47.5'%3E%3Cpath d='M29.414,37.657 L0.344,8.586 L8.828,0.102 L29.414,20.686 L50,0.1 L58.484,8.585 L29.414,37.657'/%3E%3C/svg%3E");--required: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 125'%3E%3Cpath fill='hsl(var(--alert))' d='M53.5355339 41.4644661L70 25l5 5-16.4644661 16.4644661h23.2842713v7.0710678H58.5355339L75 70l-5 5-16.4644661-16.4644661v23.2842713h-7.0710678V58.5355339L30 75l-5-5 16.4644661-16.4644661H18.1801948v-7.0710678h23.2842713L25 30l5-5 16.4644661 16.4644661V18.1801948h7.0710678z'/%3E%3C/svg%3E");--valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 6.3 6.1'%3E%3Cpath fill='hsl(var(--success))' d='M0 2.6235l.898-.898 1.3851 1.3851L5.3936 0l.898.8981-4.0085 4.0085L0 2.6235z'/%3E%3C/svg%3E");--invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 125'%3E%3Cpath fill='hsl(var(--alert))' d='M74.749 11.109L50 35.858 25.251 11.109 11.109 25.251 35.858 50 11.109 74.749l14.142 14.142L50 64.142l24.749 24.749 14.142-14.142L64.142 50l24.749-24.749z'/%3E%3C/svg%3E");--mail: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 84 56'%3E%3Cpath d='M0 0v3.7188l42 28.62504L84.000004 3.7188V0zm0 10.9688v45.03124h84.000004V10.9688L43.6875 38.46884a3.0003 3.0003 0 0 1-3.375 0z'/%3E%3C/svg%3E");--tel: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 46 88'%3E%3Cpath d='M6 0C2.676 0 0 2.676 0 6v76.00005c0 3.324 2.676 6 6 6h34c3.324 0 6-2.676 6-6V6c0-3.324-2.676-6-6-6zM4 10h38v64.00005H4z'/%3E%3C/svg%3E")}@media screen and (min-width:37.5em){html{--light-scale: 1.25;--lightness: 40%}} -/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ -html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}details,main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{color:inherit;display:table;max-width:100%;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio],legend{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}[hidden],template{display:none} -/*! PrismJS 1.11.0 -http://prismjs.com/download.html?themes=prism-dark&languages=markup+css+clike+javascript+bash+css-extras+git+json+markdown+php+php-extras+scss */ -/*! purgecss start ignore */ -.token.cdata,.token.comment,.token.doctype,.token.prolog,.token.punctuation{color:hsl(var(--background))}.namespace{opacity:.7}.token.boolean,.token.constant,.token.number,.token.property,.token.symbol,.token.tag{color:hsl(var(--success-light))}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:hsl(var(--contrast))}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:orange}.token.atrule,.token.attr-value,.token.keyword{color:hsl(var(--success-light))}.token.important,.token.regex{color:hsl(var(--alert-light))}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.deleted{color:hsl(var(--alert));text-decoration:line-through} -/*! purgecss end ignore */ -@keyframes slide-down{0%,50%{opacity:0;transform:translateY(1.5em)}}@keyframes slide-in{0%,50%{opacity:0;transform:translateX(-1.5em)}}@keyframes footnotes{0%{color:hsl(var(--secondary))}}.dialog[aria-hidden=true],[data-a11y-dialog-native]>:first-child{display:none}dialog{border-radius:.375rem;max-width:90%;position:fixed;top:50%;transform:translate3d(0,-50%,0);z-index:13}dialog[open]{display:block}.dialog>:first-child{background:hsla(var(--muted-dark),.5);bottom:0;left:0;position:fixed;right:0;top:0;z-index:12}.dialog-close{line-height:0;padding:.5rem}.dialog-close:focus{box-shadow:inset 0 0 0 .125rem hsla(var(--accent-light),.25)}[role=tablist]{color:hsl(var(--muted));margin-bottom:0}[role=tab]{border:1px solid transparent;border-radius:.25rem .25rem 0 0;color:inherit;cursor:pointer;display:inline-block;padding:1rem;transform:translateY(1px)}[role=tab][aria-selected=true]{background:hsl(var(--contrast));border:1px solid hsla(var(--muted),.25);border-bottom-color:hsl(var(--contrast));color:hsl(var(--secondary))}[role=tab]:active{outline-color:transparent}[role=tab]:focus{outline-color:hsla(var(--muted),.25);outline-offset:-2.75rem}[role=tabpanel]{background:hsl(var(--contrast));border:1px solid hsla(var(--muted),.25);border-radius:.25rem;padding:1rem}[role=tabpanel]:first-of-type{border-radius:0 .25rem .25rem .25rem}[role=tabpanel][aria-hidden=true]{display:none}body,html[lang]{position:relative}html[lang]{box-sizing:border-box;overflow-y:scroll;overflow:-moz-scrollbars-vertical;scroll-behavior:smooth}*,::after,::before{box-sizing:inherit}body{background:hsl(var(--background));color:hsl(var(--muted-dark));counter-reset:footnotes;font:400 1em/1.5 sans-serif;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;overflow-x:hidden;-webkit-font-smoothing:subpixel-antialiased;text-rendering:optimizeSpeed}::-moz-selection{background-color:hsl(var(--accent));color:hsl(var(--background));text-shadow:none}::selection{background-color:hsl(var(--accent));color:hsl(var(--background));text-shadow:none}::-moz-placeholder{color:hsl(var(--muted))}::placeholder{color:hsl(var(--muted))}:focus{outline-color:currentColor;outline-offset:0;isolation:isolate}body:hover [tabindex="-1"]:focus{outline-color:transparent}a{color:hsl(var(--secondary));outline:.125rem solid transparent;outline-offset:2rem;-webkit-text-decoration-style:dotted;text-decoration-style:dotted;-webkit-text-decoration-skip:ink;text-decoration-skip-ink:auto;transition:outline-offset .3s var(--enter)}a:focus,a:hover{color:hsl(var(--secondary-dark))}a:active{opacity:.75;transition:none}main a:visited{color:hsl(var(--success-dark))}main a[href^="#"]::before,main a[href^="tel:"]::before{display:inline-block;margin:0 .25em 0 0}main a[target$=blank]::after{display:inline-block}main a[href^="http:"]::before,main a[href^="mailto:"]::before{display:inline-block;margin:0 .25em 0 0}main a[href^="tel:"]::before{content:"📱"}main a[href^="#"]::before{content:"⚓"}main a[target$=blank]::after{content:"🗗";margin:0 0 0 .25em}main a[href^="mailto:"]::after{display:none}main a[href^="mailto:"]::before{content:"📧"}main a[href^="http:"]::before{color:hsl(var(--alert));content:"🔓"}@media (hover:hover){main a[href^="tel:"]{color:currentColor;pointer-events:none;text-decoration:none}main a[href^="tel:"]::before{display:none!important}}@supports ((-webkit-mask-image:url()) or (mask-image:url())){main a[href^="#"]::before,main a[href^="http://"]::before,main a[href^="mailto:"]::before,main a[href^="tel:"]::before,main a[target$=blank]::after{background:currentColor;content:"";height:.625em;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center center;mask-position:center center;width:.625em}main a[href^="#"]::before{-webkit-mask-image:var(--anchor);mask-image:var(--anchor)}main a[target$=blank]::after{-webkit-mask-image:var(--external);mask-image:var(--external)}main a[href^="http://"]::before{-webkit-mask-image:var(--unsafe);mask-image:var(--unsafe)}main a[href^="mailto:"]::before{-webkit-mask-image:var(--mail);mask-image:var(--mail)}@media (hover:hover){main a[href^="tel:"]::before{-webkit-mask-image:var(--tel);mask-image:var(--tel)}}}address{font-size:1.375rem;font-style:normal;padding:0 0 0 2em}code,pre,svg,video{max-width:100%}[hidden],[role=alert]:empty{display:none}a svg,button svg{pointer-events:none}main{margin:0 auto;outline-color:transparent}@media screen and (prefers-reduced-motion:reduce){*{animation-duration:0s!important;transition:none!important;scroll-behavior:auto!important}}@media screen and (-ms-high-contrast:active){a svg,button svg{background:0 0;border-color:Highlight;fill:Highlight}mark{background-color:Highlight;color:HighlightText}}caption,ol,p,th,ul{font-size:1em;line-height:1.5;margin:1.5em 0}dl{line-height:1.5}pre,td{margin:1.5em 0}dl,td{font-size:1em}.h4,.h5,.h6,.hn,b,blockquote footer,dt,h4,h5,h6,strong{color:hsl(var(--contrast-inverse))}.h1,.h2,.h3,.h4,.h5,.h6,.hn,b,blockquote footer,cite,dt,h1,h2,h3,h4,h5,h6,strong{font-weight:700;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizelegibility}.h1:first-child,.h2:first-child,.h3:first-child,.h4:first-child,.h5:first-child,.h6:first-child,.hn:first-child,b:first-child,blockquote footer:first-child,cite:first-child,dt:first-child,h1:first-child,h2:first-child,h3:first-child,h4:first-child,h5:first-child,h6:first-child,strong:first-child{margin-top:0}.h1,h1{color:hsl(var(--secondary));font-size:2.875em;line-height:1.0434;margin:1.0434782609em 0 .5217391304em}.h1 strong,h1 strong{color:hsl(var(--muted-dark))}.h2,h2{color:hsl(var(--accent));font-size:2.5em;line-height:1.2;margin:1.2em 0 .6em}.h3,h3{color:hsl(var(--muted-dark));font-size:2.25em;line-height:1.3334;margin:1.3333333333em 0 .6666666667em}.h4,h4{font-size:1.875em;line-height:1.6;margin:1.6em 0 .8em}.h5,h5{font-size:1.625em;line-height:1.8462;margin:1.8461538462em 0 .9230769231em}.h6,h6{font-size:1.375em;line-height:1.0909;margin:2.1818181818em 0 1.0909090909em}dd,div,li,p,table,td,textarea,th{-webkit-hyphens:auto;hyphens:auto;word-wrap:break-word}dd,li,p{-ms-hyphenate-limit-chars:6 3 2;-ms-hyphenate-limit-lines:2;-ms-hyphenate-limit-last:always;-ms-hyphenate-limit-zone:8%;hyphenate-limit-chars:6 3 2;hyphenate-limit-lines:2;hyphenate-limit-last:always;hyphenate-limit-zone:8%}li ol,li p,li ul{margin-bottom:0;margin-top:0}blockquote{font-size:1em;font-style:italic;line-height:1.5;margin:3em 0 1.5em;max-width:100%;padding-left:7em;position:relative;quotes:"« " " »";z-index:2}blockquote::before{color:hsl(var(--muted-light));content:open-quote;font-size:10em;font-weight:700;left:0;line-height:0;opacity:.25;position:absolute;top:0;z-index:-1}blockquote footer,cite,dt dfn{font-style:normal}abbr[aria-label]{border-bottom:1px dotted;cursor:help;text-decoration:none;text-transform:uppercase}.small,small{font-size:.875em}cite{color:hsl(var(--accent))}hr{border-bottom:1px solid hsl(var(--contrast));border-top:1px solid hsla(var(--muted-light),.5);height:0}code,var{font:inherit;line-height:1}pre{background:hsl(var(--muted-dark));border:0;border-radius:.25em;color:hsl(var(--contrast));direction:ltr;font-family:"Fira Mono","Consolas","Monaco","Andale Mono",monospace;font-size:small;line-height:1.5;-webkit-hyphens:none;hyphens:none;-moz-tab-size:4;-o-tab-size:4;tab-size:4;overflow-x:auto;padding:2em 1em .5em;text-align:left;white-space:pre;word-break:normal;word-spacing:normal;word-wrap:normal}pre::before{background:hsl(var(--alert));border-radius:50%;box-shadow:1.5em 0 0 0 Orange,3em 0 0 0 hsl(var(--success));content:"";display:block;height:1rem;transform:translateY(-1rem);width:1rem}:not(pre)>code,:not(pre)>var{border:1px solid;border-radius:.2em;display:inline-block;font-family:inherit;padding:.1em;white-space:nowrap}:not(pre)>var{background:hsl(var(--contrast));border-style:dashed;color:hsl(var(--accent-dark))}:not(pre)>code{color:hsl(var(--accent))}dd,dl{margin:0}dd+dt{margin:1rem 0 0}figure dt{clear:left;float:left;margin:0 0 1rem}figure dd{display:flex;margin:0 0 1rem}figure dd::before{border-top:1px dotted;content:"";flex:1;margin:0 .5rem;transform:translateY(.9rem)}figure dl+figcaption{text-align:center}img[alt]{display:inline-block;font-size:0;max-width:100%;vertical-align:middle}img[alt]:not([src$=".svg"]){height:auto}figure,img[alt]::after{background:hsl(var(--contrast))}img[alt]::after{display:block;content:attr(alt) "\a" "— " attr(src);font-size:1rem;width:100%;white-space:pre-wrap;padding:.5rem}svg{fill:currentColor}figure{margin:1rem auto;max-width:100%;overflow:hidden;padding:1rem}figure figcaption{display:block;font-size:.875em;padding:1rem 0}@media screen and (min-width:37.5em){figure{min-width:37.5em;width:-moz-min-content;width:min-content}figure img{min-width:-moz-min-content;min-width:min-content}[class*=columns] figure,[class*=grid] figure,li figure{min-width:0;width:auto}[class*=columns] figure img,[class*=grid] figure img,li figure img{min-width:0}}@media (inverted-colors){img{filter:invert(100%)}}@media screen and (-ms-high-contrast:active){img{filter:brightness(1) contrast(1) saturate(1.5)}}table{border-collapse:collapse;caption-side:top;font-feature-settings:"tnum";margin-bottom:1.5rem;width:100%;vertical-align:top}table>caption:first-child{font-style:italic;margin:0;padding:2.5rem 1rem}table strong,th{color:hsl(var(--contrast-inverse))}tbody{border:1px solid hsl(var(--muted-dark));border:1px solid #696969}thead{border:1px solid hsl(var(--contrast-inverse));border:1px solid #000}.table-container{background-color:var(--contrast)}details{border:.25em solid hsl(var(--contrast-inverse))}details+details{border-top-width:0}details summary{background:hsl(var(--muted-dark));color:hsl(var(--contrast));cursor:pointer;padding:1rem;transition:background .2s var(--enter)}details summary:focus,details summary:hover{background:hsl(var(--contrast-inverse))}details summary~*{margin:1.5rem 1rem 0}details[open] summary~*{animation:slide-down .5s var(--enter)}@media screen and (min-width:30em){@supports (--css: var(--iables)){.vertical{display:flex}.vertical details{flex:0;min-width:3.5em;overflow:hidden}.vertical details+details{border-width:.25em .25em .25em 0}.vertical details summary{float:left;min-height:20em;writing-mode:sideways-lr}.vertical details summary~*{padding-left:3.5em}.vertical details summary~*>:first-child{margin-top:0}.vertical details[open]{flex:1}.vertical details[open] summary~*{animation:slide-in .5s var(--enter)}}}input,optgroup,select,textarea{line-height:inherit}input,label[for],select{vertical-align:middle}input,select,textarea{border-radius:.25rem;font-family:inherit;font-size:1em;padding:.5rem}.fieldset,fieldset,form{max-width:37.5em}form>*+*{margin-top:3em}.fieldset,fieldset{border:0;margin:1rem auto 2rem;padding:0}.fieldset>div,.fieldset>p,fieldset>div,fieldset>p{margin-bottom:inherit}legend:first-child{font-weight:700;margin-bottom:inherit}label[for]{display:block}input[type=text],select{-webkit-appearance:none;-moz-appearance:none;appearance:none}input[type=number],input[type=search],input[type=text],select{background-color:hsl(var(--contrast));border:1px solid hsl(var(--contrast-inverse));color:hsl(var(--muted-dark));transition:box-shadow .3s var(--enter);width:100%}input[type=color],input[type=date],input[type=datetime-local],input[type=email],input[type=file],input[type=month],input[type=password],input[type=tel],input[type=time],input[type=url],input[type=week],textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:hsl(var(--contrast));border:1px solid hsl(var(--contrast-inverse));color:hsl(var(--muted-dark));transition:box-shadow .3s var(--enter);width:100%}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=email]:focus,input[type=file]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,select:focus,textarea:focus{border:1px solid hsl(var(--accent-light));box-shadow:0 0 0 .125rem hsla(var(--accent-light),.25)}@media screen and (-webkit-min-device-pixel-ratio:1.5){input[type=color],input[type=date],input[type=datetime-local],input[type=email],input[type=file],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{font-size:1em}}select:-moz-focusring{color:transparent;text-shadow:0 0 0 hsl(var(--muted-dark))}input[type=checkbox],input[type=image],input[type=radio]{background-color:transparent;border:0;width:auto}.deck [class*=card] figure,input[type=range]{width:100%}input[type=number],input[type=search]{-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none}input[type=checkbox]:not(:first-of-type),input[type=radio]:not(:first-of-type){margin-left:.5rem}input[type=checkbox]:focus,input[type=radio]:focus{box-shadow:0 0 0 .125rem hsla(var(--accent-light),.25);outline-color:transparent}input[type=checkbox]+label[for],input[type=radio]+label[for]{display:inline-block}select[multiple]{vertical-align:top}select:not([multiple]){-webkit-appearance:none;-moz-appearance:none;appearance:none;background:hsl(var(--contrast)) no-repeat var(--select) center right .5em/1em 1em}textarea{resize:vertical;vertical-align:top}label[for]{-webkit-appearance:none;-moz-appearance:none;appearance:none}.button,button,input[type=button],input[type=reset],input[type=submit],label[for]{cursor:pointer}form [disabled],form [read-only]{cursor:not-allowed}label [class^=label-msg]{display:block;margin:-.25rem 0 .25rem;font-size:small}.label-msg-error{color:hsl(var(--alert))}input[type=color]:valid:focus,input[type=date]:valid:focus,input[type=datetime-local]:valid:focus,input[type=email]:valid:focus,input[type=file]:valid:focus,input[type=month]:valid:focus,input[type=number]:valid:focus,input[type=password]:valid:focus,input[type=search]:valid:focus,input[type=tel]:valid:focus,input[type=text]:valid:focus,input[type=time]:valid:focus,input[type=url]:valid:focus,input[type=week]:valid:focus,textarea:valid:focus{background:hsl(var(--contrast)) no-repeat var(--valid) center right .5em/1em 1.25em}input[type=color]:invalid:not(:focus),input[type=date]:invalid:not(:focus),input[type=datetime-local]:invalid:not(:focus),input[type=email]:invalid:not(:focus),input[type=file]:invalid:not(:focus),input[type=month]:invalid:not(:focus),input[type=number]:invalid:not(:focus),input[type=password]:invalid:not(:focus),input[type=search]:invalid:not(:focus),input[type=tel]:invalid:not(:focus),input[type=text]:invalid:not(:focus),input[type=time]:invalid:not(:focus),input[type=url]:invalid:not(:focus),input[type=week]:invalid:not(:focus),textarea:invalid:not(:focus){background:hsl(var(--contrast)) no-repeat var(--invalid) center right .5em/1em 1.25em;box-shadow:0 0 0 .125rem hsla(var(--alert-light),.5)}input[type=color]:invalid:-moz-placeholder-shown:not(:focus),input[type=date]:invalid:-moz-placeholder-shown:not(:focus),input[type=datetime-local]:invalid:-moz-placeholder-shown:not(:focus),input[type=email]:invalid:-moz-placeholder-shown:not(:focus),input[type=file]:invalid:-moz-placeholder-shown:not(:focus),input[type=month]:invalid:-moz-placeholder-shown:not(:focus),input[type=number]:invalid:-moz-placeholder-shown:not(:focus),input[type=password]:invalid:-moz-placeholder-shown:not(:focus),input[type=search]:invalid:-moz-placeholder-shown:not(:focus),input[type=tel]:invalid:-moz-placeholder-shown:not(:focus),input[type=text]:invalid:-moz-placeholder-shown:not(:focus),input[type=time]:invalid:-moz-placeholder-shown:not(:focus),input[type=url]:invalid:-moz-placeholder-shown:not(:focus),input[type=week]:invalid:-moz-placeholder-shown:not(:focus),textarea:invalid:-moz-placeholder-shown:not(:focus){box-shadow:none}input[type=color]:invalid:placeholder-shown:not(:focus),input[type=date]:invalid:placeholder-shown:not(:focus),input[type=datetime-local]:invalid:placeholder-shown:not(:focus),input[type=email]:invalid:placeholder-shown:not(:focus),input[type=file]:invalid:placeholder-shown:not(:focus),input[type=month]:invalid:placeholder-shown:not(:focus),input[type=number]:invalid:placeholder-shown:not(:focus),input[type=password]:invalid:placeholder-shown:not(:focus),input[type=search]:invalid:placeholder-shown:not(:focus),input[type=tel]:invalid:placeholder-shown:not(:focus),input[type=text]:invalid:placeholder-shown:not(:focus),input[type=time]:invalid:placeholder-shown:not(:focus),input[type=url]:invalid:placeholder-shown:not(:focus),input[type=week]:invalid:placeholder-shown:not(:focus),textarea:invalid:placeholder-shown:not(:focus){box-shadow:none}input[type=color]:required:-moz-placeholder-shown,input[type=date]:required:-moz-placeholder-shown,input[type=datetime-local]:required:-moz-placeholder-shown,input[type=email]:required:-moz-placeholder-shown,input[type=file]:required:-moz-placeholder-shown,input[type=month]:required:-moz-placeholder-shown,input[type=number]:required:-moz-placeholder-shown,input[type=password]:required:-moz-placeholder-shown,input[type=search]:required:-moz-placeholder-shown,input[type=tel]:required:-moz-placeholder-shown,input[type=text]:required:-moz-placeholder-shown,input[type=time]:required:-moz-placeholder-shown,input[type=url]:required:-moz-placeholder-shown,input[type=week]:required:-moz-placeholder-shown,textarea:required:-moz-placeholder-shown{background:hsl(var(--contrast)) no-repeat var(--required) center right .5em/1em 1.25em}input[type=color]:required:placeholder-shown,input[type=date]:required:placeholder-shown,input[type=datetime-local]:required:placeholder-shown,input[type=email]:required:placeholder-shown,input[type=file]:required:placeholder-shown,input[type=month]:required:placeholder-shown,input[type=number]:required:placeholder-shown,input[type=password]:required:placeholder-shown,input[type=search]:required:placeholder-shown,input[type=tel]:required:placeholder-shown,input[type=text]:required:placeholder-shown,input[type=time]:required:placeholder-shown,input[type=url]:required:placeholder-shown,input[type=week]:required:placeholder-shown,textarea:required:placeholder-shown{background:hsl(var(--contrast)) no-repeat var(--required) center right .5em/1em 1.25em}::-ms-clear{display:none}select::-ms-expand{display:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration,[type=search]::-webkit-search-results-button,[type=search]::-webkit-search-results-decoration{display:none}.button,button,input[type=button],input[type=reset],input[type=submit]{background-color:hsl(var(--accent));border:1px solid hsl(var(--accent));border-radius:.25rem;color:hsl(var(--contrast));font-family:inherit;font-size:1em;line-height:1.5;margin:.5rem 0;padding:.5rem;vertical-align:middle;transition:all 300ms var(--move);width:auto;-webkit-appearance:none;-moz-appearance:none;appearance:none}.button:hover,button:hover,input[type=button]:hover,input[type=reset]:hover,input[type=submit]:hover{border:1px solid hsl(var(--accent-light));background-color:hsl(var(--accent-light))}.button:active,.button:focus,.button[aria-expanded=true],button:active,button:focus,button[aria-expanded=true],input[type=button]:active,input[type=button]:focus,input[type=button][aria-expanded=true],input[type=reset]:active,input[type=reset]:focus,input[type=reset][aria-expanded=true],input[type=submit]:active,input[type=submit]:focus,input[type=submit][aria-expanded=true]{border:1px solid hsl(var(--accent-dark));background-color:hsl(var(--accent-dark))}.button:focus,button:focus,input[type=button]:focus,input[type=reset]:focus,input[type=submit]:focus{box-shadow:0 0 0 .125rem hsla(var(--accent-light),.25);outline-color:transparent}.button:active,.button[aria-expanded=true],button:active,button[aria-expanded=true],input[type=button]:active,input[type=button][aria-expanded=true],input[type=reset]:active,input[type=reset][aria-expanded=true],input[type=submit]:active,input[type=submit][aria-expanded=true]{transform:translateY(.125rem)}.button[disabled],.button[disabled]:active,.button[disabled]:focus,.button[disabled]:hover,button[disabled],button[disabled]:active,button[disabled]:focus,button[disabled]:hover,input[type=button][disabled],input[type=button][disabled]:active,input[type=button][disabled]:focus,input[type=button][disabled]:hover,input[type=reset][disabled],input[type=reset][disabled]:active,input[type=reset][disabled]:focus,input[type=reset][disabled]:hover,input[type=submit][disabled],input[type=submit][disabled]:active,input[type=submit][disabled]:focus,input[type=submit][disabled]:hover{background-color:hsl(var(--muted-dark));box-shadow:none;color:hsl(var(--background));cursor:not-allowed;pointer-events:none}.no-margin{margin:0!important}.no-padding{padding:0!important}.no-border{border:0!important}.no-list{list-style:none!important;padding:0}.no-event{pointer-events:none!important}.list-inline>li{display:inline}.m-auto{margin:auto!important}.ml-auto{margin-left:auto!important}.mx-auto{margin:0 auto!important}.mt-auto{margin-top:auto!important}.no-background{background:0 0!important}.mr-1{margin-right:1rem!important}.mt-0{margin-top:0!important}.ml-1{margin-left:1rem!important}.mb-1{margin-bottom:1rem!important}.p-relative{position:relative!important}.d-flex{align-items:center;display:flex!important;flex-wrap:wrap}.d-block{display:block!important}.align-top{align-items:flex-start!important}.align-end{place-self:flex-end!important}.flex-column{align-items:flex-start;flex-direction:column!important}.fw-400{font-weight:400!important}.fw-700{font-weight:700!important}.f-left{float:left}.stretch{height:100%!important;-o-object-fit:cover;object-fit:cover;-o-object-position:center;object-position:center;width:100%}@media screen and (max-width:29.9375em){.sm-hidden{display:none!important}}[class*="--s"],[class*="--xs"]{font-size:.75rem;line-height:1.5}[class*="--s"]{font-size:.875rem}[class*="--l"]{font-size:1.25rem;line-height:1.05}[class*="--xl"]{font-size:1.5rem;line-height:1.75;margin:2em 0}.muted{color:hsl(var(--muted))!important}.muted em,.muted strong{color:hsl(var(--background))}.clr-alert{color:hsl(var(--alert))!important}.clr-success{color:hsl(var(--success))!important}.clr-accent{color:hsl(var(--accent))!important}.clr-secondary{color:hsl(var(--secondary))!important}[class*=bg-] *{color:inherit}[class*=bg-] a:focus,[class*=bg-] a:hover{color:inherit;opacity:.75}.bg-alert{background-color:hsl(var(--alert));color:hsl(var(--contrast))}.bg-accent,.bg-secondary,.bg-success{background-color:hsl(var(--success));color:hsl(var(--contrast))}.bg-accent,.bg-secondary{background-color:hsl(var(--accent))}.bg-secondary{background-color:hsl(var(--secondary))}.rounded{border-radius:50%;-webkit-clip-path:circle(50% at 50% 50%);clip-path:circle(50% at 50% 50%)}.sr-only,.visually-hidden{border:0!important;clip:rect(1px,1px,1px,1px)!important;-webkit-clip-path:inset(50%)!important;clip-path:inset(50%)!important;height:1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;white-space:nowrap!important}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto!important;-webkit-clip-path:none!important;clip-path:none!important;height:auto!important;overflow:visible!important;width:auto!important;white-space:normal!important}body>*{background:hsla(var(--background),.75);margin:0 auto;padding:1rem;max-width:64em}[class*=columns]>*,[class*=grid]>*{display:inline-block;margin-bottom:2rem;max-width:100%}@media screen and (min-width:37.5em){[class*=columns],[class*=grid]{-moz-column-gap:2rem;column-gap:2rem;orphans:1;widows:1}[class*=columns]>*,[class*=grid]>*{page-break-inside:avoid;-moz-column-break-inside:avoid;break-inside:avoid}.columns-2,.grid-2{-moz-columns:2;columns:2}.columns-3,.grid-1-2,.grid-2-1,.grid-3{-moz-columns:3;columns:3}.columns-4,.grid-1-3,.grid-3-1,.grid-4{-moz-columns:4;columns:4}@supports (display:grid){[class*=grid]{display:grid;grid-gap:2rem;width:100%}.grid-2{grid-template-columns:repeat(2,[col] 1fr)}.grid-1-2,.grid-2-1,.grid-3{grid-template-columns:repeat(3,[col] 1fr)}.grid-1-3,.grid-3-1,.grid-4{grid-template-columns:repeat(4,[col] 1fr)}.grid-1-2>:nth-child(even){grid-column:2/span 2}.grid-2-1>:nth-child(odd){grid-column:1/span 2}.grid-1-3>:nth-child(even){grid-column:2/span 3}.grid-3-1>:nth-child(odd){grid-column:1/span 3}}}header .sr-only-focusable{left:1rem}nav ul{align-items:center;display:flex;list-style:none;margin:0;padding:0}nav a{padding:.5em 1em}nav a[aria-current]{border-bottom:.25em solid;color:hsl(var(--accent))}nav a[aria-current]:active,nav a[aria-current]:focus,nav a[aria-current]:hover{border-bottom:.25em solid}nav button[aria-current]{color:hsl(var(--accent))}nav>ul>li+li{margin-left:1rem}[id=breadcrumb] li:not(:last-child)::after{content:"→";speak:none}[id=pagination] li:first-child a::before{content:"← ";speak:none}[id=pagination] li:last-child a::after{content:" →";speak:none}[id=pagination] a{text-decoration:none}[id=pagination] a:focus,[id=pagination] a:hover{background:hsl(var(--contrast))}[id=pagination] [tabindex="-1"]{color:hsl(var(--muted));pointer-events:none}[id=pagination] [aria-current]{background:hsl(var(--accent));color:hsl(var(--contrast));pointer-events:none}.note{background:hsl(var(--contrast));border-left:1rem solid;color:hsl(var(--muted-dark));margin:1rem 0;padding:.5rem 1rem .25rem}.note :not(pre){color:inherit}.note.wip{color:hsl(var(--alert))}a[href^="#footnote"]::before{display:none}a[id^=footnote-][aria-describedby]{counter-increment:footnotes;text-decoration:none}a[id^=footnote-][aria-describedby]::after{content:"[" counter(footnotes) "]";vertical-align:super;font-size:.875em;font-weight:400;margin-left:2px;color:hsl(var(--accent));cursor:pointer}footer[id=footnotes]{max-width:75ch}[role=note]:target{animation:footnotes .5s var(--enter)}.tooltip{display:inline-block;position:relative}.tooltip button{margin:0}[role=tooltip]{--arrow: calc(100% - 0.25rem);background:hsl(var(--muted-dark));bottom:calc(100% + .5em);-webkit-clip-path:polygon(0% 0%,100% 0%,100% var(--arrow),calc(50% - .25rem) var(--arrow),50% 100%,calc(50% + .25rem) var(--arrow),0% var(--arrow));clip-path:polygon(0% 0%,100% 0%,100% var(--arrow),calc(50% - .25rem) var(--arrow),50% 100%,calc(50% + .25rem) var(--arrow),0% var(--arrow));color:hsl(var(--background));left:50%;opacity:0;margin:0;padding:.25em .5em .5em;pointer-events:none;position:absolute;transform-origin:50% calc(100% + 10px);transform:perspective(1000px) rotate3d(1,0,0,45deg) translateX(-50%);transition:opacity .2s var(--enter),transform .2s var(--enter),visibility 0s linear .2s;visibility:hidden;white-space:nowrap}.tooltip button:active+[role=tooltip],.tooltip button:focus+[role=tooltip],.tooltip button:hover+[role=tooltip],.tooltip:focus-within [role=tooltip]{opacity:1;pointer-events:auto;transform:perspective(1000px) rotate3d(1,0,0,0deg) translateX(-50%);transition:opacity .2s var(--exit),transform .2s var(--exit);visibility:visible}[role=alert]{border:1px solid var(--color);box-shadow:.25em .25em 0 0 var(--color);font-weight:700;margin:1rem .5rem;padding:0 1rem;text-shadow:.125em .125em 0 var(--color)}.bg-alert[role=alert]{--color: hsl(var(--alert-dark))}.bg-success[role=alert]{--color: hsl(var(--success-dark))}.bg-accent[role=alert]{--color: hsl(var(--accent-dark))}.bg-secondary[role=alert]{--color: hsl(var(--secondary-dark))}.card{--background: hsl(var(--contrast));--border: hsl(var(--muted-light));--color: hsl(var(--muted-dark));--shadow: hsla(var(--muted-dark), .25);--text-shadow: var(--background);background:var(--background);border:1px solid var(--border);border-radius:.25em;color:var(--color);display:flex;flex-direction:column;overflow:hidden;position:relative;transition:box-shadow .3s var(--enter)}.card:focus-within,.card:hover{box-shadow:0 0 0 .25rem var(--shadow)}.card-img{-webkit-clip-path:polygon(0 0,100% 0,100% 100%,0 80%);clip-path:polygon(0 0,100% 0,100% 100%,0 80%);height:6rem}.card-text{display:flex;flex-direction:column;flex-grow:1;margin-bottom:1rem;order:1;padding:0 1rem;text-shadow:.0625em .0625em 0 var(--text-shadow)}.card-text *{color:inherit;max-width:60ch}.card-text :last-child{margin-top:auto}.card-title{font-size:1.625em;line-height:1.2;text-shadow:.0769230769em .0769230769em 0 var(--text-shadow);margin:1rem 0!important}.card-link{text-decoration:none}.card-link::before{bottom:0;content:"";left:0;position:absolute;right:0;top:0}.card-link:hover,.card-link:visited{color:inherit}.card-link:focus{color:inherit;text-decoration:underline}.card:focus-within .card-link:focus{outline-color:transparent;text-decoration:none}.card-alert,.card-success{--color: hsl(var(--contrast));--text-shadow: var(--border)}.card-alert{--background: hsl(var(--alert));--border: hsl(var(--alert-dark));--shadow: hsla(var(--alert), .25)}.card-success{--background: hsl(var(--success));--border: hsl(var(--success-dark));--shadow: hsla(var(--success), .25)}.card-accent{--background: hsl(var(--accent));--border: hsl(var(--accent-dark));--shadow: hsla(var(--accent), .25)}.card-accent,.card-default,.card-secondary{--color: hsl(var(--contrast));--text-shadow: var(--border)}.card-default{--background: hsl(var(--default));--border: hsl(var(--default-dark));--shadow: hsla(var(--default), .25)}.card-secondary{--background: hsl(var(--secondary));--border: hsl(var(--secondary-dark));--shadow: hsla(var(--secondary), .25)}.fly-out,.fly-out ul{display:flex;flex-wrap:wrap;justify-content:space-between;list-style:none;margin:0;padding:0}.fly-out a,.fly-out button{background:hsl(var(--contrast));border:0;border-radius:0;color:hsl(var(--secondary));display:block;margin:0;outline:.125rem solid transparent;outline-offset:2rem;padding:.5rem 1rem;text-decoration:none;transition:outline-offset .3s var(--enter);white-space:nowrap}.fly-out a:active,.fly-out a:focus,.fly-out a:hover,.fly-out button:active,.fly-out button:focus,.fly-out button:hover{background:hsl(var(--background));border:0;color:hsl(var(--secondary-dark))}.fly-out a:focus,.fly-out button:focus{box-shadow:none;outline:.125rem solid currentColor;outline-offset:0}.fly-out>*{background:hsl(var(--contrast));margin:.5rem;position:relative;z-index:1}.fly-out>.focus-within,.fly-out>:hover{z-index:2}.fly-out>*>a:active,.fly-out>*>a:focus,.fly-out>*>a:hover,.fly-out>*>button:active,.fly-out>*>button:focus,.fly-out>*>button:hover{background:0 0}.fly-out>*>button{padding-right:1rem}.fly-out>*>button::after{content:"↓";display:inline-block;padding-left:.5rem;transition:transform .3s var(--enter) .5s;will-change:transform}.fly-out ul{align-items:flex-start;background:inherit;clip:rect(0,2rem,2rem,0);flex-direction:column;font-size:inherit;min-width:100%;padding-top:2.5em;position:absolute;top:0;transition:clip .3s var(--enter) .5s;will-change:clip;z-index:-1}.fly-out ul li{min-width:inherit}.fly-out ul a,.fly-out ul button{padding:.5rem 1rem}.fly-out>*>button:active+ul,.fly-out>*>button:focus+ul,.fly-out>*>button:hover+ul,.fly-out>.focus-within>ul,.fly-out>:hover>ul{box-shadow:.25em .25em 0 0 hsla(var(--muted-dark),.25);clip:auto;outline:1px solid hsl(var(--muted-light));transition:clip .3s var(--exit)}.fly-out>*>button:active::after,.fly-out>*>button:focus::after,.fly-out>*>button:hover::after,.fly-out>.focus-within>button::after,.fly-out>:hover>button::after{transform:rotateX(.5turn);transition:transform .3s var(--exit)}@supports ((-webkit-clip-path:circle(150% at top right)) or (clip-path:circle(150% at top right))){@media screen and (min-width:30em){.fly-out,.fly-out ul{justify-content:initial}.fly-out>:focus-within{z-index:2}.fly-out>:focus-within button{background:0 0}.fly-out ul{clip:auto;-webkit-clip-path:circle(1.125em at left top);clip-path:circle(1.125em at left top);transition:clip-path .3s var(--enter) .5s;transition:clip-path .3s var(--enter) .5s,-webkit-clip-path .3s var(--enter) .5s;will-change:clip-path}.fly-out>*>button:active+ul,.fly-out>*>button:focus+ul,.fly-out>*>button:hover+ul,.fly-out>:focus-within>ul,.fly-out>:hover>ul{box-shadow:.25em .25em 0 0 hsla(var(--muted-dark),.25);-webkit-clip-path:circle(150% at top right);clip-path:circle(150% at top right);outline:1px solid hsl(var(--muted-light));transition:clip-path .3s var(--exit);transition:clip-path .3s var(--exit),-webkit-clip-path .3s var(--exit)}.fly-out>:focus-within>button::after{transform:rotateX(.5turn);transition:transform .3s var(--exit)}}}button[role=switch]{background-color:hsla(var(--muted),.1);border-radius:1.375rem!important;box-sizing:content-box;color:hsl(var(--muted-dark));height:2.75rem;line-height:2.75rem;outline-color:transparent;padding:0 3rem;transition:all .3s var(--enter);width:4.75rem;will-change:background-color}button[role=switch]::before{background:currentColor;border-radius:1.375rem;content:"";position:absolute;height:2.375rem;left:.25rem;top:.25rem;transform:none;transition:transform .3s var(--enter) 0s;width:2.375rem;will-change:transform}button[role=switch]:active,button[role=switch]:focus,button[role=switch]:hover{background-color:hsla(var(--muted),.075);color:hsl(var(--contrast-inverse))}button[role=switch][aria-checked=true]{background-color:hsla(var(--success-light),.25)}button[role=switch][aria-checked=true]::before{background:hsl(var(--success-dark));transform:translateX(7.875rem)}button[role=switch][aria-checked=true]:focus{box-shadow:0 0 0 .125rem hsla(var(--success-dark),.25)}button[role=switch]>:first-child,button[role=switch][aria-checked=true]>:last-child{display:none}button[role=switch][aria-checked=true]>:first-child{display:block}.deck,.palette{display:grid;grid-gap:1rem;grid-template-columns:repeat(auto-fill,minmax(11.25rem,1fr));grid-auto-flow:dense}.deck [class*=card]{border:1px solid;flex-flow:column nowrap;height:calc(11.25rem*1.5);justify-content:space-between;min-width:unset;outline:1px dotted;outline-offset:-1.75rem;padding:1rem;text-align:center;width:11.25rem;z-index:0}.deck [class*=card] figcaption{margin:0 auto;max-width:calc(100% - 2.5rem);padding-bottom:0}.deck [class*=card] figcaption p{-webkit-hyphens:none;hyphens:none;line-height:1.2}.deck [class*=card] [class*="--l"]{border:.25rem solid currentColor;box-sizing:content-box;height:2rem;justify-content:center;margin:0 auto 0 0;width:2rem;z-index:2}.deck [class*=card]::after{content:"";display:flex;height:2.5rem;width:2.5rem}@supports (background:-moz-element(var(--card, 1))){.deck [class*=card]::after{background:-moz-element(var(--card, 1)) no-repeat bottom right;margin-left:auto;position:relative;z-index:2}}.palette figure{min-width:0;width:100%}.palette [class*=grid]{grid-gap:1rem}pre[data-line]{position:relative}.line-highlight{position:absolute;left:0;right:0;padding:.25em;margin-top:3.15em;background:#fff;mix-blend-mode:soft-light;pointer-events:none;line-height:inherit;white-space:pre}.line-highlight::before{content:attr(data-start);position:absolute;top:.4em;left:.5em;min-width:1ch;color:#000;font-weight:700}.mb-0{margin-bottom:0!important}.pb-0{padding-bottom:0!important}.fly-out [rel]::before{content:"🌍 "}@property --integer{syntax:"";initial-value:0;inherits:false}td,th{padding:.5rem .75rem;text-align:left}table strong,th{color:#000}td{line-height:1.25;max-width:100%}.table-container{background:linear-gradient(to right,#fff 30%,rgba(255,255,255,0)),linear-gradient(to right,rgba(255,255,255,0),#fff 70%) 0 100%,radial-gradient(farthest-side at 0% 50%,rgba(0,0,0,.2),transparent),radial-gradient(farthest-side at 100% 50%,rgba(0,0,0,.2),transparent) 0 100%;background-repeat:no-repeat;background-color:#fff;background-size:2.5rem 100%,2.5rem 100%,1rem 100%,1rem 100%;background-position:0 0,100%,0 0,100%;background-attachment:local,local,scroll,scroll;margin:2rem 0;max-width:100%;overflow-x:auto;overflow-y:hidden}.table-container .fieldset{display:none!important;padding:0 1rem}[class*=chaarts] [role=presentation]{display:none}[class*=chaarts] abbr[title]{border-bottom:0;font-size:small;font-weight:400;text-transform:none}.chaarts{caption-side:bottom;empty-cells:hide;margin:1.5em auto;overflow:hidden;padding:1em;--checkers: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3E%3Cg fill='%23ffffff99'%3E%3Cpath fill-rule='evenodd' d='M0 0h4v4H0V0zm4 4h4v4H4V4z'/%3E%3C/g%3E%3C/svg%3E");--hexagons: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='24' viewBox='0 0 28 49'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23ffffff99' fill-rule='nonzero'%3E%3Cpath d='M13.99 9.25l13 7.5v15l-13 7.5L1 31.75v-15l12.99-7.5zM3 17.9v12.7l10.99 6.34 11-6.35V17.9l-11-6.34L3 17.9zM0 15l12.98-7.5V0h-2v6.35L0 12.69v2.3zm0 18.5L12.98 41v8h-2v-6.85L0 35.81v-2.3zM15 0v7.5L27.99 15H28v-2.31h-.01L17 6.35V0h-2zm0 49v-8l12.99-7.5H28v2.31h-.01L17 42.15V49h-2z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");--triangles: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='16' viewBox='0 0 36 72'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23ffffff99'%3E%3Cpath d='M2 6h12L8 18 2 6zm18 36h12l-6 12-6-12z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");--zig: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='12' viewBox='0 0 20 12'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23ffffff99'%3E%3Cpath d='M9.8 12L0 2.2V.8l10 10 10-10v1.4L10.2 12h-.4zm-4 0L0 6.2V4.8L7.2 12H5.8zm8.4 0L20 6.2V4.8L12.8 12h1.4zM9.8 0l.2.2.2-.2h-.4zm-4 0L10 4.2 14.2 0h-1.4L10 2.8 7.2 0H5.8z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");--stripes: url("data:image/svg+xml,%3Csvg width='6' height='6' viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff99' fill-rule='evenodd'%3E%3Cpath d='M5 0h1L0 6V5zM6 5v1H5z'/%3E%3C/g%3E%3C/svg%3E");--dots: url("data:image/svg+xml,%3Csvg width='10' height='10' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff99' fill-rule='evenodd'%3E%3Ccircle cx='3' cy='3' r='3'/%3E%3Ccircle cx='13' cy='13' r='3'/%3E%3C/g%3E%3C/svg%3E")}.chaarts>caption:first-child{background:inherit;font-style:normal;padding:1rem 0}table:not(.chaarts) .sr-only,table:not(.chaarts) .visually-hidden{clip:auto!important;-webkit-clip-path:none!important;clip-path:none!important;height:auto!important;overflow:visible!important;position:static!important;width:auto!important;white-space:normal!important}@media screen and (min-width:30em){.chaarts{border-collapse:separate;contain:content}.chaarts:not([class*=radar]){border-spacing:0}.chaarts td,.chaarts th{border:0;padding:0}.chaarts td:empty,.chaarts th:empty{display:none!important}@supports (grid-template-columns:repeat(var(--scale, 100),minmax(0,1fr))){.bar-container .fieldset{display:flex!important}.chaarts.bar caption{text-align:initial;text-indent:13.5rem}.chaarts.bar tr{display:grid;grid-auto-rows:1fr;grid-row-gap:.5rem;grid-template-columns:minmax(min-content,12.5em) repeat(var(--scale, 100),minmax(0,1fr)) 10ch;transition:opacity .2s cubic-bezier(.5,0,.5,1)}.chaarts.bar tr:nth-child(n+1){--background: var(--checkers)}.chaarts.bar tr:nth-child(2n+2){--background: var(--hexagons)}.chaarts.bar tr:nth-child(3n+3){--background: var(--triangles)}.chaarts.bar tr:nth-child(4n+4){--background: var(--zig)}.chaarts.bar tr:nth-child(5n+5){--background: var(--stripes)}.chaarts.bar tr:nth-child(6n+6){--background: var(--dots)}.chaarts.bar th{grid-column:1/1;margin:.5rem 0 0;padding:0 1rem 0 0;text-align:right}.chaarts.bar td{--size: calc(var(--scale, 100) * 100%);--position: calc(var(--value, 0) / var(--scale, 100) * 100%);background:linear-gradient(to right,#01ac49,#444,mediumblue,rebeccapurple,crimson) var(--position) 0%/var(--size) 100%,var(--background) center/contain;background-blend-mode:hard-light;grid-column:2/var(--value, 0);margin:.5rem 0 0;position:relative}.chaarts.bar span{font-weight:700;left:100%;line-height:1.5;position:absolute}@supports ((-webkit-background-clip:text) or (background-clip:text)) or (-webkit-background-clip:text){.chaarts.bar span{background:inherit;-webkit-background-clip:text;background-clip:text;color:transparent}}.chaarts.bar:hover tr{opacity:.5}.chaarts.bar:hover tr:hover{opacity:1}@media screen and (min-width:30em) and (-ms-high-contrast:active){.chaarts.bar td{background-image:linear-gradient(to right,Window,ButtonFace,ButtonShadow,ButtonText,highlight),var(--background)}}.chaarts.bar.waterfall tr:nth-of-type(1) td{grid-column:var(--0, 2) / var(--value, 2)}.chaarts.bar.waterfall tr:nth-of-type(2) td{grid-column:var(--1, 2) / var(--value, 2)}.chaarts.bar.waterfall tr:nth-of-type(3) td{grid-column:var(--2, 2) / var(--value, 2)}.chaarts.bar.waterfall tr:nth-of-type(4) td{grid-column:var(--3, 2) / var(--value, 2)}.chaarts.bar.waterfall tr:nth-of-type(5) td{grid-column:var(--4, 2) / var(--value, 2)}.chaarts.bar.waterfall tr:nth-of-type(6) td{grid-column:var(--5, 2) / var(--value, 2)}.chaarts.bar.waterfall tr:nth-of-type(7) td{grid-column:var(--6, 2) / var(--value, 2)}.chaarts.bar.waterfall tr:nth-of-type(8) td{grid-column:var(--7, 2) / var(--value, 2)}.chaarts.bar.waterfall tr:nth-of-type(9) td{grid-column:var(--8, 2) / var(--value, 2)}.chaarts.bar.waterfall tr:nth-of-type(10) td{grid-column:var(--9, 2) / var(--value, 2)}.chaarts.bar.waterfall tr:nth-of-type(11) td{grid-column:var(--10, 2) / var(--value, 2)}}@supports ((-webkit-clip-path:polygon(50% calc(50% + (var(--gt-25, 0))))) or (clip-path:polygon(50% calc(50% + (var(--gt-25, 0)))))){.pie-container .fieldset{display:flex!important;margin-bottom:0}.chaarts.pie{--radius: 32em;margin:0 auto;padding-top:calc(var(--radius) - 2rem);position:relative}.chaarts.pie tbody{display:table-row}.chaarts.pie tr{display:table-cell;transition:opacity .3s cubic-bezier(.5,0,.5,1)}.chaarts.pie [scope=row]{padding-right:.5rem}.chaarts.pie [scope=row]::before,.chaarts.pie td::before{background:var(--color, currentColor) var(--background);content:""}.chaarts.pie [scope=row]::before{display:inline-block;height:1rem;transform:translate3d(-.2rem,.1rem,0);width:1rem}.chaarts.pie td{--position: calc(var(--start, 0) * .01turn)}.chaarts.pie td::after,.chaarts.pie td::before{left:50%;position:absolute;top:calc(var(--radius)/2);transform-origin:center center}.chaarts.pie td::before{--zoom: .75;--part: calc( var(--value) * 3.6 );--main-angle: calc( var(--part) - ( 90 * ( var(--gt-25, 0) + var(--gt-50, 0) + var(--gt-75, 0) ) ) );--β: calc( var(--main-angle) * 0.01745329251 );--α: calc( ( 90 - var(--main-angle) ) * 0.01745329251 );--sin-term-β-1: var(--β);--sin-term-β-2: calc((var(--β) * var(--β) * var(--β)) / 6);--sin-term-β-3: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 120);--sin-term-β-4: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 5040);--sin-term-β-5: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 362880);--sin-β: calc(var(--sin-term-β-1) - var(--sin-term-β-2) + var(--sin-term-β-3) - var(--sin-term-β-4) + var(--sin-term-β-5));--sin-term-α-1: var(--α);--sin-term-α-2: calc((var(--α) * var(--α) * var(--α)) / 6);--sin-term-α-3: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 120);--sin-term-α-4: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 5040);--sin-term-α-5: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 362880);--sin-α: calc(var(--sin-term-α-1) - var(--sin-term-α-2) + var(--sin-term-α-3) - var(--sin-term-α-4) + var(--sin-term-α-5));--pos-B: calc( var(--sin-β) * 50 );--pos-A: calc( var(--sin-α) * 50 );--polygon: polygon( - 50% 50%, - 50% 0%, - 100% 0%, - calc( 50% + ( var(--pos-B) * 1% * var(--lt-25, 1) ) + ( var(--gt-25, 0) * 50% ) ) calc( 50% - ( var(--pos-A) * 1% * var(--lt-25, 1) ) ), - calc( 50% + ( var(--gt-25, 0) * 50% ) ) calc( 50% + ( var(--gt-25, 0) * 50% ) ), - calc( 50% + ( var(--pos-A) * 1% * var(--lt-50, 1) ) + ( var(--gt-50, 0) * 50% ) ) calc( 50% + ( var(--pos-B) * 1% * var(--lt-50, 1) ) + ( var(--gt-50, 0) * 50% ) ), - calc( 50% - ( var(--gt-50, 0) * 50% ) ) calc( 50% + ( var(--gt-50, 0) * 50% ) ), - calc( 50% - ( var(--pos-B) * 1% * var(--lt-75, 1) ) - ( var(--gt-75, 0) * 50% ) ) calc( 50% + ( var(--pos-A) * 1% * var(--lt-75, 1) ) ), - calc( 50% - ( var(--gt-75, 0) * 50% ) ) calc( 50% - ( var(--gt-75, 0) * 50% ) ), - calc( 50% - ( var(--pos-A) * 1% * var(--gt-75, 0) ) ) calc( 50% - ( var(--pos-B) * 1% * var(--gt-75, 0) ) ), - 50% 50% - );-webkit-clip-path:var(--polygon);clip-path:var(--polygon);height:var(--radius);--mask: radial-gradient( - circle at center, - #fff 0 calc(var(--radius) / 2), - transparent 0 - );-webkit-mask-image:var(--mask);mask-image:var(--mask);transform:translate3d(-50%,-50%,0) rotate(var(--position)) scale(var(--zoom));transition:transform .2s cubic-bezier(.5,0,.5,1);width:var(--radius)}.chaarts.pie tr:hover td::before{--zoom: .8}.chaarts.pie tr:nth-child(n+1){--background: var(--checkers)}.chaarts.pie tr:nth-child(2n+2){--background: var(--hexagons)}.chaarts.pie tr:nth-child(3n+3){--background: var(--triangles)}.chaarts.pie tr:nth-child(4n+4){--background: var(--zig)}.chaarts.pie tr:nth-child(5n+5){--background: var(--stripes)}.chaarts.pie tr:nth-child(6n+6){--background: var(--dots)}.chaarts.pie td::after{--arrow: calc(100% - 0.25rem);--axis: calc( var(--position) - .25turn + var(--value) * .005turn );--away: calc( var(--radius) / 2 - 1rem );--integer: calc(var(--value));background-color:#444;color:#fff;content:var(--term) " : " counter(value) " %";counter-reset:value var(--integer);opacity:0;padding:.5rem;pointer-events:none;transform-origin:50% calc(100% + 10px);transform:translate3d(-50%,-50%,0) rotate(var(--axis)) translate(var(--away)) rotate(calc(var(--axis)*-1)) perspective(1000px) rotate3d(1,0,0,45deg);transition:opacity .2s cubic-bezier(0,.5,.5,1),transform .2s cubic-bezier(0,.5,.5,1)}.chaarts.pie tbody:hover tr{opacity:.5}.chaarts.pie tbody:hover tr:hover{opacity:1}.chaarts.pie tbody:hover tr:hover td::after{opacity:1;transform:translate3d(-50%,-50%,0) rotate(var(--axis)) translate(var(--away)) rotate(calc(var(--axis)*-1)) perspective(1000px) rotate3d(1,0,0,0deg);transition:opacity .2s cubic-bezier(.5,0,1,.5),transform .2s cubic-bezier(.5,0,1,.5)}.chaarts.polar td::before{--zoom: 50;transform:translate3d(-50%,-50%,0) rotate(var(--position)) scale(calc((var(--zoom) + var(--value)/(100/var(--zoom)))/100))}.chaarts.polar td::after{--away: calc( ( var(--radius) / 2 ) - ( ( var(--radius) / 4 ) * ( ( 100 - var(--value) ) / 100 ) ) + 2.5rem )}.chaarts.polar tr:hover td::before{--zoom: 50}.chaarts.donut{--mask: radial-gradient( - circle at 50% calc(50% - 0.25rem), - transparent 0 var(--offset), - #fff calc(var(--offset) + 1px) 100% - );-webkit-mask-image:var(--mask);mask-image:var(--mask)}.chaarts.donut td::after{--away: calc( var(--radius) / 2 - 2.5rem )}@media screen and (min-width:30em) and (-ms-high-contrast:active){.chaarts.pie tbody tr ::before{background-color:Window}.chaarts.pie tbody tr:nth-of-type(odd) ::before{background-color:WindowText}}}@supports ((-webkit-clip-path:polygon(0% calc(100% - var(--1) * 100% / var(--y)))) or (clip-path:polygon(0% calc(100% - var(--1) * 100% / var(--y))))){.line-container .fieldset{display:flex!important}.chaarts.line{--offset: calc( ( 100% / var(--x) ) / 2 );--height: calc( 32em - 2rem );--bottom: calc( 100% - var(--height) );padding:var(--height) 0 1rem;position:relative;transition:background .3s cubic-bezier(.5,0,.5,1),color .3s cubic-bezier(.5,0,.5,1)}.chaarts.line::after{--scale: calc( ( 100% - (var(--y) * 1px) ) / var(--y) );background:repeating-linear-gradient(to bottom,white 0 var(--scale),rgba(0,0,0,.25) calc(var(--scale) + 1px));bottom:var(--bottom);top:0;width:100%;z-index:1}.chaarts.line tr::before,.chaarts.line::after{content:"";position:absolute}.chaarts.line [scope=row],.chaarts.line thead th:first-child{color:var(--color, currentColor);text-align:left}.chaarts.line [style]::before{bottom:var(--bottom);background:linear-gradient(to top,#00bfff,#dc143c 75%);--polygon: polygon( - 0% 100%, - calc((100% / var(--x) * 1)) 100%, - calc((100% / var(--x) * 1)) calc(100% - (var(--1) / var(--y) * 100%)), - calc((100% / var(--x) * 1) + var(--offset)) calc(100% - (var(--1) / var(--y) * 100%)), - calc((100% / var(--x) * 2) + var(--offset)) calc(100% - (var(--2) / var(--y) * 100%)), - calc((100% / var(--x) * 3) + var(--offset)) calc(100% - (var(--3) / var(--y) * 100%)), - calc((100% / var(--x) * 4) + var(--offset)) calc(100% - (var(--4) / var(--y) * 100%)), - calc((100% / var(--x) * 5) + var(--offset)) calc(100% - (var(--5) / var(--y) * 100%)), - calc((100% / var(--x) * 6) + var(--offset)) calc(100% - (var(--6) / var(--y) * 100%)), - calc((100% / var(--x) * 7) + var(--offset)) calc(100% - (var(--7) / var(--y) * 100%)), - calc((100% / var(--x) * 8) + var(--offset)) calc(100% - (var(--8) / var(--y) * 100%)), - calc((100% / var(--x) * 9) + var(--offset)) calc(100% - (var(--9) / var(--y) * 100%)), - calc((100% / var(--x) * 10) + var(--offset)) calc(100% - (var(--10) / var(--y) * 100%)), - calc((100% / var(--x) * 11) + var(--offset)) calc(100% - (var(--11) / var(--y) * 100%)), - calc((100% / var(--x) * 12) + var(--offset)) calc(100% - (var(--12) / var(--y) * 100%)), - 100% calc(100% - (var(--12) / var(--y) * 100%)), - 100% 100%, - 0% 100% - );-webkit-clip-path:var(--polygon);clip-path:var(--polygon);content:"";position:absolute;top:0;width:100%;z-index:2}.chaarts.line td,.chaarts.line th{background:#fff;font-weight:700;text-align:center;width:calc(100%/var(--x))}.chaarts.line [scope=col]:not(:first-child)::after{background:white var(--stripes);background-blend-mode:exclusion;bottom:4rem;content:"";height:calc(100% - 4rem);left:calc(100%/var(--x)*var(--index));mix-blend-mode:soft-light;opacity:0;position:absolute;transition:opacity .3s cubic-bezier(.5,0,.5,1);width:inherit;z-index:3}.chaarts.line [scope=col]:nth-child(2)::after{--index: 1}.chaarts.line [scope=col]:nth-child(3)::after{--index: 2}.chaarts.line [scope=col]:nth-child(4)::after{--index: 3}.chaarts.line [scope=col]:nth-child(5)::after{--index: 4}.chaarts.line [scope=col]:nth-child(6)::after{--index: 5}.chaarts.line [scope=col]:nth-child(7)::after{--index: 6}.chaarts.line [scope=col]:nth-child(8)::after{--index: 7}.chaarts.line [scope=col]:nth-child(9)::after{--index: 8}.chaarts.line [scope=col]:nth-child(10)::after{--index: 9}.chaarts.line [scope=col]:nth-child(11)::after{--index: 10}.chaarts.line [scope=col]:nth-child(12)::after{--index: 11}.chaarts.line [scope=col]:nth-child(13)::after{--index: 12}.chaarts.line [scope=col]:hover::after{opacity:.75}.chaarts.line td{--value: var(--1);--term: var(--t-1);line-height:1.5}.chaarts.line td::before{content:"";height:1.5rem;position:absolute;transform:translateX(-50%);width:inherit;z-index:10}.chaarts.line td::after{--arrow: calc(100% - 0.25rem);--top: calc( var(--height) - ( var(--value) / var(--y) * var(--height) ) );--polygon: polygon( - 0% 0%, - 100% 0%, - 100% var(--arrow), - calc(50% - 0.25rem) var(--arrow), - 50% 100%, - calc(50% + 0.25rem) var(--arrow), - 0% var(--arrow) - );--integer: calc(var(--value));background-color:#444;-webkit-clip-path:var(--polygon);clip-path:var(--polygon);color:#fff;content:var(--term) " " var(--year) "\a" counter(value) " " var(--unit);counter-reset:value var(--integer);opacity:0;padding:.5rem;left:calc(var(--offset)*3);pointer-events:none;position:absolute;top:var(--top, 0);transform-origin:50% calc(100% + 10px);transform:translate3d(-50%,-125%,0) perspective(1000px) rotate3d(1,0,0,45deg);transition:opacity .2s cubic-bezier(0,.5,.5,1),transform .2s cubic-bezier(0,.5,.5,1);white-space:pre;z-index:5}.chaarts.line td+td::after,.chaarts.points [style] td+td::before{left:calc(100%/var(--x)*var(--index) + var(--offset))}.chaarts.line td:nth-child(2)::after{--value: var(--1);--term: var(--t-1);--index: 1}.chaarts.line td:nth-child(3)::after{--value: var(--2);--term: var(--t-2);--index: 2}.chaarts.line td:nth-child(4)::after{--value: var(--3);--term: var(--t-3);--index: 3}.chaarts.line td:nth-child(5)::after{--value: var(--4);--term: var(--t-4);--index: 4}.chaarts.line td:nth-child(6)::after{--value: var(--5);--term: var(--t-5);--index: 5}.chaarts.line td:nth-child(7)::after{--value: var(--6);--term: var(--t-6);--index: 6}.chaarts.line td:nth-child(8)::after{--value: var(--7);--term: var(--t-7);--index: 7}.chaarts.line td:nth-child(9)::after{--value: var(--8);--term: var(--t-8);--index: 8}.chaarts.line td:nth-child(10)::after{--value: var(--9);--term: var(--t-9);--index: 9}.chaarts.line td:nth-child(11)::after{--value: var(--10);--term: var(--t-10);--index: 10}.chaarts.line td:nth-child(12)::after{--value: var(--11);--term: var(--t-11);--index: 11}.chaarts.line td:nth-child(13)::after{--value: var(--12);--term: var(--t-12);--index: 12}.chaarts.line td:hover::after{opacity:1;transform:translate3d(-50%,-125%,0) perspective(1000px) rotate3d(1,0,0,0deg);transition:opacity .2s cubic-bezier(.5,0,1,.5),transform .2s cubic-bezier(.5,0,1,.5)}.chaarts.points [style]::before{background:var(--color, currentColor) var(--background);--polygon: polygon( - calc((100% / var(--x) * 1) + var(--offset)) calc(100% - (var(--1) / var(--y) * 100%)), - calc((100% / var(--x) * 2) + var(--offset)) calc(100% - (var(--2) / var(--y) * 100%)), - calc((100% / var(--x) * 3) + var(--offset)) calc(100% - (var(--3) / var(--y) * 100%)), - calc((100% / var(--x) * 4) + var(--offset)) calc(100% - (var(--4) / var(--y) * 100%)), - calc((100% / var(--x) * 5) + var(--offset)) calc(100% - (var(--5) / var(--y) * 100%)), - calc((100% / var(--x) * 6) + var(--offset)) calc(100% - (var(--6) / var(--y) * 100%)), - calc((100% / var(--x) * 7) + var(--offset)) calc(100% - (var(--7) / var(--y) * 100%)), - calc((100% / var(--x) * 8) + var(--offset)) calc(100% - (var(--8) / var(--y) * 100%)), - calc((100% / var(--x) * 9) + var(--offset)) calc(100% - (var(--9) / var(--y) * 100%)), - calc((100% / var(--x) * 10) + var(--offset)) calc(100% - (var(--10) / var(--y) * 100%)), - calc((100% / var(--x) * 11) + var(--offset)) calc(100% - (var(--11) / var(--y) * 100%)), - calc((100% / var(--x) * 12) + var(--offset)) calc(100% - (var(--12) / var(--y) * 100%)), - calc((100% / var(--x) * 13) + var(--offset)) calc(100% - (var(--12) / var(--y) * 100%)), - 100% calc(100% - (var(--12) / var(--y) * 100%)), - 100% calc((100% + 0.25rem) - (var(--12) / var(--y) * 100%)), - calc((100% / var(--x) * 13) + var(--offset)) calc((100% + 0.25rem) - (var(--12) / var(--y) * 100%)), - calc((100% / var(--x) * 12) + var(--offset)) calc((100% + 0.25rem) - (var(--12) / var(--y) * 100%)), - calc((100% / var(--x) * 11) + var(--offset)) calc((100% + 0.25rem) - (var(--11) / var(--y) * 100%)), - calc((100% / var(--x) * 10) + var(--offset)) calc((100% + 0.25rem) - (var(--10) / var(--y) * 100%)), - calc((100% / var(--x) * 9) + var(--offset)) calc((100% + 0.25rem) - (var(--9) / var(--y) * 100%)), - calc((100% / var(--x) * 8) + var(--offset)) calc((100% + 0.25rem) - (var(--8) / var(--y) * 100%)), - calc((100% / var(--x) * 7) + var(--offset)) calc((100% + 0.25rem) - (var(--7) / var(--y) * 100%)), - calc((100% / var(--x) * 6) + var(--offset)) calc((100% + 0.25rem) - (var(--6) / var(--y) * 100%)), - calc((100% / var(--x) * 5) + var(--offset)) calc((100% + 0.25rem) - (var(--5) / var(--y) * 100%)), - calc((100% / var(--x) * 4) + var(--offset)) calc((100% + 0.25rem) - (var(--4) / var(--y) * 100%)), - calc((100% / var(--x) * 3) + var(--offset)) calc((100% + 0.25rem) - (var(--3) / var(--y) * 100%)), - calc((100% / var(--x) * 2) + var(--offset)) calc((100% + 0.25rem) - (var(--2) / var(--y) * 100%)), - calc((100% / var(--x) * 1) + var(--offset)) calc((100% + 0.25rem) - (var(--1) / var(--y) * 100%)) - );transition:opacity .3s cubic-bezier(.5,0,.5,1)}.chaarts.points [style] th::before{background:var(--color, currentColor) var(--background);content:"";display:inline-block;height:1rem;transform:translate3d(-.2rem,.1rem,0);width:1rem}.chaarts.points [style] td::before{--size: 1rem;--top: calc( var(--height) - ( var(--value) / var(--y) * var(--height) ) );background:var(--color, currentColor) var(--background);border:2px solid #fff;border-radius:50%;box-shadow:0 0 .25rem rgba(0,0,0,.5);content:"";height:var(--size);left:calc(var(--offset)*3);position:absolute;top:var(--top, 100);transform:translate3d(calc(var(--size)/-2),calc(var(--size)/-2),0);transition:opacity .3s cubic-bezier(.5,0,.5,1),transform .3s cubic-bezier(.5,0,.5,1);width:var(--size);z-index:4}.chaarts.points [style] td:nth-of-type(2)::before{--value: var(--2);--index: 2}.chaarts.points [style] td:nth-of-type(3)::before{--value: var(--3);--index: 3}.chaarts.points [style] td:nth-of-type(4)::before{--value: var(--4);--index: 4}.chaarts.points [style] td:nth-of-type(5)::before{--value: var(--5);--index: 5}.chaarts.points [style] td:nth-of-type(6)::before{--value: var(--6);--index: 6}.chaarts.points [style] td:nth-of-type(7)::before{--value: var(--7);--index: 7}.chaarts.points [style] td:nth-of-type(8)::before{--value: var(--8);--index: 8}.chaarts.points [style] td:nth-of-type(9)::before{--value: var(--9);--index: 9}.chaarts.points [style] td:nth-of-type(10)::before{--value: var(--10);--index: 10}.chaarts.points [style] td:nth-of-type(11)::before{--value: var(--11);--index: 11}.chaarts.points [style] td:nth-of-type(12)::before{--value: var(--12);--index: 12}.chaarts.points [style]:nth-child(n+1){--background: var(--checkers)}.chaarts.points [style]:nth-child(2n+2){--background: var(--hexagons)}.chaarts.points [style]:nth-child(3n+3){--background: var(--triangles)}.chaarts.points [style]:nth-child(4n+4){--background: var(--zig)}.chaarts.points [style]:nth-child(5n+5){--background: var(--stripes)}.chaarts.points [style]:nth-child(6n+6){--background: var(--dots)}.chaarts.points tbody:hover [style] td::before,.chaarts.points tbody:hover [style]::before{opacity:.25}.chaarts.points tbody:hover [style]:hover td::before,.chaarts.points tbody:hover [style]:hover::before{opacity:1}.chaarts.points tbody:hover [style]:hover td::before{transform:translate3d(calc(var(--size)/-2),calc(var(--size)/-2),0) scale(1.25)}.chaarts.points [scope=col]:not(:first-child)::after{mix-blend-mode:multiply}.chaarts.points [scope=col]:not(:first-child):hover::after{opacity:.5}@media screen and (min-width:30em) and (-ms-high-contrast:active){.chaarts.line [style]::before{background:linear-gradient(to top,ButtonHighlight,Highlight 75%)}}}@supports (display:contents){.column-container .fieldset{display:flex!important}.chaarts[class*=column]{--gap: 0.5rem;--size: calc(var(--scale, 100) * 100%);--width: calc(64em / var(--y) - 1rem);display:grid;grid-column-gap:var(--gap);max-height:64em;position:relative}.chaarts[class*=column] td,.chaarts[class*=column] th{margin:0}.chaarts[class*=column] tr>*+*{text-align:center}.chaarts[class*=column] tbody,.chaarts[class*=column] thead,.chaarts[class*=column] tr{display:contents}.chaarts[class*=column] caption{grid-column:1/span var(--y);grid-row:-1}.chaarts[class*=column] td{--integer: calc(var(--value));grid-row:calc(var(--scale, 100) + 2 - var(--integer))/-2;pointer-events:none;position:relative;transition:opacity .2s cubic-bezier(.5,0,.5,1)}.chaarts[class*=column] td:nth-of-type(1),.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(2){grid-column:2}.chaarts[class*=column] td:nth-of-type(2),.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(3){grid-column:3}.chaarts[class*=column] td:nth-of-type(3),.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(4){grid-column:4}.chaarts[class*=column] td:nth-of-type(4),.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(5){grid-column:5}.chaarts[class*=column] td:nth-of-type(5),.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(6){grid-column:6}.chaarts[class*=column] td:nth-of-type(6),.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(7){grid-column:7}.chaarts[class*=column] td:nth-of-type(7),.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(8){grid-column:8}.chaarts[class*=column] td:nth-of-type(8),.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(9){grid-column:9}.chaarts[class*=column] td:nth-of-type(9),.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(10){grid-column:10}.chaarts[class*=column] td:nth-of-type(10),.chaarts[class*=column].column-multiple thead tr+tr :nth-of-type(11){grid-column:11}.chaarts[class*=column] span{font-weight:700;bottom:100%;left:0;line-height:1.5;pointer-events:auto;position:absolute;right:0}@supports ((-webkit-background-clip:text) or (background-clip:text)) or (-webkit-background-clip:text){.chaarts[class*=column] span{background:inherit;-webkit-background-clip:text;background-clip:text;color:transparent}}.chaarts[class*=column].column-single{grid-auto-columns:1fr;grid-template-rows:2ex repeat(var(--scale, 100),minmax(0,.25rem)) minmax(min-content,2rem)}.chaarts[class*=column].column-single tbody th{grid-row:-6/-3;grid-column:1;line-height:1}.chaarts[class*=column].column-single thead *{grid-row:-2}.chaarts[class*=column].column-single td{--position: calc(var(--integer, 0) / var(--scale, 100) * 100%);background:linear-gradient(to top,#01ac49,#444,mediumblue,rebeccapurple,crimson) 0% var(--position)/100% var(--size),var(--background) center/1rem;background-blend-mode:hard-light}.chaarts[class*=column].column-single [scope=col]::after{background:whitesmoke var(--stripes);background-blend-mode:exclusion;bottom:4rem;content:"";mix-blend-mode:multiply;opacity:0;position:absolute;transition:opacity .3s cubic-bezier(.5,0,.5,1);top:1rem;width:var(--width);z-index:0}.chaarts[class*=column].column-single [scope=col]:hover::after{opacity:.5}.chaarts[class*=column].column-single [scope=col]:nth-child(2)::after{left:calc(1em + (var(--width)*1) + (var(--gap)*1))}.chaarts[class*=column].column-single [scope=col]:nth-child(3)::after{left:calc(1em + (var(--width)*2) + (var(--gap)*2))}.chaarts[class*=column].column-single [scope=col]:nth-child(4)::after{left:calc(1em + (var(--width)*3) + (var(--gap)*3))}.chaarts[class*=column].column-single [scope=col]:nth-child(5)::after{left:calc(1em + (var(--width)*4) + (var(--gap)*4))}.chaarts[class*=column].column-single [scope=col]:nth-child(6)::after{left:calc(1em + (var(--width)*5) + (var(--gap)*5))}.chaarts[class*=column].column-single [scope=col]:nth-child(7)::after{left:calc(1em + (var(--width)*6) + (var(--gap)*6))}.chaarts[class*=column].column-single td:nth-of-type(n+1){--background: var(--checkers)}.chaarts[class*=column].column-single td:nth-of-type(2n+2){--background: var(--hexagons)}.chaarts[class*=column].column-single td:nth-of-type(3n+3){--background: var(--triangles)}.chaarts[class*=column].column-single td:nth-of-type(4n+4){--background: var(--zig)}.chaarts[class*=column].column-single td:nth-of-type(5n+5){--background: var(--stripes)}.chaarts[class*=column].column-single td:nth-of-type(6n+6){--background: var(--dots)}@media screen and (min-width:30em) and (-ms-high-contrast:active){.chaarts[class*=column].column-single td{background-image:linear-gradient(to top,Window,ButtonFace,ButtonShadow,ButtonText,highlight),var(--background)}}.chaarts[class*=column].column-multiple{grid-template-columns:minmax(min-content,14ch) repeat(calc(var(--y) - 1),1fr);grid-template-rows:2ex repeat(var(--scale, 100),minmax(0,.25rem)) repeat(2,minmax(min-content,2rem))}.chaarts[class*=column].column-multiple span{background-image:none}.chaarts[class*=column].column-multiple tbody th{grid-row:-10/span 7}.chaarts[class*=column].column-multiple thead tr *{grid-row:-2;grid-column:1}.chaarts[class*=column].column-multiple thead tr :nth-of-type(2){grid-column:calc(4 - var(--span))/span var(--span)}.chaarts[class*=column].column-multiple thead tr :nth-of-type(3){grid-column:calc(6 - var(--span))/span var(--span)}.chaarts[class*=column].column-multiple thead tr :nth-of-type(4){grid-column:calc(8 - var(--span))/span var(--span)}.chaarts[class*=column].column-multiple thead tr :nth-of-type(5){grid-column:calc(10 - var(--span))/span var(--span)}.chaarts[class*=column].column-multiple thead tr :nth-of-type(6){grid-column:calc(12 - var(--span))/span var(--span)}.chaarts[class*=column].column-multiple thead tr+tr *{font-weight:400;grid-row:-3}.chaarts[class*=column].column-multiple tr:first-child [scope=col]:nth-child(even)::after{background:whitesmoke var(--stripes);background-blend-mode:exclusion;bottom:4rem;content:"";mix-blend-mode:multiply;opacity:.25;position:absolute;transition:opacity .3s cubic-bezier(.5,0,.5,1);top:calc(1rem + 2ex);width:calc(var(--width)*2 + var(--gap)/2 + 1px);z-index:0}.chaarts[class*=column].column-multiple tr:first-child [scope=col]:nth-child(2)::after{left:calc(14ch + 1em + (((var(--width)*2) + (var(--gap)/2) + 1px)*0) + (var(--gap)*1))}.chaarts[class*=column].column-multiple tr:first-child [scope=col]:nth-child(4)::after{left:calc(14ch + 1em + (((var(--width)*2) + (var(--gap)/2) + 1px)*2) + (var(--gap)*3))}.chaarts[class*=column].column-multiple tr:first-child [scope=col]:nth-child(6)::after{left:calc(14ch + 1em + (((var(--width)*2) + (var(--gap)/2) + 1px)*4) + (var(--gap)*5))}.chaarts[class*=column].column-multiple td{background-color:#e11a81;background-image:var(--zig);grid-row-end:-3}.chaarts[class*=column].column-multiple td:nth-of-type(2n+2){background:#0172f0 var(--triangles)}@media screen and (min-width:30em) and (-ms-high-contrast:active){.chaarts[class*=column].column-multiple td{background-color:Window}.chaarts[class*=column].column-multiple td:nth-of-type(2n+2){background-color:Highlight}}}@supports ((-webkit-clip-path:polygon(0% 0%, calc(100% - var(--1) * 100% / var(--scale)) 100%, 100% 100%)) or (clip-path:polygon(0% 0%, calc(100% - var(--1) * 100% / var(--scale)) 100%, 100% 100%))){.radar-container .fieldset{display:flex!important}.chaarts[class*=radar]{--radius: 12.8em;--unitless-radius: calc( 1024 / 16 / 5 );--size: calc( var(--radius) / var(--scale) );--part: calc( 360deg / var(--items) );--integer: calc(var(--scale));background-image:repeating-radial-gradient(circle at 50%,rgba(0,0,0,.2) 0 2px,transparent 0 calc(var(--size)*var(--step))),repeating-radial-gradient(circle at 50%,rgba(0,0,0,.1) 0 2px,transparent 0 var(--size));border:2px solid;border-radius:50%;contain:layout;counter-reset:scale var(--integer);height:calc(var(--radius)*2);margin:6rem auto 12rem;overflow:visible;position:relative;width:calc(var(--radius)*2)}.chaarts[class*=radar] caption{background:0 0;bottom:-10rem;position:absolute}.chaarts[class*=radar] [scope=col]{--away: calc( (var(--radius) * -1) - 50% );left:50%;margin:0;padding:0 1rem;position:absolute;top:50%;transform:translate3d(-50%,-50%,0) rotate(calc(var(--part)*var(--index, 1))) translate(var(--away)) rotate(calc(var(--part)*var(--index, 1)*-1))}.chaarts[class*=radar] tr>:nth-of-type(1){--index: 1}.chaarts[class*=radar] tr>:nth-of-type(2){--index: 2}.chaarts[class*=radar] tr>:nth-of-type(3){--index: 3}.chaarts[class*=radar] tr>:nth-of-type(4){--index: 4}.chaarts[class*=radar] tr>:nth-of-type(5){--index: 5}.chaarts[class*=radar] tr>:nth-of-type(6){--index: 6}.chaarts[class*=radar] tr>:nth-of-type(7){--index: 7}.chaarts[class*=radar] td{--skew: calc( 90deg - var(--part) );border-bottom:1px solid #8a2be2;height:50%;left:0;margin:0;position:absolute;top:0;transform:rotate(calc(var(--part)*var(--index, 1))) skew(var(--skew));transform-origin:100% 100%;width:50%}.chaarts[class*=radar] td:nth-of-type(1) span{--point: var(--1);--pos: calc( 100% - (var(--2) * 100% / (var(--scale) * var(--ratio) ) ) )}.chaarts[class*=radar] td:nth-of-type(2) span{--point: var(--2);--pos: calc( 100% - (var(--3) * 100% / (var(--scale) * var(--ratio) ) ) )}.chaarts[class*=radar] td:nth-of-type(3) span{--point: var(--3);--pos: calc( 100% - (var(--4) * 100% / (var(--scale) * var(--ratio) ) ) )}.chaarts[class*=radar] td:nth-of-type(4) span{--point: var(--4);--pos: calc( 100% - (var(--5) * 100% / (var(--scale) * var(--ratio) ) ) )}.chaarts[class*=radar] td:nth-of-type(5) span{--point: var(--5);--pos: calc( 100% - (var(--6) * 100% / (var(--scale) * var(--ratio) ) ) )}.chaarts[class*=radar] td:nth-of-type(6) span{--point: var(--6);--pos: calc( 100% - (var(--7) * 100% / (var(--scale) * var(--ratio) ) ) )}.chaarts[class*=radar] td:nth-of-type(7) span{--point: var(--7);--pos: calc( 100% - (var(--8) * 100% / (var(--scale) * var(--ratio) ) ) )}.chaarts[class*=radar] td::after,.chaarts[class*=radar] td::before{display:none}.chaarts[class*=radar] span{--opposite: calc( 180 - (90 + (90 - (360 / var(--items)))) );--angle: calc( var(--opposite) * 0.01745329251 );--sin-term-angle-1: var(--angle);--sin-term-angle-2: calc((var(--angle) * var(--angle) * var(--angle)) / 6);--sin-term-angle-3: calc((var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle)) / 120);--sin-term-angle-4: calc((var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle)) / 5040);--sin-term-angle-5: calc((var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle)) / 362880);--sin-angle: calc(var(--sin-term-angle-1) - var(--sin-term-angle-2) + var(--sin-term-angle-3) - var(--sin-term-angle-4) + var(--sin-term-angle-5));--hypo: calc( var(--unitless-radius) / var(--sin-angle) );--ratio: calc( var(--hypo) / var(--unitless-radius) );--polygon: polygon( - 100% var(--pos), - calc( 100% - ( var(--point) * 100% / var(--scale) ) ) 100%, - 100% 100% - );background:linear-gradient(to top left,#8a2be2 10%,#00008b 75%);-webkit-clip-path:var(--polygon);clip-path:var(--polygon);filter:drop-shadow(0 0 1rem indigo);height:100%;position:absolute;width:100%}.chaarts.radar [scope=col]::after{color:#639;display:block;font-size:small;font-weight:400}.chaarts.radar [scope=col]:nth-child(1)::after{--integer: calc(var(--1));counter-reset:value var(--integer);content:counter(value) " / " counter(scale)}.chaarts.radar [scope=col]:nth-child(2)::after{--integer: calc(var(--2));counter-reset:value var(--integer);content:counter(value) " / " counter(scale)}.chaarts.radar [scope=col]:nth-child(3)::after{--integer: calc(var(--3));counter-reset:value var(--integer);content:counter(value) " / " counter(scale)}.chaarts.radar [scope=col]:nth-child(4)::after{--integer: calc(var(--4));counter-reset:value var(--integer);content:counter(value) " / " counter(scale)}.chaarts.radar [scope=col]:nth-child(5)::after{--integer: calc(var(--5));counter-reset:value var(--integer);content:counter(value) " / " counter(scale)}.chaarts.radar [scope=col]:nth-child(6)::after{--integer: calc(var(--6));counter-reset:value var(--integer);content:counter(value) " / " counter(scale)}.chaarts.radar [scope=col]:nth-child(7)::after{--integer: calc(var(--7));counter-reset:value var(--integer);content:counter(value) " / " counter(scale)}.chaarts.radar-multiple{margin-bottom:12rem}.chaarts.radar-multiple tbody{-moz-columns:var(--areas);columns:var(--areas);vertical-align:bottom}.chaarts.radar-multiple [scope=row]{bottom:-8rem;height:2rem;left:1rem;position:absolute}.chaarts.radar-multiple [scope=row]::before{background:var(--color, currentColor);content:"";display:inline-block;height:1rem;margin-right:.25rem;transform:translate3d(0,.1rem,0);width:1rem}.chaarts.radar-multiple tr:nth-child(2) [scope=row]{left:calc(1rem + (100%/var(--areas))*1)}.chaarts.radar-multiple td{align-items:flex-end;border-color:var(--color, currentColor);display:flex;justify-content:flex-end;opacity:.5;pointer-events:none;z-index:0}.chaarts.radar-multiple td::after{color:var(--color, currentColor);display:block;font-size:small;font-weight:700;text-indent:-.5rem;transform:skew(calc(var(--skew)*-1)) rotate(calc(var(--part)*var(--index, 1)*-1));transform-origin:0 0;width:100%;white-space:nowrap}.chaarts.radar-multiple td:nth-of-type(1)::after{--integer: calc(var(--1));counter-reset:value var(--integer);content:counter(value);width:calc(var(--1) * 100% / var(--scale))}.chaarts.radar-multiple td:nth-of-type(2)::after{--integer: calc(var(--2));counter-reset:value var(--integer);content:counter(value);width:calc(var(--2) * 100% / var(--scale))}.chaarts.radar-multiple td:nth-of-type(3)::after{--integer: calc(var(--3));counter-reset:value var(--integer);content:counter(value);width:calc(var(--3) * 100% / var(--scale))}.chaarts.radar-multiple td:nth-of-type(4)::after{--integer: calc(var(--4));counter-reset:value var(--integer);content:counter(value);width:calc(var(--4) * 100% / var(--scale))}.chaarts.radar-multiple td:nth-of-type(5)::after{--integer: calc(var(--5));counter-reset:value var(--integer);content:counter(value);width:calc(var(--5) * 100% / var(--scale))}.chaarts.radar-multiple td:nth-of-type(6)::after{--integer: calc(var(--6));counter-reset:value var(--integer);content:counter(value);width:calc(var(--6) * 100% / var(--scale))}.chaarts.radar-multiple td:nth-of-type(7)::after{--integer: calc(var(--7));counter-reset:value var(--integer);content:counter(value);width:calc(var(--7) * 100% / var(--scale))}.chaarts.radar-multiple span{background:var(--color, currentColor);pointer-events:auto}@supports ((-webkit-mask-image:url()) or (mask-image:url())){.chaarts.radar-multiple span{--mask: radial-gradient(circle at bottom right, rgba(0,0,0,1), rgba(0,0,0,.5));-webkit-mask-image:var(--mask);mask-image:var(--mask)}}@media screen and (min-width:30em) and (hover:hover){.chaarts.radar-multiple td{opacity:.25;transition:opacity .2s cubic-bezier(.5,0,.5,1)}.chaarts.radar-multiple td::after{opacity:0;transition:inherit}.chaarts.radar-multiple tr:hover td{opacity:1;z-index:1}.chaarts.radar-multiple tr:hover td::after{opacity:inherit}}}} \ No newline at end of file +html{--neutral:0,0%;--treshold:60%;--hue:240;--analog:calc(var(--hue) + 30);--right:150;--wrong:calc(var(--right) + 180);--light-scale:1.61803398875;--lightness:30%;--brighter:calc(var(--lightness)*var(--light-scale));--darker:calc(var(--lightness)/var(--light-scale));--switch:calc((var(--lightness) - var(--treshold))*-100);--secondary:var(--hue),100%,var(--lightness);--secondary-dark:var(--hue),100%,var(--darker);--accent:var(--analog),50%,var(--lightness);--accent-dark:var(--analog),50%,var(--darker);--alert:var(--wrong),100%,var(--lightness);--alert-light:var(--wrong),100%,var(--brighter);--success:var(--right),100%,var(--lightness);--success-light:var(--right),100%,var(--brighter);--success-dark:var(--right),100%,var(--darker);--contrast:var(--neutral),var(--switch);--contrast-inverse:var(--neutral),calc(var(--switch)*-1);--muted:var(--neutral),var(--lightness);--muted-light:var(--neutral),var(--brighter);--muted-dark:var(--neutral),var(--darker);--background:var(--neutral),96%;--enter:cubic-bezier(0,.5,.5,1);--exit:cubic-bezier(.5,0,1,.5);--external:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M91.875 62H85v23H15V15h23V0H0v100h100V62z'/%3E%3Cpath d='M54 0v.627l17.787 17.85L52.701 38H38v24h24V49.799l20.773-20.337L99.374 46H100V0z'/%3E%3C/svg%3E");--select:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 59 47.5'%3E%3Cpath d='M29.414 37.657.344 8.586 8.828.102l20.586 20.584L50 .1l8.484 8.485-29.07 29.072'/%3E%3C/svg%3E");--invalid:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 125'%3E%3Cpath fill='hsl(var(--alert))' d='M74.749 11.109 50 35.858 25.251 11.109 11.109 25.251 35.858 50 11.109 74.749l14.142 14.142L50 64.142l24.749 24.749 14.142-14.142L64.142 50l24.749-24.749z'/%3E%3C/svg%3E");color-scheme:light dark}@media screen and (min-width:37.5em){html{--light-scale:1.25;--lightness:40%}}/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{-webkit-text-size-adjust:100%;line-height:1.15}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}pre{font-family:monospace,monospace;font-size:1em}a{background-color:#0000}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sup{top:-.5em}img{border-style:none}button{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button{overflow:visible}button{text-transform:none}[type=button],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}/*! PrismJS 1.11.0 +http://prismjs.com/download.html?themes=prism-dark&languages=markup+css+clike+javascript+bash+css-extras+git+json+markdown+php+php-extras+scss */.token.cdata,.token.comment,.token.doctype,.token.prolog,.token.punctuation{color:hsl(var(--background))}.namespace{opacity:.7}.token.boolean,.token.constant,.token.number,.token.property,.token.symbol,.token.tag{color:hsl(var(--success-light))}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:hsl(var(--contrast))}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:orange}.token.atrule,.token.attr-value,.token.keyword{color:hsl(var(--success-light))}.token.important,.token.regex{color:hsl(var(--alert-light))}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.deleted{color:hsl(var(--alert));text-decoration:line-through}html[lang]{box-sizing:border-box;overflow-y:scroll;overflow:-moz-scrollbars-vertical;position:relative;scroll-behavior:smooth}*,:after,:before{box-sizing:inherit}body{-webkit-font-smoothing:subpixel-antialiased;background:hsl(var(--background));color:hsl(var(--muted-dark));counter-reset:footnotes;font:normal 400 1em/1.5 sans-serif;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;overflow-x:hidden;position:relative;text-rendering:optimizeSpeed}::selection{background-color:hsl(var(--accent));color:hsl(var(--background));text-shadow:none}::placeholder{color:hsl(var(--muted))}body:hover [tabindex="-1"]:focus{outline-color:#0000}a{-webkit-text-decoration-skip:ink;color:hsl(var(--secondary));outline:.125rem solid #0000;outline-offset:2rem;text-decoration-skip-ink:auto;text-decoration-style:dotted;transition:outline-offset .3s var(--enter)}a:focus,a:hover{color:hsl(var(--secondary-dark))}a:active{opacity:.75;transition:none}main a:visited{color:hsl(var(--success-dark))}main a[target$=blank]:after{content:"";display:inline-block;margin:0 .25em 0 0}main a[target$=blank]:after{content:"🗗";margin:0 0 0 .25em}@supports((-webkit-mask-image:url()) or (mask-image:url())){main a[target$=blank]:after{background:currentColor;content:"";height:.625em;-webkit-mask-position:center center;mask-position:center center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;width:.625em}main a[target$=blank]:after{-webkit-mask-image:var(--external);mask-image:var(--external)}}code,pre,svg{max-width:100%}a svg,button svg{pointer-events:none}main{margin:0 auto;outline-color:#0000}@media screen and (prefers-reduced-motion:reduce){*{animation-duration:0s!important;scroll-behavior:auto!important;transition:none!important}}@media screen and (-ms-high-contrast:active){a svg,button svg{fill:Highlight;background:none;border-color:Highlight}}caption,dl,ol,p,pre,td,th,ul{font-size:1em;line-height:1.5;margin:1.5em 0}.h1,.h2,.h3,.h4,.h5,b,cite,h1,h2,h3,h4,h5,strong{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:hsl(var(--contrast-inverse));font-weight:700;text-rendering:optimizelegibility}.h1:first-child,.h2:first-child,.h3:first-child,.h4:first-child,.h5:first-child,b:first-child,cite:first-child,h1:first-child,h2:first-child,h3:first-child,h4:first-child,h5:first-child,strong:first-child{margin-top:0}.h1,h1{color:hsl(var(--secondary));font-size:2.875em;line-height:1.0434;margin:1.0434782609em 0 .5217391304em}.h1 strong,h1 strong{color:hsl(var(--muted-dark))}.h2,h2{color:hsl(var(--accent));font-size:2.5em;line-height:1.2;margin:1.2em 0 .6em}.h3,h3{color:hsl(var(--muted-dark));font-size:2.25em;line-height:1.3334;margin:1.3333333333em 0 .6666666667em}.h4,h4{font-size:1.875em;line-height:1.6;margin:1.6em 0 .8em}.h5,h5{font-size:1.625em;line-height:1.8462;margin:1.8461538462em 0 .9230769231em}div,li,p,table,td,th{word-wrap:break-word;-webkit-hyphens:auto;hyphens:auto}li,p{-ms-hyphenate-limit-chars:6 3 2;-ms-hyphenate-limit-lines:2;-ms-hyphenate-limit-last:always;-ms-hyphenate-limit-zone:8%;hyphenate-limit-chars:6 3 2;hyphenate-limit-lines:2;hyphenate-limit-last:always;hyphenate-limit-zone:8%}li ol,li p,li ul{margin-bottom:0;margin-top:0}abbr[aria-label]{border-bottom:1px dotted;cursor:help;text-decoration:none;text-transform:uppercase}.small,small{font-size:.875em}cite{color:hsl(var(--accent));font-style:normal}code,var{font:inherit;line-height:1}pre{word-wrap:normal;background:hsl(var(--muted-dark));border:0;border-radius:.25em;color:hsl(var(--contrast));direction:ltr;font-family:Fira Mono,Consolas,Monaco,Andale Mono,monospace;font-size:small;-webkit-hyphens:none;hyphens:none;line-height:1.5;overflow-x:auto;padding:2em 1em .5em;tab-size:4;text-align:left;white-space:pre;word-break:normal;word-spacing:normal}pre:before{background:hsl(var(--alert));border-radius:50%;box-shadow:1.5em 0 0 0 orange,3em 0 0 0 hsl(var(--success));content:"";display:block;height:1rem;transform:translateY(-1rem);width:1rem}:not(pre)>code,:not(pre)>var{border:1px solid;border-radius:.2em;color:hsl(var(--accent));display:inline-block;font-family:inherit;padding:.1em;white-space:nowrap}:not(pre)>var{background:hsl(var(--contrast));border-style:dashed;color:hsl(var(--accent-dark))}dl{margin:0}figure dl+figcaption{text-align:center}img[alt]{display:inline-block;font-size:0;max-width:100%;vertical-align:middle}img[alt]:not([src$=".svg"]){height:auto}img[alt]:after{background:hsl(var(--contrast));content:attr(alt) "\a" "— " attr(src);display:block;font-size:1rem;padding:.5rem;white-space:pre-wrap;width:100%}svg{fill:currentColor}figure{background:hsl(var(--contrast));margin:1rem auto;max-width:100%;overflow:hidden;padding:1rem}figure figcaption{display:block;font-size:.875em;padding:1rem 0}@media screen and (min-width:37.5em){figure{min-width:37.5em;width:min-content}figure img{min-width:min-content}[class*=columns] figure,[class*=grid] figure,li figure{min-width:0;width:auto}[class*=columns] figure img,[class*=grid] figure img,li figure img{min-width:0}}@media(inverted-colors){img{filter:invert(100%)}}@media screen and (-ms-high-contrast:active){img{filter:brightness(1) contrast(1) saturate(1.5)}}table{font-feature-settings:"tnum";border-collapse:collapse;caption-side:top;margin-bottom:1.5rem;vertical-align:top;width:100%}table>caption:first-child{font-style:italic;margin:0;padding:2.5rem 1rem}td,th{padding:.5rem .75rem;text-align:left}table strong,th{color:hsl(var(--contrast-inverse))}td{line-height:1.25;max-width:100%}tbody{border:1px solid hsl(var(--muted-dark))}thead{border:1px solid hsl(var(--contrast-inverse))}.table-container{background:linear-gradient(90deg,#fff 30%,#fff0),linear-gradient(90deg,#fff0,#fff 70%) 0 100%,radial-gradient(farthest-side at 0 50%,#0003,#0000),radial-gradient(farthest-side at 100% 50%,#0003,#0000) 0 100%;background-attachment:local,local,scroll,scroll;background-color:var(--contrast);background-position:0 0,100%,0 0,100%;background-repeat:no-repeat;background-size:2.5rem 100%,2.5rem 100%,1rem 100%,1rem 100%;max-width:100%;overflow-x:auto;overflow-y:hidden}details{border:.25em solid hsl(var(--contrast-inverse))}details+details{border-top-width:0}details summary{background:hsl(var(--muted-dark));color:hsl(var(--contrast));cursor:pointer;padding:1rem;transition:background .2s var(--enter)}details summary:focus,details summary:hover{background:hsl(var(--contrast-inverse))}details summary~*{margin:1.5rem 1rem 0}details[open] summary~*{animation:slide-down .5s var(--enter)}@keyframes slide-down{0%,50%{opacity:0;transform:translateY(1.5em)}}@media screen and (min-width:30em){@supports(--css:var(--iables )){.vertical{display:flex}.vertical details{flex:0;min-width:3.5em;overflow:hidden}.vertical details+details{border-width:.25em .25em .25em 0}.vertical details summary{float:left;min-height:20em;writing-mode:vertical-lr;writing-mode:sideways-lr}.vertical details summary~*{padding-left:3.5em}.vertical details summary~*>:first-child{margin-top:0}.vertical details[open]{flex:1}.vertical details[open] summary~*{animation:slide-in .5s var(--enter)}}}@keyframes slide-in{0%,50%{opacity:0;transform:translateX(-1.5em)}}label[for]{vertical-align:middle}button{border-radius:.25rem;font-family:inherit;font-size:1em;padding:.5rem}.fieldset,fieldset,form{max-width:37.5em}form>*+*{margin-top:3em}.fieldset,fieldset{border:0;margin:1rem auto 2rem;padding:0}.fieldset>div,.fieldset>p,fieldset>div,fieldset>p,legend:first-child{margin-bottom:inherit}legend:first-child{font-weight:700}label[for]{display:block}.button,button,label[for]{-webkit-appearance:none;appearance:none;cursor:pointer}form [disabled]{cursor:not-allowed}::-ms-clear{display:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration,[type=search]::-webkit-search-results-button,[type=search]::-webkit-search-results-decoration{display:none}.button,button{-webkit-appearance:none;appearance:none;background-color:hsl(var(--accent));border:1px solid hsl(var(--accent));border-radius:.25rem;color:hsl(var(--contrast));font-family:inherit;font-size:1em;line-height:1.5;margin:.5rem 0;padding:.5rem;transition:all .3s var(--move);vertical-align:middle;width:auto}.button:hover,button:hover{background-color:hsl(var(--accent-light));border:1px solid hsl(var(--accent-light))}.button:active,.button:focus,button:active,button:focus{background-color:hsl(var(--accent-dark));border:1px solid hsl(var(--accent-dark))}.button:focus,button:focus{box-shadow:0 0 0 .125rem hsla(var(--accent-light),.25);outline-color:#0000}.button:active,button:active{transform:translateY(.125rem)}.button[disabled],.button[disabled]:active,.button[disabled]:focus,.button[disabled]:hover,button[disabled],button[disabled]:active,button[disabled]:focus,button[disabled]:hover{background-color:hsl(var(--muted-dark));box-shadow:none;color:hsl(var(--background));cursor:not-allowed;pointer-events:none}.no-margin{margin:0!important}.no-padding{padding:0!important}.no-border{border:0!important}.no-list{list-style:none!important;padding:0}.no-event{pointer-events:none!important}.ml-auto{margin-left:auto!important}.no-background{background:none!important}.ml-1{margin-left:1rem!important}.p-relative{position:relative!important}.d-flex{align-items:center;display:flex!important;flex-wrap:wrap}.fw-400{font-weight:400!important}@media screen and (max-width:29.9375em){.sm-hidden{display:none!important}}[class*="--s"]{font-size:.875rem;line-height:1.5}[class*="--l"]{font-size:1.25rem;line-height:1.05}.sr-only{clip:rect(1px,1px,1px,1px)!important;border:0!important;clip-path:inset(50%)!important;height:1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:1px!important}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto!important;clip-path:none!important;height:auto!important;overflow:visible!important;white-space:normal!important;width:auto!important}body>*{background:hsla(var(--background),.75);margin:0 auto;max-width:64em;padding:1rem}[class*=columns]>*,[class*=grid]>*{display:inline-block;margin-bottom:2rem;max-width:100%}@media screen and (min-width:37.5em){[class*=columns],[class*=grid]{column-gap:2rem;orphans:1;widows:1}[class*=columns]>*,[class*=grid]>*{break-inside:avoid;page-break-inside:avoid}.grid-2{column-count:2}.grid-1-2,.grid-2-1,.grid-3{column-count:3}.grid-1-3,.grid-3-1,.grid-4{column-count:4}@supports(display:grid){[class*=grid]{grid-gap:2rem;display:grid;width:100%}.grid-2{grid-template-columns:repeat(2,[col] 1fr)}.grid-1-2,.grid-2-1,.grid-3{grid-template-columns:repeat(3,[col] 1fr)}.grid-1-3,.grid-3-1,.grid-4{grid-template-columns:repeat(4,[col] 1fr)}.grid-1-2>:nth-child(2n){grid-column:2/span 2}.grid-2-1>:nth-child(odd){grid-column:1/span 2}.grid-1-3>:nth-child(2n){grid-column:2/span 3}.grid-3-1>:nth-child(odd){grid-column:1/span 3}}}header .sr-only-focusable{left:1rem}nav ul{align-items:center;display:flex;list-style:none;margin:0;padding:0}nav a{padding:.5em 1em}nav a[aria-current]{color:hsl(var(--accent))}nav a[aria-current],nav a[aria-current]:active,nav a[aria-current]:focus,nav a[aria-current]:hover{border-bottom:.25em solid}nav button[aria-current]{color:hsl(var(--accent))}nav>ul>li+li{margin-left:1rem}.note{background:hsl(var(--contrast));border-left:1rem solid;color:hsl(var(--muted-dark));margin:1rem 0;padding:.5rem 1rem .25rem}.note :not(pre){color:inherit}@keyframes footnotes{0%{color:hsl(var(--secondary))}}[role=note]:target{animation:footnotes .5s var(--enter)}.tooltip{display:inline-block;position:relative}.tooltip button{margin:0}[role=tooltip]{--arrow:calc(100% - 0.25rem);background:hsl(var(--muted-dark));bottom:calc(100% + .5em);clip-path:polygon(0 0,100% 0,100% var(--arrow),calc(50% - .25rem) var(--arrow),50% 100%,calc(50% + .25rem) var(--arrow),0 var(--arrow));color:hsl(var(--background));left:50%;margin:0;opacity:0;padding:.25em .5em .5em;pointer-events:none;position:absolute;transform:perspective(1000px) rotateX(45deg) translateX(-50%);transform-origin:50% calc(100% + 10px);transition:opacity .2s var(--enter),transform .2s var(--enter),visibility 0s linear .2s;visibility:hidden;white-space:nowrap}.tooltip button:active+[role=tooltip],.tooltip button:focus+[role=tooltip],.tooltip button:hover+[role=tooltip],.tooltip:focus-within [role=tooltip]{opacity:1;pointer-events:auto;transform:perspective(1000px) rotateX(0deg) translateX(-50%);transition:opacity .2s var(--exit),transform .2s var(--exit);visibility:visible}.card{--background:hsl(var(--contrast));--border:hsl(var(--muted-light));--color:hsl(var(--muted-dark));--shadow:hsla(var(--muted-dark),.25);background:var(--background);border:1px solid var(--border);border-radius:.25em;color:var(--color);display:flex;flex-direction:column;overflow:hidden;position:relative;transition:box-shadow .3s var(--enter)}.card:focus-within,.card:hover{box-shadow:0 0 0 .25rem var(--shadow)}.fly-out,.fly-out ul{display:flex;flex-wrap:wrap;justify-content:space-between;list-style:none;margin:0;padding:0}.fly-out a,.fly-out button{background:hsl(var(--contrast));border:0;border-radius:0;color:hsl(var(--secondary));display:block;margin:0;outline:.125rem solid #0000;outline-offset:2rem;padding:.5rem 1rem;text-decoration:none;transition:outline-offset .3s var(--enter);white-space:nowrap}.fly-out a:active,.fly-out a:focus,.fly-out a:hover,.fly-out button:active,.fly-out button:focus,.fly-out button:hover{background:hsl(var(--background));border:0;color:hsl(var(--secondary-dark))}.fly-out a:focus,.fly-out button:focus{box-shadow:none;outline:.125rem solid currentColor;outline-offset:0}.fly-out>*{background:hsl(var(--contrast));margin:.5rem;position:relative;z-index:1}.fly-out>:hover{z-index:2}.fly-out>*>a:active,.fly-out>*>a:focus,.fly-out>*>a:hover,.fly-out>*>button:active,.fly-out>*>button:focus,.fly-out>*>button:hover{background:none}.fly-out>*>button{padding-right:1rem}.fly-out>*>button:after{content:"↓";display:inline-block;padding-left:.5rem;transition:transform .3s var(--enter) .5s;will-change:transform}.fly-out ul{clip:rect(0,2rem,2rem,0);align-items:flex-start;background:inherit;flex-direction:column;font-size:inherit;min-width:100%;padding-top:2.5em;position:absolute;top:0;transition:clip .3s var(--enter) .5s;will-change:clip;z-index:-1}.fly-out ul li{min-width:inherit}.fly-out ul a,.fly-out ul button{padding:.5rem 1rem}.fly-out>*>button:active+ul,.fly-out>*>button:focus+ul,.fly-out>*>button:hover+ul,.fly-out>:hover>ul{clip:auto;box-shadow:.25em .25em 0 0 hsla(var(--muted-dark),.25);outline:1px solid hsl(var(--muted-light));transition:clip .3s var(--exit)}.fly-out>*>button:active:after,.fly-out>*>button:focus:after,.fly-out>*>button:hover:after,.fly-out>:hover>button:after{transform:rotateX(.5turn);transition:transform .3s var(--exit)}@supports(clip-path:circle(150% at top right)){@media screen and (min-width:30em){.fly-out,.fly-out ul{justify-content:normal}.fly-out>:focus-within{z-index:2}.fly-out>:focus-within button{background:none}.fly-out ul{clip:auto;clip-path:circle(1.125em at left top);transition:clip-path .3s var(--enter) .5s;will-change:clip-path}.fly-out>*>button:active+ul,.fly-out>*>button:focus+ul,.fly-out>*>button:hover+ul,.fly-out>:focus-within>ul,.fly-out>:hover>ul{box-shadow:.25em .25em 0 0 hsla(var(--muted-dark),.25);clip-path:circle(150% at top right);outline:1px solid hsl(var(--muted-light));transition:clip-path .3s var(--exit)}.fly-out>:focus-within>button:after{transform:rotateX(.5turn);transition:transform .3s var(--exit)}}}button[role=switch]{background-color:hsla(var(--muted),.1);border-radius:1.375rem!important;box-sizing:initial;color:hsl(var(--muted-dark));height:2.75rem;line-height:2.75rem;outline-color:#0000;padding:0 3rem;transition:all .3s var(--enter);width:4.75rem;will-change:background-color}button[role=switch]:before{background:currentColor;border-radius:1.375rem;content:"";height:2.375rem;left:.25rem;position:absolute;top:.25rem;transform:none;transition:transform .3s var(--enter) 0s;width:2.375rem;will-change:transform}button[role=switch]:active,button[role=switch]:focus,button[role=switch]:hover{background-color:hsla(var(--muted),.075);color:hsl(var(--contrast-inverse))}button[role=switch][aria-checked=true]{background-color:hsla(var(--success-light),.25)}button[role=switch][aria-checked=true]:before{background:hsl(var(--success-dark));transform:translateX(7.875rem)}button[role=switch][aria-checked=true]:focus{box-shadow:0 0 0 .125rem hsla(var(--success-dark),.25)}button[role=switch]>:first-child,button[role=switch][aria-checked=true]>:last-child{display:none}button[role=switch][aria-checked=true]>:first-child{display:block}pre[data-line]{position:relative}.line-highlight{background:#fff;left:0;line-height:inherit;margin-top:3.15em;mix-blend-mode:soft-light;padding:.25em;pointer-events:none;position:absolute;right:0;white-space:pre}.line-highlight:before{color:#000;content:attr(data-start);font-weight:700;left:.5em;min-width:1ch;position:absolute;top:.4em}.mb-0{margin-bottom:0!important}.pb-0{padding-bottom:0!important}.fly-out [rel]:before{content:"🌍 "} \ No newline at end of file diff --git a/docs/css/styles.min.css.map b/docs/css/styles.min.css.map new file mode 100644 index 0000000..a08b02f --- /dev/null +++ b/docs/css/styles.min.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["../../node_modules/sseeeedd/src/scss/abstracts/_variables.scss","../../node_modules/sseeeedd/src/scss/vendors/_normalize.scss","../../node_modules/sseeeedd/src/scss/vendors/_prism.scss","../../node_modules/sseeeedd/src/scss/vendors/_dialog.scss","../../node_modules/sseeeedd/src/scss/vendors/_tabs.scss","../../node_modules/sseeeedd/src/scss/base/_base.scss","../../node_modules/sseeeedd/src/scss/base/_typography.scss","../../node_modules/sseeeedd/src/scss/base/_contents.scss","../../node_modules/sseeeedd/src/scss/base/_images.scss","../../node_modules/sseeeedd/src/scss/base/_tables.scss","../../node_modules/sseeeedd/src/scss/base/_details.scss","../../node_modules/sseeeedd/src/scss/base/_forms.scss","../../node_modules/sseeeedd/src/scss/base/_buttons.scss","../../node_modules/sseeeedd/src/scss/base/_helpers.scss","../../node_modules/sseeeedd/src/scss/layout/_base.scss","../../node_modules/sseeeedd/src/scss/layout/_grid.scss","../../node_modules/sseeeedd/src/scss/layout/_header.scss","../../node_modules/sseeeedd/src/scss/layout/_navigation.scss","../../node_modules/sseeeedd/src/scss/components/_breadcrumb.scss","../../node_modules/sseeeedd/src/scss/components/_pagination.scss","../../node_modules/sseeeedd/src/scss/components/_notes.scss","../../node_modules/sseeeedd/src/scss/components/_footnotes.scss","../../node_modules/sseeeedd/src/scss/components/_tooltips.scss","../../node_modules/sseeeedd/src/scss/components/_alerts.scss","../../node_modules/sseeeedd/src/scss/components/_cards.scss","../../node_modules/sseeeedd/src/scss/components/_fly-out.scss","../../node_modules/sseeeedd/src/scss/components/_switch.scss","../../node_modules/sseeeedd/src/scss/components/_deck.scss","../../node_modules/sseeeedd/src/scss/components/_palette.scss","../../_site/scss/vendors/_prism.scss","../../_site/scss/styles.scss"],"names":[],"mappings":"CAqCA,KAmBE,wBACA,iBACA,gBAEA,WACA,gCACA,aACA,kCAEA,6BACA,iBACA,wDACA,sDACA,4DAEA,gDACA,qDACA,kDACA,+CACA,oDACA,iDACA,8CACA,mDACA,gDACA,gDACA,qDACA,kDACA,0CACA,6DACA,0CACA,+CACA,4CACA,kCAQA,oCACA,mCACA,mCAIA,4QACA,keACA,wcACA,6NACA,4aACA,uOACA,oTACA,2PACA,mPASF,sCACE,KACE,oBACA,kBC1HJ,4EAUA,KACE,iBACA,8BAUF,KACE,SAOF,KACE,cAQF,GACE,cACA,eAWF,GACE,uBACA,SACA,iBAQF,IACE,gCACA,cAUF,EACE,+BAQF,YACE,mBACA,0BACA,iCAOF,SAEE,mBAQF,cAGE,gCACA,cAOF,MACE,cAQF,QAEE,cACA,cACA,kBACA,wBAGF,IACE,eAGF,IACE,WAUF,IACE,kBAWF,sCAKE,oBACA,eACA,iBACA,SAQF,aAEE,iBAQF,cAEE,oBAOF,gDAIE,0BAOF,wHAIE,kBACA,UAOF,4GAIE,8BAOF,SACE,2BAUF,OACE,sBACA,cACA,cACA,eACA,UACA,mBAOF,SACE,wBAOF,SACE,cAQF,6BAEE,sBACA,UAOF,kFAEE,YAQF,cACE,6BACA,oBAOF,yCACE,wBAQF,6BACE,0BACA,aAUF,QACE,cAOF,QACE,kBAUF,SACE,aAOF,SACE,aC3VF;AAAA,iJAOA,4BACA,4EAKC,6BAGD,WACC,WAGD,sFAMC,gCAGD,0FAMC,2BAGD,0GAMC,aAGD,+CAGC,gCAGD,8BAEC,8BAGD,6BAEC,iBAGD,cACC,kBAGD,cACC,YAGD,eACC,wBACC,6BAEF,0BCpEA,iEAEE,aAGF,OACE,sBACA,cACA,eACA,QACA,kCACA,WAEA,aACE,cAIJ,qBACE,wCACA,SACA,OACA,eACA,QACA,MACA,WAGF,cACE,cACA,cAEA,oBACE,+DChCJ,eACE,wBACA,gBAGF,WACE,+BACA,gCACA,cACA,eACA,qBACA,QJMO,KILP,0BAEA,+BACE,gCACA,0CACA,yCACA,4BAGF,kBACE,4BAGF,iBACE,uCACA,wBAIJ,gBACE,gCACA,0CACA,qBACA,QJlBO,KIoBP,8BACE,qCAGF,kCACE,aCjCJ,WACE,sBAGE,kBACA,kCAGF,kBACA,uBAGF,qBAGE,mBAGF,KACE,kCACA,6BACA,wBACA,mCACA,wHACA,kBACA,kBACA,4CACA,6BAOF,YACE,oCACA,6BACA,iBAOF,cACE,wBAeF,OACE,2BACA,iBACA,kBAQF,iCACI,4BAGJ,EACE,4BACA,oCACA,oBACA,6BACA,8BACA,2CAEA,gBAEE,iCAGF,SACE,YACA,gBAQF,eACE,+BAGF,kJAKE,WACA,qBACA,mBAGF,6BACE,aAGF,0BACE,YAGF,6BACE,aACA,mBAGF,+BACE,aAGF,gCACE,aAGF,8BACE,wBACA,aAGF,qBACE,qBACE,mBACA,oBACA,qBAEA,6BACE,yBASL,6BACC,oJAKE,wBACA,WACA,cACA,sBACA,4BACA,aAGF,0BACE,yBAGF,6BACE,2BAGF,gCACE,yBAGF,gCACE,uBAGF,qBACE,6BACE,wBAMR,QACE,mBACA,kBACA,kBAGF,mBAIE,eAGF,4BAEE,aAGF,iBAEE,oBAGF,KACE,cACA,4BAGF,mDACE,EACE,iCACA,2BACA,iCAQJ,8CACE,iBAEE,gBACA,uBACA,eAGF,KACE,2BACA,qBC/PJ,6BAQE,cACA,gBACA,eAGF,iFACE,mCACA,gBACA,mCACA,kCACA,kCAEA,ySACE,aAIJ,OAEE,4BACA,kBACA,mBACA,sCAGA,qBACE,6BAIJ,OAEE,yBACA,gBACA,gBACA,oBAIF,OAEE,6BACA,iBACA,mBACA,sCAIF,OAEE,kBACA,gBACA,oBAIF,OAEE,kBACA,mBACA,sCAIF,OAEE,kBACA,mBACA,uCAIF,yBAKE,aACA,qBAQF,QAGE,gCACA,4BACA,gCACA,4BACA,4BACA,wBACA,4BACA,wBACA,aACA,qBAIA,iBAGE,gBACA,aClHJ,WACE,cACA,kBACA,gBACA,mBACA,eACA,iBACA,kBACA,iBACA,UAEA,mBACE,8BACA,mBACA,eACA,gBACA,OACA,cACA,YACA,kBACA,MACA,WAGF,kBACE,kBAKJ,iBACE,yBACA,YACA,qBACA,yBAGF,aAEE,iBASF,KACE,yBACA,kBAIF,GACE,6CACA,mDACA,SAGF,SAEE,aACA,cAGF,IACE,kCACA,SACA,oBACA,2BACA,cACA,oEACA,gBACA,gBACA,aACD,WACC,gBACA,qBACA,gBACA,gBACA,kBACA,oBACA,iBAEA,YACE,6BACA,kBACA,4DAEA,WACA,cACA,YACA,4BACA,WAIJ,6BAEE,iBACA,mBACA,yBACA,qBACA,oBACA,aACA,mBAGF,cACE,gCACA,oBACA,8BAGF,MAEE,SAGF,MACE,gBAGF,OACE,kBAIA,UACE,WACA,WACA,gBAGF,UACE,aACA,gBAEA,kBACE,sBACA,WACA,OACA,eACA,6BAIJ,qBACE,kBC9IJ,SACE,qBACA,YACA,eACA,sBAEA,4BACE,YAIF,gBACE,gCACA,cACA,QACE,8BAGF,eACA,cACA,WACA,qBAIJ,IACE,kBAGF,OACE,gCACA,iBACA,eACA,gBACA,QRpBO,KQsBP,kBACE,cACA,iBACA,eAIJ,sCACE,OACE,UR9BY,OQ+BZ,kBAEA,WACE,sBAOF,uDACE,YACA,WAEA,mEACE,aAMR,wBACE,IACE,qBAIJ,8CACE,IACE,gDClFJ,MACE,yBACA,iBACA,6BACA,qBACA,WACA,mBAEA,0BACE,kBACA,SACA,oBAIJ,MAEE,qBACA,gBAGF,gBAEE,mCAGF,GACE,iBACA,eAGF,MACE,wCAGF,MACE,8CAWF,iBACE,WACE,kUAIF,4BACA,iCACA,4DACA,sCACA,gDACA,eACA,gBACA,kBC5DF,QACE,gDAEA,gBACE,mBAGF,gBACE,kCACA,2BACA,eACA,aACA,uCAEA,4CAEE,wCAGF,kBACE,qBAIJ,wBACE,sCAIJ,sBACE,OACE,UACA,6BAIJ,oCAOG,gCACC,UACE,aAEA,kBACE,OACA,gBACA,gBAEA,0BACE,iCAGF,0BACE,WACA,gBACA,yBACA,yBAEA,4BACE,mBAEA,0CACE,aAKN,wBACE,OAEA,kCACE,sCAQZ,oBACE,OACE,UACA,8BCtFJ,+BAIE,oBAGF,wBAGE,sBAGF,6BAIE,qBACA,oBACA,cACA,cAGF,wBAGE,UXJc,OWOhB,SACE,eAGF,mBAEE,SACA,sBACA,UAEA,kDAEE,sBAIJ,mBACE,gBACA,sBAGF,WACE,cAGF,iRAEE,gBACA,sCACA,8CACA,6BACA,uCACA,WAEA,iXACE,0CACA,yDAOF,wDAlBF,iRAmBI,eAQJ,sBACE,oBACA,yCAGF,yDAEE,+BACA,SACA,WAGF,kBACE,WAGF,sCAEE,qBAGF,4FAEE,wBAIA,+EACE,kBAGF,mDACE,yDACA,4BAGF,6DACE,qBAIJ,iBACE,mBAGF,uBACE,gBACA,kFAGF,SACE,gBACA,mBAMF,kFAEE,gBACA,eAGF,iCAEE,mBAMF,yBACE,cACA,yBACA,gBAGF,iBACE,wBASA,8bACE,oFAGF,sjBACE,sFACA,uDAGF,o0BACE,gBAGF,+pBACE,uFAWJ,YACE,aAGF,mBACE,aAIA,mLAIE,aCzMJ,uEACE,oCACA,oCACA,qBACA,2BACA,oBACA,cACA,gBACA,eACA,cACA,sBACA,iCACA,WACA,gBAEA,qGACE,0CACA,0CAGF,0XAGE,yCACA,yCAGF,qGACE,yDACA,4BAGF,qRAEE,+BAIA,mkBAIE,wCACA,gBACA,6BACA,mBACA,oBCrDN,WACE,oBAGF,YACE,qBAGF,WACE,oBAGF,SACE,2BACA,UAGF,UACE,+BAIA,gBACE,eAIJ,QACE,uBAGF,SACE,4BAGF,SACE,yBAGF,SACE,2BAGF,eACE,2BAGF,MACE,6BAGF,MACE,wBAGF,MACE,4BAGF,MACE,8BAGF,YACE,6BAGF,QACE,mBACA,wBACA,eAGF,SACE,yBAGF,WACE,kCAGF,WACE,+BAGF,aACE,uBACA,iCAGF,QACE,8BAGF,QACE,4BAGF,QACE,WAIF,SACE,uBACA,iBACA,uBACA,WAIF,yCACE,WACE,yBAKJ,gBACE,iBACA,gBAGF,eACE,kBACA,gBAGF,eACE,kBACA,iBAGF,gBACE,iBACA,iBACA,aAIF,OACE,mCAEA,wBAEE,6BAKH,WACC,mCADD,aACC,qCADD,YACC,oCADD,eACC,uCAKA,eACE,cAGF,0CAEE,cACA,YAMH,UACC,mCACA,2BAFD,YACC,qCACA,2BAFD,WACC,oCACA,2BAFD,cACC,uCACA,2BAKF,SACE,kBACA,iCAgCF,0BACC,oBACA,yCACA,gCACA,sBACA,2BACA,qBACA,6BACA,qBACA,8BAQD,mDAEC,qBACA,0BACA,uBACA,4BACA,sBACA,8BCzOD,OACE,yCACA,cACA,QdkBO,KcfL,UdcI,KeVR,mCAEE,qBACA,mBACA,eAGF,sCACE,+BAEE,gBACA,UACA,SAEA,mCACE,wBACA,mBAKF,mBAEE,QAHa,EACf,uCAEE,QAHa,EACf,uCAEE,QAHa,EAUjB,yBACE,cACE,aACA,cACA,WAIA,QACE,2CADF,4BACE,2CADF,4BACE,2CAQA,4BACE,qBAOF,2BACE,qBATF,4BACE,qBAOF,2BACE,uBClEV,0BACE,KhBoBO,KiBpBP,OACE,mBACA,aACA,gBACA,SACA,UAGF,MACE,iBAGF,oBACE,0BACA,yBAEA,+EAGE,0BAIJ,yBACE,yBAGF,aACE,YjBRK,KkBrBT,2CACE,YACA,oDCCI,aACA,WAGF,uCACE,aACA,WAIJ,kBACE,qBAEA,gDAEE,gCAIJ,gCACE,wBACA,oBAGF,+BACE,8BACA,2BACA,oBC9BJ,MACE,gCACA,uBACA,6BACA,cACA,0BAEA,iBACE,cAGF,UACE,wBCTJ,6BACE,aAGF,mCACE,4BACA,qBAEA,0CACE,mCACA,qBACA,iBACA,gBACA,gBACA,yBACA,eAIJ,qBACE,eAMF,qBACE,KACE,6BAIJ,mBACE,qCCjCF,SACE,qBACA,kBAEA,gBACE,SAIJ,eACE,8BACA,kCACA,yBACA,oJASA,6BACA,SACA,UACA,SACA,wBACA,oBACA,kBACA,uCACA,UACE,8DAGF,WACE,6EAGF,kBACA,mBAEA,qJAIE,UACA,oBACA,UACE,6DAGF,WACE,kDAEF,mBCzDJ,aACE,8BACA,wCACD,iBACA,kBACA,eACC,yCAID,sBACG,gCADH,wBACG,kCADH,uBACG,iCADH,0BACG,oCCRJ,MACE,mCACA,kCACA,gCACA,uCACA,iCACA,6BACA,+BACA,oBACA,mBACA,aACA,sBACA,gBACA,kBACA,uCAEA,+BAEE,sCAIJ,UACE,iDACA,YAGF,WACE,aACA,sBACA,YACA,cxBbO,KwBcP,QACA,eACA,iDAEA,aACE,cACA,eAGF,uBACE,gBAIJ,YACE,kBACA,gBACA,6DACA,yBAGF,WACE,qBAEA,mBACE,SACA,WACA,OACA,kBACA,QACA,MAGF,oCAEE,cAGF,iBACE,cACA,0BAGF,oCACE,4BACA,qBASH,YACC,gCACE,iCACF,8BACE,kCACA,6BALH,cACC,kCACE,mCACF,8BACE,oCACA,6BALH,aACC,iCACE,kCACF,8BACE,mCACA,6BALH,cACC,kCACE,mCACF,8BACE,oCACA,6BALH,gBACC,oCACE,qCACF,8BACE,sCACA,6BChFF,qBAEE,aACA,eACA,8BACA,gBACA,SACA,UAGF,2BAEE,gCACA,SACA,gBACA,4BACA,cACA,SACA,oCACA,oBACA,mBACA,qBACA,2CACA,mBAEA,uHAGE,kCACA,SACA,iCAGF,uCACE,gBACA,mCACA,iBAIJ,WACE,gCACA,aACA,kBACA,UAEA,yCAEE,UAKA,mIAGE,gBAIJ,kBACE,czBtDG,KyByDL,yBACE,YACA,qBACA,mBACA,0CACA,sBAIJ,YACE,uBACA,mBACA,4BACA,sBACA,kBACA,eACA,kBACA,kBACA,MACA,qCACA,iBACA,WAEA,eACE,kBAGF,iCAEE,mBAIJ,iIAKE,yDACA,UACA,0CACA,gCAGF,mKAKE,2BACA,qCAIJ,gDACE,oCAEI,qBAEE,wBAGF,wBACE,UAEA,+BACE,gBAIJ,YACE,UACA,sCACA,0CACA,sBAGF,iIAKE,yDACA,oCACA,0CACA,qCAGF,sCACE,2BACA,uCCxKR,oBACE,yCACA,kCACA,uBACA,6BACA,eACA,oBACA,4BACA,eACA,gCACA,cACA,6BAEA,4BACE,wBACA,uBACA,WACA,kBACA,gBACA,YACA,WACA,eACA,yCACA,eACA,sBAGF,+EAGE,2CACA,mCAGF,uCACE,kDAEA,+CACE,oCACA,+BAGF,6CACE,yDAIJ,sFAEE,aAGF,qDACE,cCrDJ,MACE,aACA,S3BmBO,K2BlBP,+DACA,qBAEA,oBACE,iBACA,wBACA,4BACA,8BACA,gBACA,mBACA,wBACA,Q3BOK,K2BNL,kBACA,eACA,UAEA,2BACE,WAGF,+BACE,cACA,8BACA,iBAEA,iCACE,aACA,gBAIJ,mCACE,iCACA,uBACA,YACA,uBACA,kBACA,WACA,UAGF,2BACE,WACA,aACA,cACA,aAWJ,oDACE,2BACE,+DACA,iBACA,kBACA,WChEN,SACE,aACA,S5BmBO,K4BlBP,+DACA,qBAEA,gBACE,YACA,WAGF,uBACE,S5BSK,K6BrBT,eACC,kBAGD,gBACC,kBACA,OACA,QACA,cACA,kBACA,gBACA,0BACA,oBACA,oBACA,gBAGD,wBACC,yBACA,kBACA,SACA,UACA,cACA,WACA,gBCpBD,MACC,2BAGD,MACC,4BAGD,uBACC","file":"styles.min.css"} \ No newline at end of file diff --git a/docs/histogramme.html b/docs/histogramme.html index 15b5dd5..795ebd3 100644 --- a/docs/histogramme.html +++ b/docs/histogramme.html @@ -1,142 +1,146 @@ - - - - - - Histogramme — chaarts - - - - - - - - - - - + + + + + + + Histogramme — chaarts + + + + + + + + + + + - +
    - - - - - + + +
    - -

    Histogramme

    - -

    - L’histogramme sert pour les distributions de valeurs. - La structure du tableau est tout à fait ordinaire, cependant sa mise en forme repose - sur display: grid; et surtout display: contents; pour - faciliter le placement des cellules — technique inspirée par - l’article - de Hidde De Vries More accessible markup with display: contents, - et clarifiée par l’article de - Ire Aderinokun How display: contents works. -

    - -

    Le principe de base est le même que le graphique en barre :

    -
      -
    1. - la première ligne de la grille est réservée pour afficher la valeur textuelle lorsqu’elle approche du haut de l’échelle, - avec une taille fixe de 2ex - — jetez un œil rudiments - concernant les unités CSS, documentés dans Every Layout par Andy Bell et Heydon Pickering ; -
    2. -
    3. - la fonction repeat() appliquée avec la variable --scale - permet de gérer une échelle dynamique ; -
    4. -
    5. - les conteneurs <thead>, <tbody> et <tr> - sont neutralisés dans la gestion de la grille à l’aide de display: contents ; -
    6. - chaque cellule est placée sur la grille en fonction de --value - — sa valeur, donc — sa couleur d’arrière-plan dépend également de - sa valeur ; -
    7. -
    8. - et finalement la valeur textuelle — contenue dans un élément - <span> — est positionnée en haut de la colonne - à l’aide de la même astuce que dans le graphique en barre. -
    9. -
    - -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Parts de marché navigateurs en France en janvier 2019
    NavigateurChromeFirefoxSafariEdgeIEAutres
    Parts de marché62 %15 %9 %5 %6 %3 %
    -
    - -
    - Le HTML -
    <table class="chaarts column" id="column" style="--y: 7;">
    +	

    Histogramme

    + +

    + L’histogramme sert pour les distributions de valeurs. + La structure du tableau est tout à fait ordinaire, cependant sa mise en forme repose + sur display: grid; et surtout display: contents; pour + faciliter le placement des cellules — technique inspirée par + l’article + de Hidde De Vries More accessible markup with display: contents, + et clarifiée par l’article de + Ire Aderinokun How display: contents works. +

    + +

    Le principe de base est le même que le graphique en barre :

    +
      +
    1. + la première ligne de la grille est réservée pour afficher la valeur textuelle lorsqu’elle approche du haut de + l’échelle, + avec une taille fixe de 2ex + — jetez un œil rudiments + concernant les unités CSS, documentés dans Every Layout par Andy Bell et Heydon + Pickering ; +
    2. +
    3. + la fonction repeat() appliquée avec la variable --scale + permet de gérer une échelle dynamique ; +
    4. +
    5. + les conteneurs <thead>, <tbody> et <tr> + sont neutralisés dans la gestion de la grille à l’aide de display: contents ; +
    6. +
    7. + chaque cellule est placée sur la grille en fonction de --value + — sa valeur, donc — sa couleur d’arrière-plan dépend également de + sa valeur ; +
    8. +
    9. + et finalement la valeur textuelle — contenue dans un élément + <span> — est positionnée en haut de la colonne + à l’aide de la même astuce que dans le graphique en barre. +
    10. +
    + +
    +
    +

    + Interrupteur
    + Permet de désactiver les styles sur le tableau suivant. +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Parts de marché navigateurs en France en janvier 2019
    NavigateurChromeFirefoxSafariEdgeIEAutres
    Parts de marché62 %15 %9 %5 %6 %3 %
    +
    + +
    + Le HTML + +
    <table class="chaarts column" id="column" style="--y: 7;">
       <caption id="caption-7">[…]</caption>
       <thead>
         <tr>
    @@ -154,10 +158,10 @@ 

    Histogramme

    </tbody> </table>
    -
    -
    - Le css -
    @supports (display: contents) {
    +	
    +
    + Le css +
    @supports (display: contents) {
       .chaarts[class*="column"] {
         --gap: .5rem;
         --size: calc(var(--scale, 100) * 100%);
    @@ -291,123 +295,126 @@ 

    Histogramme

    } }
    -
    - -

    Colonnes multiples

    - -

    - Pour disposer de deux valeurs pour chaque colonne principale, nous devons également - disposer de deux sous-titres. - Concrètement parlant : -

    - -
      -
    1. - on ajoute une seconde ligne dans l’entête <thead> : -
        -
      • - avec deux cellules d’entête de colonne <th scope="col"> - pour chaque cellule d’entête de colonne dans la première ligne d’entête ; -
      • -
      • - n’oublions pas d’ajouter un colspan="2" sur les cellules d’entête de - la première ligne pour faire correspondre la structure du tableau ; -
      • -
      • - et enfin ajouter un identifiant à chaque cellule d’entête - afin de les référencer sur les cellules de données concernées — à l’aide - de l’attribut headers, par exemple pour la première cellule : - headers="navigateur chrome annee chrome-2018" où chaque valeur est un - identifiant de cellule d’entête. -
      • -
      -
    2. -
    3. - Côté styles : -
        -
      • - les cellules d’entête de premier niveau doivent s’étendre sur deux colonnes de la grille, - comme le réclame leur attribut colspan pour la structure du tableau. Il est - malheureusement impossible d’utiliser la valeur d’un attribut dans une autre - propriété que content — sinon nous pourrions simplement écrire - grid-column: 2 / span attr(colspan); et ça serait magnifique… -
      • -
      • - mais non ! Ainsi, une variable --span est ajoutée sur <table>, - et doit correspondre à la valeur des attributs colspan cités plus tôt : - elle sert donc à étendre les entêtes de premier niveau sur le nombre de colonnes adéquat. -
      • -
      • - les couleurs et motifs ne sont plus appliqués en fonction - de chaque valeur, mais en fonction de chaque colonne — dans l’exemple, un élément - sur deux (puisque nous avons deux entrées par colonne). - Là aussi, si nous pouvions utiliser une valeur d’attribut ou une propriété personnalisée - dans un sélecteur, ce serait génial. Imaginez un peu - tbody td:nth-of-type(var(--span)n + var(--span)) ou encore - tbody td:nth-of-type(attr(colspan)n + attr(colspan)) ! -
      • -
      -
    4. -
    - -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Parts de marché navigateurs en France en janvier 2019
    NavigateurChromeFirefoxSafariEdgeIE
    Année2018201920182019201820192018201920182019
    Parts de marché49.6 %57 %11.74 %9.59 %21.53 %18.78 %3.72 %3.5 %4.46 %3.66 %
    -
    - -
    - Le HTML -
    <table class="chaarts column-multiple" id="column-multiple" style="--y: 11; --span: 2;">
    +	
    + +

    Colonnes multiples

    + +

    + Pour disposer de deux valeurs pour chaque colonne principale, nous devons également + disposer de deux sous-titres. + Concrètement parlant : +

    + +
      +
    1. + on ajoute une seconde ligne dans l’entête <thead> : +
        +
      • + avec deux cellules d’entête de colonne <th scope="col"> + pour chaque cellule d’entête de colonne dans la première ligne d’entête ; +
      • +
      • + n’oublions pas d’ajouter un colspan="2" sur les cellules d’entête de + la première ligne pour faire correspondre la structure du tableau ; +
      • +
      • + et enfin ajouter un identifiant à chaque cellule d’entête + afin de les référencer sur les cellules de données concernées — à l’aide + de l’attribut headers, par exemple pour la première cellule : + headers="navigateur chrome annee chrome-2018" où chaque valeur est un + identifiant de cellule d’entête. +
      • +
      +
    2. +
    3. + Côté styles : +
        +
      • + les cellules d’entête de premier niveau doivent s’étendre sur deux colonnes de la grille, + comme le réclame leur attribut colspan pour la structure du tableau. Il est + malheureusement impossible d’utiliser la valeur d’un attribut dans une autre + propriété que content — sinon nous pourrions simplement écrire + grid-column: 2 / span attr(colspan); et ça serait magnifique… +
      • +
      • + mais non ! Ainsi, une variable --span est ajoutée sur <table>, + et doit correspondre à la valeur des attributs colspan cités plus tôt : + elle sert donc à étendre les entêtes de premier niveau sur le nombre de colonnes adéquat. +
      • +
      • + les couleurs et motifs ne sont plus appliqués en fonction + de chaque valeur, mais en fonction de chaque colonne — dans l’exemple, un élément + sur deux (puisque nous avons deux entrées par colonne). + Là aussi, si nous pouvions utiliser une valeur d’attribut ou une propriété personnalisée + dans un sélecteur, ce serait génial. Imaginez un peu + tbody td:nth-of-type(var(--span)n + var(--span)) ou encore + tbody td:nth-of-type(attr(colspan)n + attr(colspan)) ! +
      • +
      +
    4. +
    + +
    +
    +

    + Interrupteur
    + Permet de désactiver les styles sur le tableau suivant. +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Parts de marché navigateurs en France en janvier 2019
    NavigateurChromeFirefoxSafariEdgeIE
    Année2018201920182019201820192018201920182019
    Parts de marché49.6 %57 %11.74 %9.59 %21.53 %18.78 %3.72 %3.5 %4.46 %3.66 %
    +
    + +
    + Le HTML + +
    <table class="chaarts column-multiple" id="column-multiple" style="--y: 11; --span: 2;">
       <caption id="caption-8">[…]</caption>
       <thead>
         <tr>
    @@ -429,10 +436,10 @@ 

    Colonnes multiples

    </tbody> </table>
    -
    -
    - Le css -
    @supports (display: contents) {
    +	
    +
    + Le css +
    @supports (display: contents) {
       .chaarts.column-multiple {
         grid-template-columns: minmax(min-content, 14ch) repeat(calc(var(--y) - 1), 1fr);
         grid-template-rows: 2ex repeat(var(--scale, 100), minmax(0, .25rem)) repeat(2, minmax(min-content, 2rem));
    @@ -503,17 +510,11 @@ 

    Colonnes multiples

    } }
    -
    - +
    + + - - - - - - - - - \ No newline at end of file + + diff --git a/docs/img/hypothenuse.jpg b/docs/img/hypothenuse.jpg index faff49e..91d3c6d 100644 Binary files a/docs/img/hypothenuse.jpg and b/docs/img/hypothenuse.jpg differ diff --git a/docs/img/pie-1.jpg b/docs/img/pie-1.jpg index 4a8a88e..8d81745 100644 Binary files a/docs/img/pie-1.jpg and b/docs/img/pie-1.jpg differ diff --git a/docs/img/pie-2.jpg b/docs/img/pie-2.jpg index 668ecff..1bee5fd 100644 Binary files a/docs/img/pie-2.jpg and b/docs/img/pie-2.jpg differ diff --git a/docs/img/pie-3.jpg b/docs/img/pie-3.jpg index 5174eea..b1dfad2 100644 Binary files a/docs/img/pie-3.jpg and b/docs/img/pie-3.jpg differ diff --git a/docs/index.html b/docs/index.html index 119df04..fdad2a0 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,158 +1,159 @@ - - - - - - chaarts - - - - - - - - - - - + + + + + + + chaarts + + + + + + + + + + + - +
    - - - - - + + +
    - -

    Chaarts

    - -

    - Every charts in this project relies solely on semantic markup - — <table> based — and a spread of - CSS variables carried by the tags. - No JavaScript required for display, and styles are - progressively enhanced depending on your browser's capabilities. -

    - -

    - Note : by virtue of the experimental - nature of these techniques and a solid foundation enhanced progressively, - I don't mention browser support for each example — but - it goes without saying that this is not magic, and only modern browsers handle this right, - with the notable exception of Edge - which does not (yet) support clip-path. - Other browsers display a properly styled table, and that's nice. -

    - -

    Accessibility

    - -

    - A major effort has been made to ensure accessibility. - As mentioned above, semantic and structured markup is a prerequisite - — but it's not enough. CSS - is being applied as gradually as possible, in order to guarantee - the best possible display of data for each user. -

    - -

    Accessible table

    - -

    Wakeup call :

    - -
      -
    • a table must start with a <caption>;
    • -
    • - header cells <th> must carry a scope attribute, - with a row or col value; -
    • -
    • - and you'll usually need to distinguish the head from the body through - <thead> and <tbody>; -
    • -
    • - for values with a unit : if you venture to use the - <abbr> element to use its abbreviated version, consider doubling the - title with the aria-label attribute — this will considerably - improve the interest for many users. -
    - -

    - For other useful tips, I warmly recommend reading - - Data Tables Inclusive Component by Heydon Pickering, - which is a real gold mine. -

    - -

    Patterns

    -

    - To distinguish the different areas other than by colour, an - svg - pattern is applied in - css - — you can find some of them on the - Hero Patterns website: -

    -
      -
    1. - in order to improve blending with background colors or gradients, the - background-blend-mode proerty is used with the hard-light value; -
    2. -
    3. - pattern's size and position depends directly on the value and scale of the chart, - depending on the type of chart; -
    4. -
    5. - in order not to embed too many external files, we use a - - technique proposed by Trys Mudford to include each - svg - in data URi in a css variable; - thus, a finite list of patterns is used in the theme, without ever repeating the svg. -
    6. -
    - -
    -

    What to encode?

    -

    - Taylor Hunt - a comprehensive article on optimizing past svg - in URi data. In summary, only the chevrons and the "#" character need to be encoded - in the css. - Don't bother with the other characters, their encoding seriously affects readability. -

    -
    - -
    .chaarts {
    +		

    Chaarts

    + +

    + Every charts in this project relies solely on semantic markup + — <table> based — and a spread of + CSS variables carried by the tags. + No JavaScript required for display, and styles are + progressively enhanced depending on your browser's capabilities. +

    + +

    + Note : by virtue of the experimental + nature of these techniques and a solid foundation enhanced progressively, + I don't mention browser support for each example — but + it goes without saying that this is not magic, and only modern browsers handle this right, + with the notable exception of Edge + which does not (yet) support clip-path. + Other browsers display a properly styled table, and that's nice. +

    + +

    Accessibility

    + +

    + A major effort has been made to ensure accessibility. + As mentioned above, semantic and structured markup is a prerequisite + — but it's not enough. CSS + is being applied as gradually as possible, in order to guarantee + the best possible display of data for each user. +

    + +

    Accessible table

    + +

    Wakeup call :

    + +
      +
    • a table must start with a <caption>;
    • +
    • + header cells <th> must carry a scope attribute, + with a row or col value; +
    • +
    • + and you'll usually need to distinguish the head from the body through + <thead> and <tbody>; +
    • +
    • + for values with a unit : if you venture to use the + <abbr> element to use its abbreviated version, consider doubling the + title with the aria-label attribute — this will considerably + improve the interest for many users. +
    • +
    + +

    + For other useful tips, I warmly recommend reading + + Data Tables Inclusive Component by Heydon Pickering, + which is a real gold mine. +

    + +

    Patterns

    +

    + To distinguish the different areas other than by colour, an + svg + pattern is applied in + css + — you can find some of them on the + Hero Patterns website: +

    +
      +
    1. + in order to improve blending with background colors or gradients, the + background-blend-mode proerty is used with the hard-light value; +
    2. +
    3. + pattern's size and position depends directly on the value and scale of the chart, + depending on the type of chart; +
    4. +
    5. + in order not to embed too many external files, we use a + + technique proposed by Trys Mudford to include each + svg + in data URi in a css variable; + thus, a finite list of patterns is used in the theme, without ever repeating the svg. +
    6. +
    + +
    +

    What to encode?

    +

    + Taylor Hunt + a comprehensive article on optimizing past svg + in URi data. In summary, only the chevrons and the "#" character need to be encoded + in the css. + Don't bother with the other characters, their encoding seriously affects readability. +

    +
    + +
    .chaarts {
       --stripes: url("data:image/svg+xml,%3Csvg width='6' height='6' viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff99' fill-rule='evenodd'%3E%3Cpath d='M5 0h1L0 6V5zM6 5v1H5z'/%3E%3C/g%3E%3C/svg%3E");
     }
     
    @@ -169,54 +170,53 @@ 

    What to encode?

    background-blend-mode: hard-light; }
    - -

    User preferences

    -

    - In order to respect as much as possible the preferences of the visitors, - many elements have been adapted: -

    -
      -
    1. - dimensions are in relatives units (em or rem as the case may be), - in order to fit coherently with the body of text inherited from the browser and to be able - to be enlarged or reduced without loss; -
    2. -
    3. - colors are adjusted when Windows High Contrast Mode is detected using - -ms-high-contrast: active, inspired by - - Greg Whitworth article on the topic. I also recommend you - - Test of System Colors Specified in CSS 2 rustproof page written by - Ian Graham, published in… 2000! -
    4. -
    5. - animations and transitions are disabled when the system exposes - this preference through prefers-reduced-motion: reduce ; -
    6. -
    7. - hover effects whose initial state consists in hiding content - are activated contextually in the @media (hover: hover) { … } media query. -
    8. -
    - -

    display and semantics

    -

    - Adrian Roselli explains that playing with a <table> or <dl> - element's display endangers its semantics. - The latter is therefoore "locked" using dedicated - aria - roles — as he explains - in a detailed article. -

    -

    - That's why each table is preceded by a switch — based on - Heydon Pickering - inclusive toggle button — - whose one and only role is to disable additional styles: -

    - -
    document.addEventListener("DOMContentLoaded", function() {
    +		

    User preferences

    +

    + In order to respect as much as possible the preferences of the visitors, + many elements have been adapted: +

    +
      +
    1. + dimensions are in relatives units (em or rem as the case may be), + in order to fit coherently with the body of text inherited from the browser and to be able + to be enlarged or reduced without loss; +
    2. +
    3. + colors are adjusted when Windows High Contrast Mode is detected using + -ms-high-contrast: active, inspired by + + Greg Whitworth article on the topic. I also recommend you + + Test of System Colors Specified in CSS 2 rustproof page written by + Ian Graham, published in… 2000! +
    4. +
    5. + animations and transitions are disabled when the system exposes + this preference through prefers-reduced-motion: reduce ; +
    6. +
    7. + hover effects whose initial state consists in hiding content + are activated contextually in the @media (hover: hover) { … } media query. +
    8. +
    + +

    display and semantics

    +

    + Adrian Roselli explains that playing with a <table> or <dl> + element's display endangers its semantics. + The latter is therefoore "locked" using dedicated + aria + roles — as he explains + in a detailed article. +

    +

    + That's why each table is preceded by a switch — based on + Heydon Pickering + inclusive toggle button — + whose one and only role is to disable additional styles: +

    + +
    document.addEventListener("DOMContentLoaded", function() {
       var switches = document.querySelectorAll('[role="switch"]');
     
       Array.prototype.forEach.call(switches, function(el, i) {
    @@ -230,21 +230,14 @@ 

    display and semantics

    }); });
    - -

    - Well, we're ready to get to the heart of the matter.
    - Warm up your dev tools! -

    - +

    + Well, we're ready to get to the heart of the matter.
    + Warm up your dev tools! +

    + + - - - - - - - - - \ No newline at end of file + + diff --git a/docs/js/prism.min.js b/docs/js/prism.min.js index f1acd79..65ac311 100644 --- a/docs/js/prism.min.js +++ b/docs/js/prism.min.js @@ -1 +1 @@ -"use strict";var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(l){var e,u=/\blang(?:uage)?-([\w-]+)\b/i,t=0,N={manual:l.Prism&&l.Prism.manual,disableWorkerMessageHandler:l.Prism&&l.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof j?new j(e.type,N.util.encode(e.content),e.alias):Array.isArray(e)?e.map(N.util.encode):e.replace(/&/g,"&").replace(/e.length)return;if(!(F instanceof j)){if(p&&b!=t.length-1){if(h.lastIndex=y,!(x=h.exec(e)))break;for(var w=x.index+(g?x[1].length:0),k=x.index+x[0].length,v=b,A=y,P=t.length;v"+n.content+"")},l.document)?(e=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop())&&(N.filename=e.src,N.manual||e.hasAttribute("data-manual")||("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(N.highlightAll):window.setTimeout(N.highlightAll,16):document.addEventListener("DOMContentLoaded",N.highlightAll))):l.addEventListener&&!N.disableWorkerMessageHandler&&l.addEventListener("message",function(e){var e=JSON.parse(e.data),t=e.language,n=e.code,e=e.immediateClose;l.postMessage(N.highlight(n,N.languages[t],t)),e&&l.close()},!1),N}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism),Prism.languages.markup={comment://,prolog:/<\?[\s\S]+?\?>/,doctype://i,cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/i,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/i,inside:{punctuation:[/^=/,{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(e,t){var n={},n=(n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:Prism.languages[t]},n.cdata=/^$/i,{"included-cdata":{pattern://i,inside:n}}),t=(n["language-"+t]={pattern:/[\s\S]+/,inside:Prism.languages[t]},{});t[e]={pattern:RegExp("(<__[\\s\\S]*?>)(?:\\s*|[\\s\\S])*?(?=<\\/__>)".replace(/__/g,e),"i"),lookbehind:!0,greedy:!0,inside:n},Prism.languages.insertBefore("markup","cdata",t)}}),Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,t=(e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+[\s\S]*?(?:;|(?=\s*\{))/,inside:{rule:/@[\w-]+/}},url:{pattern:RegExp("url\\((?:"+t.source+"|[^\n\r()]*)\\)","i"),inside:{function:/^url/i,punctuation:/^\(|\)$/}},selector:RegExp("[^{}\\s](?:[^{};\"']|"+t.source+")*?(?=\\s*\\{)"),string:{pattern:t,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css,e.languages.markup);t&&(t.tag.addInlined("style","css"),e.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:t.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:e.languages.css}},alias:"language-css"}},t.tag))}(Prism),Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/},Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|})\s*)(?:catch|finally)\b/,lookbehind:!0},{pattern:/(^|[^.])\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],number:/\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,function:/[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,operator:/-[-=]?|\+[+=]?|!=?=?|<>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=\s*($|[\r\n,.;})\]]))/,lookbehind:!0,greedy:!0},"function-variable":{pattern:/[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)?\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=>)/i,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*)\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|[^\\`])*`/,greedy:!0,inside:{interpolation:{pattern:/\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/,inside:{"interpolation-punctuation":{pattern:/^\${|}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.js=Prism.languages.javascript,Prism.languages.css.selector={pattern:Prism.languages.css.selector,inside:{"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-:.\w]+/,id:/#[-:.\w]+/,attribute:{pattern:/\[(?:[^[\]"']|("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1)*\]/,greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)[-*\w\xA0-\uFFFF]*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},attribute:{pattern:/^(\s*)[-\w\xA0-\uFFFF]+/,lookbehind:!0},value:[/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,{pattern:/(=\s*)[-\w\xA0-\uFFFF]+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],punctuation:/[()]/}},Prism.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*/i,lookbehind:!0}}),Prism.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:/#[\da-f]{3,8}/i,entity:/\\[\da-f]{1,8}/i,unit:{pattern:/(\d)(?:%|[a-z]+)/,lookbehind:!0},number:/-?[\d.]+/}),Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-]+(?:\([^()]+\)|[^(])*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()]|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}]+[:{][^}]+))/m,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[\w-]|\$[-\w]+|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),Prism.languages.insertBefore("scss","atrule",{keyword:[/@(?:if|else(?: if)?|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)/i,{pattern:/( +)(?:from|through)(?= )/,lookbehind:!0}]}),Prism.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),Prism.languages.insertBefore("scss","function",{placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:true|false)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/,lookbehind:!0}}),Prism.languages.scss.atrule.inside.rest=Prism.languages.scss,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t]+.+)*/m,lookbehind:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,inside:{atrule:/(?:@[\w-]+|[+=])/m}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|or|not)\b/,{pattern:/(\s+)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s]+.*)/m,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/([ \t]*)\S(?:,?[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,?[^,\r\n]+)*)*/,lookbehind:!0}})}(Prism),function(){var n,r;function s(e,t){return Array.prototype.slice.call((t||document).querySelectorAll(e))}function i(e,t){return t=" "+t+" ",-1<(" "+e.className+" ").replace(/[\n\t]/g," ").indexOf(t)}function a(e){e()}function o(l,e,u){var t,e=(e="string"==typeof e?e:l.getAttribute("data-line")).replace(/\s+/g,"").split(","),c=+l.getAttribute("data-line-offset")||0,d=(void 0===n&&((t=document.createElement("div")).style.fontSize="13px",t.style.lineHeight="1.5",t.style.padding=0,t.style.border=0,t.innerHTML=" 
     ",document.body.appendChild(t),n=38===t.offsetHeight,document.body.removeChild(t)),(n?parseInt:parseFloat)(getComputedStyle(l).lineHeight)),g=i(l,"line-numbers"),p=!g&&l.querySelector("code")||l,m=[];return e.forEach(function(e){var t,n,a,s=e.split("-"),r=+s[0],i=+s[1]||r,o=l.querySelector('.line-highlight[data-range="'+e+'"]')||document.createElement("div");m.push(function(){o.setAttribute("aria-hidden","true"),o.setAttribute("data-range",e),o.className=(u||"")+" line-highlight"}),g&&Prism.plugins.lineNumbers?(s=Prism.plugins.lineNumbers.getLine(l,r),t=Prism.plugins.lineNumbers.getLine(l,i),s&&(n=s.offsetTop+"px",m.push(function(){o.style.top=n})),t&&(a=t.offsetTop-s.offsetTop+t.offsetHeight+"px",m.push(function(){o.style.height=a}))):m.push(function(){o.setAttribute("data-start",r),re.length)return;if(!(w instanceof r)){if(f&&F!=t.length-1){if(g.lastIndex=v,!(S=g.exec(e)))break;for(var k=S.index+(m?S[1].length:0),A=S.index+S[0].length,P=F,x=v,$=t.length;P<$&&(x"+n.content+""},!e.document)return e.addEventListener&&(a.disableWorkerMessageHandler||e.addEventListener("message",(function(t){var n=JSON.parse(t.data),r=n.language,s=n.code,i=n.immediateClose;e.postMessage(a.highlight(s,a.languages[r],r)),i&&e.close()}),!1)),a;var s=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return s&&(a.filename=s.src,a.manual||s.hasAttribute("data-manual")||("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(a.highlightAll):window.setTimeout(a.highlightAll,16):document.addEventListener("DOMContentLoaded",a.highlightAll))),a}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism),Prism.languages.markup={comment://,prolog:/<\?[\s\S]+?\?>/,doctype://i,cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/i,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/i,inside:{punctuation:[/^=/,{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:Prism.languages[t]},n.cdata=/^$/i;var a={"included-cdata":{pattern://i,inside:n}};a["language-"+t]={pattern:/[\s\S]+/,inside:Prism.languages[t]};var r={};r[e]={pattern:RegExp("(<__[\\s\\S]*?>)(?:\\s*|[\\s\\S])*?(?=<\\/__>)".replace(/__/g,e),"i"),lookbehind:!0,greedy:!0,inside:a},Prism.languages.insertBefore("markup","cdata",r)}}),Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+[\s\S]*?(?:;|(?=\s*\{))/,inside:{rule:/@[\w-]+/}},url:{pattern:RegExp("url\\((?:"+t.source+"|[^\n\r()]*)\\)","i"),inside:{function:/^url/i,punctuation:/^\(|\)$/}},selector:RegExp("[^{}\\s](?:[^{};\"']|"+t.source+")*?(?=\\s*\\{)"),string:{pattern:t,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),e.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:n.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:e.languages.css}},alias:"language-css"}},n.tag))}(Prism),Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/},Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|})\s*)(?:catch|finally)\b/,lookbehind:!0},{pattern:/(^|[^.])\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],number:/\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,function:/[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,operator:/-[-=]?|\+[+=]?|!=?=?|<>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=\s*($|[\r\n,.;})\]]))/,lookbehind:!0,greedy:!0},"function-variable":{pattern:/[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)?\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=>)/i,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*)\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|[^\\`])*`/,greedy:!0,inside:{interpolation:{pattern:/\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/,inside:{"interpolation-punctuation":{pattern:/^\${|}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.js=Prism.languages.javascript,Prism.languages.css.selector={pattern:Prism.languages.css.selector,inside:{"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-:.\w]+/,id:/#[-:.\w]+/,attribute:{pattern:/\[(?:[^[\]"']|("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1)*\]/,greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)[-*\w\xA0-\uFFFF]*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},attribute:{pattern:/^(\s*)[-\w\xA0-\uFFFF]+/,lookbehind:!0},value:[/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,{pattern:/(=\s*)[-\w\xA0-\uFFFF]+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],punctuation:/[()]/}},Prism.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*/i,lookbehind:!0}}),Prism.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:/#[\da-f]{3,8}/i,entity:/\\[\da-f]{1,8}/i,unit:{pattern:/(\d)(?:%|[a-z]+)/,lookbehind:!0},number:/-?[\d.]+/}),Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-]+(?:\([^()]+\)|[^(])*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()]|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}]+[:{][^}]+))/m,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[\w-]|\$[-\w]+|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),Prism.languages.insertBefore("scss","atrule",{keyword:[/@(?:if|else(?: if)?|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)/i,{pattern:/( +)(?:from|through)(?= )/,lookbehind:!0}]}),Prism.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),Prism.languages.insertBefore("scss","function",{placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:true|false)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/,lookbehind:!0}}),Prism.languages.scss.atrule.inside.rest=Prism.languages.scss,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t]+.+)*/m,lookbehind:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,inside:{atrule:/(?:@[\w-]+|[+=])/m}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|or|not)\b/,{pattern:/(\s+)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s]+.*)/m,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/([ \t]*)\S(?:,?[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,?[^,\r\n]+)*)*/,lookbehind:!0}})}(Prism),function(){if("undefined"!=typeof self&&self.Prism&&self.document&&document.querySelector){var e,t=function(){if(void 0===e){var t=document.createElement("div");t.style.fontSize="13px",t.style.lineHeight="1.5",t.style.padding=0,t.style.border=0,t.innerHTML=" 
     ",document.body.appendChild(t),e=38===t.offsetHeight,document.body.removeChild(t)}return e},n=0;Prism.hooks.add("before-sanity-check",(function(e){var t=e.element.parentNode,n=t&&t.getAttribute("data-line");if(t&&n&&/pre/i.test(t.nodeName)){var r=0;a(".line-highlight",t).forEach((function(e){r+=e.textContent.length,e.parentNode.removeChild(e)})),r&&/^( \n)+$/.test(e.code.slice(-r))&&(e.code=e.code.slice(0,-r))}})),Prism.hooks.add("complete",(function e(t){var a=t.element.parentNode,s=a&&a.getAttribute("data-line");if(a&&s&&/pre/i.test(a.nodeName)){clearTimeout(n);var l=Prism.plugins.lineNumbers,u=t.plugins&&t.plugins.lineNumbers;r(a,"line-numbers")&&l&&!u?Prism.hooks.add("line-numbers",e):(i(a,s)(),n=setTimeout(o,1))}})),window.addEventListener("hashchange",o),window.addEventListener("resize",(function(){var e=[];a("pre[data-line]").forEach((function(t){e.push(i(t))})),e.forEach(s)}))}function a(e,t){return Array.prototype.slice.call((t||document).querySelectorAll(e))}function r(e,t){return t=" "+t+" ",-1<(" "+e.className+" ").replace(/[\n\t]/g," ").indexOf(t)}function s(e){e()}function i(e,n,a){var i=(n="string"==typeof n?n:e.getAttribute("data-line")).replace(/\s+/g,"").split(","),o=+e.getAttribute("data-line-offset")||0,l=(t()?parseInt:parseFloat)(getComputedStyle(e).lineHeight),u=r(e,"line-numbers"),c=u?e:e.querySelector("code")||e,d=[];return i.forEach((function(t){var n=t.split("-"),r=+n[0],s=+n[1]||r,i=e.querySelector('.line-highlight[data-range="'+t+'"]')||document.createElement("div");if(d.push((function(){i.setAttribute("aria-hidden","true"),i.setAttribute("data-range",t),i.className=(a||"")+" line-highlight"})),u&&Prism.plugins.lineNumbers){var g=Prism.plugins.lineNumbers.getLine(e,r),p=Prism.plugins.lineNumbers.getLine(e,s);if(g){var m=g.offsetTop+"px";d.push((function(){i.style.top=m}))}if(p){var f=p.offsetTop-g.offsetTop+p.offsetHeight+"px";d.push((function(){i.style.height=f}))}}else d.push((function(){i.setAttribute("data-start",r),re&&t.setAttribute("tabindex","0")}))}(document); \ No newline at end of file diff --git a/docs/js/scripts.min.js.map b/docs/js/scripts.min.js.map new file mode 100644 index 0000000..b35aa8e --- /dev/null +++ b/docs/js/scripts.min.js.map @@ -0,0 +1 @@ +{"version":3,"names":["document","querySelectorAll","forEach","el","addEventListener","checked","this","getAttribute","setAttribute","classList","contains","parentNode","nextElementSibling","toggle","regions","window","matchMedia","matches","width","offsetWidth","querySelector"],"sources":["_site/js/script.js"],"mappings":"CAAA,WACC,aAGeA,SAASC,iBAAiB,mBAEhCC,SAAQ,SAAUC,GAC1BA,EAAGC,iBAAiB,SAAS,WAC5B,IAAIC,EAAgD,SAAtCC,KAAKC,aAAa,kBAA8B,GAC9DD,KAAKE,aAAa,gBAAiBH,GAE/BC,KAAKG,UAAUC,SAAS,iBACfJ,KAAKK,WAAWC,mBACtBH,UAAUI,OAAO,UAEzB,GACD,IAGA,IAAIC,EAAUd,SAASC,iBAAiB,oBAEpCc,OAAOC,WAAW,qBAAqBC,SAC1CH,EAAQZ,SAAQ,SAAUC,GACzB,IAAIe,EAAQf,EAAGgB,YACHhB,EAAGiB,cAAc,SAEnBD,YAAcD,GACvBf,EAAGK,aAAa,WAAY,IAE9B,GAED,CA/BD,CA+BGR"} \ No newline at end of file diff --git a/docs/line-charts.html b/docs/line-charts.html index 3ccb7e5..abaf7e8 100644 --- a/docs/line-charts.html +++ b/docs/line-charts.html @@ -1,267 +1,247 @@ - - - - - - Line charts — chaarts - - - - - - - - - - - + + + + + + + Line charts — chaarts + + + + + + + + + + + - +
    - - - - - + + +
    - -

    Line charts

    - -

    Area charts

    - -

    - This chart is based on CSS custom properties, grids and clip-path - — the latter being the most important. -

    - -
      -
    1. - Scales are set on the table: -
        -
      • - --y defines the y-axis scale, used to indicate the scale - in the background but also to place the points on the curve; -
      • -
      • - --x is the x-axis scale, - simply expressed as the number of columns to display; -
      • -
      • --unit defines unit to be displayed in simulated tooltip (see below).
      • -
      -
    2. -
    3. - Each line <tr> in <tbody> carries a set of variables, - corresponding to all the values it contains. - In a ::before pseudo-element, a position is defined for each value - within the clip-path polygon() function. -
        -
      • - Since this function accepts two percentage values at each point, - the method is pretty straightforward. - The x-axis position is the number of columns (i.e., the offset from the left) and - the y-axis position is the ratio of the value on the scale, formulated as follows: - calc( ( 100% / var(--x) * 1 ) + var(--offset) ) calc( 100% - ( var(--1) / var(--y) * 100% ) ), - where * 1 and var(--1) is the index of the value as a whole, - and var(--offset) is the value of half a column, - to place the point in the middle of its column. -
      • -
      • - As you may have understood, the main pitfall of this graph is - that it requires to know the number of points in advance. -
      • -
      • - Since clip-path still requires - -webkit- vendor prefix for Safari, we're using a custom property to prevent - polygon() duplication — based - on a trick shared by Michelle Barker in "7 uses for CSS custom properties". -
      • -
      -
    4. -
    5. - Each cell <td> in <tbody> carries an - ::after pseudo-element used to summarize - its headers and value in a simulated tooltip, and a ::before pseudo-element - to manage an interactive layer on the cell: - -
    6. -
    7. - Everything else is just decoration:: -
        -
      • - a big padding-top on the table is used to reserve space - for the charts — caution: - it is necessary to apply border-collapse: separate; on the table - for the padding to have an impact; -
      • -
      • each line's ::before is stretched in order to occupy all the reserved space;
      • -
      • a gradient background to represent the full area of the same ::before;
      • -
      • - a repeating-linear-gradient() to represent the vertical scale - in the table's background; -
      • -
      • - and hover interactions to highlight the hovered value: - its column using a pseudo-element — positioned with the help of clever calculations — - and mix-blend-mode for a wow effect. -
      • -
      -
    8. -
    - - - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - requires + -webkit- vendor prefix for Safari, we're using a custom property to prevent + polygon() duplication — based + on a trick shared by Michelle Barker in "7 uses for CSS custom properties". + + + +
  • + Each cell <td> in <tbody> carries an + ::after pseudo-element used to summarize + its headers and value in a simulated tooltip, and a ::before pseudo-element + to manage an interactive layer on the cell: + +
  • +
  • + Everything else is just decoration:: +
      +
    • + a big padding-top on the table is used to reserve space + for the charts — caution: + it is necessary to apply border-collapse: separate; on the table + for the padding to have an impact; +
    • +
    • each line's ::before is stretched in order to occupy all the reserved space;
    • +
    • a gradient background to represent the full area of the same ::before;
    • +
    • + a repeating-linear-gradient() to represent the vertical scale + in the table's background; +
    • +
    • + and hover interactions to highlight the hovered value: + its column using a pseudo-element — positioned with the help of clever calculations — + and mix-blend-mode for a wow effect. +
    • +
    +
  • + + + +
    +
    +

    + Switch
    + Allows you to disable styles on the following table. +

    + +
    + +
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Average monthly temperature in 2017
    YearJan.Feb.Mar.Apr.MayJuneJulyAug.Sep.Oct.Nov.Dec.
    2017 - 8 °C - - 6 °C - - 9 °C - - 12 °C - - 15 °C - - 21 °C - - 24 °C - - 25 °C - - 22 °C - - 19 °C - - 14 °C - - 9 °C -
    -
    - -
    - HTML -
    <table class="chaarts line" style="--y: 32; --x: 13; --t-1: 'Jan.'; --t-2: 'Feb.'; […]">
    +			Average monthly temperature in 2017
    +			
    +			
    +				Year
    +				Jan.
    +				Feb.
    +				Mar.
    +				Apr.
    +				May
    +				June
    +				July
    +				Aug.
    +				Sep.
    +				Oct.
    +				Nov.
    +				Dec.
    +			
    +			
    +			
    +			
    +				2017
    +					
    +		8 °C	
    +
    +					
    +		6 °C	
    +
    +					
    +		9 °C	
    +
    +					
    +		12 °C	
    +
    +					
    +		15 °C	
    +
    +					
    +		21 °C	
    +
    +					
    +		24 °C	
    +
    +					
    +		25 °C	
    +
    +					
    +		22 °C	
    +
    +					
    +		19 °C	
    +
    +					
    +		14 °C	
    +
    +					
    +		9 °C	
    +
    +			
    +			
    +		
    +	
    + +
    + HTML +
    <table class="chaarts line" style="--y: 32; --x: 13; --t-1: 'Jan.'; --t-2: 'Feb.'; […]">
       <caption id="caption-3">[…]</caption>
       <thead>
         <tr>
    @@ -279,10 +259,10 @@ 

    Area charts

    </tbody> </table>
    -
    -
    - css -
    @supports (clip-path: polygon(0% calc( 100% - ( var(--1) * 100% / var(--y) )) )) {
    +	
    +
    + css +
    @supports (clip-path: polygon(0% calc( 100% - ( var(--1) * 100% / var(--y) )) )) {
       .chaarts.line {
         --offset: calc( ( 100% / var(--x) ) / 2 );
         --height: calc( 32em - 2rem );
    @@ -463,232 +443,189 @@ 

    Area charts

    } }
    -
    -
    - The calculation twist -

    The polygon() path

    -

    - To begin with, you need to understand that clip-path is a path, - just like a vector shape. It must therefore be closed. - So the path starts at 0% 100% — bottom left, does its path life, - toggles to 100% 100% and comes back looping at 0% 100%. -

    -

    And in its path, each point must be positioned in abscissa and ordinate.

    -

    The X-axis position

    -

    - The first position is simple: divide 100% by the - var(--x) scale, and multiply by the index of the element. - For example: calc( ( 100% / var(--x) * 1) ). - To place each point in the middle of its column, we shift it by half a column - — which we do by adding to the previous calculation var(--offset), - which corresponds to calc( ( 100% / var(--x) ) / 2 ).
    - The final position is therefore, here for the third point:
    - calc( ( 100% / var(--x) * 3) + var(--offset) ). -

    -

    The Y-axis position

    -

    - In this graph, the Y-axis is the most important axis. So to place the point, - we start by calculating the ratio of its value on the scale - — formulated as follows: var(--1) / var(--y). And because - polygon() uses percentage values, we report this calculation on 100%: - ( var(--1) / var(--y) * 100% ).
    - And finally, since the polygon's datums start from the top left, the position - position must be defined according to the top of the box. - The final formula then looks like this — again for the third element: - calc( 100% - ( var(--3) / var(--y) * 100% ) ). -

    -
    -
    - -

    Line chart with dots

    - -

    In the end, this variant differs little from the previous version:

    - -
      -
    1. - the polygon() is continued to form a line, - duplicating each point with an offset of 4px - — the line thickness — and in the reverse order; -
    2. -
    3. - the ::before pseudo-element that displays the tooltip takes - here the form of a point on the curve - — positioned using the same calculations that are used in the polygon; -
    4. -
    5. - and especially, since clip-path is applied in the line - <tr>: you can put more than one ! - So we need to add a combination of color and pattern to distinguish each line - and associate them visually with their caption. -
    6. -
    - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - +
    +

    + Switch
    + Allows you to disable styles on the following table. +

    + +
    + +
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Average monthly temperature per year
    YearJan.Feb.Feb.Mar.Apr.MayJuneJulyAug.Sep.Oct.Nov.Dec.
    2017 - 8 °C - - 6 °C - - 9 °C - - 12 °C - - 15 °C - - 21 °C - - 24 °C - - 25 °C - - 22 °C - - 19 °C - - 14 °C - - 9 °C -
    2018 - 10 °C - - 4 °C - - 7 °C - - 13 °C - - 17 °C - - 20 °C - - 22 °C - - 23 °C - - 26 °C - - 17 °C - - 14 °C - - 10 °C -
    -
    - -
    - css -
    @supports (clip-path: polygon(0% calc(100% - (var(--1) * 100% / var(--y))))) {
    +			Average monthly temperature per year
    +			
    +			
    +				Year
    +				Jan.
    +				Feb.
    +				Feb.Mar.
    +				Apr.
    +				May
    +				June
    +				July
    +				Aug.
    +				Sep.
    +				Oct.
    +				Nov.
    +				Dec.
    +			
    +			
    +			
    +			
    +				2017
    +					
    +		8 °C	
    +
    +					
    +		6 °C	
    +
    +					
    +		9 °C	
    +
    +					
    +		12 °C	
    +
    +					
    +		15 °C	
    +
    +					
    +		21 °C	
    +
    +					
    +		24 °C	
    +
    +					
    +		25 °C	
    +
    +					
    +		22 °C	
    +
    +					
    +		19 °C	
    +
    +					
    +		14 °C	
    +
    +					
    +		9 °C	
    +
    +			
    +			
    +				2018
    +					
    +		10 °C	
    +
    +					
    +		4 °C	
    +
    +					
    +		7 °C	
    +
    +					
    +		13 °C	
    +
    +					
    +		17 °C	
    +
    +					
    +		20 °C	
    +
    +					
    +		22 °C	
    +
    +					
    +		23 °C	
    +
    +					
    +		26 °C	
    +
    +					
    +		17 °C	
    +
    +					
    +		14 °C	
    +
    +					
    +		10 °C	
    +
    +			
    +			
    +		
    +	
    + +
    + css +
    @supports (clip-path: polygon(0% calc(100% - (var(--1) * 100% / var(--y))))) {
       .chaarts.points [style]::before {
         background: var(--color, currentColor) var(--background);
         --polygon: polygon(
    @@ -788,26 +725,20 @@ 

    Line chart with dots

    } }
    -
    - -
    -

    Note

    -

    - To play more and familiarize yourself with clip-path, - Bennett Feely created - clippy. -

    -
    - +
    + +
    +

    Note

    +

    + To play more and familiarize yourself with clip-path, + Bennett Feely created + clippy. +

    +
    + + - - - - - - - - - \ No newline at end of file + + diff --git a/docs/pie-charts.html b/docs/pie-charts.html index f4f076f..8f1d5de 100644 --- a/docs/pie-charts.html +++ b/docs/pie-charts.html @@ -1,272 +1,250 @@ - - - - - -Pie charts — chaarts - - - - - - - - - - - + + + + + + + Pie charts — chaarts + + + + + + + + + + + - +
    - - - - - + + +
    - -

    Pie charts

    - -

    - The pie chart is used for representations of percentage proportions. - It relies on CSS variables, an outrageous abuse of calc(), - display: table-*, clip-path, mask-image, - transform and a bit of SVG - to distinguish each area. Yes, I know how to laugh. How do we use it? -

    - -
      -
    1. - On each header <th>, a --color - custom property allows you to assign, well… a color. -
    2. -
    3. - Then each cell <td> must contain the value - and its unit, as well as a style attribute to carry some variables: -
        -
      1. - --value is the percentage value, - useful for determining the angle the element should occupy on the circle. - All points of the polygon() — used to draw the pie part thanks to clip-path — - depend on this value (read the technical note after - the example for details of the calculations). -
      2. -
      3. - --start is used to define the starting point - of the arc on the circle. It's the sum of the previous definitions, and is applied - to the rotate() function of the transform poperty. -
      4. -
      5. - And finally a series of pseudo-boolean variables, each worthing 0 or 1 - — according to and idea of - Roman Komarov in "Conditions for CSS variables" — - depend on the value: --lt-25, --gt-25, --lt-50… - They allow to toggle the points from their original position - (50% 50%) to their calculated position, by adding or subtracting from the initial value; -
      6. -
      -
    4. -
    5. - a ::before pseudo-element on each cell <td>is formatted - in a clever way according to all our variables, including transform, - clip-path and mask-image. - -
    6. -
    7. - a ::after pseudo-element is used as a tooltip, to summarize header and value for each cell - —but the display of custom properties in a pseudo-element is not so trivial: - -
    8. -
    9. - And finally a pattern is applied to the background, - in order to better associate it visually with the corresponding legend. -
    10. -
    - - - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Distribution of the weight of resources for ffoodd.fr
    ResourceProportion
    HTML - 2 % -
    CSS - 2 % -
    JS - 32 % -
    Json - 1 % -
    Images - 44 % -
    Webfonts - 17 % -
    Other - 2 % -
    -
    - -
    - A bit of trigonometry -
    -

    - In this graph, each portion represents an arc of a circle based on an angle (part of 360 degrees). - To define the shape of this portion, a point must be placed on the circle. -

    -

    - To do this, I divide the circle into four squares. The position of the point on the circle - can then be calculated using the properties of the right-angled triangle formed by: -

    -
      -
    1. the center of the circle,
    2. -
    3. the point we're trying to position,
    4. -
    5. and the point perpendicular to the radius and passing through our target point.
    6. -
    -

    - We know the hypotenuse of this triangle — the radius of the circle —, - and the angle formed by the hypotenuse and starting from the center of the circle - (reducing the value to 90 degrees, since the circle is divided into four square sectors: - if the value is greater than 25: minus 90°, etc.) - — plus a right angle, of course. -

    -

    Law of sines

    -

    - We can therefore use the sine law - to measure each side, and thus obtain the position of the point on the circle. - Meaning we need to calculate the sine… Fortunately, - Stereokai implemented for us - the Taylor/Maclaurin polynomial representation in CSS — which I implemented as a mixin: -

    -
    @mixin sin($angle) {
    +	

    Pie charts

    + +

    + The pie chart is used for representations of percentage proportions. + It relies on CSS variables, an outrageous abuse of calc(), + display: table-*, clip-path, mask-image, + transform and a bit of SVG + to distinguish each area. Yes, I know how to laugh. How do we use it? +

    + +
      +
    1. + On each header <th>, a --color + custom property allows you to assign, well… a color. +
    2. +
    3. + Then each cell <td> must contain the value + and its unit, as well as a style attribute to carry some variables: +
        +
      1. + --value is the percentage value, + useful for determining the angle the element should occupy on the circle. + All points of the polygon() — used to draw the pie part thanks to clip-path — + depend on this value (read the technical note after + the example for details of the calculations). +
      2. +
      3. + --start is used to define the starting point + of the arc on the circle. It's the sum of the previous definitions, and is applied + to the rotate() function of the transform poperty. +
      4. +
      5. + And finally a series of pseudo-boolean variables, each worthing 0 or 1 + — according to and idea of + Roman Komarov in "Conditions for CSS variables" — + depend on the value: --lt-25, --gt-25, --lt-50… + They allow to toggle the points from their original position + (50% 50%) to their calculated position, by adding or subtracting from the initial value; +
      6. +
      +
    4. +
    5. + a ::before pseudo-element on each cell <td>is formatted + in a clever way according to all our variables, including transform, + clip-path and mask-image. + +
    6. +
    7. + a ::after pseudo-element is used as a tooltip, to summarize header and value for + each cell + —but the display of custom properties in a pseudo-element is not so trivial: + +
    8. +
    9. + And finally a pattern is applied to the background, + in order to better associate it visually with the corresponding legend. +
    10. +
    + + +
    +
    +

    + Switch
    + Allows you to disable styles on the following table. +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Distribution of the weight of resources for + ffoodd.fr +
    ResourceProportion
    HTML + 2 %
    CSS + 2 %
    JS + 32 %
    Json + 1 %
    Images + 44 %
    Webfonts + 17 %
    Other + 2 %
    +
    + +
    + A bit of trigonometry +
    +

    + In this graph, each portion represents an arc of a circle based on an angle (part of 360 degrees). + To define the shape of this portion, a point must be placed on the circle. +

    +

    + To do this, I divide the circle into four squares. The position of the point on the circle + can then be calculated using the properties of the right-angled triangle formed by: +

    +
      +
    1. the center of the circle,
    2. +
    3. the point we're trying to position,
    4. +
    5. and the point perpendicular to the radius and passing through our target point.
    6. +
    +

    + We know the hypotenuse of this triangle — the radius of the circle —, + and the angle formed by the hypotenuse and starting from the center of the circle + (reducing the value to 90 degrees, since the circle is divided into four square sectors: + if the value is greater than 25: minus 90°, etc.) + — plus a right angle, of course. +

    +

    Law of sines

    +

    + We can therefore use the sine law + to measure each side, and thus obtain the position of the point on the circle. + Meaning we need to calculate the sine… Fortunately, + Stereokai implemented + for us + the Taylor/Maclaurin polynomial representation in CSS — which I implemented as a mixin: +

    +
    @mixin sin($angle) {
       --sin-term-#{$angle}-1: var(--#{$angle});
       --sin-term-#{$angle}-2: calc((var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle})) / 6);
       --sin-term-#{$angle}-3: calc((var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle})) / 120);
    @@ -274,15 +252,15 @@ 

    Law of sines

    --sin-term-#{$angle}-5: calc((var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle})) / 362880); --sin-#{$angle}: calc(var(--sin-term-#{$angle}-1) - var(--sin-term-#{$angle}-2) + var(--sin-term-#{$angle}-3) - var(--sin-term-#{$angle}-4) + var(--sin-term-#{$angle}-5)); }
    - -

    - All that remains is to use these dimensions to place the points of the polygon. - It's child's play! -

    -
    -
    - HTML -
    <table class="chaarts pie">
    +			

    + All that remains is to use these dimensions to place the points of the polygon. + It's child's play! +

    +
    +
    +
    + HTML +
    <table class="chaarts pie">
       <caption id="caption-5">[…]</caption>
       <thead class="sr-only">
         <tr>
    @@ -299,268 +277,271 @@ 

    Law of sines

    </tbody> </table>
    -
    -
    - css -
    -
       
    +	
    +
    + css +
    +
    +	 
     @supports (clip-path: polygon( 50% calc( 50% + ( var(--gt-25, 0) ) ) )) {
      .chaarts.pie {
    -   --radius: 32em;
    -   margin: 0 auto;
    -   padding-top: calc(var(--radius) - 2rem);
    -   position: relative;
    +	 --radius: 32em;
    +	 margin: 0 auto;
    +	 padding-top: calc(var(--radius) - 2rem);
    +	 position: relative;
      }
     
      .chaarts.pie tbody {
    -   display: table-row;
    +	 display: table-row;
      }
     
      .chaarts.pie tr {
    -   display: table-cell;
    -   transition: opacity .3s cubic-bezier(.5, 0, .5, 1);
    +	 display: table-cell;
    +	 transition: opacity .3s cubic-bezier(.5, 0, .5, 1);
      }
     
      .chaarts.pie [scope="row"] {
    -   padding-right: .5rem;
    +	 padding-right: .5rem;
      }
     
      .chaarts.pie [scope="row"]::before {
    -   background: var(--color, currentColor);
    -   content: "";
    -   display: inline-block;
    -   height: 1rem;
    -   transform: translate3d(-.2rem, .1rem, 0);
    -   width: 1rem;
    +	 background: var(--color, currentColor);
    +	 content: "";
    +	 display: inline-block;
    +	 height: 1rem;
    +	 transform: translate3d(-.2rem, .1rem, 0);
    +	 width: 1rem;
      }
     
      .chaarts.pie td {
    -   --position: calc(var(--start, 0) * .01turn);
    +	 --position: calc(var(--start, 0) * .01turn);
      }
     
      .chaarts.pie td::after,
      .chaarts.pie td::before {
    -   left: 50%;
    -   position: absolute;
    -   top: calc(var(--radius) / 2);
    -   transform-origin: center center;
    +	 left: 50%;
    +	 position: absolute;
    +	 top: calc(var(--radius) / 2);
    +	 transform-origin: center center;
      }
     
      .chaarts.pie td::before {
    -   /* The inclination, to be in the right place */
    -   --position: calc(var(--start, 0) * .01turn);
    -   --zoom: .75;
    -   /* The angle represented by the value: 3.6 = 360deg / 100 */
    -   /* Since we're using a percentage value */
    -   --part: calc( var(--value) * 3.6 );
    -   /* The "useful" angle for the calculation, necessarily less than 90deg */
    -   /*  We therefore subtract 90deg (= ¼ × 360deg) per 25% (= ¼ × 100%, indeed) */
    -   --main-angle: calc( var(--part) - ( 90 * ( var(--gt-25, 0) + var(--gt-50, 0) + var(--gt-75, 0) ) ) );
    -   /* Main angle, in radian */
    -   --β: calc( var(--main-angle) * 0.01745329251 );
    -   /* The last angle in radian, by deduction since in a right-angled triangle */
    -   --α: calc( ( 90 - var(--main-angle) ) * 0.01745329251 );
    -   /* The magic of Stereokai, to get the sinus from these angles… */
    -   --sin-term-β-1: var(--β);
    -   --sin-term-β-2: calc((var(--β) * var(--β) * var(--β)) / 6);
    -   --sin-term-β-3: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 120);
    -   --sin-term-β-4: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 5040);
    -   --sin-term-β-5: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 362880);
    -   --sin-β: calc(var(--sin-term-β-1) - var(--sin-term-β-2) + var(--sin-term-β-3) - var(--sin-term-β-4) + var(--sin-term-β-5));
    -   --sin-term-α-1: var(--α);
    -   --sin-term-α-2: calc((var(--α) * var(--α) * var(--α)) / 6);
    -   --sin-term-α-3: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 120);
    -   --sin-term-α-4: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 5040);
    -   --sin-term-α-5: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 362880);
    -   --sin-α: calc(var(--sin-term-α-1) - var(--sin-term-α-2) + var(--sin-term-α-3) - var(--sin-term-α-4) + var(--sin-term-α-5));
    -   /* Finally, the position expressed in %, of the hypothenuse, divided by 2 to fit in ¼ of the circle
    -    * or after simplification, divided by 50 */
    -   --pos-B: calc( var(--sin-β) * 50 );
    -   --pos-A: calc( var(--sin-α) * 50 );
    -   background-color: var(--color, currentColor) var(--background);
    -   --polygon: polygon(
    -     50% 50%,
    -     50% 0%,
    -     100% 0%,
    -     calc( 50% + ( var(--pos-B) * 1% * var(--lt-25, 1) ) + ( var(--gt-25, 0) * 50% ) ) calc( 50% - ( var(--pos-A) * 1% * var(--lt-25, 1) ) ),
    -     calc( 50% + ( var(--gt-25, 0) * 50% ) )                      calc( 50% + ( var(--gt-25, 0) * 50% ) ),
    -     calc( 50% + ( var(--pos-A) * 1% * var(--lt-50, 1) ) + ( var(--gt-50, 0) * 50% ) ) calc( 50% + ( var(--pos-B) * 1% * var(--lt-50, 1) ) + ( var(--gt-50, 0) * 50% ) ),
    -     calc( 50% - ( var(--gt-50, 0) * 50% ) )                      calc( 50% + ( var(--gt-50, 0) * 50% ) ),
    -     calc( 50% - ( var(--pos-B) * 1% * var(--lt-75, 1) ) - ( var(--gt-75, 0) * 50% ) ) calc( 50% + ( var(--pos-A) * 1% * var(--lt-75, 1) ) ),
    -     calc( 50% - ( var(--gt-75, 0) * 50% ) )                      calc( 50% - ( var(--gt-75, 0) * 50% ) ),
    -     calc( 50% - ( var(--pos-A) * 1% * var(--gt-75, 0) ) )        calc( 50% - ( var(--pos-B) * 1% * var(--gt-75, 0) ) ),
    -     50% 50%
    -   );
    -   clip-path: var(--polygon);
    -   content: '';
    -   height: var(--radius);
    -   --mask: radial-gradient(
    -     circle at center,
    -     white 0%,
    -     white calc(var(--radius)  / 2),
    -     transparent calc(var(--radius)  / 2)
    -   );
    -   mask-image: var(--mask);
    -   transform:
    -     translate3d(-50%, -50%, 0)
    -     rotate( var(--position) )
    -     scale( var(--zoom) );
    -   transition: transform .2s cubic-bezier(.5, 0, .5, 1);
    -   width: var(--radius);
    +	 /* The inclination, to be in the right place */
    +	 --position: calc(var(--start, 0) * .01turn);
    +	 --zoom: .75;
    +	 /* The angle represented by the value: 3.6 = 360deg / 100 */
    +	 /* Since we're using a percentage value */
    +	 --part: calc( var(--value) * 3.6 );
    +	 /* The "useful" angle for the calculation, necessarily less than 90deg */
    +	 /*  We therefore subtract 90deg (= ¼ × 360deg) per 25% (= ¼ × 100%, indeed) */
    +	 --main-angle: calc( var(--part) - ( 90 * ( var(--gt-25, 0) + var(--gt-50, 0) + var(--gt-75, 0) ) ) );
    +	 /* Main angle, in radian */
    +	 --β: calc( var(--main-angle) * 0.01745329251 );
    +	 /* The last angle in radian, by deduction since in a right-angled triangle */
    +	 --α: calc( ( 90 - var(--main-angle) ) * 0.01745329251 );
    +	 /* The magic of Stereokai, to get the sinus from these angles… */
    +	 --sin-term-β-1: var(--β);
    +	 --sin-term-β-2: calc((var(--β) * var(--β) * var(--β)) / 6);
    +	 --sin-term-β-3: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 120);
    +	 --sin-term-β-4: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 5040);
    +	 --sin-term-β-5: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 362880);
    +	 --sin-β: calc(var(--sin-term-β-1) - var(--sin-term-β-2) + var(--sin-term-β-3) - var(--sin-term-β-4) + var(--sin-term-β-5));
    +	 --sin-term-α-1: var(--α);
    +	 --sin-term-α-2: calc((var(--α) * var(--α) * var(--α)) / 6);
    +	 --sin-term-α-3: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 120);
    +	 --sin-term-α-4: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 5040);
    +	 --sin-term-α-5: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 362880);
    +	 --sin-α: calc(var(--sin-term-α-1) - var(--sin-term-α-2) + var(--sin-term-α-3) - var(--sin-term-α-4) + var(--sin-term-α-5));
    +	 /* Finally, the position expressed in %, of the hypothenuse, divided by 2 to fit in ¼ of the circle
    +		* or after simplification, divided by 50 */
    +	 --pos-B: calc( var(--sin-β) * 50 );
    +	 --pos-A: calc( var(--sin-α) * 50 );
    +	 background-color: var(--color, currentColor) var(--background);
    +	 --polygon: polygon(
    +		 50% 50%,
    +		 50% 0%,
    +		 100% 0%,
    +		 calc( 50% + ( var(--pos-B) * 1% * var(--lt-25, 1) ) + ( var(--gt-25, 0) * 50% ) ) calc( 50% - ( var(--pos-A) * 1% * var(--lt-25, 1) ) ),
    +		 calc( 50% + ( var(--gt-25, 0) * 50% ) )                      calc( 50% + ( var(--gt-25, 0) * 50% ) ),
    +		 calc( 50% + ( var(--pos-A) * 1% * var(--lt-50, 1) ) + ( var(--gt-50, 0) * 50% ) ) calc( 50% + ( var(--pos-B) * 1% * var(--lt-50, 1) ) + ( var(--gt-50, 0) * 50% ) ),
    +		 calc( 50% - ( var(--gt-50, 0) * 50% ) )                      calc( 50% + ( var(--gt-50, 0) * 50% ) ),
    +		 calc( 50% - ( var(--pos-B) * 1% * var(--lt-75, 1) ) - ( var(--gt-75, 0) * 50% ) ) calc( 50% + ( var(--pos-A) * 1% * var(--lt-75, 1) ) ),
    +		 calc( 50% - ( var(--gt-75, 0) * 50% ) )                      calc( 50% - ( var(--gt-75, 0) * 50% ) ),
    +		 calc( 50% - ( var(--pos-A) * 1% * var(--gt-75, 0) ) )        calc( 50% - ( var(--pos-B) * 1% * var(--gt-75, 0) ) ),
    +		 50% 50%
    +	 );
    +	 clip-path: var(--polygon);
    +	 content: '';
    +	 height: var(--radius);
    +	 --mask: radial-gradient(
    +		 circle at center,
    +		 white 0%,
    +		 white calc(var(--radius)  / 2),
    +		 transparent calc(var(--radius)  / 2)
    +	 );
    +	 mask-image: var(--mask);
    +	 transform:
    +		 translate3d(-50%, -50%, 0)
    +		 rotate( var(--position) )
    +		 scale( var(--zoom) );
    +	 transition: transform .2s cubic-bezier(.5, 0, .5, 1);
    +	 width: var(--radius);
      }
     
      .chaarts.pie tr:hover td::before {
    -   --zoom: .8;
    +	 --zoom: .8;
      }
     
      .chaarts.pie tr:nth-child(2n + 2) *::before {
    -   --background: var(--stripes);
    +	 --background: var(--stripes);
      }
     
      .chaarts.pie td::after {
    -   --arrow: calc(100% - .25rem);
    -   --axis: calc( var(--position) - .25turn + var(--value) * .005turn );
    -   --away: calc( var(--radius) / 2 - 1rem );
    -   --integer: calc(var(--value));
    -   background-color: #444;
    -   color: white;
    -   content: var(--term) "\A0: " counter(value) "\A0%";
    -   counter-reset: value var(--integer);
    -   opacity: 0;
    -   padding: .5rem;
    -   pointer-events: none;
    -   transform-origin: 50% calc(100% + 10px);
    -   transform:
    -     translate3d(-50%, -50%, 0)
    -     rotate( var(--axis) )
    -     translate( var(--away) )
    -     rotate( calc( var(--axis) * -1 ) )
    -     perspective(1000px)
    -     rotate3d(1, 0, 0, 45deg);
    -   transition:
    -     opacity .2s cubic-bezier(0, .5, .5, 1),
    -     transform .2s cubic-bezier(0, .5, .5, 1);
    +	 --arrow: calc(100% - .25rem);
    +	 --axis: calc( var(--position) - .25turn + var(--value) * .005turn );
    +	 --away: calc( var(--radius) / 2 - 1rem );
    +	 --integer: calc(var(--value));
    +	 background-color: #444;
    +	 color: white;
    +	 content: var(--term) "\A0: " counter(value) "\A0%";
    +	 counter-reset: value var(--integer);
    +	 opacity: 0;
    +	 padding: .5rem;
    +	 pointer-events: none;
    +	 transform-origin: 50% calc(100% + 10px);
    +	 transform:
    +		 translate3d(-50%, -50%, 0)
    +		 rotate( var(--axis) )
    +		 translate( var(--away) )
    +		 rotate( calc( var(--axis) * -1 ) )
    +		 perspective(1000px)
    +		 rotate3d(1, 0, 0, 45deg);
    +	 transition:
    +		 opacity .2s cubic-bezier(0, .5, .5, 1),
    +		 transform .2s cubic-bezier(0, .5, .5, 1);
      }
     
      .chaarts.pie tbody:hover tr {
    -   opacity: .75;
    +	 opacity: .75;
      }
     
      .chaarts.pie tbody:hover tr:hover {
    -   opacity: 1;
    +	 opacity: 1;
      }
     
      .chaarts.pie tbody:hover td::after {
    -   opacity: 1;
    -   transform:
    -     translate3d(-50%, -50%, 0)
    -     rotate( var(--axis) )
    -     translate( var(--away) )
    -     rotate( calc( var(--axis) * -1 ) )
    -     perspective(1000px)
    -     rotate3d(1, 0, 0, 0deg);
    -   transition:
    -     opacity .2s cubic-bezier(.5, 0, 1, .5),
    -     transform .2s cubic-bezier(.5, 0, 1, .5);
    +	 opacity: 1;
    +	 transform:
    +		 translate3d(-50%, -50%, 0)
    +		 rotate( var(--axis) )
    +		 translate( var(--away) )
    +		 rotate( calc( var(--axis) * -1 ) )
    +		 perspective(1000px)
    +		 rotate3d(1, 0, 0, 0deg);
    +	 transition:
    +		 opacity .2s cubic-bezier(.5, 0, 1, .5),
    +		 transform .2s cubic-bezier(.5, 0, 1, .5);
      }
     
      @media screen and (-ms-high-contrast: active) {
    -   .chaarts.pie tr *::before {
    -     background-color: Window;
    -   }
    +	 .chaarts.pie tr *::before {
    +		 background-color: Window;
    +	 }
     
    -   .chaarts.pie tr:nth-of-type(odd) *::before {
    -     background-color: WindowText;
    -   }
    +	 .chaarts.pie tr:nth-of-type(odd) *::before {
    +		 background-color: WindowText;
    +	 }
      }
     }
    -  
    -
    -
    -
    - The calculation twist -

    The positions of the polygon

    -

    - The use of pseudo-Boolean variables makes this calculation pseudo-algorithmic. - Let's start with an essential pre-requisite: the polygon being a closed shape and CSS - not being magical, points must pre-exist. - Spoiler, we need eleven points: -

    -
      -
    1. - The initial axis, from centre upwards: 50% 50% - and 50% 0%. -
    2. -
    3. - One point for each angle at the ends: the first one is fixed, at - 100% 0% (top right) — then each of the other angles has - two states, reached or not reached. Some insights: -
        -
      • - For example, the point at the bottom right concerns values between 25% and 50%: - if the value is less than 25%, it must be in the centre (so as not to interfere - with the drawing), and if not, it must be in its corner: - calc( 50% + ( var(--gt-25, 0) * 50% ) ) calc( 50% + ( var(--gt-25, 0) * 50% ) )
        - Thus the calculated value will be 50% 50% if --gt-25 is 0, - and 100% 100% if --gt-25 is 1. -
      • -
      • - In addition, each angle has its target coordinate: - 100% 100% for bottom right, 0% 100% for bottom left, - 0% 0% for top left. It is therefore necessary to sometimes subtract - and sometimes add to the initial value 50% 50% - to switch to the right point. -
      • -
      -
    4. -
    5. - One point for each possible position per quarter circle, corresponding - to each 25% slice. Like the points at the corners, these points must be in the centre - if they are not used. That's where we laugh the most: -
        -
      • we start from 50%, to which we add or subtract the following calculation;
      • -
      • - then the calculated position is used — --pos-A - or --pos-B as the case may be — which is converted into percentages using - * 1%, and rendered inert if the value is less than the range concerned - using * var(--lt-25, 1), for example.
        - - Notice the second value in var()? - This is the default value if the variable is not defined. Cool, isn't it? - -
      • -
      • - finally when the range is exceeded, the point switches to - 0% or 100% as appropriate. -
      • -
      -
    6. -
    7. - And lastly, we lose the path by going back to the centre of the circle, - at 50% 50%. -
    8. -
    -

    That's it!

    -

    The positions illustrated

    -

    - These screenshots — taken in - the shape editor of the - Firefox devtools — - show the points of the polygon in the different cases. - You can see for each cited value the resolved polygon for clip-path - — and see how the dynamic values tilt from one position to another. -

    -
      -
    • -
      -
      Rendering example for 44%
      -
      -
      - clip-path shape with a value of 44%: six visible points. -
      Shape screenshot for 44%.
      -
      -
      -
      td[style*="--value: 44;"]::before {
      +	
      +
      +
    +
    + The calculation twist +

    The positions of the polygon

    +

    + The use of pseudo-Boolean variables makes this calculation pseudo-algorithmic. + Let's start with an essential pre-requisite: the polygon being a closed shape and CSS + not being magical, points must pre-exist. + Spoiler, we need eleven points: +

    +
      +
    1. + The initial axis, from centre upwards: 50% 50% + and 50% 0%. +
    2. +
    3. + One point for each angle at the ends: the first one is fixed, at + 100% 0% (top right) — then each of the other angles has + two states, reached or not reached. Some insights: +
        +
      • + For example, the point at the bottom right concerns values between 25% and 50%: + if the value is less than 25%, it must be in the centre (so as not to interfere + with the drawing), and if not, it must be in its corner: + calc( 50% + ( var(--gt-25, 0) * 50% ) ) calc( 50% + ( var(--gt-25, 0) * 50% ) )
        + Thus the calculated value will be 50% 50% if --gt-25 is 0, + and 100% 100% if --gt-25 is 1. +
      • +
      • + In addition, each angle has its target coordinate: + 100% 100% for bottom right, 0% 100% for bottom left, + 0% 0% for top left. It is therefore necessary to sometimes subtract + and sometimes add to the initial value 50% 50% + to switch to the right point. +
      • +
      +
    4. +
    5. + One point for each possible position per quarter circle, corresponding + to each 25% slice. Like the points at the corners, these points must be in the centre + if they are not used. That's where we laugh the most: +
        +
      • we start from 50%, to which we add or subtract the following calculation;
      • +
      • + then the calculated position is used — --pos-A + or --pos-B as the case may be — which is converted into percentages using + * 1%, and rendered inert if the value is less than the range concerned + using * var(--lt-25, 1), for example.
        + + Notice the second value in var()? + This is the default value if the variable is not defined. Cool, isn't it? + +
      • +
      • + finally when the range is exceeded, the point switches to + 0% or 100% as appropriate. +
      • +
      +
    6. +
    7. + And lastly, we lose the path by going back to the centre of the circle, + at 50% 50%. +
    8. +
    +

    That's it!

    +

    The positions illustrated

    +

    + These screenshots — taken in + the shape editor of + the + Firefox devtools — + show the points of the polygon in the different cases. + You can see for each cited value the resolved polygon for clip-path + — and see how the dynamic values tilt from one position to another. +

    +
      +
    • +
      +
      Rendering example for 44%
      +
      +
      + clip-path shape with a value of 44%: six visible points. +
      Shape screenshot for 44%.
      +
      +
      +
      td[style*="--value: 44;"]::before {
         clip-path: polygon(
           50% 50%,
           50% 0%,
      @@ -575,22 +556,22 @@ 

      The positions illustrated

      50% 50% ); }
      - -
      Code generated for 44%.
      -
      -
      -
      -
    • -
    • -
      -
      Rendering example for 64%
      -
      -
      - clip-path shape with a value of 64%: seven visible points. -
      Shape screenshot for 64%.
      -
      -
      -
      td[style*="--value: 64;"]::before {
      +							
      Code generated for 44%.
      +
      +
      +
      +
    • +
    • +
      +
      Rendering example for 64%
      +
      +
      + clip-path shape with a value of 64%: seven visible points. +
      Shape screenshot for 64%.
      +
      +
      +
      td[style*="--value: 64;"]::before {
         clip-path: polygon(
           50% 50%,
           50% 0%,
      @@ -605,22 +586,22 @@ 

      The positions illustrated

      50% 50% ); }
      - -
      Code generated for 64%.
      -
      -
      -
      -
    • -
    • -
      -
      Rendering example for 88%
      -
      -
      - clip-path shape with a value of 88%: nine visible points. -
      Shape screenshot for 88%.
      -
      -
      -
      td[style*="--value: 88;"]::before {
      +							
      Code generated for 64%.
      +
      +
      +
      +
    • +
    • +
      +
      Rendering example for 88%
      +
      +
      + clip-path shape with a value of 88%: nine visible points. +
      Shape screenshot for 88%.
      +
      +
      +
      td[style*="--value: 88;"]::before {
         clip-path: polygon(
           50% 50%,
           50% 0%,
      @@ -635,254 +616,202 @@ 

      The positions illustrated

      50% 50% ); }
      - -
      Code generated for 88%.
      -
      -
      -
      -
    • -
    -
    - -
    -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Pie chart example with a value between 50 and 75%
    ResourceProportion
    HTML - 2 % -
    CSS - 2 % -
    JS - 32 % -
    Images - 64 % -
    -
    - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Pie chart example with a value greater than 75%
    ResourceProportion
    HTML - 2 % -
    CSS - 2 % -
    JS - 8 % -
    Images - 88 % -
    -
    -
    - -

    Donut

    - -

    - On the <table> element, we add an --offset variable - that allows us to determine the size of the hole of the donut, - generated using mask-image and radial-gradient(). - Ana Tudor has made - many examples of using mask-* on CodePen, have a look! -

    - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Distribution of the weight of resources for ffoodd.fr
    ResourceProportion
    HTML - 2 % -
    CSS - 2 % -
    JS - 32 % -
    Json - 1 % -
    Images - 44 % -
    Webfonts - 17 % -
    Other - 2 % -
    -
    - -
    - css -
    .chaarts.donut {
    +							
    Code generated for 88%.
    + +
    + + + +
    + +
    +
    +
    +

    + Switch
    + Allows you to disable styles on the following table. +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Pie chart example with a value between 50 and 75%
    ResourceProportion
    HTML + 2 %
    CSS + 2 %
    JS + 32 %
    Images + 64 %
    +
    + +
    +
    +

    + Switch
    + Allows you to disable styles on the following table. +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Pie chart example with a value greater than 75%
    ResourceProportion
    HTML + 2 %
    CSS + 2 %
    JS + 8 %
    Images + 88 %
    +
    +
    + +

    Donut

    + +

    + On the <table> element, we add an --offset variable + that allows us to determine the size of the hole of the donut, + generated using mask-image and radial-gradient(). + Ana Tudor has made + many examples of using mask-* on CodePen, have a look! +

    + +
    +
    +

    + Switch
    + Allows you to disable styles on the following table. +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Distribution of the weight of resources for ffoodd.fr +
    ResourceProportion
    HTML + 2 %
    CSS + 2 %
    JS + 32 %
    Json + 1 %
    Images + 44 %
    Webfonts + 17 %
    Other + 2 %
    +
    + +
    + css +
    .chaarts.donut {
       --mask: radial-gradient(
         circle at 50% calc(50% - .25rem),
         transparent 0 var(--offset),
    @@ -895,126 +824,103 @@ 

    Donut

    --away: calc( var(--radius) / 2 - 2.5rem ); }
    -
    - -
    -

    Conical gradient

    -

    - The use of conic-gradient() is promising for this case. - You'll find examples made by Ana Tudor and Léa Verou - — who actually wrote the specification, and designed - a polyfill. - However, current support is limited to WebKit based browsers - is depressing, and still raises some accessibility issues - since you can't assign a pattern to each color of the conic-gradient(). -

    -
    - -

    Polar chart

    - -

    - For this variant, wa change almost nothing: only the --zoom variable - and its implication in the scaling of portions using scale(). -

    - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Distribution of the weight of resources for ffoodd.fr
    ResourceProportion
    HTML - 2 % -
    CSS - 2 % -
    JS - 32 % -
    Json - 1 % -
    Images - 44 % -
    Webfonts - 17 % -
    Other - 2 % -
    -
    - -
    - css -
    .chaarts.polar td::before {
    +	
    + +
    +

    Conical gradient

    +

    + The use of conic-gradient() is promising for this case. + You'll find examples made by Ana Tudor and Léa Verou + — who actually wrote the specification, and designed + a polyfill. + However, current support is limited to WebKit based + browsers + is depressing, and still raises some accessibility issues + since you can't assign a pattern to each color of the conic-gradient(). +

    +
    + +

    Polar chart

    + +

    + For this variant, wa change almost nothing: only the --zoom variable + and its implication in the scaling of portions using scale(). +

    + +
    +
    +

    + Switch
    + Allows you to disable styles on the following table. +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Distribution of the weight of resources for ffoodd.fr +
    ResourceProportion
    HTML + 2 %
    CSS + 2 %
    JS + 32 %
    Json + 1 %
    Images + 44 %
    Webfonts + 17 %
    Other + 2 %
    +
    + +
    + css +
    .chaarts.polar td::before {
       --zoom: 50;
       transform:
         translate3d( -50%, -50%, 0 )
    @@ -1034,17 +940,11 @@ 

    Polar chart

    opacity: .5; }
    -
    - +
    + + - - - - - - - - - \ No newline at end of file + + diff --git a/docs/radar-charts.html b/docs/radar-charts.html index 00663e8..4f8a0ec 100644 --- a/docs/radar-charts.html +++ b/docs/radar-charts.html @@ -1,194 +1,197 @@ - - - - - - Radar charts — chaarts - - - - - - - - - - - + + + + + + + Radar charts — chaarts + + + + + + + + + + + - +
    - - - - - + + +
    - -

    Radar charts

    - -

    - This one's kind of fun. We define some CSS - variables on the table: the scale (and tiers), the number of elements, and the values. -

    - -

    - On the CSS side, it's getting complicated: -

    - -
      -
    • - on the <table> element, the circular scale is created using two successive - repeating-radial-gradient() — depending on the - --scale and --step variables; -
    • -
    • - each element <th> is moved outside the circle thus formed, - thanks to a technique borrowed from - - Ana Tudor, who explains it on StackOverflow; -
    • -
    • - then — still on header cells — the value corresponding to each column - is displayed in a pseudo-element ::after using - a - trick from Cassie Evans, using counter-reset and counter() - to display a numerical variable in the content property. - However counter-reset only works with integers, and our value might be a number. - So we rely on - Carter Li's ruse using calc() to convert numbers to integers— and - @property for Chromium-based browsers. Boum! -
    • - Then the magic works on the <td> elements: -
        -
      1. - each of which is adjusted to form a square with a side equal - to the radius of the circle on the background; -
      2. -
      3. - then transformed to represent a portion of the circle according to - the number of elements — specified with --items — using - - a trick shared by Sara Soueidan on Codrops, -
      4. -
      5. each one is decorated with a border at the bottom;
      6. -
      7. - then we use again clip-path polygon() function - on each direct child <span> —  extended to occupy the whole surface - of its parent <td> — in order to form a triangle, based for one side - on the ratio value of the current element / scale, and on another side a ratio based on the - value of the next element (yum calc()) - — but on another scale… -
      8. -
      9. - because to compensate for the distortion - due to the skew() function, - we need to correct the scale on which the second ratio is calculated - using a little trigonometry: -
          -
        • - we know one side of the right-angled triangle obtained after the deformation, - as well as two angles — the right one, of course, and we deduce - the second from the angle used to deform the element; -
        • -
        • - so we can calculate the hypothenuse using the sine law, - — as before in the pie chart; -
        • -
        • - and finally, all we have to do is calculate the ratio between the initial dimension - — the side — and the final dimension — the hypothenuse — - and apply this ratio to the scale on which the second point of the polygon is placed. -
        • -
        -
      10. -
      11. - The third point of the polygon is the bottom right corner, whose coordinates are - 100% 100%; -
      12. -
      -
    • - one last trick is necessary to close the shape you have seen, - we use the current and next value for each element. But when we get to the last element, - there is no next! So we need to add a value, to which we assign - the first value — in this example, --8: var(--1);. -
    • -
    - -

    And that's it!

    - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Level of interest by domain, out of 20
    AccessibilitySEOPerformanceCompatibilitySecurityCode qualityTest
    1411131610124
    -
    - -
    - HTML -
    <table class="chaarts radar" id="radar" style="--scale: 20; --step: 5; --items: 7; --1: 14; --2: 11; --3: 13; --4: 16; --5: 10; --6: 12; --7: 4; --8: var(--1);">
    +	

    Radar charts

    + +

    + This one's kind of fun. We define some CSS + variables on the table: the scale (and tiers), the number of elements, and the values. +

    + +

    + On the CSS side, it's getting complicated: +

    + +
      +
    • + on the <table> element, the circular scale is created using two successive + repeating-radial-gradient() — depending on the + --scale and --step variables; +
    • +
    • + each element <th> is moved outside the circle thus formed, + thanks to a technique borrowed from + + Ana Tudor, who explains it on StackOverflow; +
    • +
    • + then — still on header cells — the value corresponding to each column + is displayed in a pseudo-element ::after using + a + trick from Cassie Evans, using counter-reset and counter() + to display a numerical variable in the content property. + However counter-reset only works with integers, and our value might be a number. + So we rely on + Carter Li's ruse using calc() to convert numbers to integers— and + @property for Chromium-based browsers. Boum! +
    • +
    • + Then the magic works on the <td> elements: +
        +
      1. + each of which is adjusted to form a square with a side equal + to the radius of the circle on the background; +
      2. +
      3. + then transformed to represent a portion of the circle according to + the number of elements — specified with --items — using + + a trick shared by Sara Soueidan on Codrops, +
      4. +
      5. each one is decorated with a border at the bottom;
      6. +
      7. + then we use again clip-path polygon() function + on each direct child <span> —  extended to occupy the whole surface + of its parent <td> — in order to form a triangle, based for one side + on the ratio value of the current element / scale, and on another side a ratio based on the + value of the next element (yum calc()) + — but on another scale… +
      8. +
      9. + because to compensate for the distortion + due to the skew() function, + we need to correct the scale on which the second ratio is calculated + using a little trigonometry: +
          +
        • + we know one side of the right-angled triangle obtained after the deformation, + as well as two angles — the right one, of course, and we deduce + the second from the angle used to deform the element; +
        • +
        • + so we can calculate the hypothenuse using the sine law, + — as before in the pie chart; +
        • +
        • + and finally, all we have to do is calculate the ratio between the initial dimension + — the side — and the final dimension — the hypothenuse — + and apply this ratio to the scale on which the second point of the polygon is placed. +
        • +
        +
      10. +
      11. + The third point of the polygon is the bottom right corner, whose coordinates are + 100% 100%; +
      12. +
      +
    • +
    • + one last trick is necessary to close the shape you have seen, + we use the current and next value for each element. But when we get to the last element, + there is no next! So we need to add a value, to which we assign + the first value — in this example, --8: var(--1);. +
    • +
    + +

    And that's it!

    + +
    +
    +

    + Switch
    + Allows you to disable styles on the following table. +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Level of interest by domain, out of 20
    AccessibilitySEOPerformanceCompatibilitySecurityCode qualityTest
    1411131610124
    +
    + +
    + HTML +
    <table class="chaarts radar" id="radar" style="--scale: 20; --step: 5; --items: 7; --1: 14; --2: 11; --3: 13; --4: 16; --5: 10; --6: 12; --7: 4; --8: var(--1);">
       <caption id="caption-9">[…]</caption>
       <thead>
         <tr>
    @@ -204,10 +207,10 @@ 

    Radar charts

    </tbody> </table>
    -
    -
    - css -
    @supports(clip-path: polygon(calc( 0% 0%, 100% - ( var(--1) * 100% / var(--scale) ) ) 100%, 100% 100%)) {
    +	
    +
    + css +
    @supports(clip-path: polygon(calc( 0% 0%, 100% - ( var(--1) * 100% / var(--scale) ) ) 100%, 100% 100%)) {
       .chaarts[class*="radar"] {
         --radius: 12.8rem;
         --unitless-radius: calc( 1024 / 16 / 5 );
    @@ -327,164 +330,172 @@ 

    Radar charts

    } }
    -
    -
    - A Chromium bug -

    - There is currently a bug in Chromium — I filled - an issue on bugs.chromium.org — - when using the border-spacing property on the table: - it prevents Chrome to define the dimensions of the table… - For Chrome user, use the inspector to uncheck this property on the - <table> tag of these examples! -

    -

    Reduced test case

    -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Level of interest by domain, out of 20
    AccessibilitySEOPerformanceCompatibilitySecurityCode qualityTest
    1411131610124
    -
    -
    -
    - A Firefox feature -
    - The skew() function deforms the element by tilting it. -
    - Screenshot of the deformation caused by skew() - – props to Patrick Brosset - who made CSS - transform Highlighter happen in Firefox DevTools. -
    -
    -
    - - -

    Overlapping radars

    - -

    Very few changes compared to the previous version:

    - -
      -
    1. - the <table> element no longer carries the values, - but has a new --areas custom property to indicate the number of rows in the table; -
    2. -
    3. - however we multiply the number of rows in the body of the table: -
        -
      • - each one carries several variables: - --color then the values — --1, etc.; -
      • -
      • - and contains several cells: a <th scope="row"> row header cell - and <td> data cells; -
      -
    4. -
    5. - the rest is relatively common now — if you've gone through the previous examples: -
        -
      1. - a color for each row, presented on the header cells - and serving as a background for the data cells; -
      2. -
      3. - a distinctive hover effect over each row: the values appear - verbatim on hovering, and the hovered row is highlighted. In order not to deprive users - who do not have a good hover pointer, this effect is a progressive enhancement - based on the @media (hover: hover) { … } media query. -
      4. -
      -
    6. - -
    - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Level of interest by domain, out of 20
    AccessibilitySEOPerformanceCompatibilitySecurityCode qualityTest
    Gaël1411131614104
    Luc18101116101211
    -
    - -
    - HTML -
    <table class="chaarts radar-multiple" id="radar-multiple" style="--scale: 20; --step: 5; --items: 7; --areas: 2;">
    +	
    +
    + A Chromium bug +

    + There is currently a bug in Chromium — I filled + an issue on bugs.chromium.org — + when using the border-spacing property on the table: + it prevents Chrome to define the dimensions of the table… + For Chrome user, use the inspector to uncheck this property on the + <table> tag of these examples! +

    +

    Reduced test case

    +
    +
    +

    + Switch
    + Allows you to disable styles on the following table. +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Level of interest by domain, out of 20
    AccessibilitySEOPerformanceCompatibilitySecurityCode qualityTest
    1411131610124
    +
    +
    +
    + A Firefox feature +
    + The skew() function deforms the element by tilting it. +
    + Screenshot of the deformation caused by skew() + – props to Patrick Brosset + who made CSS + transform Highlighter happen in Firefox DevTools. +
    +
    +
    + + +

    Overlapping radars

    + +

    Very few changes compared to the previous version:

    + +
      +
    1. + the <table> element no longer carries the values, + but has a new --areas custom property to indicate the number of rows in the table; +
    2. +
    3. + however we multiply the number of rows in the body of the table: +
        +
      • + each one carries several variables: + --color then the values — --1, etc.; +
      • +
      • + and contains several cells: a <th scope="row"> row header cell + and <td> data cells; +
      • +
      +
    4. +
    5. + the rest is relatively common now — if you've gone through the previous examples: +
        +
      1. + a color for each row, presented on the header cells + and serving as a background for the data cells; +
      2. +
      3. + a distinctive hover effect over each row: the values appear + verbatim on hovering, and the hovered row is highlighted. In order not to deprive users + who do not have a good hover pointer, this effect is a progressive enhancement + based on the @media (hover: hover) { … } media query. +
      4. +
      +
    6. + +
    + +
    +
    +

    + Switch
    + Allows you to disable styles on the following table. +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Level of interest by domain, out of 20
    AccessibilitySEOPerformanceCompatibilitySecurityCode qualityTest
    Gaël1411131614104
    Luc18101116101211
    +
    + +
    + HTML +
    <table class="chaarts radar-multiple" id="radar-multiple" style="--scale: 20; --step: 5; --items: 7; --areas: 2;">
       <caption id="caption-9">[…]</caption>
       <thead>
         <tr>
    @@ -504,10 +515,10 @@ 

    Overlapping radars

    </tbody> </table>
    -
    -
    - css -
    .chaarts.radar-multiple {
    +	
    +
    + css +
    .chaarts.radar-multiple {
       margin-bottom: 12rem;
     }
     
    @@ -601,17 +612,11 @@ 

    Overlapping radars

    } }
    -
    - +
    + + - - - - - - - - - \ No newline at end of file + + diff --git a/docs/radar.html b/docs/radar.html index 2e003d5..db10ecf 100644 --- a/docs/radar.html +++ b/docs/radar.html @@ -1,194 +1,200 @@ - - - - - - Radar — chaarts - - - - - - - - - - - + + + + + + + Radar — chaarts + + + + + + + + + + + - +
    - - - - - + + +
    - -

    Graphique radar

    - -

    - Celui-ci est plutôt amusant. On définit quelques variables - CSS sur le tableau -  : l’échelle (et les paliers), le nombre d’éléments, et les valeurs. -

    - -

    - Côté CSS, ça se complique : -

    - -
      -
    • - sur l’élément <table>, on crée l’échelle circulaire à l’aide de deux - repeating-radial-gradient() successifs — en fonction des variables - --scale et --step ; -
    • -
    • - chaque élément <th> est déplacé à l’extérieur du cercle ainsi formé, - grâce à une technique empruntée à - - Ana Tudor, qui l’explique sur StackOverflow ; -
    • -
    • - puis — toujours sur les cellules d’entête — la valeur correspondant à chaque colonne - est affichée dans un pseudo-élément ::after à l’aide - d’une - astuce de Cassie Evans, utilisant counter-reset et counter() - pour afficher une variable numérique dans la propriété content. - Cependant counter-reset ne fonctionne qu’avec un entier et notre valeur peut être un nombre. Alors on s’appuie sur - une ruse de - Carter Li utilisant calc() pour convertir les nombres en entiers — et - @property pour les navigateurs basés sur Chromium. Boum ! -
    • - Puis la magie opère sur les éléments <td> : -
        -
      1. - chacun est ajusté pour former un carré dont le côté est égal au rayon - du cercle en arrière-plan ; -
      2. -
      3. - puis transformé de façon à représenter une portion du cercle en fonction du nombre - d’éléments — précisé avec --items — grâce à - - une technique partagée par Sara Soueidan sur Codrops, -
      4. -
      5. chacun se voit décoré d’une bordure, en bas ;
      6. -
      7. - puis on utilise de nouveau clip-path et la fonction polygon() - sur chaque enfant direct <span> — étendu pour occuper toute la surface - de son <td> de parent — afin de former un triangle, basé pour un côté - sur le ratio valeur de l’élément courant / échelle, et sur un autre côté un ratio basé sur - la valeur de l’élément suivant (miam les calc()) - — mais sur une autre échelle… -
      8. -
      9. - car pour compenser la distorsion due à la fonction skew(), - nous devons corriger l’échelle sur laquelle est calculée le second ratio à l’aide d’un peu - de trigonométrie : -
          -
        • - nous connaissons un côté du triangle rectangle obtenu après la déformation, - ainsi que deux angles — le droit, bien entendu, et nous déduisons le deuxième de - l’angle utilisé pour déformer l’élément ; -
        • -
        • - nous pouvons donc calculer l’hypothénuse en utilisant la loi des sinus, - — comme précédemment dans le graphique en tarte ; -
        • -
        • - et finalement, il ne nous reste qu’à calculer le ratio entre la dimension initiale - — le côté — et la dimension finale — l’hypothénuse — et appliquer ce ratio - à l’échelle sur laquelle est placée le deuxième point du polygone. -
        • -
        -
      10. -
      11. - le troisième point du polygône est l’angle en bas à droite, dont les coordonnées sont - 100% 100% ; -
      12. -
      -
    • - une dernière astuce est nécessaire pour fermer la forme  vous l’avez vu, nous utilisons - la valeur courante et la valeur suivante pour chaque élément. Mais arrivé au dernier élément, - il n’y a plus de suivant ! Il faut donc ajouter une valeur, - à laquelle on attribue la première valeur — dans cet exemple, --8: var(--1);. -
    • -
    - -

    Et voilà, c’est tout !

    - -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Niveau d’intérêt par domaine, sur 20
    AccessibilitéRéférencementPerformanceCompatibilitéSécuritéQualité de codeTest
    1411131610124
    -
    - -
    - Le HTML -
    <table class="chaarts radar" id="radar" style="--scale: 20; --step: 5; --items: 7; --1: 14; --2: 11; --3: 13; --4: 16; --5: 10; --6: 12; --7: 4; --8: var(--1);">
    +	

    Graphique radar

    + +

    + Celui-ci est plutôt amusant. On définit quelques variables + CSS sur le tableau +  : l’échelle (et les paliers), le nombre d’éléments, et les valeurs. +

    + +

    + Côté CSS, ça se complique : +

    + +
      +
    • + sur l’élément <table>, on crée l’échelle circulaire à l’aide de deux + repeating-radial-gradient() successifs — en fonction des variables + --scale et --step ; +
    • +
    • + chaque élément <th> est déplacé à l’extérieur du cercle ainsi formé, + grâce à une technique empruntée à + + Ana Tudor, qui l’explique sur StackOverflow ; +
    • +
    • + puis — toujours sur les cellules d’entête — la valeur correspondant à chaque colonne + est affichée dans un pseudo-élément ::after à l’aide + d’une + astuce de Cassie Evans, utilisant counter-reset et counter() + pour afficher une variable numérique dans la propriété content. + Cependant counter-reset ne fonctionne qu’avec un entier et notre valeur peut être un nombre. Alors on + s’appuie sur + une ruse de + Carter Li utilisant calc() pour convertir les nombres en entiers — et + @property pour les navigateurs basés sur Chromium. Boum ! +
    • +
    • + Puis la magie opère sur les éléments <td> : +
        +
      1. + chacun est ajusté pour former un carré dont le côté est égal au rayon + du cercle en arrière-plan ; +
      2. +
      3. + puis transformé de façon à représenter une portion du cercle en fonction du nombre + d’éléments — précisé avec --items — grâce à + + une technique partagée par Sara Soueidan sur Codrops, +
      4. +
      5. chacun se voit décoré d’une bordure, en bas ;
      6. +
      7. + puis on utilise de nouveau clip-path et la fonction polygon() + sur chaque enfant direct <span> — étendu pour occuper toute la surface + de son <td> de parent — afin de former un triangle, basé pour un côté + sur le ratio valeur de l’élément courant / échelle, et sur un autre côté un ratio basé sur + la valeur de l’élément suivant (miam les calc()) + — mais sur une autre échelle… +
      8. +
      9. + car pour compenser la distorsion due à la fonction skew(), + nous devons corriger l’échelle sur laquelle est calculée le second ratio à l’aide d’un peu + de trigonométrie : +
          +
        • + nous connaissons un côté du triangle rectangle obtenu après la déformation, + ainsi que deux angles — le droit, bien entendu, et nous déduisons le deuxième de + l’angle utilisé pour déformer l’élément ; +
        • +
        • + nous pouvons donc calculer l’hypothénuse en utilisant la loi des sinus, + — comme précédemment dans le graphique en tarte ; +
        • +
        • + et finalement, il ne nous reste qu’à calculer le ratio entre la dimension initiale + — le côté — et la dimension finale — l’hypothénuse — et appliquer ce ratio + à l’échelle sur laquelle est placée le deuxième point du polygone. +
        • +
        +
      10. +
      11. + le troisième point du polygône est l’angle en bas à droite, dont les coordonnées sont + 100% 100% ; +
      12. +
      +
    • +
    • + une dernière astuce est nécessaire pour fermer la forme  vous l’avez vu, nous utilisons + la valeur courante et la valeur suivante pour chaque élément. Mais arrivé au dernier élément, + il n’y a plus de suivant ! Il faut donc ajouter une valeur, + à laquelle on attribue la première valeur — dans cet exemple, --8: var(--1);. +
    • +
    + +

    Et voilà, c’est tout !

    + +
    +
    +

    + Interrupteur
    + Permet de désactiver les styles sur le tableau suivant. +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Niveau d’intérêt par domaine, sur 20
    AccessibilitéRéférencementPerformanceCompatibilitéSécuritéQualité de codeTest
    1411131610124
    +
    + +
    + Le HTML + +
    <table class="chaarts radar" id="radar" style="--scale: 20; --step: 5; --items: 7; --1: 14; --2: 11; --3: 13; --4: 16; --5: 10; --6: 12; --7: 4; --8: var(--1);">
       <caption id="caption-9">[…]</caption>
       <thead>
         <tr>
    @@ -204,10 +210,10 @@ 

    Graphique radar

    </tbody> </table>
    -
    -
    - Le css -
    @supports(clip-path: polygon(calc( 0% 0%, 100% - ( var(--1) * 100% / var(--scale) ) ) 100%, 100% 100%)) {
    +	
    +
    + Le css +
    @supports(clip-path: polygon(calc( 0% 0%, 100% - ( var(--1) * 100% / var(--scale) ) ) 100%, 100% 100%)) {
       .chaarts[class*="radar"] {
         --radius: 12.8rem;
         --unitless-radius: calc( 1024 / 16 / 5 );
    @@ -327,164 +333,174 @@ 

    Graphique radar

    } }
    -
    -
    - Bug dans Chromium -

    - Il y a en ce moment un bug dans Chromium — j’ai saisi - un ticket sur bugs.chromium.org — - lors de l’utilisation de la propriété border-spacing sur le tableau : - cela empêche Chrome de définir les dimensions du tableau… - Pour les utilisateurs de Chrome, utilisez l’inspecteur pour décocher cette propriété - sur la balise <table> de ces exemples ! -

    -

    Cas de test réduit

    -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Niveau d’intérêt par domaine, sur 20
    AccessibilitéRéférencementPerformanceCompatibilitéSécuritéQualité de codeTest
    1411131610124
    -
    -
    -
    - Une fonctionnalité Firefox -
    - La fonction skew() déforme l’élément en l’inclinant. -
    - Capture d’écran de la déformation provoquée par skew() - – merci à Patrick Brosset - qui a mis en place la - prévisualisation des transformations CSS dans les outils de développement de Firefox. -
    -
    -
    - - -

    Radars superposés

    - -

    Très peu de changements par rapport à la version précédente :

    - -
      -
    1. - l’élément <table> ne porte plus les valeurs, mais dispose d’une nouvelle - variable --areas pour indiquer le nombre de lignes dans le tableau ; -
    2. -
    3. - en revanche on multiplie le nombre de lignes dans le corps du tableau : -
        -
      • - chacune porte plusieurs variables : - --color puis les valeurs — --1, etc. ; -
      • -
      • - et contient plusieurs cellules : une d’entête de ligne <th scope="row"> - et des cellules de données <td> ; -
      -
    4. -
    5. - le reste est relativement commun désormais — si vous avez parcourus les exemples précédents : -
        -
      1. - une couleur pour chaque ligne, présentée sur les cellules d’entête et servant d’arrière-plan aux - cellules de données ; -
      2. -
      3. - un effet distinctif au survol de chaque ligne : les valeurs apparaissent - textuellement au survol, et la ligne survolée est mise en exergue. Afin de ne pas priver les utilisateurs - n’ayant pas de pointeur doué pour le survol, cet effet est une amélioration progressive - basé sur la media query @media (hover: hover) { … }. -
      4. -
      -
    6. - -
    - -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Niveau d’intérêt par domaine, sur 20
    AccessibilitéRéférencementPerformanceCompatibilitéSécuritéQualité de codeTest
    Gaël1411131614104
    Luc18101116101211
    -
    - -
    - Le HTML -
    <table class="chaarts radar-multiple" id="radar-multiple" style="--scale: 20; --step: 5; --items: 7; --areas: 2;">
    +	
    +
    + Bug dans Chromium +

    + Il y a en ce moment un bug dans Chromium — j’ai saisi + un ticket sur bugs.chromium.org — + lors de l’utilisation de la propriété border-spacing sur le tableau : + cela empêche Chrome de définir les dimensions du tableau… + Pour les utilisateurs de Chrome, utilisez l’inspecteur pour décocher cette propriété + sur la balise <table> de ces exemples ! +

    +

    Cas de test réduit

    +
    +
    +

    + Interrupteur
    + Permet de désactiver les styles sur le tableau suivant. +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Niveau d’intérêt par domaine, sur 20
    AccessibilitéRéférencementPerformanceCompatibilitéSécuritéQualité de codeTest
    1411131610124
    +
    +
    +
    + Une fonctionnalité Firefox +
    + La fonction skew() déforme l’élément en l’inclinant. +
    + Capture d’écran de la déformation provoquée par skew() + – merci à Patrick Brosset + qui a mis en place la + prévisualisation des transformations CSS dans les outils de développement de Firefox. +
    +
    +
    + + +

    Radars superposés

    + +

    Très peu de changements par rapport à la version précédente :

    + +
      +
    1. + l’élément <table> ne porte plus les valeurs, mais dispose d’une nouvelle + variable --areas pour indiquer le nombre de lignes dans le tableau ; +
    2. +
    3. + en revanche on multiplie le nombre de lignes dans le corps du tableau : +
        +
      • + chacune porte plusieurs variables : + --color puis les valeurs — --1, etc. ; +
      • +
      • + et contient plusieurs cellules : une d’entête de ligne <th scope="row"> + et des cellules de données <td> ; +
      • +
      +
    4. +
    5. + le reste est relativement commun désormais — si vous avez parcourus les exemples précédents : +
        +
      1. + une couleur pour chaque ligne, présentée sur les cellules d’entête et servant d’arrière-plan aux + cellules de données ; +
      2. +
      3. + un effet distinctif au survol de chaque ligne : les valeurs apparaissent + textuellement au survol, et la ligne survolée est mise en exergue. Afin de ne pas priver les utilisateurs + n’ayant pas de pointeur doué pour le survol, cet effet est une amélioration progressive + basé sur la media query @media (hover: hover) { … }. +
      4. +
      +
    6. + +
    + +
    +
    +

    + Interrupteur
    + Permet de désactiver les styles sur le tableau suivant. +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Niveau d’intérêt par domaine, sur 20
    AccessibilitéRéférencementPerformanceCompatibilitéSécuritéQualité de codeTest
    Gaël1411131614104
    Luc18101116101211
    +
    + +
    + Le HTML + +
    <table class="chaarts radar-multiple" id="radar-multiple" style="--scale: 20; --step: 5; --items: 7; --areas: 2;">
       <caption id="caption-9">[…]</caption>
       <thead>
         <tr>
    @@ -504,10 +520,10 @@ 

    Radars superposés

    </tbody> </table>
    -
    -
    - Le css -
    .chaarts.radar-multiple {
    +	
    +
    + Le css +
    .chaarts.radar-multiple {
       margin-bottom: 12rem;
     }
     
    @@ -601,17 +617,11 @@ 

    Radars superposés

    } }
    -
    - +
    + + - - - - - - - - - \ No newline at end of file + + diff --git a/gulpfile.js b/gulpfile.js index 1571f4f..301c822 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -44,7 +44,7 @@ function sync(done) { * @section Watch */ function watch() { - gulp.watch( options.paths.root + 'sass/**/*.scss', gulp.series( 'compile', 'doc', 'sri', reload ) ); + gulp.watch( options.paths.root + 'src/**/*.scss', gulp.series( 'compile', 'doc', 'sri', reload ) ); gulp.watch( options.paths.root + '*.js', gulp.series( 'compile', 'doc', 'sri', reload ) ); gulp.watch( options.paths.src + 'img/**/*.*', gulp.series( 'doc', reload ) ); gulp.watch( options.paths.src + 'templates/*.html', gulp.series( 'doc', reload ) ); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..37864c0 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,10106 @@ +{ + "name": "chaarts", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "chaarts", + "version": "0.0.1", + "license": "MIT", + "dependencies": { + "normalize.css": "^8.0.1", + "sseeeedd": "^0.2.1" + }, + "devDependencies": { + "autoprefixer": "^10.4.7", + "concurrently": "^7.2.2", + "cssnano": "^5.1.12", + "html-validate": "^7.1.2", + "imagemin-cli": "^7.0.0", + "imagemin-mozjpeg": "^10.0.0", + "imagemin-pngcrush": "^7.0.0", + "imagemin-pngquant": "^9.0.2", + "imagemin-zopfli": "^7.0.0", + "nodemon": "^2.0.19", + "nunjucks-cli": "^1.0.0", + "pa11y-ci": "^3.0.1", + "pa11y-ci-reporter-html": "^5.0.0", + "postcss": "^8.4.14", + "postcss-cli": "^10.0.0", + "purgecss": "^4.1.3", + "sass": "^1.53.0", + "servor": "^4.0.2", + "shx": "^0.3.4", + "stylelint": "^15.10.1", + "stylelint-config-recommended-scss": "^12.0.0", + "stylelint-scss": "^5.0.1", + "terser": "^5.14.2" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", + "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.0.tgz", + "integrity": "sha512-dTKSIHHWc0zPvcS5cqGP+/TPFUJB0ekJ9dGKvMAFoNuBFhDPBt9OMGNZiIA5vTiNdGHHBeScYPXIGBMnVOahsA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^2.1.1" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.1.1.tgz", + "integrity": "sha512-GbrTj2Z8MCTUv+52GE0RbFGM527xuXZ0Xa5g0Z+YN573uveS4G0qi6WNOMyz3yrFM/jaILTTwJ0+umx81EzqfA==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.2.tgz", + "integrity": "sha512-M8cFGGwl866o6++vIY7j1AKuq9v57cf+dGepScwCcbut9ypJNr4Cj+LLTWligYUZ0uyhEoJDKt5lvyBfh2L3ZQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^2.3.0", + "@csstools/css-tokenizer": "^2.1.1" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.0.0.tgz", + "integrity": "sha512-hBI9tfBtuPIi885ZsZ32IMEU/5nlZH/KOVYJCOh7gyMxaVLGmLedYqFN6Ui1LXkI8JlC8IsuC0rF0btcRZKd5g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.0.13" + } + }, + "node_modules/@html-validate/stylish": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@html-validate/stylish/-/stylish-4.1.0.tgz", + "integrity": "sha512-f2MOKJ2HVdLxpOOg2jD6hjDTDJic3wpb8/UdDDIic5jTvgfMMPN3PoiNWlqDg/mCzLIj1b/p1hCRx4Kz5lbVjw==", + "dev": true, + "dependencies": { + "kleur": "^4.0.0" + }, + "engines": { + "node": ">= 14.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@sidvind/better-ajv-errors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@sidvind/better-ajv-errors/-/better-ajv-errors-2.1.0.tgz", + "integrity": "sha512-JuIb009FhHuL9priFBho2kv7QmZOydj0LgYvj+h1t0mMCmhM/YmQNRlJR5wVtBZya6wrVFK5Hi5TIbv5BKEx7w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.0", + "chalk": "^4.1.0" + }, + "engines": { + "node": ">= 14.0.0" + }, + "peerDependencies": { + "ajv": "4.11.8 - 8" + } + }, + "node_modules/@sidvind/better-ajv-errors/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@sidvind/better-ajv-errors/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@sidvind/better-ajv-errors/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@sidvind/better-ajv-errors/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@sidvind/better-ajv-errors/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sidvind/better-ajv-errors/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sindresorhus/is": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", + "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "dev": true + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==", + "dev": true, + "optional": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "node_modules/@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==", + "dev": true + }, + "node_modules/a11y-dialog": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/a11y-dialog/-/a11y-dialog-5.5.2.tgz", + "integrity": "sha512-1G7uP6z896DCBXyiwnaMze8YDoljtwgEPezgcJInq2f/chskPQooV505lHOtZpEvtI+ddDUPp0ECjHQjUIaPDw==" + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true, + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/archive-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", + "integrity": "sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA==", + "dev": true, + "dependencies": { + "file-type": "^4.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/archive-type/node_modules/file-type": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", + "integrity": "sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arrify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz", + "integrity": "sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.14", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", + "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + ], + "dependencies": { + "browserslist": "^4.21.5", + "caniuse-lite": "^1.0.30001464", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/axe-core": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz", + "integrity": "sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bfj": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", + "integrity": "sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.5", + "check-types": "^11.1.1", + "hoopy": "^0.1.4", + "tryer": "^1.0.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/bin-build": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bin-build/-/bin-build-3.0.0.tgz", + "integrity": "sha512-jcUOof71/TNAI2uM5uoUaDq2ePcVBQ3R/qhxAz1rX7UfvduAL/RXD3jXzvn8cVcDJdGVkiR1shal3OH0ImpuhA==", + "dev": true, + "dependencies": { + "decompress": "^4.0.0", + "download": "^6.2.2", + "execa": "^0.7.0", + "p-map-series": "^1.0.0", + "tempfile": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-build/node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/bin-build/node_modules/execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==", + "dev": true, + "dependencies": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-build/node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-build/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/bin-build/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true + }, + "node_modules/bin-check": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-4.1.0.tgz", + "integrity": "sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA==", + "dev": true, + "dependencies": { + "execa": "^0.7.0", + "executable": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-check/node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/bin-check/node_modules/execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==", + "dev": true, + "dependencies": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-check/node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-check/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/bin-check/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true + }, + "node_modules/bin-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-3.1.0.tgz", + "integrity": "sha512-Mkfm4iE1VFt4xd4vH+gx+0/71esbfus2LsnCGe8Pi4mndSPyT+NGES/Eg99jx8/lUGWfu3z2yuB/bt5UB+iVbQ==", + "dev": true, + "dependencies": { + "execa": "^1.0.0", + "find-versions": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/bin-version-check": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-4.0.0.tgz", + "integrity": "sha512-sR631OrhC+1f8Cvs8WyVWOA33Y8tgwjETNPyyD/myRBXLkfS/vl74FmH/lFcRl9KY3zwGh7jFhvyk9vV3/3ilQ==", + "dev": true, + "dependencies": { + "bin-version": "^3.0.0", + "semver": "^5.6.0", + "semver-truncate": "^1.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/bin-version-check/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/bin-wrapper": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bin-wrapper/-/bin-wrapper-4.1.0.tgz", + "integrity": "sha512-hfRmo7hWIXPkbpi0ZltboCMVrU+0ClXR/JgbCKKjlDjQf6igXa7OwdqNcFWQZPZTgiY7ZpzE3+LjjkLiTN2T7Q==", + "dev": true, + "dependencies": { + "bin-check": "^4.1.0", + "bin-version-check": "^4.0.0", + "download": "^7.1.0", + "import-lazy": "^3.1.0", + "os-filter-obj": "^2.0.0", + "pify": "^4.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/bin-wrapper/node_modules/download": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/download/-/download-7.1.0.tgz", + "integrity": "sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ==", + "dev": true, + "dependencies": { + "archive-type": "^4.0.0", + "caw": "^2.0.1", + "content-disposition": "^0.5.2", + "decompress": "^4.2.0", + "ext-name": "^5.0.0", + "file-type": "^8.1.0", + "filenamify": "^2.0.0", + "get-stream": "^3.0.0", + "got": "^8.3.1", + "make-dir": "^1.2.0", + "p-event": "^2.1.0", + "pify": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/bin-wrapper/node_modules/download/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-wrapper/node_modules/file-type": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-8.1.0.tgz", + "integrity": "sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/bin-wrapper/node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-wrapper/node_modules/got": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", + "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^0.7.0", + "cacheable-request": "^2.1.1", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "into-stream": "^3.1.0", + "is-retry-allowed": "^1.1.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "mimic-response": "^1.0.0", + "p-cancelable": "^0.4.0", + "p-timeout": "^2.0.1", + "pify": "^3.0.0", + "safe-buffer": "^5.1.1", + "timed-out": "^4.0.1", + "url-parse-lax": "^3.0.0", + "url-to-options": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-wrapper/node_modules/got/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-wrapper/node_modules/p-cancelable": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-wrapper/node_modules/p-event": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz", + "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==", + "dev": true, + "dependencies": { + "p-timeout": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/bin-wrapper/node_modules/p-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "dev": true, + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-wrapper/node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-wrapper/node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", + "dev": true, + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "dev": true, + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", + "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001503", + "electron-to-chromium": "^1.4.431", + "node-releases": "^2.0.12", + "update-browserslist-db": "^1.0.11" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "dependencies": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", + "dev": true + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/cacheable-request": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", + "integrity": "sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ==", + "dev": true, + "dependencies": { + "clone-response": "1.0.2", + "get-stream": "3.0.0", + "http-cache-semantics": "3.8.1", + "keyv": "3.0.0", + "lowercase-keys": "1.0.0", + "normalize-url": "2.0.1", + "responselike": "1.0.2" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz", + "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==", + "dev": true, + "dependencies": { + "camelcase": "^6.3.0", + "map-obj": "^4.1.0", + "quick-lru": "^5.1.1", + "type-fest": "^1.2.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001512", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001512.tgz", + "integrity": "sha512-2S9nK0G/mE+jasCUsMPlARhRCts1ebcp2Ji8Y8PWi4NDE1iRdLCnEPHkEfeBrGC45L4isBx5ur3IQ6yTE2mRZw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/caw": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz", + "integrity": "sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==", + "dev": true, + "dependencies": { + "get-proxy": "^2.0.0", + "isurl": "^1.0.0-alpha5", + "tunnel-agent": "^0.6.0", + "url-to-options": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/check-types": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.2.tgz", + "integrity": "sha512-HBiYvXvn9Z70Z88XKjz3AEKd4HJhBXsa3j7xFnITAzoS8+q6eIGi8qDB8FKPBAjtuxjI/zFpwuiCb8oDtKOYrA==", + "dev": true + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "dev": true, + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/ci-logger": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/ci-logger/-/ci-logger-5.1.1.tgz", + "integrity": "sha512-MZHJNlvYvlYAwWK+2c19Cwfb+cuZGVWH6lhStvSrw/8q18NmMm6hjwmAooKVhp3pOHFD2aiju5wk17ef+XrSuQ==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", + "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/concurrently": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.6.0.tgz", + "integrity": "sha512-BKtRgvcJGeZ4XttiDiNcFiRlxoAeZOseqUvyYRUp/Vtd+9p1ULmeoSqGsDA+2ivdeDFpqrJvGvmI+StKfKl5hw==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "date-fns": "^2.29.1", + "lodash": "^4.17.21", + "rxjs": "^7.0.0", + "shell-quote": "^1.7.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^17.3.1" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/concurrently/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concurrently/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/console-stream": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/console-stream/-/console-stream-0.1.1.tgz", + "integrity": "sha512-QC/8l9e6ofi6nqZ5PawlDgzmMw3OxIXtvolBzap/F4UDBJlDaZRSNbL/lb41C29FcbSJncBFlJFj2WJoNyZRfQ==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", + "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", + "dev": true, + "dependencies": { + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + } + }, + "node_modules/cosmiconfig/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/cosmiconfig/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/css-declaration-sorter": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.0.tgz", + "integrity": "sha512-jDfsatwWMWN0MODAFuHszfjphEXfNw9JUAhmY4pLu3TyTU+ohUpsbVtbU+1MZn4a47D9kqh03i4eyOm+74+zew==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-functions-list": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.1.0.tgz", + "integrity": "sha512-/9lCvYZaUbBGvYUgYGFJ4dcYiyqdhSjG7IPVluoV8A1ILjkF7ilmhp1OGUz8n+nmBcu0RNrQAzgD8B6FJbrt2w==", + "dev": true, + "engines": { + "node": ">=12.22" + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", + "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", + "dev": true, + "dependencies": { + "cssnano-preset-default": "^5.2.14", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-preset-default": { + "version": "5.2.14", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", + "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", + "dev": true, + "dependencies": { + "css-declaration-sorter": "^6.3.1", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.1", + "postcss-convert-values": "^5.1.3", + "postcss-discard-comments": "^5.1.2", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.7", + "postcss-merge-rules": "^5.1.4", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.4", + "postcss-minify-selectors": "^5.2.1", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.1", + "postcss-normalize-repeat-style": "^5.1.1", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.1", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.3", + "postcss-reduce-initial": "^5.1.2", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", + "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", + "dev": true, + "dependencies": { + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tar": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", + "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", + "dev": true, + "dependencies": { + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tar/node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tarbz2": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", + "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "dev": true, + "dependencies": { + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tarbz2/node_modules/file-type": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", + "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-targz": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", + "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", + "dev": true, + "dependencies": { + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-targz/node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-unzip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", + "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==", + "dev": true, + "dependencies": { + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-unzip/node_modules/file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-unzip/node_modules/get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", + "dev": true, + "dependencies": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-unzip/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defaults/node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/dependency-graph": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/devtools-protocol": { + "version": "0.0.869402", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.869402.tgz", + "integrity": "sha512-VvlVYY+VDJe639yHs5PHISzdWTLL3Aw8rO4cvUtwvoxFd6FHbE4OpHHcde52M6096uYYazAmd4l0o5VuFRO2WA==", + "dev": true + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/download": { + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/download/-/download-6.2.5.tgz", + "integrity": "sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA==", + "dev": true, + "dependencies": { + "caw": "^2.0.0", + "content-disposition": "^0.5.2", + "decompress": "^4.0.0", + "ext-name": "^5.0.0", + "file-type": "5.2.0", + "filenamify": "^2.0.0", + "get-stream": "^3.0.0", + "got": "^7.0.0", + "make-dir": "^1.0.0", + "p-event": "^1.0.0", + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/download/node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/download/node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/download/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/duplexer3": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", + "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", + "dev": true + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.450", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.450.tgz", + "integrity": "sha512-BLG5HxSELlrMx7dJ2s+8SFlsCtJp37Zpk2VAxyC6CZtbc+9AJeZHfYHbrlSgdXp6saQ8StMqOTEDaBKgA7u1sw==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/exec-buffer": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/exec-buffer/-/exec-buffer-3.2.0.tgz", + "integrity": "sha512-wsiD+2Tp6BWHoVv3B+5Dcx6E7u5zky+hUwOHjuH2hKSLR3dvRmX8fk8UD8uqQixHs4Wk6eDmiegVrMPjKj7wpA==", + "dev": true, + "dependencies": { + "execa": "^0.7.0", + "p-finally": "^1.0.0", + "pify": "^3.0.0", + "rimraf": "^2.5.4", + "tempfile": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/exec-buffer/node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/exec-buffer/node_modules/execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==", + "dev": true, + "dependencies": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/exec-buffer/node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/exec-buffer/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/exec-buffer/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/exec-buffer/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "dependencies": { + "pify": "^2.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/executable/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ext-list": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "dev": true, + "dependencies": { + "mime-db": "^1.28.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ext-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "dev": true, + "dependencies": { + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", + "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "peer": true + }, + "node_modules/fast-xml-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.4.tgz", + "integrity": "sha512-fbfMDvgBNIdDJLdLOwacjFAPYt67tr31H9ZhWSm45CDAxvd0I6WTlSOUo7K2P/K5sA5JgMKG64PI3DMcaFdWpQ==", + "dev": true, + "funding": [ + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + }, + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "optional": true, + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/file-url": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/file-url/-/file-url-3.0.0.tgz", + "integrity": "sha512-g872QGsHexznxkIAdK8UiZRe7SkE6kvylShU4Nsj8NvfvZag7S0QuQ4IgvPDkk75HxgjIVDwycFTDAgIiO4nDA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/filenamify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz", + "integrity": "sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==", + "dev": true, + "dependencies": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.0", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-versions": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz", + "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==", + "dev": true, + "dependencies": { + "semver-regex": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/foreground-child/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/foreground-child/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/foreground-child/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", + "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/infusion" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-proxy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz", + "integrity": "sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==", + "dev": true, + "dependencies": { + "npm-conf": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/gifsicle": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/gifsicle/-/gifsicle-5.3.0.tgz", + "integrity": "sha512-FJTpgdj1Ow/FITB7SVza5HlzXa+/lqEY0tHQazAJbuAdvyJtkH4wIdsR2K414oaTwRXHFLLF+tYbipj+OpYg+Q==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "bin-build": "^3.0.0", + "bin-wrapper": "^4.0.0", + "execa": "^5.0.0" + }, + "bin": { + "gifsicle": "cli.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/imagemin/gisicle-bin?sponsor=1" + } + }, + "node_modules/gifsicle/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "optional": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/gifsicle/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "optional": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/gifsicle/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gifsicle/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gifsicle/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/gifsicle/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "optional": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gifsicle/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "optional": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gifsicle/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/gifsicle/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "optional": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gifsicle/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/gifsicle/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "optional": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/globby/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", + "dev": true + }, + "node_modules/got": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", + "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", + "dev": true, + "dependencies": { + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/got/node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/handlebars/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "dev": true, + "dependencies": { + "has-symbol-support-x": "^1.4.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/hogan.js": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz", + "integrity": "sha512-RqGs4wavGYJWE07t35JQccByczmNUXQT0E12ZYV1VKYu5UiAU9lsos/yBAcf840+zrUQQxgVduCR5/B8nNtibg==", + "dev": true, + "dependencies": { + "mkdirp": "0.3.0", + "nopt": "1.0.10" + }, + "bin": { + "hulk": "bin/hulk" + } + }, + "node_modules/hogan.js/node_modules/mkdirp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha512-OHsdUcVAQ6pOtg5JYWpCBo9W/GySVuwvP9hueRMW7UqshC0tbfzLv8wjySTPm3tfUZ/21CE9E1pJagOA91Pxew==", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "dev": true, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html_codesniffer": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/html_codesniffer/-/html_codesniffer-2.5.1.tgz", + "integrity": "sha512-vcz0yAaX/OaV6sdNHuT9alBOKkSxYb8h5Yq26dUqgi7XmCgGUSa7U9PiY1PBXQFMjKv1wVPs5/QzHlGuxPDUGg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/html-validate": { + "version": "7.18.1", + "resolved": "https://registry.npmjs.org/html-validate/-/html-validate-7.18.1.tgz", + "integrity": "sha512-K5jb0h/xAoeR8sJqyR0n/QaKL7rdT88sPCtN+Pvtyn5JUU+nidQe2gBB09WRzPTcQtPXBj4QxBUH5IA2tt8JQg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.10.0", + "@html-validate/stylish": "^4.0.1", + "@sidvind/better-ajv-errors": "^2.0.0", + "acorn-walk": "^8.0.0", + "ajv": "^8.0.0", + "deepmerge": "^4.2.0", + "espree": "^9.0.0", + "glob": "^10.0.0", + "ignore": "^5.0.0", + "kleur": "^4.1.0", + "minimist": "^1.2.0", + "prompts": "^2.0.0", + "semver": "^7.0.0" + }, + "bin": { + "html-validate": "bin/html-validate.js" + }, + "engines": { + "node": ">= 14.0" + }, + "peerDependencies": { + "jest": "^25.1 || ^26 || ^27.1 || ^28.1.3 || ^29.0.3", + "jest-diff": "^25.1 || ^26 || ^27.1 || ^28.1.3 || ^29.0.3", + "jest-snapshot": "^25.1 || ^26 || ^27.1 || ^28.1.3 || ^29.0.3" + }, + "peerDependenciesMeta": { + "jest": { + "optional": true + }, + "jest-diff": { + "optional": true + }, + "jest-snapshot": { + "optional": true + } + } + }, + "node_modules/html-validate/node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/html-validate/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/html-validate/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/html-validate/node_modules/eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/html-validate/node_modules/espree": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", + "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/html-validate/node_modules/glob": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.1.tgz", + "integrity": "sha512-9BKYcEeIs7QwlCYs+Y3GBvqAMISufUS0i2ELd11zpZjxI5V9iyRj0HgzB5/cLf2NY4vcYBTYzJ7GIui7j/4DOw==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2", + "path-scurry": "^1.10.0" + }, + "bin": { + "glob": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/html-validate/node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/html-validate/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/html-validate/node_modules/minimatch": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.2.tgz", + "integrity": "sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/html-validate/node_modules/semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", + "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "entities": "^4.3.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", + "dev": true + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/imagemin-cli": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/imagemin-cli/-/imagemin-cli-7.0.0.tgz", + "integrity": "sha512-YXO6t3l68ZfjvnDebAjFIWUDL14p9nrH4Mf81EYviLtKuS6ngMwuylHj4gOEIazRpsZ1Agkyx5W+zGNm59dBKA==", + "dev": true, + "dependencies": { + "arrify": "^3.0.0", + "get-stdin": "^9.0.0", + "imagemin": "^8.0.0", + "lodash.pairs": "^3.0.1", + "meow": "^10.1.1", + "ora": "^5.4.1", + "plur": "^4.0.0", + "strip-indent": "^4.0.0" + }, + "bin": { + "imagemin": "cli.js" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/imagemin/imagemin-cli?sponsor=1" + }, + "optionalDependencies": { + "imagemin-gifsicle": "^7.0.0", + "imagemin-jpegtran": "^7.0.0", + "imagemin-optipng": "^8.0.0", + "imagemin-svgo": "^9.0.0" + } + }, + "node_modules/imagemin-cli/node_modules/array-union": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz", + "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-cli/node_modules/file-type": { + "version": "16.5.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", + "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", + "dev": true, + "dependencies": { + "readable-web-to-node-stream": "^3.0.0", + "strtok3": "^6.2.4", + "token-types": "^4.1.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/imagemin-cli/node_modules/get-stdin": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", + "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-cli/node_modules/globby": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-12.2.0.tgz", + "integrity": "sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA==", + "dev": true, + "dependencies": { + "array-union": "^3.0.1", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.7", + "ignore": "^5.1.9", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-cli/node_modules/globby/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-cli/node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/imagemin-cli/node_modules/imagemin": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-8.0.1.tgz", + "integrity": "sha512-Q/QaPi+5HuwbZNtQRqUVk6hKacI6z9iWiCSQBisAv7uBynZwO7t1svkryKl7+iSQbkU/6t9DWnHz04cFs2WY7w==", + "dev": true, + "dependencies": { + "file-type": "^16.5.3", + "globby": "^12.0.0", + "graceful-fs": "^4.2.8", + "junk": "^3.1.0", + "p-pipe": "^4.0.0", + "replace-ext": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/imagemin-cli/node_modules/imagemin-optipng": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/imagemin-optipng/-/imagemin-optipng-8.0.0.tgz", + "integrity": "sha512-CUGfhfwqlPjAC0rm8Fy+R2DJDBGjzy2SkfyT09L8rasnF9jSoHFqJ1xxSZWK6HVPZBMhGPMxCTL70OgTHlLF5A==", + "dev": true, + "optional": true, + "dependencies": { + "exec-buffer": "^3.0.0", + "is-png": "^2.0.0", + "optipng-bin": "^7.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/imagemin-cli/node_modules/imagemin-svgo": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/imagemin-svgo/-/imagemin-svgo-9.0.0.tgz", + "integrity": "sha512-uNgXpKHd99C0WODkrJ8OO/3zW3qjgS4pW7hcuII0RcHN3tnKxDjJWcitdVC/TZyfIqSricU8WfrHn26bdSW62g==", + "dev": true, + "optional": true, + "dependencies": { + "is-svg": "^4.2.1", + "svgo": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/imagemin-svgo?sponsor=1" + } + }, + "node_modules/imagemin-cli/node_modules/irregular-plurals": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz", + "integrity": "sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/imagemin-cli/node_modules/optipng-bin": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/optipng-bin/-/optipng-bin-7.0.1.tgz", + "integrity": "sha512-W99mpdW7Nt2PpFiaO+74pkht7KEqkXkeRomdWXfEz3SALZ6hns81y/pm1dsGZ6ItUIfchiNIP6ORDr1zETU1jA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "bin-build": "^3.0.0", + "bin-wrapper": "^4.0.0" + }, + "bin": { + "optipng": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/imagemin-cli/node_modules/p-pipe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-4.0.0.tgz", + "integrity": "sha512-HkPfFklpZQPUKBFXzKFB6ihLriIHxnmuQdK9WmLDwe4hf2PdhhfWT/FJa+pc3bA1ywvKXtedxIRmd4Y7BTXE4w==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-cli/node_modules/plur": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz", + "integrity": "sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==", + "dev": true, + "dependencies": { + "irregular-plurals": "^3.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-cli/node_modules/replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/imagemin-gifsicle": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/imagemin-gifsicle/-/imagemin-gifsicle-7.0.0.tgz", + "integrity": "sha512-LaP38xhxAwS3W8PFh4y5iQ6feoTSF+dTAXFRUEYQWYst6Xd+9L/iPk34QGgK/VO/objmIlmq9TStGfVY2IcHIA==", + "dev": true, + "optional": true, + "dependencies": { + "execa": "^1.0.0", + "gifsicle": "^5.0.0", + "is-gif": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/imagemin/imagemin-gifsicle?sponsor=1" + } + }, + "node_modules/imagemin-jpegtran": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/imagemin-jpegtran/-/imagemin-jpegtran-7.0.0.tgz", + "integrity": "sha512-MJoyTCW8YjMJf56NorFE41SR/WkaGA3IYk4JgvMlRwguJEEd3PnP9UxA8Y2UWjquz8d+On3Ds/03ZfiiLS8xTQ==", + "dev": true, + "optional": true, + "dependencies": { + "exec-buffer": "^3.0.0", + "is-jpg": "^2.0.0", + "jpegtran-bin": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/imagemin-mozjpeg": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/imagemin-mozjpeg/-/imagemin-mozjpeg-10.0.0.tgz", + "integrity": "sha512-DK85QNOjS3/GzWYfNB3CACMZD10sIQgFDv1+WTOnZljgltQTEyATjdyUVyjKu5q4sCESQdwvwq7WEZzJ5fFjlg==", + "dev": true, + "dependencies": { + "execa": "^6.0.0", + "is-jpg": "^3.0.0", + "mozjpeg": "^8.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/execa": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-6.1.0.tgz", + "integrity": "sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^3.0.1", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/human-signals": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz", + "integrity": "sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==", + "dev": true, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/is-jpg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-jpg/-/is-jpg-3.0.0.tgz", + "integrity": "sha512-Vcd67KWHZblEKEBrtP25qLZ8wN9ICoAhl1pKUqD7SM7hf2qtuRl7loDgP5Zigh2oN/+7uj+KVyC0eRJvgOEFeQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-mozjpeg/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/imagemin-pngcrush": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/imagemin-pngcrush/-/imagemin-pngcrush-7.0.0.tgz", + "integrity": "sha512-yOp5f8RH2vd2x6B7P8WCprX1Cm3LjXqBu30wy5fJoEBrwwkyx8H2+vz1g/3FkSkldNURHcc0NmJ6r0waUNQTrw==", + "dev": true, + "dependencies": { + "exec-buffer": "^3.0.0", + "is-png": "^2.0.0", + "pngcrush-bin": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/imagemin-pngquant": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/imagemin-pngquant/-/imagemin-pngquant-9.0.2.tgz", + "integrity": "sha512-cj//bKo8+Frd/DM8l6Pg9pws1pnDUjgb7ae++sUX1kUVdv2nrngPykhiUOgFeE0LGY/LmUbCf4egCHC4YUcZSg==", + "dev": true, + "dependencies": { + "execa": "^4.0.0", + "is-png": "^2.0.0", + "is-stream": "^2.0.0", + "ow": "^0.17.0", + "pngquant-bin": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/imagemin-pngquant/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/imagemin-pngquant/node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/imagemin-pngquant/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-pngquant/node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/imagemin-pngquant/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-pngquant/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/imagemin-pngquant/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imagemin-pngquant/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imagemin-pngquant/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/imagemin-pngquant/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imagemin-pngquant/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/imagemin-pngquant/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/imagemin-zopfli": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/imagemin-zopfli/-/imagemin-zopfli-7.0.0.tgz", + "integrity": "sha512-nmffj58rVb0O3AlCZLBBVKGyZ5MYPZZfKxUhvA7bwPGougHl/F7EUKSse9jkgXjdvtJYG2ojJeh5N67mYgBM9g==", + "dev": true, + "dependencies": { + "exec-buffer": "^3.0.0", + "is-png": "^2.0.0", + "zopflipng-bin": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", + "integrity": "sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/into-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", + "integrity": "sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ==", + "dev": true, + "dependencies": { + "from2": "^2.1.1", + "p-is-promise": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/is": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz", + "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "dev": true, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-gif": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-gif/-/is-gif-3.0.0.tgz", + "integrity": "sha512-IqJ/jlbw5WJSNfwQ/lHEDXF8rxhRgF6ythk2oiEvhpG29F704eX9NO6TvPfMiq9DrbwgcEDnETYNcZDPewQoVw==", + "dev": true, + "optional": true, + "dependencies": { + "file-type": "^10.4.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-gif/node_modules/file-type": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-10.11.0.tgz", + "integrity": "sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-jpg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-jpg/-/is-jpg-2.0.0.tgz", + "integrity": "sha512-ODlO0ruzhkzD3sdynIainVP5eoOFNN85rxA1+cwwnPe4dKyX0r5+hxNO5XpCrxlHcmb9vkOit9mhRD2JVuimHg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-natural-number": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", + "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==", + "dev": true + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-png": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-png/-/is-png-2.0.0.tgz", + "integrity": "sha512-4KPGizaVGj2LK7xwJIz8o5B2ubu1D/vcQsgOGFEDlpcvgZHto4gBnyd0ig7Ws+67ixmwKoNmu0hYnpo6AaKb5g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-svg": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-4.4.0.tgz", + "integrity": "sha512-v+AgVwiK5DsGtT9ng+m4mClp6zDAmwrW8nZi6Gg15qzvBnRWWdfWA1TGaXyCDnWq5g5asofIgMVl3PjKxvk1ug==", + "dev": true, + "optional": true, + "dependencies": { + "fast-xml-parser": "^4.1.3" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", + "dev": true + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "dev": true, + "dependencies": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/jackspeak": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz", + "integrity": "sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jpegtran-bin": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/jpegtran-bin/-/jpegtran-bin-5.0.2.tgz", + "integrity": "sha512-4FSmgIcr8d5+V6T1+dHbPZjaFH0ogVyP4UVsE+zri7S9YLO4qAT2our4IN3sW3STVgNTbqPermdIgt2XuAJ4EA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "bin-build": "^3.0.0", + "bin-wrapper": "^4.0.0", + "logalot": "^2.0.0" + }, + "bin": { + "jpegtran": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "peer": true + }, + "node_modules/junk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", + "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/keyv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", + "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/known-css-properties": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.27.0.tgz", + "integrity": "sha512-uMCj6+hZYDoffuvAJjFAPz56E9uoowFHmTkqRtRq5WyC5Q6Cu/fTZKNQpX/RbzChBYLLl3lo8CjFZBAZXq9qFg==", + "dev": true + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "dev": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA==", + "dev": true + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", + "dev": true + }, + "node_modules/lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha512-JwObCrNJuT0Nnbuecmqr5DgtuBppuCvGD9lxjFpAzwnVtdGoDQ1zig+5W8k5/6Gcn0gZ3936HDAlGd28i7sOGQ==", + "dev": true + }, + "node_modules/lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha512-CuBsapFjcubOGMn3VD+24HOAPxM79tH+V6ivJL3CHYjtrawauDJHUk//Yew9Hvc6e9rbCrURGk8z6PC+8WJBfQ==", + "dev": true, + "dependencies": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lodash.pairs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.pairs/-/lodash.pairs-3.0.1.tgz", + "integrity": "sha512-lgXvpU43ZNQrZ/pK2cR97YzKeAno3e3HhcyvLKsofljeHKrQcZhT1vW7fg4X61c92tM+mjD/DypoLZYuAKNIkQ==", + "dev": true, + "dependencies": { + "lodash.keys": "^3.0.0" + } + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/logalot": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/logalot/-/logalot-2.1.0.tgz", + "integrity": "sha512-Ah4CgdSRfeCJagxQhcVNMi9BfGYyEKLa6d7OA6xSbld/Hg3Cf2QiOa1mDpmG7Ve8LOH6DN3mdttzjQAvWTyVkw==", + "dev": true, + "dependencies": { + "figures": "^1.3.5", + "squeak": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/logalot/node_modules/figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha512-k+yt5n3l48JU4k8ftnKG6V7u32wyH2NfKzeMto9F/QRE0amxy/LayxwlvjjkZEIzqR+19IrtFO8p5kB9QaYUFg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==", + "dev": true, + "dependencies": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lpad-align": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/lpad-align/-/lpad-align-1.1.2.tgz", + "integrity": "sha512-MMIcFmmR9zlGZtBcFOows6c2COMekHCIFJz3ew/rRpKZ1wR4mXDPzvcVqLarux8M33X4TPSq2Jdw8WJj0q0KbQ==", + "dev": true, + "dependencies": { + "get-stdin": "^4.0.1", + "indent-string": "^2.1.0", + "longest": "^1.0.0", + "meow": "^3.3.0" + }, + "bin": { + "lpad-align": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lpad-align/node_modules/camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lpad-align/node_modules/camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ==", + "dev": true, + "dependencies": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lpad-align/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", + "dev": true, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lpad-align/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/lpad-align/node_modules/indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg==", + "dev": true, + "dependencies": { + "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lpad-align/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lpad-align/node_modules/meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA==", + "dev": true, + "dependencies": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lpad-align/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/lpad-align/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", + "dev": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lpad-align/node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lpad-align/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lpad-align/node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", + "dev": true, + "dependencies": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lpad-align/node_modules/read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", + "dev": true, + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lpad-align/node_modules/redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g==", + "dev": true, + "dependencies": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lpad-align/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/lpad-align/node_modules/strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA==", + "dev": true, + "dependencies": { + "get-stdin": "^4.0.1" + }, + "bin": { + "strip-indent": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lpad-align/node_modules/trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/make-dir/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/meow": { + "version": "10.1.5", + "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.5.tgz", + "integrity": "sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.2", + "camelcase-keys": "^7.0.0", + "decamelize": "^5.0.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.2", + "read-pkg-up": "^8.0.0", + "redent": "^4.0.0", + "trim-newlines": "^4.0.2", + "type-fest": "^1.2.2", + "yargs-parser": "^20.2.9" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/decamelize": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz", + "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minimist-options/node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/minimist-options/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/minipass": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz", + "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "node_modules/mozjpeg": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/mozjpeg/-/mozjpeg-8.0.0.tgz", + "integrity": "sha512-Ca2Yhah9hG0Iutgsn8MOrAl37P9ThnKsJatjXoWdUO+8X8GeG/6ahvHZrTyqvbs6leMww1SauWUCao/L9qBuFQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "bin-build": "^3.0.0", + "bin-wrapper": "^4.0.0" + }, + "bin": { + "mozjpeg": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-releases": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", + "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==", + "dev": true + }, + "node_modules/node.extend": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-2.0.2.tgz", + "integrity": "sha512-pDT4Dchl94/+kkgdwyS2PauDFjZG0Hk0IcHIB+LkW27HLDtdoeMxHTxZh39DYbPP8UflWXWj9JcdDozF+YDOpQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3", + "is": "^3.2.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/nodemon": { + "version": "2.0.22", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", + "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/nodemon/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", + "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", + "dev": true, + "dependencies": { + "prepend-http": "^2.0.0", + "query-string": "^5.0.1", + "sort-keys": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/normalize-url/node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/normalize-url/node_modules/sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==", + "dev": true, + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/normalize.css": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz", + "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==" + }, + "node_modules/npm-conf": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", + "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", + "dev": true, + "dependencies": { + "config-chain": "^1.1.11", + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-conf/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nunjucks": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", + "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==", + "dev": true, + "dependencies": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + }, + "bin": { + "nunjucks-precompile": "bin/precompile" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "chokidar": "^3.3.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/nunjucks-cli": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nunjucks-cli/-/nunjucks-cli-1.0.0.tgz", + "integrity": "sha512-Yo6Ti/2Ja7XQiAXWwgjNnvNV8yn6xjr7ySAou+n23L9h6aKcIPyOmQZTl/PL6kK8irtwXDvG8PLEhsYCDhK8YQ==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "chokidar": "^3.0.1", + "glob": "^7.0.3", + "mkdirp": "^0.5.1", + "nunjucks": "^3.2.0", + "yargs": "^13.2.4" + }, + "bin": { + "nunjucks": "main.js" + }, + "engines": { + "node": ">=6.4.0" + } + }, + "node_modules/nunjucks-cli/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/nunjucks-cli/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/nunjucks-cli/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/nunjucks-cli/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/nunjucks-cli/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nunjucks-cli/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nunjucks-cli/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nunjucks-cli/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/nunjucks-cli/node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/nunjucks-cli/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nunjucks-cli/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nunjucks-cli/node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true + }, + "node_modules/nunjucks-cli/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nunjucks-cli/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/nunjucks-cli/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/nunjucks-cli/node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ora/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ora/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/ora/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ora/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/os-filter-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-2.0.0.tgz", + "integrity": "sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg==", + "dev": true, + "dependencies": { + "arch": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ow": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/ow/-/ow-0.17.0.tgz", + "integrity": "sha512-i3keDzDQP5lWIe4oODyDFey1qVrq2hXKTuTH2VpqwpYtzPiKZt2ziRI4NBQmgW40AnV5Euz17OyWweCb+bNEQA==", + "dev": true, + "dependencies": { + "type-fest": "^0.11.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ow/node_modules/type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-cancelable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", + "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-event": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-1.3.0.tgz", + "integrity": "sha512-hV1zbA7gwqPVFcapfeATaNjQ3J0NuzorHPyG8GPL9g/Y/TplWVBVoCKCXL6Ej2zscrCEv195QNWJXuBH6XZuzA==", + "dev": true, + "dependencies": { + "p-timeout": "^1.1.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-is-promise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "integrity": "sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-map-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-map-series/-/p-map-series-1.0.0.tgz", + "integrity": "sha512-4k9LlvY6Bo/1FcIdV33wqZQES0Py+iKISU9Uc8p8AjWoZPnFKMpVIVD3s0EYn4jzLh1I+WeUZkJ0Yoa4Qfw3Kg==", + "dev": true, + "dependencies": { + "p-reduce": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-reduce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", + "integrity": "sha512-3Tx1T3oM1xO/Y8Gj0sWyE78EIJZ+t+aEmXUdvQgvGmSMri7aPTHoovbXEreWKkL5j21Er60XAWLTzKbAKYOujQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-timeout": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", + "integrity": "sha512-gb0ryzr+K2qFqFv6qi3khoeqMZF/+ajxQipEF6NteZVnvz9tzdsfAVj3lYtn1gAXvH5lfLwfxEII799gt/mRIA==", + "dev": true, + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pa11y": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/pa11y/-/pa11y-6.1.1.tgz", + "integrity": "sha512-2NzqA3D9CUlDWj8WuOI4fM2P0qM1d/IUxsRRpzCOfDT5eMR1oEgmUwW2TAk+f90ff/GVck0BewdYT4et4BANew==", + "dev": true, + "dependencies": { + "axe-core": "^4.0.2", + "bfj": "~7.0.2", + "commander": "~8.0.0", + "envinfo": "~7.8.1", + "hogan.js": "^3.0.2", + "html_codesniffer": "^2.5.1", + "kleur": "~4.1.4", + "node.extend": "~2.0.2", + "p-timeout": "~4.1.0", + "puppeteer": "~9.1.1", + "semver": "~7.3.5" + }, + "bin": { + "pa11y": "bin/pa11y.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/pa11y-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pa11y-ci/-/pa11y-ci-3.0.1.tgz", + "integrity": "sha512-DUtEIhEG3Ofds7qRuplq0DdCb9doILRlzcRctFNzo4QUNmVy4iZfM3u51A9cqoPo2irCJZoo5BzfiFrcriY2IQ==", + "dev": true, + "dependencies": { + "async": "~2.6.3", + "cheerio": "~1.0.0-rc.10", + "commander": "~6.2.1", + "globby": "~6.1.0", + "kleur": "~4.1.4", + "lodash": "~4.17.21", + "node-fetch": "~2.6.1", + "pa11y": "~6.1.0", + "protocolify": "~3.0.0", + "puppeteer": "~9.1.1", + "wordwrap": "~1.0.0" + }, + "bin": { + "pa11y-ci": "bin/pa11y-ci.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/pa11y-ci-reporter-html": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/pa11y-ci-reporter-html/-/pa11y-ci-reporter-html-5.1.1.tgz", + "integrity": "sha512-FjkglWQ2zMUu2WznpeHTx0/ivLugJ4cLGgfIy8jhBb1hKq8TU8ewtJnIrqmShQradpkXN/NfWqmRBQ2kOO3Ouw==", + "dev": true, + "dependencies": { + "ci-logger": "^5.1.1", + "handlebars": "^4.7.7", + "pa11y-reporter-html-plus": "^1.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.13.0 || >=18.0.0" + }, + "peerDependencies": { + "pa11y-ci": "^3.0.1" + } + }, + "node_modules/pa11y-ci/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pa11y-reporter-html-plus": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pa11y-reporter-html-plus/-/pa11y-reporter-html-plus-1.1.1.tgz", + "integrity": "sha512-PCxKpVHU9noZ/lJZDsD48jRijHSlVsJxpS+yCxZkvjmEl9dS1IgYLV2pQ1vrouV44yKrH5f3N3MyzPj6V9e+cA==", + "dev": true, + "dependencies": { + "handlebars": "^4.7.7" + }, + "engines": { + "node": "^14.15.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/pa11y/node_modules/commander": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.0.0.tgz", + "integrity": "sha512-Xvf85aAtu6v22+E5hfVoLHqyul/jyxh91zvqk/ioJTQuJR7Z78n7H558vMPKanPSRgIEeZemT92I2g9Y8LPbSQ==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/pa11y/node_modules/p-timeout": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-4.1.0.tgz", + "integrity": "sha512-+/wmHtzJuWii1sXn3HCuH/FTwGhrp4tmJTxSKJbfS+vkipci6osxXM5mY0jUiRzWKMTgUT8l7HFbeSwZAynqHw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/pa11y/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.1.tgz", + "integrity": "sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==", + "dev": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "dev": true, + "dependencies": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.0.tgz", + "integrity": "sha512-tZFEaRQbMLjwrsmidsGJ6wDMv0iazJWk6SfIKnY4Xru8auXgmJkOBa5DUbYFcFD2Rzk2+KDlIiF0GVXNCbgC7g==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.0.tgz", + "integrity": "sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/peek-readable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", + "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pngcrush-bin": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/pngcrush-bin/-/pngcrush-bin-5.0.2.tgz", + "integrity": "sha512-Tuafr/1cm7umMCkuwoXz2l311eUakE/kzv3u+zj9a6EeNGCZfK4ph3VeDdCv/WQ00u8UgO3bGbO3aJYhEAFXyg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "bin-build": "^3.0.0", + "bin-wrapper": "^4.0.0" + }, + "bin": { + "pngcrush": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pngquant-bin": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/pngquant-bin/-/pngquant-bin-6.0.1.tgz", + "integrity": "sha512-Q3PUyolfktf+hYio6wsg3SanQzEU/v8aICg/WpzxXcuCMRb7H2Q81okfpcEztbMvw25ILjd3a87doj2N9kvbpQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "bin-build": "^3.0.0", + "bin-wrapper": "^4.0.1", + "execa": "^4.0.0" + }, + "bin": { + "pngquant": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pngquant-bin/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/pngquant-bin/node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/pngquant-bin/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pngquant-bin/node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/pngquant-bin/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pngquant-bin/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pngquant-bin/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pngquant-bin/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pngquant-bin/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pngquant-bin/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pngquant-bin/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pngquant-bin/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/postcss": { + "version": "8.4.24", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", + "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-calc": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-cli": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-10.1.0.tgz", + "integrity": "sha512-Zu7PLORkE9YwNdvOeOVKPmWghprOtjFQU3srMUGbdz3pHJiFh7yZ4geiZFMkjMfB0mtTFR3h8RemR62rPkbOPA==", + "dev": true, + "dependencies": { + "chokidar": "^3.3.0", + "dependency-graph": "^0.11.0", + "fs-extra": "^11.0.0", + "get-stdin": "^9.0.0", + "globby": "^13.0.0", + "picocolors": "^1.0.0", + "postcss-load-config": "^4.0.0", + "postcss-reporter": "^7.0.0", + "pretty-hrtime": "^1.0.3", + "read-cache": "^1.0.0", + "slash": "^5.0.0", + "yargs": "^17.0.0" + }, + "bin": { + "postcss": "index.js" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-cli/node_modules/fs-extra": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", + "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/postcss-cli/node_modules/get-stdin": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", + "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/postcss-cli/node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "dev": true, + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/postcss-cli/node_modules/globby/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/postcss-cli/node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/postcss-cli/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/postcss-cli/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/postcss-cli/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/postcss-colormin": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", + "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-convert-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", + "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-comments": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-empty": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", + "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", + "dev": true, + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^2.1.1" + }, + "engines": { + "node": ">= 14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", + "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true + }, + "node_modules/postcss-merge-longhand": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", + "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-merge-rules": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", + "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", + "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", + "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "dev": true, + "dependencies": { + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-params": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", + "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", + "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", + "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", + "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", + "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-string": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", + "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", + "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", + "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", + "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "dev": true, + "dependencies": { + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-url/node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", + "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-ordered-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", + "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", + "dev": true, + "dependencies": { + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", + "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", + "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reporter": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-7.0.5.tgz", + "integrity": "sha512-glWg7VZBilooZGOFPhN9msJ3FQs19Hie7l5a/eE6WglzYqVeH3ong3ShFcp9kDWJT1g2Y/wd59cocf9XxBtkWA==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "thenby": "^1.3.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", + "dev": true + }, + "node_modules/postcss-safe-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "dev": true, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "node_modules/postcss-scss": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.6.tgz", + "integrity": "sha512-rLDPhJY4z/i4nVFZ27j9GqLxj1pwxE80eAzUNRMXtcpipFYIeowerzBgG3yJhMtObGEXidtIgbUpQ3eLDsf5OQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-scss" + } + ], + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.4.19" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", + "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", + "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true + }, + "node_modules/protocolify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/protocolify/-/protocolify-3.0.0.tgz", + "integrity": "sha512-PuvDJOkKJMVQx8jSNf8E5g0bJw/UTKm30mTjFHg4N30c8sefgA5Qr/f8INKqYBKfvP/MUSJrj+z1Smjbq4/3rQ==", + "dev": true, + "dependencies": { + "file-url": "^3.0.0", + "prepend-http": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/protocolify/node_modules/prepend-http": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-3.0.1.tgz", + "integrity": "sha512-BLxfZh+m6UiAiCPZFJ4+vYoL7NrRs5XgCTRrjseATAggXhdZKKxn+JUNmuVYWY23bDHgaEHodxw8mnmtVEDtHw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "dev": true + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/puppeteer": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-9.1.1.tgz", + "integrity": "sha512-W+nOulP2tYd/ZG99WuZC/I5ljjQQ7EUw/jQGcIb9eu8mDlZxNY2SgcJXTLG9h5gRvqA3uJOe4hZXYsd3EqioMw==", + "deprecated": "< 19.4.0 is no longer supported", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "debug": "^4.1.0", + "devtools-protocol": "0.0.869402", + "extract-zip": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.1", + "pkg-dir": "^4.2.0", + "progress": "^2.0.1", + "proxy-from-env": "^1.1.0", + "rimraf": "^3.0.2", + "tar-fs": "^2.0.0", + "unbzip2-stream": "^1.3.3", + "ws": "^7.2.3" + }, + "engines": { + "node": ">=10.18.1" + } + }, + "node_modules/puppeteer/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/puppeteer/node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/purgecss": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/purgecss/-/purgecss-4.1.3.tgz", + "integrity": "sha512-99cKy4s+VZoXnPxaoM23e5ABcP851nC2y2GROkkjS8eJaJtlciGavd7iYAw2V84WeBqggZ12l8ef44G99HmTaw==", + "dev": true, + "dependencies": { + "commander": "^8.0.0", + "glob": "^7.1.7", + "postcss": "^8.3.5", + "postcss-selector-parser": "^6.0.6" + }, + "bin": { + "purgecss": "bin/purgecss.js" + } + }, + "node_modules/purgecss/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dev": true, + "dependencies": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/read-cache/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-6.0.0.tgz", + "integrity": "sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^3.0.2", + "parse-json": "^5.2.0", + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-8.0.0.tgz", + "integrity": "sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==", + "dev": true, + "dependencies": { + "find-up": "^5.0.0", + "read-pkg": "^6.0.0", + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/readable-web-to-node-stream": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", + "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", + "dev": true, + "dependencies": { + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/readable-web-to-node-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/redent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-4.0.0.tgz", + "integrity": "sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==", + "dev": true, + "dependencies": { + "indent-string": "^5.0.0", + "strip-indent": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "dev": true + }, + "node_modules/repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==", + "dev": true, + "dependencies": { + "is-finite": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "dev": true, + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/rxjs/node_modules/tslib": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", + "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==", + "dev": true + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/sass": { + "version": "1.56.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.56.1.tgz", + "integrity": "sha512-VpEyKpyBPCxE7qGDtOcdJ6fFbcpOM+Emu7uZLxVrkX8KVU/Dp5UF7WLvzqRuUhB6mqqQt1xffLoG+AndxTZrCQ==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/sass/node_modules/immutable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==", + "dev": true + }, + "node_modules/seek-bzip": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", + "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", + "dev": true, + "dependencies": { + "commander": "^2.8.1" + }, + "bin": { + "seek-bunzip": "bin/seek-bunzip", + "seek-table": "bin/seek-bzip-table" + } + }, + "node_modules/seek-bzip/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/semver-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", + "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/semver-truncate": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-1.1.2.tgz", + "integrity": "sha512-V1fGg9i4CL3qesB6U0L6XAm4xOJiHmt4QAacazumuasc03BvtFGIMCduv01JWQ69Nv+JST9TqhSCiJoxoY031w==", + "dev": true, + "dependencies": { + "semver": "^5.3.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/semver-truncate/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/servor": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/servor/-/servor-4.0.2.tgz", + "integrity": "sha512-MlmQ5Ntv4jDYUN060x/KEmN7emvIqKMZ9OkM+nY8Bf2+KkyLmGsTqWLyAN2cZr5oESAcH00UanUyyrlS1LRjFw==", + "dev": true, + "bin": { + "servor": "cli.js" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dev": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shx": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz", + "integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==", + "dev": true, + "dependencies": { + "minimist": "^1.2.3", + "shelljs": "^0.8.5" + }, + "bin": { + "shx": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "dev": true, + "dependencies": { + "semver": "~7.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", + "dev": true, + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-keys-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==", + "dev": true, + "dependencies": { + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==", + "dev": true + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", + "dev": true + }, + "node_modules/squeak": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/squeak/-/squeak-1.3.0.tgz", + "integrity": "sha512-YQL1ulInM+ev8nXX7vfXsCsDh6IqXlrremc1hzi77776BtpWgYJUMto3UM05GSAaGzJgWekszjoKDrVNB5XG+A==", + "dev": true, + "dependencies": { + "chalk": "^1.0.0", + "console-stream": "^0.1.1", + "lpad-align": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/squeak/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/squeak/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/squeak/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/squeak/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/squeak/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/sseeeedd": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/sseeeedd/-/sseeeedd-0.2.1.tgz", + "integrity": "sha512-aiAyE7/8lglWSR36T6au3hEGUWLQqAwPaiqIx1biVY/Ny1cXPdR8GH/rIKMEzxwJczaD5OVZdP6cOSwsvAO54A==", + "dependencies": { + "a11y-dialog": "^5.2.0", + "normalize.css": "^8.0.1", + "van11y-accessible-tab-panel-aria": "^2.0.4" + } + }, + "node_modules/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", + "dev": true + }, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "dev": true, + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", + "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", + "dev": true, + "dependencies": { + "is-natural-number": "^4.0.1" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", + "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "dev": true, + "optional": true + }, + "node_modules/strtok3": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", + "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "dev": true, + "dependencies": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^4.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==", + "dev": true + }, + "node_modules/stylehacks": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", + "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/stylelint": { + "version": "15.10.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.10.1.tgz", + "integrity": "sha512-CYkzYrCFfA/gnOR+u9kJ1PpzwG10WLVnoxHDuBA/JiwGqdM9+yx9+ou6SE/y9YHtfv1mcLo06fdadHTOx4gBZQ==", + "dev": true, + "dependencies": { + "@csstools/css-parser-algorithms": "^2.3.0", + "@csstools/css-tokenizer": "^2.1.1", + "@csstools/media-query-list-parser": "^2.1.2", + "@csstools/selector-specificity": "^3.0.0", + "balanced-match": "^2.0.0", + "colord": "^2.9.3", + "cosmiconfig": "^8.2.0", + "css-functions-list": "^3.1.0", + "css-tree": "^2.3.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.0", + "fastest-levenshtein": "^1.0.16", + "file-entry-cache": "^6.0.1", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.3.1", + "ignore": "^5.2.4", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.27.0", + "mathml-tag-names": "^2.1.3", + "meow": "^10.1.5", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.24", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^6.0.0", + "postcss-selector-parser": "^6.0.13", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "style-search": "^0.1.0", + "supports-hyperlinks": "^3.0.0", + "svg-tags": "^1.0.0", + "table": "^6.8.1", + "write-file-atomic": "^5.0.1" + }, + "bin": { + "stylelint": "bin/stylelint.mjs" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + } + }, + "node_modules/stylelint-config-recommended": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-12.0.0.tgz", + "integrity": "sha512-x6x8QNARrGO2sG6iURkzqL+Dp+4bJorPMMRNPScdvaUK8PsynriOcMW7AFDKqkWAS5wbue/u8fUT/4ynzcmqdQ==", + "dev": true, + "peerDependencies": { + "stylelint": "^15.5.0" + } + }, + "node_modules/stylelint-config-recommended-scss": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-12.0.0.tgz", + "integrity": "sha512-5Bb2mlGy6WLa30oNeKpZvavv2lowJUsUJO25+OA68GFTemlwd1zbFsL7q0bReKipOSU3sG47hKneZ6Nd+ctrFA==", + "dev": true, + "dependencies": { + "postcss-scss": "^4.0.6", + "stylelint-config-recommended": "^12.0.0", + "stylelint-scss": "^5.0.0" + }, + "peerDependencies": { + "postcss": "^8.3.3", + "stylelint": "^15.5.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + } + } + }, + "node_modules/stylelint-scss": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-5.0.1.tgz", + "integrity": "sha512-n87iCRZrr2J7//I/QFsDXxFLnHKw633U4qvWZ+mOW6KDAp/HLj06H+6+f9zOuTYy+MdGdTuCSDROCpQIhw5fvQ==", + "dev": true, + "dependencies": { + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-selector-parser": "^6.0.13", + "postcss-value-parser": "^4.2.0" + }, + "peerDependencies": { + "stylelint": "^14.5.1 || ^15.0.0" + } + }, + "node_modules/stylelint/node_modules/ajv": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/stylelint/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/stylelint/node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true + }, + "node_modules/stylelint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/stylelint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/stylelint/node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/stylelint/node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/stylelint/node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/stylelint/node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/stylelint/node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint/node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint/node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/stylelint/node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/stylelint/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint/node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, + "node_modules/stylelint/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/stylelint/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/stylelint/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/table": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-hyperlinks": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", + "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/supports-hyperlinks/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true + }, + "node_modules/svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "dev": true, + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/svgo/node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/svgo/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/svgo/node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/svgo/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/svgo/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/svgo/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/svgo/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/svgo/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, + "node_modules/svgo/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/tar-fs/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tar-fs/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dev": true, + "dependencies": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/temp-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", + "integrity": "sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tempfile": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-2.0.0.tgz", + "integrity": "sha512-ZOn6nJUgvgC09+doCEF3oB+r3ag7kUvlsXEGX069QRD60p+P3uP7XG9N2/at+EyIRGSN//ZY3LyEotA1YpmjuA==", + "dev": true, + "dependencies": { + "temp-dir": "^1.0.0", + "uuid": "^3.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/terser": { + "version": "5.18.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.18.2.tgz", + "integrity": "sha512-Ah19JS86ypbJzTzvUCX7KOsEIhDaRONungA4aYBjEP3JZRf4ocuDzTg4QWZnPn9DEMiMYGJPiSOy7aykoCc70w==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/thenby": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/thenby/-/thenby-1.3.4.tgz", + "integrity": "sha512-89Gi5raiWA3QZ4b2ePcEwswC3me9JIg+ToSgtE0JWeCynLnLxNr/f9G+xfo9K+Oj4AFdom8YNJjibIARTJmapQ==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/token-types": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", + "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", + "dev": true, + "dependencies": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/trim-newlines": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.1.1.tgz", + "integrity": "sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "node_modules/update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==", + "dev": true, + "dependencies": { + "prepend-http": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/van11y-accessible-tab-panel-aria": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/van11y-accessible-tab-panel-aria/-/van11y-accessible-tab-panel-aria-2.0.4.tgz", + "integrity": "sha512-HOxAxa8062+LN6g9oOzTvgo59CE/K/kIMu1gCluvByiGAGW+jhiM2FFrsxkaXtiUrftiVL+tqjd1SeoT9HRZ6w==" + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/write-file-atomic/node_modules/signal-exit": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", + "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zopflipng-bin": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zopflipng-bin/-/zopflipng-bin-6.0.1.tgz", + "integrity": "sha512-+aybvXv/xafL6I67uSH5yLHrSy4/OaSOV9tniw4yZFIHpINXUcctVHE/WzHxOONrL2GHzJ8Fd4iDrNyaS6TVbg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "bin-build": "^3.0.0", + "bin-wrapper": "^4.0.1", + "logalot": "^2.1.0" + }, + "bin": { + "zopflipng": "cli.js" + }, + "engines": { + "node": ">=10" + } + } + } +} diff --git a/package.json b/package.json index f3f9679..22e4b5d 100644 --- a/package.json +++ b/package.json @@ -1,49 +1,94 @@ { - "name": "chaarts", - "version": "0.0.1", - "description": "Charts with HTML & CSS", - "repository": { - "type": "git", - "url": "git@github.com:ffoodd/chaarts.git" - }, - "author": "Gaël Poupard", - "license": "MIT", - "keywords": [ - "charts", - "accessibility", - "front-end", - "markup", - "HTML", - "CSS", - "progressive enhancement" - ], - "style": "chaarts.min.css", - "sass": "sass/chaarts.scss", - "main": "script.min.js", - "scripts": { - "pretest": "npm run gulp doc", - "test": "npm run gulp test", - "start": "npm run gulp" - }, - "stylelint": { - "extends": "stylelint-config-recommended-scss", - "plugins": [ - "stylelint-scss" - ], - "rules": { - "no-descending-specificity": null - } - }, - "ignore": [ - "node_modules" - ], - "devDependencies": { - "stylelint": "^14.14.1", - "stylelint-config-recommended-scss": "^3.3.0", - "stylelint-scss": "^3.19.0" - }, - "dependencies": { - "normalize.css": "^8.0.1", - "sseeeedd": "^0.2.1" - } + "name": "chaarts", + "version": "0.0.1", + "description": "Charts with HTML & CSS", + "repository": { + "type": "git", + "url": "git@github.com:ffoodd/chaarts.git" + }, + "author": "Gaël Poupard", + "license": "MIT", + "keywords": [ + "charts", + "accessibility", + "front-end", + "markup", + "HTML", + "CSS", + "progressive enhancement" + ], + "style": "chaarts.min.css", + "sass": "sass/chaarts.scss", + "ignore": [ + "node_modules" + ], + "scripts": { + "pretest": "npm run build && npm run build:docs", + "test": "concurrently \"npm:test:*\"", + "test:html": "html-validate \"docs/*.html\"", + "test:a11y": "pa11y-ci 'docs/*.html' -c .pa11yci.json", + "prestart": "npm run build && npm run build:docs", + "start": "concurrently --kill-others \"npm:watch\" \"npm:browser:start\"", + "browser:start": "servor docs --browse --reload --secure", + "build": "sass src/chaarts.scss:dist/chaarts.css --style expanded --source-map", + "postbuild": "postcss dist/chaarts.css -o dist/chaarts.min.css -u autoprefixer cssnano -m", + "prebuild:docs": "shx rm -rf docs/*", + "build:docs": "concurrently \"npm:build:docs:*\"", + "postbuild:docs": "shx cp -r _site/{favicon.ico,humans.txt} docs/ && shx cp -r dist/chaarts.min.{css,css.map} docs/css", + "build:docs:html": "nunjucks *.njk -p _site/templates -o docs", + "prebuild:docs:css": "sass _site/scss/styles.scss:docs/css/styles.min.css --load-path=./node_modules --style compressed --quiet", + "build:docs:css": "postcss docs/css/styles.min.css -r -u autoprefixer cssnano --no-map", + "postbuild:docs:css": "purgecss --config purgecss.config.js", + "build:docs:img": "imagemin _site/img/*.{png,jpg} --out-dir=docs/img --plugin=pngquant --plugin=mozjpeg --plugin=pngcrush --plugin=zopfli", + "prebuild:docs:js": "shx mkdir docs/js", + "build:docs:js": "terser _site/js/script.js -o docs/js/scripts.min.js -c -m --source-map && terser _site/js/prism.js -o docs/js/prism.min.js -c -m --source-map", + "watch": "concurrently --kill-others \"npm:watch:*\"", + "watch:html": "nodemon --watch _site/templates --ext njk --exec \"npm run build:docs:html\"", + "watch:css": "nodemon --watch _site/scss --ext scss --exec \"npm run build:docs:css\"", + "watch:src": "nodemon --watch src/ --ext scss --exec \"npm run build\"", + "watch:svg": "nodemon --watch _site/img --ext svg --exec \"npm run build:docs:svg\"", + "watch:js": "nodemon --watch _site/js --ext js --exec \"npm run build:docs:js\"", + "lint": "concurrently \"npm:lint:*\"", + "lint:scss": "stylelint src/**/*.scss", + "lint:docs:scss": "stylelint _site/scss/**/*.scss", + "lint:js": "" + }, + "devDependencies": { + "autoprefixer": "^10.4.7", + "concurrently": "^7.2.2", + "cssnano": "^5.1.12", + "html-validate": "^7.1.2", + "imagemin-cli": "^7.0.0", + "imagemin-mozjpeg": "^10.0.0", + "imagemin-pngcrush": "^7.0.0", + "imagemin-pngquant": "^9.0.2", + "imagemin-zopfli": "^7.0.0", + "nodemon": "^2.0.19", + "nunjucks-cli": "^1.0.0", + "pa11y-ci": "^3.0.1", + "pa11y-ci-reporter-html": "^5.0.0", + "postcss": "^8.4.14", + "postcss-cli": "^10.0.0", + "purgecss": "^4.1.3", + "sass": "^1.53.0", + "servor": "^4.0.2", + "shx": "^0.3.4", + "stylelint": "^15.10.1", + "stylelint-config-recommended-scss": "^12.0.0", + "stylelint-scss": "^5.0.1", + "terser": "^5.14.2" + }, + "dependencies": { + "normalize.css": "^8.0.1", + "sseeeedd": "^0.2.1" + }, + "stylelint": { + "extends": "stylelint-config-recommended-scss", + "plugins": [ + "stylelint-scss" + ], + "rules": { + "no-descending-specificity": null + } + } } diff --git a/purgecss.config.js b/purgecss.config.js new file mode 100644 index 0000000..eafe66d --- /dev/null +++ b/purgecss.config.js @@ -0,0 +1,14 @@ +module.exports = { + content: [ + 'docs/*.html', + 'docs/js/*.js' + ], + css: ['docs/css/styles.min.css'], + output: 'docs/css/styles.min.css', + safelist: { + standard: [/^no-|^grid-|^token|^line-|^ml-/] + }, + variables: true, + fontFace: true, + keyframes: true +} diff --git a/sass/_chaarts-bar.scss b/sass/_chaarts-bar.scss deleted file mode 100644 index ae029d9..0000000 --- a/sass/_chaarts-bar.scss +++ /dev/null @@ -1,132 +0,0 @@ -/* ==================== */ -/* == Bar Charts - * - * @note Grid charts based on: - * @see https://css-tricks.com/css-charts-grid-custom-properties/ - * @author Miriam Suzanne - * - * @note Grid setup: - * 1. 1st column to display legends, fixed width - * 1. 2nd column is a repeater, creating a subcolumn for each unit in --scale - * 1. 3rd columns with 6ch width to ensure that 6 characters long values has enough space to not overflow
    - * - * @note Clipped value coming from: - * @see https://www.ffoodd.fr/le-web-en-kit/ - * @see http://dabblet.com/gist/08fddf3666c39ebc62ca - * @author Gaël Poupard -/* ==================== */ - -@use "sass:math"; -@use "sass:list"; - -@supports (grid-template-columns: repeat(var(--scale, 100), minmax(0, 1fr))) { - .bar-container .fieldset { - display: flex !important; - } - - .chaarts.bar { - caption { - text-align: initial; - text-indent: #{rem( 200 ) + $gutter}; - } - - tr { - display: grid; - grid-auto-rows: 1fr; - grid-row-gap: $gutter * 0.5; - grid-template-columns: minmax(min-content, em( 200 )) repeat(var(--scale, 100), minmax(0, 1fr)) 10ch; - transition: opacity .2s map-get( $timing-functions, 'move' ); - - @each $name, $pattern in $patterns { - $i: index($patterns, ($name $pattern)); - - &:nth-child(#{$i}n + #{$i}) { - --background: var(--#{$name}); // 1 - } - } - } - - th { - grid-column: 1 / 1; - margin: $gutter * 0.5 0 0; - padding: 0 $gutter 0 0; - text-align: right; - } - - td { - --size: calc(var(--scale, 100) * 100%); - --position: calc(var(--value, 0) / var(--scale, 100) * 100%); - background: - linear-gradient(to right, - palette( success, dark ), - palette( dominant ), - palette( secondary ), - palette( accent ), - palette( alert ) - ) var(--position) list.slash(0%, var(--size)) 100%, - var(--background) center / contain; - background-blend-mode: hard-light; - grid-column: list.slash(2, var(--value, 0)); - margin: $gutter * 0.5 0 0; - position: relative; - } - - span { - font-weight: bold; - left: 100%; - line-height: 1.5; - position: absolute; - - /** - * @note Progressively enhance background-clipping - * @author S. Shaw - * @link https://twitter.com/shshaw/status/1140637533539377153 - * Support is quite good actually - * @link https://caniuse.com/background-clip-text - */ - @supports (background-clip: text) or (-webkit-background-clip: text) { - background: inherit; - -webkit-background-clip: text; - background-clip: text; - color: transparent; - } - } - - &:hover { - tr { - opacity: .5; - } - - tr:hover { - opacity: 1; - } - } - - @media screen and (-ms-high-contrast: active) { - td { - /** - * @note Custom color palette for WHCM - * @note Inspired by Greg Whitworth's post - * @link http://www.gwhitworth.com/blog/2017/04/how-to-use-ms-high-contrast - */ - background-image: - linear-gradient(to right, - Window, - ButtonFace, - ButtonShadow, - ButtonText, - highlight - ), - var(--background); - } - } - - &.waterfall { - @each $number in 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 { - tr:nth-of-type(#{$number}) td { - grid-column: list.slash(var(--#{$number - 1}, 2), var(--value, 2)); - } - } - } - } -} diff --git a/sass/_chaarts-column.scss b/sass/_chaarts-column.scss deleted file mode 100644 index e4c12af..0000000 --- a/sass/_chaarts-column.scss +++ /dev/null @@ -1,251 +0,0 @@ -/* ==================== */ -/* == Column Charts - * - * @note Grid charts based on: - * @see https://css-tricks.com/css-charts-grid-custom-properties/ - * @author Miriam Suzanne -/* ==================== */ - -@use "sass:math"; -@use "sass:list"; - -@supports (display: contents) { - .column-container .fieldset { - display: flex !important; - } - - .chaarts[class*="column"] { - --gap: #{$gutter * 0.5}; - --size: calc(var(--scale, 100) * 100%); - --width: calc(#{$width} / var(--y) - #{$gutter}); - display: grid; - grid-column-gap: var(--gap); - max-height: $width; - position: relative; - - td, - th { - margin: 0; - } - - tr > * + * { - text-align: center; - } - - /** - * @note Use display: contents to place table-cells in table's grid - * @link https://hiddedevries.nl/en/blog/2018-04-21-more-accessible-markup-with-display-contents - * @link https://bitsofco.de/how-display-contents-works/ - */ - tr, - tbody, - thead { - display: contents; - } - - caption { - grid-column: 1 / span var(--y); - grid-row: -1; - } - - td { - --integer: calc(var(--value)); - grid-row: list.slash(calc( (var(--scale, 100) + 2) - var(--integer) ), -2); - pointer-events: none; - position: relative; - transition: opacity .2s map-get( $timing-functions, 'move' ); - - @each $number in 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 { - &:nth-of-type(#{$number}) { - grid-column: #{$number + 1}; - } - } - } - - span { - font-weight: bold; - bottom: 100%; - left: 0; - line-height: 1.5; - pointer-events: auto; - position: absolute; - right: 0; - - /** - * @note Progressively enhance background-clipping - * @author S. Shaw - * @link https://twitter.com/shshaw/status/1140637533539377153 - * Support is quite good actually - * @link https://caniuse.com/background-clip-text - */ - @supports (background-clip: text) or (-webkit-background-clip: text) { - background: inherit; - -webkit-background-clip: text; - background-clip: text; - color: transparent; - } - } - - &.column-single { - grid-auto-columns: 1fr; - grid-template-rows: 2ex repeat(var(--scale, 100), minmax(0, .25rem)) minmax(min-content, 2rem); - - tbody th { - grid-row: -6 / -3; - grid-column: 1; - line-height: 1; - } - - thead * { - grid-row: -2; - } - - td { - --position: calc(var(--integer, 0) / var(--scale, 100) * 100%); - background: - linear-gradient(to top, - palette( success, dark ), - palette( dominant ), - palette( secondary ), - palette( accent ), - palette( alert ) - ) 0% list.slash(var(--position), 100%) var(--size), - var(--background) center / $gutter; - background-blend-mode: hard-light; - } - - [scope="col"] { - &::after { - background: palette( default, secondary ) var(--stripes); - background-blend-mode: exclusion; - bottom: #{$gutter * 4}; - content: ""; - mix-blend-mode: multiply; - opacity: 0; - position: absolute; - transition: opacity .3s map-get( $timing-functions, 'move' ); - top: $gutter; - width: var(--width); - z-index: 0; - } - - &:hover::after { - opacity: .5; - } - - @each $number in 1, 2, 3, 4, 5, 6 { - &:nth-child(#{$number + 1})::after { - left: calc(1em + (var(--width) * #{$number}) + (var(--gap) * #{$number})); - } - } - } - - @each $name, $pattern in $patterns { - $i: index($patterns, ($name $pattern)); - - td:nth-of-type(#{$i}n + #{$i}) { - --background: var(--#{$name}); - } - } - - @media screen and (-ms-high-contrast: active) { - td { - /** - * @note Custom color palette for WHCM - * @note Inspired by Greg Whitworth's post - * @link http://www.gwhitworth.com/blog/2017/04/how-to-use-ms-high-contrast - */ - background-image: - linear-gradient(to top, - Window, - ButtonFace, - ButtonShadow, - ButtonText, - highlight - ), - var(--background); - } - } - } - - &.column-multiple { - grid-template-columns: minmax(min-content, 14ch) repeat(calc(var(--y) - 1), 1fr); - grid-template-rows: 2ex repeat(var(--scale, 100), minmax(0, .25rem)) repeat(2, minmax(min-content, 2rem)); - - span { - background-image: none; - } - - tbody th { - grid-row: -10 / span 7; - } - - thead tr * { - grid-row: -2; - grid-column: 1; - - @each $number in 2, 3, 4, 5, 6 { - &:nth-of-type(#{$number}) { - grid-column: calc(#{($number * 2)} - var(--span)) / span var(--span); - } - } - } - - thead tr + tr * { - font-weight: normal; - grid-row: -3; - - @each $number in 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 { - &:nth-of-type(#{$number}) { - grid-column: #{$number}; - } - } - } - - tr:first-child [scope="col"] { - &:nth-child(even)::after { - background: palette( default, secondary ) var(--stripes); - background-blend-mode: exclusion; - bottom: #{$gutter * 4}; - content: ""; - mix-blend-mode: multiply; - opacity: .25; - position: absolute; - transition: opacity .3s map-get( $timing-functions, 'move' ); - top: calc(#{$gutter} + 2ex); - width: calc((var(--width) * 2) + (var(--gap) / 2) + 1px); - z-index: 0; - } - - @each $number in 1, 3, 5 { - &:nth-child(#{$number + 1})::after { - left: calc(14ch + 1em + (((var(--width) * 2) + (var(--gap) / 2) + 1px) * #{$number - 1}) + (var(--gap) * #{$number})); - } - } - } - - td { - background-color: palette( charts, pink ); - background-image: var(--zig); - grid-row-end: -3; - } - - /** - * @note Oh boy, if we could use var(--span) in selector… - */ - td:nth-of-type(2n + 2) { - background: palette( charts, blue ) var(--triangles); - } - - @media screen and (-ms-high-contrast: active) { - td { - background-color: Window; - } - - td:nth-of-type(2n + 2) { - background-color: Highlight; - } - } - } - } -} diff --git a/sass/_chaarts-line.scss b/sass/_chaarts-line.scss deleted file mode 100644 index 95dfa72..0000000 --- a/sass/_chaarts-line.scss +++ /dev/null @@ -1,339 +0,0 @@ -/* ==================== */ -/* == Line Charts - * - * @note Grid charts based on - * @see https://css-tricks.com/css-charts-grid-custom-properties/ - * @author Miriam Suzanne - * - * @note Massively using clip-path - * @see Bennett Feely's clippy to understand polygon() syntax - * @link http://bennettfeely.com/clippy/ - */ - @supports (clip-path: polygon(0% calc(100% - (var(--1) * 100% / var(--y))))) { - .line-container .fieldset { - display: flex !important; - } - - .chaarts.line { - --offset: calc( ( 100% / var(--x) ) / 2 ); - --height: calc( #{$width * 0.5} - #{$gutter * 2} ); - --bottom: calc( 100% - var(--height) ); - padding: var(--height) 0 $gutter; - position: relative; - transition: - background .3s map-get( $timing-functions, 'move' ), - color .3s map-get( $timing-functions, 'move' ); - - &::after { - --scale: calc( ( 100% - (var(--y) * 1px) ) / var(--y) ); - background: - repeating-linear-gradient( - to bottom, - white 0 var(--scale), - rgba(0, 0, 0, .25) calc(var(--scale) + 1px) - ); - bottom: var(--bottom); - content: ""; - position: absolute; - top: 0; - width: 100%; - z-index: 1; - } - - tr::before { - content: ""; - position: absolute; - } - - [scope="row"], - thead th:first-child { - color: var(--color, currentColor); - text-align: left; - } - - [style]::before { - bottom: var(--bottom); - background: linear-gradient(to top, palette( secondary, light ), palette( alert ) 75%); - --polygon: polygon( - 0% 100%, - calc((100% / var(--x) * 1)) 100%, - calc((100% / var(--x) * 1)) calc(100% - (var(--1) / var(--y) * 100%)), - calc((100% / var(--x) * 1) + var(--offset)) calc(100% - (var(--1) / var(--y) * 100%)), - calc((100% / var(--x) * 2) + var(--offset)) calc(100% - (var(--2) / var(--y) * 100%)), - calc((100% / var(--x) * 3) + var(--offset)) calc(100% - (var(--3) / var(--y) * 100%)), - calc((100% / var(--x) * 4) + var(--offset)) calc(100% - (var(--4) / var(--y) * 100%)), - calc((100% / var(--x) * 5) + var(--offset)) calc(100% - (var(--5) / var(--y) * 100%)), - calc((100% / var(--x) * 6) + var(--offset)) calc(100% - (var(--6) / var(--y) * 100%)), - calc((100% / var(--x) * 7) + var(--offset)) calc(100% - (var(--7) / var(--y) * 100%)), - calc((100% / var(--x) * 8) + var(--offset)) calc(100% - (var(--8) / var(--y) * 100%)), - calc((100% / var(--x) * 9) + var(--offset)) calc(100% - (var(--9) / var(--y) * 100%)), - calc((100% / var(--x) * 10) + var(--offset)) calc(100% - (var(--10) / var(--y) * 100%)), - calc((100% / var(--x) * 11) + var(--offset)) calc(100% - (var(--11) / var(--y) * 100%)), - calc((100% / var(--x) * 12) + var(--offset)) calc(100% - (var(--12) / var(--y) * 100%)), - 100% calc(100% - (var(--12) / var(--y) * 100%)), - 100% 100%, - 0% 100% - ); - clip-path: var(--polygon); - content: ""; - position: absolute; - top: 0; - width: 100%; - z-index: 2; - } - - th, - td { - background: palette( default, contrast ); - font-weight: bold; - text-align: center; - width: calc( 100% / var(--x) ); - } - - [scope="col"] { - &:not(:first-child)::after { - background: palette( default, contrast ) var(--stripes); - background-blend-mode: exclusion; - bottom: $gutter * 4; - content: ""; - height: calc(100% - #{$gutter * 4}); - left: calc(100% / var(--x) * var(--index)); - mix-blend-mode: soft-light; - opacity: 0; - position: absolute; - transition: opacity .3s map-get( $timing-functions, 'move' ); - width: inherit; - z-index: 3; - } - - @each $number in 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 { - &:nth-child(#{$number})::after { - --index: #{$number - 1}; - } - } - - &:hover::after { - opacity: .75; - } - } - - td { - --value: var(--1); - --term: var(--t-1); - line-height: 1.5; - - &::before { - content: ""; - height: 1.5rem; - position: absolute; - transform: translateX(-50%); - width: inherit; - z-index: 10; - } - - /** - * 1. - * @note Using white-space and: - ** `\A` to make a line-break - ** `\A0` for a non-breakable space - * @note Based on CSS Secrets by - * @author Lea Verou - * @link https://lea.verou.me/2012/02/flexible-multiline-definition-lists-with-2-lines-of-css/ - * - * 2. - * @note Display CSS integers custom properties with a trick using counters - * @author Cassie Evans - * @link https://codepen.io/cassie-codes/pen/22ea69e0f681d45f2f4c2ca5e6acf4ab - * - * 3. - * @note We need to ensure our counter uses an integer, --value might a a floating number - * @author Carter Li - * @link https://css-tricks.com/animating-number-counters/#the-new-school-css-solution - */ - &::after { - --arrow: calc(100% - #{$gutter * 0.25}); - --top: calc( var(--height) - ( var(--value) / var(--y) * var(--height) ) ); - --polygon: polygon( - 0% 0%, - 100% 0%, - 100% var(--arrow), - calc(50% - #{$gutter * 0.25}) var(--arrow), - 50% 100%, - calc(50% + #{$gutter * 0.25}) var(--arrow), - 0% var(--arrow) - ); - --integer: calc(var(--value)); // 3 - background-color: palette( dominant ); - clip-path: var(--polygon); - color: palette( dominant, contrast ); - content: var(--term) " " var(--year) "\A " counter(value) "\A0" var(--unit); // 1 - counter-reset: value var(--integer); // 2, 3 - opacity: 0; - padding: $gutter * 0.5; - left: calc( var(--offset) * 3 ); - pointer-events: none; - position: absolute; - top: var(--top, 0); - transform-origin: 50% calc(100% + 10px); - transform: - translate3d(-50%, -125%, 0) - perspective(1000px) - rotate3d(1, 0, 0, 45deg); - transition: - opacity .2s map-get( $timing-functions, 'enter' ), - transform .2s map-get( $timing-functions, 'enter' ); - white-space: pre; - z-index: 5; - } - - + td::after { - left: calc( ( 100% / var(--x) * var(--index) ) + var(--offset) ); - } - - @each $number in 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 { - &:nth-child(#{$number})::after { - --value: var(--#{$number - 1}); - --term: var(--t-#{$number - 1}); - --index: #{$number - 1}; - } - } - - &:hover::after { - opacity: 1; - transform: - translate3d(-50%, -125%, 0) - perspective(1000px) - rotate3d(1, 0, 0, 0deg); - transition: - opacity .2s map-get( $timing-functions, 'exit' ), - transform .2s map-get( $timing-functions, 'exit' ); - } - } - } - - .chaarts.points { - [style] { - &::before { - background: var(--color, currentColor) var(--background); - --polygon: polygon( - calc((100% / var(--x) * 1) + var(--offset)) calc(100% - (var(--1) / var(--y) * 100%)), - calc((100% / var(--x) * 2) + var(--offset)) calc(100% - (var(--2) / var(--y) * 100%)), - calc((100% / var(--x) * 3) + var(--offset)) calc(100% - (var(--3) / var(--y) * 100%)), - calc((100% / var(--x) * 4) + var(--offset)) calc(100% - (var(--4) / var(--y) * 100%)), - calc((100% / var(--x) * 5) + var(--offset)) calc(100% - (var(--5) / var(--y) * 100%)), - calc((100% / var(--x) * 6) + var(--offset)) calc(100% - (var(--6) / var(--y) * 100%)), - calc((100% / var(--x) * 7) + var(--offset)) calc(100% - (var(--7) / var(--y) * 100%)), - calc((100% / var(--x) * 8) + var(--offset)) calc(100% - (var(--8) / var(--y) * 100%)), - calc((100% / var(--x) * 9) + var(--offset)) calc(100% - (var(--9) / var(--y) * 100%)), - calc((100% / var(--x) * 10) + var(--offset)) calc(100% - (var(--10) / var(--y) * 100%)), - calc((100% / var(--x) * 11) + var(--offset)) calc(100% - (var(--11) / var(--y) * 100%)), - calc((100% / var(--x) * 12) + var(--offset)) calc(100% - (var(--12) / var(--y) * 100%)), - calc((100% / var(--x) * 13) + var(--offset)) calc(100% - (var(--12) / var(--y) * 100%)), - 100% calc(100% - (var(--12) / var(--y) * 100%)), - 100% calc((100% + #{$gutter * 0.25}) - (var(--12) / var(--y) * 100%)), - calc((100% / var(--x) * 13) + var(--offset)) calc((100% + #{$gutter * 0.25}) - (var(--12) / var(--y) * 100%)), - calc((100% / var(--x) * 12) + var(--offset)) calc((100% + #{$gutter * 0.25}) - (var(--12) / var(--y) * 100%)), - calc((100% / var(--x) * 11) + var(--offset)) calc((100% + #{$gutter * 0.25}) - (var(--11) / var(--y) * 100%)), - calc((100% / var(--x) * 10) + var(--offset)) calc((100% + #{$gutter * 0.25}) - (var(--10) / var(--y) * 100%)), - calc((100% / var(--x) * 9) + var(--offset)) calc((100% + #{$gutter * 0.25}) - (var(--9) / var(--y) * 100%)), - calc((100% / var(--x) * 8) + var(--offset)) calc((100% + #{$gutter * 0.25}) - (var(--8) / var(--y) * 100%)), - calc((100% / var(--x) * 7) + var(--offset)) calc((100% + #{$gutter * 0.25}) - (var(--7) / var(--y) * 100%)), - calc((100% / var(--x) * 6) + var(--offset)) calc((100% + #{$gutter * 0.25}) - (var(--6) / var(--y) * 100%)), - calc((100% / var(--x) * 5) + var(--offset)) calc((100% + #{$gutter * 0.25}) - (var(--5) / var(--y) * 100%)), - calc((100% / var(--x) * 4) + var(--offset)) calc((100% + #{$gutter * 0.25}) - (var(--4) / var(--y) * 100%)), - calc((100% / var(--x) * 3) + var(--offset)) calc((100% + #{$gutter * 0.25}) - (var(--3) / var(--y) * 100%)), - calc((100% / var(--x) * 2) + var(--offset)) calc((100% + #{$gutter * 0.25}) - (var(--2) / var(--y) * 100%)), - calc((100% / var(--x) * 1) + var(--offset)) calc((100% + #{$gutter * 0.25}) - (var(--1) / var(--y) * 100%)) - ); - transition: opacity .3s map-get( $timing-functions, 'move' ); - } - - th::before { - background: var(--color, currentColor) var(--background); - content: ""; - display: inline-block; - height: 1rem; - transform: translate3d(-.2rem, .1rem, 0); - width: 1rem; - } - - td { - &::before { - --size: #{$gutter}; - --top: calc( var(--height) - ( var(--value) / var(--y) * var(--height) ) ); - background: var(--color, currentColor) var(--background); - border: 2px solid palette( default, contrast ); - border-radius: 50%; - box-shadow: 0 0 #{$gutter * 0.25} rgba(0, 0, 0, .5); - content: ""; - height: var(--size); - left: calc( var(--offset) * 3 ); - position: absolute; - top: var(--top, 100); - transform: translate3d(calc(var(--size) / -2), calc(var(--size) / -2), 0); - transition: - opacity .3s map-get( $timing-functions, 'move' ), - transform .3s map-get( $timing-functions, 'move' ); - width: var(--size); - z-index: 4; - } - - + td::before { - left: calc( ( 100% / var(--x) * var(--index) ) + var(--offset)); - } - - @each $number in 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 { - &:nth-of-type(#{$number})::before { - --value: var(--#{$number}); - --index: #{$number}; - } - } - } - } - - @each $name, $pattern in $patterns { - $i: index($patterns, ($name $pattern)); - - [style]:nth-child(#{$i}n + #{$i}) { - --background: var(--#{$name}); // 1 - } - } - - tbody:hover [style]::before, - tbody:hover [style] td::before { - opacity: .25; - } - - tbody:hover [style]:hover::before, - tbody:hover [style]:hover td::before { - opacity: 1; - } - - tbody:hover [style]:hover td::before { - transform: - translate3d(calc(var(--size) / -2), calc(var(--size) / -2), 0) - scale(1.25); - } - - [scope="col"]:not(:first-child) { - &::after { - mix-blend-mode: multiply; - } - - &:hover::after { - opacity: .5; - } - } - } - - @media screen and (-ms-high-contrast: active) { - .chaarts.line [style]::before { - /** - * @note Custom color palette for WHCM - * @note Inspired by Greg Whitworth's post - * @link http://www.gwhitworth.com/blog/2017/04/how-to-use-ms-high-contrast - */ - background: linear-gradient(to top, ButtonHighlight, Highlight 75%); - } - } -} diff --git a/sass/_chaarts-pie.scss b/sass/_chaarts-pie.scss deleted file mode 100644 index 00f3ba8..0000000 --- a/sass/_chaarts-pie.scss +++ /dev/null @@ -1,226 +0,0 @@ -/* ==================== */ -/* == Pie Charts -/* ==================== */ -@supports (clip-path: polygon( 50% calc( 50% + ( var(--gt-25, 0) ) ) )) { - .pie-container .fieldset { - display: flex !important; - margin-bottom: 0; - } - - .chaarts.pie { - --radius: 32em; - margin: 0 auto; - padding-top: calc(var(--radius) - #{$gutter * 2}); - position: relative; - - tbody { - display: table-row; - } - - tr { - display: table-cell; - transition: opacity .3s map-get( $timing-functions, 'move' ); - } - - [scope="row"] { - padding-right: $gutter * 0.5; - - &::before { - background: var(--color, currentColor) var(--background); - content: ""; - display: inline-block; - height: $gutter; - transform: translate3d(-.2rem, .1rem, 0); - width: $gutter; - } - } - - td { - --position: calc(var(--start, 0) * .01turn); - } - - td::after, - td::before { - left: 50%; - position: absolute; - top: calc(var(--radius) / 2); - transform-origin: center center; - } - - /** - * Using clip-path + calc() + transform + CSS vars - * Using mask-image to make a circle - * - * 1. - * @note Based on Ana Tudor's work - * @link https://css-tricks.com/1-html-element-5-css-properties-magic/ - * @author Ana Tudor - * - * 2. - * @note Using a Roma Komarov's idea about boolean custom properties - * @link https://www.kizu.ru/conditions-for-css-variables/ - * - * 3. - * @note Mask support: - * @link https://caniuse.com/#search=mask - */ - td::before { - --zoom: .75; - --part: calc( var(--value) * 3.6 ); - --main-angle: calc( var(--part) - ( 90 * ( var(--gt-25, 0) + var(--gt-50, 0) + var(--gt-75, 0) ) ) ); - --β: calc( var(--main-angle) * 0.01745329251 ); - --α: calc( ( 90 - var(--main-angle) ) * 0.01745329251 ); - @include sin(β); - @include sin(α); - --pos-B: calc( var(--sin-β) * 50 ); - --pos-A: calc( var(--sin-α) * 50 ); - --polygon: polygon( - 50% 50%, - 50% 0%, - 100% 0%, - calc( 50% + ( var(--pos-B) * 1% * var(--lt-25, 1) ) + ( var(--gt-25, 0) * 50% ) ) calc( 50% - ( var(--pos-A) * 1% * var(--lt-25, 1) ) ), - calc( 50% + ( var(--gt-25, 0) * 50% ) ) calc( 50% + ( var(--gt-25, 0) * 50% ) ), - calc( 50% + ( var(--pos-A) * 1% * var(--lt-50, 1) ) + ( var(--gt-50, 0) * 50% ) ) calc( 50% + ( var(--pos-B) * 1% * var(--lt-50, 1) ) + ( var(--gt-50, 0) * 50% ) ), - calc( 50% - ( var(--gt-50, 0) * 50% ) ) calc( 50% + ( var(--gt-50, 0) * 50% ) ), - calc( 50% - ( var(--pos-B) * 1% * var(--lt-75, 1) ) - ( var(--gt-75, 0) * 50% ) ) calc( 50% + ( var(--pos-A) * 1% * var(--lt-75, 1) ) ), - calc( 50% - ( var(--gt-75, 0) * 50% ) ) calc( 50% - ( var(--gt-75, 0) * 50% ) ), - calc( 50% - ( var(--pos-A) * 1% * var(--gt-75, 0) ) ) calc( 50% - ( var(--pos-B) * 1% * var(--gt-75, 0) ) ), - 50% 50% - ); - background: var(--color, currentColor) var(--background); - clip-path: var(--polygon); - content: ''; - height: var(--radius); - --mask: radial-gradient( - circle at center, - #fff 0 calc(var(--radius) / 2), - transparent 0 - ); - mask-image: var(--mask); - transform: - translate3d(-50%, -50%, 0) - rotate( var(--position) ) - scale( var(--zoom) ); - transition: transform .2s map-get( $timing-functions, 'move' ); - width: var(--radius); - } - - tr:hover td::before { - --zoom: .8; - } - - @each $name, $pattern in $patterns { - $i: index($patterns, ($name $pattern)); - - tr:nth-child(#{$i}n + #{$i}) { - --background: var(--#{$name}); // 1 - } - } - - /** - * 1. - * @note Display CSS integers custom properties with a trick using counters - * @author Cassie Evans - * @link https://codepen.io/cassie-codes/pen/22ea69e0f681d45f2f4c2ca5e6acf4ab - * - * 2. - * @note We need to ensure our counter uses an integer, --value might a a floating number - * @author Carter Li - * @link https://css-tricks.com/animating-number-counters/#the-new-school-css-solution - */ - td::after { - --arrow: calc(100% - #{$gutter * 0.25}); - --axis: calc( var(--position) - .25turn + var(--value) * .005turn ); - --away: calc( var(--radius) / 2 - #{$gutter} ); - --integer: calc(var(--value)); // 2 - background-color: palette( dominant ); - color: palette( dominant, contrast ); - content: var(--term) "\A0: " counter(value) "\A0%"; // 1 - counter-reset: value var(--integer); // 1 - opacity: 0; - padding: $gutter * 0.5; - pointer-events: none; - transform-origin: 50% calc(100% + 10px); - transform: - translate3d(-50%, -50%, 0) - rotate( var(--axis) ) - translate( var(--away) ) - rotate( calc( var(--axis) * -1 ) ) - perspective(1000px) - rotate3d(1, 0, 0, 45deg); - transition: - opacity .2s map-get( $timing-functions, 'enter' ), - transform .2s map-get( $timing-functions, 'enter' ); - } - - tbody:hover tr { - opacity: .5; - - &:hover { - opacity: 1; - } - - &:hover td::after { - opacity: 1; - transform: - translate3d(-50%, -50%, 0) - rotate( var(--axis) ) - translate( var(--away) ) - rotate( calc( var(--axis) * -1 ) ) - perspective(1000px) - rotate3d(1, 0, 0, 0deg); - transition: - opacity .2s map-get( $timing-functions, 'exit' ), - transform .2s map-get( $timing-functions, 'exit' ); - } - } - } - - .chaarts.polar { - td::before { - --zoom: 50; - transform: - translate3d(-50%, -50%, 0) - rotate( var(--position) ) - scale( calc( ( var(--zoom) + ( var(--value) / ( 100 / var(--zoom) ) ) ) / 100 ) ); - } - - td::after { - --away: calc( ( var(--radius) / 2 ) - ( ( var(--radius) / 4 ) * ( ( 100 - var(--value) ) / 100 ) ) + #{$gutter * 2.5} ); - } - - tr:hover td::before { - --zoom: 50; - } - } - - .chaarts.donut { - --mask: radial-gradient( - circle at 50% calc(50% - #{$gutter * 0.25}), - transparent 0 var(--offset), - #fff calc(var(--offset) + 1px) 100% - ); - mask-image: var(--mask); - - td::after { - --away: calc( var(--radius) / 2 - #{$gutter * 2.5} ); - } - } - - @media screen and (-ms-high-contrast: active) { - .chaarts.pie { - tbody tr *::before { - /** - * @note Custom color palette for WHCM - * @note Inspired by Greg Whitworth's post - * @link http://www.gwhitworth.com/blog/2017/04/how-to-use-ms-high-contrast - */ - background-color: Window; - } - - tbody tr:nth-of-type(odd) *::before { - background-color: WindowText; - } - } - } -} diff --git a/sass/_chaarts-radar.scss b/sass/_chaarts-radar.scss deleted file mode 100644 index ae6df6d..0000000 --- a/sass/_chaarts-radar.scss +++ /dev/null @@ -1,269 +0,0 @@ -/* ==================== */ -/* == Radar Charts -/* ==================== */ - -@use "sass:math"; - -@supports(clip-path: polygon(0% 0%, calc(100% - ( var(--1) * 100% / var(--scale) ) ) 100%, 100% 100%)) { - .radar-container .fieldset { - display: flex !important; - } - - .chaarts[class*="radar"] { - --radius: #{$width * 0.2}; - --unitless-radius: calc( 1024 / 16 / 5 ); - --size: calc( var(--radius) / var(--scale) ); - --part: calc( 360deg / var(--items) ); - --integer: calc(var(--scale)); - background-image: - repeating-radial-gradient( - circle at 50%, - rgba(0, 0, 0, .2) 0 2px, - transparent 0 calc(var(--size) * var(--step)) - ), - repeating-radial-gradient( - circle at 50%, - rgba(0, 0, 0, .1) 0 2px, - transparent 0 var(--size) - ); - border: 2px solid; - border-radius: 50%; - contain: layout; - counter-reset: scale var(--integer); - height: calc( var(--radius) * 2 ); - margin: $gutter * 6 auto $gutter * 12; - overflow: visible; - position: relative; - width: calc( var(--radius) * 2 ); - - caption { - background: none; - bottom: $gutter * -10; - position: absolute; - } - - /** - * Placing items around a circle based on: - * @link https://stackoverflow.com/questions/12813573/position-icons-into-circle - * @link http://dabblet.com/gist/3866686 - * @author Ana Tudor - * - * @note Negative values for radius helps to start at the top left corner - */ - [scope="col"] { - --away: calc( (var(--radius) * -1) - 50% ); - left: 50%; - margin: 0; - padding: 0 $gutter; - position: absolute; - top: 50%; - transform: - translate3d(-50%, -50%, 0) - rotate( calc(var(--part) * var(--index, 1)) ) - translate( var(--away) ) - rotate( calc(var(--part) * var(--index, 1) * -1) ); - } - - @each $number in 1, 2, 3, 4, 5, 6, 7 { - tr > *:nth-of-type(#{$number}) { - --index: #{$number}; - } - } - - /** - * This is quite sophisticated, we're mixing multiple techniques - * - * @note Setting items as parts of the circle: - * @link https://tympanus.net/codrops/2013/08/09/building-a-circular-navigation-with-css-transforms/ - * @author Sara Soueidan - * - * @note Because we skew items, clip-path() needs to take skew angle into account - * @note To do so, we need to know skewed width (which is hypothenuse of the resulting triangle) - * @note We only know two angles (skew one + suqare one) and a side (initial width), - * @note So we need to compute the sinus of the opposite angle to get hypothenuse - * @note Thanks god, Stereokai made trigonometry functions in pure CSS: - * - * @note Trigonometry functions based on: - * @link https://gist.github.com/stereokai/7666bfe93929b14c2dced148c79e0e97 - * @author Stereokai - */ - td { - --skew: calc( 90deg - var(--part) ); - border-bottom: 1px solid palette( accent, light ); - height: 50%; - left: 0; - margin: 0; - position: absolute; - top: 0; - transform: - rotate( calc(var(--part) * var(--index, 1)) ) - skew( var(--skew) ); - transform-origin: 100% 100%; - width: 50%; - - @each $number in 1, 2, 3, 4, 5, 6, 7 { - &:nth-of-type(#{$number}) span { - --point: var(--#{$number}); - --pos: calc( 100% - (var(--#{$number + 1}) * 100% / (var(--scale) * var(--ratio) ) ) ); - } - } - - &::after, - &::before { - display: none; - } - } - - span { - --opposite: calc( 180 - (90 + (90 - (360 / var(--items)))) ); - // get opposite angle in radians - --angle: calc( var(--opposite) * 0.01745329251 ); - // calc() sin, dark wizardry! - @include sin(angle); - // calc() hypothenuse - --hypo: calc( var(--unitless-radius) / var(--sin-angle) ); - // get the ratio: skewed / initial width - --ratio: calc( var(--hypo) / var(--unitless-radius) ); - --polygon: polygon( - 100% var(--pos), - calc( 100% - ( var(--point) * 100% / var(--scale) ) ) 100%, - 100% 100% - ); - background: linear-gradient( - to top left, - palette( accent, light ) 10%, - palette( secondary, dark ) 75% - ); - clip-path: var(--polygon); - filter: drop-shadow( 0 0 $gutter palette( accent, dark ) ); - height: 100%; - position: absolute; - width: 100%; - } - } - - /** - * 1. - * @note Display CSS integers custom properties with a trick using counters - * @author Cassie Evans - * @link https://codepen.io/cassie-codes/pen/22ea69e0f681d45f2f4c2ca5e6acf4ab - * - * 2. - * @note We need to ensure our counter uses an integer, --value might a a floating number - * @author Carter Li - * @link https://css-tricks.com/animating-number-counters/#the-new-school-css-solution - */ - .chaarts.radar [scope="col"] { - &::after { - color: palette( accent ); - display: block; - font-size: small; - font-weight: 400; - } - - @each $number in 1, 2, 3, 4, 5, 6, 7 { - &:nth-child(#{$number})::after { - --integer: calc(var(--#{$number})); // 2 - counter-reset: value var(--integer); // 1 - content: counter(value) "\A0/\A0" counter(scale); // 1 - } - } - } - - .chaarts.radar-multiple { - margin-bottom: $gutter * 12; - - tbody { - columns: var(--areas); - vertical-align: bottom; - } - - [scope="row"] { - bottom: $gutter * -8; - height: $gutter * 2; - left: $gutter; - position: absolute; - - &::before { - background: var(--color, currentColor); - content: ""; - display: inline-block; - height: $gutter; - margin-right: $gutter * 0.25; - transform: translate3d(0, .1rem, 0); - width: $gutter; - } - } - - // Allowing more areas :) - @each $number in 1 { - tr:nth-child(#{$number + 1}) [scope="row"] { - left: calc( #{$gutter} + (100% / var(--areas)) * #{$number}); - } - } - - td { - align-items: flex-end; - border-color: var(--color, currentColor); - display: flex; - justify-content: flex-end; - opacity: .5; - pointer-events: none; - z-index: 0; - - &::after { - color: var(--color, currentColor); - display: block; - font-size: small; - font-weight: 700; - text-indent: #{math.div($gutter, -2)}; - transform: - skew( calc( var(--skew) * -1 ) ) - rotate( calc( var(--part) * var(--index, 1) * -1 ) ); - transform-origin: 0 0; - width: 100%; - white-space: nowrap; - } - - @each $number in 1, 2, 3, 4, 5, 6, 7 { - &:nth-of-type(#{$number})::after { - --integer: calc(var(--#{$number})); // 2 - counter-reset: value var(--integer); // 1 - content: counter(value); // 1 - width: calc( var(--#{$number}) * 100% / var(--scale) ); - } - } - } - - span { - background: var(--color, currentColor); - pointer-events: auto; - - @supports (mask-image: url()) { - --mask: radial-gradient(circle at bottom right, rgba(0,0,0,1), rgba(0,0,0,.5)); - mask-image: var(--mask); - } - } - - @media (hover: hover) { - td { - opacity: .25; - transition: opacity .2s map-get( $timing-functions, 'move' ); - - &::after { - opacity: 0; - transition: inherit; - } - } - - tr:hover td { - opacity: 1; - z-index: 1; - - &::after { - opacity: inherit; - } - } - } - } -} diff --git a/sass/abstracts/_functions.scss b/sass/abstracts/_functions.scss deleted file mode 100644 index 9f0c1b0..0000000 --- a/sass/abstracts/_functions.scss +++ /dev/null @@ -1,83 +0,0 @@ -// ----------------------------- */ -// == Functions -// ----------------------------- */ - -// em conversion -// @note Found in Marie Guillaumet's Gists -// @author Marie Guillaumet -// @see https://twitter.com/kReEsTaL -// @see http://marieguillaumet.com/ -// @see https://gist.github.com/ijy/1441967 -@use "sass:math"; - -@function em( $f, $base: 16 ) { - $everything-okay: true; - - @if type-of( $f ) != number { - @warn "Biip ! `{$s}` is not a valid number."; - $everything-okay: false; - } - - @if $everything-okay == true { - @if $f == 0 { @return 0 } - @return math.div($f, $base) * 1em; - } -} - -// rem conversion -@function rem( $f, $base: 16 ) { - $everything-okay: true; - - @if type-of( $f ) != number { - @warn "Biip ! `{$s}` is not a valid number."; - $everything-okay: false; - } - - @if $everything-okay == true { - @if $f == 0 { @return 0 } - @return math.div($f, $base) * 1rem; - } -} - - -// Color palette -// @note Allow to pick a color in defined color palette -// @author Tom Davies -// @see http://erskinedesign.com/blog/friendlier-colour-names-sass-maps/ -@function palette( $color, $tone: "base" ) { - @if ( map-has-key( $colors, $color ) ) { - @if ( map-has-key( map-get( $colors, $color ), $tone ) ) { - @return map-get( map-get( $colors, $color ), $tone ); - } @else { - @error "Biip ! `#{$tone}` is not a valid `#{$color}`'s variants."; - } - } @else { - @error "Biip ! `#{$color}` is not part of our palette…"; - } -} - - -// Replace `$search` with `$replace` in `$string` -// @author Kitty Giraudel -// @param {String} $string - Initial string -// @param {String} $search - Substring to replace -// @param {String} $replace ('') - New value -// @return {String} - Updated string -// @see https://www.sassmeister.com/gist/1b4f2da5527830088e4d -@function str-replace($string, $search, $replace: '') { - $index: str-index($string, $search); - - @if $index { - @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); - } - - @return $string; -} - - -// Convert value to string -// @author Kitty Giraudel -// @see https://kittygiraudel.com/2014/01/27/casting-types-in-sass/ -@function to-string($value) { - @return inspect($value); -} diff --git a/sass/abstracts/_mixins.scss b/sass/abstracts/_mixins.scss deleted file mode 100644 index f723193..0000000 --- a/sass/abstracts/_mixins.scss +++ /dev/null @@ -1,8 +0,0 @@ -@mixin sin($angle) { - --sin-term-#{$angle}-1: var(--#{$angle}); - --sin-term-#{$angle}-2: calc((var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle})) / 6); - --sin-term-#{$angle}-3: calc((var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle})) / 120); - --sin-term-#{$angle}-4: calc((var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle})) / 5040); - --sin-term-#{$angle}-5: calc((var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle})) / 362880); - --sin-#{$angle}: calc(var(--sin-term-#{$angle}-1) - var(--sin-term-#{$angle}-2) + var(--sin-term-#{$angle}-3) - var(--sin-term-#{$angle}-4) + var(--sin-term-#{$angle}-5)); -} diff --git a/sass/abstracts/_variables.scss b/sass/abstracts/_variables.scss deleted file mode 100644 index e5f353b..0000000 --- a/sass/abstracts/_variables.scss +++ /dev/null @@ -1,117 +0,0 @@ -@charset "UTF-8"; -// ----------------------------- */ -// Table of contents -// ----------------------------- */ -// -// == Paths -// == Colors -// == Timing functions -// == Spacings -// == Patterns -// == Formage -// - -// ==================== */ -// == Paths -// ==================== */ -@use "sass:math"; - -$path: "../" !default; - -// ==================== */ -// == Colors -// ==================== */ -$colors: ( - dominant: ( - base: #444, - light: mediumblue, - dark: black, - contrast: white - ), - secondary: ( - base: mediumblue, - light: deepskyblue, - dark: DarkBlue, - contrast: white - ), - accent: ( - base: rebeccapurple, - light: blueviolet, - dark: indigo, - contrast: white - ), - alert: ( - base: crimson, - light: firebrick, - dark: #911, - contrast: white - ), - success: ( - base: springgreen, - light: palegreen, - dark: #01ac49, - contrast: #444 - ), - muted: ( - base: gray, - light: darkgray, - dark: #333, - contrast: black - ), - default: ( - base: dimgray, - light: lightgray, - dark: darkgrey, - secondary: whitesmoke, - contrast: white - ), - charts: ( - purple: #734bf9, - pink: #e11a81, - blue: #0172f0, - yellow: #fdc02f, - green: #39ca74, - red: #ff2d40, - gray: #585462 - ) -); - -$blank: str-replace(to-string(palette( accent )), "#", "%23"); -$blank-focus: str-replace(to-string(palette( accent, dark )), "#", "%23"); - -// ==================== */ -// == Timing functions -// -// @note Simple cubic-bezier curves for timing functions -// @author David K. Piano -// @link https://twitter.com/DavidKPiano/status/965704092545900544 -// ==================== */ -$timing-functions: ( - enter: cubic-bezier(0, .5, .5, 1), - exit: cubic-bezier(.5, 0, 1, .5), - move: cubic-bezier(.5, 0, .5, 1) -); - -// ==================== */ -// == Spacings -// ==================== */ -$full-width: false !default; -$base: math.div(1140, 16) !default; -$width: em( 1024 ) !default; -$gutter: rem( 16 ) !default; -$content-width: em( 600 ) !default; - -// ==================== */ -// == Patterns -// -// @note SVG inline patterns coming from: -// @link http://www.heropatterns.com/ -// ==================== */ -$patterns: ( - "checkers": "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3E%3Cg fill='%23ffffff99'%3E%3Cpath fill-rule='evenodd' d='M0 0h4v4H0V0zm4 4h4v4H4V4z'/%3E%3C/g%3E%3C/svg%3E", - "hexagons": "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='24' viewBox='0 0 28 49'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23ffffff99' fill-rule='nonzero'%3E%3Cpath d='M13.99 9.25l13 7.5v15l-13 7.5L1 31.75v-15l12.99-7.5zM3 17.9v12.7l10.99 6.34 11-6.35V17.9l-11-6.34L3 17.9zM0 15l12.98-7.5V0h-2v6.35L0 12.69v2.3zm0 18.5L12.98 41v8h-2v-6.85L0 35.81v-2.3zM15 0v7.5L27.99 15H28v-2.31h-.01L17 6.35V0h-2zm0 49v-8l12.99-7.5H28v2.31h-.01L17 42.15V49h-2z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E", - "triangles": "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='16' viewBox='0 0 36 72'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23ffffff99'%3E%3Cpath d='M2 6h12L8 18 2 6zm18 36h12l-6 12-6-12z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E", - "zig": "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='12' viewBox='0 0 20 12'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23ffffff99'%3E%3Cpath d='M9.8 12L0 2.2V.8l10 10 10-10v1.4L10.2 12h-.4zm-4 0L0 6.2V4.8L7.2 12H5.8zm8.4 0L20 6.2V4.8L12.8 12h1.4zM9.8 0l.2.2.2-.2h-.4zm-4 0L10 4.2 14.2 0h-1.4L10 2.8 7.2 0H5.8z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E", - "stripes": "data:image/svg+xml,%3Csvg width='6' height='6' viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff99' fill-rule='evenodd'%3E%3Cpath d='M5 0h1L0 6V5zM6 5v1H5z'/%3E%3C/g%3E%3C/svg%3E", - "dots": "data:image/svg+xml,%3Csvg width='10' height='10' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff99' fill-rule='evenodd'%3E%3Ccircle cx='3' cy='3' r='3'/%3E%3Ccircle cx='13' cy='13' r='3'/%3E%3C/g%3E%3C/svg%3E" -); diff --git a/sass/chaarts.scss b/sass/chaarts.scss deleted file mode 100644 index e13d06e..0000000 --- a/sass/chaarts.scss +++ /dev/null @@ -1,183 +0,0 @@ -/* ==================== */ -/* == Abstracts -/* ==================== */ -@import "abstracts/functions"; -@import "abstracts/variables"; -@import "abstracts/mixins"; - -/* ==================== */ -/* == Convert to -/* ==================== */ -/** - * Using Houdini's @property to ensure --integer is type in Chromium-based browsers - * @link https://developer.mozilla.org/en-US/docs/Web/CSS/@property - * @link https://caniuse.com/mdn-css_at-rules_property - ** Based on: - ** @author Carter Li - ** @link https://css-tricks.com/animating-number-counters/#the-new-school-css-solution - */ -//noinspection ALL -@property --integer { - syntax: ""; - initial-value: 0; - inherits: false; -} - -/* ==================== */ -/* == Tables -/* ==================== */ -table { - border-collapse: collapse; - caption-side: top; - font-feature-settings: "tnum"; - margin-bottom: $gutter * 1.5; - width: 100%; - vertical-align: top; - - > caption:first-child { - font-style: italic; - margin: 0; - padding: rem( 40 ) $gutter; - } -} - -th, -td { - padding: $gutter * 0.5 rem( 12 ); - text-align: left; -} - -th, -table strong { - color: palette( dominant, dark ); -} - -td { - line-height: 1.25; - max-width: 100%; -} - -tbody { - border: 1px solid palette( default ); -} - -thead { - border: 1px solid palette( dominant, dark ); -} - -/* ==================== */ -/* == Charts -/* ==================== */ -/** - * Gives scrollable table some UX hints with shadows - * @author Chen Hui Jing - * @link https://codepen.io/huijing/pen/XBGaNQ - ** Based on: - ** @author Lea Verou - ** @link http://lea.verou.me/2012/04/background-attachment-local/ - */ -.table-container { - background: - linear-gradient(to right, rgba(255,255,255,1) 30%, rgba(255,255,255,0)), - linear-gradient(to right, rgba(255,255,255,0), rgba(255,255,255,1) 70%) 0 100%, - radial-gradient(farthest-side at 0% 50%, rgba(0,0,0,.2), rgba(0,0,0,0)), - radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%; - background-repeat: no-repeat; - background-color: palette( default, contrast ); - background-size: 2.5rem 100%, 2.5rem 100%, 1rem 100%, 1rem 100%; - background-position: 0 0, 100%, 0 0, 100%; - background-attachment: local, local, scroll, scroll; - margin: $gutter * 2 0; - max-width: 100%; - overflow-x: auto; - overflow-y: hidden; -} - -.table-container .fieldset { - display: none !important; - padding: 0 $gutter; -} - -[class*="chaarts"] { - [role="presentation"] { - display: none; - } - - abbr[title] { - border-bottom: 0; - font-size: small; - font-weight: normal; - text-transform: none; - } -} - -.chaarts { - caption-side: bottom; - empty-cells: hide; - margin: 1.5em auto; - overflow: hidden; - padding: 1em; - - /** - * @note Defining a CSS custom property for each inlined SVG pattern - * @author Trys Mudford - * @link https://www.trysmudford.com/blog/using-css-custom-properties/ - * @via Jeremy Keith - * @link https://adactio.com/journal/15075 - */ - @each $name, $pattern in $patterns { - --#{$name}: url("#{$pattern}"); - } - - > caption:first-child { - background: inherit; - font-style: normal; - padding: $gutter 0; - } -} - -table:not(.chaarts) .sr-only { - clip: auto !important; - clip-path: none !important; - height: auto !important; - overflow: visible !important; - position: static !important; - width: auto !important; - white-space: normal !important; -} - -@media screen and (min-width: em(480)) { - .chaarts { - border-collapse: separate; - /** - * @note Trying to improve paint & layout performances - * @link https://developer.mozilla.org/fr/docs/Web/CSS/contain - */ - contain: content; - - /* - * @bugfix - * @affected Chromium - * @link https://bugs.chromium.org/p/chromium/issues/detail?id=939728 - */ - &:not([class*="radar"]) { - border-spacing: 0; - } - - th, - td { - border: 0; - padding: 0; - - &:empty { - display: none !important; - } - } - } - - @import "chaarts-bar"; - @import "chaarts-pie"; - @import "chaarts-line"; - @import "chaarts-column"; - @import "chaarts-radar"; -} diff --git a/script.js b/script.js deleted file mode 100644 index 12e5416..0000000 --- a/script.js +++ /dev/null @@ -1,32 +0,0 @@ -(function () { - "use strict"; - - // Toggle switch component - var switches = document.querySelectorAll('[role="switch"]'); - - switches.forEach( function(el) { - el.addEventListener('click', function() { - var checked = this.getAttribute('aria-checked') === 'true' || false; - this.setAttribute('aria-checked', !checked); - - if (this.classList.contains('disable-css')) { - var chart = this.parentNode.nextElementSibling; - chart.classList.toggle('chaarts'); - } - }); - }); - - // Scrollable tables - var regions = document.querySelectorAll('.table-container'); - - if (window.matchMedia('(min-width: 30em)').matches) { - regions.forEach( function(el) { - var width = el.offsetWidth; - var table = el.querySelector('table'); - - if ( table.offsetWidth > width ) { - el.setAttribute('tabindex', '0'); - } - }); - } -})(document); diff --git a/script.min.js b/script.min.js deleted file mode 100644 index c7e3aab..0000000 --- a/script.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";!function(){document.querySelectorAll('[role="switch"]').forEach(function(t){t.addEventListener("click",function(){var t="true"===this.getAttribute("aria-checked")||!1;this.setAttribute("aria-checked",!t),this.classList.contains("disable-css")&&this.parentNode.nextElementSibling.classList.toggle("chaarts")})});var t=document.querySelectorAll(".table-container");window.matchMedia("(min-width: 30em)").matches&&t.forEach(function(t){var e=t.offsetWidth;t.querySelector("table").offsetWidth>e&&t.setAttribute("tabindex","0")})}(document); \ No newline at end of file diff --git a/src/_chaarts-bar.scss b/src/_chaarts-bar.scss new file mode 100644 index 0000000..aef156f --- /dev/null +++ b/src/_chaarts-bar.scss @@ -0,0 +1,134 @@ +@use "sass:map"; +@use "abstracts/functions"; +@use "abstracts/variables"; + +/* ==================== */ +/* == Bar Charts + * + * @note Grid charts based on: + * @see https://css-tricks.com/css-charts-grid-custom-properties/ + * @author Miriam Suzanne + * + * @note Grid setup: + * 1. 1st column to display legends, fixed width + * 1. 2nd column is a repeater, creating a subcolumn for each unit in --scale + * 1. 3rd columns with 6ch width to ensure that 6 characters long values has enough space to not overflow
    + * + * @note Clipped value coming from: + * @see https://www.ffoodd.fr/le-web-en-kit/ + * @see http://dabblet.com/gist/08fddf3666c39ebc62ca + * @author Gaël Poupard +/* ==================== */ + +@use "sass:math"; +@use "sass:list"; + +@supports (grid-template-columns: repeat(var(--scale, 100), minmax(0, 1fr))) { + .bar-container .fieldset { + display: flex !important; + } + + .chaarts.bar { + caption { + text-align: initial; + text-indent: #{math.div(200, 16) + variables.$gutter}; + } + + tr { + display: grid; + grid-auto-rows: 1fr; + grid-row-gap: variables.$gutter * 0.5; + grid-template-columns: minmax(min-content, math.div(200, 16) * 1em) repeat(var(--scale, 100), minmax(0, 1fr)) 10ch; + transition: opacity .2s map.get(variables.$timing-functions, 'move'); + + @each $name, $pattern in variables.$patterns { + $i: list.index(variables.$patterns, ($name $pattern)); + + &:nth-child(#{$i}n + #{$i}) { + --background: var(--#{$name}); // 1 + } + } + } + + th { + grid-column: 1 / 1; + margin: variables.$gutter * 0.5 0 0; + padding: 0 variables.$gutter 0 0; + text-align: right; + } + + td { + --size: calc(var(--scale, 100) * 100%); + --position: calc(var(--value, 0) / var(--scale, 100) * 100%); + background: linear-gradient(to right, + functions.palette(success, dark), + functions.palette(dominant), + functions.palette(secondary), + functions.palette(accent), + functions.palette(alert) + ) var(--position) list.slash(0%, var(--size)) 100%, + var(--background) center / contain; + background-blend-mode: hard-light; + grid-column: list.slash(2, var(--value, 0)); + margin: variables.$gutter * 0.5 0 0; + position: relative; + } + + span { + font-weight: bold; + left: 100%; + line-height: 1.5; + position: absolute; + + /** + * @note Progressively enhance background-clipping + * @author S. Shaw + * @link https://twitter.com/shshaw/status/1140637533539377153 + * Support is quite good actually + * @link https://caniuse.com/background-clip-text + */ + @supports (background-clip: text) or (-webkit-background-clip: text) { + background: inherit; + -webkit-background-clip: text; + background-clip: text; + color: transparent; + } + } + + &:hover { + tr { + opacity: .5; + } + + tr:hover { + opacity: 1; + } + } + + @media screen and (-ms-high-contrast: active) { + td { + /** + * @note Custom color palette for WHCM + * @note Inspired by Greg Whitworth's post + * @link http://www.gwhitworth.com/blog/2017/04/how-to-use-ms-high-contrast + */ + background-image: linear-gradient(to right, + Window, + ButtonFace, + ButtonShadow, + ButtonText, + highlight + ), + var(--background); + } + } + + &.waterfall { + @each $number in 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 { + tr:nth-of-type(#{$number}) td { + grid-column: list.slash(var(--#{$number - 1}, 2), var(--value, 2)); + } + } + } + } +} diff --git a/src/_chaarts-column.scss b/src/_chaarts-column.scss new file mode 100644 index 0000000..1689641 --- /dev/null +++ b/src/_chaarts-column.scss @@ -0,0 +1,253 @@ +@use "sass:map"; +@use "abstracts/functions"; +@use "abstracts/variables"; + +/* ==================== */ +/* == Column Charts + * + * @note Grid charts based on: + * @see https://css-tricks.com/css-charts-grid-custom-properties/ + * @author Miriam Suzanne +/* ==================== */ + +@use "sass:math"; +@use "sass:list"; + +@supports (display: contents) { + .column-container .fieldset { + display: flex !important; + } + + .chaarts[class*="column"] { + --gap: #{variables.$gutter * 0.5}; + --size: calc(var(--scale, 100) * 100%); + --width: calc(#{variables.$width} / var(--y) - #{variables.$gutter}); + display: grid; + grid-column-gap: var(--gap); + max-height: variables.$width; + position: relative; + + td, + th { + margin: 0; + } + + tr > * + * { + text-align: center; + } + + /** + * @note Use display: contents to place table-cells in table's grid + * @link https://hiddedevries.nl/en/blog/2018-04-21-more-accessible-markup-with-display-contents + * @link https://bitsofco.de/how-display-contents-works/ + */ + tr, + tbody, + thead { + display: contents; + } + + caption { + grid-column: 1 / span var(--y); + grid-row: -1; + } + + td { + --integer: calc(var(--value)); + grid-row: list.slash(calc((var(--scale, 100) + 2) - var(--integer)), -2); + pointer-events: none; + position: relative; + transition: opacity .2s map.get(variables.$timing-functions, 'move'); + + @each $number in 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 { + &:nth-of-type(#{$number}) { + grid-column: #{$number + 1}; + } + } + } + + span { + font-weight: bold; + bottom: 100%; + left: 0; + line-height: 1.5; + pointer-events: auto; + position: absolute; + right: 0; + + /** + * @note Progressively enhance background-clipping + * @author S. Shaw + * @link https://twitter.com/shshaw/status/1140637533539377153 + * Support is quite good actually + * @link https://caniuse.com/background-clip-text + */ + @supports (background-clip: text) or (-webkit-background-clip: text) { + background: inherit; + -webkit-background-clip: text; + background-clip: text; + color: transparent; + } + } + + &.column-single { + grid-auto-columns: 1fr; + grid-template-rows: 2ex repeat(var(--scale, 100), minmax(0, .25rem)) minmax(min-content, 2rem); + + tbody th { + grid-row: -6 / -3; + grid-column: 1; + line-height: 1; + } + + thead * { + grid-row: -2; + } + + td { + --position: calc(var(--integer, 0) / var(--scale, 100) * 100%); + background: linear-gradient(to top, + functions.palette(success, dark), + functions.palette(dominant), + functions.palette(secondary), + functions.palette(accent), + functions.palette(alert) + ) 0% list.slash(var(--position), 100%) var(--size), + var(--background) center / variables.$gutter; + background-blend-mode: hard-light; + } + + [scope="col"] { + &::after { + background: functions.palette(default, secondary) var(--stripes); + background-blend-mode: exclusion; + bottom: #{variables.$gutter * 4}; + content: ""; + mix-blend-mode: multiply; + opacity: 0; + position: absolute; + transition: opacity .3s map.get(variables.$timing-functions, 'move'); + top: variables.$gutter; + width: var(--width); + z-index: 0; + } + + &:hover::after { + opacity: .5; + } + + @each $number in 1, 2, 3, 4, 5, 6 { + &:nth-child(#{$number + 1})::after { + left: calc(1em + (var(--width) * #{$number}) + (var(--gap) * #{$number})); + } + } + } + + @each $name, $pattern in variables.$patterns { + $i: list.index(variables.$patterns, ($name $pattern)); + + td:nth-of-type(#{$i}n + #{$i}) { + --background: var(--#{$name}); + } + } + + @media screen and (-ms-high-contrast: active) { + td { + /** + * @note Custom color palette for WHCM + * @note Inspired by Greg Whitworth's post + * @link http://www.gwhitworth.com/blog/2017/04/how-to-use-ms-high-contrast + */ + background-image: linear-gradient(to top, + Window, + ButtonFace, + ButtonShadow, + ButtonText, + highlight + ), + var(--background); + } + } + } + + &.column-multiple { + grid-template-columns: minmax(min-content, 14ch) repeat(calc(var(--y) - 1), 1fr); + grid-template-rows: 2ex repeat(var(--scale, 100), minmax(0, .25rem)) repeat(2, minmax(min-content, 2rem)); + + span { + background-image: none; + } + + tbody th { + grid-row: -10 / span 7; + } + + thead tr * { + grid-row: -2; + grid-column: 1; + + @each $number in 2, 3, 4, 5, 6 { + &:nth-of-type(#{$number}) { + grid-column: calc(#{($number * 2)} - var(--span)) / span var(--span); + } + } + } + + thead tr + tr * { + font-weight: normal; + grid-row: -3; + + @each $number in 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 { + &:nth-of-type(#{$number}) { + grid-column: #{$number}; + } + } + } + + tr:first-child [scope="col"] { + &:nth-child(even)::after { + background: functions.palette(default, secondary) var(--stripes); + background-blend-mode: exclusion; + bottom: #{variables.$gutter * 4}; + content: ""; + mix-blend-mode: multiply; + opacity: .25; + position: absolute; + transition: opacity .3s map.get(variables.$timing-functions, 'move'); + top: calc(#{variables.$gutter} + 2ex); + width: calc((var(--width) * 2) + (var(--gap) / 2) + 1px); + z-index: 0; + } + + @each $number in 1, 3, 5 { + &:nth-child(#{$number + 1})::after { + left: calc(14ch + 1em + (((var(--width) * 2) + (var(--gap) / 2) + 1px) * #{$number - 1}) + (var(--gap) * #{$number})); + } + } + } + + td { + background-color: functions.palette(charts, pink); + background-image: var(--zig); + grid-row-end: -3; + } + + /** + * @note Oh boy, if we could use var(--span) in selector… + */ + td:nth-of-type(2n + 2) { + background: functions.palette(charts, blue) var(--triangles); + } + + @media screen and (-ms-high-contrast: active) { + td { + background-color: Window; + } + + td:nth-of-type(2n + 2) { + background-color: Highlight; + } + } + } + } +} diff --git a/src/_chaarts-line.scss b/src/_chaarts-line.scss new file mode 100644 index 0000000..50d2e98 --- /dev/null +++ b/src/_chaarts-line.scss @@ -0,0 +1,331 @@ +@use "sass:list"; +@use "sass:map"; +@use "abstracts/functions"; +@use "abstracts/variables"; + +/* ==================== */ +/* == Line Charts + * + * @note Grid charts based on + * @see https://css-tricks.com/css-charts-grid-custom-properties/ + * @author Miriam Suzanne + * + * @note Massively using clip-path + * @see Bennett Feely's clippy to understand polygon() syntax + * @link http://bennettfeely.com/clippy/ + */ +@supports (clip-path: polygon(0% calc(100% - (var(--1) * 100% / var(--y))))) { + .line-container .fieldset { + display: flex !important; + } + + .chaarts.line { + --offset: calc((100% / var(--x)) / 2); + --height: calc(#{variables.$width * 0.5} - #{variables.$gutter * 2}); + --bottom: calc(100% - var(--height)); + padding: var(--height) 0 variables.$gutter; + position: relative; + transition: background .3s map.get(variables.$timing-functions, 'move'), + color .3s map.get(variables.$timing-functions, 'move'); + + &::after { + --scale: calc((100% - (var(--y) * 1px)) / var(--y)); + background: repeating-linear-gradient( + to bottom, + white 0 var(--scale), + rgba(0, 0, 0, .25) calc(var(--scale) + 1px) + ); + bottom: var(--bottom); + content: ""; + position: absolute; + top: 0; + width: 100%; + z-index: 1; + } + + tr::before { + content: ""; + position: absolute; + } + + [scope="row"], + thead th:first-child { + color: var(--color, currentColor); + text-align: left; + } + + [style]::before { + bottom: var(--bottom); + background: linear-gradient(to top, functions.palette(secondary, light), functions.palette(alert) 75%); + --polygon: polygon( + 0% 100%, + calc((100% / var(--x) * 1)) 100%, + calc((100% / var(--x) * 1)) calc(100% - (var(--1) / var(--y) * 100%)), + calc((100% / var(--x) * 1) + var(--offset)) calc(100% - (var(--1) / var(--y) * 100%)), + calc((100% / var(--x) * 2) + var(--offset)) calc(100% - (var(--2) / var(--y) * 100%)), + calc((100% / var(--x) * 3) + var(--offset)) calc(100% - (var(--3) / var(--y) * 100%)), + calc((100% / var(--x) * 4) + var(--offset)) calc(100% - (var(--4) / var(--y) * 100%)), + calc((100% / var(--x) * 5) + var(--offset)) calc(100% - (var(--5) / var(--y) * 100%)), + calc((100% / var(--x) * 6) + var(--offset)) calc(100% - (var(--6) / var(--y) * 100%)), + calc((100% / var(--x) * 7) + var(--offset)) calc(100% - (var(--7) / var(--y) * 100%)), + calc((100% / var(--x) * 8) + var(--offset)) calc(100% - (var(--8) / var(--y) * 100%)), + calc((100% / var(--x) * 9) + var(--offset)) calc(100% - (var(--9) / var(--y) * 100%)), + calc((100% / var(--x) * 10) + var(--offset)) calc(100% - (var(--10) / var(--y) * 100%)), + calc((100% / var(--x) * 11) + var(--offset)) calc(100% - (var(--11) / var(--y) * 100%)), + calc((100% / var(--x) * 12) + var(--offset)) calc(100% - (var(--12) / var(--y) * 100%)), + 100% calc(100% - (var(--12) / var(--y) * 100%)), + 100% 100%, + 0% 100% + ); + clip-path: var(--polygon); + content: ""; + position: absolute; + top: 0; + width: 100%; + z-index: 2; + } + + th, + td { + background: functions.palette(default, contrast); + font-weight: bold; + text-align: center; + width: calc(100% / var(--x)); + } + + [scope="col"] { + &:not(:first-child)::after { + background: functions.palette(default, contrast) var(--stripes); + background-blend-mode: exclusion; + bottom: variables.$gutter * 4; + content: ""; + height: calc(100% - #{variables.$gutter * 4}); + left: calc(100% / var(--x) * var(--index)); + mix-blend-mode: soft-light; + opacity: 0; + position: absolute; + transition: opacity .3s map.get(variables.$timing-functions, 'move'); + width: inherit; + z-index: 3; + } + + @each $number in 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 { + &:nth-child(#{$number})::after { + --index: #{$number - 1}; + } + } + + &:hover::after { + opacity: .75; + } + } + + td { + --value: var(--1); + --term: var(--t-1); + line-height: 1.5; + + &::before { + content: ""; + height: 1.5rem; + position: absolute; + transform: translateX(-50%); + width: inherit; + z-index: 10; + } + + /** + * 1. + * @note Using white-space and: + ** `\A` to make a line-break + ** `\A0` for a non-breakable space + * @note Based on CSS Secrets by + * @author Lea Verou + * @link https://lea.verou.me/2012/02/flexible-multiline-definition-lists-with-2-lines-of-css/ + * + * 2. + * @note Display CSS integers custom properties with a trick using counters + * @author Cassie Evans + * @link https://codepen.io/cassie-codes/pen/22ea69e0f681d45f2f4c2ca5e6acf4ab + * + * 3. + * @note We need to ensure our counter uses an integer, --value might a a floating number + * @author Carter Li + * @link https://css-tricks.com/animating-number-counters/#the-new-school-css-solution + */ + &::after { + --arrow: calc(100% - #{variables.$gutter * 0.25}); + --top: calc(var(--height) - (var(--value) / var(--y) * var(--height))); + --polygon: polygon( + 0% 0%, + 100% 0%, + 100% var(--arrow), + calc(50% - #{variables.$gutter * 0.25}) var(--arrow), + 50% 100%, + calc(50% + #{variables.$gutter * 0.25}) var(--arrow), + 0% var(--arrow) + ); + --integer: calc(var(--value)); // 3 + background-color: functions.palette(dominant); + clip-path: var(--polygon); + color: functions.palette(dominant, contrast); + content: var(--term) " " var(--year) "\A " counter(value) "\A0" var(--unit); // 1 + counter-reset: value var(--integer); // 2, 3 + opacity: 0; + padding: variables.$gutter * 0.5; + left: calc(var(--offset) * 3); + pointer-events: none; + position: absolute; + top: var(--top, 0); + transform-origin: 50% calc(100% + 10px); + transform: translate3d(-50%, -125%, 0) perspective(1000px) rotate3d(1, 0, 0, 45deg); + transition: opacity .2s map.get(variables.$timing-functions, 'enter'), + transform .2s map.get(variables.$timing-functions, 'enter'); + white-space: pre; + z-index: 5; + } + + + td::after { + left: calc((100% / var(--x) * var(--index)) + var(--offset)); + } + + @each $number in 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 { + &:nth-child(#{$number})::after { + --value: var(--#{$number - 1}); + --term: var(--t-#{$number - 1}); + --index: #{$number - 1}; + } + } + + &:hover::after { + opacity: 1; + transform: translate3d(-50%, -125%, 0) perspective(1000px) rotate3d(1, 0, 0, 0deg); + transition: opacity .2s map.get(variables.$timing-functions, 'exit'), + transform .2s map.get(variables.$timing-functions, 'exit'); + } + } + } + + .chaarts.points { + [style] { + &::before { + background: var(--color, currentColor) var(--background); + --polygon: polygon( + calc((100% / var(--x) * 1) + var(--offset)) calc(100% - (var(--1) / var(--y) * 100%)), + calc((100% / var(--x) * 2) + var(--offset)) calc(100% - (var(--2) / var(--y) * 100%)), + calc((100% / var(--x) * 3) + var(--offset)) calc(100% - (var(--3) / var(--y) * 100%)), + calc((100% / var(--x) * 4) + var(--offset)) calc(100% - (var(--4) / var(--y) * 100%)), + calc((100% / var(--x) * 5) + var(--offset)) calc(100% - (var(--5) / var(--y) * 100%)), + calc((100% / var(--x) * 6) + var(--offset)) calc(100% - (var(--6) / var(--y) * 100%)), + calc((100% / var(--x) * 7) + var(--offset)) calc(100% - (var(--7) / var(--y) * 100%)), + calc((100% / var(--x) * 8) + var(--offset)) calc(100% - (var(--8) / var(--y) * 100%)), + calc((100% / var(--x) * 9) + var(--offset)) calc(100% - (var(--9) / var(--y) * 100%)), + calc((100% / var(--x) * 10) + var(--offset)) calc(100% - (var(--10) / var(--y) * 100%)), + calc((100% / var(--x) * 11) + var(--offset)) calc(100% - (var(--11) / var(--y) * 100%)), + calc((100% / var(--x) * 12) + var(--offset)) calc(100% - (var(--12) / var(--y) * 100%)), + calc((100% / var(--x) * 13) + var(--offset)) calc(100% - (var(--12) / var(--y) * 100%)), + 100% calc(100% - (var(--12) / var(--y) * 100%)), + 100% calc((100% + #{variables.$gutter * 0.25}) - (var(--12) / var(--y) * 100%)), + calc((100% / var(--x) * 13) + var(--offset)) calc((100% + #{variables.$gutter * 0.25}) - (var(--12) / var(--y) * 100%)), + calc((100% / var(--x) * 12) + var(--offset)) calc((100% + #{variables.$gutter * 0.25}) - (var(--12) / var(--y) * 100%)), + calc((100% / var(--x) * 11) + var(--offset)) calc((100% + #{variables.$gutter * 0.25}) - (var(--11) / var(--y) * 100%)), + calc((100% / var(--x) * 10) + var(--offset)) calc((100% + #{variables.$gutter * 0.25}) - (var(--10) / var(--y) * 100%)), + calc((100% / var(--x) * 9) + var(--offset)) calc((100% + #{variables.$gutter * 0.25}) - (var(--9) / var(--y) * 100%)), + calc((100% / var(--x) * 8) + var(--offset)) calc((100% + #{variables.$gutter * 0.25}) - (var(--8) / var(--y) * 100%)), + calc((100% / var(--x) * 7) + var(--offset)) calc((100% + #{variables.$gutter * 0.25}) - (var(--7) / var(--y) * 100%)), + calc((100% / var(--x) * 6) + var(--offset)) calc((100% + #{variables.$gutter * 0.25}) - (var(--6) / var(--y) * 100%)), + calc((100% / var(--x) * 5) + var(--offset)) calc((100% + #{variables.$gutter * 0.25}) - (var(--5) / var(--y) * 100%)), + calc((100% / var(--x) * 4) + var(--offset)) calc((100% + #{variables.$gutter * 0.25}) - (var(--4) / var(--y) * 100%)), + calc((100% / var(--x) * 3) + var(--offset)) calc((100% + #{variables.$gutter * 0.25}) - (var(--3) / var(--y) * 100%)), + calc((100% / var(--x) * 2) + var(--offset)) calc((100% + #{variables.$gutter * 0.25}) - (var(--2) / var(--y) * 100%)), + calc((100% / var(--x) * 1) + var(--offset)) calc((100% + #{variables.$gutter * 0.25}) - (var(--1) / var(--y) * 100%)) + ); + transition: opacity .3s map.get(variables.$timing-functions, 'move'); + } + + th::before { + background: var(--color, currentColor) var(--background); + content: ""; + display: inline-block; + height: 1rem; + transform: translate3d(-.2rem, .1rem, 0); + width: 1rem; + } + + td { + &::before { + --size: #{variables.$gutter}; + --top: calc(var(--height) - (var(--value) / var(--y) * var(--height))); + background: var(--color, currentColor) var(--background); + border: 2px solid functions.palette(default, contrast); + border-radius: 50%; + box-shadow: 0 0 #{variables.$gutter * 0.25} rgba(0, 0, 0, .5); + content: ""; + height: var(--size); + left: calc(var(--offset) * 3); + position: absolute; + top: var(--top, 100); + transform: translate3d(calc(var(--size) / -2), calc(var(--size) / -2), 0); + transition: opacity .3s map.get(variables.$timing-functions, 'move'), + transform .3s map.get(variables.$timing-functions, 'move'); + width: var(--size); + z-index: 4; + } + + + td::before { + left: calc((100% / var(--x) * var(--index)) + var(--offset)); + } + + @each $number in 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 { + &:nth-of-type(#{$number})::before { + --value: var(--#{$number}); + --index: #{$number}; + } + } + } + } + + @each $name, $pattern in variables.$patterns { + $i: list.index(variables.$patterns, ($name $pattern)); + + [style]:nth-child(#{$i}n + #{$i}) { + --background: var(--#{$name}); // 1 + } + } + + tbody:hover [style]::before, + tbody:hover [style] td::before { + opacity: .25; + } + + tbody:hover [style]:hover::before, + tbody:hover [style]:hover td::before { + opacity: 1; + } + + tbody:hover [style]:hover td::before { + transform: translate3d(calc(var(--size) / -2), calc(var(--size) / -2), 0) scale(1.25); + } + + [scope="col"]:not(:first-child) { + &::after { + mix-blend-mode: multiply; + } + + &:hover::after { + opacity: .5; + } + } + } + + @media screen and (-ms-high-contrast: active) { + .chaarts.line [style]::before { + /** + * @note Custom color palette for WHCM + * @note Inspired by Greg Whitworth's post + * @link http://www.gwhitworth.com/blog/2017/04/how-to-use-ms-high-contrast + */ + background: linear-gradient(to top, ButtonHighlight, Highlight 75%); + } + } +} diff --git a/src/_chaarts-pie.scss b/src/_chaarts-pie.scss new file mode 100644 index 0000000..dcc7a75 --- /dev/null +++ b/src/_chaarts-pie.scss @@ -0,0 +1,212 @@ +@use "sass:list"; +@use "sass:map"; +@use "abstracts/functions"; +@use "abstracts/mixins"; +@use "abstracts/variables"; + +/* ==================== */ +/* == Pie Charts +/* ==================== */ +@supports (clip-path: polygon( 50% calc( 50% + ( var(--gt-25, 0) ) ) )) { + .pie-container .fieldset { + display: flex !important; + margin-bottom: 0; + } + + .chaarts.pie { + --radius: 32em; + margin: 0 auto; + padding-top: calc(var(--radius) - #{variables.$gutter * 2}); + position: relative; + + tbody { + display: table-row; + } + + tr { + display: table-cell; + transition: opacity .3s map.get(variables.$timing-functions, 'move'); + } + + [scope="row"] { + padding-right: variables.$gutter * 0.5; + + &::before { + background: var(--color, currentColor) var(--background); + content: ""; + display: inline-block; + height: variables.$gutter; + transform: translate3d(-.2rem, .1rem, 0); + width: variables.$gutter; + } + } + + td { + --position: calc(var(--start, 0) * .01turn); + } + + td::after, + td::before { + left: 50%; + position: absolute; + top: calc(var(--radius) / 2); + transform-origin: center center; + } + + /** + * Using clip-path + calc() + transform + CSS vars + * Using mask-image to make a circle + * + * 1. + * @note Based on Ana Tudor's work + * @link https://css-tricks.com/1-html-element-5-css-properties-magic/ + * @author Ana Tudor + * + * 2. + * @note Using a Roma Komarov's idea about boolean custom properties + * @link https://www.kizu.ru/conditions-for-css-variables/ + * + * 3. + * @note Mask support: + * @link https://caniuse.com/#search=mask + */ + td::before { + --zoom: .75; + --part: calc(var(--value) * 3.6); + --main-angle: calc(var(--part) - (90 * (var(--gt-25, 0) + var(--gt-50, 0) + var(--gt-75, 0)))); + --β: calc(var(--main-angle) * 0.01745329251); + --α: calc((90 - var(--main-angle)) * 0.01745329251); + @include mixins.sin(β); + @include mixins.sin(α); + --pos-B: calc(var(--sin-β) * 50); + --pos-A: calc(var(--sin-α) * 50); + --polygon: polygon( + 50% 50%, + 50% 0%, + 100% 0%, + calc(50% + (var(--pos-B) * 1% * var(--lt-25, 1)) + (var(--gt-25, 0) * 50%)) calc(50% - (var(--pos-A) * 1% * var(--lt-25, 1))), + calc(50% + (var(--gt-25, 0) * 50%)) calc(50% + (var(--gt-25, 0) * 50%)), + calc(50% + (var(--pos-A) * 1% * var(--lt-50, 1)) + (var(--gt-50, 0) * 50%)) calc(50% + (var(--pos-B) * 1% * var(--lt-50, 1)) + (var(--gt-50, 0) * 50%)), + calc(50% - (var(--gt-50, 0) * 50%)) calc(50% + (var(--gt-50, 0) * 50%)), + calc(50% - (var(--pos-B) * 1% * var(--lt-75, 1)) - (var(--gt-75, 0) * 50%)) calc(50% + (var(--pos-A) * 1% * var(--lt-75, 1))), + calc(50% - (var(--gt-75, 0) * 50%)) calc(50% - (var(--gt-75, 0) * 50%)), + calc(50% - (var(--pos-A) * 1% * var(--gt-75, 0))) calc(50% - (var(--pos-B) * 1% * var(--gt-75, 0))), + 50% 50% + ); + background: var(--color, currentColor) var(--background); + clip-path: var(--polygon); + content: ''; + height: var(--radius); + --mask: radial-gradient( + circle at center, + #fff 0 calc(var(--radius) / 2), + transparent 0 + ); + mask-image: var(--mask); + transform: translate3d(-50%, -50%, 0) rotate(var(--position)) scale(var(--zoom)); + transition: transform .2s map.get(variables.$timing-functions, 'move'); + width: var(--radius); + } + + tr:hover td::before { + --zoom: .8; + } + + @each $name, $pattern in variables.$patterns { + $i: list.index(variables.$patterns, ($name $pattern)); + + tr:nth-child(#{$i}n + #{$i}) { + --background: var(--#{$name}); // 1 + } + } + + /** + * 1. + * @note Display CSS integers custom properties with a trick using counters + * @author Cassie Evans + * @link https://codepen.io/cassie-codes/pen/22ea69e0f681d45f2f4c2ca5e6acf4ab + * + * 2. + * @note We need to ensure our counter uses an integer, --value might a a floating number + * @author Carter Li + * @link https://css-tricks.com/animating-number-counters/#the-new-school-css-solution + */ + td::after { + --arrow: calc(100% - #{variables.$gutter * 0.25}); + --axis: calc(var(--position) - .25turn + var(--value) * .005turn); + --away: calc(var(--radius) / 2 - #{variables.$gutter}); + --integer: calc(var(--value)); // 2 + background-color: functions.palette(dominant); + color: functions.palette(dominant, contrast); + content: var(--term) "\A0: " counter(value) "\A0%"; // 1 + counter-reset: value var(--integer); // 1 + opacity: 0; + padding: variables.$gutter * 0.5; + pointer-events: none; + transform-origin: 50% calc(100% + 10px); + transform: translate3d(-50%, -50%, 0) rotate(var(--axis)) translate(var(--away)) rotate(calc(var(--axis) * -1)) perspective(1000px) rotate3d(1, 0, 0, 45deg); + transition: opacity .2s map.get(variables.$timing-functions, 'enter'), + transform .2s map.get(variables.$timing-functions, 'enter'); + } + + tbody:hover tr { + opacity: .5; + + &:hover { + opacity: 1; + } + + &:hover td::after { + opacity: 1; + transform: translate3d(-50%, -50%, 0) rotate(var(--axis)) translate(var(--away)) rotate(calc(var(--axis) * -1)) perspective(1000px) rotate3d(1, 0, 0, 0deg); + transition: opacity .2s map.get(variables.$timing-functions, 'exit'), + transform .2s map.get(variables.$timing-functions, 'exit'); + } + } + } + + .chaarts.polar { + td::before { + --zoom: 50; + transform: translate3d(-50%, -50%, 0) rotate(var(--position)) scale(calc((var(--zoom) + (var(--value) / (100 / var(--zoom)))) / 100)); + } + + td::after { + --away: calc((var(--radius) / 2) - ((var(--radius) / 4) * ((100 - var(--value)) / 100)) + #{variables.$gutter * 2.5}); + } + + tr:hover td::before { + --zoom: 50; + } + } + + .chaarts.donut { + --mask: radial-gradient( + circle at 50% calc(50% - #{variables.$gutter * 0.25}), + transparent 0 var(--offset), + #fff calc(var(--offset) + 1px) 100% + ); + mask-image: var(--mask); + + td::after { + --away: calc(var(--radius) / 2 - #{variables.$gutter * 2.5}); + } + } + + @media screen and (-ms-high-contrast: active) { + .chaarts.pie { + tbody tr *::before { + /** + * @note Custom color palette for WHCM + * @note Inspired by Greg Whitworth's post + * @link http://www.gwhitworth.com/blog/2017/04/how-to-use-ms-high-contrast + */ + background-color: Window; + } + + tbody tr:nth-of-type(odd) *::before { + background-color: WindowText; + } + } + } +} diff --git a/src/_chaarts-radar.scss b/src/_chaarts-radar.scss new file mode 100644 index 0000000..9f219d0 --- /dev/null +++ b/src/_chaarts-radar.scss @@ -0,0 +1,265 @@ +@use "sass:map"; +@use "abstracts/functions"; +@use "abstracts/mixins"; +@use "abstracts/variables"; + +/* ==================== */ +/* == Radar Charts +/* ==================== */ + +@use "sass:math"; + +@supports (clip-path: polygon(0% 0%, calc(100% - ( var(--1) * 100% / var(--scale) ) ) 100%, 100% 100%)) { + .radar-container .fieldset { + display: flex !important; + } + + .chaarts[class*="radar"] { + --radius: #{variables.$width * 0.2}; + --unitless-radius: calc(1024 / 16 / 5); + --size: calc(var(--radius) / var(--scale)); + --part: calc(360deg / var(--items)); + --integer: calc(var(--scale)); + background-image: repeating-radial-gradient( + circle at 50%, + rgba(0, 0, 0, .2) 0 2px, + transparent 0 calc(var(--size) * var(--step)) + ), + repeating-radial-gradient( + circle at 50%, + rgba(0, 0, 0, .1) 0 2px, + transparent 0 var(--size) + ); + border: 2px solid; + border-radius: 50%; + contain: layout; + counter-reset: scale var(--integer); + height: calc(var(--radius) * 2); + margin: variables.$gutter * 6 auto variables.$gutter * 12; + overflow: visible; + position: relative; + width: calc(var(--radius) * 2); + + caption { + background: none; + bottom: variables.$gutter * -10; + position: absolute; + } + + /** + * Placing items around a circle based on: + * @link https://stackoverflow.com/questions/12813573/position-icons-into-circle + * @link http://dabblet.com/gist/3866686 + * @author Ana Tudor + * + * @note Negative values for radius helps to start at the top left corner + */ + [scope="col"] { + --away: calc((var(--radius) * -1) - 50%); + left: 50%; + margin: 0; + padding: 0 variables.$gutter; + position: absolute; + top: 50%; + transform: translate3d(-50%, -50%, 0) rotate(calc(var(--part) * var(--index, 1))) translate(var(--away)) rotate(calc(var(--part) * var(--index, 1) * -1)); + } + + @each $number in 1, 2, 3, 4, 5, 6, 7 { + tr > *:nth-of-type(#{$number}) { + --index: #{$number}; + } + } + + /** + * This is quite sophisticated, we're mixing multiple techniques + * + * @note Setting items as parts of the circle: + * @link https://tympanus.net/codrops/2013/08/09/building-a-circular-navigation-with-css-transforms/ + * @author Sara Soueidan + * + * @note Because we skew items, clip-path() needs to take skew angle into account + * @note To do so, we need to know skewed width (which is hypothenuse of the resulting triangle) + * @note We only know two angles (skew one + suqare one) and a side (initial width), + * @note So we need to compute the sinus of the opposite angle to get hypothenuse + * @note Thanks god, Stereokai made trigonometry functions in pure CSS: + * + * @note Trigonometry functions based on: + * @link https://gist.github.com/stereokai/7666bfe93929b14c2dced148c79e0e97 + * @author Stereokai + */ + td { + --skew: calc(90deg - var(--part)); + border-bottom: 1px solid functions.palette(accent, light); + height: 50%; + left: 0; + margin: 0; + position: absolute; + top: 0; + transform: rotate(calc(var(--part) * var(--index, 1))) skew(var(--skew)); + transform-origin: 100% 100%; + width: 50%; + + @each $number in 1, 2, 3, 4, 5, 6, 7 { + &:nth-of-type(#{$number}) span { + --point: var(--#{$number}); + --pos: calc(100% - (var(--#{$number + 1}) * 100% / (var(--scale) * var(--ratio)))); + } + } + + &::after, + &::before { + display: none; + } + } + + span { + --opposite: calc(180 - (90 + (90 - (360 / var(--items))))); + // get opposite angle in radians + --angle: calc(var(--opposite) * 0.01745329251); + // calc() sin, dark wizardry! + @include mixins.sin(angle); + // calc() hypothenuse + --hypo: calc(var(--unitless-radius) / var(--sin-angle)); + // get the ratio: skewed / initial width + --ratio: calc(var(--hypo) / var(--unitless-radius)); + --polygon: polygon( + 100% var(--pos), + calc(100% - (var(--point) * 100% / var(--scale))) 100%, + 100% 100% + ); + background: linear-gradient( + to top left, + functions.palette(accent, light) 10%, + functions.palette(secondary, dark) 75% + ); + clip-path: var(--polygon); + filter: drop-shadow(0 0 variables.$gutter functions.palette(accent, dark)); + height: 100%; + position: absolute; + width: 100%; + } + } + + /** + * 1. + * @note Display CSS integers custom properties with a trick using counters + * @author Cassie Evans + * @link https://codepen.io/cassie-codes/pen/22ea69e0f681d45f2f4c2ca5e6acf4ab + * + * 2. + * @note We need to ensure our counter uses an integer, --value might a a floating number + * @author Carter Li + * @link https://css-tricks.com/animating-number-counters/#the-new-school-css-solution + */ + .chaarts.radar [scope="col"] { + &::after { + color: functions.palette(accent); + display: block; + font-size: small; + font-weight: 400; + } + + @each $number in 1, 2, 3, 4, 5, 6, 7 { + &:nth-child(#{$number})::after { + --integer: calc(var(--#{$number})); // 2 + counter-reset: value var(--integer); // 1 + content: counter(value) "\A0/\A0" counter(scale); // 1 + } + } + } + + .chaarts.radar-multiple { + margin-bottom: variables.$gutter * 12; + + tbody { + columns: var(--areas); + vertical-align: bottom; + } + + [scope="row"] { + bottom: variables.$gutter * -8; + height: variables.$gutter * 2; + left: variables.$gutter; + position: absolute; + + &::before { + background: var(--color, currentColor); + content: ""; + display: inline-block; + height: variables.$gutter; + margin-right: variables.$gutter * 0.25; + transform: translate3d(0, .1rem, 0); + width: variables.$gutter; + } + } + + // Allowing more areas :) + @each $number in 1 { + tr:nth-child(#{$number + 1}) [scope="row"] { + left: calc(#{variables.$gutter} + (100% / var(--areas)) * #{$number}); + } + } + + td { + align-items: flex-end; + border-color: var(--color, currentColor); + display: flex; + justify-content: flex-end; + opacity: .5; + pointer-events: none; + z-index: 0; + + &::after { + color: var(--color, currentColor); + display: block; + font-size: small; + font-weight: 700; + text-indent: #{math.div(variables.$gutter, -2)}; + transform: skew(calc(var(--skew) * -1)) rotate(calc(var(--part) * var(--index, 1) * -1)); + transform-origin: 0 0; + width: 100%; + white-space: nowrap; + } + + @each $number in 1, 2, 3, 4, 5, 6, 7 { + &:nth-of-type(#{$number})::after { + --integer: calc(var(--#{$number})); // 2 + counter-reset: value var(--integer); // 1 + content: counter(value); // 1 + width: calc(var(--#{$number}) * 100% / var(--scale)); + } + } + } + + span { + background: var(--color, currentColor); + pointer-events: auto; + + @supports (mask-image: url()) { + --mask: radial-gradient(circle at bottom right, rgba(0, 0, 0, 1), rgba(0, 0, 0, .5)); + mask-image: var(--mask); + } + } + + @media (hover: hover) { + td { + opacity: .25; + transition: opacity .2s map.get(variables.$timing-functions, 'move'); + + &::after { + opacity: 0; + transition: inherit; + } + } + + tr:hover td { + opacity: 1; + z-index: 1; + + &::after { + opacity: inherit; + } + } + } + } +} diff --git a/src/abstracts/_functions.scss b/src/abstracts/_functions.scss new file mode 100644 index 0000000..f04344a --- /dev/null +++ b/src/abstracts/_functions.scss @@ -0,0 +1,25 @@ +@use "sass:map"; +@use "sass:meta"; +@use "sass:string"; +@use "variables"; + +// ----------------------------- */ +// == Functions +// ----------------------------- */ + +// Color palette +// @note Allow to pick a color in defined color palette +// @author Tom Davies +// @see http://erskinedesign.com/blog/friendlier-colour-names-sass-maps/ +@function palette( $color, $tone: "base" ) { + @if (map.has-key(variables.$colors, $color)) { + @if (map.has-key(map.get(variables.$colors, $color), $tone)) { + @return map.get(map.get(variables.$colors, $color), $tone); + } @else { + @error "Biip ! `#{$tone}` is not a valid `#{$color}`'s variants."; + } + } @else { + @error "Biip ! `#{$color}` is not part of our palette…"; + } +} + diff --git a/src/abstracts/_mixins.scss b/src/abstracts/_mixins.scss new file mode 100644 index 0000000..45154ee --- /dev/null +++ b/src/abstracts/_mixins.scss @@ -0,0 +1,8 @@ +@mixin sin($angle) { + --sin-term-#{$angle}-1: var(--#{$angle}); + --sin-term-#{$angle}-2: calc((var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle})) / 6); + --sin-term-#{$angle}-3: calc((var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle})) / 120); + --sin-term-#{$angle}-4: calc((var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle})) / 5040); + --sin-term-#{$angle}-5: calc((var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle}) * var(--#{$angle})) / 362880); + --sin-#{$angle}: calc(var(--sin-term-#{$angle}-1) - var(--sin-term-#{$angle}-2) + var(--sin-term-#{$angle}-3) - var(--sin-term-#{$angle}-4) + var(--sin-term-#{$angle}-5)); +} diff --git a/src/abstracts/_variables.scss b/src/abstracts/_variables.scss new file mode 100644 index 0000000..9177218 --- /dev/null +++ b/src/abstracts/_variables.scss @@ -0,0 +1,113 @@ +// ----------------------------- */ +// Table of contents +// ----------------------------- */ +// +// == Paths +// == Colors +// == Timing functions +// == Spacings +// == Patterns +// == Formage +// + +// ==================== */ +// == Paths +// ==================== */ +@use "sass:math"; + +$path: "../" !default; + +// ==================== */ +// == Colors +// ==================== */ +$colors: ( + dominant: ( + base: #444, + light: mediumblue, + dark: black, + contrast: white + ), + secondary: ( + base: mediumblue, + light: deepskyblue, + dark: DarkBlue, + contrast: white + ), + accent: ( + base: rebeccapurple, + light: blueviolet, + dark: indigo, + contrast: white + ), + alert: ( + base: crimson, + light: firebrick, + dark: #911, + contrast: white + ), + success: ( + base: springgreen, + light: palegreen, + dark: #01ac49, + contrast: #444 + ), + muted: ( + base: gray, + light: darkgray, + dark: #333, + contrast: black + ), + default: ( + base: dimgray, + light: lightgray, + dark: darkgrey, + secondary: whitesmoke, + contrast: white + ), + charts: ( + purple: #734bf9, + pink: #e11a81, + blue: #0172f0, + yellow: #fdc02f, + green: #39ca74, + red: #ff2d40, + gray: #585462 + ) +); + +// ==================== */ +// == Timing functions +// +// @note Simple cubic-bezier curves for timing functions +// @author David K. Piano +// @link https://twitter.com/DavidKPiano/status/965704092545900544 +// ==================== */ +$timing-functions: ( + enter: cubic-bezier(0, .5, .5, 1), + exit: cubic-bezier(.5, 0, 1, .5), + move: cubic-bezier(.5, 0, .5, 1) +); + +// ==================== */ +// == Spacings +// ==================== */ +$full-width: false !default; +$width: math.div(1024em, 16) !default; +$gutter: 1rem !default; +$content-width: math.div(600em, 16) !default; +$breakpoint: math.div(480em, 16) !default; + +// ==================== */ +// == Patterns +// +// @note SVG inline patterns coming from: +// @link http://www.heropatterns.com/ +// ==================== */ +$patterns: ( + "checkers": "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3E%3Cg fill='%23ffffff99'%3E%3Cpath fill-rule='evenodd' d='M0 0h4v4H0V0zm4 4h4v4H4V4z'/%3E%3C/g%3E%3C/svg%3E", + "hexagons": "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='24' viewBox='0 0 28 49'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23ffffff99' fill-rule='nonzero'%3E%3Cpath d='M13.99 9.25l13 7.5v15l-13 7.5L1 31.75v-15l12.99-7.5zM3 17.9v12.7l10.99 6.34 11-6.35V17.9l-11-6.34L3 17.9zM0 15l12.98-7.5V0h-2v6.35L0 12.69v2.3zm0 18.5L12.98 41v8h-2v-6.85L0 35.81v-2.3zM15 0v7.5L27.99 15H28v-2.31h-.01L17 6.35V0h-2zm0 49v-8l12.99-7.5H28v2.31h-.01L17 42.15V49h-2z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E", + "triangles": "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='16' viewBox='0 0 36 72'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23ffffff99'%3E%3Cpath d='M2 6h12L8 18 2 6zm18 36h12l-6 12-6-12z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E", + "zig": "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='12' viewBox='0 0 20 12'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23ffffff99'%3E%3Cpath d='M9.8 12L0 2.2V.8l10 10 10-10v1.4L10.2 12h-.4zm-4 0L0 6.2V4.8L7.2 12H5.8zm8.4 0L20 6.2V4.8L12.8 12h1.4zM9.8 0l.2.2.2-.2h-.4zm-4 0L10 4.2 14.2 0h-1.4L10 2.8 7.2 0H5.8z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E", + "stripes": "data:image/svg+xml,%3Csvg width='6' height='6' viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff99' fill-rule='evenodd'%3E%3Cpath d='M5 0h1L0 6V5zM6 5v1H5z'/%3E%3C/g%3E%3C/svg%3E", + "dots": "data:image/svg+xml,%3Csvg width='10' height='10' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23ffffff99' fill-rule='evenodd'%3E%3Ccircle cx='3' cy='3' r='3'/%3E%3Ccircle cx='13' cy='13' r='3'/%3E%3C/g%3E%3C/svg%3E" +); diff --git a/src/chaarts.scss b/src/chaarts.scss new file mode 100644 index 0000000..f3d5b1f --- /dev/null +++ b/src/chaarts.scss @@ -0,0 +1,184 @@ +/* ==================== */ +/* == Abstracts +/* ==================== */ +@use "sass:math"; +@use "sass:meta"; +@use "abstracts/functions"; +@use "abstracts/variables"; +@use "abstracts/mixins"; + +/* ==================== */ +/* == Convert to +/* ==================== */ +/** + * Using Houdini's @property to ensure --integer is type in Chromium-based browsers + * @link https://developer.mozilla.org/en-US/docs/Web/CSS/@property + * @link https://caniuse.com/mdn-css_at-rules_property + ** Based on: + ** @author Carter Li + ** @link https://css-tricks.com/animating-number-counters/#the-new-school-css-solution + */ +//noinspection ALL +@property --integer { + syntax: ""; + initial-value: 0; + inherits: false; +} + +/* ==================== */ +/* == Tables +/* ==================== */ +table { + border-collapse: collapse; + caption-side: top; + font-feature-settings: "tnum"; + margin-bottom: variables.$gutter * 1.5; + width: 100%; + vertical-align: top; + + > caption:first-child { + font-style: italic; + margin: 0; + padding: math.div(40rem, 16) variables.$gutter; + } +} + +th, +td { + padding: math.div(variables.$gutter, 2) math.div(12rem, 16); + text-align: left; +} + +th, +table strong { + color: functions.palette(dominant, dark); +} + +td { + line-height: 1.25; + max-width: 100%; +} + +tbody { + border: 1px solid functions.palette(default); +} + +thead { + border: 1px solid functions.palette(dominant, dark); +} + +/* ==================== */ +/* == Charts +/* ==================== */ +/** + * Gives scrollable table some UX hints with shadows + * @author Chen Hui Jing + * @link https://codepen.io/huijing/pen/XBGaNQ + ** Based on: + ** @author Lea Verou + ** @link http://lea.verou.me/2012/04/background-attachment-local/ + */ +.table-container { + background: linear-gradient(to right, rgba(255, 255, 255, 1) 30%, rgba(255, 255, 255, 0)), + linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 70%) 0 100%, + radial-gradient(farthest-side at 0% 50%, rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)), + radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)) 0 100%; + background-repeat: no-repeat; + background-color: functions.palette(default, contrast); + background-size: 2.5rem 100%, 2.5rem 100%, 1rem 100%, 1rem 100%; + background-position: 0 0, 100%, 0 0, 100%; + background-attachment: local, local, scroll, scroll; + margin: variables.$gutter * 2 0; + max-width: 100%; + overflow-x: auto; + overflow-y: hidden; +} + +.table-container .fieldset { + display: none !important; + padding: 0 variables.$gutter; +} + +[class*="chaarts"] { + [role="presentation"] { + display: none; + } + + abbr[title] { + border-bottom: 0; + font-size: small; + font-weight: normal; + text-transform: none; + } +} + +.chaarts { + caption-side: bottom; + empty-cells: hide; + margin: 1.5em auto; + overflow: hidden; + padding: 1em; + + /** + * @note Defining a CSS custom property for each inlined SVG pattern + * @author Trys Mudford + * @link https://www.trysmudford.com/blog/using-css-custom-properties/ + * @via Jeremy Keith + * @link https://adactio.com/journal/15075 + */ + @each $name, $pattern in variables.$patterns { + --#{$name}: url("#{$pattern}"); + } + + > caption:first-child { + background: inherit; + font-style: normal; + padding: variables.$gutter 0; + } +} + +table:not(.chaarts) .sr-only { + clip: auto !important; + clip-path: none !important; + height: auto !important; + overflow: visible !important; + position: static !important; + width: auto !important; + white-space: normal !important; +} + +@media screen and (min-width: variables.$breakpoint) { + .chaarts { + border-collapse: separate; + /** + * @note Trying to improve paint & layout performances + * @link https://developer.mozilla.org/fr/docs/Web/CSS/contain + */ + contain: content; + + /* + * @bugfix + * @affected Chromium + * @link https://bugs.chromium.org/p/chromium/issues/detail?id=939728 + */ + &:not([class*="radar"]) { + border-spacing: 0; + } + + th, + td { + border: 0; + padding: 0; + + &:empty { + display: none !important; + } + } + } + + @include meta.load-css("chaarts-bar"); + @include meta.load-css("chaarts-pie"); + @include meta.load-css("chaarts-line"); + @include meta.load-css("chaarts-column"); + @include meta.load-css("chaarts-radar"); +} diff --git a/src/scss/print.scss b/src/scss/print.scss deleted file mode 100644 index a39a2bc..0000000 --- a/src/scss/print.scss +++ /dev/null @@ -1,63 +0,0 @@ -@media print { - body > :not(main), - main > :not(.deck), - *:not(.card)::after, - *:not(.card)::before, { - display: none !important; - } - - html, - body, - body > * { - background: none !important; - } - - /** - * 1. No orphans - * 2. No widows - */ - p, - blockquote, - .deck .card { - orphans: 3; /* 1 */ - widows: 3; /* 2 */ - } - - /* @note Avoid random page break */ - ul, - ol, - blockquote, - .deck .card { - page-break-inside: avoid; - break-inside: avoid; - } - - h1, - h2, - h3, - h4, - h5, - h6, - caption { - page-break-after: avoid; - } - - /** - * @note Display links' target, except for images - */ - a::after { - content: " (" attr(href) ") "; - display: inline-block !important; - } - - /* Hide anchors' target */ - a::after img, - a[href^="#"]::after, - a[href^="javascript"]::after { - content: ""; - } - - abbr::after { - content: " (" attr(title) ") "; - } -} diff --git a/src/scss/styles.scss b/src/scss/styles.scss deleted file mode 100644 index 0171482..0000000 --- a/src/scss/styles.scss +++ /dev/null @@ -1,24 +0,0 @@ -@charset "UTF-8"; - -/* ==================== */ -/* == Vendors -/* ==================== */ -@import "sseeeedd/src/scss/styles"; -@import "vendors/prism"; - -.mb-0 { - margin-bottom: 0 !important; -} - -.pb-0 { - padding-bottom: 0 !important; -} - -.fly-out [rel]::before { - content: "\1F30D\A0"; -} - -/* ==================== */ -/* == Chaarts -/* ==================== */ -@import "../../sass/chaarts"; diff --git a/src/templates/accueil.html b/src/templates/accueil.html deleted file mode 100644 index 39ef6be..0000000 --- a/src/templates/accueil.html +++ /dev/null @@ -1,203 +0,0 @@ -{% extends "index.html" %} - -{% block lang %}fr{% endblock %} - -{% block meta %} - chaarts - - - - - - -{% endblock %} - -{% block skiplinks %} - -{% endblock %} - -{% block label %}Navigation principale{% endblock %} - -{% block navigation %} - -{% endblock %} - -{% block main %} -

    Graphiques

    - -

    - Les différentes versions de graphiques présentées pour le moment reposent uniquement - sur un balisage sémantique — à base de <table> — - et une tartine de variables CSS portées par les balises. - Aucun JavaScript n’est requis pour l’affichage, et les styles sont - améliorés progressivement selon les capacités de votre navigateur. -

    - -

    - Note : en vertu du caractère expérimental - de ces techniques et d’une fondation solide améliorée progressivement, - je ne précise pas le support navigateur de chaque exemple — mais - il va de soi que ce n’est pas magique, et que seuls les navigateurs modernes répondent à l’appel, - à l’exception notable de Edge - qui ne supporte pas (encore) clip-path. - Les autres navigateurs affichent un tableau correctement stylé, et c’est chouette. -

    - -

    L’accessibilité

    - -

    - Un effort conséquent a été porté à l’accessibilité. - Comme évoqué précédement, un balisage sémantique et structuré est un pré-requis - — mais ça ne suffit pas. Les CSS - sont appliqués aussi progressivement que possible, afin de garantir le meilleur affichage - possible des données pour chaque internaute. -

    - -

    Tableau accessible

    - -

    Piqure de rappel :

    - -
      -
    • un tableau doit démarrer par un <caption> ;
    • -
    • - les cellules d’en-tête <th> doivent porter un attribut scope, - avec une valeur row ou col selon le cas ; -
    • -
    • - et vous aurez généralement besoin de distinguer l’entête du corps grâce à - <thead> et <tbody> ; -
    • -
    • - pour les valeurs disposant d’une unité : si vous vous aventurez à utiliser l’élement - <abbr> pour utiliser sa version abrégée, pensez à doubler l’attribut - title avec l’attribut aria-label — cela en améliorera - considérablement l’intérêt pour de nombreux internautes. -
    • -
    - -

    - Pour d’autres astuces utiles, je vous recommande chaleureusement la lecture - du - composant inclusif Data Tables de Heydon Pickering, - qui est une véritable mine d’or. -

    - -

    Motifs

    -

    - Pour distinguer les différentes zones autrement que par la couleur, un motif - svg - est appliqué en - css - — vous en trouverez quelques-uns sur le site - Hero Patterns : -

    -
      -
    1. - afin d’améliorer le mélange avec les couleurs ou dégradés d’arrière-plan, la propriété - background-blend-mode est utilisée avec la valeur hard-light ; -
    2. -
    3. - les tailles et positions du motif dépendent directement de la valeur et de l’échelle du graphique, - selon le type de graphique ; -
    4. -
    5. - pour ne pas embarquer trop de fichiers externes, on utilise - une technique - proposée par Trys Mudford pour inclure nos - svg - en data URi dans une variable - css chacun ; - ainsi, une liste finie de motifs est utilisée dans le thème, sans jamais répéter le svg. -
    6. -
    - -
    -

    Qu’encoder ?

    -

    - Taylor Hunt - a rédigé un article complet sur l’optimisation des - svg - passés en data URi. En résumé, seuls les chevrons et le - caractère « # » ont besoin d’être encodés dans le - css. - Ne vous fatiguez pas avec les autres caractères, leur encodage nuit sérieusement à la lisibilité. -

    -
    - - {% include 'includes/_svg-encoding.html' %} - -

    Respect des préférences

    -

    - Afin de respecter autant que possible les préférences des visiteurs, - de nombreux éléments ont été adaptés : -

    -
      -
    1. - les dimensions sont en unités relatives (em ou rem selon les cas), - afin de s’ajuster de manière cohérente au corps de texte hérité du navigateur et de pouvoir - être agrandi ou réduit sans perte ; -
    2. -
    3. - les couleurs sont adaptées lorsque le mode de contrastes élevés de Windows est détecté à l’aide de - -ms-high-contrast: active, inspiré par - - l’article de Greg Whitworth sur le sujet. Je vous conseille d’ailleurs - - l’increvable page Test of System Colors Specified in CSS 2 rédigée - par Ian Graham, éditée en… 2000 ! -
    4. -
    5. - les animations et transitions sont désactivées lorsque le système - expose cette préférence grâce à prefers-reduced-motion: reduce ; -
    6. -
    7. - les effets de survol dont l’état initial consiste à masquer du contenu - sont activés contextuellement dans la requête média @media (hover: hover) { … }. -
    8. -
    - -

    display et sémantique

    -

    - Adrian Roselli explique que jouer avec le display d’un élément - <table> ou <dl> met en péril sa sémantique. - Cette dernière est donc « verrouillée » à l’aide des rôles - aria - dédiés — comme il l’explique - dans un article détaillé. -

    -

    - C’est pourquoi chaque tableau est précédé d’un interrupteur — basé sur - le composant inclusif - conçu par Heydon Pickering — - dont le seul et unique rôle est de désactiver les styles supplémentaires : -

    - - {% include 'includes/_inclusive-toggle.html' %} - -

    - Voilà, nous sommes prêts à entrer dans le vif du sujet.
    - Faites chauffer votre inspecteur ! -

    -{% endblock %} diff --git a/src/templates/bar-charts.html b/src/templates/bar-charts.html deleted file mode 100644 index fd7baa6..0000000 --- a/src/templates/bar-charts.html +++ /dev/null @@ -1,185 +0,0 @@ -{% extends "index.html" %} - -{% block meta %} - Bar charts — chaarts - - - - - - -{% endblock %} - -{% block navigation %} - -{% endblock %} - -{% block main %} -

    Bar charts

    - -

    - This type of graph is used to represent one-dimensional data - (in our example, a timeline). - It's based on CSS grids and custom properties, - a technique inspired by - an article by Miriam Suzanne on - CSS Tricks - with a slight enhancement to improve accessibility. - Here's how to use it: -

    - -
      -
    1. - On the table itself, the --scale custom property is used to define the maximum value for the graph, - in order to determine its scale. Concretely, a grid will be generated with: - -
    2. -
    3. - On each cell <td>, a --value custom property - allows to place it on the grid, applied to grid-column-end. - Moreover, thanks to clever calculations based on this value, the background gradient is sized - and positioned to reflect the proportion represented by this value on the given scale - (from green for almost nothing to red for almost everything). -
    4. -
    5. - In each cell, the content must include the value and its unit in a - <span> element, possibly tagged with <abbr> - (and aria-label to complement title) if a title can explicit the unit. - This value is pushed to the right of the grid, and its text serves as a mask for the background - gradient — thanks to S. Shaw's trick to - apply background-clip: text as a progressively enhancement — allowing it to be the - corresponding color at the end of the gradient for the given position. -
    6. -
    - - {% import 'macros/_table-bar.html' as table %} -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - {{ table.bar('Time: backend', '4', 'ms', 'Millisecond', 'table') }} - {{ table.bar('Time: Frontend', '96', 'ms', 'Millisecond', 'table') }} - {{ table.bar('Delay: first byte', '102', 'ms', 'Millisecond', 'table') }} - {{ table.bar('Delay: last byte', '129', 'ms', 'Millisecond', 'table') }} - {{ table.bar('Delay: first image', '188', 'ms', 'Millisecond', 'table') }} - {{ table.bar('Delay: first CSS', '194', 'ms', 'Millisecond', 'table') }} - {{ table.bar('Delay: first JS', '326', 'ms', 'Millisecond', 'table') }} - {{ table.bar('DOM Interactive', '836', 'ms', 'Millisecond', 'table') }} - {{ table.bar('DOM loading', '836', 'ms', 'Millisecond', 'table') }} - {{ table.bar('DOM complete', '2561', 'ms', 'Millisecond', 'table') }} - {{ table.bar('HTTP traffic completed', '2980', 'ms', 'Millisecond', 'table') }} - -
    Loading time for ffoodd.fr
    Cumulative loading time
    -
    - -
    - HTML -
    {% include 'includes/_bar-markup.html' %}
    -
    -
    - css -
    {% include 'includes/_bar-styles.html' %}
    -
    - -

    Waterfall

    - -

    - The principle is the same for this variant, except for one detail: we also manage - the starting point for each measurement - — which is, very simply, the value of the previous point… - However, all the values must be passed as variables on the parent <table>. -

    - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - {{ table.bar('Time: backend', '4', 'ms', 'Millisecond', 'waterfall') }} - {{ table.bar('Time: Frontend', '96', 'ms', 'Millisecond', 'waterfall') }} - {{ table.bar('Delay: first byte', '102', 'ms', 'Millisecond', 'waterfall') }} - {{ table.bar('Delay: last byte', '129', 'ms', 'Millisecond', 'waterfall') }} - {{ table.bar('Delay: first image', '188', 'ms', 'Millisecond', 'waterfall') }} - {{ table.bar('Delay: first CSS', '194', 'ms', 'Millisecond', 'waterfall') }} - {{ table.bar('Delay: first JS', '326', 'ms', 'Millisecond', 'waterfall') }} - {{ table.bar('DOM interactive', '836', 'ms', 'Millisecond', 'waterfall') }} - {{ table.bar('DOM loading', '836', 'ms', 'Millisecond', 'waterfall') }} - {{ table.bar('DOM complete', '2561', 'ms', 'Millisecond', 'waterfall') }} - {{ table.bar('HTTP traffic completed', '2980', 'ms', 'Millisecond', 'waterfall') }} - -
    Loading time for ffoodd.fr
    Cumulative loading time
    -
    - -
    - HTML -
    {% include 'includes/_waterfall-markup.html' %}
    -
    -
    - css -
    {% include 'includes/_waterfall-styles.html' %}
    -
    -{% endblock %} diff --git a/src/templates/barres.html b/src/templates/barres.html deleted file mode 100644 index 8ac3a5a..0000000 --- a/src/templates/barres.html +++ /dev/null @@ -1,184 +0,0 @@ -{% extends "accueil.html" %} - -{% block meta %} - Graphiques en barre — chaarts - - - - - - -{% endblock %} - -{% block navigation %} - -{% endblock %} - -{% block main %} -

    Graphique en barre

    - -

    - Ce type de graphique sert à représenter des données à une dimension - (dans notre exemple, une ligne de temps). - Il repose sur les grilles et les variables CSS, - technique inspirée - d’un article de Miriam Suzanne sur - CSS Tricks - légèrement agrémentée pour en améliorer l’accessibilité. - Pour vous en servir, c’est simple : -

    - -
      -
    1. - Sur le tableau, une variable --scale permet de définir la valeur maximale du graphique, - afin d’en déterminer l’échelle. Concrètement, une grille va être générée avec : - -
    2. -
    3. - Sur chaque cellule <td>, une variable --value permet de la placer sur la grille, - appliquée à grid-column-end. - De plus grâce à de savants calculs reposant sur cette valeur, le dégradé en arrière-plan est dimensionné et positionné de façon à - refléter la proportion représentée par cette valeur sur l’échelle donnée (du vert pour presque rien au rouge pour presque tout). -
    4. -
    5. - Dans chaque cellule, le contenu doit reprendre la valeur et son unité dans un élément <span>, éventuellement - balisée avec <abbr> (et aria-label pour suppléer title) si un intitulé peut être explicité pour l’unité. - Cette valeur est poussée à droite de la grille, et son texte sert de masque pour le dégradé en arrière-plan - — grâce à une astuce de S. Shaw's pour - appliquer background-clip: text en amélioration progressive — lui permettant d’être de la couleur correspondante - à la fin du dégradé pour la position donnée. -
    6. -
    - - {% import 'macros/_table-bar.html' as table %} -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - {{ table.bar('Temps : backend', '4', 'ms', 'Milliseconde', 'table') }} - {{ table.bar('Temps : Frontend', '96', 'ms', 'Milliseconde', 'table') }} - {{ table.bar('Délai : premier octet', '102', 'ms', 'Milliseconde', 'table') }} - {{ table.bar('Délai : dernier octet', '129', 'ms', 'Milliseconde', 'table') }} - {{ table.bar('Délai : première image', '188', 'ms', 'Milliseconde', 'table') }} - {{ table.bar('Délai : premier CSS', '194', 'ms', 'Milliseconde', 'table') }} - {{ table.bar('Délai : premier JS', '326', 'ms', 'Milliseconde', 'table') }} - {{ table.bar('DOM Interactif', '836', 'ms', 'Milliseconde', 'table') }} - {{ table.bar('Chargement du DOM', '836', 'ms', 'Milliseconde', 'table') }} - {{ table.bar('DOM complet', '2561', 'ms', 'Milliseconde', 'table') }} - {{ table.bar('Trafic HTTP terminé', '2980', 'ms', 'Milliseconde', 'table') }} - -
    Temps de chargement pour ffoodd.fr
    Temps de chargement cumulé
    -
    - -
    - Le HTML -
    {% include 'includes/_bar-markup.html' %}
    -
    -
    - Le css -
    {% include 'includes/_bar-styles.html' %}
    -
    - -

    Graphique en chute d’eau

    - -

    - Le principe est le même pour cette variante, à un détail près : - on gère également le point de départ pour chaque mesure - — qui est, très simplement, la valeur du point précédent… - Il faut cependant passer toutes les valeurs en tant que variables sur - le parent <table>. -

    - -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - {{ table.bar('Temps : backend', '4', 'ms', 'Milliseconde', 'waterfall') }} - {{ table.bar('Temps : Frontend', '96', 'ms', 'Milliseconde', 'waterfall') }} - {{ table.bar('Délai : premier octet', '102', 'ms', 'Milliseconde', 'waterfall') }} - {{ table.bar('Délai : dernier octet', '129', 'ms', 'Milliseconde', 'waterfall') }} - {{ table.bar('Délai : première image', '188', 'ms', 'Milliseconde', 'waterfall') }} - {{ table.bar('Délai : premier CSS', '194', 'ms', 'Milliseconde', 'waterfall') }} - {{ table.bar('Délai : premier JS', '326', 'ms', 'Milliseconde', 'waterfall') }} - {{ table.bar('DOM Interactif', '836', 'ms', 'Milliseconde', 'waterfall') }} - {{ table.bar('Chargement du DOM', '836', 'ms', 'Milliseconde', 'waterfall') }} - {{ table.bar('DOM complet', '2561', 'ms', 'Milliseconde', 'waterfall') }} - {{ table.bar('Trafic HTTP terminé', '2980', 'ms', 'Milliseconde', 'waterfall') }} - -
    Temps de chargement pour ffoodd.fr
    Temps de chargement cumulé
    -
    - -
    - Le HTML -
    {% include 'includes/_waterfall-markup.html' %}
    -
    -
    - Le css -
    {% include 'includes/_waterfall-styles.html' %}
    -
    -{% endblock %} diff --git a/src/templates/camembert.html b/src/templates/camembert.html deleted file mode 100644 index b2fe184..0000000 --- a/src/templates/camembert.html +++ /dev/null @@ -1,667 +0,0 @@ -{% extends "accueil.html" %} - -{% block meta %} -Camemberts — chaarts - - - - - - -{% endblock %} - -{% block navigation %} - -{% endblock %} - -{% block main %} -

    Graphique en tarte

    - -

    - Le graphique en tarte sert pour les représentations de proportions en pourcentage. - Il s’appuie sur des variables CSS, un abus outrancier de calc(), - display: table-*, clip-path, mask-image, - transform et un tantinet de SVG - pour distinguer chaque zone. Oui, je sais rigoler. Comment qu’on s’en sert ? -

    - -
      -
    1. - Sur chaque entête <th>, une variable --color - permet d’attribuer, et bien… une couleur. -
    2. -
    3. - Puis chaque cellule <td> doit contenir la valeur et son unité, - ainsi qu’un attribut style pour porter quelques variables : -
        -
      1. - --value correspond à la valeur en pourcentage, - utile pour déterminer l’angle que doit occuper l’élément sur le cercle. - Tous les points du polygon() — servant à tracer la part du fromage - à l’aide de clip-path — dépendent de cette valeur (lire la note technique après l’exemple pour le détail - des calculs). -
      2. -
      3. - --start permet de définir le point de départ de l’arc - sur le cercle. Il s’agit de la somme des précédentes définitions, et est appliqué - à la fonction rotate() de la propriété transform. -
      4. -
      5. - Et enfin une série de variables booléennes valant chacune 0 ou 1 - — d’après une idée de - Roman Komarov dans son article "Conditions for CSS variables" — - dépendent de la valeur : --lt-25, --gt-25, --lt-50… - Elles permettent de faire basculer les points de leur position d’origine - (50% 50%) à leur position calculée, en s’additionnant ou se soustrayant - à la valeur initiale ; -
      6. -
      -
    4. -
    5. - un pseudo-élément ::before sur chaque cellule <td> est mis en forme - de savante manière en fonction de toutes nos variables, avec notamment transform, - clip-path et mask-image. - -
    6. -
    7. - un pseudo-élément ::after est utilisé pour simuler une infobulle, récapitulant - l’entête et la valeur de la cellule — l’affichage de propriétés personnalisées dans un pseudo-élément n’est pas si triviale : - -
    8. -
    9. - Et finalement un motif est appliqué sur l’arrière-plan, afin de mieux - l’associer visuellement avec la légende correspondante. -
    10. -
    - -{% import 'macros/_table-pie.html' as table %} - -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} - {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} - {{ table.pie('JS', '32', '%', '', '4', '#0172F0') }} - {{ table.pie('Json', '1', '%', '', '36', '#FDC02F') }} - {{ table.pie('Images', '44', '%', '', '37', '#39CA74') }} - {{ table.pie('Webfonts', '17', '%', '', '81', '#FF2D40') }} - {{ table.pie('Autres', '2', '%', '', '98', '#585462') }} - -
    Répartition du poids des ressources pour ffoodd.fr
    RessourceProportion
    -
    - -
    - Un peu de trigonométrie -
    -

    - Dans ce graphique, chaque portion représente un arc de cercle basé sur un angle (une partie de 360 degrés). - Pour définir la forme de cette portion, il faut donc placer un point sur le cercle. -

    -

    - Pour ce faire, je divise le cercle en quatre carrés. La position du point sur le cercle peut ainsi - être calculée en utilisant les propriétés du triangle rectangle formé par : -

    -
      -
    1. le centre du cercle,
    2. -
    3. le point que nous cherchons à positionner,
    4. -
    5. et le point perpendiculaire au rayon et passant par notre point cible.
    6. -
    -

    - Nous connaissons l’hypoténuse de ce triangle — le rayon du cercle —, - et l’angle formé par l’hypoténuse et partant du centre du cercle - (en ramenant la valeur sur 90 degrés, puisque le cercle est divisé en quatre secteurs carrés : - si la valeur est supérieure à 25 : moins 90°, etc.) - — plus un angle droit, bien entendu. -

    -

    La loi des sinus

    -

    - Nous pouvons donc utiliser la loi des sinus pour mesurer chaque côté, - et ainsi obtenir la position du point sur le cercle. - Cela implique de calculer le sinus… Fort heureusement, - Stereokai a implémenté pour nous - la représentation polynomiale de Taylor/Maclaurin en CSS — que j’ai implémentée sour forme d’un mixin : -

    - {% include 'includes/_sin-mixin.html' %} -

    - Il ne reste plus qu’à utiliser ces dimensions pour placer les points du polygône. - Un vrai jeu d’enfants ! -

    -
    -
    - Le HTML -
    {% include 'includes/_pie-markup.html' %}
    -
    -
    - Le css -
    -
    -   
    -@supports (clip-path: polygon( 50% calc( 50% + ( var(--gt-25, 0) ) ) )) {
    - .chaarts.pie {
    -   --radius: 32em;
    -   margin: 0 auto;
    -   padding-top: calc(var(--radius) - 2rem);
    -   position: relative;
    - }
    -
    - .chaarts.pie tbody {
    -   display: table-row;
    - }
    -
    - .chaarts.pie tr {
    -   display: table-cell;
    -   transition: opacity .3s cubic-bezier(.5, 0, .5, 1);
    - }
    -
    - .chaarts.pie [scope="row"] {
    -   padding-right: .5rem;
    - }
    -
    - .chaarts.pie [scope="row"]::before {
    -   background: var(--color, currentColor);
    -   content: "";
    -   display: inline-block;
    -   height: 1rem;
    -   transform: translate3d(-.2rem, .1rem, 0);
    -   width: 1rem;
    - }
    -
    - .chaarts.pie td {
    -   --position: calc(var(--start, 0) * .01turn);
    - }
    -
    - .chaarts.pie td::after,
    - .chaarts.pie td::before {
    -   left: 50%;
    -   position: absolute;
    -   top: calc(var(--radius) / 2);
    -   transform-origin: center center;
    - }
    -
    - .chaarts.pie td::before {
    -   /* L’inclinaison, pour se placer au bon endroit */
    -   --position: calc(var(--start, 0) * .01turn);
    -   --zoom: .75;
    -   /* L’angle représenté par la valeur : 3.6 = 360deg / 100 */
    -   /* Puisque nous utilisons une valeur en pourcentage */
    -   --part: calc( var(--value) * 3.6 );
    -   /* L’angle « utile » pour le calcul, nécessairement inférieur à 90deg */
    -   /* On soustrait donc 90deg (= ¼ × 360deg) par tranche de 25% (= ¼ × 100%, oui oui) */
    -   --main-angle: calc( var(--part) - ( 90 * ( var(--gt-25, 0) + var(--gt-50, 0) + var(--gt-75, 0) ) ) );
    -   /* L’angle principal, exprimé en radian */
    -   --β: calc( var(--main-angle) * 0.01745329251 );
    -   /* Le dernier angle en radian, par déduction puisque dans un triangle rectangle */
    -   --α: calc( ( 90 - var(--main-angle) ) * 0.01745329251 );
    -   /* La magie de Stereokai, pour obtenir le sinus de ces angles */
    -   --sin-term-β-1: var(--β);
    -   --sin-term-β-2: calc((var(--β) * var(--β) * var(--β)) / 6);
    -   --sin-term-β-3: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 120);
    -   --sin-term-β-4: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 5040);
    -   --sin-term-β-5: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 362880);
    -   --sin-β: calc(var(--sin-term-β-1) - var(--sin-term-β-2) + var(--sin-term-β-3) - var(--sin-term-β-4) + var(--sin-term-β-5));
    -   --sin-term-α-1: var(--α);
    -   --sin-term-α-2: calc((var(--α) * var(--α) * var(--α)) / 6);
    -   --sin-term-α-3: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 120);
    -   --sin-term-α-4: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 5040);
    -   --sin-term-α-5: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 362880);
    -   --sin-α: calc(var(--sin-term-α-1) - var(--sin-term-α-2) + var(--sin-term-α-3) - var(--sin-term-α-4) + var(--sin-term-α-5));
    -   /* Enfin, la position exprimée en % de l’hypothénuse, et divisée par 2 pour s’inscrire dans ¼ du cercle
    -    * soit après simplification, divisé par 50 */
    -   --pos-B: calc( var(--sin-β) * 50 );
    -   --pos-A: calc( var(--sin-α) * 50 );
    -   background-color: var(--color, currentColor) var(--background);
    -   --polygon: polygon(
    -     50% 50%,
    -     50% 0%,
    -     100% 0%,
    -     calc( 50% + ( var(--pos-B) * 1% * var(--lt-25, 1) ) + ( var(--gt-25, 0) * 50% ) ) calc( 50% - ( var(--pos-A) * 1% * var(--lt-25, 1) ) ),
    -     calc( 50% + ( var(--gt-25, 0) * 50% ) )                      calc( 50% + ( var(--gt-25, 0) * 50% ) ),
    -     calc( 50% + ( var(--pos-A) * 1% * var(--lt-50, 1) ) + ( var(--gt-50, 0) * 50% ) ) calc( 50% + ( var(--pos-B) * 1% * var(--lt-50, 1) ) + ( var(--gt-50, 0) * 50% ) ),
    -     calc( 50% - ( var(--gt-50, 0) * 50% ) )                      calc( 50% + ( var(--gt-50, 0) * 50% ) ),
    -     calc( 50% - ( var(--pos-B) * 1% * var(--lt-75, 1) ) - ( var(--gt-75, 0) * 50% ) ) calc( 50% + ( var(--pos-A) * 1% * var(--lt-75, 1) ) ),
    -     calc( 50% - ( var(--gt-75, 0) * 50% ) )                      calc( 50% - ( var(--gt-75, 0) * 50% ) ),
    -     calc( 50% - ( var(--pos-A) * 1% * var(--gt-75, 0) ) )               calc( 50% - ( var(--pos-B) * 1% * var(--gt-75, 0) ) ),
    -     50% 50%
    -   );
    -   clip-path: var(--polygon);
    -   content: '';
    -   height: var(--radius);
    -   --mask: radial-gradient(
    -     circle at center,
    -     white 0%,
    -     white calc(var(--radius)  / 2),
    -     transparent calc(var(--radius)  / 2)
    -   );
    -   mask-image: var(--mask);
    -   transform:
    -     translate3d(-50%, -50%, 0)
    -     rotate( var(--position) )
    -     scale( var(--zoom) );
    -   transition: transform .2s cubic-bezier(.5, 0, .5, 1);
    -   width: var(--radius);
    - }
    -
    - .chaarts.pie tr:hover td::before {
    -   --zoom: .8;
    - }
    -
    - .chaarts.pie tr:nth-child(2n + 2) *::before {
    -   --background: var(--stripes);
    - }
    -
    - .chaarts.pie td::after {
    -   --arrow: calc(100% - .25rem);
    -   --axis: calc( var(--position) - .25turn + var(--value) * .005turn );
    -   --away: calc( var(--radius) / 2 - 1rem );
    -   --integer: calc(var(--value));
    -   background-color: #444;
    -   color: white;
    -   content: var(--term) "\A0: " counter(value) "\A0%";
    -   counter-reset: value var(--integer);
    -   opacity: 0;
    -   padding: .5rem;
    -   pointer-events: none;
    -   transform-origin: 50% calc(100% + 10px);
    -   transform:
    -     translate3d(-50%, -50%, 0)
    -     rotate( var(--axis) )
    -     translate( var(--away) )
    -     rotate( calc( var(--axis) * -1 ) )
    -     perspective(1000px)
    -     rotate3d(1, 0, 0, 45deg);
    -   transition:
    -     opacity .2s cubic-bezier(0, .5, .5, 1),
    -     transform .2s cubic-bezier(0, .5, .5, 1);
    - }
    -
    - .chaarts.pie tbody:hover tr {
    -   opacity: .75;
    - }
    -
    - .chaarts.pie tbody:hover tr:hover {
    -   opacity: 1;
    - }
    -
    - .chaarts.pie tbody:hover td::after {
    -   opacity: 1;
    -   transform:
    -     translate3d(-50%, -50%, 0)
    -     rotate( var(--axis) )
    -     translate( var(--away) )
    -     rotate( calc( var(--axis) * -1 ) )
    -     perspective(1000px)
    -     rotate3d(1, 0, 0, 0deg);
    -   transition:
    -     opacity .2s cubic-bezier(.5, 0, 1, .5),
    -     transform .2s cubic-bezier(.5, 0, 1, .5);
    - }
    -
    - @media screen and (-ms-high-contrast: active) {
    -   .chaarts.pie tr *::before {
    -     background-color: Window;
    -   }
    -
    -   .chaarts.pie tr:nth-of-type(odd) *::before {
    -     background-color: WindowText;
    -   }
    - }
    -}
    -  
    -
    -
    -
    - Le calcul tordu -

    Les positions du polygone

    -

    - L’utilisation de variables pseudo-booléennes rend ce calcul pseudo-algorithmique. - Démarrons par un pré-requis essentiel : le polygone étant un tracé fermé et CSS - n’étant pas magique, les points doivent pré-exister. - Spoiler, il nous faut onze points : -

    -
      -
    1. - L’axe initial, du centre vers le milieu en haut : 50% 50% - et 50% 0%. -
    2. -
    3. - Un point pour chaque angle aux extrémités : le premier est fixe, à - 100% 0% (en haut à droite) — puis chacun des autres angles - a deux états, atteint ou non. Quelques détails : -
        -
      • - Par exemple le point en bas à droite concerne - les valeurs entre 25% et 50% : si la valeur est inférieure à 25%, il doit - être au centre (pour ne pas gêner le tracé), et dans le cas contraire être - dans son coin. ce qui s’exprime ainsi : - calc( 50% + ( var(--gt-25, 0) * 50% ) ) calc( 50% + ( var(--gt-25, 0) * 50% ) )
        - Ainsi la valeur calculée sera 50% 50% si --gt-25 vaut 0, - et 100% 100% si --gt-25 vaut 1. -
      • -
      • - De plus, chaque angle a sa coordonnée cible : - 100% 100% pour en bas à droite, 0% 100% pour en bas à gauche, - 0% 0% pour en haut à gauche. Il faut donc tantôt soustraire et - tantôt ajouter 50% à la valeur intitiale 50% 50% - pour basculer sur le bon point. -
      • -
      -
    4. -
    5. - Un point pour chaque position possible par quart de cercle, correspondant à - chaque tranche de 25%. À l’instar des points aux angles, ces points doivent être au centre - s’ils ne sont pas utilisés. C’est là qu’on rigole le plus : -
        -
      • on part de 50%, auxquels on ajoute ou soustrait la suite du calcul ;
      • -
      • - on utilise enfin la position calculée — --pos-A - ou --pos-B selon le cas — qu’on convertit en pourcentages à l’aide de - * 1%, et qu’on rend inerte si la valeur est inférieure à la tranche concernée - grâce à * var(--lt-25, 1), par exemple.
        - - Remarquez le seconde valeur dans var(), qui est la valeur par défaut - si la variable n’est pas définie. Cool, non ? - -
      • -
      • - et finalement lorsque la tranche est dépassée, le point bascule vers - 0% ou 100% selon le cas. -
      • -
      -
    6. -
    7. - Et enfin, on referme le tracé en revenant au centre du cercle, - à 50% 50%. -
    8. -
    -

    C’est tout !

    -

    Les positions illustrées

    -

    - Ces captures d’écran — effectuées dans - l’éditeur de formes - des outils de développement de Firefox — - montrent les points du polygone dans les différents cas. Vous pouvez consulter pour chaque valeur citée - le polygone résolu pour clip-path — et constater le basculement des valeurs dynamiques d’une position à une autre. -

    -
      -
    • -
      -
      Exemple de rendu pour 44%
      -
      -
      - Tracé pour clip-path avec une valeur de 44% : six points visibles. -
      Capture d’écran du tracé pour 44%.
      -
      -
      - {% include 'includes/_pie-styles:44.html' %} -
      Code généré pour 44%.
      -
      -
      -
      -
    • -
    • -
      -
      Exemple de rendu pour 64%
      -
      -
      - Tracé pour clip-path avec une valeur de 64% : sept points visibles. -
      Capture d’écran du tracé pour 64%.
      -
      -
      - {% include 'includes/_pie-styles:64.html' %} -
      Code généré pour 64%.
      -
      -
      -
      -
    • -
    • -
      -
      Exemple de rendu pour 88%
      -
      -
      - Tracé pour clip-path avec une valeur de 88% : neuf points visibles. -
      Capture d’écran du tracé pour 88%.
      -
      -
      - {% include 'includes/_pie-styles:88.html' %} -
      Code généré pour 88%.
      -
      -
      -
      -
    • -
    -
    - -
    -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} - {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} - {{ table.pie('JS', '32', '%', '', '4', '#0172F0') }} - {{ table.pie('Images', '64', '%', '', '36', '#39CA74') }} -
    Exemple de tarte avec une valeur entre 50 et 75%
    RessourceProportion
    -
    - -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} - {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} - {{ table.pie('JS', '8', '%', '', '4', '#0172F0') }} - {{ table.pie('Images', '88', '%', '', '12', '#39CA74') }} - -
    Exemple de tarte avec une valeur supérieure à 75%
    RessourceProportion
    -
    -
    - -

    Donut

    - -

    - Sur l’élément <table>, on ajoute une variable --offset - qui permet de déterminer la dimension du trou du donut, - généré à l’aide de mask-image et radial-gradient(). - - Ana Tudor a réalisé de très nombreux exemples - d’utilisation des mask-* sur CodePen, jetez-y un œil ! -

    - -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} - {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} - {{ table.pie('JS', '32', '%', '', '4', '#0172F0') }} - {{ table.pie('Json', '1', '%', '', '36', '#FDC02F') }} - {{ table.pie('Images', '44', '%', '', '37', '#39CA74') }} - {{ table.pie('Webfonts', '17', '%', '', '81', '#FF2D40') }} - {{ table.pie('Autres', '2', '%', '', '98', '#585462') }} - -
    Répartition du poids des ressources pour ffoodd.fr
    RessourceProportion
    -
    - -
    - Le css -
    {% include 'includes/_donut-styles.html' %}
    -
    - -
    -

    Dégradé conique

    -

    - L’utilisation de conic-gradient() est prometteuse pour ce cas précis. - Vous en trouverez des exemples réalisés par Ana Tudor ou Léa Verou — qui a carrément rédigé la spécification, - et conçu un polyfill. - Cependant le support limité aux navigateurs basés sur WebKit est déprimant, et pose tout de même quelques questions - en matière d’accessibilité puisqu’on ne peut pas affecter un motif à chaque couleur du dégradé conique. -

    -
    - -

    Polaire

    - -

    - Pour cette déclinaison, on ne change presque rien : seulement la variable --zoom - et son implication dans la mise à l’échelle des portions à l’aide de scale(). -

    - -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} - {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} - {{ table.pie('JS', '32', '%', '', '4', '#0172F0') }} - {{ table.pie('Json', '1', '%', '', '36', '#FDC02F') }} - {{ table.pie('Images', '44', '%', '', '37', '#39CA74') }} - {{ table.pie('Webfonts', '17', '%', '', '81', '#FF2D40') }} - {{ table.pie('Autres', '2', '%', '', '98', '#585462') }} - -
    Répartition du poids des ressources pour ffoodd.fr
    RessourceProportion
    -
    - -
    - Le css -
    {% include 'includes/_polar-styles.html' %}
    -
    -{% endblock %} diff --git a/src/templates/column-charts.html b/src/templates/column-charts.html deleted file mode 100644 index f3bbf4e..0000000 --- a/src/templates/column-charts.html +++ /dev/null @@ -1,246 +0,0 @@ -{% extends "index.html" %} - -{% block meta %} - Column charts — chaarts - - - - - - -{% endblock %} - -{% block navigation %} - -{% endblock %} - -{% block main %} -

    Column charts

    - -

    - Column chart is used for value distributions. - The structure of the table is quite ordinary, but its formatting is based on - display: grid; and especially display: contents; to - facilitate the placement of the cells — technique inspired by - - Hidde De Vries's article More accessible markup with display: contents, - and clarified by - Ire Aderinokun's post How display: contents works. -

    - -

    The basic principle is the same as the bar charts:

    -
      -
    1. - the first grid row is the reserved to display value in case it reaches scale's max value, - with a fixed size of 2ex - — have a look to CSS - units rudiments, documented in Every Layout by Andy Bell and Heydon Pickering ; -
    2. -
    3. - the repeat() function applied with the --scale custom property - enables us to handle a dynamic scale; -
    4. -
    5. - <thead>, <tbody> and <tr> containers - are neutralized in the grid structure using display: contents; -
    6. - each cell is placed on the grid depending its --value - — its background color also depending on its value; -
    7. -
    8. - and finally its text value — wrapped in a <span> element — - is positioned at the top of the column using the same trick as in the bar chart. -
    9. -
    - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Browser market shares in France in January 2019
    BrowserChromeFirefoxSafariEdgeIEOthers
    Market shares62%15%9%5%6%3%
    -
    - -
    - HTML -
    {% include 'includes/_column-markup.html' %}
    -
    -
    - css -
    {% include 'includes/_column-styles.html' %}
    -
    - -

    Multiple columns

    - -

    - In order to have two values for each main column, we must also have - two subheadings. Concretely speaking: -

    - -
      -
    1. - we add a second row in <thead>: -
        -
      • - with two column header cells <th scope="col"> - for each column header cell in the first row; -
      • -
      • - remember to add colspan="2" on the first row's header cell - to match the new table layout; -
      • -
      • - and finally add an identifier to each header cell - to referenced them to the relevant data cells — using the - headers attribute, par exemple pour la première cellule: - headers="browser chrome year chrome-2018" where each value - is a header cell's identifier. -
      • -
      -
    2. -
    3. - Styles: -
        -
      • - the first-level header cells must span two columns of the grid, - as required by their colspan for the table layout. It is - unfortunately impossible to use an attribute value in another - property than content — otherwise we could simply write - grid-column: 2 / span attr(colspan);, and that would be awesome… -
      • -
      • - but no! Thus, a --span custom property is added on <table>, - and must match the colspan attributes values mentionned earlier: - it is therefore used to extend the first level headers to the appropriate number of columns. -
      • -
      • - Colors and patterns are no longer applied according to each value, - but according to each column — in the example, every second element - (since we have two entries per column). - Again, if we could use an attribute value or a custom property - in a selector, that would be great. Imagine - tbody td:nth-of-type(var(--span)n + var(--span)) or even - tbody td:nth-of-type(attr(colspan)n + attr(colspan))! -
      • -
      -
    4. -
    - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Browser market shares in France in January 2019
    BrowserChromeFirefoxSafariEdgeIE
    Year2018201920182019201820192018201920182019
    Market shares49.6%57%11.74%9.59%21.53%18.78%3.72%3.5%4.46%3.66%
    -
    - -
    - HTML -
    {% include 'includes/_columns-markup.html' %}
    -
    -
    - css -
    {% include 'includes/_columns-styles.html' %}
    -
    -{% endblock %} diff --git a/src/templates/courbe.html b/src/templates/courbe.html deleted file mode 100644 index c218d10..0000000 --- a/src/templates/courbe.html +++ /dev/null @@ -1,345 +0,0 @@ -{% extends "accueil.html" %} - -{% block meta %} - Courbes — chaarts - - - - - - -{% endblock %} - -{% block navigation %} - -{% endblock %} - -{% block main %} -

    Graphique linéaire

    - -

    Graphique de surface

    - -

    - Ce graphique repose sur les variables CSS, les grilles et clip-path. - Cette dernière propriété est la plus importante. -

    - -
      -
    1. - Sur le tableau, les échelles et l’unité sont indiquées : -
        -
      • - --y définit l’échelle des ordonnées, utilisée - pour indiquer l’échelle en arrière-plan mais aussi placer - les points sur la courbe ; -
      • -
      • - --x correspond à l’échelle des abscisses, exprimée - simplement comme le nombre de colonnes à afficher ; -
      • -
      • --unit permet de définir l’unité à afficher dans l’infobulle simulée.
      • -
      -
    2. -
    3. - Chaque ligne <tr> dans <tbody> porte une palanquée - de variables, correspondant à toutes les valeurs qu’elle contient. - Dans un pseudo-élément ::before, une position est définie pour chaque valeur - au sein de la fonction polygon() de clip-path. -
        -
      • - Étant donné que cette fonction accepte deux valeurs en pourcentage - chaque point, la méthode est relativement simple. - La position en abscisse est le nombre de colonnes (le décalage depuis la gauche, donc) - et la position en ordonnée est le ratio de la valeur sur l’échelle, le tout formulé ainsi : - calc( ( 100% / var(--x) * 1 ) + var(--offset) ) calc( 100% - ( var(--1) / var(--y) * 100% ) ), - où * 1 et var(--1) correspondent à l’index de la valeur dans l’ensemble, - et var(--offset) est la valeur d’une demi-colonne, pour placer le point au milieu - de sa colonne. -
      • -
      • - Vous l’aurez peut-être compris, le principal écueil de ce graphique est qu’il - nécessite de connaître le nombre de points par avance. -
      • -
      • - Puisque clip-path requière encore - un préfixe -webkit- pour Safari, on utilise une variable CSS pour éviter la - duplication du polygon() — astuce - partagée par Michelle Barker dans "7 uses for CSS custom properties". -
      • -
      -
    4. -
    5. - Chaque cellule <td> dans <tbody> porte un pseudo-élément - ::after qui sert à récapituler ses entêtes et valeur dans - une infobulle simulée, et un pseudo-élément ::before pour gérer un calque interactif sur la cellule : - -
    6. -
    7. - Tout le reste n’est que décoration : -
        -
      • - un padding-top important sur le tableau pour - réserver l’espace d’affichage des graphiques — attention : - il est nécessaire d’appliquer border-collapse: separate; sur le tableau - afin que le padding ait un impact ; -
      • -
      • le ::before de chaque ligne est étiré afin d’occuper tout l’espace réservé ;
      • -
      • un arrière-plan dégradé pour représenter la surface pleine du même ::before ;
      • -
      • - un repeating-linear-gradient() pour représenter l’échelle verticale, - en arrière-plan du tableau ; -
      • -
      • - et des interactions au survol pour mettre en exergue la valeur survolée : - sa colonne à l’aide d’un pseudo-élément — positionné à l’aide de de savants calculs — - et mix-blend-mode pour un effet waouh. -
      • -
      -
    8. -
    - -{% import 'macros/_table-line.html' as table %} - -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - {{ table.line('8', '°C', 'Degré Celsius') }} - {{ table.line('6', '°C', 'Degré Celsius') }} - {{ table.line('9', '°C', 'Degré Celsius') }} - {{ table.line('12', '°C', 'Degré Celsius') }} - {{ table.line('15', '°C', 'Degré Celsius') }} - {{ table.line('21', '°C', 'Degré Celsius') }} - {{ table.line('24', '°C', 'Degré Celsius') }} - {{ table.line('25', '°C', 'Degré Celsius') }} - {{ table.line('22', '°C', 'Degré Celsius') }} - {{ table.line('19', '°C', 'Degré Celsius') }} - {{ table.line('14', '°C', 'Degré Celsius') }} - {{ table.line('9', '°C', 'Degré Celsius') }} - - -
    Température mensuelle moyenne en 2017
    AnnéeJan.Fév.MarsAvr.MaiJuinJuil.AoûtSep.Oct.Nov.Déc.
    2017
    -
    - -
    - Le HTML -
    {% include 'includes/_line-markup.html' %}
    -
    -
    - Le css -
    {% include 'includes/_line-styles.html' %}
    -
    -
    - Le calcul tordu -

    Le tracé du polygon()

    -

    - Pour commencer, il faut bien intégrer que clip-path est un tracé, - au même titre qu’une forme vectorielle. Il doit donc être fermé. - Ainsi le tracé démarre à 0% 100% — en bas à gauche, fait sa vie - de tracé, bascule à 100% 100% et revient boucler à 0% 100%. -

    -

    Et dans son chemin, chaque point doit être positionné en abscisses et en ordonnées.

    -

    La position en abscisse

    -

    - La première position est simple : on divise 100% par l’échelle - var(--x), et on multiplie par l’index de l’élément. Par exemple : - calc( ( 100% / var(--x) * 1) ). - Pour placer chaque point au milieu de sa colonne, on le décale d’une demi-colonne - — ce que l’on fait en ajoutant au calcul précédent var(--offset), qui correspond - à calc( ( 100% / var(--x) ) / 2 ).
    - La position finale est donc, ici pour le troisième point :
    - calc( ( 100% / var(--x) * 3) + var(--offset) ). -

    -

    La position en ordonnée

    -

    - Dans ce graphique, l’ordonnée est l’axe le plus important. Ainsi pour placer le point, - on commence par calculer le ratio de sa valeur sur l’échelle — formulé - ainsi : var(--1) / var(--y). Et parce que polygon() utilise - des valeurs en pourcentage, on rapporte ce calcul sur 100% : - ( var(--1) / var(--y) * 100% ).
    - Et pour finir, les référentiels du polygone partant d’en haut à gauche, la position - doit être définie en fonction du haut de la boîte. La formule finale ressemble - alors à ça — toujours pour le troisième élément :
    - calc( 100% - ( var(--3) / var(--y) * 100% ) ). -

    -
    - -

    Graphique à point

    - -

    Cette variante diffère finalement assez peu de la précédente mouture :

    - -
      -
    1. - le polygon() est poursuivi pour former une ligne, - en dupliquant chaque point avec un décalage de 4px - — l’épaisseur du trait — et dans l’ordre inverse ; -
    2. -
    3. - le pseudo-élément ::before qui permet d’afficher l’infobulle prend ici la forme d’un - point sur la courbe — positionné à l’aide des mêmes calculs qui servent dans le polygone ; -
    4. -
    5. - et surtout, puisque clip-path est appliqué sur la ligne - <tr> : vous pouvez en mettre plusieurs ! - Il nous faut donc ajouter une combinaison de couleur et motif pour distinguer chaque ligne - et les associer visuellement à leur légende. -
    6. -
    - -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - {{ table.line('8', '°C', 'Degré Celsius') }} - {{ table.line('6', '°C', 'Degré Celsius') }} - {{ table.line('9', '°C', 'Degré Celsius') }} - {{ table.line('12', '°C', 'Degré Celsius') }} - {{ table.line('15', '°C', 'Degré Celsius') }} - {{ table.line('21', '°C', 'Degré Celsius') }} - {{ table.line('24', '°C', 'Degré Celsius') }} - {{ table.line('25', '°C', 'Degré Celsius') }} - {{ table.line('22', '°C', 'Degré Celsius') }} - {{ table.line('19', '°C', 'Degré Celsius') }} - {{ table.line('14', '°C', 'Degré Celsius') }} - {{ table.line('9', '°C', 'Degré Celsius') }} - - - - {{ table.line('10', '°C', 'Degré Celsius') }} - {{ table.line('4', '°C', 'Degré Celsius') }} - {{ table.line('7', '°C', 'Degré Celsius') }} - {{ table.line('13', '°C', 'Degré Celsius') }} - {{ table.line('17', '°C', 'Degré Celsius') }} - {{ table.line('20', '°C', 'Degré Celsius') }} - {{ table.line('22', '°C', 'Degré Celsius') }} - {{ table.line('23', '°C', 'Degré Celsius') }} - {{ table.line('26', '°C', 'Degré Celsius') }} - {{ table.line('17', '°C', 'Degré Celsius') }} - {{ table.line('14', '°C', 'Degré Celsius') }} - {{ table.line('10', '°C', 'Degré Celsius') }} - - -
    Température mensuelle moyenne par année
    AnnéeJan.Fév.MarsAvr.MaiJuinJuil.AoûtSep.Oct.Nov.Déc.
    2017
    2018
    -
    - -
    - Le css -
    {% include 'includes/_lines-styles.html' %}
    -
    - -
    -

    Note

    -

    - Pour jouer d’avantage et vous familiariser avec clip-path, - Bennett Feely a créé - clippy. -

    -
    -{% endblock %} diff --git a/src/templates/histogramme.html b/src/templates/histogramme.html deleted file mode 100644 index db0b63a..0000000 --- a/src/templates/histogramme.html +++ /dev/null @@ -1,249 +0,0 @@ -{% extends "accueil.html" %} - -{% block meta %} - Histogramme — chaarts - - - - - - -{% endblock %} - -{% block navigation %} - -{% endblock %} - -{% block main %} -

    Histogramme

    - -

    - L’histogramme sert pour les distributions de valeurs. - La structure du tableau est tout à fait ordinaire, cependant sa mise en forme repose - sur display: grid; et surtout display: contents; pour - faciliter le placement des cellules — technique inspirée par - l’article - de Hidde De Vries More accessible markup with display: contents, - et clarifiée par l’article de - Ire Aderinokun How display: contents works. -

    - -

    Le principe de base est le même que le graphique en barre :

    -
      -
    1. - la première ligne de la grille est réservée pour afficher la valeur textuelle lorsqu’elle approche du haut de l’échelle, - avec une taille fixe de 2ex - — jetez un œil rudiments - concernant les unités CSS, documentés dans Every Layout par Andy Bell et Heydon Pickering ; -
    2. -
    3. - la fonction repeat() appliquée avec la variable --scale - permet de gérer une échelle dynamique ; -
    4. -
    5. - les conteneurs <thead>, <tbody> et <tr> - sont neutralisés dans la gestion de la grille à l’aide de display: contents ; -
    6. - chaque cellule est placée sur la grille en fonction de --value - — sa valeur, donc — sa couleur d’arrière-plan dépend également de - sa valeur ; -
    7. -
    8. - et finalement la valeur textuelle — contenue dans un élément - <span> — est positionnée en haut de la colonne - à l’aide de la même astuce que dans le graphique en barre. -
    9. -
    - -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Parts de marché navigateurs en France en janvier 2019
    NavigateurChromeFirefoxSafariEdgeIEAutres
    Parts de marché62 %15 %9 %5 %6 %3 %
    -
    - -
    - Le HTML -
    {% include 'includes/_column-markup.html' %}
    -
    -
    - Le css -
    {% include 'includes/_column-styles.html' %}
    -
    - -

    Colonnes multiples

    - -

    - Pour disposer de deux valeurs pour chaque colonne principale, nous devons également - disposer de deux sous-titres. - Concrètement parlant : -

    - -
      -
    1. - on ajoute une seconde ligne dans l’entête <thead> : -
        -
      • - avec deux cellules d’entête de colonne <th scope="col"> - pour chaque cellule d’entête de colonne dans la première ligne d’entête ; -
      • -
      • - n’oublions pas d’ajouter un colspan="2" sur les cellules d’entête de - la première ligne pour faire correspondre la structure du tableau ; -
      • -
      • - et enfin ajouter un identifiant à chaque cellule d’entête - afin de les référencer sur les cellules de données concernées — à l’aide - de l’attribut headers, par exemple pour la première cellule : - headers="navigateur chrome annee chrome-2018" où chaque valeur est un - identifiant de cellule d’entête. -
      • -
      -
    2. -
    3. - Côté styles : -
        -
      • - les cellules d’entête de premier niveau doivent s’étendre sur deux colonnes de la grille, - comme le réclame leur attribut colspan pour la structure du tableau. Il est - malheureusement impossible d’utiliser la valeur d’un attribut dans une autre - propriété que content — sinon nous pourrions simplement écrire - grid-column: 2 / span attr(colspan); et ça serait magnifique… -
      • -
      • - mais non ! Ainsi, une variable --span est ajoutée sur <table>, - et doit correspondre à la valeur des attributs colspan cités plus tôt : - elle sert donc à étendre les entêtes de premier niveau sur le nombre de colonnes adéquat. -
      • -
      • - les couleurs et motifs ne sont plus appliqués en fonction - de chaque valeur, mais en fonction de chaque colonne — dans l’exemple, un élément - sur deux (puisque nous avons deux entrées par colonne). - Là aussi, si nous pouvions utiliser une valeur d’attribut ou une propriété personnalisée - dans un sélecteur, ce serait génial. Imaginez un peu - tbody td:nth-of-type(var(--span)n + var(--span)) ou encore - tbody td:nth-of-type(attr(colspan)n + attr(colspan)) ! -
      • -
      -
    4. -
    - -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Parts de marché navigateurs en France en janvier 2019
    NavigateurChromeFirefoxSafariEdgeIE
    Année2018201920182019201820192018201920182019
    Parts de marché49.6 %57 %11.74 %9.59 %21.53 %18.78 %3.72 %3.5 %4.46 %3.66 %
    -
    - -
    - Le HTML -
    {% include 'includes/_columns-markup.html' %}
    -
    -
    - Le css -
    {% include 'includes/_columns-styles.html' %}
    -
    -{% endblock %} diff --git a/src/templates/includes/_bar-markup.html b/src/templates/includes/_bar-markup.html deleted file mode 100644 index d782f60..0000000 --- a/src/templates/includes/_bar-markup.html +++ /dev/null @@ -1,18 +0,0 @@ -
    <table class="chaarts bar" style="--scale: 3000">
    -  <caption id="caption-1">[…]</caption>
    -  <thead class="sr-only">
    -    <tr>
    -      <td></td>
    -      <th scope="col">[…]</th>
    -    </tr>
    -  </thead>
    -  <tbody>
    -    <tr>
    -      <th scope="row">[…]</th>
    -      <td style="--value: 4">
    -        <span>[…]</span>
    -      </td>
    -    </tr>
    -    <tr>[…]</tr>
    -  </tbody>
    -</table>
    diff --git a/src/templates/includes/_column-markup.html b/src/templates/includes/_column-markup.html deleted file mode 100644 index 14a983f..0000000 --- a/src/templates/includes/_column-markup.html +++ /dev/null @@ -1,17 +0,0 @@ -
    <table class="chaarts column" id="column" style="--y: 7;">
    -  <caption id="caption-7">[…]</caption>
    -  <thead>
    -    <tr>
    -      <th scope="row">[…]</th>
    -      <th scope="col" style="--value: 62;">Chrome</th>
    -      <th scope="col" style="--value: 15;">Firefox</th>
    -    </tr>
    -  </thead>
    -  <tbody>
    -    <tr>
    -      <th scope="row">[…]</th>
    -      <td style="--value: 62;"><span>62%</span></td>
    -      <td style="--value: 15;"><span>15%</span></td>
    -    </tr>
    -  </tbody>
    -</table>
    diff --git a/src/templates/includes/_columns-markup.html b/src/templates/includes/_columns-markup.html deleted file mode 100644 index d76e881..0000000 --- a/src/templates/includes/_columns-markup.html +++ /dev/null @@ -1,21 +0,0 @@ -
    <table class="chaarts column-multiple" id="column-multiple" style="--y: 11; --span: 2;">
    -  <caption id="caption-8">[…]</caption>
    -  <thead>
    -    <tr>
    -      <th scope="row" id="browser">[…]</th>
    -      <th scope="col" colspan="2" id="chrome">Chrome</th>
    -    </tr>
    -    <tr>
    -      <th scope="row" id="year">[…]</th>
    -      <th scope="col" id="chrome-2018">2018</th>
    -      <th scope="col" id="chrome-2019">2019</th>
    -    </tr>
    -  </thead>
    -  <tbody>
    -    <tr>
    -      <th scope="row" id="parts">[…]</th>
    -      <td style="--value: 50;" headers="browser chrome year chrome-2018"><span>49.6%</span></td>
    -      <td style="--value: 57;" headers="browser chrome year chrome-2019"><span>57%</span></td>
    -    </tr>
    -  </tbody>
    -</table>
    diff --git a/src/templates/includes/_line-markup.html b/src/templates/includes/_line-markup.html deleted file mode 100644 index 5c8a8f4..0000000 --- a/src/templates/includes/_line-markup.html +++ /dev/null @@ -1,17 +0,0 @@ -
    <table class="chaarts line" style="--y: 32; --x: 13; --t-1: 'Jan.'; --t-2: 'Feb.'; […]">
    -  <caption id="caption-3">[…]</caption>
    -  <thead>
    -    <tr>
    -      <th scope="col">[…]</th>
    -      <th scope="col">Jan.</th>
    -      <th scope="col">[…]</th>
    -    </tr>
    -  </thead>
    -  <tbody>
    -    <tr style="--year: '2017'; --1: 8; --2: 6; --3: 9; --4: 12; --5: 15; --6: 21; --7: 24; --8: 25; --9: 22; --10: 19; --11: 14; --12: 9;">
    -      <th scope="row">2017</th>
    -      <td>8 °C</td>
    -      <td>[…]</td>
    -    </tr>
    -  </tbody>
    -</table>
    diff --git a/src/templates/includes/_pie-markup.html b/src/templates/includes/_pie-markup.html deleted file mode 100644 index 106c3f5..0000000 --- a/src/templates/includes/_pie-markup.html +++ /dev/null @@ -1,16 +0,0 @@ -
    <table class="chaarts pie">
    -  <caption id="caption-5">[…]</caption>
    -  <thead class="sr-only">
    -    <tr>
    -      <th scope="col">[…]</th>
    -      <th scope="col">[…]</th>
    -    </tr>
    -  </thead>
    -  <tbody>
    -    <tr style="--color: #734bf9; --term: 'HTML';">
    -      <th scope="row">HTML</th>
    -      <td style="--value: 2; --start: 0;">2 %</td>
    -    </tr>
    -    <tr>[…]</tr>
    -  </tbody>
    -</table>
    diff --git a/src/templates/includes/_radar-markup.html b/src/templates/includes/_radar-markup.html deleted file mode 100644 index 5c232fe..0000000 --- a/src/templates/includes/_radar-markup.html +++ /dev/null @@ -1,15 +0,0 @@ -
    <table class="chaarts radar" id="radar" style="--scale: 20; --step: 5; --items: 7; --1: 14; --2: 11; --3: 13; --4: 16; --5: 10; --6: 12; --7: 4; --8: var(--1);">
    -  <caption id="caption-9">[…]</caption>
    -  <thead>
    -    <tr>
    -      <th scope="col">[…]</th>
    -      <th scope="col">[…]</th>
    -    </tr>
    -  </thead>
    -  <tbody>
    -    <tr>
    -      <td><span>14</span></td>
    -      <td><span>11</span></td>
    -    </tr>
    -  </tbody>
    -</table>
    diff --git a/src/templates/includes/_radars-markup.html b/src/templates/includes/_radars-markup.html deleted file mode 100644 index 454bc10..0000000 --- a/src/templates/includes/_radars-markup.html +++ /dev/null @@ -1,19 +0,0 @@ -
    <table class="chaarts radar-multiple" id="radar-multiple" style="--scale: 20; --step: 5; --items: 7; --areas: 2;">
    -  <caption id="caption-9">[…]</caption>
    -  <thead>
    -    <tr>
    -      <th scope="col">[…]</th>
    -      <th scope="col">[…]</th>
    -    </tr>
    -  </thead>
    -  <tbody>
    -    <tr style="--color: #734bf9; --1: 14; --2: 11; --3: 13; --4: 16; --5: 14; --6: 10; --7: 4; --8: var(--1);">
    -      <th scope="row">Gaël</th>
    -      <td><span>14</span></td>
    -    </tr>
    -    <tr style="-color: #e11a81; --1: 18; --2: 10; --3: 11; --4: 16; --5: 10; --6: 12; --7: 11; --8: var(--1);">
    -      <th scope="row">Luc</th>
    -      <td><span>18</span></td>
    -    </tr>
    -  </tbody>
    -</table>
    diff --git a/src/templates/index.html b/src/templates/index.html deleted file mode 100644 index edc449e..0000000 --- a/src/templates/index.html +++ /dev/null @@ -1,224 +0,0 @@ - - - - - - - {% block meta %} - chaarts - - - - - - - {% endblock %} - - - - - - -
    - {% block skiplinks %} - - {% endblock %} - - -
    - -
    - {% block main %} -

    Chaarts

    - -

    - Every charts in this project relies solely on semantic markup - — <table> based — and a spread of - CSS variables carried by the tags. - No JavaScript required for display, and styles are - progressively enhanced depending on your browser's capabilities. -

    - -

    - Note : by virtue of the experimental - nature of these techniques and a solid foundation enhanced progressively, - I don't mention browser support for each example — but - it goes without saying that this is not magic, and only modern browsers handle this right, - with the notable exception of Edge - which does not (yet) support clip-path. - Other browsers display a properly styled table, and that's nice. -

    - -

    Accessibility

    - -

    - A major effort has been made to ensure accessibility. - As mentioned above, semantic and structured markup is a prerequisite - — but it's not enough. CSS - is being applied as gradually as possible, in order to guarantee - the best possible display of data for each user. -

    - -

    Accessible table

    - -

    Wakeup call :

    - -
      -
    • a table must start with a <caption>;
    • -
    • - header cells <th> must carry a scope attribute, - with a row or col value; -
    • -
    • - and you'll usually need to distinguish the head from the body through - <thead> and <tbody>; -
    • -
    • - for values with a unit : if you venture to use the - <abbr> element to use its abbreviated version, consider doubling the - title with the aria-label attribute — this will considerably - improve the interest for many users. -
    - -

    - For other useful tips, I warmly recommend reading - - Data Tables Inclusive Component by Heydon Pickering, - which is a real gold mine. -

    - -

    Patterns

    -

    - To distinguish the different areas other than by colour, an - svg - pattern is applied in - css - — you can find some of them on the - Hero Patterns website: -

    -
      -
    1. - in order to improve blending with background colors or gradients, the - background-blend-mode proerty is used with the hard-light value; -
    2. -
    3. - pattern's size and position depends directly on the value and scale of the chart, - depending on the type of chart; -
    4. -
    5. - in order not to embed too many external files, we use a - - technique proposed by Trys Mudford to include each - svg - in data URi in a css variable; - thus, a finite list of patterns is used in the theme, without ever repeating the svg. -
    6. -
    - -
    -

    What to encode?

    -

    - Taylor Hunt - a comprehensive article on optimizing past svg - in URi data. In summary, only the chevrons and the "#" character need to be encoded - in the css. - Don't bother with the other characters, their encoding seriously affects readability. -

    -
    - - {% include 'includes/_svg-encoding.html' %} - -

    User preferences

    -

    - In order to respect as much as possible the preferences of the visitors, - many elements have been adapted: -

    -
      -
    1. - dimensions are in relatives units (em or rem as the case may be), - in order to fit coherently with the body of text inherited from the browser and to be able - to be enlarged or reduced without loss; -
    2. -
    3. - colors are adjusted when Windows High Contrast Mode is detected using - -ms-high-contrast: active, inspired by - - Greg Whitworth article on the topic. I also recommend you - - Test of System Colors Specified in CSS 2 rustproof page written by - Ian Graham, published in… 2000! -
    4. -
    5. - animations and transitions are disabled when the system exposes - this preference through prefers-reduced-motion: reduce ; -
    6. -
    7. - hover effects whose initial state consists in hiding content - are activated contextually in the @media (hover: hover) { … } media query. -
    8. -
    - -

    display and semantics

    -

    - Adrian Roselli explains that playing with a <table> or <dl> - element's display endangers its semantics. - The latter is therefoore "locked" using dedicated - aria - roles — as he explains - in a detailed article. -

    -

    - That's why each table is preceded by a switch — based on - Heydon Pickering - inclusive toggle button — - whose one and only role is to disable additional styles: -

    - - {% include 'includes/_inclusive-toggle.html' %} - -

    - Well, we're ready to get to the heart of the matter.
    - Warm up your dev tools! -

    - {% endblock %} -
    - -{% block scripts %} - - -{% endblock %} - -{% block modal %} -{% endblock %} - - diff --git a/src/templates/line-charts.html b/src/templates/line-charts.html deleted file mode 100644 index 8a13579..0000000 --- a/src/templates/line-charts.html +++ /dev/null @@ -1,347 +0,0 @@ -{% extends "index.html" %} - -{% block meta %} - Line charts — chaarts - - - - - - -{% endblock %} - -{% block navigation %} - -{% endblock %} - -{% block main %} -

    Line charts

    - -

    Area charts

    - -

    - This chart is based on CSS custom properties, grids and clip-path - — the latter being the most important. -

    - -
      -
    1. - Scales are set on the table: -
        -
      • - --y defines the y-axis scale, used to indicate the scale - in the background but also to place the points on the curve; -
      • -
      • - --x is the x-axis scale, - simply expressed as the number of columns to display; -
      • -
      • --unit defines unit to be displayed in simulated tooltip (see below).
      • -
      -
    2. -
    3. - Each line <tr> in <tbody> carries a set of variables, - corresponding to all the values it contains. - In a ::before pseudo-element, a position is defined for each value - within the clip-path polygon() function. -
        -
      • - Since this function accepts two percentage values at each point, - the method is pretty straightforward. - The x-axis position is the number of columns (i.e., the offset from the left) and - the y-axis position is the ratio of the value on the scale, formulated as follows: - calc( ( 100% / var(--x) * 1 ) + var(--offset) ) calc( 100% - ( var(--1) / var(--y) * 100% ) ), - where * 1 and var(--1) is the index of the value as a whole, - and var(--offset) is the value of half a column, - to place the point in the middle of its column. -
      • -
      • - As you may have understood, the main pitfall of this graph is - that it requires to know the number of points in advance. -
      • -
      • - Since clip-path still requires - -webkit- vendor prefix for Safari, we're using a custom property to prevent - polygon() duplication — based - on a trick shared by Michelle Barker in "7 uses for CSS custom properties". -
      • -
      -
    4. -
    5. - Each cell <td> in <tbody> carries an - ::after pseudo-element used to summarize - its headers and value in a simulated tooltip, and a ::before pseudo-element - to manage an interactive layer on the cell: - -
    6. -
    7. - Everything else is just decoration:: -
        -
      • - a big padding-top on the table is used to reserve space - for the charts — caution: - it is necessary to apply border-collapse: separate; on the table - for the padding to have an impact; -
      • -
      • each line's ::before is stretched in order to occupy all the reserved space;
      • -
      • a gradient background to represent the full area of the same ::before;
      • -
      • - a repeating-linear-gradient() to represent the vertical scale - in the table's background; -
      • -
      • - and hover interactions to highlight the hovered value: - its column using a pseudo-element — positioned with the help of clever calculations — - and mix-blend-mode for a wow effect. -
      • -
      -
    8. -
    - -{% import 'macros/_table-line.html' as table %} - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - {{ table.line('8', '°C', 'Degree Celsius') }} - {{ table.line('6', '°C', 'Degree Celsius') }} - {{ table.line('9', '°C', 'Degree Celsius') }} - {{ table.line('12', '°C', 'Degree Celsius') }} - {{ table.line('15', '°C', 'Degree Celsius') }} - {{ table.line('21', '°C', 'Degree Celsius') }} - {{ table.line('24', '°C', 'Degree Celsius') }} - {{ table.line('25', '°C', 'Degree Celsius') }} - {{ table.line('22', '°C', 'Degree Celsius') }} - {{ table.line('19', '°C', 'Degree Celsius') }} - {{ table.line('14', '°C', 'Degree Celsius') }} - {{ table.line('9', '°C', 'Degree Celsius') }} - - -
    Average monthly temperature in 2017
    YearJan.Feb.Mar.Apr.MayJuneJulyAug.Sep.Oct.Nov.Dec.
    2017
    -
    - -
    - HTML -
    {% include 'includes/_line-markup.html' %}
    -
    -
    - css -
    {% include 'includes/_line-styles.html' %}
    -
    -
    - The calculation twist -

    The polygon() path

    -

    - To begin with, you need to understand that clip-path is a path, - just like a vector shape. It must therefore be closed. - So the path starts at 0% 100% — bottom left, does its path life, - toggles to 100% 100% and comes back looping at 0% 100%. -

    -

    And in its path, each point must be positioned in abscissa and ordinate.

    -

    The X-axis position

    -

    - The first position is simple: divide 100% by the - var(--x) scale, and multiply by the index of the element. - For example: calc( ( 100% / var(--x) * 1) ). - To place each point in the middle of its column, we shift it by half a column - — which we do by adding to the previous calculation var(--offset), - which corresponds to calc( ( 100% / var(--x) ) / 2 ).
    - The final position is therefore, here for the third point:
    - calc( ( 100% / var(--x) * 3) + var(--offset) ). -

    -

    The Y-axis position

    -

    - In this graph, the Y-axis is the most important axis. So to place the point, - we start by calculating the ratio of its value on the scale - — formulated as follows: var(--1) / var(--y). And because - polygon() uses percentage values, we report this calculation on 100%: - ( var(--1) / var(--y) * 100% ).
    - And finally, since the polygon's datums start from the top left, the position - position must be defined according to the top of the box. - The final formula then looks like this — again for the third element: - calc( 100% - ( var(--3) / var(--y) * 100% ) ). -

    -
    -
    - -

    Line chart with dots

    - -

    In the end, this variant differs little from the previous version:

    - -
      -
    1. - the polygon() is continued to form a line, - duplicating each point with an offset of 4px - — the line thickness — and in the reverse order; -
    2. -
    3. - the ::before pseudo-element that displays the tooltip takes - here the form of a point on the curve - — positioned using the same calculations that are used in the polygon; -
    4. -
    5. - and especially, since clip-path is applied in the line - <tr>: you can put more than one ! - So we need to add a combination of color and pattern to distinguish each line - and associate them visually with their caption. -
    6. -
    - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - {{ table.line('8', '°C', 'Degree Celsius') }} - {{ table.line('6', '°C', 'Degree Celsius') }} - {{ table.line('9', '°C', 'Degree Celsius') }} - {{ table.line('12', '°C', 'Degree Celsius') }} - {{ table.line('15', '°C', 'Degree Celsius') }} - {{ table.line('21', '°C', 'Degree Celsius') }} - {{ table.line('24', '°C', 'Degree Celsius') }} - {{ table.line('25', '°C', 'Degree Celsius') }} - {{ table.line('22', '°C', 'Degree Celsius') }} - {{ table.line('19', '°C', 'Degree Celsius') }} - {{ table.line('14', '°C', 'Degree Celsius') }} - {{ table.line('9', '°C', 'Degree Celsius') }} - - - - {{ table.line('10', '°C', 'Degree Celsius') }} - {{ table.line('4', '°C', 'Degree Celsius') }} - {{ table.line('7', '°C', 'Degree Celsius') }} - {{ table.line('13', '°C', 'Degree Celsius') }} - {{ table.line('17', '°C', 'Degree Celsius') }} - {{ table.line('20', '°C', 'Degree Celsius') }} - {{ table.line('22', '°C', 'Degree Celsius') }} - {{ table.line('23', '°C', 'Degree Celsius') }} - {{ table.line('26', '°C', 'Degree Celsius') }} - {{ table.line('17', '°C', 'Degree Celsius') }} - {{ table.line('14', '°C', 'Degree Celsius') }} - {{ table.line('10', '°C', 'Degree Celsius') }} - - -
    Average monthly temperature per year
    YearJan.Feb.Feb.Mar.Apr.MayJuneJulyAug.Sep.Oct.Nov.Dec.
    2017
    2018
    -
    - -
    - css -
    {% include 'includes/_lines-styles.html' %}
    -
    - -
    -

    Note

    -

    - To play more and familiarize yourself with clip-path, - Bennett Feely created - clippy. -

    -
    -{% endblock %} diff --git a/src/templates/macros/_table-bar.html b/src/templates/macros/_table-bar.html deleted file mode 100644 index 1ee6f3a..0000000 --- a/src/templates/macros/_table-bar.html +++ /dev/null @@ -1,8 +0,0 @@ -{% macro bar(term='', definition='', unit='', title='', variant='') %} - - {{ term }} - - {{ definition }}{% if unit != '' %} {% if title != '' %}{% endif %}{{ unit }}{% if title != '' %}{% endif %}{% endif %} - - -{% endmacro %} diff --git a/src/templates/macros/_table-line.html b/src/templates/macros/_table-line.html deleted file mode 100644 index b2dd98b..0000000 --- a/src/templates/macros/_table-line.html +++ /dev/null @@ -1,5 +0,0 @@ -{% macro line(definition='', unit='', title='') %} - - {{ definition }}{% if unit != '' %} {% if title != '' %}{% endif %}{{ unit }}{% if title != '' %}{% endif %}{% endif %} - -{% endmacro %} diff --git a/src/templates/macros/_table-pie.html b/src/templates/macros/_table-pie.html deleted file mode 100644 index b52138f..0000000 --- a/src/templates/macros/_table-pie.html +++ /dev/null @@ -1,16 +0,0 @@ -{% macro pie(term='', definition='', unit='', title='', start='0', color='') %} - - {{ term }} - {% if definition < 25 %} - {% set style = "" %} - {% elif definition < 50 %} - {% set style = "--lt-25: 0; --gt-25: 1; --lt-50: 1; --gt-50: 0;" %} - {% elif definition < 75 %} - {% set style = "--lt-25: 0; --gt-25: 1; --lt-50: 0; --gt-50: 1; --lt-75: 1; --gt-75: 0;" %} - {% else %} - {% set style = "--lt-25: 0; --gt-25: 1; --lt-50: 0; --gt-50: 1; --lt-75: 0; --gt-75: 1; --lt-100: 1;" %} - {% endif %} - - {{ definition }}{% if unit != '' %} {% if title != '' %}{% endif %}{{ unit }}{% if title != '' %}{% endif %}{% endif %} - -{% endmacro %} diff --git a/src/templates/pie-charts.html b/src/templates/pie-charts.html deleted file mode 100644 index 0d7c762..0000000 --- a/src/templates/pie-charts.html +++ /dev/null @@ -1,667 +0,0 @@ -{% extends "index.html" %} - -{% block meta %} -Pie charts — chaarts - - - - - - -{% endblock %} - -{% block navigation %} - -{% endblock %} - -{% block main %} -

    Pie charts

    - -

    - The pie chart is used for representations of percentage proportions. - It relies on CSS variables, an outrageous abuse of calc(), - display: table-*, clip-path, mask-image, - transform and a bit of SVG - to distinguish each area. Yes, I know how to laugh. How do we use it? -

    - -
      -
    1. - On each header <th>, a --color - custom property allows you to assign, well… a color. -
    2. -
    3. - Then each cell <td> must contain the value - and its unit, as well as a style attribute to carry some variables: -
        -
      1. - --value is the percentage value, - useful for determining the angle the element should occupy on the circle. - All points of the polygon() — used to draw the pie part thanks to clip-path — - depend on this value (read the technical note after - the example for details of the calculations). -
      2. -
      3. - --start is used to define the starting point - of the arc on the circle. It's the sum of the previous definitions, and is applied - to the rotate() function of the transform poperty. -
      4. -
      5. - And finally a series of pseudo-boolean variables, each worthing 0 or 1 - — according to and idea of - Roman Komarov in "Conditions for CSS variables" — - depend on the value: --lt-25, --gt-25, --lt-50… - They allow to toggle the points from their original position - (50% 50%) to their calculated position, by adding or subtracting from the initial value; -
      6. -
      -
    4. -
    5. - a ::before pseudo-element on each cell <td>is formatted - in a clever way according to all our variables, including transform, - clip-path and mask-image. - -
    6. -
    7. - a ::after pseudo-element is used as a tooltip, to summarize header and value for each cell - —but the display of custom properties in a pseudo-element is not so trivial: - -
    8. -
    9. - And finally a pattern is applied to the background, - in order to better associate it visually with the corresponding legend. -
    10. -
    - -{% import 'macros/_table-pie.html' as table %} - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} - {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} - {{ table.pie('JS', '32', '%', '', '4', '#0172F0') }} - {{ table.pie('Json', '1', '%', '', '36', '#FDC02F') }} - {{ table.pie('Images', '44', '%', '', '37', '#39CA74') }} - {{ table.pie('Webfonts', '17', '%', '', '81', '#FF2D40') }} - {{ table.pie('Other', '2', '%', '', '98', '#585462') }} - -
    Distribution of the weight of resources for ffoodd.fr
    ResourceProportion
    -
    - -
    - A bit of trigonometry -
    -

    - In this graph, each portion represents an arc of a circle based on an angle (part of 360 degrees). - To define the shape of this portion, a point must be placed on the circle. -

    -

    - To do this, I divide the circle into four squares. The position of the point on the circle - can then be calculated using the properties of the right-angled triangle formed by: -

    -
      -
    1. the center of the circle,
    2. -
    3. the point we're trying to position,
    4. -
    5. and the point perpendicular to the radius and passing through our target point.
    6. -
    -

    - We know the hypotenuse of this triangle — the radius of the circle —, - and the angle formed by the hypotenuse and starting from the center of the circle - (reducing the value to 90 degrees, since the circle is divided into four square sectors: - if the value is greater than 25: minus 90°, etc.) - — plus a right angle, of course. -

    -

    Law of sines

    -

    - We can therefore use the sine law - to measure each side, and thus obtain the position of the point on the circle. - Meaning we need to calculate the sine… Fortunately, - Stereokai implemented for us - the Taylor/Maclaurin polynomial representation in CSS — which I implemented as a mixin: -

    - {% include 'includes/_sin-mixin.html' %} -

    - All that remains is to use these dimensions to place the points of the polygon. - It's child's play! -

    -
    -
    - HTML -
    {% include 'includes/_pie-markup.html' %}
    -
    -
    - css -
    -
    -   
    -@supports (clip-path: polygon( 50% calc( 50% + ( var(--gt-25, 0) ) ) )) {
    - .chaarts.pie {
    -   --radius: 32em;
    -   margin: 0 auto;
    -   padding-top: calc(var(--radius) - 2rem);
    -   position: relative;
    - }
    -
    - .chaarts.pie tbody {
    -   display: table-row;
    - }
    -
    - .chaarts.pie tr {
    -   display: table-cell;
    -   transition: opacity .3s cubic-bezier(.5, 0, .5, 1);
    - }
    -
    - .chaarts.pie [scope="row"] {
    -   padding-right: .5rem;
    - }
    -
    - .chaarts.pie [scope="row"]::before {
    -   background: var(--color, currentColor);
    -   content: "";
    -   display: inline-block;
    -   height: 1rem;
    -   transform: translate3d(-.2rem, .1rem, 0);
    -   width: 1rem;
    - }
    -
    - .chaarts.pie td {
    -   --position: calc(var(--start, 0) * .01turn);
    - }
    -
    - .chaarts.pie td::after,
    - .chaarts.pie td::before {
    -   left: 50%;
    -   position: absolute;
    -   top: calc(var(--radius) / 2);
    -   transform-origin: center center;
    - }
    -
    - .chaarts.pie td::before {
    -   /* The inclination, to be in the right place */
    -   --position: calc(var(--start, 0) * .01turn);
    -   --zoom: .75;
    -   /* The angle represented by the value: 3.6 = 360deg / 100 */
    -   /* Since we're using a percentage value */
    -   --part: calc( var(--value) * 3.6 );
    -   /* The "useful" angle for the calculation, necessarily less than 90deg */
    -   /*  We therefore subtract 90deg (= ¼ × 360deg) per 25% (= ¼ × 100%, indeed) */
    -   --main-angle: calc( var(--part) - ( 90 * ( var(--gt-25, 0) + var(--gt-50, 0) + var(--gt-75, 0) ) ) );
    -   /* Main angle, in radian */
    -   --β: calc( var(--main-angle) * 0.01745329251 );
    -   /* The last angle in radian, by deduction since in a right-angled triangle */
    -   --α: calc( ( 90 - var(--main-angle) ) * 0.01745329251 );
    -   /* The magic of Stereokai, to get the sinus from these angles… */
    -   --sin-term-β-1: var(--β);
    -   --sin-term-β-2: calc((var(--β) * var(--β) * var(--β)) / 6);
    -   --sin-term-β-3: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 120);
    -   --sin-term-β-4: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 5040);
    -   --sin-term-β-5: calc((var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β) * var(--β)) / 362880);
    -   --sin-β: calc(var(--sin-term-β-1) - var(--sin-term-β-2) + var(--sin-term-β-3) - var(--sin-term-β-4) + var(--sin-term-β-5));
    -   --sin-term-α-1: var(--α);
    -   --sin-term-α-2: calc((var(--α) * var(--α) * var(--α)) / 6);
    -   --sin-term-α-3: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 120);
    -   --sin-term-α-4: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 5040);
    -   --sin-term-α-5: calc((var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α) * var(--α)) / 362880);
    -   --sin-α: calc(var(--sin-term-α-1) - var(--sin-term-α-2) + var(--sin-term-α-3) - var(--sin-term-α-4) + var(--sin-term-α-5));
    -   /* Finally, the position expressed in %, of the hypothenuse, divided by 2 to fit in ¼ of the circle
    -    * or after simplification, divided by 50 */
    -   --pos-B: calc( var(--sin-β) * 50 );
    -   --pos-A: calc( var(--sin-α) * 50 );
    -   background-color: var(--color, currentColor) var(--background);
    -   --polygon: polygon(
    -     50% 50%,
    -     50% 0%,
    -     100% 0%,
    -     calc( 50% + ( var(--pos-B) * 1% * var(--lt-25, 1) ) + ( var(--gt-25, 0) * 50% ) ) calc( 50% - ( var(--pos-A) * 1% * var(--lt-25, 1) ) ),
    -     calc( 50% + ( var(--gt-25, 0) * 50% ) )                      calc( 50% + ( var(--gt-25, 0) * 50% ) ),
    -     calc( 50% + ( var(--pos-A) * 1% * var(--lt-50, 1) ) + ( var(--gt-50, 0) * 50% ) ) calc( 50% + ( var(--pos-B) * 1% * var(--lt-50, 1) ) + ( var(--gt-50, 0) * 50% ) ),
    -     calc( 50% - ( var(--gt-50, 0) * 50% ) )                      calc( 50% + ( var(--gt-50, 0) * 50% ) ),
    -     calc( 50% - ( var(--pos-B) * 1% * var(--lt-75, 1) ) - ( var(--gt-75, 0) * 50% ) ) calc( 50% + ( var(--pos-A) * 1% * var(--lt-75, 1) ) ),
    -     calc( 50% - ( var(--gt-75, 0) * 50% ) )                      calc( 50% - ( var(--gt-75, 0) * 50% ) ),
    -     calc( 50% - ( var(--pos-A) * 1% * var(--gt-75, 0) ) )        calc( 50% - ( var(--pos-B) * 1% * var(--gt-75, 0) ) ),
    -     50% 50%
    -   );
    -   clip-path: var(--polygon);
    -   content: '';
    -   height: var(--radius);
    -   --mask: radial-gradient(
    -     circle at center,
    -     white 0%,
    -     white calc(var(--radius)  / 2),
    -     transparent calc(var(--radius)  / 2)
    -   );
    -   mask-image: var(--mask);
    -   transform:
    -     translate3d(-50%, -50%, 0)
    -     rotate( var(--position) )
    -     scale( var(--zoom) );
    -   transition: transform .2s cubic-bezier(.5, 0, .5, 1);
    -   width: var(--radius);
    - }
    -
    - .chaarts.pie tr:hover td::before {
    -   --zoom: .8;
    - }
    -
    - .chaarts.pie tr:nth-child(2n + 2) *::before {
    -   --background: var(--stripes);
    - }
    -
    - .chaarts.pie td::after {
    -   --arrow: calc(100% - .25rem);
    -   --axis: calc( var(--position) - .25turn + var(--value) * .005turn );
    -   --away: calc( var(--radius) / 2 - 1rem );
    -   --integer: calc(var(--value));
    -   background-color: #444;
    -   color: white;
    -   content: var(--term) "\A0: " counter(value) "\A0%";
    -   counter-reset: value var(--integer);
    -   opacity: 0;
    -   padding: .5rem;
    -   pointer-events: none;
    -   transform-origin: 50% calc(100% + 10px);
    -   transform:
    -     translate3d(-50%, -50%, 0)
    -     rotate( var(--axis) )
    -     translate( var(--away) )
    -     rotate( calc( var(--axis) * -1 ) )
    -     perspective(1000px)
    -     rotate3d(1, 0, 0, 45deg);
    -   transition:
    -     opacity .2s cubic-bezier(0, .5, .5, 1),
    -     transform .2s cubic-bezier(0, .5, .5, 1);
    - }
    -
    - .chaarts.pie tbody:hover tr {
    -   opacity: .75;
    - }
    -
    - .chaarts.pie tbody:hover tr:hover {
    -   opacity: 1;
    - }
    -
    - .chaarts.pie tbody:hover td::after {
    -   opacity: 1;
    -   transform:
    -     translate3d(-50%, -50%, 0)
    -     rotate( var(--axis) )
    -     translate( var(--away) )
    -     rotate( calc( var(--axis) * -1 ) )
    -     perspective(1000px)
    -     rotate3d(1, 0, 0, 0deg);
    -   transition:
    -     opacity .2s cubic-bezier(.5, 0, 1, .5),
    -     transform .2s cubic-bezier(.5, 0, 1, .5);
    - }
    -
    - @media screen and (-ms-high-contrast: active) {
    -   .chaarts.pie tr *::before {
    -     background-color: Window;
    -   }
    -
    -   .chaarts.pie tr:nth-of-type(odd) *::before {
    -     background-color: WindowText;
    -   }
    - }
    -}
    -  
    -
    -
    -
    - The calculation twist -

    The positions of the polygon

    -

    - The use of pseudo-Boolean variables makes this calculation pseudo-algorithmic. - Let's start with an essential pre-requisite: the polygon being a closed shape and CSS - not being magical, points must pre-exist. - Spoiler, we need eleven points: -

    -
      -
    1. - The initial axis, from centre upwards: 50% 50% - and 50% 0%. -
    2. -
    3. - One point for each angle at the ends: the first one is fixed, at - 100% 0% (top right) — then each of the other angles has - two states, reached or not reached. Some insights: -
        -
      • - For example, the point at the bottom right concerns values between 25% and 50%: - if the value is less than 25%, it must be in the centre (so as not to interfere - with the drawing), and if not, it must be in its corner: - calc( 50% + ( var(--gt-25, 0) * 50% ) ) calc( 50% + ( var(--gt-25, 0) * 50% ) )
        - Thus the calculated value will be 50% 50% if --gt-25 is 0, - and 100% 100% if --gt-25 is 1. -
      • -
      • - In addition, each angle has its target coordinate: - 100% 100% for bottom right, 0% 100% for bottom left, - 0% 0% for top left. It is therefore necessary to sometimes subtract - and sometimes add to the initial value 50% 50% - to switch to the right point. -
      • -
      -
    4. -
    5. - One point for each possible position per quarter circle, corresponding - to each 25% slice. Like the points at the corners, these points must be in the centre - if they are not used. That's where we laugh the most: -
        -
      • we start from 50%, to which we add or subtract the following calculation;
      • -
      • - then the calculated position is used — --pos-A - or --pos-B as the case may be — which is converted into percentages using - * 1%, and rendered inert if the value is less than the range concerned - using * var(--lt-25, 1), for example.
        - - Notice the second value in var()? - This is the default value if the variable is not defined. Cool, isn't it? - -
      • -
      • - finally when the range is exceeded, the point switches to - 0% or 100% as appropriate. -
      • -
      -
    6. -
    7. - And lastly, we lose the path by going back to the centre of the circle, - at 50% 50%. -
    8. -
    -

    That's it!

    -

    The positions illustrated

    -

    - These screenshots — taken in - the shape editor of the - Firefox devtools — - show the points of the polygon in the different cases. - You can see for each cited value the resolved polygon for clip-path - — and see how the dynamic values tilt from one position to another. -

    -
      -
    • -
      -
      Rendering example for 44%
      -
      -
      - clip-path shape with a value of 44%: six visible points. -
      Shape screenshot for 44%.
      -
      -
      - {% include 'includes/_pie-styles:44.html' %} -
      Code generated for 44%.
      -
      -
      -
      -
    • -
    • -
      -
      Rendering example for 64%
      -
      -
      - clip-path shape with a value of 64%: seven visible points. -
      Shape screenshot for 64%.
      -
      -
      - {% include 'includes/_pie-styles:64.html' %} -
      Code generated for 64%.
      -
      -
      -
      -
    • -
    • -
      -
      Rendering example for 88%
      -
      -
      - clip-path shape with a value of 88%: nine visible points. -
      Shape screenshot for 88%.
      -
      -
      - {% include 'includes/_pie-styles:88.html' %} -
      Code generated for 88%.
      -
      -
      -
      -
    • -
    -
    - -
    -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} - {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} - {{ table.pie('JS', '32', '%', '', '4', '#0172F0') }} - {{ table.pie('Images', '64', '%', '', '36', '#39CA74') }} -
    Pie chart example with a value between 50 and 75%
    ResourceProportion
    -
    - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} - {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} - {{ table.pie('JS', '8', '%', '', '4', '#0172F0') }} - {{ table.pie('Images', '88', '%', '', '12', '#39CA74') }} - -
    Pie chart example with a value greater than 75%
    ResourceProportion
    -
    -
    - -

    Donut

    - -

    - On the <table> element, we add an --offset variable - that allows us to determine the size of the hole of the donut, - generated using mask-image and radial-gradient(). - Ana Tudor has made - many examples of using mask-* on CodePen, have a look! -

    - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} - {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} - {{ table.pie('JS', '32', '%', '', '4', '#0172F0') }} - {{ table.pie('Json', '1', '%', '', '36', '#FDC02F') }} - {{ table.pie('Images', '44', '%', '', '37', '#39CA74') }} - {{ table.pie('Webfonts', '17', '%', '', '81', '#FF2D40') }} - {{ table.pie('Other', '2', '%', '', '98', '#585462') }} - -
    Distribution of the weight of resources for ffoodd.fr
    ResourceProportion
    -
    - -
    - css -
    {% include 'includes/_donut-styles.html' %}
    -
    - -
    -

    Conical gradient

    -

    - The use of conic-gradient() is promising for this case. - You'll find examples made by Ana Tudor and Léa Verou - — who actually wrote the specification, and designed - a polyfill. - However, current support is limited to WebKit based browsers - is depressing, and still raises some accessibility issues - since you can't assign a pattern to each color of the conic-gradient(). -

    -
    - -

    Polar chart

    - -

    - For this variant, wa change almost nothing: only the --zoom variable - and its implication in the scaling of portions using scale(). -

    - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - {{ table.pie('HTML', '2', '%', '', '0', '#734BF9') }} - {{ table.pie('CSS', '2', '%', '', '2', '#E11A81') }} - {{ table.pie('JS', '32', '%', '', '4', '#0172F0') }} - {{ table.pie('Json', '1', '%', '', '36', '#FDC02F') }} - {{ table.pie('Images', '44', '%', '', '37', '#39CA74') }} - {{ table.pie('Webfonts', '17', '%', '', '81', '#FF2D40') }} - {{ table.pie('Other', '2', '%', '', '98', '#585462') }} - -
    Distribution of the weight of resources for ffoodd.fr
    ResourceProportion
    -
    - -
    - css -
    {% include 'includes/_polar-styles.html' %}
    -
    -{% endblock %} diff --git a/src/templates/radar-charts.html b/src/templates/radar-charts.html deleted file mode 100644 index 81e69ed..0000000 --- a/src/templates/radar-charts.html +++ /dev/null @@ -1,345 +0,0 @@ -{% extends "index.html" %} - -{% block meta %} - Radar charts — chaarts - - - - - - -{% endblock %} - -{% block navigation %} - -{% endblock %} - -{% block main %} -

    Radar charts

    - -

    - This one's kind of fun. We define some CSS - variables on the table: the scale (and tiers), the number of elements, and the values. -

    - -

    - On the CSS side, it's getting complicated: -

    - -
      -
    • - on the <table> element, the circular scale is created using two successive - repeating-radial-gradient() — depending on the - --scale and --step variables; -
    • -
    • - each element <th> is moved outside the circle thus formed, - thanks to a technique borrowed from - - Ana Tudor, who explains it on StackOverflow; -
    • -
    • - then — still on header cells — the value corresponding to each column - is displayed in a pseudo-element ::after using - a - trick from Cassie Evans, using counter-reset and counter() - to display a numerical variable in the content property. - However counter-reset only works with integers, and our value might be a number. - So we rely on - Carter Li's ruse using calc() to convert numbers to integers— and - @property for Chromium-based browsers. Boum! -
    • - Then the magic works on the <td> elements: -
        -
      1. - each of which is adjusted to form a square with a side equal - to the radius of the circle on the background; -
      2. -
      3. - then transformed to represent a portion of the circle according to - the number of elements — specified with --items — using - - a trick shared by Sara Soueidan on Codrops, -
      4. -
      5. each one is decorated with a border at the bottom;
      6. -
      7. - then we use again clip-path polygon() function - on each direct child <span> —  extended to occupy the whole surface - of its parent <td> — in order to form a triangle, based for one side - on the ratio value of the current element / scale, and on another side a ratio based on the - value of the next element (yum calc()) - — but on another scale… -
      8. -
      9. - because to compensate for the distortion - due to the skew() function, - we need to correct the scale on which the second ratio is calculated - using a little trigonometry: -
          -
        • - we know one side of the right-angled triangle obtained after the deformation, - as well as two angles — the right one, of course, and we deduce - the second from the angle used to deform the element; -
        • -
        • - so we can calculate the hypothenuse using the sine law, - — as before in the pie chart; -
        • -
        • - and finally, all we have to do is calculate the ratio between the initial dimension - — the side — and the final dimension — the hypothenuse — - and apply this ratio to the scale on which the second point of the polygon is placed. -
        • -
        -
      10. -
      11. - The third point of the polygon is the bottom right corner, whose coordinates are - 100% 100%; -
      12. -
      -
    • - one last trick is necessary to close the shape you have seen, - we use the current and next value for each element. But when we get to the last element, - there is no next! So we need to add a value, to which we assign - the first value — in this example, --8: var(--1);. -
    • -
    - -

    And that's it!

    - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Level of interest by domain, out of 20
    AccessibilitySEOPerformanceCompatibilitySecurityCode qualityTest
    1411131610124
    -
    - -
    - HTML -
    {% include 'includes/_radar-markup.html' %}
    -
    -
    - css -
    {% include 'includes/_radar-styles.html' %}
    -
    -
    - A Chromium bug -

    - There is currently a bug in Chromium — I filled - an issue on bugs.chromium.org — - when using the border-spacing property on the table: - it prevents Chrome to define the dimensions of the table… - For Chrome user, use the inspector to uncheck this property on the - <table> tag of these examples! -

    -

    Reduced test case

    -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Level of interest by domain, out of 20
    AccessibilitySEOPerformanceCompatibilitySecurityCode qualityTest
    1411131610124
    -
    -
    -
    - A Firefox feature -
    - The skew() function deforms the element by tilting it. -
    - Screenshot of the deformation caused by skew() - – props to Patrick Brosset - who made CSS - transform Highlighter happen in Firefox DevTools. -
    -
    -
    - - -

    Overlapping radars

    - -

    Very few changes compared to the previous version:

    - -
      -
    1. - the <table> element no longer carries the values, - but has a new --areas custom property to indicate the number of rows in the table; -
    2. -
    3. - however we multiply the number of rows in the body of the table: -
        -
      • - each one carries several variables: - --color then the values — --1, etc.; -
      • -
      • - and contains several cells: a <th scope="row"> row header cell - and <td> data cells; -
      -
    4. -
    5. - the rest is relatively common now — if you've gone through the previous examples: -
        -
      1. - a color for each row, presented on the header cells - and serving as a background for the data cells; -
      2. -
      3. - a distinctive hover effect over each row: the values appear - verbatim on hovering, and the hovered row is highlighted. In order not to deprive users - who do not have a good hover pointer, this effect is a progressive enhancement - based on the @media (hover: hover) { … } media query. -
      4. -
      -
    6. - -
    - -
    -
    -

    - Switch
    - Allows you to disable styles on the following table. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Level of interest by domain, out of 20
    AccessibilitySEOPerformanceCompatibilitySecurityCode qualityTest
    Gaël1411131614104
    Luc18101116101211
    -
    - -
    - HTML -
    {% include 'includes/_radars-markup.html' %}
    -
    -
    - css -
    {% include 'includes/_radars-styles.html' %}
    -
    -{% endblock %} diff --git a/src/templates/radar.html b/src/templates/radar.html deleted file mode 100644 index e940f68..0000000 --- a/src/templates/radar.html +++ /dev/null @@ -1,345 +0,0 @@ -{% extends "accueil.html" %} - -{% block meta %} - Radar — chaarts - - - - - - -{% endblock %} - -{% block navigation %} - -{% endblock %} - -{% block main %} -

    Graphique radar

    - -

    - Celui-ci est plutôt amusant. On définit quelques variables - CSS sur le tableau -  : l’échelle (et les paliers), le nombre d’éléments, et les valeurs. -

    - -

    - Côté CSS, ça se complique : -

    - -
      -
    • - sur l’élément <table>, on crée l’échelle circulaire à l’aide de deux - repeating-radial-gradient() successifs — en fonction des variables - --scale et --step ; -
    • -
    • - chaque élément <th> est déplacé à l’extérieur du cercle ainsi formé, - grâce à une technique empruntée à - - Ana Tudor, qui l’explique sur StackOverflow ; -
    • -
    • - puis — toujours sur les cellules d’entête — la valeur correspondant à chaque colonne - est affichée dans un pseudo-élément ::after à l’aide - d’une - astuce de Cassie Evans, utilisant counter-reset et counter() - pour afficher une variable numérique dans la propriété content. - Cependant counter-reset ne fonctionne qu’avec un entier et notre valeur peut être un nombre. Alors on s’appuie sur - une ruse de - Carter Li utilisant calc() pour convertir les nombres en entiers — et - @property pour les navigateurs basés sur Chromium. Boum ! -
    • - Puis la magie opère sur les éléments <td> : -
        -
      1. - chacun est ajusté pour former un carré dont le côté est égal au rayon - du cercle en arrière-plan ; -
      2. -
      3. - puis transformé de façon à représenter une portion du cercle en fonction du nombre - d’éléments — précisé avec --items — grâce à - - une technique partagée par Sara Soueidan sur Codrops, -
      4. -
      5. chacun se voit décoré d’une bordure, en bas ;
      6. -
      7. - puis on utilise de nouveau clip-path et la fonction polygon() - sur chaque enfant direct <span> — étendu pour occuper toute la surface - de son <td> de parent — afin de former un triangle, basé pour un côté - sur le ratio valeur de l’élément courant / échelle, et sur un autre côté un ratio basé sur - la valeur de l’élément suivant (miam les calc()) - — mais sur une autre échelle… -
      8. -
      9. - car pour compenser la distorsion due à la fonction skew(), - nous devons corriger l’échelle sur laquelle est calculée le second ratio à l’aide d’un peu - de trigonométrie : -
          -
        • - nous connaissons un côté du triangle rectangle obtenu après la déformation, - ainsi que deux angles — le droit, bien entendu, et nous déduisons le deuxième de - l’angle utilisé pour déformer l’élément ; -
        • -
        • - nous pouvons donc calculer l’hypothénuse en utilisant la loi des sinus, - — comme précédemment dans le graphique en tarte ; -
        • -
        • - et finalement, il ne nous reste qu’à calculer le ratio entre la dimension initiale - — le côté — et la dimension finale — l’hypothénuse — et appliquer ce ratio - à l’échelle sur laquelle est placée le deuxième point du polygone. -
        • -
        -
      10. -
      11. - le troisième point du polygône est l’angle en bas à droite, dont les coordonnées sont - 100% 100% ; -
      12. -
      -
    • - une dernière astuce est nécessaire pour fermer la forme  vous l’avez vu, nous utilisons - la valeur courante et la valeur suivante pour chaque élément. Mais arrivé au dernier élément, - il n’y a plus de suivant ! Il faut donc ajouter une valeur, - à laquelle on attribue la première valeur — dans cet exemple, --8: var(--1);. -
    • -
    - -

    Et voilà, c’est tout !

    - -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Niveau d’intérêt par domaine, sur 20
    AccessibilitéRéférencementPerformanceCompatibilitéSécuritéQualité de codeTest
    1411131610124
    -
    - -
    - Le HTML -
    {% include 'includes/_radar-markup.html' %}
    -
    -
    - Le css -
    {% include 'includes/_radar-styles.html' %}
    -
    -
    - Bug dans Chromium -

    - Il y a en ce moment un bug dans Chromium — j’ai saisi - un ticket sur bugs.chromium.org — - lors de l’utilisation de la propriété border-spacing sur le tableau : - cela empêche Chrome de définir les dimensions du tableau… - Pour les utilisateurs de Chrome, utilisez l’inspecteur pour décocher cette propriété - sur la balise <table> de ces exemples ! -

    -

    Cas de test réduit

    -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    Niveau d’intérêt par domaine, sur 20
    AccessibilitéRéférencementPerformanceCompatibilitéSécuritéQualité de codeTest
    1411131610124
    -
    -
    -
    - Une fonctionnalité Firefox -
    - La fonction skew() déforme l’élément en l’inclinant. -
    - Capture d’écran de la déformation provoquée par skew() - – merci à Patrick Brosset - qui a mis en place la - prévisualisation des transformations CSS dans les outils de développement de Firefox. -
    -
    -
    - - -

    Radars superposés

    - -

    Très peu de changements par rapport à la version précédente :

    - -
      -
    1. - l’élément <table> ne porte plus les valeurs, mais dispose d’une nouvelle - variable --areas pour indiquer le nombre de lignes dans le tableau ; -
    2. -
    3. - en revanche on multiplie le nombre de lignes dans le corps du tableau : -
        -
      • - chacune porte plusieurs variables : - --color puis les valeurs — --1, etc. ; -
      • -
      • - et contient plusieurs cellules : une d’entête de ligne <th scope="row"> - et des cellules de données <td> ; -
      -
    4. -
    5. - le reste est relativement commun désormais — si vous avez parcourus les exemples précédents : -
        -
      1. - une couleur pour chaque ligne, présentée sur les cellules d’entête et servant d’arrière-plan aux - cellules de données ; -
      2. -
      3. - un effet distinctif au survol de chaque ligne : les valeurs apparaissent - textuellement au survol, et la ligne survolée est mise en exergue. Afin de ne pas priver les utilisateurs - n’ayant pas de pointeur doué pour le survol, cet effet est une amélioration progressive - basé sur la media query @media (hover: hover) { … }. -
      4. -
      -
    6. - -
    - -
    -
    -

    - Interrupteur
    - Permet de désactiver les styles sur le tableau suivant. -

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Niveau d’intérêt par domaine, sur 20
    AccessibilitéRéférencementPerformanceCompatibilitéSécuritéQualité de codeTest
    Gaël1411131614104
    Luc18101116101211
    -
    - -
    - Le HTML -
    {% include 'includes/_radars-markup.html' %}
    -
    -
    - Le css -
    {% include 'includes/_radars-styles.html' %}
    -
    -{% endblock %} diff --git a/tasks/compile.js b/tasks/compile.js deleted file mode 100644 index d5bb1ca..0000000 --- a/tasks/compile.js +++ /dev/null @@ -1,44 +0,0 @@ -const gulp = require('gulp'); -const sass = require('gulp-dart-sass'); -const maps = require('gulp-sourcemaps'); -const csso = require('gulp-csso'); -const prefix = require('gulp-autoprefixer'); -const rename = require('gulp-rename'); -const newer = require('gulp-newer'); -const babel = require('gulp-babel'); -const uglify = require('gulp-uglify'); -const options = require('./options'); - -function js() { - return gulp.src(options.paths.root + 'script.js') - .pipe(newer(options.paths.root + 'script.min.js')) - .pipe(babel(options.babel)) - .pipe(uglify().on('error', function(err) { - console.error(`${err.cause.message} in ${err.cause.filename} at line ${err.cause.line}`); - this.emit('end'); - })) - .pipe(rename({suffix: '.min'})) - .pipe(gulp.dest(options.paths.root)); -} - -function css() { - return gulp.src(options.paths.root + 'sass/*.scss') - .pipe(newer(options.paths.root + 'chaarts.css')) - .pipe(sass({outputStyle: 'expanded'}).on('error', sass.logError)) - .pipe(prefix(options.browsers)) - .pipe(gulp.dest(options.paths.root)); -} - -function mincss() { - return gulp.src(options.paths.root + 'sass/*.scss') - .pipe(newer(options.paths.root + 'chaarts.min.css')) - .pipe(maps.init()) - .pipe(sass({outputStyle: 'compressed'}).on('error', sass.logError)) - .pipe(prefix(options.browsers)) - .pipe(csso(options.csso)) - .pipe(rename({suffix: '.min'})) - .pipe(maps.write()) - .pipe(gulp.dest(options.paths.root)); -} - -module.exports = gulp.parallel( js, css, mincss ); diff --git a/tasks/docs.js b/tasks/docs.js deleted file mode 100644 index 237c447..0000000 --- a/tasks/docs.js +++ /dev/null @@ -1,70 +0,0 @@ -const fs = require('fs'); -const gulp = require('gulp'); -const nunjucks = require('gulp-nunjucks-render'); -const newer = require('gulp-newer'); -const data = require('gulp-data'); -const babel = require('gulp-babel'); -const uglify = require('gulp-uglify'); -const imgmin = require('gulp-imagemin'); -const sass = require('gulp-dart-sass'); -const maps = require('gulp-sourcemaps'); -const csso = require('gulp-csso'); -const prefix = require('gulp-autoprefixer'); -const rename = require('gulp-rename'); -const purge = require('gulp-purgecss'); -const options = require('./options'); - -function move() { - return gulp.src(options.files) - .pipe(gulp.dest(options.paths.docs)) -} - -function script() { - return gulp.src(options.paths.root + 'script.min.js') - .pipe(gulp.dest(options.paths.docs + 'js')) -} - -function js() { - return gulp.src(options.paths.src + 'js/**/*.js') - .pipe(newer(options.paths.docs + 'js')) - .pipe(babel(options.babel)) - .pipe(uglify().on('error', function(err) { - console.error(`${err.cause.message} in ${err.cause.filename} at line ${err.cause.line}`); - this.emit('end'); - })) - .pipe(rename({suffix: '.min'})) - .pipe(gulp.dest(options.paths.docs + 'js')); -} - -function css() { - return gulp.src(options.paths.src + 'scss/*.scss') - .pipe(newer(options.paths.docs + 'css')) - .pipe(maps.init()) - .pipe(sass({ - includePaths: [options.paths.node] - }).on('error', sass.logError)) - .pipe(prefix(options.browsers)) - .pipe(csso(options.csso)) - //.pipe(purge(options.purge)) - .pipe(rename({suffix: '.min'})) - .pipe(maps.write()) - .pipe(gulp.dest(options.paths.docs + 'css')); -} - -function img() { - return gulp.src(options.paths.src + 'img/*') - .pipe(newer(options.paths.docs + 'img')) - .pipe(imgmin({verbose: true})) - .pipe(gulp.dest(options.paths.docs + 'img')); -} - -function template() { - return gulp.src([ - options.paths.src + 'templates/**/*.html', - '!' + options.paths.src + 'templates/macros/*.html' - ]) - .pipe(nunjucks(options.nunjucks)) - .pipe(gulp.dest(options.paths.docs)); -} - -module.exports = gulp.series( script, move, gulp.parallel( css, img, js, template ) ); diff --git a/tasks/lint.js b/tasks/lint.js deleted file mode 100644 index eaf4ff2..0000000 --- a/tasks/lint.js +++ /dev/null @@ -1,16 +0,0 @@ -const gulp = require('gulp'); -const eslinter = require('gulp-eslint'); -const linter = require('gulp-stylelint'); -const options = require('./options'); - -function eslint() { - return gulp.src(options.paths.root + 'script.js') - .pipe(eslinter()); -} - -function stylelint() { - return gulp.src(options.paths.root + 'sass/**/*.scss') - .pipe(linter(options.stylelint)); -} - -module.exports = gulp.parallel( eslint, stylelint ); diff --git a/tasks/options.js b/tasks/options.js deleted file mode 100644 index 8d99fa9..0000000 --- a/tasks/options.js +++ /dev/null @@ -1,72 +0,0 @@ -module.exports = { - paths: { - root: './', - docs: './docs/', - src: './src/', - node: './node_modules/', - live: 'http://localhost:3000/' - }, - test: { - all: './docs/*.html', - arr: [ - './docs/index.html', - './docs/pie-charts.html', - './docs/bar-charts.html', - './docs/column-charts.html', - './docs/line-charts.html', - './docs/radar-charts.html' - ], - css: './chaarts.css', - live: 'http://localhost:3000/index.html', - home: './docs/index.html', - pie: './docs/pie-charts.html' - }, - files: [ - './src/favicon.ico', - './src/humans.txt', - './src/fonts/*.{woff,woff2}' - ], - browsers: [ - 'last 1 versions', - 'not dead' - ], - babel: { - presets: ['@babel/env'] - }, - csso: { - sourceMap: false - }, - purge: { - content: ['./docs/*.html'], - whitelistPatterns: [/^no-|^grid-|^token|^line-|^ml-/] - }, - nunjucks: { - path: './src/templates/' - }, - svgo: { - plugins: [{ - removeUnknownsAndDefaults: false - }] - }, - axe: { - saveOutputIn: 'axe.json', - folderOutputReport: 'reports', - urls: ['./docs/*.html'] - }, - stylelint: { - failAfterError: false, - reporters: [{ - formatter: 'string', - console: true - }] - }, - travis: { - stylelint: { - failAfterError: true, - reporters: [{ - formatter: 'string', - console: true - }] - } - } -} diff --git a/tasks/sri.js b/tasks/sri.js deleted file mode 100644 index a07484f..0000000 --- a/tasks/sri.js +++ /dev/null @@ -1,11 +0,0 @@ -const gulp = require('gulp'); -const hash = require('gulp-sri-hash'); -const options = require('./options'); - -function sri() { - return gulp.src(options.test.all) - .pipe(hash()) - .pipe(gulp.dest(options.paths.docs)); -} - -module.exports = sri; diff --git a/tasks/tests.js b/tasks/tests.js deleted file mode 100644 index 63007f6..0000000 --- a/tasks/tests.js +++ /dev/null @@ -1,74 +0,0 @@ -const fs = require('fs'); -const gulp = require('gulp'); -const options = require('./options'); -const html = require('html-validator'); -const symbols = require('log-symbols'); -const chalk = require('chalk'); - -function displayTest(test) { - let symbol; - switch(test.status) { - case 'error': - case false: - symbol = symbols.error; - break; - case 'warning': - symbol = symbols.warning; - break; - case 'info': - symbol = symbols.info; - break; - case true: - default: - symbol = symbols.success; - } - - console.log(chalk`${symbol} {white ${test.name}} ${test.value}`) -} - -/** - * HTML Validation - */ -function markup(done) { - for (let page in options.test.arr) { - fs.readFile(options.test.arr[page], 'utf8', (error, response) => { - if (error) { - throw error; - } - - html({data: response}) - .then(data => { - console.log(chalk.cyan(`File to test: ${options.test.arr[page]}`)) - - let messages = JSON.parse(data); - let results = messages.messages.reduce((results, value, key) => { results[key] = value; return results; }, {}); - let errors = 0; - - for (let result in results) { - let test = new Object(results[result]); - if ('error' === results[result].type && ! results[result].message.includes('--') ) { - errors++; - test.status = results[result].type; - test.name = results[result].message; - if (!results[result].firstLine) { - test.firstLine = results[result].lastLine; - } - test.value = `From line ${results[result].firstLine}, column ${results[result].firstColumn}; to line ${results[result].lastLine}, column ${results[result].lastColumn}`; - displayTest(test) - } - } - - if (0 === errors) { - console.log(chalk`${symbols.success} {green The HTML document validates according to the W3C}`); - } - }) - .catch(error => { - console.error(error) - }) - }); - - } - done(); -} - -module.exports = gulp.parallel( markup );