Fehler bei der Verarbeitung der Vorlage.
Java method "as.asac.template.tools.DLToolImpl.getThumbnailByJSON(String, String)" threw an exception when invoked on as.asac.template.tools.DLToolImpl object "as.asac.template.tools.DLToolImpl@78fe86d7"; see cause exception in the Java stack trace.

----
FTL stack trace ("~" means nesting-related):
	- Failed at: #assign slideThumbnail1 = dlTool.getT...  [in template "37703#37743#8258493" at line 703, column 81]
----
1<#-- Services --> 
2<#assign assetEntryLocalServiceUtil = serviceLocator.findService("com.liferay.asset.kernel.service.AssetEntryLocalService")/> 
3<#assign assetLinkLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetLinkLocalService")/> 
4<#assign journalArticleResourceServiceUtil = serviceLocator.findService("com.liferay.journal.service.JournalArticleResourceLocalService")/> 
5<#assign assetVocabularyLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetVocabularyLocalService") /> 
6<#assign assetCategoryLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetCategoryLocalService")> 
7<#assign ddmStructureLocalService = serviceLocator.findService("com.liferay.dynamic.data.mapping.service.DDMStructureLocalService")/> 
8 
9<#-- Reserved vbles --> 
10<#assign title = .vars['reserved-article-title'].data> 
11<#assign articleId=.vars["reserved-article-id"].data /> 
12<#assign description=.vars["reserved-article-description"].data /> 
13<#assign smallImageUrl=.vars["reserved-article-small-image-url"].data /> 
14<#assign date=.vars["reserved-article-display-date"].data /> 
15<#assign request = .vars['request']> 
16 
17<#-- Init --> 
18<#assign assetEntry = journalTool.getAssetEntryByArticleId(groupId, articleId)> 
19<#assign journalArticle = journalTool.getJournalArticleByAssetEntry(assetEntry)> 
20<#assign resourcePrimKey = journalArticle.getResourcePrimKey()> 
21<#assign articleURL = themeDisplay.getURLPortal()+themeDisplay.getURLCurrent()> 
22<#assign articleSocialBookmarks = themeDisplay.getThemeSetting("article-social-bookmarks")!> 
23<#assign layoutSetBannerPath = layoutTool.getLayoutSetBannerPath(groupId, themeDisplay.getLayout().isPrivateLayout())!> 
24<#assign articleMainImageThumbnail1 = dlTool.getThumbnail(smallImageUrl, "1", layoutSetBannerPath)! /> 
25<#assign articleMainImageThumbnail3 = dlTool.getThumbnail(smallImageUrl, "3", layoutSetBannerPath)! /> 
26<#assign articleMainImageThumbnail1 = dlTool.getThumbnail(smallImageUrl, "1")! /> 
27<#assign ddmStructureNameNormalize = "template-${friendlyURLNormalizerTool.normalize(journalArticle.getDDMStructure().getName(localeUtil.getDefault()))}" /> 
28<#assign group = themeDisplay.getScopeGroup()/> 
29<#setting time_zone="Europe/Madrid"> 
30 
31<#-- Settings --> 
32<#assign schema = "http://schema.org/Article"/> 
33<#assign ddmStructure = journalArticle.getDDMStructure() /> 
34<#assign structureId = "" /> 
35<#assign structureKey = "" /> 
36<#assign filterStructuresIds = ""/> 
37<#assign filterStructuresKeys = []> 
38<#assign filterStructures = []> 
39<#assign filterDDMStructures = []> 
40<#if validator.isNotNull(ddmStructure)> 
41	<#assign structureId = ddmStructure.getStructureId() /> 
42	<#assign structureKey = ddmStructure.getStructureKey()/> 
43	<#assign filterStructuresIdsKey = "${structureId}[filterStructuresIds]"/> 
44	<#assign filterStructuresIdsValue = group.getTypeSettingsProperty(filterStructuresIdsKey)!/> 
45	<#if validator.isNotNull(filterStructuresIdsValue)> 
46		<#assign filterStructuresIds = getterUtil.getLongValues(stringUtil.split(filterStructuresIdsValue))/> 
47		<#list filterStructuresIds as filterStructuresId> 
48			<#assign filterStructure = ddmStructureLocalService.fetchDDMStructure(filterStructuresId)/> 
49			<#if validator.isNotNull(filterStructure)> 
50				<#assign filterStructureKey = filterStructure.getStructureKey()/> 
51				<#assign filterStructuresKeys = filterStructuresKeys + [filterStructureKey] > 
52				<#assign filterDDMStructures = filterDDMStructures + [filterStructure] > 
53			</#if> 
54		</#list> 
55	</#if> 
56	<#assign schemaKey = "${ddmStructure.getStructureKey()}[schema]"/> 
57	<#assign schemaValue = group.getTypeSettingsProperty(schemaKey)!/> 
58	<#if validator.isNotNull(schemaValue)> 
59		<#assign schema = "${schemaValue}"/> 
60	</#if> 
61</#if> 
62 
63<#-- Settings Cicloturismo --> 
64<#assign tracksModesJSONObject = "" /> 
65<#assign routeDetailServicesDistance = 5.0 /> 
66<#assign ddmStructureSettingsJSONObject = "" /> 
67<#assign templateVblesJSONObject = jsonFactoryUtil.createJSONObject(group.getTypeSettingsProperty("templateVbles"))!/> 
68<#if validator.isNotNull(templateVblesJSONObject) && templateVblesJSONObject.has("cicloturismo")>	 
69	<#assign micrositeJSONObject = templateVblesJSONObject.getJSONObject("cicloturismo")!/> 
70	<#assign tracksModesOrderJSONArray = micrositeJSONObject.getJSONArray("tracksModesOrder")!/> 
71	<#assign tracksModesJSONObject = micrositeJSONObject.getJSONObject("tracksModes")!/> 
72	<#assign ddmStructureSettingsJSONObject = micrositeJSONObject.getJSONObject("structureSettings")!/> 
73	<#assign routeDetailServicesDistance = templateVblesJSONObject.getJSONObject("cicloturismo").getDouble("routeDetailServicesDistance")!/> 
74</#if> 
75 
76<#-- Vocabularies --> 
77<#assign concejosVocabulary = assetVocabularyLocalService.fetchGroupVocabulary(groupId, "Concejos")! /> 
78<#assign modeVocabulary = assetVocabularyLocalService.fetchGroupVocabulary(groupId, "Cicloturismo :: Temática/Modalidad")! /> 
79<#assign routeTypeVocabulary = assetVocabularyLocalService.fetchGroupVocabulary(groupId, "Cicloturismo :: Tipo de Ruta")! /> 
80<#assign trackVocabulary = assetVocabularyLocalService.fetchGroupVocabulary(groupId, "Cicloturismo :: Recorrido")! /> 
81<#assign tracksVocabulary = assetVocabularyLocalService.fetchGroupVocabulary(groupId, "Cicloturismo :: Recorridos")! /> 
82<#assign routeVocabularyIds = [modeVocabulary.getVocabularyId(), routeTypeVocabulary.getVocabularyId() , trackVocabulary.getVocabularyId(), tracksVocabulary.getVocabularyId()] /> 
83 
84<#-- Categories --> 
85<#assign concejos = journalTool.getCategories(groupId, articleId, ["Concejos"])/> 
86<#assign comarcas = journalTool.getCategoriesNames(groupId, articleId, locale, ["Comarcas"])/> 
87<#assign tipoRuta = journalTool.getCategoriesNames(groupId, articleId, locale, ["Cicloturismo :: Tipo de Ruta"])/> 
88<#assign modalidad = journalTool.getCategoriesNames(groupId, articleId, locale, ["Cicloturismo :: Temática/Modalidad"])/> 
89<#assign tipoRecorrido = journalTool.getCategoriesNames(groupId, articleId, locale, ["Cicloturismo :: Recorrido"])/> 
90<#assign tipoRecorridos = journalTool.getCategoriesNames(groupId, articleId, locale, ["Cicloturismo :: Recorridos"])/> 
91<#assign dificultad = journalTool.getCategories(groupId, articleId, ["Microsite :: Dificultad"])/> 
92<#assign duracion = journalTool.getCategoriesNames(groupId, articleId, locale, ["Cicloturismo :: Duración"])/> 
93<#assign routeTypesCategories = assetCategoryTool.getAssetCategoriesByVocabularyName(tracksVocabulary)! /> 
94 
95<#-- Build --> 
96<#assign numero = Numero.data> 
97<#assign routeTag = "rutacicloturismo${numero}"> 
98 
99<#assign portletId = portletTool.getPortletId(request)!/> 
100<#assign namespace = "_"+portletId+"_" /> 
101<#if Denominacion.data?has_content> 
102	<#assign title = Denominacion.data> 
103</#if> 
104<#assign markersServicesDDMStructureKeys = [] /> 
105<#assign markersNotices = [] /> 
106<#assign markersServicesDDMStructureKeys = [] /> 
107 
108<#-- GPX --> 
109<#assign gpxRutaPath = ""/> 
110<#assign gpxRutaJSONObject = ""/> 
111<#assign gpxRoute = ""/> 
112<#assign gpxPOIRutaPath = ""/> 
113<#assign gpxPOIRutaJSONObject = ""/> 
114<#assign gpxPOIRoute = ""/> 
115 
116<#if validator.isNotNull(Documentos.GPXRuta.data) && Documentos.GPXRuta.getData()!=""> 
117	<#assign gpxRutaJSONStr = Documentos.GPXRuta.data! /> 
118	<#assign gpxRutaPath = dlTool.getPathByJSON(gpxRutaJSONStr, themeDisplay.getScopeGroupId())!/> 
119	<#assign gpxRutaJSONObject = jsonFactoryUtil.createJSONObject(Documentos.GPXRuta.data)! /> 
120	<#assign gpxRoute = gpxTool.parser(gpxRutaJSONObject.getLong("classPK"), "Parser", themeDisplay)! /> 
121	 
122</#if> 
123<#if validator.isNotNull(Documentos.GPXPOIRuta.data) && Documentos.GPXPOIRuta.getData()!=""> 
124	<#assign gpxPOIRutaJSONStr = Documentos.GPXPOIRuta.data! /> 
125	<#assign gpxPOIRutaPath = dlTool.getPathByJSON(gpxPOIRutaJSONStr, themeDisplay.getScopeGroupId())!/> 
126	<#assign gpxPOIRutaJSONObject = jsonFactoryUtil.createJSONObject(Documentos.GPXPOIRuta.data)! /> 
127	<#assign gpxPOIRoute = gpxTool.parser(gpxPOIRutaJSONObject.getLong("classPK"), "Parser", themeDisplay)! /> 
128</#if> 
129 
130 
131 
132 
133<#-- Near routes --> 
134<#assign gpxRoutes = [] /> 
135<#assign classTypeIds = [structureId]/> 
136<#assign routesNearJournalArticles = assetNearTool.getNearJournalArticles(themeDisplay.getScopeGroupId(), assetEntry.getEntryId(), 50.0, classTypeIds, 5, true, [])! /> 
137<#list routesNearJournalArticles as routeNearJournalArticle> 
138 
139	<#assign routeNearJournalArticleArticleId = routeNearJournalArticle.getArticleId()! > 
140	<#assign routeNearJournalArticleResourcePrimKey = routeNearJournalArticle.getResourcePrimKey()! > 
141	<#assign routeNearJournalArticleJSONObject = journalTool.contentXMLtoJSONObject(routeNearJournalArticle.getContentByLocale(locale), locale)/> 
142	<#assign routeNearJournalArticleEntryTitle = htmlUtil.escape(routeNearJournalArticle.getTitle(locale)) /> 
143	<#assign routeNearJournalArticleViewURL = journalTool.getDisplayPage(routeNearJournalArticle, themeDisplay, true) /> 
144	<#assign routeNearJournalArticleThumbnailPath = routeNearJournalArticle.getSmallImageURL()! /> 
145	<#assign routeNearJournalArticleThumbnail = dlTool.getThumbnail(routeNearJournalArticleThumbnailPath, "2", layoutSetBannerPath)! /> 
146 
147	<#-- Categories --> 
148	<#assign rutaCercanaTipoRuta = "" /> 
149	<#assign rutaCercanaModalidad = "" /> 
150	<#assign rutaCercanaTipoRecorrido = "" /> 
151	<#assign rutaCercanaTipoRecorridos = "" /> 
152	<#assign rutaCercanaColor = "000" /> 
153	<#assign journalArticleCategories = assetCategoryLocalService.getCategories("com.liferay.journal.model.JournalArticle", routeNearJournalArticleResourcePrimKey) /> 
154	<#list journalArticleCategories as journalArticleCategory> 
155 
156		<#assign vocabularyId = journalArticleCategory.getVocabularyId() /> 
157		<#assign level = 1 /> 
158		<#if validator.isNotNull(journalArticleCategory.getAncestors())> 
159			<#assign level = journalArticleCategory.getAncestors()?size + 1 /> 
160		</#if> 
161 
162		<#if vocabularyId == routeTypeVocabulary.getVocabularyId()> 
163			<#assign rutaCercanaTipoRuta = journalArticleCategory.getTitle(locale) /> 
164		</#if> 
165 
166		<#if vocabularyId == modeVocabulary.getVocabularyId()> 
167			<#assign rutaCercanaModalidad = journalArticleCategory.getTitle(locale) /> 
168		</#if> 
169 
170		<#if vocabularyId == trackVocabulary.getVocabularyId()> 
171			<#assign rutaCercanaTipoRecorrido = journalArticleCategory.getTitle(locale) /> 
172		</#if> 
173 
174		<#if vocabularyId == tracksVocabulary.getVocabularyId()> 
175			<#if level == 1> 
176				<#assign type = assetCategoryTool.getCategoryProperty(journalArticleCategory.getCategoryId(), "type") /> 
177				<#if type != "links"> 
178					<#assign rutaCercanaColor = assetCategoryTool.getCategoryProperty(journalArticleCategory.getCategoryId(), "color") /> 
179					<#assign rutaCercanaTipoRecorridos = journalArticleCategory.getTitle(locale) /> 
180				</#if> 
181			</#if> 
182		</#if> 
183		 
184	</#list> 
185	 
186	<#assign rutaCercanaIbp = routeNearJournalArticleJSONObject.getString("IBP")! /> 
187	<#assign rutaCercanaDistancia = routeNearJournalArticleJSONObject.getString("Distancia")! /> 
188	<#assign rutaCercanaInicio = routeNearJournalArticleJSONObject.getString("Inicio")! /> 
189	<#assign rutaCercanaFinalizacion = routeNearJournalArticleJSONObject.getString("Finalizacion")! /> 
190	<#assign rutaCercanaGpxRuta = routeNearJournalArticleJSONObject.getJSONObject("Documentos").getString("GPXRuta")! /> 
191	<#assign rutaCercanaGpxPOIRuta = routeNearJournalArticleJSONObject.getJSONObject("Documentos").getString("GPXPOIRuta")! /> 
192	<#assign rutaCercanaKmlRuta = routeNearJournalArticleJSONObject.getJSONObject("Documentos").getString("KMLRuta")! /> 
193	<#assign rutaCercanaDenominacion = routeNearJournalArticleJSONObject.getString("Denominacion")! /> 
194	<#if validator.isNotNull(rutaCercanaDenominacion)> 
195		<#assign routeNearJournalArticleEntryTitle = rutaCercanaDenominacion !/> 
196	</#if> 
197	 
198	<#assign rutaCercanaInicioFinalizacion = rutaCercanaInicio! /> 
199	<#if validator.isNotNull(rutaCercanaFinalizacion)> 
200		<#assign rutaCercanaInicioFinalizacion = rutaCercanaInicio + " - " + rutaCercanaFinalizacion !/> 
201	</#if> 
202	 
203	<#if validator.isNotNull(rutaCercanaGpxRuta)> 
204		<#assign gpxRutaJSONObject = jsonFactoryUtil.createJSONObject(rutaCercanaGpxRuta)! /> 
205		<#assign jsonGPX = gpxTool.parser(gpxRutaJSONObject.getLong("classPK"), "Parser", themeDisplay)! /> 
206			 
207		<#assign jsonGPX = jsonGPX.put("articleId", routeNearJournalArticleArticleId)! /> 
208		<#assign jsonGPX = jsonGPX.put("color", rutaCercanaColor)! /> 
209		<#assign jsonGPX = jsonGPX.put("url", routeNearJournalArticleViewURL)! /> 
210		<#assign jsonGPX = jsonGPX.put("title", routeNearJournalArticleEntryTitle)! /> 
211		<#assign jsonGPX = jsonGPX.put("image", routeNearJournalArticleThumbnail)! /> 
212		<#assign jsonGPX = jsonGPX.put("startEnd", rutaCercanaInicioFinalizacion)! /> 
213		<#assign jsonGPX = jsonGPX.put("routeTypes", rutaCercanaTipoRecorridos)! /> 
214		<#assign jsonGPX = jsonGPX.put("ibp", rutaCercanaIbp)! /> 
215		<#assign jsonGPX = jsonGPX.put("mode", rutaCercanaModalidad)! /> 
216		<#assign jsonGPX = jsonGPX.put("distance", rutaCercanaDistancia)! /> 
217		 
218		<#assign gpxRoutes = gpxRoutes + [jsonGPX] /> 
219	</#if> 
220	 
221</#list> 
222 
223<#-- ALT destacada --> 
224<#assign altImgDestacada = title /> 
225<#if AltImagenDestacada ??> 
226	<#if validator.isNotNull(AltImagenDestacada.getData())> 
227		<#assign altImgDestacada = AltImagenDestacada.getData() /> 
228	</#if> 
229</#if> 
230 
231<article class="template template-cicloturismo template-layout-map template-route template-${ddmStructureNameNormalize} position-relative" role="article" itemscope itemtype="http://schema.org/TravelAction"> 
232 
233	<div class="container"> 
234	<div class="row no-gutters"> 
235		<div class="col-md-5 col-12 col-sidebar"> 
236		 
237		<h2 class="article-title" itemprop="name">${title}</h2> 
238 
239		<div id="article-display-container" class="hide"> 
240			<button id="close-article-display" type="button" class="btn btn-light"> 
241				<span class="fas fa-times"><span class="hide-accessible">${languageUtil.get(locale, "close")}</span></span> 
242			</button> 
243			<div id="article-display"></div> 
244		</div> 
245 
246		<div id="search-container"> 
247 
248			<#if validator.isNotNull(description)> 
249				<div class="article-description" itemprop="description"> 
250					${htmlUtil.extractText(description)} 
251				</div> 
252			</#if> 
253 
254			<#if Avisos.TituloAviso.getSiblings()?has_content> 
255				<#assign noticeCoordinatesIndex = 1 /> 
256				<#list Avisos.TituloAviso.getSiblings() as tituloAviso> 
257				 
258					<#-- Schduler --> 
259					<#assign fechaPublicacion = ""/> 
260					<#assign fechaExpiracion = ""/> 
261					<#assign nowDateTime = .now?long /> 
262					<#assign scheduler = true /> 
263					<#if validator.isNotNull(tituloAviso.FechaPublicacionAviso.getData()) && validator.isNotNull(tituloAviso.FechaPublicacionAviso.HoraPublicacionAviso.getData())> 
264						<#assign fechaPublicacion = "${tituloAviso.FechaPublicacionAviso.getData()} ${tituloAviso.FechaPublicacionAviso.HoraPublicacionAviso.getData()}"/> 
265						<#assign fechaPublicacion = fechaPublicacion?datetime("yyyy-MM-dd HH:mm:ss")/> 
266						 
267						<#assign fechaPublicacion = fechaPublicacion?long/>				 
268					</#if> 
269					<#if validator.isNotNull(tituloAviso.FechaExpiracionAviso.getData()) && validator.isNotNull(tituloAviso.FechaExpiracionAviso.HoraExpiracionAviso.getData())> 
270						<#assign fechaExpiracion = "${tituloAviso.FechaExpiracionAviso.getData()} ${tituloAviso.FechaExpiracionAviso.HoraExpiracionAviso.getData()}"/> 
271						<#assign fechaExpiracion = fechaExpiracion?datetime("yyyy-MM-dd HH:mm:ss")/> 
272						<#assign fechaExpiracion = fechaExpiracion?long/> 
273					</#if> 
274 
275					<#-- Filter --> 
276					<#if validator.isNull(tituloAviso.getData()) > 
277							<#assign scheduler = false /> 
278					</#if> 
279					<#if validator.isNotNull(fechaPublicacion) && validator.isNotNull(fechaExpiracion)> 
280						<#if !((nowDateTime gte fechaPublicacion) && (nowDateTime lte fechaExpiracion))> 
281							<#assign scheduler = false /> 
282						</#if> 
283					</#if> 
284					 
285					<#if scheduler> 
286 
287						<#assign routeAlertCssClass = "route-alert alert ${tituloAviso.TipoAviso.getData()} mb-3 alert-dismissible fade hide"/> 
288 
289						<#assign markerNoticeCoordinates = (tituloAviso.CoordenadasAviso??)?then(tituloAviso.CoordenadasAviso.getData(),'') /> 
290						<#if validator.isNotNull(markerNoticeCoordinates)> 
291							<#assign noticeCoordinatesIndex = noticeCoordinatesIndex + 1 /> 
292							<#assign routeAlertCssClass = routeAlertCssClass + " route-alert-coordinates"/> 
293						</#if> 
294 
295						<div id="route-${articleId}-alert-coordinates-${noticeCoordinatesIndex}" class="${routeAlertCssClass}" role="alert"> 
296 
297							<#assign markerNoticeIcon = "fa-solid fa-triangle-exclamation" /> 
298							<div class="alert-title-wrapper"> 
299								<span class="alert-icon"> 
300									<#switch tituloAviso.TipoAviso.getData()> 
301										<#case "alert-info"> 
302											<i class="fa-solid fa-info"><!--icon--></i> 
303											<#assign markerNoticeIcon = "fa-solid fa-info" /> 
304											<#break> 
305										<#case "alert-success"> 
306											<i class="fa-regular fa-circle-check"><!--icon--></i> 
307											<#assign markerNoticeIcon = "fa-solid fa-check" /> 
308											<#break> 
309										<#case "alert-warning"> 
310											<i class="fa-solid fa-triangle-exclamation"><!--icon--></i> 
311											<#assign markerNoticeIcon = "fa-solid fa-triangle-exclamation" /> 
312											<#break> 
313										<#case "alert-danger"> 
314											<i class="fa-solid fa-ban"><!--icon--></i> 
315											<#assign markerNoticeIcon = "fa-solid fa-ban" /> 
316											<#break> 
317										<#default> 
318											<i class="${markerNoticeIcon}"><!--icon--></i> 
319									</#switch> 
320								</span> 
321 
322								<#if validator.isNotNull(markerNoticeCoordinates)> 
323									<#assign markerNotice = {"id": noticeCoordinatesIndex, "title": tituloAviso.getData(), "description": tituloAviso.DescripcionAviso.getData(), "type": tituloAviso.TipoAviso.getData(), "icon": markerNoticeIcon, "coordinates": markerNoticeCoordinates} /> 
324									<#assign markersNotices = arrayUtil.append(markersNotices, markerNotice) /> 
325								</#if> 
326 
327								<#if validator.isNotNull(tituloAviso.getData())> 
328									<p class="alert-title">${stringUtil.replace(tituloAviso.getData(),"\n", "<br/>")}</p> 
329								</#if> 
330							</div> 
331 
332							<#if validator.isNotNull(tituloAviso.DescripcionAviso.getData())> 
333								<div class="alert-description">${tituloAviso.DescripcionAviso.getData()}</div> 
334							</#if> 
335 
336							<button type="button" class="close" data-dismiss="alert" aria-label="Close"> 
337								<span aria-hidden="true">&times;</span> 
338							</button> 
339						</div> 
340					</#if> 
341				</#list> 
342			</#if> 
343		 
344			<#assign slideImagesCount = 0 /> 
345			<#assign slideImagesSize = Visualizador.Imagen.getSiblings()?size /> 
346			<#if  Visualizador.Imagen.getSiblings()?has_content || validator.isNotNull(smallImageUrl)> 
347				<div id="article-carousel" class="carousel slide carousel-fade carousel-article" data-ride="carousel" data-interval="5000"> 
348					<span aria-hidden="true" class="loading-animation loading-bg"></span> 
349					<div class="carousel-inner"> 
350						<#if validator.isNotNull(smallImageUrl)> 
351							<div class="carousel-item active aspect-ratio-bg-cover" style="background-image: url(${articleMainImageThumbnail3});"> 
352								<img class="hide" src="${articleMainImageThumbnail1}" alt="${altImgDestacada}" title="${altImgDestacada}"/> 
353							</div> 
354							<#assign slideImagesCount = slideImagesCount + 1 /> 
355						</#if> 
356						<#list 0..2 as item> 
357							<#if item < Visualizador.Imagen.getSiblings()?size > 
358								<#assign Slide = Visualizador.Imagen.getSiblings()[item]!/> 
359								<#if Slide?? && validator.isNotNull(Slide) && Slide.data?? && validator.isNotNull(Slide.data)> 
360 
361									<#assign slideThumbnail1 = dlTool.getThumbnailByJSON(Slide.data, "1")! /> 
362									<#assign slideThumbnail3 = dlTool.getThumbnailByJSON(Slide.data, "3")! /> 
363									<#assign slideTitle = "${languageUtil.get(request, 'image')} ${title}" /> 
364									<#assign slideAlt = slideTitle /> 
365									<#if Slide.TituloImagen?? && Slide.TituloImagen.data?has_content> 
366										<#assign slideTitle = Slide.TituloImagen.data />   
367										<#assign slideAlt = slideTitle /> 
368									</#if> 
369									<#if Slide.AltImagen?? && validator.isNotNull(Slide.AltImagen.getData())> 
370										<#assign slideAlt = Slide.AltImagen.getData() /> 
371									</#if> 
372								<#else> 
373									<#continue> 
374								</#if> 
375								<div class="carousel-item aspect-ratio-bg-cover" style="background-image: url(${slideThumbnail3});"> 
376									<img class="hide" src="${slideThumbnail1}" alt="${slideAlt}" title="${slideTitle}"/> 
377								</div> 
378								<#assign slideImagesCount = slideImagesCount + 1 /> 
379							</#if> 
380						</#list> 
381					</div> 
382					<a class="carousel-control-prev" href="#article-carousel" data-slide="prev"> 
383						<span class="carousel-control-prev-icon" aria-hidden="true"><!-- ${languageUtil.get(request, "previous")} --></span> 
384						<span class="hide-accessible">${languageUtil.get(request, "previous")}</span> 
385					</a> 
386					<a class="carousel-control-next" href="#article-carousel" data-slide="next"> 
387						<span class="carousel-control-next-icon" aria-hidden="true"><!-- ${languageUtil.get(request, "next")}--></span> 
388						<span class="hide-accessible">${languageUtil.get(request, "next")}</span> 
389					</a> 
390					<ol class="carousel-indicators d-none"> 
391						<#assign index = 0 /> 
392						<#list 1..slideImagesCount as item> 
393							<li data-target="#article-carousel" data-slide-to="${index}" <#if index==0> class="active"</#if>></li> 
394							<#assign index = index + 1 /> 
395						</#list> 
396					</ol> 
397				</div> 
398			</#if> 
399			 
400			<div class="article-data-wrapper"> 
401			<#if validator.isNotNull(concejos) || validator.isNotNull(Distancia.getData()) || validator.isNotNull(dificultad) || validator.isNotNull(DesnivelAcumulado.getData()) || validator.isNotNull(AltitudMaxima.getData()) 
402			|| validator.isNotNull(AltitudMaxima.getData()) || validator.isNotNull(AltitudMinima.getData()) || validator.isNotNull(IBP.getData()) || validator.isNotNull(tipoRuta) || validator.isNotNull(modalidad) 
403			|| validator.isNotNull(tipoRecorrido) || getterUtil.getBoolean(Transporte.Retorno.getData())> 
404					 
405					<#if validator.isNotNull(PoblacionesPrincipales.getData())> 
406						<ul class="article-list list-unstyled article-list-info"> 
407							<li class="article-list-item"> 
408								<span class="fas fa-map-marker-alt"> 
409									<span class="hide-accessible">${languageUtil.get(request,"address")}</span> 
410								</span>											 
411								<span class="field-wrapper" itemprop="address">						 
412									<span class="text d-block important">${PoblacionesPrincipales.getData()}</span> 
413									<#assign zoneNames = [] /> 
414									<#if concejos?size gt 0> 
415										<#list concejos as concejo> 
416											<#if concejo.getParentCategoryId() == 0> 
417												<#if !zoneNames?seq_contains("${concejo.getTitle(locale)}")> 
418													<#assign zoneNames = zoneNames + ["${concejo.getTitle(locale)}"]/> 
419												</#if> 
420											</#if> 
421										</#list> 
422										<#if validator.isNotNull(zoneNames)> 
423											<span class="text zones d-block">${zoneNames?join(", ")}</span> 
424										</#if> 
425									</#if> 
426								</span> 
427							</li> 
428						</ul> 
429					</#if> 
430				 
431					<div class="article-info-table"> 
432					<div class="article-info-table-row"> 
433						<div class="article-info-table-cell"> 
434						<ul class="article-list list-unstyled article-list-info"> 
435						<#if validator.isNotNull(Distancia.getData())> 
436							<li class="article-list-item"> 
437								<span class="fas fa-ruler-horizontal"> 
438									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-distancia")}</span> 
439								</span> 
440								<span class="field-wrapper"> 
441									<span class="field">${languageUtil.get(request, "infoasturias-distancia")}:</span>	 
442									<span class="text text-featured">${Distancia.getData()} kms</span> 
443								</span> 
444							</li> 
445						</#if> 
446						<#if validator.isNotNull(dificultad) && dificultad?has_content> 
447							<li class="article-list-item"> 
448								<span class="fas fa-layer-group"> 
449									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-dificultad")}</span> 
450								</span> 
451								<span class="field-wrapper"> 
452									<span class="field">${languageUtil.get(request, "infoasturias-dificultad")}:</span> 
453									<span class="text">${dificultad[0].getTitle(locale)}</span> 
454								</span> 
455							</li> 
456						</#if> 
457						<#if validator.isNotNull(DesnivelAcumulado.getData())> 
458							<li class="article-list-item"> 
459								<span class="fas fa-chart-line">	 
460									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-ascenso-acumulado")}</span> 
461								</span> 
462								<span class="field-wrapper"> 
463									<span class="field">${languageUtil.get(request, "infoasturias-route-ascenso-acumulado")}:</span> 
464									<span class="text">${DesnivelAcumulado.data} m</span> 
465								</span> 
466							</li> 
467						</#if> 
468						<#if validator.isNotNull(AltitudMaxima.getData())> 
469							<li class="article-list-item"> 
470								<span class="fas fa-ruler-vertical"> 
471									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-altitud-maxima")}</span> 
472								</span> 
473								<span class="field-wrapper"> 
474									<span class="field">${languageUtil.get(request, "infoasturias-route-altitud-maxima")}:</span> 
475									<span class="text">${AltitudMaxima.data} m</span> 
476								</span> 
477							</li> 
478						</#if> 
479						<#if validator.isNotNull(AltitudMinima.getData())> 
480							<li class="article-list-item"> 
481								<span class="fas fa-ruler-vertical"> 
482									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-altitud-minima")}</span> 
483								</span> 
484								<span class="field-wrapper"> 
485									<span class="field">${languageUtil.get(request, "infoasturias-route-altitud-minima")}:</span> 
486									<span class="text">${AltitudMinima.data} m</span> 
487								</span> 
488							</li> 
489						</#if> 
490						<#if validator.isNotNull(IBP.getData())> 
491							<li class="article-list-item"> 
492								<span class="fas fa-mountain"> 
493									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-ibp-index")}</span> 
494								</span> 
495								<span class="field-wrapper"> 
496									<span class="field">${languageUtil.get(request, "infoasturias-route-ibp-index")}:</span> 
497									<span class="text">${IBP.data}</span> 
498								</span> 
499							</li> 
500						</#if> 
501						</ul> 
502						</div> 
503						<div class="article-info-table-cell"> 
504							<ul class="article-list list-unstyled article-list-info"> 
505								<#if validator.isNotNull(tipoRecorridos)> 
506									<li class="article-list-item"> 
507										<span class="fas fa-bicycle"> 
508											<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-recorrido")}</span> 
509										</span> 
510										<span class="field-wrapper"> 
511											<span class="field">${tipoRecorridos}</span> 
512										</span> 
513									</li> 
514								</#if> 
515								<#if validator.isNotNull(modalidad)> 
516									<li class="article-list-item"> 
517										<span class="fas fa-bicycle"> 
518											<span class="hide-accessible">${modeVocabulary.getDescription(locale)}</span> 
519										</span> 
520										<span class="field-wrapper"> 
521											<span class="field">${modeVocabulary.getDescription(locale)}:</span> 
522											<span class="text">${modalidad}</span> 
523										</span> 
524									</li> 
525								</#if> 
526								<#if validator.isNotNull(tipoRecorrido)> 
527									<li class="article-list-item"> 
528										<span class="fas fa-route"> 
529											<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-tipo-recorrido")}</span> 
530										</span> 
531										<span class="field-wrapper"> 
532											<span class="field">${languageUtil.get(request, "infoasturias-route-tipo-recorrido")}:</span> 
533											<span class="text">${tipoRecorrido}</span> 
534										</span> 
535									</li> 
536								</#if> 
537								<li class="article-list-item"> 
538									<span class="fas fa-train"> 
539										<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-retorno-ferrocarril")}</span> 
540									</span> 
541									<span class="field-wrapper"> 
542									<span class="field">${languageUtil.get(request, "infoasturias-route-retorno-ferrocarril")}:</span> 
543									<#if getterUtil.getBoolean(Transporte.Retorno.getData())> 
544										<span class="text">${languageUtil.get(locale, "yes")}</span> 
545									<#else> 
546										<span class="text">${languageUtil.get(locale, "no")}</span> 
547									</#if> 
548									</span> 
549								</li> 
550								<#if validator.isNotNull(Transporte.Empresa.getData()) && getterUtil.getBoolean(Transporte.Retorno.getData())> 
551									<li class="article-list-item"> 
552										<span class="fas fa-train"> 
553											<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-retorno-ferrocarril")}</span> 
554										</span> 
555										<span class="field-wrapper"> 
556										<span class="field">${Transporte.Empresa.getData()} 
557											<#if validator.isNotNull(Transporte.WebInformativa.getData())> 
558												<#list Transporte.WebInformativa.getSiblings() as web> 
559													<a class="fas fa-external-link-alt" href="${web.getData()}" onclick="this.target='_blank'" title="${languageUtil.get(locale, 'go-to')} ${web.getData()}"> 
560														<span class="hide-accessible">${web.getData()}</span> 
561													</a> 
562												</#list> 
563											</#if> 
564										</span> 
565										</span> 
566									</li> 
567								</#if> 
568							</ul> 
569						</div> 
570					</div> 
571				 
572				<div class="article-info-table-row"> 
573					<div class="article-info-table-cell"> 
574					<ul class="article-list list-unstyled article-list-info"> 
575						<#if validator.isNotNull(Inicio.getData())> 
576							<li class="article-list-item"> 
577								<span class="fas fa-map-marker"> 
578									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-lugar-inicio")}</span> 
579								</span> 
580								<span class="field-wrapper"> 
581								<span class="field">${languageUtil.get(request, "infoasturias-route-lugar-inicio")}:</span> 
582									<span class="text">${Inicio.getData()}</span> 
583								</span> 
584							</li> 
585						</#if> 
586						<#if validator.isNotNull(Finalizacion.getData())> 
587							<li class="article-list-item"> 
588								<span class="fas fa-map-marker"> 
589									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-lugar-finalizacion")}</span> 
590								</span> 
591								<span class="field-wrapper"> 
592								<span class="field">${languageUtil.get(request, "infoasturias-route-lugar-finalizacion")}:</span> 
593									<span class="text">${Finalizacion.getData()}</span> 
594								</span> 
595							</li> 
596						</#if> 
597						<#if validator.isNotNull(duracion)> 
598							<li class="article-list-item"> 
599								<span class="fas fa-stopwatch"> 
600									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-duracion-estimada")}</span> 
601								</span> 
602								<span class="field-wrapper"> 
603								<span class="field">${languageUtil.get(request, "infoasturias-route-duracion-estimada")}:</span> 
604									<span class="text">${duracion}</span> 
605								</span> 
606							</li> 
607						</#if> 
608						 
609					</ul> 
610					</div> 
611					<div class="article-info-table-cell"> 
612						<#if validator.isNotNull(Documentos.GPXRuta.getData()) || validator.isNotNull(Documentos.GPXPOIRuta.getData()) || validator.isNotNull(Documentos.KMLRuta.getData())> 
613							<ul class="article-list article-list-documents"> 
614								<#if validator.isNotNull(Documentos.GPXRuta.getData())> 
615									<li class="article-list-item"> 
616									<span class="field-wrapper"> 
617									<a class="btn btn-border btn-inline-block btn-thin" href="${Documentos.GPXRuta.getData()}" onclick="this.target='_blank'" title="${languageUtil.get(request, 'infoasturias-download')} GPX"> 
618										<i class="fas fa-file-download"><!--icon--></i> ${languageUtil.format(request, "infoasturias-route-format", "GPX")} 
619									</a> 
620									</span> 
621									</li> 
622								</#if> 
623								<#if validator.isNotNull(Documentos.GPXPOIRuta.getData())> 
624									<li class="article-list-item"> 
625									<span class="field-wrapper"> 
626									<a class="btn btn-border btn-inline-block btn-thin" href="${Documentos.GPXPOIRuta.getData()}" onclick="this.target='_blank'"  title="${languageUtil.get(request, 'infoasturias-download')} POI GPX"> 
627										<i class="fas fa-file-download"><!--icon--></i> ${languageUtil.format(request, "infoasturias-poi-format", "GPX") } 
628									</a> 
629									</span> 
630									</li> 
631								</#if> 
632								<#if validator.isNotNull(Documentos.KMLRuta.getData())> 
633									<li class="article-list-item"> 
634									<span class="field-wrapper"> 
635									<a class="btn btn-border btn-inline-block btn-thin" href="${Documentos.KMLRuta.getData()}" onclick="this.target='_blank'"  title="${languageUtil.get(request, 'infoasturias-download')} KML"> 
636										<i class="fas fa-file-download"><!--icon--></i>  ${languageUtil.format(request, "infoasturias-route-format", "KML")} 
637									</a> 
638									</span> 
639									</li> 
640								</#if> 
641							</ul> 
642						</#if> 
643					</div> 
644				</div> 
645			</#if> 
646 
647			</div> 
648			 
649			<div class="leaflet-elevation-wrapper" id="elevation-div-${articleId}"> 
650				<div class="btn-route-ctrl-wrapper"> 
651					<button id="userLocation" type="button" class="btn-circle-icon btn-route-ctrl btn-route-ctrl-location text-white active bottom d-md-none"> 
652						<span class="fa-solid fa-location-crosshairs"><span class="hide-accessible">${languageUtil.format(request, "infoasturias-route-format", "KMZ")}</span> 
653					</button> 
654					<button id="toggleElevation" type="button" class="btn-circle-icon btn-route-ctrl btn-route-ctrl-elevation btn-selected text-white active bottom d-md-none"> 
655						<span class="fa-solid fa-chart-line"><span class="hide-accessible">${languageUtil.format(request, "infoasturias-route-format", "KMZ")}</span> 
656					</button> 
657				</div> 
658			</div> 
659			 
660			</div> 
661			 
662			<#if validator.isNotNull(DescripcionCorta.getData()) || validator.isNotNull(DescripcionLarga.getData())> 
663				<div class="article-text-wrapper article-panel-wrapper article-panel-wrapper-white"> 
664 
665					<div class="article-social-bookmarks article-social-bookmarks-circle text-right"> 
666						<@liferay_social_bookmarks["bookmarks"] 
667							className="com.liferay.journal.model.JournalArticle" 
668							classPK=assetEntry.getEntryId() 
669							displayStyle="menu" 
670							target="_blank" 
671							title=title 
672							types=articleSocialBookmarks 
673							url="${articleURL}" 
674						/> 
675					</div> 
676 
677					<div class="article-text article-panel"> 
678 
679						<#if validator.isNotNull(DescripcionCorta.getData())> 
680							<div class="article-short-description">${DescripcionCorta.getData()}</div> 
681						</#if> 
682						<#if validator.isNotNull(DescripcionLarga.getData()) || validator.isNotNull(Observaciones.getData())> 
683							<div class="article-long-description-wrapper"> 
684							 
685								<#if validator.isNotNull(DescripcionLarga.getData())> 
686									<div class="article-long-description">${DescripcionLarga.getData()}</div> 
687								</#if> 
688 
689								<#if validator.isNotNull(Observaciones.getData())> 
690									<div class="article-observations">${Observaciones.getData()}</div> 
691								</#if> 
692							</div> 
693						</#if> 
694						 
695						<#assign slideImagesCount = slideImagesCount - 1 /> 
696						<#if slideImagesSize gt slideImagesCount > 
697							<#assign index = 0 /> 
698							<div id="article-carousel-round" class="carousel slide carousel-fade carousel-article" data-ride="carousel" data-interval="5000"> 
699								<span aria-hidden="true" class="loading-animation loading-bg"></span> 
700								<div class="carousel-inner"> 
701									<#list slideImagesCount..slideImagesSize-1 as item> 
702										<#assign Slide = Visualizador.Imagen.getSiblings()[item]/> 
703										<#assign slideThumbnail1 = dlTool.getThumbnailByJSON(Slide.data, "1")! /> 
704										<#assign slideThumbnail3 = dlTool.getThumbnailByJSON(Slide.data, "3")! /> 
705										<#assign slideTitle = "${languageUtil.get(request, 'image')} ${title}" /> 
706										<#assign slideAlt = slideTitle /> 
707										<#if Slide.TituloImagen.data?has_content> 
708											<#assign slideTitle = Slide.TituloImagen.data />   
709											<#assign slideAlt = slideTitle /> 
710										</#if> 
711										<#if Slide.AltImagen?? && validator.isNotNull(Slide.AltImagen.getData())> 
712											<#assign slideAlt = Slide.AltImagen.getData() /> 
713										</#if> 
714										<div class="carousel-item aspect-ratio-bg-cover <#if index==0> active</#if>" style="background-image: url(${slideThumbnail3});"> 
715											<img class="hide" src="${slideThumbnail1}" alt="${slideAlt}"  title="${slideTitle}"/> 
716										</div> 
717										<#assign index = index + 1 /> 
718									</#list> 
719								</div> 
720 
721								<#if (index>1)> 
722									<a class="carousel-control-prev" href="#article-carousel-round" data-slide="prev"> 
723										<span class="carousel-control-prev-icon" aria-hidden="true"><!-- ${languageUtil.get(request, "previous")} --></span> 
724										<span class="hide-accessible">${languageUtil.get(request, "previous")}</span> 
725									</a> 
726									<a class="carousel-control-next" href="#article-carousel-round" data-slide="next"> 
727										<span class="carousel-control-next-icon" aria-hidden="true"><!-- ${languageUtil.get(request, "next")}--></span> 
728										<span class="hide-accessible">${languageUtil.get(request, "next")}</span> 
729									</a> 
730									<ol class="carousel-indicators d-none"> 
731										<#assign index = 0 /> 
732										<#list slideImagesCount..slideImagesSize-1 as item> 
733											<li data-target="#article-carousel-round" data-slide-to="${index}" <#if index==0> class="active"</#if>></li> 
734											<#assign index = index + 1 /> 
735										</#list> 
736									</ol> 
737								</#if> 
738							</div> 
739						</#if> 
740					</div> 
741				</div> 
742			</#if> 
743			 
744			<#-- PDI -->		 
745			<#assign arrayPDIs = [] /> 
746			<#if  PDI.getSiblings()?has_content && validator.isNotNull(PDI.getSiblings()[0]) && (PDI.getSiblings()[0].JournalPDI.data?has_content || PDI.getSiblings()[0].TituloPDI.data?has_content)> 
747				<div class="article-panel-wrapper"> 
748					<div class="article-panel"> 
749						<h3 class="title-section">${languageUtil.get(request,'infoasturias-pois')}</h3> 
750						<div class="slide-wrapper"> 
751							<div id="slick-pdi" class="slick slick-slider"> 
752								<#assign pdiCount = 0 /> 
753								<#list PDI.getSiblings() as pdi> 
754									<#assign journalPDIComarcas = "" /> 
755									<#assign pdiJSONObject = "" /> 
756									<#assign pdiArticleId = "" /> 
757									<#assign pdiURL = "#" /> 
758									<#assign pdiTitle = "" /> 
759									<#assign pdiImgAlt = "" /> 
760									<#assign pdiImgTitle = "" /> 
761									<#assign pdiDescription = "" /> 
762									<#assign smallImageThumbnail2 = "" /> 
763									<#if validator.isNotNull(pdi.JournalPDI.getData()) || (validator.isNotNull(pdi.TituloPDI.getData()) && validator.isNotNull(pdi.TituloPDI.ImagenPDI.getData()))> 
764										<#if validator.isNotNull(pdi.JournalPDI.getData())> 
765											<#assign pdiJSON = pdi.JournalPDI.data?eval/> 
766											<#assign journalPDI = journalTool.getJournalArticleByResourcePrimKey(getterUtil.getLong(pdiJSON.classPK))/> 
767											<#if validator.isNotNull(journalPDI)> 
768												<#assign pdiAssetEntry = journalTool.getAssetEntryByArticleId(journalPDI.getGroupId(), journalPDI.getArticleId())/>  
769												<#if validator.isNotNull(pdiAssetEntry)> 
770													<#assign journalPDIComarcas = journalTool.getCategoriesNames(groupId, journalPDI.getArticleId(), locale, ["Comarcas"])/> 
771													<#assign pdiURL = assetPublisherTool.getAssetViewURL(renderRequest, renderResponse, pdiAssetEntry) /> 
772													<#assign smallImageThumbnail2 = dlTool.getThumbnail(journalPDI.getSmallImageURL(), "2", layoutSetBannerPath)! /> 
773													<#assign pdiArticleId = journalPDI.getArticleId() /> 
774													<#assign pdiId = journalPDI.getArticleId() /> 
775													<#assign pdiTitle = journalPDI.getTitle(locale)! /> 
776													<#assign pdiDescription = stringUtil.shorten(htmlUtil.extractText(journalPDI.getDescription(locale)), 150)! /> 
777													<#assign pdiCoordinates = journalTool.getJournalArticleField(groupId, journalPDI.getArticleId(), "Coordenadas")! /> 
778													 
779													<#assign pdiJSONObject = jsonFactoryUtil.createJSONObject()! /> 
780													<#assign pdiJSONObject = pdiJSONObject.put("articleId", journalPDI.getArticleId())! /> 
781													<#assign pdiJSONObject = pdiJSONObject.put("title", pdiTitle)! /> 
782													<#assign pdiJSONObject = pdiJSONObject.put("description", pdiDescription)! /> 
783													<#assign pdiJSONObject = pdiJSONObject.put("subtitle", journalPDIComarcas)! /> 
784													<#assign pdiJSONObject = pdiJSONObject.put("image", smallImageThumbnail2)! /> 
785													<#assign pdiJSONObject = pdiJSONObject.put("url", pdiURL)! /> 
786													<#assign pdiJSONObject = pdiJSONObject.put("coordinates", pdiCoordinates)! /> 
787													<#assign pdiJSONObject = pdiJSONObject.put("icon", "")! /> 
788													<#if pdi.IconFontAwesomePDI?? && validator.isNotNull(pdi.IconFontAwesomePDI.getData())> 
789														<#assign pdiJSONObject = pdiJSONObject.put("icon", pdi.IconFontAwesomePDI.getData())! /> 
790													</#if> 
791												</#if> 
792											</#if> 
793										<#elseif validator.isNotNull(pdi.TituloPDI.getData()) && validator.isNotNull(pdi.TituloPDI.ImagenPDI.getData())> 
794 
795											<#assign pdiId = pdiCount! /> 
796											<#assign pdiTitle = pdi.TituloPDI.getData()! /> 
797											<#assign pdiImgAlt = pdi.TituloPDI.getData()! /> 
798											<#assign pdiImgTitle = pdi.TituloPDI.getData()! /> 
799											<#assign pdiCoordinates = pdi.TituloPDI.CoordenadasPDI.getData()! /> 
800											<#assign smallImageThumbnail2 = dlTool.getThumbnail(pdi.TituloPDI.ImagenPDI.getData(), "2", layoutSetBannerPath)! /> 
801											<#if pdi.TituloPDI.ImagenPDI.TitleImagenPDI??> 
802												<#if validator.isNotNull(pdi.TituloPDI.ImagenPDI.TitleImagenPDI.getData())> 
803													<#assign pdiImgTitle = pdi.TituloPDI.ImagenPDI.TitleImagenPDI.getData()/> 
804												</#if> 
805											</#if> 
806											<#if pdi.TituloPDI.ImagenPDI.AltImagenPDI??> 
807												<#if validator.isNotNull(pdi.TituloPDI.ImagenPDI.AltImagenPDI.getData())> 
808													<#assign pdiImgAlt = pdi.TituloPDI.ImagenPDI.AltImagenPDI.getData()/> 
809												</#if> 
810											</#if> 
811											<#assign pdiJSONObject = jsonFactoryUtil.createJSONObject()! /> 
812											<#assign pdiJSONObject = pdiJSONObject.put("articleId", pdiId)! /> 
813											<#assign pdiJSONObject = pdiJSONObject.put("title", pdiTitle)! /> 
814											<#assign pdiJSONObject = pdiJSONObject.put("description", "")! /> 
815											<#assign pdiJSONObject = pdiJSONObject.put("subtitle", "")! /> 
816											<#assign pdiJSONObject = pdiJSONObject.put("image", smallImageThumbnail2)! /> 
817											<#assign pdiJSONObject = pdiJSONObject.put("url", "")! /> 
818											<#assign pdiJSONObject = pdiJSONObject.put("coordinates", pdiCoordinates)! /> 
819											<#assign pdiJSONObject = pdiJSONObject.put("icon", "")! /> 
820											<#if pdi.IconFontAwesomePDI?? && validator.isNotNull(pdi.IconFontAwesomePDI.getData())> 
821												<#assign pdiJSONObject = pdiJSONObject.put("icon", pdi.IconFontAwesomePDI.getData())! /> 
822											</#if> 
823										</#if> 
824										<#if validator.isNotNull(pdiJSONObject)> 
825											<#assign arrayPDIs = arrayPDIs + [pdiJSONObject] /> 
826										</#if> 
827 
828										<div class="slide"> 
829											<a class="card poi" href="${pdiURL}" data-articleid="${pdiArticleId}" data-id="poi-${pdiId}" title="${languageUtil.format(request, 'go-to-x', htmlUtil.escape(pdiTitle))}"> 
830												<span class="d-block image-wrapper aspect-ratio-bg-cover aspect-ratio-4-to-3" style="background-image: url(${smallImageThumbnail2});"> 
831													<img class="hide-accessible" src="${smallImageThumbnail2}" alt="${pdiImgAlt}" /> 
832													<#if validator.isNotNull(pdiDescription)> 
833														<span class="card-hover"> 
834															<span class="card-hover-text" itemprop="description"> 
835																${pdiDescription} 
836															</span> 
837														</span> 
838													</#if> 
839												</span> 
840												<span class="card-body"> 
841													<span class="card-title">${pdiTitle}</span> 
842													<#if validator.isNotNull(journalPDIComarcas)> 
843														<span class="card-subtitle">${journalPDIComarcas}</span> 
844													</#if> 
845												</span> 
846											</a> 
847										</div> 
848										<#assign pdiCount = pdiCount + 1 /> 
849									</#if> 
850								</#list> 
851							</div> 
852						</div> 
853					</div> 
854				</div> 
855 
856				<script type="text/javascript"> 
857 
858					// bootstrap 4 breakpoints 
859					var breakpoint${namespace} = { 
860						// small screen / phone 
861						sm: 576, 
862						// medium screen / tablet 
863						md: 768, 
864						// large screen / desktop 
865						lg: 992, 
866						// extra large screen / wide desktop 
867						xl: 1200 
868					}; 
869 
870					// bootstrap 4 responsive multi column slick carousel 
871					$('#slick-pdi').slick({ 
872						autoplay: false, 
873						autoplaySpeed: 1000, 
874						draggable: true, 
875						pauseOnHover: false, 
876						infinite: false, 
877						dots: false, 
878						arrows: true, 
879						speed: 1000, 
880						mobileFirst: true, 
881						slidesToShow: 1, 
882						slidesToScroll: 1, 
883						centerMode: false, 
884						responsive: [{ 
885							breakpoint: breakpoint${namespace}.sm, 
886							settings: { 
887							slidesToShow: 1, 
888							slidesToScroll: 1 
889
890						}, 
891
892							breakpoint: breakpoint${namespace}.md, 
893							settings: { 
894							slidesToShow: 2, 
895							slidesToScroll: 1 
896
897						}, 
898
899							breakpoint: breakpoint${namespace}.lg, 
900							settings: { 
901							slidesToShow: 2, 
902							slidesToScroll: 1 
903
904						}, 
905
906							breakpoint: breakpoint${namespace}.xl, 
907							settings: { 
908							slidesToShow: 2, 
909							slidesToScroll: 1 
910
911
912
913					}); 
914				</script> 
915			</#if> 
916			 
917			<#-- Services --> 
918			<#assign servicesNearJournalArticles = [] /> 
919			<div id="services-panel" class="article-panel-wrapper article-panel-services hide"> 
920				<div class="article-panel"> 
921					<h3 class="title-section">${languageUtil.get(request,'infoasturias-route-services')}</h3> 
922					 
923					<div class="filter-categories mb-4"> 
924 
925						<#list filterDDMStructures as filterDDMStructure> 
926 
927							<#assign filterStructureCustomNameKey = "${filterDDMStructure.getStructureId()}[customName]"/> 
928							<#assign filterStructureCustomNameValue = group.getTypeSettingsProperty(filterStructureCustomNameKey)!/> 
929 
930							<#assign filterStructureKey = filterDDMStructure.getStructureKey()! /> 
931							<#assign filterStructureName = filterDDMStructure.getName(locale) /> 
932							<#assign filterStructureDescription = filterDDMStructure.getDescription(locale) /> 
933							 
934 
935							<#if validator.isNotNull(filterStructureDescription)> 
936								<#assign filterStructureName = filterStructureDescription! /> 
937							</#if> 
938 
939							<#if validator.isNotNull(filterStructureCustomNameValue)> 
940								<#assign filterStructureName = languageUtil.get(request, filterStructureCustomNameValue)! /> 
941							</#if> 
942 
943							<a class="button-vocabulary-structure btn btn-border btn-thin mb-1 disabled-service" href="#" id="button-vocabulary-structure-id-${filterStructureKey}" data-vocabulary-structure-id="${filterStructureKey}">${filterStructureName}</a> 
944 
945						</#list> 
946 
947					</div> 
948					 
949					<div id="services-entries-container" class="slide-wrapper lfr-spa-loading"> 
950						<div class="lfr-spa-loading-spinner" style="position: absolute;"></div> 
951						<ul class="slider slick slick-slider pl-0"></ul> 
952						<@liferay_aui["script"] use="aui-base"> 
953							$(function() { 
954								$(".slider").slick({ 
955									arrows: true, 
956									dots: false, 
957									slidesToShow: 2, 
958									slidesToScroll: 1, 
959									mobileFirst: false, 
960									centerMode: false, 
961									infinite: false, 
962									responsive: [{ 
963										breakpoint: breakpoint${namespace}.sm, 
964										settings: { 
965										slidesToShow: 1, 
966										slidesToScroll: 1 
967
968									}, 
969
970										breakpoint: breakpoint${namespace}.md, 
971										settings: { 
972										slidesToShow: 2, 
973										slidesToScroll: 1 
974
975									}, 
976
977										breakpoint: breakpoint${namespace}.lg, 
978										settings: { 
979										slidesToShow: 2, 
980										slidesToScroll: 1 
981
982									}, 
983
984										breakpoint: breakpoint${namespace}.xl, 
985										settings: { 
986										slidesToShow: 2, 
987										slidesToScroll: 1 
988
989
990
991								}); 
992							}); 
993						</@> 
994					</div> 
995				</div> 
996			</div> 
997			 
998			<#if validator.isNotNull(routesNearJournalArticles) && routesNearJournalArticles?size gt 0> 
999				<div class="article-panel-wrapper article-panel-wrapper-white template-routes"> 
1000					<div class="article-panel"> 
1001					<h3 class="title-section">${languageUtil.get(request,'infoasturias-routes-near-here')}</h3> 
1002					<div class="slide-wrapper"> 
1003						<div id="slick-near" class="slick slick-slider"> 
1004							<#list routesNearJournalArticles as currentJournalArticle> 
1005								<#assign viewURL = journalTool.getDisplayPage(currentJournalArticle, themeDisplay, true)/> 
1006								<#assign smallImageThumbnail2 = dlTool.getThumbnail(currentJournalArticle.getSmallImageURL(), "2", layoutSetBannerPath)! /> 
1007								<#assign routeTitle = currentJournalArticle.getTitle(locale)/> 
1008								<#assign denominacion = journalTool.getJournalArticleField(currentJournalArticle.getGroupId(), currentJournalArticle.getArticleId(), "Denominacion", locale)/> 
1009								<#assign assetEntry = journalTool.getAssetEntryByArticleId(groupId, articleId)> 
1010								<#if validator.isNotNull(denominacion)> 
1011									<#assign routeTitle = denominacion /> 
1012								</#if> 
1013								<div class="slide"> 
1014									<a class="card route-near" data-id="route-near-${currentJournalArticle.getArticleId()}" href="${viewURL}" title="${languageUtil.format(request, 'go-to-x', routeTitle)}"> 
1015										<span class="d-block image-wrapper aspect-ratio-bg-cover aspect-ratio-4-to-3" style="background-image: url('${smallImageThumbnail2}');"> 
1016											<img class="hide-accessible" src="${smallImageThumbnail2}" alt="${routeTitle}"> 
1017											<#if validator.isNotNull(htmlUtil.extractText(currentJournalArticle.getDescription(locale)))> 
1018												<span class="card-hover"> 
1019													<span class="card-hover-text" itemprop="description"> 
1020														${stringUtil.shorten(htmlUtil.extractText(currentJournalArticle.getDescription(locale)), 150)} 
1021													</span> 
1022												</span> 
1023											</#if> 
1024										</span> 
1025										<span class="card-body"> 
1026											<span class="card-title">${routeTitle}</span> 
1027											<span class="card-subtitle"> 
1028												<#-- <span class="d-block">${currentJournalArticle.getVersion()} Kms</span>--> 
1029												<#assign currentJournalArticleConcejos = journalTool.getCategoriesNames(groupId, currentJournalArticle.getArticleId(), locale, ["Concejos"])/> 
1030												<#if validator.isNotNull(currentJournalArticleConcejos)> 
1031													<#assign currentJournalArticleConcejos = stringUtil.replace(currentJournalArticleConcejos,",",", ") /> 
1032													<span class="d-block">${currentJournalArticleConcejos}</span> 
1033												</#if> 
1034											</span> 
1035										</span> 
1036									</a> 
1037								</div> 
1038							</#list> 
1039						</div> 
1040					</div> 
1041					</div> 
1042				</div> 
1043 
1044				<script type="text/javascript"> 
1045 
1046					// bootstrap 4 breakpoints 
1047					var breakpoint${namespace} = { 
1048						// small screen / phone 
1049						sm: 576, 
1050						// medium screen / tablet 
1051						md: 768, 
1052						// large screen / desktop 
1053						lg: 992, 
1054						// extra large screen / wide desktop 
1055						xl: 1200 
1056					}; 
1057 
1058					// bootstrap 4 responsive multi column slick carousel 
1059					$('#slick-near').slick({ 
1060						autoplay: false, 
1061						autoplaySpeed: 1000, 
1062						draggable: true, 
1063						pauseOnHover: false, 
1064						infinite: false, 
1065						dots: false, 
1066						arrows: true, 
1067						speed: 1000, 
1068						mobileFirst: true, 
1069						slidesToShow: 1, 
1070						slidesToScroll: 1, 
1071						centerMode: false, 
1072						responsive: [{ 
1073							breakpoint: breakpoint${namespace}.sm, 
1074							settings: { 
1075							slidesToShow: 1, 
1076							slidesToScroll: 1 
1077
1078						}, 
1079
1080							breakpoint: breakpoint${namespace}.md, 
1081							settings: { 
1082							slidesToShow: 2, 
1083							slidesToScroll: 1 
1084
1085						}, 
1086
1087							breakpoint: breakpoint${namespace}.lg, 
1088							settings: { 
1089							slidesToShow: 2, 
1090							slidesToScroll: 1 
1091
1092						}, 
1093
1094							breakpoint: breakpoint${namespace}.xl, 
1095							settings: { 
1096							slidesToShow: 2, 
1097							slidesToScroll: 1 
1098
1099
1100
1101					}); 
1102				</script> 
1103			</#if> 
1104			</div> 
1105		</div> 
1106		 
1107		<div class="col-md-7 col-12 col-map d-md-inline-block d-none"> 
1108			<div id="map" class="lfr-spa-loading"> 
1109				<div class="lfr-spa-loading-spinner" style="position: absolute;"></div> 
1110				 
1111				<#if validator.isNotNull(filterStructuresIds)> 
1112					<div id="map-filter" class="hide"> 
1113						<div class="vocabularies"> 
1114							<#list filterStructuresIds as filterStructuresId> 
1115								<#assign filterStructure = ddmStructureLocalService.fetchDDMStructure(filterStructuresId)/> 
1116								<#if validator.isNotNull(filterStructure)> 
1117									<#assign filterStructureKey = filterStructure.getStructureKey()/> 
1118										<#assign markersServicesDDMStructureKeys = arrayUtil.append(markersServicesDDMStructureKeys, filterStructureKey) /> 
1119										<#assign filterStructureFontAwesomeKey = "${filterStructure.getStructureId()}[fontAwesome]"/> 
1120										<#assign filterStructureFontAwesomeValue = group.getTypeSettingsProperty(filterStructureFontAwesomeKey)!/> 
1121										<#assign filterStructureVocabularyKey = "${filterStructure.getStructureId()}[vocabularyId]"/> 
1122										<#assign filterStructureVocabularyValue = getterUtil.getLong(group.getTypeSettingsProperty(filterStructureVocabularyKey))!/> 
1123										<#assign filterStructurevocabularyLevelCategoriesKey = "${filterStructure.getStructureId()}[vocabularyLevelCategories]"/> 
1124										<#assign filterStructurevocabularyLevelCategoriesValue = group.getTypeSettingsProperty(filterStructurevocabularyLevelCategoriesKey)!1/> 
1125										<#assign filterStructurevocabularyCategoryIdsKey = "${filterStructure.getStructureId()}[vocabularyCategoryIds]"/> 
1126										<#assign filterStructurevocabularyCategoryIdsValue = group.getTypeSettingsProperty(filterStructurevocabularyCategoryIdsKey)!/> 
1127										<#assign filterStructurevocabularyTagsKey = "${filterStructure.getStructureId()}[vocabularyTags]"/> 
1128										<#assign filterStructurevocabularyTagsValue = group.getTypeSettingsProperty(filterStructurevocabularyTagsKey)!/> 
1129										<#assign filterStructureCustomNameKey = "${filterStructure.getStructureId()}[customName]"/> 
1130										<#assign filterStructureCustomNameValue = group.getTypeSettingsProperty(filterStructureCustomNameKey)!/> 
1131										<#assign filterStructureStructureIdsKey = "${filterStructure.getStructureId()}[filterStructuresIds]"/> 
1132										<#assign filterStructureStructureIdsValues = group.getTypeSettingsProperty(filterStructureStructureIdsKey)!/> 
1133 
1134										<#-- Cicloturismo Settings --> 
1135										<#assign filterStructureCardSubtitleCategoryIdsValue = "" /> 
1136										<#if validator.isNotNull(ddmStructureSettingsJSONObject) && ddmStructureSettingsJSONObject.has(filterStructureName)> 
1137 
1138											<#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).has("icon")> 
1139												<#assign filterStructureFontAwesomeValue = ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getString("icon")/> 
1140											</#if> 
1141 
1142											<#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).has("label")> 
1143												<#assign filterStructureCustomNameValue = ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getString("label")/> 
1144											</#if> 
1145 
1146											<#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).has("cardSubtitleCategoryIds")> 
1147												<#assign filterStructureCardSubtitleCategoryIdsValue = ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getString("cardSubtitleCategoryIds")/> 
1148											</#if> 
1149 
1150											<#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).has("filters")> 
1151 
1152												<#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").has("vocabularyId")> 
1153													<#assign filterStructureVocabularyValue = ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").getLong("vocabularyId")/> 
1154												</#if> 
1155 
1156												<#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").has("vocabularyLevelCategories")> 
1157													<#assign filterStructurevocabularyLevelCategoriesValue = ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").getString("vocabularyLevelCategories", "1")/> 
1158												</#if> 
1159 
1160												<#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").has("vocabularyCategoryIds")> 
1161													<#assign filterStructurevocabularyCategoryIdsValue = ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").getString("vocabularyCategoryIds")/> 
1162												</#if> 
1163 
1164												<#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").has("vocabularyTags")> 
1165													<#assign filterStructurevocabularyTagsValue = ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").getString("vocabularyTags")/> 
1166												</#if> 
1167 
1168												<#if ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").has("filterStructuresIds")> 
1169													<#assign filterStructureStructureIdsValues = ddmStructureSettingsJSONObject.getJSONObject(filterStructureName).getJSONObject("filters").getString("filterStructuresIds")/> 
1170												</#if> 
1171 
1172											</#if> 
1173 
1174										</#if> 
1175 
1176										<#assign filterStructureStructureKeys = [filterStructureKey]/> 
1177										<#if validator.isNotNull(filterStructureStructureIdsValues)> 
1178											<#list stringUtil.split(filterStructureStructureIdsValues) as filterStructureStructureIdsValue> 
1179												<#assign ddmStructure = ddmStructureLocalService.fetchDDMStructure(getterUtil.getLong(filterStructureStructureIdsValue))! /> 
1180												<#if validator.isNotNull(ddmStructure)> 
1181													<#assign filterStructureStructureKeys = filterStructureStructureKeys + [ddmStructure.getStructureKey()]/> 
1182												</#if> 
1183											</#list> 
1184										</#if> 
1185										 
1186										<#assign filterStructureJSONObject = jsonFactoryUtil.createJSONObject()> 
1187										<#assign filterStructureJSONObject = filterStructureJSONObject.put("structureId", filterStructuresId)! /> 
1188										<#assign filterStructureJSONObject = filterStructureJSONObject.put("structureKey", filterStructureKey)! /> 
1189										<#assign filterStructureJSONObject = filterStructureJSONObject.put("fontAwesome", filterStructureFontAwesomeValue)! /> 
1190										<#assign filterStructureJSONObject = filterStructureJSONObject.put("vocabularyId", filterStructureVocabularyValue)! /> 
1191										<#assign filterStructureJSONObject = filterStructureJSONObject.put("vocabularyLevelCategories", filterStructurevocabularyLevelCategoriesValue)! /> 
1192										<#assign filterStructureJSONObject = filterStructureJSONObject.put("vocabularyCategoryIds", filterStructurevocabularyCategoryIdsValue)! /> 
1193										<#assign filterStructureJSONObject = filterStructureJSONObject.put("vocabularyTags", filterStructurevocabularyTagsValue)! /> 
1194										<#assign filterStructureJSONObject = filterStructureJSONObject.put("cardSubtitleCategoryIds", filterStructureCardSubtitleCategoryIdsValue)! /> 
1195										<#assign filterStructureJSONObject = filterStructureJSONObject.put("name", filterStructure.getName(locale))! /> 
1196										<#assign filterStructureJSONObject = filterStructureJSONObject.put("customName", filterStructureCustomNameValue)! /> 
1197										<#assign filterStructureJSONObject = filterStructureJSONObject.put("description", filterStructure.getDescription(locale))! /> 
1198										<#assign filterStructureJSONObject = filterStructureJSONObject.put("structureKeys", stringUtil.merge(filterStructureStructureKeys))! /> 
1199										<#assign filterStructures = filterStructures + [filterStructureJSONObject] /> 
1200 
1201									<#assign filterStructureName = filterStructure.getName(locale) /> 
1202									<#assign filterStructureDescription = filterStructure.getDescription(locale) /> 
1203									 
1204									<#if validator.isNotNull(filterStructureDescription)> 
1205										<#assign filterStructureName = filterStructureDescription! /> 
1206									</#if> 
1207 
1208									<#if validator.isNotNull(filterStructureCustomNameValue)> 
1209										<#assign filterStructureName = languageUtil.get(request, filterStructureCustomNameValue)! /> 
1210									</#if> 
1211									 
1212									<div class="vocabulary-wrapper disabled-service" title="${filterStructureName}" data-structurekey="${filterStructure.getStructureKey()}"> 
1213										<div class="vocabulary" id="vocabulary-structure-id-${filterStructure.getStructureKey()}" data-vocabulary-structure-id="${filterStructure.getStructureKey()}"> 
1214											<span class="icon ${filterStructureFontAwesomeValue}"><span class="hide-accessible">${filterStructureName}</span></span> 
1215										</div> 
1216										<#if validator.isNotNull(filterStructureVocabularyValue)> 
1217 
1218											<#assign filterStructureVocabulary = assetVocabularyLocalService.fetchAssetVocabulary(filterStructureVocabularyValue)! /> 
1219											<#assign filterStructureVocabularyCategories = assetCategoryTool.getAssetCategoriesByVocabulary(filterStructureVocabulary, getterUtil.getInteger(filterStructurevocabularyLevelCategoriesValue))! /> 
1220 
1221											<#if validator.isNotNull(filterStructureVocabularyCategories)> 
1222												<div class="categories"> 
1223													<#list filterStructureVocabularyCategories as filterStructureVocabularyCategory> 
1224														<div class="category category-${filterStructureVocabularyCategory.getCategoryId()} hide"> 
1225															<input type="checkbox" name="category-${filterStructureVocabularyCategory.getCategoryId()}" id="category-${filterStructureVocabularyCategory.getCategoryId()}" data-id="${filterStructureVocabularyCategory.getCategoryId()}" /> 
1226															<label for="category-${filterStructureVocabularyCategory.getCategoryId()}">${filterStructureVocabularyCategory.getTitle(locale)}</label> 
1227														</div> 
1228													</#list> 
1229												</div> 
1230											</#if> 
1231										</#if> 
1232									</div> 
1233								</#if> 
1234							</#list> 
1235						</div> 
1236					</div> 
1237				</#if> 
1238			</div> 
1239		</div> 
1240	</div> 
1241	</div> 
1242	 
1243</article> 
1244 
1245<@liferay_aui["script"] use="aui-base, anim, aui-io-request, cookie, async-queue, node-event-simulate"> 
1246 
1247	var mapZoom = ${getterUtil.getInteger(mapZoom, 12)};//MapZoom 
1248	var mapLat = ${getterUtil.getString(mapLat, "43.362597693870434")};//MapLat 
1249	var mapLng = ${getterUtil.getString(mapLng, "-5.846235457402242")};//MapLng 
1250	var osm = new L.TileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', 
1251
1252			attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>' 
1253
1254	); 
1255	 
1256	var map = new L.map('map', {center: [${gpxRoute.get("centerLatLon")}], zoom: mapZoom, zoomControl: false, minZoom: 9, bounceAtZoomLimits: false, layers: [osm]}); 
1257	map.doubleClickZoom.disable(); 
1258	map.whenReady(function(){ 
1259		A.one('#map').removeClass('lfr-spa-loading'); 
1260	}); 
1261	 
1262	//Map Height 
1263	mapFullHeight(scroll=true, map); 
1264	 
1265	//FilterStructures 
1266	var fontAwesomeIconClassCSS = []; 
1267	<#list filterStructures as filterStructure> 
1268		fontAwesomeIconClassCSS['${filterStructure["structureKey"]}'] = { 
1269			cssClass:'${filterStructure["fontAwesome"]}',  
1270			vocabularyId: ${filterStructure["vocabularyId"]},  
1271			vocabularyLevelCategories: ${filterStructure["vocabularyLevelCategories"]}, 
1272			vocabularyTags: '${filterStructure["vocabularyTags"]}', 
1273			cardSubtitleCategoryIds: '${filterStructure["cardSubtitleCategoryIds"]}' 
1274		}; 
1275	</#list> 
1276	 
1277	//ServiceMarkers 
1278	var serviceMarkers = []; 
1279	var markersServicesGroups = {}; 
1280	var servicesContainer = A.one('#services-entries-container'); 
1281	var mapFilter = A.one('#map-filter'); 
1282	var servicesPanel = A.one('#services-panel'); 
1283	 
1284	Liferay.provide(window,'journalArticlesResourcesCount', function(deltaParam, structureKeys, anyCategoryIds, allCategoryIds, anyTagNames, allTagNames, vocabularyIds){ 
1285		var url = '/o/asac-web-services/ws/journalArticlesResourcesCount'; 
1286		A.io.request(url, { 
1287			method: 'GET', 
1288			type: 'JSON', 
1289			data: { 
1290				companyId: ${companyId}, 
1291				groupId: ${groupId}, 
1292				structureKeys: structureKeys, 
1293				anyCategoryIds: assetAnyCategoryIds, 
1294				allCategoryIds: assetAllCategoryIds, 
1295				anyTagNames: anyTagNames, 
1296				allTagNames: allTagNames, 
1297				coordinates: '[${gpxRoute.get("coordinatesLatLonSplit")}]', 
1298				coordinatesDistance: ${routeDetailServicesDistance} 
1299			}, 
1300			on: { 
1301				success: function() { 
1302					var count = this.get('responseData'); 
1303					if(count>deltaParam){ 
1304						var pages = Math.ceil(count/deltaParam); 
1305						for(var cur = 0; cur < pages; cur++){ 
1306							journalArticlesResources(cur, deltaParam, structureKeys, anyCategoryIds, allCategoryIds, anyTagNames, allTagNames, vocabularyIds, count); 
1307
1308					}else{ 
1309						var cur  = -1; 
1310						var delta  = -1; 
1311						journalArticlesResources(cur, deltaParam, structureKeys, anyCategoryIds, allCategoryIds, anyTagNames, allTagNames, vocabularyIds, count); 
1312
1313
1314
1315		}); 
1316	}); 
1317	 
1318	Liferay.provide(window,'journalArticlesResources', function(cur, delta, structureKeys, anyCategoryIds, allCategoryIds, anyTagNames, allTagNames, vocabularyIds, total){ 
1319		var structureKey = structureKeys.split(',')[0]; 
1320		var url = '/o/asac-web-services/ws/journalArticlesResources'; 
1321		A.io.request(url, { 
1322			method: 'GET', 
1323			type: 'JSON', 
1324			data: { 
1325				companyId: ${companyId}, 
1326				groupId: ${groupId}, 
1327				structureKeys: structureKeys, 
1328				anyCategoryIds: anyCategoryIds, 
1329				allCategoryIds: allCategoryIds, 
1330				anyTagNames: anyTagNames, 
1331				allTagNames: allTagNames, 
1332				coordinates: '[${gpxRoute.get("coordinatesLatLonSplit")}]', 
1333				coordinatesDistance: ${routeDetailServicesDistance}, 
1334				projectionAssetCategoriesVocabularyIds: vocabularyIds, 
1335				cur: cur, 
1336				delta: delta, 
1337			}, 
1338			on: { 
1339				success: function() { 
1340					var vocabularyId = 0; 
1341					var points = JSON.parse(this.get('responseData')); 
1342					if(points && points.length>0){ 
1343						var slickAddHTML = ''; 
1344						for(var index in points) { 
1345						 
1346							var point = points[index]; 
1347							var articleId = point.articleId; 
1348							var title = point.title; 
1349							var descriptionText = point.descriptionText; 
1350							var assetCategories = point.assetCategories; 
1351							var subTypeId = point.subTypeId; //structureKey 
1352							var subTypeName = point.subTypeName; //structureName 
1353							var coordinates = point.coordinates; 
1354							var detailURL = point.detailURL; 
1355							var detailFullURL = point.detailFullURL; 
1356							if(detailFullURL!='') 
1357								detailURL = detailFullURL; 
1358							var image = point.image; 
1359							var imageThumbnail2 = point.imageThumbnail2; 
1360							var icon = fontAwesomeIconClassCSS[subTypeId].cssClass; 
1361							var vocabularyId = (vocabularyId==0) ? fontAwesomeIconClassCSS[subTypeId].vocabularyId : vocabularyId; 
1362							var vocabularyLevelCategories = fontAwesomeIconClassCSS[subTypeId].vocabularyLevelCategories; 
1363							var cardSubtitleCategoryIds = fontAwesomeIconClassCSS[subTypeId].cardSubtitleCategoryIds; 
1364							var concejosVocabularyId = ${concejosVocabulary.getVocabularyId()}; 
1365							var pointGroups = []; 
1366							 
1367							const fontAwesomeIcon = L.divIcon({ 
1368								className: 'marker-wrapper', 
1369								html: "<div class='marker-icon-blue'><i class='"+icon+"'><!-- icon--></i></div>", 
1370								iconSize: [26, 30], 
1371								iconAnchor: [13, 30] 
1372							}); 
1373 
1374							if(coordinates!=''){ 
1375								var latLng = coordinates.split(','); 
1376								if(!isNaN(latLng[0]) && !isNaN(latLng[1])){ 
1377									var pointGroup = ''; 
1378									var categoryTitle = ''; 
1379									var categoryId = ''; 
1380									var categoryConcejos = []; 
1381									var categoryIds = []; 
1382									var categoryTitles = []; 
1383									var pointGroups = []; 
1384									for(var assetCategoriesIndex in assetCategories) { 
1385 
1386										var assetCategory = assetCategories[assetCategoriesIndex]; 
1387										if(assetCategory){ 
1388 
1389											categoryId = assetCategory.categoryId; 
1390											categoryTitle = assetCategory.title; 
1391 
1392											//Concejos 
1393											if(assetCategory.vocabularyId==concejosVocabularyId){ 
1394												if(!categoryConcejos.includes(assetCategory.title)) 
1395													categoryConcejos.push(assetCategory.title); 
1396
1397 
1398											if(assetCategory.vocabularyId==vocabularyId){ 
1399 
1400												//Filter 
1401												if(vocabularyLevelCategories && vocabularyLevelCategories>0){ 
1402													var level = assetCategory.level; 
1403													if(vocabularyLevelCategories!=level) 
1404														continue; 
1405
1406 
1407												if(markersServicesGroups && markersServicesGroups[categoryId]){ 
1408													pointGroup = markersServicesGroups[categoryId]; 
1409												}else{ 
1410													var pointGroup = L.markerClusterGroup({ 
1411														maxClusterRadius: 100, 
1412														showCoverageOnHover: false, 
1413														//zoomToBoundsOnClick: false, 
1414														//spiderfyOnMaxZoom: false, 
1415														iconCreateFunction: function(cluster) { 
1416															var childMarkers = cluster.getAllChildMarkers(); 
1417															var n = 0; 
1418															for (var i = 0; i < childMarkers.length; i++) { 
1419																n += 1; 
1420
1421															return L.divIcon({ 
1422																className: 'marker-wrapper', 
1423																html: "<div class='marker-circle'>"+n+"</i></div>", 
1424																iconSize: [26, 30], 
1425																iconAnchor: [13, 5] 
1426															}); 
1427
1428													}); 
1429													markersServicesGroups[categoryId] = pointGroup; 
1430
1431 
1432												if(pointGroup) 
1433													pointGroups.push(pointGroup); 
1434 
1435												if(categoryTitle!='' && !categoryTitles.includes(categoryTitle)){ 
1436													if(cardSubtitleCategoryIds=='' || (cardSubtitleCategoryIds.split(",").includes(categoryId))) 
1437														categoryTitles.push(categoryTitle); 
1438
1439 
1440												if(categoryId!='' && !categoryIds.includes(categoryId)) 
1441													categoryIds.push(categoryId); 
1442													 
1443												var serviceFilterCategory = A.one('.categories .category-'+categoryId) 
1444												if(serviceFilterCategory) 
1445													serviceFilterCategory.show(); 
1446
1447
1448
1449								 
1450									var popupContentTemplate = '<a data-articleid="'+articleId+'" href="'+detailURL+'" class="popup popup-service">'+ 
1451									'<span class="popup-image-wrapper" style="background-image: url('+imageThumbnail2+');"><!-- image--></span>'+ 
1452									'<span class="popup-body">'+ 
1453									'<span class="popup-subtitle">'+categoryTitles.join()+'</span>'+ 
1454									'<span class="popup-title">'+title+'</span>'+ 
1455									'<span class="popup-desciption">'+descriptionText+'</span>'+ 
1456									'</span>'+ 
1457									'</a>'; 
1458 
1459									var newNodeObject = A.Node.create(popupContentTemplate); 
1460									newNodeObject.on('click', function(event){ 
1461										event.preventDefault(); 
1462										var nodeArticleId = this.attr('data-articleid'); 
1463										${namespace}getArticleDisplay(nodeArticleId); 
1464									}); 
1465								 
1466									var marker = L.marker([latLng[0],latLng[1]],  
1467
1468											"icon": fontAwesomeIcon, 
1469											"title": title 
1470
1471									); 
1472									marker.articleId='service-'+articleId; 
1473									marker.bindPopup(newNodeObject.getDOMNode()); 
1474									marker.on('popupopen', function(e) { 
1475										map.panTo(this.getLatLng()); 
1476									}); 
1477									marker.on('popupclose', function(e) { 
1478										${namespace}closeArticleDisplay(); 
1479									}); 
1480									//markersServicesGroup.addLayer(marker); 
1481									 
1482									for(var pointGroupsIndex in pointGroups) { 
1483										var pointGroup = pointGroups[pointGroupsIndex]; 
1484										if(pointGroup) 
1485											pointGroup.addLayer(marker); 
1486
1487 
1488									serviceMarkers.push(marker); 
1489 
1490									//CreateObject 
1491									var entry = A.Node.create('<div class="slide service-structure service-structure-'+subTypeId+' '+categoryIds.map(id => 'service-category-' + id).join(' ')+'"></div>'); 
1492									var anchor = A.Node.create('<a onclick="event.preventDefault(); ${namespace}getArticleDisplay('+articleId+');" class="card service item-card" data-articleid="'+articleId+'" data-id="service-'+articleId+'" href="'+detailURL+'" title="'+title+'"></a>'); 
1493									var anchorImageWrapper = A.Node.create('<span class="d-block image-wrapper aspect-ratio-bg-cover aspect-ratio-4-to-3"></span>'); 
1494									if(descriptionText!=''){ 
1495										var anchorImageWrapperHover = A.Node.create('<span class="card-hover"></span>'); 
1496										var anchorImageWrapperHoverDescription = A.Node.create('<span class="card-hover-text" itemprop="description">'+descriptionText+'</span>'); 
1497										anchorImageWrapperHover.append(anchorImageWrapperHoverDescription); 
1498										anchorImageWrapper.append(anchorImageWrapperHover); 
1499
1500									var anchorImage = A.Node.create('<img class="" src="'+imageThumbnail2+'" alt="'+title+'" loading="lazy" onload="this.parentElement.style.backgroundImage = \'url(\'+this.src+\')\'; this.classList.add(\'hide-accessible\');" />'); 
1501									var anchorBody = A.Node.create('<span class="card-body"></span>'); 
1502									var anchorTitle = A.Node.create('<span class="card-title">'+title+'</span>'); 
1503									var anchorCategories = A.Node.create('<span class="card-categories">'+categoryTitles.join()+'</span>'); 
1504									var anchorConcejos = A.Node.create('<span class="card-subtitle">'+categoryConcejos.join()+'</span>'); 
1505									 
1506									anchorImageWrapper.append(anchorImage); 
1507									anchor.append(anchorImageWrapper); 
1508									anchorBody.append(anchorTitle); 
1509									anchorBody.append(anchorCategories); 
1510									anchorBody.append(anchorConcejos); 
1511									anchor.append(anchorBody); 
1512									 
1513									entry.append(anchor); 
1514 
1515									slickAddHTML += '<li class="service-structure-'+subTypeId+' '+categoryIds.map(id => 'service-category-' + id).join(' ')+'">'+entry.outerHTML()+'</li>'; 
1516
1517
1518
1519						$('.slider').slick('slickAdd', slickAddHTML); 
1520 
1521						A.all('.card.service').each(function(item){ 
1522							item.on('mouseover', function(event){ 
1523								var articleId = item.getAttribute("data-id"); 
1524								${namespace}markerServicePopup(articleId, true); 
1525							}); 
1526							item.on('mouseout', function(event){ 
1527								var articleId = item.getAttribute("data-id"); 
1528								${namespace}markerServicePopup(articleId, false); 
1529							}); 
1530						}); 
1531 
1532						var vocabularyWrapper = A.one('.vocabulary-wrapper[data-structurekey="' + structureKey + '"]'); 
1533						var vocabularyButtonWrapper = A.one('.filter-categories .button-vocabulary-structure[data-vocabulary-structure-id="' + structureKey + '"]'); 
1534						if(vocabularyWrapper){ 
1535							vocabularyWrapper.addClass("selectable"); 
1536							vocabularyWrapper.one('.vocabulary').on('click', function(){ 
1537								if($(window).width() > 768) 
1538									${namespace}toggleMarkersServicesStructure(structureKey); 
1539								else 
1540									vocabularyWrapper.toggleClass('hover'); 
1541 
1542							}); 
1543							vocabularyWrapper.removeClass("disabled-service"); 
1544							if(vocabularyButtonWrapper) 
1545								vocabularyButtonWrapper.removeClass("disabled-service"); 
1546
1547
1548 
1549					if(serviceMarkers && serviceMarkers.length>0){ 
1550						if(servicesPanel) 
1551							servicesPanel.show(); 
1552						if(mapFilter) 
1553							mapFilter.show(); 
1554
1555
1556
1557		}); 
1558	}); 
1559	 
1560	<#list filterStructures as filterStructure> 
1561	 
1562		var structureKeys = '${filterStructure["structureKeys"]}'; 
1563		var assetAnyCategoryIds = '${filterStructure["vocabularyCategoryIds"]}'; 
1564		var assetAllCategoryIds = ''; 
1565		var assetAnyTags = ''; 
1566		var assetAllTags = ''; 
1567		var vocabularyIds = '${filterStructure["vocabularyId"]},${concejosVocabulary.getVocabularyId()}'; 
1568		var delta = 500; 
1569		journalArticlesResourcesCount(delta, structureKeys, assetAnyCategoryIds, assetAllCategoryIds, assetAnyTags, assetAllTags, vocabularyIds); 
1570		servicesContainer.removeClass('lfr-spa-loading'); 
1571		 
1572	</#list> 
1573 
1574	//Filter categories 
1575	//console.log(markersServicesGroups); 
1576	A.all('.categories input').each(function(item){ 
1577		item.on('click', function(){ 
1578 
1579			var categoryIds = []; 
1580			var categoryIdsCssClass = ''; 
1581			var vocabularyWrapper = item.ancestor('.vocabulary-wrapper'); 
1582			var vocabulary = vocabularyWrapper.one('.vocabulary'); 
1583			var categoryId = item.getAttribute('data-id'); 
1584			var structureId = vocabulary.getAttribute('data-vocabulary-structure-id'); 
1585			var button = A.one('#button-vocabulary-structure-id-'+structureId); 
1586			var pointsGroup = markersServicesGroups[categoryId]; 
1587			 
1588			if(pointsGroup){ 
1589				if(item.attr('checked')){ 
1590					map.addLayer(pointsGroup); 
1591				}else{ 
1592					map.removeLayer(pointsGroup); 
1593
1594
1595			if(item.attr('checked')){ 
1596				vocabularyWrapper.addClass('selected'); 
1597				button.addClass('selected'); 
1598			}else{ 
1599				var flag = true; 
1600				var categories = vocabularyWrapper.all('.categories input').each(function(index){ 
1601					if(index.attr('checked')) 
1602						flag = false; 
1603				}); 
1604				if(flag){ 
1605					vocabularyWrapper.removeClass('selected'); 
1606					button.removeClass('selected'); 
1607
1608
1609 
1610			A.all('.categories input').each(function(index){ 
1611				if(index.attr('checked')){ 
1612					var categoryId = index.getAttribute('data-id'); 
1613					categoryIds.push('.service-category-'+categoryId); 
1614
1615			}); 
1616 
1617			$(".slider").slick('slickUnfilter'); 
1618			categoryIdsCssClass = categoryIds.join(); 
1619			if(categoryIdsCssClass!='') 
1620				$(".slider").slick('slickFilter', categoryIdsCssClass); 
1621 
1622		}); 
1623	}); 
1624	 
1625	//Filter services 
1626	A.all('.button-vocabulary-structure').each(function(item){ 
1627		item.on('click', function(event){ 
1628			event.preventDefault(); 
1629			var structureId = item.attr('data-vocabulary-structure-id'); 
1630            if($(window).width() > 768) 
1631			    ${namespace}toggleMarkersServicesStructure(structureId); 
1632		}); 
1633	}); 
1634	 
1635	//Route 
1636	var routesPolylines = []; 
1637	var routesPolylinesGroup = L.featureGroup(); 
1638	var routesNearPolylinesGroup = L.layerGroup(); 
1639	const fontAwesomeRouteStartIcon = L.divIcon({ 
1640		className: 'marker-wrapper', 
1641		html: "<div class='marker-icon marker-icon-start marker-icon-start-min'><i class='fas fa-bicycle'><!-- icon--></i></div>", 
1642		iconSize: [26, 30], 
1643        iconAnchor: [13, 5] 
1644	}); 
1645	const fontAwesomeRouteEndIcon = L.divIcon({ 
1646		className: 'marker-wrapper', 
1647		html: "<div class='marker-icon marker-icon-end marker-icon-end-min'><i class='fas fa-bicycle'><!-- icon--></i></div>", 
1648		iconSize: [26, 30], 
1649        iconAnchor: [13, 30] 
1650	}); 
1651	const fontAwesomeRouteNearIcon = L.divIcon({ 
1652		className: 'marker-wrapper', 
1653		html: "<div class='marker-icon marker-icon-near marker-icon-near-min'><i class='fas fa-bicycle'><!-- icon--></i></div>", 
1654		iconSize: [26, 30], 
1655        iconAnchor: [13, 5] 
1656	}); 
1657	 
1658	<#if gpxRoute?has_content> 
1659		 
1660		<#assign gpxRoute = gpxRoute.put("articleId", articleId)! /> 
1661		<#assign gpxRoute = gpxRoute.put("color", "000")! /> 
1662		<#assign gpxRoute = gpxRoute.put("url", "")! /> 
1663		<#assign gpxRoute = gpxRoute.put("title", title)! /> 
1664		 
1665		var popupTextStartTemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-subtitle">${languageUtil.get(request, 'infoasturias-route-start')}</span><span class="popup-title">${htmlUtil.escape(Inicio.getData())}</span></span></span>'; 
1666		var popupTextEndTemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-subtitle">${languageUtil.get(request, 'infoasturias-route-end')}</span><span class="popup-title">${htmlUtil.escape(Finalizacion.getData())}</span></span></span>'; 
1667		 
1668		//Markers Route Start/End 
1669		var latLng = '${gpxRoute.get("coordinatesStart")}'; 
1670		latLng = latLng.replaceAll(' ', ''); 
1671		latLng = latLng.split(','); 
1672		var markerRouteStart = L.marker([latLng[0],latLng[1]], 
1673
1674				"icon": fontAwesomeRouteStartIcon, 
1675				"title": '${languageUtil.format(request, 'infoasturias-route-start-x', '${htmlUtil.escape(gpxRoute.get("title"))}')}' 
1676
1677		).bindPopup(popupTextStartTemplate).addTo(map); 
1678		var latLng = '${gpxRoute.get("coordinatesEnd")}'; 
1679		latLng = latLng.replaceAll(' ', ''); 
1680		latLng = latLng.split(','); 
1681		var markerRouteEnd = L.marker([latLng[0],latLng[1]],  
1682
1683				"icon": fontAwesomeRouteEndIcon, 
1684				"title": '${languageUtil.format(request, 'infoasturias-route-end-x', '${htmlUtil.escape(gpxRoute.get("title"))}')}' 
1685
1686		).bindPopup(popupTextEndTemplate).addTo(map); 
1687		 
1688		//POIs 
1689		var poiMarkers = []; 
1690		<#if arrayPDIs?has_content> 
1691			<#list arrayPDIs as arrayPDI> 
1692				var poiArticleId = '${arrayPDI.get("articleId")}'; 
1693				var latLng = '${arrayPDI.get("coordinates")}'; 
1694				var url = '${arrayPDI.get("url")}'; 
1695				var image = '${arrayPDI.get("image")}'; 
1696				var title = '${htmlUtil.escape(arrayPDI.get("title"))}'; 
1697				var description = '${htmlUtil.escape(arrayPDI.get("description"))}'; 
1698				var subtitle = '${htmlUtil.escape(arrayPDI.get("subtitle"))}'; 
1699				var icon = 'fas fa-info'; 
1700				<#if arrayPDI.get("icon")?has_content> 
1701					var icon = '${arrayPDI.get("icon")}'; 
1702				</#if> 
1703				if(latLng){ 
1704				 
1705					latLng = latLng.replaceAll(' ', ''); 
1706					latLng = latLng.split(','); 
1707					 
1708					var fontAwesomeRoutePOIIcon = L.divIcon({ 
1709						className: 'marker-wrapper', 
1710						html: "<div class='marker-icon marker-icon-poi marker-icon-poi-min'><i class='"+icon+"'><!-- icon--></i></div>", 
1711						iconSize: [26, 30], 
1712						iconAnchor: [13, 5] 
1713					}); 
1714					 
1715					var popupContentTemplate = '<a data-articleid="'+poiArticleId+'" href="'+url+'" class="popup popup-service">'+ 
1716							'<span class="popup-image-wrapper" style="background-image: url('+image+');"><img src="'+image+'"/></span>'+ 
1717							'<span class="popup-body">'+ 
1718							'<span class="popup-subtitle">'+subtitle+'</span>'+ 
1719							'<span class="popup-title">'+title+'</span>'+ 
1720							'<span class="popup-desciption">'+description+'</span>'+ 
1721							'</span>'+ 
1722							'</a>'; 
1723					 
1724					var newNodeObject = A.Node.create(popupContentTemplate); 
1725					newNodeObject.on('click', function(event){ 
1726						event.preventDefault(); 
1727						var nodeArticleId = this.attr('data-articleid'); 
1728						${namespace}getArticleDisplay(nodeArticleId); 
1729					}); 
1730 
1731					var marker = L.marker([latLng[0],latLng[1]], 
1732
1733							"icon": fontAwesomeRoutePOIIcon, 
1734							"title": title 
1735
1736					); 
1737					marker.articleId = 'poi-'+poiArticleId; 
1738					marker.bindPopup(newNodeObject.getDOMNode()).addTo(map); 
1739					marker.on('popupopen', function(e) { 
1740						map.panTo(this.getLatLng()); 
1741					}); 
1742					marker.getPopup().on('remove', function() { 
1743						${namespace}closeArticleDisplay(); 
1744					}); 
1745					 
1746					poiMarkers.push(marker); 
1747
1748			</#list> 
1749		</#if> 
1750		A.all('.card.poi').each(function(item){ 
1751			item.on('mouseover', function(event){ 
1752				var articleId = item.getAttribute("data-id"); 
1753				${namespace}markerPopup(articleId, true); 
1754			}); 
1755			item.on('mouseout', function(event){ 
1756				var articleId = item.getAttribute("data-id"); 
1757				${namespace}markerPopup(articleId, false); 
1758			}); 
1759		}); 
1760		 
1761		//RouteNears 
1762		routesNearPolylines = []; 
1763		<#list gpxRoutes as gpxRoute> 
1764			var polylinePopupHTML = '<a href="${gpxRoute.get("url")}" class="popup">'+ 
1765				'<span class="popup-image-wrapper" style="background-image: url(${gpxRoute.get("image")});"><img src="${gpxRoute.get("image")}"/>'+ 
1766				<#--'<span class="ribbon ribbon-circle"><span class="ribbon-text ">${gpxRoute.get("distance")}</span><span class="ribbon-text ribbon-text-meta">km</span></span>'+--> 
1767				'</span>'+ 
1768				'<span class="popup-body">'+ 
1769				'<span class="popup-title" style="color: #${gpxRoute.get("color")};">${htmlUtil.escape(gpxRoute.get("title"))}</span>'+ 
1770				'<span class="d-block"><span class="icon fas fa-map-marker-alt"><span class="hide-accessible">${languageUtil.get(request, "infoasturias-route-lugar-inicio-fin")}</span></span> <span class="value important text-uppercase">${htmlUtil.escape(gpxRoute.get("startEnd"))}</span></span>'+ 
1771				'<span class="d-block"><span class="icon fas fa-bicycle"><span class="hide-accessible">${languageUtil.get(request, "infoasturias-route-recorridos")}</span></span> <span class="value">${htmlUtil.escape(gpxRoute.get("routeTypes"))}</span></span>'+ 
1772				'<span class="d-block"><span class="icon fas fa-mountain"><span class="hide-accessible">${languageUtil.get(request, "infoasturias-route-ibp-index")}</span></span> <span class="important">IBP Index: </span> <span class="value">${gpxRoute.get("ibp")}</span></span>'+ 
1773				'<span class="d-block"><span class="icon fas fa-bicycle"><span class="hide-accessible">${languageUtil.get(request, "mode")}</span></span> <span class="value">${gpxRoute.get("mode")}</span></span>'+ 
1774				'</span>'+ 
1775				'</a>'; 
1776			var polyline = L.polyline(${gpxRoute.get("coordinates")}, {color: '#cacaca', opacity: 1, weight: 3, className: "bordered-polyline"}).bindPopup(polylinePopupHTML); 
1777			polyline.articleId = 'route-near-${gpxRoute.get("articleId")}'; 
1778			polyline.flag = true; 
1779			polyline.on('mouseover', function(e) { 
1780				var layer = e.target; 
1781				layer.setStyle({ 
1782					color: '#cacaca', 
1783					opacity: 1, 
1784					weight: 5 
1785				}); 
1786				layer.bringToFront(); 
1787			}); 
1788			polyline.on('mouseout', function(e) { 
1789				if(this.flag){ 
1790					var layer = e.target; 
1791					layer.setStyle({ 
1792						color: '#cacaca', 
1793						opacity: 0.9, 
1794						weight: 3 
1795					}); 
1796
1797			}); 
1798			polyline.on('click', function(e) { 
1799				var popup = this.getPopup(); 
1800				var layer = e.target; 
1801				layer.setStyle({ 
1802					color: '#cacaca', 
1803					opacity: 1, 
1804					weight: 5 
1805				}); 
1806				this.flag = false; 
1807				layer.bringToFront(); 
1808				popup.setLatLng(this.getCenter()); 
1809				popup.openPopup(); 
1810				map.setView(this.getCenter()); 
1811				var pixelesCenter = map.latLngToContainerPoint(this.getCenter()); 
1812				pixelesCenter.y -= map.getSize().y * 0.2; 
1813				var centerMap = map.containerPointToLatLng(pixelesCenter); 
1814				map.setView(centerMap); 
1815			}); 
1816			polyline.on('popupclose', function(e) { 
1817				var layer = e.target; 
1818				layer.setStyle({ 
1819					color: '#cacaca', 
1820					opacity: 0.9, 
1821					weight: 3 
1822				}); 
1823			}); 
1824			routesNearPolylines.push(polyline); 
1825 
1826			var popupTextStartTemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-subtitle">${languageUtil.get(request, 'infoasturias-route-start')}</span><span class="popup-title">${htmlUtil.escape(gpxRoute.get("title"))}</span></span></span>'; 
1827			var popupTextEndTemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-subtitle">${languageUtil.get(request, 'infoasturias-route-end')}</span><span class="popup-title">${htmlUtil.escape(gpxRoute.get("title"))}</span></span></span>'; 
1828			 
1829			//Markers Route Near Start/End 
1830			var latLng = '${gpxRoute.get("coordinatesStart")}'; 
1831			latLng = latLng.replaceAll(' ', ''); 
1832			latLng = latLng.split(','); 
1833			var markerRouteStart = L.marker([latLng[0],latLng[1]], 
1834
1835					"icon": fontAwesomeRouteNearIcon, 
1836					"title": '${languageUtil.format(request, 'infoasturias-route-start-x', '${htmlUtil.escape(gpxRoute.get("title"))}')}' 
1837
1838			).bindPopup(popupTextStartTemplate).addTo(routesNearPolylinesGroup); 
1839			var latLng = '${gpxRoute.get("coordinatesEnd")}'; 
1840			latLng = latLng.replaceAll(' ', ''); 
1841			latLng = latLng.split(','); 
1842			var markerRouteEnd = L.marker([latLng[0],latLng[1]],  
1843
1844					"icon": fontAwesomeRouteNearIcon, 
1845					"title": '${languageUtil.format(request, 'infoasturias-route-end-x', '${htmlUtil.escape(gpxRoute.get("title"))}')}' 
1846
1847			).bindPopup(popupTextEndTemplate).addTo(routesNearPolylinesGroup); 
1848 
1849			routesPolylinesGroup.addLayer(polyline); 
1850			routesNearPolylinesGroup.addLayer(polyline); 
1851 
1852		</#list> 
1853		//List 
1854		A.all('.route-near').each(function(item){ 
1855			item.on('mouseover', function(event){ 
1856				var articleId = item.getAttribute("data-id"); 
1857				${namespace}polylinePopup(articleId, true); 
1858			}); 
1859			item.on('mouseout', function(event){ 
1860				var articleId = item.getAttribute("data-id"); 
1861				${namespace}polylinePopup(articleId, false); 
1862			}); 
1863		}); 
1864 
1865		var gropedOverlayslehen = { 
1866			"${languageUtil.get(locale, "infoasturias-routes-near")}": routesNearPolylinesGroup 
1867
1868		var layerControl = L.control.layers('', gropedOverlayslehen, { 
1869			collapsed: false, 
1870			position:'topleft' 
1871		}); 
1872		layerControl.addTo(map); 
1873	 
1874	//Elevation 
1875 
1876	var elevation_options = { 
1877 
1878		// Default chart colors: theme lime-theme, magenta-theme, ... 
1879		theme: "custom-theme", 
1880		 
1881		useHeightIndicator: true,  
1882 
1883		// Chart container outside/inside map container 
1884		detached: true, 
1885 
1886		// if (detached), the elevation chart container 
1887		elevationDiv: "#elevation-div-${articleId}", 
1888 
1889		// if (!detached) autohide chart profile on chart mouseleave 
1890		autohide: false, 
1891 
1892		// if (!detached) initial state of chart profile control 
1893		collapsed: false, 
1894 
1895		// if (!detached) control position on one of map corners 
1896		position: "topright", 
1897 
1898		// Toggle close icon visibility 
1899		closeBtn: false, 
1900 
1901		// Autoupdate map center on chart mouseover. 
1902		followMarker: true, 
1903 
1904		// Autoupdate map bounds on chart update. 
1905		autofitBounds: false, 
1906 
1907		// Chart distance/elevation units. 
1908		imperial: false, 
1909 
1910		// [Lat, Long] vs [Long, Lat] points. (leaflet default: [Lat, Long]) 
1911		reverseCoords: false, 
1912 
1913		// Acceleration chart profile: true || "summary" || "disabled" || false 
1914		acceleration: false, 
1915 
1916		// Slope chart profile: true || "summary" || "disabled" || false 
1917		slope: false, 
1918 
1919		// Speed chart profile: true || "summary" || "disabled" || false 
1920		speed: false, 
1921 
1922		// Altitude chart profile: true || "summary" || "disabled" || false 
1923		altitude: true, 
1924 
1925		// Display time info: true || "summary" || false 
1926		time: false, 
1927 
1928		// Display distance info: true || "summary" || false 
1929		distance: true, 
1930 
1931		// Summary track info style: "inline" || "multiline" || false 
1932		summary: false, 
1933 
1934		// Download link: "link" || false || "modal" 
1935		downloadLink: false, 
1936 
1937		// Toggle chart ruler filter 
1938		ruler: true, 
1939 
1940		// Toggle chart legend filter 
1941		legend: false, 
1942 
1943		// Toggle "leaflet-almostover" integration 
1944		almostOver: true, 
1945 
1946		// Toggle "leaflet-distance-markers" integration 
1947		distanceMarkers: false, 
1948 
1949		// Toggle "leaflet-edgescale" integration 
1950		edgeScale: false, 
1951 
1952		// Toggle "leaflet-hotline" integration 
1953		hotline: true, 
1954 
1955		// Display track datetimes: true || false 
1956		timestamps: false, 
1957 
1958		// Display track waypoints: true || "markers" || "dots" || false 
1959		waypoints: true, 
1960 
1961		// Toggle custom waypoint icons: true || { associative array of <sym> tags } || false 
1962		wptIcons: false, 
1963 
1964		// Toggle waypoint labels: true || "markers" || "dots" || false 
1965		wptLabels: false, 
1966 
1967		// Render chart profiles as Canvas or SVG Paths 
1968		preferCanvas: false, 
1969 
1970		height: 200, 
1971	}; 
1972 
1973	${namespace}initializeElevation(map, elevation_options); 
1974 
1975	//Center 
1976	var routesMainPolyline = L.polyline(${gpxRoute.get("coordinates")}); 
1977	routesPolylinesGroup.addLayer(routesMainPolyline); 
1978	map.fitBounds(routesMainPolyline.getBounds()); 
1979 
1980	//Enabled/Disabled routesNearPolylinesGroup 
1981	let previousBounds = null; 
1982	map.on('overlayadd', function (e) { 
1983		if (e.layer === routesNearPolylinesGroup) { 
1984			previousBounds = map.getBounds(); 
1985			const groupBounds = routesPolylinesGroup.getBounds(); 
1986			if (groupBounds.isValid())  
1987				map.fitBounds(groupBounds); 
1988
1989	}); 
1990	map.on('overlayremove', function (e) { 
1991		if (e.layer === routesNearPolylinesGroup && previousBounds) { 
1992			map.fitBounds(previousBounds); 
1993			previousBounds = null; 
1994
1995	}); 
1996 
1997	<#assign poiImages = { 
1998		"Beach": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/playa.png", 
1999		<#--"Bike Trail": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/rutaini-ew.png",--> 
2000		<#--"Bike Trail": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/rutaini-we.png",--> 
2001		<#--"Building": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/ciudad.png",--> 
2002		"City Hall": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/ferrocarril.png", 
2003		<#--"Civil": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/rutafin.png",--> 
2004		<#--"Flag, Green": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/ini-vv.png",--> 
2005		<#--"Flag, Red": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/fin-vv.png",--> 
2006		"Light": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/faro.png", 
2007		<#--"Navaid, Blue": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/cultural.png",--> 
2008		<#--"Navaid, Green": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/natural.png",--> 
2009		<#--"Navaid, Red": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/warning.png",--> 
2010		<#--"Residence": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/pueblo.png",--> 
2011		"Scenic Area": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/paisaje.png", 
2012		"Summit": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/cumbre.png" 
2013	}> 
2014	<#assign poiFontAwesome = { 
2015		"": "fas fa-info", 
2016		"Beach": "fas fa-umbrella-beach", 
2017		<#--"Bike Trail": "",--> 
2018		<#--"Bike Trail": "",--> 
2019		<#--"Building": "",--> 
2020		"City Hall": "fas fa-train", 
2021		<#--"Civil": "",--> 
2022		<#--"Flag, Green": "",--> 
2023		<#--"Flag, Red": "",--> 
2024		"Light": "fas fa-monument", 
2025		<#--"Navaid, Blue": "",--> 
2026		<#--"Navaid, Green": "",--> 
2027		<#--"Navaid, Red": "",--> 
2028		<#--"Residence": "",--> 
2029		"Scenic Area": "fas fa-camera", 
2030		"Summit": "fas fa-mountain" 
2031	}> 
2032	 
2033	<#if validator.isNotNull(gpxPOIRoute)> 
2034		<#if gpxPOIRoute.has("wpts") && validator.isNotNull(gpxPOIRoute.has("wpts"))> 
2035			<#assign wptJSONArray = jsonFactoryUtil.createJSONArray(gpxPOIRoute.get("wpts"))! /> 
2036			<#list 0..wptJSONArray.length() as i> 
2037				<#assign wptJSONObject = wptJSONArray.get(i)! /> 
2038				<#if validator.isNotNull(wptJSONObject)> 
2039 
2040					<#assign wptName = wptJSONObject.get("name")! /> 
2041					<#assign wptSym = wptJSONObject.get("sym")! /> 
2042					<#assign wptLat = wptJSONObject.get("lat")! /> 
2043					<#assign wptLon = wptJSONObject.get("lon")! /> 
2044					<#assign wptEle = wptJSONObject.get("ele")! /> 
2045					<#assign wptSymImage = poiImages[wptSym]! /> 
2046					<#assign wptSymFontAwesome = poiFontAwesome[wptSym]! /> 
2047					<#if validator.isNotNull(wptSymFontAwesome)> 
2048 
2049						var divIcon = L.divIcon({ 
2050							className: 'marker-wrapper', 
2051							html: "<div class='marker-icon marker-icon-poi marker-icon-poi-min'><i class='${wptSymFontAwesome}'><!-- icon--></i></div>", 
2052							iconSize: [26, 30], 
2053							iconAnchor: [13, 30] 
2054						}); 
2055						var popupPOITemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-title">${htmlUtil.escape(wptName)}</span></span></span>'; 
2056						var marker = L.marker([${wptLat}, ${wptLon}],  
2057
2058								"icon": divIcon, 
2059								"title": '${htmlUtil.escape(wptName)}' 
2060
2061						).bindPopup(popupPOITemplate).addTo(map); 
2062						marker.on('popupopen', function(e) { 
2063							map.panTo(this.getLatLng()); 
2064						}); 
2065					</#if> 
2066				</#if> 
2067			</#list> 
2068		</#if> 
2069 
2070		<#-- TODO --> 
2071		<#assign dlFileEntryGPXPOI = dlTool.getDLFileEntryByPath(Documentos.GPXPOIRuta.data)!/> 
2072		<#if validator.isNotNull(dlFileEntryGPXPOI)> 
2073			<#assign document = saxReaderUtil.read(dlFileEntryGPXPOI.getContentStream())/> 
2074			<#assign root = document.getRootElement()/> 
2075			<#assign trks = root.elements("trk")!> 
2076			<#if validator.isNotNull(trks)> 
2077				<#list trks as trk> 
2078					<#assign trkName = trk.elementText("name")!> 
2079					<#assign trkseg = trk.element("trkseg")!> 
2080					<#if validator.isNotNull(trkseg)> 
2081						<#assign trkpts = trkseg.elements("trkpt")!> 
2082						<#if validator.isNotNull(trkpts)> 
2083							var trksegsLatLngs = []; 
2084							<#list trkpts as trkpt> 
2085								<#assign trksegLat = trkpt.attributeValue("lat")!> 
2086								<#assign trksegLon = trkpt.attributeValue("lon")!> 
2087								<#if validator.isNotNull(trksegLat) && validator.isNotNull(trksegLon)> 
2088									var trksegsLatLng = [${trksegLat}, ${trksegLon}]; 
2089									trksegsLatLngs.push(trksegsLatLng); 
2090								</#if> 
2091							</#list> 
2092							if(trksegsLatLngs.length>0){ 
2093								var popupGpxPOITemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-title">${htmlUtil.escape(trkName)}</span></span></span>'; 
2094								var trkPolyline = L.polyline(trksegsLatLngs, {color: '#006db0', dashArray: '5, 10', lineCap: 'square', opacity: 1, weight: 5, className: "bordered-polyline-white"}).bindPopup(popupGpxPOITemplate).addTo(map); 
2095
2096						</#if> 
2097					</#if> 
2098				</#list> 
2099			</#if> 
2100		</#if> 
2101	</#if> 
2102 
2103	<#--Notices--> 
2104	<#if validator.isNotNull(markersNotices) && markersNotices?size gt 0> 
2105		const markersNotices = {}; 
2106		<#list markersNotices as markersNotice> 
2107 
2108			<#if validator.isNotNull(markersNotice)> 
2109 
2110				(function() { 
2111					 
2112					const id = '${markersNotice.id}'; 
2113					var notice = A.one('#route-${articleId}-alert-coordinates-' + id); 
2114					if(notice){ 
2115 
2116						//SessionStorage 
2117						if (!sessionStorage.getItem(id)) { 
2118 
2119							notice.show(); 
2120							notice.addClass('show'); 
2121 
2122							//Marker 
2123							var divIcon = L.divIcon({ 
2124								className: 'marker-wrapper', 
2125								html: "<div class='marker-circle marker-notice marker-notice-${markersNotice.type}'><i class='${markersNotice.icon}'><!-- icon--></i></div>", 
2126								iconSize: [26, 30], 
2127								iconAnchor: [13, 30] 
2128							}); 
2129							var popupPOITemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-title">${htmlUtil.escape(htmlUtil.extractText(markersNotice.title))}</span><span class="popup-text">${htmlUtil.escape(htmlUtil.extractText(markersNotice.description))}</span></span></span>'; 
2130							var marker = L.marker([${markersNotice.coordinates}],  
2131
2132									"icon": divIcon, 
2133									"title": '${htmlUtil.escape(htmlUtil.extractText(markersNotice.title))}' 
2134
2135							).bindPopup(popupPOITemplate).addTo(map); 
2136							marker.on('popupopen', function(e) { 
2137								map.panTo(this.getLatLng()); 
2138							}); 
2139							markersNotices[id] = marker; 
2140 
2141							//Notice 
2142							notice.on('hover', function(){ 
2143								markersNotices[id].openPopup(); 
2144								map.panTo(markersNotices[id].getLatLng()); 
2145							}); 
2146							var close = notice.one('.close'); 
2147							if(close){ 
2148								close.on('click', function(){ 
2149									sessionStorage.setItem(id, 'true'); 
2150								}); 
2151
2152
2153
2154				})(); 
2155 
2156			</#if> 
2157 
2158		</#list> 
2159	</#if> 
2160	 
2161	//Functions 
2162	function ${namespace}initializeElevation(map, elevation_options) { 
2163 
2164		const controlElevation = L.control.elevation(elevation_options).addTo(map); 
2165	 
2166		//Fixed random hotline route map error not rendering 
2167		const hotlineLayer = L.hotline(${gpxRoute.get("coordinates")}, { 
2168			min: ${gpxRoute.get("elevationMin")}, 
2169			max: ${gpxRoute.get("elevationMax")}, 
2170			palette: { 
2171                0.0: 'green', 
2172                0.5: 'yellow', 
2173                1.0: 'red' 
2174            }, 
2175            weight: 5, 
2176            outlineColor: 'black', 
2177            outlineWidth: 1 
2178		}).addTo(map); 
2179 
2180		controlElevation.load('${gpxRutaPath}'); 
2181
2182 
2183	function ${namespace}markerPopup(articleId, hover){ 
2184		for (var i in poiMarkers){ 
2185			var marker = poiMarkers[i]; 
2186			var id = marker.articleId; 
2187			if (id == articleId){ 
2188				if(hover){ 
2189					marker.openPopup(); 
2190					map.panTo(marker.getLatLng()); 
2191				}else{ 
2192					//marker.closePopup(); 
2193
2194			}; 
2195
2196
2197	 
2198	function ${namespace}markerServicePopup(articleId, hover){ 
2199		for (var i in serviceMarkers){ 
2200			var marker = serviceMarkers[i]; 
2201			var id = marker.articleId; 
2202			if (id == articleId){ 
2203				if(hover){ 
2204					map.addLayer(marker); 
2205					marker.openPopup(); 
2206					map.panTo(marker.getLatLng()); 
2207				}else{ 
2208					//map.removeLayer(marker); 
2209					//marker.closePopup(); 
2210
2211			}; 
2212
2213
2214	 
2215	function ${namespace}polylinePopup(articleId, hover){ 
2216		for (var i in routesNearPolylines){ 
2217			var polyline = routesNearPolylines[i]; 
2218			if (map.hasLayer(routesNearPolylinesGroup)){ 
2219				var id = polyline.articleId; 
2220				if (id == articleId){ 
2221					if(hover){ 
2222						polyline.openPopup(); 
2223						polyline.setStyle({ 
2224							weight: 5, 
2225							opacity: 1 
2226						}); 
2227						map.panTo(polyline.getCenter()); 
2228						polyline.bringToFront(); 
2229					}else{ 
2230						polyline.setStyle({ 
2231							weight: 3, 
2232							opacity: 0.9 
2233						}); 
2234						polyline.closePopup(); 
2235
2236
2237
2238
2239
2240	 
2241	function ${namespace}toggleMarkersServicesStructure(structureId){ 
2242		 
2243		var item = A.one('#vocabulary-structure-id-'+structureId); 
2244		var button = A.one('#button-vocabulary-structure-id-'+structureId); 
2245		if(item){ 
2246			 
2247			var vocabularyWrapper = item.ancestor('.vocabulary-wrapper'); 
2248			if(!vocabularyWrapper.hasClass('selected')){ 
2249				vocabularyWrapper.all('.categories input').attr('checked',''); 
2250				vocabularyWrapper.all('.categories input').each(function(cat){ 
2251					cat.simulate('click'); 
2252				}); 
2253				vocabularyWrapper.addClass('selected'); 
2254				if(button){ 
2255					button.addClass('selected'); 
2256
2257			}else{ 
2258				vocabularyWrapper.all('.categories input').attr('checked','checked'); 
2259				vocabularyWrapper.all('.categories input').each(function(cat){ 
2260					cat.simulate('click'); 
2261				}); 
2262				vocabularyWrapper.removeClass('selected'); 
2263				if(button){ 
2264					button.removeClass('selected'); 
2265					var allNoSelectedButtons = true; 
2266					A.all('.button-vocabulary-structure').each(function(item){ 
2267						if(item.hasClass('selected')) 
2268							allNoSelectedButtons = false; 
2269					}); 
2270
2271
2272
2273
2274 
2275	Liferay.provide(window, '${namespace}closeArticleDisplay', function(){ 
2276		A.one("#article-display-container").hide('fadeOut'); 
2277		A.one("#search-container").show('fadeIn'); 
2278	}); 
2279 
2280	Liferay.provide(window, '${namespace}openArticleDisplay', function(){ 
2281		A.one("#search-container").hide(); 
2282		A.one("#article-display-container").show('fadeIn'); 
2283 
2284		//Map 
2285		var articleDisplayContainerMap = A.one("#article-display-container").one('.article-section-map script[type="text/javascript"]'); 
2286		if(articleDisplayContainerMap) 
2287			eval(articleDisplayContainerMap.html()); 
2288 
2289		//Scroll 
2290		var to = A.one('#article-display-container'); 
2291		if(to){ 
2292			var position = 100; 
2293			var toggleMap = A.one('#toggle-map'); 
2294			if(toggleMap && toggleMap.hasClass('active')){ 
2295				position = 0; 
2296				to = A.one('body'); 
2297
2298			var anim = new A.Anim({ 
2299				duration: 0.2, 
2300				node:  A.getWin(), 
2301				to: { 
2302					scroll: [0, to.getY() - position] 
2303
2304			}).run(); 
2305
2306	}); 
2307 
2308    Liferay.provide(window, '${namespace}getArticleDisplay', function(articleId){ 
2309	 
2310        var url = "${themeDisplay.getURLPortal()+themeDisplay.getLayout().getFriendlyURL(locale)}?p_p_id=${themeDisplay.getPortletDisplay().getId()}&p_p_lifecycle=2&p_p_state=normal&p_p_mode=view&p_p_resource_id=journalDisplayContent&p_p_cacheability=cacheLevelPage&_${themeDisplay.getPortletDisplay().getId()}_articleId="+articleId;	 
2311        A.io.request(url, { 
2312            method: 'GET', 
2313            type: 'HTML', 
2314            on: { 
2315                success: function() { 
2316                    var journalArticleContentDisplay = this.get('responseData'); 
2317                    journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("col-md-6", "col-12"); 
2318                    journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-info-wrapper", ""); 
2319                    journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-info-table", ""); 
2320                    journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-info-table-row", ""); 
2321                    journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-info-table-cell", ""); 
2322                    journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-info", "article-info m-0 px-4 pt-4"); 
2323					//journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-section-map", "article-section-map hide"); 
2324                    A.one("#article-display").html(journalArticleContentDisplay); 
2325                    ${namespace}openArticleDisplay(); 
2326
2327
2328        }); 
2329	}); 
2330		 
2331	</#if> 
2332 
2333	var closeArticleDisplayNode = A.one("#close-article-display"); 
2334	if(closeArticleDisplayNode){ 
2335		closeArticleDisplayNode.on('click', function(event) { 
2336			${namespace}closeArticleDisplay(); 
2337		}); 
2338
2339 
2340	A.all(".template-layout-map .item-card").each(function(item) { 
2341        item.on("click", function(event) { 
2342            event.preventDefault(); 
2343            var articleId = item.attr("data-articleid"); 
2344            ${namespace}getArticleDisplay(articleId); 
2345        }); 
2346    }); 
2347	 
2348	//Map Mobile Toggle 
2349	mapMobileToggle('${languageUtil.get(request, "infoasturias-abrir-mapa")}','${languageUtil.get(request, "infoasturias-cerrar-mapa")}', map, '.leaflet-elevation-wrapper'); 
2350	var toggleMap = A.one('#toggle-map'); 
2351	if(toggleMap){ 
2352		toggleMap.on('click', function(event){ 
2353			A.one('.template-layout-map').toggleClass('template-layout-map-mobile'); 
2354			A.one('#content').toggleClass('content-map-mobile'); 
2355			map.closePopup(); 
2356			if(this.hasClass('active')){ 
2357				${namespace}closeArticleDisplay(); 
2358				//Scroll 
2359				var to = A.one('body'); 
2360				if(to){ 
2361					var anim = new A.Anim({ 
2362						duration: 0.2, 
2363						node:  A.getWin(), 
2364						to: { 
2365							scroll: [0, to.getY()-100] 
2366
2367					}).run(); 
2368
2369
2370		}); 
2371
2372 
2373	/* Location */ 
2374	let userMarkerShadow = null; 
2375	let userMarker = null; 
2376	let currentPosition = null; 
2377	function ${namespace}onUserLocationFound(e) { 
2378    	const baseColor = '#0f53ff'; 
2379		currentPosition = e.latlng; 
2380		if (!userMarker) { 
2381			userMarkerShadow = L.circleMarker(e.latlng, {radius: 15, color: null, fillColor: baseColor, fillOpacity: 0.3, interactive: false}).addTo(map); 
2382			userMarker = L.circleMarker(e.latlng, {radius: 7, color: '#fff', fillColor: baseColor, fillOpacity: 1, weight: 2}).addTo(map); 
2383			map.setView(currentPosition, 16); 
2384		}else{ 
2385			userMarkerShadow.setLatLng(e.latlng); 
2386			userMarker.setLatLng(e.latlng); 
2387
2388
2389	var userLocationNode = A.one("#userLocation"); 
2390	if(userLocationNode){ 
2391		userLocationNode.on('click', function(){ 
2392			if(this.hasClass('btn-selected')){ 
2393				this.removeClass('btn-selected'); 
2394				currentPosition = null; 
2395				if (userMarker) { 
2396					map.removeLayer(userMarker); 
2397					userMarker = null; 
2398
2399				if (userMarkerShadow) { 
2400					map.removeLayer(userMarkerShadow); 
2401					userMarkerShadow = null; 
2402
2403				map.stopLocate(); 
2404			}else{ 
2405				if(currentPosition){ 
2406					map.setView(currentPosition, 16); 
2407				}else{ 
2408					map.locate({setView: false, maxZoom: 16, watch: true, enableHighAccuracy: true}); 
2409					map.on('locationfound', ${namespace}onUserLocationFound); 
2410					this.addClass('btn-selected'); 
2411
2412
2413		}); 
2414
2415 
2416	/* Toggle elevation */ 
2417	var toggleElevationNode = A.one("#toggleElevation"); 
2418	if(toggleElevationNode){ 
2419		var elevationPanel = A.one("#elevation-div-${articleId} .elevation-control"); 
2420		toggleElevationNode.on('click', function(){ 
2421			if (!elevationPanel.hasClass('elevation-control-hide')) { 
2422				elevationPanel.addClass('elevation-control-hide'); 
2423				this.removeClass('btn-selected'); 
2424			} else { 
2425				elevationPanel.removeClass('elevation-control-hide'); 
2426				this.addClass('btn-selected'); 
2427
2428		}); 
2429
2430 
2431	/* Center Map Services */ 
2432	function fitToVisibleMarkerGroups(map, markersServicesGroups) { 
2433 
2434		//Init 
2435		let bounds = null; 
2436 
2437		for (const key in markersServicesGroups) { 
2438			if (markersServicesGroups.hasOwnProperty(key)) { 
2439			const group = markersServicesGroups[key]; 
2440 
2441			if (map.hasLayer(group) && group.getLayers().length > 0) { 
2442				const groupBounds = group.getBounds(); 
2443				if (bounds) { 
2444				bounds.extend(groupBounds); 
2445				} else { 
2446				bounds = groupBounds; 
2447
2448
2449
2450
2451 
2452		if (bounds) { 
2453			map.fitBounds(bounds, { padding: [50, 50] }); 
2454
2455
2456     
2457</@>