Compare commits

...

43 Commits

Author SHA1 Message Date
1aababe2ae docs: update user manual with simplified program management for animators 2024-02-06 09:57:21 +01:00
0dd961e0bb db: create program editors groups 2024-02-06 09:57:20 +01:00
f9da318a38 db: add missing migration on schedule timezone 2024-02-06 09:57:20 +01:00
26fa426416 views: avoid failing on missing parent cover 2024-02-06 09:40:45 +01:00
71f4d2473e episode-form: add tracks inline formset 2024-02-06 09:40:45 +01:00
2e9ebaded2 templatetags: display edit-links for admins 2024-02-06 09:40:45 +01:00
c6a4196319 templates: update after merging branch 118-design 2024-02-06 09:40:37 +01:00
be224d0efb templatetags: return on none type object 2024-02-05 10:29:58 +01:00
89f80ad103 templates: add in-context edition links 2024-02-05 10:29:58 +01:00
6d556fcd5d db: migrations merge 2024-02-05 10:29:55 +01:00
4201d50f4b templates: update container block names 2024-02-05 10:24:48 +01:00
6c942f36fa templatetags: avoid failing on nav_items when no station is defined 2024-02-05 10:24:48 +01:00
d51b9ee58b signals: disable schedule_pre_save when using loaddata 2024-02-05 10:24:48 +01:00
1a27ae2a76 misc: add in-site episode management for animators 2024-02-05 10:24:46 +01:00
e5862ee59b templates: set document type to html, prevent quicks mode 2024-02-05 10:22:16 +01:00
8f88b15536 ProgramUpdateView: use ckeditor RichTextField 2024-02-05 10:22:16 +01:00
10dfe3811b context_processors: prevent a null station error when no default station is defined 2024-02-05 10:22:16 +01:00
f71c201020 views/program: allow changing program cover 2024-02-05 10:22:16 +01:00
0812f3a0a1 misc: add a profile view for authenticated users 2024-02-05 10:22:14 +01:00
ad2ed17c34 misc: use the django authentication system 2024-02-05 10:19:05 +01:00
9db69580e0 misc: move station and audio_streams to context_processors (in order to have them available in accounts views) 2024-02-05 10:19:05 +01:00
4ead6b154b misc: edit programs in site 2024-02-05 10:19:05 +01:00
811cc97e07 templatetags: parametrize has_perm() in order to enable aircox namespace permissions 2024-02-05 10:19:05 +01:00
b794e24d0c models/program: link to editor groups 2024-02-05 10:19:05 +01:00
269b29b2c1 aircox/conf: user cannot edit all programs/episode 2024-02-05 10:19:05 +01:00
bkfox
df41885cca various fixes 2024-02-02 19:36:02 +01:00
bkfox
2a75608701 admin rendering 2024-02-01 20:01:57 +01:00
bkfox
e1cf455384 page glitch 2024-02-01 19:45:14 +01:00
bkfox
93e286fa62 music stream 2024-02-01 19:31:30 +01:00
bkfox
e3966ca5cb logs 2024-02-01 18:15:24 +01:00
bkfox
c335ed9fb9 logs 2024-02-01 17:58:42 +01:00
bkfox
ad90255570 design 2024-02-01 17:29:35 +01:00
bkfox
cab6cacd0b design / mockups 2024-01-31 20:24:38 +01:00
bkfox
1475a80316 fixes 2024-01-30 20:19:44 +01:00
bkfox
b9148933f4 rendering 2024-01-27 19:24:24 +01:00
bkfox
5bb52a9d67 rendering 2024-01-27 18:56:05 +01:00
bkfox
8cf57c07b2 rendering 2024-01-26 22:43:16 +01:00
bkfox
20aa3aba9d rendering 2024-01-26 22:28:08 +01:00
bkfox
d53cb3e935 missing file 2024-01-26 21:56:56 +01:00
bkfox
25ceacdff9 work on main design & layout 2024-01-26 21:55:43 +01:00
bkfox
0adcacf375 merge upstream 2024-01-24 16:20:18 +01:00
bkfox
c31d776504 breadcrumbs; urls 2024-01-24 16:13:35 +01:00
bkfox
69b77a675b breadcrumbs 2024-01-24 16:13:02 +01:00
79 changed files with 2838 additions and 1169 deletions

View File

@ -86,8 +86,8 @@ class Settings(BaseSettings):
# TODO include content_type in order to avoid clash with potential
# extra applications
# aircox
"change_program",
"change_episode",
"view_program",
"view_episode",
"change_diffusion",
"add_comment",
"change_comment",

View File

@ -0,0 +1,4 @@
def station(request):
station = request.station
audio_streams = station.streams if station else None
return {"station": station, "audio_streams": audio_streams}

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Aircox 0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-01-16 13:25+0000\n"
"POT-Creation-Date: 2024-02-01 18:22+0000\n"
"PO-Revision-Date: 2016-10-10 16:00+02\n"
"Last-Translator: Aarys\n"
"Language-Team: Aircox's translators team\n"
@ -19,7 +19,7 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: aircox/admin/diffusion.py:26 aircox/models/diffusion.py:122
#: aircox/models/log.py:75
#: aircox/models/log.py:76
msgid "start"
msgstr "début"
@ -40,7 +40,7 @@ msgstr "Depuis"
msgid "Until"
msgstr "Jusque"
#: aircox/admin/filters.py:28 aircox/models/page.py:260
#: aircox/admin/filters.py:28 aircox/models/page.py:263
#: aircox/tests/admin/test_filters.py:53
msgid "None"
msgstr "Aucun"
@ -77,7 +77,7 @@ msgstr "Audio"
msgid "Program / Episode"
msgstr "Émission / Épisode"
#: aircox/admin/sound.py:135 aircox/templates/aircox/episode_detail.html:30
#: aircox/admin/sound.py:135 aircox/templates/aircox/episode_detail.html:29
msgid "Playlist"
msgstr "Playlist"
@ -115,7 +115,7 @@ msgstr "Article"
msgid "Articles"
msgstr "Articles"
#: aircox/models/diffusion.py:100 aircox/models/log.py:77
#: aircox/models/diffusion.py:100 aircox/models/log.py:78
msgid "on air"
msgstr "à l'antenne"
@ -123,7 +123,7 @@ msgstr "à l'antenne"
msgid "not confirmed"
msgstr "non confirmé"
#: aircox/models/diffusion.py:102 aircox/models/log.py:76
#: aircox/models/diffusion.py:102 aircox/models/log.py:77
msgid "cancelled"
msgstr "annulé"
@ -136,12 +136,12 @@ msgstr "épisode"
msgid "schedule"
msgstr "horaire"
#: aircox/models/diffusion.py:118 aircox/models/log.py:87
#: aircox/models/sound.py:113 aircox/models/station.py:156
#: aircox/models/diffusion.py:118 aircox/models/log.py:88
#: aircox/models/sound.py:113 aircox/models/station.py:160
msgid "type"
msgstr "type"
#: aircox/models/diffusion.py:133 aircox/models/log.py:126
#: aircox/models/diffusion.py:133 aircox/models/log.py:127
msgid "Diffusion"
msgstr "Date de diffusion"
@ -165,57 +165,57 @@ msgstr "Épisode"
msgid "Episodes"
msgstr "Épisodes"
#: aircox/models/log.py:74
#: aircox/models/log.py:75
msgid "stop"
msgstr "stop"
#: aircox/models/log.py:78 aircox/models/sound.py:90
#: aircox/models/log.py:79 aircox/models/sound.py:90
msgid "other"
msgstr "autre"
#: aircox/models/log.py:84 aircox/models/page.py:320
#: aircox/models/program.py:50 aircox/models/station.py:154
#: aircox/models/log.py:85 aircox/models/page.py:323
#: aircox/models/program.py:50 aircox/models/station.py:158
msgid "station"
msgstr "station"
#: aircox/models/log.py:85
#: aircox/models/log.py:86
msgid "related station"
msgstr "station relative"
#: aircox/models/log.py:88 aircox/models/schedule.py:48
#: aircox/models/log.py:89 aircox/models/schedule.py:48
msgid "date"
msgstr "date"
#: aircox/models/log.py:95
#: aircox/models/log.py:96
msgid "source"
msgstr "source"
#: aircox/models/log.py:96
#: aircox/models/log.py:97
msgid "identifier of the source related to this log"
msgstr "identifiant de la source relative à ce log"
#: aircox/models/log.py:102
#: aircox/models/log.py:103
msgid "comment"
msgstr "commentaire"
#: aircox/models/log.py:110 aircox/models/sound.py:163
#: aircox/models/log.py:111 aircox/models/sound.py:163
msgid "Sound"
msgstr "Son"
#: aircox/models/log.py:118 aircox/models/sound.py:294
#: aircox/models/log.py:119 aircox/models/sound.py:294
#: aircox/templates/admin/aircox/statistics.html:24
msgid "Track"
msgstr "Morceau"
#: aircox/models/log.py:150
#: aircox/models/log.py:151
msgid "Log"
msgstr "Log"
#: aircox/models/log.py:151
#: aircox/models/log.py:152
msgid "Logs"
msgstr "Logs"
#: aircox/models/page.py:43 aircox/models/page.py:323
#: aircox/models/page.py:43 aircox/models/page.py:326
#: aircox/models/sound.py:277
msgid "title"
msgstr "titre"
@ -253,125 +253,117 @@ msgstr "statut"
msgid "cover"
msgstr "couverture"
#: aircox/models/page.py:111 aircox/models/page.py:300
#: aircox/models/page.py:111 aircox/models/page.py:303
msgid "content"
msgstr "contenu"
#: aircox/models/page.py:205
#: aircox/models/page.py:208
msgid "category"
msgstr "catégorie"
#: aircox/models/page.py:210
#: aircox/models/page.py:213
msgid "publication date"
msgstr "date de publication"
#: aircox/models/page.py:212
#: aircox/models/page.py:215
msgid "featured"
msgstr "en avant"
#: aircox/models/page.py:216
#: aircox/models/page.py:219
msgid "allow comments"
msgstr "autoriser les commentaires"
#: aircox/models/page.py:240
#: aircox/models/page.py:243
msgid "Publication"
msgstr "Publication"
#: aircox/models/page.py:241
#: aircox/models/page.py:244
msgid "Publications"
msgstr "Publications"
#: aircox/models/page.py:261
#, fuzzy
#| msgid "Home page"
#: aircox/models/page.py:264
msgid "Home Page"
msgstr "Page d'accueil"
#: aircox/models/page.py:262
#, fuzzy
#| msgid "Timestamp"
#: aircox/models/page.py:265
msgid "Timetable"
msgstr "Temps"
#: aircox/models/page.py:263
#: aircox/models/page.py:266
msgid "Programs list"
msgstr "Liste des émissions"
#: aircox/models/page.py:264
#: aircox/models/page.py:267
msgid "Episodes list"
msgstr "Liste des épisodes"
#: aircox/models/page.py:265
#: aircox/models/page.py:268
msgid "Articles list"
msgstr "Liste des articles"
#: aircox/models/page.py:266
#, fuzzy
#| msgid "Publications"
#: aircox/models/page.py:269
msgid "Publications list"
msgstr "Publications"
#: aircox/models/page.py:267
#, fuzzy
#| msgid "Podcasts"
#: aircox/models/page.py:270
msgid "Podcasts list"
msgstr "Podcasts"
#: aircox/models/page.py:270
#: aircox/models/page.py:273
msgid "attach to"
msgstr "attacher à"
#: aircox/models/page.py:275
#: aircox/models/page.py:278
msgid "display this page content to related element"
msgstr "Afficher le contenu de cette page pour l'élément sélectionné"
#: aircox/models/page.py:293
#: aircox/models/page.py:296
msgid "related page"
msgstr "page liée"
#: aircox/models/page.py:297
#: aircox/models/page.py:300
msgid "nickname"
msgstr "pseudo"
#: aircox/models/page.py:298
#: aircox/models/page.py:301
msgid "email"
msgstr "email"
#: aircox/models/page.py:313
#: aircox/models/page.py:316
msgid "Comment"
msgstr "Commentaire"
#: aircox/models/page.py:314 aircox/templates/aircox/page_detail.html:59
#: aircox/models/page.py:317 aircox/templates/aircox/page_detail.html:60
msgid "Comments"
msgstr "Commentaires"
#: aircox/models/page.py:321
#: aircox/models/page.py:324
msgid "menu"
msgstr "menu"
#: aircox/models/page.py:322 aircox/models/sound.py:115
#: aircox/models/page.py:325 aircox/models/sound.py:115
#: aircox/models/sound.py:267
msgid "order"
msgstr "ordre"
#: aircox/models/page.py:324
#: aircox/models/page.py:327
msgid "url"
msgstr "url"
#: aircox/models/page.py:329
#: aircox/models/page.py:332
msgid "page"
msgstr "page"
#: aircox/models/page.py:335
#: aircox/models/page.py:338
msgid "Menu item"
msgstr "Élément du menu"
#: aircox/models/page.py:336
#: aircox/models/page.py:339
msgid "Menu items"
msgstr "Éléments de menu"
#: aircox/models/program.py:52 aircox/models/station.py:48
#: aircox/models/station.py:157
#: aircox/models/station.py:161
msgid "active"
msgstr "actif"
@ -533,7 +525,7 @@ msgstr "émission apparentée à celui-ci"
msgid "position in the playlist"
msgstr "position dans la playlist"
#: aircox/models/sound.py:125 aircox/models/station.py:151
#: aircox/models/sound.py:125 aircox/models/station.py:155
msgid "file"
msgstr "fichier"
@ -666,27 +658,35 @@ msgstr ""
msgid "Default pages' cover"
msgstr "Couverture par défault des pages."
#: aircox/models/station.py:133
#: aircox/models/station.py:80
msgid "Music stream's title"
msgstr "Titre du flux musical"
#: aircox/models/station.py:81
msgid "Music stream"
msgstr "Flux musical"
#: aircox/models/station.py:137
msgid "input"
msgstr "entrée"
#: aircox/models/station.py:134
#: aircox/models/station.py:138
msgid "output"
msgstr "sortie"
#: aircox/models/station.py:155
#: aircox/models/station.py:159
msgid "direction"
msgstr "direction"
#: aircox/models/station.py:157
#: aircox/models/station.py:161
msgid "this port is active"
msgstr "ce port est actif"
#: aircox/models/station.py:159
#: aircox/models/station.py:163
msgid "port settings"
msgstr "paramètres du port"
#: aircox/models/station.py:161
#: aircox/models/station.py:165
msgid ""
"list of comma separated params available; this is put in the output config "
"file as raw code; plugin related"
@ -757,7 +757,7 @@ msgid "Total"
msgstr "Total"
#: aircox/templates/admin/base.html:72 aircox/templates/admin/index.html:12
#: aircox/templates/aircox/home.html:48
#: aircox/templates/aircox/home.html:51
msgid "Today"
msgstr "Aujourd'hui"
@ -817,24 +817,9 @@ msgstr "Dernières publications"
msgid "Administration"
msgstr "Administration"
#. Translators: in page detail sidebar
#: aircox/templates/aircox/article_detail.html:12
msgid "Latest news"
msgstr "Dernières nouvelles"
#: aircox/templates/aircox/article_detail.html:23
msgid "Show all news"
msgstr "Afficher toutes les nouvelles"
#: aircox/templates/aircox/article_detail.html:24
msgid "More news"
msgstr "Plus de nouvelles"
#: aircox/templates/aircox/base.html:61
#, fuzzy
#| msgid "menu"
msgid "Main menu"
msgstr "menu"
msgstr "Menu principal"
#: aircox/templates/aircox/base.html:71
msgid "Admin"
@ -853,8 +838,8 @@ msgstr "pagination"
msgid "Previous"
msgstr "Précédent"
#: aircox/templates/aircox/basepage_list.html:53
#: aircox/templates/aircox/basepage_list.html:54
#: aircox/templates/aircox/basepage_list.html:57
#: aircox/templates/aircox/basepage_list.html:58
msgid "Next"
msgstr "Prochain"
@ -863,17 +848,17 @@ msgstr "Prochain"
msgid "This week on %(station)s"
msgstr "Cette semaine sur %(station)s"
#: aircox/templates/aircox/episode_detail.html:17
#: aircox/templates/aircox/episode_detail.html:16
#: aircox/templates/aircox/episode_list.html:8
msgid "Podcasts"
msgstr "Podcasts"
#: aircox/templates/aircox/episode_detail.html:35
#: aircox/templates/aircox/episode_detail.html:34
#: aircox/templatetags/aircox_admin.py:48
msgid "Artist"
msgstr "Artiste"
#: aircox/templates/aircox/episode_detail.html:36
#: aircox/templates/aircox/episode_detail.html:35
#: aircox/templatetags/aircox_admin.py:50
msgid "Title"
msgstr "Titre"
@ -915,35 +900,30 @@ msgstr "Si vous êtes un visiteur ou visiteuse, contactez votre radio favorite"
msgid "Today on %(station)s"
msgstr "Aujourd'hui sur %(station)s"
#: aircox/templates/aircox/home.html:40
#: aircox/templates/aircox/home.html:42
msgid "It just happened"
msgstr "Ça vient juste d'arriver"
#: aircox/templates/aircox/home.html:47
#: aircox/templates/aircox/home.html:50
msgid "Show all program's for today"
msgstr "Tous les articles de l'émission"
#: aircox/templates/aircox/home.html:57
#: aircox/templates/aircox/home.html:60
msgid "Last podcasts"
msgstr "Derniers Podcasts"
#: aircox/templates/aircox/home.html:58
#: aircox/templates/aircox/home.html:61
msgid "All podcasts"
msgstr "Tous les podcasts"
#: aircox/templates/aircox/home.html:64
#: aircox/templates/aircox/home.html:67
msgid "Last publications"
msgstr "Dernières publications"
#: aircox/templates/aircox/home.html:65
#: aircox/templates/aircox/home.html:68
msgid "All publications"
msgstr "Toutes les publications"
#: aircox/templates/aircox/log_list.html:9
#, python-format
msgid "That happened on %(station)s"
msgstr "C'est passé sur %(station)s"
#: aircox/templates/aircox/page_detail.html:21
msgid "Edit"
msgstr "Éditer"
@ -953,11 +933,11 @@ msgstr "Éditer"
msgid "Related %(models)s"
msgstr "%(models)s connexes"
#: aircox/templates/aircox/page_detail.html:71
#: aircox/templates/aircox/page_detail.html:72
msgid "Post a comment"
msgstr "Poster un commentaire"
#: aircox/templates/aircox/page_detail.html:98
#: aircox/templates/aircox/page_detail.html:99
msgid "Post comment"
msgstr "Commenter"
@ -971,24 +951,18 @@ msgid "Rerun"
msgstr "Rediffusion"
#: aircox/templates/aircox/program_detail.html:41
#, fuzzy
#| msgid "Episodes"
msgid "Last Episodes"
msgstr "Épisodes"
msgstr "Derniers Épisodes"
#: aircox/templates/aircox/program_detail.html:42
msgid "All episodes"
msgstr "Tous les épisodes"
#: aircox/templates/aircox/program_detail.html:49
#, fuzzy
#| msgid "Articles"
msgid "Last Articles"
msgstr "Derniers articles"
#: aircox/templates/aircox/program_detail.html:50
#, fuzzy
#| msgid "Articles"
msgid "All articles"
msgstr "Tous les articles"
@ -998,7 +972,7 @@ msgstr "Plus d'infos"
#: aircox/templates/aircox/widgets/carousel.html:25
msgid "Show all"
msgstr "Afficher tout"
msgstr "Tout Afficher"
#: aircox/templates/aircox/widgets/comment.html:37
#: aircox/templates/aircox/widgets/comment.html:38
@ -1019,8 +993,6 @@ msgid "Dates"
msgstr "Dates"
#: aircox/templates/aircox/widgets/dates_menu.html:33
#, fuzzy
#| msgid "pick a date"
msgid "Pick a date"
msgstr "Choisir une date"
@ -1036,6 +1008,10 @@ msgstr "Diffusion différée"
msgid "Listen"
msgstr "Écouter"
#: aircox/templates/aircox/widgets/page.html:40
msgid "Show"
msgstr "Voir"
#: aircox/templates/aircox/widgets/page_list.html:20
msgid "Show all publications"
msgstr "Afficher toutes les publications"
@ -1060,11 +1036,11 @@ msgstr "Lire ou suspendre l'audio"
msgid "Track currently on air"
msgstr "Morceau en ce moment sur les ondes"
#: aircox/templates/aircox/widgets/player.html:42
#: aircox/templates/aircox/widgets/player.html:44
msgid "Diffusion currently on air"
msgstr "Épisode en ce moment sur les ondes"
#: aircox/templates/aircox/widgets/player.html:46
#: aircox/templates/aircox/widgets/player.html:48
msgid "Currently playing"
msgstr "En ce moment"
@ -1101,108 +1077,115 @@ msgid "Timestamp"
msgstr "Temps"
#: aircox/urls.py:44
msgid "articles/"
msgstr "articles/"
#: aircox/urls.py:49
#, fuzzy
#| msgid "articles/<slug:slug>/"
msgid "articles/c/<slug:category_slug>/"
msgstr "articles/<slug:slug>/"
#: aircox/urls.py:52
msgid "articles/<slug:slug>/"
msgstr "articles/<slug:slug>/"
#: aircox/urls.py:57
msgid "episodes/"
msgstr "episodes/"
#: aircox/urls.py:49
msgid "articles/"
msgstr "articles/"
#: aircox/urls.py:58
msgid "episodes/c/<slug:category_slug>/"
msgstr "episodes/c/<slug:category_slug>/"
#: aircox/urls.py:54
msgid "articles/c/<slug:category_slug>/"
msgstr "articles/<slug:slug>/"
#: aircox/urls.py:60
msgid "episodes/<slug:slug>/"
msgstr "episodes/<slug:slug>/"
#: aircox/urls.py:64
msgid "podcasts/"
msgstr "podcasts/"
#: aircox/urls.py:65
msgid "podcasts/c/<slug:category_slug>/"
msgstr "podcasts/c/<slug:category_slug>/"
#: aircox/urls.py:68
#: aircox/urls.py:59
msgid "timetable/"
msgstr "grille/"
#: aircox/urls.py:70
#: aircox/urls.py:61
msgid "timetable/<date:date>/"
msgstr "grille/<date:date>/"
#: aircox/urls.py:76
#: aircox/urls.py:67
msgid "publications/"
msgstr "publications/"
#: aircox/urls.py:81
#, fuzzy
#| msgid "publications/c/<slug:category_slug>/"
#: aircox/urls.py:72
msgid "publications/c/<slug:category_slug>"
msgstr "publications/c/<slug:category_slug>/"
#: aircox/urls.py:86
msgid "pages/"
msgstr "pages/"
#: aircox/urls.py:94
#: aircox/urls.py:77
msgid "pages/<slug:slug>/"
msgstr "pages/<slug:slug>/"
#: aircox/urls.py:102
#: aircox/urls.py:85
msgid "pages/"
msgstr "pages/"
#: aircox/urls.py:93
msgid "programs/"
msgstr "emissions/"
#: aircox/urls.py:103
#: aircox/urls.py:94
msgid "programs/c/<slug:category_slug>/"
msgstr "emissions/c/<slug:category_slug>/"
#: aircox/urls.py:105
msgid "programs/<slug:slug>/"
msgstr "emissions/<slug:slug>/"
#: aircox/urls.py:96
msgid "programs/<slug:slug>"
msgstr "emissions/<slug:slug>"
#: aircox/urls.py:109
msgid "programs/<slug:parent_slug>/articles/"
msgstr "emissions/<slug:parent_slug>/articles/"
#: aircox/urls.py:100
msgid "programs/<slug:parent_slug>/articles"
msgstr "emissions/<slug:parent_slug>/articles"
#: aircox/urls.py:101
msgid "programs/<slug:parent_slug>/podcasts"
msgstr "emissions/<slug:parent_slug>/podcasts"
#: aircox/urls.py:102
msgid "programs/<slug:parent_slug>/episodes"
msgstr "emissions/<slug:parent_slug>/episodes"
#: aircox/urls.py:103
msgid "programs/<slug:parent_slug>/diffusions"
msgstr "emissions/<slug:parent_slug>/diffusions"
#: aircox/urls.py:105
msgid "programs/<slug:parent_slug>/publications"
msgstr "emissions/<slug:parent_slug>/publications"
#: aircox/urls.py:110
msgid "programs/<slug:parent_slug>/podcasts/"
msgstr "emissions/<slug:parent_slug>/episodes/"
msgid "programs/episodes/"
msgstr "emissions/episodes/"
#: aircox/urls.py:111
msgid "programs/<slug:parent_slug>/episodes/"
msgstr "emissions/<slug:parent_slug>/episodes/"
msgid "programs/episodes/c/<slug:category_slug>"
msgstr "emissions/episodes/c/<slug:category_slug>"
#: aircox/urls.py:112
msgid "programs/<slug:parent_slug>/diffusions/"
msgstr "emissions/<slug:parent_slug>/diffusions/"
#: aircox/urls.py:113
msgid "programs/episodes/<slug:slug>"
msgstr "emissions/episodes/<slug:slug>"
#: aircox/urls.py:119
#, fuzzy
#| msgid "programs/<slug:parent_slug>/publications/"
msgid "program/<slug:parent_slug>/publications"
msgstr "emissions/<slug:parent_slug>/publications/"
#: aircox/urls.py:117
msgid "podcasts/"
msgstr "podcasts/"
#: aircox/views/page.py:69
#: aircox/urls.py:118
msgid "podcasts/c/<slug:category_slug>/"
msgstr "podcasts/c/<slug:category_slug>/"
#: aircox/views/page.py:75
#, python-brace-format
msgid "{model}"
msgstr "{model}"
#: aircox/views/page.py:192
#: aircox/views/page.py:180
msgid "comments are not allowed"
msgstr "les commentaires ne sont pas autorisés"
#~ msgid "Latest news"
#~ msgstr "Dernières nouvelles"
#~ msgid "Show all news"
#~ msgstr "Afficher toutes les nouvelles"
#~ msgid "More news"
#~ msgstr "Plus de nouvelles"
#, python-format
#~ msgid "That happened on %(station)s"
#~ msgstr "C'est passé sur %(station)s"
#~ msgid "Diffusions page"
#~ msgstr "Grille horaire"

View File

@ -0,0 +1,25 @@
# Generated by Django 4.2.5 on 2023-10-18 13:50
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("auth", "0012_alter_user_first_name_max_length"),
("aircox", "0014_alter_schedule_timezone"),
]
operations = [
migrations.AddField(
model_name="program",
name="editors",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="auth.group",
verbose_name="editors",
),
),
]

View File

@ -0,0 +1,12 @@
# Generated by Django 4.2.7 on 2024-01-19 09:22
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("aircox", "0015_program_editors"),
("aircox", "0018_alter_staticpage_attach_to"),
]
operations = []

View File

@ -0,0 +1,42 @@
# Generated by Django 4.2.1 on 2024-02-01 18:12
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("aircox", "0018_alter_staticpage_attach_to"),
]
operations = [
migrations.AddField(
model_name="station",
name="music_stream_title",
field=models.CharField(
default="Music stream",
max_length=64,
verbose_name="Music stream's title",
),
),
migrations.AlterField(
model_name="staticpage",
name="attach_to",
field=models.CharField(
blank=True,
choices=[
("", "None"),
("home", "Home Page"),
("timetable-list", "Timetable"),
("program-list", "Programs list"),
("episode-list", "Episodes list"),
("article-list", "Articles list"),
("page-list", "Publications list"),
("podcast-list", "Podcasts list"),
],
help_text="display this page content to related element",
max_length=32,
null=True,
verbose_name="attach to",
),
),
]

View File

@ -0,0 +1,12 @@
# Generated by Django 4.2.7 on 2024-02-05 09:27
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("aircox", "0019_merge_20240119_1022"),
("aircox", "0019_station_program_streams_title_and_more"),
]
operations = []

View File

