Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

47
Sitios web SPI céntricos en el servidor SEO Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA! compatibles sin estado ... ¡ALELUYA! Jose María Arranz Santamaría [email protected] @jmarranz http://www.innowhere.com

description

Hoy día estamos acostumbrados a utilizar aplicaciones Single Page Interface (SPI), es decir, sin recargas, cualquier usuario de GMail está usando este tipo de aplicaciones. Sin embargo el uso de SPI en sitios web es extremadamente raro por dos razones: la necesidad de la compatibilidad SEO y la necesidad de escalabilidad implica servidores replicados (prácticamente) sin estado, ambos aspectos muy enemigos del enfoque SPI. ItsNat v1.3 rompe estas dos aparentemente insalvables limitaciones. Diapositivas de la charla en el Codemotion Madrid 18-19 octubre 2013

Transcript of Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

Page 1: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

Sitios web SPI céntricos en el servidor SEO Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!compatibles sin estado ... ¡ALELUYA!

Jose María Arranz Santamaría

[email protected]

@jmarranz

http://www.innowhere.com

Page 2: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

LA GRAN PREGUNTA

¿PERO TÚ POR QUÉ ESTÁS LEYENDO

ESTO?

Page 3: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

LA GRAN PREGUNTA

¡NADIE HABLA de Single Page Interface Server Centric SEO

Compatible Stateless!

Page 4: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

LA PRUEBA

Buscando en

Google...(3 oct 2013)

¡MIO!¡MIO!

¡MIO!¡MIO!

¡MIO!¡MIO!

¡MIO!¡MIO!

¡MIO!¡MIO!

Page 5: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

LA GRAN PREGUNTA

MIENTO,

ES EL HYPE DE MODA...

Page 6: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

LA GRAN PREGUNTA

AQUÍ

Page 7: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

LA GRAN PREGUNTA

Es fácil concluir que...

Page 8: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

LA GRAN PREGUNTA

¡SOY UN ALIEN!

Page 9: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

LA GRAN PREGUNTA

Umm no, error,

este es mi cuñado...

Page 10: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

LA GRAN PREGUNTA

Este soy yo

Page 11: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

LA GRAN PREGUNTA

Dominar el buscador Dominar el buscador de Google es nuestro de Google es nuestro primer paso en la primer paso en la invasión de la Tierrainvasión de la Tierra

Page 12: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

LA GRAN PREGUNTA

La segunda búsqueda La segunda búsqueda en Google a dominar en Google a dominar es “Coco Loco”es “Coco Loco”

Page 13: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

LA GRAN PREGUNTA

Si esto te interesa también a ti, entonces...

Page 14: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

LA GRAN PREGUNTA

TÚ TAMBIÉN ERES UN ALIEN

Page 15: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿QUIEN SOY YO?

¿QUIEN SOY YO?

Page 16: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿QUIEN SOY YO?

Soy código– ItsNat

– JProxy

– JNIEasy

– JEPLayer

– JEPDroid

– LAMEOnJ

– XPDOM

– ...

Soy empleadohttp://www.linkedin.com/in/jmarranz

http://www.innowhere.com/docs/curriculum_completo.pdf

Soy “activista”“The Single Page Interface Manifesto”

http://itsnat.sourceforge.net/php/spim/spi_manifesto_en.php

y también...

Fui (¿soy?) empresariohttp://www.innowhere.com

Page 17: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿QUIEN SOY YO?

SOY

PROGRAMADOR

Page 18: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

Buscando el Santo Grial Web

Single Page SEO compatible server centric stateless web framework...

o la búsqueda del

Santo Grial del Web

Page 19: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

Buscando el Santo Grial Web

Single Page Interface● No recargas completas (cambios parciales)

=> mayor rendimiento

=> mejor experiencia de usuario

- no página en blanco transitoria

- no scroll al principio de la página

Page 20: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

Buscando el Santo Grial Web

SEO compatible

● Web crawlers capaces de recorrer nuestro sitio web

– Los robots ven nuestra web como paginada (JavaScript es ignorado)

Aproximación “clásica” indeseable

=> hacer "dos webs” SPI y paginada

Page 21: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

Buscando el Santo Grial Web

Server Centric ● Lógica de vista y proceso de eventos

programado fundamentalmente en el servidor*✔ Datos y “vista” en el mismo espacio de memoria✔ Lenguaje estático (Java, Scala...) o dinámico (Groovy...)

favorito✔ Herramientas favoritas (Eclipse, IntelliJ, NetBeans...)

➔ Autocompletado, static analysis, navegación de código, refactorización...

✔ Código fuente puede crecer en libertad *bueno sí, algún inconveniente tiene...

