import%20marimo%0A%0A__generated_with%20%3D%20%220.14.10%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20sala_01(Path%2C%20mo)%3A%0A%20%20%20%20mo.vstack(%5B%0A%20%20%20%20%20%20%20%20mo.image(Path(%22public%2FQR_CODE.svg%22)%2C%20%22QR%20Pycon%202025%20Geopozo%20package%22%2C%20200%2C%20200)%2C%0A%20%20%20%20%20%20%20%20mo.md(%22%23%23%20Como%20instalar%3A%22)%2C%0A%20%20%20%20%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%60%60%60%0A%20%20%20%20uv%20add%20pycon-co-2025-geopozo%0A%20%20%20%20PYTHON_GIL%3D0%20uv%20run%20marimo%20edit%20%23%20si%20linux%0A%20%20%20%20uv%20run%20--python%203.14%20marimo%20edit%20%23%20si%20windows%0A%20%20%20%20%60%60%60%22%22%22)%2C%20%0A%20%20%20%20%5D)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20import_02()%3A%0A%20%20%20%20import%20asyncio%20%23%20herramientas%20para%20asyncio%0A%20%20%20%20import%20math%0A%20%20%20%20import%20pprint%0A%20%20%20%20import%20time%20%23%20sleep%2C%20contar%20segundos%2C%20etc%0A%20%20%20%20from%20pathlib%20import%20Path%20%23%20operaci%C3%B3nes%20para%20archivos%0A%0A%20%20%20%20import%20viztracer%20%23%20calcular%20desempe%C3%B1o%20de%20funciones%0A%20%20%20%20import%20marimo%20as%20mo%20%23%20funciones%20para%20este%20cuaderno%0A%20%20%20%20import%20plotly.graph_objects%20as%20go%20%23%20gr%C3%A1ficos%0A%0A%20%20%20%20%23%20nuestras%20herramientas%0A%20%20%20%20from%20pycon_co_2025_geopozo%20import%20dag%2C%20icicle%0A%20%20%20%20return%20Path%2C%20asyncio%2C%20dag%2C%20go%2C%20icicle%2C%20math%2C%20mo%2C%20pprint%2C%20time%2C%20viztracer%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20intro_03(Path%2C%20mo)%3A%0A%20%20%20%20%23%20Andrew%20Pikul%0A%0A%20%20%20%20mo.vstack(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.Html('%3Ccenter%20style%3D%22font-size%3A%203em%22%3EEl%20asincronismo%20y%20la%20concurrencia%20de%20Python%20en%202025%3C%2Fcenter%3E')%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.hstack(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.vstack(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.md(%22%23%23%20Andrew%20Pikul%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.image(Path(%22public%2Fandrew.png%22)%2C%20rounded%3DTrue%2C%20width%3D%2225em%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.md(%22**Author%20of**%3A%20plotly%2Fchoreographer%2C%20plotly%2Fkaleido%2C%20plotly%2Fpozo%2C%20plotly%2Fgithub-helper%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.md(%22%5Blinkedin%5D(https%3A%2F%2Fwww.linkedin.com%2Fin%2Fajpikul%2F)%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.md(%22%5Bgithub%5D(https%3A%2F%2Fgithub.com%2Fayjayt)%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%20align%3D%22center%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.vstack(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.md(%22%23%23%20David%20Angarita%20Ruiz%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.image(Path(%22public%2Fdavid.png%22)%2C%20rounded%3DTrue%2C%20width%3D%2225em%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.md(%22**Author%20of**%3A%20choreographer%2C%20kaleido%2C%20pozo%2C%20github-helper%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.md(%22%5Blinkedin%5D(https%3A%2F%2Fwww.linkedin.com%2Fin%2Fdavidangaritaruiz%2F)%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.md(%22%5Bgithub%5D(https%3A%2F%2Fgithub.com%2Fdavidangarita1)%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%20align%3D%22center%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20justify%3D%22space-around%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20align%3D%22start%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20%23%20The%20geopozo%20team%20www.geopozo.ing%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20version_04(mo)%3A%0A%20%20%20%20mo.Html(%22%22%22%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20class%3D%22release-cycle-chart%22%20viewBox%3D%220%200%20828%20378.0%22%3E%0A%20%20%20%20%20%20%20%20%3Cdefs%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3ClinearGradient%20id%3D%22release-cycle-mask-gradient-active%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cstop%20stop-color%3D%22black%22%20offset%3D%220%25%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cstop%20stop-color%3D%22white%22%20offset%3D%22100%25%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FlinearGradient%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdefs%3E%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Row%20shading%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20class%3D%22release-cycle-row-shade%22%20x%3D%220em%22%20y%3D%226.75%22%20width%3D%22828%22%20height%3D%2227.0%22%20style%3D%22fill%3Argb(68%2C%2068%2C%2068)%3B%20stroke%3Anone%3B%20stroke-width%3A1px%3B%20%22%2F%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Row%20shading%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20class%3D%22release-cycle-row-shade%22%20x%3D%220em%22%20y%3D%2260.75%22%20width%3D%22828%22%20height%3D%2227.0%22%20style%3D%22fill%3Argb(68%2C%2068%2C%2068)%3B%20stroke%3Anone%3B%20stroke-width%3A1px%3B%20%22%2F%3E%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Row%20shading%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20class%3D%22release-cycle-row-shade%22%20x%3D%220em%22%20y%3D%22114.75%22%20width%3D%22828%22%20height%3D%2227.0%22%20style%3D%22fill%3Argb(68%2C%2068%2C%2068)%3B%20stroke%3Anone%3B%20stroke-width%3A1px%3B%20%22%2F%3E%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Row%20shading%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20class%3D%22release-cycle-row-shade%22%20x%3D%220em%22%20y%3D%22168.75%22%20width%3D%22828%22%20height%3D%2227.0%22%20style%3D%22fill%3Argb(68%2C%2068%2C%2068)%3B%20stroke%3Anone%3B%20stroke-width%3A1px%3B%20%22%2F%3E%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Row%20shading%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20class%3D%22release-cycle-row-shade%22%20x%3D%220em%22%20y%3D%22222.75%22%20width%3D%22828%22%20height%3D%2227.0%22%20style%3D%22fill%3Argb(68%2C%2068%2C%2068)%3B%20stroke%3Anone%3B%20stroke-width%3A1px%3B%20%22%2F%3E%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Row%20shading%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20class%3D%22release-cycle-row-shade%22%20x%3D%220em%22%20y%3D%22276.75%22%20width%3D%22828%22%20height%3D%2227.0%22%20style%3D%22fill%3Argb(68%2C%2068%2C%2068)%3B%20stroke%3Anone%3B%20stroke-width%3A1px%3B%20%22%2F%3E%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-year-text%22%20x%3D%22121.39975247524754%22%20y%3D%22351.0%22%20font-size%3D%2213.5%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'19%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cline%20class%3D%22release-cycle-year-line%22%20x1%3D%22149.85891089108912%22%20x2%3D%22149.85891089108912%22%20y1%3D%220%22%20y2%3D%22351.0%22%20font-size%3D%2218%22%20style%3D%22stroke%3Argb(207%2C%20208%2C%20208)%3B%20stroke-width%3A0.8px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-year-text%22%20x%3D%22178.39603960396042%22%20y%3D%22351.0%22%20font-size%3D%2213.5%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'20%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cline%20class%3D%22release-cycle-year-line%22%20x1%3D%22206.9331683168317%22%20x2%3D%22206.9331683168317%22%20y1%3D%220%22%20y2%3D%22351.0%22%20font-size%3D%2218%22%20style%3D%22stroke%3Argb(207%2C%20208%2C%20208)%3B%20stroke-width%3A0.8px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-year-text%22%20x%3D%22235.39232673267327%22%20y%3D%22351.0%22%20font-size%3D%2213.5%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'21%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cline%20class%3D%22release-cycle-year-line%22%20x1%3D%22263.8514851485148%22%20x2%3D%22263.8514851485148%22%20y1%3D%220%22%20y2%3D%22351.0%22%20font-size%3D%2218%22%20style%3D%22stroke%3Argb(207%2C%20208%2C%20208)%3B%20stroke-width%3A0.8px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-year-text%22%20x%3D%22292.3106435643564%22%20y%3D%22351.0%22%20font-size%3D%2213.5%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'22%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cline%20class%3D%22release-cycle-year-line%22%20x1%3D%22320.769801980198%22%20x2%3D%22320.769801980198%22%20y1%3D%220%22%20y2%3D%22351.0%22%20font-size%3D%2218%22%20style%3D%22stroke%3Argb(207%2C%20208%2C%20208)%3B%20stroke-width%3A0.8px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-year-text%22%20x%3D%22349.2289603960396%22%20y%3D%22351.0%22%20font-size%3D%2213.5%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'23%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cline%20class%3D%22release-cycle-year-line%22%20x1%3D%22377.68811881188117%22%20x2%3D%22377.68811881188117%22%20y1%3D%220%22%20y2%3D%22351.0%22%20font-size%3D%2218%22%20style%3D%22stroke%3Argb(207%2C%20208%2C%20208)%3B%20stroke-width%3A0.8px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-year-text%22%20x%3D%22406.2252475247525%22%20y%3D%22351.0%22%20font-size%3D%2213.5%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'24%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cline%20class%3D%22release-cycle-year-line%22%20x1%3D%22434.76237623762376%22%20x2%3D%22434.76237623762376%22%20y1%3D%220%22%20y2%3D%22351.0%22%20font-size%3D%2218%22%20style%3D%22stroke%3Argb(207%2C%20208%2C%20208)%3B%20stroke-width%3A0.8px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-year-text%22%20x%3D%22463.22153465346537%22%20y%3D%22351.0%22%20font-size%3D%2213.5%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'25%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cline%20class%3D%22release-cycle-year-line%22%20x1%3D%22491.6806930693069%22%20x2%3D%22491.6806930693069%22%20y1%3D%220%22%20y2%3D%22351.0%22%20font-size%3D%2218%22%20style%3D%22stroke%3Argb(207%2C%20208%2C%20208)%3B%20stroke-width%3A0.8px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-year-text%22%20x%3D%22520.1398514851485%22%20y%3D%22351.0%22%20font-size%3D%2213.5%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'26%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cline%20class%3D%22release-cycle-year-line%22%20x1%3D%22548.5990099009902%22%20x2%3D%22548.5990099009902%22%20y1%3D%220%22%20y2%3D%22351.0%22%20font-size%3D%2218%22%20style%3D%22stroke%3Argb(207%2C%20208%2C%20208)%3B%20stroke-width%3A0.8px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-year-text%22%20x%3D%22577.0581683168316%22%20y%3D%22351.0%22%20font-size%3D%2213.5%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'27%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cline%20class%3D%22release-cycle-year-line%22%20x1%3D%22605.5173267326732%22%20x2%3D%22605.5173267326732%22%20y1%3D%220%22%20y2%3D%22351.0%22%20font-size%3D%2218%22%20style%3D%22stroke%3Argb(207%2C%20208%2C%20208)%3B%20stroke-width%3A0.8px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-year-text%22%20x%3D%22634.0544554455445%22%20y%3D%22351.0%22%20font-size%3D%2213.5%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'28%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cline%20class%3D%22release-cycle-year-line%22%20x1%3D%22662.5915841584158%22%20x2%3D%22662.5915841584158%22%20y1%3D%220%22%20y2%3D%22351.0%22%20font-size%3D%2218%22%20style%3D%22stroke%3Argb(207%2C%20208%2C%20208)%3B%20stroke-width%3A0.8px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-year-text%22%20x%3D%22691.0507425742574%22%20y%3D%22351.0%22%20font-size%3D%2213.5%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'29%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cline%20class%3D%22release-cycle-year-line%22%20x1%3D%22719.5099009900989%22%20x2%3D%22719.5099009900989%22%20y1%3D%220%22%20y2%3D%22351.0%22%20font-size%3D%2218%22%20style%3D%22stroke%3Argb(207%2C%20208%2C%20208)%3B%20stroke-width%3A0.8px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-year-text%22%20x%3D%22747.9690594059406%22%20y%3D%22351.0%22%20font-size%3D%2213.5%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'30%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cline%20class%3D%22release-cycle-year-line%22%20x1%3D%22776.4282178217823%22%20x2%3D%22776.4282178217823%22%20y1%3D%220%22%20y2%3D%22351.0%22%20font-size%3D%2218%22%20style%3D%22stroke%3Argb(207%2C%20208%2C%20208)%3B%20stroke-width%3A0.8px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-year-text%22%20x%3D%22804.8873762376238%22%20y%3D%22351.0%22%20font-size%3D%2213.5%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20'31%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%0A%20%20%20%20%20%20%20%20%3C!--%20Gradient%20mask%20to%20fade%20out%20end-of-life%20versions%20--%3E%0A%20%20%20%20%20%20%20%20%3Cmask%20id%3D%22release-cycle-mask-active%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20x%3D%220%22%20y%3D%220%22%20width%3D%22126%22%20height%3D%22378.0%22%20fill%3D%22black%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20x%3D%22117.0%22%20y%3D%220%22%20width%3D%229.0%22%20height%3D%22378.0%22%20fill%3D%22url(%23release-cycle-mask-gradient-active)%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20x%3D%22126%22%20y%3D%220%22%20width%3D%22828%22%20height%3D%22378.0%22%20fill%3D%22white%22%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2Fmask%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Colourful%20blob%20with%20a%20label.%20--%3E%0A%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20bugfix%2Fsecurity%20blobs%20need%20to%20be%20split%20between%20the%20two%20phases.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Draw%20the%20rectangle%20with%20two%20path%20elements%20instead.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Thanks%20Claude.ai%20for%20the%20initial%20conversion.%0A%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20For%20EOL%20releases%2C%20use%20a%20single%20rounded%20rectangle%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20class%3D%22release-cycle-blob%20release-cycle-blob-full%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20release-cycle-status-end-of-life%22%20x%3D%22-391.0990099009901%22%20y%3D%229.0%22%20width%3D%22540.9579207920792%22%20height%3D%2222.5%22%20rx%3D%224.5%22%20ry%3D%224.5%22%20mask%3D%22url(%23release-cycle-mask-active)%22%20style%3D%22fill%3Argb(221%2C%2034%2C%200)%3B%20stroke%3Argb(255%2C%20136%2C%20136)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20text%20before%2Fafter%2Finside%20the%20blob%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-blob-label%20release-cycle-status-end-of-life%22%20font-size%3D%2213.5%22%20y%3D%2225.2%22%20x%3D%22154.35891089108912%22%20text-anchor%3D%22start%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Astart%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20end-of-life%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Legend%20on%20the%20left%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-version-label%22%20x%3D%229.0%22%20y%3D%2227.0%22%20font-size%3D%2218%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A18px%3B%20text-anchor%3Astart%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Python%202.7%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Colourful%20blob%20with%20a%20label.%20--%3E%0A%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20bugfix%2Fsecurity%20blobs%20need%20to%20be%20split%20between%20the%20two%20phases.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Draw%20the%20rectangle%20with%20two%20path%20elements%20instead.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Thanks%20Claude.ai%20for%20the%20initial%20conversion.%0A%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20For%20EOL%20releases%2C%20use%20a%20single%20rounded%20rectangle%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20class%3D%22release-cycle-blob%20release-cycle-blob-full%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20release-cycle-status-end-of-life%22%20x%3D%22-22.29950495049506%22%20y%3D%2263.0%22%20width%3D%22284.7475247524753%22%20height%3D%2222.5%22%20rx%3D%224.5%22%20ry%3D%224.5%22%20mask%3D%22url(%23release-cycle-mask-active)%22%20style%3D%22fill%3Argb(221%2C%2034%2C%200)%3B%20stroke%3Argb(255%2C%20136%2C%20136)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20text%20before%2Fafter%2Finside%20the%20blob%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-blob-label%20release-cycle-status-end-of-life%22%20font-size%3D%2213.5%22%20y%3D%2279.2%22%20x%3D%22266.9480198019802%22%20text-anchor%3D%22start%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Astart%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20end-of-life%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Legend%20on%20the%20left%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-version-label%22%20x%3D%229.0%22%20y%3D%2281.0%22%20font-size%3D%2218%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A18px%3B%20text-anchor%3Astart%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Python%203.6%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Colourful%20blob%20with%20a%20label.%20--%3E%0A%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20bugfix%2Fsecurity%20blobs%20need%20to%20be%20split%20between%20the%20two%20phases.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Draw%20the%20rectangle%20with%20two%20path%20elements%20instead.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Thanks%20Claude.ai%20for%20the%20initial%20conversion.%0A%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20For%20EOL%20releases%2C%20use%20a%20single%20rounded%20rectangle%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20class%3D%22release-cycle-blob%20release-cycle-blob-full%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20release-cycle-status-end-of-life%22%20x%3D%2263.62376237623762%22%20y%3D%2290.0%22%20width%3D%22284.7475247524753%22%20height%3D%2222.5%22%20rx%3D%224.5%22%20ry%3D%224.5%22%20mask%3D%22url(%23release-cycle-mask-active)%22%20style%3D%22fill%3Argb(221%2C%2034%2C%200)%3B%20stroke%3Argb(255%2C%20136%2C%20136)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20text%20before%2Fafter%2Finside%20the%20blob%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-blob-label%20release-cycle-status-end-of-life%22%20font-size%3D%2213.5%22%20y%3D%22106.2%22%20x%3D%22352.8712871287129%22%20text-anchor%3D%22start%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Astart%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20end-of-life%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Legend%20on%20the%20left%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-version-label%22%20x%3D%229.0%22%20y%3D%22108.0%22%20font-size%3D%2218%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A18px%3B%20text-anchor%3Astart%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Python%203.7%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Colourful%20blob%20with%20a%20label.%20--%3E%0A%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20bugfix%2Fsecurity%20blobs%20need%20to%20be%20split%20between%20the%20two%20phases.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Draw%20the%20rectangle%20with%20two%20path%20elements%20instead.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Thanks%20Claude.ai%20for%20the%20initial%20conversion.%0A%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20For%20EOL%20releases%2C%20use%20a%20single%20rounded%20rectangle%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20class%3D%22release-cycle-blob%20release-cycle-blob-full%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20release-cycle-status-end-of-life%22%20x%3D%22137.53960396039605%22%20y%3D%22117.0%22%20width%3D%22283.8118811881188%22%20height%3D%2222.5%22%20rx%3D%224.5%22%20ry%3D%224.5%22%20mask%3D%22url(%23release-cycle-mask-active)%22%20style%3D%22fill%3Argb(221%2C%2034%2C%200)%3B%20stroke%3Argb(255%2C%20136%2C%20136)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20text%20before%2Fafter%2Finside%20the%20blob%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-blob-label%20release-cycle-status-end-of-life%22%20font-size%3D%2213.5%22%20y%3D%22133.2%22%20x%3D%22425.8514851485148%22%20text-anchor%3D%22start%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Astart%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20end-of-life%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Legend%20on%20the%20left%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-version-label%22%20x%3D%229.0%22%20y%3D%22135.0%22%20font-size%3D%2218%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A18px%3B%20text-anchor%3Astart%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Python%203.8%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Colourful%20blob%20with%20a%20label.%20--%3E%0A%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20bugfix%2Fsecurity%20blobs%20need%20to%20be%20split%20between%20the%20two%20phases.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Draw%20the%20rectangle%20with%20two%20path%20elements%20instead.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Thanks%20Claude.ai%20for%20the%20initial%20conversion.%0A%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Split%20the%20blob%20using%20path%20operations%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(Move-to%2C%20Vertical%2FHorizontal%2C%20Arc%2C%20Z%3Dclose%20shape%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lowercase%20means%20relative%20to%20the%20last%20point.)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20We%20start%20drawing%20from%20the%20top%20of%20the%20straight%20boundary%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20between%20the%20half-blobs.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20class%3D%22release-cycle-blob%20release-cycle-status-bugfix%22%20d%3D%22%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20M278.509900990099%2C144.0v22.5H197.71039603960398a4.5%2C4.5%2090%200%201-4.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v-13.5a4.5%2C4.5%2090%200%2014.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Z%22%20style%3D%22fill%3Argb(0%2C%20221%2C%2034)%3B%20stroke%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20class%3D%22release-cycle-blob%20release-cycle-status-security%22%20d%3D%22%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20M278.509900990099%2C144.0v22.5H472.83415841584167a4.5%2C4.5%2090%200%2004.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v-13.5a4.5%2C4.5%2090%200%200-4.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Z%22%20style%3D%22fill%3Argb(255%2C%20221%2C%2068)%3B%20stroke%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20a%20common%20border%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20class%3D%22release-cycle-border%20release-cycle-status-security%22%20x%3D%22193.21039603960398%22%20y%3D%22144.0%22%20width%3D%22284.12376237623766%22%20height%3D%2222.5%22%20rx%3D%224.5%22%20ry%3D%224.5%22%20style%3D%22fill%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke%3Argb(255%2C%20136%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20text%20before%2Fafter%2Finside%20the%20blob%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-blob-label%20release-cycle-status-security%22%20font-size%3D%2213.5%22%20y%3D%22160.2%22%20x%3D%22377.92202970297035%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(0%2C%200%2C%200)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20%20color%3A%20black%3B%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20security%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Legend%20on%20the%20left%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-version-label%22%20x%3D%229.0%22%20y%3D%22162.0%22%20font-size%3D%2218%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A18px%3B%20text-anchor%3Astart%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Python%203.9%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Colourful%20blob%20with%20a%20label.%20--%3E%0A%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20bugfix%2Fsecurity%20blobs%20need%20to%20be%20split%20between%20the%20two%20phases.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Draw%20the%20rectangle%20with%20two%20path%20elements%20instead.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Thanks%20Claude.ai%20for%20the%20initial%20conversion.%0A%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Split%20the%20blob%20using%20path%20operations%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(Move-to%2C%20Vertical%2FHorizontal%2C%20Arc%2C%20Z%3Dclose%20shape%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lowercase%20means%20relative%20to%20the%20last%20point.)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20We%20start%20drawing%20from%20the%20top%20of%20the%20straight%20boundary%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20between%20the%20half-blobs.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20class%3D%22release-cycle-blob%20release-cycle-status-bugfix%22%20d%3D%22%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20M335.27227722772284%2C171.0v22.5H254.4727722772277a4.5%2C4.5%2090%200%201-4.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v-13.5a4.5%2C4.5%2090%200%2014.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Z%22%20style%3D%22fill%3Argb(0%2C%20221%2C%2034)%3B%20stroke%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20class%3D%22release-cycle-blob%20release-cycle-status-security%22%20d%3D%22%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20M335.27227722772284%2C171.0v22.5H529.7524752475248a4.5%2C4.5%2090%200%2004.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v-13.5a4.5%2C4.5%2090%200%200-4.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Z%22%20style%3D%22fill%3Argb(255%2C%20221%2C%2068)%3B%20stroke%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20a%20common%20border%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20class%3D%22release-cycle-border%20release-cycle-status-security%22%20x%3D%22249.9727722772277%22%20y%3D%22171.0%22%20width%3D%22284.2797029702971%22%20height%3D%2222.5%22%20rx%3D%224.5%22%20ry%3D%224.5%22%20style%3D%22fill%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke%3Argb(255%2C%20136%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20text%20before%2Fafter%2Finside%20the%20blob%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-blob-label%20release-cycle-status-security%22%20font-size%3D%2213.5%22%20y%3D%22187.2%22%20x%3D%22434.7623762376238%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(0%2C%200%2C%200)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20%20color%3A%20black%3B%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20security%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Legend%20on%20the%20left%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-version-label%22%20x%3D%229.0%22%20y%3D%22189.0%22%20font-size%3D%2218%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A18px%3B%20text-anchor%3Astart%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Python%203.10%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Colourful%20blob%20with%20a%20label.%20--%3E%0A%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20bugfix%2Fsecurity%20blobs%20need%20to%20be%20split%20between%20the%20two%20phases.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Draw%20the%20rectangle%20with%20two%20path%20elements%20instead.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Thanks%20Claude.ai%20for%20the%20initial%20conversion.%0A%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Split%20the%20blob%20using%20path%20operations%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(Move-to%2C%20Vertical%2FHorizontal%2C%20Arc%2C%20Z%3Dclose%20shape%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lowercase%20means%20relative%20to%20the%20last%20point.)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20We%20start%20drawing%20from%20the%20top%20of%20the%20straight%20boundary%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20between%20the%20half-blobs.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20class%3D%22release-cycle-blob%20release-cycle-status-bugfix%22%20d%3D%22%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20M395.30940594059405%2C198.0v22.5H314.509900990099a4.5%2C4.5%2090%200%201-4.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v-13.5a4.5%2C4.5%2090%200%2014.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Z%22%20style%3D%22fill%3Argb(0%2C%20221%2C%2034)%3B%20stroke%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20class%3D%22release-cycle-blob%20release-cycle-status-security%22%20d%3D%22%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20M395.30940594059405%2C198.0v22.5H586.670792079208a4.5%2C4.5%2090%200%2004.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v-13.5a4.5%2C4.5%2090%200%200-4.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Z%22%20style%3D%22fill%3Argb(255%2C%20221%2C%2068)%3B%20stroke%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20a%20common%20border%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20class%3D%22release-cycle-border%20release-cycle-status-security%22%20x%3D%22310.009900990099%22%20y%3D%22198.0%22%20width%3D%22281.160891089109%22%20height%3D%2222.5%22%20rx%3D%224.5%22%20ry%3D%224.5%22%20style%3D%22fill%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke%3Argb(255%2C%20136%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20text%20before%2Fafter%2Finside%20the%20blob%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-blob-label%20release-cycle-status-security%22%20font-size%3D%2213.5%22%20y%3D%22214.2%22%20x%3D%22493.24009900990103%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(0%2C%200%2C%200)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20%20color%3A%20black%3B%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20security%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Legend%20on%20the%20left%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-version-label%22%20x%3D%229.0%22%20y%3D%22216.0%22%20font-size%3D%2218%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A18px%3B%20text-anchor%3Astart%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Python%203.11%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Colourful%20blob%20with%20a%20label.%20--%3E%0A%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20bugfix%2Fsecurity%20blobs%20need%20to%20be%20split%20between%20the%20two%20phases.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Draw%20the%20rectangle%20with%20two%20path%20elements%20instead.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Thanks%20Claude.ai%20for%20the%20initial%20conversion.%0A%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Split%20the%20blob%20using%20path%20operations%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(Move-to%2C%20Vertical%2FHorizontal%2C%20Arc%2C%20Z%3Dclose%20shape%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lowercase%20means%20relative%20to%20the%20last%20point.)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20We%20start%20drawing%20from%20the%20top%20of%20the%20straight%20boundary%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20between%20the%20half-blobs.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20class%3D%22release-cycle-blob%20release-cycle-status-bugfix%22%20d%3D%22%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20M448.7970297029703%2C225.0v22.5H367.9975247524752a4.5%2C4.5%2090%200%201-4.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v-13.5a4.5%2C4.5%2090%200%2014.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Z%22%20style%3D%22fill%3Argb(0%2C%20221%2C%2034)%3B%20stroke%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20class%3D%22release-cycle-blob%20release-cycle-status-security%22%20d%3D%22%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20M448.7970297029703%2C225.0v22.5H643.7450495049505a4.5%2C4.5%2090%200%2004.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v-13.5a4.5%2C4.5%2090%200%200-4.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Z%22%20style%3D%22fill%3Argb(255%2C%20221%2C%2068)%3B%20stroke%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20a%20common%20border%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20class%3D%22release-cycle-border%20release-cycle-status-security%22%20x%3D%22363.4975247524752%22%20y%3D%22225.0%22%20width%3D%22284.74752475247533%22%20height%3D%2222.5%22%20rx%3D%224.5%22%20ry%3D%224.5%22%20style%3D%22fill%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke%3Argb(255%2C%20136%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20text%20before%2Fafter%2Finside%20the%20blob%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-blob-label%20release-cycle-status-security%22%20font-size%3D%2213.5%22%20y%3D%22241.2%22%20x%3D%22548.5210396039604%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(0%2C%200%2C%200)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20color%3A%20black%3B%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20security%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Legend%20on%20the%20left%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-version-label%22%20x%3D%229.0%22%20y%3D%22243.0%22%20font-size%3D%2218%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A18px%3B%20text-anchor%3Astart%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Python%203.12%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Colourful%20blob%20with%20a%20label.%20--%3E%0A%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20bugfix%2Fsecurity%20blobs%20need%20to%20be%20split%20between%20the%20two%20phases.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Draw%20the%20rectangle%20with%20two%20path%20elements%20instead.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Thanks%20Claude.ai%20for%20the%20initial%20conversion.%0A%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Split%20the%20blob%20using%20path%20operations%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(Move-to%2C%20Vertical%2FHorizontal%2C%20Arc%2C%20Z%3Dclose%20shape%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lowercase%20means%20relative%20to%20the%20last%20point.)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20We%20start%20drawing%20from%20the%20top%20of%20the%20straight%20boundary%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20between%20the%20half-blobs.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20class%3D%22release-cycle-blob%20release-cycle-status-bugfix%22%20d%3D%22%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20M535.1881188118812%2C252.0v22.5H425.8514851485148a4.5%2C4.5%2090%200%201-4.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v-13.5a4.5%2C4.5%2090%200%2014.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Z%22%20style%3D%22fill%3Argb(0%2C%20221%2C%2034)%3B%20stroke%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20class%3D%22release-cycle-blob%20release-cycle-status-security%22%20d%3D%22%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20M535.1881188118812%2C252.0v22.5H700.6633663366337a4.5%2C4.5%2090%200%2004.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v-13.5a4.5%2C4.5%2090%200%200-4.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Z%22%20style%3D%22fill%3Argb(255%2C%20221%2C%2068)%3B%20stroke%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20a%20common%20border%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20class%3D%22release-cycle-border%20release-cycle-status-bugfix%22%20x%3D%22421.3514851485148%22%20y%3D%22252.0%22%20width%3D%22283.81188118811883%22%20height%3D%2222.5%22%20rx%3D%224.5%22%20ry%3D%224.5%22%20style%3D%22fill%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke%3Argb(0%2C%20136%2C%2068)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20text%20before%2Fafter%2Finside%20the%20blob%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-blob-label%20release-cycle-status-bugfix%22%20font-size%3D%2213.5%22%20y%3D%22268.2%22%20x%3D%22478.269801980198%22%20text-anchor%3D%22middle%22%20style%3D%22fill%3Argb(255%2C%20255%2C%20255)%3B%20font-size%3A13.5px%3B%20text-anchor%3Amiddle%3B%20color%3A%20black%3B%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20bugfix%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Legend%20on%20the%20left%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-version-label%22%20x%3D%229.0%22%20y%3D%22270.0%22%20font-size%3D%2218%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A18px%3B%20text-anchor%3Astart%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Python%203.13%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Colourful%20blob%20with%20a%20label.%20--%3E%0A%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20bugfix%2Fsecurity%20blobs%20need%20to%20be%20split%20between%20the%20two%20phases.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Draw%20the%20rectangle%20with%20two%20path%20elements%20instead.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Thanks%20Claude.ai%20for%20the%20initial%20conversion.%0A%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Split%20the%20blob%20using%20path%20operations%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(Move-to%2C%20Vertical%2FHorizontal%2C%20Arc%2C%20Z%3Dclose%20shape%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lowercase%20means%20relative%20to%20the%20last%20point.)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20We%20start%20drawing%20from%20the%20top%20of%20the%20straight%20boundary%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20between%20the%20half-blobs.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20class%3D%22release-cycle-blob%20release-cycle-status-bugfix%22%20d%3D%22%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20M592.1064356435643%2C279.0v22.5H482.76980198019805a4.5%2C4.5%2090%200%201-4.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v-13.5a4.5%2C4.5%2090%200%2014.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Z%22%20style%3D%22fill%3Argb(0%2C%20221%2C%2034)%3B%20stroke%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20class%3D%22release-cycle-blob%20release-cycle-status-security%22%20d%3D%22%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20M592.1064356435643%2C279.0v22.5H757.5816831683169a4.5%2C4.5%2090%200%2004.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v-13.5a4.5%2C4.5%2090%200%200-4.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Z%22%20style%3D%22fill%3Argb(255%2C%20221%2C%2068)%3B%20stroke%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20a%20common%20border%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20class%3D%22release-cycle-border%20release-cycle-status-prerelease%22%20x%3D%22478.26980198019805%22%20y%3D%22279.0%22%20width%3D%22283.81188118811883%22%20height%3D%2222.5%22%20rx%3D%224.5%22%20ry%3D%224.5%22%20style%3D%22fill%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke%3Argb(0%2C%20100%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20text%20before%2Fafter%2Finside%20the%20blob%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-blob-label%20release-cycle-status-prerelease%22%20font-size%3D%2213.5%22%20y%3D%22295.2%22%20x%3D%22473.76980198019805%22%20text-anchor%3D%22end%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Aend%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20prerelease%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Legend%20on%20the%20left%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-version-label%22%20x%3D%229.0%22%20y%3D%22297.0%22%20font-size%3D%2218%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A18px%3B%20text-anchor%3Astart%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Python%203.14%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Colourful%20blob%20with%20a%20label.%20--%3E%0A%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20bugfix%2Fsecurity%20blobs%20need%20to%20be%20split%20between%20the%20two%20phases.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Draw%20the%20rectangle%20with%20two%20path%20elements%20instead.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Thanks%20Claude.ai%20for%20the%20initial%20conversion.%0A%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Split%20the%20blob%20using%20path%20operations%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(Move-to%2C%20Vertical%2FHorizontal%2C%20Arc%2C%20Z%3Dclose%20shape%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lowercase%20means%20relative%20to%20the%20last%20point.)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20We%20start%20drawing%20from%20the%20top%20of%20the%20straight%20boundary%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20between%20the%20half-blobs.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20class%3D%22release-cycle-blob%20release-cycle-status-bugfix%22%20d%3D%22%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20M648.0891089108911%2C306.0v22.5H538.7524752475248a4.5%2C4.5%2090%200%201-4.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v-13.5a4.5%2C4.5%2090%200%2014.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Z%22%20style%3D%22fill%3Argb(0%2C%20221%2C%2034)%3B%20stroke%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cpath%20class%3D%22release-cycle-blob%20release-cycle-status-security%22%20d%3D%22%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20M648.0891089108911%2C306.0v22.5H814.5a4.5%2C4.5%2090%200%2004.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20v-13.5a4.5%2C4.5%2090%200%200-4.5%20-4.5%26%23xA%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Z%22%20style%3D%22fill%3Argb(255%2C%20221%2C%2068)%3B%20stroke%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20a%20common%20border%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Crect%20class%3D%22release-cycle-border%20release-cycle-status-feature%22%20x%3D%22534.2524752475248%22%20y%3D%22306.0%22%20width%3D%22284.7475247524752%22%20height%3D%2222.5%22%20rx%3D%224.5%22%20ry%3D%224.5%22%20style%3D%22fill%3Argba(0%2C%200%2C%200%2C%200)%3B%20stroke%3Argb(0%2C%20136%2C%20136)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Add%20text%20before%2Fafter%2Finside%20the%20blob%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-blob-label%20release-cycle-status-feature%22%20font-size%3D%2213.5%22%20y%3D%22322.2%22%20x%3D%22529.7524752475248%22%20text-anchor%3D%22end%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A13.5px%3B%20text-anchor%3Aend%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20feature%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C!--%20Legend%20on%20the%20left%20--%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Ctext%20class%3D%22release-cycle-version-label%22%20x%3D%229.0%22%20y%3D%22324.0%22%20font-size%3D%2218%22%20style%3D%22fill%3Argb(207%2C%20208%2C%20208)%3B%20font-size%3A18px%3B%20text-anchor%3Astart%3B%20%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Python%203.15%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2Ftext%3E%0A%0A%20%20%20%20%20%20%20%20%3C!--%20A%20line%20for%20today%20--%3E%0A%20%20%20%20%20%20%20%20%3Cline%20class%3D%22release-cycle-today-line%22%20x1%3D%22462.98762376237624%22%20x2%3D%22462.98762376237624%22%20y1%3D%220%22%20y2%3D%22351.0%22%20font-size%3D%2218%22%20style%3D%22stroke%3Argb(61%2C%20148%2C%20255)%3B%20stroke-width%3A1.6px%3B%20%22%2F%3E%0A%20%20%20%20%3C%2Fsvg%3E%0A%0A%20%20%20%20source%3A%20https%3A%2F%2Fdevguide.python.org%2Fversions%2F%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20cuatro_jinetes_05(Path%2C%20mo)%3A%0A%20%20%20%20mo.image(Path(%22public%2Fcuatro_gatos.svg%22))%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20gato_sync_06(time)%3A%0A%20%20%20%20%23%20DEFINICI%C3%93N%0A%20%20%20%20def%20siesta()%3A%0A%20%20%20%20%20%20%20%20time.sleep(1)%0A%0A%20%20%20%20def%20gato(p%3DTrue)%3A%0A%20%20%20%20%20%20%20%20siesta()%0A%20%20%20%20%20%20%20%20siesta()%0A%20%20%20%20%20%20%20%20if%20p%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22miau%22)%0A%0A%20%20%20%20def%20yo(p%3DTrue)%3A%0A%20%20%20%20%20%20%20%20siesta()%0A%20%20%20%20%20%20%20%20if%20p%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22buen%20d%C3%ADa%22)%0A%20%20%20%20return%20gato%2C%20yo%0A%0A%0A%40app.cell%0Adef%20sync_dur_07(gato%2C%20time%2C%20yo)%3A%0A%20%20%20%20%23%20CONTAR%0A%20%20%20%20_inicio%20%3D%20time.perf_counter()%20%23%20hora%20inicio%0A%0A%20%20%20%20gato()%20%23%20mi%20gato%0A%20%20%20%20yo()%20%23%20yo%0A%0A%20%20%20%20print(f%22Duraci%C3%B3n%3A%20%7Btime.perf_counter()%20-%20_inicio%7D%22)%20%23%20calcular%20duraci%C3%B3n%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20sync_perf_08(Path%2C%20gato%2C%20go%2C%20icicle%2C%20math%2C%20viztracer%2C%20yo)%3A%0A%20%20%20%20%23%20CALCULAR%20FLAMEGRAPH%0A%0A%20%20%20%20with%20(%0A%20%20%20%20%20%20%20%20viztracer.VizTracer(%0A%20%20%20%20%20%20%20%20%20%20%20%20output_file%3D(%20_path%20%3A%3D%20%22results%2Fsync_profile.json%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20verbose%3D0%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20)%3A%0A%20%20%20%20%20%20%20%20gato(False)%0A%20%20%20%20%20%20%20%20yo(False)%0A%0A%20%20%20%20%23%23%20MOSTRAR%20GR%C3%81FICO%0A%0A%20%20%20%20_labels%2C%20_parents%2C%20_values%20%3D%20icicle.from_threads(%0A%20%20%20%20%20%20%20%20icicle.sort_and_strip_json(Path(_path))%0A%20%20%20%20)%0A%0A%20%20%20%20_fig%20%3D%20go.Figure(go.Icicle(%0A%20%20%20%20%20%20%20%20%20%20%20%20labels%3D_labels%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20parents%3D_parents%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20values%3D%5Bmath.log1p(v)%20for%20v%20in%20_values%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20branchvalues%3D%22remainder%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20textinfo%3D%22label%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20textfont%3Ddict(size%3D20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker%3Ddict(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20line%3Ddict(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width%3D2%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22black%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20tiling%20%3D%20dict(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20orientation%3D'v'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20))%0A%20%20%20%20_fig.update_layout(%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Perf%C3%ADl%20por%20Hilo%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20margin%3Ddict(l%3D10%2C%20r%3D10%2C%20t%3D40%2C%20b%3D10)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20paper_bgcolor%3D%22rgba(0%2C0%2C0%2C0)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20plot_bgcolor%3D%22rgba(0%2C0%2C0%2C0)%22%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20_fig.show()%20%23%20o%20https%3A%2F%2Fwww.speedscope.app%2F%20%23%20TO%20lots%20otros%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20gato_async_09(asyncio)%3A%0A%20%20%20%20%23%20DEFINICI%C3%93N%0A%0A%20%20%20%20async%20def%20siesta_async()%3A%20%23%20estas%20son%20corrutinas%0A%20%20%20%20%20%20%20%20await%20asyncio.sleep(1)%0A%0A%20%20%20%20async%20def%20gato_async(p%3DTrue)%3A%0A%20%20%20%20%20%20%20%20await%20siesta_async()%0A%20%20%20%20%20%20%20%20await%20siesta_async()%0A%20%20%20%20%20%20%20%20if%20p%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22miau%22)%0A%0A%20%20%20%20async%20def%20yo_async(p%3DTrue)%3A%0A%20%20%20%20%20%20%20%20await%20siesta_async()%0A%20%20%20%20%20%20%20%20if%20p%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22buen%20d%C3%ADa%22)%0A%20%20%20%20return%20gato_async%2C%20yo_async%0A%0A%0A%40app.cell%0Aasync%20def%20gato_dur_10(gato_async%2C%20time%2C%20yo_async)%3A%0A%20%20%20%20%23%20CONTAR%0A%0A%20%20%20%20_inicio%20%3D%20time.perf_counter()%20%23%20hora%20inicio%0A%0A%20%20%20%20await%20gato_async()%0A%20%20%20%20await%20yo_async()%0A%0A%20%20%20%20print(f%22Duraci%C3%B3n%3A%20%7Btime.perf_counter()%20-%20_inicio%7D%22)%20%23%20calcular%20duraci%C3%B3n%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Aasync%20def%20gato_perf_11(%0A%20%20%20%20Path%2C%0A%20%20%20%20gato_async%2C%0A%20%20%20%20go%2C%0A%20%20%20%20icicle%2C%0A%20%20%20%20math%2C%0A%20%20%20%20viztracer%2C%0A%20%20%20%20yo_async%2C%0A)%3A%0A%20%20%20%20%23%20MIRAR%20FLAMEGRAPH%0A%0A%20%20%20%20with%20(%0A%20%20%20%20%20%20%20%20viztracer.VizTracer(%0A%20%20%20%20%20%20%20%20%20%20%20%20output_file%3D(%20_path%20%3A%3D%20%22results%2Fasync_profile.json%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20verbose%3D0%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20)%3A%0A%20%20%20%20%20%20%20%20await%20gato_async(False)%0A%20%20%20%20%20%20%20%20await%20yo_async(False)%0A%0A%20%20%20%20_labels%2C%20_parents%2C%20_values%20%3D%20icicle.from_threads(%0A%20%20%20%20%20%20%20%20icicle.sort_and_strip_json(Path(_path))%0A%20%20%20%20)%0A%0A%20%20%20%20_fig%20%3D%20go.Figure(go.Icicle(%0A%20%20%20%20%20%20%20%20%20%20%20%20labels%3D_labels%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20parents%3D_parents%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20values%3D%5Bmath.log1p(v)%20for%20v%20in%20_values%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20branchvalues%3D%22remainder%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20textinfo%3D%22label%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20textfont%3Ddict(size%3D20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker%3Ddict(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20line%3Ddict(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width%3D2%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22black%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20tiling%20%3D%20dict(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20orientation%3D'v'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20))%0A%20%20%20%20_fig.update_layout(%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Perf%C3%ADl%20por%20Hilo%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20margin%3Ddict(l%3D10%2C%20r%3D10%2C%20t%3D40%2C%20b%3D10)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20paper_bgcolor%3D%22rgba(0%2C0%2C0%2C0)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20plot_bgcolor%3D%22rgba(0%2C0%2C0%2C0)%22%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20_fig.show()%20%23%20o%20https%3A%2F%2Fwww.speedscope.app%2F%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Aasync%20def%20gather_gato_12(asyncio%2C%20gato_async%2C%20time%2C%20yo_async)%3A%0A%0A%20%20%20%20_inicio%20%3D%20time.perf_counter()%20%23%20hora%20inicio%0A%0A%20%20%20%20resultados%20%3D%20await%20asyncio.gather(%0A%20%20%20%20%20%20%20%20gato_async()%2C%0A%20%20%20%20%20%20%20%20yo_async()%0A%20%20%20%20)%0A%0A%20%20%20%20print(f%22Duraci%C3%B3n%3A%20%7Btime.perf_counter()%20-%20_inicio%7D%22)%20%23%20calcular%20duraci%C3%B3n%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20sync_async_13(mo)%3A%0A%20%20%20%20mo.hstack(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20S%C3%ADncrono%0A%20%20%20%20%60%60%60python%0A%20%20%20%20def%20siesta()%3A%0A%20%20%20%20%20%20%20%20time.sleep(1)%0A%0A%20%20%20%20def%20gato()%3A%0A%20%20%20%20%20%20%20%20siesta()%0A%20%20%20%20%20%20%20%20siesta()%0A%20%20%20%20%20%20%20%20print(%22miau%22)%0A%0A%20%20%20%20def%20yo()%3A%0A%20%20%20%20%20%20%20%20siesta()%0A%20%20%20%20%20%20%20%20print(%22buen%20d%C3%ADa%22)%0A%20%20%20%20%60%60%60%0A%20%20%20%20%22%22%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20As%C3%ADncrono%0A%20%20%20%20%60%60%60python%0A%20%20%20%20async%20def%20siesta_async()%3A%0A%20%20%20%20%20%20%20%20await%20asyncio.sleep(1)%0A%0A%20%20%20%20async%20def%20gato_async()%3A%0A%20%20%20%20%20%20%20%20await%20siesta_async()%0A%20%20%20%20%20%20%20%20await%20siesta_async()%0A%20%20%20%20%20%20%20%20print(%22miau%22)%0A%0A%20%20%20%20async%20def%20yo_async()%3A%0A%20%20%20%20%20%20%20%20await%20siesta_async()%0A%20%20%20%20%20%20%20%20print(%22buen%20d%C3%ADa%22)%0A%20%20%20%20%60%60%60%22%22%22)%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20justify%3D%22center%22%2C%0A%20%20%20%20%20%20%20%20gap%3D1%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20ac%C3%A1%20hacemos%20comparaci%C3%B3n%20del%20flamegraph%20real%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20cheatsheet_14(Path%2C%20mo)%3A%0A%20%20%20%20mo.image(Path(%22public%2Fmug_screenshot.png%22))%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20dag_15(dag%2C%20mo)%3A%0A%20%20%20%20tree1%20%3D%20%7Bdag.Node(%22gather%22%2C%20%220%22)%3A%20%7Bdag.Node(%22gato%22%2C%20%221%22)%3A%20%5B%22siesta%22%2C%20%22siesta%22%5D%2C%20%22yo%22%3A%20dag.Node(%22siesta%22%2C%222%22)%7D%7D%0A%20%20%20%20errors1%20%3D%20%5B(%221%22%2C%20%220%22%2C%20%7B%7D)%5D%0A%20%20%20%20mo.vstack(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.hstack(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.Html(dag.from_function_tree(tree1%2C%20errors1))%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.md(r%22%22%22%23%20Un%20DAG%20(Grafo%20Ac%C3%ADclico%20Dirigido)%0A%20%20%20%20Ayuda%20m%C3%A1s%20con%20el%20pensamiento.%0A%0A%20%20%20%20%60%60%60python%0A%20%20%20%20async%20def%20siesta_async()%3A%0A%20%20%20%20%20%20%20%20await%20asyncio.sleep(1)%0A%0A%20%20%20%20async%20def%20gato_async()%3A%0A%20%20%20%20%20%20%20%20await%20siesta_async()%0A%20%20%20%20%20%20%20%20await%20siesta_async()%0A%20%20%20%20%20%20%20%20raise%20RuntimeError(%22gato%20bravo!%22)%20%23%20%3C---%0A%20%20%20%20%20%20%20%20print(%22miau%22)%0A%0A%20%20%20%20async%20def%20yo_async()%3A%0A%20%20%20%20%20%20%20%20await%20siesta_async()%0A%20%20%20%20%20%20%20%20print(%22buen%20d%C3%ADa%22)%0A%0A%20%20%20%20await%20asyncio.gather(gato_async()%2C%20yo_async())%0A%20%20%20%20%60%60%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20justify%3D%22start%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20align%3D%22center%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20gap%3D3%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.md(%0A%20%20%20%20%22%22%22%3E%20%C2%BFY%20de%20d%C3%B3nde%20vienen%20los%20errores%3F%20Normalmente%20desde%20abajo.%20Pero%20con%20async%2Fawait%2C%20no.%20Vienen%20de%20todos%20lados.%20Tambi%C3%A9n%2C%20no%20vemos%20toda%20la%20misma%20informaci%C3%B3n.%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20align%3D%22center%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%20(tree1%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20try_16(mo)%3A%0A%20%20%20%20mo.vstack(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.hstack(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%60%60%60python%0A%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20await%20asyncio.gather(%0A%20%20%20%20%20%20%20%20%20%20%20%20gato_async()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20yo_async()%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20except%20RuntimeError%3A%0A%20%20%20%20%20%20%20%20...%20%23%20haz%20algo%20con%20los%20errores%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20...%20%23%20si%20no%20hay%20errores!%20tambi%C3%A9n%20parte%20de%20la%20familia%0A%20%20%20%20finally%3A%0A%20%20%20%20%20%20%20%20...%20%23%20haz%20algo%20en%20toda%20situaci%C3%B3n%0A%20%20%20%20%60%60%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20justify%3D%22start%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20align%3D%22center%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20gap%3D3%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%3E%20Pero%20normalmente%20tenemos%20que%20medir%2C%20proporcionar%20el%20riesgo%20de%20error.%20Y%20si%20es%20riesgo%2C%20hacemos%20envoltura%20de%20try%2Fawait.%20%C2%BFPero%20qu%C3%A9%20peligro%20hay%20en%20un%20gato%20dormido%3F%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20align%3D%22center%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20timeout_17(dag%2C%20mo%2C%20tree1)%3A%0A%20%20%20%20tree2%20%3D%20%7Bdag.Node(%22timeout%22%2C%20%22-1%22)%3A%20tree1%7D%0A%20%20%20%20errors2%20%3D%20%5B%0A%20%20%20%20%20%20%20%20(%22-1%22%2C%20%221%22%2C%20%7B%7D)%2C%0A%20%20%20%20%20%20%20%20(%22-1%22%2C%20%222%22%2C%20%7B%7D)%2C%0A%20%20%20%20%5D%0A%0A%20%20%20%20mo.vstack(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.hstack(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.Html(dag.from_function_tree(tree2%2Cerrors2))%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%60%60%60python%0A%20%20%20%20%23%20python%20v3.11%0A%20%20%20%20async%20with%20asyncio.timeout(0.5)%3A%0A%20%20%20%20%20%20%20%20await%20una_api.gato_y_yo()%0A%20%20%20%20%60%60%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20justify%3D%22start%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20align%3D%22center%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20gap%3D3%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%3E%20Si%20nosotros%20creamos%20un%20API%2C%20los%20usuarios%20pueden%20cancelar%20nuestras%20tareas%20sin%20permiso.%20%C2%BFQu%C3%A9%20hacemos%20con%20los%20errores%3F%20%C2%BFCancelar%3F%20%C2%BFCapturarlos%20para%20crear%20uno%20solo%3F%20En%20este%20caso%2C%20se%20cancela%20todo.%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20align%3D%22center%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.function%0Aasync%20def%20co_mal_impar(i)%3A%0A%20%20%20%20if%20i%20in%20(0%2C%202%2C%204%2C%206%2C%208%2C%2010)%3A%0A%20%20%20%20%20%20%20%20return%20i%0A%20%20%20%20raise%20ValueError(f%22Error%3A%20%7Bstr(i)%7D%20es%20impar%22)%0A%0A%0A%40app.cell%0Aasync%20def%20ret_exc_19(asyncio%2C%20pprint)%3A%0A%20%20%20%20_t%20%3D%20%5Bco_mal_impar(i)%20for%20i%20in%20range(10)%5D%0A%20%20%20%20_r%20%3D%20await%20asyncio.gather(*_t%2C%20return_exceptions%3DTrue)%0A%0A%20%20%20%20%23%20Todo%20va%20a%20seguir%20hasta%20el%20fin%2C%20no%20hay%20cancelaci%C3%B3n.%20Es%20lo%20contrario%20de%20arriba.%0A%0A%20%20%20%20print(%22%22)%0A%20%20%20%20print(%22Resultado%3A%22)%0A%20%20%20%20print(%22%22)%0A%20%20%20%20pprint.pp(_r)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20rest_tree_20(Path%2C%20dag%2C%20mo)%3A%0A%20%20%20%20_node%20%3D%20dag.Node(%22gather%22%2C%20%221%22)%0A%0A%20%20%20%20tree3%20%3D%20%7B%22iniciar%22%3A%20%5B%7B%22REST%22%3A%20_node%7D%20for%20i%20in%20range(5)%5D%7D%0A%20%20%20%20errors3%20%3D%20%5B%5D%0A%0A%20%20%20%20mo.vstack(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%5Bgeopozo%2Fgithub-helper%5D(https%3A%2F%2Fwww.github.com%2Fgeopozo%2Fgithub-helper)%22%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.Html(dag.from_function_tree(tree3%2C%20errors3))%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.image(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Path(%22public%2Fgh_helper_screenshot.png%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%3E%20C%C3%B3digo%20abierto.%20Mucho%20llamadas%20de%20rest.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Paralelo%20por%20utilizar%20otros%20servidores.%20Microservicios.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Hemos%20visto%20cancelar%20nada%20y%20cancelar%20todo.%20'Y%20hay%20m%C3%A1s%3F%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20align%3D%22center%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Aasync%20def%20a_mano_21(asyncio)%3A%0A%20%20%20%20async%20def%20gato_y_yo_gather()%3A%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_t%20%3D%20%5Basyncio.create_task(co_mal_impar(i))%20for%20i%20in%20range(3)%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20resultados%20%3D%20await%20asyncio.gather(*_t)%20%23%20solo%20con%20tareas!%0A%20%20%20%20%20%20%20%20except%20Exception%20as%20e%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20t%20in%20_t%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20t.cancel()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20Tambi%C3%A9n%20se%20pudo%20cancelar%20el%20grupo%20para%20lograr%20el%20mismo%20efecto.%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20raise%20e%0A%20%20%20%20%20%20%20%20%20%20%20%20print(e)%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20resultados%0A%0A%20%20%20%20await%20gato_y_yo_gather()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Aasync%20def%20tg_22(asyncio)%3A%0A%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20async%20with%20asyncio.TaskGroup()%20as%20_tg%3A%20%23%20Python%203.11%20%23%20es%20bueno%20para%20envolver%0A%20%20%20%20%20%20%20%20%20%20%20%20_s%20%3D%20_tg.create_task(asyncio.sleep(1))%0A%20%20%20%20%20%20%20%20%20%20%20%20_g%20%3D%20asyncio.create_task(asyncio.sleep(10))%0A%20%20%20%20%20%20%20%20%20%20%20%20_tg.create_task(co_mal_impar(1))%0A%20%20%20%20%20%20%20%20%20%20%20%20_tg.create_task(co_mal_impar(3))%0A%0A%20%20%20%20finally%3A%0A%20%20%20%20%20%20%20%20print(f%22Sleep%20cancelado%3A%20%7B_s.cancelled()%7D%22)%0A%20%20%20%20%20%20%20%20print(f%22Sleep%20global%20cancelado%3A%20%7B_g.cancelled()%7D%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Aasync%20def%20e_group_23(asyncio)%3A%0A%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20async%20with%20asyncio.TaskGroup()%20as%20_tg%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_s%20%3D%20_tg.create_task(asyncio.sleep(1))%0A%20%20%20%20%20%20%20%20%20%20%20%20_tg.create_task(co_mal_impar(1))%0A%20%20%20%20%20%20%20%20%20%20%20%20_tg.create_task(co_mal_impar(3))%0A%20%20%20%20except*%20ValueError%20as%20e%3A%0A%20%20%20%20%20%20%20%20print(%22Errores%20esperados%20dentro%20del%20grupo.%22)%0A%20%20%20%20finally%3A%0A%20%20%20%20%20%20%20%20print(f%22Sleep%20cancelado%3A%20%7B_s.cancelled()%7D%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20thread_24()%3A%0A%20%20%20%20%23%20con%20no-GIL%0A%20%20%20%20import%20sys%3B%20print(sys._is_gil_enabled())%20%23%20PEP%20703%0A%20%20%20%20%23%20no%20todo%20funciona%20(no%20hagas%20conversiones)%0A%0A%0A%20%20%20%20from%20threading%20import%20Thread%0A%0A%20%20%20%20%23%20shared%20state%0A%20%20%20%20counter%20%3D%200%0A%0A%20%20%20%20def%20hilo()%3A%0A%20%20%20%20%20%20%20%20global%20counter%0A%20%20%20%20%20%20%20%20for%20_%20in%20range(10_000_000)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20counter%20%2B%3D%201%0A%0A%20%20%20%20if%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%20%20%20%20_t1%20%3D%20Thread(target%20%3D%20hilo)%0A%20%20%20%20%20%20%20%20_t2%20%3D%20Thread(target%20%3D%20hilo)%0A%20%20%20%20%20%20%20%20_t1.start()%0A%20%20%20%20%20%20%20%20_t2.start()%0A%20%20%20%20%20%20%20%20_t1.join()%0A%20%20%20%20%20%20%20%20_t2.join()%0A%0A%20%20%20%20%20%20%20%20print(counter)%20%20%23%20%E2%86%92%20Final%20counter%20value%3A%202000%0A%20%20%20%20return%20(Thread%2C)%0A%0A%0A%40app.cell%0Adef%20thread_25(Thread)%3A%0A%20%20%20%20%23%20con%20no-GIL%2C%20tienes%20que%20hacer%20todo%20a%20mano.%0A%20%20%20%20from%20threading%20import%20Lock%0A%0A%20%20%20%20%23%20shared%20state%0A%20%20%20%20counter_locked%20%3D%200%0A%20%20%20%20lock%20%3D%20Lock()%0A%0A%20%20%20%20def%20hilo_locked()%3A%0A%20%20%20%20%20%20%20%20global%20counter_locked%0A%20%20%20%20%20%20%20%20for%20_%20in%20range(10_000_000)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20with%20lock%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20counter_locked%20%2B%3D%201%0A%0A%0A%20%20%20%20_t1%20%3D%20Thread(target%20%3D%20hilo_locked)%0A%20%20%20%20_t2%20%3D%20Thread(target%20%3D%20hilo_locked)%0A%20%20%20%20_t1.start()%0A%20%20%20%20_t2.start()%0A%20%20%20%20_t1.join()%0A%20%20%20%20_t2.join()%0A%0A%20%20%20%20print(counter_locked)%20%20%23%20%E2%86%92%20Final%20counter%20value%3A%202000%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
661acda77ed55b3460f7642589d6f7fbbd6e22e599f828b6903b8201dfeef325