Category: Desarrollo

Adiós, try_files: Optimizando el rendimiento de Nginx

2025-02-21
Adiós, try_files: Optimizando el rendimiento de Nginx

Este artículo analiza las implicaciones de rendimiento de la directiva try_files en Nginx. Si bien try_files maneja URLs amigables para SEO, genera E/S de disco innecesarias para las comprobaciones de existencia de archivos, lo que afecta al rendimiento. El artículo aboga por un enfoque específico para cada framework (por ejemplo, utilizando el directorio /wp-content/ de WordPress) para configurar Nginx directamente, permitiendo que Nginx sirva archivos estáticos sin try_files. También se proporciona un script de Python para automatizar la generación de bloques de location de Nginx para varios tipos de archivos estáticos, mejorando aún más la eficiencia y la seguridad.

Desarrollo

Cinco Tipos de No Determinismo: Perspectivas Prácticas de los Métodos Formales

2025-02-20
Cinco Tipos de No Determinismo: Perspectivas Prácticas de los Métodos Formales

Este artículo explora cinco tipos de no determinismo en el modelado de sistemas: aleatoriedad verdadera, concurrencia, entrada del usuario, fuerzas externas y abstracción. El autor explica cada tipo claramente con ejemplos prácticos. La aleatoriedad verdadera, aunque a menudo se simula con generadores de números pseudoaleatorios, generalmente se trata como una elección no determinista en el modelado. La concurrencia es una fuente principal de no determinismo, que requiere un manejo especial debido a la explosión del espacio de estados. La entrada del usuario y las fuerzas externas se tratan como influencias externas no deterministas. Fundamentalmente, la abstracción simplifica los procesos deterministas complejos en elecciones no deterministas, simplificando los modelos y aumentando la sensibilidad a los errores potenciales. Esto proporciona información valiosa para comprender el no determinismo y sus aplicaciones en el desarrollo de software.

TinyCompiler: Un compilador de fin de semana

2025-02-20

Este proyecto detalla la creación de TinyCompiler, un compilador minimalista construido en un fin de semana. Traduce el lenguaje de programación esotérico Wend (creado por el autor) a ensamblador GNU. Wend es un lenguaje simple, omitiendo punteros, matrices y otras complejidades, centrándose en los conceptos básicos de los compiladores. El proyecto completo tiene menos de 500 líneas de Python e incluye programas de prueba como el cálculo de la raíz cuadrada de punto fijo, la representación del conjunto de Mandelbrot y juegos simples. Es un gran recurso para aprender sobre la teoría de compiladores.

Desarrollo

El kernel de Linux abraza Rust: Menos errores, mayor eficiencia

2025-02-20

El correo electrónico de Greg KH defiende firmemente la incorporación de Rust en el kernel de Linux. Su amplia experiencia resolviendo errores del kernel durante más de 15 años destaca la capacidad de Rust para prevenir problemas comunes de seguridad de memoria en C, como sobrescrituras de memoria, limpieza de rutas de error y errores de uso después de la liberación. Si bien C++ ofrece algunas mejoras, Rust proporciona garantías de seguridad de memoria más sólidas. KH argumenta que el uso de Rust para nuevos controladores y componentes del kernel reducirá significativamente los errores, aumentará la eficiencia del desarrollo y liberará a los mantenedores para que se centren en problemas de lógica más complejos y condiciones de carrera. Aunque el mantenimiento de bases de código de lenguajes mixtos es un desafío, cree que la comunidad de Linux puede superar este obstáculo, garantizando el éxito continuo de Linux durante los próximos 20 años.

Desarrollo

Carga de Recursos del Navegador: Una Inmersión Profunda en la Caja Negra

2025-02-20
Carga de Recursos del Navegador: Una Inmersión Profunda en la Caja Negra

Cargar una página web y sus subrecursos implica una compleja interacción de factores. Los navegadores tienen en cuenta los recursos que bloquean la representación, los analizadores de precarga, las sugerencias de recursos (precarga/preconexión), los modificadores de carga (async/defer/module), fetchpriority, imágenes receptivas y mucho más. Luego deciden cuándo cargar cada recurso, optimizando para HTTP/2 y HTTP/3 modernos. Sin embargo, los diferentes navegadores emplean estrategias muy diferentes, a veces incluso retrasando intencionalmente las solicitudes. Esta charla profundiza en el proceso de toma de decisiones detrás de la carga de recursos, mostrando cómo influir en el comportamiento del navegador para priorizar recursos críticos, como la imagen LCP. Analizaremos varias cascadas, explicaremos las discrepancias de los navegadores y ofreceremos soluciones a problemas comunes, sin recurrir a la precarga ciega de todo con fetchpriority=high. Obtendrás una comprensión más profunda de los mecanismos internos del navegador y afrontarás con confianza los desafíos de carga de recursos.

La Doble Filo de la IA en la Codificación: La Perspectiva de un Estudiante de Secundaria

2025-02-20
La Doble Filo de la IA en la Codificación: La Perspectiva de un Estudiante de Secundaria

Un programador de secundaria reflexiona sobre su trayectoria de programación, contrastando la experiencia de aprendizaje antes y después de la llegada de herramientas de programación con IA, como Cursor. Si bien inicialmente luchó con errores de sintaxis y de tipo, obtuvo una comprensión profunda de los principios de la programación. Ahora, las herramientas de IA aumentan la eficiencia, pero potencialmente perjudican el proceso de aprendizaje al reducir la experiencia práctica. El autor aboga por minimizar la dependencia de la IA en las etapas iniciales de aprendizaje para construir una base sólida.

Ejecutando Pong en Pestañas del Navegador

2025-02-20
Ejecutando Pong en Pestañas del Navegador

Un desarrollador, de forma ingeniosa, ejecutó el juego Pong en 240 pestañas del navegador. Usando AppleScript para crear una cuadrícula de pestañas, Web Workers para actualizaciones de fondo eficientes y Broadcast Channel para la comunicación entre pestañas, renderizó el juego en los favicons de las pestañas. Este proyecto demuestra el poder de las APIs del navegador y la resolución creativa de problemas.

La Fundación Matrix enfrenta una crisis de financiación que amenaza el protocolo de comunicación de código abierto

2025-02-20
La Fundación Matrix enfrenta una crisis de financiación que amenaza el protocolo de comunicación de código abierto

La Fundación Matrix.org, responsable del mantenimiento del protocolo de comunicación de código abierto Matrix, se enfrenta a una grave escasez de fondos. A pesar de un exitoso 2024 y una Conferencia Matrix que celebró los 10 años de Matrix, la Fundación opera con un presupuesto ajustado y enfrenta amenazas existenciales. El trabajo de la Fundación en el mantenimiento de la especificación Matrix, garantizando su seguridad e interoperabilidad, es crucial. Sin financiación suficiente, estas funciones principales corren el riesgo de verse afectadas, lo que podría provocar la fragmentación del protocolo. La Fundación está buscando financiación urgente para mantener programas críticos y evitar el cierre de sus servicios de puente, haciendo un llamamiento a individuos, organizaciones e inversores para que ayuden a preservar esta red de comunicación descentralizada y cifrada de extremo a extremo.

Julia 1.11 y más allá: Compilación estática, juliaup y avances en WebAssembly

2025-02-20

La versión 1.11 de Julia ha traído mejoras significativas, abordando preocupaciones de larga data de los usuarios. La más impactante es el avance en la compilación estática; la próxima versión 1.12 producirá ejecutables más pequeños, facilitando la distribución. Además, la nueva utilidad juliaup simplifica la instalación y actualización de Julia, mientras que el soporte de WebAssembly continúa madurando, permitiendo que los programas Julia se ejecuten en navegadores. Estas mejoras hacen que Julia sea más fácil de usar y amplían su alcance, convirtiéndolo en un fuerte competidor para la computación científica y el desarrollo de utilidades del sistema.

Las sumas de comprobación fuertes de AWS S3 rompen la compatibilidad: ¿OpenDAL al rescate?

2025-02-20

La última actualización del SDK de AWS S3 establece como predeterminado las sumas de comprobación fuertes de integridad, una medida de seguridad positiva, pero rompe la compatibilidad con muchos servicios compatibles con S3, como Minio, Vast y Dell EC. Proyectos como Trino y Apache Iceberg están experimentando problemas de compatibilidad como resultado, y Iceberg incluso envió un PR para deshabilitar la función. Esto destaca los riesgos de depender directamente de los SDK de S3 y pone de relieve OpenDAL. OpenDAL, al comunicarse directamente con las API, evita problemas de compatibilidad relacionados con el SDK, ofreciendo a los usuarios un método de acceso a datos más estable y confiable.

Desarrollo

DotSlash: Simplificación de la implementación de ejecutables

2025-02-20
DotSlash: Simplificación de la implementación de ejecutables

DotSlash es una herramienta de línea de comandos que permite representar un conjunto de ejecutables pesados y específicos de la plataforma con un archivo de texto pequeño y fácil de leer. Esto hace que sea eficiente almacenar ejecutables en el control de versiones sin afectar el tamaño del repositorio. Esto allana el camino para verificar las cadenas de herramientas de compilación y otras herramientas directamente en el repositorio, reduciendo las dependencias en el entorno host y, por lo tanto, facilitando las compilaciones reproducibles. La primera ejecución descarga y verifica los binarios; las ejecuciones posteriores son instantáneas.

Chrome Canary 130: ¡Llega el elemento <select> personalizable!

2025-02-20
Chrome Canary 130: ¡Llega el elemento <select> personalizable!

Chrome Canary 130 presenta una actualización importante: ¡un elemento `` personalizable! Este problema que ha afectado a los desarrolladores durante mucho tiempo finalmente tiene una solución. Con la propiedad `appearance: base-select`, los desarrolladores pueden personalizar profundamente el elemento `` y su selector emergente, incluyendo el estilo, el contenido y la interactividad. La función se encuentra oficialmente en la Fase 2 en WHATWG, con un fuerte interés entre navegadores. Esta publicación detalla cómo habilitar la función, personalizar sus componentes y las consideraciones sobre las limitaciones y la accesibilidad. Si bien algunas funciones aún están en desarrollo, esta nueva función potente mejorará significativamente la experiencia de desarrollo web.

Desarrollo

Obsidian se vuelve freemium: licencia comercial ya no requerida para uso profesional

2025-02-20
Obsidian se vuelve freemium: licencia comercial ya no requerida para uso profesional

La aplicación para tomar notas Obsidian ha eliminado su licencia comercial, ¡haciéndola gratuita para uso en el trabajo! Más de 10.000 organizaciones, incluyendo gigantes como Amazon y Google, ya utilizan Obsidian. Este cambio simplifica los precios y se alinea con el manifiesto de Obsidian: "todos deberían tener las herramientas para pensar con claridad y organizar ideas de manera efectiva". Si bien ya no es obligatoria, las organizaciones aún pueden comprar licencias comerciales para apoyar el desarrollo y obtener oportunidades de exhibición en la página Obsidian Enterprise.

Lanzamiento de iText Suite 9.1: Mejora del rendimiento y soporte mejorado para SVG

2025-02-20
Lanzamiento de iText Suite 9.1: Mejora del rendimiento y soporte mejorado para SVG

Celebrando su 25 aniversario, iText lanza iText Suite 9.1. Esta versión amplía masivamente la implementación de SVG en iText Core, mejorando el posicionamiento de texto, el manejo de fuentes y añadiendo soporte para atributos de tamaño relativo. También aumenta significativamente el rendimiento de la generación de tablas grandes, especialmente al agregar información de etiquetado estructural, crucial para PDF/A y PDF/UA. El complemento pdfHTML se beneficia del aumento de rendimiento y ahora admite la compilación GraalVM Native Image, lo que aumenta la flexibilidad en la generación de PDF en entornos con recursos limitados. Otras mejoras incluyen capacidades de firma digital mejoradas, soporte mejorado para PDF/UA-2 y actualizaciones en varios complementos.

Desarrollo

Lox: Una Biblioteca Moderna de Astrodinámica para Misiones Espaciales

2025-02-20
Lox: Una Biblioteca Moderna de Astrodinámica para Misiones Espaciales

Lox es una biblioteca de astrodinámica segura y ergonómica para la industria espacial moderna. Ofrece una API completa, que abarca desde herramientas de planificación y análisis de misiones de alto nivel hasta utilidades de bajo nivel. Admite varios sistemas de coordenadas, incluye datos de efemérides para los principales cuerpos celestes y maneja fácilmente los parámetros de orientación de la Tierra. Lox también proporciona enlaces de Python para uso interactivo y es extensible, permitiendo a los usuarios agregar escalas de tiempo personalizadas, algoritmos de transformación y fuentes de datos. Encargada por la Agencia Espacial Europea, es un simulador de misiones espaciales de código abierto de próxima generación.