Page 22: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

Buscando el Santo Grial Web

Stateless● El framework no hace uso de la sesión web

– "share nothing" entre nodos● no necesaria sincronización de sesiones● ni afinidad de sesión (sticky sessions)

escalabilidad

horizontal lineal

Page 23: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

Buscando el Santo Grial Web

¿Es ItsNat Single Page Interface SEO Compatible Server Centric y Stateless?

Page 24: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

¡¡¡ SÍ !!!

Page 25: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

¡¡CÓDIGO!!¡¡CÓDIGO!!¡¡CÓDIGO!!

Page 26: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

Page 27: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>ItsNat Core Example</title> </head> <body> <h3>ItsNat Core Example</h3>

<div itsnat:nocache="true" xmlns:itsnat="http://itsnat.org/itsnat"> <div id="clickableId1">Clickable Elem 1</div> <br /> <div id="clickableId2">Clickable Elem 2</div> </div> </body> </html>

Page 28: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

public class CoreExampleDocument implements EventListener { ... public void load() { ... ((EventTarget)clickElem1).addEventListener("click", this,false); } public void handleEvent(Event evt) { EventTarget currTarget = evt.getCurrentTarget(); if (currTarget == clickElem1) { removeClickable(clickElem1); setAsClickable(clickElem2); } else { setAsClickable(clickElem1); removeClickable(clickElem2); } ItsNatEvent itsNatEvt = (ItsNatEvent)evt; ItsNatServletRequest itsNatReq = itsNatEvt.getItsNatServletRequest(); ItsNatDocument itsNatDoc = itsNatReq.getItsNatDocument(); HTMLDocument doc = (HTMLDocument)itsNatDoc.getDocument(); Element noteElem = doc.createElement("p"); noteElem.appendChild(doc.createTextNode("Clicked " + ((Element)currTarget).getAttribute("id"))); doc.getBody().appendChild(noteElem); }

public void setAsClickable(Element elem) { elem.setAttribute("style","color:red;"); Text text = (Text)elem.getFirstChild(); text.setData("Click Me!"); ((EventTarget)elem).addEventListener( "click",this,false); }

public void removeClickable(Element elem){ elem.removeAttribute("style"); Text text = (Text)elem.getFirstChild(); text.setData("Cannot be clicked"); ((EventTarget)elem).removeEventListener( "click",this,false); }}

DOM

Page 29: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

http://www.innowhere.com/itsnat/servlet?itsnat_doc_name=manual.core.example

Page 30: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

✔ Single Page Interface

✔ Server Centric

¿SEO Compatible?

¿Stateless?

Page 31: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

SEO CompatibleEl oscuro secreto de ItsNat: Fast Load Mode

public void setAsClickable(Element elem) public void setAsClickable(Element elem) { { elem.setAttribute("style","color:red;"); elem.setAttribute("style","color:red;"); Text text = (Text)elem.getFirstChild(); Text text = (Text)elem.getFirstChild(); text.setData("Click Me!");text.setData("Click Me!"); ((EventTarget)elem).addEventListener("click",this,false); ((EventTarget)elem).addEventListener("click",this,false); }}

itsNatDoc.setAttribute2("cn_2","style","color:red;");itsNatDoc.setAttribute2("cn_2","style","color:red;");

itsNatDoc.setTextData2("cn_2",null,"Click Me!");itsNatDoc.setTextData2("cn_2",null,"Click Me!");

itsNatDoc.addDOMEventListener("cn_2","click","el_10",null,false,3,-1,2);itsNatDoc.addDOMEventListener("cn_2","click","el_10",null,false,3,-1,2);

itsNatDoc.setAttribute2("cn_2","style","color:red;");itsNatDoc.setAttribute2("cn_2","style","color:red;");

itsNatDoc.setTextData2("cn_2",null,"Click Me!");itsNatDoc.setTextData2("cn_2",null,"Click Me!");

itsNatDoc.addDOMEventListener("cn_2","click","el_10",null,false,3,-1,2);itsNatDoc.addDOMEventListener("cn_2","click","el_10",null,false,3,-1,2);

<div style="color:red;" id="clickableId1">Click Me!</div><div style="color:red;" id="clickableId1">Click Me!</div><div style="color:red;" id="clickableId1">Click Me!</div><div style="color:red;" id="clickableId1">Click Me!</div>

(EN CARGA)

(EVENTO AJAX)

¡¡SEO!!

Page 32: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

SEO Compatible (cont.)Dual links links con “doble vida”

“HTML de día, JavaScript de noche”➔ Link normal con JavaScript desactivado (web crawlers)

➔ Disparador de eventos AJAX con JS activado

