44 Commits

Author SHA1 Message Date
NH Gooi
c7243f31a0 Render articles directly from block source instead of prerendered text 2025-03-18 21:53:01 +01:00
NH Gooi
2e1f496eea Render articles directly from block source instead of prerendered text 2025-03-18 21:51:18 +01:00
NH Gooi
37745e8ae9 Margin toegevoegd op div.text in post, want intranet editor maakt geen p tags 2025-01-04 17:51:04 +01:00
NH Gooi
eb9813c239 Contactinfo aangepast 2024-12-21 11:31:11 +01:00
NH Gooi
9dc9b30afa Regionieuws lengte - 4 samples per seconde 2024-12-16 20:40:43 +01:00
NH Gooi
761cec4257 Laad 'meer fragmenten' in de juiste container 2024-12-16 20:27:47 +01:00
NH Gooi
0e2148956f Regionieuws waveform gefixt 2024-12-07 18:37:57 +01:00
1863ff766f Merge pull request 'Correcties voor banner placement' (#10) from dev into main
Reviewed-on: #10
2024-12-06 17:45:27 +01:00
96748c0c01 fix: center sidebar banner on mobile 2024-12-06 14:58:16 +01:00
c16a2db01d fix: set correct margin on banner 2024-12-06 14:54:51 +01:00
df4d48a327 fix: remove extra margin above banner 2024-12-06 14:49:26 +01:00
187fc7b273 fix: small styling fixes for sidebar banner 2024-12-06 14:46:28 +01:00
06e7741d3b fix: less space above homepage banner 2024-12-06 14:15:18 +01:00
262aec618b fix: build was not run properly 2024-12-06 14:05:30 +01:00
98a9cd2c53 fix: center banners on mobile 2024-12-06 14:02:56 +01:00
21ca729958 fix: placement of mobile banner 2024-12-06 13:49:31 +01:00
367527098d Merge pull request 'Add mobile header banner' (#9) from dev into main
Reviewed-on: #9
2024-12-04 11:15:40 +01:00
a86f8e56a1 fix: show banner full-width on mobile 2024-12-04 10:42:30 +01:00
c1ddaa15c6 fix: only show mobile banner on mobile 2024-12-04 10:27:15 +01:00
39f1ee4823 feat: add mobile banner to header 2024-12-04 08:07:46 +01:00
71a5d3a690 fix: add mobile banner 2024-12-02 12:09:22 +01:00
NH Gooi
6db6de8e49 Artiest en titel omgedraaid in nustraks 2024-11-28 21:45:17 +01:00
NH Gooi
e06ce1507b Revive URL en ID via .env 2024-11-28 21:09:07 +01:00
3ef630c7cc fix: correct margin for homepage banner 2024-11-25 20:57:49 +01:00
2ba81f8550 fix: add leaderboard on homepage 2024-11-25 20:52:33 +01:00
f3fa2c109a fix: add margin to header banner 2024-11-25 20:49:31 +01:00
52df85716b fix: move new styling into scss files 2024-11-25 20:47:18 +01:00
22292e10ed fix: add banner styling 2024-11-25 20:03:11 +01:00
9428e1d2ee fix: move ad prefix to banner system 2024-11-25 19:44:07 +01:00
1c587684f3 fix: enable banners by default 2024-11-25 19:30:18 +01:00
918255be1c feat: update banners with new system 2024-11-25 19:28:35 +01:00
NH Gooi
35a5aa636f Merge branch 'main' into dev 2024-11-12 14:17:24 +01:00
NH Gooi
e2551b1dab Podcast toegevoegd, NH Gooi -> NHGooi 2024-11-12 14:16:01 +01:00
NH Gooi
552c638571 Agenda items kon niet doorklikken 2024-10-20 18:02:20 +02:00
NH Gooi
a930fb7216 Merge remote-tracking branch 'origin/main' into dev 2024-10-03 19:33:29 +02:00
NH Gooi
58ea5c0c85 iframe blocktype toegevoegd [#00033] 2024-10-03 19:32:44 +02:00
NH Gooi
8616cb3d56 Relatieve links gefixt in Lees Ook blok 2024-10-03 19:22:25 +02:00
NH Gooi
dbca7e2bc5 Composer autoload opnieuw gegenereerd 2024-09-29 19:10:40 +02:00
NH Gooi
437e6243e7 Merge branch 'feature/api-to-repo' into dev 2024-09-29 19:06:46 +02:00
NH Gooi
6008d3175b Merge remote-tracking branch 'origin/main' into dev 2024-09-25 21:19:15 +02:00
NH Gooi
ab7246e123 Merge remote-tracking branch 'origin/main' into dev 2024-09-25 17:32:04 +02:00
NH Gooi
d9627a54c4 Player styling verplaatst naar style.css 2024-09-25 17:32:00 +02:00
NH Gooi
6c732f90e8 Wavesurfer voor audio file player 2024-09-25 17:30:15 +02:00
NH Gooi
1dadbc62af WaveSurfer player voor podcasts, voor live WIP 2024-09-24 17:29:57 +02:00
44 changed files with 987 additions and 324 deletions

View File

@@ -10,7 +10,7 @@ class CalendarController extends Controller
{
parent::registerView($request, 'agenda', $id);
$apiResult = $this->API('agenda/item/' . (int)$id);
$calendarEvent = new \Model\CalendarEvent($apiResult);
$calendarEvent = new \Model\CalendarEvent($apiResult->news);
return view('calendarevent', array_merge($this->getSidebareData(), ['event' => $calendarEvent, 'metadata' => $calendarEvent->metadata]));
}

View File

@@ -88,7 +88,7 @@ class Controller extends BaseController
$this->getDataFromFileAndConvert('laatste_podcasts.json', ['podcasts'], '\Model\Podcast'));
});
View::share('disableBanners', env('DISABLE_BANNERS', true));
View::share('disableBanners', env('DISABLE_BANNERS', false));
}
protected function registerView(Request $request, $type, $id)

View File

@@ -22,22 +22,24 @@ class NewsController extends Controller
switch ($apiResult->version) {
case 1:
if (!$newsItem->content) return redirect('//nhnieuws.nl/gooi');
return view('newsitem', ['news' => $newsItem, 'metadata' => $newsItem->metadata]);
break;
if (!$newsItem->content) return redirect('//nhnieuws.nl/gooi');
case 2:
case 2:
if(isset($apiResult->source->article)) {
$source = $apiResult->source->article;
$newsItem->published = self::TimestampToDateTime($source->created);
$newsItem->edited = self::TimestampToDateTime($source->updated);
$newsItem->author = $source->author;
$newsItem->images = null; // Images will be embedded
$newsItem->video = null; // Videos will be embedded
$newsItem->content = $source->blocks;
$newsItem->content = $source->blocks;
} elseif(isset($apiResult->source->blocks)) {
$newsItem->content = $apiResult->source->blocks;
}
return view('newsitem', array_merge($this->getSidebareData(), ['news' => $newsItem, 'metadata' => $newsItem->metadata, 'searchURL' => 'nieuws/zoeken']));
return view('newsitem', array_merge($this->getSidebareData(), ['type' => $apiResult->type, 'news' => $newsItem, 'metadata' => $newsItem->metadata, 'searchURL' => 'nieuws/zoeken']));
}
}
@@ -186,11 +188,15 @@ class NewsController extends Controller
public function regionieuws()
{
$data = $this->API('nieuws/regionieuws.json');
return view('listen', [
'source' => $this->API_URL . 'nieuws/regionieuws',
'source' => $this->API_URL . 'nieuws/regionieuws.mp3',
'title' => 'Regionieuws',
'content' => 'het laatste nieuws uit de regio',
'isStream' => false,
'canDownload' => true]);
'canDownload' => true,
'lengte' => $data->length * 0.25,
'waveform' => $data
]);
}
}

View File

