OrderedCollection [
	GrafoscopioNode {
		#header : '%metadata Tutorial (Spanish)',
		#body : '| metadata |
metadata := 
{ 
\'title\' -> \'Live coding & agile visualization for Data Activism\'.
\'author\' -> \'Offray Vladimir Luna Cárdenas\'.
\'colaborators\' -> #(\'Rafael Medina\' \'Iván Pulido\' \'Camilo Hurtado\').
\'date\' -> Date today.
\'shortTitle\' -> \'Data Activism Techniques\'.
\'showOnHelp\' -> true.
\'docType\' -> \'tutorial\'
} asOrderedDictionary
',
		#tags : OrderedCollection [
			'código'
		],
		#children : OrderedCollection [ ],
		#parent : GrafoscopioNode {
			#header : 'Arbol principal',
			#key : '',
			#body : '',
			#tags : OrderedCollection [
				'text'
			],
			#children : @1,
			#level : 0,
			#nodesInPreorder : OrderedCollection [
				@5,
				@2,
				GrafoscopioNode {
					#header : 'Presentación',
					#key : '',
					#body : 'El presente documento tiene como finalidad ayudarte a comprender el funcionamiento básico de Pharo y Grafoscopio.
Se trata de un documento rápido. Para una introducción alternativa a Grafoscopio, su historia, inspiraciones e innovación,
puedes revisar el "Manual de Grafoscopio", que está disponible desde el menú  ̀Ayuda ̀ en sus distintos formatos.
Tanto este tutorial como el manual están construyéndose y podrían llegar a integrarse luego en un único documento.

Para navegar este tutorial, si lo estás viendo como un documento interactivo dentro de grafoscopio, 
(si no lo estás viendo así, te recomendamos que lo abras para hacer la experiencia más interactiva)
basta con que hagas click en cada uno de los nodos que aparecen en el árbol lateral izquierdo. 
Dichos nodos pueden contener otros subnodos lo cual se indica por un pequeño triángulo a la izquierda del nombre
del nodo, que puede estar apuntando a la derecha, para indicar que los contenidos del nodo están comprimidos
o hacia abajo, cuando están extendidos.
Para desplegar o contraer los contenidos de un nodo que agrupa a otros, haces click en dicho triángulo.
',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [ ],
					#parent : @5,
					#level : 1,
					#links : OrderedCollection [
						''
					]
				},
				GrafoscopioNode {
					#header : 'Actos de extrañeza',
					#key : '',
					#body : 'Este tutorial puede lucir un poco extraño, particularmente si no eres programador.
Esto es porque la primera parte es la adaptación de un tutorial para programadores,
que presupone muchos conceptos familiares con la jerga de la programación.
Si eres un programador notarás que, si bien los conceptos son familiares, las maneras
de implementarlos en Smalltalk son distintas y, de hecho más puros y cercanos a las
ideas originales (allí se inició mucho de la computación actual, aunque lo que tenemos
es distinto de lo que se soño).
No te inquietes, iremos explorando y entendiendo con el tiempo esos artefactos extraños, 
y si lees esto como parte de un taller cara a cara (como el Data Week) tendremos tiempo
para conversarlos con mayor detalle.
Además las versiones de este tutorial han cambiado y mejorado con el tiempo, por
lo cual, una versión posterior de grafoscopio y su documentación tendrán mejores
formas de abordar los conceptos.

Por lo pronto te invitamos a que mires este ejercicio de manera casi que etnográfica:
Te aproximarás a un cultura (la de la programación) desde los artefactos prototípicos
que sus pobladores (los programadores) usan, pero en la medida en que lo vayas haciendo
dicha cultura te parecerá menos extraña y ayudarás a construir artefactos menos ajenos, 
que brinden bienvenidas más cálidas y conectadas con personas de culturas más diversas,
como tu.',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [ ],
					#parent : @5,
					#level : 1,
					#links : OrderedCollection [
						''
					]
				},
				GrafoscopioNode {
					#header : 'Agradecimientos',
					#key : '',
					#body : 'Este tutorial es producto del trabajo realizado durante varios talleres en el hackerspace
 [Hackbo](http://hackbo.co) en Bogotá, Colombia, entre ellos:

  - Los talleres de indie web science, ( 1 noviembre de 2014)
  - Los talleres del [Data Week](http://mutabit.com/dataweek) y sus eventos preparatorios y posteriores.

Agradecemos a las personas que asistieron a los talleres y ayudaron con su presencia a probar este material,
Entre ellos: César Augusto Arias, Claudia Baez, Carlos Barreneche, Luis Alejandro Bernal, Fernando Castro, 
Felix Gerlof, Florencia Goldsman, Camilo Hurtado, Luis Linares, Offray Luna, Rafael Medida, Gloria Meneses, 
Fredy Pulido,  Iván Pulido, Sebastian Pulido  y David Salvador.',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [ ],
					#parent : @5,
					#level : 1,
					#links : OrderedCollection [
						''
					]
				},
				GrafoscopioNode {
					#header : 'Introductorio: Professor Stef',
					#headers : OrderedCollection [
						'Tutorial 1',
						'Tutorial 2',
						'Tutorial 3',
						'Tutorial 4',
						'Tutorial 5.',
						'Tutorial 6',
						'Tutorial 7',
						'Tutorial 8',
						'Tutorial 9',
						'Tutorial 10',
						'Tutorial 11'
					],
					#key : '',
					#body : 'Este tutorial mostrará los aspectos básicos de la sintaxis de Smalltalk y está basado
en el tutorial ProfStef que viene integrado a Pharo, pero convertido en un cuaderno
interactivo de Grafoscopio.
Está separado por lecciones. que vienen numeradas y en ocasiones están agrupadas.
Para ver el contenido particular de una lección se debe hacer click en ella en el árbol
lateral a la izquierda.
Si están agrupadas, se verá un triangulito en el título que las agrupa.
Al hacer click en él, se mostrarán los contenidos del mismo, que podremos seguir
explorando con la misma lógica.
',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [
						GrafoscopioNode {
							#header : 'Lección 1: Bienvenida',
							#headers : OrderedCollection [ ],
							#key : '',
							#body : '"Hola!, Soy el profesor Stef. Debes querer que te ayude a aprender 
Pharo. Así que vamos a la primera lección: aprender a ejecutar código. 
Para ello hay varias opciones:
  - Opción 1: Selecciona el texto debajo, o coloca el cursor luego del punto, dale clic 
    derecho y selecciona \'do it (d)\'
  - Opción 2: Haz click en el botón con el ícono de play que aparece justo cerca a la 
    esquina superior derecha de este panel"

ProfStef  openPharoZenWorkspace 

',
							#tags : 'código',
							#children : OrderedCollection [ ],
							#parent : @20,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Lección 2: Haciendo',
							#headers : OrderedCollection [ ],
							#key : '',
							#body : '"Excelente! (quise decir Súper)). Acabas de ejecutar una expresión de Pharo. Más precisamente,
enviaste el mensaje \'next\' a PharoTutorial class (¡soy yo!).

Nota que puedes correr este tutorial nuevamente evaluado \'PharoTutorial go\'.
\'PharoTutorial previous\' te devolverá a la lección anterior.

También puedes ejecutar \'Do it\' usando el comando de teclado \'ALT d\' (esto cambia de acuerdo a 
tu sistema operativo/computador: puede ser \'CMD d\' o \'CTRL d\').

Trata de evaluar las siguientes expresiones:"

Nautilus open.

SmalltalkImage current aboutThisSystem.

"Ahora ve a la siguiente lección"',
							#tags : 'código',
							#children : OrderedCollection [ ],
							#parent : @20,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Lección 3: Imprimiendo',
							#headers : OrderedCollection [ ],
							#key : '',
							#body : '"Now you\'re a Do It master ! Let\'s talk about printing. 
It\'s a Do It which prints the result next to the expression you\'ve selected.
For example, select the text below, open the menu and click on \'print it (p)\':"

1 + 2.

"You\'ve seen the letter \'p\' between parentheses next to \'print it\' ? It indicates the 
ALT- (or CMD- or CTRL-) shortcut to execute this command.

Try ALT-p (or CMD-p or CTRL-p) on the following expressions:"

Date today.

Time now.

"The result is selected, so you can erase it using the backspace key. Try it !"

SmalltalkImage current datedVersion.

"Ahora ve a la siguiente lección"',
							#tags : 'código',
							#children : OrderedCollection [ ],
							#parent : @20,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Lección 4: Inspeccionando',
							#key : '',
							#body : '"Now you\'re a Do It and Print It master ! Let\'s talk about inspecting. 
It\'s a Do It which opens an Inspector on the result of evaluating the expression you\'ve selected. 
The Inspector is a tool that allows you to have a look inside an object.

For example, select the text below, open the menu and click on \'inspect it (i)\':"

1 / 2.

"You\'ve seen the letter \'i\' between parentheses next to \'inspect it\' ? It indicates the 
ALT- (or CMD- or CTRL-) shortcut to execute this command.

You can use Ctrl+g to get and embedded inspector.

Try ALT-i (or CMD-i or CTRL-i) on the following expressions:"

DateAndTime today.

Float pi.

SystemVersion current.

"Ahora ve a la siguiente lección"',
							#tags : 'código',
							#children : OrderedCollection [ ],
							#parent : @20,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Tipos básicos',
							#key : '',
							#body : '',
							#tags : OrderedCollection [
								'text'
							],
							#children : OrderedCollection [
								GrafoscopioNode {
									#header : 'Lección 5: Números',
									#key : '',
									#body : '"You now know how to execute Pharo code. 

Now let\'s talk about basic objects.

1, 2, 100, 2/3 ... are Numbers, and respond to many messages evaluating mathematical expressions.
Evaluate these ones:"

2.

20 factorial.

1000 factorial / 999 factorial.

(1/3).

(1/3) + (4/5).

(1/3) asFloat.

1 class.

1 class maxVal class.

.

"Ahora ve a la siguiente lección"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @39,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Lección 6: Caracteres',
									#key : '',
									#body : '"Un caracter puede ser instanciado usando el operador $"

$A.

$A class.

$@ charCode.

Character cr.

Character space.

"Puedes imprimir todos los 256 caracteres del código extendido ASCII"

Character allByteCharacters.

"Ahora ve a la siguiente lección"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @39,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Lección 7: Cadenas',
									#headers : OrderedCollection [ ],
									#key : '',
									#body : '"Un String o cadena es una colección de caracteres. 
Usa comillas simples para crear un objeto String. 
Imprime estas expresiones"

\'a\' class.

$a class.

\'PharoTutorial\'.

\'PharoTutorial\' size.

\'abc\' asUppercase.

\'NO more Hello World!\' reverse.

\'Adan no calla con nada\' reverse.

\'Anita lava la tina\' reverse.

"Puedes acceder a cada caracter usando \'at:mensaje\'"

\'PharoTutorial\' at:6.

"La concatenación de String usa el operador coma:"

[\'PharoTutorial\', \' is cool\']. "versión cambiada"

\'Pharo tutorial \', \' is cool\', \' when i active the code \'.

"Ahora ve a la siguiente lección"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @39,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Lección 8: Símbolos',
									#headers : OrderedCollection [ ],
									#key : '',
									#body : '"Un \'Symbol\' es un String único globalmente.

Hay uno y solo un Symbol #PharoTutorial. Pueden existir varios objetos String \'PharoTutorial\'

(Message=retorna \'true\' si los dos objetos son IGUALES)"

\'PharoTutorial\' asSymbol.

#PharoTutorial asString.

"Notra: En mátemáticas hay dos tipos de igualdad:

x = 3 <- Aginación. A la variable x, le estamos asignando el valor 3.
2 = 3 <- Comparación: dados dos elementos conocidos decir si es o no el mismo.

Para Smalltalk es:

x := 3. <- Aginación.
2 = 3 <- Comparación.
a == a <- Comparación fuerte. Se trata del mismo símbolo?
"

\'PharoTutorial\' = \'PharoTutorial\'.
\'PharoTutorial\' == \'PharoTutorial\'.

#PharoTutorial = \'PharoTutorial\'.
#PharoTutorial == \'PharoTutorial\'.

(2 asString) == (2 asString).


(2 asString) asSymbol == (2 asString) asSymbol.


"Ahora ve a la siguiente lección"
',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @39,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Lección 9: Arreglos',
									#headers : OrderedCollection [ ],
									#key : '',
									#body : '"Los arreglos son maneras de guardar información información diversa.
Los hay de dos tipos, estáticos y dinámicos. Acá veremos los primeros"
#(1 2 3).

#( 1 2 3 #(4 5 6)) size.

#(1 2 4) isEmpty.

#(1 2 3) first.

#(\'hello\' \'World\') 
    at: 2 put: \'Pharo\'; 
   yourself.
',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @39,
									#level : 3,
									#links : OrderedCollection [
										'',
										'http://ws.stfx.eu/7FXPZYUXWU54'
									]
								},
								GrafoscopioNode {
									#header : 'Lección 10: Arreglos dinámicos',
									#headers : OrderedCollection [ ],
									#key : '',
									#body : '"Los arreglos dinámicos son creados durante el tiempo de ejecución, es decir que podemos
guardar en ellos cálculos que luego se ejecutarán y determinarán lo que en ellos se guarda"

{ (2+3).(6*6) }.

"Comparemos este arreglo estático"

#( (2+3)  (6+6)  \'hello\' , \'Stef\') size.  

"con este arreglo dinámico:"

{ (2+3) . (6+6) . \'hello\' , \'Stef\' } size.

"Ahora ve a la siguiente lección"
',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @39,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								}
							],
							#parent : @20,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Mensajes',
							#key : '',
							#body : '',
							#tags : OrderedCollection [
								'text'
							],
							#children : OrderedCollection [
								GrafoscopioNode {
									#header : 'Lección 11:  Unarios',
									#headers : OrderedCollection [ ],
									#key : '',
									#body : '"Los mensajes son enviados a objetos. 
Hay tres tipos de mensajes: unary (unarios), binary (binary) y keyword.

Los mensajes unarios tienen la forma siguiente.

anObject aMessage

Tu ya has enviado mensajes unarios. Por ejemplo:"

1 class.
#b class.

$b class.

true not.

false not.

Time now.

Date today.

Date yesterday.

Date tomorrow.

Float pi.

"Ahora ve a la siguiente lección"
',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @65,
									#level : 3,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Lección 12: Binarios',
									#headers : OrderedCollection [ ],
									#key : '',
									#body : '"Los mensajes binarios tienen la forma siguiente:
anObjecto aMessage anotherObject"

3 + 2.

25 * 25.

1 + 1 = 2.

Date today + 3 weeks.

Date today + 3 years.

Date today - 3 years.

false | false.


true | false.


true | true.

false | true.


true & true.

true & false.

10 @ 100.

10 <= 12.


10 >= 12.

\'ab\', \'cd\'.

Date today < Date yesterday.
Date today > Date yesterday.

"Ahora ve a la siguiente lección"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @65,
									#level : 3,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Lección 13: keywords',
									#key : '',
									#body : '"Los mensajes \'keyword\' son mensajes con argumentos. Tienen la siguiente forma:
    anObject akey: anotherObject akey2: anotherObject2"


4 between: 0 and: 5.

"El mensaje lo que nos dice es: si (4) esta entre (0 y 10) cuya respuesta es verdadero, pero si cambio el valor del 0 por 3, el resultado es falso"

1 max: 3.

"determina el valor máximo"

Color r:1 g:0 b:0.

"El mensaje es r:g:b: implementado en la clase Color. Note que también puede escribir"

Color
\tr: 15
\tg: 99
\tb: 100.

\t
"Si quieres usar código RGB usando valores de 0 a 255, como es la práctica usual, deberás
escribirlos como cociente, de forma que sean un número entre 0 y 1. 
Por ejemplo r: x/255 g: y/255 b: z/255, donde x,y,z son los valores entre 0 y 255 correspondientes al código que color que queremos obtener."
\t
"Ahora ve a la siguiente lección"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @65,
									#level : 3,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Lección 14: Prioridad',
									#key : '',
									#body : '"los mensajes unarios son ejectuados primero, los mensajes binarios son ejecutados despues 
y finalmente las cadenas de mensajes:  paréntesis > Unary > Binary > Keywords"

2 + 3 raisedTo: 2.

2 + 3 + 4.


2 raisedTo: (3 + 2). 
  
(0@0) class.

0@0 corner: 100@200.

(0@0 corner: 100@200) class.

"entre mensajes de procedencia similar, las expresiones son ejectuadas de izquierda a derecha"

-3 abs negated reciprocal.

"Ahora ve a la siguiente lección"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @65,
									#level : 3,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Lección 15: Cambiar prioridad de los mensajes',
									#key : '',
									#body : '"usar parentesis cambia el orden de evaluación de la sentencia, primero se ejecuta la parte interna() 
y posteriormente la sentencia"

(2 + 3) squared.

(2 raisedTo: 3) + 2.

(0@0 extent: 100@200) bottomRight.

"Ahora ve a la siguiente lección"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @65,
									#level : 3,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Lección 16: Prioridad de los mensajes matemáticos',
									#key : '',
									#body : '"Las reglas tradicionales de las matematicas NO aplican dentro de Pharo."

2 * 10 + 2.

"aqui el mensaje por (*) es enviado a dos, corresponde a 20, entonces 20 reciben el mensaje +,

recuerde que todos los mensajes simpre siguen una regla precente de izquierda a derecha, sin excepciones."

2 + 2 * 10. 

2 + (2 * 10). 

(2 * 10) + 2. 

8 - 5 / 2. 

(8 - 5) / 2. 

8-(5/2).

"Ahora ve a la siguiente lección"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @65,
									#level : 3,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Lección 17: Mensajes en cascada',
									#key : '',
									#body : '"; es un operador en cascada. Es usado para enviar mensajes al mismo receptor
Abrir un Transcript (consola):"

Transcript open.

"Entonces:"

Transcript show: \'hola\'.
Transcript cr.
Transcript show: \'Pharo\'.


"Es igual a:"

Transcript 
\t   show: \'hello\';
\t   cr;
\t   show: \'Pharo\'.

"Intenta ir a la siguiente leccion con un cascada de dos mensjaes \'siguiente\'"

"Ahora ve a la siguiente lección"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @65,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Lección 18: Perdido?',
									#key : '',
									#body : '"Esta era una lección que venía en el viejo tutorial. Fue mantenida para
preservar la numeración. No es necesario hacer nada"

"Ahora ve a la siguiente lección"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @65,
									#level : 3,
									#links : OrderedCollection [ ]
								}
							],
							#parent : @20,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Lección 19: Bloques',
							#key : '',
							#body : '"Los mensajes en cascada son chéveres. Ahora hablemos de los bloques.
Los bloques son métodos anónimos que pueden ser almacenados en variables y ejecutados por demanda.

Los bloques están delimitados por paréntesis cuadrados: []"

[Nautilus open].

"No abre un Nautilus porque el bloque no es ejecutado.

Acá hay otro bloque que suma 2 a su argumento (su argumento se llama x):"

[:x | x+2].

"Podemos ejecutar un bloque enviandole mensajes \'value\' "
[:x | x+2] value: 5.

[Nautilus open] value.

[:x | x+2] value: 10.

[:x :y | x - y] value:3 value:5.

"Ahora ve a la siguiente lección"',
							#tags : 'código',
							#children : OrderedCollection [ ],
							#parent : @20,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Lección 20: Asignación de Bloques',
							#key : '',
							#body : '"Los bloques pueden ser asignados a variables y ejecutados después.

Note que |b| es la declaración de una variable llamada \'b\' y que \':=\' asigna un valor a una variable.

Selecciona las siguientes tres líneas e imprimelas (Print it)" 

| b |

[:x | x+2] value: 20.


b := [:x | x+2].


b value: 20. 


"Ahora ve a la siguiente lección"',
							#tags : 'código',
							#children : OrderedCollection [ ],
							#parent : @20,
							#level : 2,
							#links : OrderedCollection [ ]
						},
						GrafoscopioNode {
							#header : 'Lección 21: Condicionales',
							#key : '',
							#body : '"Los condicionales son sólo menajes enviados a objetos Boolean (booleanos)"

1 < 2
  ifTrue: [Transcript show: \'Es cierto\']
  ifFalse: [Transcript show: \'Es falso\'].

"Aquí el mensajes es ifTrue:ifFalse

Prueba esto:"

Transcript open. 

3 > 10 
\tifTrue: [Transcript show: \'Quizás hay un error ....\']
\tifFalse: [Transcript show: \'No: 3 es menor que 10\']. 

3=3 ifTrue: [ProfStef openPharoZenWorkspace].

"Ahora ve a la siguiente lección"',
							#tags : 'código',
							#children : OrderedCollection [ ],
							#parent : @20,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Lección22: Ciclos e Iteradores',
							#key : '',
							#body : '"Los ciclos con iteradores de alto nivel sobre las colecciones, implementados como métodos regulares."

"Ciclos básicos:
  to: do:
  to:by:do"

1 to: 10.

1 to: 15 do:
  [:i | Transcript show: i*2  "asString"; cr ]. 

1 to: 20 by: 3 do: [:i | Transcript show: i asString; cr].

30 to: 0 by: -2 do: 
    [:i | Transcript show: i asString; cr].

"Ahora ve a la siguiente lección"',
							#tags : OrderedCollection [
								'código'
							],
							#children : OrderedCollection [
								GrafoscopioNode {
									#header : '¿Qué hacer cuando necesito tanto el índice como el objeto?',
									#key : '',
									#body : '"doWithIndex permite trabajar con los objetos y con su índice, es decir tener bloques
que reciben dos argumentos"
| colors |

colors := OrderedCollection new.
colors 
\tadd:(Color r: 1 g: 0 b: 0);
\tadd:(Color r: 0 g: 1 b: 0);
\tyourself.
colors doWithIndex: [ :color :i | Transcript show: \'El color número \', i asString, \' es: \', color name asString; cr ]

',
									#tags : OrderedCollection [
										'código'
									],
									#children : OrderedCollection [ ],
									#parent : @104,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								}
							],
							#parent : @20,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Lección 23: Colecciones',
							#key : '',
							#body : '"El mensaje do: es enviado a una colección de objetos (Array, Set, OrderedCollection),
evaluando el bloque para cada elemento.

Acá queremos imprimir todos los números sobre el Transcript (una consola)"

| miColeccion |

#(11 38 3 -2 10) do: [:each |
     Transcript show: each*2; cr].

"Some other really nice iterators"

miColeccion := #(11 38 3 -2 10) collect: [:each | each abs].

#(11 38 3 -2 10) collect: [:each | each odd]. 

#(11 38 3 -2 10) select: [:each | each odd]. 

#(11 38 3 -2 10) select: [:each | each >= 10].  

#(11 38 3 -2 10) reject: [:each | each > 10]. 

#(11 38 3 -2 10) 
     do: [:each | Transcript show: each printString]
     separatedBy: [Transcript show: \'.\'].

#(11 38 3 -2 10) detect: [ :el | el = 0 ] 
\tifFound: [ Transcript show: \'Encontrado\' ]
 \tifNone: [  ^ nil ]

"Ahora ve a la siguiente lección"',
							#tags : OrderedCollection [
								'código'
							],
							#children : OrderedCollection [ ],
							#parent : @20,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Opcional',
							#key : '',
							#body : 'Las siguientes lecciones son algo más avanzadas y referidas a elementos  de interfaces gráficas
(botones, morphs) y cambios en caliente en los métodos de Smalltalk.
Si bien son importantes, las exploraremos con detalle en otros lugares, así que puedes
pasar al cierre de este tutorial y luego ir  a otros nodos como los de
código elegante en Pharo y otros ejemplos minimalistas para terminar en los distintos
proyectos del nodo titulado "Visualización de datos".',
							#tags : OrderedCollection [
								'text'
							],
							#children : OrderedCollection [
								GrafoscopioNode {
									#header : 'Lección24',
									#key : '',
									#body : '"Los objetos son instancias de sus clases. Usualmente, enviamos el mensaje #new a una clase
para crear una instancia de esta clase.

El mensaje #allInstances enviado a una clase, responde un arreglo con todas las instancias de esta clase.

Por ejemplo, miremos cuántas instancias de SimpleButtonMorph existen, imprimiendo la siguiente línea:"

SimpleButtonMorph allInstances size.

"Ahora creemos una nueva instancia de él"

SimpleButtonMorph new
\tlabel: \'Un agradable botón\';
\topenCenteredInWorld.

"Ves el botón centrado en el mundo? La lista de todas las instancias debería contener una instancia más:"

SimpleButtonMorph allInstances size.

"Juguemos con él:"

SimpleButtonMorph allInstances last 
\tlabel: \'El Tutorial de Pharo es cheeevere !\';
\tcolor: Color cyan.
\t
"Borrémosla y pidámosle al sistema limpiar la memoria:"

SimpleButtonMorph allInstances last delete.
Smalltalk garbageCollect.
SimpleButtonMorph allInstances size.

"Haz click sobre el botón para ir a la siguiente lección:"

SimpleButtonMorph new
\tlabel: \'Go to next lesson\';
\ttarget: [ProfStef next. 
\t\t\tSimpleButtonMorph allInstances last delete];
\tactionSelector: #value;
\topenCenteredInWorld.
\t
"Ahora ve a la siguiente lección"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @116,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Lección 25',
									#key : '',
									#body : '"Puedes inspeccionar y cambiar el sistema en tiempo de ejecución.

Mira el código fuente del método #ifFalse:ifTrue: de la clase True:"

(True>>#ifFalse:ifTrue:) definition.

"O sólo su comentario:"

(True>>#ifFalse:ifTrue:) comment.

"Acá están todos los métodos que implementa el ProfStef, base de este notebook:"

ProfStef selectors.

"Creemos un nuevo método para ir a la siguiente lección:"

ProfStef class compile:\'goToNextLesson
  self next\'.

"Wow! No puedo esperar a usar mi nuevo método!"

"Ahora ve a la siguiente lección"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @116,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Lección 26',
									#key : '',
									#body : '"Tan chévere, ¿no? Antes de ir más allá, removamos este método:"

ProfStef respondsTo: #goToNextLesson.

ProfStef class removeSelector: #goToNextLesson.

ProfStef respondsTo: #goToNextLesson.

"Ahora mover hacia adelante"



"Ahora ve a la siguiente lección"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @116,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Lección 27',
									#key : '',
									#body : '"Pharo is full of objects. There are windows, text, numbers, dates, colors, points and much more. You can interact with objects in a much more direct way than is possible with other programming languages.

Every object understands the message \'explore\'. As a result, you get an Explorer window that shows details about the object."

Date today explore.

"This shows that the date object consists of a point in time (start) and a duration (one day long)."

ProfStef explore.

"You see,  class has a lot of objects. Let\'s take a look at my code:"

ProfStef browse.

"Ahora ve a la siguiente lección"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @116,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Lección 28',
									#body : '',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @116,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Lección 29',
									#body : '"This tutorial is done. Enjoy programming with Pharo. 

Don\'t forget to read \'Pharo By Example\' found here:  

\thttp://pharobyexample.org/

You can run this tutorial again by evaluating:"

ProfStef go.

"Do you want to create your own interactive tutorial with ProfStef? That\'s very easy!!  How ? There\'s a ProfStef interactive tutorial for that :D
Just evaluate the following code:"

ProfStef goOn: HowToMakeYourOwnTutorial

"But, of course, if you are reading this as a Grafoscopio notebook, you will be able to create
other tutorials as interactive notebooks, like this one in a really easy way.

Please explore the next parts of this interactive notebook or go to the Grafoscopio page to learn
more about it: 

http://mutabit.com/grafoscopio/ <~ Spanish page
http://mutabit.com/grafoscopio/index.en.html <~ Engish page

"

"See you soon !"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @116,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								}
							],
							#parent : @20,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Cierre',
							#body : 'Esta parte del tutorial ha introducido la sintaxis y los elementos básicos del lenguaje.
Las lecciones venideras construyen sobre ello y profundizan en Pharo, aplicándolo a
problemas cada vez más complejos y específicos, desde los cuales esperamos puedas
construir tus propias recontextualizaciones y adaptaciones.',
							#tags : OrderedCollection [
								'text'
							],
							#children : OrderedCollection [ ],
							#parent : @20,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						}
					],
					#parent : @5,
					#level : 1,
					#links : OrderedCollection [ ]
				},
				@24,
				@28,
				@32,
				@36,
				@39,
				@42,
				@45,
				@48,
				@52,
				@56,
				@60,
				@65,
				@68,
				@72,
				@76,
				@79,
				@82,
				@85,
				@88,
				@91,
				@95,
				@98,
				@101,
				@104,
				@107,
				@112,
				@116,
				@119,
				@122,
				@125,
				@128,
				@131,
				@134,
				@138,
				GrafoscopioNode {
					#header : 'Intermedio: Scripting',
					#key : '',
					#body : '',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [
						GrafoscopioNode {
							#header : '"one liners"',
							#key : '',
							#body : 'Estos scripts de una sóla línea (o "casi una" :-P) que fueron tomados de 
[elegant pharo code](https://medium.com/concerning-pharo/elegant-pharo-code-bb590f0856d0#.6kmkvmvre).
Recomendamos que le des una mirada esta excelente entrada de blog com más detalles e
ir completando los ejemplos que iniciamos acá.',
							#tags : OrderedCollection [
								'text'
							],
							#children : OrderedCollection [
								GrafoscopioNode {
									#header : 'Get the HTML source of a web page',
									#key : '',
									#body : '\'http://www.pharo.org\' asUrl retrieveContents
',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @146,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Compute difference in days between two dates',
									#key : '',
									#body : '(\'2014-070-01\' asDate - \'2013/2/1\' asDate) days',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @146,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Decimal digit length of 42!',
									#key : '',
									#body : '42 factorial decimalDigitLength',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @146,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Set up an HTTP server that returns the current timestamp',
									#key : '',
									#body : '(ZnServer startDefaultOn: 8080) 
  onRequestRespond: [ :request | 
    ZnResponse ok: (ZnEntity with: DateAndTime now printString) ]',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @146,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Take an email address and get its respective avatar from Gravatar when exits',
									#key : '',
									#body : '| email url |
email := \'Gpmeneses@gmail.com\'.
email trimBoth asLowercase.
(MD5 hashMessage: email trimBoth asLowercase) hex.

url := 
 \'http://www.gravatar.com/avatar/\', 
 (MD5 hashMessage: email trimBoth asLowercase) hex,
 \'.jpg\'.
(ZnEasy getJpeg: url) asMorph openInWindow 
',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @146,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Convert all JPG files in the current directory to PNG format',
									#key : '',
									#body : '(FileLocator workingDirectory filesMatching: \'*.jpg\') do: [ :each |
  (each withExtension: \'png\') writeStreamDo: [ :out |
    each readStreamDo: [ :in |
      (PNGReadWriter on: out) nextPutImage: 
        (JPEGReadWriter on: in) nextImage ] ] ]',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @146,
									#level : 3,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Sum of the primes up to 64',
									#key : '',
									#body : '(Integer primesUpTo: 64) sum',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @146,
									#level : 3,
									#links : OrderedCollection [ ]
								}
							],
							#parent : @143,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : '"Few liners" ;-)',
							#key : '',
							#body : 'Estos son otros scripts interesantes que fueron tomados de ejemplos de la comunidad.
Los créditos al autor original están colocados en los comentarios de cada script.',
							#tags : OrderedCollection [
								'text'
							],
							#children : OrderedCollection [
								GrafoscopioNode {
									#header : 'Composición y escalado de morphs (elementos gráficos)',
									#key : '',
									#body : '"Este script toma una image grande, la coloca como fondo y coloca dos morphs simples, un
círculo y un rectángulo escalados sobre ella. Puede tardar un poco en ejecutarse"
| window pane board background scaler|

background := AlphaImageMorph withForm: 
\t(ZnEasy getJpeg: \'http://i.imgur.com/K1QR9vA.jpg\').
background lock.

board := PasteUpMorph new.
board 
color: Color gray;
borderWidth: 3;
borderColor: Color black;
extent: 2000@2000; 
backgroundMorph: background;
addMorph: (CircleMorph new color: Color cyan; position: 41@23; yourself);
addMorph: (Morph new color: Color orange; position: 1200@1200; yourself).

scaler := TransformMorph new.
scaler extent: 1000@1000.
scaler scale: 0.5@0.5.
scaler addMorph: board.

pane := ScrollPane new.
pane scroller addMorph: scaler.

window := pane openInWindow.
window position: 20@20; extent: 420@420.
',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @171,
									#level : 3,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Traer un avatar asociado a un correo electrónico',
									#key : '',
									#body : '| email url |
email := \'gpmeneses@gmail.com\'.
url := \'http://www.gravatar.com/avatar/\', (MD5 hashMessage: email trimBoth asLowercase) hex, \'.jpg\'.
(ZnEasy getJpeg: url) asMorph openInWindow 
',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @171,
									#level : 3,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Graficar un AST (árbol de sintaxis abstracta)',
									#key : '',
									#body : '| ast builder |
ast := RBParser parseExpression: \'self foo. super foo\'.
    builder := RTMondrian new.
    builder shape ellipse size: 15.
    builder nodes: ast allChildren.
    builder edges connectFrom: #parent.
    builder layout tree.
    builder',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @171,
									#level : 3,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'OSM: Consultar Nominatim',
									#key : '',
									#body : '"Thanks to Henrik Nergard"
"Nominatim es un motor de búsqueda para OpenStreetMap. 
Para mayor información sobre este consultar:

http://nominatim.openstreetmap.org/

Este pequeño script extrae resultados de Nominatim y entrega
un polígo que delimita una zona geográfica, reconocida por un nombre, 
por ejemplo \'Teusaquillo\',en Bogotá
"

| baseURL query settings result entries |

query := UIManager default request: \'Find location for\' .

baseURL := \'http://nominatim.openstreetmap.org/search/\'.
settings := \'?format=jsonv2&limit=10\'.

result := MCFileTreeJsonParser parse: (baseURL , query asString, settings) asZnUrl retrieveContents.

(result collect: [ :dct |
\t(dct at: \'display_name\') -> 
\t\t((dct at: \'lat\') asNumber @ (dct at: \'lon\') asNumber)
]) inspect .',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @171,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Lista de las capitales del mundo',
									#key : '',
									#body : '"Thanks to Hernán Morales Durand"
((NeoJSONReader fromString: (
    ZnEasy 
        get: \'http://api.geonames.org/countryInfoJSON\'
        username: \'demo\'
        password: \'\') contents) at: #geonames) collect: [ : d | d at: #capital ]',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @171,
									#level : 3,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Jugando un poco con Open Movie Database',
									#key : '',
									#body : 'Veremos cómo consultar la base de datos de Open
Movie Data Base y extraer datos particulares. 

Los ejemplos acá están basados en variaciones de
código provisto por Hernan Morales Durand.',
									#tags : OrderedCollection [
										'text'
									],
									#children : OrderedCollection [
										GrafoscopioNode {
											#header : 'Afiche de tu película favorita',
											#key : '',
											#body : '',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [
												GrafoscopioNode {
													#header : 'Ejemplos',
													#key : '',
													#body : '',
													#tags : '',
													#children : OrderedCollection [
														GrafoscopioNode {
															#header : 'Blade Runner',
															#key : '',
															#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Blade Runner\';
        get;
        contents)) at: #Poster))
',
															#tags : OrderedCollection [
																'código'
															],
															#children : OrderedCollection [ ],
															#parent : @195,
															#level : 5,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Back to the future',
															#key : '',
															#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Back to the future\';
        get;
        contents)) at: #Poster))
',
															#tags : OrderedCollection [
																'código'
															],
															#children : OrderedCollection [ ],
															#parent : @195,
															#level : 5,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Ghost in the Shell',
															#key : '',
															#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'ghost in the shell\';
        get;
        contents)) at: #Poster))
',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @195,
															#level : 5,
															#links : OrderedCollection [ ]
														},
														GrafoscopioNode {
															#header : 'Good will hunting',
															#key : '',
															#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Good will hunting\';
        get;
        contents)) at: #Poster))
',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @195,
															#level : 5,
															#links : OrderedCollection [
																''
															]
														},
														GrafoscopioNode {
															#header : 'Magnolia',
															#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Magnolia\';
        get;
        contents)) at: #Poster))
',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @195,
															#level : 5,
															#links : OrderedCollection [
																'',
																'http://ws.stfx.eu/6IAL3JKJRYBU'
															],
															#output : @211
														},
														GrafoscopioNode {
															#header : 'Life Is Beautiful',
															#body : '(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: \'Life Is Beautiful\';
        get;
        contents)) at: #Poster))
',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @195,
															#level : 5,
															#links : OrderedCollection [
																'',
																'http://ws.stfx.eu/L27MW66U41R3'
															],
															#output : @214
														}
													],
													#parent : @192,
													#level : 5,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Deconstruyendo el ejemplo',
													#key : '',
													#body : '',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [
														GrafoscopioNode {
															#header : 'Película con variable',
															#key : '',
															#body : '| aTitle |

aTitle := \'Fight club\'.

(ZnEasy getJpeg: ((NeoJSONReader fromString: 
    (ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: aTitle;
        get;
        contents)) at: #Poster))
',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @218,
															#level : 6,
															#links : OrderedCollection [ ]
														},
														GrafoscopioNode {
															#header : 'Con bloques para contenidos traer el JSON)',
															#key : '',
															#body : '| getJSONString temp myDict |

getJSONString := [ :aTitle | ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: aTitle;
        get;
        contents].

temp := getJSONString value: \'Magnolia\'.
temp.
myDict := NeoJSONReader fromString: temp.
"myDict at: #Director."

ZnEasy getJpeg: (myDict at: #Poster)
',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @218,
															#level : 6,
															#links : OrderedCollection [
																'',
																'http://ws.stfx.eu/N002L3K1ZU80'
															]
														},
														GrafoscopioNode {
															#header : 'Usando dos bloques',
															#key : '',
															#body : '| getJSONString movieInfoFromJSONString jsonDataString |

getJSONString := [ :aTitle | ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: aTitle;
        get;
        contents].

jsonDataString := getJSONString value: \'Fight club\'.

movieInfoFromJSONString := [ :aJSONString | NeoJSONReader fromString: aJSONString].


ZnEasy getJpeg:((movieInfoFromJSONString value: jsonDataString) at: #Poster)
',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @218,
															#level : 6,
															#links : OrderedCollection [ ]
														},
														GrafoscopioNode {
															#header : 'Con llaves para diferentes atributos de la peli',
															#key : '',
															#body : '| getJSONString movieInfoFromJSONString jsonDataString movieInfoForKey getPoster |

getJSONString := [ :aTitle | ZnClient new
        url: \'http://www.omdbapi.com/\';
        queryAt: \'t\' put: aTitle;
        get;
        contents].

jsonDataString := getJSONString value: \'E.T.\'.
movieInfoFromJSONString := [ :aJSONString | NeoJSONReader fromString: aJSONString].
movieInfoForKey := [ :aKey | (movieInfoFromJSONString value: jsonDataString) at: aKey ].
movieInfoForKey value: #Actors.
getPoster := [:key | ZnEasy getJpeg:(movieInfoForKey value: key)] value: #Poster
',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @218,
															#level : 6,
															#links : OrderedCollection [ ]
														}
													],
													#parent : @192,
													#level : 5,
													#links : OrderedCollection [
														''
													]
												},
												GrafoscopioNode {
													#header : 'Trivia',
													#body : '',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [
														GrafoscopioNode {
															#header : 'And the oscar winner is...',
															#body : '| o i |
o :=  #[76 97 32 76 97 32 76 97 110 100] asString asText.
i := GTInspector openOn: o.
[ 1 second wait.
o
    addAttribute: TextEmphasis struckOut;
    append: #[77 111 111 110 108 105 103 104 116] asString.
i model update ] fork.
',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @234,
															#level : 6,
															#links : OrderedCollection [
																'',
																'http://ws.stfx.eu/6MEJ55EXLSOA'
															]
														}
													],
													#parent : @192,
													#level : 5,
													#links : OrderedCollection [
														''
													]
												}
											],
											#parent : @189,
											#level : 4,
											#links : OrderedCollection [
												''
											]
										}
									],
									#parent : @171,
									#level : 3,
									#links : OrderedCollection [
										''
									]
								}
							],
							#parent : @143,
							#level : 2,
							#links : OrderedCollection [
								''
							]
						}
					],
					#parent : @5,
					#level : 1,
					#links : OrderedCollection [ ]
				},
				@146,
				@149,
				@152,
				@155,
				@158,
				@161,
				@164,
				@167,
				@171,
				@174,
				@177,
				@180,
				@183,
				@186,
				@189,
				@192,
				@195,
				@197,
				@201,
				@205,
				@208,
				@211,
				@214,
				@218,
				@221,
				@224,
				@227,
				@230,
				@234,
				@237,
				GrafoscopioNode {
					#header : 'CInemania: Creando el primer paquete',
					#key : '',
					#body : 'Acá tomaremos el ejemplo anterior de Open  Movie Data Base y lo convertiremos en una aplicación.
Esto nos permitirá entender la lógica con la que eso se hace y  "leer" la forma en que otras aplicaciones
están hechas.',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [
						GrafoscopioNode {
							#header : 'Los de Offray',
							#key : '',
							#body : '',
							#tags : OrderedCollection [
								'text'
							],
							#children : OrderedCollection [
								GrafoscopioNode {
									#header : 'Crear un nuevo paquete',
									#key : '',
									#body : '"Esta es la ventana que nos pide el nombre de un paquete que estamos agregando al sistema"
ZnEasy getPng: \'http://mutabit.com/repos.fossil/grafoscopio/doc/tip/Docs/Es/Tutoriales/Cinemania/create-new-package.png\'',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @248,
									#level : 3,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Paquete recien creado',
									#key : '',
									#body : '"Una vez hallamos creado el paquete cinemanía veremos lo siguiente:"

ZnEasy getPng: \'http://mutabit.com/repos.fossil/grafoscopio/doc/tip/Docs/Es/Tutoriales/Cinemania/new-package-created.png\'

"Este es el paquete vacio, aún sin ningún objeto en particular"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @248,
									#level : 3,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Comentarios de una clase: por llenar',
									#key : '',
									#body : '"Recien se crea una clase, aparece un símbolo de admiración al lado izquierdo
de su nombre. Si hacemos click en el botón \'Comments\' podremos indicar el propósito de dicha
clase, como se muestra en la siguiente pantalla"
ZnEasy getPng: \'http://mutabit.com/repos.fossil/grafoscopio/doc/tip/Docs/Es/Tutoriales/Cinemania/add-comments.png\'',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @248,
									#level : 3,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Comentarios de una clase: llenándolos (dirty)',
									#key : '',
									#body : '"Reemplazamos la plantilla de comentarios que se nos da por omisión, por alguna descripción de lo que hace el paquete.
Veremos que la esquina superior derecha está resaltada, lo que indica que el comentario aún no se ha salvado,
como muestra esta pantalla"

ZnEasy getPng: \'http://mutabit.com/repos.fossil/grafoscopio/doc/tip/Docs/Es/Tutoriales/Cinemania/add-comments-filled.png\'

"y luego salvamos usando Comand S (Mac), Ctrl S (Windows, Gnu/Linux) o el menú"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @248,
									#level : 3,
									#links : OrderedCollection [ ]
								}
							],
							#parent : @245,
							#level : 2,
							#links : OrderedCollection [ ]
						}
					],
					#parent : @5,
					#level : 1,
					#links : OrderedCollection [ ]
				},
				@248,
				@251,
				@254,
				@257,
				@260,
				GrafoscopioNode {
					#header : 'Nix: Instalación de software',
					#key : '',
					#body : 'En ocasiones el software que tenemos instalado en nuestra máquina es insuficiente para
realizar la tareas que queremos.
En ese caso, apelamos a sistemas de instalación de paquetes y existen distintos que son 
multiplataforma ([Zero Install]( )) o específicos de ciertas plataformas.
Por ejemplo, en plataformas Gnu/Linux contamos con sistemas como `apt-get` o `pacman`
para gestionar la instalación de software.
Sin embargo, dichos gestores de instalación de software son específicos de una distribución
y sus derivados ( ̀apt-get ̀ funciona para Debian y Ubuntu,  ̀pacman ̀ para Arch y Mnajaro) y
en ocasiones queremos instalar software que no está disponible en nuestra distribución  
o que es inconpatible con las versiones actuales de lo que tenemos instalado
(particularmente para las que manejas ramas, como Debian y sus derivados) o queremos
abstraer el proceso para que no depende de una variante particular de Linux, entre las más
de 300 distribuciones disponibles (ver [Distro Watch]()).
En dichos casos, un gestor de paquetes como Nix nos brinda una alternativa para
despreocuparnos de la distribución subyacente funcionando sobre distintas variantes del
sistema Unix, incluidos Gnu/Linux, Solaris y Mac.

Para mayor información ver:

  - [https://nixos.org/nix/manual/](https://nixos.org/nix/manual/ ).
  - [NixOS](https://nixos.org/ ): The Purely Functional Linux Distribution. Una distribución basada en este gestor de paquetes.
  - [About NixOS](https://nixos.org/nixos/about.html )',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [ ],
					#parent : @5,
					#level : 1,
					#links : OrderedCollection [ ]
				},
				GrafoscopioNode {
					#header : 'Fossil: Colaboración y control de versiones minimalista.',
					#key : '',
					#body : '',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [ ],
					#parent : @5,
					#level : 1,
					#links : OrderedCollection [ ]
				},
				GrafoscopioNode {
					#header : 'Mustache: automatizando la creación de HTML',
					#key : '',
					#body : '',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [
						GrafoscopioNode {
							#header : 'Instalación',
							#key : '',
							#body : 'Gofer it
   smalltalkhubUser: \'NorbertHartl\' project: \'Mustache\';
   configuration;
   loadStable',
							#tags : 'código',
							#children : OrderedCollection [ ],
							#parent : GrafoscopioNode {
								#header : 'Mustache: automatizando la creación de HTML',
								#key : '',
								#body : Text {
									#string : '',
									#runs : RunArray {
										#runs : [ ],
										#values : [ ]
									}
								},
								#tags : OrderedCollection [
									'text'
								],
								#children : @275,
								#parent : GrafoscopioNode {
									#header : 'twitter.com',
									#key : '',
									#body : 'Twitter: La más popular red social de microblogging, basada en comunicación vía
mensajes de un límite de hasta 140 caracteres',
									#tags : OrderedCollection [
										'text'
									],
									#children : OrderedCollection [
										GrafoscopioNode {
											#header : 'Micrositio Web',
											#key : '',
											#body : 'Este nodo explicará como crear un micrositio web para publicar en línea resultados de las
visualizaciones.',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [
												GrafoscopioNode {
													#header : 'Pecha Kucha',
													#key : '',
													#body : 'Para detalles ver: https://github.com/Pharophile/PechaKucha 

Gracias a Philippe Back por esto.',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [
														GrafoscopioNode {
															#header : 'Cargar soporte para MDL en Seaside',
															#key : '',
															#body : 'Metacello new
    githubUser: \'DuneSt\' project: \'MaterialDesignLite\' commitish: \'development\' path: \'src\';
    baseline: \'MaterialDesignLite\';
    onWarningLog;
    load',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @290,
															#level : 4
														},
														GrafoscopioNode {
															#header : 'Cargar soporte Pecha Kucha',
															#key : '',
															#body : 'Metacello new
    githubUser: \'Pharophile\' 
    project: \'PechaKucha\' 
    commitish: \'master\' 
    path: \'packages\';
    baseline: \'PechaKucha\';
    onWarningLog;
    load',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @290,
															#level : 3
														},
														GrafoscopioNode {
															#header : 'Iniciar la aplicación',
															#key : '',
															#body : 'PKApplication declareApplicationAndStartServer.',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @290,
															#level : 3
														}
													],
													#parent : @287,
													#level : 3
												}
											],
											#parent : @284,
											#level : 2
										},
										GrafoscopioNode {
											#header : 'Prototipo Data Selfie',
											#key : '',
											#body : '',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [
												GrafoscopioNode {
													#header : 'Básico',
													#key : '',
													#body : '"Esto supone que ya se ha descargado y descompreso el archivo de mensajes de Twitter"
| profile aMessagesFile |
profile := TwitterProfileOverview new
\tscreenName: \'offrayLC\'.
profile getAvatar.
aMessagesFile := (FileLocator documents / \'Grafoscopio\' / \'Projects\' / \'DataSelfies\' / \'Twitter\' / \'DataDumps\' / \'offrayLC\' / \'data\' / \'js\' / \'tweets\' /\'2013_02.js\') asFileReference.
profile splitMessagesByTypeFrom: aMessagesFile.
profile avatarWheel ',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @299,
													#level : 3
												},
												GrafoscopioNode {
													#header : 'Cargar mensajes',
													#key : '',
													#body : '"Esto supone que ya se ha descargado y descompreso el archivo de mensajes de Twitter"
| aMessagesFile |
aMessagesFile := (FileLocator documents / \'Grafoscopio\' / \'Projects\' / \'DataSelfies\' / \'Twitter\' / \'DataDumps\' / \'offrayLC\' / \'data\' / \'js\' / \'tweets\' /\'2013_02.js\') asFileReference.
TPMessages new splitMessagesByTypeFrom: aMessagesFile.
',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @299,
													#level : 3
												}
											],
											#parent : @284,
											#level : 2
										}
									],
									#level : 1
								},
								#level : 2
							},
							#level : 3,
							#links : OrderedCollection [ ]
						},
						GrafoscopioNode {
							#header : 'Crear con moustache el archivo de data selfies',
							#key : '',
							#body : '| workingFolder moustacheTplFile templateContent context rendered targetFile tempStream |

"Ubicación de la plantilla en el sistema de archivos"
workingFolder := FileLocator documents / \'Grafoscopio\' / \'Projects\' / \'TwitterDataSelfies\'..
moustacheTplFile := (workingFolder / \'templates\' / \'index.html\') asFileReference.

"Leer el template como string"
templateContent := moustacheTplFile contents asString.

"Estos datos de contexto deben ser llenados desde Twitter"
context := {
   \'screen_name\' -> \'offrayLC\'.
   \'page_title\' -> \'Mi data selfie de Twitter\'.
   \'bio_message\' -> \'Esto viene de Twitter\'.
   \'url_link\' -> \'http://algo.com\'.
\t\'month\' -> \'2013_02.png\' } asDictionary.

"Procesar la plantilla con los datos de contexto"
rendered := (MustacheTemplate on: templateContent) value: context.

"Guardar el contenido renderizado en un archivo"
targetFile := (workingFolder / \'profiles\' / (context at: #screen_name) / \'index.html\') asFileReference.
tempStream := targetFile writeStream.
tempStream nextPutAll: rendered.
tempStream close.
',
							#tags : 'código',
							#children : OrderedCollection [ ],
							#parent : @278,
							#level : 3,
							#links : OrderedCollection [ ]
						},
						GrafoscopioNode {
							#header : 'http://ws.stfx.eu/1N9FKAUI2UI0',
							#key : '',
							#body : '| profile workingFolder moustacheTplFile templateContent context rendered targetFile tempStream |

profile := TwitterProfileOverview new
\tscreenName: \'LuLinGar\'.

"Ubicación de la plantilla en el sistema de archivos"
workingFolder := FileLocator root / \'media\' / \'hackbo\' / \'memoluis\' / \'dataweek\' / \'repo-dataselfies\'.
moustacheTplFile := (workingFolder / \'templates\' / \'index.html\') asFileReference.

"Leer el template como string"
templateContent := moustacheTplFile contents asString.

"Estos datos de contexto deben ser llenados desde Twitter"
context := {
   \'screen_name\' -> (profile screenName).
   \'page_title\' -> \'Mi data selfie\'.
   \'bio_message\' -> \'Esto viene de Twitter\'.
   \'url_link\' -> \'http://algo.com\' } asDictionary.

"Procesar la plantilla con los datos de contexto"
rendered := (MustacheTemplate on: templateContent) value: context.

"Guardar el contenido renderizado en un archivo"
targetFile := (workingFolder / \'profiles\' / (profile screenName) / \'index.html\') asFileReference.
tempStream := targetFile writeStream.
tempStream nextPutAll: rendered.
tempStream close.
',
							#tags : 'código',
							#children : OrderedCollection [ ],
							#parent : @278,
							#level : 3,
							#links : OrderedCollection [ ]
						}
					],
					#parent : @5,
					#level : 1,
					#nodesInPreorder : OrderedCollection [
						@273,
						@276,
						@307,
						@310
					],
					#links : OrderedCollection [ ]
				},
				@276,
				@307,
				@310,
				GrafoscopioNode {
					#header : 'Teapot: constructor minimalista de aplicaciones web',
					#key : '',
					#body : '',
					#tags : '',
					#children : OrderedCollection [
						GrafoscopioNode {
							#header : 'Minitutorial',
							#key : '',
							#body : '',
							#tags : OrderedCollection [
								'text'
							],
							#children : OrderedCollection [
								GrafoscopioNode {
									#header : 'Instalación',
									#key : '',
									#body : 'Gofer it
    smalltalkhubUser: \'zeroflag\' project: \'Teapot\';
    configuration;
    loadStable.',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @317,
									#level : 4,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Hello World',
									#key : '',
									#body : 'Teapot on
    GET: \'/welcome\' -> \'Hello World!\';
    start.

"Do it and view at: http://localhost:1701/welcome"',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @317,
									#level : 4,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Hello User',
									#key : '',
									#body : 'Teapot on
    GET: \'/hi\' -> \'Bonjour!\';
    GET: \'/hi/<user>\' -> [:req | \'Hello \', (req at: #user)];
start',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @317,
									#level : 4,
									#links : OrderedCollection [
										''
									]
								}
							],
							#parent : GrafoscopioNode {
								#header : 'Teapot: constructor minimalista de aplicaciones web',
								#key : '',
								#body : Text {
									#string : '',
									#runs : RunArray {
										#runs : [ ],
										#values : [ ]
									}
								},
								#tags : '',
								#children : @316,
								#parent : @284,
								#level : 2
							},
							#level : 3,
							#links : OrderedCollection [
								''
							]
						},
						GrafoscopioNode {
							#header : 'Tealight',
							#key : '',
							#body : '',
							#tags : OrderedCollection [
								'text'
							],
							#children : OrderedCollection [
								GrafoscopioNode {
									#header : 'Instalación',
									#key : '',
									#body : 'Metacello new 
    repository: \'github://astares/Tealight/repository\';
    baseline: \'Tealight\';
    load  ',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @335,
									#level : 4,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Acceder a un Teapot por omisión',
									#key : '',
									#body : 'TLWebserver teapot',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @335,
									#level : 4,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Definir una ruta para una instancia de Teapot',
									#key : '',
									#body : 'TLWebserver teapot 
    GET: \'/hi\' -> \'HelloWorld\'',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @335,
									#level : 4,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Hola usuario',
									#key : '',
									#body : 'TLWebserver teapot 
    GET: \'/hi/<user>\' -> [:req | \'Hello \', (req at: #user)]',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @335,
									#level : 4,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Transformadores de respuestas',
									#key : '',
									#body : '',
									#tags : OrderedCollection [
										'text'
									],
									#children : OrderedCollection [
										GrafoscopioNode {
											#header : 'A json',
											#key : '',
											#body : 'TLWebserver teapot
\tGET: \'/jsonlist\' -> #(1 2 3 4); output: #json',
											#tags : 'código',
											#children : OrderedCollection [ ],
											#parent : @350,
											#level : 5,
											#links : OrderedCollection [
												''
											]
										},
										GrafoscopioNode {
											#header : 'A texto plano',
											#key : '',
											#body : 'TLWebserver teapot
\tGET: \'/textoplano\' -> \'Esto es texto plano\'; output: #text',
											#tags : 'código',
											#children : OrderedCollection [ ],
											#parent : @350,
											#level : 5,
											#links : OrderedCollection [
												''
											]
										},
										GrafoscopioNode {
											#header : 'Descargas',
											#key : '',
											#body : 'TLWebserver teapot
\tGET: \'/descargas\' -> [\'/tmp/prueba.txt\' asFileReference readStream]; output: #stream',
											#tags : 'código',
											#children : OrderedCollection [ ],
											#parent : @350,
											#level : 5,
											#links : OrderedCollection [
												''
											]
										}
									],
									#parent : @335,
									#level : 4,
									#links : OrderedCollection [
										''
									]
								},
								GrafoscopioNode {
									#header : 'Plantillas',
									#key : '',
									#body : '',
									#tags : OrderedCollection [
										'text'
									],
									#children : OrderedCollection [
										GrafoscopioNode {
											#header : 'Instalar soporte Mustache',
											#key : '',
											#body : 'Gofer it
   smalltalkhubUser: \'NorbertHartl\' project: \'Mustache\';
   configuration;
   loadStable',
											#tags : 'código',
											#children : OrderedCollection [ ],
											#parent : @363,
											#level : 5,
											#links : OrderedCollection [ ]
										},
										GrafoscopioNode {
											#header : 'Usarlas',
											#key : '',
											#body : 'TLWebserver teapot
\tGET: \'/saludo\' -> {\'phrase\' -> \'Hello\'. \'name\' -> \'World\'};
\toutput: (TeaOutput mustacheHtml: \'<b>{{phrase}}</b> <i>{{name}}</i>!\')',
											#tags : 'código',
											#children : OrderedCollection [ ],
											#parent : @363,
											#level : 5,
											#links : OrderedCollection [ ]
										}
									],
									#parent : @335,
									#level : 4,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Manejo de errores',
									#key : '',
									#body : '3',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @335,
									#level : 4,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Servir archivos locales',
									#key : '',
									#body : '<b>Hello</b> <i>World</i>!',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @335,
									#level : 4,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Mirar procesos de Tealight',
									#key : '',
									#body : 'TLWebserver teapot inspect',
									#tags : 'código',
									#children : OrderedCollection [ ],
									#parent : @335,
									#level : 4,
									#links : OrderedCollection [ ]
								}
							],
							#parent : @329,
							#level : 3,
							#links : OrderedCollection [
								'',
								'https://github.com/astares/Tealight'
							]
						}
					],
					#parent : @5,
					#level : 1,
					#nodesInPreorder : OrderedCollection [
						@315,
						@317,
						@320,
						@323,
						@326,
						@335,
						@338,
						@341,
						@344,
						@347,
						@350,
						@353,
						@356,
						@359,
						@363,
						@366,
						@369,
						@373,
						@376,
						@379
					],
					#links : OrderedCollection [
						''
					]
				},
				@317,
				@320,
				@323,
				@326,
				@335,
				@338,
				@341,
				@344,
				@347,
				@350,
				@353,
				@356,
				@359,
				@363,
				@366,
				@369,
				@373,
				@376,
				@379,
				GrafoscopioNode {
					#header : 'Borradores',
					#key : '',
					#body : 'Acá encontrarás código que aún no está tan maduro como el que has visto hasta el momento.
Son algunos apuntes de diferentes prototipos que están avanzando y algún código que no continuo.
Pharo es un entorno dinámico que mejora continuamente.
Al darte una mirada de estos borradores puedes ver parte del proceso de construcción del cierto 
código y vincularte al proceso.

Futuras versiones de este cuaderno interactivo, tendrán ediciones más maduras y robustas del
código.',
					#tags : OrderedCollection [
						'text'
					],
					#children : OrderedCollection [
						GrafoscopioNode {
							#header : 'Visualización de datos',
							#key : '',
							#body : 'Acá están recopilados algunos ejemplos que hemos hecho con data scrapping (raspado de datos)',
							#tags : OrderedCollection [
								'text'
							],
							#children : OrderedCollection [
								GrafoscopioNode {
									#header : 'Twitter',
									#key : '',
									#body : '',
									#tags : OrderedCollection [
										'text'
									],
									#children : OrderedCollection [
										GrafoscopioNode {
											#header : 'Usando algunos scrappers predefinidos',
											#key : '',
											#body : '',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [
												GrafoscopioNode {
													#header : 'Ejemplo 1: Un perfil',
													#key : '',
													#body : '',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @394,
													#level : 4,
													#links : OrderedCollection [ ]
												},
												GrafoscopioNode {
													#header : 'Ejemplo 2: Dos perfiles',
													#key : '',
													#body : '| perfil1 perfil2 perfiles |

perfil1 := TwitterProfile new.
perfil2 := TwitterProfile new.

"Vmmos a crear un nuevo perfil"
perfil1 scrapDataForProfile: \'PetroGustavo\'.
perfil2 scrapDataForProfile: \'JuanManSantos\'.

perfiles := OrderedCollection new.
perfiles 
\tadd: perfil1;
\tadd: perfil2.
perfiles.',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @394,
													#level : 4,
													#links : OrderedCollection [ ]
												},
												GrafoscopioNode {
													#header : 'Ejemplo 3: Varios perfiles',
													#key : '',
													#body : '| perfil perfiles misPoliticos |

misPoliticos := #(\'PetroGustavo\' "Alcalde de Bogotá"
\t\t\t\t\t\t\'JuanManSantos\' "Presidente de Colombia" 
\t\t\t\t\t\t\'ginaparody\' "Ministra de educación de Colombia"
\t\t\t\t\t\t\'CFKArgentina\' "Presidenta de Argentina").

perfiles := OrderedCollection new.

misPoliticos do: [:politico |
\t  \tperfil := TwitterProfile new.
\t\tperfil scrapDataForProfile: politico.
\t\tperfiles add: perfil.].
perfiles.',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @394,
													#level : 4,
													#links : OrderedCollection [ ]
												}
											],
											#parent : @391,
											#level : 3,
											#links : OrderedCollection [ ]
										},
										GrafoscopioNode {
											#header : 'Deconstruyendo un scrapper.',
											#key : '',
											#body : '',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [
												GrafoscopioNode {
													#header : 'Traerse el html',
													#key : '',
													#body : '\t| client anUrl aProfileName |
\taProfileName := \'dominemosLasTIC\'.
\tanUrl := \'https://twitter.com/\', aProfileName.
\tclient := ZnClient new.
\tclient get: anUrl.',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @407,
													#level : 4,
													#links : OrderedCollection [ ]
												},
												GrafoscopioNode {
													#header : 'Encontrar algo dentro del html',
													#key : '',
													#body : '\t| client anUrl aProfileName |
\taProfileName := \'dominemosLasTIC\'.
\tanUrl := \'https://twitter.com/\', aProfileName.
\tclient := ZnClient new.
\tclient get: anUrl.',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @407,
													#level : 4,
													#links : OrderedCollection [ ]
												}
											],
											#parent : @391,
											#level : 3,
											#links : OrderedCollection [ ]
										}
									],
									#parent : @388,
									#level : 2,
									#links : OrderedCollection [ ]
								},
								GrafoscopioNode {
									#header : 'Contratos públicos',
									#key : '',
									#body : '',
									#tags : OrderedCollection [
										'text'
									],
									#children : OrderedCollection [
										GrafoscopioNode {
											#header : 'Visualización Guía: Treemapping',
											#key : '',
											#body : 'Para mirar cómo se han realizado los gastos presupuestales, usaremos como visualización guía una que es producida por
la técnica de *treemapping* y que permite explorar cómo una jerarquía está compuesta por partes disyuntas que la conforman
(como en el caso de la división de presupuestos).
Para mayor información sobre dicha técnica véase la 
[página de la wikipedia sobre treemapping](https://en.wikipedia.org/wiki/Treemapping)',
											#tags : OrderedCollection [
												'text'
											],
											#children : OrderedCollection [
												GrafoscopioNode {
													#header : 'Ejemplo 1',
													#key : '',
													#body : '\t| b |
\tb := RTTreeMapBuilder new.
\tb shape fillColor: Color veryLightGray.
\t
\tb from: (1 to: 17) using: [#()].
\tb weight: #yourself.
\tb build.
\t^ b view',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @421,
													#level : 4,
													#links : OrderedCollection [ ]
												},
												GrafoscopioNode {
													#header : 'Ejemplo 2',
													#key : '',
													#body : 'RTTreeMapExample new exampleNumber',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @421,
													#level : 4,
													#links : OrderedCollection [ ]
												},
												GrafoscopioNode {
													#header : 'Integrando datos a la visualización',
													#key : '',
													#body : '| aFile aCharacter table b |

aFile := (FileLocator documents / \'DataWeek\' / \'query-subtotales-por-segmentos.csv\') asFileReference.
aCharacter := $,.
table := RTTabTable new input: aFile contents usingDelimiter: aCharacter.
table valuesOfColumn: 2.

\tb := RTTreeMapBuilder new.
\tb shape fillColor: Color veryLightGray.
\tb from: (2 to: table numberOfRows) using: [#()].
\tb weight: [:n | (table valuesOfColumn: 2) at: n ].
\tb build.
\tb view.
table values',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @421,
													#level : 4,
													#links : OrderedCollection [ ]
												},
												GrafoscopioNode {
													#header : 'Probando OpenSpending',
													#key : '',
													#body : '| contratos archivo |

archivo := (FileLocator documents / \'DataWeek\' / \'query-subtotales-por-segmentos.csv\') asFileReference.
contratos := OpenSpending new.
contratos loadDataFromCSV: archivo usingDelimiter: $,.
contratos',
													#tags : 'código',
													#children : OrderedCollection [ ],
													#parent : @421,
													#level : 4,
													#links : OrderedCollection [ ]
												},
												GrafoscopioNode {
													#header : 'Treemap con etiquetas',
													#key : '',
													#body : '',
													#tags : OrderedCollection [
														'text'
													],
													#children : OrderedCollection [
														GrafoscopioNode {
															#header : 'Primera versión',
															#key : '',
															#body : '| b labels popup |
\tlabels := RTLabel elementsOn: #(\'uno\' \'dos\' \'tres\' \'cuatro\' \'cinco\').
\tpopup := RTPopup new.
\tpopup text: [:object | labels at: object  ].
\tb := RTTreeMapBuilder new.
\tb shape fillColor: Color random.
\tb from: (1 to: 5) using: [#()].
\tb weight: [:n | n].
\tb build.
\tb view elements @ RTLabelled.
\t^ b view.',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @436,
															#level : 5,
															#links : OrderedCollection [ ]
														},
														GrafoscopioNode {
															#header : 'Entendiendo popups dinámicos',
															#key : '',
															#body : '',
															#tags : 'código',
															#children : OrderedCollection [ ],
															#parent : @436,
															#level : 5,
															#links : OrderedCollection [ ]
														}
													],
													#parent : @421,
													#level : 4,
													#links : OrderedCollection [ ]
												}
											],
											#parent : @418,
											#level : 3,
											#links : OrderedCollection [ ]
										}
									],
									#parent : @388,
									#level : 2,
									#links : OrderedCollection [ ]
								}
							],
							#parent : @385,
							#level : 2,
							#links : OrderedCollection [ ]
						}
					],
					#parent : @5,
					#level : 1,
					#links : OrderedCollection [ ]
				},
				@388,
				@391,
				@394,
				@397,
				@400,
				@403,
				@407,
				@410,
				@413,
				@418,
				@421,
				@424,
				@427,
				@430,
				@433,
				@436,
				@439,
				@442
			]
		},
		#level : 1,
		#links : OrderedCollection [
			''
		]
	},
	@8,
	@12,
	@16,
	@20,
	@143,
	@245,
	@265,
	@269,
	@273,
	@315,
	@385
]