1. Introducción
El arte generativo es una forma contemporánea de creación artística, hace referencia al arte que en su totalidad o parcialmente ha sido creado con el uso de un sistema autónomo (Urgiles, 2019). Se encuentra presente en la música, el diseño y la pintura. En este reporte se genera una colección de 10 piezas de arte generativo creadas a través de algoritmos usando funciones trigonométricas hipérbolicas, distribuciones de probabilidad multivariadas y métodos de aprendizaje estadístico.
2. Piezas
Pieza 1 - Ying-Yang fragmentado
La siguiente pieza se crea inspirada en las figuras de voronoi, que consisten en construcciones geométricas que permiten realizar particiones del plano o del espacio. Los pasos a seguir en la construcción fueron:
- Generar un dos sets de números aleatorios (x,y), calcular las distancias entre los puntos y guardar estos datos en un dataframe. Una vista del dataframe generado es:
Tabla 1: Datos para gráficar
|
x
|
y
|
dist
|
|
324
|
193
|
109.6586
|
|
167
|
111
|
231.1060
|
|
129
|
485
|
251.9246
|
|
418
|
342
|
125.2517
|
|
471
|
85
|
274.7108
|
- Con el set de datos y apoyándose en las librerias
ggplot2yggvoronoi, generamos un procedimiento adaptado con las funciones cosh y tanh para realizar el gráfico.
En el resultado obtenido se observa la figura de voronoi generada y con su particular forma de ying-yang. Se escoge la tonalidad azul por ser la favorita del autor.
Pieza 2 - simetría invertida
La siguiente pieza, se crea a partir de un círculo y con la función sinh se adiciona la perfecta simetría de la figura representada en las dos formas salientes del radio. Nuevamente se aprovecha ggplot2 y variando las constantes y valores de la función e llega a esta figura.
Pieza 3 - Distorsión Gaussiana
La pieza denominada Distorsión Gaussiana, se generó con apoyo de la función mvrnorm para poder así crear muestras a partir de la Distribución Normal Multivariada especificada. Luego, para crear la figura se empleó ggplot2. El resultado que se obtuvo fue el siguiente:
Pieza 4 - La Normalidad de Bessel
Con apoyo de la función Bessel y rlnorm se diseñó esta pieza. Es decir, la figura tiene su base en una combinación entre las funciones de Bessel y la Distribución Lognormal Multivariada. A consecuencia de dicha unión se obtuvo la siguiente obra de arte:
Pieza 5 - Rainbow.
La pieza denominada Rainbow, se generó con apoyo dedatos normales para poder así crear muestras a partir de registros los cuales son año, grupo y valores. Luego, para crear la figura se empleó ggplot. El resultado que se obtuvo fue el siguiente:
Pieza 6 - Gamma Big Bang
La pieza denominada Gamma Big Bang, se generó con apoyo de la función rgamma para poder así crear muestras aleatorias a partir de la Distribución Gamma especificada. Luego, para crear la figura se empleó el devtoolsdjnavarro/jasmines. El resultado que se obtuvo fue el siguiente:
Pieza 7 - Tornado
La siguiente pieza, se crea a partir del experimento tornado de StarCircle, creando un aspecto tridimensional, casi esférico (Kumar, 2020). El tornado presenta pequeñas modificaciones para estar más cerrado, aumentando su secuencia, cambiando la función (cos(y+x)+1.3*y) por (cos(y+x)+10*y) en el eje X y (sin(x+y)+2.3*x) por (sin(x+y)+0.1*x) en el eje Y. Nuevamente se hace usos de ggplot2 llegando a esta figura.
Pieza 8 - Casualidad
La siguiente pieza, se crea a partir de los datos X y Y de la pieza 3, Distorsión Gaussiana, realizando todas las combinaciones posibles entre los dos factores con la función expand.grid() y la función (cos(y+x)+1.3*y) en el eje X y (sin(x+y)+2.3*x) en el eje Y. Dando como resultado la siguiente figura.
Pieza 9 - tree_1
Para el tree_1.png se muestra una grafica creada a partir de random forest generado con un gran dataset de sklearn, es interesante ver como con la gran cantidad de datos salen muchas ramas que pueden parecer una granja de hormigas o un enorme árbol genealógico o de evolución.
Pieza 10 - tree_2
Para el tree_2.png se muestra igualmente una grafica generada con random forest y el mismo dataset, es menos llamativo y al parecer menos complejo pero realmente puede variar más visualmente, las formas que muestra pueden parecerse a un cerebro, un elefante, un cráneo… depende la percepción de quein lo esté viendo y de como se alla generado la imagen aleatoriamente, todos los pequeños letreros o cuadros de la imagen son valores de las hojas del random forest, los valores del dataset son irrelevantes para lo que estamos haciendo, sólo pueden variar el color de cada uno de estos letreros naranjas.
LS0tDQp0aXRsZTogIkFydGUgZ2VuZXJhdGl2byINCmF1dGhvcjogIkplc3VzIERhdmlkIFNhbnRvcyBNb250ZXMsIEtsZWlkZXIgU3RpdmVuIFbDoXNxdWV6IEfDs21leiwgRGFuaWVsIEFuZHLDqXMgVG9ybyBBZ3VpcnJlLCBKZWxzc2luIERvbm5vdmFuIFJvYmxlZG8gTWVuYSwgSnVhbiBFc3RlYmFuIENhcnZhamFsIE1vbGluYS4iDQpkYXRlOiAiMDgvMDIvMjAyMiINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdGhlbWU6IHNwYWNlbGFiDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiANCiAgICAgIGNvbGFwc2U6IGZhbHNlDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KDQojIyAxLiBJbnRyb2R1Y2Npw7NuDQoNCg0KRWwgYXJ0ZSBnZW5lcmF0aXZvIGVzIHVuYSBmb3JtYSBjb250ZW1wb3LDoW5lYSBkZSBjcmVhY2nDs24gYXJ0w61zdGljYSwgaGFjZSByZWZlcmVuY2lhIGFsIGFydGUgcXVlIGVuIHN1IHRvdGFsaWRhZCBvIHBhcmNpYWxtZW50ZSBoYSBzaWRvIGNyZWFkbyBjb24gZWwgdXNvIGRlIHVuIHNpc3RlbWEgYXV0w7Nub21vIChVcmdpbGVzLCAyMDE5KS4gU2UgZW5jdWVudHJhIHByZXNlbnRlIGVuIGxhIG3DunNpY2EsIGVsIGRpc2XDsW8geSBsYSBwaW50dXJhLiBFbiBlc3RlIHJlcG9ydGUgc2UgZ2VuZXJhIHVuYSBjb2xlY2Npw7NuIGRlIDEwIHBpZXphcyBkZSBhcnRlIGdlbmVyYXRpdm8gY3JlYWRhcyBhIHRyYXbDqXMgZGUgYWxnb3JpdG1vcyB1c2FuZG8gZnVuY2lvbmVzIHRyaWdvbm9tw6l0cmljYXMgaGlww6lyYm9saWNhcywgZGlzdHJpYnVjaW9uZXMgZGUgcHJvYmFiaWxpZGFkIG11bHRpdmFyaWFkYXMgeSBtw6l0b2RvcyBkZSBhcHJlbmRpemFqZSBlc3RhZMOtc3RpY28uDQoNCg0KDQoNCg0KIyMgMi4gUGllemFzDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHMgPSAnaGlkZScsIGVjaG89RiwgaW5jbHVkZT1GQUxTRSB9DQoNCiNjYXJnYXMgbGlicmVyw61hcyBuZWNlc2FyaWFzDQoNCiNpbnN0YWxsLnBhY2thZ2VzKCJnZ3Zvcm9ub2kiKQ0KDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGdndm9yb25vaSkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQoNCmBgYA0KDQoNCg0KIyMjIFBpZXphIDEgLSBZaW5nLVlhbmcgZnJhZ21lbnRhZG8NCg0KTGEgc2lndWllbnRlIHBpZXphIHNlIGNyZWEgaW5zcGlyYWRhIGVuIGxhcyBmaWd1cmFzIGRlIFt2b3Jvbm9pXShodHRwczovL3JlcG9zaXRvcmlvLnVuaWNhbi5lcy94bWx1aS9iaXRzdHJlYW0vaGFuZGxlLzEwOTAyLzE4ODg1L09ydGVnYURlbENhbXBvTHVjaWEucGRmP3NlcXVlbmNlPTEmaXNBbGxvd2VkPXkpLCBxdWUgY29uc2lzdGVuIGVuIGNvbnN0cnVjY2lvbmVzIGdlb23DqXRyaWNhcyBxdWUgcGVybWl0ZW4gcmVhbGl6YXIgcGFydGljaW9uZXMgZGVsIHBsYW5vIG8gZGVsIGVzcGFjaW8uIExvcyBwYXNvcyBhIHNlZ3VpciBlbiBsYSBjb25zdHJ1Y2Npw7NuIGZ1ZXJvbjoNCg0KKiAxLiBHZW5lcmFyIHVuIGRvcyBzZXRzIGRlIG7Dum1lcm9zIGFsZWF0b3Jpb3MgKHgseSksIGNhbGN1bGFyIGxhcyBkaXN0YW5jaWFzIGVudHJlIGxvcyBwdW50b3MgeSBndWFyZGFyIGVzdG9zIGRhdG9zIGVuIHVuIGRhdGFmcmFtZS4gVW5hIHZpc3RhIGRlbCBkYXRhZnJhbWUgZ2VuZXJhZG8gZXM6DQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UgLCBlY2hvPUYgfQ0KI2xpYnJhcnkoZ2dwbG90MikNCiNsaWJyYXJ5KGdndm9yb25vaSkNCg0KIyBHZW5lcmFuZG8gZGF0b3MgcGFyYSBncsOhZmljYXINCg0Kc2V0LnNlZWQoMSkNCnggPC0gc2FtcGxlKDE6NTAwLCBzaXplID0gNTAwKQ0KeSA8LSBzYW1wbGUoMTo1MDAsIHNpemUgPSA1MDApDQpkaXN0IDwtIHNxcnQoKHggLSAzMDApIF4gMiArICh5IC0gMzAwKSBeIDIpDQoNCmRmIDwtIGRhdGEuZnJhbWUoeCwgeSwgZGlzdCA9IGRpc3QpDQpkYXRvcyA8LSBoZWFkKGRmLCBuPTUpDQoNCmtibChkYXRvcyxjYXB0aW9uID0gIlRhYmxhIDE6IERhdG9zIHBhcmEgZ3LDoWZpY2FyIikgJT4lIGthYmxlX3N0eWxpbmcobGF0ZXhfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCJjb25kZW5zZWQiLCJIT0xEX3Bvc2l0aW9uIiksIHBvc2l0aW9uID0gImNlbnRlciIsZnVsbF93aWR0aCA9IEZBTFNFKQ0KYGBgDQoyLiBDb24gZWwgc2V0IGRlIGRhdG9zIHkgYXBvecOhbmRvc2UgZW4gbGFzIGxpYnJlcmlhcyBgZ2dwbG90MmB5YGdndm9yb25vaWAsIGdlbmVyYW1vcyB1biBwcm9jZWRpbWllbnRvIGFkYXB0YWRvIGNvbiBsYXMgZnVuY2lvbmVzIGNvc2ggeSB0YW5oIHBhcmEgcmVhbGl6YXIgZWwgZ3LDoWZpY28uICANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSAsIGVjaG89RiwgaW5jbHVkZT1GQUxTRSAgfQ0KIyBjb2xhDQpzIDwtIHNlcSgwLCAxICogcGksIGxlbmd0aC5vdXQgPSAzMDAwKQ0KY29sYSA8LSBkYXRhLmZyYW1lKHggPSAxMDAgKiAoMSArIGNvc2gocykpLA0KICAgICAgICAgICAgICAgICAgICAgIHkgPSAyMDAgKiAoMSArIHRhbmgocykpLA0KICAgICAgICAgICAgICAgICAgICAgIGdydXBvID0gcmVwKDEsIDMwMDApKQ0KDQpwbmcoImFydGUxLnBuZyIpDQoNCmdncGxvdChkZiwgYWVzKHgsIHksIGZpbGwgPSBkaXN0KSkgKw0KICBnZW9tX3Zvcm9ub2kob3V0bGluZSA9IGNvbGEsDQogICAgICAgICAgICAgICBjb2xvciA9IDEsIHNpemUgPSAwLjEpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiI0I5RERGMSIsICAjIiNCOURERjEiDQogICAgICAgICAgICAgICAgICAgICAgaGlnaCA9ICIjMkE1NzgzIiwgICMyQTU3ODMNCiAgICAgICAgICAgICAgICAgICAgICBndWlkZSA9ICJub25lIikgKw0KICB0aGVtZV92b2lkKCkgKw0KICBjb29yZF9wb2xhcigpDQoNCmRldi5vZmYoKQ0KIA0KYGBgDQpFbiBlbCByZXN1bHRhZG8gb2J0ZW5pZG8gc2Ugb2JzZXJ2YSBsYSBmaWd1cmEgZGUgdm9yb25vaSBnZW5lcmFkYSB5IGNvbiBzdSBwYXJ0aWN1bGFyIGZvcm1hIGRlIHlpbmcteWFuZy4gU2UgZXNjb2dlIGxhIHRvbmFsaWRhZCBhenVsIHBvciBzZXIgbGEgZmF2b3JpdGEgZGVsIGF1dG9yLg0KDQohW1BpZXphIDE6IFlpbmctWWFuZyBmcmFnbWVudGFkb10oYXJ0ZTEucG5nKXt3aXRoZD04MCV9DQoNCiMjIyBQaWV6YSAyIC0gc2ltZXRyw61hIGludmVydGlkYQ0KDQpMYSBzaWd1aWVudGUgcGllemEsIHNlIGNyZWEgYSBwYXJ0aXIgZGUgdW4gY8OtcmN1bG8geSBjb24gbGEgZnVuY2nDs24gc2luaCBzZSBhZGljaW9uYSBsYSBwZXJmZWN0YSBzaW1ldHLDrWEgZGUgbGEgZmlndXJhIHJlcHJlc2VudGFkYSBlbiBsYXMgZG9zIGZvcm1hcyBzYWxpZW50ZXMgZGVsIHJhZGlvLiBOdWV2YW1lbnRlIHNlIGFwcm92ZWNoYSBgZ2dwbG90MmAgeSB2YXJpYW5kbyBsYXMgY29uc3RhbnRlcyB5IHZhbG9yZXMgZGUgbGEgZnVuY2nDs24gZSBsbGVnYSBhIGVzdGEgZmlndXJhLg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFICwgZWNobz1GLCBpbmNsdWRlPUZBTFNFfQ0KcG5nKCJhcnRlMi5wbmciKQ0KDQpzZXEoLTE1LCAxNSwgYnkgPSAwLjA1KSAlPiUNCmV4cGFuZC5ncmlkKHg9LiwgeT0uKSAlPiUNCmdncGxvdChhZXMoeD0oMip4KSwgeT0oc2luaCh4K3kpKzIuOCp4KSkpICsNCmdlb21fcG9pbnQoYWxwaGE9LjEsDQogICAgICAgICAgIHNoYXBlPTIwLA0KY29sb3I9ImFxdWFtYXJpbmU0IiwNCnNpemU9MSkrdGhlbWVfdm9pZCgpKw0KY29vcmRfcG9sYXIoKQ0KDQpkZXYub2ZmKCkNCmBgYA0KDQohW1BpZXphIDI6IHNpbWV0csOtYSBpbnZlcnRpZGFdKGFydGUyLnBuZyl7d2l0aGQ9ODAlfQ0KDQojIyMgUGllemEgMyAtIERpc3RvcnNpw7NuIEdhdXNzaWFuYQ0KDQpMYSBwaWV6YSBkZW5vbWluYWRhIERpc3RvcnNpw7NuIEdhdXNzaWFuYSwgc2UgZ2VuZXLDsyBjb24gYXBveW8gZGUgbGEgZnVuY2nDs24gYG12cm5vcm1gIHBhcmEgcG9kZXIgYXPDrSBjcmVhciBtdWVzdHJhcyBhIHBhcnRpciBkZSBsYSBEaXN0cmlidWNpw7NuIE5vcm1hbCBNdWx0aXZhcmlhZGEgZXNwZWNpZmljYWRhLiBMdWVnbywgcGFyYSBjcmVhciBsYSBmaWd1cmEgc2UgZW1wbGXDsyBgZ2dwbG90MmAuIEVsIHJlc3VsdGFkbyBxdWUgc2Ugb2J0dXZvIGZ1ZSBlbCBzaWd1aWVudGU6DQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UgLCBpbmNsdWRlPUZBTFNFIH0NCiNsaWJyZXJpYXMgcmVxdWVyaWRhcy4NCnJlcXVpcmUodGlkeXZlcnNlKQ0KcmVxdWlyZShnZ3Bsb3QyKQ0KcmVxdWlyZShNQVNTKQ0KcmVxdWlyZShnZ3Zvcm9ub2kpDQoNCnNldC5zZWVkKDEyMzQ1KSAjRmlqYXIgdW5hIHNlbWlsbGEuDQoNClhfMCA8LSBzYW1wbGUoMToxMDAwMCwgc2l6ZSA9IDEwMDApICNNdWVzdHJhIGRlIHRhbWHDsW8gbWlsLg0KeV8wIDwtIHNhbXBsZSgxOjEwMDAwLCBzaXplID0gMTAwMCkgI011ZXN0cmEgZGUgdGFtYcOxbyBtaWwuDQpEYXRhIDwtIGRhdGEuZnJhbWUoeCA9IFhfMCwgeSA9IHlfMCkgI0RhdGEgcXVlIGFsbWFjZW5hIGEgJ3gnIHkgJ3knLg0KDQpYXzEgPC0gbXZybm9ybShuID0gMTUwLCBtdSA9IGMoMCwwLDApLCBTaWdtYSA9IGRpYWcoMykpICNFc3BlY2lmaWNhY2lvbiBkZSBEaXN0IE5vcm1hbCBNdWx0aXZhcmlhZGEuDQp5XzEgPC0gbXZybm9ybShuID0gMTUwLCBtdT01LCBTaWdtYT0gMiwgdG9sID0gMWUtMDYsIGVtcGlyaWNhbCA9IEZBTFNFKSAjT3RyYSBlc3BlY2lmaWNhY2lvbiBkZSBEaXN0IE5vcm1hbCBNdWx0aXZhcmlhZGEuDQoNCk1WTiA8LSBkYXRhLmZyYW1lKHggPSAxMDAgKiBYXzEsIHkgPSAxMDAgKiB5XzEsIGdydXBvID0gcmVwKDEsIDMwMDApKSAjRGF0YSBhc29jaWFkYSBhIGxhcyBlc3BlY2lmaWNhY2lvbmVzIGFudGVyaW9yZXMgeSBnZW5lcmFuZG8gMSByZXBsaWNhIGNhZGEgMzAwMCB2ZWNlcy4NCg0KI1NlIHByb2NlZGUgYSBncmFmaWNhcjoNCnBuZygiYXJ0ZTMucG5nIikNCg0KZ2dwbG90KERhdGEsIGFlcyh4PVhfMCwgeT15XzAsKSkgKw0KICBnZW9tX3Zvcm9ub2kob3V0bGluZSA9IE1WTiwNCiAgICAgICAgICAgICAgIGNvbG9yID0gNSwgc2l6ZSA9IDAuMSkgKw0KICB0aGVtZV92b2lkKCkgKw0KICBjb29yZF9wb2xhcigpICNHZW5lcmFuZG8gZ3JhZmljbyBhcG95YWRvIGRlIHVuYSBkaXN0cmlidWNpb24gZGUgcHJvYmFiaWxpZGFkIG5vcm1hbCBtdWx0aXZhcmlhZGEuDQoNCmRldi5vZmYoKQ0KYGBgDQoNCiFbUGllemEgMzogRGlzdG9yc2nDs24gR2F1c3NpYW5hXShhcnRlMy5wbmcpe3dpdGhkPTgwJX0NCg0KIyMjIFBpZXphIDQgLSBMYSBOb3JtYWxpZGFkIGRlIEJlc3NlbA0KDQpDb24gYXBveW8gZGUgbGEgZnVuY2nDs24gYEJlc3NlbGAgeSBgcmxub3JtYCBzZSBkaXNlw7HDsyBlc3RhIHBpZXphLiBFcyBkZWNpciwgbGEgZmlndXJhIHRpZW5lIHN1IGJhc2UgZW4gdW5hIGNvbWJpbmFjacOzbiBlbnRyZSBsYXMgZnVuY2lvbmVzIGRlIEJlc3NlbCB5IGxhIERpc3RyaWJ1Y2nDs24gTG9nbm9ybWFsIE11bHRpdmFyaWFkYS4gQSBjb25zZWN1ZW5jaWEgZGUgZGljaGEgdW5pw7NuIHNlIG9idHV2byBsYSBzaWd1aWVudGUgb2JyYSBkZSBhcnRlOiANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSAsIGluY2x1ZGU9RkFMU0UgfQ0KI1BhcXVldGUgcmVxdWVyaWRvDQpyZXF1aXJlKEJlc3NlbCkNCg0Kc2V0LnNlZWQoMTIzNDU2Nzg5MCkgI1NlIGZpamEgdW5hIHNlbWlsbGENCg0KeF9tIDwtIHNhbXBsZSgxOjUwMDAsIHNpemUgPSAyMDAwKSNNdWVzdHJhIGRlIHRhbWHDsW8gZG9zIG1pbA0KeV9tIDwtIHNhbXBsZSgxOjUwMDAsIHNpemUgPSAyMDAwKSNNdWVzdHJhIGRlIHRhbWHDsW8gZG9zIG1pbA0KRGF0YV9tIDwtIGRhdGEuZnJhbWUoeF9tLCB5X20pDQoNCnhfbG5vcm0gPC0gc29ydChyb3VuZChybG5vcm0oMTAwMCksIDIpKSAjRGlzdCBsb2cgbm9ybWFsIG11bHRpdmFyaWFkYS4NCnlfQmVzc2VsIDwtIGNiaW5kKHhfbG5vcm0sIGEgPSBiZXNzZWxJKHhfbG5vcm0sIDMpLCBiID0gQmVzc2VsSSh4X2xub3JtLCAzKSkgI0Z1bmNpb25lcyBkZSBCZXNzZWwuDQp4X3kgPC0geF9sbm9ybSArIHlfQmVzc2VsI1NlIGFsbWFjZW5hIGxvIHJlYWxpemFkbyBlbiBlbCBwYXNvIGFudGVyaW9yIGVuIGVzdGEgbnVldmEgdmFyaWFibGUNCg0KI1NlIHByb2NlZGUgYSBncmFmaWNhciBjb24gYXBveW8gZGUgZ2dwbG90MjoNCnBuZygiYXJ0ZTQucG5nIikNCg0KZ2dwbG90KERhdGFfbSwgYWVzKHg9eF9tLCB5PXlfbSkpICsNCiAgICBnZW9tX3Zvcm9ub2kob3V0bGluZSA9IHhfeSwNCiAgICAgICAgICAgICAgIGNvbG9yID0iI0NEMEJCQyIsIHNpemUgPSAwLjAwNSkrIA0KICBnZW9tX3BvaW50KHNpemU9MC41LHN0cm9rZT0xLCBzaGFwZT0yMSxjb2xvcj0iI0NEMEJCQyIpKyANCiAgdGhlbWVfdm9pZCgpICsgY29vcmRfZml4ZWQoKSNHZW5lcmFuZG8gZ3JhZmljbyBhcG95YWRvIGRlIHVuYSBkaXN0cmlidWNpb24gbG9nIG5vcm1hbCBtdWx0aXZhcmlhZGEgeSAgZGUgbGFzIEZ1bmNpb25lcyBkZSBCZXNzZWwuDQoNCmRldi5vZmYoKQ0KYGBgDQoNCiFbUGllemEgNDogTGEgTm9ybWFsaWRhZCBkZSBCZXNzZWxdKGFydGU0LnBuZyl7d2l0aGQ9ODAlfQ0KDQojIyMgUGllemEgNSAtIFJhaW5ib3cuDQoNCkxhIHBpZXphIGRlbm9taW5hZGEgUmFpbmJvdywgc2UgZ2VuZXLDsyBjb24gYXBveW8gZGVkYXRvcyBub3JtYWxlcyBwYXJhIHBvZGVyIGFzw60gY3JlYXIgbXVlc3RyYXMgYSBwYXJ0aXIgZGUgcmVnaXN0cm9zIGxvcyBjdWFsZXMgc29uIGHDsW8sIGdydXBvIHkgdmFsb3Jlcy4gTHVlZ28sIHBhcmEgY3JlYXIgbGEgZmlndXJhIHNlIGVtcGxlw7MgYGdncGxvdGAuIEVsIHJlc3VsdGFkbyBxdWUgc2Ugb2J0dXZvIGZ1ZSBlbCBzaWd1aWVudGU6DQoNCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0KDQojR2VuZXJhbmRvIGRhdG9zIHBhcmEgZ3JhZmljYXIuDQpzZXQuc2VlZCgxMTUyMikNCmxpYnJhcnkoUkNvbG9yQnJld2VyKQ0Kbmdyb3VwPTUwDQpuYW1lcz1wYXN0ZSgiR18iLHNlcSgxLG5ncm91cCksc2VwPSIiKQ0KREFUPWRhdGEuZnJhbWUoKQ0KDQpmb3IoaSBpbiBzZXEoMTozMCkpew0KICAgIGRhdGE9ZGF0YS5mcmFtZSggbWF0cml4KDAsIG5ncm91cCAsIDMpKQ0KICAgIGRhdGFbLDFdPWkNCiAgICBkYXRhWywyXT1zYW1wbGUobmFtZXMsIG5yb3coZGF0YSkpDQogICAgZGF0YVssM109cHJvcC50YWJsZShzYW1wbGUoIGMocmVwKDAsMTAwKSxjKDE6bmdyb3VwKSkgLG5yb3coZGF0YSkpKQ0KICAgIERBVD1yYmluZChEQVQsZGF0YSkNCiAgICB9DQpjb2xuYW1lcyhEQVQpPWMoIlllYXIiLCJHcm91cCIsIlZhbHVlIikNCkRBVD1EQVRbb3JkZXIoIERBVCRZZWFyLCBEQVQkR3JvdXApICwgXQ0KDQoNCmNvdWwgPSBicmV3ZXIucGFsKDEyLCAiUGFpcmVkIikgDQpjb3VsID0gY29sb3JSYW1wUGFsZXR0ZShjb3VsKShuZ3JvdXApDQpjb3VsPWNvdWxbc2FtcGxlKGMoMTpsZW5ndGgoY291bCkpICwgc2l6ZT1sZW5ndGgoY291bCkgKSBdDQpgYGANCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQojR3JhZmljYQ0KcG5nKCJhcnRlNS5wbmciKQ0KDQpnZ3Bsb3QoREFULCBhZXMoeD1ZZWFyLCB5PVZhbHVlLCBmaWxsPUdyb3VwICkpICsgDQogICAgZ2VvbV9hcmVhKGFscGhhPTEgICkrDQogICAgdGhlbWVfYncoKSArDQogICAgI3NjYWxlX2ZpbGxfYnJld2VyKGNvbG91cj0icmVkIiwgYnJlYWtzPXJldihsZXZlbHMoREFUJEdyb3VwKSkpKw0KICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvdWwpKw0KICAgICB0aGVtZSgNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgbGluZSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGl0bGUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIsDQogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSkNCg0KZGV2Lm9mZigpDQpgYGANCg0KIVtQaWV6YSA1OiBSYWluYm93XShhcnRlNS5wbmcpe3dpdGhkPTgwJX0NCg0KIyMjIFBpZXphIDYgLSBHYW1tYSBCaWcgQmFuZw0KDQpMYSBwaWV6YSBkZW5vbWluYWRhIEdhbW1hIEJpZyBCYW5nLCBzZSBnZW5lcsOzIGNvbiBhcG95byBkZSBsYSBmdW5jacOzbiBgcmdhbW1hYCBwYXJhIHBvZGVyIGFzw60gY3JlYXIgbXVlc3RyYXMgYWxlYXRvcmlhcyBhIHBhcnRpciBkZSBsYSBEaXN0cmlidWNpw7NuIEdhbW1hIGVzcGVjaWZpY2FkYS4gTHVlZ28sIHBhcmEgY3JlYXIgbGEgZmlndXJhIHNlIGVtcGxlw7MgZWwgZGV2dG9vbHNgZGpuYXZhcnJvL2phc21pbmVzYC4gRWwgcmVzdWx0YWRvIHF1ZSBzZSBvYnR1dm8gZnVlIGVsIHNpZ3VpZW50ZToNCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQojUGFxdWV0ZSByZXF1ZXJpZG9zDQojaW5zdGFsbC5wYWNrYWdlcygic2NpY28iKSAgICAgDQojaW5zdGFsbC5wYWNrYWdlcygiVFNQIikgICAgIA0KI2RldnRvb2xzOjppbnN0YWxsX2dpdGh1YigiZGpuYXZhcnJvL2phc21pbmVzIikgICAgICAgICAgIA0KDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShzY2ljbykNCmxpYnJhcnkoVFNQKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGphc21pbmVzKQ0KDQpwbmcoImFydGU2LnBuZyIpDQoNCnVzZV9zZWVkKDExNTIyKSAlPiUNCiAgc2NlbmVfZGlzY3MoDQogICAgcmluZ3MgPSAyMCwgDQogICAgcG9pbnRzID0gcmdhbW1hKDMsIDEsMSkqMTAwMCwgDQogICAgc2l6ZSA9IDUNCiAgKSAlPiUNCiAgbXV0YXRlKGluZCA9IDE6bigpKSAlPiUNCiAgdW5mb2xkX3dhcnAoDQogICAgaXRlcmF0aW9ucyA9IDIsDQogICAgc2NhbGUgPSAwLjUsIA0KICAgIG91dHB1dCA9ICJsYXllciIgDQogICkgJT4lDQogIHVuZm9sZF90ZW1wZXN0KA0KICAgIGl0ZXJhdGlvbnMgPSAyMCwNCiAgICBzY2FsZSA9IDAuMDENCiAgKSAlPiUNCiAgc3R5bGVfcmliYm9uKA0KICAgIHBhbGV0dGUgPSBwYWxldHRlX25hbWVkKCJwbGFzbWEiKSwNCiAgICBjb2xvdXIgPSAiaW5kIiwNCiAgICBhbHBoYSA9IGMoMC4xLCAwLjEpLA0KICAgIGJhY2tncm91bmQgPSAiI0ZCRTVFMjQwIg0KICApDQoNCmRldi5vZmYoKQ0KDQpgYGANCg0KIVtQaWV6YSA2OiBHYW1tYSBCaWcgQmFuZ10oYXJ0ZTYucG5nKXt3aXRoZD04MCV9DQoNCiMjIyBQaWV6YSA3IC0gVG9ybmFkbw0KDQpMYSBzaWd1aWVudGUgcGllemEsIHNlIGNyZWEgYSBwYXJ0aXIgZGVsIGV4cGVyaW1lbnRvIHRvcm5hZG8gZGUgU3RhckNpcmNsZSwgY3JlYW5kbyB1biBhc3BlY3RvIHRyaWRpbWVuc2lvbmFsLCBjYXNpIGVzZsOpcmljbyAoS3VtYXIsIDIwMjApLiBFbCB0b3JuYWRvIHByZXNlbnRhIHBlcXVlw7FhcyBtb2RpZmljYWNpb25lcyBwYXJhIGVzdGFyIG3DoXMgY2VycmFkbywgYXVtZW50YW5kbyBzdSBzZWN1ZW5jaWEsIGNhbWJpYW5kbyBsYSBmdW5jacOzbiBgKGNvcyh5K3gpKzEuMyp5KWAgcG9yIGAoY29zKHkreCkrMTAqeSlgIGVuIGVsIGVqZSBYIHkgYChzaW4oeCt5KSsyLjMqeClgIHBvciBgKHNpbih4K3kpKzAuMSp4KWAgZW4gZWwgZWplIFkuIE51ZXZhbWVudGUgc2UgaGFjZSB1c29zIGRlICBgZ2dwbG90MmAgbGxlZ2FuZG8gYSBlc3RhIGZpZ3VyYS4NCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQpwbmcoImFydGU3LnBuZyIpIA0KDQojc2VxKC0xMiwgMTIsIGJ5ID0gMC4xKSAlPiUNCiNleHBhbmQuZ3JpZCh4PS4sIHk9LikgJT4lDQojZ2dwbG90KGFlcyh4PShjb3MoeSt4KSsxLjMqeSksIHk9KHNpbih4K3kpKzIuMyp4KSkpICsNCiNnZW9tX3BvaW50KGFscGhhPS4wNSwNCiMgICAgICAgICAgIHNoYXBlPTIwLA0KI2NvbG9yPSJyZWQiLA0KI3NpemU9MSkrdGhlbWVfdm9pZCgpKw0KI2Nvb3JkX3BvbGFyKCkNCg0Kc2VxKC0yMCwgMjAsIGJ5ID0gMC4xKSAlPiUNCmV4cGFuZC5ncmlkKHg9LiwgeT0uKSAlPiUNCmdncGxvdChhZXMoeD0oY29zKHkreCkrMTAqeSksIHk9KHNpbih4K3kpKzAuMSp4KSkpICsNCmdlb21fcG9pbnQoYWxwaGE9LjA1LA0KICAgICAgICAgICBzaGFwZT0yMCwNCmNvbG9yPSJyZWQiLA0Kc2l6ZT0xKSt0aGVtZV92b2lkKCkrDQpjb29yZF9wb2xhcigpDQoNCmRldi5vZmYoKQ0KYGBgDQoNCiFbUGllemEgNzogVG9ybmFkb10oYXJ0ZTcucG5nKXt3aXRoZD04MCV9DQoNCiMjIyBQaWV6YSA4IC0gQ2FzdWFsaWRhZA0KDQpMYSBzaWd1aWVudGUgcGllemEsIHNlIGNyZWEgYSBwYXJ0aXIgZGUgbG9zIGRhdG9zIFggeSBZIGRlIGxhIHBpZXphIDMsIERpc3RvcnNpw7NuIEdhdXNzaWFuYSwgcmVhbGl6YW5kbyB0b2RhcyBsYXMgY29tYmluYWNpb25lcyBwb3NpYmxlcyBlbnRyZSBsb3MgZG9zIGZhY3RvcmVzIGNvbiBsYSBmdW5jacOzbiBgZXhwYW5kLmdyaWQoKWAgeSBsYSBmdW5jacOzbiBgKGNvcyh5K3gpKzEuMyp5KWAgZW4gZWwgZWplIFggeSBgKHNpbih4K3kpKzIuMyp4KWAgZW4gZWwgZWplIFkuIERhbmRvIGNvbW8gcmVzdWx0YWRvIGxhIHNpZ3VpZW50ZSBmaWd1cmEuDQoNCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0KcG5nKCJhcnRlOC5wbmciKQ0KDQpleHBhbmQuZ3JpZCh4PVhfMSwgeT15XzEpICU+JQ0KZ2dwbG90KGFlcyh4PShjb3MoeSt4KSsxLjMqeSksIHk9KHNpbih4K3kpKzIuMyp4KSkpICsNCmdlb21fcG9pbnQoYWxwaGE9LjA1LA0KICAgICAgICAgICBzaGFwZT0yMCwNCmNvbG9yPSJyZWQiLA0Kc2l6ZT0xKSt0aGVtZV92b2lkKCkrDQpjb29yZF9wb2xhcigpDQoNCmRldi5vZmYoKQ0KYGBgDQoNCiFbUGllemEgODogQ2FzdWFsaWRhZF0oYXJ0ZTgucG5nKXt3aXRoZD04MCV9DQoNCiMjIyBQaWV6YSA5IC0gdHJlZV8xDQoNClBhcmEgZWwgdHJlZV8xLnBuZyBzZSBtdWVzdHJhIHVuYSBncmFmaWNhIGNyZWFkYSBhIHBhcnRpciBkZSByYW5kb20gZm9yZXN0IGdlbmVyYWRvIGNvbiB1biBncmFuIGRhdGFzZXQgZGUgc2tsZWFybiwgZXMgaW50ZXJlc2FudGUgdmVyIGNvbW8gY29uIGxhIGdyYW4gY2FudGlkYWQgZGUgZGF0b3Mgc2FsZW4gbXVjaGFzIHJhbWFzIHF1ZSBwdWVkZW4gcGFyZWNlciB1bmEgZ3JhbmphIGRlIGhvcm1pZ2FzIG8gdW4gZW5vcm1lIMOhcmJvbCBnZW5lYWzDs2dpY28gbyBkZSBldm9sdWNpw7NuLg0KDQohW1BpZXphIDk6IHRyZWVfMV0odHJlZV8xLnBuZyl7d2l0aGQ9ODAlfQ0KDQojIyMgUGllemEgMTAgLSB0cmVlXzINCg0KUGFyYSBlbCB0cmVlXzIucG5nIHNlIG11ZXN0cmEgaWd1YWxtZW50ZSB1bmEgZ3JhZmljYSBnZW5lcmFkYSBjb24gcmFuZG9tIGZvcmVzdCB5IGVsIG1pc21vIGRhdGFzZXQsIGVzIG1lbm9zIGxsYW1hdGl2byB5IGFsIHBhcmVjZXIgbWVub3MgY29tcGxlam8gcGVybyByZWFsbWVudGUgcHVlZGUgdmFyaWFyIG3DoXMgdmlzdWFsbWVudGUsIGxhcyBmb3JtYXMgcXVlIG11ZXN0cmEgcHVlZGVuIHBhcmVjZXJzZSBhIHVuIGNlcmVicm8sIHVuIGVsZWZhbnRlLCB1biBjcsOhbmVvLi4uIGRlcGVuZGUgbGEgcGVyY2VwY2nDs24gZGUgcXVlaW4gbG8gZXN0w6kgdmllbmRvIHkgZGUgY29tbyBzZSBhbGxhIGdlbmVyYWRvIGxhIGltYWdlbiBhbGVhdG9yaWFtZW50ZSwgdG9kb3MgbG9zIHBlcXVlw7FvcyBsZXRyZXJvcyBvIGN1YWRyb3MgZGUgbGEgaW1hZ2VuIHNvbiB2YWxvcmVzIGRlIGxhcyBob2phcyBkZWwgcmFuZG9tIGZvcmVzdCwgbG9zIHZhbG9yZXMgZGVsIGRhdGFzZXQgc29uIGlycmVsZXZhbnRlcyBwYXJhIGxvIHF1ZSBlc3RhbW9zIGhhY2llbmRvLCBzw7NsbyBwdWVkZW4gdmFyaWFyIGVsIGNvbG9yIGRlIGNhZGEgdW5vIGRlIGVzdG9zIGxldHJlcm9zIG5hcmFuamFzLg0KDQohW1BpZXphIDEwOiB0cmVlXzJdKHRyZWVfMi5wbmcpe3dpdGhkPTgwJX0NCg0KDQoNCg0KDQoNCiMjIDMuIENvbmNsdXNpb25lcw0KDQotIExhcyBwaWV6YXMgYXJ0w61zdGljYXMgY3JlYWRhcyBwb3IgbWVkaW8gZGUgbGFzIHTDqWNuaWNhcyBhZmlhbnphZGFzIGVuIGVsIGN1cnNvIHNvbiB1bmEgbXVlc3RyYSBkZSBsbyBiZWxsbyBxdWUgZXMgbGEgQ2llbmNpYS4gRXMgZGVjaXIsIG5vIHNvbGFtZW50ZSBhcGxpY2FyIG3DqXRvZG9zIG1hdGVtw6F0aWNvcyB5IGVzdGFkw61zdGljb3MgcGFyYSBzb2x1Y2lvbmFyIHByb2JsZW1hcyBkZSBsYSBjb3RpZGlhbmlkYWQsIHNpbm8gYWhvcmEgcGFyYSBoYWNlciBkZSBlbGxvIGFsZ28gbcOhcyB0YW5naWJsZSwgcHJveWVjdGFkbyBlbiB1bmEgc2VyaWUgZGUgaW3DoWdlbmVzLCBwYXJhIHF1ZSBzZSBwdWVkYSBhcHJlY2lhciB0YW1iacOpbiBwb3IgcGVyc29uYXMgcXVlIG5vIG5lY2VzYXJpYW1lbnRlIGVzdMOhbiBpbm1lcnNhcyBlbiBlc3RlIG11bmRvIGxhcyBjaWVuY2lhcyBmb3JtYWxlcy4NCg0KLSBGdWUgdW4gZXhjZWxlbnRlIHJldG8gaGFjZXIgZXN0ZSBwcm95ZWN0bywgeWEgcXVlIG5pbmd1bm8gZXN0YWJhIGZhbWlsaWFyaXphZG8gY29uIGVsIGNvbmNlcHRvIGRlICJBcnRlIEdlbmVyYXRpdm8iLiBBZGVtw6FzLCBjb25zaWRlcmFuZG8gcXVlIHNlIGVzdMOhIGN1bG1pbmFuZG8gZWwgcGVyw61vZG8gYWNhZMOpbWljbyBzaXJ2acOzIGRlIHRlcmFwaWEgYW50aWVzdHLDqXMgcmVhbGl6YXIgY2FkYSBmaWd1cmEuDQoNCi0gTGFzIHBpZXphcyBxdWUgc2UgZ2VuZXJhcm9uIHBhcmEgZXN0ZSB0cmFiYWpvIHZhbiBkZXNkZSBtZXRvZG9sb2fDrWFzIGNvbW8gInJhbmRvbSBmb3Jlc3QiLCBoYXN0YSAiZnVuY2lvbmVzIGRlIEJlc3NlbCIsIGxvIGN1YWwgaW1wbGljYSBxdWUgc2UgcHJvcG9yY2lvbsOzIGdyYW4gdmFyaWVkYWQgZGUgY29udGVuaWRvIHkgaGFjZSBxdWUgaW1wbMOtY2l0YW1lbnRlIHNlIG5vdGUgbGEgc2VyaWVkYWQgeSBjb21wcm9taXNvIGNvbiBlbCBxdWUgc2UgdG9tw7MgZWwgw7psdGltbyB0cmFiYWpvIHBhcmEgZGljaG8gY3Vyc28uDQoNCg0KDQoNCg0KDQojIyA0LiBFbmxhY2VzIGRlIGludGVyw6lzDQoNCg0KVXN0ZWQgcHVlZGUgcmV2aXNhciBlbCBjw7NkaWdvIHkgbG9zIGRhdG9zIHVzYWRvcyBlbiBlc3RlIHByb3llY3RvIGVuIG51ZXN0cm8gcmVwb3NpdG9yaW8gZW4gW0dpdGh1Yl0oaHR0cHM6Ly9naXRodWIuY29tL2RhYXRvcm9hZy9QUk9ZRUNUT1MtVEFFL3RyZWUvbWFpbi9DdWFydGElMjBlbnRyZWdhKQ0KDQojIyA1LiBSZWZlcmVuY2lhcw0KDQorIFVyZ2lsZXMsIEouICgyMiBkZSBub3ZpZW1icmUgZGUgMjAxOSkuICpFbCBhcnRlIGdlbmVyYXRpdm8sIGVudHJlIGxhIGNpZW5jaWEgY29tcHV0YWNpb25hbCB5IGxhIGNyZWF0aXZpZGFkIGFydMOtc3RpY2EuIFVjdWVuY2EuIE9idGVuaWRvIGRlIGh0dHBzOi8vd3d3LnVjdWVuY2EuZWR1LmVjL2NvbXBvbmVudC9jb250ZW50L2FydGljbGUvMjMzLWVzcGFub2wvaW52ZXN0aWdhY2lvbi9ibG9nLWRlLWNpZW5jaWEvMTM4Ny1hcnRlLWpvc2UtdXJnaWxlcz9JdGVtaWQ9NDM3Kg0KDQorIEt1bWFyLCBTLiAoMjcgZGUgbWF5byBkZSAyMDIwKS4gKkFkdmFuY2VkIEFuYWx5dGljcywgTWFjaGluZSBMZWFybmluZywgQXJ0aWZpY2lhbCBJbnRlbGxpZ2VuY2U6IEV4cGVyaW1lbnRzIGluIEdlbmVyYXRpdmUgQXJ0IFdpdGggUlN0YXRzLiBBQU1MQUkgT2J0ZW5pZG8gZGUgaHR0cHM6Ly93d3cuYWFtbGFpLmNvbS8yMDIwLzA1LzI3L2V4cGVyaW1lbnRzLWluLWdlbmVyYXRpdmUtYXJ0LXdpdGgtcnN0YXRzLyoNCg0K