Ocorreu um erro ao processar o template.
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@4ded13f"; see cause exception in the Java stack trace.

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