From 4245adced4edba3e516823a71bc2e0419398bf67 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Tue, 7 Nov 2023 17:34:58 +0100 Subject: [PATCH 01/66] Fix: Update locales and add floating options for images --- djangocms_frontend/contrib/image/forms.py | 6 +- .../contrib/image/frameworks/bootstrap5.py | 6 +- .../locale/ar/LC_MESSAGES/django.mo | Bin 3599 -> 3599 bytes .../locale/de/LC_MESSAGES/django.mo | Bin 28086 -> 28083 bytes .../locale/es/LC_MESSAGES/django.mo | Bin 28066 -> 28031 bytes .../locale/fr/LC_MESSAGES/django.mo | Bin 29617 -> 29566 bytes .../locale/fr/LC_MESSAGES/django.po | 128 +++++++++--------- .../locale/nl/LC_MESSAGES/django.mo | Bin 13054 -> 14412 bytes .../locale/nl/LC_MESSAGES/django.po | 116 ++++++++-------- .../locale/sq/LC_MESSAGES/django.mo | Bin 24671 -> 24639 bytes 10 files changed, 132 insertions(+), 124 deletions(-) diff --git a/djangocms_frontend/contrib/image/forms.py b/djangocms_frontend/contrib/image/forms.py index 82fe6acf..32dd2777 100644 --- a/djangocms_frontend/contrib/image/forms.py +++ b/djangocms_frontend/contrib/image/forms.py @@ -22,8 +22,8 @@ def get_alignment(): settings, "DJANGOCMS_PICTURE_ALIGN", ( - ("start", _("Align left")), - ("end", _("Align right")), + ("start", _("Float left")), + ("end", _("Float right")), ("center", _("Align center")), ), ) @@ -42,7 +42,7 @@ def get_templates(): return choices -# required for backwards compability +# required for backwards compatibility PICTURE_ALIGNMENT = get_alignment() diff --git a/djangocms_frontend/contrib/image/frameworks/bootstrap5.py b/djangocms_frontend/contrib/image/frameworks/bootstrap5.py index 4cf5529c..c425d99f 100644 --- a/djangocms_frontend/contrib/image/frameworks/bootstrap5.py +++ b/djangocms_frontend/contrib/image/frameworks/bootstrap5.py @@ -11,7 +11,11 @@ def render(self, context, instance, placeholder): ) context["img_srcset_data"] = instance.img_srcset_data if instance.alignment: - instance.add_classes(f"align-{instance.alignment}") + # See https://getbootstrap.com/docs/5.2/content/images/#aligning-images + if instance.alignment != "center": + instance.add_classes(f"float-{instance.alignment}") + else: + instance.add_classes("mx-auto d-block") if instance.picture_fluid: instance.add_classes("img-fluid") if instance.picture_rounded: diff --git a/djangocms_frontend/locale/ar/LC_MESSAGES/django.mo b/djangocms_frontend/locale/ar/LC_MESSAGES/django.mo index 8ce2507894996119be8391f8a2a23c5194fb6ff9..16b41d8fed1b89514efdf56b8400d15ca2caf7d5 100644 GIT binary patch delta 29 kcmeB|>6h7XmW{_JF)zI|F+J5vA+c!k8Mf%nChWJ_0HW&(#sB~S delta 29 kcmeB|>6h7XmTmGawkRH-#Ju#<#Pn1vg~X!G#_V_40I5g{(*OVf diff --git a/djangocms_frontend/locale/de/LC_MESSAGES/django.mo b/djangocms_frontend/locale/de/LC_MESSAGES/django.mo index eebaa4fed437a9e0aeeb03516118a6474436915c..cd317c59b971b1d5a81dfee448ac07bcd3053952 100644 GIT binary patch delta 5464 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 J9WK4?_dl?Dm}~$5 diff --git a/djangocms_frontend/locale/es/LC_MESSAGES/django.mo b/djangocms_frontend/locale/es/LC_MESSAGES/django.mo index febbfa1524c8175bb03d30cbaaa1e07f7869a782..ae3339509afc67701d3323d72bfc494cc4b997fb 100644 GIT binary patch delta 6262 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 G9`ZjB^3d@B delta 6295 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 diff --git a/djangocms_frontend/locale/fr/LC_MESSAGES/django.mo b/djangocms_frontend/locale/fr/LC_MESSAGES/django.mo index 88b73c1298c21a389890c6bc3bb1d1e5b53f0773..a1adc73ef6d91a0aec6138184f40f891630f1d82 100644 GIT binary patch delta 7875 zcmYk>2YgTG9>?(~QzS+rMu;>)5<%=0L=YP$*VhWdHj9T!*!{I_cFsZ%EOrQ zI4i)ITcq!lR;e*_UofT}&O`n)U-M59`~!pVnKdZfn8M^MVKJKWl)XZjBm!W39+17t(^ZRZ72zpch z8T#QFo6kp0L?kt_gzu# z4o0;%0(BO~q9!;UeQ;?M>#vShQlOcxMm4w@)!;7F%nzWJ{xquL%Qk-#HK6<04!xqC z0dz#Q)7R#Qq6RV^HGo&J1}=(b{Z(<80(E#CwWnuLdwCNzqXKMjY+7%Bx_gH5)DAjWGrf66R|K(v*mNK zKl#_t2Y*3LqyTllS2bsb{-}Hy`e7t$0M#)-ixN-5pMoT77t{>WQA?O*9fxXYDhA+8 zTfPW2uoc#I*7vP@tVd7-{1nyx1@zUX+#;dVd>1uyuUKc~rBDyVpeM$mR-_54!{(@g zx3~FjSe<--?1--+|Cx*YGZy`*WcAGyJct|7M~7k%N3kdlM=j+9tcO!k9qdGPd=RyV zM=<~kZ2dDVMc%)r(@q3xscT>|HpJpM6E*N0)XJ_#mkKu8itSj8{C?D1a1!-pyKM9K zF_?U@T26-*Q3HuXO`sL3O0T3wkD${m}c{?fh4qa z!>~GLV?3_IRJ?>b3pE=!Gi-zEa1?4r<86ML&CkXt$`_#qz6Z5M2T;%HAT$C$T%h+q zk%VqMjoOoQ7>t)uOI={=AD|le8@*d3SPNX)^f z*jVrX5{9D{IECSuk6PLX*b$TX@T-I6SQ=NOX1*IW@I$D9=2=hL@-I;Ber@xYQSID7 zP2`U1_5R-@k%*>=(_l-~X>Etv%kHQLHlt>~1Kk5a&GZlk;R)10F4+1@s19$T+PjO{ z_!wK`i|n&Yd$Wf`3w(qz7|%}*CT}uO9jrxlumv^a1E}xBQRF=i<;3!)D~<- z4LlbI;y!GPWobk!Fc3A6QK;u8qVAt+o$j)US=PDMg}B0l8KU+orj;|G(WsehK+SBo z&7VN6$a&Nuy=Hxg<;e%qh$d1Ut72V@MOQir-YByGS#6VtJYziDI7`|V*(eX%AELq1|=1^VDAR7YRo zWW0`bFr5R$3uKmH89aqr^6S_W@1nM{ZF}0pSFjJ>KySVOEs~ujYlC4_^ut3q1--FR z2V*K=0&2zsPy-r+dJ86^?wgH%xWLxGfknu#vgPlg_I?NY;%-U*<^T!J>|;~|=j;tX zpgO#c+S5N#dtQXEQY{Qeo#Ir~jMGu~4M%n0LJf2_7Quz6rGL}b??;zL{*k@mnDr}k ze}b_h^#%9>mhR-dCG|0cd{cCPTCo@Tk*EP4Lk%b&HL+`02=8Gje1aSwQzC`+R|CEH z-fHhhqdJ_7n)%zPfo#Lhc+{4cOm#YlLUmjdHRE~K#TY<-1!~6Y@mzhV)ImvW1O}0hMV*BN)Y7%Zl9+WhFBx4G1gkBm5xKT z+t(>~nJf~eC>V#@`}wFFw>dYMv*=0w0%|7TqXzt=^&XZW@6*HiqJ`if@~u&Oy%|^F z6|9Go_$a)A+t5eveHdDb(SO#UKj4=eMNN-I_$wPI~iOWy}| zn1|yC%tkHwCDg$0qwe$LD^!^NO(`WX9Mw=2)TwQXT9JO%>DKkua`zvtC6l`BTimz<$ni6R;Ke z`B)myp!WKv^)J+beAAusqUo%^mOP9CEmewRN@nJ1ZM+ZG$>%sn`&Q_IGg-Nvxqj-}uKEhG7Hvl^UC%2Dlg1@jD$dKh)zG4#Q67=_=V>h;%$PIngz5fSEa4^kj z)Pu2XtWIqmWE)K)YRNaCI{W}NfLzpDa~$>7O|qNALAFs71^L9M`K^v7u!fb(qmGSsPGg&Oz{ zjKVy0X@<8+cwzEre!s&M)Sf*;o!U|_I)^b9)!`h}7cC$E!r!q8{`8VFk;pO5z+XnK z%q)z+l~@7yqgLwT7}j4S{gDFA^jFmBe257cKh~M?6x0K+qPAcj2H|4Vz~4pQT(b!~ zpl`PGTo+XPy-+KZfx3T$b#yjIR0U&g!368e=s~&r%Bc_;`lWkcp>As|Y$1sc|hB(DcRncQETKzZl46v%A)b)#het4iXh*asiV`=7F4XNt=W_aY zJ}Fczq4Wz|6--`NI$pq%m|)AkB;SK{OXQHbuV&=ylbTC}+WT5rojaWOZa8K4Dd>%* zUG|1f&+ovcM2gLKqJA~$=|mcFn5a$!QT`T=z+*U%_?fs&455q@>;3_dgSv(g=iMnz zB=whUI`f20q*ADtQ9m8*qL`YLwI_5H!3vm3#1o$p*NBZo4eACFX+&M}LkV5K5ML9i z#EzV+WrJP&NzEd3Jtn3RgO%ZWNc@-RNYo;h5zC1c#7g2#q6%@Ec!8dD{hQe7PVqKV zR$$Yj3^Bvz6RF#xiEXD~D49ZpH=!$t=t;UA5lz$~^chIPDL5E=;3tHxcZhD3=?CKT zOK)`XF`xBXZL~HwSMbdo~Hs2H%k=Iqtmc2rH zK5>`$hWM1w^(s-3dtS$xgg@yCSQ$%WB<{jY4AlF)kjxn(f^=~lNxVnI5>=I_{Q314 zi7fK^-;^KO!qL_ZSk0yfQa{_KqcGziZ9F3Xqpfr4C;mC2Fp*DqaAOO?k4PsUj>U;h zr2imv&2cckls6)Jkq@k-edqwWNsuHfe-Sd8dE z{D)}F&Ev2>Hu=YcYbn!}O)PMy_+!kv)yj+O{?nz1&3}j!iOn`I;s{Uu(0E`AOQ;hf zC$&|0?ui%Lh2@rwzfr+6W74kl`CguxqjMJyjP>*Bl9f3mBlk$=c#oVJDJ64LM-KG+ E9|eS99smFU delta 7963 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 qibiJF^YiUGK5yEzoT)`C@@9DWcFi7, YEAR. -# +# # Translators: # Adrien Delhorme, 2023 -# +# #, fuzzy msgid "" msgstr "" @@ -15,12 +15,11 @@ msgstr "" "PO-Revision-Date: 2023-01-20 15:48+0000\n" "Last-Translator: Adrien Delhorme, 2023\n" "Language-Team: French (https://app.transifex.com/divio/teams/58664/fr/)\n" -"Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % " -"1000000 == 0 ? 1 : 2;\n" +"Language: fr\n" +"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #: common/attributes.py:9 msgid "" @@ -54,10 +53,11 @@ msgstr "Opacité du fond" #: common/bootstrap5/background.py:62 msgid "Opacity of card background color (only if no outline selected)" msgstr "" -"Opacité de la couleur de fond de l'encart (uniquement si aucun contour n'est " -"sélectionné)" +"Opacité de la couleur de fond de l'encart (uniquement si aucun contour n'est" +" sélectionné)" -#: common/bootstrap5/background.py:66 contrib/alert/frameworks/bootstrap5.py:42 +#: common/bootstrap5/background.py:66 +#: contrib/alert/frameworks/bootstrap5.py:42 msgid "Shadow" msgstr "Ombre" @@ -104,7 +104,8 @@ msgstr "Hauteur" #: common/bootstrap5/sizing.py:60 msgid "" -"Sets the vertical size relative to the surrounding container or the viewport." +"Sets the vertical size relative to the surrounding container or the " +"viewport." msgstr "" "Définit la hauteur par rapport au conteneur ou à la fenêtre d'affichage." @@ -114,11 +115,11 @@ msgstr "Veuillez choisir un côté sur lequel l'espacement doit être appliqué. #: common/spacing.py:113 msgid "Margin" -msgstr "Marge interne (margin)" +msgstr "Marge externe (margin)" #: common/spacing.py:139 common/spacing.py:147 msgid "Padding" -msgstr "Marge externe (padding)" +msgstr "Marge interne (padding)" #: common/spacing.py:175 contrib/utilities/cms_plugins.py:22 #: contrib/utilities/models.py:14 @@ -142,9 +143,9 @@ msgid "" "Select only devices on which the margin should be applied. On other devices " "larger than the first selected device the margin will be set to zero." msgstr "" -"Sélectionnez uniquement les équipements sur lesquels les marges doivent être " -"affichées. Sur les autres équipements plus grands que le premier équipement " -"sélectionné, les marges seront mises à zéro." +"Sélectionnez uniquement les équipements sur lesquels les marges doivent être" +" affichées. Sur les autres équipements plus grands que le premier équipement" +" sélectionné, les marges seront mises à zéro." #: common/spacing.py:221 msgid "Horizontal padding" @@ -160,8 +161,8 @@ msgstr "Afficher les marges internes sur les équipements suivants" #: common/spacing.py:236 msgid "" -"Select only devices on which the padding should be applied. On other devices " -"larger than the first selected device the padding will be set to zero." +"Select only devices on which the padding should be applied. On other devices" +" larger than the first selected device the padding will be set to zero." msgstr "" "Sélectionnez uniquement les équipements sur lesquels les marges internes " "doivent être affichées. Sur les autres équipements plus grands que le " @@ -177,8 +178,8 @@ msgstr "Titre" #: common/title.py:67 msgid "" -"Optional title of the plugin for easier identification. Its title attribute will only be set if the checkbox is selected." +"Optional title of the plugin for easier identification. Its " +"title attribute will only be set if the checkbox is selected." msgstr "" "Titre optionnel du plugin pour l'identifier. L'attribut title " "sera défini uniquement si la case est cochée." @@ -235,8 +236,8 @@ msgstr "Intégrer au parent" #: contrib/accordion/forms.py:52 msgid "" -"Removes the default background-color, some borders, and some rounded corners " -"to render accordions edge-to-edge with their parent container " +"Removes the default background-color, some borders, and some rounded corners" +" to render accordions edge-to-edge with their parent container " msgstr "" "Supprimer la couleur de fond, les bordures et les coins arrondis pour " "afficher l'accordéon sur toute la largeur du conteneur parent" @@ -397,10 +398,11 @@ msgstr "Occuper toute la hauteur" #: contrib/card/forms.py:152 msgid "" -"If checked cards in one row will automatically extend to the full row height." +"If checked cards in one row will automatically extend to the full row " +"height." msgstr "" -"Lorsque cette case est cochée, les encarts sur une ligne occuperont toute la " -"hauteur de la ligne." +"Lorsque cette case est cochée, les encarts sur une ligne occuperont toute la" +" hauteur de la ligne." #: contrib/card/forms.py:186 msgid "Inner type" @@ -447,7 +449,7 @@ msgstr "Par défaut" #: contrib/carousel/constants.py:36 msgid "Slide" -msgstr "Glisser" +msgstr "Slide" #: contrib/carousel/constants.py:37 contrib/tabs/constants.py:21 msgid "Fade" @@ -469,8 +471,8 @@ msgstr "Intervalle" #: contrib/carousel/forms.py:67 msgid "" -"The amount of time to delay between automatically cycling an item. If false, " -"carousel will not automatically cycle." +"The amount of time to delay between automatically cycling an item. If false," +" carousel will not automatically cycle." msgstr "" "Le délai avant le défilement automatique d'un slide. Indiquez 0 pour ne pas " "que les slides défilent automatiquement." @@ -742,8 +744,8 @@ msgid "" "should fill the full width without margins or padding." msgstr "" "Définit si la grille doit utiliser une largeur fixe, une largeur fluide ou " -"si le conteneur doit remplir toute la largeur sans marges externes ni marges " -"internes." +"si le conteneur doit remplir toute la largeur sans marges externes ni marges" +" internes." #: contrib/grid/forms.py:97 msgid "Create columns" @@ -780,8 +782,8 @@ msgstr "Alignement de la colonne" msgid "" "Column size needs to be empty, \"auto\", or a number between 1 and %(cols)d" msgstr "" -"La taille de la colonne doit être vide, \"auto\", ou un nombre compris entre " -"1 et %(cols)d" +"La taille de la colonne doit être vide, \"auto\", ou un nombre compris entre" +" 1 et %(cols)d" #: contrib/grid/models.py:29 msgid "GridContainer" @@ -958,16 +960,15 @@ msgid "" "them into view. " msgstr "" "À utiliser pour les images situées en dessous de la limite de « scroll ». " -"Chargera les images seulement si le visiteur les fait apparaître en défilant " -"dans la page." +"Chargera les images seulement si le visiteur les fait apparaître en défilant" +" dans la page." #: contrib/image/forms.py:131 msgid "Width" msgstr "Largeur" #: contrib/image/forms.py:135 -msgid "" -"The image width as number in pixels. Example: \"720\" and not \"720px\"." +msgid "The image width as number in pixels. Example: \"720\" and not \"720px\"." msgstr "" "La largeur de l'image en pixels. Un nombre (sans unité), par exemple : " "\"720\"." @@ -977,8 +978,7 @@ msgid "Height" msgstr "Hauteur" #: contrib/image/forms.py:143 -msgid "" -"The image height as number in pixels. Example: \"720\" and not \"720px\"." +msgid "The image height as number in pixels. Example: \"720\" and not \"720px\"." msgstr "" "La hauteur de l'image en pixels. Un nombre (sans unité), par exemple : " "\"720\"." @@ -1019,7 +1019,8 @@ msgstr "Recadrer l'image" #: contrib/image/forms.py:179 msgid "" -"Crops the image according to the thumbnail settings provided in the template." +"Crops the image according to the thumbnail settings provided in the " +"template." msgstr "" "Recadre l'image d'après les paramètres de miniature fournis dans le gabarit " "de la page." @@ -1041,8 +1042,8 @@ msgstr "Image « responsive »" #: contrib/image/forms.py:194 msgid "" -"Uses responsive image technique to choose better image to display based upon " -"screen viewport. This configuration only applies to uploaded images " +"Uses responsive image technique to choose better image to display based upon" +" screen viewport. This configuration only applies to uploaded images " "(external pictures will not be affected). " msgstr "" "Utilise la technique de l'image « responsive » pour choisir la meilleure " @@ -1091,11 +1092,12 @@ msgid "" "You have given more than one external, internal, or file link target. Only " "one option is allowed." msgstr "" -"Seulement un champ parmi : lien externe, lien interne, lien vers un fichier, " -"doit être rempli." +"Seulement un champ parmi : lien externe, lien interne, lien vers un fichier," +" doit être rempli." #: contrib/image/forms.py:255 -msgid "You need to add either an image, or a URL linking to an external image." +msgid "" +"You need to add either an image, or a URL linking to an external image." msgstr "" "Vous devez soit charger une image ou fournir une URL vers une image externe." @@ -1105,8 +1107,8 @@ msgid "" "Invalid cropping settings. You cannot combine \"{field_a}\" with " "\"{field_b}\"." msgstr "" -"Paramètres de recadrage invalides. Vous ne pouvez pas utiliser en même temps " -"\"{field_a}\" et \"{field_b}\"." +"Paramètres de recadrage invalides. Vous ne pouvez pas utiliser en même temps" +" \"{field_a}\" et \"{field_b}\"." #: contrib/jumbotron/cms_plugins.py:31 contrib/jumbotron/models.py:14 msgid "Jumbotron" @@ -1120,8 +1122,8 @@ msgstr "Fluide" msgid "Makes the jumbotron fill the full width of the container or window." msgstr "Le Jumbotron occupe toute la largeur du conteneur ou de la fenêtre." -#: contrib/link/apps.py:7 contrib/link/constants.py:5 contrib/link/models.py:11 -#: contrib/link/models.py:114 +#: contrib/link/apps.py:7 contrib/link/constants.py:5 +#: contrib/link/models.py:11 contrib/link/models.py:114 msgid "Link" msgstr "Lien" @@ -1201,8 +1203,8 @@ msgid "" "Appends the value only after the internal or external link. Do not " "include a preceding \"#\" symbol." msgstr "" -"Ajoute la valeur uniquement après le lien interne ou externe. Ne pas inclure le symbole \"# ;\" qui précède." +"Ajoute la valeur uniquement après le lien interne ou externe. Ne " +"pas inclure le symbole \"# ;\" qui précède." #: contrib/link/forms.py:205 msgid "Email address" @@ -1389,8 +1391,8 @@ msgstr "" #: contrib/navigation/forms.py:106 msgid "Enter brand name or add child plugins for brand icon or image" msgstr "" -"Entrez un nom de marque ou ajoutez des plugins enfants pour afficher un logo " -"ou une image" +"Entrez un nom de marque ou ajoutez des plugins enfants pour afficher un logo" +" ou une image" #: contrib/navigation/models.py:30 msgid "Navigation Link" @@ -1435,8 +1437,8 @@ msgstr "Index" #: contrib/tabs/forms.py:67 msgid "Index of element to open on page load starting at 1." msgstr "" -"Index de l'élément à ouvrir au chargement de la page (en numérotant à partir " -"de 1)." +"Index de l'élément à ouvrir au chargement de la page (en numérotant à partir" +" de 1)." #: contrib/tabs/forms.py:70 msgid "Animation effect" @@ -1500,8 +1502,8 @@ msgid "" "Padding does not have an auto spacing. Either switch to a defined size or " "change the spacing property." msgstr "" -"Les marges internes n'ont pas d'espacement automatique. Il faut soit définir " -"une taille, soit changer la propriété de l'espacement." +"Les marges internes n'ont pas d'espacement automatique. Il faut soit définir" +" une taille, soit changer la propriété de l'espacement." #: contrib/utilities/forms.py:101 settings.py:38 msgid "Heading 1" @@ -1533,8 +1535,8 @@ msgstr "ID" #: contrib/utilities/forms.py:128 msgid "" -"Fill in unique ID for table of contents. If empty heading will not appear in " -"table of contents." +"Fill in unique ID for table of contents. If empty heading will not appear in" +" table of contents." msgstr "" "Remplir un identifiant unique qui sera utile pour la table des matières. Si " "le titre est vide, il n'apparaîtra pas dans la table des matières." @@ -1558,8 +1560,8 @@ msgstr "" msgid "" "Attributes apply to the link for each entry in the table of contents." msgstr "" -"Les attributs s'appliquent au lien pour chaque entrée de la table des " -"matières." +"Les attributs s'appliquent au lien pour chaque entrée de la table des" +" matières." #: contrib/utilities/forms.py:173 msgid "Item attributes" @@ -1570,8 +1572,8 @@ msgid "" "Attributes apply to the list items for each entry in the table of " "contents." msgstr "" -"Les attributs s'appliquent aux élément de liste pour chaque entrée de " -"la table des matières." +"Les attributs s'appliquent aux élément de liste pour chaque entrée de" +" la table des matières." #: fields.py:94 msgid "Please select at least one device size" @@ -1676,8 +1678,7 @@ msgstr "Très très grand" #: helpers.py:112 #, python-brace-format -msgid "" -"Read more in the documentation." +msgid "Read more in the documentation." msgstr "" "Lire la documentation pour en " "savoir plus." @@ -1695,6 +1696,3 @@ msgstr "" #: settings.py:73 msgid "Offcanvas" msgstr "Déroulante" - -#~ msgid "Template" -#~ msgstr "Gabarit" diff --git a/djangocms_frontend/locale/nl/LC_MESSAGES/django.mo b/djangocms_frontend/locale/nl/LC_MESSAGES/django.mo index 1391a122d6f9f4ef730e8c686d9c08f9af9d5f2e..d927bc7a47e2a4937dedbb59031da21136bf6e3c 100644 GIT binary patch literal 14412 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 CXzbPi delta 5654 zcmZA533OD|9mnxIAt3}1!VV!o!jcdnEP;RoS;{KAppAyDf=$B`k`RJG3l57=QY;|D zrWKQbdpfBCDQ$fAju1p5r_H&F9|x=H2bRH^J`7`#IBp zs%rQ$$8n#;%1Gx1`a~QSd zr%*e14b@**ZLc1MnrICAHDCe-ZE-59-UT)AK-7Tg*aF8``wG-RMX0S`i@I(TY9gQ7 z`TaP6`Z3f566$ypPDb^gQiuI-L?Mj^&3Gj0A(@D}V3s)_HQ*xDfGbfeScBS`jaU!2 zp(b+D+ApKNch@Y-6RQPPMeSVU81`QSCDEWAXk{nTP!s8bIzI?C!E~#SMNKFVHQ+SV zK=V;6TWY?H>bKZjZ*DQS`>n7CHQ*7{iY}lA{sHx{+_Ur1b-9n!<4`MTgc_hJYU@+1 z-U;=L^hWhJ!0N+L-y4Ox-k(iDGoNTDW}q&Zk6Ph!)WnKVD|-idFt*4Q!9Mt-TdLE^2Rw>c1n>uiy2th78oqvb+;6AGNaCs0luAu0%Zp#i#){qOL1J z?bvp!??z4h5NZd{S^W;`x+or)aJ~PPDQHWpV*=K~rq~&^vMkiS&%N^5bAx-Kn*w^bv_T(?=-8=MDqOMR?ND2r zhMH(k)PRFg6HG@v)g!SFW}~j#jCyvqqIPmGs-JJL2VU`0&`MGodS84P)zKi-7e}B5 z7=xNvp7{)FrPEOZ%|%VD5Y^u@)C7y{e6hLKe9QE2u)=#d)92h4~ehKw#=*iVvPz&{}B_g-Z?;fI{t?p|lGEgfY zhp9LjBXAw6gN>+r`3dTK`;al*anug{Z0+R}ytkkRsyzuKFxBcEG4%fTrl5}chZ>xF z0=2cnQ5R&IYac~Td=zTOvQQJ9V&|X3&@+OezyC!P zBKg94)YG~dTi|YMzm2*;?~FPuj~XxrbzhK(-4VaN#2UequzpQW<2T{X^C1%XXH6`{ZJj{SoQ*$x z3Ycu|{tgt>Q4iD>4MxpuC~9TnP!q~W-RnZEfJLYYtur@bC+a0uzlj>~9#%lt-0Qa@ zYG-4ScE4*uL0g%InrT1pgiFVY)JLOMn2Q>42I_lrP&>8|wdKoD&qxt!=hj<&JL5b{racO12{ zYpDKiqWZaS?GY`#_9)bjN26aWi>IL9{AS2M)m>lgg->H8d=nG!ebfZcpuTqzb-k~Z zcdsj;&PSsrSR13UKI&O$X|_e}T!&Wdzh>H#hKkr9)j9SaRVmePpE#HwDu;}vNiW#Gwn))UYlO1fiqBF9D$l?7HYsrs0mI* zeSaqQ!2s&Ilc>LbUnBp#b3bD=#-@0G?~_rtEFbkZVTPYV6$(pGGcHCA@Gh#utycdC zwG+EgzX$tK6FP{x?x@wzqprJTes5kke>CqRf9;)rAs?m3?a>l5-E5`Y#_H`W<apbooo9M}3ODYl_ z-+8z*<{+F;29wIxR*K$+(j$|?Yow($psa8F}hE1$*nqyu?` zd`vcyUmyDQTV##H@g(`)>R;hwB!;|7o+NLRAW6{u*DsllvL2!Lbs}Zmnn+SWUL+gH zJfhc5M?Cp3RPtU;6^B~=xcO%+A+yM%)^-%HlMM2?1{q5_5*=;G_)v+z`B;rSL4LHh z#kiXMo}?1}fjUiIAp^+`a+|zPbR>}}qzTzU>JS}`$q?dyijPa=IdYBYNGFFvCGVrP zm78G}=}!JZUM5$_H{>8$Mn;ee1CI0_DyiC?v{TTMM@(0+EOeIUn-$;2fhs-9Qk}wkbX=@NF{PMAe;wduY zm!?qZ7N3*J1hSbtOWq-S$@JjdnnQhoO0~xai)#1r1yf?ig#|v0ofjBW?|9&m`cnf3 z>faB1)u1@ICT@o>P_|L9?1a4RQ3aX7&5aKDf^Re#TPDyusUUbZsg19BcJ73@$zuz$ z$BxSxo0H}Gsh*Xen_Ezj>H6hTn~<3kmzS9zm!CT&xTsmhu<%I}Mr8+HO0w1(q8JwL`#}}46C9tZ^@j&&|f#HwoqO8<0r8C)+de0ZQ I)PD5;0hii7$^ZZW diff --git a/djangocms_frontend/locale/nl/LC_MESSAGES/django.po b/djangocms_frontend/locale/nl/LC_MESSAGES/django.po index e27bdb94..7cc4fef3 100644 --- a/djangocms_frontend/locale/nl/LC_MESSAGES/django.po +++ b/djangocms_frontend/locale/nl/LC_MESSAGES/django.po @@ -2,10 +2,11 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# # Translators: +# Fabian Braun , 2023 # Stefan van den Eertwegh , 2023 -# +# #, fuzzy msgid "" msgstr "" @@ -15,10 +16,10 @@ msgstr "" "PO-Revision-Date: 2023-01-20 15:48+0000\n" "Last-Translator: Stefan van den Eertwegh , 2023\n" "Language-Team: Dutch (https://app.transifex.com/divio/teams/58664/nl/)\n" -"Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: nl\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: common/attributes.py:9 @@ -37,7 +38,7 @@ msgstr "Achtergrond" #: common/bootstrap5/background.py:48 msgid "Background context" -msgstr "" +msgstr "Achtergrond context" #: common/bootstrap5/background.py:52 contrib/card/forms.py:32 #: contrib/card/models.py:7 @@ -46,13 +47,14 @@ msgstr "Transparant" #: common/bootstrap5/background.py:57 msgid "Background opacity" -msgstr "" +msgstr "Achtergrond opacity" #: common/bootstrap5/background.py:62 msgid "Opacity of card background color (only if no outline selected)" msgstr "" -#: common/bootstrap5/background.py:66 contrib/alert/frameworks/bootstrap5.py:42 +#: common/bootstrap5/background.py:66 +#: contrib/alert/frameworks/bootstrap5.py:42 msgid "Shadow" msgstr "Schaduw" @@ -70,7 +72,8 @@ msgstr "Toon element op apparaat" #: common/bootstrap5/responsive.py:60 msgid "Select only devices on which this element should be shown." -msgstr "Selecteer alleen apparaten waarop dit element moet worden weergegeven." +msgstr "" +"Selecteer alleen apparaten waarop dit element moet worden weergegeven." #: common/bootstrap5/sizing.py:8 common/spacing.py:11 #: contrib/utilities/forms.py:51 frameworks/bootstrap5.py:90 @@ -87,6 +90,8 @@ msgid "" "Sets the horizontal size relative to the surrounding container or the " "viewport." msgstr "" +"Sets the horizontal size relative to the surrounding container or the " +"viewport." #: common/bootstrap5/sizing.py:54 msgid "Vertical size" @@ -94,8 +99,11 @@ msgstr "Verticale grootte" #: common/bootstrap5/sizing.py:60 msgid "" -"Sets the vertical size relative to the surrounding container or the viewport." +"Sets the vertical size relative to the surrounding container or the " +"viewport." msgstr "" +"Sets the vertical size relative to the surrounding container or the " +"viewport." #: common/spacing.py:84 msgid "Please choose a side to which the spacing should be applied." @@ -116,15 +124,15 @@ msgstr "" #: common/spacing.py:189 msgid "Horizontal margin" -msgstr "" +msgstr "Horizontale margin" #: common/spacing.py:195 msgid "Vertical margin" -msgstr "" +msgstr "Verticale margin" #: common/spacing.py:201 msgid "Apply margin on device" -msgstr "" +msgstr "Pas margin op apparaat tie" #: common/spacing.py:204 msgid "" @@ -134,25 +142,25 @@ msgstr "" #: common/spacing.py:221 msgid "Horizontal padding" -msgstr "" +msgstr "Horizontale paddign" #: common/spacing.py:227 msgid "Vertical padding" -msgstr "" +msgstr "Verticale padding" #: common/spacing.py:233 msgid "Apply padding on device" -msgstr "" +msgstr "Pas padding op apparaat toe" #: common/spacing.py:236 msgid "" -"Select only devices on which the padding should be applied. On other devices " -"larger than the first selected device the padding will be set to zero." +"Select only devices on which the padding should be applied. On other devices" +" larger than the first selected device the padding will be set to zero." msgstr "" #: common/title.py:40 msgid "Please add a title if you want to publish it." -msgstr "" +msgstr "Voeg een titel toe als je het wilt publiceren." #: common/title.py:64 msgid "Title" @@ -160,8 +168,8 @@ msgstr "Titel" #: common/title.py:67 msgid "" -"Optional title of the plugin for easier identification. Its title attribute will only be set if the checkbox is selected." +"Optional title of the plugin for easier identification. Its " +"title attribute will only be set if the checkbox is selected." msgstr "" #: contrib/accordion/cms_plugins.py:21 contrib/accordion/models.py:14 @@ -216,8 +224,8 @@ msgstr "" #: contrib/accordion/forms.py:52 msgid "" -"Removes the default background-color, some borders, and some rounded corners " -"to render accordions edge-to-edge with their parent container " +"Removes the default background-color, some borders, and some rounded corners" +" to render accordions edge-to-edge with their parent container " msgstr "" #: contrib/accordion/forms.py:78 contrib/card/constants.py:16 @@ -373,7 +381,8 @@ msgstr "Volledige hoogte" #: contrib/card/forms.py:152 msgid "" -"If checked cards in one row will automatically extend to the full row height." +"If checked cards in one row will automatically extend to the full row " +"height." msgstr "" #: contrib/card/forms.py:186 @@ -391,7 +400,7 @@ msgstr "Content uitlijning" #: contrib/card/templates/djangocms_frontend/admin/card_layout.html:14 #: contrib/grid/templates/djangocms_frontend/admin/grid_row.html:13 msgid "Colums per row" -msgstr "Kolommen per row" +msgstr "Kolommen per rij" #: contrib/carousel/cms_plugins.py:25 contrib/carousel/models.py:20 msgid "Carousel" @@ -431,7 +440,7 @@ msgstr "Vervagen" #: contrib/jumbotron/forms.py:44 contrib/link/forms.py:324 #: contrib/navigation/forms.py:42 contrib/tabs/forms.py:45 msgid "Layout" -msgstr "" +msgstr "Lay-out" #: contrib/carousel/forms.py:61 contrib/tabs/forms.py:48 msgid "This is the template that will be used for the component." @@ -443,8 +452,8 @@ msgstr "Interval" #: contrib/carousel/forms.py:67 msgid "" -"The amount of time to delay between automatically cycling an item. If false, " -"carousel will not automatically cycle." +"The amount of time to delay between automatically cycling an item. If false," +" carousel will not automatically cycle." msgstr "" #: contrib/carousel/forms.py:72 contrib/carousel/models.py:25 @@ -634,7 +643,7 @@ msgstr "Container" #: contrib/grid/cms_plugins.py:72 contrib/grid/models.py:55 msgid "Row" -msgstr "Row" +msgstr "Rij" #: contrib/grid/cms_plugins.py:149 contrib/grid/models.py:79 #: contrib/tabs/constants.py:15 @@ -733,21 +742,22 @@ msgstr "" #: contrib/grid/forms.py:167 msgid "Column alignment" -msgstr "Klom uitlijning" +msgstr "Kolom uitlijning" #: contrib/grid/forms.py:195 #, python-format msgid "" "Column size needs to be empty, \"auto\", or a number between 1 and %(cols)d" msgstr "" +"Kolom grootte dient leeg, \"auto\" of een nummer tussen 1 en %(cols)dte zijn" #: contrib/grid/models.py:29 msgid "GridContainer" -msgstr "" +msgstr "Grid container" #: contrib/grid/models.py:56 msgid "GridRow" -msgstr "" +msgstr "Grid rij" #: contrib/grid/models.py:64 #, python-format @@ -758,11 +768,11 @@ msgstr[1] "(%(count)i kolommen)" #: contrib/grid/models.py:80 msgid "GridColumn" -msgstr "" +msgstr "Grid kolom" #: contrib/grid/templates/djangocms_frontend/admin/grid_column.html:15 msgid "Column size" -msgstr "Klom grootte" +msgstr "Kolom grootte" #: contrib/grid/templates/djangocms_frontend/admin/grid_column.html:16 msgid "Order" @@ -770,7 +780,7 @@ msgstr "Sortering" #: contrib/grid/templates/djangocms_frontend/admin/grid_column.html:17 msgid "Offset" -msgstr "" +msgstr "Offset" #: contrib/grid/templates/djangocms_frontend/admin/grid_column.html:18 msgid "Margin left" @@ -918,8 +928,7 @@ msgid "Width" msgstr "Breedte" #: contrib/image/forms.py:135 -msgid "" -"The image width as number in pixels. Example: \"720\" and not \"720px\"." +msgid "The image width as number in pixels. Example: \"720\" and not \"720px\"." msgstr "" #: contrib/image/forms.py:139 @@ -927,8 +936,7 @@ msgid "Height" msgstr "Hoogte" #: contrib/image/forms.py:143 -msgid "" -"The image height as number in pixels. Example: \"720\" and not \"720px\"." +msgid "The image height as number in pixels. Example: \"720\" and not \"720px\"." msgstr "" "De afbeelding-hoogte als nummer in pixels. Voorbeeld: \"720\" en niet " "\"720px\"." @@ -967,10 +975,11 @@ msgstr "Afbeelding bijsnijden" #: contrib/image/forms.py:179 msgid "" -"Crops the image according to the thumbnail settings provided in the template." -msgstr "" -"Snij de afbeelding bij volgens de thumbnail instellingen mits gebruikt in de " +"Crops the image according to the thumbnail settings provided in the " "template." +msgstr "" +"Snij de afbeelding bij volgens de thumbnail instellingen mits gebruikt in de" +" template." #: contrib/image/forms.py:183 msgid "Upscale image" @@ -988,8 +997,8 @@ msgstr "Gebruik afbeelding responsive" #: contrib/image/forms.py:194 msgid "" -"Uses responsive image technique to choose better image to display based upon " -"screen viewport. This configuration only applies to uploaded images " +"Uses responsive image technique to choose better image to display based upon" +" screen viewport. This configuration only applies to uploaded images " "(external pictures will not be affected). " msgstr "" @@ -1034,7 +1043,8 @@ msgid "" msgstr "" #: contrib/image/forms.py:255 -msgid "You need to add either an image, or a URL linking to an external image." +msgid "" +"You need to add either an image, or a URL linking to an external image." msgstr "" #: contrib/image/forms.py:281 @@ -1056,8 +1066,8 @@ msgstr "" msgid "Makes the jumbotron fill the full width of the container or window." msgstr "" -#: contrib/link/apps.py:7 contrib/link/constants.py:5 contrib/link/models.py:11 -#: contrib/link/models.py:114 +#: contrib/link/apps.py:7 contrib/link/constants.py:5 +#: contrib/link/models.py:11 contrib/link/models.py:114 msgid "Link" msgstr "Link" @@ -1072,7 +1082,7 @@ msgstr "Knop" #: contrib/link/constants.py:10 frameworks/bootstrap5.py:7 #: frameworks/bootstrap5.py:133 msgid "Small" -msgstr "Smal" +msgstr "Klein" #: contrib/link/constants.py:11 frameworks/bootstrap5.py:8 #: frameworks/bootstrap5.py:134 @@ -1451,8 +1461,8 @@ msgstr "ID" #: contrib/utilities/forms.py:128 msgid "" -"Fill in unique ID for table of contents. If empty heading will not appear in " -"table of contents." +"Fill in unique ID for table of contents. If empty heading will not appear in" +" table of contents." msgstr "" #: contrib/utilities/forms.py:132 @@ -1461,7 +1471,7 @@ msgstr "Heading context" #: contrib/utilities/forms.py:160 msgid "List attributes" -msgstr "" +msgstr "Lijst attributen" #: contrib/utilities/forms.py:162 msgid "" @@ -1511,7 +1521,7 @@ msgstr "Selecteer een HTML tag om te gebruiken" #: frameworks/bootstrap5.py:6 frameworks/bootstrap5.py:132 msgid "Extra small" -msgstr "Extra smal" +msgstr "Extra klein" #: frameworks/bootstrap5.py:10 frameworks/bootstrap5.py:136 msgid "Extra large" @@ -1584,8 +1594,7 @@ msgstr "XX groot" #: helpers.py:112 #, python-brace-format -msgid "" -"Read more in the documentation." +msgid "Read more in the documentation." msgstr "Lees meer in de documentatie." #: models.py:24 @@ -1599,6 +1608,3 @@ msgstr "" #: settings.py:73 msgid "Offcanvas" msgstr "" - -#~ msgid "Template" -#~ msgstr "Template" diff --git a/djangocms_frontend/locale/sq/LC_MESSAGES/django.mo b/djangocms_frontend/locale/sq/LC_MESSAGES/django.mo index d941688ce4edb42b9157d4a0278098110216c84d..8e9889c6b9a7b31a64f3d926622691864964e033 100644 GIT binary patch delta 5193 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 ZOBOX;?^BTEEuJ@f){C Date: Tue, 28 Nov 2023 16:49:19 +0100 Subject: [PATCH 02/66] fix: icons not showing in ckeditor --- .../ckeditor/icon}/ckeditor.icons.js | 0 docs/source/components.rst | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename djangocms_frontend/contrib/icon/static/{djangocms_frontend/icon/ckeditor => djangocms_text_ckeditor/ckeditor/icon}/ckeditor.icons.js (100%) diff --git a/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/ckeditor/ckeditor.icons.js b/djangocms_frontend/contrib/icon/static/djangocms_text_ckeditor/ckeditor/icon/ckeditor.icons.js similarity index 100% rename from djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/ckeditor/ckeditor.icons.js rename to djangocms_frontend/contrib/icon/static/djangocms_text_ckeditor/ckeditor/icon/ckeditor.icons.js diff --git a/docs/source/components.rst b/docs/source/components.rst index 76b22baf..7c1896b4 100644 --- a/docs/source/components.rst +++ b/docs/source/components.rst @@ -462,7 +462,7 @@ To disable this behavior of CKEDITOR, you need to add a ``stylesSet`` entry in ` CKEDITOR_SETTINGS = { ..., - "stylesSet": f"default:{STATIC_URL}djangocms_frontend/icon/ckeditor/ckeditor.icons.js", + "stylesSet": "default:icon/ckeditor.icons.js", ..., } From a9ead97e19d77d72a98e887cb6656526f35c6baf Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Tue, 28 Nov 2023 20:38:38 +0100 Subject: [PATCH 03/66] Add image drag and drop --- djangocms_frontend/contrib/image/forms.py | 3 +- .../contrib/image/image_save.py | 35 +++++++++++++++++++ docs/source/components.rst | 21 ++++++++++- 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 djangocms_frontend/contrib/image/image_save.py diff --git a/djangocms_frontend/contrib/image/forms.py b/djangocms_frontend/contrib/image/forms.py index 32dd2777..b448658f 100644 --- a/djangocms_frontend/contrib/image/forms.py +++ b/djangocms_frontend/contrib/image/forms.py @@ -145,7 +145,8 @@ class Meta: ) alignment = forms.ChoiceField( label=_("Alignment"), - choices=get_alignment(), + choices=settings.EMPTY_CHOICE + get_alignment(), + initial=settings.EMPTY_CHOICE[0][0], required=False, help_text=_("Aligns the image according to the selected option."), ) diff --git a/djangocms_frontend/contrib/image/image_save.py b/djangocms_frontend/contrib/image/image_save.py new file mode 100644 index 00000000..27faa268 --- /dev/null +++ b/djangocms_frontend/contrib/image/image_save.py @@ -0,0 +1,35 @@ +from django.core.files.base import ContentFile + +from djangocms_frontend.contrib.image.cms_plugins import ImagePlugin +from djangocms_frontend.contrib.image.forms import get_templates +from djangocms_frontend.contrib.image.models import Image +from djangocms_frontend.helpers import add_plugin, first_choice + +default_template = first_choice(get_templates()) + + +def create_image_plugin(filename, file, parent_plugin, **kwargs): + + # Set the FilerImageField value. + from filer.settings import FILER_IMAGE_MODEL + from filer.utils.loader import load_model + image_class = load_model(FILER_IMAGE_MODEL) + image_obj = image_class(file=ContentFile(file.read(), name=filename)) + image_obj.save() + + img = Image( + parent=parent_plugin, + position=parent_plugin.position + 1, + placeholder=parent_plugin.placeholder, + language=parent_plugin.language, + plugin_type=ImagePlugin.__name__, + ui_item=Image.__class__.__name__, + config={}, + ).initialize_from_form() + img.config.update({ + "picture": {"pk": image_obj.pk, "model": "filer.image"}, + "use_no_cropping": True, + }) + add_plugin(parent_plugin.placeholder, img) + + return img diff --git a/docs/source/components.rst b/docs/source/components.rst index 7c1896b4..271ca05d 100644 --- a/docs/source/components.rst +++ b/docs/source/components.rst @@ -286,6 +286,25 @@ Picture / image component The image or picture component make responsive picture uploads available as well as responsive embedding of external pictures. +.. versionadded:: 1.2 + + djangocms-text-ckeditor supports dragging and dropping images into a rich + text field. If you add the following line to your `settings.py` file, + djangocms-text-ckeditor will automatically convert an image dropped into it + to a djangocms-frontend image component. + + .. code-block:: + + TEXT_SAVE_IMAGE_FUNCTION = 'djangocms_frontend.contrib.image.image_save.create_image_plugin' + + Please note, that images dropped into djangocms-text-ckeditor are base64- + encoded and take a quite a bit of band width. You may have to increase your + `DATA_UPLOAD_MAX_MEMORY_SIZE` setting in `settings.py`. + + We recommend not using this feature but instead adding a image component + through the "CMS Plugin" menu of Ckeditor. + + .. index:: single: Spacing @@ -462,7 +481,7 @@ To disable this behavior of CKEDITOR, you need to add a ``stylesSet`` entry in ` CKEDITOR_SETTINGS = { ..., - "stylesSet": "default:icon/ckeditor.icons.js", + "customConfig": "icon/ckeditor.icons.js", ..., } From f5f27b68e16c35130c0db02deebf7e689aa64861 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Tue, 28 Nov 2023 20:47:55 +0100 Subject: [PATCH 04/66] Update docs --- docs/source/reference.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/source/reference.rst b/docs/source/reference.rst index 8c3c843c..8525f2e0 100644 --- a/docs/source/reference.rst +++ b/docs/source/reference.rst @@ -223,15 +223,14 @@ in your project's ``settings.py``. .. py:attribute:: settings.TEXT_SAVE_IMAGE_FUNCTION - Requirement: ``TEXT_SAVE_IMAGE_FUNCTION = None`` + If you want to use + djangocms-text-ckeditor's `Drag & Drop Images + `_ + so be sure to set ``TEXT_SAVE_IMAGE_FUNCTION``:: - .. warning:: - - Please be aware that this package does not support - djangocms-text-ckeditor's `Drag & Drop Images - `_ - so be sure to set ``TEXT_SAVE_IMAGE_FUNCTION = None``. + TEXT_SAVE_IMAGE_FUNCTION = 'djangocms_frontend.contrib.image.image_save.create_image_plugin' + Otherwise set ``TEXT_SAVE_IMAGE_FUNCTION = None`` .. py:attribute:: settings.DJANGOCMS_FRONTEND_ICON_LIBRARIES From 6d5fac44ad9ae46e96d92db9d84676795808a2e6 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Tue, 28 Nov 2023 21:02:50 +0100 Subject: [PATCH 05/66] Add tests --- tests/image/test_drag_n_drop.py | 32 ++++++++++++++++++++++++++++++++ tests/test_settings.py | 2 ++ 2 files changed, 34 insertions(+) create mode 100644 tests/image/test_drag_n_drop.py diff --git a/tests/image/test_drag_n_drop.py b/tests/image/test_drag_n_drop.py new file mode 100644 index 00000000..edbc7128 --- /dev/null +++ b/tests/image/test_drag_n_drop.py @@ -0,0 +1,32 @@ +from cms.api import add_plugin +from cms.test_utils.testcases import CMSTestCase + +from djangocms_frontend.contrib.image.models import Image +from tests.fixtures import TestFixture + + +class DjangoCMSPictureIntegrationTestCase(TestFixture, CMSTestCase): + def setUp(self): + super().setUp() + self.page = self.create_page('test page', template='page.html', language='en') + self.placeholder = self.get_placeholders(self.page).get(slot='content') + + def test_extract_images(self): + text_plugin = add_plugin( + self.placeholder, + 'TextPlugin', + 'en', + body='', + ) + + picture_plugins = Image.objects.order_by('-id') + self.assertEqual(len(picture_plugins), 1) + self.assertEqual(picture_plugins[0].parent.id, text_plugin.id) + id = picture_plugins[0].id + self.assertHTMLEqual( + text_plugin.body, + f'', + ) diff --git a/tests/test_settings.py b/tests/test_settings.py index ec735ce9..b5792bef 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -119,3 +119,5 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" CMS_CONFIRM_VERSION4 = True # Needed for v4, neglected in v3 + +TEXT_SAVE_IMAGE_FUNCTION = 'djangocms_frontend.contrib.image.image_save.create_image_plugin' From 18d60ab19915c90b150e8fa8b0b6ac7ae2463355 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Tue, 28 Nov 2023 21:10:01 +0100 Subject: [PATCH 06/66] Fix tests for v4 --- tests/image/test_drag_n_drop.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/image/test_drag_n_drop.py b/tests/image/test_drag_n_drop.py index edbc7128..e6f91216 100644 --- a/tests/image/test_drag_n_drop.py +++ b/tests/image/test_drag_n_drop.py @@ -8,8 +8,7 @@ class DjangoCMSPictureIntegrationTestCase(TestFixture, CMSTestCase): def setUp(self): super().setUp() - self.page = self.create_page('test page', template='page.html', language='en') - self.placeholder = self.get_placeholders(self.page).get(slot='content') + self.placeholder = self.get_placeholders(self.home).get(slot='content') def test_extract_images(self): text_plugin = add_plugin( From 44d5035abbb869d06834fcc582d98b1ecd515885 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Tue, 28 Nov 2023 21:14:13 +0100 Subject: [PATCH 07/66] Bump version --- djangocms_frontend/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/djangocms_frontend/__init__.py b/djangocms_frontend/__init__.py index 476313cf..1af421e0 100644 --- a/djangocms_frontend/__init__.py +++ b/djangocms_frontend/__init__.py @@ -19,4 +19,4 @@ 13. Github actions will publish the new package to pypi """ -__version__ = "1.1.10" +__version__ = "1.2.0" From 210cccd12220aef2b5bbb01b8dc96ea1912ab801 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Tue, 28 Nov 2023 21:17:02 +0100 Subject: [PATCH 08/66] Update changelog --- CHANGELOG.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b288adda..7a042677 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,16 @@ Changelog ========= +1.2.0 (2023-11-28) +================== + +* feat: Add float option for images by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/162 +* feat: Add drag'n'drop support for djangocms-text-ckeditor by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/165 +* fix: Ckeditor does not show icons for editing by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/163 +* fix: Replace ``stylesSet`` setting in docs with ``customConfig` for icons in ckeditor by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/164 +* ci: pre-commit autoupdate by @pre-commit-ci in https://github.com/django-cms/djangocms-frontend/pull/161 + + 1.1.10 (2023-10-23) =================== From 606cc91a0225086c3606cb0c0882414abfe2c70d Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Fri, 15 Dec 2023 23:38:00 +0100 Subject: [PATCH 09/66] fix/remove-unused-css --- .../vendor/assets/stylesheets/happy-icons.css | 2245 ----------------- .../assets/stylesheets/happy-icons.min.css | 1 - .../vendor/assets/stylesheets/icomoon.css | 1991 --------------- .../vendor/assets/stylesheets/icomoon.min.css | 1 - .../stylesheets/universal-icon-picker.css | 292 --- .../stylesheets/universal-icon-picker.min.css | 1 - .../vendor/assets/stylesheets/zondicons.css | 1213 --------- .../assets/stylesheets/zondicons.min.css | 1 - 8 files changed, 5745 deletions(-) delete mode 100644 djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/happy-icons.css delete mode 100644 djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/happy-icons.min.css delete mode 100644 djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/icomoon.css delete mode 100644 djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/icomoon.min.css delete mode 100644 djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/universal-icon-picker.css delete mode 100644 djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/universal-icon-picker.min.css delete mode 100644 djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/zondicons.css delete mode 100644 djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/zondicons.min.css diff --git a/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/happy-icons.css b/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/happy-icons.css deleted file mode 100644 index 9317f412..00000000 --- a/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/happy-icons.css +++ /dev/null @@ -1,2245 +0,0 @@ -@font-face { - font-family: 'Happy Icons'; - src: url('../fonts/happy-icons.woff2') format('woff2'), - url('../fonts/happy-icons.woff') format('woff'), - url('../fonts/happy-icons.svg#happy-icons') format('svg'); - font-weight: normal; - font-style: normal; - font-display: swap; -} - -.hm, -.fashm { - /* use !important to prevent issues with browser extensions that change fonts */ - font-family: 'Happy Icons' !important; - speak: none; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - - /* Better Font Rendering =========== */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.hm-3d-rotate:before { - content: "\e900"; -} - -.hm-degree:before { - content: "\e901"; -} - -.hm-accordion-horizontal:before { - content: "\e902"; -} - -.hm-accordion-vertical:before { - content: "\e903"; -} - -.hm-alarm-clock:before { - content: "\e904"; -} - -.hm-alien-gun:before { - content: "\e905"; -} - -.hm-alien:before { - content: "\e906"; -} - -.hm-anchor:before { - content: "\e907"; -} - -.hm-android:before { - content: "\e908"; -} - -.hm-angle-down:before { - content: "\e909"; -} - -.hm-angle-left:before { - content: "\e90a"; -} - -.hm-angle-right:before { - content: "\e90b"; -} - -.hm-angle-up:before { - content: "\e90c"; -} - -.hm-apple:before { - content: "\e90d"; -} - -.hm-arrow-left:before { - content: "\e90e"; -} - -.hm-arrow-right:before { - content: "\e90f"; -} - -.hm-arrow-zoom-out:before { - content: "\e910"; -} - -.hm-arrow-corner:before { - content: "\e911"; -} - -.hm-arrow-down:before { - content: "\e912"; -} - -.hm-arrow-left1:before { - content: "\e913"; -} - -.hm-arrow-right1:before { - content: "\e914"; -} - -.hm-arrow-up:before { - content: "\e915"; -} - -.hm-article:before { - content: "\e916"; -} - -.hm-avatar-man:before { - content: "\e917"; -} - -.hm-avatar-woman:before { - content: "\e918"; -} - -.hm-badge1:before { - content: "\e919"; -} - -.hm-badge2:before { - content: "\e91a"; -} - -.hm-badge3:before { - content: "\e91b"; -} - -.hm-bamboo:before { - content: "\e91c"; -} - -.hm-basketball:before { - content: "\e91d"; -} - -.hm-battery:before { - content: "\e91e"; -} - -.hm-beach-seat:before { - content: "\e91f"; -} - -.hm-bell:before { - content: "\e920"; -} - -.hm-bicycle:before { - content: "\e921"; -} - -.hm-blog-content:before { - content: "\e922"; -} - -.hm-bluetooth:before { - content: "\e923"; -} - -.hm-board:before { - content: "\e924"; -} - -.hm-body:before { - content: "\e925"; -} - -.hm-bomb:before { - content: "\e926"; -} - -.hm-bond-hand:before { - content: "\e927"; -} - -.hm-bond:before { - content: "\e928"; -} - -.hm-bonsai:before { - content: "\e929"; -} - -.hm-book:before { - content: "\e92a"; -} - -.hm-bowl:before { - content: "\e92b"; -} - -.hm-brick-wall:before { - content: "\e92c"; -} - -.hm-brush-paint:before { - content: "\e92d"; -} - -.hm-brush-roll:before { - content: "\e92e"; -} - -.hm-brush:before { - content: "\e92f"; -} - -.hm-bug:before { - content: "\e930"; -} - -.hm-bulb:before { - content: "\e931"; -} - -.hm-calculation:before { - content: "\e932"; -} - -.hm-calendar:before { - content: "\e933"; -} - -.hm-camera:before { - content: "\e934"; -} - -.hm-candle:before { - content: "\e935"; -} - -.hm-candles:before { - content: "\e936"; -} - -.hm-car:before { - content: "\e937"; -} - -.hm-card:before { - content: "\e938"; -} - -.hm-caret-down:before { - content: "\e939"; -} - -.hm-caret-fill-down:before { - content: "\e93a"; -} - -.hm-caret-fill-left:before { - content: "\e93b"; -} - -.hm-caret-fill-right:before { - content: "\e93c"; -} - -.hm-caret-fill-up:before { - content: "\e93d"; -} - -.hm-caret-left:before { - content: "\e93e"; -} - -.hm-caret-right:before { - content: "\e93f"; -} - -.hm-caret-up:before { - content: "\e940"; -} - -.hm-carousal:before { - content: "\e941"; -} - -.hm-cart-empty:before { - content: "\e942"; -} - -.hm-cart-full:before { - content: "\e943"; -} - -.hm-caution:before { - content: "\e944"; -} - -.hm-chair:before { - content: "\e945"; -} - -.hm-chair2:before { - content: "\e946"; -} - -.hm-chat-bubble-single:before { - content: "\e947"; -} - -.hm-chat-bubble:before { - content: "\e948"; -} - -.hm-cheese:before { - content: "\e949"; -} - -.hm-chef-cap:before { - content: "\e94a"; -} - -.hm-clip-board:before { - content: "\e94b"; -} - -.hm-clip:before { - content: "\e94c"; -} - -.hm-cloud-down:before { - content: "\e94d"; -} - -.hm-cloud-up:before { - content: "\e94e"; -} - -.hm-cloud:before { - content: "\e94f"; -} - -.hm-code-browser:before { - content: "\e950"; -} - -.hm-code-clean:before { - content: "\e951"; -} - -.hm-code:before { - content: "\e952"; -} - -.hm-cog:before { - content: "\e953"; -} - -.hm-color-card:before { - content: "\e954"; -} - -.hm-color-plate:before { - content: "\e955"; -} - -.hm-compass-math:before { - content: "\e956"; -} - -.hm-compass:before { - content: "\e957"; -} - -.hm-corner:before { - content: "\e958"; -} - -.hm-crop:before { - content: "\e959"; -} - -.hm-cross-circle:before { - content: "\e95a"; -} - -.hm-cross-game:before { - content: "\e95b"; -} - -.hm-cross-gap:before { - content: "\e95c"; -} - -.hm-cross:before { - content: "\e95d"; -} - -.hm-crown:before { - content: "\e95e"; -} - -.hm-cube:before { - content: "\e95f"; -} - -.hm-cup-coffee:before { - content: "\e960"; -} - -.hm-cup:before { - content: "\e961"; -} - -.hm-currency-paper:before { - content: "\e962"; -} - -.hm-dashboard:before { - content: "\e963"; -} - -.hm-delivery-van:before { - content: "\e964"; -} - -.hm-diamond-ring:before { - content: "\e965"; -} - -.hm-direction-both:before { - content: "\e966"; -} - -.hm-direction-right:before { - content: "\e967"; -} - -.hm-disable-person:before { - content: "\e968"; -} - -.hm-disc:before { - content: "\e969"; -} - -.hm-dislike:before { - content: "\e96a"; -} - -.hm-dollar-on-hand:before { - content: "\e96b"; -} - -.hm-door-path:before { - content: "\e96c"; -} - -.hm-Download-circle:before { - content: "\e96d"; -} - -.hm-download:before { - content: "\e96e"; -} - -.hm-drag-inside:before { - content: "\e96f"; -} - -.hm-drag-outside:before { - content: "\e970"; -} - -.hm-drag:before { - content: "\e971"; -} - -.hm-drawer:before { - content: "\e972"; -} - -.hm-dribbble:before { - content: "\e973"; -} - -.hm-dropper:before { - content: "\e974"; -} - -.hm-egg-fry:before { - content: "\e975"; -} - -.hm-ellipsis-fill-h:before { - content: "\e976"; -} - -.hm-ellipsis-fill-v:before { - content: "\e977"; -} - -.hm-ellipsis-horizontal:before { - content: "\e978"; -} - -.hm-ellipsis-vertical:before { - content: "\e979"; -} - -.hm-emo-normal:before { - content: "\e97a"; -} - -.hm-emo-sad:before { - content: "\e97b"; -} - -.hm-emo-smile:before { - content: "\e97c"; -} - -.hm-envelop:before { - content: "\e97d"; -} - -.hm-facebook:before { - content: "\e97e"; -} - -.hm-fancy-futton:before { - content: "\e97f"; -} - -.hm-feeder:before { - content: "\e980"; -} - -.hm-file-cabinet:before { - content: "\e981"; -} - -.hm-file-rotate:before { - content: "\e982"; -} - -.hm-file:before { - content: "\e983"; -} - -.hm-files:before { - content: "\e984"; -} - -.hm-film-roll:before { - content: "\e985"; -} - -.hm-film:before { - content: "\e986"; -} - -.hm-finger-index:before { - content: "\e987"; -} - -.hm-finger-print:before { - content: "\e988"; -} - -.hm-fire-flame:before { - content: "\e989"; -} - -.hm-flag:before { - content: "\e98a"; -} - -.hm-flip-card1:before { - content: "\e98b"; -} - -.hm-flip-card2:before { - content: "\e98c"; -} - -.hm-folder-network:before { - content: "\e98d"; -} - -.hm-folder:before { - content: "\e98e"; -} - -.hm-football:before { - content: "\e98f"; -} - -.hm-footer:before { - content: "\e990"; -} - -.hm-form:before { - content: "\e991"; -} - -.hm-forward:before { - content: "\e992"; -} - -.hm-fountain-pen:before { - content: "\e993"; -} - -.hm-gender-female:before { - content: "\e994"; -} - -.hm-gender-male:before { - content: "\e995"; -} - -.hm-gender-sign:before { - content: "\e996"; -} - -.hm-gender:before { - content: "\e997"; -} - -.hm-ghost:before { - content: "\e998"; -} - -.hm-gift-box:before { - content: "\e999"; -} - -.hm-globe1:before { - content: "\e99a"; -} - -.hm-globe2:before { - content: "\e99b"; -} - -.hm-globe3:before { - content: "\e99c"; -} - -.hm-globe4:before { - content: "\e99d"; -} - -.hm-google:before { - content: "\e99e"; -} - -.hm-graduate-cap:before { - content: "\e99f"; -} - -.hm-graph-bar:before { - content: "\e9a0"; -} - -.hm-graph-pie:before { - content: "\e9a1"; -} - -.hm-graph:before { - content: "\e9a2"; -} - -.hm-grid-even:before { - content: "\e9a3"; -} - -.hm-grid-masonry:before { - content: "\e9a4"; -} - -.hm-grid-twist:before { - content: "\e9a5"; -} - -.hm-grid:before { - content: "\e9a6"; -} - -.hm-group:before { - content: "\e9a7"; -} - -.hm-hand-mike:before { - content: "\e9a8"; -} - -.hm-hand-watch:before { - content: "\e9a9"; -} - -.hm-hand:before { - content: "\e9aa"; -} - -.hm-header:before { - content: "\e9ab"; -} - -.hm-headphone:before { - content: "\e9ac"; -} - -.hm-headset:before { - content: "\e9ad"; -} - -.hm-heart-beat:before { - content: "\e9ae"; -} - -.hm-hexa:before { - content: "\e9af"; -} - -.hm-highlighter:before { - content: "\e9b0"; -} - -.hm-home:before { - content: "\e9b1"; -} - -.hm-hot-spot:before { - content: "\e9b2"; -} - -.hm-hotdog:before { - content: "\e9b3"; -} - -.hm-ice-cream:before { - content: "\e9b4"; -} - -.hm-icon-box:before { - content: "\e9b5"; -} - -.hm-imac:before { - content: "\e9b6"; -} - -.hm-image-compare:before { - content: "\e9b7"; -} - -.hm-image-slider:before { - content: "\e9b8"; -} - -.hm-image:before { - content: "\e9b9"; -} - -.hm-inbox:before { - content: "\e9ba"; -} - -.hm-infinity:before { - content: "\e9bb"; -} - -.hm-info:before { - content: "\e9bc"; -} - -.hm-injection:before { - content: "\e9bd"; -} - -.hm-instagram:before { - content: "\e9be"; -} - -.hm-jar-chemical:before { - content: "\e9bf"; -} - -.hm-key:before { - content: "\e9c0"; -} - -.hm-language-change:before { - content: "\e9c1"; -} - -.hm-laptop:before { - content: "\e9c2"; -} - -.hm-layer:before { - content: "\e9c3"; -} - -.hm-lens:before { - content: "\e9c4"; -} - -.hm-like:before { - content: "\e9c5"; -} - -.hm-line-graph-pointed:before { - content: "\e9c6"; -} - -.hm-link:before { - content: "\e9c7"; -} - -.hm-linkedin:before { - content: "\e9c8"; -} - -.hm-linux:before { - content: "\e9c9"; -} - -.hm-list-2:before { - content: "\e9ca"; -} - -.hm-list-group:before { - content: "\e9cb"; -} - -.hm-list:before { - content: "\e9cc"; -} - -.hm-location-pointer:before { - content: "\e9cd"; -} - -.hm-lock:before { - content: "\e9ce"; -} - -.hm-logo-carousel:before { - content: "\e9cf"; -} - -.hm-logo-grid:before { - content: "\e9d0"; -} - -.hm-lotus:before { - content: "\e9d1"; -} - -.hm-love:before { - content: "\e9d2"; -} - -.hm-madel:before { - content: "\e9d3"; -} - -.hm-magic-wand:before { - content: "\e9d4"; -} - -.hm-magnet:before { - content: "\e9d5"; -} - -.hm-mail-open:before { - content: "\e9d6"; -} - -.hm-man-range:before { - content: "\e9d7"; -} - -.hm-map-marker:before { - content: "\e9d8"; -} - -.hm-map-pointer:before { - content: "\e9d9"; -} - -.hm-measurement:before { - content: "\e9da"; -} - -.hm-memory:before { - content: "\e9db"; -} - -.hm-menu-price:before { - content: "\e9dc"; -} - -.hm-micro-chip:before { - content: "\e9dd"; -} - -.hm-microphone1:before { - content: "\e9de"; -} - -.hm-microphone2:before { - content: "\e9df"; -} - -.hm-mobile:before { - content: "\e9e0"; -} - -.hm-money-bag:before { - content: "\e9e1"; -} - -.hm-money:before { - content: "\e9e2"; -} - -.hm-monitor:before { - content: "\e9e3"; -} - -.hm-mouse:before { - content: "\e9e4"; -} - -.hm-muscle:before { - content: "\e9e5"; -} - -.hm-net:before { - content: "\e9e6"; -} - -.hm-network1:before { - content: "\e9e7"; -} - -.hm-network2:before { - content: "\e9e8"; -} - -.hm-newspaper:before { - content: "\e9e9"; -} - -.hm-nuclear-circle:before { - content: "\e9ea"; -} - -.hm-office-file:before { - content: "\e9eb"; -} - -.hm-pacman:before { - content: "\e9ec"; -} - -.hm-paper-fold:before { - content: "\e9ed"; -} - -.hm-paper-plane-alt:before { - content: "\e9ee"; -} - -.hm-paper-plane:before { - content: "\e9ef"; -} - -.hm-pause:before { - content: "\e9f0"; -} - -.hm-pen-head:before { - content: "\e9f1"; -} - -.hm-pen-pencil:before { - content: "\e9f2"; -} - -.hm-pen-scale:before { - content: "\e9f3"; -} - -.hm-pen-paper:before { - content: "\e9f4"; -} - -.hm-pen:before { - content: "\e9f5"; -} - -.hm-pencil:before { - content: "\e9f6"; -} - -.hm-pendrive:before { - content: "\e9f7"; -} - -.hm-phone:before { - content: "\e9f8"; -} - -.hm-pillar:before { - content: "\e9f9"; -} - -.hm-pin-man-range:before { - content: "\e9fa"; -} - -.hm-pin-man:before { - content: "\e9fb"; -} - -.hm-pin:before { - content: "\e9fc"; -} - -.hm-plane:before { - content: "\e9fd"; -} - -.hm-play-end:before { - content: "\e9fe"; -} - -.hm-play-next:before { - content: "\e9ff"; -} - -.hm-play-previous:before { - content: "\ea00"; -} - -.hm-play-start:before { - content: "\ea01"; -} - -.hm-play-button:before { - content: "\ea02"; -} - -.hm-play-store:before { - content: "\ea03"; -} - -.hm-play:before { - content: "\ea04"; -} - -.hm-playing-card:before { - content: "\ea05"; -} - -.hm-plus-box:before { - content: "\ea06"; -} - -.hm-plus-circle:before { - content: "\ea07"; -} - -.hm-plus-gap:before { - content: "\ea08"; -} - -.hm-plus-open:before { - content: "\ea09"; -} - -.hm-popup:before { - content: "\ea0a"; -} - -.hm-power:before { - content: "\ea0b"; -} - -.hm-printer:before { - content: "\ea0c"; -} - -.hm-progress-bar:before { - content: "\ea0d"; -} - -.hm-promo:before { - content: "\ea0e"; -} - -.hm-pulse:before { - content: "\ea0f"; -} - -.hm-puzzle:before { - content: "\ea10"; -} - -.hm-question:before { - content: "\ea11"; -} - -.hm-quote:before { - content: "\ea12"; -} - -.hm-radar:before { - content: "\ea13"; -} - -.hm-radiation:before { - content: "\ea14"; -} - -.hm-reading-glass-alt:before { - content: "\ea15"; -} - -.hm-reading-glass:before { - content: "\ea16"; -} - -.hm-recycle-bin:before { - content: "\ea17"; -} - -.hm-recycle:before { - content: "\ea18"; -} - -.hm-refresh-time:before { - content: "\ea19"; -} - -.hm-reply:before { - content: "\ea1a"; -} - -.hm-responsive-device:before { - content: "\ea1b"; -} - -.hm-review:before { - content: "\ea1c"; -} - -.hm-rocket1:before { - content: "\ea1d"; -} - -.hm-rocket2:before { - content: "\ea1e"; -} - -.hm-rss:before { - content: "\ea1f"; -} - -.hm-safety-cap:before { - content: "\ea20"; -} - -.hm-safety-kit:before { - content: "\ea21"; -} - -.hm-sand-watch:before { - content: "\ea22"; -} - -.hm-scale:before { - content: "\ea23"; -} - -.hm-scanner:before { - content: "\ea24"; -} - -.hm-scissor:before { - content: "\ea25"; -} - -.hm-screen:before { - content: "\ea26"; -} - -.hm-search:before { - content: "\ea27"; -} - -.hm-seo:before { - content: "\ea28"; -} - -.hm-server-network:before { - content: "\ea29"; -} - -.hm-server:before { - content: "\ea2a"; -} - -.hm-share:before { - content: "\ea2b"; -} - -.hm-shield:before { - content: "\ea2c"; -} - -.hm-ship:before { - content: "\ea2d"; -} - -.hm-shirt:before { - content: "\ea2e"; -} - -.hm-shopping-bag1:before { - content: "\ea2f"; -} - -.hm-shopping-bag2:before { - content: "\ea30"; -} - -.hm-shopping-bag3:before { - content: "\ea31"; -} - -.hm-shopping-bag4:before { - content: "\ea32"; -} - -.hm-shuffle:before { - content: "\ea33"; -} - -.hm-shutter:before { - content: "\ea34"; -} - -.hm-sign-in:before { - content: "\ea35"; -} - -.hm-sign-out:before { - content: "\ea36"; -} - -.hm-sitemap1:before { - content: "\ea37"; -} - -.hm-sitemap2:before { - content: "\ea38"; -} - -.hm-skart:before { - content: "\ea39"; -} - -.hm-skull:before { - content: "\ea3a"; -} - -.hm-skyscraper:before { - content: "\ea3b"; -} - -.hm-slider-doc:before { - content: "\ea3c"; -} - -.hm-slider-h-range:before { - content: "\ea3d"; -} - -.hm-slider-image:before { - content: "\ea3e"; -} - -.hm-slider-range-h:before { - content: "\ea3f"; -} - -.hm-slider-v-open:before { - content: "\ea40"; -} - -.hm-slider-video:before { - content: "\ea41"; -} - -.hm-slider:before { - content: "\ea42"; -} - -.hm-smart-watch:before { - content: "\ea43"; -} - -.hm-snow:before { - content: "\ea44"; -} - -.hm-spa-face:before { - content: "\ea45"; -} - -.hm-spa-stone-flower:before { - content: "\ea46"; -} - -.hm-spa-stone:before { - content: "\ea47"; -} - -.hm-spark:before { - content: "\ea48"; -} - -.hm-speaker-off:before { - content: "\ea49"; -} - -.hm-speaker-on:before { - content: "\ea4a"; -} - -.hm-spoon-fork:before { - content: "\ea4b"; -} - -.hm-spoon:before { - content: "\ea4c"; -} - -.hm-star:before { - content: "\ea4d"; -} - -.hm-step-flow:before { - content: "\ea4e"; -} - -.hm-steps:before { - content: "\ea4f"; -} - -.hm-stop-watch:before { - content: "\ea50"; -} - -.hm-stop:before { - content: "\ea51"; -} - -.hm-support-call:before { - content: "\ea52"; -} - -.hm-tab:before { - content: "\ea53"; -} - -.hm-table-lamp:before { - content: "\ea54"; -} - -.hm-tablet:before { - content: "\ea55"; -} - -.hm-tag:before { - content: "\ea56"; -} - -.hm-target-arrow:before { - content: "\ea57"; -} - -.hm-target:before { - content: "\ea58"; -} - -.hm-target1:before { - content: "\ea59"; -} - -.hm-team-carousel:before { - content: "\ea5a"; -} - -.hm-team-member:before { - content: "\ea5b"; -} - -.hm-tennis-ball:before { - content: "\ea5c"; -} - -.hm-terminal:before { - content: "\ea5d"; -} - -.hm-testimonial-carousel:before { - content: "\ea5e"; -} - -.hm-testimonial:before { - content: "\ea5f"; -} - -.hm-text-animation:before { - content: "\ea60"; -} - -.hm-theatre:before { - content: "\ea61"; -} - -.hm-tick-circle:before { - content: "\ea62"; -} - -.hm-tick:before { - content: "\ea63"; -} - -.hm-tickets:before { - content: "\ea64"; -} - -.hm-tie-knot:before { - content: "\ea65"; -} - -.hm-tie:before { - content: "\ea66"; -} - -.hm-timeline:before { - content: "\ea67"; -} - -.hm-toggle:before { - content: "\ea68"; -} - -.hm-tools:before { - content: "\ea69"; -} - -.hm-tree-square:before { - content: "\ea6a"; -} - -.hm-twitter-bird:before { - content: "\ea6b"; -} - -.hm-twitter:before { - content: "\ea6c"; -} - -.hm-ufo:before { - content: "\ea6d"; -} - -.hm-umbralla:before { - content: "\ea6e"; -} - -.hm-unlock:before { - content: "\ea6f"; -} - -.hm-up-down:before { - content: "\ea70"; -} - -.hm-upload:before { - content: "\ea71"; -} - -.hm-upward-top-right:before { - content: "\ea72"; -} - -.hm-user-female:before { - content: "\ea73"; -} - -.hm-user-id:before { - content: "\ea74"; -} - -.hm-user-male:before { - content: "\ea75"; -} - -.hm-video-camera:before { - content: "\ea76"; -} - -.hm-water-drop:before { - content: "\ea77"; -} - -.hm-weather-cloud-day:before { - content: "\ea78"; -} - -.hm-weather-cloud:before { - content: "\ea79"; -} - -.hm-weather-day-rain:before { - content: "\ea7a"; -} - -.hm-weather-day-snow:before { - content: "\ea7b"; -} - -.hm-weather-day-windy-rain:before { - content: "\ea7c"; -} - -.hm-weather-flood:before { - content: "\ea7d"; -} - -.hm-weather-night-cloud:before { - content: "\ea7e"; -} - -.hm-weather-rain-alt:before { - content: "\ea7f"; -} - -.hm-weather-rain:before { - content: "\ea80"; -} - -.hm-weather-snow:before { - content: "\ea81"; -} - -.hm-weather-sun-rain:before { - content: "\ea82"; -} - -.hm-weather-sun:before { - content: "\ea83"; -} - -.hm-weather-sunny-day:before { - content: "\ea84"; -} - -.hm-weather-thunder:before { - content: "\ea85"; -} - -.hm-weather-windy-rain:before { - content: "\ea86"; -} - -.hm-webcam1:before { - content: "\ea87"; -} - -.hm-webcam2:before { - content: "\ea88"; -} - -.hm-weight-scale:before { - content: "\ea89"; -} - -.hm-windows:before { - content: "\ea8a"; -} - -.hm-wine-glass2:before { - content: "\ea8b"; -} - -.hm-wine-glass:before { - content: "\ea8c"; -} - -.hm-worker-cap:before { - content: "\ea8d"; -} - -.hm-youtube:before { - content: "\ea8e"; -} - -.hm-centralize:before { - content: "\ea8f"; -} - -.hm-add-section:before { - content: "\ea90"; -} - -.hm-advanced-heading:before { - content: "\ea91"; -} - -.hm-air-baloon:before { - content: "\ea92"; -} - -.hm-arrow2:before { - content: "\ea93"; -} - -.hm-bicycle2:before { - content: "\ea94"; -} - -.hm-bond2:before { - content: "\ea95"; -} - -.hm-bond3:before { - content: "\ea96"; -} - -.hm-bond4:before { - content: "\ea97"; -} - -.hm-calendar2:before { - content: "\ea98"; -} - -.hm-carousel:before { - content: "\ea99"; -} - -.hm-code-page:before { - content: "\ea9a"; -} - -.hm-comment-circle:before { - content: "\ea9b"; -} - -.hm-comment-square:before { - content: "\ea9c"; -} - -.hm-copy:before { - content: "\ea9d"; -} - -.hm-cursor:before { - content: "\ea9e"; -} - -.hm-envelop2:before { - content: "\ea9f"; -} - -.hm-factory:before { - content: "\eaa0"; -} - -.hm-finger-point:before { - content: "\eaa1"; -} - -.hm-finger-swipe-both:before { - content: "\eaa2"; -} - -.hm-finger-swipe-corner:before { - content: "\eaa3"; -} - -.hm-finger-swipe-left:before { - content: "\eaa4"; -} - -.hm-finger-swipe-up:before { - content: "\eaa5"; -} - -.hm-finger-swipe:before { - content: "\eaa6"; -} - -.hm-finger-touch:before { - content: "\eaa7"; -} - -.hm-folder-network:before { - content: "\eaa8"; -} - -.hm-folder-sync:before { - content: "\eaa9"; -} - -.hm-graph-bar2:before { - content: "\eaaa"; -} - -.hm-graph-pie2:before { - content: "\eaab"; -} - -.hm-heading-h:before { - content: "\eaac"; -} - -.hm-heading-html:before { - content: "\eaad"; -} - -.hm-heart:before { - content: "\eaae"; -} - -.hm-home2:before { - content: "\eaaf"; -} - -.hm-indent-left:before { - content: "\eab0"; -} - -.hm-indent-right:before { - content: "\eab1"; -} - -.hm-lock-close:before { - content: "\eab2"; -} - -.hm-lock-open:before { - content: "\eab3"; -} - -.hm-map-pointer-add:before { - content: "\eab4"; -} - -.hm-map-pointer-check:before { - content: "\eab5"; -} - -.hm-map-pointer-delete:before { - content: "\eab6"; -} - -.hm-map-pointer2:before { - content: "\eab7"; -} - -.hm-map:before { - content: "\eab8"; -} - -.hm-navigation1:before { - content: "\eab9"; -} - -.hm-navigation2:before { - content: "\eaba"; -} - -.hm-page-export:before { - content: "\eabb"; -} - -.hm-page-sync:before { - content: "\eabc"; -} - -.hm-piramid:before { - content: "\eabd"; -} - -.hm-plug:before { - content: "\eabe"; -} - -.hm-point-marker:before { - content: "\eabf"; -} - -.hm-quote2:before { - content: "\eac0"; -} - -.hm-refresh-check:before { - content: "\eac1"; -} - -.hm-refresh:before { - content: "\eac2"; -} - -.hm-refresh2:before { - content: "\eac3"; -} - -.hm-scrolling-image:before { - content: "\eac4"; -} - -.hm-sign-turn-right:before { - content: "\eac5"; -} - -.hm-speedometer:before { - content: "\eac6"; -} - -.hm-sticky:before { - content: "\eac7"; -} - -.hm-sync-cloud:before { - content: "\eac8"; -} - -.hm-sync:before { - content: "\eac9"; -} - -.hm-sync2:before { - content: "\eaca"; -} - -.hm-table-lamp2:before { - content: "\eacb"; -} - -.hm-target2:before { - content: "\eacc"; -} - -.hm-timeline-spiral:before { - content: "\eacd"; -} - -.hm-tv:before { - content: "\eace"; -} - -.hm-vespa:before { - content: "\eacf"; -} - -.hm-happyaddons:before { - content: "\ead0"; -} - -.hm-brain:before { - content: "\ead1"; -} - -.hm-breadcrumbs:before { - content: "\ead2"; -} - -.hm-circular-chat:before { - content: "\ead3"; -} - -.hm-currency-exchange:before { - content: "\ead4"; -} - -.hm-cta:before { - content: "\ead5"; -} - -.hm-data-table:before { - content: "\ead6"; -} - -.hm-display-condition:before { - content: "\ead7"; -} - -.hm-digital-memory:before { - content: "\ead8"; -} - -.hm-dollar-box:before { - content: "\ead9"; -} - -.hm-faq:before { - content: "\eada"; -} - -.hm-facebook-feed:before { - content: "\eadb"; -} - -.hm-header-footer:before { - content: "\eadc"; -} - -.hm-heart:before { - content: "\eadd"; -} - -.hm-image-accordion:before { - content: "\eade"; -} - -.hm-image-masking:before { - content: "\eadf"; -} - -.hm-instagram:before { - content: "\eae0"; -} - -.hm-mail-chimp:before { - content: "\eae1"; -} - -.hm-minus-large:before { - content: "\eae2"; -} - -.hm-minus-small:before { - content: "\eae3"; -} - -.hm-mobile-chat:before { - content: "\eae4"; -} - -.hm-motion-button:before { - content: "\eae5"; -} - -.hm-news-ticker:before { - content: "\eae6"; -} - -.hm-offcanvas-menu:before { - content: "\eae7"; -} - -.hm-post-grid:before { - content: "\eae8"; -} - -.hm-post-list:before { - content: "\eae9"; -} - -.hm-post-tab:before { - content: "\eaea"; -} - -.hm-pricing-menu:before { - content: "\eaeb"; -} - -.hm-scheduled-section:before { - content: "\eaec"; -} - -.hm-section-link:before { - content: "\eaed"; -} - -.hm-sticky-video:before { - content: "\eaee"; -} - -.hm-section-nesting:before { - content: "\eaef"; -} - -.hm-traffic-signal:before { - content: "\eaf0"; -} - -.hm-tshirt:before { - content: "\eaf1"; -} - -.hm-twitter-feed:before { - content: "\eaf2"; -} - -.hm-grid-layout:before { - content: "\eaf3"; -} - -.hm-add-to-cart-button:before { - content: "\eaf4"; - -} - -.hm-billing-address:before { - content: "\eaf5"; - -} - -.hm-cart:before { - content: "\eaf6"; - -} - -.hm-Category-Carousel:before { - content: "\eaf7"; - -} - -.hm-Category-Grid:before { - content: "\eaf8"; - -} - -.hm-Category-List:before { - content: "\eaf9"; - -} - -.hm-checkout-1:before { - content: "\eafa"; - -} - -.hm-checkout-2:before { - content: "\eafb"; - -} - -.hm-compare:before { - content: "\eafc"; - -} - -.hm-edit-menu:before { - content: "\eafd"; - -} - -.hm-facebook-review:before { - content: "\eafe"; - -} - -.hm-fb-messanger:before { - content: "\eaff"; - -} - -.hm-filter:before { - content: "\eb00"; - -} - -.hm-google-review:before { - content: "\eb01"; - -} - -.hm-grid-filter:before { - content: "\eb02"; - -} - -.hm-home3:before { - content: "\eb03"; - -} - -.hm-horizontal-timeline:before { - content: "\eb04"; - -} - -.hm-image-scroll:before { - content: "\eb05"; - -} - -.hm-mini-cart:before { - content: "\eb06"; - -} - -.hm-off-canvas-cart:before { - content: "\eb07"; - -} - -.hm-popup1:before { - content: "\eb08"; - -} - -.hm-post-list:before { - content: "\eb09"; - -} - -.hm-Product-Carousel:before { - content: "\eb0a"; - -} - -.hm-product-filter:before { - content: "\eb0b"; - -} - -.hm-product-gallery:before { - content: "\eb0c"; - -} - -.hm-Product-Grid:before { - content: "\eb0d"; - -} - -.hm-Product-List-double:before { - content: "\eb0e"; - -} - -.hm-product-list-single:before { - content: "\eb0f"; - -} - -.hm-product-rating:before { - content: "\eb10"; - -} - -.hm-product-table:before { - content: "\eb11"; - -} - -.hm-product-variation:before { - content: "\eb12"; - -} - -.hm-retina-image:before { - content: "\eb13"; - -} - -.hm-shipping-address:before { - content: "\eb14"; - -} - -.hm-shop:before { - content: "\eb15"; - -} - -.hm-shopping-details:before { - content: "\eb16"; - -} - -.hm-sticky-video-2:before { - content: "\eb17"; - -} - -.hm-Template-Import:before { - content: "\eb18"; - -} - -.hm-trendy-product:before { - content: "\eb19"; - -} - -.hm-user-check:before { - content: "\eb1a"; - -} - -.hm-User-Circle:before { - content: "\eb1b"; - -} - -.hm-user-plus:before { - content: "\eb1c"; - -} - -.hm-user:before { - content: "\eb1d"; - -} - -.hm-video-gallery:before { - content: "\eb1e"; - -} - -.hm-wishlist:before { - content: "\eb1f"; - -} diff --git a/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/happy-icons.min.css b/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/happy-icons.min.css deleted file mode 100644 index 4b8a3495..00000000 --- a/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/happy-icons.min.css +++ /dev/null @@ -1 +0,0 @@ -@font-face{font-family:'Happy Icons';src:url('../fonts/happy-icons.woff2') format('woff2'),url('../fonts/happy-icons.woff') format('woff'),url('../fonts/happy-icons.svg#happy-icons') format('svg');font-weight:normal;font-style:normal;font-display:swap}.hm,.fashm{font-family:'Happy Icons'!important;speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale} .hm-3d-rotate:before{content:"\e900"} .hm-degree:before{content:"\e901"} .hm-accordion-horizontal:before{content:"\e902"} .hm-accordion-vertical:before{content:"\e903"} .hm-alarm-clock:before{content:"\e904"} .hm-alien-gun:before{content:"\e905"} .hm-alien:before{content:"\e906"} .hm-anchor:before{content:"\e907"} .hm-android:before{content:"\e908"} .hm-angle-down:before{content:"\e909"} .hm-angle-left:before{content:"\e90a"} .hm-angle-right:before{content:"\e90b"} .hm-angle-up:before{content:"\e90c"} .hm-apple:before{content:"\e90d"} .hm-arrow-left:before{content:"\e90e"} .hm-arrow-right:before{content:"\e90f"} .hm-arrow-zoom-out:before{content:"\e910"} .hm-arrow-corner:before{content:"\e911"} .hm-arrow-down:before{content:"\e912"} .hm-arrow-left1:before{content:"\e913"} .hm-arrow-right1:before{content:"\e914"} .hm-arrow-up:before{content:"\e915"} .hm-article:before{content:"\e916"} .hm-avatar-man:before{content:"\e917"} .hm-avatar-woman:before{content:"\e918"} .hm-badge1:before{content:"\e919"} .hm-badge2:before{content:"\e91a"} .hm-badge3:before{content:"\e91b"} .hm-bamboo:before{content:"\e91c"} .hm-basketball:before{content:"\e91d"} .hm-battery:before{content:"\e91e"} .hm-beach-seat:before{content:"\e91f"} .hm-bell:before{content:"\e920"} .hm-bicycle:before{content:"\e921"} .hm-blog-content:before{content:"\e922"} .hm-bluetooth:before{content:"\e923"} .hm-board:before{content:"\e924"} .hm-body:before{content:"\e925"} .hm-bomb:before{content:"\e926"} .hm-bond-hand:before{content:"\e927"} .hm-bond:before{content:"\e928"} .hm-bonsai:before{content:"\e929"} .hm-book:before{content:"\e92a"} .hm-bowl:before{content:"\e92b"} .hm-brick-wall:before{content:"\e92c"} .hm-brush-paint:before{content:"\e92d"} .hm-brush-roll:before{content:"\e92e"} .hm-brush:before{content:"\e92f"} .hm-bug:before{content:"\e930"} .hm-bulb:before{content:"\e931"} .hm-calculation:before{content:"\e932"} .hm-calendar:before{content:"\e933"} .hm-camera:before{content:"\e934"} .hm-candle:before{content:"\e935"} .hm-candles:before{content:"\e936"} .hm-car:before{content:"\e937"} .hm-card:before{content:"\e938"} .hm-caret-down:before{content:"\e939"} .hm-caret-fill-down:before{content:"\e93a"} .hm-caret-fill-left:before{content:"\e93b"} .hm-caret-fill-right:before{content:"\e93c"} .hm-caret-fill-up:before{content:"\e93d"} .hm-caret-left:before{content:"\e93e"} .hm-caret-right:before{content:"\e93f"} .hm-caret-up:before{content:"\e940"} .hm-carousal:before{content:"\e941"} .hm-cart-empty:before{content:"\e942"} .hm-cart-full:before{content:"\e943"} .hm-caution:before{content:"\e944"} .hm-chair:before{content:"\e945"} .hm-chair2:before{content:"\e946"} .hm-chat-bubble-single:before{content:"\e947"} .hm-chat-bubble:before{content:"\e948"} .hm-cheese:before{content:"\e949"} .hm-chef-cap:before{content:"\e94a"} .hm-clip-board:before{content:"\e94b"} .hm-clip:before{content:"\e94c"} .hm-cloud-down:before{content:"\e94d"} .hm-cloud-up:before{content:"\e94e"} .hm-cloud:before{content:"\e94f"} .hm-code-browser:before{content:"\e950"} .hm-code-clean:before{content:"\e951"} .hm-code:before{content:"\e952"} .hm-cog:before{content:"\e953"} .hm-color-card:before{content:"\e954"} .hm-color-plate:before{content:"\e955"} .hm-compass-math:before{content:"\e956"} .hm-compass:before{content:"\e957"} .hm-corner:before{content:"\e958"} .hm-crop:before{content:"\e959"} .hm-cross-circle:before{content:"\e95a"} .hm-cross-game:before{content:"\e95b"} .hm-cross-gap:before{content:"\e95c"} .hm-cross:before{content:"\e95d"} .hm-crown:before{content:"\e95e"} .hm-cube:before{content:"\e95f"} .hm-cup-coffee:before{content:"\e960"} .hm-cup:before{content:"\e961"} .hm-currency-paper:before{content:"\e962"} .hm-dashboard:before{content:"\e963"} .hm-delivery-van:before{content:"\e964"} .hm-diamond-ring:before{content:"\e965"} .hm-direction-both:before{content:"\e966"} .hm-direction-right:before{content:"\e967"} .hm-disable-person:before{content:"\e968"} .hm-disc:before{content:"\e969"} .hm-dislike:before{content:"\e96a"} .hm-dollar-on-hand:before{content:"\e96b"} .hm-door-path:before{content:"\e96c"} .hm-Download-circle:before{content:"\e96d"} .hm-download:before{content:"\e96e"} .hm-drag-inside:before{content:"\e96f"} .hm-drag-outside:before{content:"\e970"} .hm-drag:before{content:"\e971"} .hm-drawer:before{content:"\e972"} .hm-dribbble:before{content:"\e973"} .hm-dropper:before{content:"\e974"} .hm-egg-fry:before{content:"\e975"} .hm-ellipsis-fill-h:before{content:"\e976"} .hm-ellipsis-fill-v:before{content:"\e977"} .hm-ellipsis-horizontal:before{content:"\e978"} .hm-ellipsis-vertical:before{content:"\e979"} .hm-emo-normal:before{content:"\e97a"} .hm-emo-sad:before{content:"\e97b"} .hm-emo-smile:before{content:"\e97c"} .hm-envelop:before{content:"\e97d"} .hm-facebook:before{content:"\e97e"} .hm-fancy-futton:before{content:"\e97f"} .hm-feeder:before{content:"\e980"} .hm-file-cabinet:before{content:"\e981"} .hm-file-rotate:before{content:"\e982"} .hm-file:before{content:"\e983"} .hm-files:before{content:"\e984"} .hm-film-roll:before{content:"\e985"} .hm-film:before{content:"\e986"} .hm-finger-index:before{content:"\e987"} .hm-finger-print:before{content:"\e988"} .hm-fire-flame:before{content:"\e989"} .hm-flag:before{content:"\e98a"} .hm-flip-card1:before{content:"\e98b"} .hm-flip-card2:before{content:"\e98c"} .hm-folder-network:before{content:"\e98d"} .hm-folder:before{content:"\e98e"} .hm-football:before{content:"\e98f"} .hm-footer:before{content:"\e990"} .hm-form:before{content:"\e991"} .hm-forward:before{content:"\e992"} .hm-fountain-pen:before{content:"\e993"} .hm-gender-female:before{content:"\e994"} .hm-gender-male:before{content:"\e995"} .hm-gender-sign:before{content:"\e996"} .hm-gender:before{content:"\e997"} .hm-ghost:before{content:"\e998"} .hm-gift-box:before{content:"\e999"} .hm-globe1:before{content:"\e99a"} .hm-globe2:before{content:"\e99b"} .hm-globe3:before{content:"\e99c"} .hm-globe4:before{content:"\e99d"} .hm-google:before{content:"\e99e"} .hm-graduate-cap:before{content:"\e99f"} .hm-graph-bar:before{content:"\e9a0"} .hm-graph-pie:before{content:"\e9a1"} .hm-graph:before{content:"\e9a2"} .hm-grid-even:before{content:"\e9a3"} .hm-grid-masonry:before{content:"\e9a4"} .hm-grid-twist:before{content:"\e9a5"} .hm-grid:before{content:"\e9a6"} .hm-group:before{content:"\e9a7"} .hm-hand-mike:before{content:"\e9a8"} .hm-hand-watch:before{content:"\e9a9"} .hm-hand:before{content:"\e9aa"} .hm-header:before{content:"\e9ab"} .hm-headphone:before{content:"\e9ac"} .hm-headset:before{content:"\e9ad"} .hm-heart-beat:before{content:"\e9ae"} .hm-hexa:before{content:"\e9af"} .hm-highlighter:before{content:"\e9b0"} .hm-home:before{content:"\e9b1"} .hm-hot-spot:before{content:"\e9b2"} .hm-hotdog:before{content:"\e9b3"} .hm-ice-cream:before{content:"\e9b4"} .hm-icon-box:before{content:"\e9b5"} .hm-imac:before{content:"\e9b6"} .hm-image-compare:before{content:"\e9b7"} .hm-image-slider:before{content:"\e9b8"} .hm-image:before{content:"\e9b9"} .hm-inbox:before{content:"\e9ba"} .hm-infinity:before{content:"\e9bb"} .hm-info:before{content:"\e9bc"} .hm-injection:before{content:"\e9bd"} .hm-instagram:before{content:"\e9be"} .hm-jar-chemical:before{content:"\e9bf"} .hm-key:before{content:"\e9c0"} .hm-language-change:before{content:"\e9c1"} .hm-laptop:before{content:"\e9c2"} .hm-layer:before{content:"\e9c3"} .hm-lens:before{content:"\e9c4"} .hm-like:before{content:"\e9c5"} .hm-line-graph-pointed:before{content:"\e9c6"} .hm-link:before{content:"\e9c7"} .hm-linkedin:before{content:"\e9c8"} .hm-linux:before{content:"\e9c9"} .hm-list-2:before{content:"\e9ca"} .hm-list-group:before{content:"\e9cb"} .hm-list:before{content:"\e9cc"} .hm-location-pointer:before{content:"\e9cd"} .hm-lock:before{content:"\e9ce"} .hm-logo-carousel:before{content:"\e9cf"} .hm-logo-grid:before{content:"\e9d0"} .hm-lotus:before{content:"\e9d1"} .hm-love:before{content:"\e9d2"} .hm-madel:before{content:"\e9d3"} .hm-magic-wand:before{content:"\e9d4"} .hm-magnet:before{content:"\e9d5"} .hm-mail-open:before{content:"\e9d6"} .hm-man-range:before{content:"\e9d7"} .hm-map-marker:before{content:"\e9d8"} .hm-map-pointer:before{content:"\e9d9"} .hm-measurement:before{content:"\e9da"} .hm-memory:before{content:"\e9db"} .hm-menu-price:before{content:"\e9dc"} .hm-micro-chip:before{content:"\e9dd"} .hm-microphone1:before{content:"\e9de"} .hm-microphone2:before{content:"\e9df"} .hm-mobile:before{content:"\e9e0"} .hm-money-bag:before{content:"\e9e1"} .hm-money:before{content:"\e9e2"} .hm-monitor:before{content:"\e9e3"} .hm-mouse:before{content:"\e9e4"} .hm-muscle:before{content:"\e9e5"} .hm-net:before{content:"\e9e6"} .hm-network1:before{content:"\e9e7"} .hm-network2:before{content:"\e9e8"} .hm-newspaper:before{content:"\e9e9"} .hm-nuclear-circle:before{content:"\e9ea"} .hm-office-file:before{content:"\e9eb"} .hm-pacman:before{content:"\e9ec"} .hm-paper-fold:before{content:"\e9ed"} .hm-paper-plane-alt:before{content:"\e9ee"} .hm-paper-plane:before{content:"\e9ef"} .hm-pause:before{content:"\e9f0"} .hm-pen-head:before{content:"\e9f1"} .hm-pen-pencil:before{content:"\e9f2"} .hm-pen-scale:before{content:"\e9f3"} .hm-pen-paper:before{content:"\e9f4"} .hm-pen:before{content:"\e9f5"} .hm-pencil:before{content:"\e9f6"} .hm-pendrive:before{content:"\e9f7"} .hm-phone:before{content:"\e9f8"} .hm-pillar:before{content:"\e9f9"} .hm-pin-man-range:before{content:"\e9fa"} .hm-pin-man:before{content:"\e9fb"} .hm-pin:before{content:"\e9fc"} .hm-plane:before{content:"\e9fd"} .hm-play-end:before{content:"\e9fe"} .hm-play-next:before{content:"\e9ff"} .hm-play-previous:before{content:"\ea00"} .hm-play-start:before{content:"\ea01"} .hm-play-button:before{content:"\ea02"} .hm-play-store:before{content:"\ea03"} .hm-play:before{content:"\ea04"} .hm-playing-card:before{content:"\ea05"} .hm-plus-box:before{content:"\ea06"} .hm-plus-circle:before{content:"\ea07"} .hm-plus-gap:before{content:"\ea08"} .hm-plus-open:before{content:"\ea09"} .hm-popup:before{content:"\ea0a"} .hm-power:before{content:"\ea0b"} .hm-printer:before{content:"\ea0c"} .hm-progress-bar:before{content:"\ea0d"} .hm-promo:before{content:"\ea0e"} .hm-pulse:before{content:"\ea0f"} .hm-puzzle:before{content:"\ea10"} .hm-question:before{content:"\ea11"} .hm-quote:before{content:"\ea12"} .hm-radar:before{content:"\ea13"} .hm-radiation:before{content:"\ea14"} .hm-reading-glass-alt:before{content:"\ea15"} .hm-reading-glass:before{content:"\ea16"} .hm-recycle-bin:before{content:"\ea17"} .hm-recycle:before{content:"\ea18"} .hm-refresh-time:before{content:"\ea19"} .hm-reply:before{content:"\ea1a"} .hm-responsive-device:before{content:"\ea1b"} .hm-review:before{content:"\ea1c"} .hm-rocket1:before{content:"\ea1d"} .hm-rocket2:before{content:"\ea1e"} .hm-rss:before{content:"\ea1f"} .hm-safety-cap:before{content:"\ea20"} .hm-safety-kit:before{content:"\ea21"} .hm-sand-watch:before{content:"\ea22"} .hm-scale:before{content:"\ea23"} .hm-scanner:before{content:"\ea24"} .hm-scissor:before{content:"\ea25"} .hm-screen:before{content:"\ea26"} .hm-search:before{content:"\ea27"} .hm-seo:before{content:"\ea28"} .hm-server-network:before{content:"\ea29"} .hm-server:before{content:"\ea2a"} .hm-share:before{content:"\ea2b"} .hm-shield:before{content:"\ea2c"} .hm-ship:before{content:"\ea2d"} .hm-shirt:before{content:"\ea2e"} .hm-shopping-bag1:before{content:"\ea2f"} .hm-shopping-bag2:before{content:"\ea30"} .hm-shopping-bag3:before{content:"\ea31"} .hm-shopping-bag4:before{content:"\ea32"} .hm-shuffle:before{content:"\ea33"} .hm-shutter:before{content:"\ea34"} .hm-sign-in:before{content:"\ea35"} .hm-sign-out:before{content:"\ea36"} .hm-sitemap1:before{content:"\ea37"} .hm-sitemap2:before{content:"\ea38"} .hm-skart:before{content:"\ea39"} .hm-skull:before{content:"\ea3a"} .hm-skyscraper:before{content:"\ea3b"} .hm-slider-doc:before{content:"\ea3c"} .hm-slider-h-range:before{content:"\ea3d"} .hm-slider-image:before{content:"\ea3e"} .hm-slider-range-h:before{content:"\ea3f"} .hm-slider-v-open:before{content:"\ea40"} .hm-slider-video:before{content:"\ea41"} .hm-slider:before{content:"\ea42"} .hm-smart-watch:before{content:"\ea43"} .hm-snow:before{content:"\ea44"} .hm-spa-face:before{content:"\ea45"} .hm-spa-stone-flower:before{content:"\ea46"} .hm-spa-stone:before{content:"\ea47"} .hm-spark:before{content:"\ea48"} .hm-speaker-off:before{content:"\ea49"} .hm-speaker-on:before{content:"\ea4a"} .hm-spoon-fork:before{content:"\ea4b"} .hm-spoon:before{content:"\ea4c"} .hm-star:before{content:"\ea4d"} .hm-step-flow:before{content:"\ea4e"} .hm-steps:before{content:"\ea4f"} .hm-stop-watch:before{content:"\ea50"} .hm-stop:before{content:"\ea51"} .hm-support-call:before{content:"\ea52"} .hm-tab:before{content:"\ea53"} .hm-table-lamp:before{content:"\ea54"} .hm-tablet:before{content:"\ea55"} .hm-tag:before{content:"\ea56"} .hm-target-arrow:before{content:"\ea57"} .hm-target:before{content:"\ea58"} .hm-target1:before{content:"\ea59"} .hm-team-carousel:before{content:"\ea5a"} .hm-team-member:before{content:"\ea5b"} .hm-tennis-ball:before{content:"\ea5c"} .hm-terminal:before{content:"\ea5d"} .hm-testimonial-carousel:before{content:"\ea5e"} .hm-testimonial:before{content:"\ea5f"} .hm-text-animation:before{content:"\ea60"} .hm-theatre:before{content:"\ea61"} .hm-tick-circle:before{content:"\ea62"} .hm-tick:before{content:"\ea63"} .hm-tickets:before{content:"\ea64"} .hm-tie-knot:before{content:"\ea65"} .hm-tie:before{content:"\ea66"} .hm-timeline:before{content:"\ea67"} .hm-toggle:before{content:"\ea68"} .hm-tools:before{content:"\ea69"} .hm-tree-square:before{content:"\ea6a"} .hm-twitter-bird:before{content:"\ea6b"} .hm-twitter:before{content:"\ea6c"} .hm-ufo:before{content:"\ea6d"} .hm-umbralla:before{content:"\ea6e"} .hm-unlock:before{content:"\ea6f"} .hm-up-down:before{content:"\ea70"} .hm-upload:before{content:"\ea71"} .hm-upward-top-right:before{content:"\ea72"} .hm-user-female:before{content:"\ea73"} .hm-user-id:before{content:"\ea74"} .hm-user-male:before{content:"\ea75"} .hm-video-camera:before{content:"\ea76"} .hm-water-drop:before{content:"\ea77"} .hm-weather-cloud-day:before{content:"\ea78"} .hm-weather-cloud:before{content:"\ea79"} .hm-weather-day-rain:before{content:"\ea7a"} .hm-weather-day-snow:before{content:"\ea7b"} .hm-weather-day-windy-rain:before{content:"\ea7c"} .hm-weather-flood:before{content:"\ea7d"} .hm-weather-night-cloud:before{content:"\ea7e"} .hm-weather-rain-alt:before{content:"\ea7f"} .hm-weather-rain:before{content:"\ea80"} .hm-weather-snow:before{content:"\ea81"} .hm-weather-sun-rain:before{content:"\ea82"} .hm-weather-sun:before{content:"\ea83"} .hm-weather-sunny-day:before{content:"\ea84"} .hm-weather-thunder:before{content:"\ea85"} .hm-weather-windy-rain:before{content:"\ea86"} .hm-webcam1:before{content:"\ea87"} .hm-webcam2:before{content:"\ea88"} .hm-weight-scale:before{content:"\ea89"} .hm-windows:before{content:"\ea8a"} .hm-wine-glass2:before{content:"\ea8b"} .hm-wine-glass:before{content:"\ea8c"} .hm-worker-cap:before{content:"\ea8d"} .hm-youtube:before{content:"\ea8e"} .hm-centralize:before{content:"\ea8f"} .hm-add-section:before{content:"\ea90"} .hm-advanced-heading:before{content:"\ea91"} .hm-air-baloon:before{content:"\ea92"} .hm-arrow2:before{content:"\ea93"} .hm-bicycle2:before{content:"\ea94"} .hm-bond2:before{content:"\ea95"} .hm-bond3:before{content:"\ea96"} .hm-bond4:before{content:"\ea97"} .hm-calendar2:before{content:"\ea98"} .hm-carousel:before{content:"\ea99"} .hm-code-page:before{content:"\ea9a"} .hm-comment-circle:before{content:"\ea9b"} .hm-comment-square:before{content:"\ea9c"} .hm-copy:before{content:"\ea9d"} .hm-cursor:before{content:"\ea9e"} .hm-envelop2:before{content:"\ea9f"} .hm-factory:before{content:"\eaa0"} .hm-finger-point:before{content:"\eaa1"} .hm-finger-swipe-both:before{content:"\eaa2"} .hm-finger-swipe-corner:before{content:"\eaa3"} .hm-finger-swipe-left:before{content:"\eaa4"} .hm-finger-swipe-up:before{content:"\eaa5"} .hm-finger-swipe:before{content:"\eaa6"} .hm-finger-touch:before{content:"\eaa7"} .hm-folder-network:before{content:"\eaa8"} .hm-folder-sync:before{content:"\eaa9"} .hm-graph-bar2:before{content:"\eaaa"} .hm-graph-pie2:before{content:"\eaab"} .hm-heading-h:before{content:"\eaac"} .hm-heading-html:before{content:"\eaad"} .hm-heart:before{content:"\eaae"} .hm-home2:before{content:"\eaaf"} .hm-indent-left:before{content:"\eab0"} .hm-indent-right:before{content:"\eab1"} .hm-lock-close:before{content:"\eab2"} .hm-lock-open:before{content:"\eab3"} .hm-map-pointer-add:before{content:"\eab4"} .hm-map-pointer-check:before{content:"\eab5"} .hm-map-pointer-delete:before{content:"\eab6"} .hm-map-pointer2:before{content:"\eab7"} .hm-map:before{content:"\eab8"} .hm-navigation1:before{content:"\eab9"} .hm-navigation2:before{content:"\eaba"} .hm-page-export:before{content:"\eabb"} .hm-page-sync:before{content:"\eabc"} .hm-piramid:before{content:"\eabd"} .hm-plug:before{content:"\eabe"} .hm-point-marker:before{content:"\eabf"} .hm-quote2:before{content:"\eac0"} .hm-refresh-check:before{content:"\eac1"} .hm-refresh:before{content:"\eac2"} .hm-refresh2:before{content:"\eac3"} .hm-scrolling-image:before{content:"\eac4"} .hm-sign-turn-right:before{content:"\eac5"} .hm-speedometer:before{content:"\eac6"} .hm-sticky:before{content:"\eac7"} .hm-sync-cloud:before{content:"\eac8"} .hm-sync:before{content:"\eac9"} .hm-sync2:before{content:"\eaca"} .hm-table-lamp2:before{content:"\eacb"} .hm-target2:before{content:"\eacc"} .hm-timeline-spiral:before{content:"\eacd"} .hm-tv:before{content:"\eace"} .hm-vespa:before{content:"\eacf"} .hm-happyaddons:before{content:"\ead0"} .hm-brain:before{content:"\ead1"} .hm-breadcrumbs:before{content:"\ead2"} .hm-circular-chat:before{content:"\ead3"} .hm-currency-exchange:before{content:"\ead4"} .hm-cta:before{content:"\ead5"} .hm-data-table:before{content:"\ead6"} .hm-display-condition:before{content:"\ead7"} .hm-digital-memory:before{content:"\ead8"} .hm-dollar-box:before{content:"\ead9"} .hm-faq:before{content:"\eada"} .hm-facebook-feed:before{content:"\eadb"} .hm-header-footer:before{content:"\eadc"} .hm-heart:before{content:"\eadd"} .hm-image-accordion:before{content:"\eade"} .hm-image-masking:before{content:"\eadf"} .hm-instagram:before{content:"\eae0"} .hm-mail-chimp:before{content:"\eae1"} .hm-minus-large:before{content:"\eae2"} .hm-minus-small:before{content:"\eae3"} .hm-mobile-chat:before{content:"\eae4"} .hm-motion-button:before{content:"\eae5"} .hm-news-ticker:before{content:"\eae6"} .hm-offcanvas-menu:before{content:"\eae7"} .hm-post-grid:before{content:"\eae8"} .hm-post-list:before{content:"\eae9"} .hm-post-tab:before{content:"\eaea"} .hm-pricing-menu:before{content:"\eaeb"} .hm-scheduled-section:before{content:"\eaec"} .hm-section-link:before{content:"\eaed"} .hm-sticky-video:before{content:"\eaee"} .hm-section-nesting:before{content:"\eaef"} .hm-traffic-signal:before{content:"\eaf0"} .hm-tshirt:before{content:"\eaf1"} .hm-twitter-feed:before{content:"\eaf2"} .hm-grid-layout:before{content:"\eaf3"} .hm-add-to-cart-button:before{content:"\eaf4"} .hm-billing-address:before{content:"\eaf5"} .hm-cart:before{content:"\eaf6"} .hm-Category-Carousel:before{content:"\eaf7"} .hm-Category-Grid:before{content:"\eaf8"} .hm-Category-List:before{content:"\eaf9"} .hm-checkout-1:before{content:"\eafa"} .hm-checkout-2:before{content:"\eafb"} .hm-compare:before{content:"\eafc"} .hm-edit-menu:before{content:"\eafd"} .hm-facebook-review:before{content:"\eafe"} .hm-fb-messanger:before{content:"\eaff"} .hm-filter:before{content:"\eb00"} .hm-google-review:before{content:"\eb01"} .hm-grid-filter:before{content:"\eb02"} .hm-home3:before{content:"\eb03"} .hm-horizontal-timeline:before{content:"\eb04"} .hm-image-scroll:before{content:"\eb05"} .hm-mini-cart:before{content:"\eb06"} .hm-off-canvas-cart:before{content:"\eb07"} .hm-popup1:before{content:"\eb08"} .hm-post-list:before{content:"\eb09"} .hm-Product-Carousel:before{content:"\eb0a"} .hm-product-filter:before{content:"\eb0b"} .hm-product-gallery:before{content:"\eb0c"} .hm-Product-Grid:before{content:"\eb0d"} .hm-Product-List-double:before{content:"\eb0e"} .hm-product-list-single:before{content:"\eb0f"} .hm-product-rating:before{content:"\eb10"} .hm-product-table:before{content:"\eb11"} .hm-product-variation:before{content:"\eb12"} .hm-retina-image:before{content:"\eb13"} .hm-shipping-address:before{content:"\eb14"} .hm-shop:before{content:"\eb15"} .hm-shopping-details:before{content:"\eb16"} .hm-sticky-video-2:before{content:"\eb17"} .hm-Template-Import:before{content:"\eb18"} .hm-trendy-product:before{content:"\eb19"} .hm-user-check:before{content:"\eb1a"} .hm-User-Circle:before{content:"\eb1b"} .hm-user-plus:before{content:"\eb1c"} .hm-user:before{content:"\eb1d"} .hm-video-gallery:before{content:"\eb1e"} .hm-wishlist:before{content:"\eb1f"} diff --git a/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/icomoon.css b/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/icomoon.css deleted file mode 100644 index 5b03a69e..00000000 --- a/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/icomoon.css +++ /dev/null @@ -1,1991 +0,0 @@ -@font-face { - font-family: 'icomoon'; - src: url('../fonts/icomoon.eot?shgsy3'); - src: url('../fonts/icomoon.eot?shgsy3#iefix') format('embedded-opentype'), - url('../fonts/icomoon.ttf?shgsy3') format('truetype'), - url('../fonts/icomoon.woff?shgsy3') format('woff'), - url('../fonts/icomoon.svg?shgsy3#icomoon') format('svg'); - font-weight: normal; - font-style: normal; - font-display: block; -} - -[class^="icon-"], -[class*=" icon-"] { - /* use !important to prevent issues with browser extensions that change fonts */ - font-family: 'icomoon' !important; - speak: never; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - - /* Better Font Rendering =========== */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.icon-home:before { - content: "\e900"; -} - -.icon-home2:before { - content: "\e901"; -} - -.icon-home3:before { - content: "\e902"; -} - -.icon-office:before { - content: "\e903"; -} - -.icon-newspaper:before { - content: "\e904"; -} - -.icon-pencil:before { - content: "\e905"; -} - -.icon-pencil2:before { - content: "\e906"; -} - -.icon-quill:before { - content: "\e907"; -} - -.icon-pen:before { - content: "\e908"; -} - -.icon-blog:before { - content: "\e909"; -} - -.icon-eyedropper:before { - content: "\e90a"; -} - -.icon-droplet:before { - content: "\e90b"; -} - -.icon-paint-format:before { - content: "\e90c"; -} - -.icon-image:before { - content: "\e90d"; -} - -.icon-images:before { - content: "\e90e"; -} - -.icon-camera:before { - content: "\e90f"; -} - -.icon-headphones:before { - content: "\e910"; -} - -.icon-music:before { - content: "\e911"; -} - -.icon-play:before { - content: "\e912"; -} - -.icon-film:before { - content: "\e913"; -} - -.icon-video-camera:before { - content: "\e914"; -} - -.icon-dice:before { - content: "\e915"; -} - -.icon-pacman:before { - content: "\e916"; -} - -.icon-spades:before { - content: "\e917"; -} - -.icon-clubs:before { - content: "\e918"; -} - -.icon-diamonds:before { - content: "\e919"; -} - -.icon-bullhorn:before { - content: "\e91a"; -} - -.icon-connection:before { - content: "\e91b"; -} - -.icon-podcast:before { - content: "\e91c"; -} - -.icon-feed:before { - content: "\e91d"; -} - -.icon-mic:before { - content: "\e91e"; -} - -.icon-book:before { - content: "\e91f"; -} - -.icon-books:before { - content: "\e920"; -} - -.icon-library:before { - content: "\e921"; -} - -.icon-file-text:before { - content: "\e922"; -} - -.icon-profile:before { - content: "\e923"; -} - -.icon-file-empty:before { - content: "\e924"; -} - -.icon-files-empty:before { - content: "\e925"; -} - -.icon-file-text2:before { - content: "\e926"; -} - -.icon-file-picture:before { - content: "\e927"; -} - -.icon-file-music:before { - content: "\e928"; -} - -.icon-file-play:before { - content: "\e929"; -} - -.icon-file-video:before { - content: "\e92a"; -} - -.icon-file-zip:before { - content: "\e92b"; -} - -.icon-copy:before { - content: "\e92c"; -} - -.icon-paste:before { - content: "\e92d"; -} - -.icon-stack:before { - content: "\e92e"; -} - -.icon-folder:before { - content: "\e92f"; -} - -.icon-folder-open:before { - content: "\e930"; -} - -.icon-folder-plus:before { - content: "\e931"; -} - -.icon-folder-minus:before { - content: "\e932"; -} - -.icon-folder-download:before { - content: "\e933"; -} - -.icon-folder-upload:before { - content: "\e934"; -} - -.icon-price-tag:before { - content: "\e935"; -} - -.icon-price-tags:before { - content: "\e936"; -} - -.icon-barcode:before { - content: "\e937"; -} - -.icon-qrcode:before { - content: "\e938"; -} - -.icon-ticket:before { - content: "\e939"; -} - -.icon-cart:before { - content: "\e93a"; -} - -.icon-coin-dollar:before { - content: "\e93b"; -} - -.icon-coin-euro:before { - content: "\e93c"; -} - -.icon-coin-pound:before { - content: "\e93d"; -} - -.icon-coin-yen:before { - content: "\e93e"; -} - -.icon-credit-card:before { - content: "\e93f"; -} - -.icon-calculator:before { - content: "\e940"; -} - -.icon-lifebuoy:before { - content: "\e941"; -} - -.icon-phone:before { - content: "\e942"; -} - -.icon-phone-hang-up:before { - content: "\e943"; -} - -.icon-address-book:before { - content: "\e944"; -} - -.icon-envelop:before { - content: "\e945"; -} - -.icon-pushpin:before { - content: "\e946"; -} - -.icon-location:before { - content: "\e947"; -} - -.icon-location2:before { - content: "\e948"; -} - -.icon-compass:before { - content: "\e949"; -} - -.icon-compass2:before { - content: "\e94a"; -} - -.icon-map:before { - content: "\e94b"; -} - -.icon-map2:before { - content: "\e94c"; -} - -.icon-history:before { - content: "\e94d"; -} - -.icon-clock:before { - content: "\e94e"; -} - -.icon-clock2:before { - content: "\e94f"; -} - -.icon-alarm:before { - content: "\e950"; -} - -.icon-bell:before { - content: "\e951"; -} - -.icon-stopwatch:before { - content: "\e952"; -} - -.icon-calendar:before { - content: "\e953"; -} - -.icon-printer:before { - content: "\e954"; -} - -.icon-keyboard:before { - content: "\e955"; -} - -.icon-display:before { - content: "\e956"; -} - -.icon-laptop:before { - content: "\e957"; -} - -.icon-mobile:before { - content: "\e958"; -} - -.icon-mobile2:before { - content: "\e959"; -} - -.icon-tablet:before { - content: "\e95a"; -} - -.icon-tv:before { - content: "\e95b"; -} - -.icon-drawer:before { - content: "\e95c"; -} - -.icon-drawer2:before { - content: "\e95d"; -} - -.icon-box-add:before { - content: "\e95e"; -} - -.icon-box-remove:before { - content: "\e95f"; -} - -.icon-download:before { - content: "\e960"; -} - -.icon-upload:before { - content: "\e961"; -} - -.icon-floppy-disk:before { - content: "\e962"; -} - -.icon-drive:before { - content: "\e963"; -} - -.icon-database:before { - content: "\e964"; -} - -.icon-undo:before { - content: "\e965"; -} - -.icon-redo:before { - content: "\e966"; -} - -.icon-undo2:before { - content: "\e967"; -} - -.icon-redo2:before { - content: "\e968"; -} - -.icon-forward:before { - content: "\e969"; -} - -.icon-reply:before { - content: "\e96a"; -} - -.icon-bubble:before { - content: "\e96b"; -} - -.icon-bubbles:before { - content: "\e96c"; -} - -.icon-bubbles2:before { - content: "\e96d"; -} - -.icon-bubble2:before { - content: "\e96e"; -} - -.icon-bubbles3:before { - content: "\e96f"; -} - -.icon-bubbles4:before { - content: "\e970"; -} - -.icon-user:before { - content: "\e971"; -} - -.icon-users:before { - content: "\e972"; -} - -.icon-user-plus:before { - content: "\e973"; -} - -.icon-user-minus:before { - content: "\e974"; -} - -.icon-user-check:before { - content: "\e975"; -} - -.icon-user-tie:before { - content: "\e976"; -} - -.icon-quotes-left:before { - content: "\e977"; -} - -.icon-quotes-right:before { - content: "\e978"; -} - -.icon-hour-glass:before { - content: "\e979"; -} - -.icon-spinner:before { - content: "\e97a"; -} - -.icon-spinner2:before { - content: "\e97b"; -} - -.icon-spinner3:before { - content: "\e97c"; -} - -.icon-spinner4:before { - content: "\e97d"; -} - -.icon-spinner5:before { - content: "\e97e"; -} - -.icon-spinner6:before { - content: "\e97f"; -} - -.icon-spinner7:before { - content: "\e980"; -} - -.icon-spinner8:before { - content: "\e981"; -} - -.icon-spinner9:before { - content: "\e982"; -} - -.icon-spinner10:before { - content: "\e983"; -} - -.icon-spinner11:before { - content: "\e984"; -} - -.icon-binoculars:before { - content: "\e985"; -} - -.icon-search:before { - content: "\e986"; -} - -.icon-zoom-in:before { - content: "\e987"; -} - -.icon-zoom-out:before { - content: "\e988"; -} - -.icon-enlarge:before { - content: "\e989"; -} - -.icon-shrink:before { - content: "\e98a"; -} - -.icon-enlarge2:before { - content: "\e98b"; -} - -.icon-shrink2:before { - content: "\e98c"; -} - -.icon-key:before { - content: "\e98d"; -} - -.icon-key2:before { - content: "\e98e"; -} - -.icon-lock:before { - content: "\e98f"; -} - -.icon-unlocked:before { - content: "\e990"; -} - -.icon-wrench:before { - content: "\e991"; -} - -.icon-equalizer:before { - content: "\e992"; -} - -.icon-equalizer2:before { - content: "\e993"; -} - -.icon-cog:before { - content: "\e994"; -} - -.icon-cogs:before { - content: "\e995"; -} - -.icon-hammer:before { - content: "\e996"; -} - -.icon-magic-wand:before { - content: "\e997"; -} - -.icon-aid-kit:before { - content: "\e998"; -} - -.icon-bug:before { - content: "\e999"; -} - -.icon-pie-chart:before { - content: "\e99a"; -} - -.icon-stats-dots:before { - content: "\e99b"; -} - -.icon-stats-bars:before { - content: "\e99c"; -} - -.icon-stats-bars2:before { - content: "\e99d"; -} - -.icon-trophy:before { - content: "\e99e"; -} - -.icon-gift:before { - content: "\e99f"; -} - -.icon-glass:before { - content: "\e9a0"; -} - -.icon-glass2:before { - content: "\e9a1"; -} - -.icon-mug:before { - content: "\e9a2"; -} - -.icon-spoon-knife:before { - content: "\e9a3"; -} - -.icon-leaf:before { - content: "\e9a4"; -} - -.icon-rocket:before { - content: "\e9a5"; -} - -.icon-meter:before { - content: "\e9a6"; -} - -.icon-meter2:before { - content: "\e9a7"; -} - -.icon-hammer2:before { - content: "\e9a8"; -} - -.icon-fire:before { - content: "\e9a9"; -} - -.icon-lab:before { - content: "\e9aa"; -} - -.icon-magnet:before { - content: "\e9ab"; -} - -.icon-bin:before { - content: "\e9ac"; -} - -.icon-bin2:before { - content: "\e9ad"; -} - -.icon-briefcase:before { - content: "\e9ae"; -} - -.icon-airplane:before { - content: "\e9af"; -} - -.icon-truck:before { - content: "\e9b0"; -} - -.icon-road:before { - content: "\e9b1"; -} - -.icon-accessibility:before { - content: "\e9b2"; -} - -.icon-target:before { - content: "\e9b3"; -} - -.icon-shield:before { - content: "\e9b4"; -} - -.icon-power:before { - content: "\e9b5"; -} - -.icon-switch:before { - content: "\e9b6"; -} - -.icon-power-cord:before { - content: "\e9b7"; -} - -.icon-clipboard:before { - content: "\e9b8"; -} - -.icon-list-numbered:before { - content: "\e9b9"; -} - -.icon-list:before { - content: "\e9ba"; -} - -.icon-list2:before { - content: "\e9bb"; -} - -.icon-tree:before { - content: "\e9bc"; -} - -.icon-menu:before { - content: "\e9bd"; -} - -.icon-menu2:before { - content: "\e9be"; -} - -.icon-menu3:before { - content: "\e9bf"; -} - -.icon-menu4:before { - content: "\e9c0"; -} - -.icon-cloud:before { - content: "\e9c1"; -} - -.icon-cloud-download:before { - content: "\e9c2"; -} - -.icon-cloud-upload:before { - content: "\e9c3"; -} - -.icon-cloud-check:before { - content: "\e9c4"; -} - -.icon-download2:before { - content: "\e9c5"; -} - -.icon-upload2:before { - content: "\e9c6"; -} - -.icon-download3:before { - content: "\e9c7"; -} - -.icon-upload3:before { - content: "\e9c8"; -} - -.icon-sphere:before { - content: "\e9c9"; -} - -.icon-earth:before { - content: "\e9ca"; -} - -.icon-link:before { - content: "\e9cb"; -} - -.icon-flag:before { - content: "\e9cc"; -} - -.icon-attachment:before { - content: "\e9cd"; -} - -.icon-eye:before { - content: "\e9ce"; -} - -.icon-eye-plus:before { - content: "\e9cf"; -} - -.icon-eye-minus:before { - content: "\e9d0"; -} - -.icon-eye-blocked:before { - content: "\e9d1"; -} - -.icon-bookmark:before { - content: "\e9d2"; -} - -.icon-bookmarks:before { - content: "\e9d3"; -} - -.icon-sun:before { - content: "\e9d4"; -} - -.icon-contrast:before { - content: "\e9d5"; -} - -.icon-brightness-contrast:before { - content: "\e9d6"; -} - -.icon-star-empty:before { - content: "\e9d7"; -} - -.icon-star-half:before { - content: "\e9d8"; -} - -.icon-star-full:before { - content: "\e9d9"; -} - -.icon-heart:before { - content: "\e9da"; -} - -.icon-heart-broken:before { - content: "\e9db"; -} - -.icon-man:before { - content: "\e9dc"; -} - -.icon-woman:before { - content: "\e9dd"; -} - -.icon-man-woman:before { - content: "\e9de"; -} - -.icon-happy:before { - content: "\e9df"; -} - -.icon-happy2:before { - content: "\e9e0"; -} - -.icon-smile:before { - content: "\e9e1"; -} - -.icon-smile2:before { - content: "\e9e2"; -} - -.icon-tongue:before { - content: "\e9e3"; -} - -.icon-tongue2:before { - content: "\e9e4"; -} - -.icon-sad:before { - content: "\e9e5"; -} - -.icon-sad2:before { - content: "\e9e6"; -} - -.icon-wink:before { - content: "\e9e7"; -} - -.icon-wink2:before { - content: "\e9e8"; -} - -.icon-grin:before { - content: "\e9e9"; -} - -.icon-grin2:before { - content: "\e9ea"; -} - -.icon-cool:before { - content: "\e9eb"; -} - -.icon-cool2:before { - content: "\e9ec"; -} - -.icon-angry:before { - content: "\e9ed"; -} - -.icon-angry2:before { - content: "\e9ee"; -} - -.icon-evil:before { - content: "\e9ef"; -} - -.icon-evil2:before { - content: "\e9f0"; -} - -.icon-shocked:before { - content: "\e9f1"; -} - -.icon-shocked2:before { - content: "\e9f2"; -} - -.icon-baffled:before { - content: "\e9f3"; -} - -.icon-baffled2:before { - content: "\e9f4"; -} - -.icon-confused:before { - content: "\e9f5"; -} - -.icon-confused2:before { - content: "\e9f6"; -} - -.icon-neutral:before { - content: "\e9f7"; -} - -.icon-neutral2:before { - content: "\e9f8"; -} - -.icon-hipster:before { - content: "\e9f9"; -} - -.icon-hipster2:before { - content: "\e9fa"; -} - -.icon-wondering:before { - content: "\e9fb"; -} - -.icon-wondering2:before { - content: "\e9fc"; -} - -.icon-sleepy:before { - content: "\e9fd"; -} - -.icon-sleepy2:before { - content: "\e9fe"; -} - -.icon-frustrated:before { - content: "\e9ff"; -} - -.icon-frustrated2:before { - content: "\ea00"; -} - -.icon-crying:before { - content: "\ea01"; -} - -.icon-crying2:before { - content: "\ea02"; -} - -.icon-point-up:before { - content: "\ea03"; -} - -.icon-point-right:before { - content: "\ea04"; -} - -.icon-point-down:before { - content: "\ea05"; -} - -.icon-point-left:before { - content: "\ea06"; -} - -.icon-warning:before { - content: "\ea07"; -} - -.icon-notification:before { - content: "\ea08"; -} - -.icon-question:before { - content: "\ea09"; -} - -.icon-plus:before { - content: "\ea0a"; -} - -.icon-minus:before { - content: "\ea0b"; -} - -.icon-info:before { - content: "\ea0c"; -} - -.icon-cancel-circle:before { - content: "\ea0d"; -} - -.icon-blocked:before { - content: "\ea0e"; -} - -.icon-cross:before { - content: "\ea0f"; -} - -.icon-checkmark:before { - content: "\ea10"; -} - -.icon-checkmark2:before { - content: "\ea11"; -} - -.icon-spell-check:before { - content: "\ea12"; -} - -.icon-enter:before { - content: "\ea13"; -} - -.icon-exit:before { - content: "\ea14"; -} - -.icon-play2:before { - content: "\ea15"; -} - -.icon-pause:before { - content: "\ea16"; -} - -.icon-stop:before { - content: "\ea17"; -} - -.icon-previous:before { - content: "\ea18"; -} - -.icon-next:before { - content: "\ea19"; -} - -.icon-backward:before { - content: "\ea1a"; -} - -.icon-forward2:before { - content: "\ea1b"; -} - -.icon-play3:before { - content: "\ea1c"; -} - -.icon-pause2:before { - content: "\ea1d"; -} - -.icon-stop2:before { - content: "\ea1e"; -} - -.icon-backward2:before { - content: "\ea1f"; -} - -.icon-forward3:before { - content: "\ea20"; -} - -.icon-first:before { - content: "\ea21"; -} - -.icon-last:before { - content: "\ea22"; -} - -.icon-previous2:before { - content: "\ea23"; -} - -.icon-next2:before { - content: "\ea24"; -} - -.icon-eject:before { - content: "\ea25"; -} - -.icon-volume-high:before { - content: "\ea26"; -} - -.icon-volume-medium:before { - content: "\ea27"; -} - -.icon-volume-low:before { - content: "\ea28"; -} - -.icon-volume-mute:before { - content: "\ea29"; -} - -.icon-volume-mute2:before { - content: "\ea2a"; -} - -.icon-volume-increase:before { - content: "\ea2b"; -} - -.icon-volume-decrease:before { - content: "\ea2c"; -} - -.icon-loop:before { - content: "\ea2d"; -} - -.icon-loop2:before { - content: "\ea2e"; -} - -.icon-infinite:before { - content: "\ea2f"; -} - -.icon-shuffle:before { - content: "\ea30"; -} - -.icon-arrow-up-left:before { - content: "\ea31"; -} - -.icon-arrow-up:before { - content: "\ea32"; -} - -.icon-arrow-up-right:before { - content: "\ea33"; -} - -.icon-arrow-right:before { - content: "\ea34"; -} - -.icon-arrow-down-right:before { - content: "\ea35"; -} - -.icon-arrow-down:before { - content: "\ea36"; -} - -.icon-arrow-down-left:before { - content: "\ea37"; -} - -.icon-arrow-left:before { - content: "\ea38"; -} - -.icon-arrow-up-left2:before { - content: "\ea39"; -} - -.icon-arrow-up2:before { - content: "\ea3a"; -} - -.icon-arrow-up-right2:before { - content: "\ea3b"; -} - -.icon-arrow-right2:before { - content: "\ea3c"; -} - -.icon-arrow-down-right2:before { - content: "\ea3d"; -} - -.icon-arrow-down2:before { - content: "\ea3e"; -} - -.icon-arrow-down-left2:before { - content: "\ea3f"; -} - -.icon-arrow-left2:before { - content: "\ea40"; -} - -.icon-circle-up:before { - content: "\ea41"; -} - -.icon-circle-right:before { - content: "\ea42"; -} - -.icon-circle-down:before { - content: "\ea43"; -} - -.icon-circle-left:before { - content: "\ea44"; -} - -.icon-tab:before { - content: "\ea45"; -} - -.icon-move-up:before { - content: "\ea46"; -} - -.icon-move-down:before { - content: "\ea47"; -} - -.icon-sort-alpha-asc:before { - content: "\ea48"; -} - -.icon-sort-alpha-desc:before { - content: "\ea49"; -} - -.icon-sort-numeric-asc:before { - content: "\ea4a"; -} - -.icon-sort-numberic-desc:before { - content: "\ea4b"; -} - -.icon-sort-amount-asc:before { - content: "\ea4c"; -} - -.icon-sort-amount-desc:before { - content: "\ea4d"; -} - -.icon-command:before { - content: "\ea4e"; -} - -.icon-shift:before { - content: "\ea4f"; -} - -.icon-ctrl:before { - content: "\ea50"; -} - -.icon-opt:before { - content: "\ea51"; -} - -.icon-checkbox-checked:before { - content: "\ea52"; -} - -.icon-checkbox-unchecked:before { - content: "\ea53"; -} - -.icon-radio-checked:before { - content: "\ea54"; -} - -.icon-radio-checked2:before { - content: "\ea55"; -} - -.icon-radio-unchecked:before { - content: "\ea56"; -} - -.icon-crop:before { - content: "\ea57"; -} - -.icon-make-group:before { - content: "\ea58"; -} - -.icon-ungroup:before { - content: "\ea59"; -} - -.icon-scissors:before { - content: "\ea5a"; -} - -.icon-filter:before { - content: "\ea5b"; -} - -.icon-font:before { - content: "\ea5c"; -} - -.icon-ligature:before { - content: "\ea5d"; -} - -.icon-ligature2:before { - content: "\ea5e"; -} - -.icon-text-height:before { - content: "\ea5f"; -} - -.icon-text-width:before { - content: "\ea60"; -} - -.icon-font-size:before { - content: "\ea61"; -} - -.icon-bold:before { - content: "\ea62"; -} - -.icon-underline:before { - content: "\ea63"; -} - -.icon-italic:before { - content: "\ea64"; -} - -.icon-strikethrough:before { - content: "\ea65"; -} - -.icon-omega:before { - content: "\ea66"; -} - -.icon-sigma:before { - content: "\ea67"; -} - -.icon-page-break:before { - content: "\ea68"; -} - -.icon-superscript:before { - content: "\ea69"; -} - -.icon-subscript:before { - content: "\ea6a"; -} - -.icon-superscript2:before { - content: "\ea6b"; -} - -.icon-subscript2:before { - content: "\ea6c"; -} - -.icon-text-color:before { - content: "\ea6d"; -} - -.icon-pagebreak:before { - content: "\ea6e"; -} - -.icon-clear-formatting:before { - content: "\ea6f"; -} - -.icon-table:before { - content: "\ea70"; -} - -.icon-table2:before { - content: "\ea71"; -} - -.icon-insert-template:before { - content: "\ea72"; -} - -.icon-pilcrow:before { - content: "\ea73"; -} - -.icon-ltr:before { - content: "\ea74"; -} - -.icon-rtl:before { - content: "\ea75"; -} - -.icon-section:before { - content: "\ea76"; -} - -.icon-paragraph-left:before { - content: "\ea77"; -} - -.icon-paragraph-center:before { - content: "\ea78"; -} - -.icon-paragraph-right:before { - content: "\ea79"; -} - -.icon-paragraph-justify:before { - content: "\ea7a"; -} - -.icon-indent-increase:before { - content: "\ea7b"; -} - -.icon-indent-decrease:before { - content: "\ea7c"; -} - -.icon-share:before { - content: "\ea7d"; -} - -.icon-new-tab:before { - content: "\ea7e"; -} - -.icon-embed:before { - content: "\ea7f"; -} - -.icon-embed2:before { - content: "\ea80"; -} - -.icon-terminal:before { - content: "\ea81"; -} - -.icon-share2:before { - content: "\ea82"; -} - -.icon-mail:before { - content: "\ea83"; -} - -.icon-mail2:before { - content: "\ea84"; -} - -.icon-mail3:before { - content: "\ea85"; -} - -.icon-mail4:before { - content: "\ea86"; -} - -.icon-amazon:before { - content: "\ea87"; -} - -.icon-google:before { - content: "\ea88"; -} - -.icon-google2:before { - content: "\ea89"; -} - -.icon-google3:before { - content: "\ea8a"; -} - -.icon-google-plus:before { - content: "\ea8b"; -} - -.icon-google-plus2:before { - content: "\ea8c"; -} - -.icon-google-plus3:before { - content: "\ea8d"; -} - -.icon-hangouts:before { - content: "\ea8e"; -} - -.icon-google-drive:before { - content: "\ea8f"; -} - -.icon-facebook:before { - content: "\ea90"; -} - -.icon-facebook2:before { - content: "\ea91"; -} - -.icon-instagram:before { - content: "\ea92"; -} - -.icon-whatsapp:before { - content: "\ea93"; -} - -.icon-spotify:before { - content: "\ea94"; -} - -.icon-telegram:before { - content: "\ea95"; -} - -.icon-twitter:before { - content: "\ea96"; -} - -.icon-vine:before { - content: "\ea97"; -} - -.icon-vk:before { - content: "\ea98"; -} - -.icon-renren:before { - content: "\ea99"; -} - -.icon-sina-weibo:before { - content: "\ea9a"; -} - -.icon-rss:before { - content: "\ea9b"; -} - -.icon-rss2:before { - content: "\ea9c"; -} - -.icon-youtube:before { - content: "\ea9d"; -} - -.icon-youtube2:before { - content: "\ea9e"; -} - -.icon-twitch:before { - content: "\ea9f"; -} - -.icon-vimeo:before { - content: "\eaa0"; -} - -.icon-vimeo2:before { - content: "\eaa1"; -} - -.icon-lanyrd:before { - content: "\eaa2"; -} - -.icon-flickr:before { - content: "\eaa3"; -} - -.icon-flickr2:before { - content: "\eaa4"; -} - -.icon-flickr3:before { - content: "\eaa5"; -} - -.icon-flickr4:before { - content: "\eaa6"; -} - -.icon-dribbble:before { - content: "\eaa7"; -} - -.icon-behance:before { - content: "\eaa8"; -} - -.icon-behance2:before { - content: "\eaa9"; -} - -.icon-deviantart:before { - content: "\eaaa"; -} - -.icon-500px:before { - content: "\eaab"; -} - -.icon-steam:before { - content: "\eaac"; -} - -.icon-steam2:before { - content: "\eaad"; -} - -.icon-dropbox:before { - content: "\eaae"; -} - -.icon-onedrive:before { - content: "\eaaf"; -} - -.icon-github:before { - content: "\eab0"; -} - -.icon-npm:before { - content: "\eab1"; -} - -.icon-basecamp:before { - content: "\eab2"; -} - -.icon-trello:before { - content: "\eab3"; -} - -.icon-wordpress:before { - content: "\eab4"; -} - -.icon-joomla:before { - content: "\eab5"; -} - -.icon-ello:before { - content: "\eab6"; -} - -.icon-blogger:before { - content: "\eab7"; -} - -.icon-blogger2:before { - content: "\eab8"; -} - -.icon-tumblr:before { - content: "\eab9"; -} - -.icon-tumblr2:before { - content: "\eaba"; -} - -.icon-yahoo:before { - content: "\eabb"; -} - -.icon-yahoo2:before { - content: "\eabc"; -} - -.icon-tux:before { - content: "\eabd"; -} - -.icon-appleinc:before { - content: "\eabe"; -} - -.icon-finder:before { - content: "\eabf"; -} - -.icon-android:before { - content: "\eac0"; -} - -.icon-windows:before { - content: "\eac1"; -} - -.icon-windows8:before { - content: "\eac2"; -} - -.icon-soundcloud:before { - content: "\eac3"; -} - -.icon-soundcloud2:before { - content: "\eac4"; -} - -.icon-skype:before { - content: "\eac5"; -} - -.icon-reddit:before { - content: "\eac6"; -} - -.icon-hackernews:before { - content: "\eac7"; -} - -.icon-wikipedia:before { - content: "\eac8"; -} - -.icon-linkedin:before { - content: "\eac9"; -} - -.icon-linkedin2:before { - content: "\eaca"; -} - -.icon-lastfm:before { - content: "\eacb"; -} - -.icon-lastfm2:before { - content: "\eacc"; -} - -.icon-delicious:before { - content: "\eacd"; -} - -.icon-stumbleupon:before { - content: "\eace"; -} - -.icon-stumbleupon2:before { - content: "\eacf"; -} - -.icon-stackoverflow:before { - content: "\ead0"; -} - -.icon-pinterest:before { - content: "\ead1"; -} - -.icon-pinterest2:before { - content: "\ead2"; -} - -.icon-xing:before { - content: "\ead3"; -} - -.icon-xing2:before { - content: "\ead4"; -} - -.icon-flattr:before { - content: "\ead5"; -} - -.icon-foursquare:before { - content: "\ead6"; -} - -.icon-yelp:before { - content: "\ead7"; -} - -.icon-paypal:before { - content: "\ead8"; -} - -.icon-chrome:before { - content: "\ead9"; -} - -.icon-firefox:before { - content: "\eada"; -} - -.icon-IE:before { - content: "\eadb"; -} - -.icon-edge:before { - content: "\eadc"; -} - -.icon-safari:before { - content: "\eadd"; -} - -.icon-opera:before { - content: "\eade"; -} - -.icon-file-pdf:before { - content: "\eadf"; -} - -.icon-file-openoffice:before { - content: "\eae0"; -} - -.icon-file-word:before { - content: "\eae1"; -} - -.icon-file-excel:before { - content: "\eae2"; -} - -.icon-libreoffice:before { - content: "\eae3"; -} - -.icon-html-five:before { - content: "\eae4"; -} - -.icon-html-five2:before { - content: "\eae5"; -} - -.icon-css3:before { - content: "\eae6"; -} - -.icon-git:before { - content: "\eae7"; -} - -.icon-codepen:before { - content: "\eae8"; -} - -.icon-svg:before { - content: "\eae9"; -} - -.icon-IcoMoon:before { - content: "\eaea"; -} diff --git a/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/icomoon.min.css b/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/icomoon.min.css deleted file mode 100644 index c9395d71..00000000 --- a/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/icomoon.min.css +++ /dev/null @@ -1 +0,0 @@ -@font-face{font-family:'icomoon';src:url('../fonts/icomoon.eot?shgsy3');src:url('../fonts/icomoon.eot?shgsy3#iefix') format('embedded-opentype'),url('../fonts/icomoon.ttf?shgsy3') format('truetype'),url('../fonts/icomoon.woff?shgsy3') format('woff'),url('../fonts/icomoon.svg?shgsy3#icomoon') format('svg');font-weight:normal;font-style:normal;font-display:block;}[class^="icon-"],[class*=" icon-"]{font-family:'icomoon'!important;speak:never;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;} .icon-home:before{content:"\e900";} .icon-home2:before{content:"\e901";} .icon-home3:before{content:"\e902";} .icon-office:before{content:"\e903";} .icon-newspaper:before{content:"\e904";} .icon-pencil:before{content:"\e905";} .icon-pencil2:before{content:"\e906";} .icon-quill:before{content:"\e907";} .icon-pen:before{content:"\e908";} .icon-blog:before{content:"\e909";} .icon-eyedropper:before{content:"\e90a";} .icon-droplet:before{content:"\e90b";} .icon-paint-format:before{content:"\e90c";} .icon-image:before{content:"\e90d";} .icon-images:before{content:"\e90e";} .icon-camera:before{content:"\e90f";} .icon-headphones:before{content:"\e910";} .icon-music:before{content:"\e911";} .icon-play:before{content:"\e912";} .icon-film:before{content:"\e913";} .icon-video-camera:before{content:"\e914";} .icon-dice:before{content:"\e915";} .icon-pacman:before{content:"\e916";} .icon-spades:before{content:"\e917";} .icon-clubs:before{content:"\e918";} .icon-diamonds:before{content:"\e919";} .icon-bullhorn:before{content:"\e91a";} .icon-connection:before{content:"\e91b";} .icon-podcast:before{content:"\e91c";} .icon-feed:before{content:"\e91d";} .icon-mic:before{content:"\e91e";} .icon-book:before{content:"\e91f";} .icon-books:before{content:"\e920";} .icon-library:before{content:"\e921";} .icon-file-text:before{content:"\e922";} .icon-profile:before{content:"\e923";} .icon-file-empty:before{content:"\e924";} .icon-files-empty:before{content:"\e925";} .icon-file-text2:before{content:"\e926";} .icon-file-picture:before{content:"\e927";} .icon-file-music:before{content:"\e928";} .icon-file-play:before{content:"\e929";} .icon-file-video:before{content:"\e92a";} .icon-file-zip:before{content:"\e92b";} .icon-copy:before{content:"\e92c";} .icon-paste:before{content:"\e92d";} .icon-stack:before{content:"\e92e";} .icon-folder:before{content:"\e92f";} .icon-folder-open:before{content:"\e930";} .icon-folder-plus:before{content:"\e931";} .icon-folder-minus:before{content:"\e932";} .icon-folder-download:before{content:"\e933";} .icon-folder-upload:before{content:"\e934";} .icon-price-tag:before{content:"\e935";} .icon-price-tags:before{content:"\e936";} .icon-barcode:before{content:"\e937";} .icon-qrcode:before{content:"\e938";} .icon-ticket:before{content:"\e939";} .icon-cart:before{content:"\e93a";} .icon-coin-dollar:before{content:"\e93b";} .icon-coin-euro:before{content:"\e93c";} .icon-coin-pound:before{content:"\e93d";} .icon-coin-yen:before{content:"\e93e";} .icon-credit-card:before{content:"\e93f";} .icon-calculator:before{content:"\e940";} .icon-lifebuoy:before{content:"\e941";} .icon-phone:before{content:"\e942";} .icon-phone-hang-up:before{content:"\e943";} .icon-address-book:before{content:"\e944";} .icon-envelop:before{content:"\e945";} .icon-pushpin:before{content:"\e946";} .icon-location:before{content:"\e947";} .icon-location2:before{content:"\e948";} .icon-compass:before{content:"\e949";} .icon-compass2:before{content:"\e94a";} .icon-map:before{content:"\e94b";} .icon-map2:before{content:"\e94c";} .icon-history:before{content:"\e94d";} .icon-clock:before{content:"\e94e";} .icon-clock2:before{content:"\e94f";} .icon-alarm:before{content:"\e950";} .icon-bell:before{content:"\e951";} .icon-stopwatch:before{content:"\e952";} .icon-calendar:before{content:"\e953";} .icon-printer:before{content:"\e954";} .icon-keyboard:before{content:"\e955";} .icon-display:before{content:"\e956";} .icon-laptop:before{content:"\e957";} .icon-mobile:before{content:"\e958";} .icon-mobile2:before{content:"\e959";} .icon-tablet:before{content:"\e95a";} .icon-tv:before{content:"\e95b";} .icon-drawer:before{content:"\e95c";} .icon-drawer2:before{content:"\e95d";} .icon-box-add:before{content:"\e95e";} .icon-box-remove:before{content:"\e95f";} .icon-download:before{content:"\e960";} .icon-upload:before{content:"\e961";} .icon-floppy-disk:before{content:"\e962";} .icon-drive:before{content:"\e963";} .icon-database:before{content:"\e964";} .icon-undo:before{content:"\e965";} .icon-redo:before{content:"\e966";} .icon-undo2:before{content:"\e967";} .icon-redo2:before{content:"\e968";} .icon-forward:before{content:"\e969";} .icon-reply:before{content:"\e96a";} .icon-bubble:before{content:"\e96b";} .icon-bubbles:before{content:"\e96c";} .icon-bubbles2:before{content:"\e96d";} .icon-bubble2:before{content:"\e96e";} .icon-bubbles3:before{content:"\e96f";} .icon-bubbles4:before{content:"\e970";} .icon-user:before{content:"\e971";} .icon-users:before{content:"\e972";} .icon-user-plus:before{content:"\e973";} .icon-user-minus:before{content:"\e974";} .icon-user-check:before{content:"\e975";} .icon-user-tie:before{content:"\e976";} .icon-quotes-left:before{content:"\e977";} .icon-quotes-right:before{content:"\e978";} .icon-hour-glass:before{content:"\e979";} .icon-spinner:before{content:"\e97a";} .icon-spinner2:before{content:"\e97b";} .icon-spinner3:before{content:"\e97c";} .icon-spinner4:before{content:"\e97d";} .icon-spinner5:before{content:"\e97e";} .icon-spinner6:before{content:"\e97f";} .icon-spinner7:before{content:"\e980";} .icon-spinner8:before{content:"\e981";} .icon-spinner9:before{content:"\e982";} .icon-spinner10:before{content:"\e983";} .icon-spinner11:before{content:"\e984";} .icon-binoculars:before{content:"\e985";} .icon-search:before{content:"\e986";} .icon-zoom-in:before{content:"\e987";} .icon-zoom-out:before{content:"\e988";} .icon-enlarge:before{content:"\e989";} .icon-shrink:before{content:"\e98a";} .icon-enlarge2:before{content:"\e98b";} .icon-shrink2:before{content:"\e98c";} .icon-key:before{content:"\e98d";} .icon-key2:before{content:"\e98e";} .icon-lock:before{content:"\e98f";} .icon-unlocked:before{content:"\e990";} .icon-wrench:before{content:"\e991";} .icon-equalizer:before{content:"\e992";} .icon-equalizer2:before{content:"\e993";} .icon-cog:before{content:"\e994";} .icon-cogs:before{content:"\e995";} .icon-hammer:before{content:"\e996";} .icon-magic-wand:before{content:"\e997";} .icon-aid-kit:before{content:"\e998";} .icon-bug:before{content:"\e999";} .icon-pie-chart:before{content:"\e99a";} .icon-stats-dots:before{content:"\e99b";} .icon-stats-bars:before{content:"\e99c";} .icon-stats-bars2:before{content:"\e99d";} .icon-trophy:before{content:"\e99e";} .icon-gift:before{content:"\e99f";} .icon-glass:before{content:"\e9a0";} .icon-glass2:before{content:"\e9a1";} .icon-mug:before{content:"\e9a2";} .icon-spoon-knife:before{content:"\e9a3";} .icon-leaf:before{content:"\e9a4";} .icon-rocket:before{content:"\e9a5";} .icon-meter:before{content:"\e9a6";} .icon-meter2:before{content:"\e9a7";} .icon-hammer2:before{content:"\e9a8";} .icon-fire:before{content:"\e9a9";} .icon-lab:before{content:"\e9aa";} .icon-magnet:before{content:"\e9ab";} .icon-bin:before{content:"\e9ac";} .icon-bin2:before{content:"\e9ad";} .icon-briefcase:before{content:"\e9ae";} .icon-airplane:before{content:"\e9af";} .icon-truck:before{content:"\e9b0";} .icon-road:before{content:"\e9b1";} .icon-accessibility:before{content:"\e9b2";} .icon-target:before{content:"\e9b3";} .icon-shield:before{content:"\e9b4";} .icon-power:before{content:"\e9b5";} .icon-switch:before{content:"\e9b6";} .icon-power-cord:before{content:"\e9b7";} .icon-clipboard:before{content:"\e9b8";} .icon-list-numbered:before{content:"\e9b9";} .icon-list:before{content:"\e9ba";} .icon-list2:before{content:"\e9bb";} .icon-tree:before{content:"\e9bc";} .icon-menu:before{content:"\e9bd";} .icon-menu2:before{content:"\e9be";} .icon-menu3:before{content:"\e9bf";} .icon-menu4:before{content:"\e9c0";} .icon-cloud:before{content:"\e9c1";} .icon-cloud-download:before{content:"\e9c2";} .icon-cloud-upload:before{content:"\e9c3";} .icon-cloud-check:before{content:"\e9c4";} .icon-download2:before{content:"\e9c5";} .icon-upload2:before{content:"\e9c6";} .icon-download3:before{content:"\e9c7";} .icon-upload3:before{content:"\e9c8";} .icon-sphere:before{content:"\e9c9";} .icon-earth:before{content:"\e9ca";} .icon-link:before{content:"\e9cb";} .icon-flag:before{content:"\e9cc";} .icon-attachment:before{content:"\e9cd";} .icon-eye:before{content:"\e9ce";} .icon-eye-plus:before{content:"\e9cf";} .icon-eye-minus:before{content:"\e9d0";} .icon-eye-blocked:before{content:"\e9d1";} .icon-bookmark:before{content:"\e9d2";} .icon-bookmarks:before{content:"\e9d3";} .icon-sun:before{content:"\e9d4";} .icon-contrast:before{content:"\e9d5";} .icon-brightness-contrast:before{content:"\e9d6";} .icon-star-empty:before{content:"\e9d7";} .icon-star-half:before{content:"\e9d8";} .icon-star-full:before{content:"\e9d9";} .icon-heart:before{content:"\e9da";} .icon-heart-broken:before{content:"\e9db";} .icon-man:before{content:"\e9dc";} .icon-woman:before{content:"\e9dd";} .icon-man-woman:before{content:"\e9de";} .icon-happy:before{content:"\e9df";} .icon-happy2:before{content:"\e9e0";} .icon-smile:before{content:"\e9e1";} .icon-smile2:before{content:"\e9e2";} .icon-tongue:before{content:"\e9e3";} .icon-tongue2:before{content:"\e9e4";} .icon-sad:before{content:"\e9e5";} .icon-sad2:before{content:"\e9e6";} .icon-wink:before{content:"\e9e7";} .icon-wink2:before{content:"\e9e8";} .icon-grin:before{content:"\e9e9";} .icon-grin2:before{content:"\e9ea";} .icon-cool:before{content:"\e9eb";} .icon-cool2:before{content:"\e9ec";} .icon-angry:before{content:"\e9ed";} .icon-angry2:before{content:"\e9ee";} .icon-evil:before{content:"\e9ef";} .icon-evil2:before{content:"\e9f0";} .icon-shocked:before{content:"\e9f1";} .icon-shocked2:before{content:"\e9f2";} .icon-baffled:before{content:"\e9f3";} .icon-baffled2:before{content:"\e9f4";} .icon-confused:before{content:"\e9f5";} .icon-confused2:before{content:"\e9f6";} .icon-neutral:before{content:"\e9f7";} .icon-neutral2:before{content:"\e9f8";} .icon-hipster:before{content:"\e9f9";} .icon-hipster2:before{content:"\e9fa";} .icon-wondering:before{content:"\e9fb";} .icon-wondering2:before{content:"\e9fc";} .icon-sleepy:before{content:"\e9fd";} .icon-sleepy2:before{content:"\e9fe";} .icon-frustrated:before{content:"\e9ff";} .icon-frustrated2:before{content:"\ea00";} .icon-crying:before{content:"\ea01";} .icon-crying2:before{content:"\ea02";} .icon-point-up:before{content:"\ea03";} .icon-point-right:before{content:"\ea04";} .icon-point-down:before{content:"\ea05";} .icon-point-left:before{content:"\ea06";} .icon-warning:before{content:"\ea07";} .icon-notification:before{content:"\ea08";} .icon-question:before{content:"\ea09";} .icon-plus:before{content:"\ea0a";} .icon-minus:before{content:"\ea0b";} .icon-info:before{content:"\ea0c";} .icon-cancel-circle:before{content:"\ea0d";} .icon-blocked:before{content:"\ea0e";} .icon-cross:before{content:"\ea0f";} .icon-checkmark:before{content:"\ea10";} .icon-checkmark2:before{content:"\ea11";} .icon-spell-check:before{content:"\ea12";} .icon-enter:before{content:"\ea13";} .icon-exit:before{content:"\ea14";} .icon-play2:before{content:"\ea15";} .icon-pause:before{content:"\ea16";} .icon-stop:before{content:"\ea17";} .icon-previous:before{content:"\ea18";} .icon-next:before{content:"\ea19";} .icon-backward:before{content:"\ea1a";} .icon-forward2:before{content:"\ea1b";} .icon-play3:before{content:"\ea1c";} .icon-pause2:before{content:"\ea1d";} .icon-stop2:before{content:"\ea1e";} .icon-backward2:before{content:"\ea1f";} .icon-forward3:before{content:"\ea20";} .icon-first:before{content:"\ea21";} .icon-last:before{content:"\ea22";} .icon-previous2:before{content:"\ea23";} .icon-next2:before{content:"\ea24";} .icon-eject:before{content:"\ea25";} .icon-volume-high:before{content:"\ea26";} .icon-volume-medium:before{content:"\ea27";} .icon-volume-low:before{content:"\ea28";} .icon-volume-mute:before{content:"\ea29";} .icon-volume-mute2:before{content:"\ea2a";} .icon-volume-increase:before{content:"\ea2b";} .icon-volume-decrease:before{content:"\ea2c";} .icon-loop:before{content:"\ea2d";} .icon-loop2:before{content:"\ea2e";} .icon-infinite:before{content:"\ea2f";} .icon-shuffle:before{content:"\ea30";} .icon-arrow-up-left:before{content:"\ea31";} .icon-arrow-up:before{content:"\ea32";} .icon-arrow-up-right:before{content:"\ea33";} .icon-arrow-right:before{content:"\ea34";} .icon-arrow-down-right:before{content:"\ea35";} .icon-arrow-down:before{content:"\ea36";} .icon-arrow-down-left:before{content:"\ea37";} .icon-arrow-left:before{content:"\ea38";} .icon-arrow-up-left2:before{content:"\ea39";} .icon-arrow-up2:before{content:"\ea3a";} .icon-arrow-up-right2:before{content:"\ea3b";} .icon-arrow-right2:before{content:"\ea3c";} .icon-arrow-down-right2:before{content:"\ea3d";} .icon-arrow-down2:before{content:"\ea3e";} .icon-arrow-down-left2:before{content:"\ea3f";} .icon-arrow-left2:before{content:"\ea40";} .icon-circle-up:before{content:"\ea41";} .icon-circle-right:before{content:"\ea42";} .icon-circle-down:before{content:"\ea43";} .icon-circle-left:before{content:"\ea44";} .icon-tab:before{content:"\ea45";} .icon-move-up:before{content:"\ea46";} .icon-move-down:before{content:"\ea47";} .icon-sort-alpha-asc:before{content:"\ea48";} .icon-sort-alpha-desc:before{content:"\ea49";} .icon-sort-numeric-asc:before{content:"\ea4a";} .icon-sort-numberic-desc:before{content:"\ea4b";} .icon-sort-amount-asc:before{content:"\ea4c";} .icon-sort-amount-desc:before{content:"\ea4d";} .icon-command:before{content:"\ea4e";} .icon-shift:before{content:"\ea4f";} .icon-ctrl:before{content:"\ea50";} .icon-opt:before{content:"\ea51";} .icon-checkbox-checked:before{content:"\ea52";} .icon-checkbox-unchecked:before{content:"\ea53";} .icon-radio-checked:before{content:"\ea54";} .icon-radio-checked2:before{content:"\ea55";} .icon-radio-unchecked:before{content:"\ea56";} .icon-crop:before{content:"\ea57";} .icon-make-group:before{content:"\ea58";} .icon-ungroup:before{content:"\ea59";} .icon-scissors:before{content:"\ea5a";} .icon-filter:before{content:"\ea5b";} .icon-font:before{content:"\ea5c";} .icon-ligature:before{content:"\ea5d";} .icon-ligature2:before{content:"\ea5e";} .icon-text-height:before{content:"\ea5f";} .icon-text-width:before{content:"\ea60";} .icon-font-size:before{content:"\ea61";} .icon-bold:before{content:"\ea62";} .icon-underline:before{content:"\ea63";} .icon-italic:before{content:"\ea64";} .icon-strikethrough:before{content:"\ea65";} .icon-omega:before{content:"\ea66";} .icon-sigma:before{content:"\ea67";} .icon-page-break:before{content:"\ea68";} .icon-superscript:before{content:"\ea69";} .icon-subscript:before{content:"\ea6a";} .icon-superscript2:before{content:"\ea6b";} .icon-subscript2:before{content:"\ea6c";} .icon-text-color:before{content:"\ea6d";} .icon-pagebreak:before{content:"\ea6e";} .icon-clear-formatting:before{content:"\ea6f";} .icon-table:before{content:"\ea70";} .icon-table2:before{content:"\ea71";} .icon-insert-template:before{content:"\ea72";} .icon-pilcrow:before{content:"\ea73";} .icon-ltr:before{content:"\ea74";} .icon-rtl:before{content:"\ea75";} .icon-section:before{content:"\ea76";} .icon-paragraph-left:before{content:"\ea77";} .icon-paragraph-center:before{content:"\ea78";} .icon-paragraph-right:before{content:"\ea79";} .icon-paragraph-justify:before{content:"\ea7a";} .icon-indent-increase:before{content:"\ea7b";} .icon-indent-decrease:before{content:"\ea7c";} .icon-share:before{content:"\ea7d";} .icon-new-tab:before{content:"\ea7e";} .icon-embed:before{content:"\ea7f";} .icon-embed2:before{content:"\ea80";} .icon-terminal:before{content:"\ea81";} .icon-share2:before{content:"\ea82";} .icon-mail:before{content:"\ea83";} .icon-mail2:before{content:"\ea84";} .icon-mail3:before{content:"\ea85";} .icon-mail4:before{content:"\ea86";} .icon-amazon:before{content:"\ea87";} .icon-google:before{content:"\ea88";} .icon-google2:before{content:"\ea89";} .icon-google3:before{content:"\ea8a";} .icon-google-plus:before{content:"\ea8b";} .icon-google-plus2:before{content:"\ea8c";} .icon-google-plus3:before{content:"\ea8d";} .icon-hangouts:before{content:"\ea8e";} .icon-google-drive:before{content:"\ea8f";} .icon-facebook:before{content:"\ea90";} .icon-facebook2:before{content:"\ea91";} .icon-instagram:before{content:"\ea92";} .icon-whatsapp:before{content:"\ea93";} .icon-spotify:before{content:"\ea94";} .icon-telegram:before{content:"\ea95";} .icon-twitter:before{content:"\ea96";} .icon-vine:before{content:"\ea97";} .icon-vk:before{content:"\ea98";} .icon-renren:before{content:"\ea99";} .icon-sina-weibo:before{content:"\ea9a";} .icon-rss:before{content:"\ea9b";} .icon-rss2:before{content:"\ea9c";} .icon-youtube:before{content:"\ea9d";} .icon-youtube2:before{content:"\ea9e";} .icon-twitch:before{content:"\ea9f";} .icon-vimeo:before{content:"\eaa0";} .icon-vimeo2:before{content:"\eaa1";} .icon-lanyrd:before{content:"\eaa2";} .icon-flickr:before{content:"\eaa3";} .icon-flickr2:before{content:"\eaa4";} .icon-flickr3:before{content:"\eaa5";} .icon-flickr4:before{content:"\eaa6";} .icon-dribbble:before{content:"\eaa7";} .icon-behance:before{content:"\eaa8";} .icon-behance2:before{content:"\eaa9";} .icon-deviantart:before{content:"\eaaa";} .icon-500px:before{content:"\eaab";} .icon-steam:before{content:"\eaac";} .icon-steam2:before{content:"\eaad";} .icon-dropbox:before{content:"\eaae";} .icon-onedrive:before{content:"\eaaf";} .icon-github:before{content:"\eab0";} .icon-npm:before{content:"\eab1";} .icon-basecamp:before{content:"\eab2";} .icon-trello:before{content:"\eab3";} .icon-wordpress:before{content:"\eab4";} .icon-joomla:before{content:"\eab5";} .icon-ello:before{content:"\eab6";} .icon-blogger:before{content:"\eab7";} .icon-blogger2:before{content:"\eab8";} .icon-tumblr:before{content:"\eab9";} .icon-tumblr2:before{content:"\eaba";} .icon-yahoo:before{content:"\eabb";} .icon-yahoo2:before{content:"\eabc";} .icon-tux:before{content:"\eabd";} .icon-appleinc:before{content:"\eabe";} .icon-finder:before{content:"\eabf";} .icon-android:before{content:"\eac0";} .icon-windows:before{content:"\eac1";} .icon-windows8:before{content:"\eac2";} .icon-soundcloud:before{content:"\eac3";} .icon-soundcloud2:before{content:"\eac4";} .icon-skype:before{content:"\eac5";} .icon-reddit:before{content:"\eac6";} .icon-hackernews:before{content:"\eac7";} .icon-wikipedia:before{content:"\eac8";} .icon-linkedin:before{content:"\eac9";} .icon-linkedin2:before{content:"\eaca";} .icon-lastfm:before{content:"\eacb";} .icon-lastfm2:before{content:"\eacc";} .icon-delicious:before{content:"\eacd";} .icon-stumbleupon:before{content:"\eace";} .icon-stumbleupon2:before{content:"\eacf";} .icon-stackoverflow:before{content:"\ead0";} .icon-pinterest:before{content:"\ead1";} .icon-pinterest2:before{content:"\ead2";} .icon-xing:before{content:"\ead3";} .icon-xing2:before{content:"\ead4";} .icon-flattr:before{content:"\ead5";} .icon-foursquare:before{content:"\ead6";} .icon-yelp:before{content:"\ead7";} .icon-paypal:before{content:"\ead8";} .icon-chrome:before{content:"\ead9";} .icon-firefox:before{content:"\eada";} .icon-IE:before{content:"\eadb";} .icon-edge:before{content:"\eadc";} .icon-safari:before{content:"\eadd";} .icon-opera:before{content:"\eade";} .icon-file-pdf:before{content:"\eadf";} .icon-file-openoffice:before{content:"\eae0";} .icon-file-word:before{content:"\eae1";} .icon-file-excel:before{content:"\eae2";} .icon-libreoffice:before{content:"\eae3";} .icon-html-five:before{content:"\eae4";} .icon-html-five2:before{content:"\eae5";} .icon-css3:before{content:"\eae6";} .icon-git:before{content:"\eae7";} .icon-codepen:before{content:"\eae8";} .icon-svg:before{content:"\eae9";} .icon-IcoMoon:before{content:"\eaea";} diff --git a/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/universal-icon-picker.css b/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/universal-icon-picker.css deleted file mode 100644 index d8411a85..00000000 --- a/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/universal-icon-picker.css +++ /dev/null @@ -1,292 +0,0 @@ -.uip-modal { - position: fixed; - height: 100%; - width: 100%; - bottom: 0; - left: 0; - background-color: rgba(0, 0, 0, 0.6); - z-index: 9999; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - /* Footer */ -} -.uip-modal *, -.uip-modal :before, -.uip-modal :after { - -webkit-box-sizing: border-box; - box-sizing: border-box; -} -.uip-modal.uip-close { - opacity: 0; - visibility: hidden; - -webkit-transition: all 0.4s ease-in-out; - transition: all 0.4s ease-in-out; -} -.uip-modal.uip-open { - opacity: 1; - visibility: visible; - -webkit-transition: all 0.4s ease-in-out; - transition: all 0.4s ease-in-out; -} -.uip-modal .uip-modal--content { - position: absolute; - border-radius: 3px; - -webkit-box-shadow: 2px 8px 23px 3px rgba(0, 0, 0, 0.2); - box-shadow: 2px 8px 23px 3px rgba(0, 0, 0, 0.2); - overflow: hidden; - font-family: Roboto, Arial, Helvetica, Verdana, sans-serif; - background-color: #f1f3f5; - width: 100%; - margin: auto; - left: 0; - right: 0; - /* Header */ - /* body */ -} -.uip-modal .uip-modal--content .uip-modal--header { - padding: 15px 15px; - background-color: #fff; - -webkit-box-shadow: 0 0 8px rgba(0, 0, 0, 0.1); - box-shadow: 0 0 8px rgba(0, 0, 0, 0.1); - position: relative; - z-index: 1; - font-size: 15px; - color: #495157; - font-weight: 500; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: justify; - -ms-flex-pack: justify; - justify-content: space-between; -} -.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-logo-title { - padding-top: 2px; - line-height: 1; - text-transform: uppercase; - font-weight: bold; - cursor: pointer; -} -.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-close-btn { - cursor: pointer; -} -.uip-modal .uip-modal--content .uip-modal--body { - font-size: 12px; - line-height: 1.5; - -webkit-box-sizing: border-box; - box-sizing: border-box; - padding: 0; - height: 700px; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - min-height: 50px; - max-height: 85vh; - overflow: auto; - /* Sidebar Tabs */ - /* Preview wrapper */ -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar { - -ms-flex-negative: 0; - flex-shrink: 0; - width: 25%; - background-color: rgba(255, 255, 255, 0.3); -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs { - margin-top: 30px; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item { - padding: 15px; - font-size: 14px; - color: #6d7882; - text-align: left; - cursor: pointer; - position: relative; - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - text-transform: capitalize; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item i { - font-size: 20px; - padding-right: 15px; - color: #a4afb7; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item img { - padding-right: 15px; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active { - background-color: #fff; - -webkit-box-shadow: 0 6px 20px 0 rgba(0, 0, 0, 0.1); - box-shadow: 0 6px 20px 0 rgba(0, 0, 0, 0.1); -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active:after { - content: ""; - position: absolute; - height: 100%; - width: 5px; - top: 0; - left: 0; - background-color: #1cc2ff; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active i { - color: #1cc2ff; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap { - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -ms-flex-direction: column; - flex-direction: column; - padding: 30px 80px 0; - width: 75%; - /* search filter */ -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner { - overflow: auto; - margin: 25px -15px 0; - padding: 0 15px 15px; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview { - display: -ms-grid; - display: grid; - -ms-grid-columns: 1fr 20px 1fr 20px 1fr 20px 1fr 20px 1fr 20px 1fr 20px 1fr; - grid-template-columns: repeat(7, 1fr); - grid-gap: 20px; - margin: 20px 0; - /* Icon Item */ -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item { - position: relative; - padding: 10px; - background-color: #fff; - -webkit-box-shadow: 0 1px 12px rgba(0, 0, 0, 0.05); - box-shadow: 0 1px 12px rgba(0, 0, 0, 0.05); - border-radius: 3px; - cursor: pointer; - -webkit-transition: all 0.3s; - transition: all 0.3s; - overflow: hidden; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item:hover { - -webkit-box-shadow: 0 1px 14px rgba(0, 0, 0, 0.16); - box-shadow: 0 1px 14px rgba(0, 0, 0, 0.16); -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item.universal-selected { - -webkit-box-shadow: 0 1px 12px rgba(0, 0, 0, 0.05), 0 0 0 3px #1cc2ff; - box-shadow: 0 1px 12px rgba(0, 0, 0, 0.05), 0 0 0 3px #1cc2ff; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner { - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -ms-flex-direction: column; - flex-direction: column; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 1px; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner i, -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item__icon { - font-size: 25px; - color: #6d7882; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item-name { - color: #c2cbd2; - font-size: 11px; - padding: 13px 0 0; - max-width: 100%; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - text-transform: capitalize; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search { - position: relative; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input { - width: calc(100% - 15px); - padding: 8px 15px; - background-color: #fff; - border: none; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input::-webkit-input-placeholder { - font-style: italic; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input::-moz-placeholder { - font-style: italic; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input:-ms-input-placeholder { - font-style: italic; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input::-ms-input-placeholder { - font-style: italic; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input::placeholder { - font-style: italic; -} -.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search img { - position: absolute; - top: 50%; - -webkit-transform: translateY(-50%); - transform: translateY(-50%); - right: 25px; -} -.uip-modal .uip-modal--footer { - border-top: 1px solid #e6e9ec; - text-align: center; - background-color: #fff; - border: none; - display: none; - -webkit-box-pack: end; - -ms-flex-pack: end; - justify-content: flex-end; - padding: 5px; - -webkit-box-shadow: 0 0 8px rgba(0, 0, 0, 0.1); - box-shadow: 0 0 8px rgba(0, 0, 0, 0.1); - position: relative; - display: -webkit-box; - display: -ms-flexbox; - display: flex; -} -.uip-modal .uip-modal--footer button.uip-insert-icon-button { - padding: 10px 35px; - color: #fff; - font-size: 15px; - background-color: #42d6a0; - border: none; - cursor: pointer; - outline: 0; -} -.uip-modal .uip-modal--footer .universal-button { - height: 40px; - margin-left: 5px; -} -.uip-modal .uip-modal--footer .universal-button-success { - padding: 12px 36px; - color: #fff; - width: initial; - font-size: 15px; -} -.uip-modal .uip-modal--footer .universal-button-success:hover { - background-color: #42d6a0; -} diff --git a/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/universal-icon-picker.min.css b/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/universal-icon-picker.min.css deleted file mode 100644 index ae510e49..00000000 --- a/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/universal-icon-picker.min.css +++ /dev/null @@ -1 +0,0 @@ -.uip-modal{position:fixed;height:100%;width:100%;bottom:0;left:0;background-color:rgba(0,0,0,0.6);z-index:9999;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.uip-modal *,.uip-modal :after,.uip-modal :before{-webkit-box-sizing:border-box;box-sizing:border-box}.uip-modal.uip-close{opacity:0;visibility:hidden;-webkit-transition:all 0.4s ease-in-out;transition:all 0.4s ease-in-out}.uip-modal.uip-open{opacity:1;visibility:visible;-webkit-transition:all 0.4s ease-in-out;transition:all 0.4s ease-in-out}.uip-modal .uip-modal--content{position:absolute;border-radius:3px;-webkit-box-shadow:2px 8px 23px 3px rgba(0,0,0,0.2);box-shadow:2px 8px 23px 3px rgba(0,0,0,0.2);overflow:hidden;font-family:Roboto,Arial,Helvetica,Verdana,sans-serif;background-color:#f1f3f5;width:100%;margin:auto;left:0;right:0}.uip-modal .uip-modal--content .uip-modal--header{padding:15px 15px;background-color:#fff;-webkit-box-shadow:0 0 8px rgba(0,0,0,0.1);box-shadow:0 0 8px rgba(0,0,0,0.1);position:relative;z-index:1;font-size:15px;color:#495157;font-weight:500;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-logo-title{padding-top:2px;line-height:1;text-transform:uppercase;font-weight:bold;cursor:pointer}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-close-btn{cursor:pointer}.uip-modal .uip-modal--content .uip-modal--body{font-size:12px;line-height:1.5;-webkit-box-sizing:border-box;box-sizing:border-box;padding:0;height:700px;display:-webkit-box;display:-ms-flexbox;display:flex;min-height:50px;max-height:85vh;overflow:auto}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar{-ms-flex-negative:0;flex-shrink:0;width:25%;background-color:rgba(255,255,255,0.3)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs{margin-top:30px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item{padding:15px;font-size:14px;color:#6d7882;text-align:left;cursor:pointer;position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item i{font-size:20px;padding-right:15px;color:#a4afb7}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item img{padding-right:15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active{background-color:#fff;-webkit-box-shadow:0 6px 20px 0 rgba(0,0,0,0.1);box-shadow:0 6px 20px 0 rgba(0,0,0,0.1)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active:after{content:"";position:absolute;height:100%;width:5px;top:0;left:0;background-color:#1cc2ff}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active i{color:#1cc2ff}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding:30px 80px 0;width:75%}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner{overflow:auto;margin:25px -15px 0;padding:0 15px 15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview{display:-ms-grid;display:grid;-ms-grid-columns:1fr 20px 1fr 20px 1fr 20px 1fr 20px 1fr 20px 1fr 20px 1fr;grid-template-columns:repeat(7,1fr);grid-gap:20px;margin:20px 0}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item{position:relative;padding:10px;background-color:#fff;-webkit-box-shadow:0 1px 12px rgba(0,0,0,0.05);box-shadow:0 1px 12px rgba(0,0,0,0.05);border-radius:3px;cursor:pointer;-webkit-transition:all 0.3s;transition:all 0.3s;overflow:hidden}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item:hover{-webkit-box-shadow:0 1px 14px rgba(0,0,0,0.16);box-shadow:0 1px 14px rgba(0,0,0,0.16)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item.universal-selected{-webkit-box-shadow:0 1px 12px rgba(0,0,0,0.05),0 0 0 3px #1cc2ff;box-shadow:0 1px 12px rgba(0,0,0,0.05),0 0 0 3px #1cc2ff}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:1px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item__icon,.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner i{font-size:25px;color:#6d7882}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item-name{color:#c2cbd2;font-size:11px;padding:13px 0 0;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search{position:relative}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input{width:calc(100% - 15px);padding:8px 15px;background-color:#fff;border:none}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input::-webkit-input-placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input::-moz-placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input:-ms-input-placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input::-ms-input-placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input::placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search img{position:absolute;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);right:25px}.uip-modal .uip-modal--footer{border-top:1px solid #e6e9ec;text-align:center;background-color:#fff;border:none;display:none;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;padding:5px;-webkit-box-shadow:0 0 8px rgba(0,0,0,0.1);box-shadow:0 0 8px rgba(0,0,0,0.1);position:relative;display:-webkit-box;display:-ms-flexbox;display:flex}.uip-modal .uip-modal--footer button.uip-insert-icon-button{padding:10px 35px;color:#fff;font-size:15px;background-color:#42d6a0;border:none;cursor:pointer;outline:0}.uip-modal .uip-modal--footer .universal-button{height:40px;margin-left:5px}.uip-modal .uip-modal--footer .universal-button-success{padding:12px 36px;color:#fff;width:initial;font-size:15px}.uip-modal .uip-modal--footer .universal-button-success:hover{background-color:#42d6a0}@media (max-width:1439px){.uip-modal .uip-modal--content{max-width:990px}}@media (min-width:1440px){.uip-modal .uip-modal--content{max-width:1200px}}@media (max-width:1439px){.uip-modal--icon-preview-wrap{padding:30px 50px 0}}@media (max-width:479px){.uip-modal--icon-preview-wrap{width:100%}}@media (max-width:1439px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[6];grid-template-columns:repeat(6,1fr)}}@media (max-width:1024px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[5];grid-template-columns:repeat(5,1fr)}}@media (max-width:767px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[4];grid-template-columns:repeat(4,1fr)}}@media (max-width:479px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[3];grid-template-columns:repeat(3,1fr)}}@media (max-width:479px){.uip-modal--sidebar{display:none}}@media (max-width:1439px){.uip-modal--sidebar-tab-item{padding:15px 15px 15px 25px;font-size:11px}.uip-modal--sidebar-tab-item i{font-size:15px}}@media (max-width:1024px){.uip-modal--sidebar-tab-item i,.uip-modal--sidebar-tab-item img{display:none}} \ No newline at end of file diff --git a/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/zondicons.css b/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/zondicons.css deleted file mode 100644 index 112907ed..00000000 --- a/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/zondicons.css +++ /dev/null @@ -1,1213 +0,0 @@ -@font-face { - font-family: 'zondicon'; - src: url('../fonts/zondicon.eot?sm22ej'); - src: url('../fonts/zondicon.eot?sm22ej#iefix') format('embedded-opentype'), - url('../fonts/zondicon.ttf?sm22ej') format('truetype'), - url('../fonts/zondicon.woff?sm22ej') format('woff'), - url('../fonts/zondicon.svg?sm22ej#zondicon') format('svg'); - font-weight: normal; - font-style: normal; -} - -.zi { - /* use !important to prevent issues with browser extensions that change fonts */ - font-family: 'zondicon' !important; - speak: none; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - - /* Better Font Rendering =========== */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.zi-zoom-out:before { - content: "\e900"; -} - -.zi-zoom-in:before { - content: "\e901"; -} - -.zi-yin-yang:before { - content: "\e902"; -} - -.zi-wrench:before { - content: "\e903"; -} - -.zi-window:before { - content: "\e904"; -} - -.zi-window-open:before { - content: "\e905"; -} - -.zi-window-new:before { - content: "\e906"; -} - -.zi-watch:before { - content: "\e907"; -} - -.zi-wallet:before { - content: "\e908"; -} - -.zi-volume-up:before { - content: "\e909"; -} - -.zi-volume-off:before { - content: "\e90a"; -} - -.zi-volume-mute:before { - content: "\e90b"; -} - -.zi-volume-down:before { - content: "\e90c"; -} - -.zi-view-tile:before { - content: "\e90d"; -} - -.zi-view-show:before { - content: "\e90e"; -} - -.zi-view-list:before { - content: "\e90f"; -} - -.zi-view-hide:before { - content: "\e910"; -} - -.zi-view-column:before { - content: "\e911"; -} - -.zi-view-carousel:before { - content: "\e912"; -} - -.zi-video-camera:before { - content: "\e913"; -} - -.zi-vector:before { - content: "\e914"; -} - -.zi-user:before { - content: "\e915"; -} - -.zi-user-solid-square:before { - content: "\e916"; -} - -.zi-user-solid-circle:before { - content: "\e917"; -} - -.zi-user-group:before { - content: "\e918"; -} - -.zi-user-add:before { - content: "\e919"; -} - -.zi-usb:before { - content: "\e91a"; -} - -.zi-upload:before { - content: "\e91b"; -} - -.zi-tuning:before { - content: "\e91c"; -} - -.zi-trophy:before { - content: "\e91d"; -} - -.zi-travel:before { - content: "\e91e"; -} - -.zi-travel-walk:before { - content: "\e91f"; -} - -.zi-travel-train:before { - content: "\e920"; -} - -.zi-travel-taxi-cab:before { - content: "\e921"; -} - -.zi-travel-case:before { - content: "\e922"; -} - -.zi-travel-car:before { - content: "\e923"; -} - -.zi-travel-bus:before { - content: "\e924"; -} - -.zi-trash:before { - content: "\e925"; -} - -.zi-translate:before { - content: "\e926"; -} - -.zi-tools-copy:before { - content: "\e927"; -} - -.zi-timer:before { - content: "\e928"; -} - -.zi-time:before { - content: "\e929"; -} - -.zi-ticket:before { - content: "\e92a"; -} - -.zi-thumbs-up:before { - content: "\e92b"; -} - -.zi-thumbs-down:before { - content: "\e92c"; -} - -.zi-thermometer:before { - content: "\e92d"; -} - -.zi-text-decoration:before { - content: "\e92e"; -} - -.zi-text-box:before { - content: "\e92f"; -} - -.zi-target:before { - content: "\e930"; -} - -.zi-tag:before { - content: "\e931"; -} - -.zi-tablet:before { - content: "\e932"; -} - -.zi-swap:before { - content: "\e933"; -} - -.zi-subdirectory-right:before { - content: "\e934"; -} - -.zi-subdirectory-left:before { - content: "\e935"; -} - -.zi-stroke-width:before { - content: "\e936"; -} - -.zi-store-front:before { - content: "\e937"; -} - -.zi-stethoscope:before { - content: "\e938"; -} - -.zi-step-forward:before { - content: "\e939"; -} - -.zi-step-backward:before { - content: "\e93a"; -} - -.zi-station:before { - content: "\e93b"; -} - -.zi-star-full:before { - content: "\e93c"; -} - -.zi-stand-by:before { - content: "\e93d"; -} - -.zi-shuffle:before { - content: "\e93e"; -} - -.zi-show-sidebar:before { - content: "\e93f"; -} - -.zi-shopping-cart:before { - content: "\e940"; -} - -.zi-shield:before { - content: "\e941"; -} - -.zi-share:before { - content: "\e942"; -} - -.zi-share-alt:before { - content: "\e943"; -} - -.zi-share-01:before { - content: "\e944"; -} - -.zi-servers:before { - content: "\e945"; -} - -.zi-send:before { - content: "\e946"; -} - -.zi-search:before { - content: "\e947"; -} - -.zi-screen-full:before { - content: "\e948"; -} - -.zi-save-disk:before { - content: "\e949"; -} - -.zi-repost:before { - content: "\e94a"; -} - -.zi-reply:before { - content: "\e94b"; -} - -.zi-reply-all:before { - content: "\e94c"; -} - -.zi-reload:before { - content: "\e94d"; -} - -.zi-refresh:before { - content: "\e94e"; -} - -.zi-radio:before { - content: "\e94f"; -} - -.zi-radar:before { - content: "\e950"; -} - -.zi-radar-copy-2:before { - content: "\e951"; -} - -.zi-queue:before { - content: "\e952"; -} - -.zi-question:before { - content: "\e953"; -} - -.zi-pylon:before { - content: "\e954"; -} - -.zi-printer:before { - content: "\e955"; -} - -.zi-portfolio:before { - content: "\e956"; -} - -.zi-plugin:before { - content: "\e957"; -} - -.zi-playlist:before { - content: "\e958"; -} - -.zi-play:before { - content: "\e959"; -} - -.zi-play-outline:before { - content: "\e95a"; -} - -.zi-pin:before { - content: "\e95b"; -} - -.zi-php-elephant:before { - content: "\e95c"; -} - -.zi-photo:before { - content: "\e95d"; -} - -.zi-phone:before { - content: "\e95e"; -} - -.zi-pen-tool:before { - content: "\e95f"; -} - -.zi-pause:before { - content: "\e960"; -} - -.zi-pause-solid:before { - content: "\e961"; -} - -.zi-pause-outline:before { - content: "\e962"; -} - -.zi-paste:before { - content: "\e963"; -} - -.zi-notifications:before { - content: "\e964"; -} - -.zi-notifications-outline:before { - content: "\e965"; -} - -.zi-notification:before { - content: "\e966"; -} - -.zi-news-paper:before { - content: "\e967"; -} - -.zi-network:before { - content: "\e968"; -} - -.zi-navigation-more:before { - content: "\e969"; -} - -.zi-music-playlist:before { - content: "\e96a"; -} - -.zi-music-notes:before { - content: "\e96b"; -} - -.zi-music-artist:before { - content: "\e96c"; -} - -.zi-music-album:before { - content: "\e96d"; -} - -.zi-mouse:before { - content: "\e96e"; -} - -.zi-mood-sad-solid:before { - content: "\e96f"; -} - -.zi-mood-sad-outline:before { - content: "\e970"; -} - -.zi-mood-neutral-solid:before { - content: "\e971"; -} - -.zi-mood-neutral-outline:before { - content: "\e972"; -} - -.zi-mood-happy-solid:before { - content: "\e973"; -} - -.zi-mood-happy-outline:before { - content: "\e974"; -} - -.zi-mobile-devices:before { - content: "\e975"; -} - -.zi-minus-solid:before { - content: "\e976"; -} - -.zi-minus-outline:before { - content: "\e977"; -} - -.zi-mic:before { - content: "\e978"; -} - -.zi-menu:before { - content: "\e979"; -} - -.zi-map:before { - content: "\e97a"; -} - -.zi-lock-open:before { - content: "\e97b"; -} - -.zi-lock-closed:before { - content: "\e97c"; -} - -.zi-location:before { - content: "\e97d"; -} - -.zi-location-shopping:before { - content: "\e97e"; -} - -.zi-location-restroom:before { - content: "\e97f"; -} - -.zi-location-park:before { - content: "\e980"; -} - -.zi-location-marina:before { - content: "\e981"; -} - -.zi-location-hotel:before { - content: "\e982"; -} - -.zi-location-gas-station:before { - content: "\e983"; -} - -.zi-location-food:before { - content: "\e984"; -} - -.zi-location-current:before { - content: "\e985"; -} - -.zi-load-balancer:before { - content: "\e986"; -} - -.zi-list:before { - content: "\e987"; -} - -.zi-list-bullet:before { - content: "\e988"; -} - -.zi-list-add:before { - content: "\e989"; -} - -.zi-link:before { - content: "\e98a"; -} - -.zi-light-bulb:before { - content: "\e98b"; -} - -.zi-library:before { - content: "\e98c"; -} - -.zi-layers:before { - content: "\e98d"; -} - -.zi-keyboard:before { - content: "\e98e"; -} - -.zi-key:before { - content: "\e98f"; -} - -.zi-information-solid:before { - content: "\e990"; -} - -.zi-information-outline:before { - content: "\e991"; -} - -.zi-indent-increase:before { - content: "\e992"; -} - -.zi-indent-decrease:before { - content: "\e993"; -} - -.zi-inbox:before { - content: "\e994"; -} - -.zi-inbox-full:before { - content: "\e995"; -} - -.zi-inbox-download:before { - content: "\e996"; -} - -.zi-inbox-check:before { - content: "\e997"; -} - -.zi-hour-glass:before { - content: "\e998"; -} - -.zi-hot:before { - content: "\e999"; -} - -.zi-home:before { - content: "\e99a"; -} - -.zi-heart:before { - content: "\e99b"; -} - -.zi-headphones:before { - content: "\e99c"; -} - -.zi-hard-drive:before { - content: "\e99d"; -} - -.zi-hand-stop:before { - content: "\e99e"; -} - -.zi-globe:before { - content: "\e99f"; -} - -.zi-gift:before { - content: "\e9a0"; -} - -.zi-forward:before { - content: "\e9a1"; -} - -.zi-forward-step:before { - content: "\e9a2"; -} - -.zi-format-underline:before { - content: "\e9a3"; -} - -.zi-format-text-size:before { - content: "\e9a4"; -} - -.zi-format-italic:before { - content: "\e9a5"; -} - -.zi-format-font-size:before { - content: "\e9a6"; -} - -.zi-format-bold:before { - content: "\e9a7"; -} - -.zi-folder:before { - content: "\e9a8"; -} - -.zi-folder-outline:before { - content: "\e9a9"; -} - -.zi-folder-outline-add:before { - content: "\e9aa"; -} - -.zi-flashlight:before { - content: "\e9ab"; -} - -.zi-flag:before { - content: "\e9ac"; -} - -.zi-filter:before { - content: "\e9ad"; -} - -.zi-film:before { - content: "\e9ae"; -} - -.zi-fast-rewind:before { - content: "\e9af"; -} - -.zi-fast-forward:before { - content: "\e9b0"; -} - -.zi-factory:before { - content: "\e9b1"; -} - -.zi-explore:before { - content: "\e9b2"; -} - -.zi-exclamation-solid:before { - content: "\e9b3"; -} - -.zi-exclamation-outline:before { - content: "\e9b4"; -} - -.zi-envelope:before { - content: "\e9b5"; -} - -.zi-education:before { - content: "\e9b6"; -} - -.zi-edit-pencil:before { - content: "\e9b7"; -} - -.zi-edit-cut:before { - content: "\e9b8"; -} - -.zi-edit-crop:before { - content: "\e9b9"; -} - -.zi-edit-copy:before { - content: "\e9ba"; -} - -.zi-duplicate:before { - content: "\e9bb"; -} - -.zi-download:before { - content: "\e9bc"; -} - -.zi-dots-horizontal-triple:before { - content: "\e9bd"; -} - -.zi-dots-horizontal-double:before { - content: "\e9be"; -} - -.zi-document:before { - content: "\e9bf"; -} - -.zi-document-add:before { - content: "\e9c0"; -} - -.zi-directions:before { - content: "\e9c1"; -} - -.zi-dial-pad:before { - content: "\e9c2"; -} - -.zi-date-add:before { - content: "\e9c3"; -} - -.zi-dashboard:before { - content: "\e9c4"; -} - -.zi-currency-dollar:before { - content: "\e9c5"; -} - -.zi-credit-card:before { - content: "\e9c6"; -} - -.zi-copy:before { - content: "\e9c7"; -} - -.zi-conversation:before { - content: "\e9c8"; -} - -.zi-computer-laptop:before { - content: "\e9c9"; -} - -.zi-computer-desktop:before { - content: "\e9ca"; -} - -.zi-compose:before { - content: "\e9cb"; -} - -.zi-color-palette:before { - content: "\e9cc"; -} - -.zi-cog:before { - content: "\e9cd"; -} - -.zi-coffee:before { - content: "\e9ce"; -} - -.zi-code:before { - content: "\e9cf"; -} - -.zi-cloud:before { - content: "\e9d0"; -} - -.zi-cloud-upload:before { - content: "\e9d1"; -} - -.zi-close:before { - content: "\e9d2"; -} - -.zi-close-solid:before { - content: "\e9d3"; -} - -.zi-close-outline:before { - content: "\e9d4"; -} - -.zi-clipboard:before { - content: "\e9d5"; -} - -.zi-cheveron-up:before { - content: "\e9d6"; -} - -.zi-cheveron-right:before { - content: "\e9d7"; -} - -.zi-cheveron-outline-up:before { - content: "\e9d8"; -} - -.zi-cheveron-outline-right:before { - content: "\e9d9"; -} - -.zi-cheveron-outline-left:before { - content: "\e9da"; -} - -.zi-cheveron-outline-down:before { - content: "\e9db"; -} - -.zi-cheveron-left:before { - content: "\e9dc"; -} - -.zi-cheveron-down:before { - content: "\e9dd"; -} - -.zi-checkmark:before { - content: "\e9de"; -} - -.zi-checkmark-outline:before { - content: "\e9df"; -} - -.zi-chat-bubble-dots:before { - content: "\e9e0"; -} - -.zi-chart:before { - content: "\e9e1"; -} - -.zi-chart-pie:before { - content: "\e9e2"; -} - -.zi-chart-bar:before { - content: "\e9e3"; -} - -.zi-camera:before { - content: "\e9e4"; -} - -.zi-calendar:before { - content: "\e9e5"; -} - -.zi-calculator:before { - content: "\e9e6"; -} - -.zi-buoy:before { - content: "\e9e7"; -} - -.zi-bug:before { - content: "\e9e8"; -} - -.zi-browser-window:before { - content: "\e9e9"; -} - -.zi-browser-window-open:before { - content: "\e9ea"; -} - -.zi-browser-window-new:before { - content: "\e9eb"; -} - -.zi-brightness-up:before { - content: "\e9ec"; -} - -.zi-brightness-down:before { - content: "\e9ed"; -} - -.zi-box:before { - content: "\e9ee"; -} - -.zi-border-vertical:before { - content: "\e9ef"; -} - -.zi-border-top:before { - content: "\e9f0"; -} - -.zi-border-right:before { - content: "\e9f1"; -} - -.zi-border-outer:before { - content: "\e9f2"; -} - -.zi-border-none:before { - content: "\e9f3"; -} - -.zi-border-left:before { - content: "\e9f4"; -} - -.zi-border-inner:before { - content: "\e9f5"; -} - -.zi-border-horizontal:before { - content: "\e9f6"; -} - -.zi-border-bottom:before { - content: "\e9f7"; -} - -.zi-border-all:before { - content: "\e9f8"; -} - -.zi-bookmark:before { - content: "\e9f9"; -} - -.zi-bookmark-outline:before { - content: "\e9fa"; -} - -.zi-bookmark-outline-add:before { - content: "\e9fb"; -} - -.zi-bookmark-copy-3:before { - content: "\e9fc"; -} - -.zi-bookmark-copy-2:before { - content: "\e9fd"; -} - -.zi-book-reference:before { - content: "\e9fe"; -} - -.zi-bolt:before { - content: "\e9ff"; -} - -.zi-bluetooth:before { - content: "\ea00"; -} - -.zi-block:before { - content: "\ea01"; -} - -.zi-beverage:before { - content: "\ea02"; -} - -.zi-battery-low:before { - content: "\ea03"; -} - -.zi-battery-half:before { - content: "\ea04"; -} - -.zi-battery-full:before { - content: "\ea05"; -} - -.zi-badge:before { - content: "\ea06"; -} - -.zi-backward:before { - content: "\ea07"; -} - -.zi-backward-step:before { - content: "\ea08"; -} - -.zi-backspace:before { - content: "\ea09"; -} - -.zi-attachment:before { - content: "\ea0a"; -} - -.zi-at-symbol:before { - content: "\ea0b"; -} - -.zi-artist:before { - content: "\ea0c"; -} - -.zi-arrow-up:before { - content: "\ea0d"; -} - -.zi-arrow-thin-up:before { - content: "\ea0e"; -} - -.zi-arrow-thin-right:before { - content: "\ea0f"; -} - -.zi-arrow-thin-left:before { - content: "\ea10"; -} - -.zi-arrow-thin-down:before { - content: "\ea11"; -} - -.zi-arrow-thick-up:before { - content: "\ea12"; -} - -.zi-arrow-thick-right:before { - content: "\ea13"; -} - -.zi-arrow-thick-left:before { - content: "\ea14"; -} - -.zi-arrow-thick-down:before { - content: "\ea15"; -} - -.zi-arrow-right:before { - content: "\ea16"; -} - -.zi-arrow-outline-up:before { - content: "\ea17"; -} - -.zi-arrow-outline-right:before { - content: "\ea18"; -} - -.zi-arrow-outline-left:before { - content: "\ea19"; -} - -.zi-arrow-outline-down:before { - content: "\ea1a"; -} - -.zi-arrow-left:before { - content: "\ea1b"; -} - -.zi-arrow-down:before { - content: "\ea1c"; -} - -.zi-apparel:before { - content: "\ea1d"; -} - -.zi-announcement:before { - content: "\ea1e"; -} - -.zi-anchor:before { - content: "\ea1f"; -} - -.zi-align-right:before { - content: "\ea20"; -} - -.zi-align-left:before { - content: "\ea21"; -} - -.zi-align-justified:before { - content: "\ea22"; -} - -.zi-align-center:before { - content: "\ea23"; -} - -.zi-album:before { - content: "\ea24"; -} - -.zi-airplane:before { - content: "\ea25"; -} - -.zi-adjust:before { - content: "\ea26"; -} - -.zi-add-solid:before { - content: "\ea27"; -} - -.zi-add-outline:before { - content: "\ea28"; -} diff --git a/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/zondicons.min.css b/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/zondicons.min.css deleted file mode 100644 index 055868c1..00000000 --- a/djangocms_frontend/contrib/icon/static/djangocms_frontend/icon/vendor/assets/stylesheets/zondicons.min.css +++ /dev/null @@ -1 +0,0 @@ -@font-face{font-family:'zondicon';src:url('../fonts/zondicon.eot?sm22ej');src:url('../fonts/zondicon.eot?sm22ej#iefix') format('embedded-opentype'),url('../fonts/zondicon.ttf?sm22ej') format('truetype'),url('../fonts/zondicon.woff?sm22ej') format('woff'),url('../fonts/zondicon.svg?sm22ej#zondicon') format('svg');font-weight:normal;font-style:normal;}.zi{font-family:'zondicon'!important;speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;} .zi-zoom-out:before{content:"\e900";} .zi-zoom-in:before{content:"\e901";} .zi-yin-yang:before{content:"\e902";} .zi-wrench:before{content:"\e903";} .zi-window:before{content:"\e904";} .zi-window-open:before{content:"\e905";} .zi-window-new:before{content:"\e906";} .zi-watch:before{content:"\e907";} .zi-wallet:before{content:"\e908";} .zi-volume-up:before{content:"\e909";} .zi-volume-off:before{content:"\e90a";} .zi-volume-mute:before{content:"\e90b";} .zi-volume-down:before{content:"\e90c";} .zi-view-tile:before{content:"\e90d";} .zi-view-show:before{content:"\e90e";} .zi-view-list:before{content:"\e90f";} .zi-view-hide:before{content:"\e910";} .zi-view-column:before{content:"\e911";} .zi-view-carousel:before{content:"\e912";} .zi-video-camera:before{content:"\e913";} .zi-vector:before{content:"\e914";} .zi-user:before{content:"\e915";} .zi-user-solid-square:before{content:"\e916";} .zi-user-solid-circle:before{content:"\e917";} .zi-user-group:before{content:"\e918";} .zi-user-add:before{content:"\e919";} .zi-usb:before{content:"\e91a";} .zi-upload:before{content:"\e91b";} .zi-tuning:before{content:"\e91c";} .zi-trophy:before{content:"\e91d";} .zi-travel:before{content:"\e91e";} .zi-travel-walk:before{content:"\e91f";} .zi-travel-train:before{content:"\e920";} .zi-travel-taxi-cab:before{content:"\e921";} .zi-travel-case:before{content:"\e922";} .zi-travel-car:before{content:"\e923";} .zi-travel-bus:before{content:"\e924";} .zi-trash:before{content:"\e925";} .zi-translate:before{content:"\e926";} .zi-tools-copy:before{content:"\e927";} .zi-timer:before{content:"\e928";} .zi-time:before{content:"\e929";} .zi-ticket:before{content:"\e92a";} .zi-thumbs-up:before{content:"\e92b";} .zi-thumbs-down:before{content:"\e92c";} .zi-thermometer:before{content:"\e92d";} .zi-text-decoration:before{content:"\e92e";} .zi-text-box:before{content:"\e92f";} .zi-target:before{content:"\e930";} .zi-tag:before{content:"\e931";} .zi-tablet:before{content:"\e932";} .zi-swap:before{content:"\e933";} .zi-subdirectory-right:before{content:"\e934";} .zi-subdirectory-left:before{content:"\e935";} .zi-stroke-width:before{content:"\e936";} .zi-store-front:before{content:"\e937";} .zi-stethoscope:before{content:"\e938";} .zi-step-forward:before{content:"\e939";} .zi-step-backward:before{content:"\e93a";} .zi-station:before{content:"\e93b";} .zi-star-full:before{content:"\e93c";} .zi-stand-by:before{content:"\e93d";} .zi-shuffle:before{content:"\e93e";} .zi-show-sidebar:before{content:"\e93f";} .zi-shopping-cart:before{content:"\e940";} .zi-shield:before{content:"\e941";} .zi-share:before{content:"\e942";} .zi-share-alt:before{content:"\e943";} .zi-share-01:before{content:"\e944";} .zi-servers:before{content:"\e945";} .zi-send:before{content:"\e946";} .zi-search:before{content:"\e947";} .zi-screen-full:before{content:"\e948";} .zi-save-disk:before{content:"\e949";} .zi-repost:before{content:"\e94a";} .zi-reply:before{content:"\e94b";} .zi-reply-all:before{content:"\e94c";} .zi-reload:before{content:"\e94d";} .zi-refresh:before{content:"\e94e";} .zi-radio:before{content:"\e94f";} .zi-radar:before{content:"\e950";} .zi-radar-copy-2:before{content:"\e951";} .zi-queue:before{content:"\e952";} .zi-question:before{content:"\e953";} .zi-pylon:before{content:"\e954";} .zi-printer:before{content:"\e955";} .zi-portfolio:before{content:"\e956";} .zi-plugin:before{content:"\e957";} .zi-playlist:before{content:"\e958";} .zi-play:before{content:"\e959";} .zi-play-outline:before{content:"\e95a";} .zi-pin:before{content:"\e95b";} .zi-php-elephant:before{content:"\e95c";} .zi-photo:before{content:"\e95d";} .zi-phone:before{content:"\e95e";} .zi-pen-tool:before{content:"\e95f";} .zi-pause:before{content:"\e960";} .zi-pause-solid:before{content:"\e961";} .zi-pause-outline:before{content:"\e962";} .zi-paste:before{content:"\e963";} .zi-notifications:before{content:"\e964";} .zi-notifications-outline:before{content:"\e965";} .zi-notification:before{content:"\e966";} .zi-news-paper:before{content:"\e967";} .zi-network:before{content:"\e968";} .zi-navigation-more:before{content:"\e969";} .zi-music-playlist:before{content:"\e96a";} .zi-music-notes:before{content:"\e96b";} .zi-music-artist:before{content:"\e96c";} .zi-music-album:before{content:"\e96d";} .zi-mouse:before{content:"\e96e";} .zi-mood-sad-solid:before{content:"\e96f";} .zi-mood-sad-outline:before{content:"\e970";} .zi-mood-neutral-solid:before{content:"\e971";} .zi-mood-neutral-outline:before{content:"\e972";} .zi-mood-happy-solid:before{content:"\e973";} .zi-mood-happy-outline:before{content:"\e974";} .zi-mobile-devices:before{content:"\e975";} .zi-minus-solid:before{content:"\e976";} .zi-minus-outline:before{content:"\e977";} .zi-mic:before{content:"\e978";} .zi-menu:before{content:"\e979";} .zi-map:before{content:"\e97a";} .zi-lock-open:before{content:"\e97b";} .zi-lock-closed:before{content:"\e97c";} .zi-location:before{content:"\e97d";} .zi-location-shopping:before{content:"\e97e";} .zi-location-restroom:before{content:"\e97f";} .zi-location-park:before{content:"\e980";} .zi-location-marina:before{content:"\e981";} .zi-location-hotel:before{content:"\e982";} .zi-location-gas-station:before{content:"\e983";} .zi-location-food:before{content:"\e984";} .zi-location-current:before{content:"\e985";} .zi-load-balancer:before{content:"\e986";} .zi-list:before{content:"\e987";} .zi-list-bullet:before{content:"\e988";} .zi-list-add:before{content:"\e989";} .zi-link:before{content:"\e98a";} .zi-light-bulb:before{content:"\e98b";} .zi-library:before{content:"\e98c";} .zi-layers:before{content:"\e98d";} .zi-keyboard:before{content:"\e98e";} .zi-key:before{content:"\e98f";} .zi-information-solid:before{content:"\e990";} .zi-information-outline:before{content:"\e991";} .zi-indent-increase:before{content:"\e992";} .zi-indent-decrease:before{content:"\e993";} .zi-inbox:before{content:"\e994";} .zi-inbox-full:before{content:"\e995";} .zi-inbox-download:before{content:"\e996";} .zi-inbox-check:before{content:"\e997";} .zi-hour-glass:before{content:"\e998";} .zi-hot:before{content:"\e999";} .zi-home:before{content:"\e99a";} .zi-heart:before{content:"\e99b";} .zi-headphones:before{content:"\e99c";} .zi-hard-drive:before{content:"\e99d";} .zi-hand-stop:before{content:"\e99e";} .zi-globe:before{content:"\e99f";} .zi-gift:before{content:"\e9a0";} .zi-forward:before{content:"\e9a1";} .zi-forward-step:before{content:"\e9a2";} .zi-format-underline:before{content:"\e9a3";} .zi-format-text-size:before{content:"\e9a4";} .zi-format-italic:before{content:"\e9a5";} .zi-format-font-size:before{content:"\e9a6";} .zi-format-bold:before{content:"\e9a7";} .zi-folder:before{content:"\e9a8";} .zi-folder-outline:before{content:"\e9a9";} .zi-folder-outline-add:before{content:"\e9aa";} .zi-flashlight:before{content:"\e9ab";} .zi-flag:before{content:"\e9ac";} .zi-filter:before{content:"\e9ad";} .zi-film:before{content:"\e9ae";} .zi-fast-rewind:before{content:"\e9af";} .zi-fast-forward:before{content:"\e9b0";} .zi-factory:before{content:"\e9b1";} .zi-explore:before{content:"\e9b2";} .zi-exclamation-solid:before{content:"\e9b3";} .zi-exclamation-outline:before{content:"\e9b4";} .zi-envelope:before{content:"\e9b5";} .zi-education:before{content:"\e9b6";} .zi-edit-pencil:before{content:"\e9b7";} .zi-edit-cut:before{content:"\e9b8";} .zi-edit-crop:before{content:"\e9b9";} .zi-edit-copy:before{content:"\e9ba";} .zi-duplicate:before{content:"\e9bb";} .zi-download:before{content:"\e9bc";} .zi-dots-horizontal-triple:before{content:"\e9bd";} .zi-dots-horizontal-double:before{content:"\e9be";} .zi-document:before{content:"\e9bf";} .zi-document-add:before{content:"\e9c0";} .zi-directions:before{content:"\e9c1";} .zi-dial-pad:before{content:"\e9c2";} .zi-date-add:before{content:"\e9c3";} .zi-dashboard:before{content:"\e9c4";} .zi-currency-dollar:before{content:"\e9c5";} .zi-credit-card:before{content:"\e9c6";} .zi-copy:before{content:"\e9c7";} .zi-conversation:before{content:"\e9c8";} .zi-computer-laptop:before{content:"\e9c9";} .zi-computer-desktop:before{content:"\e9ca";} .zi-compose:before{content:"\e9cb";} .zi-color-palette:before{content:"\e9cc";} .zi-cog:before{content:"\e9cd";} .zi-coffee:before{content:"\e9ce";} .zi-code:before{content:"\e9cf";} .zi-cloud:before{content:"\e9d0";} .zi-cloud-upload:before{content:"\e9d1";} .zi-close:before{content:"\e9d2";} .zi-close-solid:before{content:"\e9d3";} .zi-close-outline:before{content:"\e9d4";} .zi-clipboard:before{content:"\e9d5";} .zi-cheveron-up:before{content:"\e9d6";} .zi-cheveron-right:before{content:"\e9d7";} .zi-cheveron-outline-up:before{content:"\e9d8";} .zi-cheveron-outline-right:before{content:"\e9d9";} .zi-cheveron-outline-left:before{content:"\e9da";} .zi-cheveron-outline-down:before{content:"\e9db";} .zi-cheveron-left:before{content:"\e9dc";} .zi-cheveron-down:before{content:"\e9dd";} .zi-checkmark:before{content:"\e9de";} .zi-checkmark-outline:before{content:"\e9df";} .zi-chat-bubble-dots:before{content:"\e9e0";} .zi-chart:before{content:"\e9e1";} .zi-chart-pie:before{content:"\e9e2";} .zi-chart-bar:before{content:"\e9e3";} .zi-camera:before{content:"\e9e4";} .zi-calendar:before{content:"\e9e5";} .zi-calculator:before{content:"\e9e6";} .zi-buoy:before{content:"\e9e7";} .zi-bug:before{content:"\e9e8";} .zi-browser-window:before{content:"\e9e9";} .zi-browser-window-open:before{content:"\e9ea";} .zi-browser-window-new:before{content:"\e9eb";} .zi-brightness-up:before{content:"\e9ec";} .zi-brightness-down:before{content:"\e9ed";} .zi-box:before{content:"\e9ee";} .zi-border-vertical:before{content:"\e9ef";} .zi-border-top:before{content:"\e9f0";} .zi-border-right:before{content:"\e9f1";} .zi-border-outer:before{content:"\e9f2";} .zi-border-none:before{content:"\e9f3";} .zi-border-left:before{content:"\e9f4";} .zi-border-inner:before{content:"\e9f5";} .zi-border-horizontal:before{content:"\e9f6";} .zi-border-bottom:before{content:"\e9f7";} .zi-border-all:before{content:"\e9f8";} .zi-bookmark:before{content:"\e9f9";} .zi-bookmark-outline:before{content:"\e9fa";} .zi-bookmark-outline-add:before{content:"\e9fb";} .zi-bookmark-copy-3:before{content:"\e9fc";} .zi-bookmark-copy-2:before{content:"\e9fd";} .zi-book-reference:before{content:"\e9fe";} .zi-bolt:before{content:"\e9ff";} .zi-bluetooth:before{content:"\ea00";} .zi-block:before{content:"\ea01";} .zi-beverage:before{content:"\ea02";} .zi-battery-low:before{content:"\ea03";} .zi-battery-half:before{content:"\ea04";} .zi-battery-full:before{content:"\ea05";} .zi-badge:before{content:"\ea06";} .zi-backward:before{content:"\ea07";} .zi-backward-step:before{content:"\ea08";} .zi-backspace:before{content:"\ea09";} .zi-attachment:before{content:"\ea0a";} .zi-at-symbol:before{content:"\ea0b";} .zi-artist:before{content:"\ea0c";} .zi-arrow-up:before{content:"\ea0d";} .zi-arrow-thin-up:before{content:"\ea0e";} .zi-arrow-thin-right:before{content:"\ea0f";} .zi-arrow-thin-left:before{content:"\ea10";} .zi-arrow-thin-down:before{content:"\ea11";} .zi-arrow-thick-up:before{content:"\ea12";} .zi-arrow-thick-right:before{content:"\ea13";} .zi-arrow-thick-left:before{content:"\ea14";} .zi-arrow-thick-down:before{content:"\ea15";} .zi-arrow-right:before{content:"\ea16";} .zi-arrow-outline-up:before{content:"\ea17";} .zi-arrow-outline-right:before{content:"\ea18";} .zi-arrow-outline-left:before{content:"\ea19";} .zi-arrow-outline-down:before{content:"\ea1a";} .zi-arrow-left:before{content:"\ea1b";} .zi-arrow-down:before{content:"\ea1c";} .zi-apparel:before{content:"\ea1d";} .zi-announcement:before{content:"\ea1e";} .zi-anchor:before{content:"\ea1f";} .zi-align-right:before{content:"\ea20";} .zi-align-left:before{content:"\ea21";} .zi-align-justified:before{content:"\ea22";} .zi-align-center:before{content:"\ea23";} .zi-album:before{content:"\ea24";} .zi-airplane:before{content:"\ea25";} .zi-adjust:before{content:"\ea26";} .zi-add-solid:before{content:"\ea27";} .zi-add-outline:before{content:"\ea28";} From a8e5f2ddd2824328414544440816be654c28af4f Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Tue, 9 Jan 2024 00:15:07 +0100 Subject: [PATCH 10/66] Doc typos --- docs/source/components.rst | 71 ++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 19 deletions(-) diff --git a/docs/source/components.rst b/docs/source/components.rst index 271ca05d..9575778f 100644 --- a/docs/source/components.rst +++ b/docs/source/components.rst @@ -1,7 +1,7 @@ + .. index:: single: Plugins - ################### Component plugins ################### @@ -160,10 +160,18 @@ A `Carousel `_ is a set of images (potentially with some description) that slide in (or fade in) one after the other after a certain amount of time. -Each slide requires a Carousel Slide child plugin. The simplest case specifies an image, potentially a caption and a link which is followed once the slide is clicked. +Each slide requires a Carousel Slide child plugin. The simplest case specifies +an image, potentially a caption and a link which is followed once the slide is +clicked. + +Since the design of carousels is somewhat opinionated template sets can be +specified using the ``DJANGOCMS_FRONTEND_CAROUSEL_TEMPLATES`` setting. -Since the design of carousels is somewhat opinionated template sets can be specified using the ``DJANGOCMS_FRONTEND_CAROUSEL_TEMPLATES`` setting. -.. note:: A Carousel Slide plugin can have child plugins itself. If an image is specified the child plugins add to the caption. If no image is specified the child plugins make up the slide. +.. note:: + + A Carousel Slide plugin can have child plugins itself. If an image is + specified the child plugins add to the caption. If no image is specified + the child plugins make up the slide. ****************** Collapse component @@ -349,6 +357,7 @@ djangocms-frontend offers the `ace code editor `_ to enter code bits. .. warning:: + By default the ace code editor javascript code is retrieved over the internet from a cdn. If you do not want this to happen, e.g., for data privacy reasons or because your system is not connected to the internet, please use the @@ -391,11 +400,14 @@ Icon component .. versionadded:: 1.1 -djangocms-frontend's icon plugin supports a variety of popular icon fonts. The icon component is centered around Gilles Migliori's `universal icon picker `_. +djangocms-frontend's icon plugin supports a variety of popular icon fonts. The +icon component is centered around Gilles Migliori's +`universal icon picker `_. .. image:: screenshots/icon-picker.png -A version of it is bundled with djangocms-frontend. It currently contains support for the following icon sets: +A version of it is bundled with djangocms-frontend. It currently contains +support for the following icon sets: * `Bootstrap icons `_ * `Elegant icons `_ (bundled) @@ -414,21 +426,30 @@ A version of it is bundled with djangocms-frontend. It currently contains suppor .. note:: - The icon picker needs a config file for each icon set. This requires regular update. Please be patient if new icons do not appear immediately in djangocms-frontend's icon picker or - even better - `create a pull request! `_ + The icon picker needs a config file for each icon set. This requires regular + update. Please be patient if new icons do not appear immediately in + djangocms-frontend's icon picker or - even better - + `create a pull request! `_ .. warning:: - You may either use djangocms-icon or djangocms-frontent's icon contrib package but not both, since they both register an ``IconPlugin``. + You may either use djangocms-icon or djangocms-frontent's icon contrib + package but not both, since they both register an ``IconPlugin``. Icon fonts ========== -As marked in the overview above, some MIT licenced icon fonts are bundled for convenience. They are available to the web page through static files. +As marked in the overview above, some MIT licenced icon fonts are bundled for +convenience. They are available to the web page through static files. -For other icon sets source files are loaded from CDN through the internet by default. This is not necessarily a configuration you want to have in a production situation. To specify where to get the required css files from please use the :py:attr:`~settings.DJANGOCMS_FRONTEND_ICON_LIBRARIES` setting. +For other icon sets source files are loaded from CDN through the internet by +default. This is not necessarily a configuration you want to have in a production +situation. To specify where to get the required css files from please use the +:py:attr:`~settings.DJANGOCMS_FRONTEND_ICON_LIBRARIES` setting. -To just restrict the available choices of icon sets for the user use the :py:attr:`~settings.DJANGOCMS_FRONTEND_ICON_LIBRARIES_SHOWN` setting. +To just restrict the available choices of icon sets for the user use the +:py:attr:`~settings.DJANGOCMS_FRONTEND_ICON_LIBRARIES_SHOWN` setting. Icons can be sized. Options for icon sizes are defined by the :py:attr:`~settings.DJANGOCMS_FRONTEND_ICON_SIZE_CHOICES` setting. @@ -436,7 +457,9 @@ Icons can be sized. Options for icon sizes are defined by the :py:attr:`~setting Adding custom icon fonts ======================== -To add a custom icon font you need to generate a config file. This is a json file that tells the icon picker which icons are available. As an example check out the `config file for Bootstrap Icons `_:: +To add a custom icon font you need to generate a config file. This is a json +file that tells the icon picker which icons are available. As an example check +out the `config file for Bootstrap Icons `_:: { "prefix": "bi bi-", @@ -455,13 +478,16 @@ To add a custom icon font you need to generate a config file. This is a json fil Icons are rendered as ``>`` tags with classes. -``.prefix`` defines a string that is prepended to all icons. For Bootstrap icons that's the class ``bi`` and the prefix for the icon selecting class ``bi-``. +``.prefix`` defines a string that is prepended to all icons. For Bootstrap icons +that's the class ``bi`` and the prefix for the icon selecting class ``bi-``. The list ``.icons`` contains all available icons in the set. ``.list-icon`` contains the classes for the example icon. You can probably ignore it. -``.icon-style`` currently is unused. It may in future determine how icons are rendered. Currently all icons a re rendered by ```` except material design icon which are rendered by ``bla``. +``.icon-style`` currently is unused. It may in future determine how icons are +rendered. Currently all icons a re rendered by ```` except +material design icon which are rendered by ``bla``. Using svg sprites @@ -473,9 +499,12 @@ Currently only font-based icons are supported. Icon plugins inside text plugins ================================ -The icon plugin is text-enabled, i.e., you can add it to a text plugin through djangocms-text-ckeditor's CKEDITOR. By default, however, CKEDITOR removes empty ```` or ```` tags which most icons use. +The icon plugin is text-enabled, i.e., you can add it to a text plugin through +djangocms-text-ckeditor's CKEDITOR. By default, however, CKEDITOR removes empty +```` or ```` tags which most icons use. -To disable this behavior of CKEDITOR, you need to add a ``stylesSet`` entry in ``CKEDITOR_SETTINGS``, e.g., +To disable this behavior of CKEDITOR, you need to add a ``customConfig`` entry +in ``CKEDITOR_SETTINGS``, e.g., .. code-block:: python @@ -485,16 +514,20 @@ To disable this behavior of CKEDITOR, you need to add a ``stylesSet`` entry in ` ..., } -This will load the ``ckeditor.icons.js`` file which in turn will allow empty ``span``and ``i`` tags. +This will load the ``ckeditor.icons.js`` file which in turn will allow empty +``span``and ``i`` tags. -If you already have a ``styleSet`` file specified it will suffice to add the following two lines to it. +If you already have a ``customConfig`` file specified it will suffice to add +the following two lines to it. .. code-block:: javascript CKEDITOR.dtd.$removeEmpty.span = 0; CKEDITOR.dtd.$removeEmpty.i = 0; -Finally, you potentially need to add the necessary icon css files to the ``contentCss`` property of ``CKEDITOR_SETTINGS``, e.g., for bootstrap icons from their cdn +Finally, you potentially need to add the necessary icon css files to the +``contentCss`` property of ``CKEDITOR_SETTINGS``, e.g., for bootstrap icons +from their cdn .. code-block:: python From ad90c57c872a7aba256e3d97efd5a4c4acb57d7d Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Thu, 11 Jan 2024 01:10:14 +0100 Subject: [PATCH 11/66] Fix: Missing space in auto column short description --- djangocms_frontend/contrib/grid/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/djangocms_frontend/contrib/grid/models.py b/djangocms_frontend/contrib/grid/models.py index 771c47d1..b0181ea9 100644 --- a/djangocms_frontend/contrib/grid/models.py +++ b/djangocms_frontend/contrib/grid/models.py @@ -87,5 +87,5 @@ def get_short_description(self): if self.xs_col: text += f" (col-{self.xs_col}) " else: - text += "(auto) " + text += " (auto) " return text.strip() From ef87c911254bad812316d7a740b34650136bfb3a Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Fri, 12 Jan 2024 23:37:44 +0100 Subject: [PATCH 12/66] Unlist removed iconsets from the docs --- docs/source/components.rst | 3 --- docs/source/reference.rst | 31 ++++++++++++++----------------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/docs/source/components.rst b/docs/source/components.rst index 9575778f..33a60954 100644 --- a/docs/source/components.rst +++ b/docs/source/components.rst @@ -415,13 +415,10 @@ support for the following icon sets: * `Fomatic UI icons `_ (bundled) * `Font awesome (regular, solid and brands) `_ * `Foundation icons `_ (bundled) -* Happy icons (bundled) -* `Icomoon `_ (bundled) * `Material icons (filled, outlined, sharp, two-tone) `_ * `Open iconic `_ * `Tabler icons `_ * Eric Flower's `Weather icons `_ (bundled) -* Steve Schoger's `Zondicons `_ (bundled) .. note:: diff --git a/docs/source/reference.rst b/docs/source/reference.rst index 8525f2e0..a15a1212 100644 --- a/docs/source/reference.rst +++ b/docs/source/reference.rst @@ -262,23 +262,20 @@ in your project's ``settings.py``. Default:: DJANGOCMS_FRONTEND_ICON_LIBRARIES_SHOWN = ( - 'font-awesome', - 'bootstrap-icons', - 'material-icons-filled', - 'material-icons-outlined', - 'material-icons-round', - 'material-icons-sharp', - 'material-icons-two-tone', - 'fomantic-ui', - 'foundation-icons', - 'elegant-icons', - 'feather-icons', - 'happy-icons', - 'icomoon', - 'open-iconic', - 'tabler-icons', - 'zondicons', - 'weather-icons' + "font-awesome", + "bootstrap-icons", + "material-icons-filled", + "material-icons-outlined", + "material-icons-round", + "material-icons-sharp", + "material-icons-two-tone", + "fomantic-ui", + "foundation-icons", + "elegant-icons", + "feather-icons", + "open-iconic", + "tabler-icons", + "weather-icons", ) This settings allows to restrict the number of icon sets shown to the user. Typically one or two icon sets should be sufficient to keep a consistent icon expierence. From 25cbc79f9e37bc38b9bb49050892450854a51acb Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Thu, 21 Mar 2024 08:45:22 +0100 Subject: [PATCH 13/66] Bump version --- CHANGELOG.rst | 10 ++++++++++ djangocms_frontend/__init__.py | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 12c2df70..691f720c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,16 @@ Changelog ========= +1.3.0 (2024-03-21) +================== + +* feat: Add abstract base model `AbstractFrontendUIItem` by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/195 +* feat: Add icons for selected text-enabled plugins by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/195 +* fix: removed Nav Container plugin and fixed Navigation Link plugin by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/192 +* fix: Remove `{% spaceless %}` around `{% block "content" %}` by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/188 +* fix: Improved fieldset layout for Django 4.2+ by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/185 + + 1.2.2 (2024-01-13) ================== diff --git a/djangocms_frontend/__init__.py b/djangocms_frontend/__init__.py index 96d01747..229aea75 100644 --- a/djangocms_frontend/__init__.py +++ b/djangocms_frontend/__init__.py @@ -19,4 +19,4 @@ 13. Github actions will publish the new package to pypi """ -__version__ = "1.2.2" +__version__ = "1.3.0" From a006821463595f337704d9a1b8e853f9c49eb18d Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Thu, 21 Mar 2024 08:48:13 +0100 Subject: [PATCH 14/66] Add translations --- .../locale/ar/LC_MESSAGES/django.mo | Bin 3599 -> 7645 bytes .../locale/ar/LC_MESSAGES/django.po | 190 ++++++++++-------- .../locale/de/LC_MESSAGES/django.mo | Bin 28083 -> 28135 bytes .../locale/de/LC_MESSAGES/django.po | 112 +++++------ .../locale/es/LC_MESSAGES/django.mo | Bin 28031 -> 27932 bytes .../locale/es/LC_MESSAGES/django.po | 95 ++++----- .../locale/fr/LC_MESSAGES/django.mo | Bin 29566 -> 29475 bytes .../locale/fr/LC_MESSAGES/django.po | 137 ++++++------- .../locale/nl/LC_MESSAGES/django.mo | Bin 14412 -> 14324 bytes .../locale/nl/LC_MESSAGES/django.po | 86 ++++---- .../locale/sq/LC_MESSAGES/django.mo | Bin 24639 -> 24556 bytes .../locale/sq/LC_MESSAGES/django.po | 123 ++++++------ 12 files changed, 352 insertions(+), 391 deletions(-) diff --git a/djangocms_frontend/locale/ar/LC_MESSAGES/django.mo b/djangocms_frontend/locale/ar/LC_MESSAGES/django.mo index 16b41d8fed1b89514efdf56b8400d15ca2caf7d5..5b191d85790d22c5d1b5dcd9981ccfcfd089088d 100644 GIT binary patch literal 7645 zcmdUyS!^9w8OIM$3YdK@WhtixN=$pbq)ABJy2aTVLpEZkWs}aY>zT{U+@vY= zp{bpwX;oCVB7_7e1UqhA*GXt%Kw^^+AdmnRF&9C3K;i)&SRN3l5Age+nY+|U11f!C zXx@>-olf4E*Q|`QfoIGUjFA<={)e9`F_5dhq4o zjo_=nz2F!)0cz`y!OOs(fo}l+3|<0W{90q~{FKMZQ!QIMm}JScf5i}$mj^!g5{b-w~7|4C5$e_xFM8RXCW zogeA_uVTClGPLg1pzMDuDE)iESArWs$=d_=gExb(2k$H9zXbAU7Wt8W%b?bO7nGhq z0LAZ5K*{?xC_VoO_JMx|uLrL{Ded>b5*UEjfe(XMf=?9lPl5OI{sNSKE%-@L=NttQ zWsZXnfv3PvgIjR=0N4QE2EGnuc7bca9pE%5eSQIo#|9`p{!-vSK=Gzv(K#;xUjV)m zV1oIQ zyTIRqZ|40e@blm$I7@OK1FrzT3ChkV3%nF3D&9v6^gyi-LB;O@@KW$0Q1(3nveldh z#m5f{{3)n?Pk=iAcc6HD3e^5LqqNqq1yRjh2WtI}0zU|@;=K%N-20VcqRA|f=qZ26z|7D@%epF=llXhUB}4~_&yq{I<6?OuGRtu zbIiMFeYCZ-URv{!-tVO;-u0Ad%K3i1@F;HeC{C2a@1|{`4b$`xYVNt5-}OabpgevL zZI51fHqn%u*U;o6OM53x_HU$#FFoRU4Q(4uw(8kQ+e%wa+dxx{DSvm+^eA`bPd%yw zosZ&P520YLrfsKPM^m0OpKdye?ya)V z3(J1RCVrX*;Y4DFR*u-JpCS3j$Ys*oX`gf$ALs88u2k8NZ zDiePGYx6Zxh0!QYqbak=i!1KON@gwZ24U#OdAI7pPii({x`rkrR87n#nPN5-XKspp zFU8iTW1Kq@v)KzL*t6M-Z#SERWGYCKV65t!tx+UdTVrjtr(b2X1`2lA^ihP58DNd3a_R zg(hOz5`_4yhF8PXD4aS1BY%%-ewg<@ewW$qkEdpPFfpm$@b-4dZ4Z*PbL$T0bhEQQ zHAY-T<15s0L08V%+&}4uHu3fm3_WI7?n>>g_0&>lRiwM2)ct;$L+8qZZ!U40#pNjVR zdCpY)aj#xYJB%zjBd@keH09edvfq!Bt6k!`5tj^PI(31#?abVkx5;0Upp-@>A*q`> z3xc?CvdbS2)?$k;Ni7PKV4o-~YR4Yu+!3ENt4QAw$1Uc-dTvjmSZY&Kr1!bZ*j*$& zr6F$Zs}dBvrjuUiSRD^ym}+{jNtdcgA#{IGt%_{4lRxhCe9K{i$f?U!K2%#LZ#tKiM0vW_JG|zwCVjr zH*T>vZP_z2ylZFI9$!8v?MNnqN@-(#A}NhV1Ga1TuF@W^M(rtWrYH~C)qSh4DfRW2 zR`=QdwF7I`U)9IcwVlFJa)jaeC?2pQe(c?5hbk2+=ti%a*00viH7pD#>QwvEsP9b; z*rC`P3(9uYWSZ8Jf!Rh=3bM*b=TUwI~WcQ_SqY3pJjG%u%B*!-d#<1wYu-@ z@9VpM@EUvNm3jZV!G7(yrajl+-!Zvi1Cwi*TzhSo`{>G!WsBLP*=%Dvo6Y9Cjq4q4 z+|xLmEoF<1BaOq2Lnd2p9Lm0)E!k%?dn{Y#h*{U>ZDS^zZyZGOOm^I4^Sm6%7Hng> zaZfJ%>8o{K=Z@?Fn;p#_XZY^yxXr!}pmqLXhXu=x2hsX*+qgG-ESt>*7OHFKY<7wh zAJyTkV16!Jz*01^GL!j5w$C>1mtqUqW2m-dpkRhYhirB%`-WI*9LxpJvty3gdrfwR z&O^nxBqQ>4z6fR!d7^Q|qTF=jzI^m3Bll(}#lSOf6=#pK=NY%kXQwy{22hxl2kCyT zam2W7ccVS>7tm%}TnQwu7@x;0aNn3YXXZ3gme?wn=abEm?1awC$>GR3l!py1oxz|P zLT0&nQhUxF+pOiH_W) zVnn*mDloOJ6&QLsidPOgxz3>0q7I%q7dc87M0qa1*e;V4WQRd%g21zld&ydUR;Ghh z95i=7E!jI}=9IHiD`#}kW~7A(XiVo@m46HJq0;$;btz7at#H6>HfNfFn(r(8V_J?v z=-u*Tw$K{mqno2oVabxo9%t$+COfw{C|@%|#uUM?Tz2#{69e0ebZjxs5on4vQe*ZR z>sl^{z_aLaBAc_>u_D60Dxvvyq$sf#Q2(rP-P5W`d6ucH$sN>=j_h-z(wRY$$F7p| z75&GYmlTsaao%~i9r_lg7olOX+q7+J1xS82l?H=IfMe|%iIMCgIa&u$%(8j;aw+?U z%$jp%ElFz63OOCAm)oGaRWRJi%)F~(N17#YMt*|_7dTWfiN28JB9wx4u#Q`FBxzMGP6GJlr9!o7#twam5Q<_eZq zjGmNEcqPA78ZvMmcW^;qBmuBYrx38>@{~#oEPMo~>ROc}RFoY%b0o2hyPPdo4=QgEm9bEBC&`HH5~u>y6mqo^&^Ut&}))m<#A7um@z4)X<% zs+s7LGe+kE1~`v33FaVGt|g-VIc2PsjZ#UW>jMA(h_OxsF2Gphq5nS0juP+i@JVGz z<3Vx+C!TW|waGFB9k)FRp?{g&|Aj6v6u2(uT3>KItwKP@uw|KJTyCwr7nOko7gg>Q zJy#Z}*bKGPO~FHiosr{+!8|fMa{4T*xk=AGMm2;2^em1*9TkDcitx=Vh|xER!4$q@ z8=q=cl-B1=M>#CgMjBxqyBGDrc7pCg^V^TY}Fc_5?eMY;RtN5{fgH zvUwdTZvN8=avi#y@3U%|63K;$dhQdoV_9dQqeOd|Q@`WWsx=2i5YcjscyIoP@NbVb Btm*&& delta 906 zcmY+?-%FEG7{KwPE`Pf@e@*9xLn_LW%2>s`j1Wt&+(qO?9%0O-j(E4S8ySL(=qBYM z@G_7xf|Ae*38{Y|in@6xWnFnQFS@Fro4(H+K@U6c=e+0LInQ~Y^L`z?AIj~vcpexc zObgLG6~-LLebiX0G{%q1IEky+fz?&U1Tc&qjAA{;umvxby^1=2x_m#6KJJ&W$(WpZ zNT-^C=U9U;u^+c_8H*@5PnH<^4;}n}1a%{0sPk?hKjUy|z&m&W7f};#V>7--5}RGD zC%@UJ^M<$mh21>ZV6_$efSPcs_P|wa)QPBXT12hDPwYZ(oiT^;SlLn3=ML(+_fY@$ zxa>O|BEQ+8bA}D{vZ@+q`_~!IlTAyzhbORznmEAr)m|jG=|_v_@F=d7eT$lK551@t zmM@LztyV7=FKllcuHA&=PCtH>2mRZ%Q81O4IY!Xs2;{rOmeK z0HGDs%Efe+U zrO?>3@u}frg?w&0;*Y1YGYJ!SY&vt(I*D{vCcIhs;>~sqXB=xISM02viHzA9JDZp~ z85uY|a8{DO;l>f0PTsP~L@Z(*S@(@gpgAXhnqSE`|81FU8J6*IxAe3Pb-Rz;EqC2r zE48N)cdfAKzTozW`&zDrgR(%g9ha+~x$E*V*eBmR{IU}CZESYVRZ3rIu+`lv1x{s_^Z)<= diff --git a/djangocms_frontend/locale/ar/LC_MESSAGES/django.po b/djangocms_frontend/locale/ar/LC_MESSAGES/django.po index 4c011590..6674569e 100644 --- a/djangocms_frontend/locale/ar/LC_MESSAGES/django.po +++ b/djangocms_frontend/locale/ar/LC_MESSAGES/django.po @@ -2,10 +2,11 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# # Translators: -# Israa Kamal Salameh, 2023 -# +# Israa Kamal Salameh , 2023 +# Seraj Adden Baltu, 2024 +# #, fuzzy msgid "" msgstr "" @@ -13,22 +14,21 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-02-28 23:03+0100\n" "PO-Revision-Date: 2023-01-20 15:48+0000\n" -"Last-Translator: Israa Kamal Salameh, 2023\n" +"Last-Translator: Seraj Adden Baltu, 2024\n" "Language-Team: Arabic (https://app.transifex.com/divio/teams/58664/ar/)\n" -"Language: ar\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " -"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"Language: ar\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" #: common/attributes.py:9 msgid "" "Advanced settings lets you add html attributes to render this element. Use " "them wisely and rarely." msgstr "" -"تتيح لك الإعدادات المتقدمة، أضافة صفات html لعَرض هذا العنصر، استخدمها بحكمة " -"ونادراً" +"تتيح لك الإعدادات المتقدمة، أضافة صفات html لعَرض هذا العنصر، استخدمها بحكمة" +" ونادراً" #: common/attributes.py:26 contrib/accordion/cms_plugins.py:91 msgid "Advanced settings" @@ -53,9 +53,10 @@ msgstr "تعتيم الخلفية" #: common/bootstrap5/background.py:62 msgid "Opacity of card background color (only if no outline selected)" -msgstr "" +msgstr "الشفافية للون الخلفي للبطاقة (فقط إذا لم يتم اختيار حدود)" -#: common/bootstrap5/background.py:66 contrib/alert/frameworks/bootstrap5.py:42 +#: common/bootstrap5/background.py:66 +#: contrib/alert/frameworks/bootstrap5.py:42 msgid "Shadow" msgstr "ظل" @@ -89,7 +90,7 @@ msgstr "الحجم الأفقي" msgid "" "Sets the horizontal size relative to the surrounding container or the " "viewport." -msgstr "" +msgstr "تعين حجم الأفقي بالنسبة للحاوية المحيطة أو العرض الظاهر" #: common/bootstrap5/sizing.py:54 msgid "Vertical size" @@ -97,20 +98,21 @@ msgstr "الحجم العمودي" #: common/bootstrap5/sizing.py:60 msgid "" -"Sets the vertical size relative to the surrounding container or the viewport." -msgstr "" +"Sets the vertical size relative to the surrounding container or the " +"viewport." +msgstr "تعين حجم راسي بالنسبة للحاوية المحيطة أو نافذة العرض" #: common/spacing.py:84 msgid "Please choose a side to which the spacing should be applied." -msgstr "" +msgstr "الرجاء اختيار الجهة التي يجب تطبيق المسافة عليها" #: common/spacing.py:113 msgid "Margin" -msgstr "محاذاة خارجية" +msgstr "هامش خارجي" #: common/spacing.py:139 common/spacing.py:147 msgid "Padding" -msgstr "محاذاة داخلية" +msgstr "هامش داخلي" #: common/spacing.py:175 contrib/utilities/cms_plugins.py:22 #: contrib/utilities/models.py:14 @@ -152,8 +154,8 @@ msgstr "طبّق الهامش الداخلي على الأجهزة" #: common/spacing.py:236 msgid "" -"Select only devices on which the padding should be applied. On other devices " -"larger than the first selected device the padding will be set to zero." +"Select only devices on which the padding should be applied. On other devices" +" larger than the first selected device the padding will be set to zero." msgstr "" "حدد فقط الأجهزة التي يجب تطبيق المحاذاة الداخلية عليها. أما في الأجهزة " "الأخرى التي يزيد حجمها عن الجهاز الأول الذي تم تحديده، ستكون قيمة المحاذاة " @@ -169,13 +171,13 @@ msgstr "عنوان" #: common/title.py:67 msgid "" -"Optional title of the plugin for easier identification. Its title attribute will only be set if the checkbox is selected." +"Optional title of the plugin for easier identification. Its " +"title attribute will only be set if the checkbox is selected." msgstr "" #: contrib/accordion/cms_plugins.py:21 contrib/accordion/models.py:14 msgid "Accordion" -msgstr "" +msgstr "الأكورديون" #: contrib/accordion/cms_plugins.py:22 contrib/accordion/cms_plugins.py:72 #: contrib/alert/cms_plugins.py:25 contrib/badge/cms_plugins.py:21 @@ -197,90 +199,92 @@ msgstr "" #: contrib/utilities/cms_plugins.py:50 contrib/utilities/cms_plugins.py:62 #: contrib/utilities/cms_plugins.py:123 msgid "Frontend" -msgstr "" +msgstr "واجهة امامية" #: contrib/accordion/cms_plugins.py:57 msgid "Item {}" -msgstr "" +msgstr "عنصر{}" #: contrib/accordion/cms_plugins.py:71 contrib/accordion/models.py:33 msgid "Accordion item" -msgstr "" +msgstr "عنصر الأكورديون" #: contrib/accordion/forms.py:34 msgid "Create accordion items" -msgstr "" +msgstr "انشاء عنصر الأكورديون" #: contrib/accordion/forms.py:35 msgid "Number of accordion items to create when saving." -msgstr "" +msgstr "عدد عناصر الأكورديون التي يجب إنشاؤها عند الحفظ" #: contrib/accordion/forms.py:42 msgid "Header type" -msgstr "" +msgstr "نوع الرأس" #: contrib/accordion/forms.py:48 msgid "Integrate into parent" -msgstr "" +msgstr "دمج داخل عنصر الاب" #: contrib/accordion/forms.py:52 msgid "" -"Removes the default background-color, some borders, and some rounded corners " -"to render accordions edge-to-edge with their parent container " +"Removes the default background-color, some borders, and some rounded corners" +" to render accordions edge-to-edge with their parent container " msgstr "" +"يقوم بإزالة لون الخلفي الافتراضي وبعض الحدود وبعض الزوايا المستديرة لعرض " +"الأكورديون بحيث يكون حافة بجوار حاوية الاب" #: contrib/accordion/forms.py:78 contrib/card/constants.py:16 msgid "Header" -msgstr "" +msgstr "رأس" #: contrib/accordion/forms.py:82 msgid "Item open" -msgstr "" +msgstr "عنصر مفتوح" #: contrib/accordion/forms.py:85 msgid "Initially shows this accordion item on page load." -msgstr "" +msgstr "يظهر هذا العنصر في الأكورديون في البداية عند تحميل الصفحة" #: contrib/accordion/models.py:20 msgid "({} entries)" -msgstr "" +msgstr "({} إدخالات)" #: contrib/accordion/models.py:29 msgid "AccordionItem" -msgstr "" +msgstr "عنصر الأكورديون" #: contrib/alert/cms_plugins.py:24 contrib/alert/models.py:14 msgid "Alert" -msgstr "" +msgstr "تحذير" #: contrib/alert/forms.py:41 contrib/badge/forms.py:37 #: contrib/link/forms.py:344 contrib/listgroup/forms.py:71 msgid "Context" -msgstr "" +msgstr "محتوى" #: contrib/alert/forms.py:47 msgid "Dismissible" -msgstr "" +msgstr "يمكن إغلاقه" #: contrib/alert/forms.py:50 msgid "Allows the alert to be closed." -msgstr "" +msgstr "يمكن إغلاق التنبيه" #: contrib/alert/frameworks/bootstrap5.py:47 msgid "Use shadows to optically lift alerts from the background." -msgstr "" +msgstr "استخدام الظلال لرفع التنبيهات بصرياً عن الخلفية" #: contrib/alert/templates/djangocms_frontend/bootstrap5/alert.html:4 msgid "Close" -msgstr "" +msgstr "اغلاق" #: contrib/badge/cms_plugins.py:20 contrib/badge/models.py:14 msgid "Badge" -msgstr "" +msgstr "شارة" #: contrib/badge/forms.py:33 msgid "Badge text" -msgstr "" +msgstr "نص الشارة" #: contrib/badge/forms.py:43 msgid "Pills style" @@ -292,50 +296,50 @@ msgstr "" #: contrib/card/cms_plugins.py:24 contrib/card/models.py:20 msgid "Card layout" -msgstr "" +msgstr "تخطيط البطاقة" #: contrib/card/cms_plugins.py:47 contrib/grid/cms_plugins.py:93 #: contrib/grid/cms_plugins.py:173 msgid "Responsive settings" -msgstr "" +msgstr "إعدادات التوفق" #: contrib/card/cms_plugins.py:85 contrib/card/models.py:35 msgid "Card" -msgstr "" +msgstr "بطاقة" #: contrib/card/cms_plugins.py:145 contrib/card/models.py:57 msgid "Card inner" -msgstr "" +msgstr "البطاقة الداخلية" #: contrib/card/constants.py:4 msgid "Card group" -msgstr "" +msgstr "مجموعة البطاقة" #: contrib/card/constants.py:5 msgid "Grid cards" -msgstr "" +msgstr "شبكة البطاقات" #: contrib/card/constants.py:9 contrib/utilities/forms.py:108 #: frameworks/bootstrap5.py:59 settings.py:47 msgid "Left" -msgstr "" +msgstr "يسار" #: contrib/card/constants.py:10 contrib/utilities/forms.py:109 settings.py:48 msgid "Center" -msgstr "" +msgstr "وسط" #: contrib/card/constants.py:11 contrib/utilities/forms.py:110 #: frameworks/bootstrap5.py:60 settings.py:49 msgid "Right" -msgstr "" +msgstr "يمين" #: contrib/card/constants.py:15 msgid "Body" -msgstr "" +msgstr "جسم" #: contrib/card/constants.py:17 msgid "Footer" -msgstr "" +msgstr "ذيل" #: contrib/card/constants.py:18 msgid "Image overlay" @@ -382,7 +386,8 @@ msgstr "" #: contrib/card/forms.py:152 msgid "" -"If checked cards in one row will automatically extend to the full row height." +"If checked cards in one row will automatically extend to the full row " +"height." msgstr "" #: contrib/card/forms.py:186 @@ -452,8 +457,8 @@ msgstr "" #: contrib/carousel/forms.py:67 msgid "" -"The amount of time to delay between automatically cycling an item. If false, " -"carousel will not automatically cycle." +"The amount of time to delay between automatically cycling an item. If false," +" carousel will not automatically cycle." msgstr "" #: contrib/carousel/forms.py:72 contrib/carousel/models.py:25 @@ -931,8 +936,7 @@ msgid "Width" msgstr "" #: contrib/image/forms.py:135 -msgid "" -"The image width as number in pixels. Example: \"720\" and not \"720px\"." +msgid "The image width as number in pixels. Example: \"720\" and not \"720px\"." msgstr "" #: contrib/image/forms.py:139 @@ -940,8 +944,7 @@ msgid "Height" msgstr "" #: contrib/image/forms.py:143 -msgid "" -"The image height as number in pixels. Example: \"720\" and not \"720px\"." +msgid "The image height as number in pixels. Example: \"720\" and not \"720px\"." msgstr "" #: contrib/image/forms.py:151 @@ -978,7 +981,8 @@ msgstr "" #: contrib/image/forms.py:180 msgid "" -"Crops the image according to the thumbnail settings provided in the template." +"Crops the image according to the thumbnail settings provided in the " +"template." msgstr "" #: contrib/image/forms.py:184 @@ -996,8 +1000,8 @@ msgstr "" #: contrib/image/forms.py:195 msgid "" -"Uses responsive image technique to choose better image to display based upon " -"screen viewport. This configuration only applies to uploaded images " +"Uses responsive image technique to choose better image to display based upon" +" screen viewport. This configuration only applies to uploaded images " "(external pictures will not be affected). " msgstr "" @@ -1042,7 +1046,8 @@ msgid "" msgstr "" #: contrib/image/forms.py:256 -msgid "You need to add either an image, or a URL linking to an external image." +msgid "" +"You need to add either an image, or a URL linking to an external image." msgstr "" #: contrib/image/forms.py:282 @@ -1064,8 +1069,8 @@ msgstr "" msgid "Makes the jumbotron fill the full width of the container or window." msgstr "" -#: contrib/link/apps.py:7 contrib/link/constants.py:5 contrib/link/models.py:11 -#: contrib/link/models.py:114 +#: contrib/link/apps.py:7 contrib/link/constants.py:5 +#: contrib/link/models.py:11 contrib/link/models.py:114 msgid "Link" msgstr "" @@ -1463,8 +1468,8 @@ msgstr "" #: contrib/utilities/forms.py:128 msgid "" -"Fill in unique ID for table of contents. If empty heading will not appear in " -"table of contents." +"Fill in unique ID for table of contents. If empty heading will not appear in" +" table of contents." msgstr "" #: contrib/utilities/forms.py:132 @@ -1473,7 +1478,7 @@ msgstr "" #: contrib/utilities/forms.py:160 msgid "List attributes" -msgstr "" +msgstr "قائمة السمات" #: contrib/utilities/forms.py:162 msgid "" @@ -1487,7 +1492,7 @@ msgstr "" #: contrib/utilities/forms.py:173 msgid "Item attributes" -msgstr "" +msgstr "سمات العنصر" #: contrib/utilities/forms.py:175 msgid "" @@ -1498,14 +1503,19 @@ msgstr "" #: fields.py:94 msgid "Please select at least one device size" msgstr "" +"الرجاء اختيار حجم جهاز واحد على الأقل\n" +" \n" +" \n" +" \n" +" " #: fields.py:102 fields.py:110 msgid "Attributes" -msgstr "" +msgstr "السمات" #: fields.py:131 msgid "Choices" -msgstr "" +msgstr "اختيارات" #: fields.py:142 msgid "" @@ -1515,11 +1525,16 @@ msgstr "" #: fields.py:160 fields.py:170 msgid "Tag type" -msgstr "" +msgstr "نوع Tag" #: fields.py:164 msgid "Select the HTML tag to be used." msgstr "" +"اختر Tag HTML التي ستستخدم.\n" +" \n" +" \n" +" \n" +" " #: frameworks/bootstrap5.py:6 frameworks/bootstrap5.py:132 msgid "Extra small" @@ -1535,35 +1550,35 @@ msgstr "" #: frameworks/bootstrap5.py:19 msgid "Primary" -msgstr "" +msgstr "أساسي" #: frameworks/bootstrap5.py:20 msgid "Secondary" -msgstr "" +msgstr "ثانوي" #: frameworks/bootstrap5.py:21 msgid "Success" -msgstr "" +msgstr "نجاح" #: frameworks/bootstrap5.py:22 msgid "Danger" -msgstr "" +msgstr "خطر" #: frameworks/bootstrap5.py:23 msgid "Warning" -msgstr "" +msgstr "تحذير" #: frameworks/bootstrap5.py:24 msgid "Info" -msgstr "" +msgstr "معلومات" #: frameworks/bootstrap5.py:25 frameworks/bootstrap5.py:178 msgid "Light" -msgstr "" +msgstr "ضوء" #: frameworks/bootstrap5.py:26 frameworks/bootstrap5.py:179 msgid "Dark" -msgstr "" +msgstr "مظلم" #: frameworks/bootstrap5.py:58 frameworks/bootstrap5.py:64 msgid "Both" @@ -1571,11 +1586,11 @@ msgstr "" #: frameworks/bootstrap5.py:65 msgid "Top" -msgstr "" +msgstr "فوق" #: frameworks/bootstrap5.py:66 msgid "Bottom" -msgstr "" +msgstr "تحت" #: frameworks/bootstrap5.py:91 msgid "Screen" @@ -1596,13 +1611,12 @@ msgstr "" #: helpers.py:112 #, python-brace-format -msgid "" -"Read more in the documentation." +msgid "Read more in the documentation." msgstr "" #: models.py:24 msgid "UI item" -msgstr "" +msgstr "عنصر UI" #: settings.py:14 msgid "There are no further settings for this plugin. Please press save." diff --git a/djangocms_frontend/locale/de/LC_MESSAGES/django.mo b/djangocms_frontend/locale/de/LC_MESSAGES/django.mo index cd317c59b971b1d5a81dfee448ac07bcd3053952..21cd3b66ced3aa22c273021a41c2f60e7274cdc3 100644 GIT binary patch delta 8019 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 Sk0vvQW##7;KI`#uh5rLCEOM&= delta 8014 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 xF(f5_()hxLS, YEAR. -# +# # Translators: # Mark Walker , 2023 -# Fabian Braun , 2023 -# +# Fabian Braun , 2024 +# #, fuzzy msgid "" msgstr "" @@ -14,12 +14,12 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-02-28 23:03+0100\n" "PO-Revision-Date: 2023-01-20 15:48+0000\n" -"Last-Translator: Fabian Braun , 2023\n" +"Last-Translator: Fabian Braun , 2024\n" "Language-Team: German (https://app.transifex.com/divio/teams/58664/de/)\n" -"Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: common/attributes.py:9 @@ -57,7 +57,8 @@ msgstr "" "Gibt die Deckkraft der Hintergrundfarbe an (nur wirksam, wenn Kontur nicht " "angewählt ist)." -#: common/bootstrap5/background.py:66 contrib/alert/frameworks/bootstrap5.py:42 +#: common/bootstrap5/background.py:66 +#: contrib/alert/frameworks/bootstrap5.py:42 msgid "Shadow" msgstr "Schatten" @@ -103,7 +104,8 @@ msgstr "Vertikale Größe" #: common/bootstrap5/sizing.py:60 msgid "" -"Sets the vertical size relative to the surrounding container or the viewport." +"Sets the vertical size relative to the surrounding container or the " +"viewport." msgstr "" "Legt die vertikale Größe im Verhältnis zum umgebenden Container oder dem " "Fenster fest." @@ -160,8 +162,8 @@ msgstr "Anzuwenden auf diesen Geräten" #: common/spacing.py:236 msgid "" -"Select only devices on which the padding should be applied. On other devices " -"larger than the first selected device the padding will be set to zero." +"Select only devices on which the padding should be applied. On other devices" +" larger than the first selected device the padding will be set to zero." msgstr "" "Nur Bildschirmgrößen auswählen, auf denen der Abstand angewendet werden " "soll. Auf größeren Bildschirmen als dem ersten ausgewählten, wird der " @@ -177,8 +179,8 @@ msgstr "Titel-Attribut" #: common/title.py:67 msgid "" -"Optional title of the plugin for easier identification. Its title attribute will only be set if the checkbox is selected." +"Optional title of the plugin for easier identification. Its " +"title attribute will only be set if the checkbox is selected." msgstr "" "Optionaler Titel des Plugin für eine einfachere Identifikation. Sei " "title-Attribut wird nur gesetzt, wenn das Auswahlkästchen " @@ -237,8 +239,8 @@ msgstr "In Eltern-Element einfügen" #: contrib/accordion/forms.py:52 msgid "" -"Removes the default background-color, some borders, and some rounded corners " -"to render accordions edge-to-edge with their parent container " +"Removes the default background-color, some borders, and some rounded corners" +" to render accordions edge-to-edge with their parent container " msgstr "" "Entfernt die Hintergrundfarbe, Rahmen und ausgewählte abgerundete Ecken, um " "Akkordions direkt in ihren Eltern-Elementen anzuzeigen." @@ -396,7 +398,8 @@ msgstr "Volle Höhe" #: contrib/card/forms.py:152 msgid "" -"If checked cards in one row will automatically extend to the full row height." +"If checked cards in one row will automatically extend to the full row " +"height." msgstr "Wenn angewählt, erhalten alle Cards in einer Reihe die volle Höhe." #: contrib/card/forms.py:186 @@ -466,11 +469,11 @@ msgstr "Intervall" #: contrib/carousel/forms.py:67 msgid "" -"The amount of time to delay between automatically cycling an item. If false, " -"carousel will not automatically cycle." +"The amount of time to delay between automatically cycling an item. If false," +" carousel will not automatically cycle." msgstr "" -"Die Zeitspanne zwischen dem automatischen Wechseln der Einträge. Wenn false, " -"dann wird nicht automatisch gewechselt." +"Die Zeitspanne zwischen dem automatischen Wechseln der Einträge. Wenn false," +" dann wird nicht automatisch gewechselt." #: contrib/carousel/forms.py:72 contrib/carousel/models.py:25 msgid "Controls" @@ -883,16 +886,12 @@ msgid "Cropping" msgstr "Beschneiden" #: contrib/image/forms.py:25 -#, fuzzy -#| msgid "Icon left" msgid "Float left" -msgstr "Icon links" +msgstr "Fließt links" #: contrib/image/forms.py:26 -#, fuzzy -#| msgid "Icon right" msgid "Float right" -msgstr "Icon rechts" +msgstr "Fließt rechts" #: contrib/image/forms.py:27 msgid "Align center" @@ -917,8 +916,8 @@ msgstr "An oberstes Element delegieren" #: contrib/image/forms.py:57 msgid "Let settings.DJANGOCMS_PICTURE_RESPONSIVE_IMAGES decide" msgstr "" -"Gemäß Einstellungen in settings.DJANGOCMS_PICTURE_RESPONSIVE_IMAGES" +"Gemäß Einstellungen in " +"settings.DJANGOCMS_PICTURE_RESPONSIVE_IMAGES" #: contrib/image/forms.py:58 msgid "Yes" @@ -962,20 +961,16 @@ msgid "Width" msgstr "Breite" #: contrib/image/forms.py:135 -msgid "" -"The image width as number in pixels. Example: \"720\" and not \"720px\"." -msgstr "" -"Bild-Breite in Pixeln (ohne Enheit). Beispiel: \"720\" and not \"720px\"." +msgid "The image width as number in pixels. Example: \"720\" and not \"720px\"." +msgstr "Bild-Breite in Pixeln (ohne Enheit). Beispiel: \"720\" and not \"720px\"." #: contrib/image/forms.py:139 msgid "Height" msgstr "Höhe" #: contrib/image/forms.py:143 -msgid "" -"The image height as number in pixels. Example: \"720\" and not \"720px\"." -msgstr "" -"Bild-Höhe in Pixeln (ohne Enheit). Beispiel: \"720\" and not \"720px\"." +msgid "The image height as number in pixels. Example: \"720\" and not \"720px\"." +msgstr "Bild-Höhe in Pixeln (ohne Enheit). Beispiel: \"720\" and not \"720px\"." #: contrib/image/forms.py:151 msgid "Aligns the image according to the selected option." @@ -1011,8 +1006,10 @@ msgstr "Bild beschneiden" #: contrib/image/forms.py:180 msgid "" -"Crops the image according to the thumbnail settings provided in the template." -msgstr "Schneidet das Bild gemäß der Vorschau-Einstellungen in der Vorlage zu." +"Crops the image according to the thumbnail settings provided in the " +"template." +msgstr "" +"Schneidet das Bild gemäß der Vorschau-Einstellungen in der Vorlage zu." #: contrib/image/forms.py:184 msgid "Upscale image" @@ -1029,8 +1026,8 @@ msgstr "Bild responsive darstellen" #: contrib/image/forms.py:195 msgid "" -"Uses responsive image technique to choose better image to display based upon " -"screen viewport. This configuration only applies to uploaded images " +"Uses responsive image technique to choose better image to display based upon" +" screen viewport. This configuration only applies to uploaded images " "(external pictures will not be affected). " msgstr "" "Nutzt Responsive-Technologie, um die optimale Bildgröße auf Basis der " @@ -1082,7 +1079,8 @@ msgstr "" "mehr als ein Ziel ausgewählt." #: contrib/image/forms.py:256 -msgid "You need to add either an image, or a URL linking to an external image." +msgid "" +"You need to add either an image, or a URL linking to an external image." msgstr "Entweder ein Bild oder eine URL für ein externed Bild angeben." #: contrib/image/forms.py:282 @@ -1107,8 +1105,8 @@ msgid "Makes the jumbotron fill the full width of the container or window." msgstr "" "Erweitert Jas Jumbotron auf die volle Breite des Containers oder Fensters." -#: contrib/link/apps.py:7 contrib/link/constants.py:5 contrib/link/models.py:11 -#: contrib/link/models.py:114 +#: contrib/link/apps.py:7 contrib/link/constants.py:5 +#: contrib/link/models.py:11 contrib/link/models.py:114 msgid "Link" msgstr "Link" @@ -1217,8 +1215,8 @@ msgstr "Bitte geben Sie ein Ziel an." msgid "" "%(anchor_field_verbose_name)s is not allowed together with %(field_name)s" msgstr "" -"%(anchor_field_verbose_name)s kann nicht zusammen mit %(field_name)s gewählt " -"werden." +"%(anchor_field_verbose_name)s kann nicht zusammen mit %(field_name)s gewählt" +" werden." #: contrib/link/forms.py:320 msgid "Display name" @@ -1233,8 +1231,8 @@ msgid "" "Stretches the active link area to the containing block (with position: " "relative)." msgstr "" -"Dehnt die aktive Fläche des Link auf den umgebenden Block aus (sofern dieser " -"mit position: relative markiert ist)." +"Dehnt die aktive Fläche des Link auf den umgebenden Block aus (sofern dieser" +" mit position: relative markiert ist)." #: contrib/link/forms.py:337 contrib/tabs/forms.py:51 msgid "Type" @@ -1347,10 +1345,8 @@ msgid "Brand" msgstr "Marke" #: contrib/navigation/cms_plugins.py:133 -#, fuzzy -#| msgid "Collapse container" msgid "Collapsible container" -msgstr "Collapse-Container" +msgstr "Faltbarer Container" #: contrib/navigation/cms_plugins.py:164 msgid "Navigation link" @@ -1525,8 +1521,8 @@ msgstr "ID" #: contrib/utilities/forms.py:128 msgid "" -"Fill in unique ID for table of contents. If empty heading will not appear in " -"table of contents." +"Fill in unique ID for table of contents. If empty heading will not appear in" +" table of contents." msgstr "" "Eine eindeutige ID nimmt die Überschrift in das Inhaltsverzeichnis auf." @@ -1581,8 +1577,8 @@ msgid "" "Please enter at least one choice. Use the + symbol to add a " "choice." msgstr "" -"Mindestens eine Option angeben. +-Symbol nutzen, um eine Option " -"hinzuzufügen." +"Mindestens eine Option angeben. +-Symbol nutzen, um eine Option" +" hinzuzufügen." #: fields.py:160 fields.py:170 msgid "Tag type" @@ -1667,8 +1663,7 @@ msgstr "XXL" #: helpers.py:112 #, python-brace-format -msgid "" -"Read more in the documentation." +msgid "Read more in the documentation." msgstr "Mehr in der Dokumentation." #: models.py:24 @@ -1684,12 +1679,3 @@ msgstr "" #: settings.py:73 msgid "Offcanvas" msgstr "Off-Canvas" - -#~ msgid "Align left" -#~ msgstr "Links ausrichten" - -#~ msgid "Align right" -#~ msgstr "Rechts ausrichten" - -#~ msgid "Template" -#~ msgstr "Vorlage" diff --git a/djangocms_frontend/locale/es/LC_MESSAGES/django.mo b/djangocms_frontend/locale/es/LC_MESSAGES/django.mo index ae3339509afc67701d3323d72bfc494cc4b997fb..8361e2dd052b9fc9e93e345b661753cfc5c4c908 100644 GIT binary patch delta 7688 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 DvT7k6 delta 7782 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 diff --git a/djangocms_frontend/locale/es/LC_MESSAGES/django.po b/djangocms_frontend/locale/es/LC_MESSAGES/django.po index 71e38eb6..9cf24b2d 100644 --- a/djangocms_frontend/locale/es/LC_MESSAGES/django.po +++ b/djangocms_frontend/locale/es/LC_MESSAGES/django.po @@ -2,10 +2,10 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# # Translators: # Biel Frontera, 2023 -# +# #, fuzzy msgid "" msgstr "" @@ -15,12 +15,11 @@ msgstr "" "PO-Revision-Date: 2023-01-20 15:48+0000\n" "Last-Translator: Biel Frontera, 2023\n" "Language-Team: Spanish (https://app.transifex.com/divio/teams/58664/es/)\n" -"Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? " -"1 : 2;\n" +"Language: es\n" +"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #: common/attributes.py:9 msgid "" @@ -57,7 +56,8 @@ msgstr "" "Opacidad del color de fondo de la tarjeta (solo si no se ha seleccionado " "contorno)" -#: common/bootstrap5/background.py:66 contrib/alert/frameworks/bootstrap5.py:42 +#: common/bootstrap5/background.py:66 +#: contrib/alert/frameworks/bootstrap5.py:42 msgid "Shadow" msgstr "Sombra" @@ -101,7 +101,8 @@ msgstr "Alto" #: common/bootstrap5/sizing.py:60 msgid "" -"Sets the vertical size relative to the surrounding container or the viewport." +"Sets the vertical size relative to the surrounding container or the " +"viewport." msgstr "Configura el alto relativo a su contenedor o el viewport." #: common/spacing.py:84 @@ -155,8 +156,8 @@ msgstr "Aplica el padding en dispositivo" #: common/spacing.py:236 msgid "" -"Select only devices on which the padding should be applied. On other devices " -"larger than the first selected device the padding will be set to zero." +"Select only devices on which the padding should be applied. On other devices" +" larger than the first selected device the padding will be set to zero." msgstr "" "Selecciona aquellos dispositivos en los que el padding se aplicará. En los " "dispositivos superiores a los seleccionados, el padding será cero." @@ -171,8 +172,8 @@ msgstr "Título" #: common/title.py:67 msgid "" -"Optional title of the plugin for easier identification. Its title attribute will only be set if the checkbox is selected." +"Optional title of the plugin for easier identification. Its " +"title attribute will only be set if the checkbox is selected." msgstr "" "Título opcional de la extensión para su mejor identificación. El atributo " "title solo se asignará si se selecciona la casilla." @@ -229,8 +230,8 @@ msgstr "Integra en su contenedor" #: contrib/accordion/forms.py:52 msgid "" -"Removes the default background-color, some borders, and some rounded corners " -"to render accordions edge-to-edge with their parent container " +"Removes the default background-color, some borders, and some rounded corners" +" to render accordions edge-to-edge with their parent container " msgstr "" "Elimina el color de fondo por defecto, algunos bordes y algunas esquinas " "redondeadas para renderizar los acordeones de borde a borde de su contenedor" @@ -390,7 +391,8 @@ msgstr "Altura completa" #: contrib/card/forms.py:152 msgid "" -"If checked cards in one row will automatically extend to the full row height." +"If checked cards in one row will automatically extend to the full row " +"height." msgstr "" "Las tarjetas que se muestren en la misma fila se extenderán hasta la altura " "de la fila." @@ -462,8 +464,8 @@ msgstr "Intervalo" #: contrib/carousel/forms.py:67 msgid "" -"The amount of time to delay between automatically cycling an item. If false, " -"carousel will not automatically cycle." +"The amount of time to delay between automatically cycling an item. If false," +" carousel will not automatically cycle." msgstr "" "Tiempo de espera entre las transiciones automáticas de elementos. Si no se " "selecciona, el carrusel no realizará transiciones automáticas." @@ -534,8 +536,8 @@ msgstr "Relación de aspecto" msgid "" "Determines width and height of the image according to the selected ratio." msgstr "" -"Calcula el ancho y el alto de la imagen en función de la relación de aspecto " -"seleccionada." +"Calcula el ancho y el alto de la imagen en función de la relación de aspecto" +" seleccionada." #: contrib/carousel/forms.py:129 msgid "Transition" @@ -887,16 +889,12 @@ msgid "Cropping" msgstr "Recorte" #: contrib/image/forms.py:25 -#, fuzzy -#| msgid "Icon left" msgid "Float left" -msgstr "Icono izquierda" +msgstr "" #: contrib/image/forms.py:26 -#, fuzzy -#| msgid "Icon right" msgid "Float right" -msgstr "Icono derecha" +msgstr "" #: contrib/image/forms.py:27 msgid "Align center" @@ -963,18 +961,15 @@ msgid "Width" msgstr "Ancho" #: contrib/image/forms.py:135 -msgid "" -"The image width as number in pixels. Example: \"720\" and not \"720px\"." -msgstr "" -"El ancho de la imagen como número en píxeles. Ejemplo: \"720\" y no \"720px\"" +msgid "The image width as number in pixels. Example: \"720\" and not \"720px\"." +msgstr "El ancho de la imagen como número en píxeles. Ejemplo: \"720\" y no \"720px\"" #: contrib/image/forms.py:139 msgid "Height" msgstr "Altura" #: contrib/image/forms.py:143 -msgid "" -"The image height as number in pixels. Example: \"720\" and not \"720px\"." +msgid "The image height as number in pixels. Example: \"720\" and not \"720px\"." msgstr "" "La altura de la imagen como número en píxeles. Ejemplo: \"720\" y no " "\"720px\"" @@ -1014,7 +1009,8 @@ msgstr "Recorte de la imagen" #: contrib/image/forms.py:180 msgid "" -"Crops the image according to the thumbnail settings provided in the template." +"Crops the image according to the thumbnail settings provided in the " +"template." msgstr "" "Recorta la imagen según las opciones de miniatura proporcionadas en la " "plantilla." @@ -1036,8 +1032,8 @@ msgstr "Utiliza imagen responsive" #: contrib/image/forms.py:195 msgid "" -"Uses responsive image technique to choose better image to display based upon " -"screen viewport. This configuration only applies to uploaded images " +"Uses responsive image technique to choose better image to display based upon" +" screen viewport. This configuration only applies to uploaded images " "(external pictures will not be affected). " msgstr "" "Utiliza la técnica de imagen adaptable para seleccionar las dimensiones de " @@ -1089,7 +1085,8 @@ msgstr "" "fichero." #: contrib/image/forms.py:256 -msgid "You need to add either an image, or a URL linking to an external image." +msgid "" +"You need to add either an image, or a URL linking to an external image." msgstr "Debes introducir o una imagen o un enlace a una imagen externa." #: contrib/image/forms.py:282 @@ -1115,8 +1112,8 @@ msgstr "" "Configura el jumbotron para que ocupe todo el ancho del contenedor o de la " "ventana." -#: contrib/link/apps.py:7 contrib/link/constants.py:5 contrib/link/models.py:11 -#: contrib/link/models.py:114 +#: contrib/link/apps.py:7 contrib/link/constants.py:5 +#: contrib/link/models.py:11 contrib/link/models.py:114 msgid "Link" msgstr "Enlace" @@ -1225,7 +1222,8 @@ msgstr "Introduce un enlace." msgid "" "%(anchor_field_verbose_name)s is not allowed together with %(field_name)s" msgstr "" -"%(anchor_field_verbose_name)s no se permite conjuntamente con %(field_name)s." +"%(anchor_field_verbose_name)s no se permite conjuntamente con " +"%(field_name)s." #: contrib/link/forms.py:320 msgid "Display name" @@ -1353,10 +1351,8 @@ msgid "Brand" msgstr "Marca" #: contrib/navigation/cms_plugins.py:133 -#, fuzzy -#| msgid "Collapse container" msgid "Collapsible container" -msgstr "Contenedor para colapsar" +msgstr "" #: contrib/navigation/cms_plugins.py:164 msgid "Navigation link" @@ -1381,7 +1377,8 @@ msgstr "Nivel inicial" #: contrib/navigation/forms.py:84 msgid "Start level of this page tree (0: root, 1: level below root, etc.)" msgstr "" -"Nivel inicial de este árbol de páginas (0: raíz, 1: nivel bajo la raíz, etc.)" +"Nivel inicial de este árbol de páginas (0: raíz, 1: nivel bajo la raíz, " +"etc.)" #: contrib/navigation/forms.py:106 msgid "Enter brand name or add child plugins for brand icon or image" @@ -1532,8 +1529,8 @@ msgstr "Identificador" #: contrib/utilities/forms.py:128 msgid "" -"Fill in unique ID for table of contents. If empty heading will not appear in " -"table of contents." +"Fill in unique ID for table of contents. If empty heading will not appear in" +" table of contents." msgstr "" "Asigna un identificador único para la tabla de contenidos. En caso de no " "rellenar, este encabezado no aparecerá en la tabla de contenidos." @@ -1675,8 +1672,7 @@ msgstr "XX grande" #: helpers.py:112 #, python-brace-format -msgid "" -"Read more in the documentation." +msgid "Read more in the documentation." msgstr "Leer más en la documentación." #: models.py:24 @@ -1690,12 +1686,3 @@ msgstr "No hay más opciones para esta extensión. Haz clic en guardar." #: settings.py:73 msgid "Offcanvas" msgstr "" - -#~ msgid "Align left" -#~ msgstr "Alinear a la izquierda" - -#~ msgid "Align right" -#~ msgstr "Alinear a la derecha" - -#~ msgid "Template" -#~ msgstr "Plantilla" diff --git a/djangocms_frontend/locale/fr/LC_MESSAGES/django.mo b/djangocms_frontend/locale/fr/LC_MESSAGES/django.mo index a1adc73ef6d91a0aec6138184f40f891630f1d82..3e30a9f178cd75e83f19f348ff5a34e757c30550 100644 GIT binary patch delta 7807 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 LX5QN58P)#}FoI^K diff --git a/djangocms_frontend/locale/fr/LC_MESSAGES/django.po b/djangocms_frontend/locale/fr/LC_MESSAGES/django.po index 1fa2aa58..7ed7da7b 100644 --- a/djangocms_frontend/locale/fr/LC_MESSAGES/django.po +++ b/djangocms_frontend/locale/fr/LC_MESSAGES/django.po @@ -2,10 +2,10 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# # Translators: # Adrien Delhorme, 2023 -# +# #, fuzzy msgid "" msgstr "" @@ -15,12 +15,11 @@ msgstr "" "PO-Revision-Date: 2023-01-20 15:48+0000\n" "Last-Translator: Adrien Delhorme, 2023\n" "Language-Team: French (https://app.transifex.com/divio/teams/58664/fr/)\n" -"Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % " -"1000000 == 0 ? 1 : 2;\n" +"Language: fr\n" +"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" #: common/attributes.py:9 msgid "" @@ -54,10 +53,11 @@ msgstr "Opacité du fond" #: common/bootstrap5/background.py:62 msgid "Opacity of card background color (only if no outline selected)" msgstr "" -"Opacité de la couleur de fond de l'encart (uniquement si aucun contour n'est " -"sélectionné)" +"Opacité de la couleur de fond de l'encart (uniquement si aucun contour n'est" +" sélectionné)" -#: common/bootstrap5/background.py:66 contrib/alert/frameworks/bootstrap5.py:42 +#: common/bootstrap5/background.py:66 +#: contrib/alert/frameworks/bootstrap5.py:42 msgid "Shadow" msgstr "Ombre" @@ -104,7 +104,8 @@ msgstr "Hauteur" #: common/bootstrap5/sizing.py:60 msgid "" -"Sets the vertical size relative to the surrounding container or the viewport." +"Sets the vertical size relative to the surrounding container or the " +"viewport." msgstr "" "Définit la hauteur par rapport au conteneur ou à la fenêtre d'affichage." @@ -142,9 +143,9 @@ msgid "" "Select only devices on which the margin should be applied. On other devices " "larger than the first selected device the margin will be set to zero." msgstr "" -"Sélectionnez uniquement les équipements sur lesquels les marges doivent être " -"affichées. Sur les autres équipements plus grands que le premier équipement " -"sélectionné, les marges seront mises à zéro." +"Sélectionnez uniquement les équipements sur lesquels les marges doivent être" +" affichées. Sur les autres équipements plus grands que le premier équipement" +" sélectionné, les marges seront mises à zéro." #: common/spacing.py:221 msgid "Horizontal padding" @@ -160,8 +161,8 @@ msgstr "Afficher les marges internes sur les équipements suivants" #: common/spacing.py:236 msgid "" -"Select only devices on which the padding should be applied. On other devices " -"larger than the first selected device the padding will be set to zero." +"Select only devices on which the padding should be applied. On other devices" +" larger than the first selected device the padding will be set to zero." msgstr "" "Sélectionnez uniquement les équipements sur lesquels les marges internes " "doivent être affichées. Sur les autres équipements plus grands que le " @@ -177,8 +178,8 @@ msgstr "Titre" #: common/title.py:67 msgid "" -"Optional title of the plugin for easier identification. Its title attribute will only be set if the checkbox is selected." +"Optional title of the plugin for easier identification. Its " +"title attribute will only be set if the checkbox is selected." msgstr "" "Titre optionnel du plugin pour l'identifier. L'attribut title " "sera défini uniquement si la case est cochée." @@ -235,8 +236,8 @@ msgstr "Intégrer au parent" #: contrib/accordion/forms.py:52 msgid "" -"Removes the default background-color, some borders, and some rounded corners " -"to render accordions edge-to-edge with their parent container " +"Removes the default background-color, some borders, and some rounded corners" +" to render accordions edge-to-edge with their parent container " msgstr "" "Supprimer la couleur de fond, les bordures et les coins arrondis pour " "afficher l'accordéon sur toute la largeur du conteneur parent" @@ -397,10 +398,11 @@ msgstr "Occuper toute la hauteur" #: contrib/card/forms.py:152 msgid "" -"If checked cards in one row will automatically extend to the full row height." +"If checked cards in one row will automatically extend to the full row " +"height." msgstr "" -"Lorsque cette case est cochée, les encarts sur une ligne occuperont toute la " -"hauteur de la ligne." +"Lorsque cette case est cochée, les encarts sur une ligne occuperont toute la" +" hauteur de la ligne." #: contrib/card/forms.py:186 msgid "Inner type" @@ -469,8 +471,8 @@ msgstr "Intervalle" #: contrib/carousel/forms.py:67 msgid "" -"The amount of time to delay between automatically cycling an item. If false, " -"carousel will not automatically cycle." +"The amount of time to delay between automatically cycling an item. If false," +" carousel will not automatically cycle." msgstr "" "Le délai avant le défilement automatique d'un slide. Indiquez 0 pour ne pas " "que les slides défilent automatiquement." @@ -742,8 +744,8 @@ msgid "" "should fill the full width without margins or padding." msgstr "" "Définit si la grille doit utiliser une largeur fixe, une largeur fluide ou " -"si le conteneur doit remplir toute la largeur sans marges externes ni marges " -"internes." +"si le conteneur doit remplir toute la largeur sans marges externes ni marges" +" internes." #: contrib/grid/forms.py:97 msgid "Create columns" @@ -780,8 +782,8 @@ msgstr "Alignement de la colonne" msgid "" "Column size needs to be empty, \"auto\", or a number between 1 and %(cols)d" msgstr "" -"La taille de la colonne doit être vide, \"auto\", ou un nombre compris entre " -"1 et %(cols)d" +"La taille de la colonne doit être vide, \"auto\", ou un nombre compris entre" +" 1 et %(cols)d" #: contrib/grid/models.py:29 msgid "GridContainer" @@ -893,16 +895,12 @@ msgid "Cropping" msgstr "Recadrage" #: contrib/image/forms.py:25 -#, fuzzy -#| msgid "Icon left" msgid "Float left" -msgstr "Icône à gauche" +msgstr "" #: contrib/image/forms.py:26 -#, fuzzy -#| msgid "Icon right" msgid "Float right" -msgstr "Icône à droite" +msgstr "" #: contrib/image/forms.py:27 msgid "Align center" @@ -962,16 +960,15 @@ msgid "" "them into view. " msgstr "" "À utiliser pour les images situées en dessous de la limite de « scroll ». " -"Chargera les images seulement si le visiteur les fait apparaître en défilant " -"dans la page." +"Chargera les images seulement si le visiteur les fait apparaître en défilant" +" dans la page." #: contrib/image/forms.py:131 msgid "Width" msgstr "Largeur" #: contrib/image/forms.py:135 -msgid "" -"The image width as number in pixels. Example: \"720\" and not \"720px\"." +msgid "The image width as number in pixels. Example: \"720\" and not \"720px\"." msgstr "" "La largeur de l'image en pixels. Un nombre (sans unité), par exemple : " "\"720\"." @@ -981,8 +978,7 @@ msgid "Height" msgstr "Hauteur" #: contrib/image/forms.py:143 -msgid "" -"The image height as number in pixels. Example: \"720\" and not \"720px\"." +msgid "The image height as number in pixels. Example: \"720\" and not \"720px\"." msgstr "" "La hauteur de l'image en pixels. Un nombre (sans unité), par exemple : " "\"720\"." @@ -1023,7 +1019,8 @@ msgstr "Recadrer l'image" #: contrib/image/forms.py:180 msgid "" -"Crops the image according to the thumbnail settings provided in the template." +"Crops the image according to the thumbnail settings provided in the " +"template." msgstr "" "Recadre l'image d'après les paramètres de miniature fournis dans le gabarit " "de la page." @@ -1045,8 +1042,8 @@ msgstr "Image « responsive »" #: contrib/image/forms.py:195 msgid "" -"Uses responsive image technique to choose better image to display based upon " -"screen viewport. This configuration only applies to uploaded images " +"Uses responsive image technique to choose better image to display based upon" +" screen viewport. This configuration only applies to uploaded images " "(external pictures will not be affected). " msgstr "" "Utilise la technique de l'image « responsive » pour choisir la meilleure " @@ -1095,11 +1092,12 @@ msgid "" "You have given more than one external, internal, or file link target. Only " "one option is allowed." msgstr "" -"Seulement un champ parmi : lien externe, lien interne, lien vers un fichier, " -"doit être rempli." +"Seulement un champ parmi : lien externe, lien interne, lien vers un fichier," +" doit être rempli." #: contrib/image/forms.py:256 -msgid "You need to add either an image, or a URL linking to an external image." +msgid "" +"You need to add either an image, or a URL linking to an external image." msgstr "" "Vous devez soit charger une image ou fournir une URL vers une image externe." @@ -1109,8 +1107,8 @@ msgid "" "Invalid cropping settings. You cannot combine \"{field_a}\" with " "\"{field_b}\"." msgstr "" -"Paramètres de recadrage invalides. Vous ne pouvez pas utiliser en même temps " -"\"{field_a}\" et \"{field_b}\"." +"Paramètres de recadrage invalides. Vous ne pouvez pas utiliser en même temps" +" \"{field_a}\" et \"{field_b}\"." #: contrib/jumbotron/cms_plugins.py:31 contrib/jumbotron/models.py:14 msgid "Jumbotron" @@ -1124,8 +1122,8 @@ msgstr "Fluide" msgid "Makes the jumbotron fill the full width of the container or window." msgstr "Le Jumbotron occupe toute la largeur du conteneur ou de la fenêtre." -#: contrib/link/apps.py:7 contrib/link/constants.py:5 contrib/link/models.py:11 -#: contrib/link/models.py:114 +#: contrib/link/apps.py:7 contrib/link/constants.py:5 +#: contrib/link/models.py:11 contrib/link/models.py:114 msgid "Link" msgstr "Lien" @@ -1205,8 +1203,8 @@ msgid "" "Appends the value only after the internal or external link. Do not " "include a preceding \"#\" symbol." msgstr "" -"Ajoute la valeur uniquement après le lien interne ou externe. Ne pas inclure le symbole \"# ;\" qui précède." +"Ajoute la valeur uniquement après le lien interne ou externe. Ne " +"pas inclure le symbole \"# ;\" qui précède." #: contrib/link/forms.py:205 msgid "Email address" @@ -1361,10 +1359,8 @@ msgid "Brand" msgstr "Marque" #: contrib/navigation/cms_plugins.py:133 -#, fuzzy -#| msgid "Collapse container" msgid "Collapsible container" -msgstr "Conteneur de l'élément repliable" +msgstr "" #: contrib/navigation/cms_plugins.py:164 msgid "Navigation link" @@ -1395,8 +1391,8 @@ msgstr "" #: contrib/navigation/forms.py:106 msgid "Enter brand name or add child plugins for brand icon or image" msgstr "" -"Entrez un nom de marque ou ajoutez des plugins enfants pour afficher un logo " -"ou une image" +"Entrez un nom de marque ou ajoutez des plugins enfants pour afficher un logo" +" ou une image" #: contrib/navigation/models.py:24 msgid "Navigation container" @@ -1445,8 +1441,8 @@ msgstr "Index" #: contrib/tabs/forms.py:67 msgid "Index of element to open on page load starting at 1." msgstr "" -"Index de l'élément à ouvrir au chargement de la page (en numérotant à partir " -"de 1)." +"Index de l'élément à ouvrir au chargement de la page (en numérotant à partir" +" de 1)." #: contrib/tabs/forms.py:70 msgid "Animation effect" @@ -1510,8 +1506,8 @@ msgid "" "Padding does not have an auto spacing. Either switch to a defined size or " "change the spacing property." msgstr "" -"Les marges internes n'ont pas d'espacement automatique. Il faut soit définir " -"une taille, soit changer la propriété de l'espacement." +"Les marges internes n'ont pas d'espacement automatique. Il faut soit définir" +" une taille, soit changer la propriété de l'espacement." #: contrib/utilities/forms.py:101 settings.py:38 msgid "Heading 1" @@ -1543,8 +1539,8 @@ msgstr "ID" #: contrib/utilities/forms.py:128 msgid "" -"Fill in unique ID for table of contents. If empty heading will not appear in " -"table of contents." +"Fill in unique ID for table of contents. If empty heading will not appear in" +" table of contents." msgstr "" "Remplir un identifiant unique qui sera utile pour la table des matières. Si " "le titre est vide, il n'apparaîtra pas dans la table des matières." @@ -1568,8 +1564,8 @@ msgstr "" msgid "" "Attributes apply to the link for each entry in the table of contents." msgstr "" -"Les attributs s'appliquent au lien pour chaque entrée de la table des " -"matières." +"Les attributs s'appliquent au lien pour chaque entrée de la table des" +" matières." #: contrib/utilities/forms.py:173 msgid "Item attributes" @@ -1580,8 +1576,8 @@ msgid "" "Attributes apply to the list items for each entry in the table of " "contents." msgstr "" -"Les attributs s'appliquent aux élément de liste pour chaque entrée de " -"la table des matières." +"Les attributs s'appliquent aux élément de liste pour chaque entrée de" +" la table des matières." #: fields.py:94 msgid "Please select at least one device size" @@ -1686,8 +1682,7 @@ msgstr "Très très grand" #: helpers.py:112 #, python-brace-format -msgid "" -"Read more in the documentation." +msgid "Read more in the documentation." msgstr "" "Lire la documentation pour en " "savoir plus." @@ -1705,9 +1700,3 @@ msgstr "" #: settings.py:73 msgid "Offcanvas" msgstr "Déroulante" - -#~ msgid "Align left" -#~ msgstr "Aligner à gauche" - -#~ msgid "Align right" -#~ msgstr "Aligner à droite" diff --git a/djangocms_frontend/locale/nl/LC_MESSAGES/django.mo b/djangocms_frontend/locale/nl/LC_MESSAGES/django.mo index d927bc7a47e2a4937dedbb59031da21136bf6e3c..52118881fd66f6dffceb17ec28ebc5092073fdb8 100644 GIT binary patch delta 5797 zcmZA53!F}M9>?)BW5zHFLoQ`gav5oe5sOkr$YtHqg-SO>(NY^~V;?EYRPFh7bdhe-em>9n&2FzfufFsC|NrMX|Jym|nbGEP2gYW0*2R<;^v1O_EV{lcXVDiA6XAtKxh-1|P)A_*|TS5%a0PjYr^4tc82A z1|CNHsa`K@COMu$bs9?1G0V^a&c;%_2pwQnoWBd{BY6b*FL{<94)i7#;)mD-KgB$( zT|aHFj}F{8>g}*rl1Y*-*+P;GLT7$Od|*t}Cq{iT+TjdjlaiTHzYCq<0`&UDQD1`9 zs4v9=T!mi$0y@!+o@e}I8-=6rU3BFK&;bskJ5z9UIzU~tqhs+%Y>KX^Ejn;_bbvnS z00Yo|E<|s^aCCR@fohN1_9c zMQ_RV=ylW33C)S~i?A>CCC9M;&g38s&in^-fZPV$CoDu~-U@wq%Fxdb32JF9uH)(K1AD|OCfDZI6x&yu%wiluksezt94xM1L zsCPss)CC=|7ux?|bO(l`6B~;zbaEyN)54kPfOEq|;iKWQa1A<<4QPjNp%dDTK1=)1 z1?8}OCs-T(d^60&_UM8#9Vs~A>F5l5MtubGF_p^N$=bfHVp2|t~c`@f!o56@O~fSu@tyU>a3kNQD$pq%5Xg^o^yP9zFJs>PM}`Yi_w*} z#Fp3*-RhC(M1F(z`w%*Ta?IGUA{w5>rqnlJH~a)WU)m@gxD&cFUC;^lL05c9oF9&U z{wl15*J5RyfPT+RMi+7i@?s@-H{$;Lv@WNi6K+CRkaq&F7S_c6*c$ud6tu%v(3QP` z?$|zbB431GNBbePzg)gd{9JYP`lHbH28}c6iDDXj23n#k=!BK9E4o!Z(3$r~U#lVL zfTQF5IJDy%(0-<1cbtjd`)%m;htTUQH%Z5>pP}FvMMJEFEzvD*gU;|Y%)_4O#QLI7 z{khl+hoRS%qwo0>=#H*K``M1&a2Gm(6S=>Bt}XiPWO`8W-kgVaJQBTdJUZYM%*Pqw z9q5kCK?h!lPV|0sfO5>km2rM`_--jdo*SopfLrvrUbp0 zr=nYZ78YVZbSH+O16+p=JPE7fO=v&2p<6u%-QtJQiLZ?M8uS@^1$*O;7VN(tEIuji zr~^8YuINAm(Wi9?w!$&dz5pHg0rXatqXVzO?6ZJ{)OX`~_!(vwRFY1-AA0?u687JF zIFtqlnu>Nf7oEUE=*r5`nXd@fp%Z-_kHGhl@0#ROw4b7uX?qi_M!ikg8J%b^wBHLe z6r9;`w4>4JYjr(3kx6m>cJ#v8n4K7ACx$+3E6|;M30?U+=mbAPKlc@S-Qln@+vyHu zsz;%IctThbwnrz@1&_o5=!7puU#}79iYK8HnH4^Oxztyp&%iV2PCSn;bTiUlCfQEG z8Sgu)z0! zQ8YY)ojFk+^}Xo8pQ9HZ#2T2}I=vOO&@FF*o^KcRGIT*_NBdB8qF16jI02o&Em-LL ze=7yIbS`>N?!oH#FuJ8rMST-`;oInnccRbA9`p-rFE+Zc*U50`y>x{0b3>~O9y2a<99bF#hM@D^IoF9+B;QY<# zEqo2V{u^{cx$V;l*2Y@Yk4DEUK|hyiO~Dy
  • )B&a4l5!658~SD+U@j{cfmj{L=* zY()p!kKNF})qPgF<54&OJwF1Aa6&i(v+w_W3J$mgvjaqZIl3dO(Jzwq=ma;SJF_L~ z@1WPc7w!r_4)=whA%A9M5Bu>|{=M)2MHJSMSIAJZgj5{2M_~b8NS2Z7h!gM_LVS=s z+(?dcHI=^N5cyIi#u~VKT1d+!rPZU3hDUWDEp9je4mp2>HTa)#*#mhaby*_ zhMYmJC40#8)k-S6xNsc2u$uP2sbRdff-#Pz1 zxV71b^+P-}S|7rE`mQ)eMqz7sSyuM{cNE?ycgBgo;2UIa)P4W^kpkkAJ&$;NM0|4| zCuO8L`RVZzl?LRCXzY$Rl7nO_`JDLtWxqNtf9(&BrDQ_3^uHfXD7GVw$V`%xlfG_M zC~qVlx1=PehA-fs$!OwV%pUh;fAU8yt|$Kghva7R4^naXh0>BtCw0l|yuCEG|tvYo6TF7z`}aokN|t<8fdTt%9ad&s{?57LEPPIi%V$OXjX z1oAC8kNlcEK%OL@5RWU#iR4u>o4iOoCXzpp-B#k5?6l@nxt{z;UXBy(!$~-b)U(c( zpAVfabMzv$Nq;hcj3F(^uSi?s@d%lgE%DE9tVHf0Uq#z2w`DL{7Y%Ye`MZTU-oo69 zO1K>7kUS=}5D!QDS)trO`jQ7p0iXL6SCS%fHQ7QkJNQwBlc%7^d*orVpLmQ&Nrs2t zg;Vf0Qcm*8H{@^RWKxO#Job^3vLzNkTVu+PkwxSK@$FpU44n@$6}J*Df1c NuWHe<>CM;I_z!HW7{dSn delta 5882 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 Xx~29VIP#f>+2xBTZhE8I?5O_&WL7kU diff --git a/djangocms_frontend/locale/nl/LC_MESSAGES/django.po b/djangocms_frontend/locale/nl/LC_MESSAGES/django.po index 1536d99f..6efa1a2b 100644 --- a/djangocms_frontend/locale/nl/LC_MESSAGES/django.po +++ b/djangocms_frontend/locale/nl/LC_MESSAGES/django.po @@ -2,11 +2,11 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# # Translators: # Fabian Braun , 2023 # Stefan van den Eertwegh , 2023 -# +# #, fuzzy msgid "" msgstr "" @@ -16,10 +16,10 @@ msgstr "" "PO-Revision-Date: 2023-01-20 15:48+0000\n" "Last-Translator: Stefan van den Eertwegh , 2023\n" "Language-Team: Dutch (https://app.transifex.com/divio/teams/58664/nl/)\n" -"Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: nl\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: common/attributes.py:9 @@ -53,7 +53,8 @@ msgstr "Achtergrond opacity" msgid "Opacity of card background color (only if no outline selected)" msgstr "" -#: common/bootstrap5/background.py:66 contrib/alert/frameworks/bootstrap5.py:42 +#: common/bootstrap5/background.py:66 +#: contrib/alert/frameworks/bootstrap5.py:42 msgid "Shadow" msgstr "Schaduw" @@ -71,7 +72,8 @@ msgstr "Toon element op apparaat" #: common/bootstrap5/responsive.py:60 msgid "Select only devices on which this element should be shown." -msgstr "Selecteer alleen apparaten waarop dit element moet worden weergegeven." +msgstr "" +"Selecteer alleen apparaten waarop dit element moet worden weergegeven." #: common/bootstrap5/sizing.py:8 common/spacing.py:11 #: contrib/utilities/forms.py:51 frameworks/bootstrap5.py:90 @@ -97,9 +99,11 @@ msgstr "Verticale grootte" #: common/bootstrap5/sizing.py:60 msgid "" -"Sets the vertical size relative to the surrounding container or the viewport." +"Sets the vertical size relative to the surrounding container or the " +"viewport." msgstr "" -"Sets the vertical size relative to the surrounding container or the viewport." +"Sets the vertical size relative to the surrounding container or the " +"viewport." #: common/spacing.py:84 msgid "Please choose a side to which the spacing should be applied." @@ -150,8 +154,8 @@ msgstr "Pas padding op apparaat toe" #: common/spacing.py:236 msgid "" -"Select only devices on which the padding should be applied. On other devices " -"larger than the first selected device the padding will be set to zero." +"Select only devices on which the padding should be applied. On other devices" +" larger than the first selected device the padding will be set to zero." msgstr "" #: common/title.py:40 @@ -164,8 +168,8 @@ msgstr "Titel" #: common/title.py:67 msgid "" -"Optional title of the plugin for easier identification. Its title attribute will only be set if the checkbox is selected." +"Optional title of the plugin for easier identification. Its " +"title attribute will only be set if the checkbox is selected." msgstr "" #: contrib/accordion/cms_plugins.py:21 contrib/accordion/models.py:14 @@ -220,8 +224,8 @@ msgstr "" #: contrib/accordion/forms.py:52 msgid "" -"Removes the default background-color, some borders, and some rounded corners " -"to render accordions edge-to-edge with their parent container " +"Removes the default background-color, some borders, and some rounded corners" +" to render accordions edge-to-edge with their parent container " msgstr "" #: contrib/accordion/forms.py:78 contrib/card/constants.py:16 @@ -377,7 +381,8 @@ msgstr "Volledige hoogte" #: contrib/card/forms.py:152 msgid "" -"If checked cards in one row will automatically extend to the full row height." +"If checked cards in one row will automatically extend to the full row " +"height." msgstr "" #: contrib/card/forms.py:186 @@ -447,8 +452,8 @@ msgstr "Interval" #: contrib/carousel/forms.py:67 msgid "" -"The amount of time to delay between automatically cycling an item. If false, " -"carousel will not automatically cycle." +"The amount of time to delay between automatically cycling an item. If false," +" carousel will not automatically cycle." msgstr "" #: contrib/carousel/forms.py:72 contrib/carousel/models.py:25 @@ -855,16 +860,12 @@ msgid "Cropping" msgstr "Bijsnijden" #: contrib/image/forms.py:25 -#, fuzzy -#| msgid "Icon left" msgid "Float left" -msgstr "Icoon links" +msgstr "" #: contrib/image/forms.py:26 -#, fuzzy -#| msgid "Icon right" msgid "Float right" -msgstr "Icoon rechts" +msgstr "" #: contrib/image/forms.py:27 msgid "Align center" @@ -927,8 +928,7 @@ msgid "Width" msgstr "Breedte" #: contrib/image/forms.py:135 -msgid "" -"The image width as number in pixels. Example: \"720\" and not \"720px\"." +msgid "The image width as number in pixels. Example: \"720\" and not \"720px\"." msgstr "" #: contrib/image/forms.py:139 @@ -936,8 +936,7 @@ msgid "Height" msgstr "Hoogte" #: contrib/image/forms.py:143 -msgid "" -"The image height as number in pixels. Example: \"720\" and not \"720px\"." +msgid "The image height as number in pixels. Example: \"720\" and not \"720px\"." msgstr "" "De afbeelding-hoogte als nummer in pixels. Voorbeeld: \"720\" en niet " "\"720px\"." @@ -976,10 +975,11 @@ msgstr "Afbeelding bijsnijden" #: contrib/image/forms.py:180 msgid "" -"Crops the image according to the thumbnail settings provided in the template." -msgstr "" -"Snij de afbeelding bij volgens de thumbnail instellingen mits gebruikt in de " +"Crops the image according to the thumbnail settings provided in the " "template." +msgstr "" +"Snij de afbeelding bij volgens de thumbnail instellingen mits gebruikt in de" +" template." #: contrib/image/forms.py:184 msgid "Upscale image" @@ -997,8 +997,8 @@ msgstr "Gebruik afbeelding responsive" #: contrib/image/forms.py:195 msgid "" -"Uses responsive image technique to choose better image to display based upon " -"screen viewport. This configuration only applies to uploaded images " +"Uses responsive image technique to choose better image to display based upon" +" screen viewport. This configuration only applies to uploaded images " "(external pictures will not be affected). " msgstr "" @@ -1043,7 +1043,8 @@ msgid "" msgstr "" #: contrib/image/forms.py:256 -msgid "You need to add either an image, or a URL linking to an external image." +msgid "" +"You need to add either an image, or a URL linking to an external image." msgstr "" #: contrib/image/forms.py:282 @@ -1065,8 +1066,8 @@ msgstr "" msgid "Makes the jumbotron fill the full width of the container or window." msgstr "" -#: contrib/link/apps.py:7 contrib/link/constants.py:5 contrib/link/models.py:11 -#: contrib/link/models.py:114 +#: contrib/link/apps.py:7 contrib/link/constants.py:5 +#: contrib/link/models.py:11 contrib/link/models.py:114 msgid "Link" msgstr "Link" @@ -1294,10 +1295,8 @@ msgid "Brand" msgstr "Brand" #: contrib/navigation/cms_plugins.py:133 -#, fuzzy -#| msgid "Collapse container" msgid "Collapsible container" -msgstr "Collaps container" +msgstr "" #: contrib/navigation/cms_plugins.py:164 msgid "Navigation link" @@ -1466,8 +1465,8 @@ msgstr "ID" #: contrib/utilities/forms.py:128 msgid "" -"Fill in unique ID for table of contents. If empty heading will not appear in " -"table of contents." +"Fill in unique ID for table of contents. If empty heading will not appear in" +" table of contents." msgstr "" #: contrib/utilities/forms.py:132 @@ -1599,8 +1598,7 @@ msgstr "XX groot" #: helpers.py:112 #, python-brace-format -msgid "" -"Read more in the documentation." +msgid "Read more in the documentation." msgstr "Lees meer in de documentatie." #: models.py:24 @@ -1614,9 +1612,3 @@ msgstr "" #: settings.py:73 msgid "Offcanvas" msgstr "" - -#~ msgid "Align left" -#~ msgstr "Links uitlijnen" - -#~ msgid "Align right" -#~ msgstr "Rechts uitlijnen" diff --git a/djangocms_frontend/locale/sq/LC_MESSAGES/django.mo b/djangocms_frontend/locale/sq/LC_MESSAGES/django.mo index 8e9889c6b9a7b31a64f3d926622691864964e033..9f33eca49100ff9b17a4a431a245e06a24d8c619 100644 GIT binary patch delta 6373 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 eI, YEAR. -# +# # Translators: # Mark Walker , 2023 # Besnik Bleta , 2023 -# +# #, fuzzy msgid "" msgstr "" @@ -16,10 +16,10 @@ msgstr "" "PO-Revision-Date: 2023-01-20 15:48+0000\n" "Last-Translator: Besnik Bleta , 2023\n" "Language-Team: Albanian (https://app.transifex.com/divio/teams/58664/sq/)\n" -"Language: sq\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: sq\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: common/attributes.py:9 @@ -57,7 +57,8 @@ msgstr "" "Patejdukshmëri e ngjyrës së sfondit të kartës (nëse s’është përzgjedhur " "përvijim)" -#: common/bootstrap5/background.py:66 contrib/alert/frameworks/bootstrap5.py:42 +#: common/bootstrap5/background.py:66 +#: contrib/alert/frameworks/bootstrap5.py:42 msgid "Shadow" msgstr "Hije" @@ -101,7 +102,8 @@ msgstr "Madhësi vertikale" #: common/bootstrap5/sizing.py:60 msgid "" -"Sets the vertical size relative to the surrounding container or the viewport." +"Sets the vertical size relative to the surrounding container or the " +"viewport." msgstr "" "Cakton madhësinë vertikale, relative ndaj kontejnerit ose pjesës së ekranit " "që e rrethon." @@ -140,8 +142,8 @@ msgid "" "Select only devices on which the margin should be applied. On other devices " "larger than the first selected device the margin will be set to zero." msgstr "" -"Përgjidhni një anë mbi të cilën duhet aplikuar hapësira. Select only devices " -"on which the margin should be applied. On other devices larger than the " +"Përgjidhni një anë mbi të cilën duhet aplikuar hapësira. Select only devices" +" on which the margin should be applied. On other devices larger than the " "first selected device the margin will be set to zero." #: common/spacing.py:221 @@ -158,8 +160,8 @@ msgstr "Apliko mbushje te pajisja" #: common/spacing.py:236 msgid "" -"Select only devices on which the padding should be applied. On other devices " -"larger than the first selected device the padding will be set to zero." +"Select only devices on which the padding should be applied. On other devices" +" larger than the first selected device the padding will be set to zero." msgstr "" "Përzgjidhni vetëm pajisjet mbi të cilat duhet aplikuar mbushja. Në pajisje " "të tjera, më të mëdha se pajisja e parë e përzgjedhur, mbushja do të " @@ -175,8 +177,8 @@ msgstr "Titull" #: common/title.py:67 msgid "" -"Optional title of the plugin for easier identification. Its title attribute will only be set if the checkbox is selected." +"Optional title of the plugin for easier identification. Its " +"title attribute will only be set if the checkbox is selected." msgstr "" "Titull i shtojcës, në daçi, për identifikim më të kollajtë. Atributi " "title për të do të ujdiset vetëm nëse përzgjidhet kutiza." @@ -233,8 +235,8 @@ msgstr "Integroje te mëma" #: contrib/accordion/forms.py:52 msgid "" -"Removes the default background-color, some borders, and some rounded corners " -"to render accordions edge-to-edge with their parent container " +"Removes the default background-color, some borders, and some rounded corners" +" to render accordions edge-to-edge with their parent container " msgstr "" "Bën heqjen e ngjyrës parazgjedhje për sfondin, disa anë dhe disa cepa të " "rrumbullakosur, për t’i shfaqur fizarmonikat nga skaji në skaj, me " @@ -393,7 +395,8 @@ msgstr "Lartësi e plotë" #: contrib/card/forms.py:152 msgid "" -"If checked cards in one row will automatically extend to the full row height." +"If checked cards in one row will automatically extend to the full row " +"height." msgstr "" "Në iu vëntë shenjë, kartat e një rreshti do të zgjerohen vetvetiu sa " "lartësia e plotë e rreshtit." @@ -465,8 +468,8 @@ msgstr "Interval" #: contrib/carousel/forms.py:67 msgid "" -"The amount of time to delay between automatically cycling an item. If false, " -"carousel will not automatically cycle." +"The amount of time to delay between automatically cycling an item. If false," +" carousel will not automatically cycle." msgstr "" "Sasia e kohës në sekonda për vonim zërash te kalimi automatikisht në ta. Në " "u vëntë 0, rrotullamja s’do të kalojë automatikisht nëpër ta." @@ -520,7 +523,8 @@ msgid "" "\"carousel\", autoplays the carousel on load." msgstr "" "Vetëluhet rrotullamja, pasi përdoruesi vë në punë dorazi kuadrin e parë. Në " -"u vëntë “carousel”, vetëluhet automatikisht rrotullamja, kur ngarkohet faqja." +"u vëntë “carousel”, vetëluhet automatikisht rrotullamja, kur ngarkohet " +"faqja." #: contrib/carousel/forms.py:111 contrib/carousel/models.py:30 msgid "Wrap" @@ -539,8 +543,8 @@ msgstr "Përpjesëtim" msgid "" "Determines width and height of the image according to the selected ratio." msgstr "" -"Përcakton gjerësinë dhe lartësinë e fizarmonikës së figurave sa përpjesëtimi " -"i përzgjedhur." +"Përcakton gjerësinë dhe lartësinë e fizarmonikës së figurave sa përpjesëtimi" +" i përzgjedhur." #: contrib/carousel/forms.py:129 msgid "Transition" @@ -887,16 +891,12 @@ msgid "Cropping" msgstr "Qethje" #: contrib/image/forms.py:25 -#, fuzzy -#| msgid "Icon left" msgid "Float left" -msgstr "Ikonë majtas" +msgstr "" #: contrib/image/forms.py:26 -#, fuzzy -#| msgid "Icon right" msgid "Float right" -msgstr "Ikonë djathas" +msgstr "" #: contrib/image/forms.py:27 msgid "Align center" @@ -943,8 +943,8 @@ msgid "" "If provided, overrides the embedded image. Certain options such as cropping " "are not applicable to external images." msgstr "" -"Nëse jepet, anashkalon figurën e trupëzuar. Disa mundësi, bie fjala, qethja, " -"s’janë të zbatueshme mbi figura të jashtme." +"Nëse jepet, anashkalon figurën e trupëzuar. Disa mundësi, bie fjala, qethja," +" s’janë të zbatueshme mbi figura të jashtme." #: contrib/image/forms.py:123 msgid "Load lazily" @@ -963,18 +963,18 @@ msgid "Width" msgstr "Gjerësi" #: contrib/image/forms.py:135 -msgid "" -"The image width as number in pixels. Example: \"720\" and not \"720px\"." -msgstr "Gjerësia e figurës si numër pikselash. Shembull: “720” dhe jo “720px”." +msgid "The image width as number in pixels. Example: \"720\" and not \"720px\"." +msgstr "" +"Gjerësia e figurës si numër pikselash. Shembull: “720” dhe jo “720px”." #: contrib/image/forms.py:139 msgid "Height" msgstr "Lartësi" #: contrib/image/forms.py:143 -msgid "" -"The image height as number in pixels. Example: \"720\" and not \"720px\"." -msgstr "Lartësia e figurës si numër pikselash. Shembull: “720” dhe jo “720px”." +msgid "The image height as number in pixels. Example: \"720\" and not \"720px\"." +msgstr "" +"Lartësia e figurës si numër pikselash. Shembull: “720” dhe jo “720px”." #: contrib/image/forms.py:151 msgid "Aligns the image according to the selected option." @@ -1011,7 +1011,8 @@ msgstr "Qetheni figurën" #: contrib/image/forms.py:180 msgid "" -"Crops the image according to the thumbnail settings provided in the template." +"Crops the image according to the thumbnail settings provided in the " +"template." msgstr "E qeth figurën sipas rregullimeve miniaturash të dhëna te gjedhja." #: contrib/image/forms.py:184 @@ -1029,8 +1030,8 @@ msgstr "Përdor figurë reaguese" #: contrib/image/forms.py:195 msgid "" -"Uses responsive image technique to choose better image to display based upon " -"screen viewport. This configuration only applies to uploaded images " +"Uses responsive image technique to choose better image to display based upon" +" screen viewport. This configuration only applies to uploaded images " "(external pictures will not be affected). " msgstr "" "Përdor teknikën e figurave reaguese për të zgjedhur figurë më të mirë për " @@ -1078,11 +1079,12 @@ msgid "" "You have given more than one external, internal, or file link target. Only " "one option is allowed." msgstr "" -"Keni dhënë më shumë se një objektiv të jashtëm, të brendshëm, ose lidhje për " -"te kartelë. Lejohet vetëm një mundësi." +"Keni dhënë më shumë se një objektiv të jashtëm, të brendshëm, ose lidhje për" +" te kartelë. Lejohet vetëm një mundësi." #: contrib/image/forms.py:256 -msgid "You need to add either an image, or a URL linking to an external image." +msgid "" +"You need to add either an image, or a URL linking to an external image." msgstr "" "Lypset të shtoni ose një figurë, ose një URL që shpie te një figurë e " "jashtme." @@ -1109,8 +1111,8 @@ msgid "Makes the jumbotron fill the full width of the container or window." msgstr "" "E bën jumbotron-in të mbushë krejt gjerësinë e kontejnerit ose dritares." -#: contrib/link/apps.py:7 contrib/link/constants.py:5 contrib/link/models.py:11 -#: contrib/link/models.py:114 +#: contrib/link/apps.py:7 contrib/link/constants.py:5 +#: contrib/link/models.py:11 contrib/link/models.py:114 msgid "Link" msgstr "Lidhje" @@ -1342,10 +1344,8 @@ msgid "Brand" msgstr "Markë" #: contrib/navigation/cms_plugins.py:133 -#, fuzzy -#| msgid "Collapse container" msgid "Collapsible container" -msgstr "Tkurre kontejnerin" +msgstr "" #: contrib/navigation/cms_plugins.py:164 msgid "Navigation link" @@ -1374,7 +1374,8 @@ msgstr "" #: contrib/navigation/forms.py:106 msgid "Enter brand name or add child plugins for brand icon or image" -msgstr "Jepni emër marke, ose shtoni shtojca pjellë për ikonë ose figurë marke" +msgstr "" +"Jepni emër marke, ose shtoni shtojca pjellë për ikonë ose figurë marke" #: contrib/navigation/models.py:24 msgid "Navigation container" @@ -1422,7 +1423,8 @@ msgstr "Tregues" #: contrib/tabs/forms.py:67 msgid "Index of element to open on page load starting at 1." -msgstr "Tregues elementësh për t’u hapur në ngarkim faqeje, duke filluar me 1." +msgstr "" +"Tregues elementësh për t’u hapur në ngarkim faqeje, duke filluar me 1." #: contrib/tabs/forms.py:70 msgid "Animation effect" @@ -1519,8 +1521,8 @@ msgstr "ID" #: contrib/utilities/forms.py:128 msgid "" -"Fill in unique ID for table of contents. If empty heading will not appear in " -"table of contents." +"Fill in unique ID for table of contents. If empty heading will not appear in" +" table of contents." msgstr "" "Plotësoni ID unike për tryezë lënde. Në u lëntë e zbrazët, kryet s’do të " "duken te tryezë e lëndës." @@ -1551,7 +1553,8 @@ msgstr "Atribute objekti" msgid "" "Attributes apply to the list items for each entry in the table of " "contents." -msgstr "Atribute aplikohen te zëra liste për çdo zë te tryeza e lëndës." +msgstr "" +"Atribute aplikohen te zëra liste për çdo zë te tryeza e lëndës." #: fields.py:94 msgid "Please select at least one device size" @@ -1570,8 +1573,8 @@ msgid "" "Please enter at least one choice. Use the + symbol to add a " "choice." msgstr "" -"Ju lutemi, jepni të paktën një zgjedhje. Që të shtoni një zgjedhje, përdorni " -"simbolin +." +"Ju lutemi, jepni të paktën një zgjedhje. Që të shtoni një zgjedhje, përdorni" +" simbolin +." #: fields.py:160 fields.py:170 msgid "Tag type" @@ -1656,10 +1659,8 @@ msgstr "" #: helpers.py:112 #, python-brace-format -msgid "" -"Read more in the documentation." -msgstr "" -"Lexoni më tepër, te dokumentimi." +msgid "Read more in the documentation." +msgstr "Lexoni më tepër, te dokumentimi." #: models.py:24 msgid "UI item" @@ -1667,17 +1668,9 @@ msgstr "Element UI" #: settings.py:14 msgid "There are no further settings for this plugin. Please press save." -msgstr "S’ka rregullime të tjera për këtë shtojcë. Ju lutemi, shtypni “Ruaje”." +msgstr "" +"S’ka rregullime të tjera për këtë shtojcë. Ju lutemi, shtypni “Ruaje”." #: settings.py:73 msgid "Offcanvas" msgstr "" - -#~ msgid "Align left" -#~ msgstr "Vëre majtas" - -#~ msgid "Align right" -#~ msgstr "Vëre djathtas" - -#~ msgid "Template" -#~ msgstr "Gjedhe" From 47cb3d0aa517cc3038371db0d607f84e0c4b4c14 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Thu, 21 Mar 2024 13:19:38 +0100 Subject: [PATCH 15/66] Update test environment --- CHANGELOG.rst | 1 + djangocms_frontend/contrib/link/forms.py | 74 ++++++++++++------- .../djangocms_frontend/admin/link.html | 8 ++ .../static/djangocms_frontend/css/select2.css | 8 -- .../djangocms_frontend/css/select2.css.map | 1 - private/sass/select2.scss | 22 ------ setup.py | 7 +- tests/requirements/dj41_cms41.txt | 8 +- tests/requirements/dj42_cms41.txt | 4 +- tests/requirements/dj50_cms41.txt | 4 +- 10 files changed, 67 insertions(+), 70 deletions(-) delete mode 100644 djangocms_frontend/static/djangocms_frontend/css/select2.css delete mode 100644 djangocms_frontend/static/djangocms_frontend/css/select2.css.map delete mode 100644 private/sass/select2.scss diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 691f720c..5cdc42de 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -7,6 +7,7 @@ Changelog * feat: Add abstract base model `AbstractFrontendUIItem` by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/195 * feat: Add icons for selected text-enabled plugins by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/195 +* fix: Correct site used when using Link plugin within a static placholder in django CMS 3.x by @fsbraun * fix: removed Nav Container plugin and fixed Navigation Link plugin by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/192 * fix: Remove `{% spaceless %}` around `{% block "content" %}` by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/188 * fix: Improved fieldset layout for Django 4.2+ by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/185 diff --git a/djangocms_frontend/contrib/link/forms.py b/djangocms_frontend/contrib/link/forms.py index 7a464cec..edafb1f4 100644 --- a/djangocms_frontend/contrib/link/forms.py +++ b/djangocms_frontend/contrib/link/forms.py @@ -1,15 +1,17 @@ +import json +from types import SimpleNamespace + from django import apps, forms from django.conf import settings as django_settings -from django.contrib.admin.widgets import SELECT2_TRANSLATIONS +from django.contrib.admin.widgets import AutocompleteMixin from django.contrib.contenttypes.models import ContentType from django.contrib.sites.models import Site from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.db import models from django.db.models.fields.related import ManyToOneRel +from django.urls import reverse from django.utils.encoding import force_str -from django.utils.translation import get_language from django.utils.translation import gettext as _ -from django_select2.forms import HeavySelect2Widget, Select2Widget # from djangocms_link.validators import IntranetURLValidator from entangled.forms import EntangledModelForm @@ -56,41 +58,59 @@ def __init__(self, *args, **kwargs): ) -class Select2jqWidget(HeavySelect2Widget if MINIMUM_INPUT_LENGTH else Select2Widget): - """Make jQuery available to Select2 widget""" - +class Select2jqWidget(AutocompleteMixin, forms.Select): empty_label = _("Select a destination") - @property - def media(self): - extra = ".min" - i18n_name = SELECT2_TRANSLATIONS.get(get_language()) - i18n_file = ( - ("admin/js/vendor/select2/i18n/%s.js" % i18n_name,) if i18n_name else () - ) - return forms.Media( - js=("admin/js/vendor/select2/select2.full%s.js" % extra,) - + i18n_file - + ("djangocms_frontend/js/django_select2.js",), - css={ - "screen": ( - "admin/css/vendor/select2/select2%s.css" % extra, - "djangocms_frontend/css/select2.css", - ), - }, - ) - def __init__(self, *args, **kwargs): - if MINIMUM_INPUT_LENGTH: + if MINIMUM_INPUT_LENGTH and False: if "attrs" in kwargs: kwargs["attrs"].setdefault( "data-minimum-input-length", MINIMUM_INPUT_LENGTH ) else: kwargs["attrs"] = {"data-minimum-input-length": MINIMUM_INPUT_LENGTH} - kwargs.setdefault("data_view", "dcf_autocomplete:ac_view") + kwargs.setdefault("admin_site", None) + kwargs.setdefault("field", SimpleNamespace(name="name", model=SimpleNamespace( + _meta=SimpleNamespace(app="app", label="label") + ))) super().__init__(*args, **kwargs) + def get_url(self): + return reverse("dcf_autocomplete:ac_view") + + def build_attrs(self, base_attrs, extra_attrs=None): + """ + Set select2's AJAX attributes. + + Attributes can be set using the html5 data attribute. + Nested attributes require a double dash as per + https://select2.org/configuration/data-attributes#nested-subkey-options + """ + attrs = super(forms.Select, self).build_attrs(base_attrs, extra_attrs=extra_attrs) + attrs.setdefault("class", "") + attrs.update( + { + "data-ajax--cache": "true", + "data-ajax--delay": 250, + "data-ajax--type": "GET", + "data-ajax--url": self.get_url(), + "data-theme": "admin-autocomplete", + "data-app-label": "app", + "data-model-name": "model", + "data-field-name": "field", + "data-allow-clear": json.dumps(not self.is_required), + "data-placeholder": "", # Allows clearing of the input. + "lang": self.i18n_name, + "class": attrs["class"] + + (" " if attrs["class"] else "") + + "admin-autocomplete", + } + ) + return attrs + + def optgroups(self, name, value, attr=None): + return super(forms.Select, self).optgroups(name, value) + class SmartLinkField(forms.ChoiceField): widget = Select2jqWidget diff --git a/djangocms_frontend/contrib/link/templates/djangocms_frontend/admin/link.html b/djangocms_frontend/contrib/link/templates/djangocms_frontend/admin/link.html index ae8f899d..d931501c 100644 --- a/djangocms_frontend/contrib/link/templates/djangocms_frontend/admin/link.html +++ b/djangocms_frontend/contrib/link/templates/djangocms_frontend/admin/link.html @@ -3,6 +3,14 @@ {% block extrahead %} {{ block.super }} + {% endblock %} diff --git a/djangocms_frontend/static/djangocms_frontend/css/select2.css b/djangocms_frontend/static/djangocms_frontend/css/select2.css deleted file mode 100644 index dd7d7530..00000000 --- a/djangocms_frontend/static/djangocms_frontend/css/select2.css +++ /dev/null @@ -1,8 +0,0 @@ -/* - This file is generated. - Do not edit directly. - Edit original files in - /private/sass instead - */ - -@media screen{.change-form .select2-container--default .select2-selection--single,.change-form .select2-dropdown{background:var(--dca-white,var(--body-bg,#fff))}.change-form .select2-container--default .select2-results__option[aria-selected=true]{background:var(--dca-gray,var(--body-quiet-color,#666))}.change-form .select2-container--default .select2-selection--single .select2-selection__rendered{color:var(--dca-black,var(--body-fg,#000))}.change-form .popover{background:var(--dca-white,var(--body-bg,#fff))}} \ No newline at end of file diff --git a/djangocms_frontend/static/djangocms_frontend/css/select2.css.map b/djangocms_frontend/static/djangocms_frontend/css/select2.css.map deleted file mode 100644 index 7b2ac8e9..00000000 --- a/djangocms_frontend/static/djangocms_frontend/css/select2.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sourceRoot":"","sources":["../../../../private/sass/select2.scss"],"names":[],"mappings":"AAEA,mCACI,yEACI,qCAEJ,yEACI,oCAEJ,oFACI,6BAEJ,SACI,sCAIR,4BACI","file":"select2.css"} \ No newline at end of file diff --git a/private/sass/select2.scss b/private/sass/select2.scss deleted file mode 100644 index 4b5c6dc9..00000000 --- a/private/sass/select2.scss +++ /dev/null @@ -1,22 +0,0 @@ -@import "components/variables"; - -@media screen { - .change-form { - .select2-container--default .select2-selection--single, - .select2-dropdown { - background: var(--dca-white, var(--body-bg, white)); - } - - .select2-container--default .select2-results__option[aria-selected=true] { - background: var(--dca-gray, var(--body-quiet-color, #666)); - } - - .select2-container--default .select2-selection--single .select2-selection__rendered { - color: var(--dca-black, var(--body-fg, #000)); - } - - .popover { - background: var(--dca-white, var(--body-bg, white)); // standard django admin - } - } -} diff --git a/setup.py b/setup.py index e34f52bc..8c1534ce 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,6 @@ "easy-thumbnails", "djangocms-attributes-field>=1", "djangocms-text-ckeditor>=3.1.0", - "django-select2", "django-entangled>=0.5.4", ] @@ -22,10 +21,10 @@ "djangocms-static-ace", ], "cms-4": [ - "django-cms>=4.1.0rc4", + "django-cms>=4.1.0", "django-parler", - "djangocms-versioning>=2.0.0rc1", - "djangocms-alias>=2.0.0rc1", + "djangocms-versioning>=2.0.0", + "djangocms-alias>=2.0.0", ], "cms-3": [ "django-cms<4", diff --git a/tests/requirements/dj41_cms41.txt b/tests/requirements/dj41_cms41.txt index fd4cb1e8..1c207cae 100644 --- a/tests/requirements/dj41_cms41.txt +++ b/tests/requirements/dj41_cms41.txt @@ -1,7 +1,7 @@ -r base.txt Django>=4.1,<4.2 -django-cms>=4.1rc2 --e git+https://github.com/fsbraun/djangocms-alias.git@master#egg=djangocms-alias --e git+https://github.com/fsbraun/djangocms-url-manager.git@master#egg=djangocms-url-manager -https://github.com/django-cms/djangocms-versioning/tarball/master#egg=djangocms-versioning +django-cms>=4.1 +djangocms-alias>=2.0.0 +djangocms-versioning>=2.0.0 +git+https://github.com/fsbraun/djangocms-url-manager.git@master#egg=djangocms-url-manager diff --git a/tests/requirements/dj42_cms41.txt b/tests/requirements/dj42_cms41.txt index 861ab22f..381aa811 100644 --- a/tests/requirements/dj42_cms41.txt +++ b/tests/requirements/dj42_cms41.txt @@ -2,6 +2,6 @@ Django>=4.2,<4.3 django-cms>=4.1rc2 -git+https://github.com/fsbraun/djangocms-alias.git@master#egg=djangocms-alias +djangocms-alias>=2.0.0 +djangocms-versioning>=2.0.0 git+https://github.com/fsbraun/djangocms-url-manager.git@master#egg=djangocms-url-manager -https://github.com/django-cms/djangocms-versioning/tarball/master#egg=djangocms-versioning diff --git a/tests/requirements/dj50_cms41.txt b/tests/requirements/dj50_cms41.txt index 002f7efb..ef612d80 100644 --- a/tests/requirements/dj50_cms41.txt +++ b/tests/requirements/dj50_cms41.txt @@ -2,6 +2,6 @@ Django>=5.0,<5.1 django-cms>=4.1rc5 -git+https://github.com/fsbraun/djangocms-alias.git@master#egg=djangocms-alias +djangocms-alias>=2.0.0 +djangocms-versioning>=2.0.0 git+https://github.com/fsbraun/djangocms-url-manager.git@master#egg=djangocms-url-manager -https://github.com/django-cms/djangocms-versioning/tarball/master#egg=djangocms-versioning From 17f3b7197d6fd0d415d42ad273500854bdb39373 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Thu, 21 Mar 2024 14:23:35 +0100 Subject: [PATCH 16/66] Fix: Tree structure for pages --- djangocms_frontend/contrib/link/forms.py | 11 +++++++---- djangocms_frontend/contrib/link/helpers.py | 4 +++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/djangocms_frontend/contrib/link/forms.py b/djangocms_frontend/contrib/link/forms.py index edafb1f4..aae74bc2 100644 --- a/djangocms_frontend/contrib/link/forms.py +++ b/djangocms_frontend/contrib/link/forms.py @@ -62,7 +62,7 @@ class Select2jqWidget(AutocompleteMixin, forms.Select): empty_label = _("Select a destination") def __init__(self, *args, **kwargs): - if MINIMUM_INPUT_LENGTH and False: + if MINIMUM_INPUT_LENGTH: if "attrs" in kwargs: kwargs["attrs"].setdefault( "data-minimum-input-length", MINIMUM_INPUT_LENGTH @@ -70,9 +70,12 @@ def __init__(self, *args, **kwargs): else: kwargs["attrs"] = {"data-minimum-input-length": MINIMUM_INPUT_LENGTH} kwargs.setdefault("admin_site", None) - kwargs.setdefault("field", SimpleNamespace(name="name", model=SimpleNamespace( - _meta=SimpleNamespace(app="app", label="label") - ))) + kwargs.setdefault( + "field", + SimpleNamespace(name="", model=SimpleNamespace( + _meta=SimpleNamespace(app="djangocms_frontend", label="link") + )) + ) # Fake field properties for autocomplete field (unused by link) super().__init__(*args, **kwargs) def get_url(self): diff --git a/djangocms_frontend/contrib/link/helpers.py b/djangocms_frontend/contrib/link/helpers.py index 88514459..f854c4fd 100644 --- a/djangocms_frontend/contrib/link/helpers.py +++ b/djangocms_frontend/contrib/link/helpers.py @@ -61,9 +61,11 @@ def get_object_for_value(value): return None -def get_link_choices(request, term="", lang=None, nbsp=""): +def get_link_choices(request, term="", lang=None, nbsp=None): global _querysets + if nbsp is None: + nbsp = "" if term else "\u2000" available_objects = [] # Now create our list of cms pages type_id = ContentType.objects.get_for_model(Page).id From 1dd0e83c614a513bc8fd4453c88f44ced1c6f075 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Thu, 21 Mar 2024 14:29:56 +0100 Subject: [PATCH 17/66] Restore Django 3.2 compatibility --- djangocms_frontend/contrib/link/forms.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/djangocms_frontend/contrib/link/forms.py b/djangocms_frontend/contrib/link/forms.py index aae74bc2..c5eb137f 100644 --- a/djangocms_frontend/contrib/link/forms.py +++ b/djangocms_frontend/contrib/link/forms.py @@ -3,7 +3,7 @@ from django import apps, forms from django.conf import settings as django_settings -from django.contrib.admin.widgets import AutocompleteMixin +from django.contrib.admin.widgets import SELECT2_TRANSLATIONS, AutocompleteMixin from django.contrib.contenttypes.models import ContentType from django.contrib.sites.models import Site from django.core.exceptions import ObjectDoesNotExist, ValidationError @@ -11,6 +11,7 @@ from django.db.models.fields.related import ManyToOneRel from django.urls import reverse from django.utils.encoding import force_str +from django.utils.translation import get_language from django.utils.translation import gettext as _ # from djangocms_link.validators import IntranetURLValidator @@ -91,6 +92,7 @@ def build_attrs(self, base_attrs, extra_attrs=None): """ attrs = super(forms.Select, self).build_attrs(base_attrs, extra_attrs=extra_attrs) attrs.setdefault("class", "") + i18n_name = getattr(self, "i18n_name", SELECT2_TRANSLATIONS.get(get_language())) # Django 3.2 compat attrs.update( { "data-ajax--cache": "true", @@ -103,7 +105,7 @@ def build_attrs(self, base_attrs, extra_attrs=None): "data-field-name": "field", "data-allow-clear": json.dumps(not self.is_required), "data-placeholder": "", # Allows clearing of the input. - "lang": self.i18n_name, + "lang": i18n_name, "class": attrs["class"] + (" " if attrs["class"] else "") + "admin-autocomplete", From d405c51654538d5a0437281b07df2496ab3ce03e Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Thu, 21 Mar 2024 15:39:29 +0100 Subject: [PATCH 18/66] Update changelog --- CHANGELOG.rst | 1 + djangocms_frontend/contrib/link/views.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5cdc42de..7f330d35 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -11,6 +11,7 @@ Changelog * fix: removed Nav Container plugin and fixed Navigation Link plugin by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/192 * fix: Remove `{% spaceless %}` around `{% block "content" %}` by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/188 * fix: Improved fieldset layout for Django 4.2+ by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/185 +* fix: Dropped django-select2 dependency 1.2.2 (2024-01-13) diff --git a/djangocms_frontend/contrib/link/views.py b/djangocms_frontend/contrib/link/views.py index 7b5b9429..72779ff7 100644 --- a/djangocms_frontend/contrib/link/views.py +++ b/djangocms_frontend/contrib/link/views.py @@ -22,7 +22,7 @@ def get(self, request, *args, **kwargs): # TODO Check permissions # ====================== - self.term = kwargs.get("term", request.GET.get("term", "")) + self.term = kwargs.get("term", request.GET.get("term", "")).strip() results = get_link_choices(request, self.term) return JsonResponse( { From 123ee859d2627d90b9e8c26f649058d4c5772d35 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Thu, 21 Mar 2024 16:01:01 +0100 Subject: [PATCH 19/66] Fix: Min width of select2 box --- .../link/templates/djangocms_frontend/admin/link.html | 11 +++++++---- .../djangocms_frontend/admin/includes/fieldset.html | 3 +-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/djangocms_frontend/contrib/link/templates/djangocms_frontend/admin/link.html b/djangocms_frontend/contrib/link/templates/djangocms_frontend/admin/link.html index d931501c..b9ca1608 100644 --- a/djangocms_frontend/contrib/link/templates/djangocms_frontend/admin/link.html +++ b/djangocms_frontend/contrib/link/templates/djangocms_frontend/admin/link.html @@ -5,11 +5,14 @@ {{ block.super }} {% endblock %} diff --git a/djangocms_frontend/templates/djangocms_frontend/admin/includes/fieldset.html b/djangocms_frontend/templates/djangocms_frontend/admin/includes/fieldset.html index c3d670e5..705faefb 100644 --- a/djangocms_frontend/templates/djangocms_frontend/admin/includes/fieldset.html +++ b/djangocms_frontend/templates/djangocms_frontend/admin/includes/fieldset.html @@ -1,5 +1,5 @@
    - {% if fieldset.name and not "collapse" in fieldset.classes %}

    {{ fieldset.name }}

    {% endif %} + {% if fieldset.name %}

    {{ fieldset.name }}

    {% endif %} {% if fieldset.description %}
    {{ fieldset.description|safe }}
    {% endif %} @@ -32,4 +32,3 @@ {% endfor %}
    - From b8ba77154984efbd410974adb1e13429af25a270 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Thu, 21 Mar 2024 16:25:49 +0100 Subject: [PATCH 20/66] Fix icon picker --- djangocms_frontend/static/djangocms_frontend/css/base.css | 2 +- private/sass/components/_icon-picker.scss | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/djangocms_frontend/static/djangocms_frontend/css/base.css b/djangocms_frontend/static/djangocms_frontend/css/base.css index adddcd18..16451606 100644 --- a/djangocms_frontend/static/djangocms_frontend/css/base.css +++ b/djangocms_frontend/static/djangocms_frontend/css/base.css @@ -5,4 +5,4 @@ /private/sass instead */ -@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:0.8125rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#0d6efd;--bs-link-hover-color:#0a58ca;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-size:0.8125rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#212529;--bs-btn-bg:transparent;--bs-btn-border-width:1px;--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-ms-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.015625rem;--bs-btn-border-radius:0.5rem}.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.7109375rem;--bs-btn-border-radius:0.25rem}.link-primary{color:#0d6efd!important}.link-primary:focus,.link-primary:hover{color:#0a58ca!important}.link-secondary{color:#6c757d!important}.link-secondary:focus,.link-secondary:hover{color:#565e64!important}.link-success{color:#198754!important}.link-success:focus,.link-success:hover{color:#146c43!important}.link-info{color:#0dcaf0!important}.link-info:focus,.link-info:hover{color:#3dd5f3!important}.link-warning{color:#ffc107!important}.link-warning:focus,.link-warning:hover{color:#ffcd39!important}.link-danger{color:#dc3545!important}.link-danger:focus,.link-danger:hover{color:#b02a37!important}.link-light{color:#f8f9fa!important}.link-light:focus,.link-light:hover{color:#f9fafb!important}.link-dark{color:#212529!important}.link-dark:focus,.link-dark:hover{color:#1a1e21!important}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.3rem;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#6c757d;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:1px;--bs-nav-tabs-border-color:#dee2e6;--bs-nav-tabs-border-radius:0.375rem;--bs-nav-tabs-link-hover-border-color:#e9ecef #e9ecef #dee2e6;--bs-nav-tabs-link-active-color:#495057;--bs-nav-tabs-link-active-bg:#fff;--bs-nav-tabs-link-active-border-color:#dee2e6 #dee2e6 #fff;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:4px;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0bf}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.icon{display:inline-block;vertical-align:top;width:1em;height:1em;background-position:center;background-repeat:no-repeat}.icon svg{display:block;width:100%;height:100%}.icon-info{width:.9em;font-size:110%!important}.icon-white{color:#fff}.icon-white svg{fill:#fff}.icon-black{color:#000}.icon-black svg{fill:#000}.icon-primary{color:#0bf}.icon-primary svg{fill:#0bf}.djangocms-icon .icon>input{float:left;position:relative;top:12px}.djangocms-icon .caret{margin-inline-start:8px}.aligned .frontend-button-group label{min-width:unset}.frontend-button-group .btn{box-sizing:border-box;cursor:pointer;-webkit-appearance:none;margin:2px;overflow:hidden;text-overflow:ellipsis}.frontend-button-group .btn.active{outline:3px solid #0bf;border-color:#fff!important}.frontend-button-group .btn-default.active{border-radius:0;background-color:#0bf!important}.frontend-button-group-context-colors>div,.frontend-button-group-context-size>div{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;min-height:75px}.frontend-button-group-context-colors .btn{-ms-flex-preferred-size:calc(25% - 4px);flex-basis:calc(25% - 4px)}@media (min-width:820px){.frontend-button-group-context-colors .btn{-ms-flex-preferred-size:calc(20% - 4px);flex-basis:calc(20% - 4px)}}.frontend-button-group-icons .icon,.frontend-grid-icons .icon{font-size:24px}.frontend-button-group-icons .icon-flex-align-center,.frontend-button-group-icons .icon-flex-align-end,.frontend-button-group-icons .icon-flex-align-start,.frontend-grid-icons .icon-flex-align-center,.frontend-grid-icons .icon-flex-align-end,.frontend-grid-icons .icon-flex-align-start{transform:scale(1.4)}.frontend-button-group-icons .icon-flex-content-around,.frontend-button-group-icons .icon-flex-content-between,.frontend-grid-icons .icon-flex-content-around,.frontend-grid-icons .icon-flex-content-between{transform:scale(1.6)}.frontend-button-group-icons .icon-flex-self-center,.frontend-button-group-icons .icon-flex-self-end,.frontend-button-group-icons .icon-flex-self-start,.frontend-grid-icons .icon-flex-self-center,.frontend-grid-icons .icon-flex-self-end,.frontend-grid-icons .icon-flex-self-start{transform:scale(1.4)}.frontend-button-group-icons .icon-align-reset,.frontend-button-group-icons .icon-no-selection,.frontend-grid-icons .icon-align-reset,.frontend-grid-icons .icon-no-selection{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-align-items-start,.frontend-button-group-icons .icon-flex-align-start,.frontend-grid-icons .icon-align-items-start,.frontend-grid-icons .icon-flex-align-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-items-center,.frontend-button-group-icons .icon-flex-align-center,.frontend-grid-icons .icon-align-items-center,.frontend-grid-icons .icon-flex-align-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-items-end,.frontend-button-group-icons .icon-flex-align-end,.frontend-grid-icons .icon-align-items-end,.frontend-grid-icons .icon-flex-align-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-flex-content-start,.frontend-button-group-icons .icon-justify-content-start,.frontend-button-group-icons .icon-start,.frontend-grid-icons .icon-flex-content-start,.frontend-grid-icons .icon-justify-content-start,.frontend-grid-icons .icon-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-center,.frontend-button-group-icons .icon-flex-content-center,.frontend-button-group-icons .icon-justify-content-center,.frontend-grid-icons .icon-center,.frontend-grid-icons .icon-flex-content-center,.frontend-grid-icons .icon-justify-content-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-end,.frontend-button-group-icons .icon-flex-content-end,.frontend-button-group-icons .icon-justify-content-end,.frontend-grid-icons .icon-end,.frontend-grid-icons .icon-flex-content-end,.frontend-grid-icons .icon-justify-content-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-flex-content-around,.frontend-button-group-icons .icon-justify-content-around,.frontend-grid-icons .icon-flex-content-around,.frontend-grid-icons .icon-justify-content-around{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.6)}.frontend-button-group-icons .icon-flex-content-between,.frontend-button-group-icons .icon-justify-content-between,.frontend-grid-icons .icon-flex-content-between,.frontend-grid-icons .icon-justify-content-between{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.6)}.frontend-button-group-icons .icon-nav-fill,.frontend-grid-icons .icon-nav-fill{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-nav-justified,.frontend-grid-icons .icon-nav-justified{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-flex-column,.frontend-grid-icons .icon-flex-column{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-start,.frontend-button-group-icons .icon-flex-self-start,.frontend-grid-icons .icon-align-self-start,.frontend-grid-icons .icon-flex-self-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-center,.frontend-button-group-icons .icon-flex-self-center,.frontend-grid-icons .icon-align-self-center,.frontend-grid-icons .icon-flex-self-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-end,.frontend-button-group-icons .icon-flex-self-end,.frontend-grid-icons .icon-align-self-end,.frontend-grid-icons .icon-flex-self-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-size-sm,.frontend-button-group-icons .icon-size-xs,.frontend-button-group-icons .icon-sm,.frontend-button-group-icons .icon-xs,.frontend-grid-icons .icon-size-sm,.frontend-grid-icons .icon-size-xs,.frontend-grid-icons .icon-sm,.frontend-grid-icons .icon-xs{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-sm,.frontend-button-group-icons .icon-sm,.frontend-grid-icons .icon-size-sm,.frontend-grid-icons .icon-sm{transform:rotate(-90deg)}.frontend-button-group-icons .icon-md,.frontend-button-group-icons .icon-size-md,.frontend-grid-icons .icon-md,.frontend-grid-icons .icon-size-md{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-lg,.frontend-button-group-icons .icon-size-lg,.frontend-grid-icons .icon-lg,.frontend-grid-icons .icon-size-lg{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-xl,.frontend-button-group-icons .icon-xl,.frontend-grid-icons .icon-size-xl,.frontend-grid-icons .icon-xl{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-xxl,.frontend-button-group-icons .icon-xxl,.frontend-grid-icons .icon-size-xxl,.frontend-grid-icons .icon-xxl{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-mb,.frontend-grid-icons .icon-mb{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-me,.frontend-grid-icons .icon-me{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-ms,.frontend-grid-icons .icon-ms{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-mt,.frontend-grid-icons .icon-mt{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-mx,.frontend-grid-icons .icon-mx{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-my,.frontend-grid-icons .icon-my{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pb,.frontend-grid-icons .icon-pb{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pe,.frontend-grid-icons .icon-pe{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-ps,.frontend-grid-icons .icon-ps{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pt,.frontend-grid-icons .icon-pt{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-px,.frontend-grid-icons .icon-px{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-py,.frontend-grid-icons .icon-py{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.icon-info{background-image:url('data:image/svg+xml;utf8,')}.module{margin:0 0 20px}.djangocms-frontend-row .form-row.field-create .icon{position:absolute;font-size:30px;margin-block-start:28px;margin-inline-start:4px}.djangocms-frontend-row .form-row.field-create input[name=create]{width:130px!important;padding-inline-end:5px!important;text-align:start}.djangocms-frontend-column .form-row.field-xs_col,.djangocms-frontend-column .form-row.field-xs_me,.djangocms-frontend-column .form-row.field-xs_ms,.djangocms-frontend-column .form-row.field-xs_offset,.djangocms-frontend-column .form-row.field-xs_order,.djangocms-frontend-row .form-row.field-row_cols_xs{position:relative;display:-ms-flexbox;display:flex;padding:0;min-width:800px}.djangocms-frontend-column .form-row.field-xs_col .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_me .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_ms .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_offset .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_order .field-box:first-child,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box:first-child{width:115px!important}.djangocms-frontend-column .form-row.field-xs_col .field-box,.djangocms-frontend-column .form-row.field-xs_col .fieldBox,.djangocms-frontend-column .form-row.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_me .fieldBox,.djangocms-frontend-column .form-row.field-xs_ms .field-box,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox,.djangocms-frontend-column .form-row.field-xs_offset .field-box,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox,.djangocms-frontend-column .form-row.field-xs_order .field-box,.djangocms-frontend-column .form-row.field-xs_order .fieldBox,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox{position:relative;box-sizing:content-box;width:86px!important;-ms-flex:none;flex:none;padding:15px 10px;margin:0!important;border-bottom:1px solid #eee;float:left!important}.djangocms-frontend-column .form-row.field-xs_col .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_col .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_me .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_me .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_ms .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_ms .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_offset .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_offset .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_order .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_order .fieldBox input:not([type=checkbox]),.djangocms-frontend-row .form-row.field-row_cols_xs .field-box input:not([type=checkbox]),.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox input:not([type=checkbox]){text-align:end;padding-inline-end:5px!important;box-sizing:border-box;width:100%}.djangocms-frontend-column .form-row.field-xs_col .field-box label,.djangocms-frontend-column .form-row.field-xs_col .fieldBox label,.djangocms-frontend-column .form-row.field-xs_me .field-box label,.djangocms-frontend-column .form-row.field-xs_me .fieldBox label,.djangocms-frontend-column .form-row.field-xs_ms .field-box label,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox label,.djangocms-frontend-column .form-row.field-xs_offset .field-box label,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox label,.djangocms-frontend-column .form-row.field-xs_order .field-box label,.djangocms-frontend-column .form-row.field-xs_order .fieldBox label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box label,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox label{font-size:12px!important;font-weight:400!important;color:#ccc!important;position:absolute;inset-inline-start:15px;inset-block-end:17px;text-transform:lowercase}.djangocms-frontend-column .form-row.field-xs_col .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_col .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_me .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_me .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_ms .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_offset .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_order .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_order .fieldBox .disabled,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box .disabled,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox .disabled{color:#ccc;background:#eee}.djangocms-frontend-column .form-row.field-xs_col .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_col .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_me .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_me .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_ms .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_offset .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_order .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_order .fieldBox:last-child,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box:last-child,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox:last-child{border-inline-end:none}.djangocms-frontend-column .form-row.field-xs_col .errors,.djangocms-frontend-column .form-row.field-xs_me .errors,.djangocms-frontend-column .form-row.field-xs_ms .errors,.djangocms-frontend-column .form-row.field-xs_offset .errors,.djangocms-frontend-column .form-row.field-xs_order .errors,.djangocms-frontend-row .form-row.field-row_cols_xs .errors{margin-bottom:0}.djangocms-frontend-column .form-row.field-xs_col .errorlist,.djangocms-frontend-column .form-row.field-xs_me .errorlist,.djangocms-frontend-column .form-row.field-xs_ms .errorlist,.djangocms-frontend-column .form-row.field-xs_offset .errorlist,.djangocms-frontend-column .form-row.field-xs_order .errorlist,.djangocms-frontend-row .form-row.field-row_cols_xs .errorlist{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.djangocms-frontend-column .form-row.field-xs_col.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_me.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_ms.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_offset.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_order.field-xs_me .field-box,.djangocms-frontend-row .form-row.field-row_cols_xs.field-xs_me .field-box{border-bottom:none}.djangocms-frontend-column .form-row.field-xs_col .field-box-label,.djangocms-frontend-column .form-row.field-xs_me .field-box-label,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label,.djangocms-frontend-column .form-row.field-xs_order .field-box-label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label{display:-ms-flexbox;display:flex;margin-top:auto;color:#999}.djangocms-frontend-column .form-row.field-xs_col .field-box-label a,.djangocms-frontend-column .form-row.field-xs_me .field-box-label a,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label a,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label a,.djangocms-frontend-column .form-row.field-xs_order .field-box-label a,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label a{width:100%;margin-top:auto;color:#999}.djangocms-frontend-column .form-row.field-xs_col .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_me .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_order .field-box-label a a,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label a a{width:100%;margin-top:auto}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_col .field-md_me,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_me .field-md_me,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_order .field-md_me,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms{text-align:start}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-md_me label,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-md_me label,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-md_me label,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms label{inset-inline-start:30px;inset-block-start:14px}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-md_me input,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-md_me input,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-md_me input,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms input{position:relative;box-sizing:border-box;top:-3px}.grid-reset{position:absolute;inset-inline-end:5px;inset-block-start:0}.icon-thead{text-align:center;margin-bottom:15px}.icon-thead .icon{font-size:30px}.icon-thead .icon-size-sm{transform:rotate(90deg)}.icon-title{display:block;font-size:12px;color:#999;padding:5px 0 0}.djangocms-frontend-preview{position:fixed;inset-block-start:0;inset-inline-end:0;z-index:10;text-align:center;border-radius:0 0 0 3px;padding:10px 20px 27px;border:1px solid var(--dca-gray,var(--hairline-color,#ccc));border-block-start:none;border-inline-end:none;background:var(--body-bg,#fff)}@media (prefers-color-scheme:dark){.djangocms-frontend-preview{background:var(--body-bg,#000)}}.djangocms-frontend-preview h2{font-size:14px;min-width:150px;margin:0 0 12px}.djangocms-frontend-preview .b4-preview{margin:0 0 -15px}.djangocms-frontend-preview .b4-close{position:absolute;inset-inline-end:10px;inset-block-start:8px;z-index:100;display:block;color:#5e5e5e;font-size:12px;line-height:20px;font-weight:700;text-transform:uppercase;width:20px;height:20px;border-radius:3px;background:#ddd}.djangocms-frontend-preview .b4-close:hover{color:#fff!important;text-decoration:none;background:#0bf}.djangocms-frontend-preview .btn>span{vertical-align:middle}.djangocms-frontend-preview .btn>span>.icon{vertical-align:middle}.djangocms-frontend-preview .btn>span svg,.djangocms-frontend-preview .btn>span use{fill:currentColor}.djangocms-frontend-blockquote textarea{height:110px}#id_link_type{padding:0;margin:0;border:none}#id_link_type li{padding:0;margin:0 15px 5px 0;border:none}#id_link_type label input{position:relative;top:-4px}a[data-pk]{position:relative}a[data-pk]:after{content:attr(data-pk);visibility:hidden;width:auto;font-weight:400;font-size:80%;background-color:var(--dca-white,var(--body-bg,#fff));color:var(--dca-gray,var(--body-fg,#333));border:solid 1px var(--dca-gray,var(--body-fg,#333));text-align:center;padding:5px 10px;position:absolute;z-index:1;top:110%;inset-inline-start:50%;margin-inline-start:-50%}a[data-pk]:hover:after{visibility:visible}.djangocms-admin-style .form-row.field-plugin_title input[name=plugin_title_0]{margin-bottom:.5em!important}.djangocms-admin-style .form-row.field-plugin_title input[name=plugin_title_1]{width:calc(100% - 2em)!important}body:not(.djangocms-admin-style) .form-row.field-plugin_title input[name=plugin_title_1]{width:calc(100% - 200px - 1em)!important;margin-inline-start:1em}.frontend-icon-picker{text-align:center;display:inline-block}.frontend-icon-picker .icon-container{position:relative;margin-bottom:.5em;margin-left:auto;margin-right:auto;width:7em;height:7em;border:1px var(--dca-gray-light,var(--border-color,#d3d3d3)) solid;transition:background-color .15s,color .15s}.frontend-icon-picker .icon-container .icon-preview{width:7em;height:7em;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.frontend-icon-picker .icon-container .icon-preview .icon-box{font-size:500%;line-height:1.3;margin:0;text-align:center}.frontend-icon-picker .icon-container .icon-preview .icon-box i,.frontend-icon-picker .icon-container .icon-preview .icon-box span{font-size:unset}.frontend-icon-picker .icon-container .icon-preview .empty-box{text-align:center;overflow:hidden;text-overflow:ellipsis;line-height:1;font-size:100%}.frontend-icon-picker .icon-container .icon-preview .empty-box.hidden{display:none}.frontend-icon-picker .icon-container .icon-preview:hover{background:var(--dca-gray-light,var(--border-color,#d3d3d3));cursor:pointer}.frontend-icon-picker .icon-container .icon-close-indicator{display:block;border-radius:50%;color:var(--dca-black,var(--body-fg,#000));background-color:var(--dca-white,var(--body-bg,#fff));padding:.3rem;border:1px solid var(--dca-black,var(--body-fg,#000));transform:translate(-50%,-50%);top:0;inset-inline-start:100%;width:.6em;height:.6em;line-height:.5em;position:absolute;transition:background-color .15s}.frontend-icon-picker .icon-container .icon-close-indicator:before{content:"×"}.frontend-icon-picker .icon-container .icon-close-indicator:hover{background:var(--delete-button-bg,red);color:var(--delete-button-fg,#fff);cursor:pointer}.uip-modal{position:fixed;height:100%;width:100%;inset-block-end:0;inset-inline-start:0;background-color:rgba(0,0,0,.8);z-index:9999;-webkit-user-select:none;-ms-user-select:none;user-select:none;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.uip-modal *,.uip-modal :after,.uip-modal :before{box-sizing:border-box}.uip-modal.uip-close{opacity:0;visibility:hidden;transition:all .4s ease-in-out}.uip-modal.uip-open{opacity:1;visibility:visible;transition:all .4s ease-in-out}.uip-modal .uip-modal--content{position:absolute;border-radius:3px;box-shadow:2px 8px 23px 3px rgba(0,0,0,.2);overflow:hidden;font-family:Roboto,Arial,Helvetica,Verdana,sans-serif;background-color:var(--dca-gray-lightest,var(--darkened-bg,#f8f8f8));width:100%;margin:auto;left:0;right:0;margin-bottom:2em}.uip-modal .uip-modal--content .uip-modal--header{padding:15px 15px;background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 0 8px rgba(0,0,0,.1);position:relative;z-index:1;font-size:15px;color:var(--dca-gray,var(--body-quiet-color,#666));font-weight:500;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-logo-title{padding-top:2px;line-height:1;text-transform:uppercase;font-weight:700;cursor:pointer}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-close-btn{cursor:pointer}.uip-modal .uip-modal--content .uip-modal--body{font-size:12px;line-height:1.5;box-sizing:border-box;padding:0;height:70vh;display:-ms-flexbox;display:flex;min-height:50px;max-height:85vh;overflow:auto}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar{-ms-flex-negative:0;flex-shrink:0;max-width:25%}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs{margin-top:30px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item{padding:15px;font-size:14px;color:var(--dca-gray,var(--body-quiet-color,#666));text-align:start;cursor:pointer;position:relative;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item i{font-size:20px;padding-inline-end:15px;color:var(--dca-gray-lighter,var(--border-color,#ccc))}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item img{padding-inline-end:15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active{background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 6px 20px 0 rgba(0,0,0,.1)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active:after{content:"";position:absolute;height:100%;width:5px;inset-block-start:0;inset-inline-start:0;background-color:#0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active i{color:#0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item:only-child{display:none}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding:30px 80px 0;width:100%}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner{overflow:auto;margin:25px -15px 0;padding:0 15px 15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview{display:-ms-grid;display:grid;grid-gap:20px;margin:20px 0}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item{position:relative;padding:10px;background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 1px 12px rgba(0,0,0,.05);border-radius:3px;cursor:pointer;transition:all .3s;overflow:hidden}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item:hover{box-shadow:0 1px 14px rgba(0,0,0,.16)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item.universal-selected{box-shadow:0 1px 12px rgba(0,0,0,.05),0 0 0 3px #0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-align:center;align-items:center;padding:1px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item__icon,.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner i{font-size:25px;color:var(--dca-gray-darkest,var(--body-fg,#333))}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item-name{color:var(--dca-gray,var(--body-quiet-color,#666));font-size:11px;padding:13px 0 0;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search{position:relative}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input{width:100%;padding:8px 15px;background-color:var(--dca-white,var(--bg-color,#fff));border:none}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input:-ms-input-placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input::placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search img{position:absolute;top:50%;transform:translateY(-50%);inset-inline-end:10px}.uip-modal .uip-modal--footer{border-top:1px solid var(--dca-gray-lighter,var(--border-color,#ccc));text-align:center;background-color:var(--dca-white,var(--bg-color,#fff));border:none;display:none;-ms-flex-pack:end;justify-content:flex-end;padding:5px;box-shadow:0 0 8px rgba(0,0,0,.1);position:relative;display:-ms-flexbox;display:flex}.uip-modal .uip-modal--footer button.uip-insert-icon-button{padding:10px 35px!important;color:var(--dca-white,var(--bg-color,#fff))!important;background-color:#0bf!important;border:none;cursor:pointer;outline:0}.uip-modal .uip-modal--footer .universal-button{height:40px;margin-inline-start:5px}.uip-modal .uip-modal--footer .universal-button-success{padding:12px 36px;color:var(--dca-white,var(--bg-color,#fff));width:initial}.uip-modal .uip-modal--footer .universal-button-success:hover{background-color:#0bf}@media (min-width:1440px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:1200px}}@media (max-width:1439px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:990px}.uip-modal--icon-preview-wrap{padding:30px 50px 0}}@media (max-width:1023px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:740px}}@media (max-width:767px){.uip-modal--icon-preview-wrap{padding:15px!important}.uip-modal--sidebar{display:none}}@media (min-width:1440px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[7];grid-template-columns:repeat(7,1fr)}}@media (max-width:1439px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[6];grid-template-columns:repeat(6,1fr)}}@media (max-width:1024px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[5];grid-template-columns:repeat(5,1fr)}}@media (max-width:767px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[4];grid-template-columns:repeat(4,1fr)}}@media (max-width:479px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[3];grid-template-columns:repeat(3,1fr)}}@media (max-width:1439px){.uip-modal--sidebar-tab-item{padding:15px 15px 15px 25px;font-size:11px}.uip-modal--sidebar-tab-item i{font-size:15px}}@media (max-width:1024px){.uip-modal--sidebar-tab-item i,.uip-modal--sidebar-tab-item img{display:none}}.sr-only{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}ul.nav{margin-bottom:1em}ul.nav>li.nav-item{list-style-type:none;padding:inherit}.colM ul:not(.object-tools).nav{margin-top:0;margin-bottom:20px}ul.nav .nav-item{margin-inline-end:1rem}ul.nav .nav-link{position:relative;text-decoration:none}ul.nav .nav-link span.indicator{display:none;border-radius:50%;padding:.5rem;border:1px solid var(--dca-white,var(--body-bg,#fff));transform:translate(-50%,-50%);inset-block-start:0;inset-inline-start:100%;position:absolute}ul.nav .nav-link span.indicator.error{background-color:var(--bs-danger)}ul.nav .nav-link span.indicator.attributes{background-color:var(--bs-info);display:block}ul.nav .nav-link.error>span.indicator{display:block}ul.nav.nav-pills .nav-link:not(.active){border-style:solid;border-width:1px}body:not(.djangocms-admin-style) ul.djangocms-frontend.nav-tabs+div.tab-content .tab-pane{border-left-style:solid;border-bottom-style:solid;border-right-style:solid;border-left-color:var(--hairline-color);border-bottom-color:var(--hairline-color);border-right-color:var(--hairline-color);border-width:1px}body:not(.djangocms-admin-style) ul.djangocms-frontend.nav-tabs+div.tab-content .tab-pane fieldset:last-child{margin-bottom:0}div.tab-pk{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;color:var(--dca-gray-darker,var(--body-fg,#333));font-size:80%;margin-inline-start:auto}.djangocms-admin-style .colM ul.nav:not(.object-tools):not(.messagelist){margin-top:0}.djangocms-admin-style .colM ul.nav:not(.object-tools):not(.messagelist) li.nav-item{border-top:none}input[type=number].auto-field+span{display:none;position:absolute;inset-block-end:0;inset-inline-end:0;text-align:end;margin-inline-end:31px;margin-block-end:23px;cursor:pointer}body:not(.djangocms-admin-style) input[type=number].auto-field+span{margin-bottom:23px}@media (max-width:1024px){body:not(.djangocms-admin-style) input[type=number].auto-field+span{margin-bottom:24px}}input[type=number].auto-field+span:after{content:"auto"}input[type=number].auto-field.auto{color:var(--dca-white,var(--body-bg,#fff));caret-color:var(--dca-black,var(--body-fg,#000))}input[type=number].auto-field.auto+span{display:block} \ No newline at end of file +@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:0.8125rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#0d6efd;--bs-link-hover-color:#0a58ca;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-size:0.8125rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#212529;--bs-btn-bg:transparent;--bs-btn-border-width:1px;--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-ms-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.015625rem;--bs-btn-border-radius:0.5rem}.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.7109375rem;--bs-btn-border-radius:0.25rem}.link-primary{color:#0d6efd!important}.link-primary:focus,.link-primary:hover{color:#0a58ca!important}.link-secondary{color:#6c757d!important}.link-secondary:focus,.link-secondary:hover{color:#565e64!important}.link-success{color:#198754!important}.link-success:focus,.link-success:hover{color:#146c43!important}.link-info{color:#0dcaf0!important}.link-info:focus,.link-info:hover{color:#3dd5f3!important}.link-warning{color:#ffc107!important}.link-warning:focus,.link-warning:hover{color:#ffcd39!important}.link-danger{color:#dc3545!important}.link-danger:focus,.link-danger:hover{color:#b02a37!important}.link-light{color:#f8f9fa!important}.link-light:focus,.link-light:hover{color:#f9fafb!important}.link-dark{color:#212529!important}.link-dark:focus,.link-dark:hover{color:#1a1e21!important}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.3rem;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#6c757d;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:1px;--bs-nav-tabs-border-color:#dee2e6;--bs-nav-tabs-border-radius:0.375rem;--bs-nav-tabs-link-hover-border-color:#e9ecef #e9ecef #dee2e6;--bs-nav-tabs-link-active-color:#495057;--bs-nav-tabs-link-active-bg:#fff;--bs-nav-tabs-link-active-border-color:#dee2e6 #dee2e6 #fff;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:4px;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0bf}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.icon{display:inline-block;vertical-align:top;width:1em;height:1em;background-position:center;background-repeat:no-repeat}.icon svg{display:block;width:100%;height:100%}.icon-info{width:.9em;font-size:110%!important}.icon-white{color:#fff}.icon-white svg{fill:#fff}.icon-black{color:#000}.icon-black svg{fill:#000}.icon-primary{color:#0bf}.icon-primary svg{fill:#0bf}.djangocms-icon .icon>input{float:left;position:relative;top:12px}.djangocms-icon .caret{margin-inline-start:8px}.aligned .frontend-button-group label{min-width:unset}.frontend-button-group .btn{box-sizing:border-box;cursor:pointer;-webkit-appearance:none;margin:2px;overflow:hidden;text-overflow:ellipsis}.frontend-button-group .btn.active{outline:3px solid #0bf;border-color:#fff!important}.frontend-button-group .btn-default.active{border-radius:0;background-color:#0bf!important}.frontend-button-group-context-colors>div,.frontend-button-group-context-size>div{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;min-height:75px}.frontend-button-group-context-colors .btn{-ms-flex-preferred-size:calc(25% - 4px);flex-basis:calc(25% - 4px)}@media (min-width:820px){.frontend-button-group-context-colors .btn{-ms-flex-preferred-size:calc(20% - 4px);flex-basis:calc(20% - 4px)}}.frontend-button-group-icons .icon,.frontend-grid-icons .icon{font-size:24px}.frontend-button-group-icons .icon-flex-align-center,.frontend-button-group-icons .icon-flex-align-end,.frontend-button-group-icons .icon-flex-align-start,.frontend-grid-icons .icon-flex-align-center,.frontend-grid-icons .icon-flex-align-end,.frontend-grid-icons .icon-flex-align-start{transform:scale(1.4)}.frontend-button-group-icons .icon-flex-content-around,.frontend-button-group-icons .icon-flex-content-between,.frontend-grid-icons .icon-flex-content-around,.frontend-grid-icons .icon-flex-content-between{transform:scale(1.6)}.frontend-button-group-icons .icon-flex-self-center,.frontend-button-group-icons .icon-flex-self-end,.frontend-button-group-icons .icon-flex-self-start,.frontend-grid-icons .icon-flex-self-center,.frontend-grid-icons .icon-flex-self-end,.frontend-grid-icons .icon-flex-self-start{transform:scale(1.4)}.frontend-button-group-icons .icon-align-reset,.frontend-button-group-icons .icon-no-selection,.frontend-grid-icons .icon-align-reset,.frontend-grid-icons .icon-no-selection{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-align-items-start,.frontend-button-group-icons .icon-flex-align-start,.frontend-grid-icons .icon-align-items-start,.frontend-grid-icons .icon-flex-align-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-items-center,.frontend-button-group-icons .icon-flex-align-center,.frontend-grid-icons .icon-align-items-center,.frontend-grid-icons .icon-flex-align-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-items-end,.frontend-button-group-icons .icon-flex-align-end,.frontend-grid-icons .icon-align-items-end,.frontend-grid-icons .icon-flex-align-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-flex-content-start,.frontend-button-group-icons .icon-justify-content-start,.frontend-button-group-icons .icon-start,.frontend-grid-icons .icon-flex-content-start,.frontend-grid-icons .icon-justify-content-start,.frontend-grid-icons .icon-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-center,.frontend-button-group-icons .icon-flex-content-center,.frontend-button-group-icons .icon-justify-content-center,.frontend-grid-icons .icon-center,.frontend-grid-icons .icon-flex-content-center,.frontend-grid-icons .icon-justify-content-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-end,.frontend-button-group-icons .icon-flex-content-end,.frontend-button-group-icons .icon-justify-content-end,.frontend-grid-icons .icon-end,.frontend-grid-icons .icon-flex-content-end,.frontend-grid-icons .icon-justify-content-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-flex-content-around,.frontend-button-group-icons .icon-justify-content-around,.frontend-grid-icons .icon-flex-content-around,.frontend-grid-icons .icon-justify-content-around{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.6)}.frontend-button-group-icons .icon-flex-content-between,.frontend-button-group-icons .icon-justify-content-between,.frontend-grid-icons .icon-flex-content-between,.frontend-grid-icons .icon-justify-content-between{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.6)}.frontend-button-group-icons .icon-nav-fill,.frontend-grid-icons .icon-nav-fill{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-nav-justified,.frontend-grid-icons .icon-nav-justified{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-flex-column,.frontend-grid-icons .icon-flex-column{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-start,.frontend-button-group-icons .icon-flex-self-start,.frontend-grid-icons .icon-align-self-start,.frontend-grid-icons .icon-flex-self-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-center,.frontend-button-group-icons .icon-flex-self-center,.frontend-grid-icons .icon-align-self-center,.frontend-grid-icons .icon-flex-self-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-end,.frontend-button-group-icons .icon-flex-self-end,.frontend-grid-icons .icon-align-self-end,.frontend-grid-icons .icon-flex-self-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-size-sm,.frontend-button-group-icons .icon-size-xs,.frontend-button-group-icons .icon-sm,.frontend-button-group-icons .icon-xs,.frontend-grid-icons .icon-size-sm,.frontend-grid-icons .icon-size-xs,.frontend-grid-icons .icon-sm,.frontend-grid-icons .icon-xs{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-sm,.frontend-button-group-icons .icon-sm,.frontend-grid-icons .icon-size-sm,.frontend-grid-icons .icon-sm{transform:rotate(-90deg)}.frontend-button-group-icons .icon-md,.frontend-button-group-icons .icon-size-md,.frontend-grid-icons .icon-md,.frontend-grid-icons .icon-size-md{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-lg,.frontend-button-group-icons .icon-size-lg,.frontend-grid-icons .icon-lg,.frontend-grid-icons .icon-size-lg{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-xl,.frontend-button-group-icons .icon-xl,.frontend-grid-icons .icon-size-xl,.frontend-grid-icons .icon-xl{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-xxl,.frontend-button-group-icons .icon-xxl,.frontend-grid-icons .icon-size-xxl,.frontend-grid-icons .icon-xxl{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-mb,.frontend-grid-icons .icon-mb{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-me,.frontend-grid-icons .icon-me{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-ms,.frontend-grid-icons .icon-ms{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-mt,.frontend-grid-icons .icon-mt{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-mx,.frontend-grid-icons .icon-mx{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-my,.frontend-grid-icons .icon-my{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pb,.frontend-grid-icons .icon-pb{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pe,.frontend-grid-icons .icon-pe{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-ps,.frontend-grid-icons .icon-ps{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pt,.frontend-grid-icons .icon-pt{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-px,.frontend-grid-icons .icon-px{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-py,.frontend-grid-icons .icon-py{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.icon-info{background-image:url('data:image/svg+xml;utf8,')}.module{margin:0 0 20px}.djangocms-frontend-row .form-row.field-create .icon{position:absolute;font-size:30px;margin-block-start:28px;margin-inline-start:4px}.djangocms-frontend-row .form-row.field-create input[name=create]{width:130px!important;padding-inline-end:5px!important;text-align:start}.djangocms-frontend-column .form-row.field-xs_col,.djangocms-frontend-column .form-row.field-xs_me,.djangocms-frontend-column .form-row.field-xs_ms,.djangocms-frontend-column .form-row.field-xs_offset,.djangocms-frontend-column .form-row.field-xs_order,.djangocms-frontend-row .form-row.field-row_cols_xs{position:relative;display:-ms-flexbox;display:flex;padding:0;min-width:800px}.djangocms-frontend-column .form-row.field-xs_col .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_me .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_ms .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_offset .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_order .field-box:first-child,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box:first-child{width:115px!important}.djangocms-frontend-column .form-row.field-xs_col .field-box,.djangocms-frontend-column .form-row.field-xs_col .fieldBox,.djangocms-frontend-column .form-row.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_me .fieldBox,.djangocms-frontend-column .form-row.field-xs_ms .field-box,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox,.djangocms-frontend-column .form-row.field-xs_offset .field-box,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox,.djangocms-frontend-column .form-row.field-xs_order .field-box,.djangocms-frontend-column .form-row.field-xs_order .fieldBox,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox{position:relative;box-sizing:content-box;width:86px!important;-ms-flex:none;flex:none;padding:15px 10px;margin:0!important;border-bottom:1px solid #eee;float:left!important}.djangocms-frontend-column .form-row.field-xs_col .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_col .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_me .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_me .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_ms .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_ms .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_offset .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_offset .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_order .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_order .fieldBox input:not([type=checkbox]),.djangocms-frontend-row .form-row.field-row_cols_xs .field-box input:not([type=checkbox]),.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox input:not([type=checkbox]){text-align:end;padding-inline-end:5px!important;box-sizing:border-box;width:100%}.djangocms-frontend-column .form-row.field-xs_col .field-box label,.djangocms-frontend-column .form-row.field-xs_col .fieldBox label,.djangocms-frontend-column .form-row.field-xs_me .field-box label,.djangocms-frontend-column .form-row.field-xs_me .fieldBox label,.djangocms-frontend-column .form-row.field-xs_ms .field-box label,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox label,.djangocms-frontend-column .form-row.field-xs_offset .field-box label,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox label,.djangocms-frontend-column .form-row.field-xs_order .field-box label,.djangocms-frontend-column .form-row.field-xs_order .fieldBox label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box label,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox label{font-size:12px!important;font-weight:400!important;color:#ccc!important;position:absolute;inset-inline-start:15px;inset-block-end:17px;text-transform:lowercase}.djangocms-frontend-column .form-row.field-xs_col .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_col .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_me .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_me .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_ms .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_offset .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_order .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_order .fieldBox .disabled,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box .disabled,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox .disabled{color:#ccc;background:#eee}.djangocms-frontend-column .form-row.field-xs_col .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_col .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_me .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_me .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_ms .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_offset .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_order .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_order .fieldBox:last-child,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box:last-child,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox:last-child{border-inline-end:none}.djangocms-frontend-column .form-row.field-xs_col .errors,.djangocms-frontend-column .form-row.field-xs_me .errors,.djangocms-frontend-column .form-row.field-xs_ms .errors,.djangocms-frontend-column .form-row.field-xs_offset .errors,.djangocms-frontend-column .form-row.field-xs_order .errors,.djangocms-frontend-row .form-row.field-row_cols_xs .errors{margin-bottom:0}.djangocms-frontend-column .form-row.field-xs_col .errorlist,.djangocms-frontend-column .form-row.field-xs_me .errorlist,.djangocms-frontend-column .form-row.field-xs_ms .errorlist,.djangocms-frontend-column .form-row.field-xs_offset .errorlist,.djangocms-frontend-column .form-row.field-xs_order .errorlist,.djangocms-frontend-row .form-row.field-row_cols_xs .errorlist{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.djangocms-frontend-column .form-row.field-xs_col.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_me.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_ms.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_offset.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_order.field-xs_me .field-box,.djangocms-frontend-row .form-row.field-row_cols_xs.field-xs_me .field-box{border-bottom:none}.djangocms-frontend-column .form-row.field-xs_col .field-box-label,.djangocms-frontend-column .form-row.field-xs_me .field-box-label,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label,.djangocms-frontend-column .form-row.field-xs_order .field-box-label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label{display:-ms-flexbox;display:flex;margin-top:auto;color:#999}.djangocms-frontend-column .form-row.field-xs_col .field-box-label a,.djangocms-frontend-column .form-row.field-xs_me .field-box-label a,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label a,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label a,.djangocms-frontend-column .form-row.field-xs_order .field-box-label a,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label a{width:100%;margin-top:auto;color:#999}.djangocms-frontend-column .form-row.field-xs_col .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_me .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_order .field-box-label a a,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label a a{width:100%;margin-top:auto}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_col .field-md_me,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_me .field-md_me,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_order .field-md_me,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms{text-align:start}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-md_me label,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-md_me label,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-md_me label,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms label{inset-inline-start:30px;inset-block-start:14px}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-md_me input,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-md_me input,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-md_me input,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms input{position:relative;box-sizing:border-box;top:-3px}.grid-reset{position:absolute;inset-inline-end:5px;inset-block-start:0}.icon-thead{text-align:center;margin-bottom:15px}.icon-thead .icon{font-size:30px}.icon-thead .icon-size-sm{transform:rotate(90deg)}.icon-title{display:block;font-size:12px;color:#999;padding:5px 0 0}.djangocms-frontend-preview{position:fixed;inset-block-start:0;inset-inline-end:0;z-index:10;text-align:center;border-radius:0 0 0 3px;padding:10px 20px 27px;border:1px solid var(--dca-gray,var(--hairline-color,#ccc));border-block-start:none;border-inline-end:none;background:var(--body-bg,#fff)}@media (prefers-color-scheme:dark){.djangocms-frontend-preview{background:var(--body-bg,#000)}}.djangocms-frontend-preview h2{font-size:14px;min-width:150px;margin:0 0 12px}.djangocms-frontend-preview .b4-preview{margin:0 0 -15px}.djangocms-frontend-preview .b4-close{position:absolute;inset-inline-end:10px;inset-block-start:8px;z-index:100;display:block;color:#5e5e5e;font-size:12px;line-height:20px;font-weight:700;text-transform:uppercase;width:20px;height:20px;border-radius:3px;background:#ddd}.djangocms-frontend-preview .b4-close:hover{color:#fff!important;text-decoration:none;background:#0bf}.djangocms-frontend-preview .btn>span{vertical-align:middle}.djangocms-frontend-preview .btn>span>.icon{vertical-align:middle}.djangocms-frontend-preview .btn>span svg,.djangocms-frontend-preview .btn>span use{fill:currentColor}.djangocms-frontend-blockquote textarea{height:110px}#id_link_type{padding:0;margin:0;border:none}#id_link_type li{padding:0;margin:0 15px 5px 0;border:none}#id_link_type label input{position:relative;top:-4px}a[data-pk]{position:relative}a[data-pk]:after{content:attr(data-pk);visibility:hidden;width:auto;font-weight:400;font-size:80%;background-color:var(--dca-white,var(--body-bg,#fff));color:var(--dca-gray,var(--body-fg,#333));border:solid 1px var(--dca-gray,var(--body-fg,#333));text-align:center;padding:5px 10px;position:absolute;z-index:1;top:110%;inset-inline-start:50%;margin-inline-start:-50%}a[data-pk]:hover:after{visibility:visible}.djangocms-admin-style .form-row.field-plugin_title input[name=plugin_title_0]{margin-bottom:.5em!important}.djangocms-admin-style .form-row.field-plugin_title input[name=plugin_title_1]{width:calc(100% - 2em)!important}body:not(.djangocms-admin-style) .form-row.field-plugin_title input[name=plugin_title_1]{width:calc(100% - 200px - 1em)!important;margin-inline-start:1em}.frontend-icon-picker{text-align:center;display:inline-block}.frontend-icon-picker .icon-container{position:relative;margin:.5em auto;width:7em;height:7em;border:1px var(--dca-gray-light,var(--border-color,#d3d3d3)) solid;transition:background-color .15s,color .15s}.frontend-icon-picker .icon-container .icon-preview{width:7em;height:7em;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.frontend-icon-picker .icon-container .icon-preview .icon-box{font-size:500%;line-height:1.3;margin:0;text-align:center}.frontend-icon-picker .icon-container .icon-preview .icon-box i,.frontend-icon-picker .icon-container .icon-preview .icon-box span{font-size:unset}.frontend-icon-picker .icon-container .icon-preview .empty-box{text-align:center;overflow:hidden;text-overflow:ellipsis;line-height:1;font-size:100%}.frontend-icon-picker .icon-container .icon-preview .empty-box.hidden{display:none}.frontend-icon-picker .icon-container .icon-preview:hover{background:var(--dca-gray-light,var(--border-color,#d3d3d3));cursor:pointer}.frontend-icon-picker .icon-container .icon-close-indicator{display:block;border-radius:50%;color:var(--dca-black,var(--body-fg,#000));background-color:var(--dca-white,var(--body-bg,#fff));padding:.3rem;border:1px solid var(--dca-black,var(--body-fg,#000));transform:translate(-50%,-50%);top:0;inset-inline-start:100%;width:.6em;height:.6em;line-height:.5em;position:absolute;transition:background-color .15s}.frontend-icon-picker .icon-container .icon-close-indicator:before{content:"×"}.frontend-icon-picker .icon-container .icon-close-indicator:hover{background:var(--delete-button-bg,red);color:var(--delete-button-fg,#fff);cursor:pointer}.uip-modal{position:fixed;height:100%;width:100%;inset-block-end:0;inset-inline-start:0;background-color:rgba(0,0,0,.8);z-index:9999;-webkit-user-select:none;-ms-user-select:none;user-select:none;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.uip-modal *,.uip-modal :after,.uip-modal :before{box-sizing:border-box}.uip-modal.uip-close{opacity:0;visibility:hidden;transition:all .4s ease-in-out}.uip-modal.uip-open{opacity:1;visibility:visible;transition:all .4s ease-in-out}.uip-modal .uip-modal--content{position:absolute;border-radius:3px;box-shadow:2px 8px 23px 3px rgba(0,0,0,.2);overflow:hidden;font-family:Roboto,Arial,Helvetica,Verdana,sans-serif;background-color:var(--dca-gray-lightest,var(--darkened-bg,#f8f8f8));width:100%;margin:auto;left:0;right:0;margin-bottom:2em}.uip-modal .uip-modal--content .uip-modal--header{padding:15px 15px;background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 0 8px rgba(0,0,0,.1);position:relative;z-index:1;font-size:15px;color:var(--dca-gray,var(--body-quiet-color,#666));font-weight:500;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-logo-title{padding-top:2px;line-height:1;text-transform:uppercase;font-weight:700;cursor:pointer}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-close-btn{cursor:pointer}.uip-modal .uip-modal--content .uip-modal--body{font-size:12px;line-height:1.5;box-sizing:border-box;padding:0;height:70vh;display:-ms-flexbox;display:flex;min-height:50px;max-height:85vh;overflow:auto}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar{-ms-flex-negative:0;flex-shrink:0;max-width:25%}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs{margin-top:30px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item{padding:15px;font-size:14px;color:var(--dca-gray,var(--body-quiet-color,#666));text-align:start;cursor:pointer;position:relative;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item i{font-size:20px;padding-inline-end:15px;color:var(--dca-gray-lighter,var(--border-color,#ccc))}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item img{padding-inline-end:15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active{background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 6px 20px 0 rgba(0,0,0,.1)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active:after{content:"";position:absolute;height:100%;width:5px;inset-block-start:0;inset-inline-start:0;background-color:#0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active i{color:#0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item:only-child{display:none}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding:30px 80px 0;width:100%}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner{overflow:auto;margin:25px -15px 0;padding:0 15px 15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview{display:-ms-grid;display:grid;grid-gap:20px;margin:20px 0}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item{position:relative;padding:10px;background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 1px 12px rgba(0,0,0,.05);border-radius:3px;cursor:pointer;transition:all .3s;overflow:hidden}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item:hover{box-shadow:0 1px 14px rgba(0,0,0,.16)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item.universal-selected{box-shadow:0 1px 12px rgba(0,0,0,.05),0 0 0 3px #0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-align:center;align-items:center;padding:1px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item__icon,.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner i{font-size:25px;color:var(--dca-gray-darkest,var(--body-fg,#333))}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item-name{color:var(--dca-gray,var(--body-quiet-color,#666));font-size:11px;padding:13px 0 0;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search{position:relative}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input{width:100%;padding:8px 15px;background-color:var(--dca-white,var(--bg-color,#fff));border:none}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input:-ms-input-placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input::placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search img{position:absolute;top:50%;transform:translateY(-50%);inset-inline-end:10px}.uip-modal .uip-modal--footer{border-top:1px solid var(--dca-gray-lighter,var(--border-color,#ccc));text-align:center;background-color:var(--dca-white,var(--bg-color,#fff));border:none;display:none;-ms-flex-pack:end;justify-content:flex-end;padding:5px;box-shadow:0 0 8px rgba(0,0,0,.1);position:relative;display:-ms-flexbox;display:flex}.uip-modal .uip-modal--footer button.uip-insert-icon-button{padding:10px 35px!important;color:var(--dca-white,var(--bg-color,#fff))!important;background-color:#0bf!important;border:none;cursor:pointer;outline:0}.uip-modal .uip-modal--footer .universal-button{height:40px;margin-inline-start:5px}.uip-modal .uip-modal--footer .universal-button-success{padding:12px 36px;color:var(--dca-white,var(--bg-color,#fff));width:initial}.uip-modal .uip-modal--footer .universal-button-success:hover{background-color:#0bf}@media (min-width:1440px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:1200px}}@media (max-width:1439px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:990px}.uip-modal--icon-preview-wrap{padding:30px 50px 0}}@media (max-width:1023px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:740px}}@media (max-width:767px){.uip-modal--icon-preview-wrap{padding:15px!important}.uip-modal--sidebar{display:none}}@media (min-width:1440px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[7];grid-template-columns:repeat(7,1fr)}}@media (max-width:1439px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[6];grid-template-columns:repeat(6,1fr)}}@media (max-width:1024px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[5];grid-template-columns:repeat(5,1fr)}}@media (max-width:767px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[4];grid-template-columns:repeat(4,1fr)}}@media (max-width:479px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[3];grid-template-columns:repeat(3,1fr)}}@media (max-width:1439px){.uip-modal--sidebar-tab-item{padding:15px 15px 15px 25px;font-size:11px}.uip-modal--sidebar-tab-item i{font-size:15px}}@media (max-width:1024px){.uip-modal--sidebar-tab-item i,.uip-modal--sidebar-tab-item img{display:none}}.sr-only{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}ul.nav{margin-bottom:1em}ul.nav>li.nav-item{list-style-type:none;padding:inherit}.colM ul:not(.object-tools).nav{margin-top:0;margin-bottom:20px}ul.nav .nav-item{margin-inline-end:1rem}ul.nav .nav-link{position:relative;text-decoration:none}ul.nav .nav-link span.indicator{display:none;border-radius:50%;padding:.5rem;border:1px solid var(--dca-white,var(--body-bg,#fff));transform:translate(-50%,-50%);inset-block-start:0;inset-inline-start:100%;position:absolute}ul.nav .nav-link span.indicator.error{background-color:var(--bs-danger)}ul.nav .nav-link span.indicator.attributes{background-color:var(--bs-info);display:block}ul.nav .nav-link.error>span.indicator{display:block}ul.nav.nav-pills .nav-link:not(.active){border-style:solid;border-width:1px}body:not(.djangocms-admin-style) ul.djangocms-frontend.nav-tabs+div.tab-content .tab-pane{border-left-style:solid;border-bottom-style:solid;border-right-style:solid;border-left-color:var(--hairline-color);border-bottom-color:var(--hairline-color);border-right-color:var(--hairline-color);border-width:1px}body:not(.djangocms-admin-style) ul.djangocms-frontend.nav-tabs+div.tab-content .tab-pane fieldset:last-child{margin-bottom:0}div.tab-pk{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;color:var(--dca-gray-darker,var(--body-fg,#333));font-size:80%;margin-inline-start:auto}.djangocms-admin-style .colM ul.nav:not(.object-tools):not(.messagelist){margin-top:0}.djangocms-admin-style .colM ul.nav:not(.object-tools):not(.messagelist) li.nav-item{border-top:none}input[type=number].auto-field+span{display:none;position:absolute;inset-block-end:0;inset-inline-end:0;text-align:end;margin-inline-end:31px;margin-block-end:23px;cursor:pointer}body:not(.djangocms-admin-style) input[type=number].auto-field+span{margin-bottom:23px}@media (max-width:1024px){body:not(.djangocms-admin-style) input[type=number].auto-field+span{margin-bottom:24px}}input[type=number].auto-field+span:after{content:"auto"}input[type=number].auto-field.auto{color:var(--dca-white,var(--body-bg,#fff));caret-color:var(--dca-black,var(--body-fg,#000))}input[type=number].auto-field.auto+span{display:block} \ No newline at end of file diff --git a/private/sass/components/_icon-picker.scss b/private/sass/components/_icon-picker.scss index d7815239..216e2941 100644 --- a/private/sass/components/_icon-picker.scss +++ b/private/sass/components/_icon-picker.scss @@ -3,9 +3,7 @@ display: inline-block; .icon-container { position: relative; - margin-bottom: 0.5em; - margin-left: auto; - margin-right: auto; + margin: 0.5em auto; width: 7em; height: 7em; border: 1px var(--dca-gray-light, var(--border-color, lightgray)) solid; From 68e988938481831e84e3a5fa6a2fcce8029b4964 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Thu, 21 Mar 2024 16:33:20 +0100 Subject: [PATCH 21/66] Prepopulate badge --- djangocms_frontend/contrib/badge/forms.py | 1 + djangocms_frontend/contrib/link/forms.py | 1 + 2 files changed, 2 insertions(+) diff --git a/djangocms_frontend/contrib/badge/forms.py b/djangocms_frontend/contrib/badge/forms.py index 2fd21ac8..f71a6b45 100644 --- a/djangocms_frontend/contrib/badge/forms.py +++ b/djangocms_frontend/contrib/badge/forms.py @@ -32,6 +32,7 @@ class Meta: badge_text = forms.CharField( label=_("Badge text"), max_length=255, + widget=forms.TextInput(attrs={"class": "js-prepopulate-selected-text"}), ) badge_context = forms.ChoiceField( label=_("Context"), diff --git a/djangocms_frontend/contrib/link/forms.py b/djangocms_frontend/contrib/link/forms.py index c5eb137f..f2c9c942 100644 --- a/djangocms_frontend/contrib/link/forms.py +++ b/djangocms_frontend/contrib/link/forms.py @@ -344,6 +344,7 @@ class Meta: name = forms.CharField( label=_("Display name"), required=False, + widget=forms.TextInput(attrs={"class": "js-prepopulate-selected-text"}), ) template = forms.ChoiceField( label=_("Layout"), From 1d735ba868c119c02b393a8be0cf15c75fc7c8c8 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Wed, 24 Apr 2024 13:36:04 +0200 Subject: [PATCH 22/66] Add empty selection to internal link choices (fixes #206) --- djangocms_frontend/contrib/link/helpers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/djangocms_frontend/contrib/link/helpers.py b/djangocms_frontend/contrib/link/helpers.py index f854c4fd..f25ed5e0 100644 --- a/djangocms_frontend/contrib/link/helpers.py +++ b/djangocms_frontend/contrib/link/helpers.py @@ -10,6 +10,8 @@ from django.utils.encoding import force_str from django.utils.html import mark_safe +from djangocms_frontend.settings import EMPTY_CHOICE + LINK_MODELS = getattr(django_settings, "DJANGOCMS_FRONTEND_LINK_MODELS", []) @@ -66,7 +68,7 @@ def get_link_choices(request, term="", lang=None, nbsp=None): if nbsp is None: nbsp = "" if term else "\u2000" - available_objects = [] + available_objects = [dict(id=EMPTY_CHOICE[0][0], text=EMPTY_CHOICE[0][1])] # Now create our list of cms pages type_id = ContentType.objects.get_for_model(Page).id for value, descr in get_page_choices(lang): From 0eb5feb780766e35e3c90ceb6529077fa6f72c4c Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Thu, 25 Apr 2024 01:09:11 +0200 Subject: [PATCH 23/66] Fix pypi actions --- .github/workflows/publish-to-live-pypi.yml | 7 ++----- .github/workflows/publish-to-test-pypi.yml | 2 -- djangocms_frontend/contrib/link/views.py | 2 -- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/publish-to-live-pypi.yml b/.github/workflows/publish-to-live-pypi.yml index 2fbbc5d8..3d186a5a 100644 --- a/.github/workflows/publish-to-live-pypi.yml +++ b/.github/workflows/publish-to-live-pypi.yml @@ -11,10 +11,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.12' - name: Install pypa/build run: >- @@ -34,6 +34,3 @@ jobs: - name: Publish distribution 📦 to PyPI if: startsWith(github.ref, 'refs/tags') uses: pypa/gh-action-pypi-publish@release/v1 - with: - user: __token__ - password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/.github/workflows/publish-to-test-pypi.yml b/.github/workflows/publish-to-test-pypi.yml index 3f5b04f1..acca7622 100644 --- a/.github/workflows/publish-to-test-pypi.yml +++ b/.github/workflows/publish-to-test-pypi.yml @@ -34,7 +34,5 @@ jobs: - name: Publish distribution 📦 to Test PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: - user: __token__ - password: ${{ secrets.TEST_PYPI_API_TOKEN }} repository_url: https://test.pypi.org/legacy/ skip_existing: true diff --git a/djangocms_frontend/contrib/link/views.py b/djangocms_frontend/contrib/link/views.py index 72779ff7..87102528 100644 --- a/djangocms_frontend/contrib/link/views.py +++ b/djangocms_frontend/contrib/link/views.py @@ -20,8 +20,6 @@ def get(self, request, *args, **kwargs): } """ - # TODO Check permissions - # ====================== self.term = kwargs.get("term", request.GET.get("term", "")).strip() results = get_link_choices(request, self.term) return JsonResponse( From 6554f84ba65a81d49278c181223ae39eb1d63579 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Thu, 25 Apr 2024 01:11:42 +0200 Subject: [PATCH 24/66] Add write permissions to pypi actions --- .github/workflows/publish-to-live-pypi.yml | 2 ++ .github/workflows/publish-to-test-pypi.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/publish-to-live-pypi.yml b/.github/workflows/publish-to-live-pypi.yml index 3d186a5a..066cebb4 100644 --- a/.github/workflows/publish-to-live-pypi.yml +++ b/.github/workflows/publish-to-live-pypi.yml @@ -9,6 +9,8 @@ jobs: build-n-publish: name: Build and publish Python 🐍 distributions 📦 to pypi runs-on: ubuntu-latest + permissions: + id-token: write steps: - uses: actions/checkout@v4 - name: Set up Python 3.12 diff --git a/.github/workflows/publish-to-test-pypi.yml b/.github/workflows/publish-to-test-pypi.yml index acca7622..b352feba 100644 --- a/.github/workflows/publish-to-test-pypi.yml +++ b/.github/workflows/publish-to-test-pypi.yml @@ -9,6 +9,8 @@ jobs: build-n-publish: name: Build and publish Python 🐍 distributions 📦 to TestPyPI runs-on: ubuntu-latest + permissions: + id-token: write steps: - uses: actions/checkout@v4 - name: Set up Python 3.10 From 83e99f03666374cbee45ab588dc8fc14890f6c0a Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Thu, 25 Apr 2024 01:24:26 +0200 Subject: [PATCH 25/66] Add env. --- .github/workflows/publish-to-live-pypi.yml | 3 +++ .github/workflows/publish-to-test-pypi.yml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.github/workflows/publish-to-live-pypi.yml b/.github/workflows/publish-to-live-pypi.yml index 066cebb4..45a7372e 100644 --- a/.github/workflows/publish-to-live-pypi.yml +++ b/.github/workflows/publish-to-live-pypi.yml @@ -9,6 +9,9 @@ jobs: build-n-publish: name: Build and publish Python 🐍 distributions 📦 to pypi runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/djangocms-frontend permissions: id-token: write steps: diff --git a/.github/workflows/publish-to-test-pypi.yml b/.github/workflows/publish-to-test-pypi.yml index b352feba..7067e75a 100644 --- a/.github/workflows/publish-to-test-pypi.yml +++ b/.github/workflows/publish-to-test-pypi.yml @@ -9,6 +9,9 @@ jobs: build-n-publish: name: Build and publish Python 🐍 distributions 📦 to TestPyPI runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/djangocms-frontend permissions: id-token: write steps: From f3d5a93eff392fb361a08711caffeca7e7497713 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Mon, 29 Apr 2024 15:20:02 +0200 Subject: [PATCH 26/66] fix: Unescape JSONView for django admin's autocomplete widget --- djangocms_frontend/contrib/link/helpers.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/djangocms_frontend/contrib/link/helpers.py b/djangocms_frontend/contrib/link/helpers.py index 3f0fdd61..8f431f30 100644 --- a/djangocms_frontend/contrib/link/helpers.py +++ b/djangocms_frontend/contrib/link/helpers.py @@ -7,7 +7,6 @@ from django.contrib.contenttypes.models import ContentType from django.core.exceptions import FieldError, ObjectDoesNotExist from django.utils.encoding import force_str -from django.utils.html import mark_safe from djangocms_frontend.settings import EMPTY_CHOICE @@ -62,6 +61,15 @@ def get_object_for_value(value): return None +def unescape(text, nbsp): + return (text.replace(" ", nbsp) + .replace("&", "&") + .replace("<", "<") + .replace(">", ">") + .replace(""", '"') + .replace("'", "'")) + + def get_link_choices(request, term="", lang=None, nbsp=None): global _querysets @@ -78,7 +86,9 @@ def get_link_choices(request, term="", lang=None, nbsp=None): "children": [ dict( id=f"{type_id}-{page}", - text=mark_safe(name.replace(" ", nbsp)), + # django admin's autocomplete view requires unescaped strings + # get_page_choices escepes strings, so we undo the escape + text=unescape(name, nbsp), ) for page, name in descr if not isinstance(term, str) or term.upper() in name.upper() From c6158956c8c6aeb6f62ffb9116ab3bcb3b680437 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Mon, 29 Apr 2024 15:46:10 +0200 Subject: [PATCH 27/66] Add tests --- djangocms_frontend/contrib/link/helpers.py | 4 +- tests/link/test_plugins.py | 56 +++++++++++++++++----- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/djangocms_frontend/contrib/link/helpers.py b/djangocms_frontend/contrib/link/helpers.py index 8f431f30..437b0a4a 100644 --- a/djangocms_frontend/contrib/link/helpers.py +++ b/djangocms_frontend/contrib/link/helpers.py @@ -8,8 +8,6 @@ from django.core.exceptions import FieldError, ObjectDoesNotExist from django.utils.encoding import force_str -from djangocms_frontend.settings import EMPTY_CHOICE - LINK_MODELS = getattr(django_settings, "DJANGOCMS_FRONTEND_LINK_MODELS", []) @@ -75,7 +73,7 @@ def get_link_choices(request, term="", lang=None, nbsp=None): if nbsp is None: nbsp = "" if term else "\u2000" - available_objects = [dict(id=EMPTY_CHOICE[0][0], text=EMPTY_CHOICE[0][1])] + available_objects = [] # Now create our list of cms pages type_id = ContentType.objects.get_for_model(Page).id for value, descr in get_page_choices(lang): diff --git a/tests/link/test_plugins.py b/tests/link/test_plugins.py index cdf97806..d69d860c 100644 --- a/tests/link/test_plugins.py +++ b/tests/link/test_plugins.py @@ -1,5 +1,6 @@ from cms.api import add_plugin from cms.test_utils.testcases import CMSTestCase +from cms.utils.urlutils import admin_reverse from django.http import HttpRequest from djangocms_frontend import settings @@ -116,19 +117,6 @@ def test_plugin(self): f'Cound not find class="btn btn-outline-primary" in {response.content.decode("utf-8")}', ) - def test_smart_link_field(self): - slf = SmartLinkField() - choices = get_choices(None) - self.assertEqual("example.com", choices[1][0]) # Site name - self.assertIn(("2-1", "home"), choices[1][1]) - - cleaned = slf.clean("2-1") - self.assertEqual(dict(model="cms.page", pk=1), cleaned) - - self.assertEqual(slf.prepare_value("blabla"), "") - self.assertEqual(slf.prepare_value(dict(model="cms.page", pk=1)), "2-1") - self.assertEqual(slf.prepare_value(self.home), "2-1") - def test_link_form(self): request = HttpRequest() request.POST = { @@ -165,3 +153,45 @@ def test_link_form(self): request.POST["external_link"] = None form = LinkForm(request.POST) self.assertFalse(form.is_valid()) # no anchor for mail + + +class AutocompleteViewTestCase(TestFixture, CMSTestCase): + + def test_smart_link_field(self): + slf = SmartLinkField() + choices = get_choices(None) + self.assertEqual("example.com", choices[0][0]) # Site name + self.assertIn(("2-1", "home"), choices[0][1]) + + cleaned = slf.clean("2-1") + self.assertEqual(dict(model="cms.page", pk=1), cleaned) + + self.assertEqual(slf.prepare_value("blabla"), "") + self.assertEqual(slf.prepare_value(dict(model="cms.page", pk=1)), "2-1") + self.assertEqual(slf.prepare_value(self.home), "2-1") + + def test_autocomplete_view(self): + tricky_title = """d'acceuil: """ + + page = self.create_page( + title=tricky_title, + template="page.html", + ) + self.publish(page, self.language) + autocomplete_url = admin_reverse("link_link_autocomplete") + + with self.login_user_context(self.superuser): + response = self.client.get(autocomplete_url) + + autocomplete_result = response.json() + choices = autocomplete_result.get("results")[0] + + self.assertFalse((autocomplete_result.get("pagination") or {}).get("more")) + self.assertEqual( + choices.get("children"), + [ + {'id': '2-1', 'text': 'home'}, + {'id': '2-2', 'text': 'content'}, + {'id': '2-3', 'text': tricky_title}, + ] + ) From 659ed56d9786652461667890b911b9985a5f180f Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Mon, 29 Apr 2024 15:52:31 +0200 Subject: [PATCH 28/66] Fix tests --- tests/link/test_plugins.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/tests/link/test_plugins.py b/tests/link/test_plugins.py index d69d860c..1a0c5eba 100644 --- a/tests/link/test_plugins.py +++ b/tests/link/test_plugins.py @@ -172,11 +172,14 @@ def test_smart_link_field(self): def test_autocomplete_view(self): tricky_title = """d'acceuil: """ - page = self.create_page( title=tricky_title, template="page.html", ) + expected_choices = [ + "home", "content", tricky_title, + ] + self.publish(page, self.language) autocomplete_url = admin_reverse("link_link_autocomplete") @@ -187,11 +190,6 @@ def test_autocomplete_view(self): choices = autocomplete_result.get("results")[0] self.assertFalse((autocomplete_result.get("pagination") or {}).get("more")) - self.assertEqual( - choices.get("children"), - [ - {'id': '2-1', 'text': 'home'}, - {'id': '2-2', 'text': 'content'}, - {'id': '2-3', 'text': tricky_title}, - ] - ) + + for expected, sent in zip(expected_choices, choices.get("children")): + self.assertEqual(expected, sent.get("text")) From 981c00c5e53ca4cbf26fbf0a1ccd9db23491fa6f Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Mon, 28 Oct 2024 00:08:32 +0100 Subject: [PATCH 29/66] Add support for djangocms-link 5 --- .../common/bootstrap5/background.py | 11 +- .../common/bootstrap5/responsive.py | 2 +- djangocms_frontend/common/title.py | 1 + .../contrib/link/cms_plugins.py | 20 +-- djangocms_frontend/contrib/link/forms.py | 126 ++---------------- .../contrib/link/frameworks/bootstrap5.py | 1 - djangocms_frontend/contrib/link/helpers.py | 96 +------------ .../navigation/offcanvas/brand.html | 2 +- djangocms_frontend/models.py | 2 +- setup.py | 5 + tests/component/test_plugins.py | 2 +- tests/fixtures.py | 4 +- tests/link/test_models.py | 2 +- tests/link/test_plugins.py | 10 +- tests/navigation/test_plugins.py | 2 +- tests/requirements/base.txt | 2 +- tests/test_plugin_tag.py | 7 +- tests/test_settings.py | 1 + 18 files changed, 47 insertions(+), 249 deletions(-) diff --git a/djangocms_frontend/common/bootstrap5/background.py b/djangocms_frontend/common/bootstrap5/background.py index d930c808..235aff22 100644 --- a/djangocms_frontend/common/bootstrap5/background.py +++ b/djangocms_frontend/common/bootstrap5/background.py @@ -4,7 +4,7 @@ from djangocms_frontend import settings from djangocms_frontend.fields import ButtonGroup, ColoredButtonGroup -from djangocms_frontend.helpers import first_choice, insert_fields +from djangocms_frontend.helpers import insert_fields class BackgroundMixin: @@ -23,9 +23,8 @@ def get_fieldsets(self, request, obj=None): def render(self, context, instance, placeholder): if getattr(instance, "background_context", ""): instance.add_classes(f"bg-{instance.background_context}") - if getattr(instance, "background_opacity", "100") != "100": - if instance.background_opacity: - instance.add_classes(f"bg-opacity-{instance.background_opacity}") + if getattr(instance, "background_opacity", ""): + instance.add_classes(f"bg-opacity-{instance.background_opacity}") if getattr(instance, "background_shadow", ""): if instance.background_shadow == "reg": instance.add_classes("shadow") @@ -54,8 +53,8 @@ class Meta: background_opacity = forms.ChoiceField( label=_("Background opacity"), required=False, - choices=settings.framework_settings.OPACITY_CHOICES, - initial=first_choice(settings.framework_settings.OPACITY_CHOICES), + choices=settings.EMPTY_CHOICE + settings.framework_settings.OPACITY_CHOICES, + initial=settings.EMPTY_CHOICE[0][0], widget=ButtonGroup(attrs=dict(property="opacity")), help_text=_("Opacity of card background color (only if no outline selected)"), ) diff --git a/djangocms_frontend/common/bootstrap5/responsive.py b/djangocms_frontend/common/bootstrap5/responsive.py index e9a0a04f..2fcdb8e6 100644 --- a/djangocms_frontend/common/bootstrap5/responsive.py +++ b/djangocms_frontend/common/bootstrap5/responsive.py @@ -36,7 +36,7 @@ def get_fieldsets(self, request, obj=None): ) def render(self, context, instance, placeholder): - if instance.config.get("responsive_visibility", None) is not None: + if instance.config.get("responsive_visibility", None): instance.add_classes( get_display_classes( instance.responsive_visibility, diff --git a/djangocms_frontend/common/title.py b/djangocms_frontend/common/title.py index e63c88db..f9983231 100644 --- a/djangocms_frontend/common/title.py +++ b/djangocms_frontend/common/title.py @@ -61,6 +61,7 @@ class Meta: plugin_title = TitleField( label=_("Title"), required=False, + initial={"show": False, "title": ""}, help_text=_( "Optional title of the plugin for easier identification. " "Its title attribute " diff --git a/djangocms_frontend/contrib/link/cms_plugins.py b/djangocms_frontend/contrib/link/cms_plugins.py index dd6c0564..99f80bf5 100644 --- a/djangocms_frontend/contrib/link/cms_plugins.py +++ b/djangocms_frontend/contrib/link/cms_plugins.py @@ -12,13 +12,14 @@ from .. import link from . import forms, models, views from .constants import USE_LINK_ICONS +from .helpers import GetLinkMixin mixin_factory = settings.get_renderer(link) UILINK_FIELDS = ( ("name", "link_type"), - ("site", "url_grouper") if apps.is_installed("djangocms_url_manager") else ("external_link", "internal_link"), + ("site", "url_grouper") if apps.is_installed("djangocms_url_manager") else "link", ("link_context", "link_size"), ("link_outline", "link_block"), "link_stretched", @@ -33,20 +34,6 @@ }, ), ] -if not apps.is_installed("djangocms_url_manager"): - UILINK_FIELDSET += [ - ( - _("Link settings"), - { - "classes": ("collapse",), - "fields": ( - ("mailto", "phone"), - ("anchor", "target"), - ("file_link",), - ), - }, - ), - ] class LinkPluginMixin: @@ -65,6 +52,7 @@ class LinkPluginMixin: def render(self, context, instance, placeholder): if "request" in context: instance._cms_page = getattr(context["request"], "current_page", None) + context["link"] = instance.get_link() return super().render(context, instance, placeholder) def get_form(self, request, obj=None, change=False, **kwargs): @@ -85,7 +73,7 @@ def get_fieldsets(self, request, obj=None): return fieldsets -class TextLinkPlugin(mixin_factory("Link"), AttributesMixin, SpacingMixin, LinkPluginMixin, CMSUIPlugin): +class TextLinkPlugin(mixin_factory("Link"), AttributesMixin, SpacingMixin, LinkPluginMixin, GetLinkMixin, CMSUIPlugin): """ Components > "Button" Plugin https://getbootstrap.com/docs/5.0/components/buttons/ diff --git a/djangocms_frontend/contrib/link/forms.py b/djangocms_frontend/contrib/link/forms.py index f7e36efd..5936a3ce 100644 --- a/djangocms_frontend/contrib/link/forms.py +++ b/djangocms_frontend/contrib/link/forms.py @@ -7,17 +7,14 @@ from django.contrib.admin.widgets import SELECT2_TRANSLATIONS, AutocompleteMixin from django.contrib.contenttypes.models import ContentType from django.contrib.sites.models import Site -from django.core.exceptions import ObjectDoesNotExist, ValidationError +from django.core.exceptions import ObjectDoesNotExist from django.db import models -from django.db.models.fields.related import ManyToOneRel -from django.utils.encoding import force_str from django.utils.translation import get_language from django.utils.translation import gettext as _ +from djangocms_link.fields import LinkFormField # from djangocms_link.validators import IntranetURLValidator from entangled.forms import EntangledModelForm -from filer.fields.image import AdminFileFormField, FilerFileField -from filer.models import File from ... import settings from ...common import SpacingFormMixin @@ -28,11 +25,11 @@ TagTypeFormField, TemplateChoiceMixin, ) -from ...helpers import first_choice, get_related_object +from ...helpers import first_choice from ...models import FrontendUIItem from .. import link from .constants import LINK_CHOICES, LINK_SIZE_CHOICES, TARGET_CHOICES -from .helpers import get_choices, get_object_for_value +from .helpers import get_object_for_value mixin_factory = settings.get_forms(link) @@ -174,59 +171,18 @@ class AbstractLinkForm(EntangledModelForm): class Meta: entangled_fields = { "config": [ - "external_link", - "internal_link", - "file_link", - "anchor", - "mailto", - "phone", + "link", "target", ] } link_is_optional = False - # url_validators = [ - # IntranetURLValidator(intranet_host_re=HOSTNAME), - # ] - - external_link = forms.URLField( - label=_("External link"), - required=False, - # validators=url_validators, - help_text=_("Provide a link to an external source."), - ) - internal_link = SmartLinkField( - label=_("Internal link"), - required=False, - help_text=_("If provided, overrides the external link."), - ) - file_link = AdminFileFormField( - rel=ManyToOneRel(FilerFileField, File, "id"), - queryset=File.objects.all(), - to_field_name="id", - label=_("File link"), + link = LinkFormField( + label=_("Link"), + initial={}, required=False, - help_text=_("If provided links a file from the filer app."), ) - # other link types - anchor = forms.CharField( - label=_("Anchor"), - required=False, - help_text=_( - "Appends the value only after the internal or external link. " - 'Do not include a preceding "#" symbol.' - ), - ) - mailto = forms.EmailField( - label=_("Email address"), - required=False, - ) - phone = forms.CharField( - label=_("Phone"), - required=False, - ) - # advanced options target = forms.ChoiceField( label=_("Target"), choices=settings.EMPTY_CHOICE + TARGET_CHOICES, @@ -235,71 +191,7 @@ class Meta: def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.fields["internal_link"].choices = self.get_choices - - def get_choices(self): - if MINIMUM_INPUT_LENGTH == 0: - return get_choices(self.request) - if not self.is_bound: # find initial value - int_link_field = self.fields["internal_link"] - initial = self.get_initial_for_field(int_link_field, "internal_link") - if initial: # Initial set? - obj = get_related_object(dict(obj=initial), "obj") # get it! - if obj is not None: - value = int_link_field.prepare_value(initial) - return ((value, str(obj)),) - return () # nothing found - - def clean(self): - super().clean() - link_field_names = ( - "external_link", - "internal_link", - "mailto", - "phone", - "file_link", - ) - anchor_field_name = "anchor" - field_names_allowed_with_anchor = ( - "external_link", - "internal_link", - ) - anchor_field_verbose_name = force_str(self.fields[anchor_field_name].label) - anchor_field_value = self.cleaned_data.get(anchor_field_name, None) - link_fields = {key: self.cleaned_data.get(key, None) for key in link_field_names} - link_field_verbose_names = {key: force_str(self.fields[key].label) for key in link_fields.keys()} - provided_link_fields = {key: value for key, value in link_fields.items() if value} - - if len(provided_link_fields) > 1: - # Too many fields have a value. - verbose_names = sorted(link_field_verbose_names.values()) - error_msg = _("Only one of {0} or {1} may be given.").format( - ", ".join(verbose_names[:-1]), - verbose_names[-1], - ) - errors = {}.fromkeys(provided_link_fields.keys(), error_msg) - raise ValidationError(errors) - - if ( - len(provided_link_fields) == 0 - and not self.cleaned_data.get(anchor_field_name, None) - and not self.link_is_optional - ): - raise ValidationError(_("Please provide a link.")) - - if anchor_field_value: - for field_name in provided_link_fields.keys(): - if field_name not in field_names_allowed_with_anchor: - error_msg = _("%(anchor_field_verbose_name)s is not allowed together with %(field_name)s") % { - "anchor_field_verbose_name": anchor_field_verbose_name, - "field_name": link_field_verbose_names.get(field_name), - } - raise ValidationError( - { - anchor_field_name: error_msg, - field_name: error_msg, - } - ) + self.fields["link"].required = not self.link_is_optional class LinkForm(mixin_factory("Link"), SpacingFormMixin, TemplateChoiceMixin, AbstractLinkForm): diff --git a/djangocms_frontend/contrib/link/frameworks/bootstrap5.py b/djangocms_frontend/contrib/link/frameworks/bootstrap5.py index 1123d0c4..6dab2a29 100644 --- a/djangocms_frontend/contrib/link/frameworks/bootstrap5.py +++ b/djangocms_frontend/contrib/link/frameworks/bootstrap5.py @@ -28,6 +28,5 @@ def render(self, context, instance, placeholder): link_classes.append("d-block") if instance.config.get("link_stretched", False): link_classes.append("stretched-link") - context["link"] = instance.get_link() instance.add_classes(link_classes) return super().render(context, instance, placeholder) diff --git a/djangocms_frontend/contrib/link/helpers.py b/djangocms_frontend/contrib/link/helpers.py index d71c587c..04a1864c 100644 --- a/djangocms_frontend/contrib/link/helpers.py +++ b/djangocms_frontend/contrib/link/helpers.py @@ -2,6 +2,7 @@ from cms.forms.utils import get_page_choices from cms.models import Page +from django.apps import apps from django.conf import settings as django_settings from django.contrib.admin import site from django.contrib.contenttypes.models import ContentType @@ -138,99 +139,16 @@ def to_choices(json): class GetLinkMixin: - def __init__(self, *args, **kwargs): - self._cms_page = None - super().__init__(*args, **kwargs) - - def get_link(self): - if getattr(self, "url_grouper", None): + def get_link(self) -> str: + if "url_grouper" in self.config and self.config["url_grouper"] and apps.is_installed("djangocms_url_manager"): url_grouper = get_related_object(self.config, "url_grouper") if not url_grouper: return "" - # The next line is a workaround, since djangocms-url-manager does not provide a way of - # getting the current URL object. from djangocms_url_manager.models import Url - url = Url._base_manager.filter(url_grouper=url_grouper).order_by("pk").last() + url = Url.objects.filter(url_grouper=url_grouper).order_by("pk").last() if not url: # pragma: no cover return "" - # simulate the call to the unauthorized CMSPlugin.page property - cms_page = self.placeholder.page if self.placeholder_id else None - - # first, we check if the placeholder the plugin is attached to - # has a page. Thus, the check "is not None": - if cms_page is not None: - if getattr(cms_page, "node", None): - cms_page_site_id = getattr(cms_page.node, "site_id", None) - else: - cms_page_site_id = getattr(cms_page, "site_id", None) - # a plugin might not be attached to a page and thus has no site - # associated with it. This also applies to plugins inside - # static placeholders - else: - cms_page_site_id = None - return url.get_url(cms_page_site_id) or "" - - if getattr(self, "internal_link", None): - try: - ref_page = get_related_object(self.config, "internal_link") - link = ref_page.get_absolute_url() - except ( - KeyError, - TypeError, - ValueError, - AttributeError, - ObjectDoesNotExist, - ): - self.internal_link = None - return "" - - # simulate the call to the unauthorized CMSPlugin.page property - cms_page = self._cms_page or self.placeholder.page if self.placeholder_id else None - - # first, we check if the placeholder the plugin is attached to - # has a page. Thus, the check "is not None": - if cms_page is not None: - if getattr(cms_page, "node", None): - cms_page_site_id = getattr(cms_page.node, "site_id", None) - else: - cms_page_site_id = getattr(cms_page, "site_id", None) - # a plugin might not be attached to a page and thus has no site - # associated with it. This also applies to plugins inside - # static placeholders - else: - cms_page_site_id = None - - # now we do the same for the reference page the plugin links to - # in order to compare them later - if getattr(ref_page, "node", None): - ref_page_site_id = ref_page.node.site_id - elif getattr(ref_page, "site_id", None): - ref_page_site_id = ref_page.site_id - # if no external reference is found the plugin links to the - # current page - else: - ref_page_site_id = Site.objects.get_current().pk - - if ref_page_site_id != cms_page_site_id: - ref_site = Site.objects._get_site_by_id(ref_page_site_id).domain - link = f"//{ref_site}{link}" - - elif getattr(self, "file_link", None): - link = getattr(get_related_object(self.config, "file_link"), "url", "") - - elif getattr(self, "external_link", None): - link = self.external_link - - elif getattr(self, "phone", None): - link = "tel:{}".format(self.phone.replace(" ", "")) - - elif getattr(self, "mailto", None): - link = f"mailto:{self.mailto}" - - else: - link = "" - - if (not getattr(self, "phone", None) and not getattr(self, "mailto", None)) and getattr(self, "anchor", None): - link += f"#{self.anchor}" + return url.get_absolute_url() or "" - return link + from djangocms_link.helpers import get_link as djangocms_link_get_link + return djangocms_link_get_link(self.config.get("link", {}), Site.objects.get_current().pk) or "" diff --git a/djangocms_frontend/contrib/navigation/templates/djangocms_frontend/bootstrap5/navigation/offcanvas/brand.html b/djangocms_frontend/contrib/navigation/templates/djangocms_frontend/bootstrap5/navigation/offcanvas/brand.html index 1cd8da16..90f2d5c5 100644 --- a/djangocms_frontend/contrib/navigation/templates/djangocms_frontend/bootstrap5/navigation/offcanvas/brand.html +++ b/djangocms_frontend/contrib/navigation/templates/djangocms_frontend/bootstrap5/navigation/offcanvas/brand.html @@ -1,4 +1,4 @@ -{% load cms_tags sekizai_tags %}{% spaceless %}{% with link=instance.get_link %}{% if link %}{% else %} <{{ instance.tag_type }}{{ instance.get_attributes }}>{% endif %} +{% load cms_tags sekizai_tags %}{% spaceless %}{% with link=instance.get_link %}{% if link %}{% else %}<{{ instance.tag_type }}{{ instance.get_attributes }}>{% endif %} {% for plugin in instance.child_plugin_instances %} {% with parentloop=forloop parent=instance %}{% render_plugin plugin %}{% endwith %} {% empty %}{{ instance.simple_content }}{% endfor %} diff --git a/djangocms_frontend/models.py b/djangocms_frontend/models.py index 64e05afd..3239f292 100644 --- a/djangocms_frontend/models.py +++ b/djangocms_frontend/models.py @@ -99,7 +99,7 @@ def initialize_from_form(self, form=None): if not getattr(form._meta, "model", None): form._meta.model = self.__class__ form = form() # instantiate - entangled_fields = getattr(getattr(form, "Meta", None), "entangled_fields", {}).get("config", ()) + entangled_fields = getattr(getattr(form, "_meta", None), "entangled_fields", {}).get("config", ()) for field in entangled_fields: self.config.setdefault(field, {} if field == "attributes" else form[field].initial or "") return self diff --git a/setup.py b/setup.py index 1e49003b..20d7727e 100644 --- a/setup.py +++ b/setup.py @@ -18,8 +18,12 @@ "static-ace": [ "djangocms-static-ace", ], + "djangocms-link": [ + "djangocms-link>=5.0.0", + ], "cms-4": [ "django-cms>=4.1.0", + "djangocms-link>=5.0.0", "django-parler", "djangocms-versioning>=2.0.0", "djangocms-alias>=2.0.0", @@ -28,6 +32,7 @@ "cms-3": [ "django-cms<4", "djangocms-text", + "djangocms-link>=5.0.0", "django-parler", ], } diff --git a/tests/component/test_plugins.py b/tests/component/test_plugins.py index 61d175d6..ec5570d9 100644 --- a/tests/component/test_plugins.py +++ b/tests/component/test_plugins.py @@ -149,7 +149,7 @@ def test_simple_component_plugin(self): language=self.language, ) instance.initialize_from_form(MyButtonPlugin.form) - instance.config["internal_link"] = {"model": "cms.page", "pk": self.page.pk} + instance.config["link"] = {"internal_link": f"cms.page:{self.page.pk}"} instance.save() link = instance.get_link() diff --git a/tests/fixtures.py b/tests/fixtures.py index a041b842..216590d3 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -2,6 +2,7 @@ from django.apps import apps from django.contrib.contenttypes.models import ContentType from django.contrib.sites.models import Site +from djangocms_versioning.constants import PUBLISHED DJANGO_CMS4 = apps.is_installed("djangocms_versioning") @@ -97,7 +98,6 @@ def create_url( ): from djangocms_url_manager.models import Url, UrlGrouper from djangocms_url_manager.utils import is_versioning_enabled - from djangocms_versioning.constants import DRAFT from djangocms_versioning.models import Version if site is None: @@ -117,7 +117,7 @@ def create_url( Version.objects.create( content=url, created_by=self.superuser, - state=DRAFT, + state=PUBLISHED, content_type_id=ContentType.objects.get_for_model(Url).id, ) diff --git a/tests/link/test_models.py b/tests/link/test_models.py index c7da7bcc..6d193745 100644 --- a/tests/link/test_models.py +++ b/tests/link/test_models.py @@ -6,7 +6,7 @@ class LinkModelTestCase(TestCase): def test_instance(self): instance = Link.objects.create( - config=dict(name="Get it!", external_link="https://www.django-cms.com/") + config=dict(name="Get it!", link=dict(external_link="https://www.django-cms.com/")) ) self.assertEqual(str(instance), "Link (1)") self.assertEqual( diff --git a/tests/link/test_plugins.py b/tests/link/test_plugins.py index 62646e82..e15b4234 100644 --- a/tests/link/test_plugins.py +++ b/tests/link/test_plugins.py @@ -18,7 +18,7 @@ def test_plugin(self): plugin_type=TextLinkPlugin.__name__, language=self.language, config=dict( - external_link="https://www.divio.com", + link=dict(external_link="https://www.divio.com"), ), ).initialize_from_form(LinkForm).save() self.publish(self.page, self.language) @@ -34,7 +34,7 @@ def test_plugin(self): plugin_type=TextLinkPlugin.__name__, language=self.language, config=dict( - external_link="https://www.divio.com", + dict(link=dict(external_link="https://www.divio.com")), link_context="primary", link_size="btn-sm", link_block=True, @@ -57,7 +57,7 @@ def test_plugin(self): plugin_type=TextLinkPlugin.__name__, language=self.language, config=dict( - internal_link=dict(model="cms.page", pk=self.page.id), + link=dict(internal_link=f"cms.page:{self.page.id}"), link_context="primary", link_type="btn", name="django CMS rocks!", @@ -71,8 +71,6 @@ def test_plugin(self): self.assertEqual(response.status_code, 200) self.assertContains(response, "btn-primary") self.assertContains(response, 'href="/content/"') - # Finally, test the descriptor - self.assertEqual(plugin.internal_link, self.page) # alternate version broken link plugin = add_plugin( @@ -101,7 +99,7 @@ def test_plugin(self): plugin_type=TextLinkPlugin.__name__, language=self.language, config=dict( - external_link="https://www.divio.com", + link=dict(external_link="https://www.divio.com"), link_context="primary", link_type="btn", link_outline=True, diff --git a/tests/navigation/test_plugins.py b/tests/navigation/test_plugins.py index 0677c2e0..b6739c9c 100644 --- a/tests/navigation/test_plugins.py +++ b/tests/navigation/test_plugins.py @@ -57,7 +57,7 @@ def test_plugin(self): language=self.language, target=nav, config=dict( - internal_link=dict(model="cms.page", pk=self.page.id), + link=dict(internal_link=f"cms.page:{self.page.id}"), link_context="primary", link_type="btn", name="django CMS rocks!", diff --git a/tests/requirements/base.txt b/tests/requirements/base.txt index 9f16ee5d..601ba32b 100644 --- a/tests/requirements/base.txt +++ b/tests/requirements/base.txt @@ -10,4 +10,4 @@ black pre-commit djangocms-text html5lib -. +djangocms-link>=5.0.0 diff --git a/tests/test_plugin_tag.py b/tests/test_plugin_tag.py index 4031f9db..e1f074e3 100644 --- a/tests/test_plugin_tag.py +++ b/tests/test_plugin_tag.py @@ -28,7 +28,6 @@ def test_tag_rendering_with_paramter(self): expected_result = """""" - result = template.render({"request": None}) self.assertInHTML(expected_result, result) @@ -72,7 +71,6 @@ def test_complex_tags(self):
    A third item
    """ result = template.render({"request": None}) - self.assertInHTML(expected_result, result) def test_link_plugin(self): @@ -85,8 +83,8 @@ def test_link_plugin(self): """) # noqa: B950 else: grouper = None - template = django_engine.from_string("""{% load frontend %} - {% plugin "textlink" name="Click" external_link="/test/" link_type="btn" link_context="primary" link_outline=False %} + template = django_engine.from_string("""{% load frontend djangocms_link_tags %}{{ "test"|to_link }} + {% plugin "textlink" name="Click" link="/test/"|to_link link_type="btn" link_context="primary" link_outline=False %} Click me! {% endplugin %} """) # noqa: B950 @@ -94,7 +92,6 @@ def test_link_plugin(self): expected_result = """
    Click me!""" result = template.render({"request": None, "test_site": get_current_site(None), "grouper": grouper}) - self.assertInHTML(expected_result, result) @override_settings(DEBUG=True) diff --git a/tests/test_settings.py b/tests/test_settings.py index b7645be9..96e1511a 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -15,6 +15,7 @@ "menus", "treebeard", "djangocms_text", + "djangocms_link", "djangocms_frontend", "djangocms_frontend.contrib.accordion", "djangocms_frontend.contrib.alert", From e18961e37504cead84ee5888849b24775c80f40f Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Mon, 28 Oct 2024 00:29:55 +0100 Subject: [PATCH 30/66] Update documentation --- README.rst | 4 +- .../contrib/link/cms_plugins.py | 8 +- djangocms_frontend/contrib/link/forms.py | 28 ---- djangocms_frontend/contrib/link/helpers.py | 120 +----------------- djangocms_frontend/contrib/link/views.py | 30 ----- docs/source/components.rst | 23 +--- docs/source/getting_started.rst | 2 + docs/source/how-to/internal-link-targets.rst | 112 ++-------------- tests/link/test_plugins.py | 44 +------ 9 files changed, 17 insertions(+), 354 deletions(-) delete mode 100644 djangocms_frontend/contrib/link/views.py diff --git a/README.rst b/README.rst index ff929a91..f9c383f9 100644 --- a/README.rst +++ b/README.rst @@ -21,8 +21,8 @@ Key features rebuild you site's plugin tree if css framework is changed in the future, e.g. from Bootstrap 5 to a future version. -- **New link plugin** allowing to link to internal pages provided by - other applications, such as `djangocms-blog +- Leverage of new **djangocms-link features** allowing to link to internal pages + provided by other applications, such as `djangocms-blog `_. - **Nice and well-arranged admin frontend** of `djangocms-bootstrap4 diff --git a/djangocms_frontend/contrib/link/cms_plugins.py b/djangocms_frontend/contrib/link/cms_plugins.py index 99f80bf5..b4950755 100644 --- a/djangocms_frontend/contrib/link/cms_plugins.py +++ b/djangocms_frontend/contrib/link/cms_plugins.py @@ -1,7 +1,6 @@ from cms.plugin_pool import plugin_pool from django.apps import apps from django.conf import settings as django_settings -from django.urls import path from django.utils.translation import gettext_lazy as _ from djangocms_frontend.helpers import get_plugin_template, insert_fields @@ -10,7 +9,7 @@ from ...cms_plugins import CMSUIPlugin from ...common import AttributesMixin, SpacingMixin from .. import link -from . import forms, models, views +from . import forms, models from .constants import USE_LINK_ICONS from .helpers import GetLinkMixin @@ -99,11 +98,6 @@ class TextLinkPlugin(mixin_factory("Link"), AttributesMixin, SpacingMixin, LinkP def get_render_template(self, context, instance, placeholder): return get_plugin_template(instance, "link", "link", settings.LINK_TEMPLATE_CHOICES) - def get_plugin_urls(self): - return [ - path("autocomplete/", views.AutocompleteJsonView.as_view(), name="link_link_autocomplete"), - ] - if "djangocms_frontend.contrib.link" in django_settings.INSTALLED_APPS: # Only register plugin if in INSTALLED_APPS diff --git a/djangocms_frontend/contrib/link/forms.py b/djangocms_frontend/contrib/link/forms.py index 5936a3ce..1ee579ff 100644 --- a/djangocms_frontend/contrib/link/forms.py +++ b/djangocms_frontend/contrib/link/forms.py @@ -5,10 +5,7 @@ from django import apps, forms from django.conf import settings as django_settings from django.contrib.admin.widgets import SELECT2_TRANSLATIONS, AutocompleteMixin -from django.contrib.contenttypes.models import ContentType from django.contrib.sites.models import Site -from django.core.exceptions import ObjectDoesNotExist -from django.db import models from django.utils.translation import get_language from django.utils.translation import gettext as _ from djangocms_link.fields import LinkFormField @@ -29,7 +26,6 @@ from ...models import FrontendUIItem from .. import link from .constants import LINK_CHOICES, LINK_SIZE_CHOICES, TARGET_CHOICES -from .helpers import get_object_for_value mixin_factory = settings.get_forms(link) @@ -112,30 +108,6 @@ def optgroups(self, name, value, attr=None): return groups -class SmartLinkField(forms.ChoiceField): - widget = Select2jqWidget - - def prepare_value(self, value): - if value: - if isinstance(value, dict): # Entangled dictionary? - try: - app_label, model = value["model"].rsplit(".", 1) - content_type = ContentType.objects.get(app_label=app_label, model=model) - return f"{content_type.id}-{value['pk']}" - except (TypeError, ValueError, KeyError, ObjectDoesNotExist): - pass - elif isinstance(value, models.Model): - content_type = ContentType.objects.get_for_model(value) - return f"{content_type.id}-{value.id}" - return "" - - def clean(self, value): - obj = get_object_for_value(value) - if obj is not None: - return obj - return super().clean(value) - - if apps.apps.is_installed("djangocms_url_manager"): from djangocms_url_manager.forms import ( HtmlLinkSiteSelectWidget, diff --git a/djangocms_frontend/contrib/link/helpers.py b/djangocms_frontend/contrib/link/helpers.py index 04a1864c..41d6aa8c 100644 --- a/djangocms_frontend/contrib/link/helpers.py +++ b/djangocms_frontend/contrib/link/helpers.py @@ -1,53 +1,10 @@ -from importlib import import_module - -from cms.forms.utils import get_page_choices -from cms.models import Page from django.apps import apps -from django.conf import settings as django_settings -from django.contrib.admin import site from django.contrib.contenttypes.models import ContentType from django.contrib.sites.models import Site -from django.core.exceptions import FieldError, ObjectDoesNotExist -from django.utils.encoding import force_str +from django.core.exceptions import ObjectDoesNotExist from djangocms_frontend.helpers import get_related_object -LINK_MODELS = getattr(django_settings, "DJANGOCMS_FRONTEND_LINK_MODELS", []) - - -def create_querysets(link_models): - querysets = [] - for item in link_models: - if item["class_path"] != "cms.models.Page": - # CMS pages are collected using a cms function to preserve hierarchy - section = item["type"] - parts = item["class_path"].rsplit(".", 1) - cls = getattr(import_module(parts[0]), parts[1]) - queryset = cls.objects - - if "manager_method" in item: - queryset = getattr(queryset, item["manager_method"])() - - if "filter" in item: - for k, v in item["filter"].items(): - try: - # Attempt to execute any callables in the filter dict. - item["filter"][k] = v() - except TypeError: - # OK, it wasn't a callable, so, leave it be - pass - queryset = queryset.filter(**item["filter"]) - else: - if "manager_method" not in item: - queryset = queryset.all() - if "order_by" in item: - queryset = queryset.order_by(item["order_by"]) - querysets.append((section, queryset, item.get("search", None), cls)) - return querysets - - -_querysets = create_querysets(LINK_MODELS) - def get_object_for_value(value): if isinstance(value, str) and "-" in value: @@ -63,81 +20,6 @@ def get_object_for_value(value): return None -def unescape(text, nbsp): - return ( - text.replace(" ", nbsp) - .replace("&", "&") - .replace("<", "<") - .replace(">", ">") - .replace(""", '"') - .replace("'", "'") - ) - - -def get_link_choices(request, term="", lang=None, nbsp=None): - global _querysets - - if nbsp is None: - nbsp = "" if term else "\u2000" - available_objects = [] - # Now create our list of cms pages - type_id = ContentType.objects.get_for_model(Page).id - for value, descr in get_page_choices(lang): - if isinstance(descr, list): - available_objects.append( - { - "text": value, - "children": [ - dict( - id=f"{type_id}-{page}", - # django admin's autocomplete view requires unescaped strings - # get_page_choices escapes strings, so we undo the escape - text=unescape(name, nbsp), - ) - for page, name in descr - if not isinstance(term, str) or term.upper() in name.upper() - ], - } - ) - elif value and isinstance(value, int): - available_objects.append(dict(id=f"{type_id}-{value}")) - - # Add list of additional non-cms pages - for section, qs, search, cls in _querysets: - objects = None - model_admin = site._registry.get(cls, None) - if search: - try: - objects = qs.filter(**{search + "__icontains": term}) - except FieldError: - pass - if objects is None: - objects = [item for item in qs.all() if (not isinstance(term, str)) or term.upper() in str(item).upper()] - if objects: - type_class = ContentType.objects.get_for_model(objects[0].__class__) - available_objects.append( - { - "text": force_str(section), - "children": [ - dict(id=f"{type_class.id}-{obj.id}", text=str(obj)) - for obj in objects - if request is None or model_admin and model_admin.has_view_permission(request, obj=obj) - ], - } - ) - return available_objects - - -def get_choices(request, term="", lang=None) -> list: - def to_choices(json): - return list( - (elem["text"], to_choices(elem["children"])) if "children" in elem else (elem["id"], elem["text"]) - for elem in json - ) - - return to_choices(get_link_choices(request, term, lang, " ")) - - class GetLinkMixin: def get_link(self) -> str: if "url_grouper" in self.config and self.config["url_grouper"] and apps.is_installed("djangocms_url_manager"): diff --git a/djangocms_frontend/contrib/link/views.py b/djangocms_frontend/contrib/link/views.py deleted file mode 100644 index 87102528..00000000 --- a/djangocms_frontend/contrib/link/views.py +++ /dev/null @@ -1,30 +0,0 @@ -from django.contrib.auth.mixins import LoginRequiredMixin -from django.http import JsonResponse -from django.views.generic import View - -from .helpers import get_link_choices - - -class AutocompleteJsonView(LoginRequiredMixin, View): - """Handle AutocompleteWidget's AJAX requests for data.""" - - paginate_by = 20 - admin_site = None - - def get(self, request, *args, **kwargs): - """ - Return a JsonResponse with search results of the form: - { - results: [{id: "123" text: "foo"}], - pagination: {more: true} - } - """ - - self.term = kwargs.get("term", request.GET.get("term", "")).strip() - results = get_link_choices(request, self.term) - return JsonResponse( - { - "results": results, - "pagination": {"more": False}, - } - ) diff --git a/docs/source/components.rst b/docs/source/components.rst index d3fdf149..b2fba86a 100644 --- a/docs/source/components.rst +++ b/docs/source/components.rst @@ -342,29 +342,8 @@ to a CMS page or pages of other Django applications. They are dynamic, i.e. if the page's url changes (e.g. because it is moved in the page tree) all links pointing to the page change accordingly. -.. note:: - - **djangocms-frontend** uses django-cms' function ``get_page_choices(lang)`` - to get the list of available pages in the current language. - -The developer can extend the list of available internal link targets to pages -outside the CMS page tree using the -``DJANGOCMS_FRONTEND_LINK_MODELS`` setting in the project's ``.settings`` file. -The link/button -component can point to any page controlled by a Django model if the model class -implements the ``get_absolute_url`` method. A typical use case would, e.g., -blog entries of `djangocms-blog `_. -(This approach was inspired by mkoisten's `djangocms-styledlink -`_.) - -For more information, see -:ref:`How to add internal link targets outside of the CMS` - -.. note:: +If targets are deleted the link will fallback to regular text. - Only those destinations (outside the CMS) are shown for which a model admin - is registered and the logged in user has view permissions: A user will only - see a destination if they can view it in the admin site. Re-usable component example =========================== diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index 183e0ff6..4a42dc7e 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -29,6 +29,7 @@ by adding an option: djangocms-frontend[djangocms-icon] # Installs djangocms-icon for icons support in links djangocms-frontend[static-ace] # Installs djangocms-static-ace to include the ace code editor in static files djangocms-frontend[static-ace, djangocms-icon] # comma-separate multiple dependencies + djangocms-frontend[djangocms-link] # Installs djangocms-link for link support ``djangocms-frontend[static-ace]`` is useful if your project cannot or should not access a CDN to load the `ace code editor `_ for the code plugin. @@ -44,6 +45,7 @@ Add the following entries to your ``INSTALLED_APPS``: "djangocms_icon", # optional "easy_thumbnails", + "djangocms_link", # Needed for link support "djangocms_frontend", "djangocms_frontend.contrib.accordion", "djangocms_frontend.contrib.alert", diff --git a/docs/source/how-to/internal-link-targets.rst b/docs/source/how-to/internal-link-targets.rst index 5ebcc353..8f727713 100644 --- a/docs/source/how-to/internal-link-targets.rst +++ b/docs/source/how-to/internal-link-targets.rst @@ -4,109 +4,15 @@ How to add internal link targets outside the CMS ************************************************** -By default the link/button component offers available CMS pages of the -selected language as internal links. +As of version 2 of **djangocms-frontend**, the link/button plugin builds upon +the ``LinkFormField`` of djangocms-link. djangocms-link uses Django admin to +autodetect linkable models. This means that any model that has a +``get_absolute_url()`` method and a ``search_fields`` attribute in its +``ModelAdmin`` will be available as an internal link target. -The developer may extend this setting to include other page-generating -Django models as well by adding the ``DJANGOCMS_FRONTEND_LINK_MODELS`` -setting to the project's ``settings.py`` file. +The ``DJANGOCMS_FRONTEND_LINK_MODELS`` setting if djangocms-frontend before +version 2 does not have any effect anymore. -.. py:attribute:: settings.DJANGOCMS_FRONTEND_LINK_MODELS +See the README file of `djangocms-link `_ +for more information. - ``DJANGOCMS_FRONTEND_LINK_MODELS`` contains a list - of additional models that can be linked. - - Each model is specified within its own dict. The resulting drop-down - list will contain objects grouped by their type. The order of the types - in the list is defined by the order of their definition in this setting. - - The only required attribute for each model is ``class_path``, which must - be the full python path to the model. - - Additional attributes are: - - ``type``: - This is the name that will appear in the grouped dropdown menu. If - not specified, the name of the class will be used E.g., "``Page``". - - ``filter``: - You can specify additional filtering rules here. This must be - specified as a dict but is converted directly into kwargs internally, - so, ``{'published': True}`` becomes ``filter(published=True)`` for - example. - - ``order_by``: - Specify the ordering of any found objects exactly as you would in a - queryset. If this is not provided, the objects will be ordered in the - natural order of your model, if any. - - ``search``: - Specifies which (text) field of the model should be searched when - the user types a search string. - -.. note:: - - Each of the defined models must define a ``get_absolute_url()`` - method on its objects or the configuration will be rejected. - -Example for a configuration that allows linking CMS pages plus two -different page types from two djangocms-blog apps called "Blog" and -"Content hub" (having the ``app_config_id`` 1 and 2, respectively): - -.. code:: python - - DJANGOCMS_FRONTEND_LINK_MODELS = [ - { - "type": _("Blog pages"), - "class_path": "djangocms_blog.models.Post", - "filter": {"publish": True, "app_config_id": 1}, - "search": "translations__title", - }, - { - "type": _("Content hub pages"), - "class_path": "djangocms_blog.models.Post", - "filter": {"publish": True, "app_config_id": 2}, - "search": "translations__title", - }, - ] - -Another example might be (taken from djangocms-styledlink -documentation): - -.. code:: python - - DJANGOCMS_FRONTEND_LINK_MODELS = [ - { - 'type': 'Clients', - 'class_path': 'myapp.Client', - 'manager_method': 'published', - 'order_by': 'title' - }, - { - 'type': 'Projects', - 'class_path': 'myapp.Project', - 'filter': { 'approved': True }, - 'order_by': 'title', - }, - { - 'type': 'Solutions', - 'class_path': 'myapp.Solution', - 'filter': { 'published': True }, - 'order_by': 'name', - } - ] - -The link/button plugin uses select2 to show all available link targets. -This allows you to search the page titles. - -.. warning:: - - If you have a huge number (> 1,000) of link target (i.e., pages or - blog entries or whatever) the current implementation might slow down - the editing process. In your ``settings`` file you can set - ``DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH`` to a value greater than 1 and - **djangocms-frontend** will wait until the user inputs at least this many - characters before querying potential link targets. - -.. index:: - single: Extend plugins diff --git a/tests/link/test_plugins.py b/tests/link/test_plugins.py index e15b4234..d4d8f2d2 100644 --- a/tests/link/test_plugins.py +++ b/tests/link/test_plugins.py @@ -1,12 +1,10 @@ from cms.api import add_plugin from cms.test_utils.testcases import CMSTestCase -from cms.utils.urlutils import admin_reverse from django.http import HttpRequest from djangocms_frontend import settings from djangocms_frontend.contrib.link.cms_plugins import TextLinkPlugin -from djangocms_frontend.contrib.link.forms import LinkForm, SmartLinkField -from djangocms_frontend.contrib.link.helpers import get_choices +from djangocms_frontend.contrib.link.forms import LinkForm from ..fixtures import TestFixture @@ -153,43 +151,3 @@ def test_link_form(self): request.POST["external_link"] = None form = LinkForm(request.POST) self.assertFalse(form.is_valid()) # no anchor for mail - - -class AutocompleteViewTestCase(TestFixture, CMSTestCase): - - def test_smart_link_field(self): - slf = SmartLinkField() - choices = get_choices(None) - self.assertEqual("example.com", choices[0][0]) # Site name - self.assertIn(("2-1", "home"), choices[0][1]) - - cleaned = slf.clean("2-1") - self.assertEqual(dict(model="cms.page", pk=1), cleaned) - - self.assertEqual(slf.prepare_value("blabla"), "") - self.assertEqual(slf.prepare_value(dict(model="cms.page", pk=1)), "2-1") - self.assertEqual(slf.prepare_value(self.home), "2-1") - - def test_autocomplete_view(self): - tricky_title = """d'acceuil: """ - page = self.create_page( - title=tricky_title, - template="page.html", - ) - expected_choices = [ - "home", "content", tricky_title, - ] - - self.publish(page, self.language) - autocomplete_url = admin_reverse("link_link_autocomplete") - - with self.login_user_context(self.superuser): - response = self.client.get(autocomplete_url) - - autocomplete_result = response.json() - choices = autocomplete_result.get("results")[0] - - self.assertFalse((autocomplete_result.get("pagination") or {}).get("more")) - - for expected, sent in zip(expected_choices, choices.get("children")): - self.assertEqual(expected, sent.get("text")) From b5d6930ce81b99d2d8155d244211c66c7481a469 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Mon, 28 Oct 2024 00:32:51 +0100 Subject: [PATCH 31/66] Test against djangocms-link PR version --- tests/requirements/base.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/requirements/base.txt b/tests/requirements/base.txt index 601ba32b..ce093de9 100644 --- a/tests/requirements/base.txt +++ b/tests/requirements/base.txt @@ -10,4 +10,5 @@ black pre-commit djangocms-text html5lib -djangocms-link>=5.0.0 +git+https://github.com/django-cms/djangocms-link@feat/url-mngr + From 109e69789bf1c03d74bf07fed36e5a4f55e97b05 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Mon, 28 Oct 2024 00:37:39 +0100 Subject: [PATCH 32/66] Add filer and easy thumbnails to test requirements --- tests/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/requirements/base.txt b/tests/requirements/base.txt index ce093de9..d0928737 100644 --- a/tests/requirements/base.txt +++ b/tests/requirements/base.txt @@ -9,6 +9,6 @@ wheel black pre-commit djangocms-text +django-filer html5lib git+https://github.com/django-cms/djangocms-link@feat/url-mngr - From 0e23abaf22f0e04ed9bf19fce291229ae2b26446 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Mon, 28 Oct 2024 00:39:39 +0100 Subject: [PATCH 33/66] Add package itself to the test requirements --- tests/requirements/base.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/requirements/base.txt b/tests/requirements/base.txt index d0928737..c3393eab 100644 --- a/tests/requirements/base.txt +++ b/tests/requirements/base.txt @@ -12,3 +12,4 @@ djangocms-text django-filer html5lib git+https://github.com/django-cms/djangocms-link@feat/url-mngr +-e . From 881341233b7243691e975e68b77a74d211a050ad Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Mon, 28 Oct 2024 00:45:45 +0100 Subject: [PATCH 34/66] Fix: update test fixtures for v3 --- tests/fixtures.py | 3 ++- tests/link/test_plugins.py | 12 ++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/tests/fixtures.py b/tests/fixtures.py index 216590d3..6984ffc9 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -2,7 +2,6 @@ from django.apps import apps from django.contrib.contenttypes.models import ContentType from django.contrib.sites.models import Site -from djangocms_versioning.constants import PUBLISHED DJANGO_CMS4 = apps.is_installed("djangocms_versioning") @@ -114,6 +113,8 @@ def create_url( url_grouper=UrlGrouper.objects.create(), ) if is_versioning_enabled(): + from djangocms_versioning.constants import PUBLISHED + Version.objects.create( content=url, created_by=self.superuser, diff --git a/tests/link/test_plugins.py b/tests/link/test_plugins.py index d4d8f2d2..02030c37 100644 --- a/tests/link/test_plugins.py +++ b/tests/link/test_plugins.py @@ -136,7 +136,10 @@ def test_link_form(self): ) ) if hasattr(self, "create_url") - else dict(external_link="https://www.django-cms.org/") + else dict( + link_0="external_link", + link_1="https://www.django-cms.org/", + ) ), } ) @@ -144,10 +147,3 @@ def test_link_form(self): self.assertTrue(form.is_valid(), f"{form.__class__.__name__}:form errors: {form.errors}") if hasattr(self, "create_url"): self.delete_urls() - else: - request.POST.update({"mailto": "none@nowhere.com"}) - form = LinkForm(request.POST) - self.assertFalse(form.is_valid()) # Two targets - request.POST["external_link"] = None - form = LinkForm(request.POST) - self.assertFalse(form.is_valid()) # no anchor for mail From 9d0511ab0c8d5510e49d84416ee3a44645d37a17 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Mon, 28 Oct 2024 00:48:25 +0100 Subject: [PATCH 35/66] Remove outdated urlconf test --- tests/link/test_urlconf.py | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 tests/link/test_urlconf.py diff --git a/tests/link/test_urlconf.py b/tests/link/test_urlconf.py deleted file mode 100644 index b90454ce..00000000 --- a/tests/link/test_urlconf.py +++ /dev/null @@ -1,16 +0,0 @@ -from unittest import skipIf - -from cms.test_utils.testcases import CMSTestCase -from cms.utils.urlutils import admin_reverse -from django.urls import NoReverseMatch - -from tests.fixtures import DJANGO_CMS4, TestFixture - - -@skipIf(DJANGO_CMS4, "Tests for django CMS 4 use URL manager with own select2") -class TestUrlConfTestCase(TestFixture, CMSTestCase): - def test_select2_url_reversible(self): - try: - admin_reverse("link_link_autocomplete") - except NoReverseMatch as e: - self.fail(str(e)) From 5a68e45190768cfa446bfc9f7ff1fbb8864395d8 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Mon, 28 Oct 2024 00:54:23 +0100 Subject: [PATCH 36/66] Remove unused autocomplete select2 widget --- djangocms_frontend/contrib/link/forms.py | 69 ------------------------ 1 file changed, 69 deletions(-) diff --git a/djangocms_frontend/contrib/link/forms.py b/djangocms_frontend/contrib/link/forms.py index 1ee579ff..aa2b7c9e 100644 --- a/djangocms_frontend/contrib/link/forms.py +++ b/djangocms_frontend/contrib/link/forms.py @@ -1,12 +1,6 @@ -import json -from types import SimpleNamespace - -from cms.utils.urlutils import admin_reverse from django import apps, forms from django.conf import settings as django_settings -from django.contrib.admin.widgets import SELECT2_TRANSLATIONS, AutocompleteMixin from django.contrib.sites.models import Site -from django.utils.translation import get_language from django.utils.translation import gettext as _ from djangocms_link.fields import LinkFormField @@ -45,69 +39,6 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) -HOSTNAME = getattr(settings, "DJANGOCMS_LINK_INTRANET_HOSTNAME_PATTERN", None) -LINK_MODELS = getattr(django_settings, "DJANGOCMS_FRONTEND_LINK_MODELS", []) -MINIMUM_INPUT_LENGTH = getattr(django_settings, "DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH", 0) - - -class Select2jqWidget(AutocompleteMixin, forms.Select): - empty_label = _("Select a destination") - - def __init__(self, *args, **kwargs): - if MINIMUM_INPUT_LENGTH: # no-cover - if "attrs" in kwargs: - kwargs["attrs"].setdefault("data-minimum-input-length", MINIMUM_INPUT_LENGTH) - else: - kwargs["attrs"] = {"data-minimum-input-length": MINIMUM_INPUT_LENGTH} - kwargs.setdefault("admin_site", None) - kwargs.setdefault( - "field", - SimpleNamespace( - name="", model=SimpleNamespace(_meta=SimpleNamespace(app="djangocms_frontend", label="link")) - ), - ) # Fake field properties for autocomplete field (unused by link) - super().__init__(*args, **kwargs) - - def get_url(self): - return admin_reverse("link_link_autocomplete") - - def build_attrs(self, base_attrs, extra_attrs=None): - """ - Set select2's AJAX attributes. - - Attributes can be set using the html5 data attribute. - Nested attributes require a double dash as per - https://select2.org/configuration/data-attributes#nested-subkey-options - """ - attrs = super(forms.Select, self).build_attrs(base_attrs, extra_attrs=extra_attrs) - attrs.setdefault("class", "") - i18n_name = getattr(self, "i18n_name", SELECT2_TRANSLATIONS.get(get_language())) # Django 3.2 compat - attrs.update( - { - "data-ajax--cache": "true", - "data-ajax--delay": 250, - "data-ajax--type": "GET", - "data-ajax--url": self.get_url(), - "data-theme": "admin-autocomplete", - "data-app-label": "app", - "data-model-name": "model", - "data-field-name": "field", - "data-allow-clear": json.dumps(not self.is_required), - "data-placeholder": "", # Allows clearing of the input. - "lang": i18n_name, - "class": attrs["class"] + (" " if attrs["class"] else "") + "admin-autocomplete", - } - ) - return attrs - - def optgroups(self, name, value, attr=None): - groups = super(forms.Select, self).optgroups(name, value) - if not self.is_required and groups: - # Add an empty entry to allow for an empty value to be preselected - groups[0][1].insert(0, self.create_option(name, "", "", False, 0)) - return groups - - if apps.apps.is_installed("djangocms_url_manager"): from djangocms_url_manager.forms import ( HtmlLinkSiteSelectWidget, From 526dc9d316d3653cdc3204d7decba57cec9eb843 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Mon, 28 Oct 2024 10:15:34 +0100 Subject: [PATCH 37/66] Add warning for discontinued settings --- djangocms_frontend/apps.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/djangocms_frontend/apps.py b/djangocms_frontend/apps.py index 444c1cee..7c1195d7 100644 --- a/djangocms_frontend/apps.py +++ b/djangocms_frontend/apps.py @@ -1,11 +1,39 @@ from django import apps +from django.core.checks import Warning, register class DjangocmsFrontendConfig(apps.AppConfig): name = "djangocms_frontend" - verbose_name = "DjangoCMS Frontend" + verbose_name = "django CMS Frontend" def ready(self): from .component_pool import setup + register(check_settings) setup() + + +def check_settings(*args, **kwargs): + from django.conf import settings + + warnings = [] + + if hasattr(settings, "DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH"): + warnings.append(Warning( + "The DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH setting was removed in djangocms-frontend 2.\n" + "Use DJANGOCMS_LINK_MINIMUM_INPUT_LENGTH instead.", + "This message disappears after removing the DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH from your project's " + "settings.\n", + id="djangocms_frontend.W001", + obj="settings.DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH", + )) + if hasattr(settings, "DJANGOCMS_FRONTEND_LINK_MODELS"): + warnings.append(Warning( + "The DJANGOCMS_FRONTEND_LINK_MODELS setting was removed in djangocms-frontend 2.\n" + "djangocms-frontend 2 uses linkable models from djangocms-link. See " + "https://github.com/django-cms/djangocms-link#django-cms-link for more info.", + "This message disappears after removing the DJANGOCMS_FRONTEND_LINK_MODELS from your project's settings.\n", + id="djangocms_frontend.W002", + obj="settings.DJANGOCMS_FRONTEND_LINK_MODELS", + )) + return warnings From 462d07af9d02ef86f92dd3e3da0adaa42c9d7a65 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Fri, 1 Nov 2024 19:56:12 +0100 Subject: [PATCH 38/66] Fix `LinkPluginMixin` --- djangocms_frontend/contrib/image/forms.py | 29 +------------------ .../contrib/link/cms_plugins.py | 7 +---- 2 files changed, 2 insertions(+), 34 deletions(-) diff --git a/djangocms_frontend/contrib/image/forms.py b/djangocms_frontend/contrib/image/forms.py index 0a1043e1..09786199 100644 --- a/djangocms_frontend/contrib/image/forms.py +++ b/djangocms_frontend/contrib/image/forms.py @@ -2,7 +2,6 @@ from django.conf import settings as django_settings from django.db.models.fields.related import ManyToOneRel from django.utils.translation import gettext_lazy as _ -from entangled.forms import EntangledModelForm from filer.fields.image import AdminImageFormField, FilerImageField from filer.models import Image, ThumbnailOption @@ -45,13 +44,6 @@ def get_templates(): PICTURE_ALIGNMENT = get_alignment() -LINK_TARGET = ( - ("_blank", _("Open in new window")), - ("_self", _("Open in same window")), - ("_parent", _("Delegate to parent")), - ("_top", _("Delegate to top")), -) - RESPONSIVE_IMAGE_CHOICES = ( ("inherit", _("Let settings.DJANGOCMS_PICTURE_RESPONSIVE_IMAGES decide")), ("yes", _("Yes")), @@ -61,10 +53,9 @@ def get_templates(): class ImageForm( TemplateChoiceMixin, - AbstractLinkForm, ResponsiveFormMixin, MarginFormMixin, - EntangledModelForm, + AbstractLinkForm, ): """ Content > "Image" Plugin @@ -217,24 +208,6 @@ class Meta: def clean(self): super().clean() data = self.cleaned_data - # there can be only one link type - if ( - sum( - ( - bool(data.get("external_link", False)), - bool(data.get("internal_link", False)), - bool(data.get("file_link", False)), - ) - ) - > 1 - ): - raise forms.ValidationError( - _( - "You have given more than one external, internal, or file link target. " - "Only one option is allowed." - ) - ) - # you shall only set one image kind if not data.get("picture", False) and not data.get("external_picture", False): raise forms.ValidationError( diff --git a/djangocms_frontend/contrib/link/cms_plugins.py b/djangocms_frontend/contrib/link/cms_plugins.py index b4950755..dea1f3e1 100644 --- a/djangocms_frontend/contrib/link/cms_plugins.py +++ b/djangocms_frontend/contrib/link/cms_plugins.py @@ -40,12 +40,7 @@ class LinkPluginMixin: link_fields = ( (("site", "url_grouper"),) if apps.is_installed("djangocms_url_manager") - else ( - ("external_link", "internal_link"), - ("mailto", "phone"), - ("anchor", "target"), - "file_link", - ) + else ("link", "target") ) def render(self, context, instance, placeholder): From 75d616a9dc242a2cfde666d41baddcdf15399d1d Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Fri, 1 Nov 2024 20:38:59 +0100 Subject: [PATCH 39/66] Nocover for checks warnings --- djangocms_frontend/apps.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/djangocms_frontend/apps.py b/djangocms_frontend/apps.py index 7c1195d7..0de7123c 100644 --- a/djangocms_frontend/apps.py +++ b/djangocms_frontend/apps.py @@ -18,7 +18,7 @@ def check_settings(*args, **kwargs): warnings = [] - if hasattr(settings, "DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH"): + if hasattr(settings, "DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH"): # pragma: no cover warnings.append(Warning( "The DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH setting was removed in djangocms-frontend 2.\n" "Use DJANGOCMS_LINK_MINIMUM_INPUT_LENGTH instead.", @@ -27,7 +27,7 @@ def check_settings(*args, **kwargs): id="djangocms_frontend.W001", obj="settings.DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH", )) - if hasattr(settings, "DJANGOCMS_FRONTEND_LINK_MODELS"): + if hasattr(settings, "DJANGOCMS_FRONTEND_LINK_MODELS"): # pragma: no cover warnings.append(Warning( "The DJANGOCMS_FRONTEND_LINK_MODELS setting was removed in djangocms-frontend 2.\n" "djangocms-frontend 2 uses linkable models from djangocms-link. See " From 982739eb1ac0cfc256e85f89ae01debcd8b530b3 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Fri, 1 Nov 2024 21:06:45 +0100 Subject: [PATCH 40/66] Fix: Carousel links --- djangocms_frontend/contrib/carousel/cms_plugins.py | 12 +----------- djangocms_frontend/contrib/carousel/forms.py | 4 ++-- djangocms_frontend/contrib/link/forms.py | 10 +++++++--- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/djangocms_frontend/contrib/carousel/cms_plugins.py b/djangocms_frontend/contrib/carousel/cms_plugins.py index 421db65d..f004234d 100644 --- a/djangocms_frontend/contrib/carousel/cms_plugins.py +++ b/djangocms_frontend/contrib/carousel/cms_plugins.py @@ -81,18 +81,8 @@ class CarouselSlidePlugin( ) }, ), - ( - _("Link settings"), - { - "classes": ("collapse",), - "fields": ( - ("external_link", "internal_link"), - ("mailto", "phone"), - ("anchor", "target"), - ), - }, - ), ] + link_fieldset_position = 1 def get_render_template(self, context, instance, placeholder): return get_plugin_template( diff --git a/djangocms_frontend/contrib/carousel/forms.py b/djangocms_frontend/contrib/carousel/forms.py index ec2a09e3..1aeec88e 100644 --- a/djangocms_frontend/contrib/carousel/forms.py +++ b/djangocms_frontend/contrib/carousel/forms.py @@ -18,7 +18,7 @@ from ...helpers import first_choice from ...models import FrontendUIItem from .. import carousel -from ..link.forms import AbstractLinkForm +from ..link.forms import LinkFormMixin from .constants import ( CAROUSEL_ASPECT_RATIO_CHOICES, CAROUSEL_PAUSE_CHOICES, @@ -143,8 +143,8 @@ class Meta: class CarouselSlideForm( mixin_factory("CarouselSlide"), - AbstractLinkForm, BackgroundFormMixin, + LinkFormMixin, EntangledModelForm, ): """ diff --git a/djangocms_frontend/contrib/link/forms.py b/djangocms_frontend/contrib/link/forms.py index aa2b7c9e..bc801a29 100644 --- a/djangocms_frontend/contrib/link/forms.py +++ b/djangocms_frontend/contrib/link/forms.py @@ -5,7 +5,7 @@ from djangocms_link.fields import LinkFormField # from djangocms_link.validators import IntranetURLValidator -from entangled.forms import EntangledModelForm +from entangled.forms import EntangledModelForm, EntangledModelFormMixin from ... import settings from ...common import SpacingFormMixin @@ -46,7 +46,7 @@ def __init__(self, *args, **kwargs): ) from djangocms_url_manager.models import UrlGrouper - class AbstractLinkForm(EntangledModelForm): + class LinkFormMixin(EntangledModelFormMixin): class Meta: entangled_fields = { "config": [ @@ -70,7 +70,7 @@ class Meta: else: - class AbstractLinkForm(EntangledModelForm): + class LinkFormMixin(EntangledModelFormMixin): class Meta: entangled_fields = { "config": [ @@ -97,6 +97,10 @@ def __init__(self, *args, **kwargs): self.fields["link"].required = not self.link_is_optional +class AbstractLinkForm(LinkFormMixin, EntangledModelForm): + pass + + class LinkForm(mixin_factory("Link"), SpacingFormMixin, TemplateChoiceMixin, AbstractLinkForm): class Meta: model = FrontendUIItem From ff7002c5255d2330c1e6c6eb841405e70ac098ed Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Fri, 1 Nov 2024 21:36:27 +0100 Subject: [PATCH 41/66] Remove component link mixin --- docs/source/custom_components.rst | 3 +++ tests/component/test_plugins.py | 3 ++- tests/test_app/cms_components.py | 9 ++++----- tests/test_app/templates/button.html | 2 +- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/source/custom_components.rst b/docs/source/custom_components.rst index 9ce61fb9..0b8f1035 100644 --- a/docs/source/custom_components.rst +++ b/docs/source/custom_components.rst @@ -45,6 +45,8 @@ Add a ``cms_components.py`` file to the ``theme`` app: .. code-block:: python # theme/cms_components.py + from djangocms_link.fields import LinkFormField + from djangocms_frontend.contrib.component.components import ComponentLinkMixin, CMSFrontendComponent from djangocms_frontend.contrib.component.components import components from djangocms_frontend.contrib.image.fields import ImageFormField @@ -77,6 +79,7 @@ Add a ``cms_components.py`` file to the ``theme`` app: allow_children = False text = forms.CharField(required=True) + link = LinkFormField() def get_short_description(self): return self.text diff --git a/tests/component/test_plugins.py b/tests/component/test_plugins.py index ec5570d9..f6cdd448 100644 --- a/tests/component/test_plugins.py +++ b/tests/component/test_plugins.py @@ -152,7 +152,8 @@ def test_simple_component_plugin(self): instance.config["link"] = {"internal_link": f"cms.page:{self.page.pk}"} instance.save() - link = instance.get_link() + from djangocms_link.templatetags.djangocms_link_tags import to_url + link = to_url(instance.link) self.publish(self.page, self.language) diff --git a/tests/test_app/cms_components.py b/tests/test_app/cms_components.py index 20890102..c319ecae 100644 --- a/tests/test_app/cms_components.py +++ b/tests/test_app/cms_components.py @@ -1,9 +1,7 @@ from django import forms +from djangocms_link.fields import LinkFormField -from djangocms_frontend.contrib.component.components import ( - CMSFrontendComponent, - ComponentLinkMixin, -) +from djangocms_frontend.contrib.component.components import CMSFrontendComponent from djangocms_frontend.contrib.component.registry import components from djangocms_frontend.contrib.image.fields import ImageFormField @@ -33,13 +31,14 @@ def get_short_description(self): @components.register -class MyButton(ComponentLinkMixin, CMSFrontendComponent): +class MyButton(CMSFrontendComponent): class Meta: name = "Button" render_template = "button.html" allow_children = False text = forms.CharField(required=True, initial="Click me") + link = LinkFormField() def get_short_description(self): return self.text diff --git a/tests/test_app/templates/button.html b/tests/test_app/templates/button.html index 218fe92a..c145c6eb 100644 --- a/tests/test_app/templates/button.html +++ b/tests/test_app/templates/button.html @@ -1 +1 @@ -{{ instance.text }} +{% load djangocms_link_tags %}{{ instance.text }} From 832d5f089388b737148c3bdefd7b28c0faeaca53 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Sat, 2 Nov 2024 10:51:44 +0100 Subject: [PATCH 42/66] Add migration --- djangocms_frontend/migrations/0001_initial.py | 8 +- .../migrations/0002_migrate_links.py | 85 +++++++++++++++++++ tests/link/test_migration.py | 27 ++++++ 3 files changed, 113 insertions(+), 7 deletions(-) create mode 100644 djangocms_frontend/migrations/0002_migrate_links.py create mode 100644 tests/link/test_migration.py diff --git a/djangocms_frontend/migrations/0001_initial.py b/djangocms_frontend/migrations/0001_initial.py index a9588ed0..c566543e 100644 --- a/djangocms_frontend/migrations/0001_initial.py +++ b/djangocms_frontend/migrations/0001_initial.py @@ -2,16 +2,10 @@ import django.core.serializers.json import django.db.models.deletion -from cms.utils.compat import DJANGO_3_1 from django.db import migrations, models import djangocms_frontend.fields -if DJANGO_3_1: - from django_jsonfield_backport.models import JSONField -else: - JSONField = models.JSONField - class Migration(migrations.Migration): initial = True @@ -49,7 +43,7 @@ class Migration(migrations.Migration): ), ( "config", - JSONField( + models.JSONField( default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder, ), diff --git a/djangocms_frontend/migrations/0002_migrate_links.py b/djangocms_frontend/migrations/0002_migrate_links.py new file mode 100644 index 00000000..aeec1205 --- /dev/null +++ b/djangocms_frontend/migrations/0002_migrate_links.py @@ -0,0 +1,85 @@ +from django.db import migrations + + +def convert_item(config, direction): + """Convert FrontendUIItem config to new djangocms_link format.""" + if direction == "forward": + if config.get("external_link"): + if config.get("anchor"): + anchor = "#" + config.get("anchor") + del config["anchor"] + else: + anchor = "" + config["link"] = {"external_link": config.get("external_link") + anchor} + del config["external_link"] + return True + if config.get("internal_link"): + model = config.get("internal_link").get("model") + pk = config.get("internal_link").get("pk") + config["link"] = {"internal_link": f"{model}:{pk}"} + if config.get("anchor"): + config["link"]["anchor"] = "#" + config.get("anchor") + del config["anchor"] + del config["internal_link"] + return True + if config.get("file_link"): + config["link"] = {"file_link": config.get("file_link").get("pk")} + del config["file_link"] + return True + if config.get("phone"): + config["link"] = {"external_link": f"tel:{config.get('phone')}"} + del config["phone"] + return True + if config.get("mailto"): + config["link"] = {"external_link": f"mailto:{config.get('mailto')}"} + del config["mailto"] + return True + if config.get("anchor"): + config["link"] = {"external_link": "#" + config.get('anchor')} + del config["anchor"] + return True + + elif direction == "backward" and config.get("link"): + link = config.get("link") + if link.get("external_link"): + if "#" in link.get("external_link"): + config["anchor"] = link.get("external_link").split("#", 1)[1] + ext = link.get("external_link").split("#", 1)[0] + if ext.startswith("tel:"): + config["phone"] = ext[4:] + elif ext.startswith("mailto:"): + config["mailto"] = ext[7:] + elif ext: + config["external_link"] = ext + elif link.get("internal_link"): + model, pk = link.get("internal_link").split(":") + config["internal_link"] = {"model": model, "pk": int(pk)} + if link.get("anchor"): + config["anchor"] = link.get("anchor")[1:] + elif link.get("file_link"): + config["file_link"] = {"model": "filer.file", "pk": int(link.get("file_link"))} + del config["link"] + return True + return False + + +def convert(apps, schema_editor, direction): + FrontendUIItem = apps.get_model("djangocms_frontend", "FrontendUIItem") + for item in FrontendUIItem.objects.all(): + changed = convert_item(item.config, direction) + if changed: + item.save() + + +class Migration(migrations.Migration): + dependencies = [ + ("djangocms_frontend", "0001_initial"), + ] + + operations = [ + migrations.RunPython( + lambda apps, schema_editor: convert(apps, schema_editor, "forward"), + lambda apps, schema_editor: convert(apps, schema_editor, "backward"), + elidable=True + ), + ] diff --git a/tests/link/test_migration.py b/tests/link/test_migration.py new file mode 100644 index 00000000..77e4104e --- /dev/null +++ b/tests/link/test_migration.py @@ -0,0 +1,27 @@ +from django.test.testcases import TestCase + + +class LinkMigrationTestCase(TestCase): + def setUp(self): + import importlib + + link_migration = importlib.import_module("djangocms_frontend.migrations.0002_migrate_links") + self.convert = staticmethod(link_migration.convert_item) + + def test_link_migration(self): + test_links = ( + dict(external_link="https://www.django-cms.com"), + dict(external_link="https://www.django-cms.com", anchor="top"), + dict(internal_link=dict(model="cms.page", pk=1)), + dict(internal_link=dict(model="cms.page", pk=1), anchor="top"), + dict(file_link=dict(model="filer.file", pk=1)), + dict(phone="1234567890"), + dict(mailto="mail@example.com") + ) + + for link in test_links: + with self.subTest(link=link): + config = link.copy() + self.convert(config, "forward") + self.convert(config, "backward") + self.assertEqual(link, config) From 3793655da8af8c10a4f5687af98bb6ec80bff000 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Sat, 2 Nov 2024 10:52:53 +0100 Subject: [PATCH 43/66] Fix attributes common mixin --- djangocms_frontend/common/__init__.py | 2 +- djangocms_frontend/common/{bootstrap5 => }/attributes.py | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename djangocms_frontend/common/{bootstrap5 => }/attributes.py (100%) diff --git a/djangocms_frontend/common/__init__.py b/djangocms_frontend/common/__init__.py index 0957b32d..32e4e449 100644 --- a/djangocms_frontend/common/__init__.py +++ b/djangocms_frontend/common/__init__.py @@ -2,10 +2,10 @@ from djangocms_frontend import settings +from .attributes import AttributesMixin from .title import TitleFormMixin, TitleMixin __common = { - "attributes": ("AttributesMixin",), "background": ("BackgroundFormMixin", "BackgroundMixin"), "responsive": ("ResponsiveFormMixin", "ResponsiveMixin"), "sizing": ("SizingFormMixin", "SizingMixin"), diff --git a/djangocms_frontend/common/bootstrap5/attributes.py b/djangocms_frontend/common/attributes.py similarity index 100% rename from djangocms_frontend/common/bootstrap5/attributes.py rename to djangocms_frontend/common/attributes.py From d65ed7092f4586df4c24e745a636a895480e6956 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Tue, 5 Nov 2024 22:15:28 +0100 Subject: [PATCH 44/66] Refactor components --- djangocms_frontend/apps.py | 4 +- djangocms_frontend/cms_plugins.py | 55 +++------ .../components.py => component_base.py} | 31 ++---- djangocms_frontend/component_pool.py | 104 +++--------------- .../contrib/component/__init__.py | 0 .../contrib/component/cms_plugins.py | 18 --- .../contrib/component/registry.py | 25 ----- djangocms_frontend/helpers.py | 2 +- djangocms_frontend/plugin_tag.py | 97 ++++++++++++++++ .../templates/djangocms_frontend/slot.html | 0 djangocms_frontend/templatetags/frontend.py | 2 +- djangocms_frontend/ui_plugin_base.py | 51 +++++++++ docs/source/custom_components.rst | 17 +-- tests/component/test_models.py | 2 +- tests/component/test_plugins.py | 11 +- tests/test_app/cms_components.py | 4 +- tests/test_settings.py | 1 - tests/utilities/test_plugins.py | 9 +- 18 files changed, 213 insertions(+), 220 deletions(-) rename djangocms_frontend/{contrib/component/components.py => component_base.py} (89%) delete mode 100644 djangocms_frontend/contrib/component/__init__.py delete mode 100644 djangocms_frontend/contrib/component/cms_plugins.py delete mode 100644 djangocms_frontend/contrib/component/registry.py create mode 100644 djangocms_frontend/plugin_tag.py rename djangocms_frontend/{contrib/component => }/templates/djangocms_frontend/slot.html (100%) create mode 100644 djangocms_frontend/ui_plugin_base.py diff --git a/djangocms_frontend/apps.py b/djangocms_frontend/apps.py index 0de7123c..ade4c34b 100644 --- a/djangocms_frontend/apps.py +++ b/djangocms_frontend/apps.py @@ -7,10 +7,10 @@ class DjangocmsFrontendConfig(apps.AppConfig): verbose_name = "django CMS Frontend" def ready(self): - from .component_pool import setup + from . import plugin_tag register(check_settings) - setup() + plugin_tag.setup() def check_settings(*args, **kwargs): diff --git a/djangocms_frontend/cms_plugins.py b/djangocms_frontend/cms_plugins.py index d4610163..d36657c7 100644 --- a/djangocms_frontend/cms_plugins.py +++ b/djangocms_frontend/cms_plugins.py @@ -1,44 +1,23 @@ -from cms.constants import SLUG_REGEXP -from cms.plugin_base import CMSPluginBase -from django.utils.encoding import force_str +from cms.plugin_pool import plugin_pool -from djangocms_frontend.helpers import get_related +from .component_pool import components +from .ui_plugin_base import CMSUIPluginBase -if hasattr(CMSPluginBase, "edit_field"): - # FrontendEditable functionality already implemented in core? - FrontendEditableAdminMixin = object -else: - # If not use our own version of the plugin-enabled mixin - from .helpers import FrontendEditableAdminMixin +class CMSUIPlugin(CMSUIPluginBase): + pass -class CMSUIPlugin(FrontendEditableAdminMixin, CMSPluginBase): - render_template = "djangocms_frontend/html_container.html" - change_form_template = "djangocms_frontend/admin/base.html" - def __str__(self): - return force_str(super().__str__()) +# Loop through the values in the components' registry +for _, plugin, slot_plugins in components._registry.values(): + # Add the plugin to the global namespace + globals()[plugin.__name__] = plugin + # Register the plugin with the plugin pool + plugin_pool.register_plugin(plugin) - def render(self, context, instance, placeholder): - for key, value in instance.config.items(): - if isinstance(value, dict) and set(value.keys()) == {"pk", "model"}: - if key not in instance.__dir__(): # hasattr would return the value in the config dict - setattr(instance.__class__, key, get_related(key)) - return super().render(context, instance, placeholder) - - def get_plugin_urls(self): - from django.urls import re_path - - info = f"{self.model._meta.app_label}_{self.model._meta.model_name}" - - def pat(regex, fn): - return re_path(regex, fn, name=f"{info}_{fn.__name__}") - - return [ - pat(r'edit-field/(%s)/([a-z\-]+)/$' % SLUG_REGEXP, self.edit_field), - ] - - def _get_object_for_single_field(self, object_id, language): - from .models import FrontendUIItem - - return FrontendUIItem.objects.get(pk=object_id) + # Loop through the slot plugins associated with the current plugin + for slot_plugin in slot_plugins: + # Add the slot plugin to the global namespace + globals()[slot_plugin.__name__] = slot_plugin + # Register the slot plugin with the plugin pool + plugin_pool.register_plugin(slot_plugin) diff --git a/djangocms_frontend/contrib/component/components.py b/djangocms_frontend/component_base.py similarity index 89% rename from djangocms_frontend/contrib/component/components.py rename to djangocms_frontend/component_base.py index f8d4d603..3659fb0f 100644 --- a/djangocms_frontend/contrib/component/components.py +++ b/djangocms_frontend/component_base.py @@ -9,6 +9,8 @@ from django.utils.translation import gettext_lazy as _ from entangled.forms import EntangledModelForm +from .ui_plugin_base import CMSUIPluginBase + def _get_mixin_classes(mixins: list, suffix: str = "") -> list[type]: """Find and import mixin classes from a list of mixin strings""" @@ -112,8 +114,6 @@ def plugin_model_factory(cls) -> type: @classmethod def plugin_factory(cls) -> type: if cls._plugin is None: - from djangocms_frontend.cms_plugins import CMSUIPlugin - mixins = getattr(cls._component_meta, "mixins", []) slots = cls.get_slot_plugins() mixins = _get_mixin_classes(mixins) @@ -123,16 +123,18 @@ def plugin_factory(cls) -> type: ( *mixins, *cls._plugin_mixins, - CMSUIPlugin, + CMSUIPluginBase, ), { "name": getattr(cls._component_meta, "name", cls.__name__), - "module": getattr(cls._component_meta, "module", _("Component")), + "module": getattr(cls._component_meta, "module", _("Components")), "model": cls.plugin_model_factory(), "form": cls.admin_form_factory(), "allow_children": getattr(cls._component_meta, "allow_children", False) or slots, + "require_parent": getattr(cls._component_meta, "require_parent", False), "child_classes": getattr(cls._component_meta, "child_classes", []) + list(slots.keys()), - "render_template": getattr(cls._component_meta, "render_template", CMSUIPlugin.render_template), + "parent_classes": getattr(cls._component_meta, "parent_classes", []), + "render_template": getattr(cls._component_meta, "render_template", CMSUIPluginBase.render_template), "fieldsets": getattr(cls, "fieldsets", cls._generate_fieldset()), "change_form_template": "djangocms_frontend/admin/base.html", "slots": slots, @@ -182,9 +184,7 @@ def get_registration(cls) -> tuple[type, type, list[type]]: @classmethod @property def _component_meta(cls) -> typing.Optional[type]: - if hasattr(cls, "Meta"): - return cls.Meta - return None + return getattr(cls, "Meta", None) @classmethod def _generate_fieldset(cls) -> list[tuple[typing.Optional[str], dict]]: @@ -194,20 +194,9 @@ def get_short_description(self) -> str: return self.config.get("title", "") def save_model(self, request, obj, form: forms.Form, change: bool) -> None: - """Auto-createas slot plugins upon creation of component plugin instance""" - from djangocms_frontend.cms_plugins import CMSUIPlugin + """Auto-creates slot plugins upon creation of component plugin instance""" - super(CMSUIPlugin, self).save_model(request, obj, form, change) + super(CMSUIPluginBase, self).save_model(request, obj, form, change) if not change: for slot in self.slots.keys(): add_plugin(obj.placeholder, slot, obj.language, target=obj) - - -class ComponentLinkMixin: - from djangocms_frontend.contrib.link.cms_plugins import LinkPluginMixin - from djangocms_frontend.contrib.link.forms import AbstractLinkForm - from djangocms_frontend.contrib.link.helpers import GetLinkMixin - - _base_form = AbstractLinkForm - _model_mixins = [GetLinkMixin] - _plugin_mixins = [LinkPluginMixin] diff --git a/djangocms_frontend/component_pool.py b/djangocms_frontend/component_pool.py index c1024d32..95c8fb8d 100644 --- a/djangocms_frontend/component_pool.py +++ b/djangocms_frontend/component_pool.py @@ -1,97 +1,25 @@ -import copy -import importlib import warnings -from cms.plugin_pool import plugin_pool -from cms.templatetags.cms_tags import render_plugin -from django.conf import settings -from django.contrib.admin.sites import site as admin_site -from django.template import engines -from django.template.library import SimpleNode -from django.template.loader import get_template +from django.utils.module_loading import autodiscover_modules -django_engine = engines["django"] -plugin_tag_pool = {} +class Components: + _registry: dict = {} + _discovered: bool = False + def register(self, component): + if component.__name__ in self._registry: + warnings.warn(f"Component {component.__name__} already registered", stacklevel=2) + return component + self._registry[component.__name__] = component.get_registration() + return component -IGNORED_FIELDS = ( - "id", - "cmsplugin_ptr", - "language", - "plugin_type", - "position", - "creation_date", - "ui_item", -) + def __getitem__(self, item): + return self._registry[item] -allowed_plugin_types = tuple( - getattr(importlib.import_module(cls.rsplit(".", 1)[0]), cls.rsplit(".", 1)[-1]) if isinstance(cls, str) else cls - for cls in getattr(settings, "CMS_COMPONENT_PLUGINS", []) -) +components = Components() -def _get_plugindefaults(instance): - defaults = { - field.name: getattr(instance, field.name) - for field in instance._meta.fields - if field.name not in IGNORED_FIELDS and bool(getattr(instance, field.name)) - } - defaults["plugin_type"] = instance.__class__.__name__ - return defaults - - -class _DummyUser: - is_superuser = True - is_staff = True - - -class _DummyRequest: - user = _DummyUser() - - -def render_dummy_plugin(context, dummy_plugin): - return dummy_plugin.nodelist.render(context) - - -def patch_template(template): - """Patches the template to use the dummy plugin renderer instead of the real one.""" - copied_template = copy.deepcopy(template) - patch = False - for node in copied_template.template.nodelist.get_nodes_by_type(SimpleNode): - if node.func == render_plugin: - patch = True - node.func = render_dummy_plugin - return copied_template if patch else template - - -def setup(): - global plugin_tag_pool - - for plugin in plugin_pool.get_all_plugins(): - if not issubclass(plugin, allowed_plugin_types): - continue - tag_name = plugin.__name__.lower() - if tag_name.endswith("plugin"): - tag_name = tag_name[:-6] - try: - instance = plugin.model() # Create instance with defaults - plugin_admin = plugin(admin_site=admin_site) - if hasattr(instance, "initialize_from_form"): - instance.initialize_from_form(plugin.form) - if tag_name not in plugin_tag_pool: - template = get_template(plugin_admin._get_render_template({"request": None}, instance, None)) - plugin_tag_pool[tag_name] = { - "defaults": { - **_get_plugindefaults(instance), - **dict(plugin_type=plugin.__name__), - }, - "template": patch_template(template), - "class": plugin, - } - else: # pragma: no cover - warnings.warn( - f"Duplicate candidates for {{% plugin \"{tag_name}\" %}} found. " - f"Only registered {plugin_tag_pool[tag_name]['class'].__name__}.", stacklevel=1) - except Exception as exc: # pragma: no cover - warnings.warn(f"{plugin.__name__}: \n{str(exc)}", stacklevel=1) +if not components._discovered: + autodiscover_modules("cms_components", register_to=components) + components._discovered = True diff --git a/djangocms_frontend/contrib/component/__init__.py b/djangocms_frontend/contrib/component/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/djangocms_frontend/contrib/component/cms_plugins.py b/djangocms_frontend/contrib/component/cms_plugins.py deleted file mode 100644 index 896bcab0..00000000 --- a/djangocms_frontend/contrib/component/cms_plugins.py +++ /dev/null @@ -1,18 +0,0 @@ -from cms.plugin_pool import plugin_pool - -# Import the components from the current directory's models module -from .registry import components - -# Loop through the values in the components' registry -for _, plugin, slot_plugins in components._registry.values(): - # Add the plugin to the global namespace - globals()[plugin.__name__] = plugin - # Register the plugin with the plugin pool - plugin_pool.register_plugin(plugin) - - # Loop through the slot plugins associated with the current plugin - for slot_plugin in slot_plugins: - # Add the slot plugin to the global namespace - globals()[slot_plugin.__name__] = slot_plugin - # Register the slot plugin with the plugin pool - plugin_pool.register_plugin(slot_plugin) diff --git a/djangocms_frontend/contrib/component/registry.py b/djangocms_frontend/contrib/component/registry.py deleted file mode 100644 index 95c8fb8d..00000000 --- a/djangocms_frontend/contrib/component/registry.py +++ /dev/null @@ -1,25 +0,0 @@ -import warnings - -from django.utils.module_loading import autodiscover_modules - - -class Components: - _registry: dict = {} - _discovered: bool = False - - def register(self, component): - if component.__name__ in self._registry: - warnings.warn(f"Component {component.__name__} already registered", stacklevel=2) - return component - self._registry[component.__name__] = component.get_registration() - return component - - def __getitem__(self, item): - return self._registry[item] - - -components = Components() - -if not components._discovered: - autodiscover_modules("cms_components", register_to=components) - components._discovered = True diff --git a/djangocms_frontend/helpers.py b/djangocms_frontend/helpers.py index dd007707..d768fbd4 100644 --- a/djangocms_frontend/helpers.py +++ b/djangocms_frontend/helpers.py @@ -256,5 +256,5 @@ def edit_field(self, request, object_id, language): obj.placeholder.mark_as_dirty(obj.language, clear_cache=False) # Update the structure board by populating the data bridge return self.render_close_frame(request, obj) - render(request, 'admin/cms/page/plugin/confirm_form.html', context) + return render(request, 'admin/cms/page/plugin/confirm_form.html', context) return render(request, 'admin/cms/page/plugin/change_form.html', context) diff --git a/djangocms_frontend/plugin_tag.py b/djangocms_frontend/plugin_tag.py new file mode 100644 index 00000000..c1024d32 --- /dev/null +++ b/djangocms_frontend/plugin_tag.py @@ -0,0 +1,97 @@ +import copy +import importlib +import warnings + +from cms.plugin_pool import plugin_pool +from cms.templatetags.cms_tags import render_plugin +from django.conf import settings +from django.contrib.admin.sites import site as admin_site +from django.template import engines +from django.template.library import SimpleNode +from django.template.loader import get_template + +django_engine = engines["django"] + +plugin_tag_pool = {} + + +IGNORED_FIELDS = ( + "id", + "cmsplugin_ptr", + "language", + "plugin_type", + "position", + "creation_date", + "ui_item", +) + +allowed_plugin_types = tuple( + getattr(importlib.import_module(cls.rsplit(".", 1)[0]), cls.rsplit(".", 1)[-1]) if isinstance(cls, str) else cls + for cls in getattr(settings, "CMS_COMPONENT_PLUGINS", []) +) + + +def _get_plugindefaults(instance): + defaults = { + field.name: getattr(instance, field.name) + for field in instance._meta.fields + if field.name not in IGNORED_FIELDS and bool(getattr(instance, field.name)) + } + defaults["plugin_type"] = instance.__class__.__name__ + return defaults + + +class _DummyUser: + is_superuser = True + is_staff = True + + +class _DummyRequest: + user = _DummyUser() + + +def render_dummy_plugin(context, dummy_plugin): + return dummy_plugin.nodelist.render(context) + + +def patch_template(template): + """Patches the template to use the dummy plugin renderer instead of the real one.""" + copied_template = copy.deepcopy(template) + patch = False + for node in copied_template.template.nodelist.get_nodes_by_type(SimpleNode): + if node.func == render_plugin: + patch = True + node.func = render_dummy_plugin + return copied_template if patch else template + + +def setup(): + global plugin_tag_pool + + for plugin in plugin_pool.get_all_plugins(): + if not issubclass(plugin, allowed_plugin_types): + continue + tag_name = plugin.__name__.lower() + if tag_name.endswith("plugin"): + tag_name = tag_name[:-6] + try: + instance = plugin.model() # Create instance with defaults + plugin_admin = plugin(admin_site=admin_site) + if hasattr(instance, "initialize_from_form"): + instance.initialize_from_form(plugin.form) + if tag_name not in plugin_tag_pool: + template = get_template(plugin_admin._get_render_template({"request": None}, instance, None)) + plugin_tag_pool[tag_name] = { + "defaults": { + **_get_plugindefaults(instance), + **dict(plugin_type=plugin.__name__), + }, + "template": patch_template(template), + "class": plugin, + } + else: # pragma: no cover + warnings.warn( + f"Duplicate candidates for {{% plugin \"{tag_name}\" %}} found. " + f"Only registered {plugin_tag_pool[tag_name]['class'].__name__}.", stacklevel=1) + except Exception as exc: # pragma: no cover + warnings.warn(f"{plugin.__name__}: \n{str(exc)}", stacklevel=1) diff --git a/djangocms_frontend/contrib/component/templates/djangocms_frontend/slot.html b/djangocms_frontend/templates/djangocms_frontend/slot.html similarity index 100% rename from djangocms_frontend/contrib/component/templates/djangocms_frontend/slot.html rename to djangocms_frontend/templates/djangocms_frontend/slot.html diff --git a/djangocms_frontend/templatetags/frontend.py b/djangocms_frontend/templatetags/frontend.py index 87172e25..fa12c1a5 100644 --- a/djangocms_frontend/templatetags/frontend.py +++ b/djangocms_frontend/templatetags/frontend.py @@ -159,7 +159,7 @@ def message(self, message): return f"" if django_settings.DEBUG else "" def get_value(self, context, name, kwargs, nodelist): - from djangocms_frontend.component_pool import plugin_tag_pool + from djangocms_frontend.plugin_tag import plugin_tag_pool if name not in plugin_tag_pool: return self.message(f'Plugin "{name}" not found in pool for plugins usable with {{% plugin %}}') diff --git a/djangocms_frontend/ui_plugin_base.py b/djangocms_frontend/ui_plugin_base.py new file mode 100644 index 00000000..e61d13ad --- /dev/null +++ b/djangocms_frontend/ui_plugin_base.py @@ -0,0 +1,51 @@ +from cms.admin.placeholderadmin import PlaceholderAdmin +from cms.plugin_base import CMSPluginBase + +# Import the components from the current directory's models module +from django.utils.encoding import force_str + +from djangocms_frontend.helpers import get_related + +if hasattr(PlaceholderAdmin, "edit_field"): + # FrontendEditable functionality already implemented in core? + class FrontendEditableAdminMixin: + pass +else: + # If not use our own version of the plugin-enabled mixin + from .helpers import FrontendEditableAdminMixin + + +class CMSUIPluginBase(FrontendEditableAdminMixin, CMSPluginBase): + render_template = "djangocms_frontend/html_container.html" + change_form_template = "djangocms_frontend/admin/base.html" + + def __str__(self): + return force_str(super().__str__()) + + def render(self, context, instance, placeholder): + for key, value in instance.config.items(): + if isinstance(value, dict) and set(value.keys()) == {"pk", "model"}: + if key not in instance.__dir__(): # hasattr would return the value in the config dict + setattr(instance.__class__, key, get_related(key)) + return super().render(context, instance, placeholder) + + if not hasattr(PlaceholderAdmin, "edit_field"): + # If the PlaceholderAdmin does not have the edit_field method, we need to provide + # the urls and the object getter here + def get_plugin_urls(self): + from django.urls import re_path + + info = f"{self.model._meta.app_label}_{self.model._meta.model_name}" + + def pat(regex, fn): + return re_path(regex, fn, name=f"{info}_{fn.__name__}") + + return [ + pat(r'edit-field/([0-9]+)/([a-z\-]+)/$', self.edit_field), + ] + super().get_plugin_urls() + + def _get_object_for_single_field(self, object_id, language): + # Method to get the object for the single field edit view + from .models import FrontendUIItem + + return FrontendUIItem.objects.get(pk=object_id) diff --git a/docs/source/custom_components.rst b/docs/source/custom_components.rst index 0b8f1035..26bb9070 100644 --- a/docs/source/custom_components.rst +++ b/docs/source/custom_components.rst @@ -19,17 +19,8 @@ With django CMS you make your components available to the content editors for drag and drop **and** frontend developers for use in templates from a single source. -To use custom components in your project, add -``"djangocms_frontend.contrib.component"`` to your ``INSTALLED_APPS`` setting. - -.. code-block:: python - - INSTALLED_APPS = [ - ... - "djangocms_frontend.contrib.component", - ... - ] - +Custom components are part of the djangocms-frontend root package and do not +require additional listing in the ``INSTALLED_APPS`` setting. **djangocms-frontend** will look for custom components in the ``cms_components`` module in any of your apps. This way you can @@ -47,8 +38,8 @@ Add a ``cms_components.py`` file to the ``theme`` app: # theme/cms_components.py from djangocms_link.fields import LinkFormField - from djangocms_frontend.contrib.component.components import ComponentLinkMixin, CMSFrontendComponent - from djangocms_frontend.contrib.component.components import components + from djangocms_frontend.component_base import CMSFrontendComponent + from djangocms_frontend.component_pool import components from djangocms_frontend.contrib.image.fields import ImageFormField diff --git a/tests/component/test_models.py b/tests/component/test_models.py index c1fa79c8..001e0d79 100644 --- a/tests/component/test_models.py +++ b/tests/component/test_models.py @@ -1,6 +1,6 @@ from django.test import TestCase -from djangocms_frontend.contrib.component.registry import components +from djangocms_frontend.component_pool import components class ComponentPluginTestCase(TestCase): diff --git a/tests/component/test_plugins.py b/tests/component/test_plugins.py index f6cdd448..3368d341 100644 --- a/tests/component/test_plugins.py +++ b/tests/component/test_plugins.py @@ -1,12 +1,12 @@ from cms.api import add_plugin from cms.test_utils.testcases import CMSTestCase -from djangocms_frontend.contrib.alert.cms_plugins import AlertPlugin -from djangocms_frontend.contrib.component.cms_plugins import ( +from djangocms_frontend.cms_plugins import ( MyButtonPlugin, MyHeroPlugin, MyStrangeComponentPlugin, ) +from djangocms_frontend.contrib.alert.cms_plugins import AlertPlugin from ..fixtures import TestFixture @@ -54,7 +54,7 @@ def test_component_with_empty_slots_plugin(self): ) def test_component_with_slots_plugin(self): - from djangocms_frontend.contrib.component.cms_plugins import MyHeroSlotPlugin + from djangocms_frontend.cms_plugins import MyHeroSlotPlugin instance = add_plugin( placeholder=self.placeholder, @@ -119,10 +119,7 @@ def test_component_with_slots_plugin(self): ) def test_autocreate_slots(self): - from djangocms_frontend.contrib.component.cms_plugins import ( - MyHeroSlotPlugin, - MyHeroTitlePlugin, - ) + from djangocms_frontend.cms_plugins import MyHeroSlotPlugin, MyHeroTitlePlugin instance = add_plugin( placeholder=self.placeholder, diff --git a/tests/test_app/cms_components.py b/tests/test_app/cms_components.py index c319ecae..ba7e5721 100644 --- a/tests/test_app/cms_components.py +++ b/tests/test_app/cms_components.py @@ -1,8 +1,8 @@ from django import forms from djangocms_link.fields import LinkFormField -from djangocms_frontend.contrib.component.components import CMSFrontendComponent -from djangocms_frontend.contrib.component.registry import components +from djangocms_frontend.component_base import CMSFrontendComponent +from djangocms_frontend.component_pool import components from djangocms_frontend.contrib.image.fields import ImageFormField diff --git a/tests/test_settings.py b/tests/test_settings.py index 96e1511a..68ea56b6 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -23,7 +23,6 @@ "djangocms_frontend.contrib.card", "djangocms_frontend.contrib.carousel", "djangocms_frontend.contrib.collapse", - "djangocms_frontend.contrib.component", "djangocms_frontend.contrib.content", "djangocms_frontend.contrib.grid", "djangocms_frontend.contrib.icon", diff --git a/tests/utilities/test_plugins.py b/tests/utilities/test_plugins.py index ee3f6987..222da531 100644 --- a/tests/utilities/test_plugins.py +++ b/tests/utilities/test_plugins.py @@ -1,3 +1,4 @@ +from cms.admin.placeholderadmin import PlaceholderAdmin from cms.api import add_plugin from cms.test_utils.testcases import CMSTestCase from cms.utils.urlutils import admin_reverse @@ -100,8 +101,12 @@ def test_heading_inline_endpoint(self): "heading_id": "id1", }, ) - url_endpoint = admin_reverse("utilities_heading_edit_field", args=[heading.pk, self.language]) - url_endpoint += "?edit_fields=heading" + + if hasattr(PlaceholderAdmin, "edit_field"): + url_endpoint = "cms_placeholder_edit_field" + else: + url_endpoint = "utilities_heading_edit_field" + url_endpoint = admin_reverse(url_endpoint, args=[heading.pk, self.language]) + "?edit_fields=heading" data = { "heading": "My new heading", } From f865a486cadf1ce44332e887d3a7e508c6974e51 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Tue, 5 Nov 2024 22:22:48 +0100 Subject: [PATCH 45/66] Fix: Version 3 import --- README.rst | 9 ++++++--- djangocms_frontend/ui_plugin_base.py | 19 ++++++++++++------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/README.rst b/README.rst index f9c383f9..85451e68 100644 --- a/README.rst +++ b/README.rst @@ -4,16 +4,19 @@ |pypi| |docs| |coverage| |python| |django| |djangocms| |djangocms4| -**django CMS Frontend** is a plugin bundle which builds on and improves +**django CMS Frontend** is a plugin bundle which originally built on and improved the architecture of `djangocms-bootstrap4 `_. -Its objective is to provide a set of popular frontend components independent of the -currently used frontend framework such as Bootstrap, or its specific version. +Its objective is to provide a toolset to quickly create re-usable frontend +components and comes preloaded with a set of popular frontend components +independent of the currently used frontend framework such as Bootstrap, or +its specific version. .. image:: preview.png Key features ============ +- Easy to implement re-usable frontend custom components. - Support of `Bootstrap 5 `_, django CMS 3.8+ and django CMS 4. diff --git a/djangocms_frontend/ui_plugin_base.py b/djangocms_frontend/ui_plugin_base.py index e61d13ad..3ac0226f 100644 --- a/djangocms_frontend/ui_plugin_base.py +++ b/djangocms_frontend/ui_plugin_base.py @@ -1,4 +1,3 @@ -from cms.admin.placeholderadmin import PlaceholderAdmin from cms.plugin_base import CMSPluginBase # Import the components from the current directory's models module @@ -6,12 +5,18 @@ from djangocms_frontend.helpers import get_related -if hasattr(PlaceholderAdmin, "edit_field"): - # FrontendEditable functionality already implemented in core? - class FrontendEditableAdminMixin: - pass -else: - # If not use our own version of the plugin-enabled mixin +try: + from cms.admin.placeholderadmin import PlaceholderAdmin + + if hasattr(PlaceholderAdmin, "edit_field"): + # FrontendEditable functionality already implemented in core? + class FrontendEditableAdminMixin: + pass + else: + # If not use our own version of the plugin-enabled mixin + raise ImportError +except ImportError: + # django CMS 3 did not implement this: use our own version of the plugin-enabled mixin from .helpers import FrontendEditableAdminMixin From fdfe7f28075da5e2d5d1e3cb2057143af25e68b4 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Tue, 5 Nov 2024 23:37:37 +0100 Subject: [PATCH 46/66] Update docs --- README.rst | 50 +++++++-------- .../static/djangocms_frontend/css/base.css | 2 +- .../djangocms_frontend/admin/base-tabs.html | 62 +++++++++---------- docs/source/custom_components.rst | 9 +-- docs/source/grid.rst | 8 ++- docs/source/index.rst | 59 +++++++----------- private/sass/components/_tabs.scss | 4 ++ 7 files changed, 93 insertions(+), 101 deletions(-) diff --git a/README.rst b/README.rst index 85451e68..45e85833 100644 --- a/README.rst +++ b/README.rst @@ -16,9 +16,11 @@ its specific version. Key features ============ -- Easy to implement re-usable frontend custom components. +- **Easy to implement re-usable frontend custom components**, which in the + simples case consist of a template and declarative sort of form class. + - Support of `Bootstrap 5 `_, django CMS 3.8+ - and django CMS 4. + and django CMS 4 out of the box. - **Separation of plugins from css framework**, i.e. no need to rebuild you site's plugin tree if css framework is changed in the @@ -38,10 +40,6 @@ Key features (e.g. in a custom app) giving your whole project a more consistent user experience. -- A management command to **migrate from djangocms-bootstrap4**. This - command automatically migrates all ``djangocms-bootstrap4`` plugins to - ``djangocms-frontend``. - Description =========== @@ -58,10 +56,6 @@ Instead all design parameters are stored in a common JSON field and future releases of improved frontend features will not require to rebuild your full plugin tree. -The link plugin has been rewritten to not only allow internal links to other -CMS pages, but also to other django models such as, e.g., posts of -`djangocms-blog `_. - The plugins are designed to be re-usable as UI components in your project, e.g. in a custom app, giving your whole project a more consistent user experience. @@ -101,8 +95,7 @@ file for additional dependencies: - django-cms, version 3.7 or later - django-filer, version 1.7 or later - djangocms-attributes-field, version 1.0 or later -- djangocms-text-ckeditor, version 3.1 or later -- django-select2 +- djangocms-text - django-entangled Make sure `django Filer @@ -124,23 +117,22 @@ For a manual install: 'easy_thumbnails', 'djangocms_frontend', - 'djangocms_frontend.contrib.accordion', - 'djangocms_frontend.contrib.alert', - 'djangocms_frontend.contrib.badge', - 'djangocms_frontend.contrib.card', - 'djangocms_frontend.contrib.carousel', - 'djangocms_frontend.contrib.collapse', - 'djangocms_frontend.contrib.component', - 'djangocms_frontend.contrib.content', - 'djangocms_frontend.contrib.grid', - 'djangocms_frontend.contrib.icon', - 'djangocms_frontend.contrib.image', - 'djangocms_frontend.contrib.jumbotron', - 'djangocms_frontend.contrib.link', - 'djangocms_frontend.contrib.listgroup', - 'djangocms_frontend.contrib.media', - 'djangocms_frontend.contrib.tabs', - 'djangocms_frontend.contrib.utilities', + 'djangocms_frontend.contrib.accordion', # optional + 'djangocms_frontend.contrib.alert', # optional + 'djangocms_frontend.contrib.badge', # optional + 'djangocms_frontend.contrib.card', # optional + 'djangocms_frontend.contrib.carousel', # optional + 'djangocms_frontend.contrib.collapse', # optional + 'djangocms_frontend.contrib.content', # optional + 'djangocms_frontend.contrib.grid', # optional + 'djangocms_frontend.contrib.icon', # optional + 'djangocms_frontend.contrib.image', # optional + 'djangocms_frontend.contrib.jumbotron', # optional + 'djangocms_frontend.contrib.link', # optional + 'djangocms_frontend.contrib.listgroup', # optional + 'djangocms_frontend.contrib.media', # optional + 'djangocms_frontend.contrib.tabs', # optional + 'djangocms_frontend.contrib.utilities', # optional - run ``python manage.py migrate`` diff --git a/djangocms_frontend/static/djangocms_frontend/css/base.css b/djangocms_frontend/static/djangocms_frontend/css/base.css index d73825f1..f9ccbb45 100644 --- a/djangocms_frontend/static/djangocms_frontend/css/base.css +++ b/djangocms_frontend/static/djangocms_frontend/css/base.css @@ -5,4 +5,4 @@ /private/sass instead */ -@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:0.8125rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#0d6efd;--bs-link-hover-color:#0a58ca;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-size:0.8125rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#212529;--bs-btn-bg:transparent;--bs-btn-border-width:1px;--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-ms-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.015625rem;--bs-btn-border-radius:0.5rem}.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.7109375rem;--bs-btn-border-radius:0.25rem}.link-primary{color:#0d6efd!important}.link-primary:focus,.link-primary:hover{color:#0a58ca!important}.link-secondary{color:#6c757d!important}.link-secondary:focus,.link-secondary:hover{color:#565e64!important}.link-success{color:#198754!important}.link-success:focus,.link-success:hover{color:#146c43!important}.link-info{color:#0dcaf0!important}.link-info:focus,.link-info:hover{color:#3dd5f3!important}.link-warning{color:#ffc107!important}.link-warning:focus,.link-warning:hover{color:#ffcd39!important}.link-danger{color:#dc3545!important}.link-danger:focus,.link-danger:hover{color:#b02a37!important}.link-light{color:#f8f9fa!important}.link-light:focus,.link-light:hover{color:#f9fafb!important}.link-dark{color:#212529!important}.link-dark:focus,.link-dark:hover{color:#1a1e21!important}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.3rem;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#6c757d;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:1px;--bs-nav-tabs-border-color:#dee2e6;--bs-nav-tabs-border-radius:0.375rem;--bs-nav-tabs-link-hover-border-color:#e9ecef #e9ecef #dee2e6;--bs-nav-tabs-link-active-color:#495057;--bs-nav-tabs-link-active-bg:#fff;--bs-nav-tabs-link-active-border-color:#dee2e6 #dee2e6 #fff;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:4px;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0bf}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.icon{display:inline-block;vertical-align:top;width:1em;height:1em;background-position:center;background-repeat:no-repeat}.icon svg{display:block;width:100%;height:100%}.icon-info{width:.9em;font-size:110%!important}.icon-white{color:#fff}.icon-white svg{fill:#fff}.icon-black{color:#000}.icon-black svg{fill:#000}.icon-primary{color:#0bf}.icon-primary svg{fill:#0bf}.djangocms-icon .icon>input{float:left;position:relative;top:12px}.djangocms-icon .caret{margin-inline-start:8px}.aligned .frontend-button-group label{min-width:unset}.frontend-button-group{display:inline-block}.frontend-button-group .btn{box-sizing:border-box;cursor:pointer;-webkit-appearance:none;margin:2px;overflow:hidden;text-overflow:ellipsis}.frontend-button-group .btn.active{outline:3px solid #0bf;border-color:#fff!important}.frontend-button-group .btn-default.active{border-radius:0;background-color:#0bf!important}.frontend-button-group-context-colors>div,.frontend-button-group-context-size>div{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;min-height:75px}.frontend-button-group-context-colors .btn{-ms-flex-preferred-size:calc(25% - 4px);flex-basis:calc(25% - 4px)}@media (min-width:820px){.frontend-button-group-context-colors .btn{-ms-flex-preferred-size:calc(20% - 4px);flex-basis:calc(20% - 4px)}}.frontend-button-group-icons .icon,.frontend-grid-icons .icon{font-size:24px}.frontend-button-group-icons .icon-flex-align-center,.frontend-button-group-icons .icon-flex-align-end,.frontend-button-group-icons .icon-flex-align-start,.frontend-grid-icons .icon-flex-align-center,.frontend-grid-icons .icon-flex-align-end,.frontend-grid-icons .icon-flex-align-start{transform:scale(1.4)}.frontend-button-group-icons .icon-flex-content-around,.frontend-button-group-icons .icon-flex-content-between,.frontend-grid-icons .icon-flex-content-around,.frontend-grid-icons .icon-flex-content-between{transform:scale(1.6)}.frontend-button-group-icons .icon-flex-self-center,.frontend-button-group-icons .icon-flex-self-end,.frontend-button-group-icons .icon-flex-self-start,.frontend-grid-icons .icon-flex-self-center,.frontend-grid-icons .icon-flex-self-end,.frontend-grid-icons .icon-flex-self-start{transform:scale(1.4)}.frontend-button-group-icons .icon-align-reset,.frontend-button-group-icons .icon-no-selection,.frontend-grid-icons .icon-align-reset,.frontend-grid-icons .icon-no-selection{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-align-items-start,.frontend-button-group-icons .icon-flex-align-start,.frontend-grid-icons .icon-align-items-start,.frontend-grid-icons .icon-flex-align-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-items-center,.frontend-button-group-icons .icon-flex-align-center,.frontend-grid-icons .icon-align-items-center,.frontend-grid-icons .icon-flex-align-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-items-end,.frontend-button-group-icons .icon-flex-align-end,.frontend-grid-icons .icon-align-items-end,.frontend-grid-icons .icon-flex-align-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-flex-content-start,.frontend-button-group-icons .icon-justify-content-start,.frontend-button-group-icons .icon-start,.frontend-grid-icons .icon-flex-content-start,.frontend-grid-icons .icon-justify-content-start,.frontend-grid-icons .icon-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-center,.frontend-button-group-icons .icon-flex-content-center,.frontend-button-group-icons .icon-justify-content-center,.frontend-grid-icons .icon-center,.frontend-grid-icons .icon-flex-content-center,.frontend-grid-icons .icon-justify-content-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-end,.frontend-button-group-icons .icon-flex-content-end,.frontend-button-group-icons .icon-justify-content-end,.frontend-grid-icons .icon-end,.frontend-grid-icons .icon-flex-content-end,.frontend-grid-icons .icon-justify-content-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-flex-content-around,.frontend-button-group-icons .icon-justify-content-around,.frontend-grid-icons .icon-flex-content-around,.frontend-grid-icons .icon-justify-content-around{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.6)}.frontend-button-group-icons .icon-flex-content-between,.frontend-button-group-icons .icon-justify-content-between,.frontend-grid-icons .icon-flex-content-between,.frontend-grid-icons .icon-justify-content-between{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.6)}.frontend-button-group-icons .icon-nav-fill,.frontend-grid-icons .icon-nav-fill{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-nav-justified,.frontend-grid-icons .icon-nav-justified{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-flex-column,.frontend-grid-icons .icon-flex-column{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-start,.frontend-button-group-icons .icon-flex-self-start,.frontend-grid-icons .icon-align-self-start,.frontend-grid-icons .icon-flex-self-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-center,.frontend-button-group-icons .icon-flex-self-center,.frontend-grid-icons .icon-align-self-center,.frontend-grid-icons .icon-flex-self-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-end,.frontend-button-group-icons .icon-flex-self-end,.frontend-grid-icons .icon-align-self-end,.frontend-grid-icons .icon-flex-self-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-size-sm,.frontend-button-group-icons .icon-size-xs,.frontend-button-group-icons .icon-sm,.frontend-button-group-icons .icon-xs,.frontend-grid-icons .icon-size-sm,.frontend-grid-icons .icon-size-xs,.frontend-grid-icons .icon-sm,.frontend-grid-icons .icon-xs{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-sm,.frontend-button-group-icons .icon-sm,.frontend-grid-icons .icon-size-sm,.frontend-grid-icons .icon-sm{transform:rotate(-90deg)}.frontend-button-group-icons .icon-md,.frontend-button-group-icons .icon-size-md,.frontend-grid-icons .icon-md,.frontend-grid-icons .icon-size-md{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-lg,.frontend-button-group-icons .icon-size-lg,.frontend-grid-icons .icon-lg,.frontend-grid-icons .icon-size-lg{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-xl,.frontend-button-group-icons .icon-xl,.frontend-grid-icons .icon-size-xl,.frontend-grid-icons .icon-xl{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-xxl,.frontend-button-group-icons .icon-xxl,.frontend-grid-icons .icon-size-xxl,.frontend-grid-icons .icon-xxl{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-mb,.frontend-grid-icons .icon-mb{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-me,.frontend-grid-icons .icon-me{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-ms,.frontend-grid-icons .icon-ms{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-mt,.frontend-grid-icons .icon-mt{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-mx,.frontend-grid-icons .icon-mx{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-my,.frontend-grid-icons .icon-my{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pb,.frontend-grid-icons .icon-pb{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pe,.frontend-grid-icons .icon-pe{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-ps,.frontend-grid-icons .icon-ps{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pt,.frontend-grid-icons .icon-pt{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-px,.frontend-grid-icons .icon-px{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-py,.frontend-grid-icons .icon-py{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.icon-info{background-image:url('data:image/svg+xml;utf8,')}.module{margin:0 0 20px}.djangocms-frontend-row .form-row.field-create .icon{position:absolute;font-size:30px;margin-block-start:28px;margin-inline-start:4px}.djangocms-frontend-row .form-row.field-create input[name=create]{width:130px!important;padding-inline-end:5px!important;text-align:start}.djangocms-frontend-column .form-row.field-xs_col,.djangocms-frontend-column .form-row.field-xs_me,.djangocms-frontend-column .form-row.field-xs_ms,.djangocms-frontend-column .form-row.field-xs_offset,.djangocms-frontend-column .form-row.field-xs_order,.djangocms-frontend-row .form-row.field-row_cols_xs{position:relative;display:-ms-flexbox;display:flex;padding:0;min-width:800px}.djangocms-frontend-column .form-row.field-xs_col>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_me>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_ms>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_offset>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_order>div>div:not([class]),.djangocms-frontend-row .form-row.field-row_cols_xs>div>div:not([class]){width:unset!important;max-width:unset!important}.djangocms-frontend-column .form-row.field-xs_col .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_me .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_ms .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_offset .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_order .field-box:first-child,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box:first-child{width:115px!important}.djangocms-frontend-column .form-row.field-xs_col .field-box,.djangocms-frontend-column .form-row.field-xs_col .fieldBox,.djangocms-frontend-column .form-row.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_me .fieldBox,.djangocms-frontend-column .form-row.field-xs_ms .field-box,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox,.djangocms-frontend-column .form-row.field-xs_offset .field-box,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox,.djangocms-frontend-column .form-row.field-xs_order .field-box,.djangocms-frontend-column .form-row.field-xs_order .fieldBox,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox{position:relative;box-sizing:content-box;width:86px!important;-ms-flex:none;flex:none;display:block;padding:15px 10px;margin:0!important;border-bottom:1px solid #eee;float:left!important}.djangocms-frontend-column .form-row.field-xs_col .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_col .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_me .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_me .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_ms .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_ms .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_offset .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_offset .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_order .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_order .fieldBox input:not([type=checkbox]),.djangocms-frontend-row .form-row.field-row_cols_xs .field-box input:not([type=checkbox]),.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox input:not([type=checkbox]){text-align:end;padding-inline-end:5px!important;box-sizing:border-box;width:100%}.djangocms-frontend-column .form-row.field-xs_col .field-box label,.djangocms-frontend-column .form-row.field-xs_col .fieldBox label,.djangocms-frontend-column .form-row.field-xs_me .field-box label,.djangocms-frontend-column .form-row.field-xs_me .fieldBox label,.djangocms-frontend-column .form-row.field-xs_ms .field-box label,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox label,.djangocms-frontend-column .form-row.field-xs_offset .field-box label,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox label,.djangocms-frontend-column .form-row.field-xs_order .field-box label,.djangocms-frontend-column .form-row.field-xs_order .fieldBox label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box label,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox label{font-size:12px!important;font-weight:400!important;color:#ccc!important;position:absolute;inset-inline-start:15px;inset-block-end:17px;text-transform:lowercase}.djangocms-frontend-column .form-row.field-xs_col .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_col .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_me .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_me .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_ms .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_offset .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_order .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_order .fieldBox .disabled,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box .disabled,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox .disabled{color:#ccc;background:#eee}.djangocms-frontend-column .form-row.field-xs_col .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_col .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_me .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_me .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_ms .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_offset .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_order .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_order .fieldBox:last-child,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box:last-child,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox:last-child{border-inline-end:none}.djangocms-frontend-column .form-row.field-xs_col .errors,.djangocms-frontend-column .form-row.field-xs_me .errors,.djangocms-frontend-column .form-row.field-xs_ms .errors,.djangocms-frontend-column .form-row.field-xs_offset .errors,.djangocms-frontend-column .form-row.field-xs_order .errors,.djangocms-frontend-row .form-row.field-row_cols_xs .errors{margin-bottom:0}.djangocms-frontend-column .form-row.field-xs_col .errorlist,.djangocms-frontend-column .form-row.field-xs_me .errorlist,.djangocms-frontend-column .form-row.field-xs_ms .errorlist,.djangocms-frontend-column .form-row.field-xs_offset .errorlist,.djangocms-frontend-column .form-row.field-xs_order .errorlist,.djangocms-frontend-row .form-row.field-row_cols_xs .errorlist{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.djangocms-frontend-column .form-row.field-xs_col.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_me.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_ms.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_offset.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_order.field-xs_me .field-box,.djangocms-frontend-row .form-row.field-row_cols_xs.field-xs_me .field-box{border-bottom:none}.djangocms-frontend-column .form-row.field-xs_col .field-box-label,.djangocms-frontend-column .form-row.field-xs_me .field-box-label,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label,.djangocms-frontend-column .form-row.field-xs_order .field-box-label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label{display:-ms-flexbox;display:flex;margin-top:auto;color:#999}.djangocms-frontend-column .form-row.field-xs_col .field-box-label a,.djangocms-frontend-column .form-row.field-xs_me .field-box-label a,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label a,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label a,.djangocms-frontend-column .form-row.field-xs_order .field-box-label a,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label a{width:100%;margin-top:auto;color:#999}.djangocms-frontend-column .form-row.field-xs_col .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_me .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_order .field-box-label a a,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label a a{width:100%;margin-top:auto}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_col .field-md_me,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_me .field-md_me,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_order .field-md_me,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms{text-align:start}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-md_me label,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-md_me label,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-md_me label,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms label{inset-inline-start:30px;inset-block-start:14px}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-md_me input,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-md_me input,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-md_me input,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms input{position:relative;box-sizing:border-box;top:-3px}.grid-reset{position:absolute;inset-inline-end:5px;inset-block-start:0}.icon-thead{text-align:center;margin-bottom:15px}.icon-thead .icon{font-size:30px}.icon-thead .icon-size-sm{transform:rotate(90deg)}.icon-title{display:block;font-size:12px;color:#999;padding:5px 0 0}.djangocms-frontend-preview{position:fixed;inset-block-start:0;inset-inline-end:0;z-index:10;text-align:center;border-radius:0 0 0 3px;padding:10px 20px 27px;border:1px solid var(--dca-gray,var(--hairline-color,#ccc));border-block-start:none;border-inline-end:none;background:var(--body-bg,#fff)}@media (prefers-color-scheme:dark){.djangocms-frontend-preview{background:var(--body-bg,#000)}}.djangocms-frontend-preview h2{font-size:14px;min-width:150px;margin:0 0 12px}.djangocms-frontend-preview .b4-preview{margin:0 0 -15px}.djangocms-frontend-preview .b4-close{position:absolute;inset-inline-end:10px;inset-block-start:8px;z-index:100;display:block;color:#5e5e5e;font-size:12px;line-height:20px;font-weight:700;text-transform:uppercase;width:20px;height:20px;border-radius:3px;background:#ddd}.djangocms-frontend-preview .b4-close:hover{color:#fff!important;text-decoration:none;background:#0bf}.djangocms-frontend-preview .btn>span{vertical-align:middle}.djangocms-frontend-preview .btn>span>.icon{vertical-align:middle}.djangocms-frontend-preview .btn>span svg,.djangocms-frontend-preview .btn>span use{fill:currentColor}.djangocms-frontend-blockquote textarea{height:110px}#id_link_type{padding:0;margin:0;border:none}#id_link_type li{padding:0;margin:0 15px 5px 0;border:none}#id_link_type label input{position:relative;top:-4px}a[data-pk]{position:relative}a[data-pk]:after{content:attr(data-pk);visibility:hidden;width:auto;font-weight:400;font-size:80%;background-color:var(--dca-white,var(--body-bg,#fff));color:var(--dca-gray,var(--body-fg,#333));border:solid 1px var(--dca-gray,var(--body-fg,#333));text-align:center;padding:5px 10px;position:absolute;z-index:1;top:110%;inset-inline-start:50%;margin-inline-start:-50%}a[data-pk]:hover:after{visibility:visible}.djangocms-admin-style .form-row.field-plugin_title input[name=plugin_title_0]{margin-bottom:.5em!important}.djangocms-admin-style .form-row.field-plugin_title input[name=plugin_title_1]{width:calc(100% - 2em)!important}body:not(.djangocms-admin-style) .form-row.field-plugin_title input[name=plugin_title_1]{width:calc(100% - 200px - 1em)!important;margin-inline-start:1em}.frontend-icon-picker{text-align:center;display:inline-block}.frontend-icon-picker .icon-container{position:relative;margin:.5em auto;width:7em;height:7em;border:1px var(--dca-gray-light,var(--border-color,#d3d3d3)) solid;transition:background-color .15s,color .15s}.frontend-icon-picker .icon-container .icon-preview{width:7em;height:7em;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.frontend-icon-picker .icon-container .icon-preview .icon-box{font-size:500%;line-height:1.3;margin:0;text-align:center}.frontend-icon-picker .icon-container .icon-preview .icon-box i,.frontend-icon-picker .icon-container .icon-preview .icon-box span{font-size:unset}.frontend-icon-picker .icon-container .icon-preview .empty-box{text-align:center;overflow:hidden;text-overflow:ellipsis;line-height:1;font-size:100%}.frontend-icon-picker .icon-container .icon-preview .empty-box.hidden{display:none}.frontend-icon-picker .icon-container .icon-preview:hover{background:var(--dca-gray-light,var(--border-color,#d3d3d3));cursor:pointer}.frontend-icon-picker .icon-container .icon-close-indicator{display:block;border-radius:50%;color:var(--dca-black,var(--body-fg,#000));background-color:var(--dca-white,var(--body-bg,#fff));padding:.3rem;border:1px solid var(--dca-black,var(--body-fg,#000));transform:translate(-50%,-50%);top:0;inset-inline-start:100%;width:.6em;height:.6em;line-height:.5em;position:absolute;transition:background-color .15s}.frontend-icon-picker .icon-container .icon-close-indicator:before{content:"×"}.frontend-icon-picker .icon-container .icon-close-indicator:hover{background:var(--delete-button-bg,red);color:var(--delete-button-fg,#fff);cursor:pointer}.uip-modal{position:fixed;height:100%;width:100%;inset-block-end:0;inset-inline-start:0;background-color:rgba(0,0,0,.8);z-index:9999;-webkit-user-select:none;-ms-user-select:none;user-select:none;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.uip-modal *,.uip-modal :after,.uip-modal :before{box-sizing:border-box}.uip-modal.uip-close{opacity:0;visibility:hidden;transition:all .4s ease-in-out}.uip-modal.uip-open{opacity:1;visibility:visible;transition:all .4s ease-in-out}.uip-modal .uip-modal--content{position:absolute;border-radius:3px;box-shadow:2px 8px 23px 3px rgba(0,0,0,.2);overflow:hidden;font-family:Roboto,Arial,Helvetica,Verdana,sans-serif;background-color:var(--dca-gray-lightest,var(--darkened-bg,#f8f8f8));width:100%;margin:auto;left:0;right:0;margin-bottom:2em}.uip-modal .uip-modal--content .uip-modal--header{padding:15px 15px;background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 0 8px rgba(0,0,0,.1);position:relative;z-index:1;font-size:15px;color:var(--dca-gray,var(--body-quiet-color,#666));font-weight:500;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-logo-title{padding-top:2px;line-height:1;text-transform:uppercase;font-weight:700;cursor:pointer}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-close-btn{cursor:pointer}.uip-modal .uip-modal--content .uip-modal--body{font-size:12px;line-height:1.5;box-sizing:border-box;padding:0;height:70vh;display:-ms-flexbox;display:flex;min-height:50px;max-height:85vh;overflow:auto}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar{-ms-flex-negative:0;flex-shrink:0;max-width:25%}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs{margin-top:30px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item{padding:15px;font-size:14px;color:var(--dca-gray,var(--body-quiet-color,#666));text-align:start;cursor:pointer;position:relative;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item i{font-size:20px;padding-inline-end:15px;color:var(--dca-gray-lighter,var(--border-color,#ccc))}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item img{padding-inline-end:15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active{background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 6px 20px 0 rgba(0,0,0,.1)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active:after{content:"";position:absolute;height:100%;width:5px;inset-block-start:0;inset-inline-start:0;background-color:#0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active i{color:#0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item:only-child{display:none}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding:30px 80px 0;width:100%}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner{overflow:auto;margin:25px -15px 0;padding:0 15px 15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview{display:-ms-grid;display:grid;grid-gap:20px;margin:20px 0}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item{position:relative;padding:10px;background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 1px 12px rgba(0,0,0,.05);border-radius:3px;cursor:pointer;transition:all .3s;overflow:hidden}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item:hover{box-shadow:0 1px 14px rgba(0,0,0,.16)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item.universal-selected{box-shadow:0 1px 12px rgba(0,0,0,.05),0 0 0 3px #0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-align:center;align-items:center;padding:1px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item__icon,.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner i{font-size:25px;color:var(--dca-gray-darkest,var(--body-fg,#333))}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item-name{color:var(--dca-gray,var(--body-quiet-color,#666));font-size:11px;padding:13px 0 0;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search{position:relative}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input{width:100%;padding:8px 15px;background-color:var(--dca-white,var(--bg-color,#fff));border:none}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input:-ms-input-placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input::placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search img{position:absolute;top:50%;transform:translateY(-50%);inset-inline-end:10px}.uip-modal .uip-modal--footer{border-top:1px solid var(--dca-gray-lighter,var(--border-color,#ccc));text-align:center;background-color:var(--dca-white,var(--bg-color,#fff));border:none;display:none;-ms-flex-pack:end;justify-content:flex-end;padding:5px;box-shadow:0 0 8px rgba(0,0,0,.1);position:relative;display:-ms-flexbox;display:flex}.uip-modal .uip-modal--footer button.uip-insert-icon-button{padding:10px 35px!important;color:var(--dca-white,var(--bg-color,#fff))!important;background-color:#0bf!important;border:none;cursor:pointer;outline:0}.uip-modal .uip-modal--footer .universal-button{height:40px;margin-inline-start:5px}.uip-modal .uip-modal--footer .universal-button-success{padding:12px 36px;color:var(--dca-white,var(--bg-color,#fff));width:initial}.uip-modal .uip-modal--footer .universal-button-success:hover{background-color:#0bf}@media (min-width:1440px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:1200px}}@media (max-width:1439px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:990px}.uip-modal--icon-preview-wrap{padding:30px 50px 0}}@media (max-width:1023px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:740px}}@media (max-width:767px){.uip-modal--icon-preview-wrap{padding:15px!important}.uip-modal--sidebar{display:none}}@media (min-width:1440px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[7];grid-template-columns:repeat(7,1fr)}}@media (max-width:1439px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[6];grid-template-columns:repeat(6,1fr)}}@media (max-width:1024px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[5];grid-template-columns:repeat(5,1fr)}}@media (max-width:767px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[4];grid-template-columns:repeat(4,1fr)}}@media (max-width:479px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[3];grid-template-columns:repeat(3,1fr)}}@media (max-width:1439px){.uip-modal--sidebar-tab-item{padding:15px 15px 15px 25px;font-size:11px}.uip-modal--sidebar-tab-item i{font-size:15px}}@media (max-width:1024px){.uip-modal--sidebar-tab-item i,.uip-modal--sidebar-tab-item img{display:none}}.sr-only{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}ul.nav{margin-bottom:1em}ul.nav>li.nav-item{list-style-type:none;padding:inherit}.colM ul:not(.object-tools).nav{margin-top:0;margin-bottom:20px}ul.nav .nav-item{margin-inline-end:1rem}ul.nav .nav-link{position:relative;text-decoration:none}ul.nav .nav-link span.indicator{display:none;border-radius:50%;padding:.5rem;border:1px solid var(--dca-white,var(--body-bg,#fff));transform:translate(-50%,-50%);inset-block-start:0;inset-inline-start:100%;position:absolute}ul.nav .nav-link span.indicator.error{background-color:var(--bs-danger)}ul.nav .nav-link span.indicator.attributes{background-color:var(--bs-info);display:block}ul.nav .nav-link.error>span.indicator{display:block}ul.nav.nav-pills .nav-link:not(.active){border-style:solid;border-width:1px}body:not(.djangocms-admin-style) ul.djangocms-frontend.nav-tabs+div.tab-content .tab-pane{border-left-style:solid;border-bottom-style:solid;border-right-style:solid;border-left-color:var(--hairline-color);border-bottom-color:var(--hairline-color);border-right-color:var(--hairline-color);border-width:1px}body:not(.djangocms-admin-style) ul.djangocms-frontend.nav-tabs+div.tab-content .tab-pane fieldset:last-child{margin-bottom:0}div.tab-pk{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;color:var(--dca-gray-darker,var(--body-fg,#333));font-size:80%;margin-inline-start:auto}.djangocms-admin-style .colM ul.nav:not(.object-tools):not(.messagelist){margin-top:0}.djangocms-admin-style .colM ul.nav:not(.object-tools):not(.messagelist) li.nav-item{border-top:none}input[type=number].auto-field+span{display:none;position:absolute;inset-block-end:0;inset-inline-end:0;text-align:end;margin-inline-end:31px;margin-block-end:23px;cursor:pointer}body:not(.djangocms-admin-style) input[type=number].auto-field+span{margin-bottom:23px}@media (max-width:1024px){body:not(.djangocms-admin-style) input[type=number].auto-field+span{margin-bottom:24px}}input[type=number].auto-field+span:after{content:"auto"}input[type=number].auto-field.auto{color:var(--dca-white,var(--body-bg,#fff));caret-color:var(--dca-black,var(--body-fg,#000))}input[type=number].auto-field.auto+span{display:block} \ No newline at end of file +@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:0.8125rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#0d6efd;--bs-link-hover-color:#0a58ca;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-size:0.8125rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#212529;--bs-btn-bg:transparent;--bs-btn-border-width:1px;--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-ms-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.015625rem;--bs-btn-border-radius:0.5rem}.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.7109375rem;--bs-btn-border-radius:0.25rem}.link-primary{color:#0d6efd!important}.link-primary:focus,.link-primary:hover{color:#0a58ca!important}.link-secondary{color:#6c757d!important}.link-secondary:focus,.link-secondary:hover{color:#565e64!important}.link-success{color:#198754!important}.link-success:focus,.link-success:hover{color:#146c43!important}.link-info{color:#0dcaf0!important}.link-info:focus,.link-info:hover{color:#3dd5f3!important}.link-warning{color:#ffc107!important}.link-warning:focus,.link-warning:hover{color:#ffcd39!important}.link-danger{color:#dc3545!important}.link-danger:focus,.link-danger:hover{color:#b02a37!important}.link-light{color:#f8f9fa!important}.link-light:focus,.link-light:hover{color:#f9fafb!important}.link-dark{color:#212529!important}.link-dark:focus,.link-dark:hover{color:#1a1e21!important}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.3rem;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#6c757d;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:1px;--bs-nav-tabs-border-color:#dee2e6;--bs-nav-tabs-border-radius:0.375rem;--bs-nav-tabs-link-hover-border-color:#e9ecef #e9ecef #dee2e6;--bs-nav-tabs-link-active-color:#495057;--bs-nav-tabs-link-active-bg:#fff;--bs-nav-tabs-link-active-border-color:#dee2e6 #dee2e6 #fff;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:4px;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0bf}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.icon{display:inline-block;vertical-align:top;width:1em;height:1em;background-position:center;background-repeat:no-repeat}.icon svg{display:block;width:100%;height:100%}.icon-info{width:.9em;font-size:110%!important}.icon-white{color:#fff}.icon-white svg{fill:#fff}.icon-black{color:#000}.icon-black svg{fill:#000}.icon-primary{color:#0bf}.icon-primary svg{fill:#0bf}.djangocms-icon .icon>input{float:left;position:relative;top:12px}.djangocms-icon .caret{margin-inline-start:8px}.aligned .frontend-button-group label{min-width:unset}.frontend-button-group{display:inline-block}.frontend-button-group .btn{box-sizing:border-box;cursor:pointer;-webkit-appearance:none;margin:2px;overflow:hidden;text-overflow:ellipsis}.frontend-button-group .btn.active{outline:3px solid #0bf;border-color:#fff!important}.frontend-button-group .btn-default.active{border-radius:0;background-color:#0bf!important}.frontend-button-group-context-colors>div,.frontend-button-group-context-size>div{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;min-height:75px}.frontend-button-group-context-colors .btn{-ms-flex-preferred-size:calc(25% - 4px);flex-basis:calc(25% - 4px)}@media (min-width:820px){.frontend-button-group-context-colors .btn{-ms-flex-preferred-size:calc(20% - 4px);flex-basis:calc(20% - 4px)}}.frontend-button-group-icons .icon,.frontend-grid-icons .icon{font-size:24px}.frontend-button-group-icons .icon-flex-align-center,.frontend-button-group-icons .icon-flex-align-end,.frontend-button-group-icons .icon-flex-align-start,.frontend-grid-icons .icon-flex-align-center,.frontend-grid-icons .icon-flex-align-end,.frontend-grid-icons .icon-flex-align-start{transform:scale(1.4)}.frontend-button-group-icons .icon-flex-content-around,.frontend-button-group-icons .icon-flex-content-between,.frontend-grid-icons .icon-flex-content-around,.frontend-grid-icons .icon-flex-content-between{transform:scale(1.6)}.frontend-button-group-icons .icon-flex-self-center,.frontend-button-group-icons .icon-flex-self-end,.frontend-button-group-icons .icon-flex-self-start,.frontend-grid-icons .icon-flex-self-center,.frontend-grid-icons .icon-flex-self-end,.frontend-grid-icons .icon-flex-self-start{transform:scale(1.4)}.frontend-button-group-icons .icon-align-reset,.frontend-button-group-icons .icon-no-selection,.frontend-grid-icons .icon-align-reset,.frontend-grid-icons .icon-no-selection{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-align-items-start,.frontend-button-group-icons .icon-flex-align-start,.frontend-grid-icons .icon-align-items-start,.frontend-grid-icons .icon-flex-align-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-items-center,.frontend-button-group-icons .icon-flex-align-center,.frontend-grid-icons .icon-align-items-center,.frontend-grid-icons .icon-flex-align-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-items-end,.frontend-button-group-icons .icon-flex-align-end,.frontend-grid-icons .icon-align-items-end,.frontend-grid-icons .icon-flex-align-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-flex-content-start,.frontend-button-group-icons .icon-justify-content-start,.frontend-button-group-icons .icon-start,.frontend-grid-icons .icon-flex-content-start,.frontend-grid-icons .icon-justify-content-start,.frontend-grid-icons .icon-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-center,.frontend-button-group-icons .icon-flex-content-center,.frontend-button-group-icons .icon-justify-content-center,.frontend-grid-icons .icon-center,.frontend-grid-icons .icon-flex-content-center,.frontend-grid-icons .icon-justify-content-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-end,.frontend-button-group-icons .icon-flex-content-end,.frontend-button-group-icons .icon-justify-content-end,.frontend-grid-icons .icon-end,.frontend-grid-icons .icon-flex-content-end,.frontend-grid-icons .icon-justify-content-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-flex-content-around,.frontend-button-group-icons .icon-justify-content-around,.frontend-grid-icons .icon-flex-content-around,.frontend-grid-icons .icon-justify-content-around{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.6)}.frontend-button-group-icons .icon-flex-content-between,.frontend-button-group-icons .icon-justify-content-between,.frontend-grid-icons .icon-flex-content-between,.frontend-grid-icons .icon-justify-content-between{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.6)}.frontend-button-group-icons .icon-nav-fill,.frontend-grid-icons .icon-nav-fill{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-nav-justified,.frontend-grid-icons .icon-nav-justified{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-flex-column,.frontend-grid-icons .icon-flex-column{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-start,.frontend-button-group-icons .icon-flex-self-start,.frontend-grid-icons .icon-align-self-start,.frontend-grid-icons .icon-flex-self-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-center,.frontend-button-group-icons .icon-flex-self-center,.frontend-grid-icons .icon-align-self-center,.frontend-grid-icons .icon-flex-self-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-end,.frontend-button-group-icons .icon-flex-self-end,.frontend-grid-icons .icon-align-self-end,.frontend-grid-icons .icon-flex-self-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-size-sm,.frontend-button-group-icons .icon-size-xs,.frontend-button-group-icons .icon-sm,.frontend-button-group-icons .icon-xs,.frontend-grid-icons .icon-size-sm,.frontend-grid-icons .icon-size-xs,.frontend-grid-icons .icon-sm,.frontend-grid-icons .icon-xs{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-sm,.frontend-button-group-icons .icon-sm,.frontend-grid-icons .icon-size-sm,.frontend-grid-icons .icon-sm{transform:rotate(-90deg)}.frontend-button-group-icons .icon-md,.frontend-button-group-icons .icon-size-md,.frontend-grid-icons .icon-md,.frontend-grid-icons .icon-size-md{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-lg,.frontend-button-group-icons .icon-size-lg,.frontend-grid-icons .icon-lg,.frontend-grid-icons .icon-size-lg{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-xl,.frontend-button-group-icons .icon-xl,.frontend-grid-icons .icon-size-xl,.frontend-grid-icons .icon-xl{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-xxl,.frontend-button-group-icons .icon-xxl,.frontend-grid-icons .icon-size-xxl,.frontend-grid-icons .icon-xxl{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-mb,.frontend-grid-icons .icon-mb{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-me,.frontend-grid-icons .icon-me{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-ms,.frontend-grid-icons .icon-ms{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-mt,.frontend-grid-icons .icon-mt{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-mx,.frontend-grid-icons .icon-mx{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-my,.frontend-grid-icons .icon-my{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pb,.frontend-grid-icons .icon-pb{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pe,.frontend-grid-icons .icon-pe{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-ps,.frontend-grid-icons .icon-ps{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pt,.frontend-grid-icons .icon-pt{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-px,.frontend-grid-icons .icon-px{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-py,.frontend-grid-icons .icon-py{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.icon-info{background-image:url('data:image/svg+xml;utf8,')}.module{margin:0 0 20px}.djangocms-frontend-row .form-row.field-create .icon{position:absolute;font-size:30px;margin-block-start:28px;margin-inline-start:4px}.djangocms-frontend-row .form-row.field-create input[name=create]{width:130px!important;padding-inline-end:5px!important;text-align:start}.djangocms-frontend-column .form-row.field-xs_col,.djangocms-frontend-column .form-row.field-xs_me,.djangocms-frontend-column .form-row.field-xs_ms,.djangocms-frontend-column .form-row.field-xs_offset,.djangocms-frontend-column .form-row.field-xs_order,.djangocms-frontend-row .form-row.field-row_cols_xs{position:relative;display:-ms-flexbox;display:flex;padding:0;min-width:800px}.djangocms-frontend-column .form-row.field-xs_col>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_me>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_ms>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_offset>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_order>div>div:not([class]),.djangocms-frontend-row .form-row.field-row_cols_xs>div>div:not([class]){width:unset!important;max-width:unset!important}.djangocms-frontend-column .form-row.field-xs_col .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_me .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_ms .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_offset .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_order .field-box:first-child,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box:first-child{width:115px!important}.djangocms-frontend-column .form-row.field-xs_col .field-box,.djangocms-frontend-column .form-row.field-xs_col .fieldBox,.djangocms-frontend-column .form-row.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_me .fieldBox,.djangocms-frontend-column .form-row.field-xs_ms .field-box,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox,.djangocms-frontend-column .form-row.field-xs_offset .field-box,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox,.djangocms-frontend-column .form-row.field-xs_order .field-box,.djangocms-frontend-column .form-row.field-xs_order .fieldBox,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox{position:relative;box-sizing:content-box;width:86px!important;-ms-flex:none;flex:none;display:block;padding:15px 10px;margin:0!important;border-bottom:1px solid #eee;float:left!important}.djangocms-frontend-column .form-row.field-xs_col .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_col .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_me .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_me .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_ms .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_ms .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_offset .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_offset .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_order .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_order .fieldBox input:not([type=checkbox]),.djangocms-frontend-row .form-row.field-row_cols_xs .field-box input:not([type=checkbox]),.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox input:not([type=checkbox]){text-align:end;padding-inline-end:5px!important;box-sizing:border-box;width:100%}.djangocms-frontend-column .form-row.field-xs_col .field-box label,.djangocms-frontend-column .form-row.field-xs_col .fieldBox label,.djangocms-frontend-column .form-row.field-xs_me .field-box label,.djangocms-frontend-column .form-row.field-xs_me .fieldBox label,.djangocms-frontend-column .form-row.field-xs_ms .field-box label,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox label,.djangocms-frontend-column .form-row.field-xs_offset .field-box label,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox label,.djangocms-frontend-column .form-row.field-xs_order .field-box label,.djangocms-frontend-column .form-row.field-xs_order .fieldBox label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box label,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox label{font-size:12px!important;font-weight:400!important;color:#ccc!important;position:absolute;inset-inline-start:15px;inset-block-end:17px;text-transform:lowercase}.djangocms-frontend-column .form-row.field-xs_col .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_col .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_me .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_me .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_ms .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_offset .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_order .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_order .fieldBox .disabled,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box .disabled,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox .disabled{color:#ccc;background:#eee}.djangocms-frontend-column .form-row.field-xs_col .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_col .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_me .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_me .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_ms .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_offset .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_order .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_order .fieldBox:last-child,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box:last-child,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox:last-child{border-inline-end:none}.djangocms-frontend-column .form-row.field-xs_col .errors,.djangocms-frontend-column .form-row.field-xs_me .errors,.djangocms-frontend-column .form-row.field-xs_ms .errors,.djangocms-frontend-column .form-row.field-xs_offset .errors,.djangocms-frontend-column .form-row.field-xs_order .errors,.djangocms-frontend-row .form-row.field-row_cols_xs .errors{margin-bottom:0}.djangocms-frontend-column .form-row.field-xs_col .errorlist,.djangocms-frontend-column .form-row.field-xs_me .errorlist,.djangocms-frontend-column .form-row.field-xs_ms .errorlist,.djangocms-frontend-column .form-row.field-xs_offset .errorlist,.djangocms-frontend-column .form-row.field-xs_order .errorlist,.djangocms-frontend-row .form-row.field-row_cols_xs .errorlist{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.djangocms-frontend-column .form-row.field-xs_col.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_me.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_ms.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_offset.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_order.field-xs_me .field-box,.djangocms-frontend-row .form-row.field-row_cols_xs.field-xs_me .field-box{border-bottom:none}.djangocms-frontend-column .form-row.field-xs_col .field-box-label,.djangocms-frontend-column .form-row.field-xs_me .field-box-label,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label,.djangocms-frontend-column .form-row.field-xs_order .field-box-label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label{display:-ms-flexbox;display:flex;margin-top:auto;color:#999}.djangocms-frontend-column .form-row.field-xs_col .field-box-label a,.djangocms-frontend-column .form-row.field-xs_me .field-box-label a,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label a,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label a,.djangocms-frontend-column .form-row.field-xs_order .field-box-label a,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label a{width:100%;margin-top:auto;color:#999}.djangocms-frontend-column .form-row.field-xs_col .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_me .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_order .field-box-label a a,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label a a{width:100%;margin-top:auto}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_col .field-md_me,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_me .field-md_me,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_order .field-md_me,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms{text-align:start}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-md_me label,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-md_me label,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-md_me label,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms label{inset-inline-start:30px;inset-block-start:14px}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-md_me input,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-md_me input,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-md_me input,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms input{position:relative;box-sizing:border-box;top:-3px}.grid-reset{position:absolute;inset-inline-end:5px;inset-block-start:0}.icon-thead{text-align:center;margin-bottom:15px}.icon-thead .icon{font-size:30px}.icon-thead .icon-size-sm{transform:rotate(90deg)}.icon-title{display:block;font-size:12px;color:#999;padding:5px 0 0}.djangocms-frontend-preview{position:fixed;inset-block-start:0;inset-inline-end:0;z-index:10;text-align:center;border-radius:0 0 0 3px;padding:10px 20px 27px;border:1px solid var(--dca-gray,var(--hairline-color,#ccc));border-block-start:none;border-inline-end:none;background:var(--body-bg,#fff)}@media (prefers-color-scheme:dark){.djangocms-frontend-preview{background:var(--body-bg,#000)}}.djangocms-frontend-preview h2{font-size:14px;min-width:150px;margin:0 0 12px}.djangocms-frontend-preview .b4-preview{margin:0 0 -15px}.djangocms-frontend-preview .b4-close{position:absolute;inset-inline-end:10px;inset-block-start:8px;z-index:100;display:block;color:#5e5e5e;font-size:12px;line-height:20px;font-weight:700;text-transform:uppercase;width:20px;height:20px;border-radius:3px;background:#ddd}.djangocms-frontend-preview .b4-close:hover{color:#fff!important;text-decoration:none;background:#0bf}.djangocms-frontend-preview .btn>span{vertical-align:middle}.djangocms-frontend-preview .btn>span>.icon{vertical-align:middle}.djangocms-frontend-preview .btn>span svg,.djangocms-frontend-preview .btn>span use{fill:currentColor}.djangocms-frontend-blockquote textarea{height:110px}#id_link_type{padding:0;margin:0;border:none}#id_link_type li{padding:0;margin:0 15px 5px 0;border:none}#id_link_type label input{position:relative;top:-4px}a[data-pk]{position:relative}a[data-pk]:after{content:attr(data-pk);visibility:hidden;width:auto;font-weight:400;font-size:80%;background-color:var(--dca-white,var(--body-bg,#fff));color:var(--dca-gray,var(--body-fg,#333));border:solid 1px var(--dca-gray,var(--body-fg,#333));text-align:center;padding:5px 10px;position:absolute;z-index:1;top:110%;inset-inline-start:50%;margin-inline-start:-50%}a[data-pk]:hover:after{visibility:visible}.djangocms-admin-style .form-row.field-plugin_title input[name=plugin_title_0]{margin-bottom:.5em!important}.djangocms-admin-style .form-row.field-plugin_title input[name=plugin_title_1]{width:calc(100% - 2em)!important}body:not(.djangocms-admin-style) .form-row.field-plugin_title input[name=plugin_title_1]{width:calc(100% - 200px - 1em)!important;margin-inline-start:1em}.frontend-icon-picker{text-align:center;display:inline-block}.frontend-icon-picker .icon-container{position:relative;margin:.5em auto;width:7em;height:7em;border:1px var(--dca-gray-light,var(--border-color,#d3d3d3)) solid;transition:background-color .15s,color .15s}.frontend-icon-picker .icon-container .icon-preview{width:7em;height:7em;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.frontend-icon-picker .icon-container .icon-preview .icon-box{font-size:500%;line-height:1.3;margin:0;text-align:center}.frontend-icon-picker .icon-container .icon-preview .icon-box i,.frontend-icon-picker .icon-container .icon-preview .icon-box span{font-size:unset}.frontend-icon-picker .icon-container .icon-preview .empty-box{text-align:center;overflow:hidden;text-overflow:ellipsis;line-height:1;font-size:100%}.frontend-icon-picker .icon-container .icon-preview .empty-box.hidden{display:none}.frontend-icon-picker .icon-container .icon-preview:hover{background:var(--dca-gray-light,var(--border-color,#d3d3d3));cursor:pointer}.frontend-icon-picker .icon-container .icon-close-indicator{display:block;border-radius:50%;color:var(--dca-black,var(--body-fg,#000));background-color:var(--dca-white,var(--body-bg,#fff));padding:.3rem;border:1px solid var(--dca-black,var(--body-fg,#000));transform:translate(-50%,-50%);top:0;inset-inline-start:100%;width:.6em;height:.6em;line-height:.5em;position:absolute;transition:background-color .15s}.frontend-icon-picker .icon-container .icon-close-indicator:before{content:"×"}.frontend-icon-picker .icon-container .icon-close-indicator:hover{background:var(--delete-button-bg,red);color:var(--delete-button-fg,#fff);cursor:pointer}.uip-modal{position:fixed;height:100%;width:100%;inset-block-end:0;inset-inline-start:0;background-color:rgba(0,0,0,.8);z-index:9999;-webkit-user-select:none;-ms-user-select:none;user-select:none;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.uip-modal *,.uip-modal :after,.uip-modal :before{box-sizing:border-box}.uip-modal.uip-close{opacity:0;visibility:hidden;transition:all .4s ease-in-out}.uip-modal.uip-open{opacity:1;visibility:visible;transition:all .4s ease-in-out}.uip-modal .uip-modal--content{position:absolute;border-radius:3px;box-shadow:2px 8px 23px 3px rgba(0,0,0,.2);overflow:hidden;font-family:Roboto,Arial,Helvetica,Verdana,sans-serif;background-color:var(--dca-gray-lightest,var(--darkened-bg,#f8f8f8));width:100%;margin:auto;left:0;right:0;margin-bottom:2em}.uip-modal .uip-modal--content .uip-modal--header{padding:15px 15px;background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 0 8px rgba(0,0,0,.1);position:relative;z-index:1;font-size:15px;color:var(--dca-gray,var(--body-quiet-color,#666));font-weight:500;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-logo-title{padding-top:2px;line-height:1;text-transform:uppercase;font-weight:700;cursor:pointer}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-close-btn{cursor:pointer}.uip-modal .uip-modal--content .uip-modal--body{font-size:12px;line-height:1.5;box-sizing:border-box;padding:0;height:70vh;display:-ms-flexbox;display:flex;min-height:50px;max-height:85vh;overflow:auto}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar{-ms-flex-negative:0;flex-shrink:0;max-width:25%}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs{margin-top:30px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item{padding:15px;font-size:14px;color:var(--dca-gray,var(--body-quiet-color,#666));text-align:start;cursor:pointer;position:relative;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item i{font-size:20px;padding-inline-end:15px;color:var(--dca-gray-lighter,var(--border-color,#ccc))}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item img{padding-inline-end:15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active{background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 6px 20px 0 rgba(0,0,0,.1)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active:after{content:"";position:absolute;height:100%;width:5px;inset-block-start:0;inset-inline-start:0;background-color:#0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active i{color:#0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item:only-child{display:none}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding:30px 80px 0;width:100%}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner{overflow:auto;margin:25px -15px 0;padding:0 15px 15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview{display:-ms-grid;display:grid;grid-gap:20px;margin:20px 0}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item{position:relative;padding:10px;background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 1px 12px rgba(0,0,0,.05);border-radius:3px;cursor:pointer;transition:all .3s;overflow:hidden}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item:hover{box-shadow:0 1px 14px rgba(0,0,0,.16)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item.universal-selected{box-shadow:0 1px 12px rgba(0,0,0,.05),0 0 0 3px #0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-align:center;align-items:center;padding:1px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item__icon,.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner i{font-size:25px;color:var(--dca-gray-darkest,var(--body-fg,#333))}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item-name{color:var(--dca-gray,var(--body-quiet-color,#666));font-size:11px;padding:13px 0 0;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search{position:relative}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input{width:100%;padding:8px 15px;background-color:var(--dca-white,var(--bg-color,#fff));border:none}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input:-ms-input-placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input::placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search img{position:absolute;top:50%;transform:translateY(-50%);inset-inline-end:10px}.uip-modal .uip-modal--footer{border-top:1px solid var(--dca-gray-lighter,var(--border-color,#ccc));text-align:center;background-color:var(--dca-white,var(--bg-color,#fff));border:none;display:none;-ms-flex-pack:end;justify-content:flex-end;padding:5px;box-shadow:0 0 8px rgba(0,0,0,.1);position:relative;display:-ms-flexbox;display:flex}.uip-modal .uip-modal--footer button.uip-insert-icon-button{padding:10px 35px!important;color:var(--dca-white,var(--bg-color,#fff))!important;background-color:#0bf!important;border:none;cursor:pointer;outline:0}.uip-modal .uip-modal--footer .universal-button{height:40px;margin-inline-start:5px}.uip-modal .uip-modal--footer .universal-button-success{padding:12px 36px;color:var(--dca-white,var(--bg-color,#fff));width:initial}.uip-modal .uip-modal--footer .universal-button-success:hover{background-color:#0bf}@media (min-width:1440px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:1200px}}@media (max-width:1439px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:990px}.uip-modal--icon-preview-wrap{padding:30px 50px 0}}@media (max-width:1023px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:740px}}@media (max-width:767px){.uip-modal--icon-preview-wrap{padding:15px!important}.uip-modal--sidebar{display:none}}@media (min-width:1440px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[7];grid-template-columns:repeat(7,1fr)}}@media (max-width:1439px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[6];grid-template-columns:repeat(6,1fr)}}@media (max-width:1024px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[5];grid-template-columns:repeat(5,1fr)}}@media (max-width:767px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[4];grid-template-columns:repeat(4,1fr)}}@media (max-width:479px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[3];grid-template-columns:repeat(3,1fr)}}@media (max-width:1439px){.uip-modal--sidebar-tab-item{padding:15px 15px 15px 25px;font-size:11px}.uip-modal--sidebar-tab-item i{font-size:15px}}@media (max-width:1024px){.uip-modal--sidebar-tab-item i,.uip-modal--sidebar-tab-item img{display:none}}.sr-only{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}ul.nav{margin-bottom:1em}ul.nav>li.nav-item{list-style-type:none;padding:inherit}.colM ul:not(.object-tools).nav{margin-top:0;margin-bottom:20px}ul.nav:has(>li~div){display:none}ul.nav .nav-item{margin-inline-end:1rem}ul.nav .nav-link{position:relative;text-decoration:none}ul.nav .nav-link span.indicator{display:none;border-radius:50%;padding:.5rem;border:1px solid var(--dca-white,var(--body-bg,#fff));transform:translate(-50%,-50%);inset-block-start:0;inset-inline-start:100%;position:absolute}ul.nav .nav-link span.indicator.error{background-color:var(--bs-danger)}ul.nav .nav-link span.indicator.attributes{background-color:var(--bs-info);display:block}ul.nav .nav-link.error>span.indicator{display:block}ul.nav.nav-pills .nav-link:not(.active){border-style:solid;border-width:1px}body:not(.djangocms-admin-style) ul.djangocms-frontend.nav-tabs+div.tab-content .tab-pane{border-left-style:solid;border-bottom-style:solid;border-right-style:solid;border-left-color:var(--hairline-color);border-bottom-color:var(--hairline-color);border-right-color:var(--hairline-color);border-width:1px}body:not(.djangocms-admin-style) ul.djangocms-frontend.nav-tabs+div.tab-content .tab-pane fieldset:last-child{margin-bottom:0}div.tab-pk{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;color:var(--dca-gray-darker,var(--body-fg,#333));font-size:80%;margin-inline-start:auto}.djangocms-admin-style .colM ul.nav:not(.object-tools):not(.messagelist){margin-top:0}.djangocms-admin-style .colM ul.nav:not(.object-tools):not(.messagelist) li.nav-item{border-top:none}input[type=number].auto-field+span{display:none;position:absolute;inset-block-end:0;inset-inline-end:0;text-align:end;margin-inline-end:31px;margin-block-end:23px;cursor:pointer}body:not(.djangocms-admin-style) input[type=number].auto-field+span{margin-bottom:23px}@media (max-width:1024px){body:not(.djangocms-admin-style) input[type=number].auto-field+span{margin-bottom:24px}}input[type=number].auto-field+span:after{content:"auto"}input[type=number].auto-field.auto{color:var(--dca-white,var(--body-bg,#fff));caret-color:var(--dca-black,var(--body-fg,#000))}input[type=number].auto-field.auto+span{display:block} \ No newline at end of file diff --git a/djangocms_frontend/templates/djangocms_frontend/admin/base-tabs.html b/djangocms_frontend/templates/djangocms_frontend/admin/base-tabs.html index de155e49..481e5f48 100644 --- a/djangocms_frontend/templates/djangocms_frontend/admin/base-tabs.html +++ b/djangocms_frontend/templates/djangocms_frontend/admin/base-tabs.html @@ -7,36 +7,36 @@ {% endblock %} {% block content_subtitle %}{% endblock %} {% block field_sets %} -
    - -
    - {% for fieldset in adminform %} - {% if forloop.counter == 1 or "collapse" in fieldset.classes %} - {% if forloop.counter != 1 %}
    {% endif %} -
    - {% endif %} - {% include "djangocms_frontend/admin/includes/fieldset.html" %} - {% endfor %}{# djlint:off #}
    -
    +
    + +
    + {% for fieldset in adminform %} + {% if forloop.counter == 1 or "collapse" in fieldset.classes %} + {% if forloop.counter != 1 %}
    {% endif %} +
    + {% endif %} + {% include "djangocms_frontend/admin/includes/fieldset.html" %} + {% endfor %}{# djlint:off #}
    +
    {# djlint:on #} {% endblock %} diff --git a/docs/source/custom_components.rst b/docs/source/custom_components.rst index 26bb9070..2b20235a 100644 --- a/docs/source/custom_components.rst +++ b/docs/source/custom_components.rst @@ -6,8 +6,9 @@ Custom Components .. versionadded:: 2.0 -Some frontend developers prefer custom components specifically tailored to -give the project a unique and distinct look. +Custom components are a powerful tool for content editors, allowing them to build pages without needing +in-depth knowledge of design, HTML, or nested structures. Editors can simply add content to pre-defined +components, creating visually cohesive pages with ease. When working with `Tailwind CSS `_, for example, you either create your custom components or customize components from providers, @@ -15,8 +16,8 @@ e.g. `Tailwind UI `_, `Flowbite `_, or the commiunity `Tailwind Components `_. -With django CMS you make your components available to the content editors for -drag and drop **and** frontend developers for use in templates from a single +With django CMS you make your components available to the content editors to +simply add them to a page by a click **and** frontend developers for use in templates from a single source. Custom components are part of the djangocms-frontend root package and do not diff --git a/docs/source/grid.rst b/docs/source/grid.rst index c493c7d0..8cfa7a78 100644 --- a/docs/source/grid.rst +++ b/docs/source/grid.rst @@ -3,7 +3,13 @@ Grid plugins ############## -For details on how grids work, see, e.g. the `Bootstrap 5 documentation +The grid is the basis for responsive page design. It splits the page into +containers, rows and columns. Depending on the device, columns are shown +next to each other (larger screens) or one below the other (smaller +screens). + +The details of the grid system are based on the Bootstrap framework. Therefore, +for details on how grids work, see, e.g. the `Bootstrap 5 documentation `_. .. index:: diff --git a/docs/source/index.rst b/docs/source/index.rst index d1e7257b..99996acb 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,9 +1,3 @@ -.. - djangocms-blog documentation master file, created by - sphinx-quickstart on Sun Jun 5 23:27:04 2016. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - ################################################ Welcome to djangocms-frontend's documentation! ################################################ @@ -12,11 +6,12 @@ djangocms-frontend ******************** -**djangocms-frontend** is a plugin bundle based on `djangocms_bootstrap5 -`_. Its objective is to -provide a set of popular frontend components independent of the -currently used frontend framework such as Bootstrap, or its specific -version. +**django CMS Frontend** is a plugin bundle which originally built on and improved +the architecture of `djangocms-bootstrap4 `_. +Its objective is to provide a toolset to quickly create re-usable frontend +components and comes preloaded with a set of popular frontend components +independent of the currently used frontend framework such as Bootstrap, or +its specific version. .. image:: ../../preview.png @@ -24,27 +19,29 @@ version. Key features ************** -- Support of `Bootstrap 5 `_. +- **Easy to implement re-usable frontend custom components**, which in the + simples case consist of a template and declarative sort of form class. -- **Separation of plugins from css framework**, i.e., no need to - rebuild you site's plugin tree if css framework is changed in the - future, e.g., from Bootstrap 5 to a future version. +- Support of `Bootstrap 5 `_, django CMS 3.8+ + and django CMS 4 out of the box. -- **New link plugin** allowing to link to internal pages provided by - other applications, such as `djangocms-blog - `_. +- **Separation of plugins from css framework**, i.e. no need to + rebuild you site's plugin tree if css framework is changed in the + future, e.g. from Bootstrap 5 to a future version. -- **Nice and well-arranged admin frontend** of `djangocms-bootstrap4 - `_ +- Leverage of new **djangocms-link features** allowing to link to internal pages + provided by other applications, such as `djangocms-blog + `_. -- Management command to **migrate from djangocms-bootstrap4**. This - command automatically migrates all djangocms-bootstrap4 plugins to - djangocms-frontend. +- **Nice and well-arranged admin frontend** of `djangocms-bootstrap4 + `_ -- **Extensible** within the project and with separate project (e.g., a - theme app) +- **Extensible** within the project and with separate project (e.g. a + theme app). Create your own components with a few lines of code only. -- **Accordion** plugin. +- **Plugins are re-usable as UI components** anywhere in your project + (e.g. in a custom app) giving your whole project a more consistent + user experience. ************* Description @@ -62,10 +59,6 @@ Instead all design parameters are stored in a common JSON field and future releases of improved frontend features will not require to rebuild your full plugin tree. -The link plugin has been rewritten to not allow internal links to other -CMS pages, but also to other django models such as, e.g., posts of -`djangocms-blog `_. - **djangocms-frontend** provides a set of plugins to structure your layout. This includes three basic elements @@ -80,10 +73,6 @@ Components to grasp and easy to use look. Alerts or cards are examples of components. -Forms - To nicely integrate formss into your page we recommend - **djangocms-form-builder** which works stand-alone but also nicely - integrates with **djangocms-frontend**. Contents ======== @@ -92,9 +81,9 @@ Contents :maxdepth: 3 getting_started + custom_components grid components - custom_components how-to/index reference diff --git a/private/sass/components/_tabs.scss b/private/sass/components/_tabs.scss index 1be37e14..139421a4 100644 --- a/private/sass/components/_tabs.scss +++ b/private/sass/components/_tabs.scss @@ -4,6 +4,10 @@ } ul.nav { + &:has(> li ~ div) { + // Hide single tab + display: none; + } .nav-item { margin-inline-end: 1rem; } From 19ce8e9c1a2f2112985dcc416ab392aa51e4f073 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Thu, 7 Nov 2024 22:34:49 +0100 Subject: [PATCH 47/66] feat: pytest --- .github/workflows/codecov.yml | 2 +- run_tests.py => conftest.py | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) rename run_tests.py => conftest.py (81%) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index e786787e..54c36c54 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -35,6 +35,6 @@ jobs: - name: Generate Report run: | pip install -r tests/requirements/${{ matrix.requirements-file }} - coverage run run_tests.py + coverage run -m pytest - name: Upload Coverage to Codecov uses: codecov/codecov-action@v4 diff --git a/run_tests.py b/conftest.py similarity index 81% rename from run_tests.py rename to conftest.py index cbc597a3..c33bbf4a 100755 --- a/run_tests.py +++ b/conftest.py @@ -7,17 +7,17 @@ from django.test.utils import get_runner -def run(argv=None): - if argv is None: - argv = ["tests"] - tests = argv[1:] if len(argv) > 1 else ["tests"] +def pytest_configure(): os.environ["DJANGO_SETTINGS_MODULE"] = "tests.test_settings" django.setup() + + +if __name__ == "__main__": + pytest_configure() + + argv = ["tests"] if sys.argv is None else sys.argv + tests = argv[1:] if len(argv) > 1 else ["tests"] TestRunner = get_runner(settings) test_runner = TestRunner() failures = test_runner.run_tests(tests) sys.exit(bool(failures)) - - -if __name__ == "__main__": - run(sys.argv) From 791f96bf92a974a8173dc002cc1bdc03190cb0c7 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Thu, 7 Nov 2024 22:37:43 +0100 Subject: [PATCH 48/66] add pytest dependency --- .github/workflows/codecov.yml | 4 +++- tests/requirements/base.txt | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 54c36c54..27696c2f 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -32,9 +32,11 @@ jobs: uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - - name: Generate Report + - name: Intall dependencies run: | pip install -r tests/requirements/${{ matrix.requirements-file }} + - name: Run coverage + run: | coverage run -m pytest - name: Upload Coverage to Codecov uses: codecov/codecov-action@v4 diff --git a/tests/requirements/base.txt b/tests/requirements/base.txt index c3393eab..983fd9c0 100644 --- a/tests/requirements/base.txt +++ b/tests/requirements/base.txt @@ -13,3 +13,5 @@ django-filer html5lib git+https://github.com/django-cms/djangocms-link@feat/url-mngr -e . +pytest +pytest-django From 35a7491b60659e46c7c8d59cac554b9223c34988 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Thu, 7 Nov 2024 22:42:55 +0100 Subject: [PATCH 49/66] fix: test for v3 --- djangocms_frontend/ui_plugin_base.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/djangocms_frontend/ui_plugin_base.py b/djangocms_frontend/ui_plugin_base.py index 3ac0226f..1fcac3cf 100644 --- a/djangocms_frontend/ui_plugin_base.py +++ b/djangocms_frontend/ui_plugin_base.py @@ -19,6 +19,9 @@ class FrontendEditableAdminMixin: # django CMS 3 did not implement this: use our own version of the plugin-enabled mixin from .helpers import FrontendEditableAdminMixin + class PlaceholderAdmin: + pass + class CMSUIPluginBase(FrontendEditableAdminMixin, CMSPluginBase): render_template = "djangocms_frontend/html_container.html" From f76f11c650eeb97a04792306d9f86f966009bc22 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Thu, 7 Nov 2024 22:46:01 +0100 Subject: [PATCH 50/66] more fixes for v3 tests --- tests/utilities/test_plugins.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/utilities/test_plugins.py b/tests/utilities/test_plugins.py index 222da531..4e7b3915 100644 --- a/tests/utilities/test_plugins.py +++ b/tests/utilities/test_plugins.py @@ -1,4 +1,3 @@ -from cms.admin.placeholderadmin import PlaceholderAdmin from cms.api import add_plugin from cms.test_utils.testcases import CMSTestCase from cms.utils.urlutils import admin_reverse @@ -9,6 +8,7 @@ TOCPlugin, ) from djangocms_frontend.contrib.utilities.forms import TableOfContentsForm +from djangocms_frontend.ui_plugin_base import PlaceholderAdmin from ..fixtures import TestFixture From 5f8bd34e0d53eb032477b7eef6e8d327a24fea79 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Sun, 10 Nov 2024 17:23:23 +0100 Subject: [PATCH 51/66] Update project settings --- .pre-commit-config.yaml | 6 +- djangocms_frontend/common/__init__.py | 10 ++- .../contrib/navigation/cms_plugins.py | 7 +- djangocms_frontend/helpers.py | 78 +++++++++---------- .../management/bootstrap4_migration.py | 7 +- pyproject.toml | 48 ++++++++++++ setup.cfg | 33 -------- 7 files changed, 107 insertions(+), 82 deletions(-) delete mode 100644 setup.cfg diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a08f7be5..073ae14c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,12 +12,12 @@ repos: rev: v3.19.0 hooks: - id: pyupgrade - args: ["--py37-plus"] + args: ["--py39-plus"] - repo: https://github.com/adamchainz/django-upgrade rev: "1.22.1" hooks: - id: django-upgrade - args: [--target-version, "2.2"] + args: [--target-version, "4.2"] - repo: https://github.com/pycqa/isort rev: 5.13.2 hooks: @@ -28,9 +28,9 @@ repos: hooks: - id: flake8 additional_dependencies: + - flake8-pyproject - flake8-bugbear - flake8-builtins - flake8-django - flake8-length - flake8-logging-format - - flake8-spellcheck diff --git a/djangocms_frontend/common/__init__.py b/djangocms_frontend/common/__init__.py index 32e4e449..4591aeab 100644 --- a/djangocms_frontend/common/__init__.py +++ b/djangocms_frontend/common/__init__.py @@ -5,11 +5,19 @@ from .attributes import AttributesMixin from .title import TitleFormMixin, TitleMixin + __common = { "background": ("BackgroundFormMixin", "BackgroundMixin"), "responsive": ("ResponsiveFormMixin", "ResponsiveMixin"), "sizing": ("SizingFormMixin", "SizingMixin"), - "spacing": ("SpacingFormMixin", "SpacingMixin", "MarginFormMixin", "MarginMixin", "PaddingFormMixin", "PaddingMixin"), + "spacing": ( + "SpacingFormMixin", + "SpacingMixin", + "MarginFormMixin", + "MarginMixin", + "PaddingFormMixin", + "PaddingMixin", + ), } for module, classes in __common.items(): diff --git a/djangocms_frontend/contrib/navigation/cms_plugins.py b/djangocms_frontend/contrib/navigation/cms_plugins.py index fb98a07b..0d070558 100644 --- a/djangocms_frontend/contrib/navigation/cms_plugins.py +++ b/djangocms_frontend/contrib/navigation/cms_plugins.py @@ -1,6 +1,7 @@ -from cms.plugin_pool import plugin_pool from django.utils.translation import gettext_lazy as _ +from cms.plugin_pool import plugin_pool + from ... import settings from ...cms_plugins import CMSUIPlugin from ...common import AttributesMixin, BackgroundMixin @@ -9,6 +10,7 @@ from ..link.cms_plugins import LinkPluginMixin, TextLinkPlugin from . import forms, models + mixin_factory = settings.get_renderer(navigation) default_template = first_choice(settings.NAVIGATION_TEMPLATE_CHOICES) @@ -176,7 +178,8 @@ class NavLinkPlugin( - `module` (str): The module where the plugin belongs, displayed in the plugin list when editing a page. - `model` (Model): The Django model used to store the plugin's data. - `form` (Form): The form used to render the plugin's settings in the admin interface. - - `change_form_template` (str): The path to the template used to render the plugin's change form in the admin interface. + - `change_form_template` (str): The path to the template used to render the plugin's change form in the admin + interface. - `allow_children` (bool): Whether the plugin allows having child plugins. - `parent_classes` (list): List of parent plugin classes that this plugin can be nested within. - `child_classes` (list): List of child plugin classes that can be nested within this plugin. diff --git a/djangocms_frontend/helpers.py b/djangocms_frontend/helpers.py index d768fbd4..448eb9d6 100644 --- a/djangocms_frontend/helpers.py +++ b/djangocms_frontend/helpers.py @@ -1,9 +1,6 @@ import copy import decimal -from cms.constants import SLUG_REGEXP -from cms.plugin_base import CMSPluginBase -from cms.utils.conf import get_cms_setting from django.apps import apps from django.contrib.admin.helpers import AdminForm from django.db.models import ObjectDoesNotExist @@ -15,6 +12,10 @@ from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ +from cms.constants import SLUG_REGEXP +from cms.plugin_base import CMSPluginBase +from cms.utils.conf import get_cms_setting + from djangocms_frontend import settings from djangocms_frontend.settings import FRAMEWORK_PLUGIN_INFO @@ -33,6 +34,7 @@ def get_related_object(scope, field_name): class get_related: """Descriptor lazily getting related objects from the config dict.""" + def __init__(self, key): self.key = key @@ -74,12 +76,12 @@ def insert_fields(fieldsets, new_fields, block=None, position=-1, blockname=None modify[1]["fields"] = ( list(fields[: position + 1] if position != -1 else fields) + list(new_fields) - + list(fields[position + 1 :] if position != -1 else []) + + list(fields[position + 1:] if position != -1 else []) ) fs = ( list(fieldsets[:block] if block != -1 else fieldsets) + [modify] - + list(fieldsets[block + 1 :] if block != -1 else []) + + list(fieldsets[block + 1:] if block != -1 else []) ) return fs @@ -165,6 +167,7 @@ class FrontendEditableAdminMixin: in the frontend by double-clicking on fields rendered with the ``render_model`` template tag. """ + frontend_editable_fields = [] def get_urls(self): # pragma: no cover @@ -177,7 +180,7 @@ def pat(regex, fn): return re_path(regex, self.admin_site.admin_view(fn), name=f"{info}_{fn.__name__}") url_patterns = [ - pat(r'edit-field/(%s)/([a-z\-]+)/$' % SLUG_REGEXP, self.edit_field), + pat(r"edit-field/(%s)/([a-z\-]+)/$" % SLUG_REGEXP, self.edit_field), ] return url_patterns + super().get_urls() @@ -203,21 +206,15 @@ def edit_field(self, request, object_id, language): raw_fields = request.GET.get("edit_fields") fields = [field for field in raw_fields.split(",") if field in self.frontend_editable_fields] if not fields: - context = { - 'opts': opts, - 'message': _("Field %s not found") % raw_fields - } - return render(request, 'admin/cms/page/plugin/error_form.html', context) + context = {"opts": opts, "message": _("Field %s not found") % raw_fields} + return render(request, "admin/cms/page/plugin/error_form.html", context) if not request.user.has_perm(f"{self.model._meta.app_label}.change_{self.model._meta.model_name}"): - context = { - 'opts': opts, - 'message': _("You do not have permission to edit this item") - } - return render(request, 'admin/cms/page/plugin/error_form.html', context) + context = {"opts": opts, "message": _("You do not have permission to edit this item")} + return render(request, "admin/cms/page/plugin/error_form.html", context) # Dynamically creates the form class with only `field_name` field # enabled form_class = self.get_form(request, obj, fields=fields) - if not cancel_clicked and request.method == 'POST': + if not cancel_clicked and request.method == "POST": form = form_class(instance=obj, data=request.POST) if form.is_valid(): new_object = form.save(commit=False) @@ -225,36 +222,37 @@ def edit_field(self, request, object_id, language): saved_successfully = True else: form = form_class(instance=obj) - admin_form = AdminForm(form, fieldsets=[(None, {'fields': fields})], prepopulated_fields={}, - model_admin=self) + admin_form = AdminForm(form, fieldsets=[(None, {"fields": fields})], prepopulated_fields={}, model_admin=self) media = self.media + admin_form.media context = { - 'CMS_MEDIA_URL': get_cms_setting('MEDIA_URL'), - 'title': opts.verbose_name, - 'plugin': None, - 'plugin_id': None, - 'adminform': admin_form, - 'add': False, - 'is_popup': True, - 'media': media, - 'opts': opts, - 'change': True, - 'save_as': False, - 'has_add_permission': False, - 'window_close_timeout': 10, + "CMS_MEDIA_URL": get_cms_setting("MEDIA_URL"), + "title": opts.verbose_name, + "plugin": None, + "plugin_id": None, + "adminform": admin_form, + "add": False, + "is_popup": True, + "media": media, + "opts": opts, + "change": True, + "save_as": False, + "has_add_permission": False, + "window_close_timeout": 10, } if cancel_clicked: # cancel button was clicked - context.update({ - 'cancel': True, - }) - return render(request, 'admin/cms/page/plugin/confirm_form.html', context) - if not cancel_clicked and request.method == 'POST' and saved_successfully: + context.update( + { + "cancel": True, + } + ) + return render(request, "admin/cms/page/plugin/confirm_form.html", context) + if not cancel_clicked and request.method == "POST" and saved_successfully: if isinstance(self, CMSPluginBase): - if hasattr(obj.placeholder, 'mark_as_dirty'): + if hasattr(obj.placeholder, "mark_as_dirty"): # Only relevant for v3: mark the placeholder as dirty so user can publish changes obj.placeholder.mark_as_dirty(obj.language, clear_cache=False) # Update the structure board by populating the data bridge return self.render_close_frame(request, obj) - return render(request, 'admin/cms/page/plugin/confirm_form.html', context) - return render(request, 'admin/cms/page/plugin/change_form.html', context) + return render(request, "admin/cms/page/plugin/confirm_form.html", context) + return render(request, "admin/cms/page/plugin/change_form.html", context) diff --git a/djangocms_frontend/management/bootstrap4_migration.py b/djangocms_frontend/management/bootstrap4_migration.py index 7db2b1c6..00163a3a 100644 --- a/djangocms_frontend/management/bootstrap4_migration.py +++ b/djangocms_frontend/management/bootstrap4_migration.py @@ -1,4 +1,5 @@ from django.conf import settings as django_setting + from djangocms_bootstrap4.constants import DEVICE_SIZES from djangocms_frontend import settings @@ -305,7 +306,7 @@ def replace(item, old, new): def replace_left(item, old, new): if item[: len(old)] == old: - return new + item[len(old) :] + return new + item[len(old):] return item classes = new_obj.attributes["class"].split() @@ -361,7 +362,7 @@ def a001_alignment(obj, new_obj, field): new_obj.config[field].replace("text-right", "end") -def m001_spacing_mixin(obj, new_obj, type): +def m001_spacing_mixin(obj, new_obj, type): # noqa: A002 classes = new_obj.config["attributes"].get("class", "").split() if classes: for size, _ in list(settings.SPACER_SIZE_CHOICES) + ([("auto", "auto")] if type == "margin" else []): @@ -404,7 +405,7 @@ def m002_responsive_mixin(obj, new_obj): visible = False hit = True classes.remove(f"{stump}{hidden}") - for type in display: + for type in display: # noqa: A001 if f"{stump}{type}" in classes and not visible: visible = True hit = True diff --git a/pyproject.toml b/pyproject.toml index 2b83d87c..c3cc48c4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,3 +33,51 @@ lint.select = [ "F", "W", ] + +[tool.isort] +line_length = 119 +skip = [ + "manage.py", + "*migrations*", + ".tox", + ".eggs", + ".env", + ".venv", + "data", +] +include_trailing_comma = true +multi_line_output = 5 +lines_after_imports = 2 +default_section = "THIRDPARTY" +sections = [ + "FUTURE", + "STDLIB", + "DJANGO", + "CMS", + "THIRDPARTY", + "FIRSTPARTY", + "LOCALFOLDER", +] +known_first_party = "djangocms_link" +known_cms = [ "cms", "menus" ] +known_django = "django" + +[tool.flake8] +max-line-length = 120 +exclude = [ + "*.egg-info", + ".eggs", + ".env", + ".git", + ".settings", + ".tox", + ".venv", + "build", + "data", + "dist", + "docs", + "*migrations*", + "requirements", + "tmp", +] + diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 506f1c46..00000000 --- a/setup.cfg +++ /dev/null @@ -1,33 +0,0 @@ -[flake8] -dictionaries=en_US,python,technical,django -ignore = D203, W503 -select = C,E,F,W,B,B950 -extend-ignore = E203, E501, E731 -max-line-length = 119 -exclude = - *.egg-info, - .eggs, - .git, - .settings, - .tox, - build, - data, - dist, - docs, - *migrations*, - requirements, - tmp - -[isort] -profile = black -;line_length = 119 -;skip = manage.py, *migrations*, .tox, .eggs, data -;include_trailing_comma = true -;multi_line_output = 5 -;not_skip = __init__.py -;lines_after_imports = 2 -;default_section = THIRDPARTY -;sections = FUTURE, STDLIB, DJANGO, CMS, THIRDPARTY, FIRSTPARTY, LIB, LOCALFOLDER -;known_first_party = djangocms_frontend -;known_cms = cms, menus -;known_django = django From 68d534dc865eb44229b448b50f695bf40c63efa4 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Sun, 10 Nov 2024 17:31:12 +0100 Subject: [PATCH 52/66] Fix linting --- djangocms_frontend/apps.py | 8 +++---- djangocms_frontend/contrib/alert/forms.py | 8 +++---- djangocms_frontend/contrib/badge/forms.py | 7 ++---- .../contrib/card/cms_plugins.py | 12 ++++------ djangocms_frontend/contrib/card/forms.py | 23 ++++-------------- .../contrib/card/frameworks/bootstrap5.py | 4 +--- djangocms_frontend/contrib/carousel/forms.py | 14 ++++------- .../contrib/grid/cms_plugins.py | 12 ++++------ djangocms_frontend/contrib/grid/forms.py | 24 +++++-------------- djangocms_frontend/contrib/icon/forms.py | 7 ++---- djangocms_frontend/contrib/jumbotron/forms.py | 14 ++++------- djangocms_frontend/contrib/link/forms.py | 17 ++++--------- djangocms_frontend/contrib/link/models.py | 2 +- djangocms_frontend/contrib/listgroup/forms.py | 8 ++----- .../contrib/navigation/forms.py | 9 +++---- djangocms_frontend/contrib/tabs/forms.py | 16 +++---------- djangocms_frontend/contrib/utilities/forms.py | 10 +++----- djangocms_frontend/ui_plugin_base.py | 5 ++-- pyproject.toml | 3 +++ 19 files changed, 62 insertions(+), 141 deletions(-) diff --git a/djangocms_frontend/apps.py b/djangocms_frontend/apps.py index ade4c34b..b17215bf 100644 --- a/djangocms_frontend/apps.py +++ b/djangocms_frontend/apps.py @@ -1,5 +1,5 @@ from django import apps -from django.core.checks import Warning, register +from django.core import checks class DjangocmsFrontendConfig(apps.AppConfig): @@ -9,7 +9,7 @@ class DjangocmsFrontendConfig(apps.AppConfig): def ready(self): from . import plugin_tag - register(check_settings) + checks.register(check_settings) plugin_tag.setup() @@ -19,7 +19,7 @@ def check_settings(*args, **kwargs): warnings = [] if hasattr(settings, "DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH"): # pragma: no cover - warnings.append(Warning( + warnings.append(checks.Warning( "The DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH setting was removed in djangocms-frontend 2.\n" "Use DJANGOCMS_LINK_MINIMUM_INPUT_LENGTH instead.", "This message disappears after removing the DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH from your project's " @@ -28,7 +28,7 @@ def check_settings(*args, **kwargs): obj="settings.DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH", )) if hasattr(settings, "DJANGOCMS_FRONTEND_LINK_MODELS"): # pragma: no cover - warnings.append(Warning( + warnings.append(checks.Warning( "The DJANGOCMS_FRONTEND_LINK_MODELS setting was removed in djangocms-frontend 2.\n" "djangocms-frontend 2 uses linkable models from djangocms-link. See " "https://github.com/django-cms/djangocms-link#django-cms-link for more info.", diff --git a/djangocms_frontend/contrib/alert/forms.py b/djangocms_frontend/contrib/alert/forms.py index 65ad4698..c53669ad 100644 --- a/djangocms_frontend/contrib/alert/forms.py +++ b/djangocms_frontend/contrib/alert/forms.py @@ -1,19 +1,17 @@ from django import forms from django.utils.translation import gettext_lazy as _ + from entangled.forms import EntangledModelForm from djangocms_frontend import settings from djangocms_frontend.common import ResponsiveFormMixin, SpacingFormMixin from djangocms_frontend.contrib import alert -from djangocms_frontend.fields import ( - AttributesFormField, - ColoredButtonGroup, - TagTypeFormField, -) +from djangocms_frontend.fields import AttributesFormField, ColoredButtonGroup, TagTypeFormField from djangocms_frontend.helpers import first_choice from djangocms_frontend.models import FrontendUIItem from djangocms_frontend.settings import COLOR_STYLE_CHOICES + mixin_factory = settings.get_forms(alert) diff --git a/djangocms_frontend/contrib/badge/forms.py b/djangocms_frontend/contrib/badge/forms.py index f71a6b45..ef979bf7 100644 --- a/djangocms_frontend/contrib/badge/forms.py +++ b/djangocms_frontend/contrib/badge/forms.py @@ -1,12 +1,9 @@ from django import forms from django.utils.translation import gettext_lazy as _ + from entangled.forms import EntangledModelForm -from djangocms_frontend.fields import ( - AttributesFormField, - ColoredButtonGroup, - TagTypeFormField, -) +from djangocms_frontend.fields import AttributesFormField, ColoredButtonGroup, TagTypeFormField from djangocms_frontend.helpers import first_choice from djangocms_frontend.models import FrontendUIItem from djangocms_frontend.settings import COLOR_STYLE_CHOICES diff --git a/djangocms_frontend/contrib/card/cms_plugins.py b/djangocms_frontend/contrib/card/cms_plugins.py index e686efe7..a2d1e644 100644 --- a/djangocms_frontend/contrib/card/cms_plugins.py +++ b/djangocms_frontend/contrib/card/cms_plugins.py @@ -1,19 +1,15 @@ -from cms.plugin_pool import plugin_pool from django.utils.translation import gettext_lazy as _ +from cms.plugin_pool import plugin_pool + from ... import settings from ...cms_plugins import CMSUIPlugin -from ...common import ( - AttributesMixin, - BackgroundMixin, - MarginMixin, - PaddingMixin, - ResponsiveMixin, -) +from ...common import AttributesMixin, BackgroundMixin, MarginMixin, PaddingMixin, ResponsiveMixin from ...helpers import add_plugin from .. import card from . import forms, models + mixin_factory = settings.get_renderer(card) diff --git a/djangocms_frontend/contrib/card/forms.py b/djangocms_frontend/contrib/card/forms.py index d56c6a98..582fd87e 100644 --- a/djangocms_frontend/contrib/card/forms.py +++ b/djangocms_frontend/contrib/card/forms.py @@ -2,33 +2,20 @@ from django import forms from django.utils.translation import gettext_lazy as _ + from entangled.forms import EntangledModelForm from djangocms_frontend.settings import COLOR_STYLE_CHOICES, DEVICE_SIZES from ... import settings -from ...common import ( - BackgroundFormMixin, - MarginFormMixin, - PaddingFormMixin, - ResponsiveFormMixin, -) -from ...fields import ( - AttributesFormField, - ButtonGroup, - ColoredButtonGroup, - IconGroup, - TagTypeFormField, -) +from ...common import BackgroundFormMixin, MarginFormMixin, PaddingFormMixin, ResponsiveFormMixin +from ...fields import AttributesFormField, ButtonGroup, ColoredButtonGroup, IconGroup, TagTypeFormField from ...helpers import first_choice, link_to_framework_doc from ...models import FrontendUIItem from .. import card from ..grid.constants import GRID_SIZE -from .constants import ( - CARD_ALIGNMENT_CHOICES, - CARD_INNER_TYPE_CHOICES, - CARD_LAYOUT_TYPE_CHOICES, -) +from .constants import CARD_ALIGNMENT_CHOICES, CARD_INNER_TYPE_CHOICES, CARD_LAYOUT_TYPE_CHOICES + # card allow for a transparent color CARD_COLOR_STYLE_CHOICES = settings.COLOR_STYLE_CHOICES + (("transparent", _("Transparent")),) diff --git a/djangocms_frontend/contrib/card/frameworks/bootstrap5.py b/djangocms_frontend/contrib/card/frameworks/bootstrap5.py index 1e7499e0..2674e5a7 100644 --- a/djangocms_frontend/contrib/card/frameworks/bootstrap5.py +++ b/djangocms_frontend/contrib/card/frameworks/bootstrap5.py @@ -1,6 +1,4 @@ -from djangocms_frontend.contrib.grid.frameworks.bootstrap5 import ( - get_row_cols_grid_values, -) +from djangocms_frontend.contrib.grid.frameworks.bootstrap5 import get_row_cols_grid_values class CardRenderMixin: diff --git a/djangocms_frontend/contrib/carousel/forms.py b/djangocms_frontend/contrib/carousel/forms.py index 1aeec88e..6aa8b9dd 100644 --- a/djangocms_frontend/contrib/carousel/forms.py +++ b/djangocms_frontend/contrib/carousel/forms.py @@ -1,16 +1,12 @@ from django import forms from django.db.models.fields.related import ManyToOneRel from django.utils.translation import gettext_lazy as _ + from entangled.forms import EntangledModelForm from filer.fields.image import AdminImageFormField, FilerImageField from filer.models import Image -from djangocms_frontend.fields import ( - AttributesFormField, - ButtonGroup, - TagTypeFormField, - TemplateChoiceMixin, -) +from djangocms_frontend.fields import AttributesFormField, ButtonGroup, TagTypeFormField, TemplateChoiceMixin from ... import settings from ...common import BackgroundFormMixin @@ -20,12 +16,10 @@ from .. import carousel from ..link.forms import LinkFormMixin from .constants import ( - CAROUSEL_ASPECT_RATIO_CHOICES, - CAROUSEL_PAUSE_CHOICES, - CAROUSEL_TEMPLATE_CHOICES, - CAROUSEL_TRANSITION_CHOICES, + CAROUSEL_ASPECT_RATIO_CHOICES, CAROUSEL_PAUSE_CHOICES, CAROUSEL_TEMPLATE_CHOICES, CAROUSEL_TRANSITION_CHOICES, ) + mixin_factory = settings.get_forms(carousel) diff --git a/djangocms_frontend/contrib/grid/cms_plugins.py b/djangocms_frontend/contrib/grid/cms_plugins.py index 26c01f8a..76fd7e53 100644 --- a/djangocms_frontend/contrib/grid/cms_plugins.py +++ b/djangocms_frontend/contrib/grid/cms_plugins.py @@ -1,14 +1,9 @@ -from cms.plugin_pool import plugin_pool from django.utils.translation import gettext_lazy as _ +from cms.plugin_pool import plugin_pool + from djangocms_frontend import settings -from djangocms_frontend.common import ( - AttributesMixin, - BackgroundMixin, - ResponsiveMixin, - SizingMixin, - SpacingMixin, -) +from djangocms_frontend.common import AttributesMixin, BackgroundMixin, ResponsiveMixin, SizingMixin, SpacingMixin from ...cms_plugins import CMSUIPlugin from ...common import TitleMixin @@ -16,6 +11,7 @@ from .. import grid from . import forms, models + mixin_factory = settings.get_renderer(grid) diff --git a/djangocms_frontend/contrib/grid/forms.py b/djangocms_frontend/contrib/grid/forms.py index 5772fbdd..6a320517 100644 --- a/djangocms_frontend/contrib/grid/forms.py +++ b/djangocms_frontend/contrib/grid/forms.py @@ -3,35 +3,23 @@ from django import forms from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ + from entangled.forms import EntangledModelForm from djangocms_frontend import settings -from djangocms_frontend.common import ( - BackgroundFormMixin, - ResponsiveFormMixin, - SizingFormMixin, - SpacingFormMixin, -) -from djangocms_frontend.fields import ( - AttributesFormField, - AutoNumberInput, - ButtonGroup, - IconGroup, - TagTypeFormField, -) +from djangocms_frontend.common import BackgroundFormMixin, ResponsiveFormMixin, SizingFormMixin, SpacingFormMixin +from djangocms_frontend.fields import AttributesFormField, AutoNumberInput, ButtonGroup, IconGroup, TagTypeFormField from djangocms_frontend.helpers import first_choice, link_to_framework_doc from djangocms_frontend.models import FrontendUIItem from ...common.title import TitleFormMixin from .. import grid from .constants import ( - GRID_COLUMN_ALIGNMENT_CHOICES, - GRID_CONTAINER_CHOICES, - GRID_ROW_HORIZONTAL_ALIGNMENT_CHOICES, - GRID_ROW_VERTICAL_ALIGNMENT_CHOICES, - GRID_SIZE, + GRID_COLUMN_ALIGNMENT_CHOICES, GRID_CONTAINER_CHOICES, GRID_ROW_HORIZONTAL_ALIGNMENT_CHOICES, + GRID_ROW_VERTICAL_ALIGNMENT_CHOICES, GRID_SIZE, ) + mixin_factory = settings.get_forms(grid) diff --git a/djangocms_frontend/contrib/icon/forms.py b/djangocms_frontend/contrib/icon/forms.py index 526b3f6c..360e79b9 100644 --- a/djangocms_frontend/contrib/icon/forms.py +++ b/djangocms_frontend/contrib/icon/forms.py @@ -1,12 +1,9 @@ from django import forms from django.utils.translation import gettext_lazy as _ + from entangled.forms import EntangledModelForm -from djangocms_frontend.fields import ( - AttributesFormField, - ColoredButtonGroup, - TagTypeFormField, -) +from djangocms_frontend.fields import AttributesFormField, ColoredButtonGroup, TagTypeFormField from ... import settings from ...common import BackgroundFormMixin, ResponsiveFormMixin, SpacingFormMixin diff --git a/djangocms_frontend/contrib/jumbotron/forms.py b/djangocms_frontend/contrib/jumbotron/forms.py index 0eb2943a..3e06b54b 100644 --- a/djangocms_frontend/contrib/jumbotron/forms.py +++ b/djangocms_frontend/contrib/jumbotron/forms.py @@ -1,22 +1,16 @@ from django import forms from django.utils.translation import gettext_lazy as _ + from entangled.forms import EntangledModelForm from djangocms_frontend import settings -from djangocms_frontend.common import ( - BackgroundFormMixin, - ResponsiveFormMixin, - SpacingFormMixin, -) +from djangocms_frontend.common import BackgroundFormMixin, ResponsiveFormMixin, SpacingFormMixin from djangocms_frontend.contrib import jumbotron from djangocms_frontend.contrib.jumbotron import models -from djangocms_frontend.fields import ( - AttributesFormField, - TagTypeFormField, - TemplateChoiceMixin, -) +from djangocms_frontend.fields import AttributesFormField, TagTypeFormField, TemplateChoiceMixin from djangocms_frontend.helpers import first_choice + mixin_factory = settings.get_forms(jumbotron) diff --git a/djangocms_frontend/contrib/link/forms.py b/djangocms_frontend/contrib/link/forms.py index bc801a29..e3db4953 100644 --- a/djangocms_frontend/contrib/link/forms.py +++ b/djangocms_frontend/contrib/link/forms.py @@ -2,25 +2,21 @@ from django.conf import settings as django_settings from django.contrib.sites.models import Site from django.utils.translation import gettext as _ -from djangocms_link.fields import LinkFormField # from djangocms_link.validators import IntranetURLValidator from entangled.forms import EntangledModelForm, EntangledModelFormMixin +from djangocms_link.fields import LinkFormField + from ... import settings from ...common import SpacingFormMixin -from ...fields import ( - AttributesFormField, - ButtonGroup, - ColoredButtonGroup, - TagTypeFormField, - TemplateChoiceMixin, -) +from ...fields import AttributesFormField, ButtonGroup, ColoredButtonGroup, TagTypeFormField, TemplateChoiceMixin from ...helpers import first_choice from ...models import FrontendUIItem from .. import link from .constants import LINK_CHOICES, LINK_SIZE_CHOICES, TARGET_CHOICES + mixin_factory = settings.get_forms(link) if "djangocms_frontend.contrib.icon" in django_settings.INSTALLED_APPS: @@ -40,10 +36,7 @@ def __init__(self, *args, **kwargs): if apps.apps.is_installed("djangocms_url_manager"): - from djangocms_url_manager.forms import ( - HtmlLinkSiteSelectWidget, - HtmlLinkUrlSelectWidget, - ) + from djangocms_url_manager.forms import HtmlLinkSiteSelectWidget, HtmlLinkUrlSelectWidget from djangocms_url_manager.models import UrlGrouper class LinkFormMixin(EntangledModelFormMixin): diff --git a/djangocms_frontend/contrib/link/models.py b/djangocms_frontend/contrib/link/models.py index 0a8df3f6..21065cdc 100644 --- a/djangocms_frontend/contrib/link/models.py +++ b/djangocms_frontend/contrib/link/models.py @@ -1,11 +1,11 @@ from django.utils.translation import gettext as _ from djangocms_frontend.contrib.link.helpers import GetLinkMixin - # 'link' type is added manually as it is only required for this plugin from djangocms_frontend.models import FrontendUIItem from djangocms_frontend.settings import COLOR_STYLE_CHOICES + COLOR_STYLE_CHOICES = (("link", _("Link")),) + COLOR_STYLE_CHOICES diff --git a/djangocms_frontend/contrib/listgroup/forms.py b/djangocms_frontend/contrib/listgroup/forms.py index cb97cd24..6dd4e4a1 100644 --- a/djangocms_frontend/contrib/listgroup/forms.py +++ b/djangocms_frontend/contrib/listgroup/forms.py @@ -1,16 +1,12 @@ from django import forms from django.utils.translation import gettext_lazy as _ + from entangled.forms import EntangledModelForm from djangocms_frontend import settings from ...common import MarginFormMixin, PaddingFormMixin, ResponsiveFormMixin -from ...fields import ( - AttributesFormField, - ButtonGroup, - ColoredButtonGroup, - TagTypeFormField, -) +from ...fields import AttributesFormField, ButtonGroup, ColoredButtonGroup, TagTypeFormField from ...models import FrontendUIItem from .constants import LISTGROUP_STATE_CHOICES diff --git a/djangocms_frontend/contrib/navigation/forms.py b/djangocms_frontend/contrib/navigation/forms.py index 67459dd3..b1f5cbb8 100644 --- a/djangocms_frontend/contrib/navigation/forms.py +++ b/djangocms_frontend/contrib/navigation/forms.py @@ -1,21 +1,18 @@ from django import forms from django.utils.translation import gettext_lazy as _ + from entangled.forms import EntangledModelForm from djangocms_frontend import settings from djangocms_frontend.common import BackgroundFormMixin from djangocms_frontend.contrib import navigation from djangocms_frontend.contrib.link.forms import AbstractLinkForm, LinkForm -from djangocms_frontend.fields import ( - AttributesFormField, - ButtonGroup, - IconGroup, - TemplateChoiceMixin, -) +from djangocms_frontend.fields import AttributesFormField, ButtonGroup, IconGroup, TemplateChoiceMixin from djangocms_frontend.helpers import first_choice from djangocms_frontend.models import FrontendUIItem from djangocms_frontend.settings import NAVBAR_DESIGNS + mixin_factory = settings.get_forms(navigation) diff --git a/djangocms_frontend/contrib/tabs/forms.py b/djangocms_frontend/contrib/tabs/forms.py index 29dd825b..14e7ffc7 100644 --- a/djangocms_frontend/contrib/tabs/forms.py +++ b/djangocms_frontend/contrib/tabs/forms.py @@ -1,24 +1,14 @@ from django import forms from django.utils.translation import gettext as _ + from entangled.forms import EntangledModelForm from ... import settings from ...common import PaddingFormMixin -from ...fields import ( - AttributesFormField, - ButtonGroup, - IconGroup, - TagTypeFormField, - TemplateChoiceMixin, -) +from ...fields import AttributesFormField, ButtonGroup, IconGroup, TagTypeFormField, TemplateChoiceMixin from ...helpers import first_choice from ...models import FrontendUIItem -from .constants import ( - TAB_ALIGNMENT_CHOICES, - TAB_EFFECT_CHOICES, - TAB_TEMPLATE_CHOICES, - TAB_TYPE_CHOICES, -) +from .constants import TAB_ALIGNMENT_CHOICES, TAB_EFFECT_CHOICES, TAB_TEMPLATE_CHOICES, TAB_TYPE_CHOICES class TabForm(TemplateChoiceMixin, EntangledModelForm): diff --git a/djangocms_frontend/contrib/utilities/forms.py b/djangocms_frontend/contrib/utilities/forms.py index 549cb2b4..35be2068 100644 --- a/djangocms_frontend/contrib/utilities/forms.py +++ b/djangocms_frontend/contrib/utilities/forms.py @@ -1,21 +1,17 @@ from django import forms from django.core.exceptions import ValidationError from django.utils.translation import gettext as _ + from entangled.forms import EntangledModelForm from ... import settings from ...common import SpacingFormMixin -from ...fields import ( - AttributesFormField, - ButtonGroup, - ColoredButtonGroup, - IconGroup, - TagTypeFormField, -) +from ...fields import AttributesFormField, ButtonGroup, ColoredButtonGroup, IconGroup, TagTypeFormField from ...helpers import first_choice from ...models import FrontendUIItem from .. import utilities + mixin_factory = settings.get_forms(utilities) diff --git a/djangocms_frontend/ui_plugin_base.py b/djangocms_frontend/ui_plugin_base.py index 1fcac3cf..1bef1f9b 100644 --- a/djangocms_frontend/ui_plugin_base.py +++ b/djangocms_frontend/ui_plugin_base.py @@ -1,10 +1,11 @@ -from cms.plugin_base import CMSPluginBase - # Import the components from the current directory's models module from django.utils.encoding import force_str +from cms.plugin_base import CMSPluginBase + from djangocms_frontend.helpers import get_related + try: from cms.admin.placeholderadmin import PlaceholderAdmin diff --git a/pyproject.toml b/pyproject.toml index c3cc48c4..b3971a97 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,6 +64,9 @@ known_django = "django" [tool.flake8] max-line-length = 120 +select = [ + "C", "E" ,"F", "W", "B", "B950" +] exclude = [ "*.egg-info", ".eggs", From 8506c2bd3bb84ad36bd7ae9693b14fbf6c79ffdd Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Sun, 10 Nov 2024 17:46:25 +0100 Subject: [PATCH 53/66] Add coverage config to pyproject.toml --- .coveragerc | 20 ---------- .pre-commit-config.yaml | 13 +++++++ pyproject.toml | 82 +++++++++++++++++++++++++++-------------- 3 files changed, 68 insertions(+), 47 deletions(-) delete mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 50625d86..00000000 --- a/.coveragerc +++ /dev/null @@ -1,20 +0,0 @@ -[run] -branch = True -source = djangocms_frontend -omit = - djangocms_frontend/migrations/* - djangocms_frontend/management/* - */foundation6.py - tests/* - -[report] -exclude_lines = - pragma: no cover - def __repr__ - if self.debug: - if settings.DEBUG - raise AssertionError - raise NotImplementedError - if 0: - if __name__ == .__main__.: -ignore_errors = True diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 073ae14c..f5154ac6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -34,3 +34,16 @@ repos: - flake8-django - flake8-length - flake8-logging-format + + - repo: https://github.com/tox-dev/pyproject-fmt + rev: v2.5.0 + hooks: + - id: pyproject-fmt + + - repo: https://github.com/rstcheck/rstcheck + rev: v6.2.4 + hooks: + - id: rstcheck + additional_dependencies: + - sphinx==6.1.3 + - tomli==2.0.1 diff --git a/pyproject.toml b/pyproject.toml index b3971a97..d2eda38b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,37 +1,34 @@ [tool.black] exclude = [ - ".git", - ".hg", - ".tox", - "venv", - ".venv", - "_build", - "build", - "dist" + ".git", + ".hg", + ".tox", + "venv", + ".venv", + "_build", + "build", + "dist", ] -[tool.djlint] -ignore="H023,T003,H006,H031,D018,H021,H025" -profile="django" - [tool.ruff] +line-length = 119 exclude = [ - ".env", - ".venv", - "**/migrations/**", -] -lint.ignore = [ - "E501", # line too long - "F403", # 'from module import *' used; unable to detect undefined names - "E701", # multiple statements on one line (colon) - "F401", # module imported but unused + "**/migrations/**", + ".env", + ".venv", ] -line-length = 119 lint.select = [ - "I", - "E", - "F", - "W", + "E", + "F", + "I", + "W", +] + +lint.ignore = [ + "E501", # line too long + "E701", # multiple statements on one line (colon) + "F401", # module imported but unused + "F403", # 'from module import *' used; unable to detect undefined names ] [tool.isort] @@ -65,7 +62,12 @@ known_django = "django" [tool.flake8] max-line-length = 120 select = [ - "C", "E" ,"F", "W", "B", "B950" + "C", + "E", + "F", + "W", + "B", + "B950", ] exclude = [ "*.egg-info", @@ -84,3 +86,29 @@ exclude = [ "tmp", ] +[tool.coverage.run] +branch = true +source = [ "djangocms_frontend" ] +omit = [ + "djangocms_frontend/migrations/*", + "djangocms_frontend/management/*", + "*/foundation6.py", + "tests/*", +] + +[tool.coverage.report] +exclude_lines = [ + "pragma: no cover", + "def __repr__", + "if self.debug:", + "if settings.DEBUG", + "raise AssertionError", + "raise NotImplementedError", + "if 0:", + "if __name__ == .__main__.:", +] +ignore_errors = true + +[tool.djlint] +ignore = "H023,T003,H006,H031,D018,H021,H025" +profile = "django" From 89c54a91cdf4c5f2cd851064c17063e1fa3d30c8 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Sun, 10 Nov 2024 17:52:05 +0100 Subject: [PATCH 54/66] Add djlint options to pyproject.toml --- .djlint_rules.yaml | 7 ------- pyproject.toml | 9 +++++++++ 2 files changed, 9 insertions(+), 7 deletions(-) delete mode 100644 .djlint_rules.yaml diff --git a/.djlint_rules.yaml b/.djlint_rules.yaml deleted file mode 100644 index 5fb69a5b..00000000 --- a/.djlint_rules.yaml +++ /dev/null @@ -1,7 +0,0 @@ -- rule: - name: D034 - message: .pk or .id should only be used with "|unlocalize" - flags: re.DOTALL|re.I - patterns: - - '{{\s*[a-zA-Z0-9_.]+\.pk\s*}}' - - '{{\s*[a-zA-Z0-9_.]+\.id\s*}}' diff --git a/pyproject.toml b/pyproject.toml index d2eda38b..f2493cca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -112,3 +112,12 @@ ignore_errors = true [tool.djlint] ignore = "H023,T003,H006,H031,D018,H021,H025" profile = "django" + +[tool.djlint.rule] +name = "D034" +message = ".pk or .id should only be used with \"|unlocalize\"" +flags = "re.DOTALL|re.I" +patterns = [ + '{{\s*[a-zA-Z0-9_.]+\.pk\s*}}', + '{{\s*[a-zA-Z0-9_.]+\.id\s*}}', +] From baabe0d249a6cf70c08928dc84550f015ffd9fc8 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Sun, 10 Nov 2024 17:57:23 +0100 Subject: [PATCH 55/66] Fix remove isort from pre-commit --- .pre-commit-config.yaml | 7 ++----- djangocms_frontend/common/__init__.py | 1 - djangocms_frontend/contrib/alert/forms.py | 2 -- djangocms_frontend/contrib/badge/forms.py | 1 - djangocms_frontend/contrib/card/cms_plugins.py | 4 +--- djangocms_frontend/contrib/card/forms.py | 2 -- djangocms_frontend/contrib/carousel/forms.py | 7 ++++--- djangocms_frontend/contrib/grid/cms_plugins.py | 4 +--- djangocms_frontend/contrib/grid/forms.py | 9 +++++---- djangocms_frontend/contrib/icon/forms.py | 1 - djangocms_frontend/contrib/jumbotron/forms.py | 2 -- djangocms_frontend/contrib/link/forms.py | 4 +--- djangocms_frontend/contrib/link/models.py | 2 +- djangocms_frontend/contrib/listgroup/forms.py | 1 - djangocms_frontend/contrib/navigation/cms_plugins.py | 4 +--- djangocms_frontend/contrib/navigation/forms.py | 2 -- djangocms_frontend/contrib/tabs/forms.py | 1 - djangocms_frontend/contrib/utilities/forms.py | 2 -- djangocms_frontend/helpers.py | 7 +++---- djangocms_frontend/management/bootstrap4_migration.py | 1 - djangocms_frontend/ui_plugin_base.py | 4 +--- pyproject.toml | 3 +++ tests/test_plugin_tag.py | 4 ++-- 23 files changed, 25 insertions(+), 50 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f5154ac6..1f78c83e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,16 +13,13 @@ repos: hooks: - id: pyupgrade args: ["--py39-plus"] + - repo: https://github.com/adamchainz/django-upgrade rev: "1.22.1" hooks: - id: django-upgrade args: [--target-version, "4.2"] - - repo: https://github.com/pycqa/isort - rev: 5.13.2 - hooks: - - id: isort - name: isort (python) + - repo: https://github.com/PyCQA/flake8 rev: 7.1.1 hooks: diff --git a/djangocms_frontend/common/__init__.py b/djangocms_frontend/common/__init__.py index 4591aeab..d020d162 100644 --- a/djangocms_frontend/common/__init__.py +++ b/djangocms_frontend/common/__init__.py @@ -5,7 +5,6 @@ from .attributes import AttributesMixin from .title import TitleFormMixin, TitleMixin - __common = { "background": ("BackgroundFormMixin", "BackgroundMixin"), "responsive": ("ResponsiveFormMixin", "ResponsiveMixin"), diff --git a/djangocms_frontend/contrib/alert/forms.py b/djangocms_frontend/contrib/alert/forms.py index c53669ad..4885f2de 100644 --- a/djangocms_frontend/contrib/alert/forms.py +++ b/djangocms_frontend/contrib/alert/forms.py @@ -1,6 +1,5 @@ from django import forms from django.utils.translation import gettext_lazy as _ - from entangled.forms import EntangledModelForm from djangocms_frontend import settings @@ -11,7 +10,6 @@ from djangocms_frontend.models import FrontendUIItem from djangocms_frontend.settings import COLOR_STYLE_CHOICES - mixin_factory = settings.get_forms(alert) diff --git a/djangocms_frontend/contrib/badge/forms.py b/djangocms_frontend/contrib/badge/forms.py index ef979bf7..37fa55e6 100644 --- a/djangocms_frontend/contrib/badge/forms.py +++ b/djangocms_frontend/contrib/badge/forms.py @@ -1,6 +1,5 @@ from django import forms from django.utils.translation import gettext_lazy as _ - from entangled.forms import EntangledModelForm from djangocms_frontend.fields import AttributesFormField, ColoredButtonGroup, TagTypeFormField diff --git a/djangocms_frontend/contrib/card/cms_plugins.py b/djangocms_frontend/contrib/card/cms_plugins.py index a2d1e644..38d7354a 100644 --- a/djangocms_frontend/contrib/card/cms_plugins.py +++ b/djangocms_frontend/contrib/card/cms_plugins.py @@ -1,6 +1,5 @@ -from django.utils.translation import gettext_lazy as _ - from cms.plugin_pool import plugin_pool +from django.utils.translation import gettext_lazy as _ from ... import settings from ...cms_plugins import CMSUIPlugin @@ -9,7 +8,6 @@ from .. import card from . import forms, models - mixin_factory = settings.get_renderer(card) diff --git a/djangocms_frontend/contrib/card/forms.py b/djangocms_frontend/contrib/card/forms.py index 582fd87e..0bceb364 100644 --- a/djangocms_frontend/contrib/card/forms.py +++ b/djangocms_frontend/contrib/card/forms.py @@ -2,7 +2,6 @@ from django import forms from django.utils.translation import gettext_lazy as _ - from entangled.forms import EntangledModelForm from djangocms_frontend.settings import COLOR_STYLE_CHOICES, DEVICE_SIZES @@ -16,7 +15,6 @@ from ..grid.constants import GRID_SIZE from .constants import CARD_ALIGNMENT_CHOICES, CARD_INNER_TYPE_CHOICES, CARD_LAYOUT_TYPE_CHOICES - # card allow for a transparent color CARD_COLOR_STYLE_CHOICES = settings.COLOR_STYLE_CHOICES + (("transparent", _("Transparent")),) diff --git a/djangocms_frontend/contrib/carousel/forms.py b/djangocms_frontend/contrib/carousel/forms.py index 6aa8b9dd..ac599722 100644 --- a/djangocms_frontend/contrib/carousel/forms.py +++ b/djangocms_frontend/contrib/carousel/forms.py @@ -1,7 +1,6 @@ from django import forms from django.db.models.fields.related import ManyToOneRel from django.utils.translation import gettext_lazy as _ - from entangled.forms import EntangledModelForm from filer.fields.image import AdminImageFormField, FilerImageField from filer.models import Image @@ -16,10 +15,12 @@ from .. import carousel from ..link.forms import LinkFormMixin from .constants import ( - CAROUSEL_ASPECT_RATIO_CHOICES, CAROUSEL_PAUSE_CHOICES, CAROUSEL_TEMPLATE_CHOICES, CAROUSEL_TRANSITION_CHOICES, + CAROUSEL_ASPECT_RATIO_CHOICES, + CAROUSEL_PAUSE_CHOICES, + CAROUSEL_TEMPLATE_CHOICES, + CAROUSEL_TRANSITION_CHOICES, ) - mixin_factory = settings.get_forms(carousel) diff --git a/djangocms_frontend/contrib/grid/cms_plugins.py b/djangocms_frontend/contrib/grid/cms_plugins.py index 76fd7e53..32b9963d 100644 --- a/djangocms_frontend/contrib/grid/cms_plugins.py +++ b/djangocms_frontend/contrib/grid/cms_plugins.py @@ -1,6 +1,5 @@ -from django.utils.translation import gettext_lazy as _ - from cms.plugin_pool import plugin_pool +from django.utils.translation import gettext_lazy as _ from djangocms_frontend import settings from djangocms_frontend.common import AttributesMixin, BackgroundMixin, ResponsiveMixin, SizingMixin, SpacingMixin @@ -11,7 +10,6 @@ from .. import grid from . import forms, models - mixin_factory = settings.get_renderer(grid) diff --git a/djangocms_frontend/contrib/grid/forms.py b/djangocms_frontend/contrib/grid/forms.py index 6a320517..5af376b1 100644 --- a/djangocms_frontend/contrib/grid/forms.py +++ b/djangocms_frontend/contrib/grid/forms.py @@ -3,7 +3,6 @@ from django import forms from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ - from entangled.forms import EntangledModelForm from djangocms_frontend import settings @@ -15,11 +14,13 @@ from ...common.title import TitleFormMixin from .. import grid from .constants import ( - GRID_COLUMN_ALIGNMENT_CHOICES, GRID_CONTAINER_CHOICES, GRID_ROW_HORIZONTAL_ALIGNMENT_CHOICES, - GRID_ROW_VERTICAL_ALIGNMENT_CHOICES, GRID_SIZE, + GRID_COLUMN_ALIGNMENT_CHOICES, + GRID_CONTAINER_CHOICES, + GRID_ROW_HORIZONTAL_ALIGNMENT_CHOICES, + GRID_ROW_VERTICAL_ALIGNMENT_CHOICES, + GRID_SIZE, ) - mixin_factory = settings.get_forms(grid) diff --git a/djangocms_frontend/contrib/icon/forms.py b/djangocms_frontend/contrib/icon/forms.py index 360e79b9..7e09ef81 100644 --- a/djangocms_frontend/contrib/icon/forms.py +++ b/djangocms_frontend/contrib/icon/forms.py @@ -1,6 +1,5 @@ from django import forms from django.utils.translation import gettext_lazy as _ - from entangled.forms import EntangledModelForm from djangocms_frontend.fields import AttributesFormField, ColoredButtonGroup, TagTypeFormField diff --git a/djangocms_frontend/contrib/jumbotron/forms.py b/djangocms_frontend/contrib/jumbotron/forms.py index 3e06b54b..bba2c1a1 100644 --- a/djangocms_frontend/contrib/jumbotron/forms.py +++ b/djangocms_frontend/contrib/jumbotron/forms.py @@ -1,6 +1,5 @@ from django import forms from django.utils.translation import gettext_lazy as _ - from entangled.forms import EntangledModelForm from djangocms_frontend import settings @@ -10,7 +9,6 @@ from djangocms_frontend.fields import AttributesFormField, TagTypeFormField, TemplateChoiceMixin from djangocms_frontend.helpers import first_choice - mixin_factory = settings.get_forms(jumbotron) diff --git a/djangocms_frontend/contrib/link/forms.py b/djangocms_frontend/contrib/link/forms.py index e3db4953..7918a0c5 100644 --- a/djangocms_frontend/contrib/link/forms.py +++ b/djangocms_frontend/contrib/link/forms.py @@ -2,12 +2,11 @@ from django.conf import settings as django_settings from django.contrib.sites.models import Site from django.utils.translation import gettext as _ +from djangocms_link.fields import LinkFormField # from djangocms_link.validators import IntranetURLValidator from entangled.forms import EntangledModelForm, EntangledModelFormMixin -from djangocms_link.fields import LinkFormField - from ... import settings from ...common import SpacingFormMixin from ...fields import AttributesFormField, ButtonGroup, ColoredButtonGroup, TagTypeFormField, TemplateChoiceMixin @@ -16,7 +15,6 @@ from .. import link from .constants import LINK_CHOICES, LINK_SIZE_CHOICES, TARGET_CHOICES - mixin_factory = settings.get_forms(link) if "djangocms_frontend.contrib.icon" in django_settings.INSTALLED_APPS: diff --git a/djangocms_frontend/contrib/link/models.py b/djangocms_frontend/contrib/link/models.py index 21065cdc..0a8df3f6 100644 --- a/djangocms_frontend/contrib/link/models.py +++ b/djangocms_frontend/contrib/link/models.py @@ -1,11 +1,11 @@ from django.utils.translation import gettext as _ from djangocms_frontend.contrib.link.helpers import GetLinkMixin + # 'link' type is added manually as it is only required for this plugin from djangocms_frontend.models import FrontendUIItem from djangocms_frontend.settings import COLOR_STYLE_CHOICES - COLOR_STYLE_CHOICES = (("link", _("Link")),) + COLOR_STYLE_CHOICES diff --git a/djangocms_frontend/contrib/listgroup/forms.py b/djangocms_frontend/contrib/listgroup/forms.py index 6dd4e4a1..cecf785d 100644 --- a/djangocms_frontend/contrib/listgroup/forms.py +++ b/djangocms_frontend/contrib/listgroup/forms.py @@ -1,6 +1,5 @@ from django import forms from django.utils.translation import gettext_lazy as _ - from entangled.forms import EntangledModelForm from djangocms_frontend import settings diff --git a/djangocms_frontend/contrib/navigation/cms_plugins.py b/djangocms_frontend/contrib/navigation/cms_plugins.py index 0d070558..784e5f6d 100644 --- a/djangocms_frontend/contrib/navigation/cms_plugins.py +++ b/djangocms_frontend/contrib/navigation/cms_plugins.py @@ -1,6 +1,5 @@ -from django.utils.translation import gettext_lazy as _ - from cms.plugin_pool import plugin_pool +from django.utils.translation import gettext_lazy as _ from ... import settings from ...cms_plugins import CMSUIPlugin @@ -10,7 +9,6 @@ from ..link.cms_plugins import LinkPluginMixin, TextLinkPlugin from . import forms, models - mixin_factory = settings.get_renderer(navigation) default_template = first_choice(settings.NAVIGATION_TEMPLATE_CHOICES) diff --git a/djangocms_frontend/contrib/navigation/forms.py b/djangocms_frontend/contrib/navigation/forms.py index b1f5cbb8..2ebf6f64 100644 --- a/djangocms_frontend/contrib/navigation/forms.py +++ b/djangocms_frontend/contrib/navigation/forms.py @@ -1,6 +1,5 @@ from django import forms from django.utils.translation import gettext_lazy as _ - from entangled.forms import EntangledModelForm from djangocms_frontend import settings @@ -12,7 +11,6 @@ from djangocms_frontend.models import FrontendUIItem from djangocms_frontend.settings import NAVBAR_DESIGNS - mixin_factory = settings.get_forms(navigation) diff --git a/djangocms_frontend/contrib/tabs/forms.py b/djangocms_frontend/contrib/tabs/forms.py index 14e7ffc7..5aaaefc3 100644 --- a/djangocms_frontend/contrib/tabs/forms.py +++ b/djangocms_frontend/contrib/tabs/forms.py @@ -1,6 +1,5 @@ from django import forms from django.utils.translation import gettext as _ - from entangled.forms import EntangledModelForm from ... import settings diff --git a/djangocms_frontend/contrib/utilities/forms.py b/djangocms_frontend/contrib/utilities/forms.py index 35be2068..8d7f2e0e 100644 --- a/djangocms_frontend/contrib/utilities/forms.py +++ b/djangocms_frontend/contrib/utilities/forms.py @@ -1,7 +1,6 @@ from django import forms from django.core.exceptions import ValidationError from django.utils.translation import gettext as _ - from entangled.forms import EntangledModelForm from ... import settings @@ -11,7 +10,6 @@ from ...models import FrontendUIItem from .. import utilities - mixin_factory = settings.get_forms(utilities) diff --git a/djangocms_frontend/helpers.py b/djangocms_frontend/helpers.py index 448eb9d6..2fc07d11 100644 --- a/djangocms_frontend/helpers.py +++ b/djangocms_frontend/helpers.py @@ -1,6 +1,9 @@ import copy import decimal +from cms.constants import SLUG_REGEXP +from cms.plugin_base import CMSPluginBase +from cms.utils.conf import get_cms_setting from django.apps import apps from django.contrib.admin.helpers import AdminForm from django.db.models import ObjectDoesNotExist @@ -12,10 +15,6 @@ from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ -from cms.constants import SLUG_REGEXP -from cms.plugin_base import CMSPluginBase -from cms.utils.conf import get_cms_setting - from djangocms_frontend import settings from djangocms_frontend.settings import FRAMEWORK_PLUGIN_INFO diff --git a/djangocms_frontend/management/bootstrap4_migration.py b/djangocms_frontend/management/bootstrap4_migration.py index 00163a3a..fcdf20cf 100644 --- a/djangocms_frontend/management/bootstrap4_migration.py +++ b/djangocms_frontend/management/bootstrap4_migration.py @@ -1,5 +1,4 @@ from django.conf import settings as django_setting - from djangocms_bootstrap4.constants import DEVICE_SIZES from djangocms_frontend import settings diff --git a/djangocms_frontend/ui_plugin_base.py b/djangocms_frontend/ui_plugin_base.py index 1bef1f9b..c2820c49 100644 --- a/djangocms_frontend/ui_plugin_base.py +++ b/djangocms_frontend/ui_plugin_base.py @@ -1,11 +1,9 @@ # Import the components from the current directory's models module -from django.utils.encoding import force_str - from cms.plugin_base import CMSPluginBase +from django.utils.encoding import force_str from djangocms_frontend.helpers import get_related - try: from cms.admin.placeholderadmin import PlaceholderAdmin diff --git a/pyproject.toml b/pyproject.toml index f2493cca..af2ff3d7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,6 +69,9 @@ select = [ "B", "B950", ] +ignore = [ + "W503", # line break before binary operator +] exclude = [ "*.egg-info", ".eggs", diff --git a/tests/test_plugin_tag.py b/tests/test_plugin_tag.py index e1f074e3..1d01cb3d 100644 --- a/tests/test_plugin_tag.py +++ b/tests/test_plugin_tag.py @@ -80,14 +80,14 @@ def test_link_plugin(self): {% plugin "textlink" name="Click" url_grouper=grouper site=test_site link_type="btn" link_context="primary" link_outline=False %} Click me! {% endplugin %} - """) # noqa: B950 + """) # noqa: B950,E501 else: grouper = None template = django_engine.from_string("""{% load frontend djangocms_link_tags %}{{ "test"|to_link }} {% plugin "textlink" name="Click" link="/test/"|to_link link_type="btn" link_context="primary" link_outline=False %} Click me! {% endplugin %} - """) # noqa: B950 + """) # noqa: B950,E501 expected_result = """Click me!""" From ba14e2f23bcf06eb31f27a5326854d7ecdb33396 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Sun, 10 Nov 2024 18:08:13 +0100 Subject: [PATCH 56/66] Fix docs --- .pre-commit-config.yaml | 8 -------- CHANGELOG.rst | 8 ++++---- README.rst | 6 ++---- docs/source/custom_components.rst | 5 +++-- docs/source/index.rst | 3 +-- 5 files changed, 10 insertions(+), 20 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1f78c83e..08639421 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,11 +36,3 @@ repos: rev: v2.5.0 hooks: - id: pyproject-fmt - - - repo: https://github.com/rstcheck/rstcheck - rev: v6.2.4 - hooks: - - id: rstcheck - additional_dependencies: - - sphinx==6.1.3 - - tomli==2.0.1 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 14248778..01d90dcc 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -82,7 +82,7 @@ Changelog * feat: Add float option for images by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/162 * feat: Add drag'n'drop support for djangocms-text-ckeditor by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/165 * fix: Ckeditor does not show icons for editing by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/163 -* fix: Replace ``stylesSet`` setting in docs with ``customConfig` for icons in ckeditor by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/164 +* fix: Replace ``stylesSet`` setting in docs with ``customConfig`` for icons in ckeditor by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/164 * ci: pre-commit autoupdate by @pre-commit-ci in https://github.com/django-cms/djangocms-frontend/pull/161 @@ -106,15 +106,15 @@ Changelog ================== * Fix incomplete migration of code plugins from djangocms-bootstrap4 -* Add compiled French locale (*.mo) +* Add compiled French locale (\*.mo) * Add partial Dutch locale 1.1.5 (2023-07-14) ================== * Fix bug where url for link select2 field was lost after app hook reload (#135) -* Use `bg-body` class on Bootstrap 5's tab navigation to support color modes (#138) -* Fix styling of icon buttons for better usager with plain django admin style (#141) +* Use ``bg-body`` class on Bootstrap 5's tab navigation to support color modes (#138) +* Fix styling of icon buttons for better usage with plain django admin style (#141) 1.1.4 (2023-05-28) ================== diff --git a/README.rst b/README.rst index 45e85833..42b7e33f 100644 --- a/README.rst +++ b/README.rst @@ -30,8 +30,7 @@ Key features provided by other applications, such as `djangocms-blog `_. -- **Nice and well-arranged admin frontend** of `djangocms-bootstrap4 - `_ +- **Nice and well-arranged admin frontend** of djangocms-bootstrap4 - **Extensible** within the project and with separate project (e.g. a theme app). Create your own components with a few lines of code only. @@ -148,8 +147,7 @@ install separately or by adding an option: Documentation ============= -See readthedocs for the `documentation -`_. +See readthedocs for the `documentation `_. License ======= diff --git a/docs/source/custom_components.rst b/docs/source/custom_components.rst index 2b20235a..15227c26 100644 --- a/docs/source/custom_components.rst +++ b/docs/source/custom_components.rst @@ -1,9 +1,10 @@ -.. _custom_components: - ################# Custom Components ################# +.. index:: + single: Custom Components + .. versionadded:: 2.0 Custom components are a powerful tool for content editors, allowing them to build pages without needing diff --git a/docs/source/index.rst b/docs/source/index.rst index 99996acb..8b8e1a2b 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -33,8 +33,7 @@ its specific version. provided by other applications, such as `djangocms-blog `_. -- **Nice and well-arranged admin frontend** of `djangocms-bootstrap4 - `_ +- **Nice and well-arranged admin frontend** of djangocms-bootstrap4 - **Extensible** within the project and with separate project (e.g. a theme app). Create your own components with a few lines of code only. From cb3fc7dedf061660a0c78fb9091f3a1f12d553cd Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Sun, 10 Nov 2024 21:38:25 +0100 Subject: [PATCH 57/66] Refactor components --- .coveragerc | 20 --- .djlint_rules.yaml | 7 - .github/workflows/codecov.yml | 6 +- .github/workflows/lint.yml | 25 ---- .pre-commit-config.yaml | 22 +-- CHANGELOG.rst | 8 +- README.rst | 63 ++++---- run_tests.py => conftest.py | 16 +- djangocms_frontend/apps.py | 16 +- djangocms_frontend/cms_plugins.py | 55 +++---- djangocms_frontend/common/__init__.py | 11 +- .../common/{bootstrap5 => }/attributes.py | 0 .../components.py => component_base.py} | 31 ++-- djangocms_frontend/component_pool.py | 104 ++----------- djangocms_frontend/contrib/alert/forms.py | 6 +- djangocms_frontend/contrib/badge/forms.py | 6 +- .../contrib/card/cms_plugins.py | 8 +- djangocms_frontend/contrib/card/forms.py | 21 +-- .../contrib/card/frameworks/bootstrap5.py | 4 +- .../contrib/carousel/cms_plugins.py | 12 +- djangocms_frontend/contrib/carousel/forms.py | 11 +- .../contrib/component/__init__.py | 0 .../contrib/component/cms_plugins.py | 18 --- .../contrib/component/registry.py | 25 ---- .../contrib/grid/cms_plugins.py | 8 +- djangocms_frontend/contrib/grid/forms.py | 15 +- djangocms_frontend/contrib/icon/forms.py | 6 +- djangocms_frontend/contrib/image/forms.py | 29 +--- djangocms_frontend/contrib/jumbotron/forms.py | 12 +- .../contrib/link/cms_plugins.py | 7 +- djangocms_frontend/contrib/link/forms.py | 23 ++- djangocms_frontend/contrib/listgroup/forms.py | 7 +- .../contrib/navigation/cms_plugins.py | 3 +- .../contrib/navigation/forms.py | 7 +- djangocms_frontend/contrib/tabs/forms.py | 15 +- djangocms_frontend/contrib/utilities/forms.py | 8 +- djangocms_frontend/helpers.py | 71 +++++---- .../management/bootstrap4_migration.py | 6 +- djangocms_frontend/migrations/0001_initial.py | 8 +- .../migrations/0002_migrate_links.py | 85 +++++++++++ djangocms_frontend/plugin_tag.py | 97 ++++++++++++ .../static/djangocms_frontend/css/base.css | 2 +- .../djangocms_frontend/admin/base-tabs.html | 62 ++++---- .../templates/djangocms_frontend/slot.html | 0 djangocms_frontend/templatetags/frontend.py | 2 +- djangocms_frontend/ui_plugin_base.py | 58 +++++++ docs/source/custom_components.rst | 34 ++--- docs/source/grid.rst | 8 +- docs/source/index.rst | 58 +++---- private/sass/components/_tabs.scss | 4 + pyproject.toml | 141 ++++++++++++++---- setup.cfg | 33 ---- tests/component/test_models.py | 2 +- tests/component/test_plugins.py | 14 +- tests/link/test_migration.py | 27 ++++ tests/requirements/base.txt | 2 + tests/test_app/cms_components.py | 11 +- tests/test_app/templates/button.html | 2 +- tests/test_plugin_tag.py | 4 +- tests/test_settings.py | 1 - tests/utilities/test_plugins.py | 9 +- 61 files changed, 678 insertions(+), 698 deletions(-) delete mode 100644 .coveragerc delete mode 100644 .djlint_rules.yaml delete mode 100644 .github/workflows/lint.yml rename run_tests.py => conftest.py (81%) rename djangocms_frontend/common/{bootstrap5 => }/attributes.py (100%) rename djangocms_frontend/{contrib/component/components.py => component_base.py} (89%) delete mode 100644 djangocms_frontend/contrib/component/__init__.py delete mode 100644 djangocms_frontend/contrib/component/cms_plugins.py delete mode 100644 djangocms_frontend/contrib/component/registry.py create mode 100644 djangocms_frontend/migrations/0002_migrate_links.py create mode 100644 djangocms_frontend/plugin_tag.py rename djangocms_frontend/{contrib/component => }/templates/djangocms_frontend/slot.html (100%) create mode 100644 djangocms_frontend/ui_plugin_base.py delete mode 100644 setup.cfg create mode 100644 tests/link/test_migration.py diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 50625d86..00000000 --- a/.coveragerc +++ /dev/null @@ -1,20 +0,0 @@ -[run] -branch = True -source = djangocms_frontend -omit = - djangocms_frontend/migrations/* - djangocms_frontend/management/* - */foundation6.py - tests/* - -[report] -exclude_lines = - pragma: no cover - def __repr__ - if self.debug: - if settings.DEBUG - raise AssertionError - raise NotImplementedError - if 0: - if __name__ == .__main__.: -ignore_errors = True diff --git a/.djlint_rules.yaml b/.djlint_rules.yaml deleted file mode 100644 index 5fb69a5b..00000000 --- a/.djlint_rules.yaml +++ /dev/null @@ -1,7 +0,0 @@ -- rule: - name: D034 - message: .pk or .id should only be used with "|unlocalize" - flags: re.DOTALL|re.I - patterns: - - '{{\s*[a-zA-Z0-9_.]+\.pk\s*}}' - - '{{\s*[a-zA-Z0-9_.]+\.id\s*}}' diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index e786787e..27696c2f 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -32,9 +32,11 @@ jobs: uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - - name: Generate Report + - name: Intall dependencies run: | pip install -r tests/requirements/${{ matrix.requirements-file }} - coverage run run_tests.py + - name: Run coverage + run: | + coverage run -m pytest - name: Upload Coverage to Codecov uses: codecov/codecov-action@v4 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 8fda05ed..00000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Lint - -on: [push, pull_request] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - ruff: - name: ruff - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.11" - cache: 'pip' - - run: | - python -m pip install --upgrade pip - pip install ruff - - name: Run Ruff - run: ruff check djangocms_frontend diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b0902ddf..08639421 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,28 +9,30 @@ ci: repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.17.0 + rev: v3.19.0 hooks: - id: pyupgrade - args: ["--py37-plus"] + args: ["--py39-plus"] + - repo: https://github.com/adamchainz/django-upgrade - rev: "1.21.0" + rev: "1.22.1" hooks: - id: django-upgrade - args: [--target-version, "2.2"] - - repo: https://github.com/pycqa/isort - rev: 5.13.2 - hooks: - - id: isort - name: isort (python) + args: [--target-version, "4.2"] + - repo: https://github.com/PyCQA/flake8 rev: 7.1.1 hooks: - id: flake8 additional_dependencies: + - flake8-pyproject - flake8-bugbear - flake8-builtins - flake8-django - flake8-length - flake8-logging-format - - flake8-spellcheck + + - repo: https://github.com/tox-dev/pyproject-fmt + rev: v2.5.0 + hooks: + - id: pyproject-fmt diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 14248778..01d90dcc 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -82,7 +82,7 @@ Changelog * feat: Add float option for images by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/162 * feat: Add drag'n'drop support for djangocms-text-ckeditor by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/165 * fix: Ckeditor does not show icons for editing by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/163 -* fix: Replace ``stylesSet`` setting in docs with ``customConfig` for icons in ckeditor by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/164 +* fix: Replace ``stylesSet`` setting in docs with ``customConfig`` for icons in ckeditor by @fsbraun in https://github.com/django-cms/djangocms-frontend/pull/164 * ci: pre-commit autoupdate by @pre-commit-ci in https://github.com/django-cms/djangocms-frontend/pull/161 @@ -106,15 +106,15 @@ Changelog ================== * Fix incomplete migration of code plugins from djangocms-bootstrap4 -* Add compiled French locale (*.mo) +* Add compiled French locale (\*.mo) * Add partial Dutch locale 1.1.5 (2023-07-14) ================== * Fix bug where url for link select2 field was lost after app hook reload (#135) -* Use `bg-body` class on Bootstrap 5's tab navigation to support color modes (#138) -* Fix styling of icon buttons for better usager with plain django admin style (#141) +* Use ``bg-body`` class on Bootstrap 5's tab navigation to support color modes (#138) +* Fix styling of icon buttons for better usage with plain django admin style (#141) 1.1.4 (2023-05-28) ================== diff --git a/README.rst b/README.rst index f9c383f9..42b7e33f 100644 --- a/README.rst +++ b/README.rst @@ -4,18 +4,23 @@ |pypi| |docs| |coverage| |python| |django| |djangocms| |djangocms4| -**django CMS Frontend** is a plugin bundle which builds on and improves +**django CMS Frontend** is a plugin bundle which originally built on and improved the architecture of `djangocms-bootstrap4 `_. -Its objective is to provide a set of popular frontend components independent of the -currently used frontend framework such as Bootstrap, or its specific version. +Its objective is to provide a toolset to quickly create re-usable frontend +components and comes preloaded with a set of popular frontend components +independent of the currently used frontend framework such as Bootstrap, or +its specific version. .. image:: preview.png Key features ============ +- **Easy to implement re-usable frontend custom components**, which in the + simples case consist of a template and declarative sort of form class. + - Support of `Bootstrap 5 `_, django CMS 3.8+ - and django CMS 4. + and django CMS 4 out of the box. - **Separation of plugins from css framework**, i.e. no need to rebuild you site's plugin tree if css framework is changed in the @@ -25,8 +30,7 @@ Key features provided by other applications, such as `djangocms-blog `_. -- **Nice and well-arranged admin frontend** of `djangocms-bootstrap4 - `_ +- **Nice and well-arranged admin frontend** of djangocms-bootstrap4 - **Extensible** within the project and with separate project (e.g. a theme app). Create your own components with a few lines of code only. @@ -35,10 +39,6 @@ Key features (e.g. in a custom app) giving your whole project a more consistent user experience. -- A management command to **migrate from djangocms-bootstrap4**. This - command automatically migrates all ``djangocms-bootstrap4`` plugins to - ``djangocms-frontend``. - Description =========== @@ -55,10 +55,6 @@ Instead all design parameters are stored in a common JSON field and future releases of improved frontend features will not require to rebuild your full plugin tree. -The link plugin has been rewritten to not only allow internal links to other -CMS pages, but also to other django models such as, e.g., posts of -`djangocms-blog `_. - The plugins are designed to be re-usable as UI components in your project, e.g. in a custom app, giving your whole project a more consistent user experience. @@ -98,8 +94,7 @@ file for additional dependencies: - django-cms, version 3.7 or later - django-filer, version 1.7 or later - djangocms-attributes-field, version 1.0 or later -- djangocms-text-ckeditor, version 3.1 or later -- django-select2 +- djangocms-text - django-entangled Make sure `django Filer @@ -121,23 +116,22 @@ For a manual install: 'easy_thumbnails', 'djangocms_frontend', - 'djangocms_frontend.contrib.accordion', - 'djangocms_frontend.contrib.alert', - 'djangocms_frontend.contrib.badge', - 'djangocms_frontend.contrib.card', - 'djangocms_frontend.contrib.carousel', - 'djangocms_frontend.contrib.collapse', - 'djangocms_frontend.contrib.component', - 'djangocms_frontend.contrib.content', - 'djangocms_frontend.contrib.grid', - 'djangocms_frontend.contrib.icon', - 'djangocms_frontend.contrib.image', - 'djangocms_frontend.contrib.jumbotron', - 'djangocms_frontend.contrib.link', - 'djangocms_frontend.contrib.listgroup', - 'djangocms_frontend.contrib.media', - 'djangocms_frontend.contrib.tabs', - 'djangocms_frontend.contrib.utilities', + 'djangocms_frontend.contrib.accordion', # optional + 'djangocms_frontend.contrib.alert', # optional + 'djangocms_frontend.contrib.badge', # optional + 'djangocms_frontend.contrib.card', # optional + 'djangocms_frontend.contrib.carousel', # optional + 'djangocms_frontend.contrib.collapse', # optional + 'djangocms_frontend.contrib.content', # optional + 'djangocms_frontend.contrib.grid', # optional + 'djangocms_frontend.contrib.icon', # optional + 'djangocms_frontend.contrib.image', # optional + 'djangocms_frontend.contrib.jumbotron', # optional + 'djangocms_frontend.contrib.link', # optional + 'djangocms_frontend.contrib.listgroup', # optional + 'djangocms_frontend.contrib.media', # optional + 'djangocms_frontend.contrib.tabs', # optional + 'djangocms_frontend.contrib.utilities', # optional - run ``python manage.py migrate`` @@ -153,8 +147,7 @@ install separately or by adding an option: Documentation ============= -See readthedocs for the `documentation -`_. +See readthedocs for the `documentation `_. License ======= diff --git a/run_tests.py b/conftest.py similarity index 81% rename from run_tests.py rename to conftest.py index cbc597a3..c33bbf4a 100755 --- a/run_tests.py +++ b/conftest.py @@ -7,17 +7,17 @@ from django.test.utils import get_runner -def run(argv=None): - if argv is None: - argv = ["tests"] - tests = argv[1:] if len(argv) > 1 else ["tests"] +def pytest_configure(): os.environ["DJANGO_SETTINGS_MODULE"] = "tests.test_settings" django.setup() + + +if __name__ == "__main__": + pytest_configure() + + argv = ["tests"] if sys.argv is None else sys.argv + tests = argv[1:] if len(argv) > 1 else ["tests"] TestRunner = get_runner(settings) test_runner = TestRunner() failures = test_runner.run_tests(tests) sys.exit(bool(failures)) - - -if __name__ == "__main__": - run(sys.argv) diff --git a/djangocms_frontend/apps.py b/djangocms_frontend/apps.py index 7c1195d7..b17215bf 100644 --- a/djangocms_frontend/apps.py +++ b/djangocms_frontend/apps.py @@ -1,5 +1,5 @@ from django import apps -from django.core.checks import Warning, register +from django.core import checks class DjangocmsFrontendConfig(apps.AppConfig): @@ -7,10 +7,10 @@ class DjangocmsFrontendConfig(apps.AppConfig): verbose_name = "django CMS Frontend" def ready(self): - from .component_pool import setup + from . import plugin_tag - register(check_settings) - setup() + checks.register(check_settings) + plugin_tag.setup() def check_settings(*args, **kwargs): @@ -18,8 +18,8 @@ def check_settings(*args, **kwargs): warnings = [] - if hasattr(settings, "DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH"): - warnings.append(Warning( + if hasattr(settings, "DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH"): # pragma: no cover + warnings.append(checks.Warning( "The DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH setting was removed in djangocms-frontend 2.\n" "Use DJANGOCMS_LINK_MINIMUM_INPUT_LENGTH instead.", "This message disappears after removing the DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH from your project's " @@ -27,8 +27,8 @@ def check_settings(*args, **kwargs): id="djangocms_frontend.W001", obj="settings.DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH", )) - if hasattr(settings, "DJANGOCMS_FRONTEND_LINK_MODELS"): - warnings.append(Warning( + if hasattr(settings, "DJANGOCMS_FRONTEND_LINK_MODELS"): # pragma: no cover + warnings.append(checks.Warning( "The DJANGOCMS_FRONTEND_LINK_MODELS setting was removed in djangocms-frontend 2.\n" "djangocms-frontend 2 uses linkable models from djangocms-link. See " "https://github.com/django-cms/djangocms-link#django-cms-link for more info.", diff --git a/djangocms_frontend/cms_plugins.py b/djangocms_frontend/cms_plugins.py index d4610163..d36657c7 100644 --- a/djangocms_frontend/cms_plugins.py +++ b/djangocms_frontend/cms_plugins.py @@ -1,44 +1,23 @@ -from cms.constants import SLUG_REGEXP -from cms.plugin_base import CMSPluginBase -from django.utils.encoding import force_str +from cms.plugin_pool import plugin_pool -from djangocms_frontend.helpers import get_related +from .component_pool import components +from .ui_plugin_base import CMSUIPluginBase -if hasattr(CMSPluginBase, "edit_field"): - # FrontendEditable functionality already implemented in core? - FrontendEditableAdminMixin = object -else: - # If not use our own version of the plugin-enabled mixin - from .helpers import FrontendEditableAdminMixin +class CMSUIPlugin(CMSUIPluginBase): + pass -class CMSUIPlugin(FrontendEditableAdminMixin, CMSPluginBase): - render_template = "djangocms_frontend/html_container.html" - change_form_template = "djangocms_frontend/admin/base.html" - def __str__(self): - return force_str(super().__str__()) +# Loop through the values in the components' registry +for _, plugin, slot_plugins in components._registry.values(): + # Add the plugin to the global namespace + globals()[plugin.__name__] = plugin + # Register the plugin with the plugin pool + plugin_pool.register_plugin(plugin) - def render(self, context, instance, placeholder): - for key, value in instance.config.items(): - if isinstance(value, dict) and set(value.keys()) == {"pk", "model"}: - if key not in instance.__dir__(): # hasattr would return the value in the config dict - setattr(instance.__class__, key, get_related(key)) - return super().render(context, instance, placeholder) - - def get_plugin_urls(self): - from django.urls import re_path - - info = f"{self.model._meta.app_label}_{self.model._meta.model_name}" - - def pat(regex, fn): - return re_path(regex, fn, name=f"{info}_{fn.__name__}") - - return [ - pat(r'edit-field/(%s)/([a-z\-]+)/$' % SLUG_REGEXP, self.edit_field), - ] - - def _get_object_for_single_field(self, object_id, language): - from .models import FrontendUIItem - - return FrontendUIItem.objects.get(pk=object_id) + # Loop through the slot plugins associated with the current plugin + for slot_plugin in slot_plugins: + # Add the slot plugin to the global namespace + globals()[slot_plugin.__name__] = slot_plugin + # Register the slot plugin with the plugin pool + plugin_pool.register_plugin(slot_plugin) diff --git a/djangocms_frontend/common/__init__.py b/djangocms_frontend/common/__init__.py index 0957b32d..d020d162 100644 --- a/djangocms_frontend/common/__init__.py +++ b/djangocms_frontend/common/__init__.py @@ -2,14 +2,21 @@ from djangocms_frontend import settings +from .attributes import AttributesMixin from .title import TitleFormMixin, TitleMixin __common = { - "attributes": ("AttributesMixin",), "background": ("BackgroundFormMixin", "BackgroundMixin"), "responsive": ("ResponsiveFormMixin", "ResponsiveMixin"), "sizing": ("SizingFormMixin", "SizingMixin"), - "spacing": ("SpacingFormMixin", "SpacingMixin", "MarginFormMixin", "MarginMixin", "PaddingFormMixin", "PaddingMixin"), + "spacing": ( + "SpacingFormMixin", + "SpacingMixin", + "MarginFormMixin", + "MarginMixin", + "PaddingFormMixin", + "PaddingMixin", + ), } for module, classes in __common.items(): diff --git a/djangocms_frontend/common/bootstrap5/attributes.py b/djangocms_frontend/common/attributes.py similarity index 100% rename from djangocms_frontend/common/bootstrap5/attributes.py rename to djangocms_frontend/common/attributes.py diff --git a/djangocms_frontend/contrib/component/components.py b/djangocms_frontend/component_base.py similarity index 89% rename from djangocms_frontend/contrib/component/components.py rename to djangocms_frontend/component_base.py index f8d4d603..3659fb0f 100644 --- a/djangocms_frontend/contrib/component/components.py +++ b/djangocms_frontend/component_base.py @@ -9,6 +9,8 @@ from django.utils.translation import gettext_lazy as _ from entangled.forms import EntangledModelForm +from .ui_plugin_base import CMSUIPluginBase + def _get_mixin_classes(mixins: list, suffix: str = "") -> list[type]: """Find and import mixin classes from a list of mixin strings""" @@ -112,8 +114,6 @@ def plugin_model_factory(cls) -> type: @classmethod def plugin_factory(cls) -> type: if cls._plugin is None: - from djangocms_frontend.cms_plugins import CMSUIPlugin - mixins = getattr(cls._component_meta, "mixins", []) slots = cls.get_slot_plugins() mixins = _get_mixin_classes(mixins) @@ -123,16 +123,18 @@ def plugin_factory(cls) -> type: ( *mixins, *cls._plugin_mixins, - CMSUIPlugin, + CMSUIPluginBase, ), { "name": getattr(cls._component_meta, "name", cls.__name__), - "module": getattr(cls._component_meta, "module", _("Component")), + "module": getattr(cls._component_meta, "module", _("Components")), "model": cls.plugin_model_factory(), "form": cls.admin_form_factory(), "allow_children": getattr(cls._component_meta, "allow_children", False) or slots, + "require_parent": getattr(cls._component_meta, "require_parent", False), "child_classes": getattr(cls._component_meta, "child_classes", []) + list(slots.keys()), - "render_template": getattr(cls._component_meta, "render_template", CMSUIPlugin.render_template), + "parent_classes": getattr(cls._component_meta, "parent_classes", []), + "render_template": getattr(cls._component_meta, "render_template", CMSUIPluginBase.render_template), "fieldsets": getattr(cls, "fieldsets", cls._generate_fieldset()), "change_form_template": "djangocms_frontend/admin/base.html", "slots": slots, @@ -182,9 +184,7 @@ def get_registration(cls) -> tuple[type, type, list[type]]: @classmethod @property def _component_meta(cls) -> typing.Optional[type]: - if hasattr(cls, "Meta"): - return cls.Meta - return None + return getattr(cls, "Meta", None) @classmethod def _generate_fieldset(cls) -> list[tuple[typing.Optional[str], dict]]: @@ -194,20 +194,9 @@ def get_short_description(self) -> str: return self.config.get("title", "") def save_model(self, request, obj, form: forms.Form, change: bool) -> None: - """Auto-createas slot plugins upon creation of component plugin instance""" - from djangocms_frontend.cms_plugins import CMSUIPlugin + """Auto-creates slot plugins upon creation of component plugin instance""" - super(CMSUIPlugin, self).save_model(request, obj, form, change) + super(CMSUIPluginBase, self).save_model(request, obj, form, change) if not change: for slot in self.slots.keys(): add_plugin(obj.placeholder, slot, obj.language, target=obj) - - -class ComponentLinkMixin: - from djangocms_frontend.contrib.link.cms_plugins import LinkPluginMixin - from djangocms_frontend.contrib.link.forms import AbstractLinkForm - from djangocms_frontend.contrib.link.helpers import GetLinkMixin - - _base_form = AbstractLinkForm - _model_mixins = [GetLinkMixin] - _plugin_mixins = [LinkPluginMixin] diff --git a/djangocms_frontend/component_pool.py b/djangocms_frontend/component_pool.py index c1024d32..95c8fb8d 100644 --- a/djangocms_frontend/component_pool.py +++ b/djangocms_frontend/component_pool.py @@ -1,97 +1,25 @@ -import copy -import importlib import warnings -from cms.plugin_pool import plugin_pool -from cms.templatetags.cms_tags import render_plugin -from django.conf import settings -from django.contrib.admin.sites import site as admin_site -from django.template import engines -from django.template.library import SimpleNode -from django.template.loader import get_template +from django.utils.module_loading import autodiscover_modules -django_engine = engines["django"] -plugin_tag_pool = {} +class Components: + _registry: dict = {} + _discovered: bool = False + def register(self, component): + if component.__name__ in self._registry: + warnings.warn(f"Component {component.__name__} already registered", stacklevel=2) + return component + self._registry[component.__name__] = component.get_registration() + return component -IGNORED_FIELDS = ( - "id", - "cmsplugin_ptr", - "language", - "plugin_type", - "position", - "creation_date", - "ui_item", -) + def __getitem__(self, item): + return self._registry[item] -allowed_plugin_types = tuple( - getattr(importlib.import_module(cls.rsplit(".", 1)[0]), cls.rsplit(".", 1)[-1]) if isinstance(cls, str) else cls - for cls in getattr(settings, "CMS_COMPONENT_PLUGINS", []) -) +components = Components() -def _get_plugindefaults(instance): - defaults = { - field.name: getattr(instance, field.name) - for field in instance._meta.fields - if field.name not in IGNORED_FIELDS and bool(getattr(instance, field.name)) - } - defaults["plugin_type"] = instance.__class__.__name__ - return defaults - - -class _DummyUser: - is_superuser = True - is_staff = True - - -class _DummyRequest: - user = _DummyUser() - - -def render_dummy_plugin(context, dummy_plugin): - return dummy_plugin.nodelist.render(context) - - -def patch_template(template): - """Patches the template to use the dummy plugin renderer instead of the real one.""" - copied_template = copy.deepcopy(template) - patch = False - for node in copied_template.template.nodelist.get_nodes_by_type(SimpleNode): - if node.func == render_plugin: - patch = True - node.func = render_dummy_plugin - return copied_template if patch else template - - -def setup(): - global plugin_tag_pool - - for plugin in plugin_pool.get_all_plugins(): - if not issubclass(plugin, allowed_plugin_types): - continue - tag_name = plugin.__name__.lower() - if tag_name.endswith("plugin"): - tag_name = tag_name[:-6] - try: - instance = plugin.model() # Create instance with defaults - plugin_admin = plugin(admin_site=admin_site) - if hasattr(instance, "initialize_from_form"): - instance.initialize_from_form(plugin.form) - if tag_name not in plugin_tag_pool: - template = get_template(plugin_admin._get_render_template({"request": None}, instance, None)) - plugin_tag_pool[tag_name] = { - "defaults": { - **_get_plugindefaults(instance), - **dict(plugin_type=plugin.__name__), - }, - "template": patch_template(template), - "class": plugin, - } - else: # pragma: no cover - warnings.warn( - f"Duplicate candidates for {{% plugin \"{tag_name}\" %}} found. " - f"Only registered {plugin_tag_pool[tag_name]['class'].__name__}.", stacklevel=1) - except Exception as exc: # pragma: no cover - warnings.warn(f"{plugin.__name__}: \n{str(exc)}", stacklevel=1) +if not components._discovered: + autodiscover_modules("cms_components", register_to=components) + components._discovered = True diff --git a/djangocms_frontend/contrib/alert/forms.py b/djangocms_frontend/contrib/alert/forms.py index 65ad4698..4885f2de 100644 --- a/djangocms_frontend/contrib/alert/forms.py +++ b/djangocms_frontend/contrib/alert/forms.py @@ -5,11 +5,7 @@ from djangocms_frontend import settings from djangocms_frontend.common import ResponsiveFormMixin, SpacingFormMixin from djangocms_frontend.contrib import alert -from djangocms_frontend.fields import ( - AttributesFormField, - ColoredButtonGroup, - TagTypeFormField, -) +from djangocms_frontend.fields import AttributesFormField, ColoredButtonGroup, TagTypeFormField from djangocms_frontend.helpers import first_choice from djangocms_frontend.models import FrontendUIItem from djangocms_frontend.settings import COLOR_STYLE_CHOICES diff --git a/djangocms_frontend/contrib/badge/forms.py b/djangocms_frontend/contrib/badge/forms.py index f71a6b45..37fa55e6 100644 --- a/djangocms_frontend/contrib/badge/forms.py +++ b/djangocms_frontend/contrib/badge/forms.py @@ -2,11 +2,7 @@ from django.utils.translation import gettext_lazy as _ from entangled.forms import EntangledModelForm -from djangocms_frontend.fields import ( - AttributesFormField, - ColoredButtonGroup, - TagTypeFormField, -) +from djangocms_frontend.fields import AttributesFormField, ColoredButtonGroup, TagTypeFormField from djangocms_frontend.helpers import first_choice from djangocms_frontend.models import FrontendUIItem from djangocms_frontend.settings import COLOR_STYLE_CHOICES diff --git a/djangocms_frontend/contrib/card/cms_plugins.py b/djangocms_frontend/contrib/card/cms_plugins.py index e686efe7..38d7354a 100644 --- a/djangocms_frontend/contrib/card/cms_plugins.py +++ b/djangocms_frontend/contrib/card/cms_plugins.py @@ -3,13 +3,7 @@ from ... import settings from ...cms_plugins import CMSUIPlugin -from ...common import ( - AttributesMixin, - BackgroundMixin, - MarginMixin, - PaddingMixin, - ResponsiveMixin, -) +from ...common import AttributesMixin, BackgroundMixin, MarginMixin, PaddingMixin, ResponsiveMixin from ...helpers import add_plugin from .. import card from . import forms, models diff --git a/djangocms_frontend/contrib/card/forms.py b/djangocms_frontend/contrib/card/forms.py index d56c6a98..0bceb364 100644 --- a/djangocms_frontend/contrib/card/forms.py +++ b/djangocms_frontend/contrib/card/forms.py @@ -7,28 +7,13 @@ from djangocms_frontend.settings import COLOR_STYLE_CHOICES, DEVICE_SIZES from ... import settings -from ...common import ( - BackgroundFormMixin, - MarginFormMixin, - PaddingFormMixin, - ResponsiveFormMixin, -) -from ...fields import ( - AttributesFormField, - ButtonGroup, - ColoredButtonGroup, - IconGroup, - TagTypeFormField, -) +from ...common import BackgroundFormMixin, MarginFormMixin, PaddingFormMixin, ResponsiveFormMixin +from ...fields import AttributesFormField, ButtonGroup, ColoredButtonGroup, IconGroup, TagTypeFormField from ...helpers import first_choice, link_to_framework_doc from ...models import FrontendUIItem from .. import card from ..grid.constants import GRID_SIZE -from .constants import ( - CARD_ALIGNMENT_CHOICES, - CARD_INNER_TYPE_CHOICES, - CARD_LAYOUT_TYPE_CHOICES, -) +from .constants import CARD_ALIGNMENT_CHOICES, CARD_INNER_TYPE_CHOICES, CARD_LAYOUT_TYPE_CHOICES # card allow for a transparent color CARD_COLOR_STYLE_CHOICES = settings.COLOR_STYLE_CHOICES + (("transparent", _("Transparent")),) diff --git a/djangocms_frontend/contrib/card/frameworks/bootstrap5.py b/djangocms_frontend/contrib/card/frameworks/bootstrap5.py index 1e7499e0..2674e5a7 100644 --- a/djangocms_frontend/contrib/card/frameworks/bootstrap5.py +++ b/djangocms_frontend/contrib/card/frameworks/bootstrap5.py @@ -1,6 +1,4 @@ -from djangocms_frontend.contrib.grid.frameworks.bootstrap5 import ( - get_row_cols_grid_values, -) +from djangocms_frontend.contrib.grid.frameworks.bootstrap5 import get_row_cols_grid_values class CardRenderMixin: diff --git a/djangocms_frontend/contrib/carousel/cms_plugins.py b/djangocms_frontend/contrib/carousel/cms_plugins.py index 421db65d..f004234d 100644 --- a/djangocms_frontend/contrib/carousel/cms_plugins.py +++ b/djangocms_frontend/contrib/carousel/cms_plugins.py @@ -81,18 +81,8 @@ class CarouselSlidePlugin( ) }, ), - ( - _("Link settings"), - { - "classes": ("collapse",), - "fields": ( - ("external_link", "internal_link"), - ("mailto", "phone"), - ("anchor", "target"), - ), - }, - ), ] + link_fieldset_position = 1 def get_render_template(self, context, instance, placeholder): return get_plugin_template( diff --git a/djangocms_frontend/contrib/carousel/forms.py b/djangocms_frontend/contrib/carousel/forms.py index ec2a09e3..ac599722 100644 --- a/djangocms_frontend/contrib/carousel/forms.py +++ b/djangocms_frontend/contrib/carousel/forms.py @@ -5,12 +5,7 @@ from filer.fields.image import AdminImageFormField, FilerImageField from filer.models import Image -from djangocms_frontend.fields import ( - AttributesFormField, - ButtonGroup, - TagTypeFormField, - TemplateChoiceMixin, -) +from djangocms_frontend.fields import AttributesFormField, ButtonGroup, TagTypeFormField, TemplateChoiceMixin from ... import settings from ...common import BackgroundFormMixin @@ -18,7 +13,7 @@ from ...helpers import first_choice from ...models import FrontendUIItem from .. import carousel -from ..link.forms import AbstractLinkForm +from ..link.forms import LinkFormMixin from .constants import ( CAROUSEL_ASPECT_RATIO_CHOICES, CAROUSEL_PAUSE_CHOICES, @@ -143,8 +138,8 @@ class Meta: class CarouselSlideForm( mixin_factory("CarouselSlide"), - AbstractLinkForm, BackgroundFormMixin, + LinkFormMixin, EntangledModelForm, ): """ diff --git a/djangocms_frontend/contrib/component/__init__.py b/djangocms_frontend/contrib/component/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/djangocms_frontend/contrib/component/cms_plugins.py b/djangocms_frontend/contrib/component/cms_plugins.py deleted file mode 100644 index 896bcab0..00000000 --- a/djangocms_frontend/contrib/component/cms_plugins.py +++ /dev/null @@ -1,18 +0,0 @@ -from cms.plugin_pool import plugin_pool - -# Import the components from the current directory's models module -from .registry import components - -# Loop through the values in the components' registry -for _, plugin, slot_plugins in components._registry.values(): - # Add the plugin to the global namespace - globals()[plugin.__name__] = plugin - # Register the plugin with the plugin pool - plugin_pool.register_plugin(plugin) - - # Loop through the slot plugins associated with the current plugin - for slot_plugin in slot_plugins: - # Add the slot plugin to the global namespace - globals()[slot_plugin.__name__] = slot_plugin - # Register the slot plugin with the plugin pool - plugin_pool.register_plugin(slot_plugin) diff --git a/djangocms_frontend/contrib/component/registry.py b/djangocms_frontend/contrib/component/registry.py deleted file mode 100644 index 95c8fb8d..00000000 --- a/djangocms_frontend/contrib/component/registry.py +++ /dev/null @@ -1,25 +0,0 @@ -import warnings - -from django.utils.module_loading import autodiscover_modules - - -class Components: - _registry: dict = {} - _discovered: bool = False - - def register(self, component): - if component.__name__ in self._registry: - warnings.warn(f"Component {component.__name__} already registered", stacklevel=2) - return component - self._registry[component.__name__] = component.get_registration() - return component - - def __getitem__(self, item): - return self._registry[item] - - -components = Components() - -if not components._discovered: - autodiscover_modules("cms_components", register_to=components) - components._discovered = True diff --git a/djangocms_frontend/contrib/grid/cms_plugins.py b/djangocms_frontend/contrib/grid/cms_plugins.py index 26c01f8a..32b9963d 100644 --- a/djangocms_frontend/contrib/grid/cms_plugins.py +++ b/djangocms_frontend/contrib/grid/cms_plugins.py @@ -2,13 +2,7 @@ from django.utils.translation import gettext_lazy as _ from djangocms_frontend import settings -from djangocms_frontend.common import ( - AttributesMixin, - BackgroundMixin, - ResponsiveMixin, - SizingMixin, - SpacingMixin, -) +from djangocms_frontend.common import AttributesMixin, BackgroundMixin, ResponsiveMixin, SizingMixin, SpacingMixin from ...cms_plugins import CMSUIPlugin from ...common import TitleMixin diff --git a/djangocms_frontend/contrib/grid/forms.py b/djangocms_frontend/contrib/grid/forms.py index 5772fbdd..5af376b1 100644 --- a/djangocms_frontend/contrib/grid/forms.py +++ b/djangocms_frontend/contrib/grid/forms.py @@ -6,19 +6,8 @@ from entangled.forms import EntangledModelForm from djangocms_frontend import settings -from djangocms_frontend.common import ( - BackgroundFormMixin, - ResponsiveFormMixin, - SizingFormMixin, - SpacingFormMixin, -) -from djangocms_frontend.fields import ( - AttributesFormField, - AutoNumberInput, - ButtonGroup, - IconGroup, - TagTypeFormField, -) +from djangocms_frontend.common import BackgroundFormMixin, ResponsiveFormMixin, SizingFormMixin, SpacingFormMixin +from djangocms_frontend.fields import AttributesFormField, AutoNumberInput, ButtonGroup, IconGroup, TagTypeFormField from djangocms_frontend.helpers import first_choice, link_to_framework_doc from djangocms_frontend.models import FrontendUIItem diff --git a/djangocms_frontend/contrib/icon/forms.py b/djangocms_frontend/contrib/icon/forms.py index 526b3f6c..7e09ef81 100644 --- a/djangocms_frontend/contrib/icon/forms.py +++ b/djangocms_frontend/contrib/icon/forms.py @@ -2,11 +2,7 @@ from django.utils.translation import gettext_lazy as _ from entangled.forms import EntangledModelForm -from djangocms_frontend.fields import ( - AttributesFormField, - ColoredButtonGroup, - TagTypeFormField, -) +from djangocms_frontend.fields import AttributesFormField, ColoredButtonGroup, TagTypeFormField from ... import settings from ...common import BackgroundFormMixin, ResponsiveFormMixin, SpacingFormMixin diff --git a/djangocms_frontend/contrib/image/forms.py b/djangocms_frontend/contrib/image/forms.py index 0a1043e1..09786199 100644 --- a/djangocms_frontend/contrib/image/forms.py +++ b/djangocms_frontend/contrib/image/forms.py @@ -2,7 +2,6 @@ from django.conf import settings as django_settings from django.db.models.fields.related import ManyToOneRel from django.utils.translation import gettext_lazy as _ -from entangled.forms import EntangledModelForm from filer.fields.image import AdminImageFormField, FilerImageField from filer.models import Image, ThumbnailOption @@ -45,13 +44,6 @@ def get_templates(): PICTURE_ALIGNMENT = get_alignment() -LINK_TARGET = ( - ("_blank", _("Open in new window")), - ("_self", _("Open in same window")), - ("_parent", _("Delegate to parent")), - ("_top", _("Delegate to top")), -) - RESPONSIVE_IMAGE_CHOICES = ( ("inherit", _("Let settings.DJANGOCMS_PICTURE_RESPONSIVE_IMAGES decide")), ("yes", _("Yes")), @@ -61,10 +53,9 @@ def get_templates(): class ImageForm( TemplateChoiceMixin, - AbstractLinkForm, ResponsiveFormMixin, MarginFormMixin, - EntangledModelForm, + AbstractLinkForm, ): """ Content > "Image" Plugin @@ -217,24 +208,6 @@ class Meta: def clean(self): super().clean() data = self.cleaned_data - # there can be only one link type - if ( - sum( - ( - bool(data.get("external_link", False)), - bool(data.get("internal_link", False)), - bool(data.get("file_link", False)), - ) - ) - > 1 - ): - raise forms.ValidationError( - _( - "You have given more than one external, internal, or file link target. " - "Only one option is allowed." - ) - ) - # you shall only set one image kind if not data.get("picture", False) and not data.get("external_picture", False): raise forms.ValidationError( diff --git a/djangocms_frontend/contrib/jumbotron/forms.py b/djangocms_frontend/contrib/jumbotron/forms.py index 0eb2943a..bba2c1a1 100644 --- a/djangocms_frontend/contrib/jumbotron/forms.py +++ b/djangocms_frontend/contrib/jumbotron/forms.py @@ -3,18 +3,10 @@ from entangled.forms import EntangledModelForm from djangocms_frontend import settings -from djangocms_frontend.common import ( - BackgroundFormMixin, - ResponsiveFormMixin, - SpacingFormMixin, -) +from djangocms_frontend.common import BackgroundFormMixin, ResponsiveFormMixin, SpacingFormMixin from djangocms_frontend.contrib import jumbotron from djangocms_frontend.contrib.jumbotron import models -from djangocms_frontend.fields import ( - AttributesFormField, - TagTypeFormField, - TemplateChoiceMixin, -) +from djangocms_frontend.fields import AttributesFormField, TagTypeFormField, TemplateChoiceMixin from djangocms_frontend.helpers import first_choice mixin_factory = settings.get_forms(jumbotron) diff --git a/djangocms_frontend/contrib/link/cms_plugins.py b/djangocms_frontend/contrib/link/cms_plugins.py index b4950755..dea1f3e1 100644 --- a/djangocms_frontend/contrib/link/cms_plugins.py +++ b/djangocms_frontend/contrib/link/cms_plugins.py @@ -40,12 +40,7 @@ class LinkPluginMixin: link_fields = ( (("site", "url_grouper"),) if apps.is_installed("djangocms_url_manager") - else ( - ("external_link", "internal_link"), - ("mailto", "phone"), - ("anchor", "target"), - "file_link", - ) + else ("link", "target") ) def render(self, context, instance, placeholder): diff --git a/djangocms_frontend/contrib/link/forms.py b/djangocms_frontend/contrib/link/forms.py index aa2b7c9e..7918a0c5 100644 --- a/djangocms_frontend/contrib/link/forms.py +++ b/djangocms_frontend/contrib/link/forms.py @@ -5,17 +5,11 @@ from djangocms_link.fields import LinkFormField # from djangocms_link.validators import IntranetURLValidator -from entangled.forms import EntangledModelForm +from entangled.forms import EntangledModelForm, EntangledModelFormMixin from ... import settings from ...common import SpacingFormMixin -from ...fields import ( - AttributesFormField, - ButtonGroup, - ColoredButtonGroup, - TagTypeFormField, - TemplateChoiceMixin, -) +from ...fields import AttributesFormField, ButtonGroup, ColoredButtonGroup, TagTypeFormField, TemplateChoiceMixin from ...helpers import first_choice from ...models import FrontendUIItem from .. import link @@ -40,13 +34,10 @@ def __init__(self, *args, **kwargs): if apps.apps.is_installed("djangocms_url_manager"): - from djangocms_url_manager.forms import ( - HtmlLinkSiteSelectWidget, - HtmlLinkUrlSelectWidget, - ) + from djangocms_url_manager.forms import HtmlLinkSiteSelectWidget, HtmlLinkUrlSelectWidget from djangocms_url_manager.models import UrlGrouper - class AbstractLinkForm(EntangledModelForm): + class LinkFormMixin(EntangledModelFormMixin): class Meta: entangled_fields = { "config": [ @@ -70,7 +61,7 @@ class Meta: else: - class AbstractLinkForm(EntangledModelForm): + class LinkFormMixin(EntangledModelFormMixin): class Meta: entangled_fields = { "config": [ @@ -97,6 +88,10 @@ def __init__(self, *args, **kwargs): self.fields["link"].required = not self.link_is_optional +class AbstractLinkForm(LinkFormMixin, EntangledModelForm): + pass + + class LinkForm(mixin_factory("Link"), SpacingFormMixin, TemplateChoiceMixin, AbstractLinkForm): class Meta: model = FrontendUIItem diff --git a/djangocms_frontend/contrib/listgroup/forms.py b/djangocms_frontend/contrib/listgroup/forms.py index cb97cd24..cecf785d 100644 --- a/djangocms_frontend/contrib/listgroup/forms.py +++ b/djangocms_frontend/contrib/listgroup/forms.py @@ -5,12 +5,7 @@ from djangocms_frontend import settings from ...common import MarginFormMixin, PaddingFormMixin, ResponsiveFormMixin -from ...fields import ( - AttributesFormField, - ButtonGroup, - ColoredButtonGroup, - TagTypeFormField, -) +from ...fields import AttributesFormField, ButtonGroup, ColoredButtonGroup, TagTypeFormField from ...models import FrontendUIItem from .constants import LISTGROUP_STATE_CHOICES diff --git a/djangocms_frontend/contrib/navigation/cms_plugins.py b/djangocms_frontend/contrib/navigation/cms_plugins.py index fb98a07b..784e5f6d 100644 --- a/djangocms_frontend/contrib/navigation/cms_plugins.py +++ b/djangocms_frontend/contrib/navigation/cms_plugins.py @@ -176,7 +176,8 @@ class NavLinkPlugin( - `module` (str): The module where the plugin belongs, displayed in the plugin list when editing a page. - `model` (Model): The Django model used to store the plugin's data. - `form` (Form): The form used to render the plugin's settings in the admin interface. - - `change_form_template` (str): The path to the template used to render the plugin's change form in the admin interface. + - `change_form_template` (str): The path to the template used to render the plugin's change form in the admin + interface. - `allow_children` (bool): Whether the plugin allows having child plugins. - `parent_classes` (list): List of parent plugin classes that this plugin can be nested within. - `child_classes` (list): List of child plugin classes that can be nested within this plugin. diff --git a/djangocms_frontend/contrib/navigation/forms.py b/djangocms_frontend/contrib/navigation/forms.py index 67459dd3..2ebf6f64 100644 --- a/djangocms_frontend/contrib/navigation/forms.py +++ b/djangocms_frontend/contrib/navigation/forms.py @@ -6,12 +6,7 @@ from djangocms_frontend.common import BackgroundFormMixin from djangocms_frontend.contrib import navigation from djangocms_frontend.contrib.link.forms import AbstractLinkForm, LinkForm -from djangocms_frontend.fields import ( - AttributesFormField, - ButtonGroup, - IconGroup, - TemplateChoiceMixin, -) +from djangocms_frontend.fields import AttributesFormField, ButtonGroup, IconGroup, TemplateChoiceMixin from djangocms_frontend.helpers import first_choice from djangocms_frontend.models import FrontendUIItem from djangocms_frontend.settings import NAVBAR_DESIGNS diff --git a/djangocms_frontend/contrib/tabs/forms.py b/djangocms_frontend/contrib/tabs/forms.py index 29dd825b..5aaaefc3 100644 --- a/djangocms_frontend/contrib/tabs/forms.py +++ b/djangocms_frontend/contrib/tabs/forms.py @@ -4,21 +4,10 @@ from ... import settings from ...common import PaddingFormMixin -from ...fields import ( - AttributesFormField, - ButtonGroup, - IconGroup, - TagTypeFormField, - TemplateChoiceMixin, -) +from ...fields import AttributesFormField, ButtonGroup, IconGroup, TagTypeFormField, TemplateChoiceMixin from ...helpers import first_choice from ...models import FrontendUIItem -from .constants import ( - TAB_ALIGNMENT_CHOICES, - TAB_EFFECT_CHOICES, - TAB_TEMPLATE_CHOICES, - TAB_TYPE_CHOICES, -) +from .constants import TAB_ALIGNMENT_CHOICES, TAB_EFFECT_CHOICES, TAB_TEMPLATE_CHOICES, TAB_TYPE_CHOICES class TabForm(TemplateChoiceMixin, EntangledModelForm): diff --git a/djangocms_frontend/contrib/utilities/forms.py b/djangocms_frontend/contrib/utilities/forms.py index 549cb2b4..8d7f2e0e 100644 --- a/djangocms_frontend/contrib/utilities/forms.py +++ b/djangocms_frontend/contrib/utilities/forms.py @@ -5,13 +5,7 @@ from ... import settings from ...common import SpacingFormMixin -from ...fields import ( - AttributesFormField, - ButtonGroup, - ColoredButtonGroup, - IconGroup, - TagTypeFormField, -) +from ...fields import AttributesFormField, ButtonGroup, ColoredButtonGroup, IconGroup, TagTypeFormField from ...helpers import first_choice from ...models import FrontendUIItem from .. import utilities diff --git a/djangocms_frontend/helpers.py b/djangocms_frontend/helpers.py index dd007707..2fc07d11 100644 --- a/djangocms_frontend/helpers.py +++ b/djangocms_frontend/helpers.py @@ -33,6 +33,7 @@ def get_related_object(scope, field_name): class get_related: """Descriptor lazily getting related objects from the config dict.""" + def __init__(self, key): self.key = key @@ -74,12 +75,12 @@ def insert_fields(fieldsets, new_fields, block=None, position=-1, blockname=None modify[1]["fields"] = ( list(fields[: position + 1] if position != -1 else fields) + list(new_fields) - + list(fields[position + 1 :] if position != -1 else []) + + list(fields[position + 1:] if position != -1 else []) ) fs = ( list(fieldsets[:block] if block != -1 else fieldsets) + [modify] - + list(fieldsets[block + 1 :] if block != -1 else []) + + list(fieldsets[block + 1:] if block != -1 else []) ) return fs @@ -165,6 +166,7 @@ class FrontendEditableAdminMixin: in the frontend by double-clicking on fields rendered with the ``render_model`` template tag. """ + frontend_editable_fields = [] def get_urls(self): # pragma: no cover @@ -177,7 +179,7 @@ def pat(regex, fn): return re_path(regex, self.admin_site.admin_view(fn), name=f"{info}_{fn.__name__}") url_patterns = [ - pat(r'edit-field/(%s)/([a-z\-]+)/$' % SLUG_REGEXP, self.edit_field), + pat(r"edit-field/(%s)/([a-z\-]+)/$" % SLUG_REGEXP, self.edit_field), ] return url_patterns + super().get_urls() @@ -203,21 +205,15 @@ def edit_field(self, request, object_id, language): raw_fields = request.GET.get("edit_fields") fields = [field for field in raw_fields.split(",") if field in self.frontend_editable_fields] if not fields: - context = { - 'opts': opts, - 'message': _("Field %s not found") % raw_fields - } - return render(request, 'admin/cms/page/plugin/error_form.html', context) + context = {"opts": opts, "message": _("Field %s not found") % raw_fields} + return render(request, "admin/cms/page/plugin/error_form.html", context) if not request.user.has_perm(f"{self.model._meta.app_label}.change_{self.model._meta.model_name}"): - context = { - 'opts': opts, - 'message': _("You do not have permission to edit this item") - } - return render(request, 'admin/cms/page/plugin/error_form.html', context) + context = {"opts": opts, "message": _("You do not have permission to edit this item")} + return render(request, "admin/cms/page/plugin/error_form.html", context) # Dynamically creates the form class with only `field_name` field # enabled form_class = self.get_form(request, obj, fields=fields) - if not cancel_clicked and request.method == 'POST': + if not cancel_clicked and request.method == "POST": form = form_class(instance=obj, data=request.POST) if form.is_valid(): new_object = form.save(commit=False) @@ -225,36 +221,37 @@ def edit_field(self, request, object_id, language): saved_successfully = True else: form = form_class(instance=obj) - admin_form = AdminForm(form, fieldsets=[(None, {'fields': fields})], prepopulated_fields={}, - model_admin=self) + admin_form = AdminForm(form, fieldsets=[(None, {"fields": fields})], prepopulated_fields={}, model_admin=self) media = self.media + admin_form.media context = { - 'CMS_MEDIA_URL': get_cms_setting('MEDIA_URL'), - 'title': opts.verbose_name, - 'plugin': None, - 'plugin_id': None, - 'adminform': admin_form, - 'add': False, - 'is_popup': True, - 'media': media, - 'opts': opts, - 'change': True, - 'save_as': False, - 'has_add_permission': False, - 'window_close_timeout': 10, + "CMS_MEDIA_URL": get_cms_setting("MEDIA_URL"), + "title": opts.verbose_name, + "plugin": None, + "plugin_id": None, + "adminform": admin_form, + "add": False, + "is_popup": True, + "media": media, + "opts": opts, + "change": True, + "save_as": False, + "has_add_permission": False, + "window_close_timeout": 10, } if cancel_clicked: # cancel button was clicked - context.update({ - 'cancel': True, - }) - return render(request, 'admin/cms/page/plugin/confirm_form.html', context) - if not cancel_clicked and request.method == 'POST' and saved_successfully: + context.update( + { + "cancel": True, + } + ) + return render(request, "admin/cms/page/plugin/confirm_form.html", context) + if not cancel_clicked and request.method == "POST" and saved_successfully: if isinstance(self, CMSPluginBase): - if hasattr(obj.placeholder, 'mark_as_dirty'): + if hasattr(obj.placeholder, "mark_as_dirty"): # Only relevant for v3: mark the placeholder as dirty so user can publish changes obj.placeholder.mark_as_dirty(obj.language, clear_cache=False) # Update the structure board by populating the data bridge return self.render_close_frame(request, obj) - render(request, 'admin/cms/page/plugin/confirm_form.html', context) - return render(request, 'admin/cms/page/plugin/change_form.html', context) + return render(request, "admin/cms/page/plugin/confirm_form.html", context) + return render(request, "admin/cms/page/plugin/change_form.html", context) diff --git a/djangocms_frontend/management/bootstrap4_migration.py b/djangocms_frontend/management/bootstrap4_migration.py index 7db2b1c6..fcdf20cf 100644 --- a/djangocms_frontend/management/bootstrap4_migration.py +++ b/djangocms_frontend/management/bootstrap4_migration.py @@ -305,7 +305,7 @@ def replace(item, old, new): def replace_left(item, old, new): if item[: len(old)] == old: - return new + item[len(old) :] + return new + item[len(old):] return item classes = new_obj.attributes["class"].split() @@ -361,7 +361,7 @@ def a001_alignment(obj, new_obj, field): new_obj.config[field].replace("text-right", "end") -def m001_spacing_mixin(obj, new_obj, type): +def m001_spacing_mixin(obj, new_obj, type): # noqa: A002 classes = new_obj.config["attributes"].get("class", "").split() if classes: for size, _ in list(settings.SPACER_SIZE_CHOICES) + ([("auto", "auto")] if type == "margin" else []): @@ -404,7 +404,7 @@ def m002_responsive_mixin(obj, new_obj): visible = False hit = True classes.remove(f"{stump}{hidden}") - for type in display: + for type in display: # noqa: A001 if f"{stump}{type}" in classes and not visible: visible = True hit = True diff --git a/djangocms_frontend/migrations/0001_initial.py b/djangocms_frontend/migrations/0001_initial.py index a9588ed0..c566543e 100644 --- a/djangocms_frontend/migrations/0001_initial.py +++ b/djangocms_frontend/migrations/0001_initial.py @@ -2,16 +2,10 @@ import django.core.serializers.json import django.db.models.deletion -from cms.utils.compat import DJANGO_3_1 from django.db import migrations, models import djangocms_frontend.fields -if DJANGO_3_1: - from django_jsonfield_backport.models import JSONField -else: - JSONField = models.JSONField - class Migration(migrations.Migration): initial = True @@ -49,7 +43,7 @@ class Migration(migrations.Migration): ), ( "config", - JSONField( + models.JSONField( default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder, ), diff --git a/djangocms_frontend/migrations/0002_migrate_links.py b/djangocms_frontend/migrations/0002_migrate_links.py new file mode 100644 index 00000000..aeec1205 --- /dev/null +++ b/djangocms_frontend/migrations/0002_migrate_links.py @@ -0,0 +1,85 @@ +from django.db import migrations + + +def convert_item(config, direction): + """Convert FrontendUIItem config to new djangocms_link format.""" + if direction == "forward": + if config.get("external_link"): + if config.get("anchor"): + anchor = "#" + config.get("anchor") + del config["anchor"] + else: + anchor = "" + config["link"] = {"external_link": config.get("external_link") + anchor} + del config["external_link"] + return True + if config.get("internal_link"): + model = config.get("internal_link").get("model") + pk = config.get("internal_link").get("pk") + config["link"] = {"internal_link": f"{model}:{pk}"} + if config.get("anchor"): + config["link"]["anchor"] = "#" + config.get("anchor") + del config["anchor"] + del config["internal_link"] + return True + if config.get("file_link"): + config["link"] = {"file_link": config.get("file_link").get("pk")} + del config["file_link"] + return True + if config.get("phone"): + config["link"] = {"external_link": f"tel:{config.get('phone')}"} + del config["phone"] + return True + if config.get("mailto"): + config["link"] = {"external_link": f"mailto:{config.get('mailto')}"} + del config["mailto"] + return True + if config.get("anchor"): + config["link"] = {"external_link": "#" + config.get('anchor')} + del config["anchor"] + return True + + elif direction == "backward" and config.get("link"): + link = config.get("link") + if link.get("external_link"): + if "#" in link.get("external_link"): + config["anchor"] = link.get("external_link").split("#", 1)[1] + ext = link.get("external_link").split("#", 1)[0] + if ext.startswith("tel:"): + config["phone"] = ext[4:] + elif ext.startswith("mailto:"): + config["mailto"] = ext[7:] + elif ext: + config["external_link"] = ext + elif link.get("internal_link"): + model, pk = link.get("internal_link").split(":") + config["internal_link"] = {"model": model, "pk": int(pk)} + if link.get("anchor"): + config["anchor"] = link.get("anchor")[1:] + elif link.get("file_link"): + config["file_link"] = {"model": "filer.file", "pk": int(link.get("file_link"))} + del config["link"] + return True + return False + + +def convert(apps, schema_editor, direction): + FrontendUIItem = apps.get_model("djangocms_frontend", "FrontendUIItem") + for item in FrontendUIItem.objects.all(): + changed = convert_item(item.config, direction) + if changed: + item.save() + + +class Migration(migrations.Migration): + dependencies = [ + ("djangocms_frontend", "0001_initial"), + ] + + operations = [ + migrations.RunPython( + lambda apps, schema_editor: convert(apps, schema_editor, "forward"), + lambda apps, schema_editor: convert(apps, schema_editor, "backward"), + elidable=True + ), + ] diff --git a/djangocms_frontend/plugin_tag.py b/djangocms_frontend/plugin_tag.py new file mode 100644 index 00000000..c1024d32 --- /dev/null +++ b/djangocms_frontend/plugin_tag.py @@ -0,0 +1,97 @@ +import copy +import importlib +import warnings + +from cms.plugin_pool import plugin_pool +from cms.templatetags.cms_tags import render_plugin +from django.conf import settings +from django.contrib.admin.sites import site as admin_site +from django.template import engines +from django.template.library import SimpleNode +from django.template.loader import get_template + +django_engine = engines["django"] + +plugin_tag_pool = {} + + +IGNORED_FIELDS = ( + "id", + "cmsplugin_ptr", + "language", + "plugin_type", + "position", + "creation_date", + "ui_item", +) + +allowed_plugin_types = tuple( + getattr(importlib.import_module(cls.rsplit(".", 1)[0]), cls.rsplit(".", 1)[-1]) if isinstance(cls, str) else cls + for cls in getattr(settings, "CMS_COMPONENT_PLUGINS", []) +) + + +def _get_plugindefaults(instance): + defaults = { + field.name: getattr(instance, field.name) + for field in instance._meta.fields + if field.name not in IGNORED_FIELDS and bool(getattr(instance, field.name)) + } + defaults["plugin_type"] = instance.__class__.__name__ + return defaults + + +class _DummyUser: + is_superuser = True + is_staff = True + + +class _DummyRequest: + user = _DummyUser() + + +def render_dummy_plugin(context, dummy_plugin): + return dummy_plugin.nodelist.render(context) + + +def patch_template(template): + """Patches the template to use the dummy plugin renderer instead of the real one.""" + copied_template = copy.deepcopy(template) + patch = False + for node in copied_template.template.nodelist.get_nodes_by_type(SimpleNode): + if node.func == render_plugin: + patch = True + node.func = render_dummy_plugin + return copied_template if patch else template + + +def setup(): + global plugin_tag_pool + + for plugin in plugin_pool.get_all_plugins(): + if not issubclass(plugin, allowed_plugin_types): + continue + tag_name = plugin.__name__.lower() + if tag_name.endswith("plugin"): + tag_name = tag_name[:-6] + try: + instance = plugin.model() # Create instance with defaults + plugin_admin = plugin(admin_site=admin_site) + if hasattr(instance, "initialize_from_form"): + instance.initialize_from_form(plugin.form) + if tag_name not in plugin_tag_pool: + template = get_template(plugin_admin._get_render_template({"request": None}, instance, None)) + plugin_tag_pool[tag_name] = { + "defaults": { + **_get_plugindefaults(instance), + **dict(plugin_type=plugin.__name__), + }, + "template": patch_template(template), + "class": plugin, + } + else: # pragma: no cover + warnings.warn( + f"Duplicate candidates for {{% plugin \"{tag_name}\" %}} found. " + f"Only registered {plugin_tag_pool[tag_name]['class'].__name__}.", stacklevel=1) + except Exception as exc: # pragma: no cover + warnings.warn(f"{plugin.__name__}: \n{str(exc)}", stacklevel=1) diff --git a/djangocms_frontend/static/djangocms_frontend/css/base.css b/djangocms_frontend/static/djangocms_frontend/css/base.css index d73825f1..f9ccbb45 100644 --- a/djangocms_frontend/static/djangocms_frontend/css/base.css +++ b/djangocms_frontend/static/djangocms_frontend/css/base.css @@ -5,4 +5,4 @@ /private/sass instead */ -@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:0.8125rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#0d6efd;--bs-link-hover-color:#0a58ca;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-size:0.8125rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#212529;--bs-btn-bg:transparent;--bs-btn-border-width:1px;--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-ms-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.015625rem;--bs-btn-border-radius:0.5rem}.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.7109375rem;--bs-btn-border-radius:0.25rem}.link-primary{color:#0d6efd!important}.link-primary:focus,.link-primary:hover{color:#0a58ca!important}.link-secondary{color:#6c757d!important}.link-secondary:focus,.link-secondary:hover{color:#565e64!important}.link-success{color:#198754!important}.link-success:focus,.link-success:hover{color:#146c43!important}.link-info{color:#0dcaf0!important}.link-info:focus,.link-info:hover{color:#3dd5f3!important}.link-warning{color:#ffc107!important}.link-warning:focus,.link-warning:hover{color:#ffcd39!important}.link-danger{color:#dc3545!important}.link-danger:focus,.link-danger:hover{color:#b02a37!important}.link-light{color:#f8f9fa!important}.link-light:focus,.link-light:hover{color:#f9fafb!important}.link-dark{color:#212529!important}.link-dark:focus,.link-dark:hover{color:#1a1e21!important}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.3rem;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#6c757d;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:1px;--bs-nav-tabs-border-color:#dee2e6;--bs-nav-tabs-border-radius:0.375rem;--bs-nav-tabs-link-hover-border-color:#e9ecef #e9ecef #dee2e6;--bs-nav-tabs-link-active-color:#495057;--bs-nav-tabs-link-active-bg:#fff;--bs-nav-tabs-link-active-border-color:#dee2e6 #dee2e6 #fff;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:4px;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0bf}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.icon{display:inline-block;vertical-align:top;width:1em;height:1em;background-position:center;background-repeat:no-repeat}.icon svg{display:block;width:100%;height:100%}.icon-info{width:.9em;font-size:110%!important}.icon-white{color:#fff}.icon-white svg{fill:#fff}.icon-black{color:#000}.icon-black svg{fill:#000}.icon-primary{color:#0bf}.icon-primary svg{fill:#0bf}.djangocms-icon .icon>input{float:left;position:relative;top:12px}.djangocms-icon .caret{margin-inline-start:8px}.aligned .frontend-button-group label{min-width:unset}.frontend-button-group{display:inline-block}.frontend-button-group .btn{box-sizing:border-box;cursor:pointer;-webkit-appearance:none;margin:2px;overflow:hidden;text-overflow:ellipsis}.frontend-button-group .btn.active{outline:3px solid #0bf;border-color:#fff!important}.frontend-button-group .btn-default.active{border-radius:0;background-color:#0bf!important}.frontend-button-group-context-colors>div,.frontend-button-group-context-size>div{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;min-height:75px}.frontend-button-group-context-colors .btn{-ms-flex-preferred-size:calc(25% - 4px);flex-basis:calc(25% - 4px)}@media (min-width:820px){.frontend-button-group-context-colors .btn{-ms-flex-preferred-size:calc(20% - 4px);flex-basis:calc(20% - 4px)}}.frontend-button-group-icons .icon,.frontend-grid-icons .icon{font-size:24px}.frontend-button-group-icons .icon-flex-align-center,.frontend-button-group-icons .icon-flex-align-end,.frontend-button-group-icons .icon-flex-align-start,.frontend-grid-icons .icon-flex-align-center,.frontend-grid-icons .icon-flex-align-end,.frontend-grid-icons .icon-flex-align-start{transform:scale(1.4)}.frontend-button-group-icons .icon-flex-content-around,.frontend-button-group-icons .icon-flex-content-between,.frontend-grid-icons .icon-flex-content-around,.frontend-grid-icons .icon-flex-content-between{transform:scale(1.6)}.frontend-button-group-icons .icon-flex-self-center,.frontend-button-group-icons .icon-flex-self-end,.frontend-button-group-icons .icon-flex-self-start,.frontend-grid-icons .icon-flex-self-center,.frontend-grid-icons .icon-flex-self-end,.frontend-grid-icons .icon-flex-self-start{transform:scale(1.4)}.frontend-button-group-icons .icon-align-reset,.frontend-button-group-icons .icon-no-selection,.frontend-grid-icons .icon-align-reset,.frontend-grid-icons .icon-no-selection{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-align-items-start,.frontend-button-group-icons .icon-flex-align-start,.frontend-grid-icons .icon-align-items-start,.frontend-grid-icons .icon-flex-align-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-items-center,.frontend-button-group-icons .icon-flex-align-center,.frontend-grid-icons .icon-align-items-center,.frontend-grid-icons .icon-flex-align-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-items-end,.frontend-button-group-icons .icon-flex-align-end,.frontend-grid-icons .icon-align-items-end,.frontend-grid-icons .icon-flex-align-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-flex-content-start,.frontend-button-group-icons .icon-justify-content-start,.frontend-button-group-icons .icon-start,.frontend-grid-icons .icon-flex-content-start,.frontend-grid-icons .icon-justify-content-start,.frontend-grid-icons .icon-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-center,.frontend-button-group-icons .icon-flex-content-center,.frontend-button-group-icons .icon-justify-content-center,.frontend-grid-icons .icon-center,.frontend-grid-icons .icon-flex-content-center,.frontend-grid-icons .icon-justify-content-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-end,.frontend-button-group-icons .icon-flex-content-end,.frontend-button-group-icons .icon-justify-content-end,.frontend-grid-icons .icon-end,.frontend-grid-icons .icon-flex-content-end,.frontend-grid-icons .icon-justify-content-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-flex-content-around,.frontend-button-group-icons .icon-justify-content-around,.frontend-grid-icons .icon-flex-content-around,.frontend-grid-icons .icon-justify-content-around{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.6)}.frontend-button-group-icons .icon-flex-content-between,.frontend-button-group-icons .icon-justify-content-between,.frontend-grid-icons .icon-flex-content-between,.frontend-grid-icons .icon-justify-content-between{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.6)}.frontend-button-group-icons .icon-nav-fill,.frontend-grid-icons .icon-nav-fill{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-nav-justified,.frontend-grid-icons .icon-nav-justified{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-flex-column,.frontend-grid-icons .icon-flex-column{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-start,.frontend-button-group-icons .icon-flex-self-start,.frontend-grid-icons .icon-align-self-start,.frontend-grid-icons .icon-flex-self-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-center,.frontend-button-group-icons .icon-flex-self-center,.frontend-grid-icons .icon-align-self-center,.frontend-grid-icons .icon-flex-self-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-end,.frontend-button-group-icons .icon-flex-self-end,.frontend-grid-icons .icon-align-self-end,.frontend-grid-icons .icon-flex-self-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-size-sm,.frontend-button-group-icons .icon-size-xs,.frontend-button-group-icons .icon-sm,.frontend-button-group-icons .icon-xs,.frontend-grid-icons .icon-size-sm,.frontend-grid-icons .icon-size-xs,.frontend-grid-icons .icon-sm,.frontend-grid-icons .icon-xs{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-sm,.frontend-button-group-icons .icon-sm,.frontend-grid-icons .icon-size-sm,.frontend-grid-icons .icon-sm{transform:rotate(-90deg)}.frontend-button-group-icons .icon-md,.frontend-button-group-icons .icon-size-md,.frontend-grid-icons .icon-md,.frontend-grid-icons .icon-size-md{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-lg,.frontend-button-group-icons .icon-size-lg,.frontend-grid-icons .icon-lg,.frontend-grid-icons .icon-size-lg{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-xl,.frontend-button-group-icons .icon-xl,.frontend-grid-icons .icon-size-xl,.frontend-grid-icons .icon-xl{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-xxl,.frontend-button-group-icons .icon-xxl,.frontend-grid-icons .icon-size-xxl,.frontend-grid-icons .icon-xxl{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-mb,.frontend-grid-icons .icon-mb{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-me,.frontend-grid-icons .icon-me{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-ms,.frontend-grid-icons .icon-ms{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-mt,.frontend-grid-icons .icon-mt{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-mx,.frontend-grid-icons .icon-mx{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-my,.frontend-grid-icons .icon-my{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pb,.frontend-grid-icons .icon-pb{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pe,.frontend-grid-icons .icon-pe{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-ps,.frontend-grid-icons .icon-ps{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pt,.frontend-grid-icons .icon-pt{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-px,.frontend-grid-icons .icon-px{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-py,.frontend-grid-icons .icon-py{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.icon-info{background-image:url('data:image/svg+xml;utf8,')}.module{margin:0 0 20px}.djangocms-frontend-row .form-row.field-create .icon{position:absolute;font-size:30px;margin-block-start:28px;margin-inline-start:4px}.djangocms-frontend-row .form-row.field-create input[name=create]{width:130px!important;padding-inline-end:5px!important;text-align:start}.djangocms-frontend-column .form-row.field-xs_col,.djangocms-frontend-column .form-row.field-xs_me,.djangocms-frontend-column .form-row.field-xs_ms,.djangocms-frontend-column .form-row.field-xs_offset,.djangocms-frontend-column .form-row.field-xs_order,.djangocms-frontend-row .form-row.field-row_cols_xs{position:relative;display:-ms-flexbox;display:flex;padding:0;min-width:800px}.djangocms-frontend-column .form-row.field-xs_col>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_me>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_ms>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_offset>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_order>div>div:not([class]),.djangocms-frontend-row .form-row.field-row_cols_xs>div>div:not([class]){width:unset!important;max-width:unset!important}.djangocms-frontend-column .form-row.field-xs_col .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_me .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_ms .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_offset .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_order .field-box:first-child,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box:first-child{width:115px!important}.djangocms-frontend-column .form-row.field-xs_col .field-box,.djangocms-frontend-column .form-row.field-xs_col .fieldBox,.djangocms-frontend-column .form-row.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_me .fieldBox,.djangocms-frontend-column .form-row.field-xs_ms .field-box,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox,.djangocms-frontend-column .form-row.field-xs_offset .field-box,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox,.djangocms-frontend-column .form-row.field-xs_order .field-box,.djangocms-frontend-column .form-row.field-xs_order .fieldBox,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox{position:relative;box-sizing:content-box;width:86px!important;-ms-flex:none;flex:none;display:block;padding:15px 10px;margin:0!important;border-bottom:1px solid #eee;float:left!important}.djangocms-frontend-column .form-row.field-xs_col .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_col .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_me .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_me .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_ms .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_ms .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_offset .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_offset .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_order .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_order .fieldBox input:not([type=checkbox]),.djangocms-frontend-row .form-row.field-row_cols_xs .field-box input:not([type=checkbox]),.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox input:not([type=checkbox]){text-align:end;padding-inline-end:5px!important;box-sizing:border-box;width:100%}.djangocms-frontend-column .form-row.field-xs_col .field-box label,.djangocms-frontend-column .form-row.field-xs_col .fieldBox label,.djangocms-frontend-column .form-row.field-xs_me .field-box label,.djangocms-frontend-column .form-row.field-xs_me .fieldBox label,.djangocms-frontend-column .form-row.field-xs_ms .field-box label,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox label,.djangocms-frontend-column .form-row.field-xs_offset .field-box label,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox label,.djangocms-frontend-column .form-row.field-xs_order .field-box label,.djangocms-frontend-column .form-row.field-xs_order .fieldBox label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box label,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox label{font-size:12px!important;font-weight:400!important;color:#ccc!important;position:absolute;inset-inline-start:15px;inset-block-end:17px;text-transform:lowercase}.djangocms-frontend-column .form-row.field-xs_col .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_col .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_me .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_me .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_ms .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_offset .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_order .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_order .fieldBox .disabled,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box .disabled,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox .disabled{color:#ccc;background:#eee}.djangocms-frontend-column .form-row.field-xs_col .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_col .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_me .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_me .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_ms .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_offset .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_order .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_order .fieldBox:last-child,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box:last-child,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox:last-child{border-inline-end:none}.djangocms-frontend-column .form-row.field-xs_col .errors,.djangocms-frontend-column .form-row.field-xs_me .errors,.djangocms-frontend-column .form-row.field-xs_ms .errors,.djangocms-frontend-column .form-row.field-xs_offset .errors,.djangocms-frontend-column .form-row.field-xs_order .errors,.djangocms-frontend-row .form-row.field-row_cols_xs .errors{margin-bottom:0}.djangocms-frontend-column .form-row.field-xs_col .errorlist,.djangocms-frontend-column .form-row.field-xs_me .errorlist,.djangocms-frontend-column .form-row.field-xs_ms .errorlist,.djangocms-frontend-column .form-row.field-xs_offset .errorlist,.djangocms-frontend-column .form-row.field-xs_order .errorlist,.djangocms-frontend-row .form-row.field-row_cols_xs .errorlist{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.djangocms-frontend-column .form-row.field-xs_col.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_me.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_ms.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_offset.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_order.field-xs_me .field-box,.djangocms-frontend-row .form-row.field-row_cols_xs.field-xs_me .field-box{border-bottom:none}.djangocms-frontend-column .form-row.field-xs_col .field-box-label,.djangocms-frontend-column .form-row.field-xs_me .field-box-label,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label,.djangocms-frontend-column .form-row.field-xs_order .field-box-label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label{display:-ms-flexbox;display:flex;margin-top:auto;color:#999}.djangocms-frontend-column .form-row.field-xs_col .field-box-label a,.djangocms-frontend-column .form-row.field-xs_me .field-box-label a,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label a,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label a,.djangocms-frontend-column .form-row.field-xs_order .field-box-label a,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label a{width:100%;margin-top:auto;color:#999}.djangocms-frontend-column .form-row.field-xs_col .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_me .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_order .field-box-label a a,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label a a{width:100%;margin-top:auto}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_col .field-md_me,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_me .field-md_me,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_order .field-md_me,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms{text-align:start}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-md_me label,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-md_me label,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-md_me label,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms label{inset-inline-start:30px;inset-block-start:14px}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-md_me input,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-md_me input,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-md_me input,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms input{position:relative;box-sizing:border-box;top:-3px}.grid-reset{position:absolute;inset-inline-end:5px;inset-block-start:0}.icon-thead{text-align:center;margin-bottom:15px}.icon-thead .icon{font-size:30px}.icon-thead .icon-size-sm{transform:rotate(90deg)}.icon-title{display:block;font-size:12px;color:#999;padding:5px 0 0}.djangocms-frontend-preview{position:fixed;inset-block-start:0;inset-inline-end:0;z-index:10;text-align:center;border-radius:0 0 0 3px;padding:10px 20px 27px;border:1px solid var(--dca-gray,var(--hairline-color,#ccc));border-block-start:none;border-inline-end:none;background:var(--body-bg,#fff)}@media (prefers-color-scheme:dark){.djangocms-frontend-preview{background:var(--body-bg,#000)}}.djangocms-frontend-preview h2{font-size:14px;min-width:150px;margin:0 0 12px}.djangocms-frontend-preview .b4-preview{margin:0 0 -15px}.djangocms-frontend-preview .b4-close{position:absolute;inset-inline-end:10px;inset-block-start:8px;z-index:100;display:block;color:#5e5e5e;font-size:12px;line-height:20px;font-weight:700;text-transform:uppercase;width:20px;height:20px;border-radius:3px;background:#ddd}.djangocms-frontend-preview .b4-close:hover{color:#fff!important;text-decoration:none;background:#0bf}.djangocms-frontend-preview .btn>span{vertical-align:middle}.djangocms-frontend-preview .btn>span>.icon{vertical-align:middle}.djangocms-frontend-preview .btn>span svg,.djangocms-frontend-preview .btn>span use{fill:currentColor}.djangocms-frontend-blockquote textarea{height:110px}#id_link_type{padding:0;margin:0;border:none}#id_link_type li{padding:0;margin:0 15px 5px 0;border:none}#id_link_type label input{position:relative;top:-4px}a[data-pk]{position:relative}a[data-pk]:after{content:attr(data-pk);visibility:hidden;width:auto;font-weight:400;font-size:80%;background-color:var(--dca-white,var(--body-bg,#fff));color:var(--dca-gray,var(--body-fg,#333));border:solid 1px var(--dca-gray,var(--body-fg,#333));text-align:center;padding:5px 10px;position:absolute;z-index:1;top:110%;inset-inline-start:50%;margin-inline-start:-50%}a[data-pk]:hover:after{visibility:visible}.djangocms-admin-style .form-row.field-plugin_title input[name=plugin_title_0]{margin-bottom:.5em!important}.djangocms-admin-style .form-row.field-plugin_title input[name=plugin_title_1]{width:calc(100% - 2em)!important}body:not(.djangocms-admin-style) .form-row.field-plugin_title input[name=plugin_title_1]{width:calc(100% - 200px - 1em)!important;margin-inline-start:1em}.frontend-icon-picker{text-align:center;display:inline-block}.frontend-icon-picker .icon-container{position:relative;margin:.5em auto;width:7em;height:7em;border:1px var(--dca-gray-light,var(--border-color,#d3d3d3)) solid;transition:background-color .15s,color .15s}.frontend-icon-picker .icon-container .icon-preview{width:7em;height:7em;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.frontend-icon-picker .icon-container .icon-preview .icon-box{font-size:500%;line-height:1.3;margin:0;text-align:center}.frontend-icon-picker .icon-container .icon-preview .icon-box i,.frontend-icon-picker .icon-container .icon-preview .icon-box span{font-size:unset}.frontend-icon-picker .icon-container .icon-preview .empty-box{text-align:center;overflow:hidden;text-overflow:ellipsis;line-height:1;font-size:100%}.frontend-icon-picker .icon-container .icon-preview .empty-box.hidden{display:none}.frontend-icon-picker .icon-container .icon-preview:hover{background:var(--dca-gray-light,var(--border-color,#d3d3d3));cursor:pointer}.frontend-icon-picker .icon-container .icon-close-indicator{display:block;border-radius:50%;color:var(--dca-black,var(--body-fg,#000));background-color:var(--dca-white,var(--body-bg,#fff));padding:.3rem;border:1px solid var(--dca-black,var(--body-fg,#000));transform:translate(-50%,-50%);top:0;inset-inline-start:100%;width:.6em;height:.6em;line-height:.5em;position:absolute;transition:background-color .15s}.frontend-icon-picker .icon-container .icon-close-indicator:before{content:"×"}.frontend-icon-picker .icon-container .icon-close-indicator:hover{background:var(--delete-button-bg,red);color:var(--delete-button-fg,#fff);cursor:pointer}.uip-modal{position:fixed;height:100%;width:100%;inset-block-end:0;inset-inline-start:0;background-color:rgba(0,0,0,.8);z-index:9999;-webkit-user-select:none;-ms-user-select:none;user-select:none;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.uip-modal *,.uip-modal :after,.uip-modal :before{box-sizing:border-box}.uip-modal.uip-close{opacity:0;visibility:hidden;transition:all .4s ease-in-out}.uip-modal.uip-open{opacity:1;visibility:visible;transition:all .4s ease-in-out}.uip-modal .uip-modal--content{position:absolute;border-radius:3px;box-shadow:2px 8px 23px 3px rgba(0,0,0,.2);overflow:hidden;font-family:Roboto,Arial,Helvetica,Verdana,sans-serif;background-color:var(--dca-gray-lightest,var(--darkened-bg,#f8f8f8));width:100%;margin:auto;left:0;right:0;margin-bottom:2em}.uip-modal .uip-modal--content .uip-modal--header{padding:15px 15px;background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 0 8px rgba(0,0,0,.1);position:relative;z-index:1;font-size:15px;color:var(--dca-gray,var(--body-quiet-color,#666));font-weight:500;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-logo-title{padding-top:2px;line-height:1;text-transform:uppercase;font-weight:700;cursor:pointer}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-close-btn{cursor:pointer}.uip-modal .uip-modal--content .uip-modal--body{font-size:12px;line-height:1.5;box-sizing:border-box;padding:0;height:70vh;display:-ms-flexbox;display:flex;min-height:50px;max-height:85vh;overflow:auto}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar{-ms-flex-negative:0;flex-shrink:0;max-width:25%}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs{margin-top:30px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item{padding:15px;font-size:14px;color:var(--dca-gray,var(--body-quiet-color,#666));text-align:start;cursor:pointer;position:relative;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item i{font-size:20px;padding-inline-end:15px;color:var(--dca-gray-lighter,var(--border-color,#ccc))}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item img{padding-inline-end:15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active{background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 6px 20px 0 rgba(0,0,0,.1)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active:after{content:"";position:absolute;height:100%;width:5px;inset-block-start:0;inset-inline-start:0;background-color:#0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active i{color:#0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item:only-child{display:none}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding:30px 80px 0;width:100%}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner{overflow:auto;margin:25px -15px 0;padding:0 15px 15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview{display:-ms-grid;display:grid;grid-gap:20px;margin:20px 0}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item{position:relative;padding:10px;background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 1px 12px rgba(0,0,0,.05);border-radius:3px;cursor:pointer;transition:all .3s;overflow:hidden}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item:hover{box-shadow:0 1px 14px rgba(0,0,0,.16)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item.universal-selected{box-shadow:0 1px 12px rgba(0,0,0,.05),0 0 0 3px #0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-align:center;align-items:center;padding:1px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item__icon,.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner i{font-size:25px;color:var(--dca-gray-darkest,var(--body-fg,#333))}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item-name{color:var(--dca-gray,var(--body-quiet-color,#666));font-size:11px;padding:13px 0 0;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search{position:relative}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input{width:100%;padding:8px 15px;background-color:var(--dca-white,var(--bg-color,#fff));border:none}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input:-ms-input-placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input::placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search img{position:absolute;top:50%;transform:translateY(-50%);inset-inline-end:10px}.uip-modal .uip-modal--footer{border-top:1px solid var(--dca-gray-lighter,var(--border-color,#ccc));text-align:center;background-color:var(--dca-white,var(--bg-color,#fff));border:none;display:none;-ms-flex-pack:end;justify-content:flex-end;padding:5px;box-shadow:0 0 8px rgba(0,0,0,.1);position:relative;display:-ms-flexbox;display:flex}.uip-modal .uip-modal--footer button.uip-insert-icon-button{padding:10px 35px!important;color:var(--dca-white,var(--bg-color,#fff))!important;background-color:#0bf!important;border:none;cursor:pointer;outline:0}.uip-modal .uip-modal--footer .universal-button{height:40px;margin-inline-start:5px}.uip-modal .uip-modal--footer .universal-button-success{padding:12px 36px;color:var(--dca-white,var(--bg-color,#fff));width:initial}.uip-modal .uip-modal--footer .universal-button-success:hover{background-color:#0bf}@media (min-width:1440px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:1200px}}@media (max-width:1439px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:990px}.uip-modal--icon-preview-wrap{padding:30px 50px 0}}@media (max-width:1023px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:740px}}@media (max-width:767px){.uip-modal--icon-preview-wrap{padding:15px!important}.uip-modal--sidebar{display:none}}@media (min-width:1440px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[7];grid-template-columns:repeat(7,1fr)}}@media (max-width:1439px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[6];grid-template-columns:repeat(6,1fr)}}@media (max-width:1024px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[5];grid-template-columns:repeat(5,1fr)}}@media (max-width:767px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[4];grid-template-columns:repeat(4,1fr)}}@media (max-width:479px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[3];grid-template-columns:repeat(3,1fr)}}@media (max-width:1439px){.uip-modal--sidebar-tab-item{padding:15px 15px 15px 25px;font-size:11px}.uip-modal--sidebar-tab-item i{font-size:15px}}@media (max-width:1024px){.uip-modal--sidebar-tab-item i,.uip-modal--sidebar-tab-item img{display:none}}.sr-only{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}ul.nav{margin-bottom:1em}ul.nav>li.nav-item{list-style-type:none;padding:inherit}.colM ul:not(.object-tools).nav{margin-top:0;margin-bottom:20px}ul.nav .nav-item{margin-inline-end:1rem}ul.nav .nav-link{position:relative;text-decoration:none}ul.nav .nav-link span.indicator{display:none;border-radius:50%;padding:.5rem;border:1px solid var(--dca-white,var(--body-bg,#fff));transform:translate(-50%,-50%);inset-block-start:0;inset-inline-start:100%;position:absolute}ul.nav .nav-link span.indicator.error{background-color:var(--bs-danger)}ul.nav .nav-link span.indicator.attributes{background-color:var(--bs-info);display:block}ul.nav .nav-link.error>span.indicator{display:block}ul.nav.nav-pills .nav-link:not(.active){border-style:solid;border-width:1px}body:not(.djangocms-admin-style) ul.djangocms-frontend.nav-tabs+div.tab-content .tab-pane{border-left-style:solid;border-bottom-style:solid;border-right-style:solid;border-left-color:var(--hairline-color);border-bottom-color:var(--hairline-color);border-right-color:var(--hairline-color);border-width:1px}body:not(.djangocms-admin-style) ul.djangocms-frontend.nav-tabs+div.tab-content .tab-pane fieldset:last-child{margin-bottom:0}div.tab-pk{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;color:var(--dca-gray-darker,var(--body-fg,#333));font-size:80%;margin-inline-start:auto}.djangocms-admin-style .colM ul.nav:not(.object-tools):not(.messagelist){margin-top:0}.djangocms-admin-style .colM ul.nav:not(.object-tools):not(.messagelist) li.nav-item{border-top:none}input[type=number].auto-field+span{display:none;position:absolute;inset-block-end:0;inset-inline-end:0;text-align:end;margin-inline-end:31px;margin-block-end:23px;cursor:pointer}body:not(.djangocms-admin-style) input[type=number].auto-field+span{margin-bottom:23px}@media (max-width:1024px){body:not(.djangocms-admin-style) input[type=number].auto-field+span{margin-bottom:24px}}input[type=number].auto-field+span:after{content:"auto"}input[type=number].auto-field.auto{color:var(--dca-white,var(--body-bg,#fff));caret-color:var(--dca-black,var(--body-fg,#000))}input[type=number].auto-field.auto+span{display:block} \ No newline at end of file +@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:0.8125rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#0d6efd;--bs-link-hover-color:#0a58ca;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-size:0.8125rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#212529;--bs-btn-bg:transparent;--bs-btn-border-width:1px;--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-ms-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.015625rem;--bs-btn-border-radius:0.5rem}.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.7109375rem;--bs-btn-border-radius:0.25rem}.link-primary{color:#0d6efd!important}.link-primary:focus,.link-primary:hover{color:#0a58ca!important}.link-secondary{color:#6c757d!important}.link-secondary:focus,.link-secondary:hover{color:#565e64!important}.link-success{color:#198754!important}.link-success:focus,.link-success:hover{color:#146c43!important}.link-info{color:#0dcaf0!important}.link-info:focus,.link-info:hover{color:#3dd5f3!important}.link-warning{color:#ffc107!important}.link-warning:focus,.link-warning:hover{color:#ffcd39!important}.link-danger{color:#dc3545!important}.link-danger:focus,.link-danger:hover{color:#b02a37!important}.link-light{color:#f8f9fa!important}.link-light:focus,.link-light:hover{color:#f9fafb!important}.link-dark{color:#212529!important}.link-dark:focus,.link-dark:hover{color:#1a1e21!important}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.3rem;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#6c757d;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:1px;--bs-nav-tabs-border-color:#dee2e6;--bs-nav-tabs-border-radius:0.375rem;--bs-nav-tabs-link-hover-border-color:#e9ecef #e9ecef #dee2e6;--bs-nav-tabs-link-active-color:#495057;--bs-nav-tabs-link-active-bg:#fff;--bs-nav-tabs-link-active-border-color:#dee2e6 #dee2e6 #fff;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:4px;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0bf}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.icon{display:inline-block;vertical-align:top;width:1em;height:1em;background-position:center;background-repeat:no-repeat}.icon svg{display:block;width:100%;height:100%}.icon-info{width:.9em;font-size:110%!important}.icon-white{color:#fff}.icon-white svg{fill:#fff}.icon-black{color:#000}.icon-black svg{fill:#000}.icon-primary{color:#0bf}.icon-primary svg{fill:#0bf}.djangocms-icon .icon>input{float:left;position:relative;top:12px}.djangocms-icon .caret{margin-inline-start:8px}.aligned .frontend-button-group label{min-width:unset}.frontend-button-group{display:inline-block}.frontend-button-group .btn{box-sizing:border-box;cursor:pointer;-webkit-appearance:none;margin:2px;overflow:hidden;text-overflow:ellipsis}.frontend-button-group .btn.active{outline:3px solid #0bf;border-color:#fff!important}.frontend-button-group .btn-default.active{border-radius:0;background-color:#0bf!important}.frontend-button-group-context-colors>div,.frontend-button-group-context-size>div{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;min-height:75px}.frontend-button-group-context-colors .btn{-ms-flex-preferred-size:calc(25% - 4px);flex-basis:calc(25% - 4px)}@media (min-width:820px){.frontend-button-group-context-colors .btn{-ms-flex-preferred-size:calc(20% - 4px);flex-basis:calc(20% - 4px)}}.frontend-button-group-icons .icon,.frontend-grid-icons .icon{font-size:24px}.frontend-button-group-icons .icon-flex-align-center,.frontend-button-group-icons .icon-flex-align-end,.frontend-button-group-icons .icon-flex-align-start,.frontend-grid-icons .icon-flex-align-center,.frontend-grid-icons .icon-flex-align-end,.frontend-grid-icons .icon-flex-align-start{transform:scale(1.4)}.frontend-button-group-icons .icon-flex-content-around,.frontend-button-group-icons .icon-flex-content-between,.frontend-grid-icons .icon-flex-content-around,.frontend-grid-icons .icon-flex-content-between{transform:scale(1.6)}.frontend-button-group-icons .icon-flex-self-center,.frontend-button-group-icons .icon-flex-self-end,.frontend-button-group-icons .icon-flex-self-start,.frontend-grid-icons .icon-flex-self-center,.frontend-grid-icons .icon-flex-self-end,.frontend-grid-icons .icon-flex-self-start{transform:scale(1.4)}.frontend-button-group-icons .icon-align-reset,.frontend-button-group-icons .icon-no-selection,.frontend-grid-icons .icon-align-reset,.frontend-grid-icons .icon-no-selection{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-align-items-start,.frontend-button-group-icons .icon-flex-align-start,.frontend-grid-icons .icon-align-items-start,.frontend-grid-icons .icon-flex-align-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-items-center,.frontend-button-group-icons .icon-flex-align-center,.frontend-grid-icons .icon-align-items-center,.frontend-grid-icons .icon-flex-align-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-items-end,.frontend-button-group-icons .icon-flex-align-end,.frontend-grid-icons .icon-align-items-end,.frontend-grid-icons .icon-flex-align-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-flex-content-start,.frontend-button-group-icons .icon-justify-content-start,.frontend-button-group-icons .icon-start,.frontend-grid-icons .icon-flex-content-start,.frontend-grid-icons .icon-justify-content-start,.frontend-grid-icons .icon-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-center,.frontend-button-group-icons .icon-flex-content-center,.frontend-button-group-icons .icon-justify-content-center,.frontend-grid-icons .icon-center,.frontend-grid-icons .icon-flex-content-center,.frontend-grid-icons .icon-justify-content-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-end,.frontend-button-group-icons .icon-flex-content-end,.frontend-button-group-icons .icon-justify-content-end,.frontend-grid-icons .icon-end,.frontend-grid-icons .icon-flex-content-end,.frontend-grid-icons .icon-justify-content-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-flex-content-around,.frontend-button-group-icons .icon-justify-content-around,.frontend-grid-icons .icon-flex-content-around,.frontend-grid-icons .icon-justify-content-around{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.6)}.frontend-button-group-icons .icon-flex-content-between,.frontend-button-group-icons .icon-justify-content-between,.frontend-grid-icons .icon-flex-content-between,.frontend-grid-icons .icon-justify-content-between{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.6)}.frontend-button-group-icons .icon-nav-fill,.frontend-grid-icons .icon-nav-fill{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-nav-justified,.frontend-grid-icons .icon-nav-justified{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-flex-column,.frontend-grid-icons .icon-flex-column{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-start,.frontend-button-group-icons .icon-flex-self-start,.frontend-grid-icons .icon-align-self-start,.frontend-grid-icons .icon-flex-self-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-center,.frontend-button-group-icons .icon-flex-self-center,.frontend-grid-icons .icon-align-self-center,.frontend-grid-icons .icon-flex-self-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-end,.frontend-button-group-icons .icon-flex-self-end,.frontend-grid-icons .icon-align-self-end,.frontend-grid-icons .icon-flex-self-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-size-sm,.frontend-button-group-icons .icon-size-xs,.frontend-button-group-icons .icon-sm,.frontend-button-group-icons .icon-xs,.frontend-grid-icons .icon-size-sm,.frontend-grid-icons .icon-size-xs,.frontend-grid-icons .icon-sm,.frontend-grid-icons .icon-xs{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-sm,.frontend-button-group-icons .icon-sm,.frontend-grid-icons .icon-size-sm,.frontend-grid-icons .icon-sm{transform:rotate(-90deg)}.frontend-button-group-icons .icon-md,.frontend-button-group-icons .icon-size-md,.frontend-grid-icons .icon-md,.frontend-grid-icons .icon-size-md{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-lg,.frontend-button-group-icons .icon-size-lg,.frontend-grid-icons .icon-lg,.frontend-grid-icons .icon-size-lg{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-xl,.frontend-button-group-icons .icon-xl,.frontend-grid-icons .icon-size-xl,.frontend-grid-icons .icon-xl{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-xxl,.frontend-button-group-icons .icon-xxl,.frontend-grid-icons .icon-size-xxl,.frontend-grid-icons .icon-xxl{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-mb,.frontend-grid-icons .icon-mb{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-me,.frontend-grid-icons .icon-me{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-ms,.frontend-grid-icons .icon-ms{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-mt,.frontend-grid-icons .icon-mt{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-mx,.frontend-grid-icons .icon-mx{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-my,.frontend-grid-icons .icon-my{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pb,.frontend-grid-icons .icon-pb{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pe,.frontend-grid-icons .icon-pe{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-ps,.frontend-grid-icons .icon-ps{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pt,.frontend-grid-icons .icon-pt{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-px,.frontend-grid-icons .icon-px{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-py,.frontend-grid-icons .icon-py{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.icon-info{background-image:url('data:image/svg+xml;utf8,')}.module{margin:0 0 20px}.djangocms-frontend-row .form-row.field-create .icon{position:absolute;font-size:30px;margin-block-start:28px;margin-inline-start:4px}.djangocms-frontend-row .form-row.field-create input[name=create]{width:130px!important;padding-inline-end:5px!important;text-align:start}.djangocms-frontend-column .form-row.field-xs_col,.djangocms-frontend-column .form-row.field-xs_me,.djangocms-frontend-column .form-row.field-xs_ms,.djangocms-frontend-column .form-row.field-xs_offset,.djangocms-frontend-column .form-row.field-xs_order,.djangocms-frontend-row .form-row.field-row_cols_xs{position:relative;display:-ms-flexbox;display:flex;padding:0;min-width:800px}.djangocms-frontend-column .form-row.field-xs_col>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_me>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_ms>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_offset>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_order>div>div:not([class]),.djangocms-frontend-row .form-row.field-row_cols_xs>div>div:not([class]){width:unset!important;max-width:unset!important}.djangocms-frontend-column .form-row.field-xs_col .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_me .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_ms .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_offset .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_order .field-box:first-child,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box:first-child{width:115px!important}.djangocms-frontend-column .form-row.field-xs_col .field-box,.djangocms-frontend-column .form-row.field-xs_col .fieldBox,.djangocms-frontend-column .form-row.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_me .fieldBox,.djangocms-frontend-column .form-row.field-xs_ms .field-box,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox,.djangocms-frontend-column .form-row.field-xs_offset .field-box,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox,.djangocms-frontend-column .form-row.field-xs_order .field-box,.djangocms-frontend-column .form-row.field-xs_order .fieldBox,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox{position:relative;box-sizing:content-box;width:86px!important;-ms-flex:none;flex:none;display:block;padding:15px 10px;margin:0!important;border-bottom:1px solid #eee;float:left!important}.djangocms-frontend-column .form-row.field-xs_col .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_col .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_me .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_me .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_ms .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_ms .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_offset .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_offset .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_order .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_order .fieldBox input:not([type=checkbox]),.djangocms-frontend-row .form-row.field-row_cols_xs .field-box input:not([type=checkbox]),.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox input:not([type=checkbox]){text-align:end;padding-inline-end:5px!important;box-sizing:border-box;width:100%}.djangocms-frontend-column .form-row.field-xs_col .field-box label,.djangocms-frontend-column .form-row.field-xs_col .fieldBox label,.djangocms-frontend-column .form-row.field-xs_me .field-box label,.djangocms-frontend-column .form-row.field-xs_me .fieldBox label,.djangocms-frontend-column .form-row.field-xs_ms .field-box label,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox label,.djangocms-frontend-column .form-row.field-xs_offset .field-box label,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox label,.djangocms-frontend-column .form-row.field-xs_order .field-box label,.djangocms-frontend-column .form-row.field-xs_order .fieldBox label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box label,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox label{font-size:12px!important;font-weight:400!important;color:#ccc!important;position:absolute;inset-inline-start:15px;inset-block-end:17px;text-transform:lowercase}.djangocms-frontend-column .form-row.field-xs_col .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_col .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_me .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_me .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_ms .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_offset .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_order .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_order .fieldBox .disabled,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box .disabled,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox .disabled{color:#ccc;background:#eee}.djangocms-frontend-column .form-row.field-xs_col .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_col .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_me .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_me .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_ms .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_offset .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_order .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_order .fieldBox:last-child,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box:last-child,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox:last-child{border-inline-end:none}.djangocms-frontend-column .form-row.field-xs_col .errors,.djangocms-frontend-column .form-row.field-xs_me .errors,.djangocms-frontend-column .form-row.field-xs_ms .errors,.djangocms-frontend-column .form-row.field-xs_offset .errors,.djangocms-frontend-column .form-row.field-xs_order .errors,.djangocms-frontend-row .form-row.field-row_cols_xs .errors{margin-bottom:0}.djangocms-frontend-column .form-row.field-xs_col .errorlist,.djangocms-frontend-column .form-row.field-xs_me .errorlist,.djangocms-frontend-column .form-row.field-xs_ms .errorlist,.djangocms-frontend-column .form-row.field-xs_offset .errorlist,.djangocms-frontend-column .form-row.field-xs_order .errorlist,.djangocms-frontend-row .form-row.field-row_cols_xs .errorlist{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.djangocms-frontend-column .form-row.field-xs_col.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_me.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_ms.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_offset.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_order.field-xs_me .field-box,.djangocms-frontend-row .form-row.field-row_cols_xs.field-xs_me .field-box{border-bottom:none}.djangocms-frontend-column .form-row.field-xs_col .field-box-label,.djangocms-frontend-column .form-row.field-xs_me .field-box-label,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label,.djangocms-frontend-column .form-row.field-xs_order .field-box-label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label{display:-ms-flexbox;display:flex;margin-top:auto;color:#999}.djangocms-frontend-column .form-row.field-xs_col .field-box-label a,.djangocms-frontend-column .form-row.field-xs_me .field-box-label a,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label a,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label a,.djangocms-frontend-column .form-row.field-xs_order .field-box-label a,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label a{width:100%;margin-top:auto;color:#999}.djangocms-frontend-column .form-row.field-xs_col .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_me .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_order .field-box-label a a,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label a a{width:100%;margin-top:auto}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_col .field-md_me,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_me .field-md_me,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_order .field-md_me,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms{text-align:start}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-md_me label,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-md_me label,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-md_me label,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms label{inset-inline-start:30px;inset-block-start:14px}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-md_me input,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-md_me input,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-md_me input,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms input{position:relative;box-sizing:border-box;top:-3px}.grid-reset{position:absolute;inset-inline-end:5px;inset-block-start:0}.icon-thead{text-align:center;margin-bottom:15px}.icon-thead .icon{font-size:30px}.icon-thead .icon-size-sm{transform:rotate(90deg)}.icon-title{display:block;font-size:12px;color:#999;padding:5px 0 0}.djangocms-frontend-preview{position:fixed;inset-block-start:0;inset-inline-end:0;z-index:10;text-align:center;border-radius:0 0 0 3px;padding:10px 20px 27px;border:1px solid var(--dca-gray,var(--hairline-color,#ccc));border-block-start:none;border-inline-end:none;background:var(--body-bg,#fff)}@media (prefers-color-scheme:dark){.djangocms-frontend-preview{background:var(--body-bg,#000)}}.djangocms-frontend-preview h2{font-size:14px;min-width:150px;margin:0 0 12px}.djangocms-frontend-preview .b4-preview{margin:0 0 -15px}.djangocms-frontend-preview .b4-close{position:absolute;inset-inline-end:10px;inset-block-start:8px;z-index:100;display:block;color:#5e5e5e;font-size:12px;line-height:20px;font-weight:700;text-transform:uppercase;width:20px;height:20px;border-radius:3px;background:#ddd}.djangocms-frontend-preview .b4-close:hover{color:#fff!important;text-decoration:none;background:#0bf}.djangocms-frontend-preview .btn>span{vertical-align:middle}.djangocms-frontend-preview .btn>span>.icon{vertical-align:middle}.djangocms-frontend-preview .btn>span svg,.djangocms-frontend-preview .btn>span use{fill:currentColor}.djangocms-frontend-blockquote textarea{height:110px}#id_link_type{padding:0;margin:0;border:none}#id_link_type li{padding:0;margin:0 15px 5px 0;border:none}#id_link_type label input{position:relative;top:-4px}a[data-pk]{position:relative}a[data-pk]:after{content:attr(data-pk);visibility:hidden;width:auto;font-weight:400;font-size:80%;background-color:var(--dca-white,var(--body-bg,#fff));color:var(--dca-gray,var(--body-fg,#333));border:solid 1px var(--dca-gray,var(--body-fg,#333));text-align:center;padding:5px 10px;position:absolute;z-index:1;top:110%;inset-inline-start:50%;margin-inline-start:-50%}a[data-pk]:hover:after{visibility:visible}.djangocms-admin-style .form-row.field-plugin_title input[name=plugin_title_0]{margin-bottom:.5em!important}.djangocms-admin-style .form-row.field-plugin_title input[name=plugin_title_1]{width:calc(100% - 2em)!important}body:not(.djangocms-admin-style) .form-row.field-plugin_title input[name=plugin_title_1]{width:calc(100% - 200px - 1em)!important;margin-inline-start:1em}.frontend-icon-picker{text-align:center;display:inline-block}.frontend-icon-picker .icon-container{position:relative;margin:.5em auto;width:7em;height:7em;border:1px var(--dca-gray-light,var(--border-color,#d3d3d3)) solid;transition:background-color .15s,color .15s}.frontend-icon-picker .icon-container .icon-preview{width:7em;height:7em;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.frontend-icon-picker .icon-container .icon-preview .icon-box{font-size:500%;line-height:1.3;margin:0;text-align:center}.frontend-icon-picker .icon-container .icon-preview .icon-box i,.frontend-icon-picker .icon-container .icon-preview .icon-box span{font-size:unset}.frontend-icon-picker .icon-container .icon-preview .empty-box{text-align:center;overflow:hidden;text-overflow:ellipsis;line-height:1;font-size:100%}.frontend-icon-picker .icon-container .icon-preview .empty-box.hidden{display:none}.frontend-icon-picker .icon-container .icon-preview:hover{background:var(--dca-gray-light,var(--border-color,#d3d3d3));cursor:pointer}.frontend-icon-picker .icon-container .icon-close-indicator{display:block;border-radius:50%;color:var(--dca-black,var(--body-fg,#000));background-color:var(--dca-white,var(--body-bg,#fff));padding:.3rem;border:1px solid var(--dca-black,var(--body-fg,#000));transform:translate(-50%,-50%);top:0;inset-inline-start:100%;width:.6em;height:.6em;line-height:.5em;position:absolute;transition:background-color .15s}.frontend-icon-picker .icon-container .icon-close-indicator:before{content:"×"}.frontend-icon-picker .icon-container .icon-close-indicator:hover{background:var(--delete-button-bg,red);color:var(--delete-button-fg,#fff);cursor:pointer}.uip-modal{position:fixed;height:100%;width:100%;inset-block-end:0;inset-inline-start:0;background-color:rgba(0,0,0,.8);z-index:9999;-webkit-user-select:none;-ms-user-select:none;user-select:none;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.uip-modal *,.uip-modal :after,.uip-modal :before{box-sizing:border-box}.uip-modal.uip-close{opacity:0;visibility:hidden;transition:all .4s ease-in-out}.uip-modal.uip-open{opacity:1;visibility:visible;transition:all .4s ease-in-out}.uip-modal .uip-modal--content{position:absolute;border-radius:3px;box-shadow:2px 8px 23px 3px rgba(0,0,0,.2);overflow:hidden;font-family:Roboto,Arial,Helvetica,Verdana,sans-serif;background-color:var(--dca-gray-lightest,var(--darkened-bg,#f8f8f8));width:100%;margin:auto;left:0;right:0;margin-bottom:2em}.uip-modal .uip-modal--content .uip-modal--header{padding:15px 15px;background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 0 8px rgba(0,0,0,.1);position:relative;z-index:1;font-size:15px;color:var(--dca-gray,var(--body-quiet-color,#666));font-weight:500;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-logo-title{padding-top:2px;line-height:1;text-transform:uppercase;font-weight:700;cursor:pointer}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-close-btn{cursor:pointer}.uip-modal .uip-modal--content .uip-modal--body{font-size:12px;line-height:1.5;box-sizing:border-box;padding:0;height:70vh;display:-ms-flexbox;display:flex;min-height:50px;max-height:85vh;overflow:auto}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar{-ms-flex-negative:0;flex-shrink:0;max-width:25%}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs{margin-top:30px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item{padding:15px;font-size:14px;color:var(--dca-gray,var(--body-quiet-color,#666));text-align:start;cursor:pointer;position:relative;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item i{font-size:20px;padding-inline-end:15px;color:var(--dca-gray-lighter,var(--border-color,#ccc))}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item img{padding-inline-end:15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active{background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 6px 20px 0 rgba(0,0,0,.1)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active:after{content:"";position:absolute;height:100%;width:5px;inset-block-start:0;inset-inline-start:0;background-color:#0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active i{color:#0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item:only-child{display:none}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding:30px 80px 0;width:100%}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner{overflow:auto;margin:25px -15px 0;padding:0 15px 15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview{display:-ms-grid;display:grid;grid-gap:20px;margin:20px 0}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item{position:relative;padding:10px;background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 1px 12px rgba(0,0,0,.05);border-radius:3px;cursor:pointer;transition:all .3s;overflow:hidden}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item:hover{box-shadow:0 1px 14px rgba(0,0,0,.16)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item.universal-selected{box-shadow:0 1px 12px rgba(0,0,0,.05),0 0 0 3px #0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-align:center;align-items:center;padding:1px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item__icon,.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner i{font-size:25px;color:var(--dca-gray-darkest,var(--body-fg,#333))}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item-name{color:var(--dca-gray,var(--body-quiet-color,#666));font-size:11px;padding:13px 0 0;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search{position:relative}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input{width:100%;padding:8px 15px;background-color:var(--dca-white,var(--bg-color,#fff));border:none}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input:-ms-input-placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input::placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search img{position:absolute;top:50%;transform:translateY(-50%);inset-inline-end:10px}.uip-modal .uip-modal--footer{border-top:1px solid var(--dca-gray-lighter,var(--border-color,#ccc));text-align:center;background-color:var(--dca-white,var(--bg-color,#fff));border:none;display:none;-ms-flex-pack:end;justify-content:flex-end;padding:5px;box-shadow:0 0 8px rgba(0,0,0,.1);position:relative;display:-ms-flexbox;display:flex}.uip-modal .uip-modal--footer button.uip-insert-icon-button{padding:10px 35px!important;color:var(--dca-white,var(--bg-color,#fff))!important;background-color:#0bf!important;border:none;cursor:pointer;outline:0}.uip-modal .uip-modal--footer .universal-button{height:40px;margin-inline-start:5px}.uip-modal .uip-modal--footer .universal-button-success{padding:12px 36px;color:var(--dca-white,var(--bg-color,#fff));width:initial}.uip-modal .uip-modal--footer .universal-button-success:hover{background-color:#0bf}@media (min-width:1440px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:1200px}}@media (max-width:1439px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:990px}.uip-modal--icon-preview-wrap{padding:30px 50px 0}}@media (max-width:1023px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:740px}}@media (max-width:767px){.uip-modal--icon-preview-wrap{padding:15px!important}.uip-modal--sidebar{display:none}}@media (min-width:1440px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[7];grid-template-columns:repeat(7,1fr)}}@media (max-width:1439px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[6];grid-template-columns:repeat(6,1fr)}}@media (max-width:1024px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[5];grid-template-columns:repeat(5,1fr)}}@media (max-width:767px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[4];grid-template-columns:repeat(4,1fr)}}@media (max-width:479px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[3];grid-template-columns:repeat(3,1fr)}}@media (max-width:1439px){.uip-modal--sidebar-tab-item{padding:15px 15px 15px 25px;font-size:11px}.uip-modal--sidebar-tab-item i{font-size:15px}}@media (max-width:1024px){.uip-modal--sidebar-tab-item i,.uip-modal--sidebar-tab-item img{display:none}}.sr-only{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}ul.nav{margin-bottom:1em}ul.nav>li.nav-item{list-style-type:none;padding:inherit}.colM ul:not(.object-tools).nav{margin-top:0;margin-bottom:20px}ul.nav:has(>li~div){display:none}ul.nav .nav-item{margin-inline-end:1rem}ul.nav .nav-link{position:relative;text-decoration:none}ul.nav .nav-link span.indicator{display:none;border-radius:50%;padding:.5rem;border:1px solid var(--dca-white,var(--body-bg,#fff));transform:translate(-50%,-50%);inset-block-start:0;inset-inline-start:100%;position:absolute}ul.nav .nav-link span.indicator.error{background-color:var(--bs-danger)}ul.nav .nav-link span.indicator.attributes{background-color:var(--bs-info);display:block}ul.nav .nav-link.error>span.indicator{display:block}ul.nav.nav-pills .nav-link:not(.active){border-style:solid;border-width:1px}body:not(.djangocms-admin-style) ul.djangocms-frontend.nav-tabs+div.tab-content .tab-pane{border-left-style:solid;border-bottom-style:solid;border-right-style:solid;border-left-color:var(--hairline-color);border-bottom-color:var(--hairline-color);border-right-color:var(--hairline-color);border-width:1px}body:not(.djangocms-admin-style) ul.djangocms-frontend.nav-tabs+div.tab-content .tab-pane fieldset:last-child{margin-bottom:0}div.tab-pk{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;color:var(--dca-gray-darker,var(--body-fg,#333));font-size:80%;margin-inline-start:auto}.djangocms-admin-style .colM ul.nav:not(.object-tools):not(.messagelist){margin-top:0}.djangocms-admin-style .colM ul.nav:not(.object-tools):not(.messagelist) li.nav-item{border-top:none}input[type=number].auto-field+span{display:none;position:absolute;inset-block-end:0;inset-inline-end:0;text-align:end;margin-inline-end:31px;margin-block-end:23px;cursor:pointer}body:not(.djangocms-admin-style) input[type=number].auto-field+span{margin-bottom:23px}@media (max-width:1024px){body:not(.djangocms-admin-style) input[type=number].auto-field+span{margin-bottom:24px}}input[type=number].auto-field+span:after{content:"auto"}input[type=number].auto-field.auto{color:var(--dca-white,var(--body-bg,#fff));caret-color:var(--dca-black,var(--body-fg,#000))}input[type=number].auto-field.auto+span{display:block} \ No newline at end of file diff --git a/djangocms_frontend/templates/djangocms_frontend/admin/base-tabs.html b/djangocms_frontend/templates/djangocms_frontend/admin/base-tabs.html index de155e49..481e5f48 100644 --- a/djangocms_frontend/templates/djangocms_frontend/admin/base-tabs.html +++ b/djangocms_frontend/templates/djangocms_frontend/admin/base-tabs.html @@ -7,36 +7,36 @@ {% endblock %} {% block content_subtitle %}{% endblock %} {% block field_sets %} -
    - -
    - {% for fieldset in adminform %} - {% if forloop.counter == 1 or "collapse" in fieldset.classes %} - {% if forloop.counter != 1 %}
    {% endif %} -
    - {% endif %} - {% include "djangocms_frontend/admin/includes/fieldset.html" %} - {% endfor %}{# djlint:off #}
    -
    +
    + +
    + {% for fieldset in adminform %} + {% if forloop.counter == 1 or "collapse" in fieldset.classes %} + {% if forloop.counter != 1 %}
    {% endif %} +
    + {% endif %} + {% include "djangocms_frontend/admin/includes/fieldset.html" %} + {% endfor %}{# djlint:off #}
    +
    {# djlint:on #} {% endblock %} diff --git a/djangocms_frontend/contrib/component/templates/djangocms_frontend/slot.html b/djangocms_frontend/templates/djangocms_frontend/slot.html similarity index 100% rename from djangocms_frontend/contrib/component/templates/djangocms_frontend/slot.html rename to djangocms_frontend/templates/djangocms_frontend/slot.html diff --git a/djangocms_frontend/templatetags/frontend.py b/djangocms_frontend/templatetags/frontend.py index 87172e25..fa12c1a5 100644 --- a/djangocms_frontend/templatetags/frontend.py +++ b/djangocms_frontend/templatetags/frontend.py @@ -159,7 +159,7 @@ def message(self, message): return f"" if django_settings.DEBUG else "" def get_value(self, context, name, kwargs, nodelist): - from djangocms_frontend.component_pool import plugin_tag_pool + from djangocms_frontend.plugin_tag import plugin_tag_pool if name not in plugin_tag_pool: return self.message(f'Plugin "{name}" not found in pool for plugins usable with {{% plugin %}}') diff --git a/djangocms_frontend/ui_plugin_base.py b/djangocms_frontend/ui_plugin_base.py new file mode 100644 index 00000000..c2820c49 --- /dev/null +++ b/djangocms_frontend/ui_plugin_base.py @@ -0,0 +1,58 @@ +# Import the components from the current directory's models module +from cms.plugin_base import CMSPluginBase +from django.utils.encoding import force_str + +from djangocms_frontend.helpers import get_related + +try: + from cms.admin.placeholderadmin import PlaceholderAdmin + + if hasattr(PlaceholderAdmin, "edit_field"): + # FrontendEditable functionality already implemented in core? + class FrontendEditableAdminMixin: + pass + else: + # If not use our own version of the plugin-enabled mixin + raise ImportError +except ImportError: + # django CMS 3 did not implement this: use our own version of the plugin-enabled mixin + from .helpers import FrontendEditableAdminMixin + + class PlaceholderAdmin: + pass + + +class CMSUIPluginBase(FrontendEditableAdminMixin, CMSPluginBase): + render_template = "djangocms_frontend/html_container.html" + change_form_template = "djangocms_frontend/admin/base.html" + + def __str__(self): + return force_str(super().__str__()) + + def render(self, context, instance, placeholder): + for key, value in instance.config.items(): + if isinstance(value, dict) and set(value.keys()) == {"pk", "model"}: + if key not in instance.__dir__(): # hasattr would return the value in the config dict + setattr(instance.__class__, key, get_related(key)) + return super().render(context, instance, placeholder) + + if not hasattr(PlaceholderAdmin, "edit_field"): + # If the PlaceholderAdmin does not have the edit_field method, we need to provide + # the urls and the object getter here + def get_plugin_urls(self): + from django.urls import re_path + + info = f"{self.model._meta.app_label}_{self.model._meta.model_name}" + + def pat(regex, fn): + return re_path(regex, fn, name=f"{info}_{fn.__name__}") + + return [ + pat(r'edit-field/([0-9]+)/([a-z\-]+)/$', self.edit_field), + ] + super().get_plugin_urls() + + def _get_object_for_single_field(self, object_id, language): + # Method to get the object for the single field edit view + from .models import FrontendUIItem + + return FrontendUIItem.objects.get(pk=object_id) diff --git a/docs/source/custom_components.rst b/docs/source/custom_components.rst index 9ce61fb9..15227c26 100644 --- a/docs/source/custom_components.rst +++ b/docs/source/custom_components.rst @@ -1,13 +1,15 @@ -.. _custom_components: - ################# Custom Components ################# +.. index:: + single: Custom Components + .. versionadded:: 2.0 -Some frontend developers prefer custom components specifically tailored to -give the project a unique and distinct look. +Custom components are a powerful tool for content editors, allowing them to build pages without needing +in-depth knowledge of design, HTML, or nested structures. Editors can simply add content to pre-defined +components, creating visually cohesive pages with ease. When working with `Tailwind CSS `_, for example, you either create your custom components or customize components from providers, @@ -15,21 +17,12 @@ e.g. `Tailwind UI `_, `Flowbite `_, or the commiunity `Tailwind Components `_. -With django CMS you make your components available to the content editors for -drag and drop **and** frontend developers for use in templates from a single +With django CMS you make your components available to the content editors to +simply add them to a page by a click **and** frontend developers for use in templates from a single source. -To use custom components in your project, add -``"djangocms_frontend.contrib.component"`` to your ``INSTALLED_APPS`` setting. - -.. code-block:: python - - INSTALLED_APPS = [ - ... - "djangocms_frontend.contrib.component", - ... - ] - +Custom components are part of the djangocms-frontend root package and do not +require additional listing in the ``INSTALLED_APPS`` setting. **djangocms-frontend** will look for custom components in the ``cms_components`` module in any of your apps. This way you can @@ -45,8 +38,10 @@ Add a ``cms_components.py`` file to the ``theme`` app: .. code-block:: python # theme/cms_components.py - from djangocms_frontend.contrib.component.components import ComponentLinkMixin, CMSFrontendComponent - from djangocms_frontend.contrib.component.components import components + from djangocms_link.fields import LinkFormField + + from djangocms_frontend.component_base import CMSFrontendComponent + from djangocms_frontend.component_pool import components from djangocms_frontend.contrib.image.fields import ImageFormField @@ -77,6 +72,7 @@ Add a ``cms_components.py`` file to the ``theme`` app: allow_children = False text = forms.CharField(required=True) + link = LinkFormField() def get_short_description(self): return self.text diff --git a/docs/source/grid.rst b/docs/source/grid.rst index c493c7d0..8cfa7a78 100644 --- a/docs/source/grid.rst +++ b/docs/source/grid.rst @@ -3,7 +3,13 @@ Grid plugins ############## -For details on how grids work, see, e.g. the `Bootstrap 5 documentation +The grid is the basis for responsive page design. It splits the page into +containers, rows and columns. Depending on the device, columns are shown +next to each other (larger screens) or one below the other (smaller +screens). + +The details of the grid system are based on the Bootstrap framework. Therefore, +for details on how grids work, see, e.g. the `Bootstrap 5 documentation `_. .. index:: diff --git a/docs/source/index.rst b/docs/source/index.rst index d1e7257b..8b8e1a2b 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,9 +1,3 @@ -.. - djangocms-blog documentation master file, created by - sphinx-quickstart on Sun Jun 5 23:27:04 2016. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - ################################################ Welcome to djangocms-frontend's documentation! ################################################ @@ -12,11 +6,12 @@ djangocms-frontend ******************** -**djangocms-frontend** is a plugin bundle based on `djangocms_bootstrap5 -`_. Its objective is to -provide a set of popular frontend components independent of the -currently used frontend framework such as Bootstrap, or its specific -version. +**django CMS Frontend** is a plugin bundle which originally built on and improved +the architecture of `djangocms-bootstrap4 `_. +Its objective is to provide a toolset to quickly create re-usable frontend +components and comes preloaded with a set of popular frontend components +independent of the currently used frontend framework such as Bootstrap, or +its specific version. .. image:: ../../preview.png @@ -24,27 +19,28 @@ version. Key features ************** -- Support of `Bootstrap 5 `_. +- **Easy to implement re-usable frontend custom components**, which in the + simples case consist of a template and declarative sort of form class. -- **Separation of plugins from css framework**, i.e., no need to - rebuild you site's plugin tree if css framework is changed in the - future, e.g., from Bootstrap 5 to a future version. +- Support of `Bootstrap 5 `_, django CMS 3.8+ + and django CMS 4 out of the box. -- **New link plugin** allowing to link to internal pages provided by - other applications, such as `djangocms-blog - `_. +- **Separation of plugins from css framework**, i.e. no need to + rebuild you site's plugin tree if css framework is changed in the + future, e.g. from Bootstrap 5 to a future version. -- **Nice and well-arranged admin frontend** of `djangocms-bootstrap4 - `_ +- Leverage of new **djangocms-link features** allowing to link to internal pages + provided by other applications, such as `djangocms-blog + `_. -- Management command to **migrate from djangocms-bootstrap4**. This - command automatically migrates all djangocms-bootstrap4 plugins to - djangocms-frontend. +- **Nice and well-arranged admin frontend** of djangocms-bootstrap4 -- **Extensible** within the project and with separate project (e.g., a - theme app) +- **Extensible** within the project and with separate project (e.g. a + theme app). Create your own components with a few lines of code only. -- **Accordion** plugin. +- **Plugins are re-usable as UI components** anywhere in your project + (e.g. in a custom app) giving your whole project a more consistent + user experience. ************* Description @@ -62,10 +58,6 @@ Instead all design parameters are stored in a common JSON field and future releases of improved frontend features will not require to rebuild your full plugin tree. -The link plugin has been rewritten to not allow internal links to other -CMS pages, but also to other django models such as, e.g., posts of -`djangocms-blog `_. - **djangocms-frontend** provides a set of plugins to structure your layout. This includes three basic elements @@ -80,10 +72,6 @@ Components to grasp and easy to use look. Alerts or cards are examples of components. -Forms - To nicely integrate formss into your page we recommend - **djangocms-form-builder** which works stand-alone but also nicely - integrates with **djangocms-frontend**. Contents ======== @@ -92,9 +80,9 @@ Contents :maxdepth: 3 getting_started + custom_components grid components - custom_components how-to/index reference diff --git a/private/sass/components/_tabs.scss b/private/sass/components/_tabs.scss index 1be37e14..139421a4 100644 --- a/private/sass/components/_tabs.scss +++ b/private/sass/components/_tabs.scss @@ -4,6 +4,10 @@ } ul.nav { + &:has(> li ~ div) { + // Hide single tab + display: none; + } .nav-item { margin-inline-end: 1rem; } diff --git a/pyproject.toml b/pyproject.toml index 2b83d87c..af2ff3d7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,35 +1,126 @@ [tool.black] exclude = [ - ".git", - ".hg", - ".tox", - "venv", - ".venv", - "_build", - "build", - "dist" + ".git", + ".hg", + ".tox", + "venv", + ".venv", + "_build", + "build", + "dist", ] -[tool.djlint] -ignore="H023,T003,H006,H031,D018,H021,H025" -profile="django" - [tool.ruff] +line-length = 119 exclude = [ - ".env", - ".venv", - "**/migrations/**", + "**/migrations/**", + ".env", + ".venv", ] +lint.select = [ + "E", + "F", + "I", + "W", +] + lint.ignore = [ - "E501", # line too long - "F403", # 'from module import *' used; unable to detect undefined names - "E701", # multiple statements on one line (colon) - "F401", # module imported but unused + "E501", # line too long + "E701", # multiple statements on one line (colon) + "F401", # module imported but unused + "F403", # 'from module import *' used; unable to detect undefined names ] -line-length = 119 -lint.select = [ - "I", - "E", - "F", - "W", + +[tool.isort] +line_length = 119 +skip = [ + "manage.py", + "*migrations*", + ".tox", + ".eggs", + ".env", + ".venv", + "data", +] +include_trailing_comma = true +multi_line_output = 5 +lines_after_imports = 2 +default_section = "THIRDPARTY" +sections = [ + "FUTURE", + "STDLIB", + "DJANGO", + "CMS", + "THIRDPARTY", + "FIRSTPARTY", + "LOCALFOLDER", +] +known_first_party = "djangocms_link" +known_cms = [ "cms", "menus" ] +known_django = "django" + +[tool.flake8] +max-line-length = 120 +select = [ + "C", + "E", + "F", + "W", + "B", + "B950", +] +ignore = [ + "W503", # line break before binary operator +] +exclude = [ + "*.egg-info", + ".eggs", + ".env", + ".git", + ".settings", + ".tox", + ".venv", + "build", + "data", + "dist", + "docs", + "*migrations*", + "requirements", + "tmp", +] + +[tool.coverage.run] +branch = true +source = [ "djangocms_frontend" ] +omit = [ + "djangocms_frontend/migrations/*", + "djangocms_frontend/management/*", + "*/foundation6.py", + "tests/*", +] + +[tool.coverage.report] +exclude_lines = [ + "pragma: no cover", + "def __repr__", + "if self.debug:", + "if settings.DEBUG", + "raise AssertionError", + "raise NotImplementedError", + "if 0:", + "if __name__ == .__main__.:", +] +ignore_errors = true + +[tool.djlint] +ignore = "H023,T003,H006,H031,D018,H021,H025" +profile = "django" + +[tool.djlint.rule] +name = "D034" +message = ".pk or .id should only be used with \"|unlocalize\"" +flags = "re.DOTALL|re.I" +patterns = [ + '{{\s*[a-zA-Z0-9_.]+\.pk\s*}}', + '{{\s*[a-zA-Z0-9_.]+\.id\s*}}', ] diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 506f1c46..00000000 --- a/setup.cfg +++ /dev/null @@ -1,33 +0,0 @@ -[flake8] -dictionaries=en_US,python,technical,django -ignore = D203, W503 -select = C,E,F,W,B,B950 -extend-ignore = E203, E501, E731 -max-line-length = 119 -exclude = - *.egg-info, - .eggs, - .git, - .settings, - .tox, - build, - data, - dist, - docs, - *migrations*, - requirements, - tmp - -[isort] -profile = black -;line_length = 119 -;skip = manage.py, *migrations*, .tox, .eggs, data -;include_trailing_comma = true -;multi_line_output = 5 -;not_skip = __init__.py -;lines_after_imports = 2 -;default_section = THIRDPARTY -;sections = FUTURE, STDLIB, DJANGO, CMS, THIRDPARTY, FIRSTPARTY, LIB, LOCALFOLDER -;known_first_party = djangocms_frontend -;known_cms = cms, menus -;known_django = django diff --git a/tests/component/test_models.py b/tests/component/test_models.py index c1fa79c8..001e0d79 100644 --- a/tests/component/test_models.py +++ b/tests/component/test_models.py @@ -1,6 +1,6 @@ from django.test import TestCase -from djangocms_frontend.contrib.component.registry import components +from djangocms_frontend.component_pool import components class ComponentPluginTestCase(TestCase): diff --git a/tests/component/test_plugins.py b/tests/component/test_plugins.py index ec5570d9..3368d341 100644 --- a/tests/component/test_plugins.py +++ b/tests/component/test_plugins.py @@ -1,12 +1,12 @@ from cms.api import add_plugin from cms.test_utils.testcases import CMSTestCase -from djangocms_frontend.contrib.alert.cms_plugins import AlertPlugin -from djangocms_frontend.contrib.component.cms_plugins import ( +from djangocms_frontend.cms_plugins import ( MyButtonPlugin, MyHeroPlugin, MyStrangeComponentPlugin, ) +from djangocms_frontend.contrib.alert.cms_plugins import AlertPlugin from ..fixtures import TestFixture @@ -54,7 +54,7 @@ def test_component_with_empty_slots_plugin(self): ) def test_component_with_slots_plugin(self): - from djangocms_frontend.contrib.component.cms_plugins import MyHeroSlotPlugin + from djangocms_frontend.cms_plugins import MyHeroSlotPlugin instance = add_plugin( placeholder=self.placeholder, @@ -119,10 +119,7 @@ def test_component_with_slots_plugin(self): ) def test_autocreate_slots(self): - from djangocms_frontend.contrib.component.cms_plugins import ( - MyHeroSlotPlugin, - MyHeroTitlePlugin, - ) + from djangocms_frontend.cms_plugins import MyHeroSlotPlugin, MyHeroTitlePlugin instance = add_plugin( placeholder=self.placeholder, @@ -152,7 +149,8 @@ def test_simple_component_plugin(self): instance.config["link"] = {"internal_link": f"cms.page:{self.page.pk}"} instance.save() - link = instance.get_link() + from djangocms_link.templatetags.djangocms_link_tags import to_url + link = to_url(instance.link) self.publish(self.page, self.language) diff --git a/tests/link/test_migration.py b/tests/link/test_migration.py new file mode 100644 index 00000000..77e4104e --- /dev/null +++ b/tests/link/test_migration.py @@ -0,0 +1,27 @@ +from django.test.testcases import TestCase + + +class LinkMigrationTestCase(TestCase): + def setUp(self): + import importlib + + link_migration = importlib.import_module("djangocms_frontend.migrations.0002_migrate_links") + self.convert = staticmethod(link_migration.convert_item) + + def test_link_migration(self): + test_links = ( + dict(external_link="https://www.django-cms.com"), + dict(external_link="https://www.django-cms.com", anchor="top"), + dict(internal_link=dict(model="cms.page", pk=1)), + dict(internal_link=dict(model="cms.page", pk=1), anchor="top"), + dict(file_link=dict(model="filer.file", pk=1)), + dict(phone="1234567890"), + dict(mailto="mail@example.com") + ) + + for link in test_links: + with self.subTest(link=link): + config = link.copy() + self.convert(config, "forward") + self.convert(config, "backward") + self.assertEqual(link, config) diff --git a/tests/requirements/base.txt b/tests/requirements/base.txt index c3393eab..983fd9c0 100644 --- a/tests/requirements/base.txt +++ b/tests/requirements/base.txt @@ -13,3 +13,5 @@ django-filer html5lib git+https://github.com/django-cms/djangocms-link@feat/url-mngr -e . +pytest +pytest-django diff --git a/tests/test_app/cms_components.py b/tests/test_app/cms_components.py index 20890102..ba7e5721 100644 --- a/tests/test_app/cms_components.py +++ b/tests/test_app/cms_components.py @@ -1,10 +1,8 @@ from django import forms +from djangocms_link.fields import LinkFormField -from djangocms_frontend.contrib.component.components import ( - CMSFrontendComponent, - ComponentLinkMixin, -) -from djangocms_frontend.contrib.component.registry import components +from djangocms_frontend.component_base import CMSFrontendComponent +from djangocms_frontend.component_pool import components from djangocms_frontend.contrib.image.fields import ImageFormField @@ -33,13 +31,14 @@ def get_short_description(self): @components.register -class MyButton(ComponentLinkMixin, CMSFrontendComponent): +class MyButton(CMSFrontendComponent): class Meta: name = "Button" render_template = "button.html" allow_children = False text = forms.CharField(required=True, initial="Click me") + link = LinkFormField() def get_short_description(self): return self.text diff --git a/tests/test_app/templates/button.html b/tests/test_app/templates/button.html index 218fe92a..c145c6eb 100644 --- a/tests/test_app/templates/button.html +++ b/tests/test_app/templates/button.html @@ -1 +1 @@ -{{ instance.text }} +{% load djangocms_link_tags %}{{ instance.text }} diff --git a/tests/test_plugin_tag.py b/tests/test_plugin_tag.py index e1f074e3..1d01cb3d 100644 --- a/tests/test_plugin_tag.py +++ b/tests/test_plugin_tag.py @@ -80,14 +80,14 @@ def test_link_plugin(self): {% plugin "textlink" name="Click" url_grouper=grouper site=test_site link_type="btn" link_context="primary" link_outline=False %} Click me! {% endplugin %} - """) # noqa: B950 + """) # noqa: B950,E501 else: grouper = None template = django_engine.from_string("""{% load frontend djangocms_link_tags %}{{ "test"|to_link }} {% plugin "textlink" name="Click" link="/test/"|to_link link_type="btn" link_context="primary" link_outline=False %} Click me! {% endplugin %} - """) # noqa: B950 + """) # noqa: B950,E501 expected_result = """Click me!""" diff --git a/tests/test_settings.py b/tests/test_settings.py index 96e1511a..68ea56b6 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -23,7 +23,6 @@ "djangocms_frontend.contrib.card", "djangocms_frontend.contrib.carousel", "djangocms_frontend.contrib.collapse", - "djangocms_frontend.contrib.component", "djangocms_frontend.contrib.content", "djangocms_frontend.contrib.grid", "djangocms_frontend.contrib.icon", diff --git a/tests/utilities/test_plugins.py b/tests/utilities/test_plugins.py index ee3f6987..4e7b3915 100644 --- a/tests/utilities/test_plugins.py +++ b/tests/utilities/test_plugins.py @@ -8,6 +8,7 @@ TOCPlugin, ) from djangocms_frontend.contrib.utilities.forms import TableOfContentsForm +from djangocms_frontend.ui_plugin_base import PlaceholderAdmin from ..fixtures import TestFixture @@ -100,8 +101,12 @@ def test_heading_inline_endpoint(self): "heading_id": "id1", }, ) - url_endpoint = admin_reverse("utilities_heading_edit_field", args=[heading.pk, self.language]) - url_endpoint += "?edit_fields=heading" + + if hasattr(PlaceholderAdmin, "edit_field"): + url_endpoint = "cms_placeholder_edit_field" + else: + url_endpoint = "utilities_heading_edit_field" + url_endpoint = admin_reverse(url_endpoint, args=[heading.pk, self.language]) + "?edit_fields=heading" data = { "heading": "My new heading", } From 784f40f8c511622fcfc9b7fb2a3e631ad2ade8e6 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Mon, 11 Nov 2024 20:08:55 +0100 Subject: [PATCH 58/66] Fix template --- djangocms_frontend/templates/djangocms_frontend.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/djangocms_frontend/templates/djangocms_frontend.html b/djangocms_frontend/templates/djangocms_frontend.html index 0d9d974e..db9a13d2 100644 --- a/djangocms_frontend/templates/djangocms_frontend.html +++ b/djangocms_frontend/templates/djangocms_frontend.html @@ -6,9 +6,9 @@ {% block meta %} - + - + {% endblock meta %} {% block canonical_url %} From 90716ac9cdb0e58d253203600226245e35186a3f Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Tue, 19 Nov 2024 09:24:45 +0100 Subject: [PATCH 59/66] Update djangocms_frontend/migrations/0002_migrate_links.py --- djangocms_frontend/migrations/0002_migrate_links.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/djangocms_frontend/migrations/0002_migrate_links.py b/djangocms_frontend/migrations/0002_migrate_links.py index aeec1205..a125f8c1 100644 --- a/djangocms_frontend/migrations/0002_migrate_links.py +++ b/djangocms_frontend/migrations/0002_migrate_links.py @@ -5,8 +5,8 @@ def convert_item(config, direction): """Convert FrontendUIItem config to new djangocms_link format.""" if direction == "forward": if config.get("external_link"): - if config.get("anchor"): - anchor = "#" + config.get("anchor") + if (config.get("anchor") or "").strip(): + anchor = "#" + config.get("anchor").strip() del config["anchor"] else: anchor = "" From 4b279b772388050627f52b8f16242c4e2d47f1b3 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Tue, 19 Nov 2024 09:29:53 +0100 Subject: [PATCH 60/66] Resolve typos from code review --- README.rst | 2 +- docs/source/custom_components.rst | 2 +- docs/source/how-to/internal-link-targets.rst | 2 +- docs/source/index.rst | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 42b7e33f..b4c64bd3 100644 --- a/README.rst +++ b/README.rst @@ -17,7 +17,7 @@ Key features ============ - **Easy to implement re-usable frontend custom components**, which in the - simples case consist of a template and declarative sort of form class. + simplest case consist of a template and declarative sort of form class. - Support of `Bootstrap 5 `_, django CMS 3.8+ and django CMS 4 out of the box. diff --git a/docs/source/custom_components.rst b/docs/source/custom_components.rst index 15227c26..79b99ee3 100644 --- a/docs/source/custom_components.rst +++ b/docs/source/custom_components.rst @@ -14,7 +14,7 @@ components, creating visually cohesive pages with ease. When working with `Tailwind CSS `_, for example, you either create your custom components or customize components from providers, e.g. `Tailwind UI `_, -`Flowbite `_, or the commiunity +`Flowbite `_, or the community `Tailwind Components `_. With django CMS you make your components available to the content editors to diff --git a/docs/source/how-to/internal-link-targets.rst b/docs/source/how-to/internal-link-targets.rst index 8f727713..c253f4fb 100644 --- a/docs/source/how-to/internal-link-targets.rst +++ b/docs/source/how-to/internal-link-targets.rst @@ -10,7 +10,7 @@ autodetect linkable models. This means that any model that has a ``get_absolute_url()`` method and a ``search_fields`` attribute in its ``ModelAdmin`` will be available as an internal link target. -The ``DJANGOCMS_FRONTEND_LINK_MODELS`` setting if djangocms-frontend before +The ``DJANGOCMS_FRONTEND_LINK_MODELS`` setting in djangocms-frontend before version 2 does not have any effect anymore. See the README file of `djangocms-link `_ diff --git a/docs/source/index.rst b/docs/source/index.rst index 8b8e1a2b..b0e2ce3c 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -20,7 +20,7 @@ its specific version. ************** - **Easy to implement re-usable frontend custom components**, which in the - simples case consist of a template and declarative sort of form class. + simplest case consist of a template and declarative sort of form class. - Support of `Bootstrap 5 `_, django CMS 3.8+ and django CMS 4 out of the box. From ff809bf7b74b9297236f655515991321e0c7d484 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Wed, 20 Nov 2024 20:11:09 +0100 Subject: [PATCH 61/66] Update __init__.py --- djangocms_frontend/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/djangocms_frontend/__init__.py b/djangocms_frontend/__init__.py index f4bc00fb..0a6d3925 100644 --- a/djangocms_frontend/__init__.py +++ b/djangocms_frontend/__init__.py @@ -19,4 +19,4 @@ 13. Github actions will publish the new package to pypi """ -__version__ = "2.0.0a" +__version__ = "2.0.0a1" From 02ef1b9936d10ca7225204e72bcb115b00de7d26 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Wed, 20 Nov 2024 20:12:25 +0100 Subject: [PATCH 62/66] Update setup.py --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 20d7727e..0109b7f8 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,8 @@ "django-cms>=3.7", "django-filer>=1.7", "easy-thumbnails", - "djangocms-attributes-field>=1", + "djangocms-attributes-field>=4", + "djangocms-link>=5", "django-entangled>=0.6", ] From b6f14700ab6d340d6b9171ec63857872a1619383 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Wed, 20 Nov 2024 20:12:53 +0100 Subject: [PATCH 63/66] Update base.txt --- tests/requirements/base.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/requirements/base.txt b/tests/requirements/base.txt index 983fd9c0..ba833b92 100644 --- a/tests/requirements/base.txt +++ b/tests/requirements/base.txt @@ -11,7 +11,6 @@ pre-commit djangocms-text django-filer html5lib -git+https://github.com/django-cms/djangocms-link@feat/url-mngr -e . pytest pytest-django From 5776cd1899cd68f5060ae83142f129bc63e7fbde Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Wed, 20 Nov 2024 20:41:04 +0100 Subject: [PATCH 64/66] feat: Check for link configuration --- djangocms_frontend/apps.py | 63 ++++++++++++++----- .../static/djangocms_frontend/css/base.css | 2 +- private/sass/components/_tabs.scss | 2 +- pyproject.toml | 20 +++--- 4 files changed, 59 insertions(+), 28 deletions(-) diff --git a/djangocms_frontend/apps.py b/djangocms_frontend/apps.py index b17215bf..4c36f5a3 100644 --- a/djangocms_frontend/apps.py +++ b/djangocms_frontend/apps.py @@ -10,6 +10,7 @@ def ready(self): from . import plugin_tag checks.register(check_settings) + checks.register(check_installed_apps) plugin_tag.setup() @@ -19,21 +20,51 @@ def check_settings(*args, **kwargs): warnings = [] if hasattr(settings, "DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH"): # pragma: no cover - warnings.append(checks.Warning( - "The DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH setting was removed in djangocms-frontend 2.\n" - "Use DJANGOCMS_LINK_MINIMUM_INPUT_LENGTH instead.", - "This message disappears after removing the DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH from your project's " - "settings.\n", - id="djangocms_frontend.W001", - obj="settings.DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH", - )) + warnings.append( + checks.Warning( + "The DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH setting was removed in djangocms-frontend 2.\n" + "Use DJANGOCMS_LINK_MINIMUM_INPUT_LENGTH instead.", + "This message disappears after removing the DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH from " + "your project's settings.\n", + id="djangocms_frontend.W001", + obj="settings.DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH", + ) + ) if hasattr(settings, "DJANGOCMS_FRONTEND_LINK_MODELS"): # pragma: no cover - warnings.append(checks.Warning( - "The DJANGOCMS_FRONTEND_LINK_MODELS setting was removed in djangocms-frontend 2.\n" - "djangocms-frontend 2 uses linkable models from djangocms-link. See " - "https://github.com/django-cms/djangocms-link#django-cms-link for more info.", - "This message disappears after removing the DJANGOCMS_FRONTEND_LINK_MODELS from your project's settings.\n", - id="djangocms_frontend.W002", - obj="settings.DJANGOCMS_FRONTEND_LINK_MODELS", - )) + warnings.append( + checks.Warning( + "The DJANGOCMS_FRONTEND_LINK_MODELS setting was removed in djangocms-frontend 2.\n" + "djangocms-frontend 2 uses linkable models from djangocms-link. See " + "https://github.com/django-cms/djangocms-link#django-cms-link for more info.", + "This message disappears after removing the DJANGOCMS_FRONTEND_LINK_MODELS from your " + "project's settings.\n", + id="djangocms_frontend.W002", + obj="settings.DJANGOCMS_FRONTEND_LINK_MODELS", + ) + ) return warnings + + +def check_installed_apps(app_configs, **kwargs): + from django.conf import settings + + errors = [] + link_contrib_apps = [ + "djangocms_frontend.contrib.carousel", + "djangocms_frontend.contrib.image", + "djangocms_frontend.contrib.link", + ] + + if any(app in settings.INSTALLED_APPS for app in link_contrib_apps): + if "djangocms_link" not in settings.INSTALLED_APPS: # pragma: no cover + errors.append( + checks.Error( + "djangocms-frontend requires djangocms-link to be installed for the following plugins: {}.\n" + "Add 'djangocms_link' to your INSTALLED_APPS setting or remove all of the above apps.".format( + ", ".join(link_contrib_apps) + ), + id="djangocms_frontend.E001", + obj="settings.INSTALLED_APPS", + ) + ) + return errors diff --git a/djangocms_frontend/static/djangocms_frontend/css/base.css b/djangocms_frontend/static/djangocms_frontend/css/base.css index f9ccbb45..e86c384f 100644 --- a/djangocms_frontend/static/djangocms_frontend/css/base.css +++ b/djangocms_frontend/static/djangocms_frontend/css/base.css @@ -5,4 +5,4 @@ /private/sass instead */ -@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:0.8125rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#0d6efd;--bs-link-hover-color:#0a58ca;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-size:0.8125rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#212529;--bs-btn-bg:transparent;--bs-btn-border-width:1px;--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-ms-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.015625rem;--bs-btn-border-radius:0.5rem}.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.7109375rem;--bs-btn-border-radius:0.25rem}.link-primary{color:#0d6efd!important}.link-primary:focus,.link-primary:hover{color:#0a58ca!important}.link-secondary{color:#6c757d!important}.link-secondary:focus,.link-secondary:hover{color:#565e64!important}.link-success{color:#198754!important}.link-success:focus,.link-success:hover{color:#146c43!important}.link-info{color:#0dcaf0!important}.link-info:focus,.link-info:hover{color:#3dd5f3!important}.link-warning{color:#ffc107!important}.link-warning:focus,.link-warning:hover{color:#ffcd39!important}.link-danger{color:#dc3545!important}.link-danger:focus,.link-danger:hover{color:#b02a37!important}.link-light{color:#f8f9fa!important}.link-light:focus,.link-light:hover{color:#f9fafb!important}.link-dark{color:#212529!important}.link-dark:focus,.link-dark:hover{color:#1a1e21!important}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.3rem;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#6c757d;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:1px;--bs-nav-tabs-border-color:#dee2e6;--bs-nav-tabs-border-radius:0.375rem;--bs-nav-tabs-link-hover-border-color:#e9ecef #e9ecef #dee2e6;--bs-nav-tabs-link-active-color:#495057;--bs-nav-tabs-link-active-bg:#fff;--bs-nav-tabs-link-active-border-color:#dee2e6 #dee2e6 #fff;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:4px;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0bf}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.icon{display:inline-block;vertical-align:top;width:1em;height:1em;background-position:center;background-repeat:no-repeat}.icon svg{display:block;width:100%;height:100%}.icon-info{width:.9em;font-size:110%!important}.icon-white{color:#fff}.icon-white svg{fill:#fff}.icon-black{color:#000}.icon-black svg{fill:#000}.icon-primary{color:#0bf}.icon-primary svg{fill:#0bf}.djangocms-icon .icon>input{float:left;position:relative;top:12px}.djangocms-icon .caret{margin-inline-start:8px}.aligned .frontend-button-group label{min-width:unset}.frontend-button-group{display:inline-block}.frontend-button-group .btn{box-sizing:border-box;cursor:pointer;-webkit-appearance:none;margin:2px;overflow:hidden;text-overflow:ellipsis}.frontend-button-group .btn.active{outline:3px solid #0bf;border-color:#fff!important}.frontend-button-group .btn-default.active{border-radius:0;background-color:#0bf!important}.frontend-button-group-context-colors>div,.frontend-button-group-context-size>div{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;min-height:75px}.frontend-button-group-context-colors .btn{-ms-flex-preferred-size:calc(25% - 4px);flex-basis:calc(25% - 4px)}@media (min-width:820px){.frontend-button-group-context-colors .btn{-ms-flex-preferred-size:calc(20% - 4px);flex-basis:calc(20% - 4px)}}.frontend-button-group-icons .icon,.frontend-grid-icons .icon{font-size:24px}.frontend-button-group-icons .icon-flex-align-center,.frontend-button-group-icons .icon-flex-align-end,.frontend-button-group-icons .icon-flex-align-start,.frontend-grid-icons .icon-flex-align-center,.frontend-grid-icons .icon-flex-align-end,.frontend-grid-icons .icon-flex-align-start{transform:scale(1.4)}.frontend-button-group-icons .icon-flex-content-around,.frontend-button-group-icons .icon-flex-content-between,.frontend-grid-icons .icon-flex-content-around,.frontend-grid-icons .icon-flex-content-between{transform:scale(1.6)}.frontend-button-group-icons .icon-flex-self-center,.frontend-button-group-icons .icon-flex-self-end,.frontend-button-group-icons .icon-flex-self-start,.frontend-grid-icons .icon-flex-self-center,.frontend-grid-icons .icon-flex-self-end,.frontend-grid-icons .icon-flex-self-start{transform:scale(1.4)}.frontend-button-group-icons .icon-align-reset,.frontend-button-group-icons .icon-no-selection,.frontend-grid-icons .icon-align-reset,.frontend-grid-icons .icon-no-selection{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-align-items-start,.frontend-button-group-icons .icon-flex-align-start,.frontend-grid-icons .icon-align-items-start,.frontend-grid-icons .icon-flex-align-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-items-center,.frontend-button-group-icons .icon-flex-align-center,.frontend-grid-icons .icon-align-items-center,.frontend-grid-icons .icon-flex-align-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-items-end,.frontend-button-group-icons .icon-flex-align-end,.frontend-grid-icons .icon-align-items-end,.frontend-grid-icons .icon-flex-align-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-flex-content-start,.frontend-button-group-icons .icon-justify-content-start,.frontend-button-group-icons .icon-start,.frontend-grid-icons .icon-flex-content-start,.frontend-grid-icons .icon-justify-content-start,.frontend-grid-icons .icon-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-center,.frontend-button-group-icons .icon-flex-content-center,.frontend-button-group-icons .icon-justify-content-center,.frontend-grid-icons .icon-center,.frontend-grid-icons .icon-flex-content-center,.frontend-grid-icons .icon-justify-content-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-end,.frontend-button-group-icons .icon-flex-content-end,.frontend-button-group-icons .icon-justify-content-end,.frontend-grid-icons .icon-end,.frontend-grid-icons .icon-flex-content-end,.frontend-grid-icons .icon-justify-content-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-flex-content-around,.frontend-button-group-icons .icon-justify-content-around,.frontend-grid-icons .icon-flex-content-around,.frontend-grid-icons .icon-justify-content-around{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.6)}.frontend-button-group-icons .icon-flex-content-between,.frontend-button-group-icons .icon-justify-content-between,.frontend-grid-icons .icon-flex-content-between,.frontend-grid-icons .icon-justify-content-between{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.6)}.frontend-button-group-icons .icon-nav-fill,.frontend-grid-icons .icon-nav-fill{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-nav-justified,.frontend-grid-icons .icon-nav-justified{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-flex-column,.frontend-grid-icons .icon-flex-column{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-start,.frontend-button-group-icons .icon-flex-self-start,.frontend-grid-icons .icon-align-self-start,.frontend-grid-icons .icon-flex-self-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-center,.frontend-button-group-icons .icon-flex-self-center,.frontend-grid-icons .icon-align-self-center,.frontend-grid-icons .icon-flex-self-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-end,.frontend-button-group-icons .icon-flex-self-end,.frontend-grid-icons .icon-align-self-end,.frontend-grid-icons .icon-flex-self-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-size-sm,.frontend-button-group-icons .icon-size-xs,.frontend-button-group-icons .icon-sm,.frontend-button-group-icons .icon-xs,.frontend-grid-icons .icon-size-sm,.frontend-grid-icons .icon-size-xs,.frontend-grid-icons .icon-sm,.frontend-grid-icons .icon-xs{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-sm,.frontend-button-group-icons .icon-sm,.frontend-grid-icons .icon-size-sm,.frontend-grid-icons .icon-sm{transform:rotate(-90deg)}.frontend-button-group-icons .icon-md,.frontend-button-group-icons .icon-size-md,.frontend-grid-icons .icon-md,.frontend-grid-icons .icon-size-md{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-lg,.frontend-button-group-icons .icon-size-lg,.frontend-grid-icons .icon-lg,.frontend-grid-icons .icon-size-lg{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-xl,.frontend-button-group-icons .icon-xl,.frontend-grid-icons .icon-size-xl,.frontend-grid-icons .icon-xl{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-xxl,.frontend-button-group-icons .icon-xxl,.frontend-grid-icons .icon-size-xxl,.frontend-grid-icons .icon-xxl{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-mb,.frontend-grid-icons .icon-mb{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-me,.frontend-grid-icons .icon-me{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-ms,.frontend-grid-icons .icon-ms{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-mt,.frontend-grid-icons .icon-mt{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-mx,.frontend-grid-icons .icon-mx{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-my,.frontend-grid-icons .icon-my{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pb,.frontend-grid-icons .icon-pb{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pe,.frontend-grid-icons .icon-pe{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-ps,.frontend-grid-icons .icon-ps{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pt,.frontend-grid-icons .icon-pt{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-px,.frontend-grid-icons .icon-px{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-py,.frontend-grid-icons .icon-py{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.icon-info{background-image:url('data:image/svg+xml;utf8,')}.module{margin:0 0 20px}.djangocms-frontend-row .form-row.field-create .icon{position:absolute;font-size:30px;margin-block-start:28px;margin-inline-start:4px}.djangocms-frontend-row .form-row.field-create input[name=create]{width:130px!important;padding-inline-end:5px!important;text-align:start}.djangocms-frontend-column .form-row.field-xs_col,.djangocms-frontend-column .form-row.field-xs_me,.djangocms-frontend-column .form-row.field-xs_ms,.djangocms-frontend-column .form-row.field-xs_offset,.djangocms-frontend-column .form-row.field-xs_order,.djangocms-frontend-row .form-row.field-row_cols_xs{position:relative;display:-ms-flexbox;display:flex;padding:0;min-width:800px}.djangocms-frontend-column .form-row.field-xs_col>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_me>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_ms>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_offset>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_order>div>div:not([class]),.djangocms-frontend-row .form-row.field-row_cols_xs>div>div:not([class]){width:unset!important;max-width:unset!important}.djangocms-frontend-column .form-row.field-xs_col .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_me .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_ms .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_offset .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_order .field-box:first-child,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box:first-child{width:115px!important}.djangocms-frontend-column .form-row.field-xs_col .field-box,.djangocms-frontend-column .form-row.field-xs_col .fieldBox,.djangocms-frontend-column .form-row.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_me .fieldBox,.djangocms-frontend-column .form-row.field-xs_ms .field-box,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox,.djangocms-frontend-column .form-row.field-xs_offset .field-box,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox,.djangocms-frontend-column .form-row.field-xs_order .field-box,.djangocms-frontend-column .form-row.field-xs_order .fieldBox,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox{position:relative;box-sizing:content-box;width:86px!important;-ms-flex:none;flex:none;display:block;padding:15px 10px;margin:0!important;border-bottom:1px solid #eee;float:left!important}.djangocms-frontend-column .form-row.field-xs_col .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_col .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_me .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_me .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_ms .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_ms .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_offset .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_offset .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_order .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_order .fieldBox input:not([type=checkbox]),.djangocms-frontend-row .form-row.field-row_cols_xs .field-box input:not([type=checkbox]),.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox input:not([type=checkbox]){text-align:end;padding-inline-end:5px!important;box-sizing:border-box;width:100%}.djangocms-frontend-column .form-row.field-xs_col .field-box label,.djangocms-frontend-column .form-row.field-xs_col .fieldBox label,.djangocms-frontend-column .form-row.field-xs_me .field-box label,.djangocms-frontend-column .form-row.field-xs_me .fieldBox label,.djangocms-frontend-column .form-row.field-xs_ms .field-box label,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox label,.djangocms-frontend-column .form-row.field-xs_offset .field-box label,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox label,.djangocms-frontend-column .form-row.field-xs_order .field-box label,.djangocms-frontend-column .form-row.field-xs_order .fieldBox label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box label,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox label{font-size:12px!important;font-weight:400!important;color:#ccc!important;position:absolute;inset-inline-start:15px;inset-block-end:17px;text-transform:lowercase}.djangocms-frontend-column .form-row.field-xs_col .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_col .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_me .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_me .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_ms .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_offset .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_order .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_order .fieldBox .disabled,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box .disabled,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox .disabled{color:#ccc;background:#eee}.djangocms-frontend-column .form-row.field-xs_col .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_col .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_me .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_me .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_ms .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_offset .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_order .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_order .fieldBox:last-child,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box:last-child,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox:last-child{border-inline-end:none}.djangocms-frontend-column .form-row.field-xs_col .errors,.djangocms-frontend-column .form-row.field-xs_me .errors,.djangocms-frontend-column .form-row.field-xs_ms .errors,.djangocms-frontend-column .form-row.field-xs_offset .errors,.djangocms-frontend-column .form-row.field-xs_order .errors,.djangocms-frontend-row .form-row.field-row_cols_xs .errors{margin-bottom:0}.djangocms-frontend-column .form-row.field-xs_col .errorlist,.djangocms-frontend-column .form-row.field-xs_me .errorlist,.djangocms-frontend-column .form-row.field-xs_ms .errorlist,.djangocms-frontend-column .form-row.field-xs_offset .errorlist,.djangocms-frontend-column .form-row.field-xs_order .errorlist,.djangocms-frontend-row .form-row.field-row_cols_xs .errorlist{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.djangocms-frontend-column .form-row.field-xs_col.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_me.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_ms.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_offset.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_order.field-xs_me .field-box,.djangocms-frontend-row .form-row.field-row_cols_xs.field-xs_me .field-box{border-bottom:none}.djangocms-frontend-column .form-row.field-xs_col .field-box-label,.djangocms-frontend-column .form-row.field-xs_me .field-box-label,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label,.djangocms-frontend-column .form-row.field-xs_order .field-box-label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label{display:-ms-flexbox;display:flex;margin-top:auto;color:#999}.djangocms-frontend-column .form-row.field-xs_col .field-box-label a,.djangocms-frontend-column .form-row.field-xs_me .field-box-label a,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label a,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label a,.djangocms-frontend-column .form-row.field-xs_order .field-box-label a,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label a{width:100%;margin-top:auto;color:#999}.djangocms-frontend-column .form-row.field-xs_col .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_me .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_order .field-box-label a a,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label a a{width:100%;margin-top:auto}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_col .field-md_me,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_me .field-md_me,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_order .field-md_me,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms{text-align:start}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-md_me label,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-md_me label,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-md_me label,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms label{inset-inline-start:30px;inset-block-start:14px}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-md_me input,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-md_me input,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-md_me input,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms input{position:relative;box-sizing:border-box;top:-3px}.grid-reset{position:absolute;inset-inline-end:5px;inset-block-start:0}.icon-thead{text-align:center;margin-bottom:15px}.icon-thead .icon{font-size:30px}.icon-thead .icon-size-sm{transform:rotate(90deg)}.icon-title{display:block;font-size:12px;color:#999;padding:5px 0 0}.djangocms-frontend-preview{position:fixed;inset-block-start:0;inset-inline-end:0;z-index:10;text-align:center;border-radius:0 0 0 3px;padding:10px 20px 27px;border:1px solid var(--dca-gray,var(--hairline-color,#ccc));border-block-start:none;border-inline-end:none;background:var(--body-bg,#fff)}@media (prefers-color-scheme:dark){.djangocms-frontend-preview{background:var(--body-bg,#000)}}.djangocms-frontend-preview h2{font-size:14px;min-width:150px;margin:0 0 12px}.djangocms-frontend-preview .b4-preview{margin:0 0 -15px}.djangocms-frontend-preview .b4-close{position:absolute;inset-inline-end:10px;inset-block-start:8px;z-index:100;display:block;color:#5e5e5e;font-size:12px;line-height:20px;font-weight:700;text-transform:uppercase;width:20px;height:20px;border-radius:3px;background:#ddd}.djangocms-frontend-preview .b4-close:hover{color:#fff!important;text-decoration:none;background:#0bf}.djangocms-frontend-preview .btn>span{vertical-align:middle}.djangocms-frontend-preview .btn>span>.icon{vertical-align:middle}.djangocms-frontend-preview .btn>span svg,.djangocms-frontend-preview .btn>span use{fill:currentColor}.djangocms-frontend-blockquote textarea{height:110px}#id_link_type{padding:0;margin:0;border:none}#id_link_type li{padding:0;margin:0 15px 5px 0;border:none}#id_link_type label input{position:relative;top:-4px}a[data-pk]{position:relative}a[data-pk]:after{content:attr(data-pk);visibility:hidden;width:auto;font-weight:400;font-size:80%;background-color:var(--dca-white,var(--body-bg,#fff));color:var(--dca-gray,var(--body-fg,#333));border:solid 1px var(--dca-gray,var(--body-fg,#333));text-align:center;padding:5px 10px;position:absolute;z-index:1;top:110%;inset-inline-start:50%;margin-inline-start:-50%}a[data-pk]:hover:after{visibility:visible}.djangocms-admin-style .form-row.field-plugin_title input[name=plugin_title_0]{margin-bottom:.5em!important}.djangocms-admin-style .form-row.field-plugin_title input[name=plugin_title_1]{width:calc(100% - 2em)!important}body:not(.djangocms-admin-style) .form-row.field-plugin_title input[name=plugin_title_1]{width:calc(100% - 200px - 1em)!important;margin-inline-start:1em}.frontend-icon-picker{text-align:center;display:inline-block}.frontend-icon-picker .icon-container{position:relative;margin:.5em auto;width:7em;height:7em;border:1px var(--dca-gray-light,var(--border-color,#d3d3d3)) solid;transition:background-color .15s,color .15s}.frontend-icon-picker .icon-container .icon-preview{width:7em;height:7em;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.frontend-icon-picker .icon-container .icon-preview .icon-box{font-size:500%;line-height:1.3;margin:0;text-align:center}.frontend-icon-picker .icon-container .icon-preview .icon-box i,.frontend-icon-picker .icon-container .icon-preview .icon-box span{font-size:unset}.frontend-icon-picker .icon-container .icon-preview .empty-box{text-align:center;overflow:hidden;text-overflow:ellipsis;line-height:1;font-size:100%}.frontend-icon-picker .icon-container .icon-preview .empty-box.hidden{display:none}.frontend-icon-picker .icon-container .icon-preview:hover{background:var(--dca-gray-light,var(--border-color,#d3d3d3));cursor:pointer}.frontend-icon-picker .icon-container .icon-close-indicator{display:block;border-radius:50%;color:var(--dca-black,var(--body-fg,#000));background-color:var(--dca-white,var(--body-bg,#fff));padding:.3rem;border:1px solid var(--dca-black,var(--body-fg,#000));transform:translate(-50%,-50%);top:0;inset-inline-start:100%;width:.6em;height:.6em;line-height:.5em;position:absolute;transition:background-color .15s}.frontend-icon-picker .icon-container .icon-close-indicator:before{content:"×"}.frontend-icon-picker .icon-container .icon-close-indicator:hover{background:var(--delete-button-bg,red);color:var(--delete-button-fg,#fff);cursor:pointer}.uip-modal{position:fixed;height:100%;width:100%;inset-block-end:0;inset-inline-start:0;background-color:rgba(0,0,0,.8);z-index:9999;-webkit-user-select:none;-ms-user-select:none;user-select:none;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.uip-modal *,.uip-modal :after,.uip-modal :before{box-sizing:border-box}.uip-modal.uip-close{opacity:0;visibility:hidden;transition:all .4s ease-in-out}.uip-modal.uip-open{opacity:1;visibility:visible;transition:all .4s ease-in-out}.uip-modal .uip-modal--content{position:absolute;border-radius:3px;box-shadow:2px 8px 23px 3px rgba(0,0,0,.2);overflow:hidden;font-family:Roboto,Arial,Helvetica,Verdana,sans-serif;background-color:var(--dca-gray-lightest,var(--darkened-bg,#f8f8f8));width:100%;margin:auto;left:0;right:0;margin-bottom:2em}.uip-modal .uip-modal--content .uip-modal--header{padding:15px 15px;background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 0 8px rgba(0,0,0,.1);position:relative;z-index:1;font-size:15px;color:var(--dca-gray,var(--body-quiet-color,#666));font-weight:500;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-logo-title{padding-top:2px;line-height:1;text-transform:uppercase;font-weight:700;cursor:pointer}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-close-btn{cursor:pointer}.uip-modal .uip-modal--content .uip-modal--body{font-size:12px;line-height:1.5;box-sizing:border-box;padding:0;height:70vh;display:-ms-flexbox;display:flex;min-height:50px;max-height:85vh;overflow:auto}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar{-ms-flex-negative:0;flex-shrink:0;max-width:25%}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs{margin-top:30px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item{padding:15px;font-size:14px;color:var(--dca-gray,var(--body-quiet-color,#666));text-align:start;cursor:pointer;position:relative;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item i{font-size:20px;padding-inline-end:15px;color:var(--dca-gray-lighter,var(--border-color,#ccc))}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item img{padding-inline-end:15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active{background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 6px 20px 0 rgba(0,0,0,.1)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active:after{content:"";position:absolute;height:100%;width:5px;inset-block-start:0;inset-inline-start:0;background-color:#0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active i{color:#0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item:only-child{display:none}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding:30px 80px 0;width:100%}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner{overflow:auto;margin:25px -15px 0;padding:0 15px 15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview{display:-ms-grid;display:grid;grid-gap:20px;margin:20px 0}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item{position:relative;padding:10px;background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 1px 12px rgba(0,0,0,.05);border-radius:3px;cursor:pointer;transition:all .3s;overflow:hidden}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item:hover{box-shadow:0 1px 14px rgba(0,0,0,.16)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item.universal-selected{box-shadow:0 1px 12px rgba(0,0,0,.05),0 0 0 3px #0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-align:center;align-items:center;padding:1px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item__icon,.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner i{font-size:25px;color:var(--dca-gray-darkest,var(--body-fg,#333))}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item-name{color:var(--dca-gray,var(--body-quiet-color,#666));font-size:11px;padding:13px 0 0;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search{position:relative}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input{width:100%;padding:8px 15px;background-color:var(--dca-white,var(--bg-color,#fff));border:none}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input:-ms-input-placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input::placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search img{position:absolute;top:50%;transform:translateY(-50%);inset-inline-end:10px}.uip-modal .uip-modal--footer{border-top:1px solid var(--dca-gray-lighter,var(--border-color,#ccc));text-align:center;background-color:var(--dca-white,var(--bg-color,#fff));border:none;display:none;-ms-flex-pack:end;justify-content:flex-end;padding:5px;box-shadow:0 0 8px rgba(0,0,0,.1);position:relative;display:-ms-flexbox;display:flex}.uip-modal .uip-modal--footer button.uip-insert-icon-button{padding:10px 35px!important;color:var(--dca-white,var(--bg-color,#fff))!important;background-color:#0bf!important;border:none;cursor:pointer;outline:0}.uip-modal .uip-modal--footer .universal-button{height:40px;margin-inline-start:5px}.uip-modal .uip-modal--footer .universal-button-success{padding:12px 36px;color:var(--dca-white,var(--bg-color,#fff));width:initial}.uip-modal .uip-modal--footer .universal-button-success:hover{background-color:#0bf}@media (min-width:1440px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:1200px}}@media (max-width:1439px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:990px}.uip-modal--icon-preview-wrap{padding:30px 50px 0}}@media (max-width:1023px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:740px}}@media (max-width:767px){.uip-modal--icon-preview-wrap{padding:15px!important}.uip-modal--sidebar{display:none}}@media (min-width:1440px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[7];grid-template-columns:repeat(7,1fr)}}@media (max-width:1439px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[6];grid-template-columns:repeat(6,1fr)}}@media (max-width:1024px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[5];grid-template-columns:repeat(5,1fr)}}@media (max-width:767px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[4];grid-template-columns:repeat(4,1fr)}}@media (max-width:479px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[3];grid-template-columns:repeat(3,1fr)}}@media (max-width:1439px){.uip-modal--sidebar-tab-item{padding:15px 15px 15px 25px;font-size:11px}.uip-modal--sidebar-tab-item i{font-size:15px}}@media (max-width:1024px){.uip-modal--sidebar-tab-item i,.uip-modal--sidebar-tab-item img{display:none}}.sr-only{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}ul.nav{margin-bottom:1em}ul.nav>li.nav-item{list-style-type:none;padding:inherit}.colM ul:not(.object-tools).nav{margin-top:0;margin-bottom:20px}ul.nav:has(>li~div){display:none}ul.nav .nav-item{margin-inline-end:1rem}ul.nav .nav-link{position:relative;text-decoration:none}ul.nav .nav-link span.indicator{display:none;border-radius:50%;padding:.5rem;border:1px solid var(--dca-white,var(--body-bg,#fff));transform:translate(-50%,-50%);inset-block-start:0;inset-inline-start:100%;position:absolute}ul.nav .nav-link span.indicator.error{background-color:var(--bs-danger)}ul.nav .nav-link span.indicator.attributes{background-color:var(--bs-info);display:block}ul.nav .nav-link.error>span.indicator{display:block}ul.nav.nav-pills .nav-link:not(.active){border-style:solid;border-width:1px}body:not(.djangocms-admin-style) ul.djangocms-frontend.nav-tabs+div.tab-content .tab-pane{border-left-style:solid;border-bottom-style:solid;border-right-style:solid;border-left-color:var(--hairline-color);border-bottom-color:var(--hairline-color);border-right-color:var(--hairline-color);border-width:1px}body:not(.djangocms-admin-style) ul.djangocms-frontend.nav-tabs+div.tab-content .tab-pane fieldset:last-child{margin-bottom:0}div.tab-pk{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;color:var(--dca-gray-darker,var(--body-fg,#333));font-size:80%;margin-inline-start:auto}.djangocms-admin-style .colM ul.nav:not(.object-tools):not(.messagelist){margin-top:0}.djangocms-admin-style .colM ul.nav:not(.object-tools):not(.messagelist) li.nav-item{border-top:none}input[type=number].auto-field+span{display:none;position:absolute;inset-block-end:0;inset-inline-end:0;text-align:end;margin-inline-end:31px;margin-block-end:23px;cursor:pointer}body:not(.djangocms-admin-style) input[type=number].auto-field+span{margin-bottom:23px}@media (max-width:1024px){body:not(.djangocms-admin-style) input[type=number].auto-field+span{margin-bottom:24px}}input[type=number].auto-field+span:after{content:"auto"}input[type=number].auto-field.auto{color:var(--dca-white,var(--body-bg,#fff));caret-color:var(--dca-black,var(--body-fg,#000))}input[type=number].auto-field.auto+span{display:block} \ No newline at end of file +@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:0.8125rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-bg:#fff;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#0d6efd;--bs-link-hover-color:#0a58ca;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-size:0.8125rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#212529;--bs-btn-bg:transparent;--bs-btn-border-width:1px;--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-ms-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.015625rem;--bs-btn-border-radius:0.5rem}.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.7109375rem;--bs-btn-border-radius:0.25rem}.link-primary{color:#0d6efd!important}.link-primary:focus,.link-primary:hover{color:#0a58ca!important}.link-secondary{color:#6c757d!important}.link-secondary:focus,.link-secondary:hover{color:#565e64!important}.link-success{color:#198754!important}.link-success:focus,.link-success:hover{color:#146c43!important}.link-info{color:#0dcaf0!important}.link-info:focus,.link-info:hover{color:#3dd5f3!important}.link-warning{color:#ffc107!important}.link-warning:focus,.link-warning:hover{color:#ffcd39!important}.link-danger{color:#dc3545!important}.link-danger:focus,.link-danger:hover{color:#b02a37!important}.link-light{color:#f8f9fa!important}.link-light:focus,.link-light:hover{color:#f9fafb!important}.link-dark{color:#212529!important}.link-dark:focus,.link-dark:hover{color:#1a1e21!important}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.3rem;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#6c757d;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:1px;--bs-nav-tabs-border-color:#dee2e6;--bs-nav-tabs-border-radius:0.375rem;--bs-nav-tabs-link-hover-border-color:#e9ecef #e9ecef #dee2e6;--bs-nav-tabs-link-active-color:#495057;--bs-nav-tabs-link-active-bg:#fff;--bs-nav-tabs-link-active-border-color:#dee2e6 #dee2e6 #fff;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:4px;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0bf}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.icon{display:inline-block;vertical-align:top;width:1em;height:1em;background-position:center;background-repeat:no-repeat}.icon svg{display:block;width:100%;height:100%}.icon-info{width:.9em;font-size:110%!important}.icon-white{color:#fff}.icon-white svg{fill:#fff}.icon-black{color:#000}.icon-black svg{fill:#000}.icon-primary{color:#0bf}.icon-primary svg{fill:#0bf}.djangocms-icon .icon>input{float:left;position:relative;top:12px}.djangocms-icon .caret{margin-inline-start:8px}.aligned .frontend-button-group label{min-width:unset}.frontend-button-group{display:inline-block}.frontend-button-group .btn{box-sizing:border-box;cursor:pointer;-webkit-appearance:none;margin:2px;overflow:hidden;text-overflow:ellipsis}.frontend-button-group .btn.active{outline:3px solid #0bf;border-color:#fff!important}.frontend-button-group .btn-default.active{border-radius:0;background-color:#0bf!important}.frontend-button-group-context-colors>div,.frontend-button-group-context-size>div{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;min-height:75px}.frontend-button-group-context-colors .btn{-ms-flex-preferred-size:calc(25% - 4px);flex-basis:calc(25% - 4px)}@media (min-width:820px){.frontend-button-group-context-colors .btn{-ms-flex-preferred-size:calc(20% - 4px);flex-basis:calc(20% - 4px)}}.frontend-button-group-icons .icon,.frontend-grid-icons .icon{font-size:24px}.frontend-button-group-icons .icon-flex-align-center,.frontend-button-group-icons .icon-flex-align-end,.frontend-button-group-icons .icon-flex-align-start,.frontend-grid-icons .icon-flex-align-center,.frontend-grid-icons .icon-flex-align-end,.frontend-grid-icons .icon-flex-align-start{transform:scale(1.4)}.frontend-button-group-icons .icon-flex-content-around,.frontend-button-group-icons .icon-flex-content-between,.frontend-grid-icons .icon-flex-content-around,.frontend-grid-icons .icon-flex-content-between{transform:scale(1.6)}.frontend-button-group-icons .icon-flex-self-center,.frontend-button-group-icons .icon-flex-self-end,.frontend-button-group-icons .icon-flex-self-start,.frontend-grid-icons .icon-flex-self-center,.frontend-grid-icons .icon-flex-self-end,.frontend-grid-icons .icon-flex-self-start{transform:scale(1.4)}.frontend-button-group-icons .icon-align-reset,.frontend-button-group-icons .icon-no-selection,.frontend-grid-icons .icon-align-reset,.frontend-grid-icons .icon-no-selection{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-align-items-start,.frontend-button-group-icons .icon-flex-align-start,.frontend-grid-icons .icon-align-items-start,.frontend-grid-icons .icon-flex-align-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-items-center,.frontend-button-group-icons .icon-flex-align-center,.frontend-grid-icons .icon-align-items-center,.frontend-grid-icons .icon-flex-align-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-items-end,.frontend-button-group-icons .icon-flex-align-end,.frontend-grid-icons .icon-align-items-end,.frontend-grid-icons .icon-flex-align-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-flex-content-start,.frontend-button-group-icons .icon-justify-content-start,.frontend-button-group-icons .icon-start,.frontend-grid-icons .icon-flex-content-start,.frontend-grid-icons .icon-justify-content-start,.frontend-grid-icons .icon-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-center,.frontend-button-group-icons .icon-flex-content-center,.frontend-button-group-icons .icon-justify-content-center,.frontend-grid-icons .icon-center,.frontend-grid-icons .icon-flex-content-center,.frontend-grid-icons .icon-justify-content-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-end,.frontend-button-group-icons .icon-flex-content-end,.frontend-button-group-icons .icon-justify-content-end,.frontend-grid-icons .icon-end,.frontend-grid-icons .icon-flex-content-end,.frontend-grid-icons .icon-justify-content-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-flex-content-around,.frontend-button-group-icons .icon-justify-content-around,.frontend-grid-icons .icon-flex-content-around,.frontend-grid-icons .icon-justify-content-around{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.6)}.frontend-button-group-icons .icon-flex-content-between,.frontend-button-group-icons .icon-justify-content-between,.frontend-grid-icons .icon-flex-content-between,.frontend-grid-icons .icon-justify-content-between{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.6)}.frontend-button-group-icons .icon-nav-fill,.frontend-grid-icons .icon-nav-fill{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-nav-justified,.frontend-grid-icons .icon-nav-justified{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-flex-column,.frontend-grid-icons .icon-flex-column{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-start,.frontend-button-group-icons .icon-flex-self-start,.frontend-grid-icons .icon-align-self-start,.frontend-grid-icons .icon-flex-self-start{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-center,.frontend-button-group-icons .icon-flex-self-center,.frontend-grid-icons .icon-align-self-center,.frontend-grid-icons .icon-flex-self-center{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-align-self-end,.frontend-button-group-icons .icon-flex-self-end,.frontend-grid-icons .icon-align-self-end,.frontend-grid-icons .icon-flex-self-end{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16));transform:scale(1.4)}.frontend-button-group-icons .icon-size-sm,.frontend-button-group-icons .icon-size-xs,.frontend-button-group-icons .icon-sm,.frontend-button-group-icons .icon-xs,.frontend-grid-icons .icon-size-sm,.frontend-grid-icons .icon-size-xs,.frontend-grid-icons .icon-sm,.frontend-grid-icons .icon-xs{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-sm,.frontend-button-group-icons .icon-sm,.frontend-grid-icons .icon-size-sm,.frontend-grid-icons .icon-sm{transform:rotate(-90deg)}.frontend-button-group-icons .icon-md,.frontend-button-group-icons .icon-size-md,.frontend-grid-icons .icon-md,.frontend-grid-icons .icon-size-md{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-lg,.frontend-button-group-icons .icon-size-lg,.frontend-grid-icons .icon-lg,.frontend-grid-icons .icon-size-lg{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-xl,.frontend-button-group-icons .icon-xl,.frontend-grid-icons .icon-size-xl,.frontend-grid-icons .icon-xl{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-size-xxl,.frontend-button-group-icons .icon-xxl,.frontend-grid-icons .icon-size-xxl,.frontend-grid-icons .icon-xxl{background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 16))}.frontend-button-group-icons .icon-mb,.frontend-grid-icons .icon-mb{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-me,.frontend-grid-icons .icon-me{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-ms,.frontend-grid-icons .icon-ms{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-mt,.frontend-grid-icons .icon-mt{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-mx,.frontend-grid-icons .icon-mx{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-my,.frontend-grid-icons .icon-my{transform:scale(1.3);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pb,.frontend-grid-icons .icon-pb{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pe,.frontend-grid-icons .icon-pe{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-ps,.frontend-grid-icons .icon-ps{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-pt,.frontend-grid-icons .icon-pt{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-px,.frontend-grid-icons .icon-px{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.frontend-button-group-icons .icon-py,.frontend-grid-icons .icon-py{transform:scale(1.5);background-image:url('data:image/svg+xml;utf8,');filter:brightness(calc(var(--dca-light-mode, 1) + var(--dca-dark-mode, 0) * 100))}.icon-info{background-image:url('data:image/svg+xml;utf8,')}.module{margin:0 0 20px}.djangocms-frontend-row .form-row.field-create .icon{position:absolute;font-size:30px;margin-block-start:28px;margin-inline-start:4px}.djangocms-frontend-row .form-row.field-create input[name=create]{width:130px!important;padding-inline-end:5px!important;text-align:start}.djangocms-frontend-column .form-row.field-xs_col,.djangocms-frontend-column .form-row.field-xs_me,.djangocms-frontend-column .form-row.field-xs_ms,.djangocms-frontend-column .form-row.field-xs_offset,.djangocms-frontend-column .form-row.field-xs_order,.djangocms-frontend-row .form-row.field-row_cols_xs{position:relative;display:-ms-flexbox;display:flex;padding:0;min-width:800px}.djangocms-frontend-column .form-row.field-xs_col>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_me>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_ms>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_offset>div>div:not([class]),.djangocms-frontend-column .form-row.field-xs_order>div>div:not([class]),.djangocms-frontend-row .form-row.field-row_cols_xs>div>div:not([class]){width:unset!important;max-width:unset!important}.djangocms-frontend-column .form-row.field-xs_col .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_me .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_ms .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_offset .field-box:first-child,.djangocms-frontend-column .form-row.field-xs_order .field-box:first-child,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box:first-child{width:115px!important}.djangocms-frontend-column .form-row.field-xs_col .field-box,.djangocms-frontend-column .form-row.field-xs_col .fieldBox,.djangocms-frontend-column .form-row.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_me .fieldBox,.djangocms-frontend-column .form-row.field-xs_ms .field-box,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox,.djangocms-frontend-column .form-row.field-xs_offset .field-box,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox,.djangocms-frontend-column .form-row.field-xs_order .field-box,.djangocms-frontend-column .form-row.field-xs_order .fieldBox,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox{position:relative;box-sizing:content-box;width:86px!important;-ms-flex:none;flex:none;display:block;padding:15px 10px;margin:0!important;border-bottom:1px solid #eee;float:left!important}.djangocms-frontend-column .form-row.field-xs_col .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_col .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_me .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_me .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_ms .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_ms .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_offset .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_offset .fieldBox input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_order .field-box input:not([type=checkbox]),.djangocms-frontend-column .form-row.field-xs_order .fieldBox input:not([type=checkbox]),.djangocms-frontend-row .form-row.field-row_cols_xs .field-box input:not([type=checkbox]),.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox input:not([type=checkbox]){text-align:end;padding-inline-end:5px!important;box-sizing:border-box;width:100%}.djangocms-frontend-column .form-row.field-xs_col .field-box label,.djangocms-frontend-column .form-row.field-xs_col .fieldBox label,.djangocms-frontend-column .form-row.field-xs_me .field-box label,.djangocms-frontend-column .form-row.field-xs_me .fieldBox label,.djangocms-frontend-column .form-row.field-xs_ms .field-box label,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox label,.djangocms-frontend-column .form-row.field-xs_offset .field-box label,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox label,.djangocms-frontend-column .form-row.field-xs_order .field-box label,.djangocms-frontend-column .form-row.field-xs_order .fieldBox label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box label,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox label{font-size:12px!important;font-weight:400!important;color:#ccc!important;position:absolute;inset-inline-start:15px;inset-block-end:17px;text-transform:lowercase}.djangocms-frontend-column .form-row.field-xs_col .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_col .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_me .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_me .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_ms .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_offset .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox .disabled,.djangocms-frontend-column .form-row.field-xs_order .field-box .disabled,.djangocms-frontend-column .form-row.field-xs_order .fieldBox .disabled,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box .disabled,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox .disabled{color:#ccc;background:#eee}.djangocms-frontend-column .form-row.field-xs_col .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_col .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_me .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_me .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_ms .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_ms .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_offset .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_offset .fieldBox:last-child,.djangocms-frontend-column .form-row.field-xs_order .field-box:last-child,.djangocms-frontend-column .form-row.field-xs_order .fieldBox:last-child,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box:last-child,.djangocms-frontend-row .form-row.field-row_cols_xs .fieldBox:last-child{border-inline-end:none}.djangocms-frontend-column .form-row.field-xs_col .errors,.djangocms-frontend-column .form-row.field-xs_me .errors,.djangocms-frontend-column .form-row.field-xs_ms .errors,.djangocms-frontend-column .form-row.field-xs_offset .errors,.djangocms-frontend-column .form-row.field-xs_order .errors,.djangocms-frontend-row .form-row.field-row_cols_xs .errors{margin-bottom:0}.djangocms-frontend-column .form-row.field-xs_col .errorlist,.djangocms-frontend-column .form-row.field-xs_me .errorlist,.djangocms-frontend-column .form-row.field-xs_ms .errorlist,.djangocms-frontend-column .form-row.field-xs_offset .errorlist,.djangocms-frontend-column .form-row.field-xs_order .errorlist,.djangocms-frontend-row .form-row.field-row_cols_xs .errorlist{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.djangocms-frontend-column .form-row.field-xs_col.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_me.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_ms.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_offset.field-xs_me .field-box,.djangocms-frontend-column .form-row.field-xs_order.field-xs_me .field-box,.djangocms-frontend-row .form-row.field-row_cols_xs.field-xs_me .field-box{border-bottom:none}.djangocms-frontend-column .form-row.field-xs_col .field-box-label,.djangocms-frontend-column .form-row.field-xs_me .field-box-label,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label,.djangocms-frontend-column .form-row.field-xs_order .field-box-label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label{display:-ms-flexbox;display:flex;margin-top:auto;color:#999}.djangocms-frontend-column .form-row.field-xs_col .field-box-label a,.djangocms-frontend-column .form-row.field-xs_me .field-box-label a,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label a,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label a,.djangocms-frontend-column .form-row.field-xs_order .field-box-label a,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label a{width:100%;margin-top:auto;color:#999}.djangocms-frontend-column .form-row.field-xs_col .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_me .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_ms .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_offset .field-box-label a a,.djangocms-frontend-column .form-row.field-xs_order .field-box-label a a,.djangocms-frontend-row .form-row.field-row_cols_xs .field-box-label a a{width:100%;margin-top:auto}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_col .field-md_me,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_me .field-md_me,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms,.djangocms-frontend-column .form-row.field-xs_order .field-md_me,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms{text-align:start}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-md_me label,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-md_me label,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me label,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-md_me label,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me label,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms label,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me label,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me label,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms label{inset-inline-start:30px;inset-block-start:14px}.djangocms-frontend-column .form-row.field-xs_col .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_col .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-md_me input,.djangocms-frontend-column .form-row.field-xs_col .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_col .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_col .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_me .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-md_me input,.djangocms-frontend-column .form-row.field-xs_me .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_me .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_me .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-md_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_ms .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-md_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_offset .field-xxl_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-lg_me input,.djangocms-frontend-column .form-row.field-xs_order .field-lg_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-md_me input,.djangocms-frontend-column .form-row.field-xs_order .field-md_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-sm_me input,.djangocms-frontend-column .form-row.field-xs_order .field-sm_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xl_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xl_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xs_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xs_ms input,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_me input,.djangocms-frontend-column .form-row.field-xs_order .field-xxl_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-lg_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-md_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-sm_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xl_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xs_ms input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_me input,.djangocms-frontend-row .form-row.field-row_cols_xs .field-xxl_ms input{position:relative;box-sizing:border-box;top:-3px}.grid-reset{position:absolute;inset-inline-end:5px;inset-block-start:0}.icon-thead{text-align:center;margin-bottom:15px}.icon-thead .icon{font-size:30px}.icon-thead .icon-size-sm{transform:rotate(90deg)}.icon-title{display:block;font-size:12px;color:#999;padding:5px 0 0}.djangocms-frontend-preview{position:fixed;inset-block-start:0;inset-inline-end:0;z-index:10;text-align:center;border-radius:0 0 0 3px;padding:10px 20px 27px;border:1px solid var(--dca-gray,var(--hairline-color,#ccc));border-block-start:none;border-inline-end:none;background:var(--body-bg,#fff)}@media (prefers-color-scheme:dark){.djangocms-frontend-preview{background:var(--body-bg,#000)}}.djangocms-frontend-preview h2{font-size:14px;min-width:150px;margin:0 0 12px}.djangocms-frontend-preview .b4-preview{margin:0 0 -15px}.djangocms-frontend-preview .b4-close{position:absolute;inset-inline-end:10px;inset-block-start:8px;z-index:100;display:block;color:#5e5e5e;font-size:12px;line-height:20px;font-weight:700;text-transform:uppercase;width:20px;height:20px;border-radius:3px;background:#ddd}.djangocms-frontend-preview .b4-close:hover{color:#fff!important;text-decoration:none;background:#0bf}.djangocms-frontend-preview .btn>span{vertical-align:middle}.djangocms-frontend-preview .btn>span>.icon{vertical-align:middle}.djangocms-frontend-preview .btn>span svg,.djangocms-frontend-preview .btn>span use{fill:currentColor}.djangocms-frontend-blockquote textarea{height:110px}#id_link_type{padding:0;margin:0;border:none}#id_link_type li{padding:0;margin:0 15px 5px 0;border:none}#id_link_type label input{position:relative;top:-4px}a[data-pk]{position:relative}a[data-pk]:after{content:attr(data-pk);visibility:hidden;width:auto;font-weight:400;font-size:80%;background-color:var(--dca-white,var(--body-bg,#fff));color:var(--dca-gray,var(--body-fg,#333));border:solid 1px var(--dca-gray,var(--body-fg,#333));text-align:center;padding:5px 10px;position:absolute;z-index:1;top:110%;inset-inline-start:50%;margin-inline-start:-50%}a[data-pk]:hover:after{visibility:visible}.djangocms-admin-style .form-row.field-plugin_title input[name=plugin_title_0]{margin-bottom:.5em!important}.djangocms-admin-style .form-row.field-plugin_title input[name=plugin_title_1]{width:calc(100% - 2em)!important}body:not(.djangocms-admin-style) .form-row.field-plugin_title input[name=plugin_title_1]{width:calc(100% - 200px - 1em)!important;margin-inline-start:1em}.frontend-icon-picker{text-align:center;display:inline-block}.frontend-icon-picker .icon-container{position:relative;margin:.5em auto;width:7em;height:7em;border:1px var(--dca-gray-light,var(--border-color,#d3d3d3)) solid;transition:background-color .15s,color .15s}.frontend-icon-picker .icon-container .icon-preview{width:7em;height:7em;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.frontend-icon-picker .icon-container .icon-preview .icon-box{font-size:500%;line-height:1.3;margin:0;text-align:center}.frontend-icon-picker .icon-container .icon-preview .icon-box i,.frontend-icon-picker .icon-container .icon-preview .icon-box span{font-size:unset}.frontend-icon-picker .icon-container .icon-preview .empty-box{text-align:center;overflow:hidden;text-overflow:ellipsis;line-height:1;font-size:100%}.frontend-icon-picker .icon-container .icon-preview .empty-box.hidden{display:none}.frontend-icon-picker .icon-container .icon-preview:hover{background:var(--dca-gray-light,var(--border-color,#d3d3d3));cursor:pointer}.frontend-icon-picker .icon-container .icon-close-indicator{display:block;border-radius:50%;color:var(--dca-black,var(--body-fg,#000));background-color:var(--dca-white,var(--body-bg,#fff));padding:.3rem;border:1px solid var(--dca-black,var(--body-fg,#000));transform:translate(-50%,-50%);top:0;inset-inline-start:100%;width:.6em;height:.6em;line-height:.5em;position:absolute;transition:background-color .15s}.frontend-icon-picker .icon-container .icon-close-indicator:before{content:"×"}.frontend-icon-picker .icon-container .icon-close-indicator:hover{background:var(--delete-button-bg,red);color:var(--delete-button-fg,#fff);cursor:pointer}.uip-modal{position:fixed;height:100%;width:100%;inset-block-end:0;inset-inline-start:0;background-color:rgba(0,0,0,.8);z-index:9999;-webkit-user-select:none;-ms-user-select:none;user-select:none;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.uip-modal *,.uip-modal :after,.uip-modal :before{box-sizing:border-box}.uip-modal.uip-close{opacity:0;visibility:hidden;transition:all .4s ease-in-out}.uip-modal.uip-open{opacity:1;visibility:visible;transition:all .4s ease-in-out}.uip-modal .uip-modal--content{position:absolute;border-radius:3px;box-shadow:2px 8px 23px 3px rgba(0,0,0,.2);overflow:hidden;font-family:Roboto,Arial,Helvetica,Verdana,sans-serif;background-color:var(--dca-gray-lightest,var(--darkened-bg,#f8f8f8));width:100%;margin:auto;left:0;right:0;margin-bottom:2em}.uip-modal .uip-modal--content .uip-modal--header{padding:15px 15px;background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 0 8px rgba(0,0,0,.1);position:relative;z-index:1;font-size:15px;color:var(--dca-gray,var(--body-quiet-color,#666));font-weight:500;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-logo-title{padding-top:2px;line-height:1;text-transform:uppercase;font-weight:700;cursor:pointer}.uip-modal .uip-modal--content .uip-modal--header .uip-modal--header-close-btn{cursor:pointer}.uip-modal .uip-modal--content .uip-modal--body{font-size:12px;line-height:1.5;box-sizing:border-box;padding:0;height:70vh;display:-ms-flexbox;display:flex;min-height:50px;max-height:85vh;overflow:auto}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar{-ms-flex-negative:0;flex-shrink:0;max-width:25%}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs{margin-top:30px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item{padding:15px;font-size:14px;color:var(--dca-gray,var(--body-quiet-color,#666));text-align:start;cursor:pointer;position:relative;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item i{font-size:20px;padding-inline-end:15px;color:var(--dca-gray-lighter,var(--border-color,#ccc))}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item img{padding-inline-end:15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active{background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 6px 20px 0 rgba(0,0,0,.1)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active:after{content:"";position:absolute;height:100%;width:5px;inset-block-start:0;inset-inline-start:0;background-color:#0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item.universal-active i{color:#0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--sidebar .uip-modal--sidebar-tabs .uip-modal--sidebar-tab-item:only-child{display:none}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding:30px 80px 0;width:100%}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner{overflow:auto;margin:25px -15px 0;padding:0 15px 15px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview{display:-ms-grid;display:grid;grid-gap:20px;margin:20px 0}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item{position:relative;padding:10px;background-color:var(--dca-white,var(--bg-color,#fff));box-shadow:0 1px 12px rgba(0,0,0,.05);border-radius:3px;cursor:pointer;transition:all .3s;overflow:hidden}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item:hover{box-shadow:0 1px 14px rgba(0,0,0,.16)}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item.universal-selected{box-shadow:0 1px 12px rgba(0,0,0,.05),0 0 0 3px #0bf}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-align:center;align-items:center;padding:1px}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item__icon,.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner i{font-size:25px;color:var(--dca-gray-darkest,var(--body-fg,#333))}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-preview-inner .uip-modal--icon-preview .uip-icon-item .uip-icon-item-inner .uip-icon-item-name{color:var(--dca-gray,var(--body-quiet-color,#666));font-size:11px;padding:13px 0 0;max-width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-transform:capitalize}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search{position:relative}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input{width:100%;padding:8px 15px;background-color:var(--dca-white,var(--bg-color,#fff));border:none}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input:-ms-input-placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search input::placeholder{font-style:italic}.uip-modal .uip-modal--content .uip-modal--body .uip-modal--icon-preview-wrap .uip-modal--icon-search img{position:absolute;top:50%;transform:translateY(-50%);inset-inline-end:10px}.uip-modal .uip-modal--footer{border-top:1px solid var(--dca-gray-lighter,var(--border-color,#ccc));text-align:center;background-color:var(--dca-white,var(--bg-color,#fff));border:none;display:none;-ms-flex-pack:end;justify-content:flex-end;padding:5px;box-shadow:0 0 8px rgba(0,0,0,.1);position:relative;display:-ms-flexbox;display:flex}.uip-modal .uip-modal--footer button.uip-insert-icon-button{padding:10px 35px!important;color:var(--dca-white,var(--bg-color,#fff))!important;background-color:#0bf!important;border:none;cursor:pointer;outline:0}.uip-modal .uip-modal--footer .universal-button{height:40px;margin-inline-start:5px}.uip-modal .uip-modal--footer .universal-button-success{padding:12px 36px;color:var(--dca-white,var(--bg-color,#fff));width:initial}.uip-modal .uip-modal--footer .universal-button-success:hover{background-color:#0bf}@media (min-width:1440px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:1200px}}@media (max-width:1439px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:990px}.uip-modal--icon-preview-wrap{padding:30px 50px 0}}@media (max-width:1023px){body:not(.cms-admin-modal) .uip-modal .uip-modal--content{max-width:740px}}@media (max-width:767px){.uip-modal--icon-preview-wrap{padding:15px!important}.uip-modal--sidebar{display:none}}@media (min-width:1440px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[7];grid-template-columns:repeat(7,1fr)}}@media (max-width:1439px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[6];grid-template-columns:repeat(6,1fr)}}@media (max-width:1024px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[5];grid-template-columns:repeat(5,1fr)}}@media (max-width:767px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[4];grid-template-columns:repeat(4,1fr)}}@media (max-width:479px){.uip-modal--icon-preview{-ms-grid-columns:(1fr)[3];grid-template-columns:repeat(3,1fr)}}@media (max-width:1439px){.uip-modal--sidebar-tab-item{padding:15px 15px 15px 25px;font-size:11px}.uip-modal--sidebar-tab-item i{font-size:15px}}@media (max-width:1024px){.uip-modal--sidebar-tab-item i,.uip-modal--sidebar-tab-item img{display:none}}.sr-only{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}ul.nav{margin-bottom:1em}ul.nav>li.nav-item{list-style-type:none;padding:inherit}.colM ul:not(.object-tools).nav{margin-top:0;margin-bottom:20px}ul.nav:not(:has(>li:nth-child(2))){display:none}ul.nav .nav-item{margin-inline-end:1rem}ul.nav .nav-link{position:relative;text-decoration:none}ul.nav .nav-link span.indicator{display:none;border-radius:50%;padding:.5rem;border:1px solid var(--dca-white,var(--body-bg,#fff));transform:translate(-50%,-50%);inset-block-start:0;inset-inline-start:100%;position:absolute}ul.nav .nav-link span.indicator.error{background-color:var(--bs-danger)}ul.nav .nav-link span.indicator.attributes{background-color:var(--bs-info);display:block}ul.nav .nav-link.error>span.indicator{display:block}ul.nav.nav-pills .nav-link:not(.active){border-style:solid;border-width:1px}body:not(.djangocms-admin-style) ul.djangocms-frontend.nav-tabs+div.tab-content .tab-pane{border-left-style:solid;border-bottom-style:solid;border-right-style:solid;border-left-color:var(--hairline-color);border-bottom-color:var(--hairline-color);border-right-color:var(--hairline-color);border-width:1px}body:not(.djangocms-admin-style) ul.djangocms-frontend.nav-tabs+div.tab-content .tab-pane fieldset:last-child{margin-bottom:0}div.tab-pk{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;color:var(--dca-gray-darker,var(--body-fg,#333));font-size:80%;margin-inline-start:auto}.djangocms-admin-style .colM ul.nav:not(.object-tools):not(.messagelist){margin-top:0}.djangocms-admin-style .colM ul.nav:not(.object-tools):not(.messagelist) li.nav-item{border-top:none}input[type=number].auto-field+span{display:none;position:absolute;inset-block-end:0;inset-inline-end:0;text-align:end;margin-inline-end:31px;margin-block-end:23px;cursor:pointer}body:not(.djangocms-admin-style) input[type=number].auto-field+span{margin-bottom:23px}@media (max-width:1024px){body:not(.djangocms-admin-style) input[type=number].auto-field+span{margin-bottom:24px}}input[type=number].auto-field+span:after{content:"auto"}input[type=number].auto-field.auto{color:var(--dca-white,var(--body-bg,#fff));caret-color:var(--dca-black,var(--body-fg,#000))}input[type=number].auto-field.auto+span{display:block} \ No newline at end of file diff --git a/private/sass/components/_tabs.scss b/private/sass/components/_tabs.scss index 139421a4..b4244f2c 100644 --- a/private/sass/components/_tabs.scss +++ b/private/sass/components/_tabs.scss @@ -4,7 +4,7 @@ } ul.nav { - &:has(> li ~ div) { + &:not(:has(> li:nth-child(2))) { // Hide single tab display: none; } diff --git a/pyproject.toml b/pyproject.toml index af2ff3d7..c8c183e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,14 +1,14 @@ [tool.black] -exclude = [ - ".git", - ".hg", - ".tox", - "venv", - ".venv", - "_build", - "build", - "dist", -] +exclude = ''' + .git + .hg + .tox + venv + .venv + _build + build + dist +''' [tool.ruff] line-length = 119 From a6a20259c175ae5e46f01caeedcf953c1cf8eaa4 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Wed, 20 Nov 2024 21:15:36 +0100 Subject: [PATCH 65/66] remove link plugin if frontend link is used --- djangocms_frontend/apps.py | 28 +++++++++---------- .../contrib/link/cms_plugins.py | 5 ++++ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/djangocms_frontend/apps.py b/djangocms_frontend/apps.py index 4c36f5a3..919e378e 100644 --- a/djangocms_frontend/apps.py +++ b/djangocms_frontend/apps.py @@ -9,31 +9,29 @@ class DjangocmsFrontendConfig(apps.AppConfig): def ready(self): from . import plugin_tag + plugin_tag.setup() checks.register(check_settings) checks.register(check_installed_apps) - plugin_tag.setup() -def check_settings(*args, **kwargs): +def check_settings(*args, **kwargs): # pragma: no cover from django.conf import settings warnings = [] - if hasattr(settings, "DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH"): # pragma: no cover + if hasattr(settings, "DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH"): warnings.append( checks.Warning( - "The DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH setting was removed in djangocms-frontend 2.\n" + "The DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH setting was removed in djangocms-frontend 2.", "Use DJANGOCMS_LINK_MINIMUM_INPUT_LENGTH instead.", - "This message disappears after removing the DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH from " - "your project's settings.\n", id="djangocms_frontend.W001", obj="settings.DJANGOCMS_FRONTEND_MINIMUM_INPUT_LENGTH", ) ) - if hasattr(settings, "DJANGOCMS_FRONTEND_LINK_MODELS"): # pragma: no cover + if hasattr(settings, "DJANGOCMS_FRONTEND_LINK_MODELS"): warnings.append( checks.Warning( - "The DJANGOCMS_FRONTEND_LINK_MODELS setting was removed in djangocms-frontend 2.\n" + "The DJANGOCMS_FRONTEND_LINK_MODELS setting was removed in djangocms-frontend 2. " "djangocms-frontend 2 uses linkable models from djangocms-link. See " "https://github.com/django-cms/djangocms-link#django-cms-link for more info.", "This message disappears after removing the DJANGOCMS_FRONTEND_LINK_MODELS from your " @@ -45,7 +43,7 @@ def check_settings(*args, **kwargs): return warnings -def check_installed_apps(app_configs, **kwargs): +def check_installed_apps(*args, **kwargs): # pragma: no cover from django.conf import settings errors = [] @@ -54,15 +52,15 @@ def check_installed_apps(app_configs, **kwargs): "djangocms_frontend.contrib.image", "djangocms_frontend.contrib.link", ] - - if any(app in settings.INSTALLED_APPS for app in link_contrib_apps): - if "djangocms_link" not in settings.INSTALLED_APPS: # pragma: no cover + link_apps_used = [app for app in link_contrib_apps if app in settings.INSTALLED_APPS] + if link_apps_used: + if "djangocms_link" not in settings.INSTALLED_APPS: errors.append( checks.Error( - "djangocms-frontend requires djangocms-link to be installed for the following plugins: {}.\n" - "Add 'djangocms_link' to your INSTALLED_APPS setting or remove all of the above apps.".format( - ", ".join(link_contrib_apps) + "djangocms-frontend requires djangocms-link to be installed for {}.".format( + ", ".join(link_apps_used) ), + "Add 'djangocms_link' to your INSTALLED_APPS setting or remove all of the above apps.", id="djangocms_frontend.E001", obj="settings.INSTALLED_APPS", ) diff --git a/djangocms_frontend/contrib/link/cms_plugins.py b/djangocms_frontend/contrib/link/cms_plugins.py index dea1f3e1..31720643 100644 --- a/djangocms_frontend/contrib/link/cms_plugins.py +++ b/djangocms_frontend/contrib/link/cms_plugins.py @@ -97,3 +97,8 @@ def get_render_template(self, context, instance, placeholder): if "djangocms_frontend.contrib.link" in django_settings.INSTALLED_APPS: # Only register plugin if in INSTALLED_APPS plugin_pool.register_plugin(TextLinkPlugin) + + if "djangocms_link" in django_settings.INSTALLED_APPS: + from djangocms_link.cms_plugins import LinkPlugin + + LinkPlugin.parent_classes = [None] # Remove it from the list of valid plugins From 4476127a6db2e6a261f91d848c87cd556140dec9 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Wed, 20 Nov 2024 22:40:15 +0100 Subject: [PATCH 66/66] fix attributes mixin --- djangocms_frontend/common/__init__.py | 3 ++- djangocms_frontend/common/attributes.py | 12 ++++++++++++ djangocms_frontend/component_base.py | 10 +++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/djangocms_frontend/common/__init__.py b/djangocms_frontend/common/__init__.py index d020d162..ccec0e60 100644 --- a/djangocms_frontend/common/__init__.py +++ b/djangocms_frontend/common/__init__.py @@ -2,7 +2,7 @@ from djangocms_frontend import settings -from .attributes import AttributesMixin +from .attributes import AttributesMixin, AttributesFormMixin from .title import TitleFormMixin, TitleMixin __common = { @@ -32,6 +32,7 @@ "TitleMixin", "TitleFormMixin", "AttributesMixin", + "AttributesFormMixin", "BackgroundFormMixin", "BackgroundMixin", "ResponsiveFormMixin", diff --git a/djangocms_frontend/common/attributes.py b/djangocms_frontend/common/attributes.py index 4bc0d617..f0fb6057 100644 --- a/djangocms_frontend/common/attributes.py +++ b/djangocms_frontend/common/attributes.py @@ -1,5 +1,7 @@ from django.utils.translation import gettext_lazy as _ +from entangled.forms import EntangledModelFormMixin +from djangocms_frontend.fields import AttributesFormField from djangocms_frontend.helpers import insert_fields @@ -25,3 +27,13 @@ def get_fieldsets(self, request, obj=None): blockattrs=self.block_attr, position=-1, # Always last ) + + +class AttributesFormMixin(EntangledModelFormMixin): + class Meta: + entangled_fields = { + "config": [ + "attributes", + ] + } + attributes = AttributesFormField() diff --git a/djangocms_frontend/component_base.py b/djangocms_frontend/component_base.py index 3659fb0f..eaa74cec 100644 --- a/djangocms_frontend/component_base.py +++ b/djangocms_frontend/component_base.py @@ -12,6 +12,13 @@ from .ui_plugin_base import CMSUIPluginBase +def _import_or_empty(module, name): + try: + return importlib.import_module(module).__dict__[name] + except (ImportError, KeyError): + return type(name, (), {}) + + def _get_mixin_classes(mixins: list, suffix: str = "") -> list[type]: """Find and import mixin classes from a list of mixin strings""" mixins = [ @@ -20,7 +27,8 @@ def _get_mixin_classes(mixins: list, suffix: str = "") -> list[type]: else ("djangocms_frontend.common", f"{mixin}{suffix}Mixin") for mixin in mixins ] - return [importlib.import_module(module).__dict__[name] for module, name in mixins] + + return [_import_or_empty(module, name) for module, name in mixins] class Slot: