From 2e3bd6531218b8c9c32535c035d5f82bcbaaadd9 Mon Sep 17 00:00:00 2001 From: hellno Date: Fri, 5 Jun 2026 14:43:49 +0200 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E2=8C=98K=20command=20palette=20(f?= =?UTF-8?q?uzzy=20search,=20grouped,=20keyboard-first)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A Superhuman/Linear-style command palette built on gpui-component's List + ListDelegate (the same searchable-list primitive Zed's palette uses): - Floating top-anchored panel over a soft scrim; fuzzy search with accent-highlighted matched characters; commands grouped by category with a Recent group; live shortcut chips derived from the keymap. - Commands run by dispatching real gpui actions, so palette == hotkey == menu. A small Run enum (Action | Accent) keeps the registry a clean, one-line-to-add literal. - Compact dependency-free fuzzy matcher (prefix/word-boundary/consecutive bonuses, returns match ranges for highlighting) with unit tests. - Wired via TogglePalette action + secondary-k; overlay rendered by Shell; run bridged through ListEvent (delegate stashes pending, Shell drains). New: src/command_palette.rs. Wiring: main.rs, shell.rs. Docs: README, LEARNINGS. --- README.md | 32 ++ docs/LEARNINGS.md | 61 +++ docs/screenshot-palette.png | Bin 0 -> 145032 bytes src/command_palette.rs | 816 ++++++++++++++++++++++++++++++++++++ src/main.rs | 18 +- src/shell.rs | 25 +- 6 files changed, 949 insertions(+), 3 deletions(-) create mode 100644 docs/screenshot-palette.png create mode 100644 src/command_palette.rs diff --git a/README.md b/README.md index 4fcdac2..54e10f6 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ You need a stable **Rust** toolchain (`rustup`) and: | | Feature | Where | |---|---|---| | πŸͺŸ | Native window + custom transparent title bar (traffic lights on macOS, window controls on Linux) | `main.rs`, `shell.rs` | +| ⌘ | **Command palette** (⌘K) β€” fuzzy search, grouped, keyboard-first, recents | `command_palette.rs` | | 🎨 | Dark/light theme + a live **accent picker** (6 colors) | `theme.rs` | | βš™οΈ | **Settings page** with preferences saved as JSON in the OS config dir | `settings.rs`, `settings_view.rs` | | ⌨️ | **Keyboard shortcuts** β†’ actions β†’ menu items | `main.rs`, `shell.rs` | @@ -77,6 +78,35 @@ Preferences live at `~/Library/Application Support//settings.json`. T ~40 lines of `serde` + the `directories` crate β€” see [LEARNINGS Β§3](docs/LEARNINGS.md#settings) for how it compares to `confy` and Zed's settings system. +## Command palette (⌘K) + +Deck command palette + +Press **⌘K** (Ctrl K) for a Superhuman/Linear-style launcher: a floating, top-anchored panel with +**fuzzy search**, commands **grouped by category**, a **Recent** group, **live shortcut chips**, and +full keyboard control (`↑↓` move, `↡` run, `esc` close). It's built on the same searchable-list +primitive (`List` + `ListDelegate`) that powers Zed's own palette, so the search box, navigation and +selection come for free β€” the whole feature is one heavily-commented file you own: +`src/command_palette.rs` (registry, fuzzy matcher, delegate, overlay, and its tests). + +**Adding a command is one line.** Edit the `commands()` registry at the top of the file. If it maps +to an action you already have, just point at it β€” the palette dispatches the *same* action as the +hotkey and the menu bar, so the three can never drift, and the trailing shortcut chip is derived +**live from your keymap** (no hand-syncing labels): + +```rust +Command { + id: "home", title: "Go Home", icon: IconName::ArrowLeft, + category: Category::Navigation, keywords: &["back", "welcome"], + run: Run::Action(|| Box::new(GoBack)), +} +``` + +The fuzzy matcher is a compact, dependency-free subsequence scorer (rewards prefixes, word +boundaries and consecutive runs; highlights the matched characters) β€” small enough to read and +tweak. See [LEARNINGS Β§16](docs/LEARNINGS.md#command-palette) for the load-bearing details (why a +custom overlay over a dialog, how commands are run via the list's event, and the gotchas). + ## Menu-bar / tray-first apps (`--features tray`) ``` @@ -135,6 +165,7 @@ Point it at the Anthropic API (Claude), a local model, or your own runtime β€” D | Shortcut | Action | |---|---| +| `⌘K` | Command palette | | `⌘N` | New (fires the `NewItem` action) | | `⌘,` | Open Settings | | `⌘[` | Back | @@ -155,6 +186,7 @@ deck/ β”œβ”€β”€ src/ β”‚ β”œβ”€β”€ main.rs bootstrap: window, menus, shortcuts, theme, settings β”‚ β”œβ”€β”€ shell.rs root view: routing (Welcome/Settings) + app state +β”‚ β”œβ”€β”€ command_palette.rs the ⌘K palette: command registry + fuzzy search + overlay β”‚ β”œβ”€β”€ welcome.rs the home page (replace me) β”‚ β”œβ”€β”€ settings.rs the persisted Settings struct (serde + config dir) β”‚ β”œβ”€β”€ settings_view.rs the settings page UI diff --git a/docs/LEARNINGS.md b/docs/LEARNINGS.md index fdbe547..d240feb 100644 --- a/docs/LEARNINGS.md +++ b/docs/LEARNINGS.md @@ -407,6 +407,9 @@ text, tooltip, tree`. Sharp edges that bite forkers: 8. Tray icon: create on the main thread in `app.run` and **keep the handle alive** (Β§8). 9. `KeyBinding::new` panics on bad strings; the `actions!` namespace is a bare ident. 10. No `Modal` (use `Dialog`); `Input` is stateful (`InputState` entity); no bundled font. +11. `List` selection is owned by `ListState` β€” never set `.selected()` in `render_item` (Β§16). +12. `.searchable(true)` lives on `ListState`, not the `List` element; `render_initial` *replaces* the + list on an empty query (Β§16). --- @@ -422,5 +425,63 @@ text, tooltip, tree`. Sharp edges that bite forkers: - **`cargo bundle` block + a single `icon.png`** β†’ rejected a Zed-style signing/notarizing script. - **Tray as an opt-in feature, window stays GPUI** β†’ rejected any second rendering system; the status item is a native image, nothing more. +- **Command palette = one file on `List`/`ListDelegate`, commands dispatch real actions** β†’ rejected a + separate registry crate, a bespoke modal, and a heavyweight background fuzzy matcher (Β§16). - **A few small files, ~700 lines** β†’ rejected a sprawling, over-engineered monorepo. Read it in ten minutes, then start deleting. + +--- + +## 16. The command palette β€” `List` + `ListDelegate` {#command-palette} + +The ⌘K palette (`src/command_palette.rs`) is one file. It leans on the same primitive Zed's own +command palette uses: a **searchable list driven by a delegate**. In gpui-component that's +`ListState` + the `ListDelegate` trait (Zed calls it `Picker` / `PickerDelegate`). You get the +search input, virtualized scrolling, `↑↓` navigation, `↡`/`esc` handling and selection styling for +free; you supply the *rows*, the *match*, and the *chrome*. + +**The shape.** A flat `commands()` registry at the top of the file (the one edit surface) β†’ a +`PaletteDelegate` that filters those into grouped `sections` β†’ the `List` renders them. A command +runs by **dispatching a real `gpui` action** (`Run::Action(|| Box::new(OpenSettings))`), so a palette +entry, its hotkey, and its menu item all funnel through the *same* `Shell` handler and can never +drift. The trailing shortcut chip is derived **live from the keymap** via +`Kbd::binding_for_action(&*action, None, window)` β€” change a `KeyBinding` in `main.rs` and the chip +follows. + +**Running a command across the view boundary.** The delegate can't reach `Shell` (its methods only +get `&mut Context>`). So `confirm()` just stashes the chosen command in a `pending` +field, and `Shell` β€” subscribed to the list via `cx.subscribe_in(&palette, window, …)` β€” drains it on +`ListEvent::Confirm`, **closes the palette first**, then dispatches (so the action lands on `Shell`'s +focus tree, not the palette's). `ListEvent::Cancel` (esc) just closes. This event bridge is the same +pattern the kit uses internally. + +**The fuzzy matcher** is ~40 lines, no deps: a subsequence scorer that rewards matches at the start, +at word boundaries (after a space/`-`/`_`) and camelCase humps, and consecutive runs, while penalizing +gaps and length β€” and returns the matched **byte ranges** so the title can highlight them with +`StyledText::with_highlights`. It runs synchronously: for dozens of commands that's microseconds, so +(unlike Zed) there's no background-threaded matcher or char-bag prefilter. If you grow to thousands of +candidates, that's where you'd add them. + +**Custom overlay, not `Dialog`.** The panel is a child the `Shell` renders when open β€” a scrim +(`background.opacity(0.55)`, correct in both modes) + a `popover`-surfaced panel, anchored near the +top (the Superhuman signature, vs. centered). `gpui-component`'s `Dialog` has title/footer chrome and +its layer only paints if your root view calls `Root::render_dialog_layer` itself β€” a child overlay is +less wiring and gives full control of position and motion. + +### Gotchas that cost real time + +- **Don't set `.selected()` in `render_item`** β€” `ListState` tracks the selected index and applies + the selection style to whatever item you return. The index you store in the delegate is only there + so `confirm()` knows what was chosen. +- **`.searchable(true)` is a `ListState` method, not a `List`-element method.** Build it on the state + (`ListState::new(delegate, …).searchable(true)`); the `List` element only takes `.search_placeholder(…)`. +- **`render_initial` *replaces* the list when the query is empty.** If you want a navigable empty-state + (recents + all commands), leave `render_initial` as the default `None` and populate the sections in + `perform_search("")` instead. +- **Unique element ids for duplicated rows.** A command can appear in "Recent" *and* its category, so + the row id is `(cmd.id, section)` β€” a bare `cmd.id` would collide and misbehave. +- **Animate opacity, not offset.** The panel sits inside a centering flex (not absolutely + positioned), so the entrance fades with `.with_animation(.., |el, t| el.opacity(t))`; animating + `.top()` there would be shaky. +- **Pre-select on open.** A fresh list with an empty query has nothing selected, and `↡` only fires + when something is selected β€” so `open_palette` calls `set_selected_index(first_row)` before focusing. diff --git a/docs/screenshot-palette.png b/docs/screenshot-palette.png new file mode 100644 index 0000000000000000000000000000000000000000..b7a947c38bef2ec3dc2a077ebfd62bf9749cd3b1 GIT binary patch literal 145032 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
X2hSFvH>~ z<6nRI#5d6r|_=I2D$*bQ^k|V^28xl?k?_e|3qFu6*jEXGYun{xO z0W!+C_PbD@Q;!oJfC_cUF~P)ycrS|@d>)fRsD>r&&KAFYX6pUpWLb1{z_a=AH>~0f zFw)SxnRqIye|6e6Gtr1!;eae_7mWmbVDSh)@gpu-**&N@U7_dU;IZ&44vNHf$>)=t z;fElZ*!YO7%bcYWH>Talh&5qg`#w2T1!h(LP&jB@@krqZLpr0AG4yWF&QDdhB}##6 z$THNAReWCBYb4-cg8EvK&*qYl{h+c~IIhGt7JPDEUDi{a>4{{SCk|R`#l1Mp6u&y@ z{k-RNb3i|*?#SBL!-6W2JeIhR^A#iqsHD|YN=j_|W6%V4e(=}1vixNsc5l~Fh!BY4 z&{e7{1+?d#|H@tTm;1QVxfaFXylyy~ZY~nx>T1yyNBiXr@P1 zH@mB|YieuXn&ZhZ*|jGIIdf0)5ac%JZMJo_&eZQMr`{@zPbJ@N^x{WgJDmxBmG^#B zMV8N3bcZKUiSysBT%&Vw?&{<2GW?0JvQ{(M z@bg1OX5mS;&R-4KulvR6Yu(1<^2;-EaHCDY7_|sUlLpunkMoGMBAAOyc8 zg`0udK9?hTFoMmo{=BY}EfKJH2bPB!bd={bQDVl`8)JvDrS_-}Hfd5F7wck>hY za{>|%c(#FrU**^DuE}yAC@W`J5*i6TX{_MlOs*6&Gjrxw5re|VDVstI)8S3H(#o4! zQgfG)0!4PtMgI4O*>@{8F=SkL;b&?GZv|W_+jw!ea80o~JedY~G8-C@PFb?ayE3S} zfJ@(}7xO?*3mnWgVJ_a=dUj-w{msWCnM@yVXLE5Yg@mVtzOI)09B5zh1ECWa7ZCG+>>xpbDhtrFF(k>CY+D%!J9KEd2s=X~0si&<7%K{UO zIaJc~e2IO9%3);R$X3h&D>CMhkQ;+wm zTnz9t6y7v#Calku?Kk?|40rd{9CWB>^Q>~4b<6Ob`fR4u*c5G`?D+lkxS;;p$TKn{ zeZHG*?+g{T*jg`CRA%Rw!XzsUJ}rj~^P5K2hDQw2ruXA{aeRliVQETVP167I0b(f@Bs9fOa0`3*^!{|?_gA&!}ry$cEU+LCH+YX32`h_Bs z*nUTmpI#iHzGf)V2ztP?}B_Tr^mUL?@%%Z$`>Fuv&Y6m*r$$gNwQhewS zd_7CGsZ+ZEH4lGZx~eNq6v|Y|)ITl=uI9A8FezW^^k5UC{|+XoC#@nu3>d#T6g=QQ z04Y23=Nys8-JQOtFWwHX3p&>9ShH)P@ag3XiQkXOA5=OtO;LIG^D`O;MRR5s26PS| z*pN3gjK7_)TUYhv0k+iLOdc%Xt}u_r+_Jc+%*g-|C}5h0<(1q+njQAC^J{b2|6<9H9r|(|uaxUnV{PcqZJWnPr5pFgHtzGt{js zEu6SGz$YAewL(+sbuIrWxqRslXa>MDeV3n_LVJ$lo#R~E6Y`HwNxPxL$(@#dNfSB~x)_YhU@^cfaZZiKy-FyQTUGRNhf)V?7f zfF3+8ek1Jf3C>^L^@e1sicEy}C|7FtRmO|A8#vQxj*NX`j`OV53NH623_mZxGKMOE z3I5lsRGTo(fuFo4?HKw5%tt46KRx^BXN5@}EwG)g>gg~9TnDeAn5oKlOgA|#;dv#z zx$rwA^w-bJQPS-)+Ire?Q~0hO+Zs`U9izhDN#0aEJTDcP%**mM3Y;;GYC&q<-6v|MlfJ$aNWoPtzQ4 zScdQNst)$LLG1#_bu;$miGTfp=M-D0V5bndJz&>2*Z8)hxJN*0R(@*sUpi`V4-~=M zrsSKP?eK#Wn*x*Yt0+<0l3VTHe*oqw{O1Au=K=iB=J?ME`2Y0^N|%2x7x470N!iQv zEGB5x9g5>g&q!sK@tb@g;WYA>R)1{)cL_W}G;9!b__s~1bqv3NI)Eyu4Ek|4{0!V$ zk*Y{ceN)P);aKl7J7;TUL8m%kO=4p@BR96?~CLdD&9CCzD zCpE;E;EP;u01JW0rFm)x)d!PjX{qJma$y*{$$eZU_X%OYc%o#AYUCv2gL%AxYBCGw z=dGUKJ1B53KRXvis^J|PPC0>)q!~zfkQZL77#~;7~U&ohMu~27I7(Jz^~+Lca}D0FM&+FZkZKaSuaMZI;O>4~jaWof`mBsb0U)+pr$N4{d3 zhEBYZm-*zW_r?`Q{7_4&?)<{2x|!p*L&koceN2yw0Ir+mos8e6-lZ zSmXNW=|r8kNK?_xC$`R91kxfILg!{pnAKS-Iwn~1%(Sk-(#mhX^^K7~l-Y=rjE8WG z`HPvcq3NNYE{1J5QIIzt1}kg1{k*|2B8d5%Du#& z_vChtz9v{Z-*4Kb36)QTCfsji}IFjMK!O z{)Vgdx6$i2S)H?kUYtVLZ z?&d|MGB!`Vb64Snm%)cajF&I$ZmkwgiQ5fuE>taR#Rz$iy%AReXOWtdWr{tc=l-52 z$qCVnv6f}1Rt5`R^+!r{SATu`{jfQ{%(LZobdbxUn)PIJ7o~7+b6LRJ$fJ+f1vNo^ zgmJT4MHFgdLpZ`3VC{@yPGNjFaAOMul6%Ow^Y8!Z2p;=hoUB zFG#@E`_dx!5^hsFbea_2N|9dz0Ck|5($FU5laA+okZz|%+j*6}{Cf%;P93m8<6zxY z?W=6a{+EHaj}RA}Xml=vk%#LdE(gI*Tu_Gm#zM(agG);!%ZQLakjw`bv}?GN&WP~NDxf7;>S2WuJP)nw^68l6_o^U1fxyu&z$piv2pAeGavs3T@|92F46@loFBlQZyIC<$X0Y4lJd{ zu9|{?2KkhR1Hv8?G09)FuFicH3jsulGc_)A@y0zP{4&tn2-a{hb|}==}$eHoyP~Uh>}hGvM_s zec%V&BO33dAlpe4z~FwoVKv|Qb$n@yRDjgR`MUd)@^m}^mNt1SSiPY;U$wm80@!Ay zIob~UaB$_5MzV~tkkD&&LbdPsOiqDV&2)ODIdHlJ$(!x|j|Pja=Oq?G+i-*;%VVyl zOv~gVmtpm_#3bJ}i8x{26;#mK7uWtO`TqA0m3OtK$M6~heP2TCY@;L!?O)S1RbROg z=a7})^3knq+=aEmHzx&GnKsdpGMg1!RY7vM=ox&KIg0>qZSm41hsgyoK%is32ugF4 z`U{Gt+&oeN=)Gc_UJ#R_kW@6Kb#3%q`N!rG511ujx=A1$U3r*Z+d4eHnIg<${P=+s za&n#E*|^*;ZN2C5sa}t3OCSK@#tPF2V^Bbx*zCAzpIn)hx#V>aOV+Ps>#6yL^BVzlsckKv74sw|`G>G42gapd7 zJQ1~tDmO8Tp_=@bQ&4@eqR$8v1rzXBu`lZF;ScY8ynXdSN5kbCA$lrPM*e%7Og9Ot z=(7re4TlAH91p!pphADVlQX#09MhV>)05r5z1hf{{H|kBe>rTg;qVn?vjv)bmkJFs z(Ku_Nizw5JHp)KF14E^~S5DF2r~@syVMC<$o;a?2TJ$!Q{*N2-c$0k!Ls(WbrNy1c zw!5mlgoP7r;=+Zz-}^fKe6y>0#aAdI)?vyMSuB(REwSo&A7SJ|JRO&ULkG92 zpwWf&Lv3Oy{WLr)fQn@qaG8bLVXIX0r}3>1eYS{h1~m?OLxOsx2}Vvg5S8RMTtP5< zvX_M(-<^-eK3k1$aT3BS>M4M&8Un8{FGIE4)gH4@L(cap;dCX^BDqi;)DGAYC%S#q zC&1G%hC%@JMm3+-=c>88?}$FlDxTSPJGiNa>PdP5q(+>9r$(yYx*)S+E)=Pb_^q zsXgGLy!8{7yiM5s93Y=))FXfkg4bf=+l!CQK4>=GB*|n@?M2R^|`U&7F*eY1CHG2GD zjw9Uak<%nN)&bMSe|+3UE`Ddi*}{aNScjqfs|5L-UiRhRq;;GURLU%6FM{kNhyB|V zKVGexSS5)^se{#+er@iX7~g4qm<>hrF&7u!ZhAG^`^~M&rdL~NrggN?-+#K0^Ya0R z!5>l!TUm)%^NA*oN8>L$viZ_PpVsonADKE1lT<0C&f5$VYN~VLEw!2o87!i<*emj{ zAiQwr=xO9X#(%X|>|8Zo`X<+H)YU9`6B?!C$O<|9ciA7!hO z92xt6%>XtwGwSI)vKf)RX=9a$xI_P#kMDC-A=9n$|_<{#c!v#)*f=>rFMTA zhAySVLf55nRk5<$Q$_6#GkfbfAFtkGhHDHyi8Sz2sJEoCf>uXj)Nov?$}+}qD)^(rtiWOipq zGhU>m`~HkOy<~leSN&Rz76GOr2`&fsqTBM;Tsz(eIJ|^86?VdJo#h(be=o>RTyi=W zfTG7qzKgJ@7gjFC$T}x%CX$2gSPctI_7ew)YOEE|&%XI1l-a!I8ViwU*Y|GCbMKbV zqUlcF4?MqN!({WXaO3+15NAD}5myjFU!Y zO7~`J9?Z7g`;vufYi5(FXf?Sa>lTF|qZ~d5smES^%V)7@I^^<^z^L{m>>d>w`f+NI z1ly5BE+fjE9(;?D*qWiC1fXop0%X{T58 z&+)Ixcx!B7Mq;SWF?UQEFtCD{UTtnr?&6AE)kq76_e9@m%=)mc(raT2ZTESf3?C?- zJjlh}T9L7)ZAYYKp-)m2Gfcps%eNtw4>Fe3)Hd?KPAvTllO41juAPJS$(8o9ub6r) z*nFdz&HD-LGu}SOq@z}u-tZKGPpP18|R^I_55JXLKaUi#xvftJxis%-~Fq?#=O! zejr#g!q4t3D;|I#^)WRwTX?G(KO7~HE2JL!jzW?1RS~+w0XLyIJ8$@I>p1NbsEo&? z__As>pQQ*^zjK_@hVBeXT$a}+P11el986d_h8&WbOBH`qzA?78gmbJ>%>4;>sz^W+ zV$JaJh?v=rdJmf~Ksi;1;+T85fEU9(_mCd1CA;g!Ea~<#Pfr=WySw12luQ1Q7Akah zOnEIn^hzZZN!&5P6XT|I_!vP`fxE`N=f}*dMkfh-9z}E~EC*eNJN=JIuY9UnZj(B` zaF^1|`)0D7Uq3~Uht|`jV=^1}W47I!>JM`4c*Y?>%)N*d7OQ&L-I_C~4pt4HyRfYBlV{{-W1H(B11EKz+ z%TIOVgo?#Tj0DXMdSNzGI`wqDeLFkL7d_Ra7oy%u?tWRCh{!tG;-CiZd1?L0AN>{& za6+je9DF25;GPjw?!w>44wiaF^wBJrR^E7az=KUhI?J|d$jfq4R)km6+w`M;o=xW6 zjiC@-Dc(mcHy3tUhnpHz-8JkI41M%VXz-CABC)LO;fsk`PjY;c!zYaJ^KGjn0df_-c(#~3@nQ-lk zF}HSB+I6?-TN`<6Fy9a1P<}^dZ{z37iEF>L!WjGm@KDXUtV@#%ZGA`!kD;1yVNJL7 zCsnL(ug$r(6SV@UXwoeUSZ4_|35S6=Np{_QRkzeoM{X$`j@N73)bJSbSp3d5(euM{ zpoT+wV*#0H@n~BW2ujD8Ae8NcP(~-0p+^0b2SOP?FN#vI_OCV=acC%ezxh)}q`CO5 zWa6WB+ijSsbl%>5E36(G-;=l9)e5Fgm9YVJ!9wKrq@gL6MtbW+g;>8bhk4*-*C{_9 z=mn?wit}nT@;P<8*NQlGYdeli((hWd#-HDR;7EwgWTNENzS=w(Uuba~$EHIHaeGi7 z%I4B0F{M;-s=K`AM44vNb%Xip?WC9OuNcdA*K5cTKNphQLh#?~;a^PDE=*;wj2=HgNDPHIUAp(_eoWTh)T@K$>+=MK zHm1w>ROZXYT_;a1(9q8^3ho*Hs1g5x9Gs86Y@o)H=pBE?w$Djj+_sG9ZBqe^$M%-j zg?;m}qPAtx7a}&%@usbV_6J*79JV%B@0wCD1v}=2FuVpIc4`X+?9GpbX7wIkTiME( z-kU?bPQhw*G$7rljJbJA8FRx)x54M6hdvr>frqt&d@5>g6%N1x zEgG8ZKdS0}eOP7U)BTp4SlYkm2=7a$dBW{1HUQ=M90#MAVCcu zBBRv(;=ED4N<-cxdmZJnY*brt0cn8P6K~sZvA1+;^&cX42Jrwq*y-Fi4y%+45JA&> z?(E92hD@9)lU{i*VBkD34D7|xmqioMlQzu9xy^!`GwZrjS*IqzfPH~I6AQ;WfaD-Bq6JH!|7VTeo z>oQSD4#LOqqs+$}9u&&j*-*=VgzZd3cev4uC-&V?{vZmxj~QDd=kKRo+NI<4*g*QC zySGi?wKrI(c<8NFpg34%51o0aP01}=&aHFy!`ZZ$)#>8*6^y7N#(TK|xH!uszGnw5 zwIZey4|O9vtJWjg%2pTr(^iPx_0>Os`vtyf;{r#t+(y=*7FJ7BqPO1`z!azD8kSrf z9{+vb(Jv;N&~r|Q{l^nMrSE5jwD37?_wV0Ye*tH<>gd!)RSeU+n$yK1w%^HI99q5v zf#mmkYBMj3{)^$&k4*)~mWW|r2ca*6jLd6Ghg0kG1gtKJ+Vs2ySxVDEJs!zBgYA%V zKqt3+=XFkN$d%PuX|rLkIv;CyRTb&ZqqO+cMkg>qJ3;ZizhE$<$SFtVcNia~rGOT* zmn`ER`YPf62nWnNs^g{BILz6*>7w}JmP-XyTvxn^W)pP{dQM(Ah2>V>T(17<0qJSzQ2BV8v`U{;;Vt{q95*kPQ_#{WG!SPVDB#Y2WeklLZi6Lz&_*D$^wJsF&CzK?gvsGKv3Ds>dmFj(F~qrFK}I zN#t@TiH5h!qUN+XvK^q&J@->Ps?fa2;76;)A|ct&=y;(8N=w+Q58L`^G4;hHLMzy} zagJUR2zXHJmE)0)lkpEgq!yWzKl5p5s-6`pH{G~`9%|gW!Y-PRq#)x4* zWHFm+IgDd~(v)YJzixAQ@>QTcw{qx}8jU+>JuN7vVeoFyS#hV|m>LXs10El6(3akO zIqkwWoaZ#kSz$=VsA`1BrpNW%nf4jL|`(He^_04(?WNmJ*M{Qq* z>51yyP-KQx=R=D_jb|qpq;kfqV)ACEuk9jR-+2zNh$$r0+OJ*St*jGYi{IN#)y-&{ z^z4dv$=ysA-j3Kiy501N3GXDBo_YapCY}4&V44ygW!Tc6{HM7Y&IH^(=m7QIgS~w* z%wMM;R-_SLUqAg&r1Mfi#Si0L&mZ+1O;2f3_Q@A-zx9%d0cqNUtquh;qcKTCoQ+1z zcdNe8X;fZ{{#l?g%RAz-*pfq^M|+pP?{OsMVjbV=tLd6V;cYL`02hg>(hZB8#m$zlH{OxmH+jtdB=(H$oNPBKxs^(6t<1IS}*&4KI&#w@iPZwq3Cv z0Ewn&Bjo*$lAY6Kb&r=>Biz}lER(z>zX|NHf$ZoqAZ?#-B)IZ3104`Z{Q+HR%EzWY zAD1mDaI9L){Lt;ERP`$Iw0P!^GR9y@Ny0qjyaoDlczR4tnGwp zdJ700x%GWYYB871m5cdJp`;GuuvIEI4|Q;5Pv!0zEUCOb6SqVp5+@f9N`X)%Y&?g? z^qL~R9XaoNYbCgD6t}m#{Romh%9v$gRA)cW2Sm(-#OV4>Ngk)*^snF;u96NJ5|?{6 zYrqrQbRnn8RM)#wnoo2USraq$e!+-jybXmO8}do=onoJqngd`o=Cki~44TrHzR`=X zL{|H55As+wP#Pvm_F8~3X<|teZ`B2y`#W6@2^tow0O0=J7~LwtLDZ|ugn>V}PG`ur zJo@FkBiw-HSx8Vpd>Xj~tjN3RxH*Z$hlOgjcqlQoiU3)NTn@6Ep4rE z5iEBH%_#-f^hDzGhrXw_A0<%8fi_*x-3s?NB8i-0Id>Gur7eeRxOPg7I7qVinvI75 zpD&|==_jc(4(g$acMwy0Z zmiH&H?Ji6OvO0VUl2rS(y-?#RfYsi0l=_W=%*YuvrJh#p5|)f6Ob=B*Ru(-Nf}#LDm@dS@8PnS z?3x>wTpeF-w``sv_`SJ(?$*=_M^=SHyw>gq?rITQEI8rzcy@eJ$$Hkqzl^$%;*RMp zDgP1X-)@5Z`9^#KnjB8e(SoMK`J)-UVs--~2kaaIWIY8cXN68G4cUfK5{eILb6*z@ z%l3HprsGK>C)TQ{IN zeHmKBs5pm5S*G#IQh)1Y2l(*a%Cw_d9=0y@XuY^yX;^)8BUmu6*_lFE>~XnQYCp8W zWZS&w!OOYpHBmTw*ahqt|3?0TX7&VLGQxXRE27VS5SPlK5jQQ6&f1LG%nk`MYWw1hyUr>~$fN4|D4sVKyy%gLhWgSh4`*Qi9LF}y3{ zCjBJ-HTE}c1>9!usMVq_+r}iQ!~${QooLPa54U44LDdq?d~-V*rCJ?!=f zclxf8L;tOA64a^@z@Kg$#`sUC41uutqF$EP=k8lGuO^yfo2$H*Tc+#G#TukG$0Ns= zngyBIG_z1z86Wg67J`AzZ~a{#>er`Quh0%y6xzyekVPa<>l`cK5tl~E zx0+}Y1%orQveZGz3@~p@YT6(y(nDPKVJ<<_y~N8VRVoLLvD;KnoZe+MsffWrPcGv@ zU7&8Bp=jmaJN-iIZXT%_P35*X?9zj=3)*Ra+mi5(X)FFBfZhZGD7T*akAW1H(rEs> zU$h$ILOP+mp+f&D74(pHd_Mp)J{^r!TvQTtuu#p}yGCIG?;n^)UyPoBE6zd$=Up_g zlrsGy&4|ya?9=UhBdmt`XLX1$XEIJ@{YEo@25=G;GxPZjr-+B8YKbN;?ejwxnuWfT zp4)YcJ{lt=H6Z)!LpFNvS5el#gymPsVQhB?Z>XZbvYxb=L;_1{+U*rU&O&cAmMsom^QzLc)c4?{)Fvu-|8wp4QR@N?9QYXQ zAx{?I`+fS)i_iv)Qvg#!0`I?Yq-m-DGW+mtVC7^GgkSYoRreUxK8lfo(^RM1|J~mI z@4jw86kIVGA^&*<|9J%ea~}S43jT8u{o^wI&qef~SnxkL#D8au{|U$c-@>s9^oeYK z3ZH9z43_%$stq=x!MEqiN0VoITG1==FJ@O4su4Wkb`oM(>a&@auJpzb=%{z}*3TOJ znz(LI<7XVR1RdPMs0%t>NrXzrg3AUwnlVDdC*NpE8y`xy4puC+!(Ik1wbgo#zO+)P zOhw@k;j>v~?!Cptp|F*-+u2>ZH8&Kp@1?wr64^d@j6I5;)ZZl8T`dYdTM&vXR`8FN zZ>_SbjedPG5f%7`LVF5-Vd@{3k$|>05U_B4*!Whl&~t&K^qVSgZ^YPl^?}`97z*2$ z_r}{2id2f1m2Rn>1Ru>)GxJY zbu9Fli~q3dvhN?44ueWD|yS|Z?>=*7?Up>JtC6#Ab5)=4F%k}8Q zcc!EmfDh5E*O-= zcK&RaL7jJlegL#Ji4tqSF^Wm2lO}@S9Wbb^^g~TT!WI z)%!N^*f8>;vU@iXC8f%^?}5J+YVc*c8sv_5maa4HBSRjyS)gqN27P}~oFBAIqm^DC z;EyQ1w;v4>&vM`&ogWI>aVZ7jG4_gmd(u!F-?l-?;MJ~-=92mHFqwqQ1fS(-#P-k0Or(0VRL1}=lVXUg?5LjsXMZb&*>H_xLdfQr7Klk ztp``|;p(RR?*sv;e9%z-h}r@8H4y-;D!HwgTt)@HH5+D*KJT`Cz`?M6)+%FfQbraN1C+y)<%&6WolC zmFK1{n|Lph<&|C#8;U`U_#!IDDC47uRYyZo_Z8h|KYq;tS3MfK=-BRI&dXi2;`F#s ziOdSbcO_xpaTix|Q?g%i+6nh9wmN>*UG}$>=6$eK9y^t5TS{|wjIKqA@hd_Ky{Eb_K3EsO+$sIyC_BH z8SJ8}tiPgu%^3-^jT8N~4rY_GrO9~zq4$k^h(Qg)K)tYUS}0d{=c6`?>j3H9YWW@y zMMuED2Y~#eZ@*&g%ck)K$&x|~@$;A=2F<#nv(J)CY~On|6RY!?`sd4FsuQnyU%?8QM9N~d^kTMpG?6ZaEeFS z3Jw1aDD?bbCe}ojMjR)wdk#6jJnsZ9UJ4Fni;iOWF20LFn4PCa{b>cKK(*L6k$9jh zyGl1B&AwyejO{>HO0s9SXos7P(opemtcefLqdYV?2P|N`YeL@xN*N(WUsB;g8Vz(k z$r~bSZxE9)?Zqz`_2W(Zrzv;MVxafdCC=*(^$1q-Cj}ttweB_n*5=5OHTS24%R4*q zvj*v!{YKsITd)=_8!EtSZtJ4or(!_kJwFDE2=^+V;?v z7n@mT8*fu11qS2qW4s9$0QM*{2O0Rqg&Ns5uiV|LkLsS;`g8Xx3(_V*`tIGZO8L}o z!6-5NsD2Z+GcJxBHzK$chidH!)ffY%vW$$=;o!OuMY-@1CH#^$`P(JFv!Av0Z+>0Y zZVK3c@N14o*w548eCW3S;LzEvY#dk7-cS&SMPgEy?rw#C0#t+!n?SjdTJ%MGdbh-49mmis zddJv{>w!^foL{Z~QD6E;O!9+FU!(h(zTiU^P;8C+l7y@BimcjdQuiQir&;S2{V)fzNAgY7EkN#I8t@R#IqLvja>+5|SAG7HNN+ zzBllw?=b&7JwB6VYS3aF@9ZC#fn48v@U`je{HZ8Vm9qX*RXPG7kvNANm8M)RFPwB4 zB5izt+(jBdEiraaV?h@4I+WJ+Yaa9|`HL*ui_d`_28)gL^tfHc9yXK>N9mlon2}LK zI%XAqgMsvA*Vv&!VG)A7%S*!zG+&lR`dQbS#k@EXT#q5VK*!Jfhl^6n!QZ|UHkPeGuFN9W~tg*9Z?mfR&%q1|HuV=z@U5bnbvzc+6{`cI4|1)Yewxq z{y4f%_2!M+H-s5fGUPr2sYo6=9n0e_Me&9Qj0Npi5ZsE-Vt~SdQC{e^AF3!x<(^EK zTe_4V!y;;ft)u7`VD{3ak&A4BsGgAihkK3eqzn9Pc^L?0;qw{7O*8+UH<-60{U0&G zAfjgD`KaJ-nRqVHhWr}7I4s&BFYxY}qXsstMY=81w$u9Yy)vicNHtuleOI1Zv<(<- zkY@dg?{}Dp$d19$5J5=}Wfsx<+rPBKmwka{!4BjGc@8I&My;iicNXd#%74{r?pK@> zpOdw8l~<<{SAMSjj~npUGdLI=-T`8qBgbH`_^<5GljF>w+<;&&c|lV2(L~do+!vv` z6!wOccb-*e>RLiRB9r9rg=UAro|{X`SUq5Bq1J069#P2qJ=uB$6RgYM@rtlD}DVD7Oh@|#_qyh;aEA@j=GfWx8>Zh3tclU z5xuLW;(9`oIAG>I=zH93l*6ytCI7V`ti{lV@J_Us%YG5K+(S~vk*(O&&1?OudeEQy zaAT-gum_9f0y{#@{gU)EZr$PYt>Pv{DYJ|9$yV*YVxBQDEbGEEZfFQVC<+VZRWheA zk{J0u9Zr6`v>H)BVO%LH>k>UiYWIOlBCk2Q+ShjgN?N*0K^g=Uq*WTEOIi$2kre5W2I=llM4C-W zZn|sJUGK4H=6;^J)%U}@*8AnZ{_|xPvxZ^s>%7kMIFIV zcFg7D{Bf@cr=$GU{2>1-^El_6#gO*`+=-Uuy_z^gr9ZNUYRNr!hB+em9%l~Yodm%{ zwU^DdTs4liue1wP<5KD*w8AA@c&FL;mkxjyva%p*8hgRv%&4ic(ON3b z&vS(g^o1%`Q~D>DFiOr5GY)n-nVOmwFYS;b6|RRF%F0#sr*)dzdSvt#M;~`sD-OkL zo#tejc}-GWbg-{quAy&va(sl!LnRU4q$JVlX&2^gk=Nr#$m?INuIIGgP^?c!XcW$w z18pm5Rca7FFXL*mV~;X1(p=!3^>8^i%Er+v>av-Mo2Ii{^tHb`=l{*K5~F+oQ9eC* zwhVh$2?Cp^`)yx*>GJ2JAg}tvVcEgGwZ}jCHgl!d5M6i-hKef31RH|Id>XG0KnV=kJ*vz}|(Xew*HrxH-P`TlDiw^38-V@Z8(*el$|s zcJ0>ueLprlcahIJCFU;8ol@#~eTlEtVg#K&>Sy#_NY|eamgF#Oeidjp@)GDb?ZM%z2Zxbs%))vmE`ID>eEZr$KgVzm2L;iPj>n% z664iUTe5AHB+pS!UM-z}=`V7F#}dEy=xA(9{HywX~x7!jXQ ztRIVYOXE$;I}dTCV*F~`g2q5q>8A%(L8G}Conw8UpTHSD?4vKl_DVXx%WkcTNw()O zqoJUKM{nKDjj&wuEFhywA(=&-$cr2qlxwlNH3%NXE7GSY_HLt&sFT9|FLvW2D*U*q z+tebJO*@Ox*PD`5f02dLTU`9aABnRiQ61KwBZAk$^wi4gE0=p6#$r8DP0Y)V=Q3mf z03Y=AwQs*_ko*MH4llXv&7EwdHjrNxRd0AKT#8t!7Sx0hYVfoRGc|HEC6YVfLksK5 z#E8=GB|I2lOd>}h6d+magU(f!E=9f)%f||azkENiJuPjgt=vf924h!BH=)_X2gvuA zx|b*CRhJ8c%E`l>+6t~xc+y{lm6_Qi}Cds`h>m!t9`4!fDc)f?Ln`=ZPZQv7?AO^6xQY*Qci6!qKh z*MBsMtasj+F^DKvIb9_yrC#hXXCJYD4D!U0MS-7x_~%I$M?PY5Q{X1!?g#$$cDab4 zn_0tZIa}!`zYr$R5aFt4onO-u7rE{WC6A}0+X#Y;h;*qtUjdZc$UExBG8&mqSJxM7 z*X$gZ*sWqjVjJu3XvayI=UwH{G-0)LDO6F|?Kd-;CK$)a74sqP)Yia~9WP(g^cL&F zge9Y0u6Ns~j3Lhx^TNWGkZnOBdcATo`_e`RITBhhW`pSlvq#8zz{CzqXr2_UUiTE|Bi_Nx%hvFwpwHOvm%T5kuSy0!AnzlgGeM; z^@ZG2&*g>V&v!j~{)s6Ae^$CmQVX;tU`?O6r;~Y!p&NS%Q6@jJ%>R6z=LmRdZoO1o zXT2`LfI1mJPKtVr1fHs96La}Do8sSt@K>|o|DuDidh*8~f1I53JZQD~k1*WQ@Y#?{ z^@HEnoZbd=24l%z!9Ud`gRgv#<|X#KHxk`jq&2QNYr4es&t>m&1QTP@Vq;4yp1F7H z6h?3&CBOSo@1VlUQfoVNZb4P|iAX~XDmxPOSubn$6W#;jFn+sGyRQ%-t1p)(^f;uP zoW)z(E;=3aJ8Xa$FeA%0E^+&QT^gh56(jrGG8U8L5w~RDts7)c1w*Z?w~3 zV?!e3rw5{zXf3a&Ak4Lz2d66FY+N?=&uASuC)&Axcnx87uSsG)LCcEGc!yl13Pb}9 zrlQuso$NQ~1mwNYj#XL^3qm1Pp+L)HJX@U?_@x;`8Td*JL}Y38Q(A-B^^KYWsa`(d zWPLlBu57QU7$?G#su&ZfO0U!iW7-kpI`1XWZRfx zd4y$sHIb*=4=R*HqmH|n321pYGUJgK&r{*G2?+~v0ZH-a<$n|T95oQisV=fnEnHEO z8j;&}rmG`M?8}Xr^^Uj$6*nc2o6(AenxE2o5^b^e3N`{5m;L$@iF1uh<~f3Wj)em0 zl);%sKQ!$9cMnTUOVf4rS9hrcZ=gf|*XBC}(pvD7sd=Rd*r5F!lmk^T2JEKT9RJU^behOJF{D(8%)*W;leYR{(C$1kTq zUOy~llHo7}^i$>HL?~o~ZmeC~qT3R{9U1XBAd9&5__oRqm84d((yI053=Ze@soWKY zhq<5J_NJLt(Y&Db9#tiu|JN@Uf~-|g-$8Tj;oyi@VTeYuZP=)UQ4+{?36iCAXjBkBbATiz3(hlk z>+_e3=a-6)4tA1p1}Ex$Tl(|#GjUxCqP7<(IDn3j-x|fM-e7_#^#(dhi}Muvate7kh^f{jwg_ zkN{yh#Pj4pua`o0vXz4T8h5$e_L9uNR{iiY7}=Ry|EzlTyap@yS}C9_^<0G3lW>Lr zqj&Qvr%}Gz0fW)9hNtX^`z$WM$6@$s&BVJFWmz6~HcmuA{Kc3-_wd{z8|`dhoTo1R zK1tSTJV9%%Tb};R4{!12@->-bl+ZZel=#Ez5;``Wx=;RAOp|C;Wh}I}j)&|38f!Wr zvfgq?dY#`^0^pUb6;AY3y3a~1b+YbdNA0x(W__w^$0cgR6S5;Ln75i1%ej~cQ;e_SSl%k+KbflbyF zczKe0PG~Si3$j>M?Y-0R@5+)Go9P_`i>XS`DVo_LNN~rN5U*wO(qevPA)videc<1d zp^kVTjcVa>*__Kw3}?~eiQu>M21DCBTuGqJRV-m1Gu!-8F4k>b#bac7AaXq@8qsEM*dg$Mopw#uOrsO*ES4t>= z4k`;mm!YPUu9f4}8p*E!RN{#@LTdrD@{PS4eqjSZ?k(g8v!5ydpo@A`bA#5Drx$EVmZE%OMA=P52h2cQ|}n`KRv__vlj0ATOfe`$2t zJaNnp!0w@#i5>%n8kvTSXPXsxKPp&@u1>rr(G4-}{+gqYI@XoNvV@h$L^|nd?PL(f zC`GJCpj95;qK3SN28%==dLidA50GU{c%)p7`=|FAoIx1^Swa+zca2AW#Pj4O=Fa9s zua*_}xJkMF+F}d+=SRaG5#9omfj=MNQ#I)Q#H3yN#vZjEzPGXiK>o&=QQqb(2dgj) zEY_0ZzJ5lz%WT$jnnjjY?et3IY(R?)dqIz4KN+UP2O4`lS=U6nm!Ejwb9dSCP&ez#wjkdC zpuJYXxKT4q9+Dq@!BDAk;Wq6_3)*|R0A56y5xM~_!L+j{+Yd{fQYFTE^Yo?uG||a8 zIowd%oA8~_e>%WX&}0LRtLf|tQvQNYE-uih@qA%4=oRH|2PRoFR~rH-N{)NA-C=I> zk)ccB!&V0({*I5Pr@3V^(7BAtzgUQWE0z+!jso6kOTH$$Bz%>97q zgo=qUK)=DiX(ftB^Hghu^k=*K4HKAVAca}&8&`$qO#sw3+bs7 zL#e!QtLoow;4>G-CPT35lxxV{$+oS|podM%?FDU~t8GVTDVA=Iy6?oOHjtGn#0We9 zLIrKAyb{_#qh(xoHrD$IFhgvzCnvg^d?>2f1jt>4Ht*4!oBCR{mYoUjPW5C(LyG%y zYL2}%T)MOmj}n2!*qd28l29<(Q=pb5kiIQAZAk(iX#brqCl%Jh&}lFQR2${eRn#@L zBn-k9xEJ`^>=D)lD>)DIzG>#oyaGY4J3JQ1z%jNa0lh*+Y$TF2n)>|-U%qEMM0>RZn_c<&s-5>tJq zaTdH~-5p^eP^S*P|km>CJgnR1T&vz4iI#uL{t|NQ2r$ z>a4dB6}|!_(Q>I-a)Q;z`{pxVq+F(Bm!3_vMX6WsGtSeVTYjWaR|d|B;npb7qwJN> z*fpd*9hcsR8e5tSXaJM3suvIB>=8#*60Zr6*cXuAcoZ{BWxeGN*TCaT?}bS6v$cs{ z4?9(b0g$v~wit|#%QFIr9yg=zlr}%52X#P4R9?xmT^Joor=p5d17;&D}A<|xu z+(8W|feY2lG1`KOh+dIv)=LybvlN*y-Rh9lfmLf5aShzRgn4uK2-WE8Wh>pVlSKVKODkG8ko*a<6R zv3m9*@_47FFY~CCuEO_ata(L>(#h8ltTUFR38vvGu89w_G}|<9Oc-<+&vp3&#UF-c zoGl|&2dyJd9VH>PsM^0a-;@5qeQ3}AtR)eheBtf(z8H=JaLob(AnQZ#7T83P5f^@K z+MpT%w%BqG&2EoPegHVCp-saK_11sc7p>>|PjziuM6s3zv|3j@5~v2KyD1vQj*AB{ z`7sq7I36kP9b?m|?`>0&=FQ=(rY1a)sh4$hEUT1hH`>`wHBy}?@vx{acU;Cpt3sZ2 zmj|#J5eq~5LE(=qt-hX`m1@UcU9&~Bc3H8}BZXT#x3QjWpNIJ-Wr4A$DXRlpF}biy zzod*u`RNjMU1#ou+N?)kUH}cPpw;g5=@QVVl*`sGGXVCb?ZGl`u-i^gdK}ttPX4BP znJsaurR*6?&^jzG%B;6&ueia#2cI()cjCqv{JH0sIIM79TY4;1#N8$RUS58IkJj3R zI^P*^NONpoJ`i-W!h$oYx!Q646h!3tmG5CvK2R?zHBjK?ZA+4d2KTvNQ_rl0W-&r_p%WZKExr zg@1v7HQG*eO69Djf=Z?a^|>26 z$nI}$QYYTwsPRx%9RYr@-|I=ARy!dlH57T#~!H7m9k+S(Ojm%N17m4{@-2I z)haRD(Xrq6;$GSqy#0^lh>B>(`B=I!56M_G)D>R$rQ?7 z^wP>aDee@-e1fLh6o3CPLTN3Ip$jwM(|P#ipb?TI3%V9<&rBX}EEOP{U`rDE1ss1- zS>!S6X$&C~_0Wdb&7xHjt5;D8SO0q4$>C54Wa9TwRV7()#d3ZrfRdbX7^?RLE)#1X zjq}3d$@nB;0@h4A<%QhlPZMyiBVq*U14NHs73Bpu9N-2LW++Cu!2j$h|Ia`0KVX32 zR`ZB`!B*Itp~hkhEyJld0rGEp%UTk99j`fOEsC!ntVCT;bsZ9U6dD^X>RIeoHO9oC zv(ISms7=o)h>9uED_MxKTUY=R6UIeWe6iX|Xta=1P)7QQaiQx?)3|PzxfD4G|7*Ox zOVcSwom-6#GlNjHWpOuoqLriHqRQ0DY-tzq!jg;L@sGGE=^{*o^uh!jqy22S$-^~VT|D60 z>5MRF31#V%>z)MxOBsLzw{F2bL!BrUz%#pzK2Dotyh!Vp#QC^jEtwy#-X149syXrG z^;0Ol0MtkaZWQ^)r^iTDi}f2W7JQpcS50l@7X4+X8KQUEK)zuZO8A%x#0(3L*H>^h z!pt4M4}N)hkZcv_)OJFYS7limpIK<)99PzJ)pDOq7$9gg1xB>TzS-c><^vvWfp?)$ z?`jn5l*d$2sr7}~GVjAV9=Co$$B-X zz+QVmVvEzD5v^N9pmUME$7Xv;!x<7$g;L_rin#|21f}z?g4IILbb>w0FMV zgM%82wkw{>?YN1Vz%({pt3b3+<#&_3+983> zbZGVDZ4slJl_@_P!Kx7fm1Y6+OIGJy&}E>TB~Z@Fkb5%I64tk`Wr@}1x&!iot~;pn zq=k}2kF&!}pKE~X8|RS1Q0j^GPelXen3NaN`P{={f8fG;@{Vhmk!sIf;2m~M1dDXF zZbZ|U(+mfryN+UI&fWVxNfX0Rlbu4>WETL!M_GhbNnV;6l%r{b%;(}`~Qb^~c>Ms+P z>SR)mN>Mt(*?D5jJdcAx0#+1`U+mooe$#bk@M;Y+{0L{gMbDEg`(}%i;ZMWrbFDOv_LmDm)8=vu(b)%Y5v#7 zJ3q$*7=m)KebREBYW;}Vq%JZpn{H7TW36De!%!VgnH>AlA^u6YLZQZf4&lyF%?)Am z#rQbJDLwS`!DV+|2m>u^e@OT9@}mQHKgKpQuTJnFYJ+Um7{+{Lo7bUhThs{@=ye=c8iBYYzdyjXr0%s3)Rz3iJ^A$59grOjWMN1KFc>FrE zIx~O2db~vMc5mMcjzQGZftS7f&g)5e-6GM#u5>0bk9g%m%T?B=+vwHxRKNGnUwO6O zy)xwOavWxOvVmCK;+nI8Y21|ewdP2UEeF@L9#k3JbtDg9@plCFUs-LiR;xu_xz_GmKfz5$k^~NSyGLuqS1R7g@*6evOw=pE3qQ7ajUQ4 zEXQEB-!;z!sm@;u#@G?I^FbRkF0b#1W|B@Ap`W)5d!QfDq=BXU1Osu;Ntq`~_c(xaI2O4a7?h=stI9*lpV|)Wv}2lN>aHm!+bV zELN;)j-$t74{ik4wq@50M-p$(r%q1quIX=QNyOE^`xpq_pTM!>*x?F;Z*RWfpvu@V za09OI$$8^lyJX)Ap9f%i8s3i?V;+)?8(WK>ff}5mO87Lo&FnaPPXL1ObNS)*2jtg( z;IsY%(Dmp%bj#Id%CAkKDxwAyY(!=?IlHTm96#ETJ)5|QRLjz)gI05~8pZn$P`*K5 zpnmH6wH6s@8MgM>7l)sD<~Voh%4LOO33AXQl{&M{dHIp)CzP;N8WOrzR1 zd@*qUY$okRb!NSZ5Uf~}JqpjKIF%OJ4p*D9hsk+Y9MpH~BZ+yr-)h*PY8C2I9YnLa z_4bPDZZtt(oll-ab!D1g)>}IvOP0liQ&& zAIQ(zIAT!4-y9lsO~mq+{1VES`5+^Ej?ibjbGFVYy0)DRWfDdIp29+1uGg5>T%%c_ zcRj?#sG)F zCX~*qWdY0;-BM?S25I4iy|g%?{=5tWs1~`LRzHa($O)Vg{0i>aF^y@<_=e1>Ox#iua#Xpk_=aHLo0V3NWoEzrV z#JyShw*`e+B}+fB>3PiW-s9a6!cE`bc9sG=_{yHFzFH)jIw~K%n#YfKNFW17ZJG+{ z8XIb}85AC?#el6smK7_Jj&^@#7EkYk!CRqG3kwHT8f#m6Lq9vU!BBD54DzVX!sLYz z)2*VN@ga-llN8Pcdj=)p;B#ONmZ=}=TNt+-D`PTh=c(&?N24j6-J_<)qIabgE-ygX zT_M_W<@-(7=mu;EUx~K@*t>UNE<-UX&qg4vLRo}SQoQ33m>@Z6Y~OaUAg58~@)|n4 z+?*N8hpm~lhNp*P;7!iwzr%A_paWE%UeqDZ~_|}@t4_=MV22wKQNDMSX2ospE7KZE|UmT@3~`qh&y*u zeVu_`vnd(lyW;>}kgUrWTzSgO8_Ht5 zFt;99E^jb4&eP-Go8qzkcJA5W!Hg+iI#n{c43?$9c_rh?`FQsqRokpnrI++=saB?c z!buJfxsD)y5&4_T3O1iqZSVwiA3ApbKrU{jTu3gKNH_1 zRTUv3!)V=|n|0T3FrlDwsjdnUCCJ>hUJK>}Y2SCa!c=-itX<|VaOnhh#^z05bdrBf zv@ncd<$I4xd!tKgYCZs^ygz!8FueSd(b)J!WN-G7Vz1jtR(gU_y{{gX zVRnW1`YhX+n??P*!JSq<4C{tF|`z9GAjzzO={s#bp^; zYKkJgNlS6BuX^F&b4wTE4f|SbtX%tW0cjs6JZz;DkYuzqfVi;b%H^tQp*d(Cve^bO4L5!sAqvu>I8cbrmuG;`6nFqq7& zzP?_@(cDN2EGucudo$a2`m(f`x@&e@%c}dWQz2r4cOG8k?EJBr`$6Sm>kGRIaMP|E z#9OZP9sa{<%xLudR#`)29?uue$aMfmzWrR7ADy#1=)Xe z?izMSeR@7w1F967a?G&~&0F7quyYf;6hxP6-c#_(Zt`!BU-VsajThm@j1<^XwLz@f z`Uvj3xu!QiLUdGPdFzy0#h~<3eNdjzB)>A7;k+^RK@e3rR7Nh4RI>zX_hr2wq)+qW zcG{Q8xf;bDP@(54mcw!QxL3CxK5BbDRDFb(+C1#UOQfTw8UUnQWsx|Z0fug(l6YWS zx$9gmsCyYhYd6!fsbXK&TJK9D?Q<~(Fh~F;0Xz_$VKeekbB}GK)KT>RrzMdP1|9!Z zTjyHh+E>?J;7m$sxyB#Ge$rI&ib8o7gA(Lk-JqStUVi=CZE-svNgQ$zN@t}i({JD@ z_%{A-T8`+Ig=Rh6ycLD+LF8ag2&1A{{Ft{SO?me7w>2tF#9w@dl*2d{?5UJeg!HO0 zRMJ%*q@pr4^cn}b*IE<=cuz#qALivlK&D)E>@dg0I@oemQj8Ir52?T%_KH&L_(S0( z*FlH-m}PZYf_ns|bvKWR)@Fx|Yt2rS5sp%-?JIf`PCA0>7iPcdx!!<`LxKh=R$Br) zp_`mNv-RTxg@6Rva6Dd zU&$_;MzHdlQjqRn7kYL}xzQ+Wakl=IAnK?SiMZg9-SXIDb7#cNk<4i-iwl_|N7-lIc=@>Il-A}y>O;BD6e2CITq!kmuDiQ~M!hDbzP-3}p#*L* zYPikp7v_S41u|~+2eIqlEh||*4T$_hh{TvFRXx-7?`3kGZ18^5`3JH*3nA^o-&FDU zoK+H(GF~PCA35i+yd7SYqkgfQ4%ZyR*xJ;q-G%W{+pF%$Z*PgZa#kvELhk}(Wb(Uz zp;3Vay94zeZ1BQr!9U(j9gq;A=2ZL)vwih$E01#9eJ_;A>ACux_&9be`89>7ki6s5 z(V3p}AdT?4_7C&;qNJqubvp{Ubv`QM?O0o89oSeTTz#ea%((8mV$3M7MQ&*I^+oLp zT=Xq;62(d#!Q@0fE4cl3ND%DVjB5CByEi+gd8IB;L_fm0ci;*Tq7Q=(mYiYb@a9P{{54fEp%^!neMt{K0!N@J2r&IQsL)`ah)y!DFs=;KExD* z_eP`Uu}z7cMcmx+W1R|NOTFeE1YHwb%{R7~G~O!0Qj5`TA8Zub5J;c z^j;17M`FW=-V0f~*7F%<1yfO0YG*v^wMCJ81WiXy54W-&7-v7|6M@^l(BE}C()*)8 zOIuZdwjZfOlIE7?jEzf;-ss5N?Z)og!%{h&Ituc_F?)SAo>u%WQ*X*HLfV!5Rq~ze zP%#+|00d?PxA9;T?U?nJKLFbmQ~xUDpfIr^Oz zA99v4YH*fs^0{oLU4YD>pw+OnHp?KL33OMB+x6A6AS0b^bIhhFHY%AeHY%GZcv_}d z@nohoOrrpCJdbIFdVVXoRv}I`OOquXpl3(Y8&}~_d~!TFjVE_}h(*}box3{MNgWI~ zd@8Qy__w!{P~MpgRJo?Aj*^w~^WKRrZJ?1Lw*1Xth5&HwlHVj~G2MW?IOF>`d`5(yxgcwMt=JKA@tL(XaK?eGPu1|RnKrcfU312{MVEpxRRgfb_$(GvK_S^Y8 z=b12>3|~KXLHm`8kPG)jpFL16wN^Imt4>tid|MPfNoTGhB@D^9rqqrAILEz;jZEhA zaqCgKNVcyU?2?^+eUmKRO!9D%!Cr+2fW`4sPbe#q_D*B2!1@R2>f>H za>US=(+5N$G;G#_qI5XqUw?rk!wCI9bRw@SKri(j|B`HuEy0L>GUHprYA1@R8XMJ- zF^@unRabZ3vZkkTPAuKoq3)i>*y=E3n4Fks-9z$oO1=!2#>0&<>wAm0-X0^&L`3Iy zeO_Im%66KOrr(Dpoy}_CumW^ZI?T)k%zFo_g4@rLZSAf#aIe=5u6)@445RV8_H10j z9>>mAZad42c7S)srM0R)oN-%@TrmLo4akTSrGuWRWH{=~hN8Mt3I^;$bq1m)jIYEN z-Imw6s9M*0uYtQSBxs$Ok-t99gQJ}}Xr4#t2@B`mUg55Wo1$c&4CI}y9@YZ7zd+jz#={n~ID zyA72VtAyVQC4LlK0(tz|o9Da?a3q+l<mdsD#-UOKyOO`}uHUH~-Eq#~m!J6Zz zQl%2DUND>o>ID+OsbU$NsKh&k2LniF>w6}IznS$tpM{ttBr3s$@0Et$k$#aRRAV}j z$gcR~vfTN(X#gL$nhn!Frv~p(DtrsLvP^t8L@s#cj-S^Dy<98k^>BJ>auuT!y+e!nR_@fkgbyXZ4xI7- zB(DF6-ebV~;zi)0?as~M*ZyLKK?HBB(7)62)B6AUum8S;e_z5s_RoLvfPYWIzv1XN z;o|?4a0C=WN#Dz1XvPA-rf6OLub)|+3!=6?{AM#yWasmAsQ3X8ahG)-YW_wZk`lig zLMOX$rTs;?(m*xb*S8t_Tgvk=j1pwohIF#*4}fR4gnwdTu)!TFemX(}Fs=_-TD| z-%B6O9+=C{GvzogWb0OaZFRJ>w0}m@*BXR(ODc^y~H|(Q^|obOYg_ zuK2o_y}_TgVmN+n@lv|L=XVy&C}2O+fm>~nTH*lz%?mLzXnZAR=^Xeg_7~gK7SHsU19;WNQhch0DyiaM6xF=YpWFzLi*#$CTi z0N4}EMiN=!R00vBD@~cYJ1xqJHIC8G9JoV5U~M`x3^m0^VkWil4ahf}C+g3~B&&-8 z4-NppG!F(F<$eKIS3oi_>Unxj6a$^Sv};*=KexhCp|C!%Ek_3qCzY#iI zt!rNd%NODZj%l|)W-nPk!IGIbTsnv4yKUx6)b@IK^V5TJbIwFiRkPec*u5Y(M9YsZr zk{hF>e2Y{X<~<4x_D0~W_CdZsRMhiSS%r;VQ;cB1Q{--jn~23bqOV7jO|#QeO++(- z5gdl0BP(0-n2GUPQ9L_Q1ELL??xP~4NF~K+zSuNfE~{?<`o79p9SBF4KS$?p8irk4 zld~7Pv$gOeqty>6l8WSRxs!WeZ^k$aTURXQGpi)tbyyq?@&m_-l$+_Rq`#z6*lgy@{vs)uy3qT){whX+Jm6F58(jCs^J}&dY_EUOi~F zn`MHrBkX5llt6*-HUn|GTf%Wb)rFV7<9{0(N$nm?dhx;O6)rz)2WmXyHiUQHq9)Nm z>|hox$4)V;vFAI(^~$22TR+sNfFnkLJD}?_Z`f%r4CZR|FVEomySP^F-`0`k&??TP zvyKw=j5VDB*!WGrmh;Y%e!XixT4B;=-7OM!Q&}60ZU#T3Fx+b%A6}lti#(qv5D@!0&{5YF@0X2AW+f$@&e7 zAY^2Zrh0SRS!Hlpx+w+gfKyVK(Au|2^x-XA%5RA-huKt!p6AhzbIbcJKzEHf@S-mn zc8s!L9+b>3n~B7fgh(3-cLi9SSZRqPIx!8m>x=qy&8rS@(sipM-CNwqfi6F&ZxIP5 zvMZlPbt<0)5l0&qgud2hIoWOa04CulL^0E0v~rhc`9Xa;_~dAX8(^{Vb~)hvx(;km zfj%#K($WWM_t;k*-)Ykmmu{hsVv#P3S#(REALa!M?M)FGxvfvP%oa{V3(4r|T|ZK? z^_>#kDwlOIs*?eUy_l8xw~=6KR-sa0q~N?ipDM2bmS=|b?}!zJxvLhlD_R}=NV$oy zg7#g}tb#@|CnOcA*pSbe4)^`dkHDB|>eEAn!Ax6g@{*ggD(-1PCln1@(D`r=v7-=| z96y#M^C8Lejfjcw~t@~EfXu`Ob8Hd=7+hp=b~a|FWnsYldl_ov|(8`eR-#kFj{o0r(2DZ zzYp1MJ=exdw9;biDQ=7%%0?l|*;O5;5(kr$m6}m47|`kK3WM#fxpR-tZ65ulejBwo zLZ3Hg3Hli=#%BbNf%qCB;_kh*(p;6ocMF((TYd74sjmUhO}N9%8?(n_Jto$|xVh4X zb}2q@M)F|*HV&UYyV#R% zVI&5>-x=bxGI9q9NM`L@Qf0Q&nbVAC-+4Q_w8jb#MRpe6vp0%pf7l&i1)XwULzrF! zoh5&RC%$zT+(!-I_Ehjh+Hza z*nnU@jdp>DFfS9v8sp~`x=8K__Ua$OfGJ`JK7TMW=%cdtg|~WUc0iZ`Zh20mlxb-x zTxth-4EtA2$5QSYLQs5mnXp=P`+wC8fQ5>6zJt_vjMnHNX3Nj12drdiP2B)_X&>QWp@+%`y{C3?lk|5m?}@GX-%CzsT`=z$9s-+oW3^ zGZ-Dn2Ypnab%x(on`P9dm26fN`P~8L&b=qC0i!vxJ6aW$_a5^b=&TG^&_CI^2Ud7v z^Tx;eu^W?k=9#%>X5SE%_lX?_01{&ye$@!_*^j{C;|n-mDqyg!Csq#^p0TXRs-7bZ zLL~w@VI66Qh}0sDECgB@P7BgOz<%yg+pPniGH%afH%?UrHv8TlutFzveOpI$$Gg#o zV%x^^$1ANkH;yJ|i*&4=k)d8p5f@afFl=dN(Dd}wXrYh&al_8!QBuL^(rk%&pRRol z_W{gDd`Z~YTU262+y_}NF_>oM1wef|OxO`OK~Qd-JKbjfMHtL-Y@0TnQ(J_5@; zJg>)fpPY>87vZr(v5D|kQWE$-l8R1>@bc5?2xux*_m@6{nlQZC^>;d<(t zt4~sp6LnesXo(2uw6Cbd)4oWTCQa=LkJ`>QG2w|`r?5`$y}-M}98aSAOc{3jjC~@6 zt1hSq?2cMF5s_C-6yqH@Y^S8ni&Zu3GC=HwF5D(;v8??C7{c|*TRSZDn3~sQvC@^o zeN)aonU<5DePB1RbGjyHtB}kE`sW6aHN7iR(!OjSfyim~uz~0u;)*g2zImZ%Utj|T zEW%Dz<8*nu$4BU?)#z}4WXz6_&Xk)7qzdbEi2>n@wa2N+wadT;X17#qI2P$N6!XEO zFv|WO5clY6)%bnbS^fh=3dVvw=Do-zpP5U??g@{lfMq|iXHgoYY+@QGTGsCZH zrJ~GBJRgmvxSm;9$tEu!MccX?w4e4YH1AUc-Evbq@K0UqDlnd#7CT+j@+%_bZ!_u3R@W?XC19UWyJRYEXJ8w|V5z$=PLDnHP;5$j!SN zrBP5FSY%%9x6fz#C_#>9K|axC%kl$QtMXag)W}aF?vdx|J5RzI(m?KtWM~1&rJ@Tn z=Q^+6-H!q87=8HTnfn)P62wE#FuI^`QVz48G<c{gsni&; z87|*ayS4eA+s-!U=v{7HP`kBxXF~GR{=jD%_e%m;XVc>o$WaFlKc+2&bCm<0ii7K>x!OyRV_t1&3vKh8mE*) z*}a(b#-G&&pN~T7c*rxcN#fN31ya1lP4QY@jLr+l7eEd!=pl#9^&*7;O_+x3qb%*R z`=QLo`!9|hX2ROTTcUX52JB?RvW47sJFrAoZdcEZq$-5r!oD*m6gGlJeXqw;Nrh_; zp1e8&DtN=Q@?i-*lea_fgT78!n~3@T(Y=DnLgxNX$hct2r(;yoRPE?F(-zgIZAO{+ z<-L2q*AP&*XIn$^Tb2+Y@*q80z1E_=y|kC|{u&9zvB_RCHZr?<-zpK?^AIsFox)){{dRBI^}0p0R+q_Qbm&u-bl)^I*! z8gb`rR;@)u^tt|SX8r{yq)k{zReI%~tl9GDHUwmigKSBW$%ZOKA7FoI!7-R?IS#N` zhodJ)O#H(oMnzRD=%jQ{5&jd)WE+9!XqA(8lAeG8R&tSfpUvkXuP9dIfpk@RKxKX- z6H1mCbA;8`DxgV?I@;K*l3~f2vkY@5Hyu-}cB}tXfOiMW61Gn0pGpSiy6#&wz4<|L zgE{h>d%%^|JXjZgjFKWP9eAu!8WB_;5DPBnFe_qtcuUWAx|tUAS@Voq>Q5>n(`-CP zJF0d;Liq9RGLQ&)_4)fR#sW{!nukU{q5f2V$r689!@_)`1S2u6&L{O*l%HRUSN6DO z%#AttTnD~D%GBh(Q{+2Epcn%I zRU8}-EwdfcWp(m7y6S}MmO-$jWSi<5!FmQMAIj}kEwp?hmdnfxUU&cpV{Qip%Ac7bAz;!Dr$nf0j?F^(IwL(L2Do96jV(K zTp6DbPKeqI7m!Q%3dW@mGSuowM<>PO;yJ;FUF(TalO$m~mOD1@&n3Pzn!jr5_J^qm zMi}@GEE7IizlquP8J!+;yG(U@g5Ht_xD=k|uy1_+NpAgherxm|N7=+XmEan&Q>n7$ zrS>YH#-?Ygy>(oo1sqi99&*n8IS2ObZOSScVXShkG1djA=JcH|IW`}+qBDZqod74= z+v?M6Q*npR6R#YTS$J}M1Bl5jnLQS*_=_FPxnCb6Ai4q3RB_#`VLE zwSv4GN7cO>vSXpqJZF0q(ra0iVuip6S$)OFo3ov6N8k8PCR z{ka}wfuogNubkM1o%9|GiRRMv`n|W-t>0-7+9mjLN*L7X4F+yYm@>OOB6%hU?+ih>1<7xjr)dxH3=A*~Q zpAM`ap+sc@)QPOx%n{%P%Q_W{8GL?j!NeWInJOrG-*cu_qCBY%>6cTlq{L zCwXasB#XgZ2i1%-uoQVl51?2e6w=$#T>P=f!s)1qe+A8SAKup`*@#Ip8h1b)<_fJh zQm2fhDJNzo%a3x;{@J_vXTPRa3HGB0sm1;~u`c*Y=HTAD=WLh>WTn&XAJoZR(xL|R z7J&z>Ce|Uk6l)=1w;bPjov3ykR+w}YRd&7) zLc|2Zxm2)4=RQEi36@6zZOQsWdu)%E;5LywMN<(r`1rLh{RoKb@pXb2sunM2s}g@Xh&PJLjP zk*V=8pe2G6$GE?2=SGx}^SeqY1GW>{T)d--^}-l?XqmRs^iCZ0Co3t>(KB2vHSKpe zST2duoy(7j5fEl3^&jx@j)ixHR*oAgxp5J>c^;K~(}Ardr#jO3HE8R5jzVmBvRtA* zl=ovF?%Zni9ejDHMv6p-`8m(CS!;AbKOriaeOX}tAiV&|_s?ZUZ|&76ba(G=^zjXR zO^AYpxU|^2chT*duf17)VvK6<g&; zcQ5tLTx5y;2wV)Xw;Dv<&x1njIW(D(ZF{9&tU4WpLP|X`D;b3=t+PLcl6~!Z$eBr>OfNX zLiN4b?o#I74@4#_UAE3?-14++>`(~%@U$;GF}=c|sW0DPtuOX^9PHI5Ki(0OLC2FL zyhd=^tt&2gT<4u|Du5j2-fiF12xmYE$_(Q5tEA5$O)GwXjh9t91}c#tXr{}i$VU)< z9N@KA>-wN{tZKg}y`!8YO<<0f7Zfb&dAM8JvSjC8f?B(L<%Q0>+ALtv_r9-6T~?1! zim`Z5?RKb=gmX@1>;~;=UJDcia;wmzLgO_o$H%knI=zH(-O$_G9o?J4wA{~xrj1+x zxp3w*UzFwnt&t6Rjr)P)JZLzXJm34FZg(55?$@Z{3Jp1bM~CWbORth)qgnq1X!?Cb zfF`u+L);-Q`|ec*yqI|&Xqk(Lh5bM5y=PQZ>DDgV0t#rOC@KnqC_w=MQF0bkBO zQ6;A$gHQx9U?d0v5()&NkW}PUNK`>`rhuXVC1)i=5zbs4_U?_Id(OCHeD}v4``@yM z!>+Z~yWV%sXFj3c;_+nzyp+{r>RSzSXt2%-en`C(HS0cH4c!B3I!~lc$Q)Set%X0N z_Y13$6TUv##g15fnQ`54Dorv4g5wb4{v6rVzif)aGfI~5c^`%^7Ju=y>gr0Uk#7Cq?!>JpB2)g-Y+$Ku zYeQ$Il#FT%Ls0y;wzDP6xQMTAV0B;}X2xmV{W*uWc2QoT5sv=IqfhZ$F*6?-@4c@u z4wRmt%GJd+wKwOv%`T@$JX#zE^hVGKK$0Bc#?)xV_2sgyJnym@5fvHmIIEj_H+m4S z?ws6O`FM{CFen;+zktq=Hpq8^sF%(duUqM(-o|{^M`h9Ni#MD+;8)Z_g%b)qDvr~w z5y6Ai8bR0IU8bJ)c~GmrZJD#tBjyK!QiaZRz9w*Xax%P}p!pP!j61Au<=%AQ)v_FX zgo0iUG197AbCKnWoOT`bA0BG-^KYQ9$DG$J-B|McZU2kGZ!;mg44KBpW2~R-Wyz+< zkqtiNJk}a4VXYSawl~{U<;(r54R!K*c3t+(IJFb!ttTK?S=&BGx}~ejMf01cxwWOe z^ZE+yWUMjwkLOxm*qJ09IM;HdMxoMI*!A|6(DiV42(5@KJ4Ifa-m{j+iz}3uA=^CX z-czuU?B@iHy-Q57c@t}n?48WFf@5`sKiMPw4hZq*?*pyERKXBR5~g}Kg`NHd;uV#g z)aY#8la`nBA)&9W+q!IX=>-UOYIf5t)e7=j6lE`TIJym*>DutgiYsd4Aem+rx}zTy z61>-z%U-;A!9b@7AuV=h`9)qrAKIn+oc%EHiBpmme`bmMeut<1)&ITkpQh{QS{E36 zIjBHx)rK9<4(_mS&tDqDf3B}ojxWMmfI=kOX*9sT@J=V?Gpgf==$R-MP2 zK?P7ze-B*90A&@*Vaa>IFW8;=)u1yCKUnG%|8e_vrjG=&sKk9aPydt-uDXsWdia)K zqP=&*K1VW0Qp3=?EGxyaLD;n3+jhxoc{DrmMSXV23>xfNHVH+ z1MVq9pm1-d0GH0!>KN8wuts^-XjK<2o|Eheh~MgXQmpB8k1*7jw-Mu!u_sp_{KQMS z16XF|fonT<^us7=)$INFX@EDu%i}RhkduauJ{fUKPUqy<1E;-tTDMK{P;XJrEALQ` z?azsg{xY1iztexFS-AoSfZ{_no&7XmbbDCYkNnf$MNW)=!8_iFvp(@@n-SFm_z62N zd_DZj$?6?wqbq;A_VRupTzCp~IUn-6(1 z?LQB!KR@jM{`~(w{eP{y|1O^Ye!BnOwEq9N^BB_gK0nNdxQ-%zS;|Yt#8u}5S;bFQ zYa9zV04WX9Z^9rb4*&TlSm}>e>$(=~_Ltn<#V9P1#8x#rM*mA}rc@seLNAL^La=q%iJ~jluwTx2_ctx~mh_m%dgXhGna_Gn z5j>=_3EvH@y$JK@8QJBH70)vLU(rqF*jnJ6JAipjeKN=fu7anVTO6nkXs{imC}>Y^ zyAqK-3=UP*9G9LSq}>#w>(xH9r3>J%#e>=5T|b@EhzJ%1Dun6F?S<67dYW+6c}%Bt zw=Wef73jZ%Ia7r!x-Kpd@-P4zdG{9U?R~R5pW#$MUD5pLP)|o{u#DF($r6*9UUv?# zzXOk|N0WyoOA`E0dim?s;?;ZqwGI9ATvI|!T@G?v$-Vj>(QGYiM~w@(JmJ+ zy9UEZq^CgCdMOvYw>hpzf6e>%n*Zx6=pceq#MPePegeh3Ut^7TIzB$m#{-m$5EyNe4EN!jnEvVrK^K7BZN^qY~ zn$Ck>IU;Y@K6l${rJvr)KYpMRaN)xarbsdPnsCv-M1HD}jguOC@{aD5(7L;iEn;5M zG0AZ5le*d*)0Z5 z(QEAk=e27-)b@=#UF(^=xlLz!#e>h8?(WXFjruUB+;l$`%>0b3I@87p=nR8mu8&Uw zgEVATIn>b<1!5f0+qKgJVK9m;PV@^2yfA=;ng;beFlv9HFx7+og*Q_4)qvM=XGdN( zACHwE9T9pZ)@03sSKy0z%X`f-qdt~#_>sMU^DHN@4RV)z9TcsOia6hn-qGBgZrK*b zm8*1Ov;l7y`;z4Zqk!SlHvXVfsA9gyXY^M>!9kSdK3(O%^$IXE@#?8{zMyla%3x2A zM&AWtZ7bd-s!U*)MU%8W46`GTNv*h<_5f?)PW9Z6>beMFDkm}N3F5MCgs^p(Q<^03 z%f-ZgzB4H4iiiDP?~@W-rrx1J5aDC!<*D56;&%?q0E|%7%xy!?!}GSaJYvurtnBM=4h3p~YKKk9O*raLUsDf?2)m z8HUm=LDLPQ{o)-AfY_PV7R?MvxuN7efImp4^HLa&>P^65=77ei-1ot~p*@i?(WcuG zW+{h~G)gH78lptIU9VkpO3;XvX_TIk1e(Juf+4yi#$&0QAED_j*SVGf*3??$lrRL& z9-VppK3fJ{>d_qFe;(ix1Bo`<7XK9~=sP~;3@OoYxWUzs%!7sFz8C3fz}nL~4cgG! zr8V?<(qL^=^o(GsFiff&*)@bMQT;i0R|#C}tNi;D4s1RJ(2H2EG<)pqZ6qrrd=BOd z%3yyv{Sk2>W%}e!gzz>#fKP*A#M@3ZMXM{k-zU3%g-i7feUcgk)*}LX*NH|kc&_pa zl60T<9+x?ms&w(GIyASaM;vCCb?fkpj?t+x`x z4Mlv1&Y^M8P|nR1I}nDQNN*24xb*y!)@6JnXGcbvuO2uxnyk*5=C?Kw@t&JhDDXEI z4h^*P*mw=6N^NS!QZ@na>ecut!TN3g?%-nu^L(Z(#BP)n&XS=$0#v|4&Mis6X4Y^^)$&I4+9R$ zm$k)yP~V6r%0HgFj?))!arxvt*}Hn{Rsjk_BKUxViw!pQ7#~y5c)m%^fz^?yj`&bh z-7IXV9nf#G3Hc}zPm>e_!-I)uU~^iVpv1rl^O_~RcBSQM*Y5)-7&Z^(TZa|RV9pIY zX>y8w$#>cq+}*2R-7^ZP?iYXtk$GNgmNB*UTY?K+@!BHu7f9cjM(16hS|V!J6gmiM z+HNkiX#i8rYxgA;0XZSr%lu(dW?3e_vN3fzh5(#hj= z9pL_ZCn>+(X=_dAJX8(gCB0=nvXYMzSLk2L5# z#pR9k^imd#jpe!ODlc0e7UqbSbPMnb=xfUzFS9u^iZ>#cISei@+5dSSG7}Q-Z{Vp> zR_N~o7sxY2RB?lt6CX)f9+3?gqDR;%}Ogon>3U zMTpqyo{0tAM_*>;_L~iITiz_I&j7H7oO-QTfcWACy$cWAsh?j4;LLgoP@VH9yp=m~Bw&pr~oJicq! zu9;y9bF&?X9g7Wn!S6l6uw>1lQqDFb)J-BZ4uwlTH|@JxEp4BwnS@&hHWyB%(GIZ4 zM5wHmy5`9WeD+Qf)252NbwW06$@0SObG^afWMC;FyUKyx{e3c{EKJ96e097JHmaWQS%f+?STWkR|2qVc%>VY4-q-#hjq3nJn0Q-u zy-%if<*)s`hfz(q#m5eRGW}{?<@I-F29nV)7=1X2`KaA1&5e=5n$FKJV!ma-=rfBV z0*2fDRQfr#v42FeND~^yW3|<6yS`&AghTzrfU_NVS*tpeTi zo8{4EXPB;;PIU<`J#)T&=}kKTSJVU; zg0B7NGgZ>c({(ZofjLLnT{KVKGB61tMTX>W(+TLuQHEPEfQdHKjT#{~SC%vcU! zh~~O6&0&9K z3>35n;j9|5RaQ#BZcW05M2marwkD`qS7KeVMb@IIyg&ChJU%bp!X2 z`tdSms@qLo7?E`KHsM^U0)f(%%CzdkcgXK2i^tnv;m0M+B@QK`M9(GOjg|45lCbvh z@$7K$Xdr@>4&Qm{JF=s}sTz&61sG^XyWW8}?-ih1V0dxmwvdDnf5W>kAHKHQ?_UMm z^!FZH!Kq>-IxNGE`04>4NR4K3`QQr}hlpPIcB)YlS1`y53DJ5WOO-e{8Rk6RTDP@f z#LqA$ETnl?B#Yq8B4MC1OP)2xeryj>I#gH!xduQr(A4fe^;nThdyjS5E$=zF{$!{w z%4k!}tCkAYUuzmD+;Cvd9kGpia-93F9c|~DE!?TlByOW_76rLAH(_*jmni$aobsIU zW!2Bf%wo7h$7r4`-eV63I(Wz*LThZS(Y^e!qiojANV2g%N7T zYeJ*=Y-vclFU;t=RYQj;ioGLB2}CCInT;R4WrhPIeVY&}9qh9uY4#Gn1%7xEV zr5-E%;b=cw_lAR^c#JeTNp;i4vpkjPtb7H764b=1<{#f&&p|JvG`SBkG#6YE=%B|~UFU6ZUb{+g&4CDk-{AOh zf_xe#vc>Z50%*xDLblhqhiSACL5xM(qh0rtWjXCnm0Tg@&=fFZ2QO2h#F2sob!C-} z>Ht6emvS{UA#w6Wu!yaMxXVNWm}S(eCa;9|V<5N79}YLgnbJ|#(U^k;i9zU@2D2vX zu0$dn>?V=PZ^?_{AJvQHrnS;;UIU9~D(U;N{S$kIcp6+$f ziIZ=ETTuvzDOMJriO;+U@>pb2se0+QX5;hilf$z}=>{!kmgR2#WPY%Cr`H_T>XzB` zuzoL$>b(h3F{FHqm_z*UEE4rI(Ch00FXzrO)JB}ZW6dYeY+0NoWb_jc?B9PUrJylt z@gu(LHV%Bl=D^y_R@1;J{nCrD_=?z3ZLI3ioGLxVq6Vrkd`z^uQF4baul5;+^yjV5 z-^0^}WIl6gyS!>~rxBs$J~JNLCW*V9)3w=dGz% zKd0Mv9PI$02{5uBXWS1^)POXKuPBghLy>L&Kl|ZHYYaqHR0SS)CkYdC9f7;w=s0TN z_L=+{86g_TP6a{K80Y(wXZoo7${!c2ZsqnUB{535P8DjUYLm>3ayMX7c&Tg_&Iqg* z9nmmJ0n)!q^QlK0F(F9F6^*P3>cSWhYz%G{LGh5=OCVRKD`$d2uFDOt#$~K=HJnn*W7p&CYOcX$! zIRxAgN9i>zrRellK|d}pE>Ju8%$8%ITh~@0t*a)*c zyjK;BkMW)$o@t!#+MaC!bu1{wi`^As?w6+{V!YIs9R0rKYBW?5_H8)rzkn6=Mq6pg zfkVO{&CiBPqxV|2WMgb0roy#5-z5YpfA!eSk2r!Wbcv(-nXbJL--9e595f>a1-!>S z&#Ho}*li-j6?9N(x48Cu@xiI5i+7Gl(<^B7I|J?4K@9#JAc^_u+F7>!r6hM9Xgy88 zeWJxOoqZ<_sYbiNlRoqqL}2?#0XXJJQ3S0p6hpYi5+(}uH{X+?gQ<=oW*I-Z_0A^L zeRD6Q$mP(Mr#$V;h}z`UM%&cv0wZtf!y<~D7zTkCDA!{V2{SH4nT+k!LrO>L=P{)6VlGw|;;ZOq4R3AH^A z5N^xC=BdGemwS@nWB%|~x{OWh5ceq>1f)=NvG6+IF=0v=T)DK3bM_nb#Zc^0U1aqw z=R;oAi{Ck7eajnYs6d35*9GvR@xwjSJHyRo| z9fL`d?sMkX-(NjJUJv7oeFdGY!Lk7|?hU;nXkAp45rsXZ4DU>f)o1<3z1TQk!rKcE z2dT6@6teCH)_i&OaX3J7=IQb#up@dFKRT~nS)MK>&x9z2a7DP(WaDE4@-k*Sh5Muw zGC$GuMvB^@c$N$U7E9q}MT{RZ#-8+dIYGM@b^#yOEy(83F}xR7JeENo;k9oYmy}&K zc`3EftT0m`MrI1&yP0`)f{j?5;z*+OVg5{l7pPBEBSve z(!jKUNLT5=Oi_Sb@rk|nJU~Hvh~_dR61DT3pd$%+wyE)wMjB$LT|8>ExP&IaK`(hk z>6C7b$eqd~;x2QKN(8hvL0lSj%i8wUbb$87j&x>**ZLVgYia;#)d*OHBrVkdOWH%d>ZeFB8Va$`D}*ishn@LDVjto-(LoK%(G%8t_GD zgXfE>HykmNiam>C&bt)|*iAgD>y4nX@eQXUT!!I>e|lP53LYvlyn6MTi_yb0qq0pi zkGk+@{`!vC8Lr>%3OpUyz4@F z&7+A?F8lXLjyfxDT{f$KbBBlJ)Ms5|0d4lZ+aVmef55ScNST-Xb;y{$P|)}GPE-%^ zX>^h5`_^_^5&#E$AhUUW+;!%u=Cn5Wv4Xh^ZsUuo3S$jct-rsE`qal_q3^A78U%ew zueDs-dhak;H)|W55_y1jTXMF85YhI?;B13sYeMKT@oW{qREFT*xrEj@8@pD>Y0Q>M zvmL@S{Q89!o02~4fmaSMLwTVGoH?YOeFYE{S78&=ml0UT0Y7HTw)oeMGyk-HIMM-E zXYvUwczV9SA%pwhB6PsD1)f)Mja&n&@{RJ2 zQs=#ewQw!XD&GD9~w-tlQnlTuc)zj%exrmk8y3?IQDCf0TsgiYXX2F>LfgzE|mbAMC1p@l(O{2L}we!J^2mOg&D_6#9R9vHTML!%S#VI?6XH8^e*bqE z6OE`mvHtmQ!@qD3@lctmyhT-c4Q}C>BF64=Ir1ARA1VA){UZ3#I?_B-KI5W!^bA(c zo8N_EpWPRLR=`N&*F&~)L{ja>*m#mY0Djq5u?f%f6s&N?%69DJ&qxQPiade8fBcHj z1vX^aRGPe9Ri*MoRCcXjnSODn zaR(8%a8WjxpB#Yjr-tyogr7e8Ki(J;`$~G8L-Xhz+^|@HME}eC$Zw>kdGgB#x`LQ4 zQ6EsFr(uAq`0P;&8HODYZjCB+F8q~w!TtLH35(A1M_*z)26s~F(7tL$B?Y%GB`0=q z`{9V((61XWcqxe=g@5_RJ^)k8-RU)ua zsuFQkQ{5HWbg?`fZdiZ?_bZPawgE)hU%bbBKaC>Xu>CQY(xW?&=5QbV-v53Af4s5( z=}+Ljl!)@*UI73791tAhfBJKfd%p{{e}54Ndg&O_^4A0jzT0@@WZqQ!_yyz8*ej#q z?_U*=fs#>d)vrIwU{(0GYAoE(Qq-u!RX5#HP;39#DbH;WhMqYG1q^j}AM|YAWm{UR z{V^Xny>)(c{k3rl)Skk_zupF)!8R2(mLNs%YXUx9VKz?!0@#D@QN)3QLmhLu_BEft zrRP#y+}9JXe6O|~$cM?&9MMjZ!BaqVJBjs=UD=);wk*;3Dru;2;i_PyaP9^T#}zof z^?)3bc;O>gd>IZ<%8E3I3Ph$0Vap> zh<}QD*An!K=j=9Ziaf`I39Lz1UR^(V(y_<-$-b>)yg|I{7T1!sk|PnV;F8Dt$0+cX z2oraTkDlex%Z~=L{Z4VSQ$kcTCCi4$1S9`EQn`Wbu`bVACxcjoIAFa1tGQVi&C%tFlgIXEgCp~ItH#F zgw=$r!x1zb8py*HM=dbOl{%KUFPrF9e&O1a!yEus^9u@4%r&x8FwfZ&#;% z4Zl9ph+*f}#0Ej@Rl}RH@caAPN3^lE?*e74`n$1edfmB}Z7%&r5a{lXAQGhY)%oE? z0-Cr1Wo#V?nWi@X8V;4r+z$M0R*}saj!b#;Gh?(A z7Z{)q(oS|1<_1H;4YPEc7tbT_e9Q+0lHx?WEeGOh66@W=J3o3!{6y~_61pZ)g>hQi zt@o8KxRoENR#hl~Ul`fU^*CB|vefIG>m&US_f7yn7gIQ$e=ytrs}ADDJDSHVx~T{= z+0kP;^96D+2QeM2nw@?I!()}nPTS4WBlkS?h_Rx_o_iMCbj-@IzZCl&@p$p zVk9orf(#3TM#5fUa2K0qP~5q`;gQkj%yjDZDQ-%*tqT-KES_&G^5m{Uk?^3lsct_F zH{5#=(_V>(a`u0rMxRx47%de94RUPPS6(#=1#4)fa_-!-`SFpB4yOTrVQ#p+X{b4l z@-P-y6s~+{q{W~EQC)G))ye#mLm~LJ8n&6p+M+~5;?4<^zlIc9hHgL@2IrIj$W|A~ zYII`5X7d&PIqmJvPIUG70!@cn8yY1>)&gMWvfUqyI zVYj2~_JTuH09yQcKdBwQdY6DQrF~SXl+rhf9xy~~oGzFh*#%a_SZUMgTcW8O(o%w<>F zt+;Tr08;M1K=Vo27kkw!PTly8jF$wnK4@zzU7f%v<-pPI?ip(u=JzhMeO_*FwLnu= z3ex#elZHs)AKAjTJz9oddEq58e@z*U^BN$ZLAuob>jV8#Pw~#YDDf-L%lTec4Vc*! zGH$CnedS;;*{K}4%tpTkJ87Kkpo2N1n=6NGCYnWVS0*~sN9Vl| z@`covr)ctx)G#m$sj^JfWPsr^;gKslr-Ve0_-qmIUk*WJ^1HEIzZqa+ZJ5a?SR56y z$i#TGZA4m^LCo+7sYxZ`T%tkJRK_kv*vvyfqVHZJD&gTz+t?aqc|x>ykAQQy_eS6T z^f{F%k@Wdv=~U=ZjCZ!jqSdHA&_0Grmit@+q}_z@v+Pa`eX2=3>405Q^_j>bs!3t z1r#z~@|aESDgswl<794_kx$7@m|a+ z0Fm0Cx@X20ES_Sc?mJygn?#Nuu$6gpUtBY7eumm-b2W+9ir90%V`F_0#u-OHUS*MiYsyG#Iuh-Ww64pKbCC zBBQNZYR{$LY^xQed+1EWyQE6ZtE$qZR7>pq_80BK!-5yAO(gGq52D@Lt@3c!A_iUZ z_zJGPq0eTsMMmIerkv|+A0H@j!vk0(Z&H>3^3;*hU#_0_eiruej9zav&rwl+vy=uf zB3FXs+6=GPez5)6=8%0?s-=&34Tr{X-6u;lTEl;{PHBtD88z@tL9-kA62aub_M-@0 z6=KsiYYOA?_zH}634|O2XM)Ex!}3ymKno1Tr?NH&dF_i^1b@#Hw3i8E`DqO!jM|IT zey9`lRIrBG-p(si$*Upsmm){5i>D1554>cV&szUc&0U-^nQmGaqo5u&Xk6{R9Cf<1 zT4hWM|~lwcxGq#2K7wk|C$fw?k!eF*VBBzX&M0 z&(-&jmjYC(3YH(AVsllq-xGE8d13`-2pPc|8JC=^@X2-hyNTntC)b|jv7W$m=D zH~t-=$C4WYkH6t<6e?knK9x~~vvQPIHUZYU* zyj*hbb-q)Uk&`BI6=kJHmMBNV}!6 zd24LH%2|YKq4f){g=$vP>veQPfoep~74nkc4xLP%UZBPq6O7vSjg!c9Ibj5;(I}wt zDVdn4-fMkV&6`irP-NlCr54E%C^eTUop|DfA74zAb_Ly$=B8ab;Q~gl03hut2T=2z znQg(>{8iv+Iy9pDGNyBnrP4Mv5N3t!=z65TziGrNkb8%NyUBaAx_(%#{wFf~qc^7+A@(~8!sqv1~ zaN2C9FVO8=fyt!m@Q`2=N`Lt#p{FgG)1@t$&%7z%=y_>Zx6TPsI+9eu3WX@fOe=}G zgReBR5r!mI!UlF4sYhL22-vH<6jV(U%w!opzWvKbA%kYUd-khBR0jaI36nb;$!^cP zo9dkXyhvh#c5)u74OnV2e3q?P;X7>-$mD}g(|R~uyWX@WxI=sAczY=9q@`a+NniYD zCUY%adg=t0pU%Jei-fU1$x(?Q-j;mYrT7*1A@ahwG2vDlc`!Ag&AKlizVvQxP6L8| zhZfFwxgVileEge!q4E>`;y6)-lDd=^jG$a1IWKpG$ohCA^TPT1uOFX8vHf5e?doTt zJ6yKuk%c*|MTnnl=fFOS-0I z9r=pqY|J1_I3Q$Bv-+pWDSth&mx52{Py9@sJ`DI@@lNVc4f%mx@C~Er1Bmp6p~#mD z4v_LZH*jXF*gyHJ1>~K(Hx(f0Ou#2v#+0JKZaBL-(v0>8cwXj9tzX%XR>|zNo9xa> zy5%-)xHb?7E) zrsEnAPhQb7+?D6FTZZpS*BP(6VK?2Aryg<@d_c~Fg-9rLLJ{1YZna-ty&GO%by7dh zkgZwb;o`nbdL!3x=p~*yr6H;y2<)itd6~c?KtC1vvl4$}C2P0O!DzNoI{MGG!2zGg zf#~gO4>m9s*VAWcWTVHyZuC`R&Qp{EMd1qp@p%UL($i2vhrsf!U2%A)I^1l8D)~_o zCE>z^m}2&NHA$;~+|Jriz0`Ja^)J>&A@zxH)x^FiyQOE#9k^Of+wbj~Y9_ONC0HKb z#N;_W0VWTNH#hLk-Bd>}fxP0&mn-B(@D1RP_58M_^?b(q1)py272qTa_mx(=ozS8v zSXm2io@YA4ua~a{1tc5vKH=sumXL^bCM@k%PA$mU8zdYAzhVnUs~8JIPhXR-dU@2= z?pB^vsMOZ_o<3B;sL)hfvqk}m6ccV&`YZy~u`ydO{S>wu4*Q(m^@rOU%5oR@R&Xj8 zDXA(Ev8Ih*V8B4sF|wn}tMX@7neEFUg2qMtH8c+08&D{#fH~rncT-FW(ptLqZycu^0pd0h z$L_kh?mpgI^nz~W`9bcJvEEGQr{Cf-I^!>?v;3*K0 zC22RaRE10=Abx>1gz0A%2h${jdK9oYaEun>0&3qdqJ3k0{!E{#tR%f6!aU-{c)G3w`_V&sw&=f{tPXY7`-&FIiv z^MZEu{Iqq~5*%AZyX8D-F@T81avw8!7TV2(+Q2e-#VT!>6)r3nB`K;bG}U4Yrl_q2 zcJ(<^wDW=5=4!DrYCzMwt6@2i1EQMZtv>W@r1z(^97dLsPOTd*Id=jl4L59C6P__h zG{mrQ+LbJZIjx%g&EmN8`VSVz2fu5LdnhvpS?^kP#O(?OPNMK+YDad3iKoF+p#3fZ zT_Xt0qq_7&?fTA46WxM%b#P*Vt#U3yU%qnP`~6({f?}BO z(XNL$HhL4J^xgMch9cWR1n3wS)%k<5@gjL(&9dL{+4IP+=ik)ENI%K7=x%hJ?kzIN zwqgzG!hus(BL+^pubm8e@p;-k9-3V${_9VOmW6%>>(3~ zHw!@wjik*a8lZja*_{N+rLKJ4&)7B=d_H(J*8)#nRrvO0v=x}2VB@V2zQ#?E%$@uX z#s*IBl0rExgG{KD`&^e3UM9j%npiL!1Qh$I-_o9!7ztQ)+(4L&nd(g>n*nUo8*wK; z&=F|3O$$XCdF7Qa89e-a+lEOFN?#qvk(c&{W!@WZSozElrzzWNodH)w{-S)5;5O5f zSNF0-8QPbO)uj)vo?EL;K0Vc}63$;#O}mxVW2DAEVDEl@j`-!Er(_ZnVhXzj+sz;K z9I=S)+77|e2*WeJ%DjK=q1<->(jJ&MMeV0K>U$fKq7LiLAGTF}d_#LO(_zpp+iE!b zo`NVwJ==X=Bp-J1{x3aacJftCCF~)me7Hb6n4P4X?|B)T*%9yVNpGl8Kj(!-k@1$g zUl%H<6^7xETlR>JX)m`%PE~Nz6SIAO2wkszh2&7p;(#kspXx2r#Jl+js)u%ZEt5{c zlgidSitq8*oG5nj7j2?HBS=vIE(TH0OTvvy<^X{MNV{GuA&Z}Cth^-tsu3WnC8odu zmFb@W#E2P*wTM1d3s3~}tdo$9ZAVI;#n?#cDnPlUhL>@D$DbR&-MIVHiSZhN6D@_t z_E1zHO)yT@PLYiRkztKLvF^ggMfus`Efa|!R&z?!1tMx6U52yikO5hlx0_4#2z!$H zW(n$zmt4@+zZe#e{n%k?&8I5MsE@dL7a1wSJh(atG z=^QA5x(glNO*%*SgOrK6U@yS!Y7cp*`zJcAhrmAOAm(HX5&JKGg_;2HD-bfDpm9~t z#Cd`{VRoXUzpGXvJ!KMz+LO*{Mi?%Kg|TZ(`mmZB7Q)($4G5W8-WwjSq}(UR18C1a zgbypyMRyoG**Pv0dm}~a#As9Oiw?V{hfklW%25gWk72b9bER6_MUH$IcMH@Y&6n(^m6sp*?pe{?Y$Vw zwhv7oJ%_{j{Y$D1IkpwpI4h1*dfb<5-ud7VJZi|wqVKdX5$P2XRt_KL}(RK;|E_;?_(9x zw2xUN_kk8kIpA0~CxkA6;)(lw-k^X(Rn_bhlAMB92F}3^P{;ZHRpxv0bA^{4j*@5U z?tD}>Aby9^gh02jzL5<(mi1 z3&9@hsf4A?LdCtTT>?Pw37O}zs0kM>YfmO#6^I%?6@)7L4=oNvhp*X8yQpn?s$8zj679G-~~};Zb6y|BF~fdO5Zl zSlPiZ!>HMVrjRRAP|F>v14bZv6(#6^67O@GsJ8O%gZG+ogb|6^P4YBe*tJJ#*=gz* zK||mLfjBD2AwezjNbZz#wIAe8o%OxCySGmT>;iDP5rHw42*?@*YO z)_}&)(~IfXw5%)V;E>>WH(Wu(AqiI|q9)Eqd_OVLB$o4OV(YJexM#_I_4@_p+|@N* zIwErBGK+Zff|=I$j@Q2?!g1i?WQ`A*lcNeo*pb;R5)uJ&-)JAn4}<|2z^$48;UM?i zn*`7pR2)z8B|aZEsXBPD~PbEb&Oo3NY`A$GZ1wieXbtn}yaD33xsoEc( z8)@Jjtn#`$8+GsDYY@&)uJ~|LHEN97((t}(R%OtiT4up8j38XwR}A5*#`?n;ABED%Uz$Z6 zC%*lvIaf}(b9!7F?HyF)WL9N$0EACct0w1_LMQg3y*EE}XIm2jZrVO@Y0k4|w1h~S z`864@zTo%o%P7T0DI~Ecc@p6bD_+N{o`CsL2*??a+K29-TvLIbX~TOKR1pcFm-yqJ zXnQN~yk5P$4J4)z-P{FyK!n{HJirJ7$A9o1ZV+no-@iX9VpB|>K_{q_E(ddKnt}OO z$vGdx*9?^<%_ZUbc;}Wrr)rjD)2`-1&34PN&Rk0sNq>@i&J6LCvEmn?c0Z877m&i_ z5A&}pXPY<8EEo?~ZC!!XjA&!m&BIq?jul)iySf7UE?;P6%4nN<4XiQ&E~k< zRM&}DuQ1c4ewn_y%Z(+K{^iqEoB9V16ao)GZF6>OQ)8xZaIa?f8gQ)~+t+7@Q!@RC z{@qTD|4Fxy8-RU*!n^_a6)v!4UOj$d?TOrP2&CdNz80UL7NrhiHSWP`e@E=gc8v~U z(nN>PoR6mRrUmwOG|MEu?AVN^_Fq!Q+1d1GJ?dpn-PxR2T>%UzP5#3KLR-!9&7gHL zWStDHjutC{tsVzxRMgu5VyOWmS~UyN>+$d2Vdi5b0pWTD|665Wik){25DQV@T>L>q z7;BH}%YU$QPo$fyfNAaP0GCx55u5qvxu0_$JDah5SusPf;+DsGzM;$RUmwr3X7o#f zCKRAtml!ALbKU=+i3p|L<)9EdJO_l9?$SKF{)#l|mHS7@o$(dH)?hyvzA&@l$5IWQ z?|93gDI_z;PiCjj!JPH@G!rew`8R_hg4@WBdAa zwboNSZhRJqS<}V224MNuaPtEnD1x1;#z4J!zU?i)Gs^wjvr|+3@{Q5^8^uZB6Y?lc zzesu4-eVS6bjiWVNZCJ>tPO6o00jYzr$Nb8mb%r;60T5A9xSA{}JB9Mas7|A+moPO@Ju_4+stu z#eCoM+QaTwY#=+ERn6*D#@D&2B2Z#OQDeHK4}Q_ZB)36a-6;OT$GDT1?((o3j0R6E z0~pC-#9~h3(ug^!Axo;C6ay!2WzZ|0{`kblM&YJi|2#;uqcU;nh_F11-&z=SC-1yA zy~bWA0@|Ki5lU|OTe78r3{e589P_>f>VFxpwJSgqFg940Y8Iw7y7zUb-n9w5Ye_jG z>X=&{)x7&S2!~$OsYWl1wO}g+TVuHFod|cf5hvKR;5(ByG9zz=XEVfkkm#!6vNa}jt1cT$;kdix)Cv2MEdPO1B34RYnH)C6g zl5YbQvr4d@rdMNqWNdf>4*zXip?33npEd{R&1wy2|8lLEe+eHB@$6*e42~byYlkqFSigEZd4aU~_|4E=wOLv9`Fvp~jICZ*z1`#eTP(?tB_o|wF}}WPbSoCd*GeFmPq>-&#@-Q# zcwFt1w=0`oG;YlJM#ZcHLWPVTus%ea#K@(2U>brucVJi9PTP0O*0Q<&-hoTkQcoH9 z?D^>Db-UEzfk<9dM!DJ+%EdrI=S|v;d%D*^sdst)!<#ZYx|bwT3Q;$@?YdZb;IZ*( zU4G!rM(+um>_FfSX*sqrWY`3b{HGI@!*lwjz%gTFYfRR3*`*}UrrYU@rIY7W*Q|Hc zC&t2YO2e5Sc(2BQX}yN62wB3cIhVEqM#Qlt{&9Y`<#dk=mx+6)`$Dw%HIaKQ!XqhK z$xP-FrGMLHEJ@fJ<(MIE8SeMH5zFS}v*?N#$T~|**J^tRMABMVi7X*dE z1F7FWu=-v_oP4x%%%oS%;}oaN_c2Rc6?)o|neGx5;A$XRa@MU;l|g-dfKhFVn{&%> zo=vKZU5kVT1?P0!-$ooY5j+{7$FC`f%8Yxtx#VBo~VM(6@ zXf0R|8Kn;F`hCp&VQO7?MprT|@IC6ZGD8Ke4d@DNol|5n*;kv;s2+849H^|097^1A zRTq?{MRX5xDmIBY!bIdDNkKaiYgWR-X-ma~qs^186_c%*E5 zaR$_p&x4$G=MF4T`VN4|Wv9>YV>>7=F#c@n z(a`>Qt7QCn?%%la^taDuDJAJq6f;slb!y>0;KEZ1pXXC;iK6_!Ts@}00)uq8XcS+> z-~IN^N59$nT;GCjG!$gVQ!DE&k2D4By2WHME@JY9j8&ePK_{@3OwG)+=!UD zS>fK48>#$d8%t46d?zGzm6GCa!j5ixZ?ntzGlmFX2F`n9bu`w@s=XS6mU076fKK%% z$)mKrQZ8cK;8+^Oo$2b4ooisR3vKV?DzWB0R1bLI#A_hF4%STsSDI7e#@J6PAtLFt z44pMFGD3A-(Zn?I$5zDqWFw9Y=@;lSucAd$;k7^<6D7z zl}pzMZf(izE^RK2&OFK_l!@}CWwukL6Jlh0fi0vDROcSY4^4zjc5R5l;#|6#q-@ig zknB_gR#rW^-KvRQRp5i6nQwFJsEm|ZWSuW%e<%<*CBhll?dxJ?%T!}!8r(;~XJ0L7 z<(ZRb3CnVMI*R0hRi4dk(u10aX%defz#j5r7O{EiVz95bT8Z+OU8e-gd)(&{)#Bkre8P2gN$Ph54gn6F|;-rW1eBfm?s&+I(4Ry;(_#WP{Jq zPkEQ$%4nwE*r4rg#j2U7u;~!XzkB%fcck11S?)vY9M>2yJG8P*VF`RRC@^dC}L5|paVXgQMwk{-_+s`PjAQeXI@77!Y!UR9B2C(jG!}tOWBUCQC?o%8UyrEr77XbGAKy5M4e@qj#a8 zcbn@x)90jgw9wt}*$>ys!3TcvIG3Syx?bn>vV#5@Yo0^A9#VWWab;kq=Vi5+gd&j1 z{95mW(%-h_YZWF_Y*S>)ArbSBd!9BQr+NThn1`j%eJ|y{&;VcR#g~XWs%z;}1^;_u z%QQCzb&b$G=SD0+7YNxh{mYC5!W&06WvcQg|1u+)`IQ+-N{5<+0d}+C|7b-*J6zt7 zQ<;ulW*po&MmS>m(5}p2_6S%Z__IpaY88a$HW4NYIaR`X7QeytmYXSe0&lD9i`|g~ z)@qPCWE;hjyfvI0OYKTOvnC5pjorp~~MS@0&T`AOWs zW(e<&MdMO6Ih6)RxSIsGHNU5kjj8fe<8 z_97oHE0wMG+7H%@#>L*RGngUkmj7B#QiO0;0NEQ_6Ij@b5K5wq>G;8bXCAjSJ>A-n=Vwq3bxPoe43_+cvrRFLO z218D%u4u7(EnFin&S+lpaO^dHFb=cNuCr568@ce4;Xs9mR?~v*U$-jU{LH9%G3jl)e|baPo$b5PBV;$SI6JnR;sPRw zp8M^)2bKHFZ2heSTjCYHxObYZ{>NqK@Yea3H#CU(nBm6andjkCppwg;e8K{h zI4sqTN1w^%%!T&hMZQtKO>+84NOyc=Y4kClFi!6>eTD=r z!zo~eWooV#xz&^e+XA-;Vbm^V@3L?jy{v@OFPi!RgsDWk{x{}DGfk1gsTQW!p#hpo zuJVt44HVdJFU-kI-Mlw0OF%?c2ENo#M%i7R6C#$a7Y)&T*tLf9FN?a%)yQD0WoygL6$czuz>05Ts9bMg6?l=B{m^z5u>#*c>p~C~1Bu;=G{eQLh z-ce01-`}VrDyS%k6h%NmM5IKNA{`4wX(CkuM1xB2olrzQqEt}?qyrZ5ON34`RX~x^ZVX=-}SC_*ShcFuUV`o&oi@U&z?PdKKru)kt3)Wezh0T zl>@b;8?a2IxT|I9?`87o)_?!1aFX?KX&DKYp4l<2zbe;X;yLKOUC?yw|CQqj5@m)= z|C8&qiCiPT0#QH3M;Y63^^jun`dwRyT%t06rb7e>cg=%*B88H7L4UZ1DJA zV=X<@NB2s7;4VtM_d?wC_|=^ zeAw~6;;d##QsVCYRWB&>6)j076&{HjT&8FD9y}fu#6u2Z{5GQwVpj;~!jtLIZNihY*#&(qLx8CHR5uo9$y?j8 z72w_W+M2i*+2f`1i2d8xP(6v^wkE#;2_^x+Gx%P9Ykh3K$%1G*ED5T$074j>>}8)D z**zAZ+@(|5Sh(D%scT|SnQOY+!q!`>;gKrqFXye>PnA*TV;7w<6MfyDv&S5hP8!4M zw+~IyYzRn&`MrQ`R%5^ds;P2p_VVH5rF$K=$rxl^{GI*8bPBMaB-U!vBGwsMYrkZ?bQXR%_vqnDgy94rg#1!9;JQx< zX4amu0qDPF%jqn)O%(TVjz6kEV&BHhyRvw@tAE^ zOTvB{{uZc}4!xCbU}iEvu-|4X4FyhsIUs|_;{!Y{sKV9H99Y^Q|$4e*P z?S6Q)R4CN2T+*ti=C%3F7VFi%L0;0AkGm*@^+gMpL3+`RrHL3>cdnUx7pUVm3&pxh zJdgo@fA@E?R)#0ws`6Ziw;vN`Umwgy(iw< zS8~ot+E!MyQ0AAn%37AI%n{wgJEWve3+_B^5$Ss5{H14S-egBgq||31%7>OK21?S& z+V1WKLrF=wo-(&GCQl>YtxI(P|E!8N?dWX&nK*$nWfYt*oLvY`8Q3`d^0k{Wr<`LH{_^51wpg z28}DnOe7iI4ue6o=STcm6u-Y;83CR_a6lO)bio&D42>-5*uZ~w*MQXhzw`j~DNqdb z&+LTEW92KL!DMaKd8+jq_|-K)Ir{f!chV7o2#98O0ky|8jWL;pl#2P5N34q%dWjBoypHC8DQ z%UlXB_RgD;W9!m2#Jr7<9XmEt=E73yw<-)%_Z%oLo-Ek+b8>!I_t=mJ)%IdG4a}UH zI|K2zQCTJ|Q`eFY^!uD0zx@w3l73%cyhCLY$OC2qJBMWDuJ?+8V85B(`wup9LhOW7 zd`035`aQt%OPvwT;Gwr+hzi7qBNj59*;N>S?Tv&+b<~R{8^>aSA7=W;CicrtaN8W% z>*a>&yYyreVAH#sCPx{+Mu5@yA5Z-4m#33&0pZ^-F6lcwb?SuE>^lqIz$Xk0{m0r{ zGq3%!Bc00w4|@~b&eQpcf`?}(To>sl)W9H=!kaJu@^q^R*e?qEp!Pp@t)JV?Pt)+n z&ti>$m@8dmj|Nt;GncNqFPC}IE%O6G@v2##{N-t@XfVUKh&d>FSw@C_+36m&!+?g6%QsBr12@2K-V~8i_)oG1Ld#w=g#OsXf9}4&JUw9m z2A`Lpt(u$%gzh)sE0$Ef3B)&1*LLeyuOdzWz|9O1S)zg3ptIVtYb;hz!8lGb<;4A} zCd+5R;El8e`CGfe!&MH796GoC>BEhNQEt-(fI_;V$ZdK_LPB0%>D6n3h(*w$^tQGu zfcJgZhV$L%6uE_Y((Hn%9AdB5u-8g==7?_IXW}O;}O;Nt26G_8^H!`DV04g=$D(i=V(Gt$)+!)#? z@?^^do3*@^mDEVyWDu$Kzgcphe9P<-;ZJHDs|BPK|C~x62PV{38=55)cyu?rtP`}t z!@{K8&f8gG@1Z$i)p%}2dD*emrpfS;kyPyaayDTjj&yErnW(k7-Zq@Z3T2g~e`_xZ zUA;J$XHdD}MKfrz_VcG_*Hg-X@>8>Olb8M^#T7oFpel{|^m~A#DAhyE@}Mt2Yz!{> zk6#j(^0-JGD7+x5-)i{VQ^?)!?1AS`o;=Zm@Sh-4$yo=x_Cjyx1DP$E4h3{B8zXrG zv3)u-UD`@n!tX(?kRKlz025uV>vACQK4`?XHQQWEPN}}U+ril}xp-FlOzu5WF0oG3 zPFQ@jvB!N@nk@_AF(fyuFaSQ%=!39(QVpNYGgvhTA6e>}RJ)x|dRboF(K55|tj^D+ zRBZ<)zxVN+VC!+Pm|Xizv>3mh`EVl;Dih3?76~dRw1jpSK9>U(a^m4W^$x0KAgcoM zE~{I1i!LM|V`$*xO*3dT0YmVg5_GrCM0T?2C;hYmKlSj(dg|LJqCbrCr%nLXN?`vy zg*yE9IQ5*zx)aFdftHmKEikYE{Po_8AHKgoAMwBRe#0%gg0aDhKJ&W8z8<2xJEH$` zw?)2r_hmUR^fVo{9YQ9^rq3R1HqqORzuEF}`nAnZ>yjKm-w@!~?>4qdb#2Ry+7W00 zW?Jraw)XX83~);Y*_foD%*I=El6dF+1LTm^a`wKDvsxTeG5&3kZW%LAr>?lsp(vk& z+AaF5Kj)Ile`5=AWw=Ype&RagabaMK@?W@{)A<3L$XdFp>*=0hwl50v4T5@5>a#(0 zN$i~EiCRrtmrhN3)DG!<^h2b|N{msoL9mwevdRqU>QuoY#m+SGl`;&NDPSNv@0i&c z(GehS&4lqPJd6V>{ z+P+OPY(L+JVW3sJ1xXL-*^v*bwT4maK7<;!9CP&Pfyp^a+EBmOl|E3m1&;oz;%x?c zyZ>k@dW0z;$uRHM%Pn%=mSy+px-r>`s?t5jdyde?bX!CPwKp9b(fE?oZCd|i=?uOf z>m>00zV8x|ETneEDFaiSWANFPj)`rmq?*|8x`1rP48L8WF8ImW<2`hUhQa~jaiXzP zYo)znQ=lHhH4fP3@Jf@TpD3~4dBHBIr5w{eTR#3GDD};oH*OT}l2kbdOwQOw%f+#5 zx25{@cOb6+4oTZA53l11NzC&ja<$j8N~HpNDPc6l%u$IQBK~1=t{C=pZ_VYs4gl_; z!C}5q?RI}YeYV?C9gyqlRFLMh<>m*Ha?xuuMeeiQ%epy%igk-qf_1x!v=#W*1BM^* zywFyhjwFPkLebx$$hNtP-1+-Mq1P0u@6YV4NBY)_} zj=(LBGc@!`C%|{Bzl+Wt>>BR7UkRSuK}S7OYUb63oxauLucH#RE@)Q{lQ99x;#Jdrd(<@Fw?*xvs9!yr|?@I zxh~T>@9@|$NN)w3Th_IF=Mdtq&)is2Z1hCNO}yx0?@GOnzr=t)K1YqnUdpWk2aNQ8 zSkb`1Bj3fr^<~09h)x0My3eS~xxkM{redl^KcOrYm%XjQ-GLrczT;4p+Xi7Fi>>?> zhEr63c-oAN#hs4ABHPEcWFa6GO+{{q`4+ypt~=807ieFS=0Ao1}L8i}ObBXDd}M?W9>alb<&6cVKzy}SelW|_wi_q;Y8T^yTxBJC2M+Vt&nQc+L-+=Eq01$Q zFwz6AEdzwKB%VfCXdGwh?hXz`TJH)Dx%ED$cky6r40;szmfCH@PNxyT=C zuk1-jz(~_O40y`~SDyf0*q$=?&M@T|x)22?TPD2!MkA5~R#fNLUj^`+M^cbd6D*?c zmrIs7QquM~@CO}a({r7-a#bn=_OBGv7A-26CTZK9W-qf6N|{k%ZZEH)7LWQvLDc_D zT9Dm z{JdfAUg5EDUAJzgKxAmawsC@WIm$=y-9Uv08_8H!U&g`8>SE$^k{UH>xu1hAeSIZe z(a?8MQA#R$zKOIiOH8*#Pg_Pb2U=298eK8p7gt+Xml?#pyy`%4uh{?WgXqJ@T#oAo zRUCafc1axOAg_MRFJ=OXw)N z(i=B%WT7|qvKIh-Dqzxmax7O8^>pOWrA0cvqx{oG8v%$u(M9u!9T%f#Bt8xRwgxZ2 z;+P)BC7oI-*bnaf`p{pC>=$2iAg{%{(4MvAuJ^}JE4tkKh+QhvH;+*J&#K=^_vqC3 z{Z>jnCsT}m;xuq|$y?n+Pfv7z9T9W^F`0s z%%j(~eP&Z-&GgE5_1NveVq8n@9S!LLmqU^f!(J`AFu3Qwe!f_*J{;0aGpmdI3gg-s#@ff`(m~Mn2M>GuJc=$Pe8{=s%eW-7hE8;q59)5OFqZgMRT+dp;LVR-> zpbf-2az5VQ3>|*nu44FMNINEAUN7XVQ^<|A2pFw)bUE1!`MyhlJjJ^?GOI^_L_GL{ zs%v!P!q%X0a1|wmR(gKGw^3`le#8GamT%D-MGK@VN)ulXq@-9;b&6EfPvbjqHinbn z2Hi>^HyBl&W7~|T@KC4fQtRZ`7*#GVZ3rtSntyvZB&=A{KwYfbX!fj%tfHYEW8&Gz zoyDl{y35s6Mk7uoZG}$0GsrrfMivp~_&8yyw7gj4M?tyZIxLDvg~;WH84rs4S?rfT z^ZG;lC{P$gx{2JQp}-&NH^57~<=hNvon@}1Lbecf%SsF05V17OK+>*tV8UT(;lv}Q zDlkNY9`bcF*vdyE_BC8)DaF!q{l;ctGBe8;!@XBhBQzp>IxIpI&7z;xAqm!=nAp4v zX$CoBA=9oIKK5NdPaFpx{%$@`6s5^BzZX2=lr@`S>*w=*4izz2!#gxI132E`_YTsUI~;IwP(CPlx;*ZY+alzsg&hdd z4bG#cCIrd5lo@~hlF%#VjZ`@pA)!ajY&V8quGV*9L0kEve_v0+6{>>R+S& zm6MHKqklmtS5S3LrPtV>ngx3Y)^3VD<|^c1>?H5N+H6;hJrf>If$#4Z^B;bM0~D8kGIZ$zEI{w z)x5g0X|$4I1bXddSqJrP2#>KQ<8k+=Ex~g0rD)EbJ~s~*jVT=4Y2qtZG-wG?gqp7v z7_q(aj0(}s6gQDH$C$!vmIarm3LT=&XEv($n%#Vy;XGJccW;xW+BEt#T?t?lVs{r- zf{ZPnBHvi~{Ou`0X^B_#suRBaYBg6kyM}MoRdw&1TL~c)_F5OCDvW8rMS=S*JETTV z_XH>!^dGn663g#yNff)mAv#wO(rFsdzDBo;|AX7) z`HPx)91n0X*aBzpgXD<}>y7*S`r&u+k4|H}!gVhhZ4FmoXR%gj&N6oXo`zJ(b7d`l z^YN7W#t<`c*$ITVgsvuulfbk1R3oH~KYw}GhQC(HkcX{zFnruBv^qqfsx=&fg2w3S zC@7#Mf_CY)a0+m|xkfK6EOIiDF) zt=X+&bHsM&x!Sp$>j6|FS|Og#`*BZAR74?~Hu^ZmoV+go@Y^D`jJ81pAi5Pq8!zvA zbehZXt_}R}r97ypz z-%eh3oO*3Xy7&z0cp_WMtI=g4GS0qa@Vw}A(Oo4M)gEi}ZnYxP8?duAt2GqChf$te zvr4sh_7|*-Ds`9Fp<73jti-R&C_);9%q{4xH3z`FcrIIg>SD2l_}AZ?1}6`p18}!l zfb`d+pA|nZqPj2I{#ba)I7@J$D7phU%uzO>r$Pus+KQ*1UVro2u}Qdk>8B}4tuF&zLD8I(Yg|~g6sEyebIwNH);mr zxwghzmREDHDN%Zhr!OG4yu8;t#$EC7!xJ7AFE!}joHE+ z!QJp*=7PPJdUZSW?c9-4tlQ(5@##|*D^N`#BQ%HUEz&n?w`XOJZ@mS%#}?zYRtS3z z-`Bli9BwddD9Zz!RO-OcmVr^sG2&q&t464ku$pf19tWbTxP1fZ0OB4GH^(J4+ou78 z-W*5x9a9deKcde2Y* zj*87mY20(G<(Yt!ORpa$`YFfQKT1u%=1ZC}Ff_r57dD?lLWjU{(=)$B^2^25B3wwD zNd6dXX~kJQ(Og8FyN_2(TW}+=;Y)!>AoTHl+O#{Z>wN?%N7x|Zb-seffuen}`AnNgysg1SseM?z08qeG%=ip zPwk$y;V8x077y~iKTsgMd%OOgw)m((nrO%aTM!n&1~>=2bpeVGhib}j;#P~p=e({S zgzzA*gmQATlbmhL`nH3dm`Mei0QQcf-|Wy4(twR9YYYDhVk}@|0ed8(vs!cw>yC`x zRq%2djfTH7?++2qm75=9(|`m*ZL2x&S-jJBe`fuy0dWC~X0Wh9TcB6^AfrD1azPG< zY#9f9&_Q_9nT|&H=s=yyX3aY)tH+YoYtr8ZDb7V=CrT$f=;V-&(R z8-eI&#qsm5#=>jtG(|ZzG_M`gds*9_n`1!%fWNUjeP2q?JH=Z!d?{@)?RON54j|WI z5*PbHM(BD92d%72VX&~Jp5!Dl1Y;Q=^qwS6r^P#bC1q9IKkEz0V#7VDU3nuedrpA`2 z?U@$XXD4sU3F3dA@mDIoJE>4i$-7y>8!!L@7-~Jru!06m+dcFSIU~xm@AGYdkBQeX zUs{4c)^|&bAm~D!c|SPBEOAsgJgNrX4re53M*i?U3m#{7*dEMmq9bG;m`CsHRi$}& z${^ydgiim3g$;;Tz5a(A=C=JWzJnh4JTv-D5sP4#I4ae+H(9u4F2Ng|4pM!KAj}U{1un59~PK+Nn=2LM1RN zjyJU>V5^WYVI9HJp>mrerG0Qyng+{XIJEU`6|4UQcQD}&L5=2okGvG41e*h!daRWA z<*1qVLxFhHSsr%<;>v}aMMKniPk-^%JGN8{o1Q6KmKyAmoHw~QXnfkzvcN_ZPh2)1 zJaou!iocyzaG}Cj@Ps2E<-@(L?TA?L@5bZJ{eAafJX|^!)Rq+J8WDGEKXRD6IXg#` z#9l6NXRL4}P%NSYvh$6VVodUSUH{`7g2OA{?}yhjqM1DOKX3EC2YW$)!n5r{(nf+? zo5~>(@^x>>+pg;EHwd^8FW= zXK_i#E5Y8~02w3^5T(@hIwQh^Z${Pt+=)f6nW!1+?<(nh|hb`&zh^HCWr!^$yjGvcr@|Z;ylc<@c33hGluazBW}c-H(>gl_u#Cp^+w_EbASz0nbrVhK_%> zd=b%Nr7-s3x#&yacFcrin85JaLf=lakX$WqZxI?5CZM=~jLO>hh{x@k&kQcffZoZ` zdzmI{Lv9*P<_TC?^0#7Avaso0m!B%Ss?45pjDMw^x&}=@Xb&uzpU9Z&nalm}p}k6J z`v`(LIPI!c-la2xeh8>1N6TkoD2QB<8dLT{N{4r1tp6+fpYEqf|bEIo)9BAN7s!o?{JmI*}BkG0RZW)heR8P;(}!i%^7XR*yk%N@CN% z(&lPR=BInfaEgcaSTG&xP?o`&uYbg5qfN{yWWc$lq?7~=J-ks(8IqCIx;+*7f$C-eAi6mv$V;p)eB=UZaMid37L=AyQLDQ>&n@sJ7%T{(3+eC)DWjjtid=5f#BJ!jArx-H$vNOfDPXw>h zeG%>BQI67+kTMH5O;ZbB=YVTTsQD`I70t3DuzFT4G>g|lV4ETl+HpLkDrJH?+D67q z{U|#bar6X;Hzl0EjN|O=E{{5SFVtznDv3^vuBMAnDbF_(xsi0EtUg5O3Ta`eyPOg$ zzfcS-s(8x4+F-raM?^;0qs=F=-ufNiPxz^x3}PpV-_R zX0L8%nzLlA^ll>0t&#mHiRo|+@2yk4}5v{j^6VrjGB=Gsd= z%}Yl$ycZhb0yHbI&Ji;$gBP6x>cN$dsNd9;h1Y95AuVw+ljT_TYS=_ehK{zsHdeiH zKg3r#I78QB+`70WCP4EW@5Z4MRWE4FeA}9$ZyL+{;|7<0kLK^UV%5hC-5I`K0yo8b zB~%y=#BD1IIN8HYu9Vo&GFVaAvIf{3s1X_Bn)Lk2BO?N(3>#CG52i2QJbddZ0*&?S zc0jLA_;Sa$KU&sz5;rg{E85>bnjqeJ%X@yEkDB91jXy%Vk+rQ7&ZgeTbeq@4H1DMQ zON!oc&9T=%NID@VE+AvXe5!YaBtz2HLxlvk>BXDTL*Ceq*Mu_QjrZe;VH+At#(d*t zXLZCmc3$d`i;kT*uez$jc@(E-?%qkl<&^ZBR%(Y@g+j*1Le_@H5zE+^rTzK9vtl2O z>qFO?<}PC){=NE2AuQTTl}m_e6yBjJ@Qb=hj2gw%ckxlM^%`F*4;PoPD!0Lv)~;&N z+*$H$?lsINp(Xf+09l(}?8=oZSn3{&hWf7RNpMIS(SLuOKlm*#7I8A|x^G7c5A<<4 zg|wjK7(f})TAc-^{!<1xZc{eh12$_%(VYCKs@GS(cn#H1MmCRs4bqU$8~iLjn7-&A zCXhz0oQOlF5%Kf&{6;P6hnh$9LY=~PNT$8DmnOhUNs3MAmFpu7>;7B*;IB??` z=kG-D450> zFU8@abj1uC@Nt+(4u4PzL=A}weZl39cFBN`#-gvdzZe_G z#NI!h!dZVmg@1Trz)j~0P(DpNwOHsLfgrZrS|D`gwZ|Li?3dSNYgyZS!GZo!lLiD6 zc6lbIp2OVBS^T;v-Lsj){339-8zR8E^$f~(4!L)mB`T77b!sP4qP2m;F6RC1ksw`F zVRNO9INM#{H@u|#ABj!zMuIdSZziLq+6mFogAsgfHSGc$)t=E1JD>M3ADsZ%6* zL$ty5%}4!whTDTn6PN^(2q6NWo2}>k#WSi>W?Lg9ceaC?iAA+9!44l5lWE{4)_qiO zQh`56+!<1=t??Ks{z5#BoFxYA0u}PGfZ=skW0fCeiJ{!{xVz&=hNo|N6JJxzDg?}> zRb>aA>+JO^_6j(~YYbTE+tO>cIS`|{T$!o8Exx1gb)gZy9Tx3lJfs>AmEcHomNeQ- zjFMvorW}Nn?LhT)5Y|Vubtp(>O^S2}cu=L;7CXePZSEbSY4aFtyt2l#<0spTLJEIk1a2$;aSVQU$>5PP z6F3+#$*V9P2v)}Ic8Ks$!D9QRQu@W)r3&my)u+aPav&$87akFYuYv77gAu(nF z&khUSl86Y;s95nagVbO8c;n!K?T~mn2*f=Jhw#E))Vbjay>g;k%3uI%UF?jmC#lEtx);A&nCOoM({Udq!p$#lY30q6zRZ)s#p@r>C z-t=v+l-3=}Hs04UG(3qps1tTNcvX5U=9x8Kad|pG14K;R_3pt})K}gx+ybdeF>7;! zW}4#O_ju5UyWO^L8P@3(RK<$Lbn7@HU3Cv~8ReKH9-Ke~_)R@puvU0iI;j^L9g;!P zmLsmfVVaif%bR3z`;q*lr2JJlaMp9~aV&W!&dLi$@Ps-^&v$dAFk3v!*bk}-z2;K~ zF**L0K2e|yq!XJH(ilU{4R7tLl2LG^!hMu4pNf{>Cp^gC=1+|FLQ@jC?ER2#_Z=1p z-hO~|{Cg0KzN%B#NIZ4!(Go+e7g9exFLYULnADN3kmZ%3tR;Eqca#PhEnub;NCwAn@{?xev z#4-2gQY9nJRKswqEc3cvOQc??axjs$jw%751rMV`N7q;Vr#Y706UF1iRc~P57lB}Z zAiZw3wF_4w_xv0a9xSem*yUOwdxp?A(^6&1? ze){=)3?gvgyz)65k5Rq-284t5Uq~I#w`l>Esh94v#VWaOtTIM%VsW}%gBMom)*nLb zlmB#Ajpx}BJ=I!<=Rt}qkyyVX_^~=q^fEHMPJoBhJs0EeT$!skEY+qG5ktF-xfFM^ zBJr*A+PWI%oehx)V;gy$sA3w?RMf zk)wgN`x4yOc4Mh1kNHx;A)3`(tc*w(M7{!@>kuJ#|G|X>FMumL5F_UpKbB)dl&e<{bS~XAr04{Q!j-lR2 z6WY?suvA)+>HbT24*=D0WTtqWagzIFbbNrgx`7@C9sR@!aD%!lj*oti)^O2<=4*}7 zIqC?~oH{>$Q24FYuDl^rdPIe%y-v`f2%f_3X+q8C&l{4uE_rzRM%_zXi;cVSN1?GMn^8z0kit#^})i#9Y2Ai$uFy~2_hp6bIfDb7Ftps z9h{qWv&!+yTDBE|e-TtF#!Nw^UO|2+$H#dlVZzO z7DIv+XRmIsOa%c{9 z++4=5xH;P{hcoxX%1MJ2?YZ2EmfACJJRpyR^8i?Fw~JCtnBNP0u-gcB>zkfDBJDL$ zHa2fE8JFWE69>1Ob4vQ;GU*&|a=z+u7%Ui`OLR~zd9^x2nuW}cq@pL+fGPu)L!CjDh7KFw|j<(~H0PEa}d5?F3~BvF|FyL?W*QY6v2iyC}|eP+wX zc_Eq8o}GX8$&(;Cv%yLtmz;0udSeQwfizwLe;?82kJ;*-v83Gw5Z5gewuBZEY_)$I zgDDR1c#>_uVlc%ERX0a`L`nuXv*cZIU+h%CX)}4}_SYo}&K?G`e)qCPJ1pbL7FM?6x`iY4oMdFHU zufNgWabm+PJXcKT`Iaytc4TS@DAz#AM+MKq?Jzs)5yZW9DDkMcVmV% zu{_NC%%)XvhJfgwO!E%}vnE50{tNNc@uUH{b`)a18aPjZLO^+r{3b}x5Ji`c^mcHD z6<^s)O84`&s{9o<{y-VG+i((^4;J*Ko zT^;7hgMXJw;KaV7a63HO7SUH_Z|f@Fk+35$9CRaG-sA9z)??*m>G4}XLJU6|tw#cv zlI(S1cc6MEW(tg7&A=JbQ%-aZ7&s21Y@m^An+96hsr^6fV&n!nT|e_?(^qHfXRz@`G)ea z$*i9d{}TY@hkA+J4_xP8qEgo0CCZ^DmH2pXeT|vvV_-I}0W+)8e^D$9Aa-lsmoN+( z<{H0>p5SUcct})B5tE;olK;GNk6v$FE=PUybARElJYmH zU7<}sgz`rt@X3CLzGH(s^^w(Y!G*7A!+mF6dWPdH%$3~v-$H-f3H{M%y}R=g^d%HF zz$oGY7Bk%OWVhOb>UR%@wTyoHhktZLLQlE1>#K*6Egco)CCuinxfIhg9HILp&HeML z>5tc*>!G`h`se^F=0E2JnSGbs@H!(yXE+jVbXs}X3rtG5=YB6gI{H1z z%2v`l!rt%utDKWZ=sp!Z@!Zh~%z7GFdZ&{||N6iWOS9c*0$-P`pmzQVvi&1E@JHj{ zxBPAP{*}wW`tlzW`XAN!KYJbJZ|-Q_v4iu|wX2u(|09uKjn4nsGWu68f04kyyUJh0 z@nci|S1$j`<%j9~*JA!y7k_E|E0@2B<6nLG_muOiLj1dv{JWF%3>zl}lPV=z81z`RXis(3ET;+Sq#N`uXd@YHHhb`*| zv;Hjx^JBQ6VU<)3h_%~au5bZDBTv(fzV%rA{|MuC7)G8JT`i0*ZmgvnPC z=jCvqOv$8=7~!9l_4ijuXx|3qBdnL7rN0xHOh9a{Z}}nGL54I}Q1YigkNNN7m^k|Z zu<8}rto9X+hZZ(-!_YP=eLj=iAiH~)s{+#Hzy0OP=QJZG@DX;F8xCg_~$6T8r&YMW!k~I3}EmMav!^P<#VIUum>ijR!vQhR^}5k2N3?wkDF9rib6O0lJa9!%~Wh(W=W%C4lZX&EC^d3tTM` z36v@<{7p3D^p61?7tLbWw5tgjsdD2()%$Hjt0WdwDEj<(b;)39es*fz`^ zz}=^I#nQ@)l$4Z#1U$Hp`iqqQ(#1U{w*gb2wO^8|OH-e__u2YLxEr+LBb28lI(Rz; z-58|uf*ARmA|FC#k?rJK5g4=E`nM4{@=rLjU*8{h=3IhW0Z0fI%NhD0M8sp1M4?sk zEyrJ{zeuQwmHH%#3gc}ixpHx7Wf|sb$}OM;gB%d;U}9K_9k2h=!N0s41S-M2$k;*S zr4l{}a9?yf!E^|srLlzK9AIzkU??$u%{eBuXeScnFlG^i1AO@H;m6BC9fxl9lH~mV zSqKagswY%YIe;wGUgQ(%k&G2rGs!;WgFXCw{g>`OdIvRlNxuB6aW9@;6km`-g@;|s z8$1umO?Z9t@2lrez2$TZEVaY~-VhwPiUrp{EGQoqj=sIAVCv=g3;4b^qvPvPH4au9Cs8EGrBs6$%^R2@yAl)p;g`7bte&!rRd-6%kA zTm*QiWNt&_)+QrCX*aR>N=s<&9cMhM>%INkE{*0gn#$O{Qug??98Ej*v9U4hm2c`M zag(X0C|~P7w5u9RIW}xWK@WpR?J7J6;}4GC)%hkBI4k&H>_PzJ z)mGH`mX%V6&y3jL7KQ@O?X?&GZG4>C$LAPQX?NaJ7^#_4n>)i$auHY5nj_#8qF^DD zz}5H$Di6!|RcYX#ZJ#%j3qe$H%etKj3k|Ii`mZBnPpt;D(d|owM!o(l`vEf3hM|oR zx4hdq*z5~FD`>&pDfKFL$=K`NX<_#9@1cXzAlKJMXi{j{J5q4I1 zRR>S`Z?6kUG``y*v?oDh&KLLE3AeW=zzF%aDuWU)_J)Ry z2U=Vyvzvpxh)DEFyzFA~PKqrPo7;8KVYKz4hwl=P152Jtu4H~rj}nV37WaCMTjuQ< zE;a2__q_Y+^EZ9@OhYalP&>=X2929Ue!cSTN$?%7GT-cQ0*BdQ7ISmtaRzCgS?sb` z7{lUiTlbQJ(ECmSP<6^XEBz2q7@xlfz>g2Dm00tM}J?yZrQ zYEoKwCF0al?5KOgtIdmxH0P;~^Z6xB;Tin*{clF+=ufH#TFZso<&s3qCACe>PUqey zcP-JG@HX-{EJqO3hPs(57qn0K%wp$iLBA%xky@yrx?$YVjWm{X z8Mu(sf1h8Hv z53MBKBpP+DE=|2g#ZW8}9kkPrS1{8GseO5wvxK$__7GCb+IyN7!*l=+alIG@GWSv} z`^@K&L|s}ub2}}K6lH_S%#BfNDf<5PE$Nf*Xj%(Go&E-9kccE}L|Fhzjp}$=ofbc+ zmr2bmH|J5nt+~+bBFICJpKnQTchmrMwA>vryX-+}v|r?`GmNo%v~-+c;jLL_9xWUZ zM!koBRTp({G=Bg!vtTPK4 z^kyHr^u|>m2dQdwQ~96Fz49TtkVy)S&+%-*)6z7TX@U4Jb%qD?vZDo?A_z(KWL`73 zrJkiyeiakc*CKJGA6YjiD}Uk4>gYHAd$NGL<{s%14_vJkK;$lFf+oc(U~P zWsr{2NQa61GuydQMSHb|am$yCQys-_8{_IzQn%tWx)+w{5B>uQ?H>*m0K`VN73tr1 zK|j5-H1TZ5**y~2^NWREeN7P!W$9Wcd-Hw8jJ-4Xvk2EB?1UohdtFwFQF96Gr3Tv4 l_At{i{jz6*i_5gVY)9$8*_vM)+yVZssc2u#y?p!O{{@{=tK9$q literal 0 HcmV?d00001 diff --git a/src/command_palette.rs b/src/command_palette.rs new file mode 100644 index 0000000..781a0ed --- /dev/null +++ b/src/command_palette.rs @@ -0,0 +1,816 @@ +//! Command palette β€” the ⌘K (Ctrl K) launcher, Superhuman / Linear style. +//! +//! A floating, top-anchored panel over a soft scrim: type to fuzzy-search every +//! command, ↑↓ to move, ↡ to run, esc to close. It's built on gpui-component's +//! `List` + `ListDelegate` (the same searchable-list primitive Zed's own palette +//! uses), so the search box, keyboard navigation, scrolling and selection styling +//! all come for free β€” this file only supplies the *commands*, the *fuzzy match*, +//! and the *chrome*. +//! +//! ## Add a command (the whole story) +//! +//! Add one line to `commands()` below. If it maps to an action you already have +//! (the common case), point `run` at it and you're done β€” the palette dispatches +//! the *same* action as the hotkey and the menu bar, so behaviour can never drift, +//! and the trailing shortcut chip is derived live from your keymap: +//! +//! ```ignore +//! Command { id: "home", title: "Go Home", icon: IconName::ArrowLeft, +//! category: Category::Navigation, keywords: &["back", "welcome"], +//! run: Run::Action(|| Box::new(GoBack)) }, +//! ``` +//! +//! For a palette-only verb with no standing action, use the `Run::Accent`-style +//! escape hatch (or add your own `Run` variant + a match arm in `run_command`). +//! +//! ## How it's wired (see `shell.rs` + `main.rs`) +//! +//! `main.rs` declares the `TogglePalette` action and binds `secondary-k` to it. +//! `Shell` owns the open/closed state, builds a fresh `ListState` each time the +//! palette opens (so the query always starts empty), and renders the overlay as +//! its last child. Because the delegate can't reach `Shell`, running a command is +//! bridged through the list's `ListEvent`: the delegate stashes the chosen command +//! in `pending`, and `Shell::on_palette_event` drains it, closes the palette, then +//! dispatches (see the `impl Shell` block at the bottom of this file). +//! +//! ## Extending +//! +//! - **A verb with no action / with data.** Add a `Run` variant (e.g. +//! `Run::OpenUrl(&'static str)`) and a match arm in `Shell::run_command`. Keep the +//! `Run` match in `render_item` (the shortcut-chip derivation) in sync too. +//! - **A new group.** Add a `Category` variant and list it in `Category::ORDER`. +//! - **Persistent recents.** Recents are session-only by design (no disk I/O on the +//! hot path). To survive restarts: add `recents: Vec` to `Settings`, load it +//! in `Shell::new`, and call `self.settings.save()` from `record_recent` β€” the same +//! pattern `settings.rs` already uses for `display_name`. + +use std::ops::Range; +use std::time::Duration; + +use gpui::{ + div, ease_out_quint, hsla, px, Animation, AnimationExt, AppContext, Context, Entity, + FontWeight, HighlightStyle, InteractiveElement, IntoElement, MouseButton, ParentElement, + Styled, StyledText, Task, Window, +}; +use gpui_component::{ + h_flex, + kbd::Kbd, + list::{List, ListDelegate, ListEvent, ListItem, ListState}, + v_flex, ActiveTheme, Icon, IconName, IndexPath, +}; + +use crate::shell::Shell; +use crate::theme::Accent; +use crate::{GoBack, NewItem, OpenSettings, Quit, TogglePalette, ToggleTheme}; + +// =========================================================================== +// 1. The command registry β€” THE place you edit to add/remove commands. +// =========================================================================== + +/// A group heading in the palette. The order here is the order on screen. +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum Category { + Navigation, + Create, + Appearance, + App, +} + +impl Category { + /// Sections render in this order; empty groups are dropped automatically. + const ORDER: [Category; 4] = [ + Category::Navigation, + Category::Create, + Category::Appearance, + Category::App, + ]; + + fn label(self) -> &'static str { + match self { + Category::Navigation => "Navigation", + Category::Create => "Create", + Category::Appearance => "Appearance", + Category::App => "App", + } + } +} + +/// What running a command does. +#[derive(Clone, Copy)] +pub enum Run { + /// Dispatch a real gpui action. This funnels through the *same* handler as + /// the keyboard shortcut and the native menu item, so the three can never + /// disagree β€” and a command that reuses an existing action needs no new code. + Action(fn() -> Box), + /// Set the brand accent. An example of a palette-only verb that has no + /// standing action/hotkey β€” handled directly in `Shell` (see `run_command`). + Accent(Accent), +} + +/// One palette entry. (`Clone`, not `Copy`, because `IconName` isn't `Copy`.) +#[derive(Clone)] +pub struct Command { + /// Stable id β€” used as the recents key and part of the row's element id. + pub id: &'static str, + /// The label you see (also what fuzzy-search matches + highlights). + pub title: &'static str, + /// Leading glyph (Lucide; see `IconName`). + pub icon: IconName, + /// Which section it lives in. + pub category: Category, + /// Extra search aliases that don't appear in the title (e.g. "prefs"). + pub keywords: &'static [&'static str], + /// What it does. + pub run: Run, +} + +/// The command set Deck ships with. **Add your commands here.** Everything maps +/// to an action `Shell`/`main.rs` already handles, except the six accent verbs, +/// which show off the `Run::Accent` escape hatch. +pub fn commands() -> Vec { + let mut cmds = vec![ + Command { + id: "settings", + title: "Open Settings", + icon: IconName::Settings, + category: Category::Navigation, + keywords: &["preferences", "prefs", "config"], + run: Run::Action(|| Box::new(OpenSettings)), + }, + Command { + id: "home", + title: "Go Home", + icon: IconName::ArrowLeft, + category: Category::Navigation, + keywords: &["back", "welcome"], + run: Run::Action(|| Box::new(GoBack)), + }, + Command { + id: "new", + title: "New Item", + icon: IconName::Plus, + category: Category::Create, + keywords: &["add", "create"], + run: Run::Action(|| Box::new(NewItem)), + }, + Command { + id: "theme", + title: "Toggle Theme", + icon: IconName::Sun, + category: Category::Appearance, + keywords: &["dark", "light", "mode", "appearance"], + run: Run::Action(|| Box::new(ToggleTheme)), + }, + ]; + + // Six accent commands, generated from `Accent::ALL` (mirrors settings_view.rs). + cmds.extend(Accent::ALL.iter().map(|&accent| { + let (id, title) = accent_meta(accent); + Command { + id, + title, + icon: IconName::Palette, + category: Category::Appearance, + keywords: &["color", "accent", "brand"], + run: Run::Accent(accent), + } + })); + + cmds.push(Command { + id: "quit", + title: "Quit", + icon: IconName::Close, + category: Category::App, + keywords: &["exit", "close"], + run: Run::Action(|| Box::new(Quit)), + }); + + cmds +} + +/// `(stable id, palette title)` for an accent β€” kept here so `theme.rs` stays +/// purely about colour. +fn accent_meta(accent: Accent) -> (&'static str, &'static str) { + match accent { + Accent::Indigo => ("accent-indigo", "Accent Β· Indigo"), + Accent::Blue => ("accent-blue", "Accent Β· Blue"), + Accent::Violet => ("accent-violet", "Accent Β· Violet"), + Accent::Emerald => ("accent-emerald", "Accent Β· Emerald"), + Accent::Amber => ("accent-amber", "Accent Β· Amber"), + Accent::Rose => ("accent-rose", "Accent Β· Rose"), + } +} + +// =========================================================================== +// 2. The fuzzy matcher. +// =========================================================================== +// +// A compact subsequence scorer β€” every query char must appear in order, and we +// reward matches at the start, at word boundaries (after a space / - / _) and +// camelCase humps, and consecutive runs, while penalising gaps and length. It +// returns the matched byte ranges so we can highlight them. This is a small, +// readable cousin of Zed's `fuzzy` crate; for a palette of dozens of commands +// it runs synchronously in microseconds β€” no background threads needed. + +/// Fuzzy-match `query` against `haystack`. `None` if not a subsequence; otherwise +/// `Some((score, matched byte ranges))`, higher score = better. +fn fuzzy(query: &str, haystack: &str) -> Option<(i32, Vec>)> { + if query.is_empty() { + return Some((0, Vec::new())); + } + + let needles: Vec = query.chars().flat_map(char::to_lowercase).collect(); + let mut ni = 0usize; + let mut ranges: Vec> = Vec::with_capacity(needles.len()); + let mut score = 0i32; + // Two cursors so multi-byte UTF-8 is handled correctly: `byte` is the real + // string offset we hand back for highlight ranges; `char_ix` counts logical + // characters, which is what adjacency/gap scoring should reason about. + let mut prev_match: i64 = -2; + let mut prev: Option = None; + + for (char_ix, (byte, ch)) in (0i64..).zip(haystack.char_indices()) { + if ni == needles.len() { + break; + } + let lc = ch.to_lowercase().next().unwrap_or(ch); + if lc == needles[ni] { + if char_ix == 0 { + score += 15; // start of string + } else if matches!(prev, Some(p) if p == ' ' || p == '-' || p == '_' || p == '/') { + score += 12; // word boundary + } else if matches!(prev, Some(p) if p.is_lowercase()) && ch.is_uppercase() { + score += 9; // camelCase hump + } + if char_ix == prev_match + 1 { + score += 6; // consecutive run + } else { + score -= ((char_ix - prev_match - 1).min(6)) as i32; // gap penalty (capped) + } + ranges.push(byte..byte + ch.len_utf8()); + prev_match = char_ix; + ni += 1; + } + prev = Some(ch); + } + + if ni == needles.len() { + score -= haystack.chars().count() as i32 / 4; // mild preference for shorter labels + Some((score, ranges)) + } else { + None + } +} + +/// Score a command: a title match (which carries highlight ranges) wins; failing +/// that, a keyword match counts but ranks a little lower and highlights nothing. +fn score_command(query: &str, cmd: &Command) -> Option<(i32, Vec>)> { + if let Some(hit) = fuzzy(query, cmd.title) { + return Some(hit); + } + let mut best: Option = None; + for kw in cmd.keywords { + if let Some((s, _)) = fuzzy(query, kw) { + best = Some(best.map_or(s, |b| b.max(s))); + } + } + best.map(|s| (s - 4, Vec::new())) +} + +// =========================================================================== +// 3. The list delegate β€” feeds rows to gpui-component's `List`. +// =========================================================================== + +/// A matched row: a command plus the byte ranges of its title to highlight. +#[derive(Clone)] +struct Hit { + cmd: Command, + ranges: Vec>, +} + +impl Hit { + /// A row with no highlighting (used for the empty-query / recents view). + fn plain(cmd: Command) -> Self { + Hit { + cmd, + ranges: Vec::new(), + } + } +} + +/// A visible group: a heading and its rows. +struct Section { + title: &'static str, + rows: Vec, +} + +/// The data + filtering behind the palette. The `List` owns the search input, +/// keyboard navigation and selection; this just answers "what rows, in what +/// groups?" and remembers which command was confirmed. +pub struct PaletteDelegate { + all: Vec, + /// Snapshot of recently-run ids, passed in by `Shell` when the palette opens. + recents: Vec<&'static str>, + sections: Vec
, + /// The currently highlighted row; the `List` keeps this in sync. Read in + /// `confirm` to know what to run. + selected: Option, + /// Set by `confirm`, drained by `Shell::on_palette_event`. + pending: Option<(Run, &'static str)>, +} + +impl PaletteDelegate { + pub fn new(recents: Vec<&'static str>) -> Self { + let mut this = Self { + all: commands(), + recents, + sections: Vec::new(), + selected: None, + pending: None, + }; + this.rebuild(""); + this + } + + fn resolve(&self, id: &str) -> Option { + self.all.iter().find(|c| c.id == id).cloned() + } + + /// The first selectable row, used to pre-select something on open. + pub fn first_row(&self) -> Option { + self.sections + .iter() + .position(|s| !s.rows.is_empty()) + .map(|s| IndexPath::new(0).section(s)) + } + + /// Take the command confirmed by the user, if any. + pub fn take_pending(&mut self) -> Option<(Run, &'static str)> { + self.pending.take() + } + + /// Recompute the visible sections for `query`. + fn rebuild(&mut self, query: &str) { + let query = query.trim(); + self.sections.clear(); + + if query.is_empty() { + // Empty query: a "Recent" group, then every *other* command grouped by + // category. Recent commands lift out of their group (Raycast/Spotlight + // style) so nothing appears twice. + let recent: Vec = self + .recents + .iter() + .filter_map(|id| self.resolve(id)) + .collect(); + if !recent.is_empty() { + self.sections.push(Section { + title: "Recent", + rows: recent.iter().map(|cmd| Hit::plain(cmd.clone())).collect(), + }); + } + for cat in Category::ORDER { + let rows: Vec = self + .all + .iter() + .filter(|c| c.category == cat && !recent.iter().any(|r| r.id == c.id)) + .map(|cmd| Hit::plain(cmd.clone())) + .collect(); + if !rows.is_empty() { + self.sections.push(Section { + title: cat.label(), + rows, + }); + } + } + } else { + // Non-empty query: each category's matches, best score first. + for cat in Category::ORDER { + let mut scored: Vec<(i32, Hit)> = self + .all + .iter() + .filter(|c| c.category == cat) + .filter_map(|cmd| { + score_command(query, cmd).map(|(s, ranges)| { + ( + s, + Hit { + cmd: cmd.clone(), + ranges, + }, + ) + }) + }) + .collect(); + scored.sort_by_key(|entry| std::cmp::Reverse(entry.0)); + if !scored.is_empty() { + self.sections.push(Section { + title: cat.label(), + rows: scored.into_iter().map(|(_, hit)| hit).collect(), + }); + } + } + } + } +} + +impl ListDelegate for PaletteDelegate { + type Item = ListItem; + + fn perform_search( + &mut self, + query: &str, + _: &mut Window, + _: &mut Context>, + ) -> Task<()> { + self.rebuild(query); + Task::ready(()) + } + + fn sections_count(&self, _: &gpui::App) -> usize { + self.sections.len() + } + + fn items_count(&self, section: usize, _: &gpui::App) -> usize { + self.sections.get(section).map_or(0, |s| s.rows.len()) + } + + fn render_section_header( + &mut self, + section: usize, + _: &mut Window, + cx: &mut Context>, + ) -> Option { + let title = self.sections.get(section)?.title; + Some( + div() + .px_3() + .pt_3() + .pb_1() + .text_xs() + .font_weight(FontWeight::SEMIBOLD) + .text_color(cx.theme().muted_foreground) + .child(title.to_uppercase()), + ) + } + + fn render_item( + &mut self, + ix: IndexPath, + window: &mut Window, + cx: &mut Context>, + ) -> Option { + let hit = self.sections.get(ix.section)?.rows.get(ix.row)?; + let cmd = &hit.cmd; + let ranges = hit.ranges.clone(); + // The List applies the selected *background*; we only use this to brighten + // the leading icon on the selected row (it stays quiet on the rest). + let is_selected = self.selected == Some(ix); + + // Derive the shortcut chip live from the keymap, so it always mirrors the + // real binding in main.rs (None = global context, which is how Deck binds). + let kbd = match cmd.run { + Run::Action(make) => Kbd::binding_for_action(&*make(), None, window), + Run::Accent(_) => None, + }; + + let foreground = cx.theme().foreground; + let muted = cx.theme().muted_foreground; + let accent = cx.theme().primary; + let icon_color = if is_selected { foreground } else { muted }; + let title = cmd.title; + + // The title, with matched characters tinted + bolded. `flex_1().truncate()` + // keeps long titles from shoving the shortcut chip off the row. + let label = { + let base = div().flex_1().truncate().text_sm().text_color(foreground); + if ranges.is_empty() { + base.child(title) + } else { + let highlights = ranges.into_iter().map(move |r| { + ( + r, + HighlightStyle { + color: Some(accent), + font_weight: Some(FontWeight::SEMIBOLD), + ..Default::default() + }, + ) + }); + base.child(StyledText::new(title).with_highlights(highlights)) + } + }; + + // NOTE: do NOT call `.selected(..)` here β€” the `List` applies selection + // styling itself from the index it tracks. The id pairs the command with + // its section so the same command can appear in "Recent" and its category + // without colliding. + Some( + ListItem::new((cmd.id, ix.section)) + .suffix(move |_, _| match kbd.clone() { + Some(k) => k.into_any_element(), + None => div().into_any_element(), + }) + .child( + h_flex() + .w_full() + .gap_3() + .items_center() + .child(Icon::new(cmd.icon.clone()).size_4().text_color(icon_color)) + .child(label), + ), + ) + } + + fn render_empty( + &mut self, + _: &mut Window, + cx: &mut Context>, + ) -> impl IntoElement { + v_flex() + .py_8() + .gap_2() + .items_center() + .child( + Icon::new(IconName::Search) + .size_6() + .text_color(cx.theme().muted_foreground.opacity(0.5)), + ) + .child( + div() + .text_sm() + .text_color(cx.theme().muted_foreground) + .child("No matching commands"), + ) + } + + fn set_selected_index( + &mut self, + ix: Option, + _: &mut Window, + _: &mut Context>, + ) { + self.selected = ix; + } + + fn confirm(&mut self, _: bool, _: &mut Window, _: &mut Context>) { + // The List only calls this when something is selected, but fall back to + // the first row defensively. + let ix = self.selected.or_else(|| self.first_row()); + if let Some(ix) = ix { + if let Some(hit) = self + .sections + .get(ix.section) + .and_then(|s| s.rows.get(ix.row)) + { + self.pending = Some((hit.cmd.run, hit.cmd.id)); + } + } + } +} + +// =========================================================================== +// 4. Shell integration β€” open/close, render the overlay, run commands. +// (These are `Shell` methods, split into this module like welcome.rs / +// settings_view.rs do; the fields live in `shell.rs`.) +// =========================================================================== + +/// How far the panel floats from the top of the window. +const TOP_OFFSET: f32 = 112.0; +const PANEL_WIDTH: f32 = 620.0; + +impl Shell { + /// ⌘K β€” toggle the palette. Bound in `main.rs`, wired in `shell.rs`'s render. + pub fn on_palette_toggle( + &mut self, + _: &TogglePalette, + window: &mut Window, + cx: &mut Context, + ) { + if self.palette.is_some() { + self.close_palette(window, cx); + } else { + self.open_palette(window, cx); + } + } + + /// Build a fresh palette (so the query always starts empty), pre-select the + /// first row, and focus the search input. + fn open_palette(&mut self, window: &mut Window, cx: &mut Context) { + let recents = self.recents.iter().copied().collect::>(); + let palette = + cx.new(|cx| ListState::new(PaletteDelegate::new(recents), window, cx).searchable(true)); + self.palette_sub = Some(cx.subscribe_in(&palette, window, Self::on_palette_event)); + palette.update(cx, |state, cx| { + let first = state.delegate().first_row(); + state.set_selected_index(first, window, cx); + state.focus(window, cx); + }); + self.palette = Some(palette); + cx.notify(); + } + + /// Close the palette and return focus to the shell so global hotkeys work. + pub fn close_palette(&mut self, window: &mut Window, cx: &mut Context) { + self.palette = None; + self.palette_sub = None; + window.focus(&self.focus_handle); + cx.notify(); + } + + /// Bridge the list's events back to the shell: run on confirm, close on cancel. + pub fn on_palette_event( + &mut self, + state: &Entity>, + event: &ListEvent, + window: &mut Window, + cx: &mut Context, + ) { + match event { + ListEvent::Confirm(_) => { + let chosen = state.update(cx, |s, _| s.delegate_mut().take_pending()); + // Close first, so the dispatched action lands on the shell's focus + // tree (not the palette's). + self.close_palette(window, cx); + if let Some((run, id)) = chosen { + self.record_recent(id); + self.run_command(run, window, cx); + } + } + ListEvent::Cancel => self.close_palette(window, cx), + ListEvent::Select(_) => {} + } + } + + fn record_recent(&mut self, id: &'static str) { + self.recents.retain(|r| *r != id); + self.recents.push_front(id); + self.recents.truncate(8); + } + + fn run_command(&mut self, run: Run, window: &mut Window, cx: &mut Context) { + match run { + Run::Action(make) => window.dispatch_action(make(), cx), + Run::Accent(accent) => self.set_accent(accent, cx), + } + } + + /// The overlay: a scrim with the floating panel, anchored near the top. + pub fn render_palette( + &self, + palette: &Entity>, + cx: &mut Context, + ) -> impl IntoElement { + let border = cx.theme().border; + + div() + .id("palette-scrim") + .absolute() + .inset_0() + .flex() + .flex_col() + .items_center() + .justify_start() + .pt(px(TOP_OFFSET)) + // A soft dark scrim that *darkens* behind the panel in BOTH modes (a + // theme `background` tint would wash out white in light mode). Kept a + // local constant β€” a scrim is conventionally mode-independent. + .bg(hsla(0.0, 0.0, 0.0, 0.45)) + // Click outside the panel to dismiss. + .on_mouse_down( + MouseButton::Left, + cx.listener(|this, _, window, cx| this.close_palette(window, cx)), + ) + .child( + v_flex() + .w(px(PANEL_WIDTH)) + .max_w_full() + .max_h(px(440.0)) + .rounded_xl() + .border_1() + .border_color(border) + .bg(cx.theme().popover) + .shadow_lg() + .overflow_hidden() + // Swallow clicks inside the panel so they don't hit the scrim. + .on_mouse_down(MouseButton::Left, |_, _, cx| cx.stop_propagation()) + .child( + List::new(palette) + .search_placeholder("Search commands…") + .max_h(px(360.0)), + ) + .child(self.render_palette_footer(cx)) + // Subtle, fast entrance β€” opacity only (the panel isn't + // absolutely positioned, so animating offset would be shaky). + .with_animation( + "palette-in", + Animation::new(Duration::from_millis(120)).with_easing(ease_out_quint()), + |el, t| el.opacity(t), + ), + ) + } + + /// The whisper-thin hint bar at the bottom of the panel. Delete this method's + /// call in `render_palette` if you want it even quieter. + fn render_palette_footer(&self, cx: &mut Context) -> impl IntoElement { + let border = cx.theme().border; + let muted = cx.theme().muted_foreground; + let surface = cx.theme().secondary; + + let chip = move |key: &str| { + div() + .px_1() + .rounded_sm() + .border_1() + .border_color(border) + .bg(surface) + .text_color(muted) + .child(key.to_string()) + }; + let hint = move |keys: Vec<&'static str>, label: &'static str| { + h_flex() + .gap_1() + .items_center() + .children(keys.into_iter().map(chip)) + .child(div().child(label)) + }; + + h_flex() + .w_full() + .px_3() + .py_1p5() + .gap_3() + .items_center() + .border_t_1() + .border_color(border) + .text_xs() + .text_color(muted) + .child(hint(vec!["↑", "↓"], "Navigate")) + .child(hint(vec!["↡"], "Open")) + .child(hint(vec!["esc"], "Close")) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn score(q: &str, hay: &str) -> Option { + fuzzy(q, hay).map(|(s, _)| s) + } + + #[test] + fn matches_are_subsequences() { + assert!(score("os", "Open Settings").is_some()); // initials + assert!(score("settings", "Open Settings").is_some()); + assert!(score("", "anything").is_some()); // empty query matches + assert!(score("xyz", "Open Settings").is_none()); // not a subsequence + assert!(score("ngs", "Open Settings").is_some()); // mid-word run + } + + #[test] + fn case_insensitive() { + assert!(score("OPEN", "open settings").is_some()); + assert!(score("open", "OPEN SETTINGS").is_some()); + } + + #[test] + fn word_boundary_beats_scatter() { + // "os" as two word-initials should outscore the same letters mid-word. + let initials = score("os", "Open Settings").unwrap(); + let scattered = score("os", "Booomerang Stew").unwrap(); + assert!(initials > scattered, "{initials} !> {scattered}"); + } + + #[test] + fn prefix_and_consecutive_win() { + // A contiguous prefix run outscores the same letters scattered mid-word. + let prefix = score("set", "Settings").unwrap(); + let scattered = score("set", "Basement").unwrap(); // s..e....t, all mid-word + assert!(prefix > scattered, "{prefix} !> {scattered}"); + + // Word-initials are also a strong signal β€” on par with a prefix run. + let initials = score("os", "Open Settings").unwrap(); + let midword = score("os", "Chaos Theory").unwrap(); // 'o','s' inside "Chaos" + assert!(initials > midword, "{initials} !> {midword}"); + } + + #[test] + fn highlight_ranges_point_at_matched_chars() { + let (_, ranges) = fuzzy("os", "Open Settings").unwrap(); + // O at byte 0, S at byte 5. + let matched: String = ranges.iter().map(|r| &"Open Settings"[r.clone()]).collect(); + assert_eq!(matched, "OS"); + } + + #[test] + fn keyword_match_included_without_title_highlight() { + let settings = commands().into_iter().find(|c| c.id == "settings").unwrap(); + // "prefs" only matches the keyword, not the title β€” included, no highlight. + let (_, ranges) = score_command("prefs", &settings).unwrap(); + assert!(ranges.is_empty()); + // "set" matches the title β€” included, with highlight ranges. + let (_, ranges) = score_command("set", &settings).unwrap(); + assert!(!ranges.is_empty()); + } +} diff --git a/src/main.rs b/src/main.rs index 52d16db..d75257d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ //! Fork checklist: rename the crate in `Cargo.toml`, change `APP_NAME` and the //! bundle identifier, swap `assets/icon.png`, then start editing the views. +mod command_palette; mod settings; mod settings_view; mod shell; @@ -31,7 +32,15 @@ pub const APP_NAME: &str = "Deck"; // to, hang a menu item off of, and handle in a view or globally. Add your own here. gpui::actions!( deck, - [Quit, About, OpenSettings, ToggleTheme, NewItem, GoBack] + [ + Quit, + About, + OpenSettings, + ToggleTheme, + NewItem, + GoBack, + TogglePalette + ] ); fn main() { @@ -57,6 +66,7 @@ fn main() { KeyBinding::new("secondary-,", OpenSettings, None), KeyBinding::new("secondary-shift-d", ToggleTheme, None), KeyBinding::new("secondary-[", GoBack, None), + KeyBinding::new("secondary-k", TogglePalette, None), ]); // 4. Global action handlers. View-local actions (NewItem, OpenSettings, @@ -96,7 +106,11 @@ fn main() { }, Menu { name: "View".into(), - items: vec![MenuItem::action("Toggle Light / Dark", ToggleTheme)], + items: vec![ + MenuItem::action("Command Palette…", TogglePalette), + MenuItem::separator(), + MenuItem::action("Toggle Light / Dark", ToggleTheme), + ], }, ]); diff --git a/src/shell.rs b/src/shell.rs index 7e603a6..1c867d9 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -4,17 +4,21 @@ //! `settings_view.rs` as `impl Shell` methods (Rust lets you split an inherent //! impl across modules), so this file stays focused on state + navigation. +use std::collections::VecDeque; + use gpui::{ div, App, AppContext, Context, Entity, FocusHandle, Focusable, FontWeight, InteractiveElement, - IntoElement, ParentElement, Render, Styled, Window, + IntoElement, ParentElement, Render, Styled, Subscription, Window, }; use gpui_component::{ button::{Button, ButtonVariants}, h_flex, input::{InputEvent, InputState}, + list::ListState, v_flex, ActiveTheme, IconName, TitleBar, }; +use crate::command_palette::PaletteDelegate; use crate::settings::{Settings, ThemeModePref}; use crate::theme::{self, Accent}; use crate::{GoBack, NewItem, OpenSettings, ToggleTheme, APP_NAME}; @@ -31,6 +35,13 @@ pub struct Shell { pub settings: Settings, pub name_input: Entity, pub created: usize, + /// The command palette's list, while it's open (rebuilt fresh each open so the + /// query always starts empty). `None` = closed. See `command_palette.rs`. + pub palette: Option>>, + /// Keeps the palette's event subscription alive while it's open. + pub palette_sub: Option, + /// Recently-run command ids, most-recent first β€” the palette's "Recent" group. + pub recents: VecDeque<&'static str>, } impl Shell { @@ -59,6 +70,10 @@ impl Shell { settings, name_input, created: 0, + palette: None, + palette_sub: None, + // Seed a few sensible "recents" so the palette is never blank on first open. + recents: ["settings", "new", "theme"].into_iter().collect(), } } @@ -191,16 +206,24 @@ impl Render for Shell { Route::Welcome => self.render_welcome(cx).into_any_element(), Route::Settings => self.render_settings(window, cx).into_any_element(), }; + // The command palette overlay (when open), painted over everything else. + let palette = self + .palette + .clone() + .map(|p| self.render_palette(&p, cx).into_any_element()); v_flex() .size_full() + .relative() .bg(background) .track_focus(&self.focus_handle) .on_action(cx.listener(Self::on_new_item)) .on_action(cx.listener(Self::on_open_settings)) .on_action(cx.listener(Self::on_go_back)) .on_action(cx.listener(Self::on_toggle_theme)) + .on_action(cx.listener(Self::on_palette_toggle)) .child(title_bar) .child(content) + .children(palette) } } From c3b1b72e972b6a30904affea43d257a1a76e1a3f Mon Sep 17 00:00:00 2001 From: hellno Date: Fri, 5 Jun 2026 15:08:16 +0200 Subject: [PATCH 2/2] ci: install libxdo-dev for the Linux `--features tray` build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Linux job's `cargo build --features tray` failed to link with `unable to find library -lxdo`: tray-icon pulls libxdo-sys, which needs the system libxdo on Linux, but it was missing from the apt list (and the README's tray deps). Pre-existing β€” unrelated to the command palette. --- .github/workflows/ci.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 802749d..1a52adb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,7 +54,7 @@ jobs: libvulkan-dev \ libfontconfig1-dev libfreetype6-dev \ libssl-dev \ - libgtk-3-dev libayatana-appindicator3-dev + libgtk-3-dev libayatana-appindicator3-dev libxdo-dev - run: cargo build - run: cargo build --features tray - run: cargo clippy --all-targets --features tray -- -D warnings diff --git a/README.md b/README.md index 54e10f6..8876ccd 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ You need a stable **Rust** toolchain (`rustup`) and: ```bash sudo apt install build-essential pkg-config libxcb1-dev libxkbcommon-dev \ libxkbcommon-x11-dev libwayland-dev libvulkan-dev libfontconfig1-dev \ - libfreetype6-dev libssl-dev # + libgtk-3-dev libayatana-appindicator3-dev for --features tray + libfreetype6-dev libssl-dev # + libgtk-3-dev libayatana-appindicator3-dev libxdo-dev for --features tray ``` > Same code on both. CI builds macOS **and** Linux on every push β€” see [Platforms](#platforms).