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

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