<a <a href="?st=overview"href="?st=overview" onclick="setState('overview'); return false;"onclick="setState('overview'); return false;">Overview</a>>Overview</a>

Page 33: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

DEMO

http://www.innowhere.com/insites

http://www.innowhere.com/insites

¡¡¡OJO FAKE!!!¡¡¡OJO FAKE!!!¡¡¡OJO FAKE!!!¡¡¡OJO FAKE!!!

Page 34: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

¿¿STATELESS??

¡¡¡MENTIRA!!!ESE EJEMPLO ES ESENCIALMENTE

STATEFUL

Page 35: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

STATELESS● Soporte introducido en ItsNat v1.3● No aprovecha todo el potencial de ItsNat● Pero permite escalabilidad lineal horizontal

✔ Sin degradación por sincronización de sesiones

✔ Sin necesidad de afinidad de sesión

Page 36: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

STATELESS (modo)● NO hay copia del árbol DOM del cliente en el

servidor– Sesión vacía

– Estado visual únicamente en el cliente

● Eventos AJAX => todos tipo “custom stateless”– Se construye bajo demanda el DOM a insertar

– Necesario enviar info del estado visual

Page 37: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

Page 38: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" xmlns:itsnat="http://itsnat.org/itsnat">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>ItsNat Stateless Example in Manual</title>

<script>

function sendEventStateless()

{

var counterElem = document.getElementById("counterId");

var userEvt = document.getItsNatDoc().createEventStateless();

userEvt.setExtraParam('counter',counterElem.firstChild.data);

userEvt.setExtraParam('itsnat_doc_name','manual.stless.example.eventReceiver');

document.getItsNatDoc().dispatchEventStateless(userEvt,3 /*XHR_ASYNC_HOLD*/, 1000000);

}

</script>

</head>

<body>

<h3>ItsNat Stateless Example in Manual</h3>

<h4 id="presentationId" itsnat:nocache="true"></h4>

<a href="javascript:sendEventStateless()">Send stateless event</a>

<div>

<div>Num. Events: <b id="counterId" itsnat:nocache="true">0</b></div>

</div>

<div>

<div>

<div id="insertHereId" />

</div>

</div> </body>

</html>

Template para carga inicial

Page 39: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" xmlns:itsnat="http://itsnat.org/itsnat">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>ItsNat Stateless Document For Stateless Event Processing</title>

</head>

<body>

<b id="counterId" itsnat:locById="true" itsnat:nocache="true">(num)</b>

<div id="insertHereId" itsnat:locById="true" itsnat:nocache="true" />

</body>

</html>

Template documento para inserción parcial(manual.stless.example.eventReceiver)

Page 40: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"

xmlns:itsnat="http://itsnat.org/itsnat">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>Fragment</title>

</head>

<body>

<h4 style="color:green"><b>Fragment...</b></h4>

<h3>Inserted!</h3>

</body>

</html>

Template fragmento que se incluye en la inserción parcial(manual.stless.example.fragment)

Page 41: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

public class StlessExampleInitialDocument{ protected ItsNatHTMLDocument itsNatDoc;

public StlessExampleInitialDocument(ItsNatHTMLDocument itsNatDoc) { this.itsNatDoc = itsNatDoc;

HTMLDocument doc = itsNatDoc.getHTMLDocument();

Text node = (Text)doc.createTextNode( "This the initial stateless page (not kept in server)");

Element presentationElem = doc.getElementById("presentationId"); presentationElem.appendChild(node); }

}

Clase procesadora de carga inicial

Page 42: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

public class StatelessExampleForProcessingEventDocument implements Serializable,EventListener