@@ -95,7 +95,7 @@ class RadioController extends Controller
{
$programs = [];
$now = new \DateTimeImmutable('2 minutes ago');
$page = (int)$request->get('pagina', 1);
$page = (int)$request->get('pagina', 1);
$apiResult = $this->API('programma/schema/recent?pagina=' . (int)max(1, $page) . '&aantal=12');
foreach($apiResult->schedule as $item) {
if(!$item->program->nonstop && !$item->program->rerun) {

View File

@@ -14,6 +14,8 @@ class StreamController extends Controller
return view('listen', [
'source' => self::$STREAM_URL . 'mp3live',
'title' => 'Luister live',
'lengte' => 0,
'waveform' => null,
'content' => 'de live-uitzending van NH Gooi.',
'isStream' => true ]);
}
@@ -53,13 +55,20 @@ class StreamController extends Controller
'source' => $this->API_URL . 'podcast/stream/' . $apiResult->url,
'title' => $podcast->title,
'content' => $podcast->title,
'lengte' => $podcast->duration / 1000,
'waveform' => $podcast->waveform,
'isStream' => false,
'canDownload' => $this->API_URL . 'podcast/download/' . $apiResult->url ]);
}
public function program(Request $request, $year, $month, $day, $hour, $duration, $offset = 0) {
$date = (new \DateTimeImmutable())->setDate($year, $month, $day)->setTime($hour, 0, 0);
$current = $date->add(\DateInterval::createFromDateString($offset . ' hours'));
$current = $date->add(\DateInterval::createFromDateString($offset . ' hours'));
$programma = $this->API("programma/details/" . $current->Format("Y/m/d/H"));
if(!$programma->is_beschikbaar) {
return view('listen', ['notAvailable' => true]);
}
$hours = [];
for($i = 0; $i < $duration; $i++) {
@@ -72,7 +81,9 @@ class StreamController extends Controller
'source' => $this->API_URL . 'programma/stream/' . $current->format('Y/m/d/H'),
'tabs' => $hours,
'title' => 'Uitzending terugluisteren',
'content' => 'de uitzending van ' . $current->format('d-m-Y, H') . ':00 uur',
'lengte' => $programma->waveform->length,
'waveform' => $programma->waveform,
'content' => $programma->programma->name . ' van ' . $current->format('d-m-Y, H') . ':00 uur',
'isStream' => false,
'canDownload' => false ]);
}

203
public/css/style.css vendored
View File