Spice86: Un emulador DOS en modo real basado en .NET para ingeniería inversa

2025-02-20
Spice86: Un emulador DOS en modo real basado en .NET para ingeniería inversa

Spice86 es un emulador en modo real para DOS basado en .NET, utilizado para ejecutar, realizar ingeniería inversa y reescribir programas DOS en modo real cuyo código fuente no está disponible. Simula la ejecución del programa, exporta datos de tiempo de ejecución (volcado de memoria y flujo de ejecución), y luego utiliza el plugin spice86-ghidra para importar estos datos a Ghidra, convirtiendo las instrucciones ensamblador en código C#. Esto permite la reimplementación gradual del código ensamblador con métodos C#. Spice86 cuenta con varias opciones de línea de comandos, incluyendo depuración, memoria EMS, puerta A20 y depuración remota GDB, además de comandos GDB personalizados para análisis dinámico. También incluye un depurador integrado para inspeccionar la memoria, el desensamblaje, los registros, la pila y las vistas de memoria estructuradas.

Desarrollo

Ingeniero de OpenAI: La IA ha alcanzado el umbral de utilidad, necesita más grandes ingenieros

2025-02-20
Ingeniero de OpenAI: La IA ha alcanzado el umbral de utilidad, necesita más grandes ingenieros

Un ingeniero de OpenAI reflexiona sobre 15 años en IA, observando que modelos de vanguardia como GPT-3, Codex y DALL-E 2 han llevado a la IA más allá de un umbral de utilidad, permitiendo tareas antes imposibles para las computadoras. El progreso depende de la ejecución precisa de modelos a gran escala, lo que exige más ingenieros con fuertes habilidades de software. OpenAI invita a ingenieros talentosos a unirse, enfatizando la importancia de la humildad técnica, ya que muchas intuiciones establecidas de ingeniería de software no se aplican al aprendizaje automático.

Desarrollo

Generador de Contraseñas xkcd: Creación de Contraseñas Seguras y Fáciles de Usar

2025-02-20
Generador de Contraseñas xkcd: Creación de Contraseñas Seguras y Fáciles de Usar

Este script de Python implementa la especificación de contraseña xkcd, generando contraseñas seguras y fáciles de recordar. Los usuarios pueden personalizar la longitud de la contraseña, el recuento de palabras, el separador y la longitud máxima de la palabra. Proporciona cálculos de entropía y estimaciones del tiempo de craqueo, ayudando a los usuarios a evaluar la fortaleza de la contraseña. También admite la generación de varias contraseñas para mitigar los riesgos de visualización por encima del hombro y ofrece varios argumentos de línea de comandos para mayor flexibilidad. La herramienta utiliza un generador de números aleatorios criptográficamente seguro, garantizando la aleatoriedad de la contraseña, y es de código abierto para facilitar su uso y mejora.

Buffers circulares en Rust: Una inmersión profunda

2025-02-20

Mientras trabajaba en un proyecto MIDI, el autor necesitaba una forma de almacenar los mensajes recientes sin un crecimiento ilimitado de memoria. Un buffer circular resultó ser la solución. Esta publicación explica los buffers circulares, su funcionalidad y casos de uso. Compara el `VecDeque` de la biblioteca estándar de Rust con bibliotecas de terceros como `circular-buffer` y `ringbuffer`. `VecDeque` ofrece flexibilidad pero redimensiona dinámicamente; las alternativas de tamaño fijo como `circular-buffer` y `ringbuffer` evitan la sobrecarga de reasignación, pero son menos flexibles. El autor concluye que para necesidades de tamaño fijo, las bibliotecas de terceros ahorran tiempo y esfuerzo de desarrollo.

Desarrollo

Monitorización de sistemas sin agente para Opsmaru: Una solución elegante con Elixir y Broadway

2025-02-20
Monitorización de sistemas sin agente para Opsmaru: Una solución elegante con Elixir y Broadway