{

protected ItsNatHTMLDocument itsNatDoc;

protected Element counterElem;

public StatelessExampleForProcessingEventDocument(

ItsNatHTMLDocument itsNatDoc, ItsNatServletRequest request, ItsNatServletResponse response)

{

this.itsNatDoc = itsNatDoc;

if (!itsNatDoc.isCreatedByStatelessEvent())

throw new RuntimeException("Only to test stateless, must be loaded by a stateless event");

// Counter node with same value (state) than in client:

String currCountStr =

request.getServletRequest().getParameter("counter");

int counter = Integer.parseInt(currCountStr);

HTMLDocument doc = itsNatDoc.getHTMLDocument();

this.counterElem = doc.getElementById("counterId");

((Text)counterElem.getFirstChild()).setData(String.valueOf(counter));

itsNatDoc.addEventListener(this);

}

Clase procesadora de eventos stateless

Page 43: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

public void handleEvent(Event evt)

{

ItsNatEventDOMStateless itsNatEvt = (ItsNatEventDOMStateless)evt;

Text counterText = (Text)counterElem.getFirstChild();

String currCountStr = counterText.getData();

int counter = Integer.parseInt(currCountStr);

counter++;

counterText.setData(String.valueOf(counter));

Document doc = itsNatDoc.getDocument();

Element elemParent = doc.getElementById("insertHereId");

ScriptUtil scriptGen = itsNatDoc.getScriptUtil();

String elemRef = scriptGen.getNodeReference(elemParent);

ClientDocument clientDoc = itsNatEvt.getClientDocument();

clientDoc.addCodeToSend(elemRef + ".innerHTML = '';");

clientDoc.addCodeToSend("alert('Currently inserted fragment removed before');");

ItsNatServlet servlet = itsNatDoc.getItsNatDocumentTemplate().getItsNatServlet();

ItsNatHTMLDocFragmentTemplate docFragTemplate =

(ItsNatHTMLDocFragmentTemplate)servlet.getItsNatDocFragmentTemplate("manual.stless.example.fragment");

DocumentFragment docFrag = docFragTemplate.loadDocumentFragmentBody(itsNatDoc);

elemParent.appendChild(docFrag); // docFrag is empty now

Clase procesadora de eventos stateless (parte 2)

Page 44: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

¿Es ItsNat SPI SEO Compatible Server Centric Stateless?

// Umm we have to celebrate/highlight this insertion

Element child1 = ItsNatTreeWalker.getFirstChildElement(elemParent);

Element child2 = ItsNatTreeWalker.getNextElement(child1);

Text textChild2 = (Text)child2.getFirstChild();

Element bold = doc.createElement("i");

bold.appendChild(textChild2); // is removed from child2

child2.appendChild(bold);

child2.setAttribute("style","color:red");

// <h3 style="color:red"><i>Inserted!</i></h3>

}

}

Clase procesadora de eventos stateless (parte 3)

Page 45: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

Epílogo

+Info● Ejemplo stateless completo

http://itsnat.sourceforge.net/index.php?_page=support.tutorial.core_stateless

http://www.innowhere.com/itsnat/feashow_servlet?itsnat_doc_name=feashow.main&feature=feashow.stless.man.statelessExampleInManual.ex

● Ejemplo sitio web SEO compatible statelesshttp://itsnat.sourceforge.net/index.php?_page=support.tutorial.spi_stateless_site

● Ejemplo sitio web real SEO compatiblehttp://asia.playstation.com/hk/en/regional/game?platform=ps3

Page 46: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

Epílogo

Imágeneshttp://2.bp.blogspot.com/-mBAlHH5OwUE/UPg7LL2ihyI/AAAAAAAAANU/Hys4TkrlNhk/s200/lego-indiana-jones8.jpg

http://mixupload.org/img/forbidden.png

http://www.pammarketingnut.com/wp-content/uploads/gmail.jpg

http://www.bfc-clan.com/PUBLIC/e107_images/custom/server-rules.jpg

http://www.mystikcreation.com/blog/wp-content/uploads/2013/07/responsive-web-design.jpg

http://jan.newmarch.name/ecommerce/stateless.gif

http://www.empowernetwork.com/workwithsheena/files/2013/09/how-to-use-an-onlne-html-editor.jpg

http://www.northeastern.edu/securenu/wp-content/uploads/2013/01/Java_Logo.jpg

http://blog.programmableweb.com/wp-content/w3c.gif

http://upload.wikimedia.org/wikipedia/commons/5/58/Dom_tree.png

http://dab1nmslvvntp.cloudfront.net/wp-content/uploads/2009/02/html1.png

http://2.bp.blogspot.com/_m39Ioh2ptw8/TAZQiFRZIVI/AAAAAAAAChI/DpUw99EcJ9o/s320/verg%C3%BCenza.jpg

http://2.bp.blogspot.com/_0s5FkH27RVs/TPQdT-74xnI/AAAAAAAAAzU/RVCd6FpGWZc/s200/verguenza.jpg

http://www.definicionabc.com/wp-content/uploads/verg%C3%BCenza.jpg

http://img.desmotivaciones.es/201102/verguenza_3.jpg

http://www.hybridcluster.com/wp-content/themes/hybridcloud/images/difficult-server-installation.jpg

http://3.bp.blogspot.com/-HiZ_0Fcc1F8/T_rZjhK4goI/AAAAAAAABUA/b61_asF8eLk/s200/empty.jpg

Page 47: Sitios web SPI céntricos en el servidor SEO compatibles sin estado ... ¡ALELUYA!

Hablemos

¿Preguntas?

?

??

?

?

??

??

?

?

? ?

?

?

? ?