From 9148c80d1ac0e561f75cafea657d0b1ba4626442 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sun, 4 Jan 2026 06:18:50 -0800 Subject: [PATCH] Update readme - Added x2 scale logo - Revised wording - Added new addons --- README.md | 44 +++++++++++++++++++++------------------- images/logo-full-x2.png | Bin 0 -> 23129 bytes typings/xterm.d.ts | 2 -- 3 files changed, 23 insertions(+), 23 deletions(-) create mode 100644 images/logo-full-x2.png diff --git a/README.md b/README.md index 4ff46aa67..e183bb563 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,29 @@ -# [](https://xtermjs.org) +
-Xterm.js is a front-end component written in TypeScript that lets applications bring fully-featured terminals to their users in the browser. It's used by popular projects such as VS Code, Hyper and Theia. +Xterm.js is a frontend component that enables applications to bring fully-featured terminals to their users in the browser. It's used by popular projects such as [VS Code](https://code.visualstudio.com/) (and its forks), [Tabby](https://tabby.sh/) and [Hyper](https://hyper.is/). ## Features - **Terminal apps just work**: Xterm.js works with most terminal apps such as `bash`, `vim`, and `tmux`, including support for curses-based apps and mouse events. -- **Performant**: Xterm.js is *really* fast, it even includes a GPU-accelerated renderer. +- **Performant**: Xterm.js is *really* fast and includes an optional GPU-accelerated renderer. - **Rich Unicode support**: Supports CJK, emojis, and IMEs. -- **Self-contained**: Requires zero dependencies to work. -- **Accessible**: Screen reader and minimum contrast ratio support can be turned on. -- **And much more**: Links, theming, addons, well documented API, etc. +- **Self-contained**: The core library has zero dependencies. +- **Accessible**: Screen reader mode and minimum contrast ratio support can be turned on. +- **And much more**: Links, theming, custom glyphs, addons, well documented API, etc. ## What xterm.js is not - Xterm.js is not a terminal application that you can download and use on your computer. -- Xterm.js is not `bash`. Xterm.js can be connected to processes like `bash` and let you interact with them (provide input, receive output). +- Xterm.js is not `bash`. Xterm.js can be connected to processes like `bash` and let you interact with them (provide input, receive output) through a library like [node-pty](https://github.com/microsoft/node-pty). ## Getting Started -First, you need to install the module, we ship exclusively through [npm](https://www.npmjs.com/), so you need that installed and then add xterm.js as a dependency by running: +First, you need to install the module. We ship exclusively through [npm](https://www.npmjs.com), so you need that installed and then add [@xterm/xterm](https://www.npmjs.com/package/@xterm/xterm) as a dependency by running: ```bash -npm install @xterm/xterm +npm install --save @xterm/xterm ``` To start using xterm.js on your browser, add the `xterm.js` and `xterm.css` to the head of your HTML page. Then create a `` onto which xterm can attach itself. Finally, instantiate the `Terminal` object and then call the `open` function with the DOM object of the `div`. @@ -54,12 +56,10 @@ import { Terminal } from '@xterm/xterm'; ### Addons -⚠️ *This section describes the new addon format introduced in v3.14.0, see [here](https://github.com/xtermjs/xterm.js/blob/3.14.2/README.md#addons) for the instructions on the old format* - Addons are separate modules that extend the `Terminal` by building on the [xterm.js API](https://github.com/xtermjs/xterm.js/blob/master/typings/xterm.d.ts). To use an addon, you first need to install it in your project: ```bash -npm i -S @xterm/addon-web-links +npm install --save @xterm/addon-web-links ``` Then import the addon, instantiate it and call `Terminal.loadAddon`: @@ -80,33 +80,35 @@ The xterm.js team maintains the following addons, but anyone can build them: - [`@xterm/addon-clipboard`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-clipboard): Access the browser's clipboard - [`@xterm/addon-fit`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-fit): Fits the terminal to the containing element - [`@xterm/addon-image`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-image): Adds image support +- [`@xterm/addon-ligatures`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-ligatures): Enables rendering of ligatures +- [`@xterm/addon-progress`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-progress): Adds support for the progress API (`OSC 9;4`) - [`@xterm/addon-search`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-search): Adds search functionality -- [`@xterm/addon-serialize`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-serialize): Serializes the terminal's buffer to a VT sequences or HTML +- [`@xterm/addon-serialize`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-serialize): Serializes the terminal's buffer to VT sequences or HTML +- [`@xterm/addon-unicode-graphemes`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-unicode-graphemes): Enhanced unicode support including grapheme clustering (experimental) - [`@xterm/addon-unicode11`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-unicode11): Updates character widths to their unicode11 values +- [`@xterm/addon-web-fonts`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-web-fonts): Easily integrate web fonts - [`@xterm/addon-web-links`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-web-links): Adds web link detection and interaction - [`@xterm/addon-webgl`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-webgl): Renders xterm.js using a `canvas` element's webgl2 context ## Browser Support -Since xterm.js is typically implemented as a developer tool, only modern browsers are supported officially. Specifically the latest versions of *Chrome*, *Edge*, *Firefox*, and *Safari*. - -Xterm.js works seamlessly in [Electron](https://electronjs.org/) apps and may even work on earlier versions of the browsers. These are the versions we strive to keep working. +Since xterm.js is typically implemented as a developer tool, generally only modern evergreen browsers are supported officially. Specifically the latest versions of *Chrome*, *Edge*, *Firefox*, and *Safari*. Xterm.js also works seamlessly in [Electron](https://electronjs.org/) apps and may even work on earlier versions of the browsers. These are the versions we strive to keep working. ### Node.js Support -We also publish [`xterm-headless`](https://www.npmjs.com/package/xterm-headless) which is a stripped down version of xterm.js that runs in Node.js. An example use case for this is to keep track of a terminal's state where the process is running and using the serialize addon so it can get all state restored upon reconnection. +We also publish [`xterm-headless`](https://www.npmjs.com/package/xterm-headless) which is a stripped down version of xterm.js that runs headless in Node.js. An example use case for this is to keep track of a terminal's state where the process is running and using the [serialize addon](https://www.npmjs.com/package/@xterm/addon-serialize) so it can get all state restored upon reconnection. ## API The full API for xterm.js is contained within the [TypeScript declaration file](https://github.com/xtermjs/xterm.js/blob/master/typings/xterm.d.ts), use the branch/tag picker in GitHub (`w`) to navigate to the correct version of the API. -Note that some APIs are marked *experimental*, these are added to enable experimentation with new ideas without committing to support it like a normal [semver](https://semver.org/) API. Note that these APIs can change radically between versions, so be sure to read release notes if you plan on using experimental APIs. +Some APIs may be marked with *experimental*, these are added to enable experimentation with new ideas without committing to support it like a normal [semver](https://semver.org/) API. Note that these APIs can change radically between versions, so be sure to read release notes if you plan on using experimental APIs. ## Releases -Xterm.js follows a monthly release cycle roughly. +Stable releases are done on an as needed basis, beta releases are continuously published off the `master` branch and this is what the principal implementation VS Code uses. Generally the beta builds are quite stable but can potentially contain breaking changes. -All current and past releases are available on this repo's [Releases page](https://github.com/sourcelair/xterm.js/releases), you can view the [high-level roadmap on the wiki](https://github.com/xtermjs/xterm.js/wiki/Roadmap) and see what we're working on now by looking through [Milestones](https://github.com/sourcelair/xterm.js/milestones). +All current and past releases are available on this repo's [releases page](https://github.com/sourcelair/xterm.js/releases), you can see what's planned for upcoming releases looking through the repository [milestones](https://github.com/sourcelair/xterm.js/milestones). ### Beta builds @@ -238,6 +240,6 @@ Do you use xterm.js in your application as well? Please [open a Pull Request](ht If you contribute code to this project, you implicitly allow your code to be distributed under the MIT license. You are also implicitly verifying that all code is your original work. -Copyright (c) 2017-2022, [The xterm.js authors](https://github.com/xtermjs/xterm.js/graphs/contributors) (MIT License)n)L5^vr1*FLb zE|s!1a!T~_eH9>ppT{+%T;?WevcNwQ3@SjP$aWp0A_)RSy^E6r1h94`OK0}* z9}fjxheQE4(!!U_9S@7ov{WMOXu#VM211f1)Bat{tsc~Q&TI9L0AVdGz(TJIn7BzO zw>Vp9{;m|m2zf@jdnq1J79`GtnEIEohqvCa%xF%BV$e~}t#t}W@dW|LzmfK78pxK! zi(8(c5v3v`=8cgCp$IBs(&0NT$$#~h=}uB`VQCJx+--?yXwO?cAhG-!?WCvztibV( z==tAZ#_=9h2-xDhf&g$hMLDHdU@e_$ri)}in0cE>B=*NL28~GysFqmaR4ah#+`3~! z%OMYD(S-;SKINs&B&-R<3ZZ*3KS1;PaozKGH6?h @BWoiLgc*%D(ND6o59*22-0dKz4T{M4$?-d&Dz!YXT@n=z+OGVt7HkA zK~l)-{yt+(l_L}5iAv&*$5$~%85(c{kBv_a3lmfiN+q47KKrGVOq;z+68~3Bn?OL! znSfrtvvX_TZOJ_QrSe8hC}>{muf+~40~cPaoz#4$DwlgL)n^Y)-;YTF&DX~eq%^oq zkh0`UuIV2QSkW$UogJ@^Bn8m@tusecqIyk>svK#IbDOZ)j=qStF=p=gKyUzoS|aRO zvU|Eh;#F$}_|k=sIiy{h86R)`&0H}i#0msoSyJMN|7);&`vP0DMqQc+aUaYdg9ee4 zGTj80i&2KClJBZlUha+Wp4Za+M7Sinw-28DiQ*7_(mG~9tFKEyR_DArf4u`dT=Kl~ zbwI{Wt?V-;0UK4T21EhkLSjf#E-lSnKRdq`8Nn;>F{A%6nOu^KfT=ZTaO^>v428}- z_r>3v{3hD%Ee%*Vn2cGLpm!pYZmK~}5=zS#9E^~rJ-|hDGJ6R(bojoG{hv&htP+3& zjFOt9{`?<%%?Jv9=G_TAwO>lj`8QERK2r%ulhQtY#vul2()lO!Fazq6J$FIuk8uIp z-DNO)4QRFsR0>%26Gnn6lr-}Q{@p;1_)i3@XE1ZQO!~vGTid{i_NCIJ=Y7T;C@VFB zH%;*nuGHu5K^WnR&TLkoh{%&8h81E&z8jT6Fx)S4O+D%; OMhr4Yj}nJ`?FF|Jm4v(ae|f0cXr6XdY$?gq1!ismhtei|8q1NrkBY z-Efe$%N;n>BqhP;?lcqvOBE%icK^3J>b={N=0(>9=0Gv@k`W^Dl{qcIE?75v@Bh6i z;N}hPgRlkkYhj@IbwCw&m*B-W 5@cN8+WZ1ZW@z@mD-Q?s`;j zmnOW7LiRuErL@!wh*hLrEBxyLOJ#s*_}l%6ICG6ZKax!|CGFe*h0gP9aN&HVC%ZK> z%Fvdgf3- `lMpwvyPg2Y;!BKG`lInPwa0ivsxOxFobw7sof&JW zJtJUQK6obSe=Y`i%$OtQ;A*32jAtCdeWrNr0QZ?|w^;huW*h?1EnA+RfHGfn0hdy# z_aMY`YTdYdeqk{(`67B}_Vt-Jp6wX`MD3M}ORi!w`dp8>aQbH2-oijYY!Dz={C{Pf zzBw2MYUVws;lho??^;%BXji*~W3!swYxe(>WC)T>(LUAUK +sSY_k}-#6Zr2Y<_S3;vHe01KsDU7H5^)r{SY$J+~~!NAna z8 xo{bX!$syyCvwF!iTM%YXeeG7B)p z))wx6^kK#ac}Kog#)n%r$Xb)Oy8YEa(A2s8MSa1fP91zJiEaGg1g|59Hv+$52Lb^o z0OXhW#08avdJE{cWBgO98hmH#D1k?Bzc%l54HlOr)4 __KHtgFj!1b`ICD3?}W)F}vLw5noURc+E6RsE&!%t~qG z*378|9o1-6asEARS07nS@gGTr-ck-}7(&_iM~g#;__$uj$@-Ju#E#2nRZcz2Z+) zD~-3}@gLu>1GOD1%}TeXEcCkXf9hc?TBe6@7Q8yTtRMHrUcqOZJt-aJ*|UD)q)Y`w zs6e134|&cJk2iYSji?2JNq6=z5CYFEdr7I~DmP4}t;>uq-r#lnaiqzZY(uEbYarOL z0`)r0dB9F$G+!3=X=?<&O-h?j(6?PeS^ Vxok8aKYz8$RXI~#G-`>_hY3o zivkGiwZN{VZ-k~4Tf($NRD+I~=JIMo1+SI)Z4Wl=Uy6zS>%t%wvIs%`!J-|c=?@WU zsqM{WJRVQ=2^n&U7L-{62!FZmtYly(zW->9!TM{oKwQo9IS;fQxrWos{N&|- LSRxMZV(5%MYoZF)4BC8MFk~&mKlu~(R)&P4?<+|RdzqF ztrm35{o~W19 {vQ|wIb2!_UfyX S>hVs+S?Bqdns V6e6@l)iMQ_)ybN?b`8Zu@^eC55YbQ* z61_#&fi}`V3C@|MM!Nt!7}libAL8-KB=Epn`XEp(RaCmvVG1ydK!UjZEGb*5=U_)r z`D^><*XR1sabe>?Aq>6P>S`gP^5ru4PsWLnhIp4~ #ZbwCX|m>2iUKHdNvWqx@=rhV-{m{0KWq z8XaJCu`ryx0Y^O8e(p~&1a7xt;&aeT(y#vlTmmQ|zEtdFgq8*DYsT1XXZATo72{ZZ zt2P`y-;83vGtR~gr!eTh*TVXb&k>Q-6Ks0N1?V=#7YbS)Ql)HlYa(W~dzO}RE?XQ- zxT;BTO?__uZ)O|53y2ovPEb}CbJv-&66=N R-oat2p4;Ic=c6fEnoz&L}8Kp4B>o3bHgdf zMN!f?hRn0>f)J%RdI0NjFp)mX$}$a9D NGHs58*{>io@ zjJ21bA7;Ir!)uY}8EpAs27n{Boc~V?3>5E_OV$vZ&OXaZC-wU6Ke~U{HzFaBXPtg; zHj;?s1}P!%oQZtM2p~TTEREP6prAM*sl)a#M!ey#Krq0Q26+Lce!6G!gl^Je5t>6! zLV1e=#Q0ZHF*g8Dyu`127QVNhzb4&t=(2PIzTgx2I$0Xh+S>Z08I|PgzqaM#wHCJf zdr-Dfdsk&50YCh7ir>ju7Ik+Sn-HY3dXa`E-S@a~k!Ea)h1cGJVY1QcwsH8b^C8%0 zTw$Wbs6lR`C~tXPWF!|>ZNztq{Qdj)&RG_^W@~NO=tZ+>Q6`uVX3Jluz75|OM6fqx zKD&pnjH=AMJ=8a~4M*)duUEZd4W6k@q;f}`YZz(6mVhgPD&QRn604tqjk-sj)IaK? z?sbIF!l&^isUYs) 0>^NS`fagU10$@xTi^!0}T@@v7Hkgmg5{%dxx;QP*5 zYYw$no|Po?hY0%L9&ehb=X5DWA{Z+e>oTxceNrl1z-F+SBQ9_DVa(#Pi%k{VR+A!5 zI`rH%db`%V8sX9uL#hf)rL zoh>O2hGkr;vrJ(BHP0V@>kQyxnH4slNb&8xhfv0~Mf6P`tH2%0qH%l$Dv3`TGigC% zYd%qGlT}^0Z#X@1`gINiV#khqsc#z=H|g&CaJs}MYOFVRx*?(y@w?n2Pak%;gXD-H z{TJ%sH@<%llt1$EEs!w<*KQ@H4 lngD&?P8D+{C|Zz#YC= zx`sMwKdRlYGC1YJ`* t0_%w+_$=B&*EfSVcsreoT1WlGAPYrFO^Ag zQ!hMOFQiL|x6l5Gv_129V49~bTz2qWs^X93VffL>!rf_`l`_@Dp5^DjrBdO>Dl|_75aa osl$eIxjFF z6Ny1zVYO%vtJm60FTA~Fu~DzP^y34?{Ye8BK738hNbpy`sB-GGhYwz0R8B2O4#P0$ zn+^t}SF8++{ShZm1K&3S2U5K9Foo7CW7H-aR4?V0A|tvlX!PSn3f8kUGOT1SfodM# zf%vlPzk!J9MBg$}^N&X7 lb>^W?}f9n`Vj-uH>&`1-%HZ5gcLx|&N z(;X^K`eZaTt{>M%WxX+NWHrSd+fnPV#W_iDG^87<-tB0VxiM DRN=1_RjBL8z?oc zUj;u_i|&M(%0N^xmS3H`Z?AFik|2BGY`w?%Cf)d&sP$XCHj}z91QCO8z;b1(Y-vHn zP_v5^26l;U>)7g%D1)zZE4e^roTkubOs{eCZKT9U_U-%X^OvDouITN(VrY0iwn8jK zFL+{e`(;_C-I!PHJNo)Z?Ed_z*;bq(6W;#$?%z;`Ji(Lc?4 WohvjSBlPhpAs=^IsWe4fJeMJsDWObLfNp0YC&1Z!8II#|OJH0#w58 z^NOX_mo8 jTT3)he}mSWsP*oV;u2BgGo& z_@`H%@utm5?a4|IfhpHlF%HPvc^dGrtYt`bYEtY=yUj8eggQSE;<*h4*(YZ5GF}X_ z$IlgaO*L|RW{f;8BLIi=&iq;vbp9C(7AFe+TWv+jZnbI-RA^LdJIf# eLL%!XOIUS2n@fx@tAGo}+b(L~Sa#I#H-)$+&KlGXY=2;N@95 -Dtx-J#dMNPuLa<^#kPPGpXSoyj-p0j6|tElkC! z(NJYZ%nla#AO?B<-7iFV@?x$u`?+*$Z1cOG2#qMyn+m!rjWQ7*A8#N7V8%WXaCU>6 zF+#*x?3Y0cnaoxvws!~X4L+{j$0hU0ajWF4=M4)9YK2}GrUBq`;l}qc_j!Vs(x@oG zK3=Fh#|#8QzV27!rQyk16_~*BF8%lq-tfz)-?q8Bqvl2h8sy>J+#8DCTo2nr!0|5* zD?=XO(``9-gC)}?4&)uxr%h|b7ODG1h+!9`%yLgmZ?0Tb8VbJbY6vv|R}0HuNN@CU zsr7L>LP6i0lG*j@BTW&9Ckx$2b)Kg;G9w$4-jUz%k15j2-pcQcrmR*5X*9v~i|fm~ zPin&xoElbzu%7{-S=~v)w9Kb8wZz`vyz`q9_)>NHXXNxc>Noo4`0c_{G4aIpKK8rG z3kY=3E!-$_a`z@s8AB3g3Bx_0Jb-Hg_!^nT>=+-G!s9dwKqKLlves&unG`}!wKq}2 z5HZ*BdDc6#_r{wH0{7($6Ko3%SiwFHIhbYMTBpM|x!PWuI8XQe@UF?p$tYgKnqzxQ z%Pm~OkG0OCv1xtp7T09!3)~^eG@)G $uJxnC5`&Ao zB;6668-CdI$=$FIp{pB#Xdwq&Od?aNxO->RZP)aJ&>@@gQ~^KIm8;G`qIXKgO}M;C z$88)n`syr9F>Z!b#K--E1)z4XfG >fsnMB8}TxUaihgGia5?O&rt>2 zjFEFa{ObH;8*9sBu|s0dilD+!q?QkjC>n(MuA>)=iTM6wAcxNob37P2u#(%LXWDZ= z6_0u+=JmNBO(H#ck}jD%Z#V=lb3JM3N41;xW^8V6 raNxO zDnl{uby+lQpw=IgHkIu&mIzI!`jynl)LJ6fdUWKuw49x)2rt^kp73qf_BkL?F(=@I z^b_d=3%ud}=Sl9`NW7bA1 469;T+A?Gk zX!(&ujWu&CeW~m-U-T^E@5wDl7bmmmtgSky@?~J1wQ){08Tc~Y;M7NZ(BqX;=|st7 z=J5rjyF{?hC-xy>>4 vSg`9u2>_x=#D>w1%$c};bDnoa=zoRXclxVJ&4WH{+C(eD3pY$m&pr~{z(N)MO zYuyoSP)7~%fDq^3EzFnWtE qj?>W`a(UZ&of^3m z?l)y!wAp-GQ=5;Cu5p|@YLmfkVFP85?8*1XCu~6?H3;Jye%1W${3sf&*n1_kufJ#* zV_ExTqHhhEXqau=o3o_YO329g#ijptFKY=ELN=tEoh*Dg$L`Y&fHs1DirHI*TG;jY z8JIM<2aVdS_ugbRSeY-j-{R$~vv1ZT>zzA~^&nuo9lH87)1qP2 fR4I`x zy?t!8{2o_}@PB$hKB^i>WU&?!Aj3^sHU!V5crx91!iUB19aI@Q*7HxhYUQN$8cpHx z&Si XSOJieEK$SfEs9qIQ`e1^p aL@fD!C>&1VgF zZ|w&sT(+R{XGVL9yPf{z8Ap?1#Y8eqZQ7a@Ql)cVp+rju;u-gv4`A1Q(=>o7g-q7R zc>v)2$anGkqf9i3m9P2nocXOIcxPp0g$(oOEQ-slUNqI@* ^_6-$}_oHi+e;%8fj|RZ+G1O;Qcei8Co!wM$$Wdo>WdCa{vNg zYNj#Wf @ ^+0 }@(ey#}nUGFifr{`jK$HxD&fDMQ!PQb`5(=0|Vn`#IzoqU-dcVSO6fXg<;w zib-r>Y${K}w%5kXFyeMy1jG5#+N`in>i~|PTQpGJs0AuhX190vJz;)p8b>nM6Bv$$ z-aUWOK|=!(9MQ!nUzU|xcK+m+U1-aG;Zf^{=5Oca7V1y$l}okxqAp3{hNqvFq&fLe z3Km~_ZqsyiypHF&GPBb~Z;~#UJsQbWVyDncQEj{hHZ*iQ-F-0aUq$&Y&^^PRGUpLT zN#G!&Z!tTfFC@Yq(JZ}k9(Knk%y=Tofo-N~H9@KZm-&(aGFtl%83Q8>0Q2mai2cb) zt6+v*LhiM7l?4?@mPDz1uHx(O3Cu^wuGM;%3%ykREp}7%7?L28FMIs^d*^M57zWQg zifD=yQ0cIUPj^$}aHh!D83fau)KQ? Be6uFM=3 z+^4Cbt}er6eiJW7X{VaUw)l;LWPsuIIxk_s=SHDucOIrM7+rTddbxp^{&H6c5XBT2 zY)fB`+d?BBapCGi>S!RnR0qv)qrh)s8;`#=Nf{Q2)HE>dH9z3$9} UIcdccGu&!NwMzRa_D#qmzI!dc)nRFLfY&3E_C5kq}k!uNJr!~?)Fdl zU)*DRo0IrWn^htr_u0w!J-@{2+?ak_5DBoTlFyM)KBni0iN2ROd<2Y9*S`teC%tlo zQq?(;>F$&D{xIJn8Ld;xkD}Wpn_vYj<4IU nIyaU8%1u62Um?rvGm9(YQj~J gCkD&rl-cG`d<)gP3a#bE$8# zJc{&<1_Y*D+A9y!adkeUt6U{FrR|DsIXF0=Lfba^gnF#$>vLw9Hn`d3zso9LtWLL< z%}@CL3gg(+G~Wc;Tz#oxjC?1RDJn~$!+-Tc&7t2KF)-l2k;xs9an<76s-DfoZ=YYQ zIx8>EtjG+pK%Ska?aH?m|HQ6(2I%g^><56nNh6;AK3#X7#g(8{Le$DSuGyVHcZTO_ z$0YS{Q(nlvS;OFQaeQ*@ UwFa7;)nld1LM*;6*Tx`!G-S`?(F4trJCt(hgLbrrDCD z51eKPopf|`bm@{7f7 Q|XM%{Mh(W2d(<4u0P<`YnPd3lu) z>F+BFiknD)2Z>6DTIB(>8aZOSt!{~}-~2_4hoMhz?9)4LH!d2Qy=yG#`hJ6=G6y*p zO{p*DFgA<(g~*aSUbMN!v`82gSKcgNb@~buoqyXmWzstP6DPlFgL}tNBTeGlp9zRT z&dA#vqmnypD>#27;O?r``J-c_Ypubk_k$9L!0kZ<0uDNTnjwm|sN+}gt8-f)_WAx? zU6I#m7?*Mx7ao%>o E<_n`0!!f9V^)fbd(ZzGdn}lW~FhCA6f{E$w+Ro+Ak 1~YBkSWm4ji&H5D!+0Q%h7<98_Av%FgrW$J#Mb$(xs z@%)9sv1Y(rao(0E`7ZTtRZRN4#=9@ii5n06aNLSp7wY4qyF vfQ`K7B%tD2tx&4p;I_`I&mwF=82t?MWpXQWdxul;(eWTuor|fSZ1tc?TUT)a z)_)I|>(ldHev<&yQ*O~cb9B hjj7ZsC6l4 z3oy#^r#cb0yG<*O)+aiw`zg3Ng(i$jdpq5d$pHPvun|+Qu%ouOeG;P9> Q&pNrEZM9gWH zL^*VQe+C5Ls`D=__J6e4WBZ*OV*~ds=MRr+7ts1V3T>}eGhS+^z`MQOH3oDn{n%6q zqsXVZ0aPoDtOt`*=GzqR0q(pdvkaSiTg(8&-Qr!#EAx7&Ur2A;a6JvyJoC^TU|XBl z+Ufz&V#0m=%|U%)&Xt4yr~ud>LR5?&1SmV5tf3O#p(4ADH+N$aJsfeSP`F;% H6Lv&r8S}Izp36@_qhHM3{{zE+r#L4+*Iu;Z*eVz-Wq3Qbq4`VO;(U~5@od (;ho8s)L)&3L!n2@n1*ou+AksE?IFH}`LzdofMdzo z)VZAieb7x{u)#(4%QV)>rSpN4NhUzSSh>7T4EcCLRb8D$FfV5Kr{MiRr`F~b@W!pZ zDAD$*zwGq%+!251)BMuG&C+YBKI*dFFX|gK_u2OG!}
`YgZH3|kQ$0z!H%c# z%%nd6i)w#5ahxiCLmu`UIIIt8@nj>$x6}I1+A9oSpWX8uzXz?-n2Rj_2Mgft;Lfmk z%r`PEJ2t%Tkd mvEADFJ8v*?1!C8aqq8Pbqq(%q?eho2$9Sob>elbymux_{r= zav%DU9VzYF$AF5O5xwUUBJP-Qf`({y7NR7PZ*#N@jGvc`rgM)Uu#EaYYV_7r;jVob zwJ6rqz&ymWKar%In=L8Mgh}Ite5Tl)GKdh!9y9$tX5NH;xv}ykDj^bR(cP8$mXC{y zilAlaBSqKkQS1@tHIj9@w;KidT#=Lc!(x^F(Opba!-rY|Bm^NL5f?^_j ~@;| zIn RqpC+`_ILvqeB~p&9<~mcag}VmZ(@sr*%y$+{$u^({4k`dU zAlx?BpiqN6cx~)RxVS60{fBOvVdFVmd&duM^v1CWA%D1^0viG^49N1R?MoWWy}O9+ zJ3mok3^%30qd6w8O`<#*WpBnjA>Lz#HJG`WBt|&0;pG_gf(6e!BFFHIcVSX|nn;cT znq|9A2LLv^$!RhLAb8{$Q-)ZN&u08 Or-ud=n@!4)bdD?pi*p5@h(CH#nSZFlZ z{1bHelU=7HgWX)u2DWSjQRj4Oc*qR7N;$cvG#9mEI-O(olZoU^G(OVVqQ!d&$|c&& z_&Rco^?K;8Jh~8XUXe$wx7~MloZOU|Ky<2avAhyW1q5vMPrkvz)?YRJWDC{>e_lk} zl` =guH}^7h*Uzx^Mg5CKk`s|RKY_UuP5{Yg zCl&`r=5iB`MY?wRimwH%pC?7mOT}mT^*4+l0aDq62;keqcE;z%t NUMN8FklnwBFJn4ylG9lCTxHgwCAmWhQnziB zBoB!6k w6? z^w&z#?#knzMS8(wy8TSPMCrXSS9P}RR2=$6Y(G=upvU2&Qav}RUGZXR89g-k6`&;$ z9H Qg2;=is|dJh0gM~;UB}c^SdLMWwYSBKzLPfqP38rbr11Y z1zKx*-cI!SC7sH;Tx}aDlM`4uXyoYSWWUu{8c8|MIA< _RUWB@g=@$zI zdjx8i==x|D&oSAQDyXL MvI|D68miC7)?W#>LHD8=Cy-@xkCK=G?wTDWZxJrX{jTxS1DngqxvM1I8GQ zi@jErG?J|kMyt%TVZO6J&SRb6r!fyAU}F|*>-x^&FAiU};hW0y%U0ioID940qu*b- zlc0Rgq}8`G>~l7?QB0}nBL_0r^;4Yphm%G^-4kRhcbnAZj)17>%DnDdr%U-AAE$2t zGhME=DGwdKBu56$qFfajdyf1GTj* b zuNVlQ lo6_}1XQ|*5E0WMI+CVU zu~LrhN`AAziY<+I%x=nn59#bS00znPh;HUn4iKSP&!udw#@Zqs?TRIN@Gst*B!+Ms zyAr)Fsn>F-c^z7w!Wr0t3kH}etk<(H6JFGS=#$MN;(uBGG~K`1wosh#2=Ous7)^Yv zCH_F3ZQf5>EGQ+rYOgjU&PsCVVXHC2$h?vNvh6@O@Blj9OOGEOk5t7dxoV)Tx%xEr z3te+^_&cT%$iy6eLaAQi@%^ga0lz{&Q^u@&E}Jj*z0+egAZD9cL3VbGod!8hB2rM1 z?wbYDU}>kZL W!}_!0C4)CsNx zvK%Cr7obJoMH61?s=Zn4R2a|2vKdPb&<=j5maGHQkE0MKVWAm34uSNmxyjA$HYnHG zfNIQQ(wXGYy~!+MR9x?DZZ1aggZiQjFwr+6Mqr~aTg)@n;)}P7f%GsZyNRELv r zz1TmQ3_E<9wT3r)y*x;jQO{$DkUm<=4p!la-F^Im=d||CVn?@q-^ZaE!j(L)tlDpk zyNIspdfzzpDq1Yv)3t7zx9ABMj$sh#WiE6|U$MD7K90zA*gp>QOZV?_i&W0t%@o8q zxm}TjKAyUuy98VQxtn2|U0OcuMPMI&BN?9*hW1!g--59Uk9iK`hfVuQef@u1f@N^7 zX}WSf7x)DbJV`3-;sjF8aE35+EZ47rDRdY24BIxJSfC^{nMmNNeZ)?s#b=#NacMc) z$Oj#je+ST{7X_5)2oa93_jQDnq#wfcPbce=KIB_IE@2Joa|8}8U|C7SLti-$p*Z=a=$%=2*Agu~b~Zma zpY+6Qfcoyy?7J-c>1rGE$`|lQfrk%M9H{`lq{r67B?QnC5AiaY2pcm1R5K}00WNRN zJZ{!`p$8A#?1fo}8Hh>a=w2T;YVdI1nppIcwn0RKw>*VqZwlNt^Y-?c&qZVuzRKGc zppKA*Eq2QnvJ7U#uQUlb+K-Q(YI9%Sfy+#un$*}&X;iabBcTS;C%OElEMTPKiz3_o zn(Q8RXGbrb=dGQs)j2m>7E~w&i;HbFhyA`weVnKc7cW8#h#?8n#R}-J`8_uDZOrh2 zfJ@MhWjxhq^y<4rbw@Jk0%wIOeuo nK)$9i3`U9P97-0{II$WhgN$%EQ6-9G8H&B>NOqD5A$R@i}8&oTE$*? zU%DyONt&p@HB1xr8@SIwg&n|yoGIU5-d!-je=wd2GS0PN>~Q?5+bMcWgo*lBS{jd% zdy1PZfUaqdCV!i#ZuF^sJZG{(-|P9{&h?P#^6n$=+g`svy3`*ZbKycqn{ GGlA47TB+TgS`m}%pE5xpHlLD m_qcRF9 zC{A-AYu|O744=HKO5GMS_n8?P!QOx#Q8+M)B{N b&PfttGKe8yY_`2lhH6o|_%k(Lw|{kyb0yB^Y_b@^LK zewo}c0~0bdQB!)eR%CN1eG|FDn_T@B-vT>GQLauUbTYKbTtL}Q&AINR7Y9Vh;g3K@ zl%yckZWpxpDVIhJ9KsVH&X`wV!T<)$+sv&bu{Gx3FTume(2=2e(NcWN56I$=@5^Ez z@xx*wl;Bxq=Ww>`O jhL z*u4)w@12JWV}}n-#~1L!m8R2QD0E~iyft(CuyyNVt_}v+gho%4iL@Ro@TxRqoNAN` z-Ebl!>N@P)FW1mKC$m!AmS)Ud&NJ!$nS2NN+@i044i>p}OB&(}l?j&B#`K7QOL2QY zf41JhUPsuk3PU{yvX))E02bYt8{G7YprZ1AbVGW%|7lm( A!4lv>qX@7LUt_Q$MwYHn2^2r}i;y4ymhVdGu&2JQg1 T}!@$wzeNmHJ1v#MXAn4&^w{xsrQk)?X#)YyMY>|WPO z_N!TTUlMsc%BOF3%*T@`M{kP8v-Ysr{~3S< N4A->wYI5^IeHjVcmBmPof8ajy88-)~){ku&j|Gusvj!^46ZG6g4g)|tc6QpS*k z=)(4##9N}&8{085EA!W0l&z#Mq7OINz(^PF3VxRX3*_PbUwcvF0MZ%^(EHN2aJQx3 zNV^ru1j`h1PaEGCnBW;$Nsq3`5Qw=L@edX-PKV*sfy+ep8z=ZQ0&}kBCw8S26#zo> z&7%)$A!axDvAxI{VDgyH<%@0eVCFJ40+f~w?${!Z9^3Mlo6F=aQ*p(lhD(3IW$>ZD ziNf#-yrzTPSPh%{rxBmCw$qEAWbC8&j8bDcRa mEv?aO8p|@rRqnny&RsY* z-7eR9X>- bW lTCn6ISJ}?kfvOLKL_=S^>)H_fs M}J0 zgGy#jMA5T*8Z|kt5`7;68YN6iMosJ^KWEbU^?mT|8uMybo*TY_wy-R79Y#zu1z~pb63P2MD5;=Rd&89TFzm_W=Ok%f?-oh1*mK`?p zyAMGcAf9k=%Mfa!T0g}qWUKDI?9-K$Z%PJ>!3LGh4ih}Ll6WP4S1_Jo5;I)iqktli zffyC;-5F>QH&-n6vZVg*l=?bvJ_#B?-1d%|G{*x@9;Gd60P+=uL)ne0*D9b$raKyR z7JS_VxZt$`@LE3=z{3kq_jh-Pih7`K5A#nU9uNWEOwzM ePTQS)W})g2a-y6T(?Z|s1({rfSnX``{uYY^{0FfMHF91 za+2}|nOV62s&@_?^4<&h+pOBdsI&<_I)o7s+@$mP*cR%s0}SkUp8oQAY8o6t3F)P@ zpRIdSxu({vc*=lCn9bbAr&pld!Q2zv((d5_CeZZ3fD>2XeGyX5ap}_r?4b3}L&u{l zY8#>0fidoLrmMU3F!_ucv@lR|6W+! P^UnM+c;0tr5yxIP285hF8E) zoN?^OTD^D8k@+@9iCzkO)wm3@vVN0Er=tFpNV90vB)4^kYQL)m<|YzJ@i2N_u9t#~ zdjp +bToN)X!jij|3Uw JXzBBF#T_| zHH!U}&b>A5JS^f1Ma)Ycgn_OCW^o5_@!RtFi+3(N8pNY7qF=7sZf|rLeIL)C|4gEz zF}!LEI`sv=bHwU _UZnXG@|vaZnKO{|W%igc>sO_U;}l z4k30rfbqlQ_GXY+)6I lUkqg5 z2>l>(bnNpr{e`U0y@1u7GOBM3K)9DlH_QgWfNK}kz{7BpnNJ%Wh5*|+ 1(?Olwst>MT;alkeOy@~etYCRe y z>t}tV{tj pRd&g(oYP) zKw9Z(&{488PK3vM-nuP05;ymGhCPxpWy`R<;V9=}mfk0)F`}K4G288j)T)f*+<~ji zuwTV1N$YfI;2jE>N#L`j%ymcBZ_VvLutuzU)qSb^-FU2&&O lr~gQGgji&IVf$rl4=upCrd(%Ez1;HCGkUss_IO{ryn*|&*@ZrRnYuBsWV zj+932jqLvDegre6F=DVa9VmzzHQByo;>IpJKz}{nCYET iV zTixfu9vc2Uab$AMJu!Y;P^81kjISy&td+Up%P}ZU>_Z^0m2vCCGow4*kEGm-6X#(A zK1VOW2`_LHNO83`Uxo0Vp90@qGhjt;>|bti&n=p0yvW#07c-VEmE}Em)R@)ze^s1$ zJk(nhz^BR7jO7VWqGBYeq)-w?(<{3++2s*hkfrQon3NJlk)mvgk}Ztp*?H+1p&?7z zDNB>>Wvy)Q+!^Hk<1@_9?|1Jx=bqoaXZcDtI^_uvpzweIuD=2!dDxemY7%{MpOd9o z*+VyP58COd5ye zn*Qwh`j=ix2>Ene+k7XTPB(ASpcVJDcH}ZMZcLQFnQHtLt(`O(2`SU{ZG_wBn}@y~ z&>EOYNIiA(pv-*tTs>y>P8o0i`k`uUTg%B6Qyw2;Am^punZ@Y5^-t%AulvVG{-&A7 z-1+TZjD&1KX+4_mtQBOU@_e8;@w2q?E-f$6=<;9r+g4M#)khv>X%NMDLR#=oA&f$f?KRH3tXA@^r_bv}?-$2{ zbklUV@uIJ+rg%o(;ae%J06IWXvd*0#WoGPJo5cv09nWu?y^fk+>CZ8gnFCzFH}Uc} zb@gDCDFnMR;e?OUJWp|7GQ+WNtiEZs&+EyYp-E9c1)#n-Vj`RlU3P2`{@Pz^``Vn< z#kfAcnU$=;U}N|#OM>vmnU@sETG!r@<&>1X{I31fSHn;updNyeO|*F)hfA(e46iJ% z=^9*UNan`NmiyukNS73k$c)X{^bW_yih3B3V{f6(I$J1Ei92%^fhM$9J8cU0UHz?D z0R^@(*dKiKUfs97qx{m75nID|tH09UeqSn)ny?d)CpsXWk_iCRkcr!VWPS09Gdam)75S(KvapN~ju1ON>oVro|&`85Jae~Hi$l2-XUVU{8r2(XLTt*8z5KKZ` zYjmO ~Dx6`uX`=*xp^k85@J%uyuemEQD=TZGxcw=J7VE*| zGr0~2daKcE)xm0I)*fEukQm}01_iY{+l2G>eIy$QZi{xK6Z158)-CU~S9XIYsDv|qRL z9?Yr`)t{`2Yx18Np&mM^6ESqsx<+cRW7|IAq?7mDm>|@90*Jz}5LXXR)b%;;4#o2O zRfZBn TVgw*S9 zysHBdHH(V!2p6Ux){AO@bVV4u1DT%TKQcWlQaIm4-tAmAk>Y)SZtSx_f!H=+GgR&> zI`8TEZx3qYoNkPn()gerF!kUEnHfhdS)JR-uuFVRE&n)ZuI4oQb~s-|EFfqL-bOQC zdgTv!;jg>L*TnceM@wyX=2*j`)!J~RrI%>?D63ape6(u9U2|7!$?lgO4%eU1ilAK( zbzRyy` z)X%%I!hC=R`E&k4hLD8$m{VW*s)6k9PJNp{t&SR$xO#Gtd0|C}&`x^&=AnX|$gZ_= z74|25GmOW63hR76JLax=gx{y6C>H m!?g{@4z6&&x5pI+fC`)8^Fd7{D z-wiT8@&HRK@ZDhHtdC^4?{rP`0;-{XOP5zu?* $0Ie{=}Zs?LwJwafsJ)Kj(NSsG3c$0uT@jVT^56psK)RX8iu|_>)k0=ewJOU zQLBO-_U*f`J)|emaY? R5wnVU5Y)k9GxMa-S(_7O3e+XLFL7@ ze<`G7+`22ql(tncJKkv^;Hk(r_xt!pZDjkf7=CB19@sSty|~|Ei;A` U6K-L)53XNJ~UMoNSfkw?XGqaMuO%Nt8~$YhIf}PXQ2guxJRbz-rFI< z*VN3~_&G}khor>iDB~Z=?sGRI&%GLI@eJ3olxljMH5;@sc)X{K%U&XvksnU*7K8Gm z^55x~bJ}o71*5OC6s%b&Dqs7H%*7<`q+o44*$N$^G9xSu(wp8j#802#8TN4?GO}VH zJC+w~uN)mysGYyLZo0Ba&9At+z5iCKqSDEOdI6KyTjq!|QU z4QP1=-tGge0r*XBatYQ%uTd4=MGN@i@6R=CpWDK)e`LR2`hMLm zI}-V5lAe!_o6R_nPw?Co1GN#CH;t{?XR8?ami;e{2l*+Hgw3s&0H7q_AT`}ZH*;dW zVml1)|6my<`$w2H#UwfM5eXXZbJAoLM bh74*8Ark(v{6;v>m{b}Mr-QhvKo7)nCYm{r|^wm1uK z0r QQ&V~IlsGs=HL+9 ze3u8vd I=o$^Ai;EF>l&KU(BFixO4Y{#x&OOz z3^BqA -^mjM_j|MAWBlOj5 z^1VJWShRhOXCR`#BsNzX=>=NU9#a7>k i11-J0rOzY2 zCX+L2@N-@r=W>fMl>$T@j3wR7+566xm)(UF)a7+f-C>#4AVk@Amj7_CW2!{^>yV9Z zKCD!25!Ev)C=umQeCDXnjbDCK5d^1$swHC~)g;|g9HJJ)C7VoT=DCMhsved8+jyDS zAM$G&px0-LLATC!-1|qB#cHRUGX4bS;?K1c$7stY3?)uP1+ PHb8$!YbiPi0(}A8Z-7$4!poL5VahB{Sp@V%p6~7I-$7uha+|qa;BtV~ z9h~x7q{@oW7dxW?elnK(v3k`naZz^QT{ol0tQ8drkxRp%_+{@aQGsPVRNw$P@FIaW zO`JXNzzz5;2Ne3veSgNLJQngF`*(k-5V|nYu!+(wUi#PkCk)IW287o8( zeZ!^bACuS(*1s5>^iWbOGVuQXL$7tu2|1&S&QEp6Rug0`mu!OaJ112VjhWLZRy dj{0(L7=mU%p23a7XD$Rr29&7bA@4rITU zO{K>cOpe%(4O%^_G-b6=EYqX!Z@XA2We7FsIoWz40&IiY!zs%m7Q$~A3Ls?HTG=eV z%u%w|!#Bt __{$)8&Eqhz(bGEO)kPH8mdY$=;3uxgl!d{Tq(Bbx|n%bhei4NEh)*&c 0I~ zQezYg_Xu9dm4?Y-sen#}yCpveEn8ym4GCDX;ZMvpP!e0AEX%ocyG(2~Ye5swpkVMJ zCi_^3rbQ&I_{p;9hezQ&w^!J4Nxy68u^0(-6wfC?5`}AR)V5zpy=s}#A{aR-5(%4X z8nU<*fcqWAh9I^k7y;#q#>eJuOTva7imVGfF