PageSourceSearch

https://absolutradio.de/_build/assets/ContentRenderer-CQRyK-so.js

js absolutradio.de collected 2026-10-02 06:27:17 UTC 44,239 bytes, 1,240 lines download raw bytes

1import { e as createSignal, i as getNextElement, t as template, l as insert, b as createComponent, v as createRenderEffect, w as className, F as For, D as createEffect, f as onCleanup, a as createMemo, M as Match, p as getNextMarker, m as memo, J as Switch, S as Show, z as setAttribute, L as ErrorBoundary, A as classList, k as mergeProps } from './web-CqJQ5ziD.js';
2import { C as ChannelCarousel, a as areChannelListsPopulated, i as isSliderPopulated, b as extractIds, c as extractId, d as BlockErrorFallback, P as PlaylistBlock, f as PodcastEpisodeListBlock, S as StationHostsBlockRenderer, h as StationShowsBlockRenderer, E as EmojiCardBlock, j as CardGridBlockRenderer, k as ChannelBlockRenderer, l as SocialHotlineBlock, F as FormBlock, R as RichTextBlock, A as AudioPlayerBlock } from './BlockRenderer-SYwZdfFN.js';
3import { n as isHydrated, h as channelListsActions, t as transformCMSChannelToPlayerChannel, j as hasAvailableStream, T as Text, o as AnchorLink, p as ArticleBlockRenderer } from './AnchorLink-xdKcA1QU.js';
4import { C as ChannelSelectorItem, S as Slider, c as ShareButton } from './AllPodcastsPage-B6iz_uTK.js';
5import { l as logger, A } from './logger-BHOJRl6t.js';
6import { H as Heading } from './Button-DlqpH0JT.js';
7import { r as resolveMediaUrl } from './embedConsentSync-D36RIyVL.js';
8import { b as audioPlayerActions } from './audioPlayer-CSGXEXsU.js';
9import { k as createAsync, u as getChannelListsByIdsQuery, v as getSliderByIdQuery } from './podcastEpisodesFetcher-BAa5SFHz.js';
10import { R as RichTextRenderer } from './RichTextRenderer-D9Zgg_g6.js';
11import './env-CTimTkDP.js';
12import { T as TextAndMediaCTABlock } from './TextAndMediaCTABlock-DV1_Wzdo.js';
13
14const channelSelector = "ChannelSelector-module_channelSelector__hvGFv";
15const divider = "ChannelSelector-module_divider__4pU2G";
16const dividerText = "ChannelSelector-module_dividerText__CnIMe";
17const styles$5 = {
18	channelSelector: channelSelector,
19	divider: divider,
20	dividerText: dividerText
21};
22
23var _tmpl$$5 = /* @__PURE__ */ template(`<div>`), _tmpl$2$4 = /* @__PURE__ */ template(`<div><span>`);
24const ChannelSelector = (props) => {
25  const [expandedChannelId, setExpandedChannelId] = createSignal(null);
26  const toggleChannel = (categoryIndex, channelIndex) => {
27    const channelId = `${categoryIndex}-${channelIndex}`;
28    setExpandedChannelId(expandedChannelId() === channelId ? null : channelId);
29  };
30  return (() => {
31    var _el$ = getNextElement(_tmpl$$5);
32    insert(_el$, createComponent(For, {
33      get each() {
34        return props.items;
35      },
36      children: (item, categoryIndex) => {
37        return [(() => {
38          var _el$2 = getNextElement(_tmpl$2$4), _el$3 = _el$2.firstChild;
39          insert(_el$3, () => item.title);
40          createRenderEffect((_p$) => {
41            var _v$ = styles$5.divider, _v$2 = styles$5.dividerText;
42            _v$ !== _p$.e && className(_el$2, _p$.e = _v$);
43            _v$2 !== _p$.t && className(_el$3, _p$.t = _v$2);
44            return _p$;
45          }, {
46            e: void 0,
47            t: void 0
48          });
49          return _el$2;
50        })(), createComponent(For, {
51          get each() {
52            return item.channels;
53          },
54          children: (channel, channelIndex) => {
55            const channelData = typeof channel === "object" && channel !== null ? channel : null;
56            if (!channelData) {
57              logger.warn("[ChannelSelector] Channel data is ID (not populated):", channel);
58              return null;
59            }
60            const channelId = `${categoryIndex()}-${channelIndex()}`;
61            return createComponent(ChannelSelectorItem, {
62              channel: channelData,
63              get isExpanded() {
64                return expandedChannelId() === channelId;
65              },
66              onToggle: () => toggleChannel(categoryIndex(), channelIndex())
67            });
68          }
69        })];
70      }
71    }));
72    createRenderEffect(() => className(_el$, styles$5.channelSelector));
73    return _el$;
74  })();
75};
76
77function useMediaQuery(query) {
78  const [matches, setMatches] = createSignal(false);
79  createEffect(() => {
80    const mediaQuery = window.matchMedia(query);
81    setMatches(mediaQuery.matches);
82    const handleChange = (e) => {
83      setMatches(e.matches);
84    };
85    mediaQuery.addEventListener("change", handleChange);
86    onCleanup(() => {
87      mediaQuery.removeEventListener("change", handleChange);
88    });
89  });
90  return matches;
91}
92function useIsDesktop() {
93  return useMediaQuery("(min-width: 1024px)");
94}
95
96const carouselWrapper = "ChannelGallery-module_carouselWrapper__iKm7G";
97const carouselSection = "ChannelGallery-module_carouselSection__psC6x";
98const sectionTitle = "ChannelGallery-module_sectionTitle__Blyos";
99const styles$4 = {
100	carouselWrapper: carouselWrapper,
101	carouselSection: carouselSection,
102	sectionTitle: sectionTitle
103};
104
105var _tmpl$$4 = /* @__PURE__ */ template(`<div>`), _tmpl$2$3 = /* @__PURE__ */ template(`<div><!$><!/><!$><!/>`);
106const ChannelGallery = (props) => {
107  const isDesktopRaw = useIsDesktop();
108  const isDesktop = createMemo(() => {
109    if (!isHydrated()) return true;
110    return isDesktopRaw();
111  });
112  const getVariantForItem = (item) => {
113    if (!item.channels || item.channels.length === 0) return "sender";
114    const firstChannel = item.channels[0];
115    if (typeof firstChannel !== "object" || firstChannel === null) return "sender";
116    return firstChannel.channelType === "stream" ? "stream" : "sender";
117  };
118  return createComponent(Switch, {
119    get children() {
120      return [createComponent(Match, {
121        get when() {
122          return isDesktop();
123        },
124        get children() {
125          return createComponent(ChannelSelector, {
126            get items() {
127              return props.items;
128            }
129          });
130        }
131      }), createComponent(Match, {
132        get when() {
133          return !isDesktop();
134        },
135        get children() {
136          var _el$ = getNextElement(_tmpl$$4);
137          insert(_el$, createComponent(For, {
138            get each() {
139              return props.items;
140            },
141            children: (item) => (() => {
142              var _el$2 = getNextElement(_tmpl$2$3), _el$3 = _el$2.firstChild, [_el$4, _co$] = getNextMarker(_el$3.nextSibling), _el$5 = _el$4.nextSibling, [_el$6, _co$2] = getNextMarker(_el$5.nextSibling);
143              insert(_el$2, (() => {
144                var _c$ = memo(() => !!item.title);
145                return () => _c$() && createComponent(Heading, {
146                  variant: "sectionTitle",
147                  as: "h2",
148                  get ["class"]() {
149                    return styles$4.sectionTitle;
150                  },
151                  get children() {
152                    return item.title;
153                  }
154                });
155              })(), _el$4, _co$);
156              insert(_el$2, createComponent(ChannelCarousel, {
157                get channels() {
158                  return item.channels || [];
159                },
160                get variant() {
161                  return getVariantForItem(item);
162                }
163              }), _el$6, _co$2);
164              createRenderEffect(() => className(_el$2, styles$4.carouselSection));
165              return _el$2;
166            })()
167          }));
168          createRenderEffect(() => className(_el$, styles$4.carouselWrapper));
169          return _el$;
170        }
171      })];
172    }
173  });
174};
175
176const heroBlock = "HeroHomeBlock-module_heroBlock__HZnPP";
177const titleSection = "HeroHomeBlock-module_titleSection__ZYHCI";
178const title = "HeroHomeBlock-module_title__PFzF1";
179const heroContent$1 = "HeroHomeBlock-module_heroContent__jAbqk";
180const gallerySection = "HeroHomeBlock-module_gallerySection__BYG-b";
181const galleryScrollContainer = "HeroHomeBlock-module_galleryScrollContainer__owdQe";
182const sliderSection = "HeroHomeBlock-module_sliderSection__iKtyT";
183const galleryErrorMessage = "HeroHomeBlock-module_galleryErrorMessage__ekw5e";
184const styles$3 = {
185	heroBlock: heroBlock,
186	titleSection: titleSection,
187	title: title,
188	heroContent: heroContent$1,
189	gallerySection: gallerySection,
190	galleryScrollContainer: galleryScrollContainer,
191	sliderSection: sliderSection,
192	galleryErrorMessage: galleryErrorMessage
193};
194
195var _tmpl$$3 = /* @__PURE__ */ template(`<div>`), _tmpl$2$2 = /* @__PURE__ */ template(`<div><div><p>Sender konnten nicht geladen werden`), _tmpl$3$1 = /* @__PURE__ */ template(`<div><div>`), _tmpl$4$1 = /* @__PURE__ */ template(`<div><!$><!/><div><!$><!/><!$><!/><!$><!/>`);
196function transformSliderData(slider) {
197  if (!slider.slides || slider.slides.length === 0) {
198    logger.warn("No slides found in slider");
199    return [];
200  }
201  return slider.slides.map((slide) => {
202    const imageUrl = typeof slide.image === "string" ? slide.image : slide.image?.url;
203    const fullImageUrl = resolveMediaUrl(imageUrl);
204    return {
205      image: fullImageUrl || "",
206      headline: slide.headline,
207      subheadline: slide.subheadline,
208      // Link URL is pre-populated by CMS, just pass through with normalized type
209      link: slide.link ? {
210        type: slide.link.type === "none" ? "none" : slide.link.type === "custom" ? "custom" : "reference",
211        url: slide.link.url,
212        label: slide.link.label,
213        newTab: slide.link.newTab
214      } : void 0
215    };
216  });
217}
218function initializeAudioPlayer(channelLists) {
219  const mainPlayerLists = channelLists.filter((list) => list.inMainPlayer === true);
220  channelListsActions.setChannelLists(mainPlayerLists);
221  const allChannels = [];
222  for (const list of mainPlayerLists) {
223    if (!list.channels) continue;
224    for (const channel of list.channels) {
225      if (typeof channel !== "object" || channel === null) continue;
226      if (!allChannels.some((c) =>
226 c.id === channel.id)) {
227        allChannels.push(channel);
228      }
229    }
230  }
231  if (allChannels.length === 0) {
232    logger.warn("No channels found in hero block channel lists");
233    return;
234  }
235  const playerChannels = allChannels.map(transformCMSChannelToPlayerChannel).filter((channel) => {
236    if (!hasAvailableStream(channel.streaming.streamUrls)) {
237      logger.warn(`Channel ${channel.identifier} has no stream URLs`);
238      return false;
239    }
240    return true;
241  });
242  if (playerChannels.length === 0) {
243    logger.warn("No valid channels with streaming data in hero block");
244    return;
245  }
246  audioPlayerActions.setCurrentPlaylist(playerChannels);
247  audioPlayerActions.setCurrentStream(playerChannels[0]);
248  audioPlayerActions.setPlayerColour(playerChannels[0]?.branding?.primaryColor || "var(--bg-player)");
249  logger.info(`[HeroBlock] Set player playlist: ${playerChannels.length} channels`);
250}
251const HeroHomeBlock = (props) => {
252  const needsChannelListFetch = createMemo(() => !areChannelListsPopulated(props.data.channelLists));
253  const needsSliderFetch = createMemo(() => props.data.slider && !isSliderPopulated(props.data.slider));
254  const channelListIds = createMemo(() => extractIds(props.data.channelLists));
255  const sliderId = createMemo(() => extractId(props.data.slider));
256  const fetchedChannelLists = createAsync(async () => {
257    if (!needsChannelListFetch()) return [];
258    return getChannelListsByIdsQuery(channelListIds());
259  }, {
260    deferStream: true
261  });
262  const fetchedSlider = createAsync(async () => {
263    if (!needsSliderFetch()) return null;
264    return getSliderByIdQuery(sliderId());
265  }, {
266    deferStream: true
267  });
268  const channelListFetchError = createMemo(() => {
269    if (!needsChannelListFetch()) return false;
270    const ids = channelListIds();
271    const fetched = fetchedChannelLists();
272    return ids.length > 0 && fetched !== void 0 && fetched.length === 0;
273  });
274  const channelLists = createMemo(() => {
275    if (needsChannelListFetch()) {
276      return fetchedChannelLists() ?? [];
277    }
278    if (!props.data.channelLists) return [];
279    return props.data.channelLists.filter((list) => typeof list === "object" && list !== null);
280  });
281  const mainPlayerChannelLists = createMemo(() => channelLists().filter((list) => list.inMainPlayer === true));
282  const sliderFetchError = createMemo(() => {
283    if (!needsSliderFetch()) return false;
284    const id = sliderId();
285    const fetched = fetchedSlider();
286    return id !== null && fetched !== void 0 && fetched === null;
287  });
288  const slider = createMemo(() => {
289    if (needsSliderFetch()) {
290      return fetchedSlider() || null;
291    }
292    return isSliderPopulated(props.data.slider) ? props.data.slider : null;
293  });
294  const galleryItems = createMemo(() => mainPlayerChannelLists().map((list) => ({
295    id: list.id,
296    title: list.title || list.name,
297    channels: list.channels || []
298  })));
299  const sliderData = createMemo(() => {
300    const sliderBlock = slider();
301    if (!sliderBlock) return [];
302    return transformSliderData(sliderBlock);
303  });
304  let audioPlayerInitialized = false;
305  createEffect(() => {
306    const lists = channelLists();
307    if (lists.length > 0 && !audioPlayerInitialized) {
308      audioPlayerInitialized = true;
309      initializeAudioPlayer(lists);
310    }
311  });
312  createEffect(() => {
313    if (channelListFetchError()) {
314      logger.error("[HeroHomeBlock] Channel lists fetch failed - gallery will be empty");
315    }
316    if (sliderFetchError()) {
317      logger.error("[HeroHomeBlock] Slider fetch failed - slider will be hidden");
318    }
319  });
320  return (() => {
321    var _el$ = getNextElement(_tmpl$4$1), _el$13 = _el$.firstChild, [_el$14, _co$4] = getNextMarker(_el$13.nextSibling), _el$3 = _el$14.nextSibling, _el$9 = _el$3.firstChild, [_el$0, _co$] = getNextMarker(_el$9.nextSibling), _el$1 = _el$0.nextSibling, [_el$10, _co$2] = getNextMarker(_el$1.nextSibling), _el$11 = _el$10.nextSibling, [_el$12, _co$3] = getNextMarker(_el$11.nextSibling);
322    insert(_el$, createComponent(Show, {
323      get when() {
324        return props.data.homeTitle;
325      },
326      get children() {
327        var _el$2 = getNextElement(_tmpl$$3);
328        insert(_el$2, createComponent(Heading, {
329          variant: "pageTitle",
330          as: "h1",
331          get ["class"]() {
332            return styles$3.title;
333          },
334          get children() {
335            return props.data.homeTitle;
336          }
337        }));
338        createRenderEffect(() => className(_el$2, styles$3.titleSection));
339        return _el$2;
340      }
341    }), _el$14, _co$4);
342    insert(_el$3, createComponent(Show, {
343      get when() {
344        return channelListFetchError();
345      },
346      get children() {
347        var _el$4 = getNextElement(_tmpl$2$2), _el$5 = _el$4.firstChild;
348        createRenderEffect((_p$) => {
349          var _v$ = styles$3.gallerySection, _v$2 = styles$3.galleryErrorMessage;
350          _v$ !== _p$.e && className(_el$4, _p$.e = _v$);
351          _v$2 !== _p$.t && className(_el$5, _p$.t = _v$2);
352          return _p$;
353        }, {
354          e: void 0,
355          t: void 0
356        });
357        return _el$4;
358      }
359    }), _el$0, _co$);
360    insert(_el$3, createComponent(Show, {
361      get when() {
362        return memo(() => !!!channelListFetchError())() && galleryItems().length > 0;
363      },
364      get children() {
365        var _el$6 = getNextElement(_tmpl$3$1), _el$7 = _el$6.firstChild;
366        insert(_el$7, createComponent(ChannelGallery, {
367          get items() {
368            return galleryItems();
369          }
370        }));
371        createRenderEffect((_p$) => {
372          var _v$3 = styles$3.gallerySection, _v$4 = styles$3.galleryScrollContainer;
373          _v$3 !== _p$.e && className(_el$6, _p$.e = _v$3);
374          _v$4 !== _p$.t && className(_el$7, _p$.t = _v$4);
375          return _p$;
376        }, {
377          e: void 0,
378          t: void 0
379        });
380        return _el$6;
381      }
382    }), _el$10, _co$2);
383    insert(_el$3, createComponent(Show, {
384      get when() {
385        return sliderData().length > 0;
386      },
387      get children() {
388        var _el$8 = getNextElement(_tmpl$$3);
389        insert(_el$8, createComponent(Slider, {
390          get slides() {
391            return sliderData();
392          },
393          get autoPlay() {
394            return slider()?.autoPlay ?? true;
395          },
396          get interval() {
397            return slider()?.interval ?? 5e3;
398          },
399          get showIndicators() {
400            return slider()?.showDots ?? true;
401          },
402          get showArrows() {
403            return slider()?.showArrows ?? false;
404          }
405        }));
406        createRenderEffect(() => className(_el$8, styles$3.sliderSection));
407        return _el$8;
408      }
409    }), _el$12, _co$3);
410    createRenderEffect((_p$) => {
411      var _v$5 = styles$3.heroBlock, _v$6 = styles$3.heroContent;
412      _v$5 !== _p$.e && className(_el$, _p$.e = _v$5);
413      _v$6 !== _p$.t && className(_el$3, _p$.t = _v$6);
414      return _p$;
415    }, {
416      e: void 0,
417      t: void 0
418    });
419    return _el$;
420  })();
421};
422
423const heroContent = "HeroContentBlock-module_heroContent__ccb9o";
424const header = "HeroContentBlock-module_header__s9XR9";
425const overlineRow = "HeroContentBlock-module_overlineRow__1fWwp";
426const overlineSeparator = "HeroContentBlock-module_overlineSeparator__zSFWG";
427const podcastLink = "HeroContentBlock-module_podcastLink__ILNYJ";
428const subtitle = "HeroContentBlock-module_subtitle__5w5ws";
429const card = "HeroContentBlock-module_card__J1Lyj";
430const cardContent = "HeroContentBlock-module_cardContent__iYXiy";
431const contentColumn = "HeroContentBlock-module_contentColumn__f9r4q";
432const episodeMeta = "HeroContentBlock-module_episodeMeta__jMuvt";
433const episodeNumber = "HeroContentBlock-module_episodeNumber__E3Xqc";
434const metaItem = "HeroContentBlock-module_metaItem__XyyzB";
435const publishDate = "HeroContentBlock-module_publishDate__hSF8-";
436const richContent = "HeroContentBlock-module_richContent__Cj7RV";
437const coverWrapper = "HeroContentBlock-module_coverWrapper__vOjqr";
438const coverImage = "HeroContentBlock-module_coverImage__1IdGK";
439const styles$2 = {
440	heroContent: heroContent,
441	header: header,
442	overlineRow: overlineRow,
443	overlineSeparator: overlineSeparator,
444	podcastLink: podcastLink,
445	subtitle: subtitle,
446	card: card,
447	cardContent: cardContent,
448	contentColumn: contentColumn,
449	episodeMeta: episodeMeta,
450	episodeNumber: episodeNumber,
451	metaItem: metaItem,
452	publishDate: publishDate,
453	richContent: richContent,
454	coverWrapper: coverWrapper,
455	coverImage: coverImage
456};
457
458var _tmpl$$2 = /* @__PURE__ */ template(`<span>|`), _tmpl$2$1 = /* @__PURE__ */ template(`<div><!$><!/><!$><!/>`), _tmpl$3 = /* @__PURE__ */ template(`<span>`), _tmpl$4 = /* @__PURE__ */ template(`<div><!$><!/><!$><!/><!$><!/>`), _tmpl$5 = /* @__PURE__ */ template(`<p>`), _tmpl$6 = /* @__PURE__ */ template(`<div>`), _tmpl$7 = /* @__PURE__ */ template(`<div><div><img loading=eager width=460 height=460></div><!$><!/>`, true, false, false), _tmpl$8 = /* @__PURE__ */ template(`<div><div><!$><!/><!$><!/><!$><!/></div><div><div><div><!$><!/><!$><!/><!$><!/></div><!$><!/>`);
459const HeroContentBlock = (props) => {
460  const episodeLabel = () => {
461    if (props.type !== "podcast-episode") return "";
462    const parts = [];
463    if (props.seasonNumber) parts.push(`S${props.seasonNumber}`);
464    if (props.episodeNumber) parts.push(`E${props.episodeNumber}`);
465    return parts.join(" ");
466  };
467  const overlineText = () => {
468    switch (props.type) {
469      case "podcast":
470        return "Podcast";
471      case "podcast-episode":
472        return "Episode";
473      default:
474        return null;
475    }
476  };
477  const shareAriaLabel = () => {
478    switch (props.type) {
479      case "article":
480        return "Artikel teilen";
481      case "podcast":
482        return "Podcast teilen";
483      case "podcast-episode":
484        return "Episode teilen";
485      default:
486        return "Teilen";
487    }
488  };
489  return (() => {
490    var _el$ = getNextElement(_tmpl$8), _el$2 = _el$.firstChild, _el$9 = _el$2.firstChild, [_el$0, _co$3] = getNextMarker(_el$9.nextSibling), _el$1 = _el$0.nextSibling, [_el$10, _co$4] = getNextMarker(_el$1.nextSibling), _el$11 = _el$10.nextSibling, [_el$12, _co$5] = getNextMarker(_el$11.nextSibling), _el$13 = _el$2.nextSibling, _el$14 = _el$13.firstChild, _el$15 = _el$14.firstChild, _el$28 = _el$15.firstChild, [_el$29, _co$9] = getNextMarker(_el$28.nextSibling), _el$30 = _el$29.nextSibling, [_el$31, _co$0] = getNextMarker(_el$30.nextSibling), _el$32 = _el$31.nextSibling, [_el$33, _co$1] = getNextMarker(_el$32.nextSibling), _el$39 = _el$15.nextSibling, [_el$40, _co$11] = getNextMarker(_el$39.nextSibling);
491    insert(_el$2, createComponent(Show, {
492      get when() {
493        return overlineText();
494      },
495      get children() {
496        var _el$3 = getNextElement(_tmpl$2$1), _el$5 = _el$3.firstChild, [_el$6, _co$] = getNextMarker(_el$5.nextSibling), _el$7 = _el$6.nextSibling, [_el$8, _co$2] = getNextMarker(_el$7.nextSibling);
497        insert(_el$3, createComponent(Text, {
498          variant: "heroOverline",
499          get children() {
500            return overlineText();
501          }
502        }), _el$6, _co$);
503        insert(_el$3, createComponent(Show, {
504          get when() {
505            return memo(() => !!(props.type === "podcast-episode" && props.podcastTitle))() && props.podcastSlug;
506          },
507          get children() {
508            return [(() => {
509              var _el$4 = getNextElement(_tmpl$$2);
510              createRenderEffect(() => className(_el$4, styles$2.overlineSeparator));
511              return _el$4;
512            })(), createComponent(A, {
513              get href() {
514                return `/podcast/${props.podcastSlug}`;
515              },
516              get ["class"]() {
517                return styles$2.podcastLink;
518              },
519              get children() {
520                return props.podcastTitle;
521              }
522            })];
523          }
524        }), _el$8, _co$2);
525        createRenderEffect(() => className(_el$3, styles$2.overlineRow));
526        return _el$3;
527      }
528    }), _el$0, _co$3);
529    insert(_el$2, createComponent(Heading, {
530      variant: "pageTitle",
531      get children() {
532        return props.title;
533      }
534    }), _el$10, _co$4);
535    insert(_el$2, createComponent(Show, {
536      get when() {
537        return props.subtitle;
538      },
539      get children() {
540        return createComponent(Heading, {
541          variant: "h2",
542          get ["class"]() {
543            return styles$2.subtitle;
544          },
545          get children() {
546            return props.subtitle;
547          }
548        });
549      }
550    }), _el$12, _co$5);
551    insert(_el$15, createComponent(Show, {
552      get when() {
553        return props.type === "podcast-episode";
554      },
555      get children() {
556        var _el$16 = getNextElement(_tmpl$4), _el$20 = _el$16.firstChild, [_el$21, _co$6] = getNextMarker(_el$20.nextSibling), _el$22 = _el$21.nextSibling, [_el$23, _co$7] = getNextMarker(_el$22.nextSibling), _el$24 = _el$23.nextSibling, [_el$25, _co$8] = getNextMarker(_el$24.nextSibling);
557        insert(_el$16, createComponent(Show, {
558          get when() {
559            return episodeLabel();
560          },
561          get children() {
562            var _el$17 = getNextElement(_tmpl$3);
563            insert(_el$17, episodeLabel);
564            createRenderEffect(() => className(_el$17, styles$2.episodeNumber));
565            return _el$17;
566          }
567        }), _el$21, _co$6);
568        insert(_el$16, createComponent(Show, {
569          get when() {
570            return props.duration;
571          },
572          get children() {
573            var _el$18 = getNextElement(_tmpl$3);
574            insert(_el$18, () => props.duration);
575            createRenderEffect(() => className(_el$18, styles$2.metaItem));
576            return _el$18;
577          }
578        }), _el$23, _co$7);
579        insert(_el$16, createComponent(Show, {
580          get when() {
581            return props.publishDate;
582          },
583          get children() {
584            var _el$19 = getNextElement(_tmpl$3);
585            insert(_el$19, () => props.publishDate);
586            createRenderEffect(() => className(_el$19, styles$2.metaItem));
587            return _el$19;
588          }
589        }), _el$25, _co$8);
590        createRenderEffect(() => className(_el$16, styles$2.episodeMeta));
591        return _el$16;
592      }
593    }), _el$29, _co$9);
594    insert(_el$15, createComponent(Show, {
595      get when() {
596        return memo(() => props.type === "article")() && props.publishDate;
597      },
598      get children() {
599        var _el$26 = getNextElement(_tmpl$5);
600        insert(_el$26, () => props.publishDate);
601        createRenderEffect(() => className(_el$26, styles$2.publishDate));
602        return _el$26;
603      }
604    }), _el$31, _co$0);
605    insert(_el$15, createComponent(Show, {
606      get when() {
607        return props.content;
608      },
609      get children() {
610        var _el$27 = getNextElement(_tmpl$6);
611        insert(_el$27, createComponent(RichTextRenderer, {
612          get content() {
613            return props.content;
614          },
615          variant: "hero"
616        }));
617        createRenderEffect(() => className(_el$27, styles$2.richContent));
618        return _el$27;
619      }
620    }), _el$33, _co$1);
621    insert(_el$14, createComponent(Show, {
622      get when() {
623        return props.imageUrl;
624      },
625      get children() {
626        var _el$34 = getNextElement(_tmpl$7), _el$35 = _el$34.firstChild, _el$36 = _el$35.firstChild, _el$37 = _el$35.nextSibling, [_el$38, _c
626o$10] = getNextMarker(_el$37.nextSibling);
627        insert(_el$34, createComponent(Show, {
628          get when() {
629            return props.showShare !== false;
630          },
631          get children() {
632            return createComponent(ShareButton, {
633              get onClick() {
634                return props.onShare;
635              },
636              get ariaLabel() {
637                return shareAriaLabel();
638              }
639            });
640          }
641        }), _el$38, _co$10);
642        createRenderEffect((_p$) => {
643          var _v$ = styles$2.coverWrapper, _v$2 = styles$2.coverImage, _v$3 = props.imageUrl, _v$4 = props.imageAlt || props.title;
644          _v$ !== _p$.e && className(_el$34, _p$.e = _v$);
645          _v$2 !== _p$.t && className(_el$35, _p$.t = _v$2);
646          _v$3 !== _p$.a && setAttribute(_el$36, "src", _p$.a = _v$3);
647          _v$4 !== _p$.o && setAttribute(_el$36, "alt", _p$.o = _v$4);
648          return _p$;
649        }, {
650          e: void 0,
651          t: void 0,
652          a: void 0,
653          o: void 0
654        });
655        return _el$34;
656      }
657    }), _el$40, _co$11);
658    createRenderEffect((_p$) => {
659      var _v$5 = styles$2.heroContent, _v$6 = styles$2.header, _v$7 = styles$2.card, _v$8 = styles$2.cardContent, _v$9 = styles$2.contentColumn;
660      _v$5 !== _p$.e && className(_el$, _p$.e = _v$5);
661      _v$6 !== _p$.t && className(_el$2, _p$.t = _v$6);
662      _v$7 !== _p$.a && className(_el$13, _p$.a = _v$7);
663      _v$8 !== _p$.o && className(_el$14, _p$.o = _v$8);
664      _v$9 !== _p$.i && className(_el$15, _p$.i = _v$9);
665      return _p$;
666    }, {
667      e: void 0,
668      t: void 0,
669      a: void 0,
670      o: void 0,
671      i: void 0
672    });
673    return _el$;
674  })();
675};
676
677const LOG_PREFIX$1 = "[transformSliderSlides]";
678function getImageUrl(image) {
679  return resolveMediaUrl(image) || "";
680}
681function normalizeLinkType(linkType) {
682  if (linkType === "none") return "none";
683  if (linkType === "custom") return "custom";
684  return "reference";
685}
686function transformSliderSlides(cmsSlides) {
687  if (!cmsSlides || !Array.isArray(cmsSlides)) {
688    logger.warn(`${LOG_PREFIX$1} no slides provided`);
689    return [];
690  }
691  return cmsSlides.map((slide) => {
692    let linkUrl;
693    let linkLabel = slide.link?.label;
694    const linkType = slide.link?.type;
695    if (linkType === "custom") {
696      linkUrl = slide.link?.url;
697    } else if (linkType === "reference") {
698      if (slide.link?.reference && typeof slide.link.reference === "object") {
699        const ref = slide.link.reference;
700        const refValue = typeof ref.value === "object" ? ref.value : null;
701        if (refValue?.slug || refValue?.identifier) {
702          switch (ref.relationTo) {
703            case "pages":
704              linkUrl = refValue.slug === "home" ? "/" : `/${refValue.slug}`;
705              break;
706            case "articles":
707              linkUrl = `/artikel/${refValue.slug}`;
708              break;
709            case "podcasts":
710              linkUrl = `/podcast/${refValue.slug}`;
711              break;
712            case "channel-pages":
713              const channelPrefix = refValue.pageType === "stream" || refValue.channelType === "stream" ? "stream" : "sender";
714              linkUrl = `/${channelPrefix}/${refValue.identifier || refValue.slug}`;
715              break;
716            default:
717              logger.warn(`${LOG_PREFIX$1} unknown reference relationTo: ${ref.relationTo}`);
718          }
719        }
720        if (!linkLabel && refValue && "title" in refValue) {
721          linkLabel = refValue.title;
722        }
723      }
724    } else if (linkType && linkType !== "none") {
725      linkUrl = slide.link?.url;
726    }
727    return {
728      image: getImageUrl(slide.image),
729      headline: slide.headline,
730      subheadline: slide.subheadline,
731      link: slide.link ? {
732        type: normalizeLinkType(linkType),
733        url: linkUrl,
734        label: linkLabel,
735        newTab: slide.link.newTab
736      } : void 0
737    };
738  });
739}
740
741const sliderBlockWrapper = "SliderBlockRenderer-module_sliderBlockWrapper__DMsaz";
742const sliderInner = "SliderBlockRenderer-module_sliderInner__xL88P";
743const styles$1 = {
744	sliderBlockWrapper: sliderBlockWrapper,
745	sliderInner: sliderInner
746};
747
748var _tmpl$$1 = /* @__PURE__ */ template(`<div><div>`);
749const LOG_PREFIX = "[SliderBlockRenderer]";
750function isCollectionId(id) {
751  if (id === void 0 || id === null) return false;
752  if (typeof id === "number") return true;
753  return /^\d+$/.test(id);
754}
755const SliderBlockRenderer = (props) => {
756  const needsFetch = createMemo(() => !isSliderPopulated(props.slider));
757  const fetchedSlider = createAsync(async () => {
758    if (!needsFetch()) return null;
759    const id = props.slider.id;
760    if (!isCollectionId(id)) {
761      logger.warn(`${LOG_PREFIX} slides unpopulated but id ${String(id)} is not a sliders collection id; skipping refetch`);
762      return null;
763    }
764    return getSliderByIdQuery(String(id));
765  }, {
766    deferStream: true
767  });
768  const resolved = createMemo(() => {
769    if (!needsFetch()) return props.slider;
770    return fetchedSlider() ?? null;
771  });
772  return createComponent(Show, {
773    get when() {
774      return resolved();
775    },
776    children: (getSlider) => (() => {
777      var _el$ = getNextElement(_tmpl$$1), _el$2 = _el$.firstChild;
778      insert(_el$2, createComponent(Slider, {
779        get slides() {
780          return transformSliderSlides(getSlider().slides);
781        },
782        get autoPlay() {
783          return getSlider().autoPlay;
784        },
785        get interval() {
786          return getSlider().interval;
787        },
788        get showIndicators() {
789          return getSlider().showDots;
790        },
791        get showArrows() {
792          return getSlider().showArrows;
793        }
794      }));
795      createRenderEffect((_p$) => {
796        var _v$ = styles$1.sliderBlockWrapper, _v$2 = styles$1.sliderInner;
797        _v$ !== _p$.e && className(_el$, _p$.e = _v$);
798        _v$2 !== _p$.t && className(_el$2, _p$.t = _v$2);
799        return _p$;
800      }, {
801        e: void 0,
802        t: void 0
803      });
804      return _el$;
805    })()
806  });
807};
808
809const contentContainer = "ContentRenderer-module_contentContainer__Rj9RJ";
810const anchorTarget = "ContentRenderer-module_anchorTarget__rzahq";
811const anchorTargetLead = "ContentRenderer-module_anchorTargetLead__TsL7f";
812const anchorLink = "ContentRenderer-module_anchorLink__RmLBP";
813const styles = {
814	contentContainer: contentContainer,
815	anchorTarget: anchorTarget,
816	anchorTargetLead: anchorTargetLead,
817	anchorLink: anchorLink
818};
819
820var _tmpl$ = /* @__PURE__ */ template(`<div>`), _tmpl$2 = /* @__PURE__ */ template(`<div><!$><!/><!$><!/>`);
821function getItemAnchor(item) {
822  if (item?.type === "block") {
823    const anchor = item.block?.[0]?.anchor;
824    return anchor || void 0;
825  }
826  if (item?.type === "reference") {
827    const value = item.contentReference?.value;
828    const anchor = typeof value === "object" ? value.anchor : void 0;
829    return anchor || void 0;
830  }
831  return void 0;
832}
833function getItemShowAnchorLink(item) {
834  if (item?.type === "block") {
835    return item.block?.[0]?.showAnchorLink !== false;
836  }
837  return true;
838}
839function renderInlineBlock(block, ctx) {
840  const {
841    currentStationId,
842    currentArticleId,
843    stationColor,
844    channelIdentifier,
845    channelId,
846    channelAccentColor,
847    articleContext,
848    podcastContext,
849    episodeContext
850  } = ctx;
851  if (!block || !block.blockType) {
852    logger.warn("[ContentRenderer] Received invalid block:", block);
853    return null;
854  }
855  switch (block.blockType) {
856    case "audioPlayer":
857      return createComponent(AudioPlayerBlock, mergeProps(block, {
858        backgroundColor: stationColor
859      }));
860    case "audioBlock":
861      return createComponent(AudioPlayerBlock, mergeProps(block, {
862        backgroundColor: stationColor,
863        get podcastSlug() {
864          return podcastContext?.slug;
865        }
866      }));
867    case "richtext":
868      return createComponent(RichTextBlock, block);
869    case "formBlock":
870      return createComponent(FormBlock, block);
871    case "socialHotline":
872      return createComponent(SocialHotlineBlock, {
873        block
874      });
875    case "channelBlock":
876      return createComponent(ChannelBlockRenderer, block);
877    case "cardGridBlock":
878      return createComponent(CardGridBlockRenderer, block);
879    case "emojiCardBlock":
880      return createComponent(EmojiCardBlock, {
881        block
882      });
883    case "stationShowsBlock":
884      return createComponent(StationShowsBlockRenderer, mergeProps(block, {
885        channelId
886      }));
887    case "stationHostsBlock":
888      return createComponent(StationHostsBlockRenderer, mergeProps(block, {
889        channelId,
890        channelAccentColor
891      }));
892    case "articleBlock": {
893      if (!block.items || !Array.isArray(block.items)) {
894        logger.warn("[ContentRenderer] articleBlock has no items");
895        return null;
896      }
897      return createComponent(ArticleBlockRenderer, {
898        block,
899        currentStationId,
900        currentArticleId
901      });
902    }
903    case "slider":
904      return createComponent(SliderBlockRenderer, {
905        slider: block
906      });
907    case "podcastEpisodeListBlock": {
908      const parentPodcast = typeof block.parentPodcast === "object" ? block.parentPodcast : void 0;
909      return createComponent(PodcastEpisodeListBlock, {
910        get episodes() {
911          return block.episodes || [];
912        },
913        get headerText() {
914          return block.headerText;
915        },
916        get initialLimit() {
917          return block.initialLimit;
918        },
919        get showPlayButton() {
920          return block.showPlayButton;
921        },
922        get showLoadMore() {
923          return block.showLoadMore;
924        },
925        get showMoreText() {
926          return block.showMoreText;
927        },
928        get sortOrder() {
929          return block.sortOrder;
930        },
931        get maxEpisodes() {
932          return block.maxEpisodes;
933        },
934        get podcastSlug() {
935          return parentPodcast?.slug;
936        },
937        parentPodcast,
938        backgroundColor: stationColor
939      });
940    }
941    case "heroBlock":
942      return renderHeroByType(block, articleContext, podcastContext, episodeContext);
943    case "textAndMediaCTA":
944      return createComponent(TextAndMediaCTABlock, block);
945    case "playlistBlock":
946      return createComponent(PlaylistBlock, {
947        channelIdentifier: channelIdentifier || "",
948        get title() {
949          return block.title;
950        },
951        get showTitle() {
952          return block.showTitle;
953        },
954        get maxItems() {
955          return block.maxItems;
956        },
957        get showSearchLink() {
958          return block.showSearchLink;
959        },
960        get showMoreButton() {
961          return block.showMoreButton;
962        },
963        get searchLinkUrl() {
964          return block.searchLinkUrl;
965        },
966        accentColor: channelAccentColor
967      });
968    default:
969      logger.warn(`[ContentRenderer] Unknown block type:`, block);
970      return null;
971  }
972}
973function transformHosts(hosts) {
974  if (!hosts || !Array.isArray(hosts)) return [];
975  return hosts.filter((host) => typeof host === "object" && host !== null).map((host) => ({
976    name: host.name,
977    imageUrl: resolveMediaUrl(host.image) || void 0
978  }));
979}
980function renderHeroByType(hero, articleContext, podcastContext, episodeContext) {
981  switch (hero.type) {
982    case "home":
983      return createComponent(HeroHomeBlock, {
984        data: hero
985      });
986    case "page":
987      return createComponent(HeroContentBlock, {
988        type: "article",
989        get title() {
990          return hero.title || "";
991        },
992        get subtitle() {
993          return hero.subtitle || hero.description;
994        },
995        get content() {
996          return hero.content;
997        },
998        get imageUrl() {
999          return resolveMediaUrl(hero.image) || void 0;
1000        },
1001        get publishDate() {
1002          return articleContext?.publishDate;
1003        },
1004        get backgroundColor() {
1005          return articleContext?.backgroundColor;
1006        },
1007        get showShare() {
1008          return articleContext?.showShare;
1009        },
1010        get onShare() {
1011          return articleContext?.onShare;
1012        }
1013      });
1014    case "article":
1015      return createComponent(HeroContentBlock, {
1016        type: "article",
1017        get title() {
1018          return hero.title || "";
1019        },
1020        get subtitle() {
1021          return hero.subtitle;
1022        },
1023        get content() {
1024          return hero.content;
1025        },
1026        get imageUrl() {
1027          return resolveMediaUrl(hero.image) || void 0;
1028        },
1029        get publishDate() {
1030          return articleContext?.publishDate;
1031        },
1032        get backgroundColor() {
1033          return articleContext?.backgroundColor;
1034        },
1035        get showShare() {
1036          return articleContext?.showShare;
1037        },
1038        get onShare() {
1039          return articleContext?.onShare;
1040        }
1041      });
1042    case "podcast":
1043      return createComponent(HeroContentBlock, {
1044        type: "podcast",
1045        get title() {
1046          return hero.title || podcastContext?.title || "";
1047        },
1048        get subtitle() {
1049          return hero.subtitle;
1050        },
1051        get content() {
1052          return hero.content;
1053        },
1054        get imageUrl() {
1055          return resolveMediaUrl(hero.image) || void 0;
1056        },
1057        get hosts() {
1058          return transformHosts(hero.hosts);
1059        },
1060        get backgroundColor() {
1061          return podcastContext?.backgroundColor;
1062        },
1063        get showShare() {
1064          return podcastContext?.showShare;
1065        },
1066        get onShare() {
1067          return podcastContext?.onShare;
1068        }
1069      });
1070    case "podcast-episode":
1071      return createComponent(HeroContentBlock, {
1072        type: "podcast-episode",
1073        get title() {
1074          return hero.title || "";
1075        },
1076        get subtitle() {
1077          return hero.subtitle;
1078        },
1079        get content() {
1080          return hero.content;
1081        },
1082        get imageUrl() {
1083          return resolveMediaUrl(hero.image) || void 0;
1084        },
1085        get podcastTitle() {
1086          return episodeContext?.podcastTitle;
1087        },
1088        get podcastSlug() {
1089          return episodeContext?.podcastSlug;
1090        },
1091        get episodeNumber() {
1092          return episodeContext?.episodeNumber;
1093        },
1094        get seasonNumber() {
1095          return episodeContext?.seasonNumber;
1096        },
1097        get duration() {
1098          return episodeContext?.duration;
1099        },
1100        get publishDate() {
1101          return episodeContext?.publishDate;
1102        },
1103        get backgroundColor() {
1104          return episodeContext?.backgroundColor;
1105        },
1106        get showShare() {
1107          return episodeContext?.showShare;
1108        },
1109        get onShare() {
1110          return episodeContext?.onShare;
1111        }
1112      });
1113    default:
1114      logger.warn(`[ContentRenderer] Unknown hero type:`, hero);
1115      return null;
1116  }
1117}
1118function renderReference(relationTo, value) {
1119  if (!value) {
1120    logger.warn(`[ContentRenderer] Reference value is null/undefined for: ${relationTo}`);
1121    return null;
1122  }
1123  if (typeof value === "string") {
1124    logger.warn(`[ContentRenderer] Reference not populated: ${relationTo}:${value}`);
1125    return null;
1126  }
1127  switch (relationTo) {
1128    // ========================================
1129    // SLIDERS
1130    // ========================================
1131    case "slider-blocks":
1132    case "sliders":
1133      return createComponent(SliderBlockRenderer, {
1134        slider: value
1135      });
1136    // ========================================
1137    // CONTENT BLOCKS
1138    // ========================================
1139    case "content-blocks": {
1140      const contentBlock = value;
1141      return createComponent(TextAndMediaCTABlock, contentBlock);
1142    }
1143    default:
1144      logger.warn(`[ContentRenderer] Unknown reference type: ${relationTo}`, value);
1145      return null;
1146  }
1147}
1148function renderContentItem(item, ctx) {
1149  if (!item) {
1150    logger.warn("[ContentRenderer] Received null/undefined content item");
1151    return null;
1152  }
1153  if (item.type === "block" && item.block && item.block.length > 0) {
1154    return renderInlineBlock(item.block[0], ctx);
1155  }
1156  if (item.type === "reference" && item.contentReference) {
1157    const {
1158      relationTo,
1159      value
1160    } = item.contentReference;
1161    return renderReference(relationTo, value);
1162  }
1163  logger.warn("[ContentRenderer] Invalid content item:", item);
1164  return null;
1165}
1166const ContentRenderer = (props) => {
1167  const ctx = {
1168    currentStationId: props.currentStationId,
1169    currentArticleId: props.currentArticleId,
1170    stationColor: props.stationColor,
1171    channelIdentifier: props.channelIdentifier,
1172    channelId: props.channelId,
1173    channelAccentColor: props.channelAccentColor,
1174    articleContext: props.articleContext,
1175    podcastContext: props.podcastContext,
1176    episodeContext: props.episodeContext
1177  };
1178  return createComponent(Show, {
1179    get when() {
1180      return memo(() => !!props.items)() && props.items.length > 0;
1181    },
1182    get children() {
1183      var _el$ = getNextElement(_tmpl$);
1184      insert(_el$, createComponent(For, {
1185        get each() {
1186          return props.items;
1187        },
1188        children: (item, index) => {
1189          const anchor = getItemAnchor(item);
1190          const itemType = item?.type === "reference" ? item.contentReference?.relationTo : item?.block?.[0]?.blockType;
1191          const rendered = createComponent(ErrorBoundary, {
1192            fallback: (err) => createComponent(BlockErrorFallback, {
1193              error: err,
1194              blockType: itemType
1195            }),
1196            get children() {
1197              return renderContentItem(item, ctx);
1198            }
1199          });
1200          if (!anchor) return rendered;
1201          return (() => {
1202            var _el$2 = getNextElement(_tmpl$2), _el$3 = _el$2.firstChild, [_el$4, _co$] = getNextMarker(_el$3.nextSibling), _el$5 = _el$4.nextSibling, [_el$6, _co$2] = getNextMarker(_el$5.nextSibling);
1203            setAttribute(_el$2, "id", anchor);
1204            insert(_el$2, createComponent(Show, {
1205              get when() {
1206                return getItemShowAnchorLink(item);
1207              },
1208              get children() {
1209                return createComponent(AnchorLink, {
1210                  anchor,
1211                  get ["class"]() {
1212                    return styles.anchorLink;
1213                  }
1214                });
1215              }
1216            }), _el$4, _co$);
1217            insert(_el$2, rendered, _el$6, _co$2);
1218            createRenderEffect((_p$) => {
1219              var _v$ = styles.anchorTarget, _v$2 = {
1220                [styles.anchorTargetLead]: index() === 0
1221              };
1222              _v$ !== _p$.e && className(_el$2, _p$.e = _v$);
1223              _p$.t = classList(_el$2, _v$2, _p$.t);
1224              return _p$;
1225            }, {
1226              e: void 0,
1227              t: void 0
1228            });
1229            return _el$2;
1230          })();
1231        }
1232      }));
1233      createRenderEffect(() => className(_el$, props.class || styles.contentContainer));
1234      return _el$;
1235    }
1236  });
1237};
1238
1239export { ContentRenderer as C };
1240//# sourceMappingURL=ContentRenderer-CQRyK-so.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.