@ -0,0 +1,623 @@
# Generated by Django 4.2.7 on 2024-02-06 08:13
import aircox.models.schedule
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("aircox", "0020_merge_20240205_1027"),
]
operations = [
migrations.AlterField(
model_name="schedule",
name="timezone",
field=models.CharField(
choices=[
("Africa/Abidjan", "Africa/Abidjan"),
("Africa/Accra", "Africa/Accra"),
("Africa/Addis_Ababa", "Africa/Addis_Ababa"),
("Africa/Algiers", "Africa/Algiers"),
("Africa/Asmara", "Africa/Asmara"),
("Africa/Asmera", "Africa/Asmera"),
("Africa/Bamako", "Africa/Bamako"),
("Africa/Bangui", "Africa/Bangui"),
("Africa/Banjul", "Africa/Banjul"),
("Africa/Bissau", "Africa/Bissau"),
("Africa/Blantyre", "Africa/Blantyre"),
("Africa/Brazzaville", "Africa/Brazzaville"),
("Africa/Bujumbura", "Africa/Bujumbura"),
("Africa/Cairo", "Africa/Cairo"),
("Africa/Casablanca", "Africa/Casablanca"),
("Africa/Ceuta", "Africa/Ceuta"),
("Africa/Conakry", "Africa/Conakry"),
("Africa/Dakar", "Africa/Dakar"),
("Africa/Dar_es_Salaam", "Africa/Dar_es_Salaam"),
("Africa/Djibouti", "Africa/Djibouti"),
("Africa/Douala", "Africa/Douala"),
("Africa/El_Aaiun", "Africa/El_Aaiun"),
("Africa/Freetown", "Africa/Freetown"),
("Africa/Gaborone", "Africa/Gaborone"),
("Africa/Harare", "Africa/Harare"),
("Africa/Johannesburg", "Africa/Johannesburg"),
("Africa/Juba", "Africa/Juba"),
("Africa/Kampala", "Africa/Kampala"),
("Africa/Khartoum", "Africa/Khartoum"),
("Africa/Kigali", "Africa/Kigali"),
("Africa/Kinshasa", "Africa/Kinshasa"),
("Africa/Lagos", "Africa/Lagos"),
("Africa/Libreville", "Africa/Libreville"),
("Africa/Lome", "Africa/Lome"),
("Africa/Luanda", "Africa/Luanda"),
("Africa/Lubumbashi", "Africa/Lubumbashi"),
("Africa/Lusaka", "Africa/Lusaka"),
("Africa/Malabo", "Africa/Malabo"),
("Africa/Maputo", "Africa/Maputo"),
("Africa/Maseru", "Africa/Maseru"),
("Africa/Mbabane", "Africa/Mbabane"),
("Africa/Mogadishu", "Africa/Mogadishu"),
("Africa/Monrovia", "Africa/Monrovia"),
("Africa/Nairobi", "Africa/Nairobi"),
("Africa/Ndjamena", "Africa/Ndjamena"),
("Africa/Niamey", "Africa/Niamey"),
("Africa/Nouakchott", "Africa/Nouakchott"),
("Africa/Ouagadougou", "Africa/Ouagadougou"),
("Africa/Porto-Novo", "Africa/Porto-Novo"),
("Africa/Sao_Tome", "Africa/Sao_Tome"),
("Africa/Timbuktu", "Africa/Timbuktu"),
("Africa/Tripoli", "Africa/Tripoli"),
("Africa/Tunis", "Africa/Tunis"),
("Africa/Windhoek", "Africa/Windhoek"),
("America/Adak", "America/Adak"),
("America/Anchorage", "America/Anchorage"),
("America/Anguilla", "America/Anguilla"),
("America/Antigua", "America/Antigua"),
("America/Araguaina", "America/Araguaina"),
("America/Argentina/Buenos_Aires", "America/Argentina/Buenos_Aires"),
("America/Argentina/Catamarca", "America/Argentina/Catamarca"),
("America/Argentina/ComodRivadavia", "America/Argentina/ComodRivadavia"),
("America/Argentina/Cordoba", "America/Argentina/Cordoba"),
("America/Argentina/Jujuy", "America/Argentina/Jujuy"),
("America/Argentina/La_Rioja", "America/Argentina/La_Rioja"),
("America/Argentina/Mendoza", "America/Argentina/Mendoza"),
("America/Argentina/Rio_Gallegos", "America/Argentina/Rio_Gallegos"),
("America/Argentina/Salta", "America/Argentina/Salta"),
("America/Argentina/San_Juan", "America/Argentina/San_Juan"),
("America/Argentina/San_Luis", "America/Argentina/San_Luis"),
("America/Argentina/Tucuman", "America/Argentina/Tucuman"),
("America/Argentina/Ushuaia", "America/Argentina/Ushuaia"),
("America/Aruba", "America/Aruba"),
("America/Asuncion", "America/Asuncion"),
("America/Atikokan", "America/Atikokan"),
("America/Atka", "America/Atka"),
("America/Bahia", "America/Bahia"),
("America/Bahia_Banderas", "America/Bahia_Banderas"),
("America/Barbados", "America/Barbados"),
("America/Belem", "America/Belem"),
("America/Belize", "America/Belize"),
("America/Blanc-Sablon", "America/Blanc-Sablon"),
("America/Boa_Vista", "America/Boa_Vista"),
("America/Bogota", "America/Bogota"),
("America/Boise", "America/Boise"),
("America/Buenos_Aires", "America/Buenos_Aires"),
("America/Cambridge_Bay", "America/Cambridge_Bay"),
("America/Campo_Grande", "America/Campo_Grande"),
("America/Cancun", "America/Cancun"),
("America/Caracas", "America/Caracas"),
("America/Catamarca", "America/Catamarca"),
("America/Cayenne", "America/Cayenne"),
("America/Cayman", "America/Cayman"),
("America/Chicago", "America/Chicago"),
("America/Chihuahua", "America/Chihuahua"),
("America/Ciudad_Juarez", "America/Ciudad_Juarez"),
("America/Coral_Harbour", "America/Coral_Harbour"),
("America/Cordoba", "America/Cordoba"),
("America/Costa_Rica", "America/Costa_Rica"),
("America/Creston", "America/Creston"),
("America/Cuiaba", "America/Cuiaba"),
("America/Curacao", "America/Curacao"),
("America/Danmarkshavn", "America/Danmarkshavn"),
("America/Dawson", "America/Dawson"),
("America/Dawson_Creek", "America/Dawson_Creek"),
("America/Denver", "America/Denver"),
("America/Detroit", "America/Detroit"),
("America/Dominica", "America/Dominica"),
("America/Edmonton", "America/Edmonton"),
("America/Eirunepe", "America/Eirunepe"),
("America/El_Salvador", "America/El_Salvador"),
("America/Ensenada", "America/Ensenada"),
("America/Fort_Nelson", "America/Fort_Nelson"),
("America/Fort_Wayne", "America/Fort_Wayne"),
("America/Fortaleza", "America/Fortaleza"),
("America/Glace_Bay", "America/Glace_Bay"),
("America/Godthab", "America/Godthab"),
("America/Goose_Bay", "America/Goose_Bay"),
("America/Grand_Turk", "America/Grand_Turk"),
("America/Grenada", "America/Grenada"),
("America/Guadeloupe", "America/Guadeloupe"),
("America/Guatemala", "America/Guatemala"),
("America/Guayaquil", "America/Guayaquil"),
("America/Guyana", "America/Guyana"),
("America/Halifax", "America/Halifax"),
("America/Havana", "America/Havana"),
("America/Hermosillo", "America/Hermosillo"),
("America/Indiana/Indianapolis", "America/Indiana/Indianapolis"),
("America/Indiana/Knox", "America/Indiana/Knox"),
("America/Indiana/Marengo", "America/Indiana/Marengo"),
("America/Indiana/Petersburg", "America/Indiana/Petersburg"),
("America/Indiana/Tell_City", "America/Indiana/Tell_City"),
("America/Indiana/Vevay", "America/Indiana/Vevay"),
("America/Indiana/Vincennes", "America/Indiana/Vincennes"),
("America/Indiana/Winamac", "America/Indiana/Winamac"),
("America/Indianapolis", "America/Indianapolis"),
("America/Inuvik", "America/Inuvik"),
("America/Iqaluit", "America/Iqaluit"),
("America/Jamaica", "America/Jamaica"),
("America/Jujuy", "America/Jujuy"),
("America/Juneau", "America/Juneau"),
("America/Kentucky/Louisville", "America/Kentucky/Louisville"),
("America/Kentucky/Monticello", "America/Kentucky/Monticello"),
("America/Knox_IN", "America/Knox_IN"),
("America/Kralendijk", "America/Kralendijk"),
("America/La_Paz", "America/La_Paz"),
("America/Lima", "America/Lima"),
("America/Los_Angeles", "America/Los_Angeles"),
("America/Louisville", "America/Louisville"),
("America/Lower_Princes", "America/Lower_Princes"),
("America/Maceio", "America/Maceio"),
("America/Managua", "America/Managua"),
("America/Manaus", "America/Manaus"),
("America/Marigot", "America/Marigot"),
("America/Martinique", "America/Martinique"),
("America/Matamoros", "America/Matamoros"),
("America/Mazatlan", "America/Mazatlan"),
("America/Mendoza", "America/Mendoza"),
("America/Menominee", "America/Menominee"),
("America/Merida", "America/Merida"),
("America/Metlakatla", "America/Metlakatla"),
("America/Mexico_City", "America/Mexico_City"),
("America/Miquelon", "America/Miquelon"),
("America/Moncton", "America/Moncton"),
("America/Monterrey", "America/Monterrey"),
("America/Montevideo", "America/Montevideo"),
("America/Montreal", "America/Montreal"),
("America/Montserrat", "America/Montserrat"),
("America/Nassau", "America/Nassau"),
("America/New_York", "America/New_York"),
("America/Nipigon", "America/Nipigon"),
("America/Nome", "America/Nome"),
("America/Noronha", "America/Noronha"),
("America/North_Dakota/Beulah", "America/North_Dakota/Beulah"),
("America/North_Dakota/Center", "America/North_Dakota/Center"),
("America/North_Dakota/New_Salem", "America/North_Dakota/New_Salem"),
("America/Nuuk", "America/Nuuk"),
("America/Ojinaga", "America/Ojinaga"),
("America/Panama", "America/Panama"),
("America/Pangnirtung", "America/Pangnirtung"),
("America/Paramaribo", "America/Paramaribo"),
("America/Phoenix", "America/Phoenix"),
("America/Port-au-Prince", "America/Port-au-Prince"),
("America/Port_of_Spain", "America/Port_of_Spain"),
("America/Porto_Acre", "America/Porto_Acre"),
("America/Porto_Velho", "America/Porto_Velho"),
("America/Puerto_Rico", "America/Puerto_Rico"),
("America/Punta_Arenas", "America/Punta_Arenas"),
("America/Rainy_River", "America/Rainy_River"),
("America/Rankin_Inlet", "America/Rankin_Inlet"),
("America/Recife", "America/Recife"),
("America/Regina", "America/Regina"),
("America/Resolute", "America/Resolute"),
("America/Rio_Branco", "America/Rio_Branco"),
("America/Rosario", "America/Rosario"),
("America/Santa_Isabel", "America/Santa_Isabel"),
("America/Santarem", "America/Santarem"),
("America/Santiago", "America/Santiago"),
("America/Santo_Domingo", "America/Santo_Domingo"),
("America/Sao_Paulo", "America/Sao_Paulo"),
("America/Scoresbysund", "America/Scoresbysund"),
("America/Shiprock", "America/Shiprock"),
("America/Sitka", "America/Sitka"),
("America/St_Barthelemy", "America/St_Barthelemy"),
("America/St_Johns", "America/St_Johns"),
("America/St_Kitts", "America/St_Kitts"),
("America/St_Lucia", "America/St_Lucia"),
("America/St_Thomas", "America/St_Thomas"),
("America/St_Vincent", "America/St_Vincent"),
("America/Swift_Current", "America/Swift_Current"),
("America/Tegucigalpa", "America/Tegucigalpa"),
("America/Thule", "America/Thule"),
("America/Thunder_Bay", "America/Thunder_Bay"),
("America/Tijuana", "America/Tijuana"),
("America/Toronto", "America/Toronto"),
("America/Tortola", "America/Tortola"),
("America/Vancouver", "America/Vancouver"),
("America/Virgin", "America/Virgin"),
("America/Whitehorse", "America/Whitehorse"),
("America/Winnipeg", "America/Winnipeg"),
("America/Yakutat", "America/Yakutat"),
("America/Yellowknife", "America/Yellowknife"),
("Antarctica/Casey", "Antarctica/Casey"),
("Antarctica/Davis", "Antarctica/Davis"),
("Antarctica/DumontDUrville", "Antarctica/DumontDUrville"),
("Antarctica/Macquarie", "Antarctica/Macquarie"),
("Antarctica/Mawson", "Antarctica/Mawson"),
("Antarctica/McMurdo", "Antarctica/McMurdo"),
("Antarctica/Palmer", "Antarctica/Palmer"),
("Antarctica/Rothera", "Antarctica/Rothera"),
("Antarctica/South_Pole", "Antarctica/South_Pole"),
("Antarctica/Syowa", "Antarctica/Syowa"),
("Antarctica/Troll", "Antarctica/Troll"),
("Antarctica/Vostok", "Antarctica/Vostok"),
("Arctic/Longyearbyen", "Arctic/Longyearbyen"),
("Asia/Aden", "Asia/Aden"),
("Asia/Almaty", "Asia/Almaty"),
("Asia/Amman", "Asia/Amman"),
("Asia/Anadyr", "Asia/Anadyr"),
("Asia/Aqtau", "Asia/Aqtau"),
("Asia/Aqtobe", "Asia/Aqtobe"),
("Asia/Ashgabat", "Asia/Ashgabat"),
("Asia/Ashkhabad", "Asia/Ashkhabad"),
("Asia/Atyrau", "Asia/Atyrau"),
("Asia/Baghdad", "Asia/Baghdad"),
("Asia/Bahrain", "Asia/Bahrain"),
("Asia/Baku", "Asia/Baku"),
("Asia/Bangkok", "Asia/Bangkok"),
("Asia/Barnaul", "Asia/Barnaul"),
("Asia/Beirut", "Asia/Beirut"),
("Asia/Bishkek", "Asia/Bishkek"),
("Asia/Brunei", "Asia/Brunei"),
("Asia/Calcutta", "Asia/Calcutta"),
("Asia/Chita", "Asia/Chita"),
("Asia/Choibalsan", "Asia/Choibalsan"),
("Asia/Chongqing", "Asia/Chongqing"),
("Asia/Chungking", "Asia/Chungking"),
("Asia/Colombo", "Asia/Colombo"),
("Asia/Dacca", "Asia/Dacca"),
("Asia/Damascus", "Asia/Damascus"),
("Asia/Dhaka", "Asia/Dhaka"),
("Asia/Dili", "Asia/Dili"),
("Asia/Dubai", "Asia/Dubai"),
("Asia/Dushanbe", "Asia/Dushanbe"),
("Asia/Famagusta", "Asia/Famagusta"),
("Asia/Gaza", "Asia/Gaza"),
("Asia/Harbin", "Asia/Harbin"),
("Asia/Hebron", "Asia/Hebron"),
("Asia/Ho_Chi_Minh", "Asia/Ho_Chi_Minh"),
("Asia/Hong_Kong", "Asia/Hong_Kong"),
("Asia/Hovd", "Asia/Hovd"),
("Asia/Irkutsk", "Asia/Irkutsk"),
("Asia/Istanbul", "Asia/Istanbul"),
("Asia/Jakarta", "Asia/Jakarta"),
("Asia/Jayapura", "Asia/Jayapura"),
("Asia/Jerusalem", "Asia/Jerusalem"),
("Asia/Kabul", "Asia/Kabul"),
("Asia/Kamchatka", "Asia/Kamchatka"),
("Asia/Karachi", "Asia/Karachi"),
("Asia/Kashgar", "Asia/Kashgar"),
("Asia/Kathmandu", "Asia/Kathmandu"),
("Asia/Katmandu", "Asia/Katmandu"),
("Asia/Khandyga", "Asia/Khandyga"),
("Asia/Kolkata", "Asia/Kolkata"),
("Asia/Krasnoyarsk", "Asia/Krasnoyarsk"),
("Asia/Kuala_Lumpur", "Asia/Kuala_Lumpur"),
("Asia/Kuching", "Asia/Kuching"),
("Asia/Kuwait", "Asia/Kuwait"),
("Asia/Macao", "Asia/Macao"),
("Asia/Macau", "Asia/Macau"),
("Asia/Magadan", "Asia/Magadan"),
("Asia/Makassar", "Asia/Makassar"),
("Asia/Manila", "Asia/Manila"),
("Asia/Muscat", "Asia/Muscat"),
("Asia/Nicosia", "Asia/Nicosia"),
("Asia/Novokuznetsk", "Asia/Novokuznetsk"),
("Asia/Novosibirsk", "Asia/Novosibirsk"),
("Asia/Omsk", "Asia/Omsk"),
("Asia/Oral", "Asia/Oral"),
("Asia/Phnom_Penh", "Asia/Phnom_Penh"),
("Asia/Pontianak", "Asia/Pontianak"),
("Asia/Pyongyang", "Asia/Pyongyang"),
("Asia/Qatar", "Asia/Qatar"),
("Asia/Qostanay", "Asia/Qostanay"),
("Asia/Qyzylorda", "Asia/Qyzylorda"),
("Asia/Rangoon", "Asia/Rangoon"),
("Asia/Riyadh", "Asia/Riyadh"),
("Asia/Saigon", "Asia/Saigon"),
("Asia/Sakhalin", "Asia/Sakhalin"),
("Asia/Samarkand", "Asia/Samarkand"),
("Asia/Seoul", "Asia/Seoul"),
("Asia/Shanghai", "Asia/Shanghai"),
("Asia/Singapore", "Asia/Singapore"),
("Asia/Srednekolymsk", "Asia/Srednekolymsk"),
("Asia/Taipei", "Asia/Taipei"),
("Asia/Tashkent", "Asia/Tashkent"),
("Asia/Tbilisi", "Asia/Tbilisi"),
("Asia/Tehran", "Asia/Tehran"),
("Asia/Tel_Aviv", "Asia/Tel_Aviv"),
("Asia/Thimbu", "Asia/Thimbu"),
("Asia/Thimphu", "Asia/Thimphu"),
("Asia/Tokyo", "Asia/Tokyo"),
("Asia/Tomsk", "Asia/Tomsk"),
("Asia/Ujung_Pandang", "Asia/Ujung_Pandang"),
("Asia/Ulaanbaatar", "Asia/Ulaanbaatar"),
("Asia/Ulan_Bator", "Asia/Ulan_Bator"),
("Asia/Urumqi", "Asia/Urumqi"),
("Asia/Ust-Nera", "Asia/Ust-Nera"),
("Asia/Vientiane", "Asia/Vientiane"),
("Asia/Vladivostok", "Asia/Vladivostok"),
("Asia/Yakutsk", "Asia/Yakutsk"),
("Asia/Yangon", "Asia/Yangon"),
("Asia/Yekaterinburg", "Asia/Yekaterinburg"),
("Asia/Yerevan", "Asia/Yerevan"),
("Atlantic/Azores", "Atlantic/Azores"),
("Atlantic/Bermuda", "Atlantic/Bermuda"),
("Atlantic/Canary", "Atlantic/Canary"),
("Atlantic/Cape_Verde", "Atlantic/Cape_Verde"),
("Atlantic/Faeroe", "Atlantic/Faeroe"),
("Atlantic/Faroe", "Atlantic/Faroe"),
("Atlantic/Jan_Mayen", "Atlantic/Jan_Mayen"),
("Atlantic/Madeira", "Atlantic/Madeira"),
("Atlantic/Reykjavik", "Atlantic/Reykjavik"),
("Atlantic/South_Georgia", "Atlantic/South_Georgia"),
("Atlantic/St_Helena", "Atlantic/St_Helena"),
("Atlantic/Stanley", "Atlantic/Stanley"),
("Australia/ACT", "Australia/ACT"),
("Australia/Adelaide", "Australia/Adelaide"),
("Australia/Brisbane", "Australia/Brisbane"),
("Australia/Broken_Hill", "Australia/Broken_Hill"),
("Australia/Canberra", "Australia/Canberra"),
("Australia/Currie", "Australia/Currie"),
("Australia/Darwin", "Australia/Darwin"),
("Australia/Eucla", "Australia/Eucla"),
("Australia/Hobart", "Australia/Hobart"),
("Australia/LHI", "Australia/LHI"),
("Australia/Lindeman", "Australia/Lindeman"),
("Australia/Lord_Howe", "Australia/Lord_Howe"),
("Australia/Melbourne", "Australia/Melbourne"),
("Australia/NSW", "Australia/NSW"),
("Australia/North", "Australia/North"),
("Australia/Perth", "Australia/Perth"),
("Australia/Queensland", "Australia/Queensland"),
("Australia/South", "Australia/South"),
("Australia/Sydney", "Australia/Sydney"),
("Australia/Tasmania", "Australia/Tasmania"),
("Australia/Victoria", "Australia/Victoria"),
("Australia/West", "Australia/West"),
("Australia/Yancowinna", "Australia/Yancowinna"),
("Brazil/Acre", "Brazil/Acre"),
("Brazil/DeNoronha", "Brazil/DeNoronha"),
("Brazil/East", "Brazil/East"),
("Brazil/West", "Brazil/West"),
("CET", "CET"),
("CST6CDT", "CST6CDT"),
("Canada/Atlantic", "Canada/Atlantic"),
("Canada/Central", "Canada/Central"),
("Canada/Eastern", "Canada/Eastern"),
("Canada/Mountain", "Canada/Mountain"),
("Canada/Newfoundland", "Canada/Newfoundland"),
("Canada/Pacific", "Canada/Pacific"),
("Canada/Saskatchewan", "Canada/Saskatchewan"),
("Canada/Yukon", "Canada/Yukon"),
("Chile/Continental", "Chile/Continental"),
("Chile/EasterIsland", "Chile/EasterIsland"),
("Cuba", "Cuba"),
("EET", "EET"),
("EST", "EST"),
("EST5EDT", "EST5EDT"),
("Egypt", "Egypt"),
("Eire", "Eire"),
("Etc/GMT", "Etc/GMT"),
("Etc/GMT+0", "Etc/GMT+0"),
("Etc/GMT+1", "Etc/GMT+1"),
("Etc/GMT+10", "Etc/GMT+10"),
("Etc/GMT+11", "Etc/GMT+11"),
("Etc/GMT+12", "Etc/GMT+12"),
("Etc/GMT+2", "Etc/GMT+2"),
("Etc/GMT+3", "Etc/GMT+3"),
("Etc/GMT+4", "Etc/GMT+4"),
("Etc/GMT+5", "Etc/GMT+5"),
("Etc/GMT+6", "Etc/GMT+6"),
("Etc/GMT+7", "Etc/GMT+7"),
("Etc/GMT+8", "Etc/GMT+8"),
("Etc/GMT+9", "Etc/GMT+9"),
("Etc/GMT-0", "Etc/GMT-0"),
("Etc/GMT-1", "Etc/GMT-1"),
("Etc/GMT-10", "Etc/GMT-10"),
("Etc/GMT-11", "Etc/GMT-11"),
("Etc/GMT-12", "Etc/GMT-12"),
("Etc/GMT-13", "Etc/GMT-13"),
("Etc/GMT-14", "Etc/GMT-14"),
("Etc/GMT-2", "Etc/GMT-2"),
("Etc/GMT-3", "Etc/GMT-3"),
("Etc/GMT-4", "Etc/GMT-4"),
("Etc/GMT-5", "Etc/GMT-5"),
("Etc/GMT-6", "Etc/GMT-6"),
("Etc/GMT-7", "Etc/GMT-7"),
("Etc/GMT-8", "Etc/GMT-8"),
("Etc/GMT-9", "Etc/GMT-9"),
("Etc/GMT0", "Etc/GMT0"),
("Etc/Greenwich", "Etc/Greenwich"),
("Etc/UCT", "Etc/UCT"),
("Etc/UTC", "Etc/UTC"),
("Etc/Universal", "Etc/Universal"),
("Etc/Zulu", "Etc/Zulu"),
("Europe/Amsterdam", "Europe/Amsterdam"),
("Europe/Andorra", "Europe/Andorra"),
("Europe/Astrakhan", "Europe/Astrakhan"),
("Europe/Athens", "Europe/Athens"),
("Europe/Belfast", "Europe/Belfast"),
("Europe/Belgrade", "Europe/Belgrade"),
("Europe/Berlin", "Europe/Berlin"),
("Europe/Bratislava", "Europe/Bratislava"),
("Europe/Brussels", "Europe/Brussels"),
("Europe/Bucharest", "Europe/Bucharest"),
("Europe/Budapest", "Europe/Budapest"),
("Europe/Busingen", "Europe/Busingen"),
("Europe/Chisinau", "Europe/Chisinau"),
("Europe/Copenhagen", "Europe/Copenhagen"),
("Europe/Dublin", "Europe/Dublin"),
("Europe/Gibraltar", "Europe/Gibraltar"),
("Europe/Guernsey", "Europe/Guernsey"),
("Europe/Helsinki", "Europe/Helsinki"),
("Europe/Isle_of_Man", "Europe/Isle_of_Man"),
("Europe/Istanbul", "Europe/Istanbul"),
("Europe/Jersey", "Europe/Jersey"),
("Europe/Kaliningrad", "Europe/Kaliningrad"),
("Europe/Kiev", "Europe/Kiev"),
("Europe/Kirov", "Europe/Kirov"),
("Europe/Kyiv", "Europe/Kyiv"),
("Europe/Lisbon", "Europe/Lisbon"),
("Europe/Ljubljana", "Europe/Ljubljana"),
("Europe/London", "Europe/London"),
("Europe/Luxembourg", "Europe/Luxembourg"),
("Europe/Madrid", "Europe/Madrid"),
("Europe/Malta", "Europe/Malta"),
("Europe/Mariehamn", "Europe/Mariehamn"),
("Europe/Minsk", "Europe/Minsk"),
("Europe/Monaco", "Europe/Monaco"),
("Europe/Moscow", "Europe/Moscow"),
("Europe/Nicosia", "Europe/Nicosia"),
("Europe/Oslo", "Europe/Oslo"),
("Europe/Paris", "Europe/Paris"),
("Europe/Podgorica", "Europe/Podgorica"),
("Europe/Prague", "Europe/Prague"),
("Europe/Riga", "Europe/Riga"),
("Europe/Rome", "Europe/Rome"),
("Europe/Samara", "Europe/Samara"),
("Europe/San_Marino", "Europe/San_Marino"),
("Europe/Sarajevo", "Europe/Sarajevo"),
("Europe/Saratov", "Europe/Saratov"),
("Europe/Simferopol", "Europe/Simferopol"),
("Europe/Skopje", "Europe/Skopje"),
("Europe/Sofia", "Europe/Sofia"),
("Europe/Stockholm", "Europe/Stockholm"),
("Europe/Tallinn", "Europe/Tallinn"),
("Europe/Tirane", "Europe/Tirane"),
("Europe/Tiraspol", "Europe/Tiraspol"),
("Europe/Ulyanovsk", "Europe/Ulyanovsk"),
("Europe/Uzhgorod", "Europe/Uzhgorod"),
("Europe/Vaduz", "Europe/Vaduz"),
("Europe/Vatican", "Europe/Vatican"),
("Europe/Vienna", "Europe/Vienna"),
("Europe/Vilnius", "Europe/Vilnius"),
("Europe/Volgograd", "Europe/Volgograd"),
("Europe/Warsaw", "Europe/Warsaw"),
("Europe/Zagreb", "Europe/Zagreb"),
("Europe/Zaporozhye", "Europe/Zaporozhye"),
("Europe/Zurich", "Europe/Zurich"),
("Factory", "Factory"),
("GB", "GB"),
("GB-Eire", "GB-Eire"),
("GMT", "GMT"),
("GMT+0", "GMT+0"),
("GMT-0", "GMT-0"),
("GMT0", "GMT0"),
("Greenwich", "Greenwich"),
("HST", "HST"),
("Hongkong", "Hongkong"),
("Iceland", "Iceland"),
("Indian/Antananarivo", "Indian/Antananarivo"),
("Indian/Chagos", "Indian/Chagos"),
("Indian/Christmas", "Indian/Christmas"),
("Indian/Cocos", "Indian/Cocos"),
("Indian/Comoro", "Indian/Comoro"),
("Indian/Kerguelen", "Indian/Kerguelen"),
("Indian/Mahe", "Indian/Mahe"),
("Indian/Maldives", "Indian/Maldives"),
("Indian/Mauritius", "Indian/Mauritius"),
("Indian/Mayotte", "Indian/Mayotte"),
("Indian/Reunion", "Indian/Reunion"),
("Iran", "Iran"),
("Israel", "Israel"),
("Jamaica", "Jamaica"),
("Japan", "Japan"),
("Kwajalein", "Kwajalein"),
("Libya", "Libya"),
("MET", "MET"),
("MST", "MST"),
("MST7MDT", "MST7MDT"),
("Mexico/BajaNorte", "Mexico/BajaNorte"),
("Mexico/BajaSur", "Mexico/BajaSur"),
("Mexico/General", "Mexico/General"),
("NZ", "NZ"),
("NZ-CHAT", "NZ-CHAT"),
("Navajo", "Navajo"),
("PRC", "PRC"),
("PST8PDT", "PST8PDT"),
("Pacific/Apia", "Pacific/Apia"),
("Pacific/Auckland", "Pacific/Auckland"),
("Pacific/Bougainville", "Pacific/Bougainville"),
("Pacific/Chatham", "Pacific/Chatham"),
("Pacific/Chuuk", "Pacific/Chuuk"),
("Pacific/Easter", "Pacific/Easter"),
("Pacific/Efate", "Pacific/Efate"),
("Pacific/Enderbury", "Pacific/Enderbury"),
("Pacific/Fakaofo", "Pacific/Fakaofo"),
("Pacific/Fiji", "Pacific/Fiji"),
("Pacific/Funafuti", "Pacific/Funafuti"),
("Pacific/Galapagos", "Pacific/Galapagos"),
("Pacific/Gambier", "Pacific/Gambier"),
("Pacific/Guadalcanal", "Pacific/Guadalcanal"),
("Pacific/Guam", "Pacific/Guam"),
("Pacific/Honolulu", "Pacific/Honolulu"),
("Pacific/Johnston", "Pacific/Johnston"),
("Pacific/Kanton", "Pacific/Kanton"),
("Pacific/Kiritimati", "Pacific/Kiritimati"),
("Pacific/Kosrae", "Pacific/Kosrae"),
("Pacific/Kwajalein", "Pacific/Kwajalein"),
("Pacific/Majuro", "Pacific/Majuro"),
("Pacific/Marquesas", "Pacific/Marquesas"),
("Pacific/Midway", "Pacific/Midway"),
("Pacific/Nauru", "Pacific/Nauru"),
("Pacific/Niue", "Pacific/Niue"),
("Pacific/Norfolk", "Pacific/Norfolk"),
("Pacific/Noumea", "Pacific/Noumea"),
("Pacific/Pago_Pago", "Pacific/Pago_Pago"),
("Pacific/Palau", "Pacific/Palau"),
("Pacific/Pitcairn", "Pacific/Pitcairn"),
("Pacific/Pohnpei", "Pacific/Pohnpei"),
("Pacific/Ponape", "Pacific/Ponape"),
("Pacific/Port_Moresby", "Pacific/Port_Moresby"),
("Pacific/Rarotonga", "Pacific/Rarotonga"),
("Pacific/Saipan", "Pacific/Saipan"),
("Pacific/Samoa", "Pacific/Samoa"),
("Pacific/Tahiti", "Pacific/Tahiti"),
("Pacific/Tarawa", "Pacific/Tarawa"),
("Pacific/Tongatapu", "Pacific/Tongatapu"),
("Pacific/Truk", "Pacific/Truk"),
("Pacific/Wake", "Pacific/Wake"),
("Pacific/Wallis", "Pacific/Wallis"),
("Pacific/Yap", "Pacific/Yap"),
("Poland", "Poland"),
("Portugal", "Portugal"),
("ROC", "ROC"),
("ROK", "ROK"),
("Singapore", "Singapore"),
("Turkey", "Turkey"),
("UCT", "UCT"),
("US/Alaska", "US/Alaska"),
("US/Aleutian", "US/Aleutian"),
("US/Arizona", "US/Arizona"),
("US/Central", "US/Central"),
("US/East-Indiana", "US/East-Indiana"),
("US/Eastern", "US/Eastern"),
("US/Hawaii", "US/Hawaii"),
("US/Indiana-Starke", "US/Indiana-Starke"),
("US/Michigan", "US/Michigan"),
("US/Mountain", "US/Mountain"),
("US/Pacific", "US/Pacific"),
("US/Samoa", "US/Samoa"),
("UTC", "UTC"),
("Universal", "Universal"),
("W-SU", "W-SU"),
("WET", "WET"),
("Zulu", "Zulu"),
("localtime", "localtime"),
],
default=aircox.models.schedule.current_timezone_key,
help_text="timezone used for the date",
max_length=100,
verbose_name="timezone",
),
),
]

