S'ha produït un error mentre es processava la plantilla.
?substring(...) argument #2 had invalid value: The index must be at least 0, but was -1.

----
FTL stack trace ("~" means nesting-related):
	- Failed at: #assign parameterKey = parameterKeyAn...  [in template "10155#10193#176057880" at line 110, column 49]
----
1<#assign reserved_article_title = "${.vars['reserved-article-title'].data}"/> 
2	<#assign reserved_article_id = "${.vars['reserved-article-id'].data}"/> 
3	<#assign viewUrl=""/> 
4	<#assign cuerpo=""/> 
5	<#assign posicion=""/> 
6	<#assign iframeId = "${.vars['reserved-article-id'].data}"/>  
7	<#assign httpComponentsUtil =  objectUtil("com.liferay.portal.kernel.util.HttpComponentsUtil")/> 
8	<#assign iframeProtocol = ""/> 
9	<#assign width = "100%"/> 
10	<#assign height = "650"/> 
11	<#assign scrolling = "auto"/> 
12	<#assign src = ""/> 
13	<#assign ajustar_alto = false/> 
14	<#assign mostrar_atras = true/> 
15	<#assign mostrar_enlazar = false/> 
16	<#assign mostrar_imprimir = false/> 
17 
18	<div class="webContent" style="float:none;"> 
19		 <#if reserved_article_title?? && reserved_article_title!=""> 
20			<p class="header10">${reserved_article_title}</p> 
21		</#if> 
22	</div> 
23 
24	<#--Dependiendo del valor de la variable posicion el Cuerpo se pinta arriba o abajo 
25	por lo que primero recogemos los valores en variables --> 
26 
27	<#--Posición arriba/abajo--> 
28	<#if Posicion?? && Posicion.getData()?? > 
29		<#assign posicion=Posicion.getData()/> 
30	</#if> 
31 
32	<#--Texto en el cuerpo caja de texto enriquecido.--> 
33	<#if Cuerpo?? && Cuerpo.getData() != "" > 
34		  <#assign cuerpo = Cuerpo.getData()/> 
35	</#if> 
36 
37	<div class="iframe"> 
38		<#--Si el valor seleccionado es arriba entonces imprimimos el contenido del cuerpo.--> 
39		<#if posicion == "arriba"> 
40		   <div class="texto_cuerpo">  
41				${cuerpo} 
42		   </div> 
43		</#if> 
44		<#--Comprobamos valores rellenados por usuario--> 
45		<#if ancho.getData()?? && ancho.getData()!="">  
46			<#assign width = ancho.getData()/> 
47		</#if> 
48		 
49		<#if alto.getData()?? && alto.getData()!=""> 
50			<#assign height = alto.getData()/> 
51		</#if> 
52		 
53		<#if barra_desplazamiento.getData()?? && barra_desplazamiento.getData()!=""> 
54			<#assign scrolling = barra_desplazamiento.getData()/> 
55		</#if> 
56		 
57		<#if url.getData()?? && url.getData()!=""> 
58			<#assign src = url.getData()/> 
59		</#if> 
60		 
61		<#if autoajustar_alto?? && autoajustar_alto.getData()=="true"> 
62			<#assign ajustar_alto = true/> 
63		</#if> 
64		 
65		<#if mostrar_enlace_atras?? && mostrar_enlace_atras.getData()=="false"> 
66			<#assign mostrar_atras = false/> 
67		</#if> 
68		 
69		<#if mostrar_enlace_enlazar?? && mostrar_enlace_enlazar.getData()=="true"> 
70			<#assign mostrar_enlazar = true/> 
71		</#if> 
72		 
73		<#if mostrar_boton_imprimir?? && mostrar_boton_imprimir.getData()=="true"> 
74			<#assign mostrar_imprimir = true/> 
75		</#if> 
76		 
77		<#--Obtengo el dominio actual--> 
78		<#assign currentUrl = Request.CURRENT_COMPLETE_URL/> 
79		<#assign urlParts = currentUrl?split("/")/> 
80		<#assign currentDomain = ""/> 
81		<#assign currentProtocol = ""/> 
82		<#assign cont = 1 /> 
83		<#list urlParts as urlPart > 
84			<#if cont == 3 > 
85				<#assign currentDomain = urlPart /> 
86			</#if> 
87			<#assign cont = cont + 1 /> 
88		</#list> 
89		<#--Obtengo el dominio del iframe --> 
90		<#assign srcParts = src?split("/")/> 
91		<#assign iframeDomain = ""/> 
92		<#assign iframeProtocol = "" /> 
93		<#assign serverUrl = ""/> 
94		 
95		<#if srcParts[0] == "http:" || srcParts[0] == "https:"> 
96			<#assign iframeDomain = srcParts[2]/> 
97			<#assign iframeProtocol = srcParts[0]/> 
98			<#assign serverUrl = iframeProtocol + "//" + iframeDomain/> 
99		</#if> 
100		<#if src?? && src!=""> 
101			<#-- parámetros de la url del portal--> 
102				 
103				<#assign parametrosString = httpComponentsUtil.getQueryString(currentUrl)/> 
104				<#assign parameterList = parametrosString?split("&")/> 
105				<#assign sufijo = ""/> 
106				 
107				<#list parameterList as parameterKeyAndValue> 
108					<#if parameterKeyAndValue?? && parameterKeyAndValue?has_content> 
109						<#assign parameterKey = parameterKeyAndValue?substring(0,parameterKeyAndValue?index_of("="))/> 
110						<#assign parameterValue = parameterKeyAndValue?substring(parameterKeyAndValue?index_of("=")+1)/> 
111 
112						<#assign anyadir = true/> 
113						 
114						<#-- ENT-308086 : Tenemos que ver si se ha añadido algún valor en el campo ignore_parametros--> 
115						<#if ignore_parametros?? && ignore_parametros?has_content> 
116							<#assign ignoreParameters = ignore_parametros.getData()?split(";")/> 
117							<#list ignoreParameters as ignoreParameter> 
118								<#if ignoreParameter?? && ignoreParameter?has_content && ignoreParameter==parameterKey> 
119									<#assign anyadir = false/> 
120								</#if>					 
121							</#list> 
122						</#if> 
123						<#--FIN ENT-308086-->  
124 
125						<#--Buscamos si se ha definido la URL que se ha de ver en el iFrame--> 
126						<#if parameterKey == "viewUrl${iframeId}"> 
127							<#assign viewUrl = parameterValue /> 
128							<#assign anyadir = false/> 
129						</#if> 
130 
131						 
132						<#if anyadir > 
133							<#if sufijo != "" > 
134								<#assign sufijo = sufijo + "&" /> 
135							<#else> 
136								<#assign sufijo = "?" /> 
137							</#if> 
138							<#assign sufijo = sufijo + parameterKeyAndValue /> 
139						</#if> 
140					</#if> 
141				</#list> 
142				 
143				<#--Establecemos la URL que se ha de ver en el iFrame, si se ha definido--> 
144 
145				<#if viewUrl?? && viewUrl!=""> 
146					<#assign src = serverUrl + viewUrl /> 
147				</#if> 
148                 
149				<#-- INICIO ENT-316287  
150    			DIFERENCIA CON LA PLANTILLA DE IFRAME GLOBAL  
151				SI NOS LLEGA UN PARÁMETRO A PARTIR DE LA URL POR LA QUE ACEDEMOS AL PORTAL  
152				ELIMINAMOS EL TEXTO "?param1=" Y REEMPLAZAMOS LO QUE HACE DE SEPARADOR PARA QUE LO PINTE CORRECTAMENTE --> 
153				<#assign sufijo = sufijo?replace("?param=", "")?replace("%2F", "/") /> 
154				<#assign sufijo = sufijo?replace("(", "%28")?replace(")", "%29") />				 
155				<#--FIN ENT-316287 --> 				 
156				 
157				<#if sufijo?? && sufijo!=""> 
158					 
159					<#--Comprobamos si la URL ya trae parametros para concatenarlos--> 
160					<#assign index = src?index_of('?')/> 
161				 
162					<#if (index >= 0) >   
163						<#assign sufijo = sufijo?replace("?", "&")/> 
164					</#if> 
165					<#assign src = "${src}${sufijo}"/> 
166				</#if> 
167 
168				<div class="iframe-error-protocol  iframe-error-protocol-${reserved_article_id}" style="display: none;"> 
169					<span> 
170						<@liferay.language key="iframe.mensaje" /> 
171						<a href="${src}" target="_blank"> 
172							<b><@liferay.language key="iframe.mensaje.ventana" /></b> 
173						</a> 
174					</span> 
175				</div> 
176				<#if mostrar_enlazar || mostrar_atras || mostrar_imprimir> 
177					<div class="iframe-controls iframe-controls-${reserved_article_id}"> 
178						<#if mostrar_atras> 
179							<a class="back-link float-right" id="iframe-back-link-${reserved_article_id}" href="javascript:history.go(-1)" style="display: none;">&laquo; <@liferay.language key="back"  /></a> 
180						</#if> 
181						<#if mostrar_enlazar> 
182							<a class="iframe-show-link float-right" id="iframe-show-link-${reserved_article_id}"  style="display: none;" ><i class="fas fa-link"></i><@liferay.language key="iframe.enlazar" /></a> 
183							<div id="iframe-link-${reserved_article_id}" class="iframe-link"> 
184								<input aria-labelledby="iframe-show-link-${reserved_article_id}" id="iframe-link-input-${reserved_article_id}" class="iframe-link-input" type="text" style="display: none;" /> 
185							</div> 
186						</#if> 
187						<#if mostrar_imprimir> 
188							<a class="taglib-icon float-right" id="iframe-print-${reserved_article_id}"  target="_self">  
189								<i class="fas fa-print"></i> 
190								<span class="taglib-text"><@liferay.language key="print" /></span>  
191							</a>  
192						</#if> 
193					</div> 
194				</#if> 
195				 
196				<div id="iframe-container-${reserved_article_id}"> 
197					<#--ENT-563348 - Se añade allow para poder copiar al portapapeles--> 
198					<iframe allow="clipboard-write" src="" width="${width}" height="${height}" scrolling="${scrolling}" title="${reserved_article_title}" id="iframe-${reserved_article_id}" name="iframe-${reserved_article_id}"></iframe> 
199				</div> 
200		 
201		  
202				<#--Si el valor seleccionado es abajo imprimimos el contenido del cuerpo.--> 
203				<#if posicion == "abajo"> 
204				  <div class="texto_cuerpo">  
205					  ${cuerpo} 
206				 </div> 
207				</#if> 
208 
209			<script type="text/javascript"> 
210 
211				 
212				// Script para que no cargue el src del iframe dos veces por el efecto del SPA https://help.liferay.com/hc/es/requests/41501 
213				var iframe = document.getElementById('iframe-${reserved_article_id}'); 
214				var url = "${src}"; 
215				if (Liferay.SPA && iframe) { 
216					iframe.src = url; 
217
218				else { 
219					Liferay.on( 
220						'SPAReady', 
221						function(event) { 
222							if (iframe) { 
223								iframe.src = url; 
224
225
226					); 
227
228				 
229				 
230				<#-- No es el mismo dominio, así que definimos el valor del document.domain --> 
231				<#if (ajustar_alto || mostrar_enlazar) && currentDomain?has_content && iframeDomain?has_content && !currentDomain.equals(iframeDomain) > 
232					document.domain = 'gva.es'; 
233				</#if> 
234				 
235				<#-- ENT-337637 Cogemos protocolo por js --> 
236				if( location.protocol == "https:" &&  "${iframeProtocol}" == "http:" ) 
237					$('.portlet-journal-content .iframe-error-protocol-${iframeId}').css('display','block'); 
238				 
239				<#-- Autoajustar el alto del iframe  --> 
240				<#if ajustar_alto > 
241					<#-- Al cambiar el tamaño de la ventana 
242					##$(window).resize(function (){ 
243					##	var iframe = document.getElementById('iframe-${iframeId}'); 
244					##	iframe.style.height = (iframe.contentWindow.document.body.offsetHeight + 30 ) + 'px'; 
245					##}); 
246 
247					## INICIO ENT-525601 
248					## DIFERENCIA CON LA PLANTILLA DE IFRAME GLOBAL 
249					## Se cambia la función para calcular el alto para que tenga en cuenta el alto de un tag del iframe 
250					## También se aprovecha para coger un id del iframe y utilizar su texto para completar el breadcrumb 
251					 
252					##Autoajustar alto del iframe cada X milisengundos --> 
253					var milisengundosRefresco = 100; 
254					//milisengundosRefresco = 2000; 
255				 
256 
257					var debug = false; 
258					//debug = true; 
259					setInterval(function() { 
260						 
261						/* Recogemos los diferentes elementos del DOM */ 
262						const iframeContainer 	= document.getElementById('iframe-container-${iframeId}'); 
263						const iframe 			= document.getElementById('iframe-${iframeId}'); 
264						const iframeWindow 		= iframe.contentWindow; 
265						const iframeDocument 	= iframeWindow.document;				 
266						const main 				= iframeDocument.querySelector("app-root main"); 
267						const header 			= iframeDocument.querySelector("app-root app-header header"); 
268						const legislation 		= iframeDocument.querySelector("app-root app-legislation-by-areas section"); 
269						const eli 				= iframeDocument.querySelector("app-root app-eli section"); 
270						 
271					 
272						/* Se setablecen los valores por defecto por si el contenido de iframe todavía no está cargado */ 
273						let mainScrollHeight 			 = 500; 
274						let headerScrollHeight 			 = 500; 
275						let iframeScrollHeight 			 = 0; 
276						 
277						/*Obtenemos los alto de los elementos*/ 
278						if(main){ 
279							mainScrollHeight = main.scrollHeight; 
280						}else if(legislation){ 
281							mainScrollHeight = legislation.scrollHeight; 
282						}else if(eli){ 
283							mainScrollHeight = eli.scrollHeight; 
284
285						if(header){ 
286							headerScrollHeight = header.scrollHeight; 
287
288						if(iframe){ 
289							iframeScrollHeight = iframe.scrollHeight 
290
291						 
292						 
293						const margenAnyadido = 100; 
294						 
295						const alturaCalculada = mainScrollHeight + headerScrollHeight + margenAnyadido + 'px'; 
296						 
297						if (debug) console.log("--------------------------------------"); 
298						if (debug) console.log("BUSCAMOS EL NUEVO ALTO DEL IFRAME"); 
299						if (debug) console.log("iframeScrollHeight = " 				+ iframeScrollHeight); 
300						if (debug) console.log("mainScrollHeight = " 				+ mainScrollHeight); 
301						if (debug) console.log("headerScrollHeight = " 				+ headerScrollHeight); 
302						if (debug) console.log("alturaCalculada = " 				+ alturaCalculada); 
303						if (debug) console.log("FIN BUSCAMOS EL NUEVO ALTO DEL IFRAME"); 
304						if (debug) console.log("--------------------------------------"); 
305						 
306						if(iframeScrollHeight != mainScrollHeight){ 
307							iframe.style.height = alturaCalculada; 
308
309 
310						 
311						/* ************************************************************************************ */ 
312						/* Cogemos del IFRAME del DOGV la parte del camino de migas que montan en la aplicacion */ 
313						/* ************************************************************************************ */ 
314						if (debug) console.log("--------------------------------------"); 
315						if (debug) console.log("BUSCAMOS EL BREADCRUMB"); 
316						 
317						/* Definimos el selector del elemento dentro del iframe con el texto que se debe incluir en el iframe */ 
318						var bselector = 'breadcrumb-title'; 
319						var biframeselector = "iframe-"+bselector; 
320						/* Definimos el selector del elemento del breadcrumb dentro del iframe */ 
321						var bselectorBreadcrumb = 'ul.breadcrumbs-horizontal'; 
322						var biframeDocument = iframeDocument; 
323						var belement =  biframeDocument.getElementById(bselector); 
324						if ((typeof belement !== 'undefined') && belement ) { 
325							if (debug) console.log("Se ha encontrado el elemento: " + bselector);  
326							var text_to_add = belement.textContent; 
327							if (debug) console.log("text_to_add: " + text_to_add); 
328							if (text_to_add.length !== 0) { 
329								/* Ya tenemos el texto ahora hay que buscar el elemento del breadcrumb donde incluirlo */ 
330								var bul = document.querySelector(bselectorBreadcrumb); 
331								if ((typeof bul !== 'undefined') && bul) { 
332									if (debug) console.log("Se encuentra el ul con el selector: " + bselectorBreadcrumb); 
333									/* Tenemos que buscar si el elemento li ya existe o hay que crearlo */ 
334									var bli =  bul.querySelector("#"+biframeselector); 
335									if ((typeof bli !== 'undefined') && bli) { 
336										if (debug) console.log("Se encuentra el li con el selector: " + biframeselector); 
337										var span = bli.getElementsByTagName("span")[0]; 
338										if (debug) console.log("Se encuentra el span"); 
339										span.innerHTML = text_to_add; 
340									} else { 
341										if (debug) console.log("Vamos a crear el li"); 
342										bli = document.createElement("li"); 
343										bli.setAttribute('id',biframeselector); 
344										var span = document.createElement("span"); 
345										span.appendChild(document.createTextNode(text_to_add)); 
346										bli.appendChild(span) 
347										bul.appendChild(bli) 
348
349
350
351
352						if (debug) console.log("FIN BUSCAMOS EL BREADCRUMB"); 
353						if (debug) console.log("--------------------------------------"); 
354						 
355					},milisengundosRefresco); 
356					<#-- FIN ENT-525601 --> 
357						 
358				</#if> 
359				 
360 
361				$(document).ready(function() { 
362			 
363					<#-- Autoajustar alto cada vez que se cargue el contenido del iframe --> 
364					<#if ajustar_alto > 
365						$('#iframe-${iframeId}').load(function() { 
366							this.style.height = (this.contentWindow.document.body.offsetHeight + 30 ) + 'px'; 
367						}); 
368					</#if>  
369 
370				 
371					<#-- Ocultar los enlaces de Atrás y Enlace permanente para que aparezcan sólo si se ha navegado dentro del iframe --> 
372					<#if mostrar_enlazar > 
373						$('#iframe-show-link-${iframeId}').hide(); 
374					</#if> 
375					<#if mostrar_atras > 
376						$('#iframe-back-link-${iframeId}').hide(); 
377					</#if> 
378 
379					var numLoads = 0; 
380					document.getElementById('iframe-${iframeId}').onload = function (element) { 
381						if (numLoads > 0) { 
382							if ($(window).scrollTop() > $('#iframe-container-${iframeId}').offset().top) { 
383								$('html, body').animate({ scrollTop: $('#iframe-container-${iframeId}').offset().top - 60 }, 'slow'); 
384
385							 
386							<#if mostrar_enlazar || mostrar_atras > 
387								$('#iframe-link-input-${iframeId}').fadeOut(); 
388							</#if> 
389
390						 
391						 
392						if (numLoads == 1) { 
393							<#if mostrar_enlazar > 
394								$('#iframe-show-link-${iframeId}').show(); 
395							</#if> 
396							<#if mostrar_atras > 
397								$('.portlet-journal-content .iframe-controls-${iframeId} .back-link').show(); 
398							</#if> 
399
400						 
401						numLoads++; 
402
403					<#-- Obtener enlace permanente del iframe --> 
404					<#if mostrar_enlazar > 
405					$('#iframe-show-link-${iframeId}').click(function (event) { 
406						//Cuando le damos click no queremos que se quede el marco del foco 
407						$('#iframe-show-link-${iframeId}').blur(); 
408						 
409						var input = $('#iframe-link-input-${iframeId}'); 
410						 
411						if (!$(input).is(':visible')) { 
412							var iframeLocation = document.getElementById('iframe-${iframeId}').contentWindow.location; 
413							var pageUrl = window.location.href; 
414							var iframeParams = iframeLocation.href; 
415 
416							if (pageUrl.includes('?')) { 
417								pageUrl = pageUrl.substring(0, pageUrl.indexOf('?')); 
418
419							 
420							if (iframeParams.includes('?')) { 
421								iframeParams = iframeParams.substring(iframeParams.indexOf('?')+1); 
422								iframeParams = '&' + iframeParams.replace(/(&)?viewUrl=[^&]+/g, ''); 
423							} else { 
424								iframeParams = ''; 
425
426							 
427							$(input).val(pageUrl + '?viewUrl${iframeId}=' + encodeURIComponent(iframeLocation.pathname) + iframeParams); 
428
429						$(input).fadeToggle(); 
430					}); 
431					<#-- Para que funcione cuando le damos al enter --> 
432					$('#iframe-show-link-${iframeId}').keyup(function(event){ 
433						if (event.keyCode == 13) { 
434							event.preventDefault(); 
435							$('#iframe-show-link-${iframeId}').click(); 
436
437					}); 
438					</#if> 
439 
440					<#-- Imprimimos sólo el contenido del iframe --> 
441					<#if mostrar_imprimir > 
442					$('#iframe-print-${iframeId}').click(function (event) { 
443						var ifr = document.getElementById("iframe-${iframeId}"); 
444						ifr.contentWindow.focus(); 
445						ifr.contentWindow.print();		 
446						//Cuando le damos click no queremos que se quede el marco del foco 
447						$('#iframe-print-${iframeId}').blur(); 
448					}); 
449					 
450					<#-- Para que funcione cuando le damos al enter --> 
451					$('#iframe-print-${iframeId}').keyup(function(event){ 
452						if (event.keyCode == 13) { 
453							event.preventDefault(); 
454							$('#iframe-print-${iframeId}').click(); 
455
456					}); 
457					</#if> 
458 
459					<#-- El enlace « Atrás de los publicadores para los contenidos de tipo IFRAME, vuelve atrás en el historial para que deshaga una posible navegación realizada en la página incrustada --> 
460					$("span[class='header-back-to']").find("a").attr("href", "javascript:window.history.back()");  
461				}); 
462	 
463				<#-- Controlamos los click en el iframe para que si está desplegado el menu del portal, se esconda 	 -->	 
464				var myConfObj = { 
465				  iframeMouseOver : false 
466
467				window.addEventListener('blur',function(event){ 
468				  if(myConfObj.iframeMouseOver){ 
469					// Ocultar menu desplegado cuando haces click en otro sitio distinto al menu 
470					var $trigger = $(".horizontal .navegacion-superior .nav-menu .level-1 li, .sede .navegacion-superior .nav-menu .level-1 li"); 
471					$trigger.children('ul').slideUp(300); 
472
473				}); 
474				document.getElementById('iframe-container-${iframeId}').addEventListener('mouseover',function(){ 
475				   myConfObj.iframeMouseOver = true; 
476				}); 
477				document.getElementById('iframe-container-${iframeId}').addEventListener('mouseout',function(){ 
478					myConfObj.iframeMouseOver = false; 
479				});				 
480					 
481			</script> 
482			 
483		<#else> 
484			No se ha introduccido una URL de iframe. 
485		</#if> 
486	</div>