Opsmaru ha desarrollado una solución de monitorización de sistemas sin agente, aprovechando su módulo Uplink propio y la API de LXD. Utilizando Elixir y la biblioteca Broadway, Opsmaru recupera directamente las métricas de CPU, memoria, disco y red de los contenedores de LXD, las convierte al formato Prometheus y utiliza Elastic Stack para el almacenamiento y el análisis. Este enfoque evita la sobrecarga de mantenimiento de la instalación de agentes y admite intervalos de monitorización personalizables y el procesamiento de datos, proporcionando a los usuarios información más profunda del sistema.

arXivLabs: Proyectos experimentales con colaboración comunitaria

2025-02-20
arXivLabs: Proyectos experimentales con colaboración comunitaria

arXivLabs es un marco que permite a los colaboradores desarrollar y compartir nuevas funciones de arXiv directamente en nuestro sitio web. Tanto las personas como las organizaciones que trabajan con arXivLabs han adoptado y aceptado nuestros valores de apertura, comunidad, excelencia y privacidad de los datos de los usuarios. arXiv está comprometido con estos valores y solo trabaja con socios que los respetan. ¿Tienes una idea para un proyecto que agregue valor a la comunidad de arXiv? Obtén más información sobre arXivLabs.

Desarrollo

KubeVPN: Conecta tu entorno de desarrollo local a clústeres Kubernetes sin problemas

2025-02-20
KubeVPN: Conecta tu entorno de desarrollo local a clústeres Kubernetes sin problemas

KubeVPN ofrece un entorno de desarrollo nativo en la nube que se conecta a la perfección a la red de tu clúster Kubernetes. Accede a la red del clúster Kubernetes sin esfuerzo utilizando nombres de servicio o IP de Pod/IP de servicio. Facilita la interceptación del tráfico entrante de los servicios del clúster Kubernetes remotos a tu PC local a través de una malla de servicio y más. Por ejemplo, tienes la flexibilidad de ejecutar tu pod Kubernetes dentro de un contenedor Docker local, asegurando una configuración idéntica de entorno, volumen y red. ¡Con KubeVPN, capacítate para desarrollar aplicaciones completamente en tu PC local!

Plea por un SDK para las gafas Meta: Desatando el potencial de los desarrolladores

2025-02-20
Plea por un SDK para las gafas Meta: Desatando el potencial de los desarrolladores

Un desarrollador está instando a Meta a lanzar un kit de desarrollo de software (SDK) para las gafas Meta. Actualmente con funcionalidades limitadas, el desarrollador imagina una comunidad construida alrededor de un SDK, aprovechando una potencial API de servicio en segundo plano para permitir que aplicaciones de terceros envíen comandos. Esto permitiría comandos de voz como "Hey Meta" para controlar dispositivos domésticos inteligentes, por ejemplo. El acceso a una transmisión de cámara en vivo, si se proporciona mediante el SDK, abriría innumerables posibilidades. Esto mejoraría enormemente la personalización y la experiencia del usuario de las gafas Meta.

Desarrollo Gafas Meta

f8: Una arquitectura de 8 bits optimizada para C y eficiencia de memoria

2025-02-20
f8: Una arquitectura de 8 bits optimizada para C y eficiencia de memoria

Los procesadores de 8 bits todavía existen en dispositivos modernos, pero sus arquitecturas a menudo no son adecuadas para lenguajes de alto nivel como C. La arquitectura f8, nacida de la experiencia de mantener el Small Device C Compiler (SDCC) y su soporte para numerosas arquitecturas de 8 bits, pretende ser una solución de 8 bits altamente eficiente. Está diseñada para situaciones en las que la potencia de RISC-V es innecesaria y cada byte de código y memoria de datos debe utilizarse de forma óptima.

Programador 10x: Cómo Aumentar Drásticamente tu Velocidad de Codificación

2025-02-20

Esta publicación argumenta la importancia de mejorar la velocidad de codificación. El autor compara el tiempo de desarrollo de dos bibliotecas similares, con seis y dos años de diferencia, demostrando un aumento de velocidad de al menos 5x, y potencialmente 20-30x. Esta mejora proviene de objetivos más claros, decisiones de diseño más rápidas y procesos de trabajo mejorados. El autor sugiere que un aumento de velocidad de 10x es posible mejorando las habilidades mecánicas, como la velocidad de escritura, reduciendo errores y refinando los flujos de trabajo. Esto se traduce en más productividad, mayor variedad de proyectos y más oportunidades de aprendizaje. La publicación explora el impacto en la selección de proyectos, los ciclos de retroalimentación, el desarrollo de herramientas y utiliza la optimización de SQLite como ejemplo de cómo las pequeñas mejoras incrementales se suman a ganancias significativas. El autor concluye que una mayor velocidad también es más agradable.