@@ -162,6 +162,16 @@ div.pp_default .pp_close:hover {
list-style: none;
}
.ad-prefix {
width: 100%;
font-family: Nunito, serif;
font-size: 12px;
font-weight: 500;
line-height: 3.17;
text-align: center;
color: #666;
}
.header {
height: 111px;
}
@@ -172,10 +182,11 @@ div.pp_default .pp_close:hover {
.header .logo img {
height: 95px;
}
.header .advertisement {
.header ins[data-revive-zoneid] {
float: right;
width: 728px;
height: 90px;
margin-top: 10px;
}
@media (max-width: 1170px) {
@@ -190,7 +201,7 @@ div.pp_default .pp_close:hover {
.header .logo {
float: none;
}
.header .advertisement {
.header ins[data-revive-zoneid] {
float: none;
}
}
@@ -778,6 +789,11 @@ div.pp_default .pp_close:hover {
color: #fff;
}
.article-iframe {
width: 100%;
aspect-ratio: 1;
}
.box_header {
border-bottom: 1px solid #efefef;
padding-right: 20px;
@@ -1151,6 +1167,16 @@ div.pp_default .pp_close:hover {
white-space: nowrap;
}
@media (max-width: 576px) {
ins[data-revive-zoneid] img {
max-width: 100%;
height: auto;
}
}
.homepage-body-banners {
margin-top: -4rem;
}
.news .blog .post {
height: 115px;
}
@@ -1204,6 +1230,19 @@ div.pp_default .pp_close:hover {
font-size: 30px;
}
.box.featured .sentence, .post_container .post_body .sentence {
font-size: 12px;
font-style: italic;
line-height: 1.3;
text-align: right;
color: #585858;
display: block;
width: 100%;
}
.box.featured .sentence span, .post_container .post_body .sentence span {
padding: 0 5px;
}
.post_container {
max-width: 1170px;
margin: 0 auto;
@@ -1231,20 +1270,6 @@ div.pp_default .pp_close:hover {
.post_container .post_body h3 {
font-size: 15px;
}
.post_container .post_body .sentence,
.box.featured .sentence {
font-size: 12px;
font-style: italic;
line-height: 1.3;
text-align: right;
color: #585858;
display: block;
width: 100%;
}
.post_container .post_body .sentence span,
.box.featured .sentence span {
padding: 0 5px;
}
.post_container .post_body blockquote {
border-left: 3px solid #5ba8f4;
margin-left: 0;
@@ -1262,6 +1287,9 @@ div.pp_default .pp_close:hover {
line-height: 3.17;
color: #585858;
}
.post_container .post_body div.text {
margin-bottom: 20px;
}
.post_container .post_body .post_details {
margin: 0;
padding: 0;
@@ -1309,19 +1337,7 @@ div.pp_default .pp_close:hover {
color: #ED1C24;
}
.post_tags {
margin: 0;
padding: 0;
list-style: none;
height: 31px;
margin: 20px 0;
}
.post_tags li {
float: left;
margin-right: 10px;
}
.post_tags li a,
#schedule .onair {
#schedule .onair, .post_tags li a {
display: block;
width: 4rem;
padding: 6px 15px 7px;
@@ -1336,18 +1352,36 @@ div.pp_default .pp_close:hover {
text-transform: uppercase;
}
#schedule a {
text-decoration: none;
.post_tags {
margin: 0;
padding: 0;
list-style: none;
height: 31px;
margin: 20px 0;
}
.post_tags li {
float: left;
margin-right: 10px;
}
@keyframes tilt-shaking {
0% { transform: rotate(0deg); }
25% { transform: rotate(5deg); }
50% { transform: rotate(0deg); }
75% { transform: rotate(-5deg); }
100% { transform: rotate(0deg); }
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(5deg);
}
50% {
transform: rotate(0deg);
}
75% {
transform: rotate(-5deg);
}
100% {
transform: rotate(0deg);
}
}
.onair {
animation: tilt-shaking 1s linear infinite;
#schedule a {
text-decoration: none;
}
#schedule .program-title {
font-family: Montserrat, serif;
@@ -1387,6 +1421,9 @@ div.pp_default .pp_close:hover {
#schedule .no-results span, #schedule .loading span {
margin-right: 10px;
}
#schedule .onair {
animation: tilt-shaking 1s linear infinite;
}
.page_container {
max-width: 1170px;
@@ -1476,6 +1513,90 @@ div.pp_default .pp_close:hover {
margin: 10px 20px 0 0;
}
.podcast-player .content {
border: solid 1px #333;
border-radius: 5px;
padding: 0.4rem;
}
.audioplayer .waveform {
cursor: pointer;
position: relative;
}
.audioplayer .hover {
position: absolute;
left: 0;
top: 0;
z-index: 10;
pointer-events: none;
height: 100%;
width: 0;
mix-blend-mode: overlay;
background: rgba(255, 255, 255, 0.5);
opacity: 0;
transition: opacity 0.2s ease;
}
.audioplayer .waveform:hover .hover {
opacity: 1;
}
.audioplayer .time,
.audioplayer .duration {
position: absolute;
z-index: 11;
top: 50%;
margin-top: -1px;
transform: translateY(-50%);
font-size: 11px;
background: rgba(0, 0, 0, 0.75);
padding: 2px;
color: #ddd;
}
.audioplayer .time {
left: 0;
}
.audioplayer .duration {
right: 0;
}
.audioplayer .audio-controls {
width: 100%;
justify-content: center;
display: flex;
}
.audioplayer .audio-controls .btn {
padding-left: 0;
padding-right: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-transform: none;
}
@media (max-width: 720px) {
.audioplayer .audio-controls .btn label {
display: none;
}
}
.audioplayer .audio-controls .btn.btn-play {
flex: 50% 1 0;
}
.audioplayer .volume-controls {
display: flex;
}
.audioplayer .volume-controls .volume-slider {
flex: 100% 1 1;
}
.audioplayer .audio-controls .btn,
.audioplayer .volume-controls .btn-toggle-mute {
flex: 100px 1 1;
padding: 10px 0 10px 0;
background: #5ba8f4;
border-radius: 5px;
border-color: solid 1px #0f259d;
color: white;
font-family: Nunito, serif;
text-align: center;
text-decoration: none;
}
.footer_container {
font-family: Montserrat, serif;
font-size: 14px;
@@ -1663,10 +1784,4 @@ a, a:hover, a:active {
}
}
.podcast-player .content {
border: solid 1px #333;
border-radius: 5px;
padding: 0.4rem;
}
/*# sourceMappingURL=style.css.map */

File diff suppressed because one or more lines are too long

1
public/js/wavesurfer.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -5,6 +5,7 @@
@use "../components/pretty_photo";
@use "../components/cookie";
@use "../components/list";
@use "../components/banners";
@use "../layout";

View File

@@ -0,0 +1,9 @@
.ad-prefix {
width: 100%;
font-family: Nunito, serif;
font-size: 12px;
font-weight: 500;
line-height: 3.17;
text-align: center;
color: #666;
}

View File

@@ -7,10 +7,11 @@
height: 95px;
}
}
.advertisement {
ins[data-revive-zoneid] {
float: right;
width: 728px;
height: 90px;
margin-top: 10px;
}
}
@@ -25,7 +26,7 @@
.logo {
float: none;
}
.advertisement {
ins[data-revive-zoneid] {
float: none;
}
}

View File

@@ -61,7 +61,8 @@
.post_details {
@include reset-list;
display: flex;
gap: 3px;
.category a {
padding: 6px 11px 7px;
border-radius: 3px;
@@ -105,3 +106,8 @@
}
}
}
.article-iframe {
width: 100%;
aspect-ratio: 1;
}

View File

@@ -0,0 +1,91 @@
.audioplayer {
.waveform {
cursor: pointer;
position: relative;
}
.hover {
position: absolute;
left: 0;
top: 0;
z-index: 10;
pointer-events: none;
height: 100%;
width: 0;
mix-blend-mode: overlay;
background: rgba(255, 255, 255, 0.5);
opacity: 0;
transition: opacity 0.2s ease;
}
.waveform:hover .hover {
opacity: 1;
}
.time,
.duration {
position: absolute;
z-index: 11;
top: 50%;
margin-top: -1px;
transform: translateY(-50%);
font-size: 11px;
background: rgba(0, 0, 0, 0.75);
padding: 2px;
color: #ddd;
}
.time {
left: 0;
}
.duration {
right: 0;
}
.audio-controls {
width: 100%;
justify-content: center;
display: flex;
}
.audio-controls .btn {
padding-left: 0;
padding-right: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-transform: none;
}
@media(max-width: 720px) {
.audio-controls .btn label {
display: none;
}
}
.audio-controls .btn.btn-play {
flex: 50% 1 0;
}
.volume-controls {
display: flex;
}
.volume-controls .volume-slider {
flex: 100% 1 1;
}
.audio-controls .btn,
.volume-controls .btn-toggle-mute {
flex: 100px 1 1;
padding: 10px 0 10px 0;
background: #5ba8f4;
border-radius: 5px;
border-color: solid 1px #0f259d;
color: white;
font-family: Nunito, serif;
text-align: center;
text-decoration: none;
}
}

View File

@@ -124,7 +124,7 @@
margin: 8px auto;
}
&:last-child {
&.search {
border: none;
line-height: 1;
}

View File

@@ -12,3 +12,9 @@
float: left;
margin: 10px 20px 0 0;
}
.podcast-player .content {
border: solid 1px #333;
border-radius: 5px;
padding: 0.4rem;
}

View File

@@ -1,6 +1,20 @@
@use "../abstracts/mixin" as *;
@use "../abstracts/variables" as *;
%sentence {
font-size: 12px;
font-style: italic;
line-height: 1.3;
text-align: right;
color: $text-description-color;
display: block;
width: 100%;
span {
padding: 0 5px;
}
}
.post_container {
@include container;
@media (min-width: 768px) {
@@ -30,17 +44,15 @@
}
.sentence {
font-size: 12px;
font-style: italic;
line-height: 1.3;
text-align: right;
color: $text-description-color;
display: block;
width: 100%;
@extend %sentence
}
span {
padding: 0 5px;
}
@at-root .box.featured .sentence {
@extend %sentence
}
div.text {
margin-bottom: 20px;
}
blockquote {
@@ -106,6 +118,22 @@
}
}
}
%post-tags-link {
display: block;
width: 4rem;
padding: 6px 15px 7px;
border-radius: 3px;
background-image: linear-gradient(to left, #0d1ca3, #45aaf8);
font-family: Nunito, serif;
font-size: 10px;
font-weight: bold;
text-align: center;
color: $text-inverted-color;
text-decoration: none;
text-transform: uppercase;
}
.post_tags {
@include reset-list;
height: 31px;
@@ -116,17 +144,11 @@
margin-right: 10px;
a {
display: block;
padding: 6px 15px 7px;
border-radius: 3px;
background-image: linear-gradient(to left, #0d1ca3, #45aaf8);
font-family: Nunito, serif;
font-size: 10px;
font-weight: bold;
text-align: center;
color: $text-inverted-color;
text-decoration: none;
text-transform: uppercase;
@extend %post-tags-link
}
@at-root #schedule .onair {
@extend %post-tags-link
}
}
}

View File

@@ -1,6 +1,14 @@
@use "../abstracts/mixin" as *;
@use "../abstracts/variables" as *;
@keyframes tilt-shaking {
0% { transform: rotate(0deg); }
25% { transform: rotate(5deg); }
50% { transform: rotate(0deg); }
75% { transform: rotate(-5deg); }
100% { transform: rotate(0deg); }
}
#schedule {
a {
text-decoration: none;
@@ -32,4 +40,8 @@
margin-right: 10px;
}
}
.onair {
animation: tilt-shaking 1s linear infinite;
}
}

View File

@@ -6,3 +6,14 @@
@use "../components/contact_box";
@use "../components/featured";
@use "../components/podcast_items";
@media (max-width: 576px) {
ins[data-revive-zoneid] img {
max-width: 100%;
height: auto;
}
}
.homepage-body-banners {
margin-top: -4rem;
}

View File

@@ -1 +1,2 @@
@use "../components/podcast_item";
@use "../components/media";

View File

@@ -104,7 +104,7 @@
@include('partial/nh_story', ['content' => $event->content]);
@else
<div class="text">
<p>{!!$event->content!!}</p>
{!!$event->content!!}
</div>
@endif

View File

@@ -41,7 +41,7 @@
@php($count = 0)
@foreach($events as $event)
@php($count++)
<?php $url = route('agenda.details', ['id' => $event->id, 'title' => $event->title]); ?>
<?php $url = $event->url; ?>
<div class="box featured">
<div class="row">
<div class="col-12 col-md-6">
@@ -52,15 +52,19 @@
<div class="col-12 col-md-6">
<h2 class="post_title"><a href="{{$url}}" title="{{$event->title}}">{!!$event->title!!}</a></h2>
<div class="sub_title" style="flex-wrap: wrap">
<ul class="post_tags" style="width: 100%; margin: 0 0 8px 0;height: 25px;">
@foreach($event->tags as $tag)
<li><a style="padding: 3px 8px 3px" title="{{$tag->title}}">{{$tag->title}}</a></li>
<ul class="post_tags" style="width: 100%; margin: 0 0 8px 0;height: 25px;">
@foreach($event->tags as $tag)
<li><a style="padding: 3px 8px 3px" title="{{$tag->title}}">{{$tag->title}}</a></li>
@endforeach
</ul>
<span class="post_date" style="line-height: 1.17; height: 14px;" title="{{Formatter::relativeDate($event->starts, 'W d m y?')}}">
<i class="fa-regular fa-clock"></i> {{Formatter::relativeDate($event->starts, 'W d m y?')}}
@if($event->ends && $event->starts != $event->ends)
t/m {{strtolower(Formatter::relativeDate($event->ends, 'W d m y?'))}}
@if($event->ends->format('d M y') != $event->starts->format('d M y'))
t/m {{strtolower(Formatter::relativeDate($event->ends, 'W d m y?'))}}
@else
van {{ $event->starts->format('H:i') }} uur tot {{ $event->ends->format('H:i') }} uur
@endif
@endif
</span>
</div>

View File

@@ -61,16 +61,9 @@ voor talent.</p>
KvK: 41194132<br>
<br>
<b>Streekredactie</b><br>
Gooise Brink, Kerkstraat 63/27<br>
11211 CL Hilversum<br>
Tiplijn: <a href="tel:+31642913637">06 - 42 91 36 37</a><br>
e-mail: {{Html::mailto('info@NHGooi.nl')}}<br>
<br>
<b>Chef redactie</b><br>
Petra de Beij<br>
{{Html::mailto('petra.debeij@nhgooi.nl')}}<br><br>
Erwin Bakker<br>
{{Html::mailto('erwin.bakker@nhgooi.nl')}}<br><br>
</p>
</div>
</div>

View File

@@ -48,19 +48,19 @@
</div>
</div>
@endif
@if($item = next($news))
<div class="post large d-block d-md-none">
<a href="{{url($item->url)}}" title="{{$item->title}}">
@if($item->video)
<span class="icon video"></span>
@elseif($item->images && count($item->images) > 1)
<span class="icon gallery"></span>
@endif
<img src='{{$item->images && count($item->images) ? $imgBase . $item->images[0]->url : '/images/noimage.png'}}'
alt='img'>
</a>
<div class="slider_content_box">
<ul class="post_details simple">
@if($item = next($news))
<div class="post large d-block d-md-none">
<a href="{{url($item->url)}}" title="{{$item->title}}">
@if($item->video)
<span class="icon video"></span>
@elseif($item->images && count($item->images) > 1)
<span class="icon gallery"></span>
@endif
<img src='{{$item->images && count($item->images) ? $imgBase . $item->images[0]->url : '/images/noimage.png'}}'
alt='img'>
</a>
<div class="slider_content_box">
<ul class="post_details simple">
@foreach($item->tags as $tag)
<li class="category">
<a title="{{$tag->titel}}"
@@ -68,23 +68,23 @@
class="over_image">{{$tag->titel}}</a>
</li>
@endforeach
</ul>
<h2><a href="{{url($item->url)}}"
title="{{$item->title}}">{!!$item->title!!}</a></h2>
<?php
$time = Formatter::relativeDate($item->published) . ' om ' . $item->published->format('H:i');
if ($item->edited && ($item->edited->format('d m H i') != $item->published->format('d m H i'))) {
$time .= ' | bijgewerkt: '
. ($item->edited->format('d m') != $item->published->format('d m') ? strtolower(Formatter::relativeDate($item->edited)) : '')
. ' ' . $item->edited->format('H:i') . ' uur';
}
?>
<span class="post_date" title="{{$time}}">
</ul>
<h2><a href="{{url($item->url)}}"
title="{{$item->title}}">{!!$item->title!!}</a></h2>
<?php
$time = Formatter::relativeDate($item->published) . ' om ' . $item->published->format('H:i');
if ($item->edited && ($item->edited->format('d m H i') != $item->published->format('d m H i'))) {
$time .= ' | bijgewerkt: '
. ($item->edited->format('d m') != $item->published->format('d m') ? strtolower(Formatter::relativeDate($item->edited)) : '')
. ' ' . $item->edited->format('H:i') . ' uur';
}
?>
<span class="post_date" title="{{$time}}">
<i class="fa-regular fa-clock"></i> {{$time}}
</span>
</div>
</div>
@endif
</div>
@endif
</div>
<div class="col-8 col-md-6">
<div class="row">
@@ -102,16 +102,16 @@
</a>
<div class="slider_content_box">
<ul class="post_details simple">
@foreach($item->tags as $tag)
<li class="category">
<a title="{{$tag->titel}}"
href="{{route('nieuws.tag', ['tag' => $tag->slug])}}"
class="over_image">{{$tag->titel}}</a>
</li>
@endforeach
@foreach($item->tags as $tag)
<li class="category">
<a title="{{$tag->titel}}"
href="{{route('nieuws.tag', ['tag' => $tag->slug])}}"
class="over_image">{{$tag->titel}}</a>
</li>
@endforeach
</ul>
<h5 class="post_title"><a href="{{url($item->url)}}"
title="{{$item->title}}">{!!$item->title!!}</a></h5>
title="{{$item->title}}">{!!$item->title!!}</a></h5>
<?php
$time = Formatter::relativeDate($item->published) . ' om ' . $item->published->format('H:i');
if ($item->edited && ($item->edited->format('d m H i') != $item->published->format('d m H i'))) {
@@ -136,13 +136,10 @@
<div class="grey_background">
<div class="body_container row">
@if(!isset($disableBanners) || !$disableBanners)
<div class="col-12">
<div class="d-none d-md-block" style="width: 100%; font-family: Nunito,serif;font-size: 12px;font-weight: 500;line-height: 3.17;text-align: center;color: #666;">
- Advertentie -
<div class="homepage-body-banners d-none d-md-flex justify-content-center mb-4">
<ins data-revive-zoneid="3" data-revive-id="{{ env('REVIVE_ID') }}"></ins>
<ins data-revive-zoneid="4" data-revive-id="{{ env('REVIVE_ID') }}"></ins>
</div>
<div id="nhgooi_homepage_top" class="d-none d-md-block" style="width: 728px; height: 90px;margin: 11px auto 50px auto;background-color: #efefef;"></div>
<script type="text/javascript">ootag.queue.push(function () {ootag.defineSlot({adSlot: "nhgooi_homepage_top",targetId: "nhgooi_homepage_top",adShownCallback: (adslot) => { calculateSize(adslot.targetId); }});});</script>
</div>
@endif
<div class="col-12 col-md content_container">
<div class="row">
@@ -175,30 +172,32 @@
<div class="row">
<div class="col-12 col-md-6">
<a href="{{$url}}" title="{{$podcast->title}}">
<img src="{{($hasImage = $podcast->image && $podcast->image->url) ? $imgBase . $podcast->image->url : '/images/noimage.png'}}"/>
<div class="sentence">
<?php
$sentence = [];
if ($hasImage) {
$sentence[] = '<span class="text">' . $podcast->image->title . '</span>';
} elseif (isset($podcast->image->title) && $podcast->image->title) {
$sentence[] = '<span class="text">' . $podcast->image->title . '</span>';
}
if (isset($podcast->image->author) && $podcast->image->author) {
$sentence[] = '<span class="author">' . $podcast->image->author . '</span>';
}
$sentence = join('<span class="separator">|</span>', $sentence);
?>
{!!$sentence!!}
</div>
<img src="{{($hasImage = $podcast->image && $podcast->image->url) ? $imgBase . $podcast->image->url : '/images/noimage.png'}}"/>
<div class="sentence">
<?php
$sentence = [];
if ($hasImage) {
$sentence[] = '<span class="text">' . $podcast->image->title . '</span>';
} elseif (isset($podcast->image->title) && $podcast->image->title) {
$sentence[] = '<span class="text">' . $podcast->image->title . '</span>';
}
if (isset($podcast->image->author) && $podcast->image->author) {
$sentence[] = '<span class="author">' . $podcast->image->author . '</span>';
}
$sentence = join('<span class="separator">|</span>', $sentence);
?>
{!!$sentence!!}
</div>
</a>
</div>
<div class="col-12 col-md-6">
<h2 class="post_title"><a href="{{$url}}" title="{{$podcast->title}}">{!!$podcast->title!!}</a></h2>
<h2 class="post_title"><a href="{{$url}}"
title="{{$podcast->title}}">{!!$podcast->title!!}</a></h2>
<div class="sub_title">
@if ($podcast->program)
<a class="program_name" href="{{ route('programma') . $podcast->program->url }}"
<a class="program_name"
href="{{ route('programma') . $podcast->program->url }}"
title="{{$podcast->program->name}}">{{$podcast->program->name}}</a>
@endif
<span class="post_date" title="{{Formatter::relativeDate($podcast->created)}}">
@@ -217,11 +216,9 @@
<div class="col-12 col-md-auto sidebar">
@include('widgets/nhgooiradiotv', ['headerClass' => 'small'])
@include('widgets/add_sidebar', ['ad_sidebar' => 'nhgooi_homepage_side', 'ad_sidebarId' => 'nhgooi_sidebar1'])
@include('widgets.banner_sidebar')
@include('widgets/contact', [])
@include('widgets/add_sidebar', ['ad_sidebar' => 'nhgooi_homepage_side2', 'ad_sidebarId' => 'nhgooi_sidebar2'])
</div>
</div>
</div>

View File

@@ -2,7 +2,7 @@
<script type="text/javascript" src="//www.cookieconsent.com/releases/3.1.0/cookie-consent.js"></script>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {
cookieconsent.run({"notice_banner_type":"simple","consent_type":"express","palette":"light","language":"nl","website_name":"NH Gooi","cookies_policy_url":"https://www.nhnieuws.nl/privacyverklaring","change_preferences_selector":"#changePreferences"});
cookieconsent.run({"notice_banner_type":"simple","consent_type":"express","palette":"light","language":"nl","website_name":"NH Gooi","cookies_policy_url":"/privacy-verklaring","change_preferences_selector":"#changePreferences"});
});
</script>
@@ -13,9 +13,7 @@ cookieconsent.run({"notice_banner_type":"simple","consent_type":"express","palet
<!-- End Google Tag Manager -->
@if(!isset($disableBanners) || !$disableBanners)
<script type="text/javascript" src="https://cdn.optoutadvertising.com/script/ootag.v2.js"></script><script>var ootag =
ootag || {}; ootag.queue = ootag.queue || [];ootag.queue.push(function () { ootag.initializeOo({
publisher: 4, onlyNoConsent: 1, consentTimeOutMS: 500 });});</script>
<script async src="{{ env('ADS_URL') }}www/delivery/asyncjs.php"></script>
@endif
<noscript>ePrivacy and GPDR Cookie Consent by <a href="https://www.CookieConsent.com/" rel="nofollow noopener">Cookie Consent</a></noscript>

View File

@@ -22,8 +22,7 @@
</div>
@if(!isset($disableBanners) || !$disableBanners)
<div id="nhgooi_header_top" class="advertisement" style="margin: 11px auto 0 auto;background-color: #efefef;"></div>
<script type="text/javascript">ootag.queue.push(function () {ootag.defineSlot({adSlot: "nhgooi_homepage_header",targetId: "nhgooi_header_top",filledCallback: (adslot) => { calculateSize(adslot.targetId); }});});</script>
<ins data-revive-zoneid="1" data-revive-id="{{ env('REVIVE_ID') }}"></ins>
@endif
</div>
@@ -89,6 +88,12 @@
@include('widgets.menu')
</div>
@if(!isset($disableBanners) || !$disableBanners)
<div class="mobile-banner-fullwidth d-flex d-md-none justify-content-center mt-4">
<ins data-revive-zoneid="6" data-revive-id="{{ env('REVIVE_ID') }}"></ins>
</div>
@endif
<!-- Content -->
<div class="page @yield('page_container_class')">
@@ -101,10 +106,10 @@
<div class="footer_menu">
<div class="row">
<div class="col-12 col-md-3">
<h4 class="box_header"><span>NH Gooi</span></h4>
<h4 class="box_header"><span>NHGooi</span></h4>
<p class="about">
NH Gooi is de streekomroep voor Gooi &amp; Vechtstreek. Wij brengen nieuws en achtergronden
op onze website, radio en televisie. Daarnaast brengen we boeiende en belangrijke podcasts
NHGooi is de streekomroep voor Gooi &amp; Vechtstreek. Wij brengen nieuws en achtergronden
op onze website, radio en televisie. Daarnaast brengen we boeiende en belangrijke podcasts
en een gevari&euml;erd programma-aanbod op al onze media-kanalen.
</p>
</div>
@@ -159,7 +164,7 @@
</div>
</div>
<div class="copyright">
© NH Gooi
© NHGooi
<a class="scroll_top" href="#top" title="Scroll to top"><i class="fa-solid fa-angle-up"></i></a>
</div>
</div>
@@ -186,6 +191,7 @@
<script type="text/javascript" src="/js/jquery.prettyPhoto.js"></script>
<script type="text/javascript" src="/js/jquery.carouFredSel-6.2.1.min.js"></script>
<script type="text/javascript" src="/js/functions.js"></script>
<script type="text/javascript" src="/js/wavesurfer.min.js"></script>
<script type="text/javascript">
$(window).resize(function () {
// Fix sticky for mobile menu indicator
@@ -202,7 +208,7 @@
function openPlayerInNewScreen() {
$(".player").click(function (e) {
e.preventDefault();
window.open($(this).attr('href'), '_player', 'width=550,height=500,titlebar,close');
window.open($(this).attr('href'), '_player', 'width=550,height=600,titlebar,close');
return false;
});
}

View File

@@ -1,6 +1,7 @@
@extends('layouts/master')
@section('content_class')box
@section('content_class')
box
@endsection
@section('page')
@@ -57,13 +58,11 @@
</div>
@endif
@include('widgets/add_sidebar', ['ad_sidebar' => $ad_sidebar1 ?? 'nhgooi_section_side', 'ad_sidebarId' => 'nhgooi_sidebar1'])
@include('widgets/nhgooiradiotv', ['headerClass' => 'small'])
@include('widgets/contact', [])
@include('widgets.banner_sidebar')
@include('widgets/add_sidebar', ['ad_sidebar' => $ad_sidebar2 ?? 'nhgooi_section_side2', 'ad_sidebarId' => 'nhgooi_sidebar2'])
@include('widgets/contact', [])
@show
</div>
</div>

View File

@@ -4,8 +4,8 @@
<a href="javascript:window.close();" class="close btn"><span class='fa fa-times fa-fw'></span> Venster sluiten</a>
<p class="logo"><a href="{{ url('/') }}"><img src="{{ url( 'images/logo-NHGooi.svg' )}}"></a></p>
@if(false && $isStream)
<p>Wegens een technisch probleem is NH Gooi momenteel niet via Internet te beluisteren. Onze excuses voor het
@if(isset($notAvailable) && $notAvailable)
<p>Helaas is de door u gekozen audio momenteel niet via Internet te beluisteren. Onze excuses voor het
ongemak.</p>
<p>In Hilversum, Huizen en de BEL-gemeenten zijn wij te ontvangen op 92.0 FM of 105.1 FM.</p>
@else
@@ -36,9 +36,16 @@
</p>
@endif
<p>
<audio controls autoplay="true">
{{-- <audio controls autoplay="true">
<source src="{{$source}}" type="audio/mp3"/>
</audio>
</audio> --}}
@include('widgets.audioplayer', [
'source' => $source,
'isStream' => $isStream,
'lengte' => $lengte,
'waveform' => $waveform
])
</p>
<p>
@@ -130,6 +137,7 @@
@push('scripts')
<script type="text/javascript" src="/js/jquery-3.7.1.min.js"></script>
<script type="text/javascript" src="/js/wavesurfer.min.js"></script>
<script>
function updateOnAir() {
$.ajax({
@@ -163,4 +171,3 @@
</script>
@endpush
@include('widgets.mediaplayer')

View File

@@ -14,13 +14,9 @@
<div class="grey_background">
<div class="body_container row">
@if(!isset($disableBanners) || !$disableBanners)
<div class="col-12">
<div style="width: 100%; font-family: Nunito,serif;font-size: 12px;font-weight: 500;line-height: 3.17;text-align: center;color: #666;">
- Advertentie -
<div class="col-12">
<ins data-revive-zoneid="5" data-revive-id="{{ env('REVIVE_ID') }}"></ins>
</div>
<div id="nhgooi_article_top" style="width: 728px; height: 90px;margin: 11px auto 50px auto;background-color: #efefef;"></div>
<script type="text/javascript">ootag.queue.push(function () {ootag.defineSlot({adSlot: "nhgooi_article_top",targetId: "nhgooi_article_top",filledCallback: (adslot) => { calculateSize(adslot.targetId); }});});</script>
</div>
@endif
<div class="col-12 col-md content_container">
<div class="row">
@@ -45,9 +41,9 @@
<div class="col-12 col-md-auto sidebar">
@include('widgets/nhgooiradiotv', ['headerClass' => 'small'])
@include('widgets/contact', [])
@include('widgets.banner_sidebar')
@include('widgets/add_sidebar', ['ad_sidebar' => 'nhgooi_article_side' ?? false, 'ad_sidebarId' => 'nhgooi_sidebar1'])
@include('widgets/contact', [])
<div class="podcast_items">
<h4 class="box_header small"><span>Fragment gemist</span></h4>
@@ -55,8 +51,6 @@
@include('partial/podcastitems', ['showTime' => false, 'showImage' => false, 'podcasts' => $podcasts, 'isPodcast' => false])
</div>
</div>
@include('widgets/add_sidebar', ['ad_sidebar' => 'nhgooi_article_side2' ?? false, 'ad_sidebarId' => 'nhgooi_sidebar2'])
</div>
</div>
</div>

View File

@@ -87,8 +87,10 @@
@endif
@endif
@if(is_array($news->content))
@include('partial/nh_story', ['content' => $news->content])
@if($type == "nhnieuws")
@include('partial/nh_story', ['content' => $news->content])
@elseif($type == "artikel")
@include('partial/block_story', ['content' => $news->content])
@else
<div class="text">
<p>{!!$news->content!!}</p>

View File

@@ -0,0 +1,161 @@
@foreach($content as $block)
@if($block->type == "headerRichA")
@php($block->data->image->url = isset($block->data->image->crops)
? $block->data->image->crops->{'16:9'}->{'1600'}
: $block->data->image->crop)
<a href="{{$block->data->image->url}}" class="post_image page_margin_top prettyPhoto" rel="prettyPhoto"
title="{{$block->data->image->title}}">
<img src="{{$block->data->image->url}}" alt="{{$block->data->image->title}}">
</a>
<div class="sentence margin_top_10">
<span class="text">{{$block->data->image->title}}</span>
@if($block->data->image->author)
<span class="author">{{$block->data->image->author}}</span>
@endif
</div>
@elseif($block->type == "paragraph")
<div class="text">{!!$block->data->text!!}</div>
@elseif($block->type == "intro")
<h3 class="excerpt">{!!strip_tags($block->data->text)!!}</h3>
@elseif($block->type == "info")
@if(strpos($block->data->text, "Meer nieuws uit 't Gooi?") === false)
<div class="info" style="background-color: {{$block->data->color}};">{!!($block->data->text)!!}</div>
@endif
@elseif($block->type == "quote")
<blockquote>
{!!$block->data->text!!}
<div class="author">{{$block->data->caption}}</div>
</blockquote>
@elseif($block->type == "image")
<?php
if(isset($block->data->image->imageWide))
$image = $block->data->image->imageWide;
else if(isset($block->data->image->crop))
$image = $block->data->image->crop;
else if(isset($block->data->image->crops) && isset($block->data->image->crops->{'16:9'}))
foreach($block->data->image->crops->{'16:9'} as $image) break;
else if(isset($block->data->image->imageHigh))
$image = $block->data->image->imageHigh;
else $image = null;
?>
@if($image)
<a class="post_image page_margin_top prettyPhoto" rel="prettyPhoto" href="{{$image}}"
title="{{$block->data->image->title}} &copy; {{$block->data->image->author}}">
<img src="{{$image}}" class="attachment-small-slider-thumb size-small-slider-thumb wp-post-image"
alt="{{$block->data->image->title}}" title="" style="display: block;">
</a>
<div class="sentence">
<?php
$sentence = [];
if (isset($block->data->image->caption) && $block->data->image->caption) {
$sentence[] = '<span class="text">' . $block->data->image->caption . '</span>';
} elseif (isset($block->data->image->title) && $block->data->image->title) {
$sentence[] = '<span class="text">' . $block->data->image->title . '</span>';
}
if (isset($block->data->image->author) && $block->data->image->author) {
$sentence[] = '<span class="author">' . $block->data->image->author . '</span>';
}
$sentence = join('<span class="separator">|</span>', $sentence);
?>
{!!$sentence!!}
</div>
@endif
@elseif($block->type == "video" || $block->type == "headerVideo")
@include('widgets/mediaplayer')
<?php
$attr = '';
if (isset($block->data->video->images[0]->imageMedia) && $block->data->video->images[0]->imageMedia) {
$attr = ' poster="' . $block->data->video->images[0]->imageMedia . '"';
}
?>
<video controls{!!$attr!!}>
@foreach($block->data->video->streams as $stream)
<source src="{!!$stream->stream_url!!}" type="application/x-mpegurl" />
@endforeach
</video>
<div class="sentence">
<span class="author">{{$block->data->video->author}}</span>
</div>
@elseif($block->type == "carousel")
<div class="horizontal_carousel_container gallery">
<ul class="horizontal_carousel visible-5 autoplay-1 scroll-1 navigation-1 easing-easeInOutQuint duration-750">
@foreach($block->data->items as $image)
<?php
if(isset($image->image->imageWide))
$img = $image->image->imageWide;
else if(isset($block->data->image->crop))
$image = $block->data->image->crop;
else if(isset($image->image->crops) && isset($image->image->crops->{'16:9'}))
foreach($image->image->crops->{'16:9'} as $img) break;
else if(isset($image->image->imageHigh))
$img = $image->image->imageHigh;
else $img = null;
?>
@if($img)
<li>
<a href="{{$img}}" class="post_image prettyPhoto" rel="prettyPhoto[gallery]"
title="{{$image->image->title}} &copy; {{$image->image->author}}">
<img src="{{$img}}" alt="{{$image->image->title}}" title="{{$image->image->title}}">
</a>
</li>
@endif
@endforeach
</ul>
</div>
@elseif($block->type == "oembed")
<div class="oembed" data-url="{{$block->data->url}}">{!!$block->data->html!!}</div>
@elseif($block->type == "podcast" && $block->data->id == $news->podcast?->id)
@include('widgets/podcastplayer', ['podcast' => $news->podcast])
<? $news->podcast = null; // Avoid adding the player again ?>
@elseif($block->type == 'article' && count($block->data->articles) && $block->data->articles[0]->published)
<div class="block">
<h4 class="box_header"><span>{{ $block->data->title }}</span></h4>
<div class="box full-width">
<ul id="items-more-news" class="blog">
@foreach($block->data->articles as $article)
<? if(!isset($article->published)) continue;
$article->published = new \DateTime($article->published); ?>
<li class="post">
<div class="row">
@if($article->image)
<div class="col-4">
<a href="{{ route('nieuws.detail', ['id' => $article->id, 'title' => $article->slug]) }}"
title="{{ $article->title }}">
<img src="{{ $article->image[0] == '/' ? '' : '/' }}{{ $article->image }}" alt="{{ $article->image_title }}">
</a>
</div>
@endif
<div class="col-8">
<h2 class="post_title"><a class="clipText clipText-3"
href="{{ route('nieuws.detail', ['id' => $article->id, 'title' => $article->slug]) }}"
title="{!! $article->title !!}">{!! $article->title !!}</a></h2>
<span class="post_date" title="Vandaag om 09:30">
<i class="fa-regular fa-clock"></i>
{{Formatter::relativeDate($article->published)}} om {{$article->published->format('H:i')}}
</span>
</div>
</div>
</li>
@endforeach
</ul>
</div>
</div>
@elseif($block->type == 'iframe')
<iframe src="{{ $block->data->url }}" class="article-iframe" id="{{ $id = uniqid('iframe_') }}"></iframe>
<style>
@if(isset($block->data->ratio))
#{{ $id }}.article-iframe {
aspect-ratio: {{ str_replace(":", "/", $block->data->ratio) }};
}
@endif
@if(isset($block->data->ratioMobile))
@media (max-width: 768px) {
#{{ $id }}.article-iframe {
aspect-ratio: {{ str_replace(":", "/", $block->data->ratioMobile) }};
}
}
@endif
</style>
@endif
@endforeach

View File

@@ -121,7 +121,7 @@
<div class="col-4">
<a href="{{ route('nieuws.detail', ['id' => $article->id, 'title' => $article->slug]) }}"
title="{{ $article->title }}">
<img src="{{ $article->image }}" alt="{{ $article->image_title }}">
<img src="{{ $article->image[0] == '/' ? '' : '/' }}{{ $article->image }}" alt="{{ $article->image_title }}">
</a>
</div>
@endif
@@ -140,5 +140,22 @@
</ul>
</div>
</div>
@elseif($block->type == 'iframe')
<iframe src="{{ $block->url }}" class="article-iframe" id="{{ $id = uniqid('iframe_') }}"></iframe>
<style>
@if(isset($block->ratio))
#{{ $id }}.article-iframe {
aspect-ratio: {{ str_replace(":", "/", $block->ratio) }};
}
@endif
@endforeach
@if(isset($block->ratioMobile))
@media (max-width: 768px) {
#{{ $id }}.article-iframe {
aspect-ratio: {{ str_replace(":", "/", $block->ratioMobile) }};
}
}
@endif
</style>
@endif
@endforeach

View File

@@ -3,13 +3,13 @@
@include('widgets/mediaplayer')
@section('title')
@if($podcast)
{{ $podcast->title }}
@elseif($isPodcast)
NH Gooi Podcast
@else
Fragment gemist
@endif
@if($podcast)
{{ $podcast->title }}
@elseif($isPodcast)
NH Gooi Podcast
@else
Fragment gemist
@endif
@endsection
@section('page_class')
@@ -20,11 +20,11 @@
<ul class="bread_crumb">
<li><a title="Home" href="/">Home</a></li>
<li class="separator"><i class="fa-solid fa-chevron-right"></i></li>
@if($isPodcast)
<li>NH Gooi podcast</li>
@else
<li><a title="Home" href="/gemist/fragment">Fragment gemist</a></li>
@endif
@if($isPodcast)
<li>NH Gooi podcast</li>
@else
<li><a title="Home" href="/gemist/fragment">Fragment gemist</a></li>
@endif
<li class="separator"><i class="fa-solid fa-chevron-right"></i></li>
@if($podcast && $podcast->program)
<li><a title="{{$podcast->program->name}}"
@@ -112,14 +112,19 @@
</ul>
<div class="announcement">
<audio controls>
<source src="{{$streamUrl}}" type="audio/mpeg"/>
</audio>
@include("widgets.audioplayer", [
'isStream' => false,
'source' => $streamUrl,
'lengte' => $podcast->duration / 1000,
'waveform' => $podcast->waveform
])
<div class="clearfix">
<a class="action_button btn" href="{{$audioUrl}}" title="Download dit fragment als MP3">
<a class="action_button btn" href="{{$audioUrl}}"
title="Download dit fragment als MP3">
<span>Download fragment</span>
</a>
<a class="action_button btn player" href="{{$popoutUrl}}">
<a class="action_button btn player" href="{{$popoutUrl}}" onclick="pause()">
<span>Luister in nieuw venster</span>
</a>
</div>
@@ -156,7 +161,8 @@
<div data-tabs>
<div class="tabs">
<h4 data-tab-content-id="tab_more_fragmenten"
class="box_header small flex-grow-1 active"><span>Meer {{$isPodcast ? 'afleveringen' : 'fragmenten'}}</span>
class="box_header small flex-grow-1 active">
<span>Meer {{$isPodcast ? 'afleveringen' : 'fragmenten'}}</span>
</h4>
</div>
<div id="tab_more_fragmenten" class="box tab_content podcast_items active">
@@ -170,8 +176,8 @@
</div>
@endif
@include('widgets/add_sidebar', ['ad_sidebar' => $ad_sidebar1 ?? 'nhgooi_section_side', 'ad_sidebarId' => 'nhgooi_sidebar1'])
@include('widgets.banner_sidebar')
</div>
</div>
</div>
@endif
@endsection

View File

@@ -54,13 +54,14 @@
</p>
@else
<p class="page_body">Hele uitzendingen kunt u binnen twee weken terugluisteren via <a
href="{{route('gemist.programma')}}">programma gemist</a>.<br /><br />
href="{{route('gemist.programma')}}">programma gemist</a>.<br/><br/>
@endif
@if(isset($podcasts))
<div class="clearfix podcast_items">
@include('partial/podcastitems', [
'id' => null,
'li' => [
'class' => 'col-12 col-md-6'
],
@@ -109,7 +110,7 @@
</div>
@endif
@include('widgets/add_sidebar', ['ad_sidebar' => $ad_sidebar1 ?? 'nhgooi_section_side', 'ad_sidebarId' => 'nhgooi_sidebar1'])
@include('widgets.banner_sidebar')
</div>
</div>
</div>

View File

@@ -1,11 +1,11 @@
@extends('layouts/full')
@section('title')
@if(isset($program))
{{ $program->name }}
@else
NH Gooi Podcast
@endif
@if(isset($program))
{{ $program->name }}
@else
NH Gooi Podcast
@endif
@endsection
@section('page_class')
@@ -40,18 +40,18 @@
</div>
</div>
@endif
@if($podcasts)
@if($podcasts)
<div class="page_layout clearfix">
<div class="grid" id="items">
@include('partial/podcastdirectitems', ['podcasts' => array_slice($podcasts, 0, 2), 'isPodcast' => $isPodcast])
</div><!--/.row-->
</div>
@else
<div class="box full-width">
<p class="page_body">Er zijn geen items beschikbaar.</p>
</div>
@endif
<div class="page_layout clearfix">
<div class="grid" id="items">
@include('partial/podcastdirectitems', ['podcasts' => array_slice($podcasts, 0, 2), 'isPodcast' => $isPodcast])
</div><!--/.row-->
</div>
@else
<div class="box full-width">
<p class="page_body">Er zijn geen items beschikbaar.</p>
</div>
@endif
</div>
<div class="col-12 col-md-auto sidebar">
@@ -73,7 +73,7 @@
</div>
@endif
@include('widgets/add_sidebar', ['ad_sidebar' => $ad_sidebar1 ?? 'nhgooi_section_side', 'ad_sidebarId' => 'nhgooi_sidebar1'])
@include('widgets.banner_sidebar')
</div>
</div>
</div>

View File

@@ -1,10 +1,12 @@
@extends('layouts/full')
@section('title')
Programma gemist
Programma gemist
@endsection
@section('page_class')news_post post_container @endsection
@section('page_class')
news_post post_container
@endsection
@section('breadcrumb')
@if(isset($program))
@@ -51,7 +53,8 @@
class="btn btn-info">Programmainfo</a>
</p>
@else
<p class="page_body">U kunt programma's terugluisteren tot twee weken na uitzending. Items blijven onbeperkt beschikbaar via <a href="{{route('gemist.fragment')}}">fragment gemist</a>.<br /><br />
<p class="page_body">U kunt programma's terugluisteren tot twee weken na uitzending. Items blijven
onbeperkt beschikbaar via <a href="{{route('gemist.fragment')}}">fragment gemist</a>.<br/><br/>
@endif
@if(isset($programs))
@@ -106,20 +109,31 @@
</div>
@endif
@include('widgets/add_sidebar', ['ad_sidebar' => $ad_sidebar1 ?? 'nhgooi_section_side', 'ad_sidebarId' => 'nhgooi_sidebar1'])
@include('widgets.banner_sidebar')
</div>
</div>
</div>
<style>
@keyframes tilt-shaking {
0% { transform: rotate(0deg); }
25% { transform: rotate(5deg); }
50% { transform: rotate(0deg); }
75% { transform: rotate(-5deg); }
100% { transform: rotate(0deg); }
}
.post_container .post_tags li a {
animation: tilt-shaking 1s linear infinite;
}
</style>
<style>
@keyframes tilt-shaking {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(5deg);
}
50% {
transform: rotate(0deg);
}
75% {
transform: rotate(-5deg);
}
100% {
transform: rotate(0deg);
}
}
.post_container .post_tags li a {
animation: tilt-shaking 1s linear infinite;
}
</style>
@endsection

View File

@@ -1,7 +0,0 @@
@if ($ad_sidebar && (!isset($disableBanners) || !$disableBanners))
<div style="width: 100%; font-family: Nunito,serif;font-size: 12px;font-weight: 500;line-height: 3.17;text-align: center;color: #666;">
- Advertentie -
</div>
<div id="{{$ad_sidebarId}}" style="width: 100%;height: 275px;margin: 11px auto 50px auto;background-color: #efefef;"></div>
<script type="text/javascript">ootag.queue.push(function () {ootag.defineSlot({adSlot: "{{$ad_sidebar}}",targetId: "{{$ad_sidebarId}}",adShownCallback: (adslot) => { calculateSize(adslot.targetId); }});});</script>
@endif

View File

@@ -0,0 +1,176 @@
<?php $id = uniqid('player_'); ?>
<div class="audioplayer" id="{{ $id }}">
@if(!$isStream)
<div class="waveform">
<div class="time">0:00</div>
<div class="duration">0:00</div>
<div class="hover"></div>
</div>
@endif
<div class="volume-controls">
<button class="btn-toggle-mute" type="button" onclick="toggleMute()">
<span class="fa fa-volume-high"></span>
</button>
<input class="volume-slider" type="range" min="0" max="1" step="0.01" value="1"
onchange="setVolume( this.value )" />
</div>
<div class="audio-controls">
@if(!$isStream)
<button class="btn btn-jump" type="button" onclick="wavesurfer_{{ $id }}.skip(-60)">
<span class="fa fa-backward-fast"></span>
<label>-60 s</label>
</button>
<button class="btn btn-jump" type="button" onclick="wavesurfer_{{ $id }}.skip(-10)">
<span class="fa fa-backward-step"></span>
<label>-10 s</label>
</button>
@endif
<button class="btn btn-play" type="button" onclick="playPause()">
<span class="play-button-icon fa fa-play"></span>
<label class="play-button-label">Afspelen</label>
</button>
@if(!$isStream)
<button class="btn btn-jump" type="button" onclick="wavesurfer_{{ $id }}.skip(10)">
<span class="fa fa-forward-step"></span>
<label>+10 s</label>
</button>
<button class="btn btn-jump" type="button" onclick="wavesurfer_{{ $id }}.skip(60)">
<span class="fa fa-forward-fast"></span>
<label>+60 s</label>
</button>
@endif
</div>
</div>
@if($isStream)
<audio id="audio_{{ $id }}">
<source src="{{ $source }}" type="audio/mp3" />
</audio>
<script>
var player_{{ $id }};
setVolume = volume => player_{{ $id }}.volume = volume;
function toggleMute () {
var isMuted = !player_{{ $id }}.muted;
player_{{ $id }}.muted = isMuted;
if(isMuted) {
$('#{{ $id }} .btn-toggle-mute').html('<span class="fa fa-volume-xmark"></span>');
$('#{{ $id }} .volume-slider').attr('disabled', 'disabled');
} else {
$('#{{ $id }} .btn-toggle-mute').html('<span class="fa fa-volume-high"></span>');
$('#{{ $id }} .volume-slider').removeAttr('disabled');
}
}
pause = () => player_{{ $id }}.pause();
function playPause() {
var player = player_{{ $id }};
if (player.paused) {
player.play();
} else {
player.pause();
}
}
addEventListener("DOMContentLoaded", function() {
var player = document.getElementById( "audio_{{ $id }}");
player_{{ $id }} = player;
$(player_{{ $id }}).on('play', () => {
$('#{{ $id }} .play-button-icon').addClass('fa-pause').removeClass('fa-play');
$('#{{ $id }} .play-button-label').text('Pauzeren');
})
$(player_{{ $id }}).on('pause', () => {
$('#{{ $id }} .play-button-icon').addClass('fa-play').removeClass('fa-pause');
$('#{{ $id }} .play-button-label').text('Verder spelen');
});
});
</script>
@else
<script>
var wavesurfer_{{ $id }};
setVolume = volume => wavesurfer_{{ $id }}.setVolume( volume );
playPause = () => wavesurfer_{{ $id }}.playPause();
pause = () => wavesurfer_{{ $id }}.pause();
function toggleMute () {
var isMuted = !wavesurfer_{{ $id }}.getMuted();
wavesurfer_{{ $id }}.setMuted(isMuted);
if(isMuted) {
$('#{{ $id }} .btn-toggle-mute').html('<span class="fa fa-volume-xmark"></span>');
$('#{{ $id }} .volume-slider').attr('disabled', 'disabled');
} else {
$('#{{ $id }} .btn-toggle-mute').html('<span class="fa fa-volume-high"></span>');
$('#{{ $id }} .volume-slider').removeAttr('disabled');
}
}
addEventListener("DOMContentLoaded", function() {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
// Create the waveform
wavesurfer_{{ $id }} = WaveSurfer.create({
container: '#{{ $id }} .waveform',
waveColor: '#3A96EE',
progressColor: '#0118A1',
height: 50,
barWidth: 1,
@if(isset($lengte))
duration: {{ $lengte }},
@endif
@if($waveform)
peaks: {{ json_encode($waveform->data) }},
normalize: true,
@endif
url: '{{ $source }}',
});
// Play/pause on click
wavesurfer_{{ $id }}.on('click', () => {
wavesurfer_{{ $id }}.play();
})
wavesurfer_{{ $id }}.on('play', () => {
$('#{{ $id }} .play-button-icon').addClass('fa-pause').removeClass('fa-play');
$('#{{ $id }} .play-button-label').text('Pauzeren');
})
wavesurfer_{{ $id }}.on('pause', () => {
$('#{{ $id }} .play-button-icon').addClass('fa-play').removeClass('fa-pause');
$('#{{ $id }} .play-button-label').text('Verder spelen');
})
// Hover effect
{
const hover = document.querySelector('#{{ $id }} .hover')
const waveform = document.querySelector('#{{ $id }} .waveform')
waveform.addEventListener('pointermove', (e) => (hover.style.width = `${e.offsetX}px`))
}
// Current time & duration
{
const formatTime = (seconds) => {
const minutes = Math.floor(seconds / 60)
const secondsRemainder = Math.round(seconds) % 60
const paddedSeconds = `0${secondsRemainder}`.slice(-2)
return `${minutes}:${paddedSeconds}`
}
const timeEl = document.querySelector('#{{ $id }} .time')
const durationEl = document.querySelector('#{{ $id }} .duration')
wavesurfer_{{ $id }}.on('decode', (duration) => (durationEl.textContent = formatTime(duration)))
wavesurfer_{{ $id }}.on('timeupdate', (currentTime) => (timeEl.textContent = formatTime(currentTime)))
}
});
</script>
@endif

View File

@@ -0,0 +1,5 @@
@if (!isset($disableBanners) || !$disableBanners)
<div class="d-flex justify-content-center my-4">
<ins data-revive-zoneid="2" data-revive-id="{{ env('REVIVE_ID') }}"></ins>
</div>
@endif

View File

@@ -2,8 +2,7 @@
<img class="logo-whatsapp" src="/images/logo-whatsapp.png"/>
<h2>Contact met de redactie</h2>
<p>Heb jij een tip voor onze streekredactie? Bel of app de tiplijn:
<a href="tel:06 - 42 91 36 37" target="_blank">06 - 42 91 36 37</a>, stuur een
<a href="mailto:info@nhgooi.nl">mail</a> of kom langs op de Gooise Brink,
Kerkstraat 63/27 in Hilversum</p>
<a href="tel:0356424774" target="_blank">035 - 64 24 774</a>, of stuur een
<a href="mailto:info@nhgooi.nl">mail</a>.</p>
<a class="read_more" href="{{url('contact')}}">Contactinformatie <i class="fa-solid fa-angle-right"></i></a>
</div>

View File

@@ -23,6 +23,7 @@
"Podcasts" => array(
"" => "/podcast",
"NH Gooi Spreekuur" => "/podcast/1091/nh-gooi-spreekuur",
"Gooise Mythes Ontrafeld" => "/podcast/1106/gooise-mythes-ontrafeld",
"NH Gooi Wijsneuzen" => "/podcast/1098/nh-gooi-wijsneuzen",
"Hilversum in de oorlog" => "/podcast/1097/hilversum-in-de-oorlog",
),
@@ -145,4 +146,3 @@ function buildMenu($menu, $ismobile)
</ul>
</nav>
</div>

View File

@@ -5,7 +5,7 @@
<h4 data-tab-content-id="tab_gooi_tv_live" class="box_header {{$headerClass ?? ''}}">
<span>NH Gooi TV live</span></h4>
</div>
<div id="tab_gooi_radio_live" class="tab_content active box radio_box">
<div id="tab_gooi_radio_live" class="tab_content active box radio_box mb-0">
<img class="logo-radio" src="/images/logo-NHGooi-radio.svg"/>
@include('widgets.nustraks')
<a class="btn" href="/gids">Programmering</a>
@@ -13,7 +13,7 @@
<a class="btn player" href="/luister/live">Luister live</a>
<a class="btn" href="/kijk/live">Kijk live mee</a>
</div>
<div id="tab_gooi_tv_live" class="tab_content box radio_box">
<div id="tab_gooi_tv_live" class="tab_content box radio_box mb-0">
<img class="logo-radio" src="/images/logo-NHGooi-televisie.svg"/>
<h2 class="post_title">Live</h2>
@include('widgets.mediaplayer')

View File

@@ -8,8 +8,8 @@
@endif
<p class="now-playing-header-small">
<strong>Nu:</strong>
<span class="title"></span> -
<span class="artist"></span>
<span class="artist"></span> -
<span class="title"></span>
</p>
<script type="text/javascript" src="/js/jquery-3.7.1.min.js"></script>
<script>

View File

@@ -45,35 +45,34 @@ class ClassLoader
/** @var \Closure(string):void */
private static $includeFile;
/** @var ?string */
/** @var string|null */
private $vendorDir;
// PSR-4
/**
* @var array[]
* @psalm-var array<string, array<string, int>>
* @var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, array<int, string>>
* @var array<string, list<string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, string>
* @var list<string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* @var array[]
* @psalm-var array<string, array<string, string[]>>
* List of PSR-0 prefixes
*
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
*
* @var array<string, array<string, list<string>>>
*/
private $prefixesPsr0 = array();
/**
* @var array[]
* @psalm-var array<string, string>
* @var list<string>
*/
private $fallbackDirsPsr0 = array();
@@ -81,8 +80,7 @@ class ClassLoader
private $useIncludePath = false;
/**
* @var string[]
* @psalm-var array<string, string>
* @var array<string, string>
*/
private $classMap = array();
@@ -90,21 +88,20 @@ class ClassLoader
private $classMapAuthoritative = false;
/**
* @var bool[]
* @psalm-var array<string, bool>
* @var array<string, bool>
*/
private $missingClasses = array();
/** @var ?string */
/** @var string|null */
private $apcuPrefix;
/**
* @var self[]
* @var array<string, self>
*/
private static $registeredLoaders = array();
/**
* @param ?string $vendorDir
* @param string|null $vendorDir
*/
public function __construct($vendorDir = null)
{
@@ -113,7 +110,7 @@ class ClassLoader
}
/**
* @return string[]
* @return array<string, list<string>>
*/
public function getPrefixes()
{
@@ -125,8 +122,7 @@ class ClassLoader
}
/**
* @return array[]
* @psalm-return array<string, array<int, string>>
* @return array<string, list<string>>
*/
public function getPrefixesPsr4()
{
@@ -134,8 +130,7 @@ class ClassLoader
}
/**
* @return array[]
* @psalm-return array<string, string>
* @return list<string>
*/
public function getFallbackDirs()
{
@@ -143,8 +138,7 @@ class ClassLoader
}
/**
* @return array[]
* @psalm-return array<string, string>
* @return list<string>
*/
public function getFallbackDirsPsr4()
{
@@ -152,8 +146,7 @@ class ClassLoader
}
/**
* @return string[] Array of classname => path
* @psalm-return array<string, string>
* @return array<string, string> Array of classname => path
*/
public function getClassMap()
{
@@ -161,8 +154,7 @@ class ClassLoader
}
/**
* @param string[] $classMap Class to filename map
* @psalm-param array<string, string> $classMap
* @param array<string, string> $classMap Class to filename map
*
* @return void
*/
@@ -179,24 +171,25 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
$paths
);
}
@@ -205,19 +198,19 @@ class ClassLoader
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
$this->prefixesPsr0[$first][$prefix] = $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
$paths
);
}
}
@@ -226,9 +219,9 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
@@ -236,17 +229,18 @@ class ClassLoader
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
$paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
@@ -256,18 +250,18 @@ class ClassLoader
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
$this->prefixDirsPsr4[$prefix] = $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
$paths
);
}
}
@@ -276,8 +270,8 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 base directories
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 base directories
*
* @return void
*/
@@ -294,8 +288,8 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
@@ -429,7 +423,8 @@ class ClassLoader
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
(self::$includeFile)($file);
$includeFile = self::$includeFile;
$includeFile($file);
return true;
}
@@ -480,9 +475,9 @@ class ClassLoader
}
/**
* Returns the currently registered loaders indexed by their corresponding vendor directories.
* Returns the currently registered loaders keyed by their corresponding vendor directories.
*
* @return self[]
* @return array<string, self>
*/
public static function getRegisteredLoaders()
{
@@ -560,7 +555,10 @@ class ClassLoader
return false;
}
private static function initializeIncludeClosure(): void
/**
* @return void
*/
private static function initializeIncludeClosure()
{
if (self::$includeFile !== null) {
return;
@@ -574,8 +572,8 @@ class ClassLoader
* @param string $file
* @return void
*/
self::$includeFile = static function($file) {
self::$includeFile = \Closure::bind(static function($file) {
include $file;
};
}, null, null);
}
}

View File

@@ -34,15 +34,15 @@ class ComposerAutoloaderInit5216a35d72a5119d2f4646cd700f802d
$loader->register(true);
$filesToLoad = \Composer\Autoload\ComposerStaticInit5216a35d72a5119d2f4646cd700f802d::$files;
$requireFile = static function ($fileIdentifier, $file) {
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
require $file;
}
};
}, null, null);
foreach ($filesToLoad as $fileIdentifier => $file) {
($requireFile)($fileIdentifier, $file);
$requireFile($fileIdentifier, $file);
}
return $loader;