View File

@ -0,0 +1,18 @@
from django.db import migrations
from aircox.models import Program
def set_group_ownership(*args):
for program in Program.objects.all():
program.set_group_ownership()
class Migration(migrations.Migration):
dependencies = [
("aircox", "0021_alter_schedule_timezone"),
]
operations = [
migrations.RunPython(set_group_ownership),
]

View File

@ -1,5 +1,6 @@
import datetime
import logging
import operator
from collections import deque
from django.db import models
@ -163,7 +164,7 @@ class Log(Renderable, models.Model):
object_list += [cls(obj) for obj in items]
@classmethod
def merge_diffusions(cls, logs, diffs, count=None, diff_count=None, log_slice=None):
def merge_diffusions(cls, logs, diffs, count=None, diff_count=None, group_logs=False):
"""Merge logs and diffusions together.
`logs` can either be a queryset or a list ordered by `Log.date`.
@ -178,7 +179,7 @@ class Log(Renderable, models.Model):
while True:
if not len(diffs):
object_list += logs
cls._append_logs(object_list, logs, len(logs), group=group_logs)
break
if not len(logs):
@ -188,16 +189,8 @@ class Log(Renderable, models.Model):
diff = diffs.popleft()
# - takes all logs after diff start
index = next(
(i for i, v in enumerate(logs) if v.date <= diff.end),
len(logs),
)
if index is not None and index > 0:
if log_slice:
object_list += logs[: min(log_slice, index)]
else:
object_list += logs[:index]
logs = logs[index:]
index = cls._next_index(logs, diff.end, len(logs), pred=operator.le)
cls._append_logs(object_list, logs, index, group=group_logs)
if len(logs):
# FIXME
@ -206,10 +199,7 @@ class Log(Renderable, models.Model):
# object_list.append(logs[0])
# - skips logs while diff is running
index = next(
(i for i, v in enumerate(logs) if v.date < diff.start),
len(logs),
)
index = cls._next_index(logs, diff.start, len(logs))
if index is not None and index > 0:
logs = logs[index:]
@ -218,6 +208,40 @@ class Log(Renderable, models.Model):
return object_list if count is None else object_list[:count]
@classmethod
def _next_index(cls, items, date, default, pred=operator.lt):
iter = (i for i, v in enumerate(items) if pred(v.date, date))
return next(iter, default)
@classmethod
def _append_logs(cls, object_list, logs, count, group=False):
logs = logs[:count]
if not logs:
return object_list
if group:
grouped = cls._group_logs_by_time(logs)
object_list.extend(grouped)
else:
object_list += logs
return object_list
@classmethod
def _group_logs_by_time(cls, logs):
last_time = -1
cum = []
for log in logs:
hour = log.date.time().hour
if hour != last_time:
if cum:
yield cum
cum = []
last_time = hour
# reverse from lowest to highest date
cum.insert(0, log)
if cum:
yield cum
def print(self):
r = []
if self.diffusion:

View File

@ -181,7 +181,7 @@ class BasePage(Renderable, models.Model):
headline = headline.split("\n")[:3]
headline[-1] += suffix
return mark_safe("<br>".join(headline))
return mark_safe(" ".join(headline))
@classmethod
def get_init_kwargs_from(cls, page, **kwargs):

View File

@ -3,6 +3,8 @@ import os
import shutil
from django.conf import settings as conf
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.db.models import F
from django.db.models.functions import Concat, Substr
@ -58,6 +60,7 @@ class Program(Page):
default=True,
help_text=_("update later diffusions according to schedule changes"),
)
editors = models.ForeignKey(Group, models.CASCADE, blank=True, null=True, verbose_name=_("editors"))
objects = ProgramQuerySet.as_manager()
detail_url_name = "program-detail"
@ -81,6 +84,14 @@ class Program(Page):
def excerpts_path(self):
return os.path.join(self.path, settings.SOUND_ARCHIVES_SUBDIR)
@property
def editors_group_name(self):
return f"{self.title} editors"
@property
def change_permission_codename(self):
return f"change_program_{self.slug}"
def __init__(self, *kargs, **kwargs):
super().__init__(*kargs, **kwargs)
if self.slug:
@ -110,6 +121,18 @@ class Program(Page):
os.makedirs(path, exist_ok=True)
return os.path.exists(path)
def set_group_ownership(self):
editors, created = Group.objects.get_or_create(name=self.editors_group_name)
if created:
self.editors = editors
permission, _ = Permission.objects.get_or_create(
name=f"change program {self.title}",
codename=self.change_permission_codename,
content_type=ContentType.objects.get_for_model(self),
)
if permission not in editors.permissions.all():
editors.permissions.add(permission)
class Meta:
verbose_name = _("Program")
verbose_name_plural = _("Programs")
@ -135,6 +158,9 @@ class Program(Page):
shutil.move(abspath, self.abspath)
Sound.objects.filter(path__startswith=path_).update(file=Concat("file", Substr(F("file"), len(path_))))
self.set_group_ownership()
super().save(*kargs, **kwargs)
class ProgramChildQuerySet(PageQuerySet):
def station(self, station=None, id=None):

View File

@ -41,8 +41,7 @@ def user_default_groups(sender, instance, created, *args, **kwargs):
@receiver(signals.post_save, sender=Page)
def page_post_save(sender, instance, created, *args, **kwargs):
return
if not created and instance.cover:
if not created and instance.cover and "raw" not in kwargs:
Page.objects.filter(parent=instance, cover__isnull=True).update(cover=instance.cover)
@ -60,8 +59,7 @@ def program_post_save(sender, instance, created, *args, **kwargs):
@receiver(signals.pre_save, sender=Schedule)
def schedule_pre_save(sender, instance, *args, **kwargs):
return
if getattr(instance, "pk") is not None:
if getattr(instance, "pk") is not None and "raw" not in kwargs:
instance._initial = Schedule.objects.get(pk=instance.pk)

View File

@ -67,7 +67,7 @@ class Station(models.Model):
max_length=2048,
null=True,
blank=True,
help_text=_("Audio streams urls used by station's player. One url " "a line."),
help_text=_("Audio streams urls used by station's player. One url a line."),
)
default_cover = FilerImageField(
on_delete=models.SET_NULL,
@ -76,6 +76,11 @@ class Station(models.Model):
blank=True,
related_name="+",
)
music_stream_title = models.CharField(
_("Music stream's title"),
max_length=64,
default=_("Music stream"),
)
objects = StationQuerySet.as_manager()

View File

@ -8,57 +8,76 @@
--subtitle-1-sz: 1.6rem;
--subtitle-2-sz: 1.4rem;
--subtitle-3-sz: 1.2rem;
--heading-title-bg-color: rgba(255, 255, 0, 1);
--heading-bg-color: var(--highlight-color);
--heading-bg-highlight-color: var(--highlight-color-2);
--heading-font-family: default;
--preview-title-sz: 1.4rem;
--preview-subtitle-sz: 1rem;
--heading-bg: var(--main-color);
--heading-fg: var(--text-color);
--heading-hg-fg: var(--text-color);
--heading-hg-bg: var(--secondary-color);
--heading-link-hv-fg: var(--link-fg);
--cover-w: 14rem;
--cover-h: 14rem;
--cover-small-w: 10rem;
--cover-small-h: 10rem;
--cover-tiny-w: 10rem;
--cover-tiny-h: 10rem;
--card-w: var(--cover-w);
--preview-bg: var(--body-bg);
--preview-title-sz: var(--title-3-sz);
--preview-subtitle-sz: var(--title-3-sz);
--preview-cover-size: 14rem;
--preview-cover-small-size: 10rem;
--preview-cover-tiny-size: 4rem;
--preview-wide-content-sz: 1.6rem;
--header-height: var(--preview-cover-size);
--preview-heading-bg-color: var(--hg-color);
--header-height: var(--cover-h);
--a-carousel-p: 1.4rem;
--a-carousel-ml: calc(1.2rem - 0.5rem);
--a-carousel-gap: 1.2rem;
--a-carousel-nav-x: -0.6em;
--a-carousel-bg: none;
--a-progress-bg: transparent;
--a-progress-bar-bg: var(--highlight-color-2);
--a-progress-bar-color: var(--highlight-color);
--a-progress-bar-bg: var(--secondary-color);
--a-progress-bar-color: var(--text-color);
--a-progress-bar-pd: 0.4rem;
--a-playlist-header-bg: var(--highlight-color-2-alpha);
--a-playlist-header-fg: var(--highlight-color);
--a-playlist-header-bg: var(--secondary-color);
--a-playlist-header-fg: var(--text-color);
--a-playlist-title-sz: 1rem;
--a-playlist-title-pd: 0.6rem;
--a-playlist-item-border: 1px var(--highlight-color-2) solid;
--a-sound-bg: var(--highlight-color-alpha);
--a-sound-hv-bg: var(--highlight-color);
--a-sound-playing-fg: var(--highlight-color-alpha);
--a-sound-hv-fg: var(--highlight-color-2);
--a-playlist-item-border: 1px var(--secondary-color) solid;
--a-sound-bg: var(--main-color);
--a-sound-hv-bg: var(--main-color);
--a-sound-hv-fg: var(--secondary-color);
--a-sound-playing-fg: var(--secondary-color-dark);
--a-sound-text-sz: 1rem;
--a-player-url-fg: var(--highlight-color-2);
--a-player-panel-bg: var(--highlight-color);
--a-player-url-fg: var(--text-color);
--a-player-panel-bg: var(--main-color);
--a-player-bar-height: var(--nav-primary-height);
--a-player-bar-bg: var(--highlight-color);
--a-player-bar-bg: var(--main-color);
--a-player-bar-title-alone-sz: 1.4rem;
--button-fg: var(--highlight-color-2);
--button-bg: var(--highlight-color);
--button-sec-bg: var(--highlight-color-alpha);
--button-hg-fg: var(--text-color);
--button-hg-bg: var(--highlight-color);
--button-active-fg: var(--highlight-color);
--button-active-bg: var(--highlight-color-2);
--a-player-bar-button-fg: var(--button-fg);
--a-player-bar-button-fg: var(--button-bg);
--a-player-bar-button-hv-fg: var(--button-hv-fg);
--a-player-bar-button-hv-bg: var(--button-hv-bg);
--button-fg: var(--text-color);
--button-bg: var(--main-color);
--button-sec-bg: var(--main-color-light);
--button-hv-fg: var(--text-color);
--button-hv-bg: var(--secondary-color-light);
--button-active-fg: var(--text-color);
--button-active-bg: var(--secondary-color);
}
@media screen and (max-width: 1380px) {
:root {
--cover-w: 10rem;
--cover-h: 10rem;
--cover-small-w: 6rem;
--cover-small-h: 6rem;
--cover-tiny-w: 4rem;
--cover-tiny-h: 4rem;
--section-content-sz: 1rem;
--preview-title-sz: 1rem;
--preview-subtitle-sz: 0.8rem;
--preview-cover-size: 10rem;
--preview-cover-small-size: 6rem;
--preview-cover-tiny-size: 4rem;
--preview-wide-content-sz: 1rem;
}
}
@ -72,6 +91,9 @@
font-size: var(--title-3-sz);
}
.subtitle, .header.preview .subtitle {
color: var(--text-color-light);
}
.subtitle.is-1, .header.preview .subtitle.is-1 {
font-size: var(--subtitle-1-sz);
}
@ -82,26 +104,30 @@
font-size: var(--subtitle-3-sz);
}
.title + .subtitle {
padding-top: 0em !important;
}
.headings a, a.heading, a.subtitle {
text-decoration: none !important;
}
.heading {
display: inline-block;
}
.heading:not(:empty) {
background-color: var(--heading-bg-color);
padding: 0.4rem;
margin-top: 0em !important;
vertical-align: top;
}
.heading:not(:empty).highlight, .heading:not(:empty).active, .preview.active .heading:not(:empty) {
background-color: var(--heading-bg-highlight-color);
color: var(--highlight-color);
}
.heading.title {
background-color: var(--heading-title-bg-color);
color: var(--heading-hg-fg);
}
.preview {
position: relative;
background-size: cover;
background-color: var(--preview-bg) !important;
}
.preview.preview-item {
width: 100%;
@ -135,21 +161,30 @@
.preview .headings a {
color: var(--text-color);
}
.preview .headings a:hover {
color: var(--heading-link-hv-fg) !important;
}
.preview.tiny .content {
font-size: 1rem;
}
@media screen and (max-width: 600px) {
.preview .content {
display: none;
}
}
.preview-cover {
background: var(--preview-bg);
background-size: cover;
background-color: transparent !important;
height: var(--preview-cover-size);
width: var(--preview-cover-size);
min-width: var(--preview-cover-size);
background-repeat: no-repeat;
height: var(--cover-h);
max-width: calc(var(--cover-w) * 1.5);
min-width: var(--cover-w);
overflow: hidden;
border: 1px #c4c4c4 solid;
}
.preview-cover img {
height: var(--cover-h);
max-width: calc(var(--cover-w) * 1.5);
min-width: var(--cover-w);
}
.preview-cover img.hide {
visibility: hidden;
}
.preview-cover.small, .preview.small .preview-cover {
min-width: unset;
@ -184,116 +219,125 @@
}
.list-item {
display: flex;
flex-direction: column;
width: 100%;
}
.list-item:not(:first-child) {
margin-top: 0.6rem;
}
.list-item .headings {
display: flex;
flex-direction: row;
padding-top: 0em;
padding: 0em;
margin-bottom: 0.4rem !important;
}
.list-item .headings .title {
.list-item .headings .heading {
padding: 0rem;
}
.list-item .title {
flex-grow: 1;
}
.list-item .subtitle {
font-size: var(--preview-title-sz);
text-align: right;
}
.list-item .subtitle:not(:empty) {
min-width: 9rem;
}
.list-item .media-content {
display: flex;
flex-direction: column;
height: 100%;
margin-bottom: unset;
}
.list-item:not(.no-cover) .list-item .media-content {
min-height: var(--preview-cover-small-size);
}
.list-item .media-content .content {
flex-grow: 1;
margin-bottom: auto;
}
.list-item .media-content .actions {
flex-grow: unset;
.list-item .actions {
text-align: right;
margin-top: auto;
}
.list-item:not(.wide) .media {
padding: 0.6rem;
border: 1px solid var(--break-color) !important;
}
.preview-wide {
height: var(--preview-cover-size);
display: flex;
@media screen and (max-width: 400px) {
.list-item .headings {
flex-direction: column;
}
.list-item .headings .heading {
display: inline;
text-align: left;
}
.list-item .headings .subtitle {
color: unset !important;
background: none !important;
}
}
.preview-wide .headings {
height: var(--preview-cover-size);
}
.preview-wide:not(.header) .headings {
.list-item.wide .preview-cover {
box-shadow: 0em 0em 1em rgba(0, 0, 0, 0.2);
}
.preview-wide .headings {
width: var(--preview-cover-size);
min-width: var(--preview-cover-size);
flex-grow: 0;
margin-right: 1.2rem;
}
.preview-wide .content {
.list-item.wide .content {
font-size: var(--preview-wide-content-sz);
flex-grow: 1;
}
.preview-card {
display: flex;
flex-direction: column;
width: var(--card-w);
padding: 0rem !important;
height: var(--preview-cover-size);
width: var(--preview-cover-size);
margin-bottom: auto;
background-color: var(--preview-bg) !important;
transition: box-shadow 0.2s;
}
.preview-card.small {
height: var(--preview-cover-small-size);
width: var(--preview-cover-small-size);
.preview-card:hover figure {
box-shadow: 0em 0em 1.2em rgba(0, 0, 0, 0.4) !important;
}
.preview-card.tiny {
height: var(--preview-cover-tiny-size);
width: var(--preview-cover-tiny-size);
.preview-card:hover a {
color: var(--heading-link-hv-fg);
}
.preview-card:not(.header) {
box-shadow: 0em 0em 1em rgba(0, 0, 0, 0.2);
.preview-card .headings {
margin-top: 0.4rem;
}
.preview-card .title {
max-height: calc(var(--preview-cover-size) / 2);
.preview-card .headings .heading {
display: block !important;
}
.preview-card .headings .title {
overflow: hidden;
}
.card-grid .preview-card {
min-width: unset;
.preview-card .headings .subtitle {
font-size: 1.2rem;
}
.preview-card .actions {
.preview-card .card-content {
flex-grow: 1;
position: relative;
}
.preview-card .card-content figure {
box-shadow: 0em 0em 1em rgba(0, 0, 0, 0.2);
height: var(--cover-h);
width: var(--cover-w);
}
.preview-card .card-content .actions {
position: absolute;
bottom: 0.6rem;
right: 0.6rem;
}
.preview-card .actions label {
display: none;
padding: 0.4rem;
bottom: 0rem;
right: 0rem;
}
.card-headings, .preview-card-headings {
padding-top: 0.6rem;
}
.card-headings > div:not(:last-child), .card-headings .column > div, .preview-card-headings > div:not(:last-child), .preview-card-headings .column > div {
margin-bottom: 0.6rem;
}
preview-header:not(.no-cover) .card-headings .heading, preview-header:not(.no-cover) .preview-card-headings .heading {
margin-bottom: 0.6rem;
}
.card-grid {
.list-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr;
grid-auto-flow: dense;
gap: 1.2rem;
}
.a-carousel {
margin-left: calc(0rem - var(--a-carousel-ml));
@media screen and (max-width: 900px) {
.list-grid {
grid-template-columns: 1fr;
}
}
.a-carousel .a-carousel-viewport {
padding: var(--a-carousel-p) 0;
padding-left: var(--a-carousel-ml);
box-shadow: inset 0em 0em 20rem var(--a-carousel-bg);
padding: 0rem;
padding-top: var(--a-carousel-p);
margin-top: calc(0rem - var(--a-carousel-p));
}
.a-carousel-container {
@ -305,18 +349,15 @@ preview-header:not(.no-cover) .card-headings .heading, preview-header:not(.no-co
flex-shrink: 0;
}
.a-carousel-button-container button, .a-carousel-button-container .button {
z-index: 1000;
position: absolute;
display: flex;
flex-direction: column;
top: 50%;
.a-carousel-bullets-container {
padding-left: var(--a-carousel-ml);
}
.a-carousel-button-container button.prev, .a-carousel-button-container .button.prev {
left: var(--a-carousel-nav-x);
.a-carousel-bullets-container .bullet {
margin: 0.2rem;
cursor: pointer;
}
.a-carousel-button-container button.next, .a-carousel-button-container .button.next {
right: var(--a-carousel-nav-x);
.a-carousel-bullets-container .bullet:hover {
color: var(--link-fg);
}
.a-progress {
@ -369,7 +410,7 @@ preview-header:not(.no-cover) .card-headings .heading, preview-header:not(.no-co
height: 3rem;
background-color: var(--a-sound-bg);
}
.a-sound-item.playing, .a-sound-item.playing .label {
.a-sound-item.playing .label {
color: var(--a-sound-playing-fg) !important;
}
.a-sound-item:hover {
@ -401,6 +442,10 @@ preview-header:not(.no-cover) .card-headings .heading, preview-header:not(.no-co
width: 3em;
font-size: var(--a-sound-text-sz);
}
.a-sound-item .button:hover {
color: var(--a-sound-hv-fg) !important;
background-color: unset;
}
.player-container {
z-index: 1000000;
@ -480,11 +525,10 @@ preview-header:not(.no-cover) .card-headings .heading, preview-header:not(.no-co
padding: 0.4rem !important;
min-width: calc(var(--a-player-bar-height) + 0.8rem);
border-radius: 0px;
transition: background-color 0.5s;
}
.a-player-bar .button.open {
background-color: var(--highlight-color-2-alpha);
color: var(--highlight-color);
background-color: var(--button-active-bg);
color: var(--button-active-fg);
}
.a-player-bar-content {
@ -2711,50 +2755,51 @@ a.navbar-item:focus, a.navbar-item:focus-within, a.navbar-item:hover, a.navbar-i
min-height: calc(100vh - 3.25rem);
}
#player .button, #player a.button, #player button.button, #player .nav-urls a, .ax .button, .ax a.button, .ax button.button, .ax .nav-urls a {
#player .button, #player a.button, #player button.button, .ax .button, .ax a.button, .ax button.button {
font-size: 1rem;
display: inline-block;
padding: 0.4rem;
border: 1px var(--highlight-color-2-alpha) solid;
border: none;
justify-content: center;
text-align: center;
cursor: pointer;
text-decoration: none;
color: var(--button-fg);
background-color: var(--button-bg);
}
#player .button.secondary, #player a.button.secondary, #player button.button.secondary, #player .nav-urls a.secondary, .ax .button.secondary, .ax a.button.secondary, .ax button.button.secondary, .ax .nav-urls a.secondary {
#player .button.secondary, #player a.button.secondary, #player button.button.secondary, .ax .button.secondary, .ax a.button.secondary, .ax button.button.secondary {
background-color: var(--button-sec-bg);
}
#player .button .icon, #player a.button .icon, #player button.button .icon, #player .nav-urls a .icon, .ax .button .icon, .ax a.button .icon, .ax button.button .icon, .ax .nav-urls a .icon {
#player .button .label, #player .button label, #player a.button .label, #player a.button label, #player button.button .label, #player button.button label, .ax .button .label, .ax .button label, .ax a.button .label, .ax a.button label, .ax button.button .label, .ax button.button label {
cursor: pointer;
}
#player .button .icon, #player a.button .icon, #player button.button .icon, .ax .button .icon, .ax a.button .icon, .ax button.button .icon {
vertical-align: middle;
}
#player .button .icon:not(:only-child):first-child, #player a.button .icon:not(:only-child):first-child, #player button.button .icon:not(:only-child):first-child, #player .nav-urls a .icon:not(:only-child):first-child, .ax .button .icon:not(:only-child):first-child, .ax a.button .icon:not(:only-child):first-child, .ax button.button .icon:not(:only-child):first-child, .ax .nav-urls a .icon:not(:only-child):first-child {
#player .button .icon:not(:only-child):first-child, #player a.button .icon:not(:only-child):first-child, #player button.button .icon:not(:only-child):first-child, .ax .button .icon:not(:only-child):first-child, .ax a.button .icon:not(:only-child):first-child, .ax button.button .icon:not(:only-child):first-child {
margin-right: 0.6rem;
}
#player .button .icon:not(:only-child):last-child, #player a.button .icon:not(:only-child):last-child, #player button.button .icon:not(:only-child):last-child, #player .nav-urls a .icon:not(:only-child):last-child, .ax .button .icon:not(:only-child):last-child, .ax a.button .icon:not(:only-child):last-child, .ax button.button .icon:not(:only-child):last-child, .ax .nav-urls a .icon:not(:only-child):last-child {
#player .button .icon:not(:only-child):last-child, #player a.button .icon:not(:only-child):last-child, #player button.button .icon:not(:only-child):last-child, .ax .button .icon:not(:only-child):last-child, .ax a.button .icon:not(:only-child):last-child, .ax button.button .icon:not(:only-child):last-child {
margin-left: 0.6rem;
}
#player .button:hover, #player a.button:hover, #player button.button:hover, #player .nav-urls a:hover, .ax .button:hover, .ax a.button:hover, .ax button.button:hover, .ax .nav-urls a:hover {
color: var(--button-hg-fg);
#player .button:hover, #player a.button:hover, #player button.button:hover, .ax .button:hover, .ax a.button:hover, .ax button.button:hover {
color: var(--button-hv-fg);
background-color: var(--button-hv-bg);
opacity: 1 !important;
}
#player .button.active, #player a.button.active, #player button.button.active, #player .nav-urls a.active, .ax .button.active, .ax a.button.active, .ax button.button.active, .ax .nav-urls a.active {
border-color: var(--highlight-color-alpha);
#player .button.active:not(:hover), #player a.button.active:not(:hover), #player button.button.active:not(:hover), .ax .button.active:not(:hover), .ax a.button.active:not(:hover), .ax button.button.active:not(:hover) {
color: var(--button-active-fg);
background-color: var(--button-active-bg);
}
#player .button.active:hover, #player a.button.active:hover, #player button.button.active:hover, #player .nav-urls a.active:hover, .ax .button.active:hover, .ax a.button.active:hover, .ax button.button.active:hover, .ax .nav-urls a.active:hover {
border-color: var(--highlight-color);
background-color: var(--highlight-color-2-alpha);
opacity: 1 !important;
}
#player .button:not([disabled]), #player .button:not(.disabled), #player a.button:not([disabled]), #player a.button:not(.disabled), #player button.button:not([disabled]), #player button.button:not(.disabled), #player .nav-urls a:not([disabled]), #player .nav-urls a:not(.disabled), .ax .button:not([disabled]), .ax .button:not(.disabled), .ax a.button:not([disabled]), .ax a.button:not(.disabled), .ax button.button:not([disabled]), .ax button.button:not(.disabled), .ax .nav-urls a:not([disabled]), .ax .nav-urls a:not(.disabled) {
#player .button:not([disabled]), #player .button:not(.disabled), #player a.button:not([disabled]), #player a.button:not(.disabled), #player button.button:not([disabled]), #player button.button:not(.disabled), .ax .button:not([disabled]), .ax .button:not(.disabled), .ax a.button:not([disabled]), .ax a.button:not(.disabled), .ax button.button:not([disabled]), .ax button.button:not(.disabled) {
cursor: pointer;
}
#player .button[disabled], #player .button.disabled, #player a.button[disabled], #player a.button.disabled, #player button.button[disabled], #player button.button.disabled, #player .nav-urls a[disabled], #player .nav-urls a.disabled, .ax .button[disabled], .ax .button.disabled, .ax a.button[disabled], .ax a.button.disabled, .ax button.button[disabled], .ax button.button.disabled, .ax .nav-urls a[disabled], .ax .nav-urls a.disabled {
background-color: var(--highlight-color-grey);
color: var(--highlight-color-2);
border-color: var(--highlight-color-2-alpha);
#player .button[disabled], #player .button.disabled, #player a.button[disabled], #player a.button.disabled, #player button.button[disabled], #player button.button.disabled, .ax .button[disabled], .ax .button.disabled, .ax a.button[disabled], .ax a.button.disabled, .ax button.button[disabled], .ax button.button.disabled {
background-color: var(--hg-color-grey);
color: var(--hg-color-2);
border-color: var(--hg-color-2-alpha);
}
#player .button .dropdown-trigger, #player a.button .dropdown-trigger, #player button.button .dropdown-trigger, #player .nav-urls a .dropdown-trigger, .ax .button .dropdown-trigger, .ax a.button .dropdown-trigger, .ax button.button .dropdown-trigger, .ax .nav-urls a .dropdown-trigger {
#player .button .dropdown-trigger, #player a.button .dropdown-trigger, #player button.button .dropdown-trigger, .ax .button .dropdown-trigger, .ax a.button .dropdown-trigger, .ax button.button .dropdown-trigger {
border-radius: 1.5em;
}
#player .button-group .button, #player .nav .button, .ax .button-group .button, .ax .nav .button {

View File

@ -8,7 +8,7 @@
}
.a-carousel-viewport[data-v-b79f173e] {
width: 100%;
overflow: hidden;
overflow-x: hidden;
}
.a-carousel-container[data-v-b79f173e] {
display: flex;
@ -18,7 +18,24 @@
.a-carousel-container > *[data-v-b79f173e] {
flex-shrink: 0;
}
.a-carousel-bullets-container[data-v-b79f173e] {
flex-grow: 1;
}
.a-carousel-bullets-container .bullet[data-v-b79f173e] {
cursor: pointer;
}
.a-carousel-bullets-container .left[data-v-b79f173e] {
min-width: 2rem;
margin-right: auto;
}
.a-carousel-bullets-container .right[data-v-b79f173e] {
min-width: 2rem;
margin-left: auto;
}
.a-carousel-bullets-container[data-v-b79f173e] {
display: flex;
flex-direction: row;
}
/*!**************************************************************************************************************************************************************************************************************************************!*\
!*** css ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-24.use[1]!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-24.use[2]!./node_modules/sass-loader/dist/cjs.js??clonedRuleSet-24.use[3]!./src/assets/common.scss ***!
@ -6837,10 +6854,34 @@ a.tag:hover {
margin-top: auto !important;
}
.grid-2 {
display: grid;
grid-template-columns: 1fr 1fr;
}
.grid-3 {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.flex-row {
display: flex;
flex-direction: row;
}
.flex-column {
display: flex;
flex-direction: column;
}
.flex-grow-0 {
flex-grow: 0 !important;
}
.flex-grow-1 {
flex-grow: 1 !important;
}
.float-right {
float: right;
}
@ -6928,11 +6969,11 @@ a.tag:hover {
animation: 1s ease-in-out 1s infinite alternate blink;
}
.highlight-color {
.hg-color {
color: var(--highlight-color);
}
.highlight-color-2 {
.hg-color-2 {
color: var(--highlight-color-2);
}
@ -6959,28 +7000,35 @@ input.half-field:not(:active):not(:hover) {
:root {
--body-bg: #fff;
--text-color: black;
--text-color-light: #555;
--break-color: rgb(225, 225, 225);
--main-color: #EFCA08;
--main-color-light: #F4da51;
--main-color-dark: #F49F0A;
--secondary-color: #00A6A6;
--secondary-color-light: #4cc0c0;
--secondary-color-dark: #007ba8;
--disabled-color: #aaa;
--disabled-bg: #eee;
--highlight-color: rgba(255, 255, 0, 1);
--highlight-color-alpha: rgba(255, 255, 0, 0.7);
--highlight-color-grey: rgba(230, 230, 60, 1);
--highlight-color-2: rgb(0, 0, 254);
--highlight-color-2-alpha: rgb(0, 0, 254, 0.7);
--highlight-color-2-grey: rgba(50, 200, 200, 1);
--link-fg: #00A6A6;
--link-hv-fg: var(--text-color);
--hg-color: #EFCA08;
--hg-color-alpha: #EFCA08B3;
--hg-color-grey: rgba(230, 230, 60, 1);
--hg-color-2: #F49F0A;
--hg-color-2-alpha: #F49F0AB3;
--hg-color-2-grey: rgba(50, 200, 200, 1);
--nav-primary-height: 3rem;
--nav-secondary-height: 2.5rem;
--nav-bg: var(--highlight-color);
--nav-fg: var(--highlight-color-2);
--nav-active-bg: var(--highlight-color-2);
--nav-active-fg: var(--highlight-color);
--nav-fg: var(--text-color);
--nav-bg: var(--main-color);
--nav-secondary-bg: var(--main-color-light);
--nav-hv-fg: var(--button-hv-fg);
--nav-hv-bg: var(--button-hv-bg);
--nav-active-fg: var(--button-active-fg);
--nav-active-bg: var(--button-active-bg);
--nav-fs: 1rem;
--nav-2-fs: 0.8rem;
--button-fg: var(--text-color);
--button-bg: var(--highlight-color);
--button-hg-fg: var(--highlight-color-2);
--button-hg-bg: var(--highlight-color);
--button-active-fg: var(--highlight-color);
--button-active-bg: var(--highlight-color-2);
--nav-2-fs: 0.9rem;
}
body {
@ -7001,12 +7049,6 @@ body {
--header-height: 20rem;
}
}
section > .toolbar {
background-color: rgba(0, 0, 0, 0.05);
padding: 1em;
margin-bottom: 1.5em;
}
h1, h2, h3, h4, h5, h6, .heading, .title, .subtitle {
font-family: var(--heading-font-family);
}

View File

@ -1211,7 +1211,7 @@
background-color: var(--vc-bg);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-tap-highlight-color: transparent;
-webkit-tap-hg-color: transparent;
}
.vc-container,

View File

@ -8,57 +8,76 @@
--subtitle-1-sz: 1.6rem;
--subtitle-2-sz: 1.4rem;
--subtitle-3-sz: 1.2rem;
--heading-title-bg-color: rgba(255, 255, 0, 1);
--heading-bg-color: var(--highlight-color);
--heading-bg-highlight-color: var(--highlight-color-2);
--heading-font-family: default;
--preview-title-sz: 1.4rem;
--preview-subtitle-sz: 1rem;
--heading-bg: var(--main-color);
--heading-fg: var(--text-color);
--heading-hg-fg: var(--text-color);
--heading-hg-bg: var(--secondary-color);
--heading-link-hv-fg: var(--link-fg);
--cover-w: 14rem;
--cover-h: 14rem;
--cover-small-w: 10rem;
--cover-small-h: 10rem;
--cover-tiny-w: 10rem;
--cover-tiny-h: 10rem;
--card-w: var(--cover-w);
--preview-bg: var(--body-bg);
--preview-title-sz: var(--title-3-sz);
--preview-subtitle-sz: var(--title-3-sz);
--preview-cover-size: 14rem;
--preview-cover-small-size: 10rem;
--preview-cover-tiny-size: 4rem;
--preview-wide-content-sz: 1.6rem;
--header-height: var(--preview-cover-size);
--preview-heading-bg-color: var(--hg-color);
--header-height: var(--cover-h);
--a-carousel-p: 1.4rem;
--a-carousel-ml: calc(1.2rem - 0.5rem);
--a-carousel-gap: 1.2rem;
--a-carousel-nav-x: -0.6em;
--a-carousel-bg: none;
--a-progress-bg: transparent;
--a-progress-bar-bg: var(--highlight-color-2);
--a-progress-bar-color: var(--highlight-color);
--a-progress-bar-bg: var(--secondary-color);
--a-progress-bar-color: var(--text-color);
--a-progress-bar-pd: 0.4rem;
--a-playlist-header-bg: var(--highlight-color-2-alpha);
--a-playlist-header-fg: var(--highlight-color);
--a-playlist-header-bg: var(--secondary-color);
--a-playlist-header-fg: var(--text-color);
--a-playlist-title-sz: 1rem;
--a-playlist-title-pd: 0.6rem;
--a-playlist-item-border: 1px var(--highlight-color-2) solid;
--a-sound-bg: var(--highlight-color-alpha);
--a-sound-hv-bg: var(--highlight-color);
--a-sound-playing-fg: var(--highlight-color-alpha);
--a-sound-hv-fg: var(--highlight-color-2);
--a-playlist-item-border: 1px var(--secondary-color) solid;
--a-sound-bg: var(--main-color);
--a-sound-hv-bg: var(--main-color);
--a-sound-hv-fg: var(--secondary-color);
--a-sound-playing-fg: var(--secondary-color-dark);
--a-sound-text-sz: 1rem;
--a-player-url-fg: var(--highlight-color-2);
--a-player-panel-bg: var(--highlight-color);
--a-player-url-fg: var(--text-color);
--a-player-panel-bg: var(--main-color);
--a-player-bar-height: var(--nav-primary-height);
--a-player-bar-bg: var(--highlight-color);
--a-player-bar-bg: var(--main-color);
--a-player-bar-title-alone-sz: 1.4rem;
--button-fg: var(--highlight-color-2);
--button-bg: var(--highlight-color);
--button-sec-bg: var(--highlight-color-alpha);
--button-hg-fg: var(--text-color);
--button-hg-bg: var(--highlight-color);
--button-active-fg: var(--highlight-color);
--button-active-bg: var(--highlight-color-2);
--a-player-bar-button-fg: var(--button-fg);
--a-player-bar-button-fg: var(--button-bg);
--a-player-bar-button-hv-fg: var(--button-hv-fg);
--a-player-bar-button-hv-bg: var(--button-hv-bg);
--button-fg: var(--text-color);
--button-bg: var(--main-color);
--button-sec-bg: var(--main-color-light);
--button-hv-fg: var(--text-color);
--button-hv-bg: var(--secondary-color-light);
--button-active-fg: var(--text-color);
--button-active-bg: var(--secondary-color);
}
@media screen and (max-width: 1380px) {
:root {
--cover-w: 10rem;
--cover-h: 10rem;
--cover-small-w: 6rem;
--cover-small-h: 6rem;
--cover-tiny-w: 4rem;
--cover-tiny-h: 4rem;
--section-content-sz: 1rem;
--preview-title-sz: 1rem;
--preview-subtitle-sz: 0.8rem;
--preview-cover-size: 10rem;
--preview-cover-small-size: 6rem;
--preview-cover-tiny-size: 4rem;
--preview-wide-content-sz: 1rem;
}
}
@ -72,6 +91,9 @@
font-size: var(--title-3-sz);
}
.subtitle, .header.preview .subtitle {
color: var(--text-color-light);
}
.subtitle.is-1, .header.preview .subtitle.is-1 {
font-size: var(--subtitle-1-sz);
}
@ -82,26 +104,30 @@
font-size: var(--subtitle-3-sz);
}
.title + .subtitle {
padding-top: 0em !important;
}
.headings a, a.heading, a.subtitle {
text-decoration: none !important;
}
.heading {
display: inline-block;
}
.heading:not(:empty) {
background-color: var(--heading-bg-color);
padding: 0.4rem;
margin-top: 0em !important;
vertical-align: top;
}
.heading:not(:empty).highlight, .heading:not(:empty).active, .preview.active .heading:not(:empty) {
background-color: var(--heading-bg-highlight-color);
color: var(--highlight-color);
}
.heading.title {
background-color: var(--heading-title-bg-color);
color: var(--heading-hg-fg);
}
.preview {
position: relative;
background-size: cover;
background-color: var(--preview-bg) !important;
}
.preview.preview-item {
width: 100%;
@ -135,21 +161,30 @@
.preview .headings a {
color: var(--text-color);
}
.preview .headings a:hover {
color: var(--heading-link-hv-fg) !important;
}
.preview.tiny .content {
font-size: 1rem;
}
@media screen and (max-width: 600px) {
.preview .content {
display: none;
}
}
.preview-cover {
background: var(--preview-bg);
background-size: cover;
background-color: transparent !important;
height: var(--preview-cover-size);
width: var(--preview-cover-size);
min-width: var(--preview-cover-size);
background-repeat: no-repeat;
height: var(--cover-h);
max-width: calc(var(--cover-w) * 1.5);
min-width: var(--cover-w);
overflow: hidden;
border: 1px #c4c4c4 solid;
}
.preview-cover img {
height: var(--cover-h);
max-width: calc(var(--cover-w) * 1.5);
min-width: var(--cover-w);
}
.preview-cover img.hide {
visibility: hidden;
}
.preview-cover.small, .preview.small .preview-cover {
min-width: unset;
@ -184,116 +219,125 @@
}
.list-item {
display: flex;
flex-direction: column;
width: 100%;
}
.list-item:not(:first-child) {
margin-top: 0.6rem;
}
.list-item .headings {
display: flex;
flex-direction: row;
padding-top: 0em;
padding: 0em;
margin-bottom: 0.4rem !important;
}
.list-item .headings .title {
.list-item .headings .heading {
padding: 0rem;
}
.list-item .title {
flex-grow: 1;
}
.list-item .subtitle {
font-size: var(--preview-title-sz);
text-align: right;
}
.list-item .subtitle:not(:empty) {
min-width: 9rem;
}
.list-item .media-content {
display: flex;
flex-direction: column;
height: 100%;
margin-bottom: unset;
}
.list-item:not(.no-cover) .list-item .media-content {
min-height: var(--preview-cover-small-size);
}
.list-item .media-content .content {
flex-grow: 1;
margin-bottom: auto;
}
.list-item .media-content .actions {
flex-grow: unset;
.list-item .actions {
text-align: right;
margin-top: auto;
}
.list-item:not(.wide) .media {
padding: 0.6rem;
border: 1px solid var(--break-color) !important;
}
.preview-wide {
height: var(--preview-cover-size);
display: flex;
@media screen and (max-width: 400px) {
.list-item .headings {
flex-direction: column;
}
.list-item .headings .heading {
display: inline;
text-align: left;
}
.list-item .headings .subtitle {
color: unset !important;
background: none !important;
}
}
.preview-wide .headings {
height: var(--preview-cover-size);
}
.preview-wide:not(.header) .headings {
.list-item.wide .preview-cover {
box-shadow: 0em 0em 1em rgba(0, 0, 0, 0.2);
}
.preview-wide .headings {
width: var(--preview-cover-size);
min-width: var(--preview-cover-size);
flex-grow: 0;
margin-right: 1.2rem;
}
.preview-wide .content {
.list-item.wide .content {
font-size: var(--preview-wide-content-sz);
flex-grow: 1;
}
.preview-card {
display: flex;
flex-direction: column;
width: var(--card-w);
padding: 0rem !important;
height: var(--preview-cover-size);
width: var(--preview-cover-size);
margin-bottom: auto;
background-color: var(--preview-bg) !important;
transition: box-shadow 0.2s;
}
.preview-card.small {
height: var(--preview-cover-small-size);
width: var(--preview-cover-small-size);
.preview-card:hover figure {
box-shadow: 0em 0em 1.2em rgba(0, 0, 0, 0.4) !important;
}
.preview-card.tiny {
height: var(--preview-cover-tiny-size);
width: var(--preview-cover-tiny-size);
.preview-card:hover a {
color: var(--heading-link-hv-fg);
}
.preview-card:not(.header) {
box-shadow: 0em 0em 1em rgba(0, 0, 0, 0.2);
.preview-card .headings {
margin-top: 0.4rem;
}
.preview-card .title {
max-height: calc(var(--preview-cover-size) / 2);
.preview-card .headings .heading {
display: block !important;
}
.preview-card .headings .title {
overflow: hidden;
}
.card-grid .preview-card {
min-width: unset;
.preview-card .headings .subtitle {
font-size: 1.2rem;
}
.preview-card .actions {
.preview-card .card-content {
flex-grow: 1;
position: relative;
}
.preview-card .card-content figure {
box-shadow: 0em 0em 1em rgba(0, 0, 0, 0.2);
height: var(--cover-h);
width: var(--cover-w);
}
.preview-card .card-content .actions {
position: absolute;
bottom: 0.6rem;
right: 0.6rem;
}
.preview-card .actions label {
display: none;
padding: 0.4rem;
bottom: 0rem;
right: 0rem;
}
.card-headings, .preview-card-headings {
padding-top: 0.6rem;
}
.card-headings > div:not(:last-child), .card-headings .column > div, .preview-card-headings > div:not(:last-child), .preview-card-headings .column > div {
margin-bottom: 0.6rem;
}
preview-header:not(.no-cover) .card-headings .heading, preview-header:not(.no-cover) .preview-card-headings .heading {
margin-bottom: 0.6rem;
}
.card-grid {
.list-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr;
grid-auto-flow: dense;
gap: 1.2rem;
}
.a-carousel {
margin-left: calc(0rem - var(--a-carousel-ml));
@media screen and (max-width: 900px) {
.list-grid {
grid-template-columns: 1fr;
}
}
.a-carousel .a-carousel-viewport {
padding: var(--a-carousel-p) 0;
padding-left: var(--a-carousel-ml);
box-shadow: inset 0em 0em 20rem var(--a-carousel-bg);
padding: 0rem;
padding-top: var(--a-carousel-p);
margin-top: calc(0rem - var(--a-carousel-p));
}
.a-carousel-container {
@ -305,18 +349,15 @@ preview-header:not(.no-cover) .card-headings .heading, preview-header:not(.no-co
flex-shrink: 0;
}
.a-carousel-button-container button, .a-carousel-button-container .button {
z-index: 1000;
position: absolute;
display: flex;
flex-direction: column;
top: 50%;
.a-carousel-bullets-container {
padding-left: var(--a-carousel-ml);
}
.a-carousel-button-container button.prev, .a-carousel-button-container .button.prev {
left: var(--a-carousel-nav-x);
.a-carousel-bullets-container .bullet {
margin: 0.2rem;
cursor: pointer;
}
.a-carousel-button-container button.next, .a-carousel-button-container .button.next {
right: var(--a-carousel-nav-x);
.a-carousel-bullets-container .bullet:hover {
color: var(--link-fg);
}
.a-progress {
@ -369,7 +410,7 @@ preview-header:not(.no-cover) .card-headings .heading, preview-header:not(.no-co
height: 3rem;
background-color: var(--a-sound-bg);
}
.a-sound-item.playing, .a-sound-item.playing .label {
.a-sound-item.playing .label {
color: var(--a-sound-playing-fg) !important;
}
.a-sound-item:hover {
@ -401,6 +442,10 @@ preview-header:not(.no-cover) .card-headings .heading, preview-header:not(.no-co
width: 3em;
font-size: var(--a-sound-text-sz);
}
.a-sound-item .button:hover {
color: var(--a-sound-hv-fg) !important;
background-color: unset;
}
.player-container {
z-index: 1000000;
@ -480,11 +525,10 @@ preview-header:not(.no-cover) .card-headings .heading, preview-header:not(.no-co
padding: 0.4rem !important;
min-width: calc(var(--a-player-bar-height) + 0.8rem);
border-radius: 0px;
transition: background-color 0.5s;
}
.a-player-bar .button.open {
background-color: var(--highlight-color-2-alpha);
color: var(--highlight-color);
background-color: var(--button-active-bg);
color: var(--button-active-fg);
}
.a-player-bar-content {
@ -7276,23 +7320,27 @@ a.tag:hover {
padding-bottom: 5rem;
}
.page a {
color: var(--highlight-color-2);
text-decoration: none;
color: var(--link-fg);
text-decoration: underline;
}
.page a:hover {
color: var(--text-color);
color: var(--link-hv-fg);
}
.page section.container {
margin-top: 0.6rem;
}
.page section.container > .title {
margin-top: unset;
padding-top: unset !important;
margin-bottom: 1.2rem;
border-bottom: 1px solid black;
}
.page section.container:not(:last-child) {
margin-bottom: 0.6rem;
padding-bottom: 0.6rem;
border-bottom: 2px var(--break-color) solid;
}
.page section.container > .title {
font-size: var(--title-2-sz);
clear: both;
margin: 0.6rem 0;
}
.page *[data-oembed-url] {
clear: both;
}
.dropdown-item {
@ -7300,7 +7348,7 @@ a.tag:hover {
}
.vc-weekday-1, .vc-weekday-7 {
color: var(--highlight-color-2) !important;
color: var(--hg-color-2) !important;
}
.schedules {
@ -7312,56 +7360,62 @@ a.tag:hover {
display: inline-block;
margin: 0.6rem;
margin-left: 0rem;
padding: 0.4rem;
border-bottom: 1px var(--main-color) solid;
}
.schedule .heading {
padding: 0em;
}
.schedule .day {
font-weight: 700;
margin-right: 0.6rem;
}
.button, a.button, button.button, .nav-urls a {
.button, a.button, button.button {
font-size: 1rem;
display: inline-block;
padding: 0.4rem;
border: 1px var(--highlight-color-2-alpha) solid;
border: none;
justify-content: center;
text-align: center;
cursor: pointer;
text-decoration: none;
color: var(--button-fg);
background-color: var(--button-bg);
}
.button.secondary, a.button.secondary, button.button.secondary, .nav-urls a.secondary {
.button.secondary, a.button.secondary, button.button.secondary {
background-color: var(--button-sec-bg);
}
.button .icon, a.button .icon, button.button .icon, .nav-urls a .icon {
.button .label, .button label, a.button .label, a.button label, button.button .label, button.button label {
cursor: pointer;
}
.button .icon, a.button .icon, button.button .icon {
vertical-align: middle;
}
.button .icon:not(:only-child):first-child, a.button .icon:not(:only-child):first-child, button.button .icon:not(:only-child):first-child, .nav-urls a .icon:not(:only-child):first-child {
.button .icon:not(:only-child):first-child, a.button .icon:not(:only-child):first-child, button.button .icon:not(:only-child):first-child {
margin-right: 0.6rem;
}
.button .icon:not(:only-child):last-child, a.button .icon:not(:only-child):last-child, button.button .icon:not(:only-child):last-child, .nav-urls a .icon:not(:only-child):last-child {
.button .icon:not(:only-child):last-child, a.button .icon:not(:only-child):last-child, button.button .icon:not(:only-child):last-child {
margin-left: 0.6rem;
}
.button:hover, a.button:hover, button.button:hover, .nav-urls a:hover {
color: var(--button-hg-fg);
.button:hover, a.button:hover, button.button:hover {
color: var(--button-hv-fg);
background-color: var(--button-hv-bg);
opacity: 1 !important;
}
.button.active, a.button.active, button.button.active, .nav-urls a.active {
border-color: var(--highlight-color-alpha);
.button.active:not(:hover), a.button.active:not(:hover), button.button.active:not(:hover) {
color: var(--button-active-fg);
background-color: var(--button-active-bg);
}
.button.active:hover, a.button.active:hover, button.button.active:hover, .nav-urls a.active:hover {
border-color: var(--highlight-color);
background-color: var(--highlight-color-2-alpha);
opacity: 1 !important;
}
.button:not([disabled]), .button:not(.disabled), a.button:not([disabled]), a.button:not(.disabled), button.button:not([disabled]), button.button:not(.disabled), .nav-urls a:not([disabled]), .nav-urls a:not(.disabled) {
.button:not([disabled]), .button:not(.disabled), a.button:not([disabled]), a.button:not(.disabled), button.button:not([disabled]), button.button:not(.disabled) {
cursor: pointer;
}
.button[disabled], .button.disabled, a.button[disabled], a.button.disabled, button.button[disabled], button.button.disabled, .nav-urls a[disabled], .nav-urls a.disabled {
background-color: var(--highlight-color-grey);
color: var(--highlight-color-2);
border-color: var(--highlight-color-2-alpha);
.button[disabled], .button.disabled, a.button[disabled], a.button.disabled, button.button[disabled], button.button.disabled {
background-color: var(--hg-color-grey);
color: var(--hg-color-2);
border-color: var(--hg-color-2-alpha);
}
.button .dropdown-trigger, a.button .dropdown-trigger, button.button .dropdown-trigger, .nav-urls a .dropdown-trigger {
.button .dropdown-trigger, a.button .dropdown-trigger, button.button .dropdown-trigger {
border-radius: 1.5em;
}
@ -7388,17 +7442,18 @@ a.tag:hover {
.actions.no-label label {
display: none;
}
.actions button, .actions .action {
.actions button, .actions .action, .actions a {
justify-content: center;
min-width: 2rem;
padding: 0.4rem;
}
.actions button .not-selected, .actions .action .not-selected {
.actions button .not-selected, .actions .action .not-selected, .actions a .not-selected {
opacity: 0.6;
}
.actions button .icon, .actions .action .icon {
.actions button .icon, .actions .action .icon, .actions a .icon {
margin: 0em !important;
}
.actions button label, .actions .action label {
.actions button label, .actions .action label, .actions a label {
margin-left: 0.4rem;
}
@ -7426,8 +7481,8 @@ a.tag:hover {
}
}
.navbar-item.active, .table tr.is-selected {
color: var(--highlight-color-2);
background-color: var(--highlight-color);
color: var(--hg-color-2);
background-color: var(--hg-color);
}
.title {
@ -7459,24 +7514,24 @@ a.tag:hover {
text-align: center;
font-family: var(--heading-font-family);
text-transform: uppercase;
}
.nav .nav-item a, .nav .nav-item .button {
display: block;
width: 100%;
color: var(--nav-fg) !important;
}
.nav .nav-item .icon:first-child, .nav .nav-item .icon + span {
text-align: center;
vertical-align: top;
display: inline-block;
}
.nav .nav-item:hover {
background-color: var(--nav-hv-bg);
color: var(--nav-hv-fg);
}
.nav .nav-item.active {
background-color: var(--nav-active-bg);
color: var(--nav-active-fg);
color: var(--nav-active-fg) !important;
}
.nav .nav-menu {
display: flex;
flex-grow: 1;
background-color: var(--nav-bg);
}
.nav .nav-menu .dropdown-content {
font-size: 1rem;
@ -7503,7 +7558,7 @@ a.tag:hover {
white-space: nowrap;
}
.nav.secondary {
background-color: var(--nav-bg);
background-color: var(--nav-secondary-bg);
justify-content: right;
}
.nav.primary:hover + .nav.secondary, .nav.secondary:hover {
@ -7518,6 +7573,7 @@ a.tag:hover {
.breadcrumbs {
text-align: right;
padding: 0.6rem 0rem;
font-size: 0.8rem;
padding-bottom: 0;
margin-bottom: 0;
}
@ -7548,7 +7604,7 @@ a.tag:hover {
flex-grow: 1;
}
.navs .nav + .nav {
flew-grow: 0 !important;
flex-grow: 0 !important;
}
.nav {
justify-content: space-between;
@ -7560,6 +7616,7 @@ a.tag:hover {
.nav .nav-menu {
display: block;
position: absolute;
background-color: var(--nav-secondary-bg);
left: 0;
top: 100%;
width: 100%;
@ -7568,10 +7625,7 @@ a.tag:hover {
.nav .nav-menu .nav-item {
display: block;
font-weight: 400;
}
.nav .nav-menu .nav-item:hover {
background-color: var(--highlight-color-2-alpha);
color: var(--highlight-color);
font-size: var(--nav-fs);
}
.nav .nav-menu:not(.active) {
display: none !important;
@ -7634,15 +7688,40 @@ nav li a, nav li .button {
.header-cover:not(:only-child) {
float: right;
height: var(--header-height);
max-width: calc(var(--header-height) * 2);
position: relative;
z-index: 1000;
background-color: var(--body-bg);
margin: 0 0 1.2rem 1.2rem;
}
.header-cover:not(:only-child) .cover {
max-width: calc(var(--header-height) * 2);
height: var(--header-height);
}
.header-cover:only-child {
with: 100%;
}
@media screen and (max-width: 600px) {
.container.header {
width: calc(100% - 0.4rem);
}
.container.header .headings {
width: 100%;
clear: both;
}
.container.header .header-cover {
float: none;
margin: 0;
text-align: center;
}
.container.header .cover {
margin-left: auto;
margin-right: auto;
max-height: calc(var(--cover-h) * 1);
max-width: calc(var(--cover-w) * 2);
}
}
.page-content {
margin-top: 2rem;
}
@ -7650,6 +7729,20 @@ nav li a, nav li .button {
margin-bottom: 2rem;
}
.list-item.logs .track {
margin-right: 0.6rem;
}
.list-item.logs .track .icon {
margin-right: 0.4rem;
color: var(--secondary-color-dark);
}
.list-item:nth-child(3n):not(.wide) .media {
border-color: var(--main-color-dark) !important;
}
.list-item:nth-child(3n+1):not(.wide) .media {
border-color: var(--secondary-color-dark) !important;
}
body {
font-size: 1.4em;
}
@ -7670,19 +7763,4 @@ body {
margin-left: 0.4rem;
margin-right: 0.4rem;
}
.container.header {
width: calc(100% - 0.4rem);
}
.container.header .headings {
width: 100%;
clear: both;
}
.container.header .header-cover {
float: none;
width: 100%;
max-width: unset;
height: unset;
margin-left: 0rem;
margin-right: 0rem;
}
}

View File

@ -35,7 +35,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _mod
\*******************************************************************************************************************************************************************************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm-bundler.js\");\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n setup() {\n return {\n viewport: (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(null),\n container: (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(null)\n };\n },\n data() {\n return {\n cards: [],\n index: 0,\n refresh_: 0\n };\n },\n props: {\n cardSelector: {\n type: String,\n default: ''\n },\n containerClass: {\n type: String,\n default: ''\n },\n buttonClass: {\n type: String,\n default: 'button'\n },\n leftButtonIcon: {\n type: String,\n default: \"fas fa-chevron-left\"\n },\n rightButtonIcon: {\n type: String,\n default: \"fas fa-chevron-right\"\n }\n },\n computed: {\n card() {\n return this.cards()[this.index];\n },\n showPrevButton() {\n return this.index > 0;\n },\n showNextButton() {\n if (!this.cards || this.cards.length <= 1) return false;\n let {\n count\n } = this.visibility;\n return this.index + count < this.cards.length;\n },\n visibility() {\n // force refresh on index\n [this.index, this.refresh_];\n if (!this.cards) return {\n min: -1,\n max: -1,\n count: 0\n };\n const vOff = this.offset(this.$refs.viewport);\n var [min, max] = [-1, -1];\n for (let at = 0; at < this.cards.length; at++) {\n const card = this.cards[at];\n const cOff = this.offset(card);\n const visible = vOff.min <= cOff.min && vOff.max >= cOff.max;\n if (visible) {\n if (min === -1) min = parseInt(at);\n max = parseInt(at);\n }\n }\n if (max !== -1) max++;\n return {\n min,\n max,\n count: min !== -1 ? max - min : 0\n };\n }\n },\n methods: {\n offset(el, parent = null) {\n const rect = el.getBoundingClientRect();\n const off = {\n min: rect.left,\n max: rect.right\n };\n if (parent === null) return off;\n const pOff = this.offset(parent);\n return {\n min: off.min - pOff.min,\n max: off.max - pOff.max\n };\n },\n getCards() {\n if (!this.$refs.container) return [];\n if (!this.cardSelector) return this.$refs.container.children;\n return this.$refs.container.querySelectorAll(this.cardSelector);\n },\n selectIndex(index, relative = false) {\n if (relative) index = this.index + index;\n index = Math.min(this.cards.length, index);\n const el = this.cards[index];\n if (!el) return null;\n const elOff = this.offset(el, this.$refs.container);\n this.$refs.container.style.marginLeft = `-${elOff.min}px`;\n this.index = index;\n return el;\n },\n next() {\n this.refresh_++;\n if (!this.visibility.count) return;\n let {\n count\n } = this.visibility;\n let at = Math.min(count === 1 ? this.index + count : this.index + count - 1, this.cards.length - count);\n this.selectIndex(at);\n },\n prev() {\n this.refresh_++;\n if (!this.visibility.count) return;\n const {\n min,\n count\n } = this.visibility;\n let at = Math.max(0, min - count);\n if (min < 0 || count <= 0) return;\n this.selectIndex(at);\n },\n refresh() {\n this.cards = this.getCards();\n this.selectIndex(this.index);\n this.refresh_++;\n }\n },\n mounted() {\n this.observers = [new MutationObserver(() => this.refresh()), new ResizeObserver(() => this.refresh())];\n this.observers[0].observe(this.$refs.container, {\n \"childList\": true\n });\n this.observers[1].observe(this.$refs.container);\n this.refresh();\n },\n unmounted() {\n for (var observer of this.observers) observer.disconnect();\n }\n});\n\n//# sourceURL=webpack://aircox-assets/./src/components/ACarousel.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.push.js */ \"./node_modules/core-js/modules/es.array.push.js\");\n/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm-bundler.js\");\n\n\nclass Offset {\n constructor(el, min = null, max = null) {\n this.el = el;\n this.rect = el.getBoundingClientRect();\n ({\n min,\n max\n } = this.minmax(min, max));\n this.min = min;\n this.max = max;\n this.size = max - min;\n }\n minmax(min = null, max = null) {\n min = min === null ? this.rect.left : min;\n max = max === null ? this.rect.right : max;\n return {\n min,\n max\n };\n }\n relative(to) {\n return new Offset(this.el, this.min - to.min, this.max - to.min);\n }\n}\nclass Card extends Offset {\n constructor(el, index) {\n super(el);\n this.index = index;\n }\n visible(viewportOffset) {\n return viewportOffset.min <= this.min && viewportOffset.max >= this.max;\n }\n}\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n setup() {\n return {\n viewport: (0,vue__WEBPACK_IMPORTED_MODULE_1__.ref)(null),\n container: (0,vue__WEBPACK_IMPORTED_MODULE_1__.ref)(null)\n };\n },\n data() {\n return {\n cards: [],\n index: 0,\n refresh_: 0\n };\n },\n props: {\n cardSelector: {\n type: String,\n default: ''\n },\n containerClass: {\n type: String,\n default: ''\n },\n buttonClass: {\n type: String,\n default: 'button'\n },\n leftButtonIcon: {\n type: String,\n default: \"fas fa-chevron-left\"\n },\n rightButtonIcon: {\n type: String,\n default: \"fas fa-chevron-right\"\n }\n },\n computed: {\n card() {\n return this.cards()[this.index];\n },\n showPrev() {\n return this.index > 0;\n },\n showNext() {\n if (!this.cards || this.cards.length <= 1) return false;\n let last = this.bullets[this.bullets.length - 1];\n return this.index != last;\n },\n bullets() {\n if (!this.cards || !this.$refs.viewport) return [];\n let contOff = new Offset(this.$refs.container);\n let viewMax = new Offset(this.$refs.viewport).size;\n let bullets = [];\n let i = 0;\n let max = viewMax;\n bullets.push(i);\n while (i < this.cards.length) {\n // skip until next view\n for (; i < this.cards.length; i++) {\n let card = this.cards[i].relative(contOff);\n if (card.max > max) {\n max = card.min + viewMax;\n bullets.push(i);\n i++;\n break;\n }\n }\n }\n return bullets;\n }\n },\n methods: {\n getCards() {\n if (!this.$refs.container) return [];\n let nodes = !this.cardSelector ? [...this.$refs.container.children] : [...this.$refs.container.querySelectorAll(this.cardSelector)];\n return nodes.map((el, index) => new Card(el, index));\n },\n select(index, relative = false) {\n if (relative) index = this.index + index;\n index = Math.min(index, this.cards.length);\n index = Math.max(index, 0);\n let card = this.cards[index];\n if (!card) return null;\n card = new Card(card.el);\n const cont = new Offset(this.$refs.container);\n const rel = card.relative(cont);\n this.$refs.container.style.marginLeft = `-${rel.min}px`;\n this.index = index;\n return card.el;\n },\n next() {\n let n = this.bullets.indexOf(this.index);\n let index = this.bullets[n + 1];\n this.select(index);\n },\n prev() {\n let n = this.bullets.indexOf(this.index);\n let index = this.bullets[n - 1];\n this.select(index);\n },\n refresh() {\n this.cards = this.getCards();\n this.select(this.index);\n this.refresh_++;\n }\n },\n mounted() {\n this.observers = [new MutationObserver(() => this.refresh()), new ResizeObserver(() => this.refresh())];\n this.observers[0].observe(this.$refs.container, {\n \"childList\": true\n });\n this.observers[1].observe(this.$refs.container);\n this.refresh();\n },\n unmounted() {\n for (var observer of this.observers) observer.disconnect();\n }\n});\n\n//# sourceURL=webpack://aircox-assets/./src/components/ACarousel.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D");
/***/ }),
@ -205,7 +205,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
\***********************************************************************************************************************************************************************************************************************************************************************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm-bundler.js\");\n\nconst _withScopeId = n => ((0,vue__WEBPACK_IMPORTED_MODULE_0__.pushScopeId)(\"data-v-b79f173e\"), n = n(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.popScopeId)(), n);\nconst _hoisted_1 = {\n class: \"a-carousel\"\n};\nconst _hoisted_2 = {\n key: 0,\n class: \"a-carousel-button-container\"\n};\nconst _hoisted_3 = {\n class: \"icon\"\n};\nconst _hoisted_4 = {\n key: 1,\n class: \"a-carousel-button-container\"\n};\nconst _hoisted_5 = {\n class: \"icon\"\n};\nconst _hoisted_6 = {\n ref: \"viewport\",\n class: \"a-carousel-viewport\"\n};\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"section\", _hoisted_1, [$options.showPrevButton ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"nav\", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([$props.buttonClass, 'prev']),\n \"aria-label\": \"Go left\",\n onClick: _cache[0] || (_cache[0] = (...args) => $options.prev && $options.prev(...args))\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"i\", {\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)($props.leftButtonIcon)\n }, null, 2 /* CLASS */)])], 2 /* CLASS */)])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), $options.showNextButton ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", _hoisted_4, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"button\", {\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)([$props.buttonClass, 'next']),\n \"aria-label\": \"Go left\",\n onClick: _cache[1] || (_cache[1] = (...args) => $options.next && $options.next(...args))\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", _hoisted_5, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"i\", {\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)($props.rightButtonIcon)\n }, null, 2 /* CLASS */)])], 2 /* CLASS */)])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"nav\", _hoisted_6, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"section\", {\n ref: \"container\",\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(['a-carousel-container', $props.containerClass])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.renderSlot)(_ctx.$slots, \"default\", {}, undefined, true)], 2 /* CLASS */)], 512 /* NEED_PATCH */)]);\n}\n\n//# sourceURL=webpack://aircox-assets/./src/components/ACarousel.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B3%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm-bundler.js\");\n\nconst _withScopeId = n => ((0,vue__WEBPACK_IMPORTED_MODULE_0__.pushScopeId)(\"data-v-b79f173e\"), n = n(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.popScopeId)(), n);\nconst _hoisted_1 = {\n class: \"a-carousel\"\n};\nconst _hoisted_2 = {\n ref: \"viewport\",\n class: \"a-carousel-viewport\"\n};\nconst _hoisted_3 = {\n class: \"a-carousel-bullets-container\"\n};\nconst _hoisted_4 = {\n class: \"left\"\n};\nconst _hoisted_5 = [\"onClick\"];\nconst _hoisted_6 = {\n key: 0,\n class: \"fa fa-circle\"\n};\nconst _hoisted_7 = {\n key: 1,\n class: \"far fa-circle\"\n};\nconst _hoisted_8 = {\n class: \"right\"\n};\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"section\", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"nav\", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"section\", {\n ref: \"container\",\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(['a-carousel-container', $props.containerClass])\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.renderSlot)(_ctx.$slots, \"default\", {}, undefined, true)], 2 /* CLASS */)], 512 /* NEED_PATCH */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"nav\", _hoisted_3, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", _hoisted_4, [$options.showPrev ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", {\n key: 0,\n class: \"icon bullet\",\n onClick: _cache[0] || (_cache[0] = $event => $options.prev())\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"i\", {\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)($props.leftButtonIcon)\n }, null, 2 /* CLASS */)])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)]), $options.bullets.length > 1 ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, {\n key: 0\n }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($options.bullets, bullet => {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", {\n class: \"icon bullet\",\n key: bullet,\n onClick: $event => $options.select(bullet)\n }, [bullet == $data.index ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"i\", _hoisted_6)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"i\", _hoisted_7))], 8 /* PROPS */, _hoisted_5);\n }), 128 /* KEYED_FRAGMENT */)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"span\", _hoisted_8, [$options.showNext ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"span\", {\n key: 0,\n class: \"icon bullet\",\n onClick: _cache[1] || (_cache[1] = $event => $options.next())\n }, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)(\"i\", {\n class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)($props.rightButtonIcon)\n }, null, 2 /* CLASS */)])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(\"v-if\", true)]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderSlot)(_ctx.$slots, \"bullets-right\", {\n vBind: this\n }, undefined, true)])]);\n}\n\n//# sourceURL=webpack://aircox-assets/./src/components/ACarousel.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B3%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D");
/***/ }),
@ -225,7 +225,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
\**********************************************************************************************************************************************************************************************************************************************************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm-bundler.js\");\n\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(\"div\", null, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.renderSlot)(_ctx.$slots, \"default\", {\n page: _ctx.page,\n podcasts: $data.podcasts\n })]);\n}\n\n//# sourceURL=webpack://aircox-assets/./src/components/AEpisode.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B3%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ render: function() { return /* binding */ render; }\n/* harmony export */ });\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm-bundler.js\");\n\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderSlot)(_ctx.$slots, \"default\", {\n page: _ctx.page,\n podcasts: $data.podcasts\n });\n}\n\n//# sourceURL=webpack://aircox-assets/./src/components/AEpisode.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use%5B0%5D!./node_modules/vue-loader/dist/templateLoader.js??ruleSet%5B1%5D.rules%5B3%5D!./node_modules/vue-loader/dist/index.js??ruleSet%5B0%5D.use%5B0%5D");
/***/ }),
@ -485,7 +485,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n// extracted by mini-css-extr
\******************************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _AActionButton_vue_vue_type_template_id_3f443389__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AActionButton.vue?vue&type=template&id=3f443389 */ \"./src/components/AActionButton.vue?vue&type=template&id=3f443389\");\n/* harmony import */ var _AActionButton_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AActionButton.vue?vue&type=script&lang=js */ \"./src/components/AActionButton.vue?vue&type=script&lang=js\");\n/* harmony import */ var _home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_AActionButton_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_AActionButton_vue_vue_type_template_id_3f443389__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/AActionButton.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/AActionButton.vue?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _AActionButton_vue_vue_type_template_id_3f443389__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AActionButton.vue?vue&type=template&id=3f443389 */ \"./src/components/AActionButton.vue?vue&type=template&id=3f443389\");\n/* harmony import */ var _AActionButton_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AActionButton.vue?vue&type=script&lang=js */ \"./src/components/AActionButton.vue?vue&type=script&lang=js\");\n/* harmony import */ var _media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_AActionButton_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_AActionButton_vue_vue_type_template_id_3f443389__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/AActionButton.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/AActionButton.vue?");
/***/ }),
@ -495,7 +495,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _AAc
\******************************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _AAutocomplete_vue_vue_type_template_id_32d72269__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AAutocomplete.vue?vue&type=template&id=32d72269 */ \"./src/components/AAutocomplete.vue?vue&type=template&id=32d72269\");\n/* harmony import */ var _AAutocomplete_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AAutocomplete.vue?vue&type=script&lang=js */ \"./src/components/AAutocomplete.vue?vue&type=script&lang=js\");\n/* harmony import */ var _home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_AAutocomplete_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_AAutocomplete_vue_vue_type_template_id_32d72269__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/AAutocomplete.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/AAutocomplete.vue?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _AAutocomplete_vue_vue_type_template_id_32d72269__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AAutocomplete.vue?vue&type=template&id=32d72269 */ \"./src/components/AAutocomplete.vue?vue&type=template&id=32d72269\");\n/* harmony import */ var _AAutocomplete_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AAutocomplete.vue?vue&type=script&lang=js */ \"./src/components/AAutocomplete.vue?vue&type=script&lang=js\");\n/* harmony import */ var _media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_AAutocomplete_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_AAutocomplete_vue_vue_type_template_id_32d72269__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/AAutocomplete.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/AAutocomplete.vue?");
/***/ }),
@ -505,7 +505,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _AAu
\**************************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ACarousel_vue_vue_type_template_id_b79f173e_scoped_true__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ACarousel.vue?vue&type=template&id=b79f173e&scoped=true */ \"./src/components/ACarousel.vue?vue&type=template&id=b79f173e&scoped=true\");\n/* harmony import */ var _ACarousel_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ACarousel.vue?vue&type=script&lang=js */ \"./src/components/ACarousel.vue?vue&type=script&lang=js\");\n/* harmony import */ var _ACarousel_vue_vue_type_style_index_0_id_b79f173e_scoped_true_lang_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ACarousel.vue?vue&type=style&index=0&id=b79f173e&scoped=true&lang=css */ \"./src/components/ACarousel.vue?vue&type=style&index=0&id=b79f173e&scoped=true&lang=css\");\n/* harmony import */ var _home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\n\n\nconst __exports__ = /*#__PURE__*/(0,_home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(_ACarousel_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_ACarousel_vue_vue_type_template_id_b79f173e_scoped_true__WEBPACK_IMPORTED_MODULE_0__.render],['__scopeId',\"data-v-b79f173e\"],['__file',\"src/components/ACarousel.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/ACarousel.vue?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ACarousel_vue_vue_type_template_id_b79f173e_scoped_true__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ACarousel.vue?vue&type=template&id=b79f173e&scoped=true */ \"./src/components/ACarousel.vue?vue&type=template&id=b79f173e&scoped=true\");\n/* harmony import */ var _ACarousel_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ACarousel.vue?vue&type=script&lang=js */ \"./src/components/ACarousel.vue?vue&type=script&lang=js\");\n/* harmony import */ var _ACarousel_vue_vue_type_style_index_0_id_b79f173e_scoped_true_lang_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ACarousel.vue?vue&type=style&index=0&id=b79f173e&scoped=true&lang=css */ \"./src/components/ACarousel.vue?vue&type=style&index=0&id=b79f173e&scoped=true&lang=css\");\n/* harmony import */ var _media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\n\n\nconst __exports__ = /*#__PURE__*/(0,_media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(_ACarousel_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_ACarousel_vue_vue_type_template_id_b79f173e_scoped_true__WEBPACK_IMPORTED_MODULE_0__.render],['__scopeId',\"data-v-b79f173e\"],['__file',\"src/components/ACarousel.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/ACarousel.vue?");
/***/ }),
@ -515,7 +515,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ACa
\**************************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ADropdown_vue_vue_type_template_id_a87ed2dc__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ADropdown.vue?vue&type=template&id=a87ed2dc */ \"./src/components/ADropdown.vue?vue&type=template&id=a87ed2dc\");\n/* harmony import */ var _ADropdown_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ADropdown.vue?vue&type=script&lang=js */ \"./src/components/ADropdown.vue?vue&type=script&lang=js\");\n/* harmony import */ var _home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_ADropdown_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_ADropdown_vue_vue_type_template_id_a87ed2dc__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/ADropdown.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/ADropdown.vue?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ADropdown_vue_vue_type_template_id_a87ed2dc__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ADropdown.vue?vue&type=template&id=a87ed2dc */ \"./src/components/ADropdown.vue?vue&type=template&id=a87ed2dc\");\n/* harmony import */ var _ADropdown_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ADropdown.vue?vue&type=script&lang=js */ \"./src/components/ADropdown.vue?vue&type=script&lang=js\");\n/* harmony import */ var _media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_ADropdown_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_ADropdown_vue_vue_type_template_id_a87ed2dc__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/ADropdown.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/ADropdown.vue?");
/***/ }),
@ -525,7 +525,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ADr
\*************************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _AEpisode_vue_vue_type_template_id_2e4db98a__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AEpisode.vue?vue&type=template&id=2e4db98a */ \"./src/components/AEpisode.vue?vue&type=template&id=2e4db98a\");\n/* harmony import */ var _AEpisode_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AEpisode.vue?vue&type=script&lang=js */ \"./src/components/AEpisode.vue?vue&type=script&lang=js\");\n/* harmony import */ var _home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_AEpisode_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_AEpisode_vue_vue_type_template_id_2e4db98a__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/AEpisode.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/AEpisode.vue?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _AEpisode_vue_vue_type_template_id_2e4db98a__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AEpisode.vue?vue&type=template&id=2e4db98a */ \"./src/components/AEpisode.vue?vue&type=template&id=2e4db98a\");\n/* harmony import */ var _AEpisode_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AEpisode.vue?vue&type=script&lang=js */ \"./src/components/AEpisode.vue?vue&type=script&lang=js\");\n/* harmony import */ var _media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_AEpisode_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_AEpisode_vue_vue_type_template_id_2e4db98a__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/AEpisode.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/AEpisode.vue?");
/***/ }),
@ -535,7 +535,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _AEp
\**********************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _AList_vue_vue_type_template_id_70c3911f__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AList.vue?vue&type=template&id=70c3911f */ \"./src/components/AList.vue?vue&type=template&id=70c3911f\");\n/* harmony import */ var _AList_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AList.vue?vue&type=script&lang=js */ \"./src/components/AList.vue?vue&type=script&lang=js\");\n/* harmony import */ var _home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_AList_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_AList_vue_vue_type_template_id_70c3911f__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/AList.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/AList.vue?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _AList_vue_vue_type_template_id_70c3911f__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AList.vue?vue&type=template&id=70c3911f */ \"./src/components/AList.vue?vue&type=template&id=70c3911f\");\n/* harmony import */ var _AList_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AList.vue?vue&type=script&lang=js */ \"./src/components/AList.vue?vue&type=script&lang=js\");\n/* harmony import */ var _media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_AList_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_AList_vue_vue_type_template_id_70c3911f__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/AList.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/AList.vue?");
/***/ }),
@ -545,7 +545,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ALi
\**********************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _APage_vue_vue_type_template_id_53c8e290__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./APage.vue?vue&type=template&id=53c8e290 */ \"./src/components/APage.vue?vue&type=template&id=53c8e290\");\n/* harmony import */ var _APage_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./APage.vue?vue&type=script&lang=js */ \"./src/components/APage.vue?vue&type=script&lang=js\");\n/* harmony import */ var _home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_APage_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_APage_vue_vue_type_template_id_53c8e290__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/APage.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/APage.vue?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _APage_vue_vue_type_template_id_53c8e290__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./APage.vue?vue&type=template&id=53c8e290 */ \"./src/components/APage.vue?vue&type=template&id=53c8e290\");\n/* harmony import */ var _APage_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./APage.vue?vue&type=script&lang=js */ \"./src/components/APage.vue?vue&type=script&lang=js\");\n/* harmony import */ var _media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_APage_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_APage_vue_vue_type_template_id_53c8e290__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/APage.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/APage.vue?");
/***/ }),
@ -555,7 +555,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _APa
\************************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ State: function() { return /* reexport safe */ _APlayer_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__.State; }\n/* harmony export */ });\n/* harmony import */ var _APlayer_vue_vue_type_template_id_1779e8bc__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./APlayer.vue?vue&type=template&id=1779e8bc */ \"./src/components/APlayer.vue?vue&type=template&id=1779e8bc\");\n/* harmony import */ var _APlayer_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./APlayer.vue?vue&type=script&lang=js */ \"./src/components/APlayer.vue?vue&type=script&lang=js\");\n/* harmony import */ var _home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_APlayer_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_APlayer_vue_vue_type_template_id_1779e8bc__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/APlayer.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/APlayer.vue?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ State: function() { return /* reexport safe */ _APlayer_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__.State; }\n/* harmony export */ });\n/* harmony import */ var _APlayer_vue_vue_type_template_id_1779e8bc__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./APlayer.vue?vue&type=template&id=1779e8bc */ \"./src/components/APlayer.vue?vue&type=template&id=1779e8bc\");\n/* harmony import */ var _APlayer_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./APlayer.vue?vue&type=script&lang=js */ \"./src/components/APlayer.vue?vue&type=script&lang=js\");\n/* harmony import */ var _media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_APlayer_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_APlayer_vue_vue_type_template_id_1779e8bc__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/APlayer.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/APlayer.vue?");
/***/ }),
@ -565,7 +565,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
\**************************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _APlaylist_vue_vue_type_template_id_60410bd3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./APlaylist.vue?vue&type=template&id=60410bd3 */ \"./src/components/APlaylist.vue?vue&type=template&id=60410bd3\");\n/* harmony import */ var _APlaylist_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./APlaylist.vue?vue&type=script&lang=js */ \"./src/components/APlaylist.vue?vue&type=script&lang=js\");\n/* harmony import */ var _home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_APlaylist_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_APlaylist_vue_vue_type_template_id_60410bd3__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/APlaylist.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/APlaylist.vue?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _APlaylist_vue_vue_type_template_id_60410bd3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./APlaylist.vue?vue&type=template&id=60410bd3 */ \"./src/components/APlaylist.vue?vue&type=template&id=60410bd3\");\n/* harmony import */ var _APlaylist_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./APlaylist.vue?vue&type=script&lang=js */ \"./src/components/APlaylist.vue?vue&type=script&lang=js\");\n/* harmony import */ var _media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_APlaylist_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_APlaylist_vue_vue_type_template_id_60410bd3__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/APlaylist.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/APlaylist.vue?");
/***/ }),
@ -575,7 +575,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _APl
\********************************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Page: function() { return /* reexport safe */ _APlaylistEditor_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__.Page; }\n/* harmony export */ });\n/* harmony import */ var _APlaylistEditor_vue_vue_type_template_id_6e4f72a0__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./APlaylistEditor.vue?vue&type=template&id=6e4f72a0 */ \"./src/components/APlaylistEditor.vue?vue&type=template&id=6e4f72a0\");\n/* harmony import */ var _APlaylistEditor_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./APlaylistEditor.vue?vue&type=script&lang=js */ \"./src/components/APlaylistEditor.vue?vue&type=script&lang=js\");\n/* harmony import */ var _home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_APlaylistEditor_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_APlaylistEditor_vue_vue_type_template_id_6e4f72a0__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/APlaylistEditor.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/APlaylistEditor.vue?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Page: function() { return /* reexport safe */ _APlaylistEditor_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__.Page; }\n/* harmony export */ });\n/* harmony import */ var _APlaylistEditor_vue_vue_type_template_id_6e4f72a0__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./APlaylistEditor.vue?vue&type=template&id=6e4f72a0 */ \"./src/components/APlaylistEditor.vue?vue&type=template&id=6e4f72a0\");\n/* harmony import */ var _APlaylistEditor_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./APlaylistEditor.vue?vue&type=script&lang=js */ \"./src/components/APlaylistEditor.vue?vue&type=script&lang=js\");\n/* harmony import */ var _media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_APlaylistEditor_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_APlaylistEditor_vue_vue_type_template_id_6e4f72a0__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/APlaylistEditor.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/APlaylistEditor.vue?");
/***/ }),
@ -585,7 +585,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
\**************************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _AProgress_vue_vue_type_template_id_6871a6ae__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AProgress.vue?vue&type=template&id=6871a6ae */ \"./src/components/AProgress.vue?vue&type=template&id=6871a6ae\");\n/* harmony import */ var _AProgress_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AProgress.vue?vue&type=script&lang=js */ \"./src/components/AProgress.vue?vue&type=script&lang=js\");\n/* harmony import */ var _home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_AProgress_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_AProgress_vue_vue_type_template_id_6871a6ae__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/AProgress.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/AProgress.vue?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _AProgress_vue_vue_type_template_id_6871a6ae__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AProgress.vue?vue&type=template&id=6871a6ae */ \"./src/components/AProgress.vue?vue&type=template&id=6871a6ae\");\n/* harmony import */ var _AProgress_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AProgress.vue?vue&type=script&lang=js */ \"./src/components/AProgress.vue?vue&type=script&lang=js\");\n/* harmony import */ var _media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_AProgress_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_AProgress_vue_vue_type_template_id_6871a6ae__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/AProgress.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/AProgress.vue?");
/***/ }),
@ -595,7 +595,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _APr
\*********************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ARow_vue_vue_type_template_id_2f72fd2e__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ARow.vue?vue&type=template&id=2f72fd2e */ \"./src/components/ARow.vue?vue&type=template&id=2f72fd2e\");\n/* harmony import */ var _ARow_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ARow.vue?vue&type=script&lang=js */ \"./src/components/ARow.vue?vue&type=script&lang=js\");\n/* harmony import */ var _home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_ARow_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_ARow_vue_vue_type_template_id_2f72fd2e__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/ARow.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/ARow.vue?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ARow_vue_vue_type_template_id_2f72fd2e__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ARow.vue?vue&type=template&id=2f72fd2e */ \"./src/components/ARow.vue?vue&type=template&id=2f72fd2e\");\n/* harmony import */ var _ARow_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ARow.vue?vue&type=script&lang=js */ \"./src/components/ARow.vue?vue&type=script&lang=js\");\n/* harmony import */ var _media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_ARow_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_ARow_vue_vue_type_template_id_2f72fd2e__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/ARow.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/ARow.vue?");
/***/ }),
@ -605,7 +605,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ARo
\**********************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ARows_vue_vue_type_template_id_24354cda__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ARows.vue?vue&type=template&id=24354cda */ \"./src/components/ARows.vue?vue&type=template&id=24354cda\");\n/* harmony import */ var _ARows_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ARows.vue?vue&type=script&lang=js */ \"./src/components/ARows.vue?vue&type=script&lang=js\");\n/* harmony import */ var _home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_ARows_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_ARows_vue_vue_type_template_id_24354cda__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/ARows.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/ARows.vue?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ARows_vue_vue_type_template_id_24354cda__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ARows.vue?vue&type=template&id=24354cda */ \"./src/components/ARows.vue?vue&type=template&id=24354cda\");\n/* harmony import */ var _ARows_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ARows.vue?vue&type=script&lang=js */ \"./src/components/ARows.vue?vue&type=script&lang=js\");\n/* harmony import */ var _media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_ARows_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_ARows_vue_vue_type_template_id_24354cda__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/ARows.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/ARows.vue?");
/***/ }),
@ -615,7 +615,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ARo
\***************************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ASoundItem_vue_vue_type_template_id_2d901711__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ASoundItem.vue?vue&type=template&id=2d901711 */ \"./src/components/ASoundItem.vue?vue&type=template&id=2d901711\");\n/* harmony import */ var _ASoundItem_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ASoundItem.vue?vue&type=script&lang=js */ \"./src/components/ASoundItem.vue?vue&type=script&lang=js\");\n/* harmony import */ var _home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_ASoundItem_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_ASoundItem_vue_vue_type_template_id_2d901711__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/ASoundItem.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/ASoundItem.vue?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ASoundItem_vue_vue_type_template_id_2d901711__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ASoundItem.vue?vue&type=template&id=2d901711 */ \"./src/components/ASoundItem.vue?vue&type=template&id=2d901711\");\n/* harmony import */ var _ASoundItem_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ASoundItem.vue?vue&type=script&lang=js */ \"./src/components/ASoundItem.vue?vue&type=script&lang=js\");\n/* harmony import */ var _media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_ASoundItem_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_ASoundItem_vue_vue_type_template_id_2d901711__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/ASoundItem.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/ASoundItem.vue?");
/***/ }),
@ -625,7 +625,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ASo
\****************************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _AStatistics_vue_vue_type_template_id_214a9738__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AStatistics.vue?vue&type=template&id=214a9738 */ \"./src/components/AStatistics.vue?vue&type=template&id=214a9738\");\n/* harmony import */ var _AStatistics_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AStatistics.vue?vue&type=script&lang=js */ \"./src/components/AStatistics.vue?vue&type=script&lang=js\");\n/* harmony import */ var _home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_AStatistics_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_AStatistics_vue_vue_type_template_id_214a9738__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/AStatistics.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/AStatistics.vue?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _AStatistics_vue_vue_type_template_id_214a9738__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AStatistics.vue?vue&type=template&id=214a9738 */ \"./src/components/AStatistics.vue?vue&type=template&id=214a9738\");\n/* harmony import */ var _AStatistics_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AStatistics.vue?vue&type=script&lang=js */ \"./src/components/AStatistics.vue?vue&type=script&lang=js\");\n/* harmony import */ var _media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_AStatistics_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_AStatistics_vue_vue_type_template_id_214a9738__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/AStatistics.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/AStatistics.vue?");
/***/ }),
@ -635,7 +635,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ASt
\**************************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _AStreamer_vue_vue_type_template_id_06ef60ae__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AStreamer.vue?vue&type=template&id=06ef60ae */ \"./src/components/AStreamer.vue?vue&type=template&id=06ef60ae\");\n/* harmony import */ var _AStreamer_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AStreamer.vue?vue&type=script&lang=js */ \"./src/components/AStreamer.vue?vue&type=script&lang=js\");\n/* harmony import */ var _home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_AStreamer_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_AStreamer_vue_vue_type_template_id_06ef60ae__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/AStreamer.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/AStreamer.vue?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _AStreamer_vue_vue_type_template_id_06ef60ae__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AStreamer.vue?vue&type=template&id=06ef60ae */ \"./src/components/AStreamer.vue?vue&type=template&id=06ef60ae\");\n/* harmony import */ var _AStreamer_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AStreamer.vue?vue&type=script&lang=js */ \"./src/components/AStreamer.vue?vue&type=script&lang=js\");\n/* harmony import */ var _media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_AStreamer_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_AStreamer_vue_vue_type_template_id_06ef60ae__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/AStreamer.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/AStreamer.vue?");
/***/ }),
@ -645,7 +645,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ASt
\************************************/
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ASwitch_vue_vue_type_template_id_62a3c675__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ASwitch.vue?vue&type=template&id=62a3c675 */ \"./src/components/ASwitch.vue?vue&type=template&id=62a3c675\");\n/* harmony import */ var _ASwitch_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ASwitch.vue?vue&type=script&lang=js */ \"./src/components/ASwitch.vue?vue&type=script&lang=js\");\n/* harmony import */ var _home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_home_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_ASwitch_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_ASwitch_vue_vue_type_template_id_62a3c675__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/ASwitch.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/ASwitch.vue?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ASwitch_vue_vue_type_template_id_62a3c675__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ASwitch.vue?vue&type=template&id=62a3c675 */ \"./src/components/ASwitch.vue?vue&type=template&id=62a3c675\");\n/* harmony import */ var _ASwitch_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ASwitch.vue?vue&type=script&lang=js */ \"./src/components/ASwitch.vue?vue&type=script&lang=js\");\n/* harmony import */ var _media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./node_modules/vue-loader/dist/exportHelper.js */ \"./node_modules/vue-loader/dist/exportHelper.js\");\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,_media_data_code_projets_aircox_assets_node_modules_vue_loader_dist_exportHelper_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_ASwitch_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"], [['render',_ASwitch_vue_vue_type_template_id_62a3c675__WEBPACK_IMPORTED_MODULE_0__.render],['__file',\"src/components/ASwitch.vue\"]])\n/* hot reload */\nif (false) {}\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (__exports__);\n\n//# sourceURL=webpack://aircox-assets/./src/components/ASwitch.vue?");
/***/ }),

View File

@ -0,0 +1,29 @@
/* global CKEDITOR, django */
/* Modified in order to be manually loaded after vue.js */
function initialiseCKEditor() {
var textareas = Array.prototype.slice.call(
document.querySelectorAll("textarea[data-type=ckeditortype]"),
)
for (var i = 0; i < textareas.length; ++i) {
var t = textareas[i]
if (
t.getAttribute("data-processed") == "0" &&
t.id.indexOf("__prefix__") == -1
) {
t.setAttribute("data-processed", "1")
var ext = JSON.parse(t.getAttribute("data-external-plugin-resources"))
for (var j = 0; j < ext.length; ++j) {
CKEDITOR.plugins.addExternal(ext[j][0], ext[j][1], ext[j][2])
}
CKEDITOR.replace(t.id, JSON.parse(t.getAttribute("data-config")))
}
}
}
function initialiseCKEditorInInlinedForms() {
if (typeof django === "object" && django.jQuery) {
django.jQuery(document).on("formset:added", initialiseCKEditor)
}
}
//})()

View File

@ -0,0 +1,34 @@
{% extends "aircox/base.html" %}
{% load i18n aircox %}
{% block head_title %}
{% block title %}{{ user.username }}{% endblock %}
{% endblock %}
{% block content-container %}
<div class="container content page-content">
<h2 class="subtitle">Mon Profil</h2>
{% translate "Username" %} : {{ user.username|title }}<br/>
<!-- Connexion: {{ user.last_login }} -->
<h2 class="subtitle is-1">Mes émissions</h2>
{% if programs|length %}
<ul>
{% for p in programs %}
<li>{{ p.title }} :
&nbsp;
<a href="{% url 'program-detail' slug=p.slug %}">
<span title="{% translate 'View' %} {{ page }}">{% translate 'View' %}</span>
</a>
&nbsp;
<a href="{% url 'program-edit' pk=p.pk %}">
<span title="{% translate 'Edit' %} {{ page }}">{% translate 'Edit' %} </span>
</a>
</li>
{% endfor %}
</ul>
{% else %}
{% trans 'You are not listed as a program editor yet' %}
{% endif %}
</div>
{% endblock %}

View File

@ -12,11 +12,10 @@
:init-data="{% track_inline_data formset=formset %}"
settings-url="{% url "api:user-settings" %}"
data-prefix="{{ formset.prefix }}-">
{% comment %}
<template #title>
<h5 class="title is-4">{% trans "Playlist" %}</h5>
</template>
<template v-slot:top="{items}">
<template #top="{items}">
<input type="hidden" name="{{ formset.prefix }}-TOTAL_FORMS"
:value="items.length || 0"/>
<input type="hidden" name="{{ formset.prefix }}-INITIAL_FORMS"
@ -80,7 +79,6 @@
</template>
{% endif %}
{% endfor %}
{% endcomment %}
</a-playlist-editor>
</div>
{% endwith %}

View File

@ -12,7 +12,7 @@
<span>{% translate "Today" %}</span>
</h1>
{% if diffusions %}
<div class="card-grid">
<div class="grid-3">
{% for obj in diffusions %}
{% page_widget "card" obj.episode diffusion=obj timetable=True admin=True tag_class="" %}
{% endfor %}

View File

@ -1,30 +1,2 @@
{% extends "aircox/page_detail.html" %}
{% comment %}Detail page for regular articles{% endcomment %}
{% load i18n %}
{% block sidebar %}
{{ block.super }}
{% if sidebar_object_list %}
<section>
{% comment %}Translators: in page detail sidebar{% endcomment %}
<h4 class="title is-4">{% translate "Latest news" %}</h4>
{% for object in sidebar_object_list %}
{% include "aircox/widgets/page_item.html" %}
{% endfor %}
<br>
<nav class="pagination is-centered">
<ul class="pagination-list">
<li>
<a href="{% url "article-list" %}" class="pagination-link"
aria-label="{% translate "Show all news" %}">
{% translate "More news" %}
</a>
</li>
</ul>
</nav>
</section>
{% endif %}
{% endblock %}

View File

@ -1,3 +1,4 @@
{% load static i18n thumbnail aircox %}<!doctype html>
{% comment %}
Base website template. It displays various elements depending on context
variables.
@ -10,8 +11,6 @@ Usefull context:
- sidebar_url_name: url name sidebar item complete list
- sidebar_url_parent: parent page for sidebar items complete list
{% endcomment %}
{% load static i18n thumbnail aircox %}
<html>
<head>
<meta charset="utf-8" />
@ -49,7 +48,7 @@ Usefull context:
})
</script>
<div id="app">
<div class="container navs">
<div class="navs">
{% block nav %}
<nav class="nav primary" role="navigation" aria-label="main navigation">
{% block nav-primary %}
@ -71,12 +70,21 @@ Usefull context:
{% translate "Admin" %}
</a>
{% endif %}
{% if user.is_authenticated %}
<a class="nav-item" href="{% url "profile" %}" target="new">
{% translate "Profile" %}
</a>
<a class="nav-item" href="{% url 'logout' %}">
<i title="{% translate 'disconnect' %}" class="fa fa-power-off"></i>
</a>
{% endif %}
{% endblock %}
</div>
{% endblock %}
</nav>
{% endblock %}
{% block secondary-nav %}{% endblock %}
{% endblock %}
</div>
{% block main-container %}
@ -90,21 +98,26 @@ Usefull context:
{% endblock %}
{% endspaceless %}
{% block header-container %}
{% if page or cover or title %}
<header class="container header preview preview-header {% if cover %}has-cover{% endif %}">
{% block header %}
{% if cover %}
<img src="{{ cover }}" class="header-cover">
<figure class="header-cover">
<img src="{{ cover }}" class="cover">
</figure>
{% endif %}
<div class="headings preview-card-headings">
{% block headings %}
<div>
<h1 class="heading title is-1 {% block title-class %}{% endblock %}">{% block title %}{{ title|default:"" }}{% endblock %}</h1>
<h1 class="title is-1 {% block title-class %}{% endblock %}">{% block title %}{{ title|default:"" }}{% endblock %}</h1>
{% include "aircox/edit-link.html" %}
</div>
<div>
{% spaceless %}
<span class="heading subtitle is-2">
<span class="subtitle is-2">
{% block subtitle %}
{% if subtitle %}
{{ subtitle }}
@ -123,11 +136,11 @@ Usefull context:
{% block content-container %}
{% if page and page.content %}
<div class="container content page-content">
<section class="container content page-content">
{% block content %}
{{ page.content|safe }}
{% endblock %}
</div>
</section>
{% endif %}
{% endblock %}
{% endblock %}

View File

@ -15,7 +15,7 @@
{{ block.super }}
{% block list-container %}
<section class="container clear-both" role="list">
<section class="container clear-both list list-grid {{ list_class|default:"" }}" role="list">
{% block list %}
{% with has_headline=True %}
{% for object in object_list %}
@ -39,16 +39,20 @@
<ul class="urls">
{% if page_obj.has_previous %}
{% comment %}Translators: Bottom of the list, "previous page"{% endcomment %}
<a href="?{{ GET }}&page={{ page_obj.previous_page_number }}" class="left button"
<a href="?{{ GET }}&page={{ page_obj.previous_page_number }}" class="left"
title="{% translate "Previous" %}"
aria-label="{% translate "Previous" %}">
<span class="icon"><i class="fa fa-chevron-left"></i></span>
</a>
{% endif %}
<span>
{{ page_obj.number }} / {{ page_obj.paginator.num_pages }}
</span>
{% if page_obj.has_next %}
{% comment %}Translators: Bottom of the list, "Nextpage"{% endcomment %}
<a href="?{{ GET }}&page={{ page_obj.next_page_number }}" class="right button"
<a href="?{{ GET }}&page={{ page_obj.next_page_number }}" class="right"
title="{% translate "Next" %}"
aria-label="{% translate "Next" %}">
<span class="icon"><i class="fa fa-chevron-right"></i></span>

View File

@ -0,0 +1,20 @@
{% load aircox i18n %}
{% block user-actions-container %}
{% has_perm page page.program.change_permission_codename simple=True as can_edit %}
{% if user.is_authenticated and can_edit %}
{% with request.resolver_match.view_name as view_name %}
&nbsp;
{% if view_name in 'program-edit,bla' %}
<!--
<a href="{% url 'program-detail' page.slug %}" target="_self">
<span title="{% translate 'View' %} {{ page }}">{% translate 'View' %} 👁 </span>
</a>
-->
{% else %}
<a href="{% url view_name|edit_view page.pk %}" target="_self">
<span title="{% translate 'Edit' %} {{ page }}">{% translate 'Edit' %} 🖉 </span>
</a>
{% endif %}
{% endwith %}
{% endif %}
{% endblock %}

View File

@ -4,7 +4,6 @@
{% block content-container %}
{{ block.container }}
<a-episode :page="{title: &quot;{{ page.title }}&quot;, podcasts: {{ object.podcasts|json }}}">
<template v-slot="{podcasts,page}">
@ -13,7 +12,7 @@
{% if object.podcasts %}
{% spaceless %}
<section class="container no-border">
<h3 class="title is-3">{% translate "Podcasts" %}</h3>
<h3 class="title">{% translate "Podcasts" %}</h3>
<a-playlist v-if="page" :set="podcasts"
name="{{ page.title }}"
list-class="menu-list" item-class="menu-item"
@ -26,7 +25,7 @@
{% if tracks %}
<section class="container">
<h3 class="title is-3">{% translate "Playlist" %}</h3>
<h3 class="title">{% translate "Playlist" %}</h3>
<table class="table is-hoverable is-fullwidth">
<thead>
<tr>
@ -48,8 +47,6 @@
</table>
</section>
{% endif %}
</template>
</a-episode>
{% endblock %}

View File

@ -0,0 +1,37 @@
{% extends "aircox/basepage_detail.html" %}
{% load static i18n humanize honeypot aircox %}
{% block head_extra %}
<script type="text/javascript" src="{% static "aircox/js/admin.js" %}"></script>
<script type="text/javascript" src="{% static "aircox/js/ckeditor-init.js" %}"></script>
<!-- <script type="text/javascript" src="{% static "ckeditor/ckeditor-init.js" %}"></script> -->
<script type="text/javascript" src="{% static "ckeditor/ckeditor/ckeditor.js" %}"></script>
{% endblock %}
{% block init-scripts %}
aircox.init(null, {hotReload:false, initPlayer:false, initApp:true})
initialiseCKEditor()
initialiseCKEditorInInlinedForms()
{% endblock %}
{% block comments %}
{% endblock %}
{% block content-container %}
<section class="container">
<form method="post" enctype="multipart/form-data">{% csrf_token %}
<table>
{{ form.as_table }}
{% render_honeypot_field "website" %}
</table>
<br/>
<input type="submit" value="Update" class="button is-success">
{% include "aircox/playlist_inline.html" %}
<input type="submit" value="Update" class="button is-success">
</form>
</section>
{% endblock %}

View File

@ -18,7 +18,7 @@
{% endblock %}
{% block content %}
{% block content-container %}
<article class="message is-danger">
<div class="message-header">
<p>{% block error_title %}{% trans "An error occurred" %}{% endblock %}</p>

View File

@ -13,7 +13,7 @@
{% if next_diffs %}
<section class="container">
<h2 class="title is-3 p-2">
<h2 class="title">
{% with station.name as station %}
{% blocktrans %}Today on {{ station }}{% endblocktrans %}
{% endwith %}
@ -25,6 +25,8 @@
{% endwith %}
</div>
<hr/>
<a-carousel section-class="card-grid">
{% for obj in next_diffs|slice:"1:" %}
{% if object != diffusion %}
@ -37,10 +39,11 @@
{% if logs %}
<section class="container">
<h2 class="title is-3 p-2">{% translate "It just happened" %}</h2>
{% for object in logs %}
{% include "./widgets/log.html" with widget="item" %}
{% endfor %}
<h2 class="title">{% translate "It just happened" %}</h2>
<div class="list-grid" role="list">
{% include "./widgets/logs.html" with object_list=logs %}
</div>
<nav class="nav-urls">
<a href="{% url "timetable-list" %}"
@ -61,7 +64,7 @@
{% if publications %}
<section class="container">
<h2 class="title is-3 p-2">{% translate "Last publications" %}</h2>
<h2 class="title">{% translate "Last publications" %}</h2>
{% include "./widgets/carousel.html" with objects=publications url_name="page-list" url_label=_("All publications") %}
</section>
{% endif %}

View File

@ -1,45 +0,0 @@
{% extends "aircox/page_list.html" %}
{% comment %}List of logs for a specific date{% endcomment %}
{% load i18n humanize aircox %}
{% block title %}
{% if not page or not page.title %}
{% with station.name as station %}
{% blocktranslate %}That happened on {{ station }}{% endblocktranslate %}
{% endwith %}
{% else %}
{{ block.super }}
{% endif %}
{% endblock %}
{% block subtitle %}{{ date|date:"l d F Y" }}{% endblock %}
{% block secondary-nav %}
<nav class="nav secondary">
{% include "./widgets/dates_menu.html" with url_name="log-list" %}
</nav>
{% endblock %}
{% block pages_list_ %}
<section>
{# <h4 class="subtitle size-4">{{ date }}</h4> #}
{% include "aircox/widgets/log_list.html" %}
</section>
{% endblock %}
{% block pages_list %}
{% with hide_schedule=True %}
<section role="list" class="list">
{% for object in object_list %}
{% if object.episode %}
{% page_widget "item" object.episode diffusion=object timetable=True %}
{% else %}
{% page_widget "item" object timetable=True %}
{% endif %}
{% endfor %}
</section>
{% endwith %}
{% endblock %}

View File

@ -10,21 +10,6 @@ Context:
- related_url: url to the full list of related_objects
{% endcomment %}
{% block top-nav-tools %}
{% has_perm page "change" as can_edit %}
{% if can_edit %}
<a class="navbar-item" href="{{ page|admin_url:'change' }}"
target="new">
<span class="icon is-small">
<i class="fa fa-pen"></i>
</span>&nbsp;
<span>{% translate "Edit" %}</span>
</a>
{% endif %}
{% endblock %}
{% block breadcrumbs %}
{% if parent %}
{% include "./widgets/breadcrumbs.html" with page=parent %}
@ -46,10 +31,11 @@ Context:
{% if related_objects %}
<section class="container">
{% with models=object|verbose_name:True %}
<h3 class="title is-3">{% blocktranslate %}Related {{models}}{% endblocktranslate %}</h3>
<h3 class="title">{% blocktranslate %}Related {{models}}{% endblocktranslate %}</h3>
{% include "./widgets/carousel.html" with objects=related_objects url_name=object.list_url_name url_category=object.category %}
{% endwith %}
</section>
{% endif %}
{% endblock %}
@ -59,9 +45,7 @@ Context:
<h2 class="title">{% translate "Comments" %}</h2>
{% for object in comments %}
<div id="comment-{{ object.pk }}">
{% page_widget "item" object %}
</div>
{% endfor %}
</section>
{% endif %}

View File

@ -0,0 +1,70 @@
{% comment %}Inline block to edit playlists{% endcomment %}
{% load aircox aircox_admin static i18n %}
<div id="inline-tracks" class="box mb-5">
{{ formset.non_form_errors }}
<!-- formset.management_form -->
<a-playlist-editor
:labels="{% track_inline_labels %}"
:init-data="{% track_inline_data formset=formset %}"
settings-url="{% url "api:user-settings" %}"
data-prefix="{{ formset.prefix }}-">
<template #title>
<h5 class="title is-4">{% trans "Playlist" %}</h5>
</template>
<template #top="{items}">
<input type="hidden" name="{{ formset.prefix }}-TOTAL_FORMS"
:value="items.length || 0"/>
<input type="hidden" name="{{ formset.prefix }}-INITIAL_FORMS"
value="{{ formset.initial_form_count }}"/>
<input type="hidden" name="{{ formset.prefix }}-MIN_NUM_FORMS"
value="{{ formset.min_num }}"/>
<input type="hidden" name="{{ formset.prefix }}-MAX_NUM_FORMS"
value="{{ formset.max_num }}"/>
</template>
<template #rows-header-head>
<th style="max-width:2em" title="{% trans "Track Position" %}"
aria-description="{% trans "Track Position" %}">
<span class="icon">
<i class="fa fa-arrow-down-1-9"></i>
</span>
</th>
</template>
<template v-slot:row-head="{item,row}">
<td>
[[ row+1 ]]
<input type="hidden"
:name="'{{ formset.prefix }}-' + row + '-position'"
:value="row"/>
<input t-if="item.data.id" type="hidden"
:name="'{{ formset.prefix }}-' + row + '-id'"
:value="item.data.id || item.id"/>
{% for field in fields %}
{% if field != 'position' %}
<input type="hidden"
:name="'{{ formset.prefix }}-' + row + '-{{ field.name }}'"
v-model="item.data[attr]"/>
{% endif %}
{% endfor %}
</td>
</template>
{% for field in fields %}
<template v-slot:row-{{ field }}="{item,cell,value,attr,emit}">
<div class="field">
<a-autocomplete
:input-class="['input', item.error(attr) ? 'is-danger' : 'half-field']"
url="{% url 'api:track-autocomplete' %}?{{ field }}=${query}&field={{ field }}"
:name="'{{ formset.prefix }}-' + cell.row + '-{{ field }}'"
v-model="item.data[attr]"
title="{{ field }}"
@change="emit('change', col)"/>
<p v-for="error in item.error(attr)" class="help is-danger">
[[ error ]] !
</p>
</div>
</template>
{% endfor %}
</a-playlist-editor>
</div>

View File

@ -2,10 +2,22 @@
{% comment %}Detail page of a show{% endcomment %}
{% load i18n aircox %}
{% block top-nav-tools %}
{% has_perm page page.change_permission_codename simple=True as can_edit %}
{% if can_edit %}
<a class="navbar-item" href="{% url 'program-edit' page.pk %}" target="_self">
<span class="icon is-small">
<i class="fa fa-pen"></i>
</span>&nbsp;
<span>{% translate "Edit" %}</span>
</a>
{% endif %}
{% endblock %}
{% block content-container %}
{% with schedules=program.schedule_set.all %}
{% if schedules %}
<section class="container schedules">
<header class="container schedules">
{% for schedule in schedules %}
<div class="schedule">
<div class="heading">
@ -29,7 +41,7 @@
</div>
</div>
{% endfor %}
</section>
</header>
{% endif %}
{% endwith %}
@ -37,7 +49,7 @@
{% if episodes %}
<section class="container">
<h3 class="title is-3">{% translate "Last Episodes" %}</h3>
<h3 class="title">{% translate "Last Episodes" %}</h3>
{% include "./widgets/carousel.html" with objects=episodes url_name="episode-list" url_parent=object url_label=_("All episodes") %}
</section>
{% endif %}
@ -45,7 +57,7 @@
{% if articles %}
<section class="container">
<h3 class="title is-3">{% translate "Last Articles" %}</h3>
<h3 class="title">{% translate "Last Articles" %}</h3>
{% include "./widgets/carousel.html" with objects=articles url_name="article-list" url_parent=object url_label=_("All articles") %}
</section>
{% endif %}

View File

@ -0,0 +1,28 @@
{% extends "aircox/page_detail.html" %}
{% load static i18n humanize honeypot aircox %}
{% block head_extra %}
{{ form.media }}
{% endblock %}
{% block init-scripts %}
{% endblock %}
{% block comments %}
{% endblock %}
{% block content-container %}
<section class="container">
<div>
<form method="post" enctype="multipart/form-data">{% csrf_token %}
<table>
{{ form.as_table }}
{% render_honeypot_field "website" %}
</table>
<br/>
<input type="submit" value="Update" class="button is-success">
</form>
</div>
</section>
{% endblock %}

View File

@ -16,12 +16,13 @@
<a href="{% url "timetable-list" date=date %}">{{ date|date:"l d F Y" }}</a>
{% endblock %}
{% block list %}
{% for object in object_list %}
{% if object.episode %}
{% page_widget "item" object.episode diffusion=object timetable=True %}
{% else %}
{% page_widget "item" object timetable=True %}
{% endif %}
{% endfor %}
{% block list-container %}
{% with list_class="list-grid" %}
{{ block.super }}
{% endwith %}
{% endblock %}
{% block list %}
{% include "./widgets/logs.html" with object_list=object_list timetable=True %}
{% endblock %}

View File

@ -2,18 +2,22 @@
{% load i18n %}
{% block tag-class %}{{ block.super }} preview-card{% endblock %}
{% block tag-extra %}
{{ block.super }}
{% if cover %}
style="background-image: url({{ cover }});"
{% endif %}
{% endblock %}
{% block headings-class %}{{ block.super }} preview-card-headings{% endblock %}
{% block inner %}
{% block headings-container %}
{{ block.super }}
{% block actions-container %}{{ block.super }}{% endblock %}
{% endblock %}
<div class="card-content">
{% if cover %}
{% if url %}<a href="{{ url }}">{% endif %}
<figure style="background-image: url({{ cover }});" class="preview-cover">
<img src="{{ cover }}" class="hide">
</figure>
{% if url %}</a>{% endif %}
{% endif %}
<footer class="actions">
{% block actions %}{{ block.super }}{% endblock %}
</footer>
</div>
{% block headings-container %}{{ block.super }}{% endblock %}
{% endblock %}

View File

@ -2,17 +2,18 @@
{% load i18n humanize aircox %}
{% block tag-class %}{{ block.super }} comment{% endblock %}
{% block tag-extra %} id="comment-{{ object.pk }}"{% endblock %}
{% block outer %}
{% with url=object.get_absolute_url %}
{% if with_title %}
{% with url=object.get_absolute_url %}
{{ block.super }}
{{ block.super }}
{% endwith %}
{% else %}
{{ block.super }}
{{ block.super }}
{% endif %}
{% endwith %}
{% endblock %}

View File

@ -25,12 +25,31 @@
{% endblock %}
{% block content %}
{% if not object.content %}
{% with object.parent.content as content %}
{{ block.super }}
{% endwith %}
{% else %}
{{ block.super }}
{% block actions %}
{% if object.sound_set.public.count %}
<button class="button" @click="player.playButtonClick($event)"
data-sounds="{{ object.podcasts|json }}">
<span class="icon is-small">
<span class="fas fa-play"></span>
</span>
</button>
{% endif %}
{% endblock %}
{% block actions %}
{% has_perm page object.program.change_permission_codename simple=True as can_edit %}
{% if can_edit %}
<a class="button" href="{% url 'episode-edit' object.pk %}" target="_self">
<span class="icon is-small"><i class="fas fa-pen" alt="{% trans 'edit' %}"></i></span>
</a>
{% endif %}
{% if object.sound_set.public.count %}
<button class="button" @click="player.playButtonClick($event)"
data-sounds="{{ object.podcasts|json }}">
<span class="icon is-small">
<span class="fas fa-play"></span>
</span>
</button>
{% endif %}
{% endblock %}

View File

@ -22,8 +22,8 @@
style="background-image: url({{ object.cover.url }})">
</a>
{% endif %}
<div class="media-content">
<section class="content">
<div class="media-content flex-column">
<section class="content flex-grow-1">
{% block content %}
{% if content and with_content %}
{% autoescape off %}
@ -32,11 +32,11 @@
{% endif %}
{% endblock %}
</section>
{% block actions-container %}
{{ block.super }}
{% endblock %}
</div>
</div>
{% endblock %}
{% endblock %}

View File

@ -8,13 +8,16 @@ Context objects:
In case of modification, you might want to check on `assets/vue/player.vue`
for design review.
{% endcomment %}
{% block outer %}
{% if object|is_diffusion %}
{% page_widget widget object.episode diffusion=object %}
{% page_widget widget object.episode diffusion=object timetable=timetable|default:False %}
{% elif object|is_log %}
{% include "./track_item.html" with object=object.track log=object timetable=timetable|default:False %}
{% else %}
{% include "./track_item.html" with object=object.track log=object %}
{% for obj in object %}
{% include "./track_item.html" with object=obj.track log=obj timetable=timetable|default:False %}
{% endfor %}
{% endif %}
{% endblock %}

View File

@ -0,0 +1,35 @@
{% comment %}
Context:
- object_list: list of logs
- timetable: defaults to False
- widget: defaults to "item"
{% endcomment %}
{% load aircox %}
{% with timetable|default:False as timetable %}
{% with widget|default:"item" as widget %}
{% for object in object_list %}
{% if object.episode %}
{% page_widget widget object.episode diffusion=object timetable=True %}
{% elif object|is_log %}
{% include "./track_item.html" with object=object.track log=object timetable=True %}
{% else %}
<div class="preview list-item logs">
<header class="headings">
<span class="heading title">
<span class="icon pr-2">
<i class="fas fa-music"></i>
</span>
{{ station.music_stream_title }}
</span>
</header>
<div class="media d-block content">
{% for obj in object %}
{% include "./track_item.html" with object=obj.track log=obj timetable=True %}
{% endfor %}
</div>
</div>
{% endif %}
{% endfor %}
{% endwith %}
{% endwith %}

View File

@ -34,3 +34,10 @@
{{ object.display_headline }}
{% endif %}
{% endblock %}
{% block actions %}
{% if url and "card" not in widget_template %}
<a href="{{ url }}">{% translate "Show" %}</a>
{% endif %}
{{ block.super }}
{% endblock %}

View File

@ -30,7 +30,9 @@ The audio player
</h4>
<h4 v-else-if="current && current.data.type == 'track'"
class="title" aria-description="{% translate "Track currently on air" %}">
<span class="has-text-info is-size-3 mr-3">&#9836;</span>
<span class="icon hg-color-2 mr-3">
<i class="fas fa-music"></i>
</span>
<span>[[ current.data.title ]]</span>
<span class="has-text-grey-dark has-text-weight-light">
&mdash; [[ current.data.artist ]]

View File

@ -23,12 +23,16 @@ Styling related context:
{% block headings-container %}
<header class="headings{% block headings-class %}{% endblock %}"{% block headings-tag-extra %}{% endblock %}>
{% block headings %}
<div>
<a href="{{ url|escape }}" class="heading title {% block title-class %}{% endblock %}"{% if title %} title="{{ title|escape }}"{% endif %}>{% block title %}{{ title|default:"" }}{% endblock %}</a>
</div>
<div>
<span class="heading subtitle {% block subtitle-class %}{% endblock %}">{% block subtitle %}{{ subtitle|default:"" }}{% endblock %}</span>
</div>
{% block title-container %}
<a href="{{ url|escape }}" class="heading title {% block title-class %}{% endblock %}"{% if title %} title="{{ title|escape }}"{% endif %}>
{% block title %}{{ title|default:"" }}{% endblock %}
</a>
{% endblock %}
{% block subtitle-container %}
<span class="heading subtitle {% block subtitle-class %}{% endblock %}">
{% block subtitle %}{{ subtitle|default:"" }}{% endblock %}
</span>
{% endblock %}
{% endblock %}
</header>
{% endblock %}

View File

@ -5,10 +5,11 @@ Context:
- object: track to render
{% endcomment %}
<span class="content mr-2">
<span class="icon highlight-color-2 m-2">
<span class="track">
<span class="icon hg-color-2">
<i class="fas fa-music"></i>
</span>
<label>
{% if log %}
<span>{{ log.date|date:"H:i" }} &mdash; </span>
{% endif %}
@ -19,4 +20,5 @@ Context:
{% if object.info %}(<i>{{ object.info }}</i>){% endif %}
</span>
{% endif %}
</label>
</span>

View File

@ -1,20 +1,43 @@
{% extends "./preview.html" %}
{% load i18n %}
{% load i18n aircox %}
{% block tag-class %}{{ block.super }} preview-wide{% endblock %}
{% block headings-class %}{{ block.super }} preview-card-headings{% endblock %}
{% block headings-tag-extra %}
{{ block.super }}
{% if cover %}
style="background-image: url({{ cover }});"
{% endif %}
{% block tag-class %}{{ block.super }} list-item wide is-fullwidth{% endblock %}
{% block headings %}
<a href="{{ url|escape }}" class="heading title {% block title-class %}{% endblock %}">
{% block title %}{{ title|default:"" }}{% endblock %}
</a>
<span class="heading subtitle {% block subtitle-class %}{% endblock %}">
{% block subtitle %}{{ subtitle|default:"" }}{% endblock %}
</span>
{% endblock %}
{% block inner %}
{% block headings-container %}{{ block.super }}{% endblock %}
<div class="is-flex-direction-column">
{% block content-container %}{{ block.super }}{% endblock %}
{% block actions-container %}{{ block.super }}{% endblock %}
</div>
{% block content-container %}
<div class="media">
{% if object.cover %}
<a href="{{ object.get_absolute_url }}"
class="media-left preview-cover"
style="background-image: url({{ object.cover.url }})">
</a>
{% endif %}
<div class="media-content">
{% block headings-container %}{{ block.super }}{% endblock %}
<section class="content">
{% block content %}
{% if content and with_content %}
{% autoescape off %}
{{ content|striptags|linebreaks }}
{% endautoescape %}
{% endif %}
{% endblock %}
</section>
{% block actions-container %}
{{ block.super }}
{% endblock %}
</div>
{% endblock %}
{% endblock %}

View File

@ -0,0 +1,18 @@
{% extends "aircox/base.html" %}
{% load i18n aircox %}
{% block content-container %}
<div class="container content page-content">
<h2>{% trans "Log in" %}</h2>
<br/>
<form method="post" action="{% url 'login' %}">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<br/>
<button class="button" type="submit">{% trans "Log in" %}</button>
<input type="hidden" name="next" value="{{ next }}">
</form>
</div>
{% endblock %}

View File

@ -57,10 +57,15 @@ def do_get_tracks(obj):
@register.simple_tag(name="has_perm", takes_context=True)
def do_has_perm(context, obj, perm, user=None):
def do_has_perm(context, obj, perm, user=None, simple=False):
"""Return True if ``user.has_perm('[APP].[perm]_[MODEL]')``"""
if not obj:
return
if user is None:
user = context["request"].user
if simple:
return user.has_perm("aircox.{}".format(perm)) or user.is_superuser
else:
return user.has_perm("{}.{}_{}".format(obj._meta.app_label, perm, obj._meta.model_name))
@ -70,6 +75,12 @@ def do_is_diffusion(obj):
return isinstance(obj, Diffusion)
@register.filter(name="is_log")
def do_is_log(obj):
"""Return True if object is a Diffusion."""
return isinstance(obj, Log)
@register.filter(name="json")
def do_json(obj, fields=""):
"""Return object as json."""
@ -93,6 +104,8 @@ def do_player_live_attr(context):
@register.simple_tag(name="nav_items", takes_context=True)
def do_nav_items(context, menu, **kwargs):
"""Render navigation items for the provided menu name."""
if not getattr(context["request"], "station"):
return []
station, request = context["station"], context["request"]
return [(item, item.render(request, **kwargs)) for item in station.navitem_set.filter(menu=menu)]
@ -125,3 +138,8 @@ def do_verbose_name(obj, plural=False):
if isinstance(obj, str):
return obj
return obj._meta.verbose_name_plural if plural else obj._meta.verbose_name
@register.filter(name="edit_view")
def do_edit_view(obj):
return "%s-edit" % obj.split("-")[0]

View File

@ -157,3 +157,8 @@ def tracks(episode, sound):
items += [baker.prepare(models.Track, sound=sound, position=i, timestamp=i * 60) for i in range(0, 3)]
models.Track.objects.bulk_create(items)
return items
@pytest.fixture
def user():
return User.objects.create_user(username="user1", password="bar")

View File

@ -0,0 +1,46 @@
import pytest
from django.contrib.auth.models import User, Group
from django.urls import reverse
@pytest.mark.django_db()
def test_no_admin(user, client):
client.force_login(user)
response = client.get("/admin/")
assert response.status_code != 200
@pytest.mark.django_db()
def test_user_cannot_change_program_or_episode(user, client, program):
assert not user.has_perm("aircox.change_program")
assert not user.has_perm("aircox.change_episode")
@pytest.mark.django_db()
def test_group_can_change_program(user, client, program):
assert program.editors in Group.objects.all()
assert not user.has_perm("aircox.%s" % program.change_permission_codename)
user.groups.add(program.editors)
user = User.objects.get(pk=user.pk) # reload user in order to have permissions set
assert program.editors in user.groups.all()
assert user.has_perm("aircox.%s" % program.change_permission_codename)
@pytest.mark.django_db()
def test_group_change_program(user, client, program):
client.force_login(user)
response = client.get(reverse("program-edit", kwargs={"pk": program.pk}))
assert response.status_code == 403
user.groups.add(program.editors)
response = client.get(reverse("program-edit", kwargs={"pk": program.pk}))
assert response.status_code == 200
@pytest.mark.django_db()
def test_group_change_episode(user, client, program, episode):
client.force_login(user)
response = client.get(reverse("episode-edit", kwargs={"pk": episode.pk}))
assert response.status_code == 403
user.groups.add(program.editors)
response = client.get(reverse("episode-edit", kwargs={"pk": episode.pk}))
assert response.status_code == 200

View File

@ -0,0 +1,22 @@
import pytest
from django.urls import reverse
@pytest.mark.django_db()
def test_authenticate(user, client, program):
r = client.get(reverse("login"))
assert r.status_code == 200
assert b"id_username" in r.content
r = client.post(reverse("login"), kwargs={"username": "foo", "password": "bar"})
assert b"errorlist" in r.content
assert client.login(username="user1", password="bar")
@pytest.mark.django_db()
def test_profile_programs(user, client, program):
client.force_login(user)
r = client.get(reverse("profile"))
assert program.title not in r.content.decode("utf-8")
user.groups.add(program.editors)
r = client.get(reverse("profile"))
assert program.title in r.content.decode("utf-8")

View File

@ -0,0 +1,73 @@
from itertools import chain
import json
import pytest
from django.urls import reverse
from django.core.files.uploadedfile import SimpleUploadedFile
from aircox.models import Program
png_content = (
b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90wS\xde"
+ b"\x00\x00\x00\x0cIDATx\x9cc`\xf8\xcf\x00\x00\x02\x02\x01\x00{\t\x81x\x00\x00\x00\x00IEND\xaeB`\x82"
)
@pytest.mark.django_db()
def test_edit_program(user, client, program):
client.force_login(user)
response = client.get(reverse("program-detail", kwargs={"slug": program.slug}))
assert response.status_code == 200
assert "🖉 ".encode() not in response.content
user.groups.add(program.editors)
response = client.get(reverse("program-detail", kwargs={"slug": program.slug}))
assert "🖉 ".encode() in response.content
assert b"foobar" not in response.content
response = client.post(reverse("program-edit", kwargs={"pk": program.pk}), {"content": "foobar"})
response = client.get(reverse("program-detail", kwargs={"slug": program.slug}))
assert b"foobar" in response.content
@pytest.mark.django_db()
def test_add_cover(user, client, program):
assert program.cover is None
user.groups.add(program.editors)
client.force_login(user)
cover = SimpleUploadedFile("cover1.png", png_content, content_type="image/png")
r = client.post(
reverse("program-edit", kwargs={"pk": program.pk}), {"content": "foobar", "new_cover": cover}, follow=True
)
assert r.status_code == 200
p = Program.objects.get(pk=program.pk)
assert "cover1.png" in p.cover.url
@pytest.mark.django_db()
def test_edit_tracklist(user, client, program, episode, tracks):
user.groups.add(program.editors)
client.force_login(user)
episode.status = 0x10 # published
episode.save()
r = client.get(reverse("program-detail", kwargs={"slug": episode.program.slug}))
assert r.status_code == 200
r = client.get(reverse("episode-detail", kwargs={"slug": episode.slug}))
assert r.status_code == 200
r2 = client.get(reverse("episode-edit", kwargs={"pk": episode.pk}))
assert r2.status_code == 200
tracklist = [t.id for t in episode.track_set.all().order_by("position")]
tracklist_details_reversed = [(t.id, t.artist, t.title) for t in episode.track_set.all().order_by("-position")]
tracklist_details_reversed = list(chain(*tracklist_details_reversed))
data = """{"website": [""], "content": ["foobar"], "new_podcast": [""], "form-TOTAL_FORMS": ["3"],
"form-INITIAL_FORMS": ["3"], "form-MIN_NUM_FORMS": ["0"], "form-MAX_NUM_FORMS": ["1000"], "form-0-position": ["0"],
"form-0-id": ["%s"], "form-0-": ["", "", "", "", "", ""], "form-0-artist": ["%s"], "form-0-title": ["%s"],
"form-0-tags": [""], "form-0-album": [""], "form-0-year": [""], "form-1-position": ["1"], "form-1-id": ["%s"],
"form-1-": ["", "", "", "", "", ""], "form-1-artist": ["%s"], "form-1-title": ["%s"], "form-1-tags": [""],
"form-1-album": [""], "form-1-year": [""], "form-2-position": ["2"], "form-2-id": ["%s"], "form-2-": ["", "", "",
"", "", ""], "form-2-artist": ["%s"], "form-2-title": ["%s"], "form-2-tags": [""], "form-2-album": [""],
"form-2-year": [""]}""" % tuple(
tracklist_details_reversed
)
r = client.post(reverse("episode-edit", kwargs={"pk": episode.pk}), json.loads(data), follow=True)
assert r.status_code == 200
assert [t.id for t in episode.track_set.all().order_by("position")] == list(reversed(tracklist))

View File

@ -40,29 +40,21 @@ urls = [
path("api/", include((api, "aircox"), namespace="api")),
# ---- ---- objects views
# ---- articles
path(
_("articles/<slug:slug>/"),
views.ArticleDetailView.as_view(),
name="article-detail",
),
path(
_("articles/"),
views.ArticleListView.as_view(model=models.Article),
name="article-list",
),
path(
_("articles/c/<slug:category_slug>/"), views.ArticleListView.as_view(model=models.Article), name="article-list"
_("articles/c/<slug:category_slug>/"),
views.ArticleListView.as_view(model=models.Article),
name="article-list",
),
path(
_("articles/<slug:slug>/"),
views.ArticleDetailView.as_view(),
name="article-detail",
),
# ---- episodes
path(_("episodes/"), views.EpisodeListView.as_view(), name="episode-list"),
path(_("episodes/c/<slug:category_slug>/"), views.EpisodeListView.as_view(), name="episode-list"),
path(
_("episodes/<slug:slug>/"),
views.EpisodeDetailView.as_view(),
name="episode-detail",
),
path(_("podcasts/"), views.PodcastListView.as_view(), name="podcast-list"),
path(_("podcasts/c/<slug:category_slug>/"), views.PodcastListView.as_view(), name="podcast-list"),
# ---- timetable
path(_("timetable/"), views.TimeTableView.as_view(), name="timetable-list"),
path(
@ -81,14 +73,6 @@ urls = [
views.PageListView.as_view(model=models.Page, attach_to_value=models.StaticPage.Target.PAGES),
name="page-list",
),
path(
_("pages/"),
views.BasePageListView.as_view(
model=models.StaticPage,
queryset=models.StaticPage.objects.filter(attach_to__isnull=True),
),
name="static-page-list",
),
path(
_("pages/<slug:slug>/"),
views.BasePageDetailView.as_view(
@ -97,26 +81,57 @@ urls = [
),
name="static-page-detail",
),
path(
_("pages/"),
views.BasePageListView.as_view(
model=models.StaticPage,
queryset=models.StaticPage.objects.filter(attach_to__isnull=True),
),
name="static-page-list",
),
# ---- programs
path(_("programs/"), views.ProgramListView.as_view(), name="program-list"),
path(_("programs/c/<slug:category_slug>/"), views.ProgramListView.as_view(), name="program-list"),
path(
_("programs/<slug:slug>/"),
_("programs/<slug:slug>"),
views.ProgramDetailView.as_view(),
name="program-detail",
),
path(_("programs/<slug:parent_slug>/articles/"), views.ArticleListView.as_view(), name="article-list"),
path(_("programs/<slug:parent_slug>/podcasts/"), views.PodcastListView.as_view(), name="podcast-list"),
path(_("programs/<slug:parent_slug>/episodes/"), views.EpisodeListView.as_view(), name="episode-list"),
path(_("programs/<slug:parent_slug>/diffusions/"), views.DiffusionListView.as_view(), name="diffusion-list"),
path(_("programs/<slug:parent_slug>/articles"), views.ArticleListView.as_view(), name="article-list"),
path(_("programs/<slug:parent_slug>/podcasts"), views.PodcastListView.as_view(), name="podcast-list"),
path(_("programs/<slug:parent_slug>/episodes"), views.EpisodeListView.as_view(), name="episode-list"),
path(_("programs/<slug:parent_slug>/diffusions"), views.DiffusionListView.as_view(), name="diffusion-list"),
path(
_("programs/<slug:parent_slug>/publications"),
views.PageListView.as_view(model=models.Page, attach_to_value=models.StaticPage.Target.PAGES),
name="page-list",
),
# ---- episodes
path(_("programs/episodes/"), views.EpisodeListView.as_view(), name="episode-list"),
path(_("programs/episodes/c/<slug:category_slug>"), views.EpisodeListView.as_view(), name="episode-list"),
path(
_("programs/episodes/<slug:slug>"),
views.EpisodeDetailView.as_view(),
name="episode-detail",
),
path(
_("programs/episodes/<pk>/edit/"),
views.EpisodeUpdateView.as_view(),
name="episode-edit",
),
path(_("podcasts/"), views.PodcastListView.as_view(), name="podcast-list"),
path(_("podcasts/c/<slug:category_slug>/"), views.PodcastListView.as_view(), name="podcast-list"),
# ---- others
path(
_("program/<pk>/edit/"),
views.ProgramUpdateView.as_view(),
name="program-edit",
),
path(
"errors/no-station",
views.errors.NoStationErrorView.as_view(),
name="errors-no-station",
),
path(
_("program/<slug:parent_slug>/publications"),
views.PageListView.as_view(model=models.Page, attach_to_value=models.StaticPage.Target.PAGES),
name="page-list",
),
path("gestion/", views.profile, name="profile"),
path("accounts/profile/", views.profile, name="profile"),
]

View File

@ -2,7 +2,7 @@ from . import admin, errors
from .article import ArticleDetailView, ArticleListView
from .base import BaseAPIView, BaseView
from .diffusion import DiffusionListView, TimeTableView
from .episode import EpisodeDetailView, EpisodeListView, PodcastListView
from .episode import EpisodeDetailView, EpisodeListView, PodcastListView, EpisodeUpdateView
from .home import HomeView
from .log import LogListAPIView, LogListView
from .page import (
@ -11,11 +11,13 @@ from .page import (
PageDetailView,
PageListView,
)
from .profile import profile
from .program import (
ProgramDetailView,
ProgramListView,
ProgramPageDetailView,
ProgramPageListView,
ProgramUpdateView,
)
__all__ = (
@ -30,6 +32,7 @@ __all__ = (
"EpisodeDetailView",
"EpisodeListView",
"PodcastListView",
"EpisodeUpdateView",
"HomeView",
"LogListAPIView",
"LogListView",
@ -37,10 +40,12 @@ __all__ = (
"BasePageListView",
"PageDetailView",
"PageListView",
"profile",
"ProgramDetailView",
"ProgramListView",
"ProgramPageDetailView",
"ProgramPageListView",
"ProgramUpdateView",
"attached",
)

View File

@ -7,13 +7,8 @@ __all__ = ["ArticleDetailView", "ArticleListView"]
class ArticleDetailView(PageDetailView):
model = Article
def get_sidebar_queryset(self):
qs = Article.objects.published().select_related("cover").order_by("-pub_date")
return qs
class ArticleListView(PageListView):
model = Article
has_headline = True
parent_model = Program
attach_to_value = StaticPage.Target.ARTICLES

View File

@ -50,13 +50,9 @@ class BaseView(TemplateResponseMixin, ContextMixin):
return None
def get_context_data(self, **kwargs):
kwargs.setdefault("station", self.station)
kwargs.setdefault("page", self.get_page())
kwargs.setdefault("header_template_name", self.header_template_name)
if "audio_streams" not in kwargs:
kwargs["audio_streams"] = self.station.streams
if "model" not in kwargs:
model = getattr(self, "model", None) or hasattr(self, "object") and type(self.object)
kwargs["model"] = model

View File

@ -50,6 +50,6 @@ class TimeTableView(GetDateMixin, BaseDiffusionListView):
if object_list is None:
logs = self.get_logs(self.date)
object_list = Log.merge_diffusions(logs, self.object_list)
object_list = Log.merge_diffusions(logs, self.object_list, group_logs=True)
object_list = list(reversed(object_list))
return super().get_context_data(date=self.date, dates=dates, object_list=object_list, **kwargs)

View File

@ -1,14 +1,26 @@
from django.shortcuts import reverse
from django.contrib.auth.mixins import UserPassesTestMixin
from django.forms import ModelForm, FileField
from django.forms.models import modelformset_factory
from django.urls import reverse
from ckeditor.fields import RichTextField
from filer.models.filemodels import File
from aircox.controllers.sound_file import SoundFile
from aircox.models import Track
from ..filters import EpisodeFilters
from ..models import Episode, Program, StaticPage
from .page import PageListView
from .program import ProgramPageDetailView
from .program import ProgramPageDetailView, BaseProgramMixin
from .page import PageUpdateView
__all__ = (
"EpisodeDetailView",
"EpisodeListView",
"PodcastListView",
"EpisodeUpdateView",
)
@ -39,3 +51,62 @@ class EpisodeListView(PageListView):
class PodcastListView(EpisodeListView):
attach_to_value = StaticPage.Target.PODCASTS
queryset = Episode.objects.published().with_podcasts().order_by("-pub_date")
class EpisodeForm(ModelForm):
content = RichTextField()
new_podcast = FileField(required=False)
class Meta:
model = Episode
fields = ["content"]
def save(self, commit=True):
file_obj = self.cleaned_data["new_podcast"]
if file_obj:
obj, _ = File.objects.get_or_create(original_filename=file_obj.name, file=file_obj)
sound_file = SoundFile(obj.path)
sound_file.sync(
program=self.instance.program, episode=self.instance, type=0, is_public=True, is_downloadable=True
)
super().save(commit=commit)
class EpisodeUpdateView(UserPassesTestMixin, BaseProgramMixin, PageUpdateView):
model = Episode
form_class = EpisodeForm
template_name = "aircox/episode_form.html"
def get_sidebar_queryset(self):
return super().get_sidebar_queryset().filter(parent=self.program)
def test_func(self):
program = self.get_object().program
return self.request.user.has_perm("aircox.%s" % program.change_permission_codename)
def get_success_url(self):
return reverse("episode-detail", kwargs={"slug": self.get_object().slug})
def get_object(self, queryset=None):
obj = Episode.objects.get(pk=self.kwargs["pk"])
return obj
def get_formset(self, *args, **kwargs):
fields = ("position", "artist", "title", "tags", "album", "year", "info")
TrackFormSet = modelformset_factory(Track, fields=fields, extra=0)
return TrackFormSet(*args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["fields"] = ("position", "artist", "title", "tags", "album", "year", "info")
context["formset"] = self.get_formset(queryset=Track.objects.filter(episode=self.object))
return context
def post(self, request, *args, **kwargs):
super().post(request, *args, **kwargs)
formset = self.get_formset(request.POST)
if formset.is_valid():
formset.save()
return super().form_valid(formset)
else:
return super().form_valid(formset) # form_invalid(formset)

View File

@ -23,16 +23,19 @@ class HomeView(AttachedToMixin, BaseView, ListView):
def get_logs(self, diffusions):
today = date.today()
now = datetime.now()
# diffs = Diffusion.objects.on_air().date(today)
object_list = self.object_list
diffs = list(object_list[: self.related_count])
logs = Log.objects.on_air().filter(track__isnull=False)
logs = Log.objects.on_air().filter(track__isnull=False, date__lte=now)
if diffs:
min_date = diffs[-1].start - timedelta(hours=1)
logs = logs.after(min_date)
else:
logs = logs.date(today)
return Log.merge_diffusions(logs, object_list, diff_count=self.related_count)
return Log.merge_diffusions(
logs, object_list, diff_count=self.related_count, count=self.related_count + 2, group_logs=True
)
def get_next_diffs(self):
now = tz.now()

View File

@ -63,7 +63,7 @@ class ParentMixin:
def get_context_data(self, **kwargs):
parent = kwargs.setdefault("parent", self.parent)
if parent is not None:
if parent is not None and parent.cover:
kwargs.setdefault("cover", parent.cover.url)
return super().get_context_data(**kwargs)

View File

@ -1,13 +1,13 @@
from django.http import Http404, HttpResponse
from django.http import HttpResponse
from django.utils.translation import gettext_lazy as _
from django.views.generic import DetailView, ListView
from django.views.generic.edit import UpdateView
from django.urls import reverse
from honeypot.decorators import check_honeypot
from ..filters import PageFilters
from ..forms import CommentForm
from ..models import Comment, Category
from ..utils import Redirect
from .base import BaseView
from .mixins import AttachedToMixin, FiltersMixin, ParentMixin
@ -22,6 +22,9 @@ __all__ = [
class BasePageMixin:
category = None
def get_queryset(self):
return super().get_queryset().select_subclasses().published().select_related("cover")
def get_category(self, page, **kwargs):
if page:
if getattr(page, "category_id", None):
@ -53,7 +56,7 @@ class BasePageListView(AttachedToMixin, BasePageMixin, ParentMixin, BaseView, Li
return super().get(*args, **kwargs)
def get_queryset(self):
query = super().get_queryset().select_subclasses().published().select_related("cover")
query = super().get_queryset()
if self.category:
query = query.filter(category=self.category)
return query
@ -71,6 +74,7 @@ class BasePageListView(AttachedToMixin, BasePageMixin, ParentMixin, BaseView, Li
if not context.get("cover") and parent and parent.cover:
context["cover"] = parent.cover.url
return context
@ -80,9 +84,6 @@ class BasePageDetailView(BasePageMixin, BaseView, DetailView):
template_name = "aircox/basepage_detail.html"
context_object_name = "page"
def get(self, *args, **kwargs):
return super().get(*args, **kwargs)
def get_context_data(self, **kwargs):
if self.object.cover:
kwargs.setdefault("cover", self.object.cover.url)
@ -90,27 +91,11 @@ class BasePageDetailView(BasePageMixin, BaseView, DetailView):
kwargs.setdefault("title", self.object.display_title)
return super().get_context_data(**kwargs)
def get_queryset(self):
return super().get_queryset().select_related("cover")
# This should not exists: it allows mapping not published pages
# or it should be only used for trashed pages.
def not_published_redirect(self, page):
"""When a page is not published, redirect to the returned url instead
of an HTTP 404 code."""
return None
def get_object(self):
if getattr(self, "object", None):
return self.object
obj = super().get_object()
if not obj.is_published:
redirect_url = self.not_published_redirect(obj)
if redirect_url:
raise Redirect(redirect_url)
raise Http404("%s not found" % self.model._meta.verbose_name)
self.category = self.get_category(obj)
return obj
@ -196,3 +181,10 @@ class PageDetailView(BasePageDetailView):
comment.page = self.object
comment.save()
return self.get(request, *args, **kwargs)
class PageUpdateView(BaseView, UpdateView):
context_object_name = "page"
def get_page(self):
return self.object

15
aircox/views/profile.py Normal file
View File

@ -0,0 +1,15 @@
from django.contrib.auth.decorators import login_required
from django.template.response import TemplateResponse
from aircox.models import Program
@login_required
def profile(request):
programs = []
ugroups = request.user.groups.all()
for p in Program.objects.all():
if p.editors in ugroups:
programs.append(p)
context = {"user": request.user, "programs": programs}
return TemplateResponse(request, "accounts/profile.html", context)

View File

@ -1,10 +1,16 @@
import random
from django.contrib.auth.mixins import UserPassesTestMixin
from django.forms import ModelForm, ImageField
from django.urls import reverse
from ..models import Article, Page, Program, StaticPage, Episode
from ckeditor.fields import RichTextField
from filer.models.imagemodels import Image
from ..models import Article, Episode, Page, Program, StaticPage
from .mixins import ParentMixin
from .page import PageDetailView, PageListView
from .page import PageDetailView, PageListView, PageUpdateView
__all__ = ["ProgramPageDetailView", "ProgramDetailView", "ProgramPageListView"]
@ -13,9 +19,6 @@ class BaseProgramMixin:
def get_program(self):
return self.object
def get_sidebar_url(self):
return reverse("program-page-list", kwargs={"parent_slug": self.program.slug})
def get_context_data(self, **kwargs):
self.program = self.get_program()
kwargs["program"] = self.program
@ -49,6 +52,40 @@ class ProgramDetailView(BaseProgramMixin, PageDetailView):
**kwargs,
)
def get_template_names(self):
return super().get_template_names() + ["aircox/program_detail.html"]
class ProgramForm(ModelForm):
content = RichTextField()
new_cover = ImageField(required=False)
class Meta:
model = Program
fields = ["content"]
def save(self, commit=True):
file_obj = self.cleaned_data["new_cover"]
if file_obj:
obj, _ = Image.objects.get_or_create(original_filename=file_obj.name, file=file_obj)
self.instance.cover = obj
super().save(commit=commit)
class ProgramUpdateView(UserPassesTestMixin, BaseProgramMixin, PageUpdateView):
model = Program
form_class = ProgramForm
def get_sidebar_queryset(self):
return super().get_sidebar_queryset().filter(parent=self.program)
def test_func(self):
program = self.get_object()
return self.request.user.has_perm("aircox.%s" % program.change_permission_codename)
def get_success_url(self):
return reverse("program-detail", kwargs={"slug": self.get_object().slug})
class ProgramListView(PageListView):
model = Program
@ -69,9 +106,6 @@ class ProgramPageDetailView(BaseProgramMixin, ParentMixin, PageDetailView):
self.parent = self.object.program
return self.object.program
def get_sidebar_queryset(self):
return super().get_sidebar_queryset().filter(parent=self.program)
class ProgramPageListView(BaseProgramMixin, PageListView):
model = Page

View File

@ -15,31 +15,39 @@ input.half-field:not(:active):not(:hover) {
:root {
--body-bg: #fff;
--text-color: black;
--text-color-light: #555;
--break-color: rgb(225, 225, 225);
--main-color: #EFCA08;
--main-color-light: #F4da51;
--main-color-dark: #F49F0A;
--secondary-color: #00A6A6;
--secondary-color-light: #4cc0c0;
--secondary-color-dark: #007ba8;
--disabled-color: #aaa;
--disabled-bg: #eee;
--link-fg: #00A6A6;
--link-hv-fg: var(--text-color);
--highlight-color: rgba(255, 255, 0, 1);
--highlight-color-alpha: rgba(255, 255, 0, 0.7);
--highlight-color-grey: rgba(230, 230, 60, 1);
--highlight-color-2: rgb(0, 0, 254);
--highlight-color-2-alpha: rgb(0, 0, 254, 0.7);
--highlight-color-2-grey: rgba(50, 200, 200, 1);
--hg-color: #EFCA08;
--hg-color-alpha: #EFCA08B3;
--hg-color-grey: rgba(230, 230, 60, 1);
--hg-color-2: #F49F0A;
--hg-color-2-alpha: #F49F0AB3;
--hg-color-2-grey: rgba(50, 200, 200, 1);
--nav-primary-height: 3rem;
--nav-secondary-height: 2.5rem;
--nav-bg: var(--highlight-color);
--nav-fg: var(--highlight-color-2);
--nav-active-bg: var(--highlight-color-2);
--nav-active-fg: var(--highlight-color);
--nav-fg: var(--text-color);
--nav-bg: var(--main-color);
--nav-secondary-bg: var(--main-color-light);
--nav-hv-fg: var(--button-hv-fg);
--nav-hv-bg: var(--button-hv-bg);
--nav-active-fg: var(--button-active-fg);
--nav-active-bg: var(--button-active-bg);
--nav-fs: 1rem;
--nav-2-fs: 0.8rem;
--button-fg: var(--text-color);
--button-bg: var(--highlight-color);
--button-hg-fg: var(--highlight-color-2);
--button-hg-bg: var(--highlight-color);
--button-active-fg: var(--highlight-color);
--button-active-bg: var(--highlight-color-2);
--nav-2-fs: 0.9rem;
}
@ -61,13 +69,6 @@ body {
}
}
section > .toolbar {
background-color: rgba(0,0,0,0.05);
padding: 1em;
margin-bottom: 1.5em;
}
h1, h2, h3, h4, h5, h6, .heading, .title, .subtitle {
font-family: var(--heading-font-family);
}

View File

@ -8,66 +8,89 @@
--subtitle-2-sz: 1.4rem;
--subtitle-3-sz: 1.2rem;
--heading-title-bg-color: rgba(255, 255, 0, 1);
--heading-bg-color: var(--highlight-color);
--heading-bg-highlight-color: var(--highlight-color-2);
--heading-font-family: default;
--heading-bg: var(--main-color);
--heading-fg: var(--text-color);
--heading-hg-fg: var(--text-color);
--heading-hg-bg: var(--secondary-color);
--heading-link-hv-fg: var(--link-fg);
--preview-title-sz: #{v.$text-size-medium};
--preview-subtitle-sz: #{v.$text-size};
--cover-w: 14rem;
--cover-h: 14rem;
--cover-small-w: 10rem;
--cover-small-h: 10rem;
--cover-tiny-w: 10rem;
--cover-tiny-h: 10rem;
--card-w: var(--cover-w);
--preview-bg: var(--body-bg);
--preview-title-sz: var(--title-3-sz);
--preview-subtitle-sz: var(--title-3-sz);
--preview-cover-size: 14rem;
--preview-cover-small-size: 10rem;
--preview-cover-tiny-size: 4rem;
--preview-wide-content-sz: #{v.$text-size-bigger};
--header-height: var(--preview-cover-size);
--preview-heading-bg-color: var(--hg-color);
--header-height: var(--cover-h);
--a-carousel-p: #{v.$text-size-medium};
--a-carousel-ml: calc(#{v.$mp-4} - 0.5rem);
--a-carousel-gap: #{v.$mp-4};
--a-carousel-nav-x: -#{v.$mp-3e};
--a-carousel-bg: none; // var(--secondary-color-light);
--a-progress-bg: transparent;
--a-progress-bar-bg: var(--highlight-color-2);
--a-progress-bar-color: var(--highlight-color);
--a-progress-bar-bg: var(--secondary-color);
--a-progress-bar-color: var(--text-color);
--a-progress-bar-pd: #{v.$mp-2};
--a-playlist-header-bg: var(--highlight-color-2-alpha);
--a-playlist-header-fg: var(--highlight-color);
--a-playlist-header-bg: var(--secondary-color);
--a-playlist-header-fg: var(--text-color);
--a-playlist-title-sz: #{v.$text-size};
--a-playlist-title-pd: #{v.$mp-3};
--a-playlist-item-border: 1px var(--highlight-color-2) solid;
--a-playlist-item-border: 1px var(--secondary-color) solid;
--a-sound-bg: var(--highlight-color-alpha);
--a-sound-hv-bg: var(--highlight-color);
--a-sound-playing-fg: var(--highlight-color-alpha);
--a-sound-hv-fg: var(--highlight-color-2);
--a-sound-bg: var(--main-color);
--a-sound-hv-bg: var(--main-color);
--a-sound-hv-fg: var(--secondary-color);
--a-sound-playing-fg: var(--secondary-color-dark);
--a-sound-text-sz: #{v.$text-size};
--a-player-url-fg: var(--highlight-color-2);
--a-player-panel-bg: var(--highlight-color);
--a-player-url-fg: var(--text-color);
--a-player-panel-bg: var(--main-color);
--a-player-bar-height: var(--nav-primary-height);
--a-player-bar-bg: var(--highlight-color);
--a-player-bar-bg: var(--main-color);
--a-player-bar-title-alone-sz: #{v.$text-size-medium};
--a-player-bar-button-fg: var(--button-fg);
--a-player-bar-button-fg: var(--button-bg);
--a-player-bar-button-hv-fg: var(--button-hv-fg);
--a-player-bar-button-hv-bg: var(--button-hv-bg);
--button-fg: var(--highlight-color-2);
--button-bg: var(--highlight-color);
--button-sec-bg: var(--highlight-color-alpha);
--button-hg-fg: var(--text-color);
--button-hg-bg: var(--highlight-color);
--button-active-fg: var(--highlight-color);
--button-active-bg: var(--highlight-color-2);
--button-fg: var(--text-color);
--button-bg: var(--main-color);
--button-sec-bg: var(--main-color-light);
--button-hv-fg: var(--text-color);
--button-hv-bg: var(--secondary-color-light);
--button-active-fg: var(--text-color);
--button-active-bg: var(--secondary-color);
}
@media screen and (max-width: v.$screen-wide) {
:root {
--cover-w: 10rem;
--cover-h: 10rem;
--cover-small-w: 6rem;
--cover-small-h: 6rem;
--cover-tiny-w: 4rem;
--cover-tiny-h: 4rem;
--section-content-sz: 1rem;
--preview-title-sz: #{v.$text-size};
--preview-subtitle-sz: #{v.$text-size-smaller};
--preview-cover-size: 10rem;
--preview-cover-small-size: 6rem;
--preview-cover-tiny-size: 4rem;
--preview-wide-content-sz: #{v.$text-size};
}
}
@ -80,16 +103,27 @@
}
.subtitle, .header.preview .subtitle {
color: var(--text-color-light);
&.is-1 { font-size: var(--subtitle-1-sz); }
&.is-2 { font-size: var(--subtitle-2-sz); }
&.is-3 { font-size: var(--subtitle-3-sz); }
}
.title + .subtitle {
padding-top: 0em !important;
}
.headings a, a.heading, a.subtitle {
text-decoration: none !important;
}
.heading {
display: inline-block;
&:not(:empty) {
background-color: var(--heading-bg-color);
// border-bottom: 1px var(--heading-bg) solid;
// color: var(--heading-fg);
padding: v.$mp-2;
margin-top: 0em !important;
vertical-align: top;
@ -97,26 +131,25 @@
&.highlight, &.active,
.preview.active &,
{
background-color: var(--heading-bg-highlight-color);
color: var(--highlight-color);
// border-color: var(--heading-hg-bg);
color: var(--heading-hg-fg);
}
}
&.title {
background-color: var(--heading-title-bg-color);
}
}
// ---- button
@mixin button {
.button, a.button, button.button, .nav-urls a {
.button, a.button, button.button {
font-size: v.$text-size;
display: inline-block;
padding: v.$mp-2;
border: 1px var(--highlight-color-2-alpha) solid;
border: none; //1px var(--button-fg) solid;
justify-content: center;
text-align: center;
// font-size: v.$text-size-medium;
cursor: pointer;
text-decoration: none;
color: var(--button-fg);
background-color: var(--button-bg);
@ -125,6 +158,10 @@
background-color: var(--button-sec-bg);
}
.label, label {
cursor: pointer;
}
.icon {
vertical-align: middle;
&:not(:only-child) {
@ -133,22 +170,16 @@
}
}
&:hover {
color: var(--button-hg-fg);
color: var(--button-hv-fg);
background-color: var(--button-hv-bg);
opacity: 1 !important;
}
&.active {
border-color: var(--highlight-color-alpha);
&.active:not(:hover) {
// border-color: var(--hg-color-alpha);
color: var(--button-active-fg);
background-color: var(--button-active-bg);
&:hover {
border-color: var(--highlight-color);
background-color: var(--highlight-color-2-alpha);
opacity: 1 !important;
}
}
&:not([disabled]), &:not(.disabled) {
@ -156,9 +187,9 @@
}
&[disabled], &.disabled {
background-color: var(--highlight-color-grey);
color: var(--highlight-color-2);
border-color: var(--highlight-color-2-alpha);
background-color: var(--hg-color-grey);
color: var(--hg-color-2);
border-color: var(--hg-color-2-alpha);
}
.dropdown-trigger {
@ -186,6 +217,7 @@
.preview {
position: relative;
background-size: cover;
background-color: var(--preview-bg) !important;
&.preview-item {
width: 100%;
@ -219,9 +251,8 @@
> * { margin: 0em; }
.column { padding: 0em; }
a {
color: var(--text-color);
}
a { color: var(--text-color); }
a:hover { color: var(--heading-link-hv-fg) !important; }
}
&.tiny {
@ -233,19 +264,23 @@
}
@media screen and (max-width: v.$screen-small) {
.preview .content {
display: none;
}
}
.preview-cover {
background: var(--preview-bg);
background-size: cover;
background-color: transparent !important;
height: var(--preview-cover-size);
width: var(--preview-cover-size);
min-width: var(--preview-cover-size);
background-repeat: no-repeat;
height: var(--cover-h);
max-width: calc( var(--cover-w) * 1.5 );
min-width: var(--cover-w);
overflow: hidden;
border: 1px #c4c4c4 solid;
img {
height: var(--cover-h);
max-width: calc( var(--cover-w) * 1.5 );
min-width: var(--cover-w);
}
img.hide { visibility: hidden; }
&.small, .preview.small & {
min-width: unset;
@ -289,70 +324,76 @@
// ---- list
.list-item {
display: flex;
flex-direction: column;
width: 100%;
&:not(:first-child) {
margin-top: calc(v.$mp-4 / 2);
}
// padding: v.$mp-3;
.headings {
display: flex;
flex-direction: row;
padding-top: 0em;
padding: 0em;
margin-bottom: v.$mp-2 !important;
.title {
flex-grow: 1;
}
.heading {
// background-color: var(--preview-heading-bg-color);
padding: 0rem;
}
}
.title { flex-grow: 1; }
.subtitle {
font-size: var(--preview-title-sz);
// background-color: var(--preview-heading-bg-color);
text-align: right;
&:not(:empty) { min-width: 9rem; }
}
.media-content {
display: flex;
flex-direction: column;
height: 100%;
margin-bottom: unset;
.list-item:not(.no-cover) & {
min-height: var(--preview-cover-small-size);
}
.content {
flex-grow: 1;
margin-bottom: auto;
}
.actions {
flex-grow: unset;
text-align: right;
margin-top: auto;
}
&:not(.wide) .media {
padding: v.$mp-3;
// border-radius: v.$mp-2;
border: 1px solid var(--break-color) !important;
}
}
@media screen and (max-width: v.$screen-very-small) {
.list-item .headings {
flex-direction: column;
.heading {
display: inline;
text-align: left;
}
.subtitle {
color: unset !important;
background: none !important;
}
}
}
// ---- wide
.preview-wide {
height: var(--preview-cover-size);
display: flex;
.headings {
height: var(--preview-cover-size)
}
&:not(.header) .headings {
.list-item.wide {
& .preview-cover {
box-shadow: 0em 0em 1em rgba(0,0,0,0.2);
}
& .headings {
width: var(--preview-cover-size);
min-width: var(--preview-cover-size);
flex-grow: 0;
margin-right: v.$mp-4;
}
& .content {
font-size: var(--preview-wide-content-sz);
flex-grow: 1;
@ -361,77 +402,90 @@
// ---- card
.preview-card {
display: flex;
flex-direction: column;
width: var(--card-w);
padding: 0rem !important;
margin-bottom: auto;
height: var(--preview-cover-size);
width: var(--preview-cover-size);
background-color: var(--preview-bg) !important;
transition: box-shadow 0.2s;
&.small {
height: var(--preview-cover-small-size);
width: var(--preview-cover-small-size);
}
&.tiny {
height: var(--preview-cover-tiny-size);
width: var(--preview-cover-tiny-size);
&:hover {
figure {
box-shadow: 0em 0em 1.2em rgba(0, 0, 0, 0.4) !important;
}
&:not(.header) {
box-shadow: 0em 0em 1em rgba(0,0,0,0.2);
a {
color: var(--heading-link-hv-fg);
}
}
.headings {
margin-top: v.$mp-2;
.heading {
display: block !important;
}
.title {
max-height: calc( var(--preview-cover-size) / 2 );
overflow: hidden;
}
.card-grid & {
min-width: unset;
.subtitle {
font-size: v.$text-size-2;
}
}
.card-content {
flex-grow: 1;
position: relative;
figure {
box-shadow: 0em 0em 1em rgba(0, 0, 0, 0.2);
height: var(--cover-h);
width: var(--cover-w);
}
.actions {
position: absolute;
bottom: v.$mp-3;
right: v.$mp-3;
label {
display: none;
padding: v.$mp-2;
bottom: 0rem;
right: 0rem;
}
}
}
.card-headings, .preview-card-headings {
padding-top: v.$mp-3;
& > div:not(:last-child),
& .column > div {
margin-bottom: v.$mp-3;
}
preview-header:not(.no-cover) & .heading {
margin-bottom: v.$mp-3;
}
}
// ---- card grid
.card-grid {
// ---- grid
.list-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr;
grid-auto-flow: dense;
gap: v.$mp-4;
// .grid-wide { grid-column: 1 / 3; }
}
@media screen and (max-width: v.$screen-smaller) {
.list-grid {
grid-template-columns: 1fr;
// .grid-wide { grid-column: 1; }
}
}
// ---- ---- Carousel
.a-carousel {
margin-left: calc( 0rem - var(--a-carousel-ml));
.a-carousel-viewport {
padding: var(--a-carousel-p) 0;
padding-left: var(--a-carousel-ml);
box-shadow: inset 0em 0em 20rem var(--a-carousel-bg);
// background-color: var(--a-carousel-bg);
padding: 0rem;
padding-top: var(--a-carousel-p);
margin-top: calc( 0rem - var(--a-carousel-p) );
}
}
@ -445,16 +499,15 @@
}
}
.a-carousel-button-container {
button, .button {
z-index:1000;
position: absolute;
display: flex;
flex-direction: column;
top: 50%;
.a-carousel-bullets-container {
// due to a-carousel margin-left
padding-left: var(--a-carousel-ml);
&.prev { left: var(--a-carousel-nav-x); }
&.next { right: var(--a-carousel-nav-x); }
.bullet {
margin: v.$mp-1;
cursor: pointer;
&:hover { color: var(--link-fg); }
}
}
@ -525,7 +578,7 @@
height: 3rem;
background-color: var(--a-sound-bg);
&.playing, &.playing .label {
&.playing .label {
color: var(--a-sound-playing-fg) !important;
}
@ -567,6 +620,11 @@
.button {
width: 3em;
font-size: var(--a-sound-text-sz);
&:hover {
color: var(--a-sound-hv-fg) !important;
background-color: unset;
}
}
}
@ -645,11 +703,10 @@
padding: v.$mp-2 !important;
min-width: calc(var(--a-player-bar-height) + v.$mp-2 * 2);
border-radius: 0px;
transition: background-color 0.5s;
&.open {
background-color: var(--highlight-color-2-alpha);
color: var(--highlight-color);
background-color: var(--button-active-bg);
color: var(--button-active-fg);
}
}
}

View File

@ -13,7 +13,15 @@
.push-right, .flex-push-right { margin-left: auto !important; }
.push-bottom { margin-top: auto !important; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr }
.grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr }
.flex-row { display: flex; flex-direction: row }
.flex-column { display: flex; flex-direction: column }
.flex-grow-0 { flex-grow: 0 !important; }
.flex-grow-1 { flex-grow: 1 !important; }
.float-right { float: right }
.float-left { float: left }
@ -59,8 +67,8 @@
// -- colors
.highlight-color { color: var(--highlight-color); }
.highlight-color-2 { color: var(--highlight-color-2); }
.hg-color { color: var(--highlight-color); }
.hg-color-2 { color: var(--highlight-color-2); }
.bg-transparent { background-color: transparent; }

View File

@ -1,7 +1,7 @@
@use "./vars" as v;
@use "./components";
@import "./vendor";
@use "./vendor";
// ---- main theme & layout
@ -9,28 +9,33 @@
padding-bottom: 5rem;
a {
color: var(--highlight-color-2);
text-decoration: none;
color: var(--link-fg);
text-decoration: underline;
&:hover {
color: var(--text-color);
color: var(--link-hv-fg);
}
}
section.container {
margin-top: v.$mp-3;
> .title {
margin-top: unset;
padding-top: unset !important;
margin-bottom: v.$mp-4;
border-bottom: 1px solid black;
}
&:not(:last-child) {
margin-bottom: v.$mp-3;
padding-bottom: calc(v.$mp-4 / 2);
border-bottom: 2px var(--break-color) solid;
}
> .title {
font-size: var(--title-2-sz);
clear: both;
margin: v.$mp-3 0;
}
}
*[data-oembed-url] {
clear: both;
}
}
@ -42,7 +47,7 @@
}
.vc-weekday-1, .vc-weekday-7 {
color: var(--highlight-color-2) !important;
color: var(--hg-color-2) !important;
}
@ -55,6 +60,12 @@
display: inline-block;
margin: v.$mp-3;
margin-left: 0rem;
padding: v.$mp-2;
border-bottom: 1px var(--main-color) solid;
.heading {
padding: 0em;
}
.day {
font-weight: v.$weight-bold;
@ -76,9 +87,10 @@
display: none;
}
button, .action {
button, .action, a {
justify-content: center;
min-width: 2rem;
padding: v.$mp-2;
.not-selected { opacity: 0.6; }
.icon { margin: 0em !important; }
@ -112,8 +124,8 @@
}
.navbar-item.active, .table tr.is-selected {
color: var(--highlight-color-2);
background-color: var(--highlight-color);
color: var(--hg-color-2);
background-color: var(--hg-color);
}
@ -154,11 +166,7 @@
font-family: var(--heading-font-family);
text-transform: uppercase;
a, .button {
display: block;
width: 100%;
}
color: var(--nav-fg) !important;
.icon:first-child, .icon + span {
text-align: center;
@ -166,17 +174,20 @@
display: inline-block;
}
&:hover {
background-color: var(--nav-hv-bg);
color: var(--nav-hv-fg);
}
&.active {
background-color: var(--nav-active-bg);
color: var(--nav-active-fg);
color: var(--nav-active-fg) !important;
}
}
.nav-menu {
display: flex;
flex-grow: 1;
background-color: var(--nav-bg);
.dropdown-content {
font-size: v.$text-size;
@ -210,7 +221,7 @@
}
&.secondary {
background-color: var(--nav-bg);
background-color: var(--nav-secondary-bg);
//position: absolute;
//width: 100%;
//box-shadow: 0em 0.5em 0.5em rgba(0, 0, 0, 0.05);
@ -235,6 +246,7 @@
.breadcrumbs {
text-align: right;
padding: v.$mp-3 0rem;
font-size: v.$text-size-smaller;
padding-bottom: 0;
margin-bottom: 0;
@ -269,7 +281,7 @@
}
.nav + .nav {
flew-grow: 0 !important;
flex-grow: 0 !important;
}
}
@ -284,6 +296,7 @@
.nav-menu {
display: block;
position: absolute;
background-color: var(--nav-secondary-bg);
left: 0;
top: 100%;
width: 100%;
@ -292,11 +305,7 @@
.nav-item {
display: block;
font-weight: v.$weight-normal;
&:hover {
background-color: var(--highlight-color-2-alpha);
color: var(--highlight-color);
}
font-size: var(--nav-fs);
}
}
@ -383,14 +392,45 @@ nav li {
.header-cover:not(:only-child) {
float: right;
height: var(--header-height);
max-width: calc(var(--header-height) * 2);
position: relative;
z-index: 1000;
background-color: var(--body-bg);
margin: 0 0 v.$mp-4 v.$mp-4;
.cover {
max-width: calc(var(--header-height) * 2);
height: var(--header-height);
}
}
.header-cover:only-child {
with: 100%;
}
@media screen and (max-width: v.$screen-small) {
.container.header {
width: calc( 100% - v.$mp-2 );
.headings {
width: 100%;
clear: both;
}
.header-cover {
float: none;
margin: 0;
text-align: center;
}
.cover {
margin-left: auto;
margin-right: auto;
max-height: calc(var(--cover-h) * 1);
max-width: calc(var(--cover-w) * 2);
}
}
}
// ---- ---- detail
.page-content {
margin-top: v.$mp-6;
@ -400,6 +440,32 @@ nav li {
}
}
// ---- ---- list
.list-item {
&.logs {
.track {
margin-right: v.$mp-3;
.icon {
margin-right: v.$mp-2;
color: var(--secondary-color-dark);
}
}
}
&:nth-child(3n):not(.wide) .media,
{
border-color: var(--main-color-dark) !important;
}
&:nth-child(3n+1):not(.wide) .media,
{
border-color: var(--secondary-color-dark) !important;
}
}
// ---- responsive
body { font-size: 1.4em; }
@ -420,22 +486,4 @@ body { font-size: 1.4em; }
margin-right: v.$mp-2;
}
.container.header {
width: calc( 100% - v.$mp-2 );
.headings {
width: 100%;
clear: both;
}
.header-cover {
float: none;
width: 100%;
max-width: unset;
height: unset;
margin-left: 0rem;
margin-right: 0rem;
}
}
}

View File

@ -45,9 +45,8 @@ $weight-bolder: 500;
$weight-bold: 700;
$screen-very-small: 400px;
//TODO: switch small & smaller
$screen-small: 600px;
$screen-smaller: 800px;
$screen-smaller: 900px;
$screen-normal: 1024px;
$screen-wider: 1280px;
$screen-wide: 1380px;

View File

@ -10,6 +10,7 @@ $title-color: #000;
@import "~bulma/sass/base/_all";
@import "~bulma/sass/components/dropdown";
// @import "~bulma/sass/components/card";
@import "~bulma/sass/components/media";
@import "~bulma/sass/components/message";
@import "~bulma/sass/components/modal";

View File

@ -1,24 +1,31 @@
<template>
<section class="a-carousel">
<nav class="a-carousel-button-container" v-if="showPrevButton">
<button :class="[buttonClass, 'prev']" aria-label="Go left" @click="prev">
<span class="icon">
<i :class="leftButtonIcon"></i>
</span>
</button>
</nav>
<div class="a-carousel-button-container" v-if="showNextButton">
<button :class="[buttonClass, 'next']" aria-label="Go left" @click="next">
<span class="icon">
<i :class="rightButtonIcon"></i>
</span>
</button>
</div>
<nav ref="viewport" class="a-carousel-viewport">
<section ref="container" :class="['a-carousel-container', containerClass]">
<slot name="default"></slot>
</section>
</nav>
<nav class="a-carousel-bullets-container">
<span class="left">
<span class="icon bullet" @click="prev()" v-if="showPrev">
<i :class="leftButtonIcon"></i>
</span>
</span>
<template v-if="bullets.length > 1">
<span class="icon bullet" v-bind:key="bullet" v-for="bullet of bullets" @click="select(bullet)">
<i v-if="bullet == index" class="fa fa-circle"></i>
<i v-else class="far fa-circle"></i>
</span>
</template>
<span class="right">
<span class="icon bullet" @click="next()" v-if="showNext">
<i :class="rightButtonIcon"></i>
</span>
</span>
<slot name="bullets-right" :v-bind="this"></slot>
</nav>
</section>
</template>
<style scoped>
@ -29,7 +36,7 @@
.a-carousel-viewport {
width: 100%;
overflow: hidden;
overflow-x: hidden;
}
.a-carousel-container {
@ -42,10 +49,67 @@
flex-shrink: 0;
}
.a-carousel-bullets-container {
flex-grow: 1;
}
.a-carousel-bullets-container .bullet {
cursor: pointer;
}
.a-carousel-bullets-container .left {
min-width: 2rem;
margin-right: auto;
}
.a-carousel-bullets-container .right {
min-width: 2rem;
margin-left: auto;
}
.a-carousel-bullets-container {
display: flex;
flex-direction: row;
}
</style>
<script>
import {ref} from 'vue'
class Offset {
constructor(el, min=null, max=null) {
this.el = el
this.rect = el.getBoundingClientRect();
({min, max} = this.minmax(min, max))
this.min = min
this.max = max
this.size = max-min
}
minmax(min=null, max=null) {
min = min === null ? this.rect.left : min
max = max === null ? this.rect.right : max
return {min, max}
}
relative(to) {
return new Offset(this.el, this.min-to.min, this.max-to.min)
}
}
class Card extends Offset {
constructor(el, index) {
super(el)
this.index = index
}
visible(viewportOffset) {
return viewportOffset.min <= this.min && viewportOffset.max >= this.max
}
}
export default {
setup() {
return {
@ -72,109 +136,89 @@ export default {
computed: {
card() { return this.cards()[this.index] },
showPrevButton() {
showPrev() {
return this.index > 0
},
showNextButton() {
showNext() {
if(!this.cards || this.cards.length <= 1)
return false
let { count } = this.visibility
return (this.index + count) < this.cards.length
let last = this.bullets[this.bullets.length-1]
return this.index != last
},
visibility() {
// force refresh on index
[this.index, this.refresh_]
bullets() {
if(!this.cards || !this.$refs.viewport)
return []
if(!this.cards)
return {min: -1, max: -1, count: 0};
let contOff = new Offset(this.$refs.container)
let viewMax = new Offset(this.$refs.viewport).size
let bullets = []
const vOff = this.offset(this.$refs.viewport)
var [min, max] = [-1, -1]
for(let at=0; at < this.cards.length; at++) {
const card = this.cards[at]
const cOff = this.offset(card)
const visible = vOff.min <= cOff.min && vOff.max >= cOff.max
if(visible) {
if(min === -1)
min = parseInt(at)
max = parseInt(at)
let i = 0;
let max = viewMax
bullets.push(i)
while(i < this.cards.length) {
// skip until next view
for(; i < this.cards.length; i++) {
let card = this.cards[i].relative(contOff)
if(card.max > max) {
max = card.min + viewMax
bullets.push(i)
i++
break
}
}
if(max !== -1)
max++
return {
min, max,
count: (min !== -1) ? max-min : 0
}
return bullets
},
},
methods: {
offset(el, parent=null) {
const rect = el.getBoundingClientRect()
const off = {min: rect.left, max: rect.right }
if(parent === null)
return off
const pOff = this.offset(parent)
return {
min: off.min - pOff.min,
max: off.max - pOff.max,
}
},
getCards() {
if(!this.$refs.container)
return []
if(!this.cardSelector)
return this.$refs.container.children
return this.$refs.container.querySelectorAll(this.cardSelector)
let nodes = (!this.cardSelector) ?
[...this.$refs.container.children] :
[...this.$refs.container.querySelectorAll(this.cardSelector)]
return nodes.map((el, index) => new Card(el, index))
},
selectIndex(index, relative=false) {
select(index, relative=false) {
if(relative)
index = this.index + index
index = Math.min(this.cards.length, index)
const el = this.cards[index]
if(!el)
index = Math.min(index, this.cards.length)
index = Math.max(index, 0)
let card = this.cards[index]
if(!card)
return null;
const elOff = this.offset(el, this.$refs.container)
this.$refs.container.style.marginLeft = `-${elOff.min}px`
card = new Card(card.el)
const cont = new Offset(this.$refs.container)
const rel = card.relative(cont)
this.$refs.container.style.marginLeft = `-${rel.min}px`
this.index = index;
return el
return card.el
},
next() {
this.refresh_++
if(!this.visibility.count)
return
let {count} = this.visibility
let at = Math.min(
count === 1 ? this.index+count : this.index+count-1,
this.cards.length-count
)
this.selectIndex(at)
let n = this.bullets.indexOf(this.index)
let index = this.bullets[n+1]
this.select(index)
},
prev() {
this.refresh_++
if(!this.visibility.count)
return
const {min, count} = this.visibility
let at = Math.max(0, min-count)
if(min < 0 || count <= 0)
return
this.selectIndex(at)
let n = this.bullets.indexOf(this.index)
let index = this.bullets[n-1]
this.select(index)
},
refresh() {
this.cards = this.getCards()
this.selectIndex(this.index)
this.select(this.index)
this.refresh_++
}
},

View File

@ -1,7 +1,5 @@
<template>
<div>
<slot :page="page" :podcasts="podcasts"></slot>
</div>
</template>
<script>

7
assets/src/public.js Normal file
View File

@ -0,0 +1,7 @@
import "./assets/public.scss"
import './index.js'
import App from './app.js'
export default App
window.App = App

Binary file not shown.

View File

@ -238,6 +238,7 @@ TEMPLATES = [
"django.template.context_processors.static",
"django.template.context_processors.tz",
"django.contrib.messages.context_processors.messages",
"aircox.context_processors.station",
),
"loaders": (
"django.template.loaders.filesystem.Loader",
@ -249,3 +250,5 @@ TEMPLATES = [
WSGI_APPLICATION = "instance.wsgi.application"
LOGOUT_REDIRECT_URL = "/"

View File

@ -23,6 +23,7 @@ import aircox.urls
urlpatterns = aircox.urls.urls + [
path("admin/", admin.site.urls),
path("accounts/", include("django.contrib.auth.urls")),
path("ckeditor/", include("ckeditor_uploader.urls")),
path("filer/", include("filer.urls")),
]