HTTL CLI: Simplifica las consultas HTTL desde la terminal

2025-02-20
HTTL CLI: Simplifica las consultas HTTL desde la terminal

A partir de la versión 0.1.7, HTTL ofrece una interfaz de línea de comandos (CLI) para ejecutar consultas HTTL directamente desde tu terminal. Esto es ideal para integrar HTTL en pipelines de CI/CD o scripts de automatización existentes. La CLI de HTTL admite todas las funciones del lenguaje HTTL y proporciona una salida formateada y en color. La instalación requiere Node.js 16.14 o posterior y se realiza mediante npm globalmente.

Desarrollo

Código C con solo directivas `#define` : Animación de fuego con magia negra

2025-02-20

Este artículo detalla cómo el autor creó un programa de animación de fuego utilizando solo la directiva `#define` en C. Esta tarea aparentemente imposible se logró utilizando inteligentemente las capacidades de reemplazo de texto de las definiciones de macro, la concatenación de tokens y las técnicas de llamada recursiva. El resultado es una simulación de fuego quemándose y propagándose, demostrando el poder del preprocesador C y su "completitud de Turing". El artículo también destaca los riesgos y problemas potenciales del uso inadecuado de macros.

Desarrollo preprocesador

Intérpretes de Llamada de Cola: Cuatro Años de Progreso

2025-02-20

Hace cuatro años, un artículo sobre cómo escribir intérpretes ultrarrápidos usando llamadas de cola y el atributo `musttail` generó un interés considerable. Ahora, esta técnica se está adoptando en Python 3.14, LuaJIT Remake y más, ofreciendo mejoras significativas en el rendimiento. El artículo explora el soporte `musttail` de GCC y Clang, el impacto potencial de la propuesta "return goto" del estándar C en los intérpretes de llamada de cola y detalla los roles de los atributos `preserve_none` y `preserve_most` en la optimización de los intérpretes de llamada de cola. Concluye con un resumen del emocionante progreso en el desarrollo de compiladores e intérpretes de lenguajes de programación.

VLM Run Hub: Esquemas Pydantic predefinidos para una extracción simplificada de datos visuales

2025-02-20
VLM Run Hub: Esquemas Pydantic predefinidos para una extracción simplificada de datos visuales

VLM Run Hub es un repositorio completo de esquemas Pydantic predefinidos para extraer datos estructurados de dominios visuales no estructurados como imágenes, videos y documentos. Diseñado para modelos de lenguaje visual (VLMs) y optimizado para casos de uso del mundo real, simplifica la integración de ETL visual en sus flujos de trabajo. Ofrece varios esquemas predefinidos, como un esquema de Factura para extraer metadatos de facturas, y admite varios VLMs, incluidos GPT-4o de OpenAI y Claude Vision de Anthropic. El uso de esquemas Pydantic garantiza la extracción precisa y confiable de datos y simplifica los flujos de trabajo posteriores.

Algoritmo revolucionario resuelve el 'Problema de ordenación de la biblioteca'

2025-02-20
Algoritmo revolucionario resuelve el 'Problema de ordenación de la biblioteca'

Un problema que ha atormentado a los científicos informáticos durante décadas, el 'problema de ordenación de la biblioteca' (o 'problema de etiquetado de listas'), ha experimentado finalmente un gran avance. El desafío consiste en diseñar una estrategia óptima para organizar libros (o datos) para minimizar el tiempo necesario para agregar un nuevo elemento. Si bien los algoritmos anteriores tenían un tiempo de inserción promedio proporcional a (log n)², el nuevo enfoque se acerca sorprendentemente al ideal teórico. Combina inteligentemente una pequeña cantidad de conocimiento sobre el contenido pasado de la estantería con el sorprendente poder de la aleatoriedad, lo que resulta en una mejora notable de la eficiencia. Esta investigación tiene implicaciones significativas para la optimización de la gestión de bases de datos y archivos de disco duro, lo que podría reducir drásticamente los tiempos de espera y la sobrecarga computacional.

Desarrollo
1 2 155 156 157 159 161 162 163 214 215