pax_global_header00006660000000000000000000000064145777004600014524gustar00rootroot0000000000000052 comment=a9e0a4a72158895c467559e55a6e9d9011a8539d golang-github-darkhz-tview-0.0~git20240308.6078a88/000077500000000000000000000000001457770046000212005ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/.github/000077500000000000000000000000001457770046000225405ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/.github/FUNDING.yml000066400000000000000000000000151457770046000243510ustar00rootroot00000000000000github: rivo golang-github-darkhz-tview-0.0~git20240308.6078a88/CONTRIBUTING.md000066400000000000000000000061001457770046000234260ustar00rootroot00000000000000# Contributing to tview First of all, thank you for taking the time to contribute. The following provides you with some guidance on how to contribute to this project. Mainly, it is meant to save us all some time so please read it, it's not long. Please note that this document is work in progress so I might add to it in the future. ## Issues - Please include enough information so everybody understands your request. - Screenshots or code that illustrates your point always helps. - It's fine to ask for help. But you should have checked out the [documentation](https://godoc.org/github.com/rivo/tview) first in any case. - If you request a new feature, state your motivation and share a use case that you faced where you needed that new feature. It should be something that others will also need. ## Pull Requests In my limited time I can spend on this project, I will always go through issues first before looking at pull requests. It takes a _lot_ of time to look at code that you submitted and I may not have that time. So be prepared to have your pull requests lying around for a long time. Therefore, if you have a feature request, open an issue first before sending me a pull request, and allow for some discussion. It may save you from writing code that will get rejected. If your case is strong, there is a good chance that I will add the feature for you. I'm very picky about the code that goes into this repo. So if you violate any of the following guidelines, there is a good chance I won't merge your pull request. - There must be a strong case for your additions/changes, such as: - Bug fixes - Features that are needed (see "Issues" above; state your motivation) - Improvements in stability or performance (if readability does not suffer) - Your code must follow the structure of the existing code. Don't just patch something on. Try to understand how `tview` is currently designed and follow that design. Your code needs to be consistent with existing code. - If you're adding code that increases the work required to maintain the project, you must be willing to take responsibility for that extra work. I will ask you to maintain your part of the code in the long run. - Function/type/variable/constant names must be as descriptive as they are right now. Follow the conventions of the package. - All functions/types/variables/constants, even private ones, must have comments in good English. These comments must be elaborate enough so that new users of the package understand them and can follow them. Provide examples if you have to. Start all sentences upper-case, as is common in English, and end them with a period. - A new function should be located close to related functions in the file. For example, `GetColor()` should come after (or before) `SetColor()`. - Your changes must not decrease the project's [Go Report](https://goreportcard.com/report/github.com/rivo/tview) rating. - No breaking changes unless there is absolutely no other way. - If an issue accompanies your pull request, reference it in the PR's comments, e.g. "Fixes #123", so it is closed automatically when the PR is closed. golang-github-darkhz-tview-0.0~git20240308.6078a88/LICENSE.txt000066400000000000000000000020601457770046000230210ustar00rootroot00000000000000MIT License Copyright (c) 2018 Oliver Kuederle Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. golang-github-darkhz-tview-0.0~git20240308.6078a88/README.md000066400000000000000000000221131457770046000224560ustar00rootroot00000000000000# Rich Interactive Widgets for Terminal UIs [![PkgGoDev](https://pkg.go.dev/badge/github.com/rivo/tview)](https://pkg.go.dev/github.com/rivo/tview) [![Go Report](https://img.shields.io/badge/go%20report-A%2B-brightgreen.svg)](https://goreportcard.com/report/github.com/rivo/tview) This Go package provides commonly used components for terminal based user interfaces. ![Screenshot](tview.gif) Among these components are: - __Input forms__ (including __text input__, __selections__, __checkboxes__, and __buttons__) - Navigable multi-color __text views__ - Editable multi-line __text areas__ - Sophisticated navigable __table views__ - Flexible __tree views__ - Selectable __lists__ - __Images__ - __Grid__, __Flexbox__ and __page layouts__ - Modal __message windows__ - An __application__ wrapper They come with lots of customization options and can be easily extended to fit your needs. ## Usage To add this package to your project: ```bash go get github.com/rivo/tview@master ``` ## Hello World This basic example creates a box titled "Hello, World!" and displays it in your terminal: ```go package main import ( "github.com/rivo/tview" ) func main() { box := tview.NewBox().SetBorder(true).SetTitle("Hello, world!") if err := tview.NewApplication().SetRoot(box, true).Run(); err != nil { panic(err) } } ``` Check out the [GitHub Wiki](https://github.com/rivo/tview/wiki) for more examples along with screenshots. Or try the examples in the "demos" subdirectory. For a presentation highlighting this package, compile and run the program found in the "demos/presentation" subdirectory. ## Projects using `tview` - [K9s - Kubernetes CLI](https://github.com/derailed/k9s) - [IRCCloud Terminal Client](https://github.com/termoose/irccloud) - [Window manager for `tview`](https://github.com/epiclabs-io/winman) - [CLI bookmark manager](https://github.com/Endi1/drawer) - [A caving database interface written in Go](https://github.com/IdlePhysicist/cave-logger) - [Interactive file browse and exec any command.](https://github.com/bannzai/itree) - [A complete TUI for LDAP](https://github.com/Macmod/godap) - [A simple CRM](https://github.com/broadcastle/crm) - [Terminal UI for todist](https://github.com/cyberdummy/todoista) - [Graphical kubectl wrapper](https://github.com/dcaiafa/kpick) - [Decred Decentralized Exchange ](https://github.com/decred/dcrdex) - [A CLI file browser for Raspberry PI](https://github.com/destinmoulton/pixi) - [A tool to manage projects.](https://github.com/divramod/dp) - [A simple app for BMI monitoring](https://github.com/erleene/go-bmi) - [Stream TIDAL from command line](https://github.com/godsic/vibe) - [Secure solution for fully decentralized password management](https://github.com/guillaumemichel/passtor/) - [A growing collection of convenient little tools to work with systemd services](https://github.com/muesli/service-tools/) - [A terminal based browser for Redis written in Go](https://github.com/nitishm/redis-terminal) - [First project for the Computer Networks course.](https://github.com/pablogadhi/XMPPClient) - [Test your typing speed in the terminal!](https://github.com/shilangyu/typer-go) - [TUI Client for Docker](https://github.com/skanehira/docui) - [SSH client using certificates signed by HashiCorp Vault](https://github.com/stephane-martin/vssh) - [A go terminal based pos software.](https://github.com/thebmw/y2kpos) - [VMware vCenter Text UI](https://github.com/thebsdbox/vctui) - [Bookmarks on terminal](https://github.com/tryffel/bookmarker) - [A UDP testing utility](https://github.com/vaelen/udp-tester) - [A simple Kanban board for your terminal](https://github.com/witchard/toukan) - [The personal information dashboard for your terminal. ](https://github.com/wtfutil/wtf) - [MySQL database to Golang struct](https://github.com/xxjwxc/gormt) - [Discord, TUI and SIXEL.](https://gitlab.com/diamondburned/6cord) - [A CLI Audio Player](https://www.github.com/dhulihan/grump) - [GLab, a GitLab CLI tool](https://gitlab.com/profclems/glab) - [Browse your AWS ECS Clusters in the Terminal](https://github.com/swartzrock/ecsview) - [The CLI Task Manager for Geeks](https://github.com/ajaxray/geek-life) - [Fast disk usage analyzer written in Go](https://github.com/dundee/gdu) - [Multiplayer Chess On Terminal](https://github.com/qnkhuat/gochess) - [Scriptable TUI music player](https://github.com/issadarkthing/gomu) - [MangaDesk : TUI Client for downloading manga to your computer](https://github.com/darylhjd/mangadesk) - [Go How Much? a Crypto coin price tracking from terminal](https://github.com/ledongthuc/gohowmuch) - [dbui: Universal CLI for Database Connections](https://github.com/KenanBek/dbui) - [ssmbrowse: Simple and elegant cli AWS SSM parameter browser](https://github.com/bnaydenov/ssmbrowse) - [gobit: binance intelligence terminal](https://github.com/infl00p/gobit) - [viddy: A modern watch command](https://github.com/sachaos/viddy) - [s3surfer: CLI tool for browsing S3 bucket and download objects interactively](https://github.com/hirose31/s3surfer) - [libgen-tui: A terminal UI for downloading books from Library Genesis](https://github.com/audstanley/libgen-tui) - [kubectl-lazy: kubectl plugin to easy to view pod](https://github.com/togettoyou/kubectl-lazy) - [podman-tui: podman user interface](https://github.com/containers/podman-tui) - [tvxwidgets: tview extra widgets](https://github.com/navidys/tvxwidgets) - [Domino card game on terminal](https://github.com/gusti-andika/card-domino.git) - [goaround: Query stackoverflow API and get results on terminal](https://github.com/glendsoza/goaround) - [resto: a CLI app can send pretty HTTP & API requests with TUI](https://github.com/abdfnx/resto) - [twad: a WAD launcher for the terminal](https://github.com/zmnpl/twad) - [pacseek: A TUI for searching and installing Arch Linux packages](https://github.com/moson-mo/pacseek) - [7GUIs demo](https://github.com/letientai299/7guis/tree/master/tui) - [tuihub: A utility hub/dashboard for personal use](https://github.com/ashis0013/tuihub) - [l'oggo: A terminal app for structured log streaming (GCP stack driver, k8s, local streaming)](https://github.com/aurc/loggo) - [reminder: Terminal based interactive app for organising tasks with minimal efforts.](https://github.com/goyalmunish/reminder) - [tufw: A terminal UI for ufw.](https://github.com/peltho/tufw) - [gh: the GitHub CLI](https://github.com/cli/cli) - [piptui: Terminal UI to manage pip packages](https://github.com/glendsoza/piptui/) - [cross-clipboard: A cross-platform clipboard sharing](https://github.com/ntsd/cross-clipboard) - [tui-deck: nextcloud deck frontend](https://github.com/mebitek/tui-deck) - [ktop: A top-like tool for your Kubernetes clusters](https://github.com/vladimirvivien/ktop) - [blimp: UI for weather, network latency, application status, & more](https://github.com/merlinfuchs/blimp) - [Curly - A simple TUI leveraging curl to test endpoints](https://github.com/migcaraballo/curly) - [amtui: Alertmanager TUI](https://github.com/pehlicd/amtui) - [A TUI CLI manager](https://github.com/costa86/cli-manager) - [PrivateBTC](https://github.com/adrianbrad/privatebtc) - [play: A TUI playground to experiment with your favorite programs, such as grep, sed, awk, jq and yq](https://github.com/paololazzari/play) - [gorest: Enjoy making HTTP requests in your terminal, just like you do in Insomnia.](https://github.com/NathanFirmo/gorest) ## Documentation Refer to https://pkg.go.dev/github.com/rivo/tview for the package's documentation. Also check out the [Wiki](https://github.com/rivo/tview/wiki). ## Dependencies This package is based on [github.com/gdamore/tcell](https://github.com/gdamore/tcell) (and its dependencies) as well as on [github.com/rivo/uniseg](https://github.com/rivo/uniseg). ## Sponsor this Project [Become a Sponsor on GitHub](https://github.com/sponsors/rivo?metadata_source=tview_readme) to further this project! ## Versioning and Backwards-Compatibility I try really hard to keep this project backwards compatible. Your software should not break when you upgrade `tview`. But this also means that some of its shortcomings that were present in the initial versions will remain. In addition, at least for the time being, you won't find any version tags in this repo. The newest version should be the one to upgrade to. It has all the bugfixes and latest features. Having said that, backwards compatibility may still break when: - a new version of an imported package (most likely [`tcell`](https://github.com/gdamore/tcell)) changes in such a way that forces me to make changes in `tview` as well, - I fix something that I consider a bug, rather than a feature, something that does not work as originally intended, - I make changes to "internal" interfaces such as [`Primitive`](https://pkg.go.dev/github.com/rivo/tview#Primitive). You shouldn't need these interfaces unless you're writing your own primitives for `tview`. (Yes, I realize these are public interfaces. This has advantages as well as disadvantages. For the time being, it is what it is.) ## Your Feedback Add your issue here on GitHub. Feel free to get in touch if you have any questions. ## Code of Conduct We follow Golang's Code of Conduct which you can find [here](https://golang.org/conduct). golang-github-darkhz-tview-0.0~git20240308.6078a88/ansi.go000066400000000000000000000165711457770046000224730ustar00rootroot00000000000000package tview import ( "bytes" "fmt" "io" "strconv" "strings" ) // The states of the ANSI escape code parser. const ( ansiText = iota ansiEscape ansiSubstring ansiControlSequence ) // ansi is a io.Writer which translates ANSI escape codes into tview color // tags. type ansi struct { io.Writer // Reusable buffers. buffer *bytes.Buffer // The entire output text of one Write(). csiParameter, csiIntermediate *bytes.Buffer // Partial CSI strings. attributes string // The buffer's current text attributes (a tview attribute string). // The current state of the parser. One of the ansi constants. state int } // ANSIWriter returns an io.Writer which translates any ANSI escape codes // written to it into tview style tags. Other escape codes don't have an effect // and are simply removed. The translated text is written to the provided // writer. func ANSIWriter(writer io.Writer) io.Writer { return &ansi{ Writer: writer, buffer: new(bytes.Buffer), csiParameter: new(bytes.Buffer), csiIntermediate: new(bytes.Buffer), state: ansiText, } } // Write parses the given text as a string of runes, translates ANSI escape // codes to style tags and writes them to the output writer. func (a *ansi) Write(text []byte) (int, error) { defer func() { a.buffer.Reset() }() for _, r := range string(text) { switch a.state { // We just entered an escape sequence. case ansiEscape: switch r { case '[': // Control Sequence Introducer. a.csiParameter.Reset() a.csiIntermediate.Reset() a.state = ansiControlSequence case 'c': // Reset. fmt.Fprint(a.buffer, "[-:-:-]") a.state = ansiText case 'P', ']', 'X', '^', '_': // Substrings and commands. a.state = ansiSubstring default: // Ignore. a.state = ansiText } // CSI Sequences. case ansiControlSequence: switch { case r >= 0x30 && r <= 0x3f: // Parameter bytes. if _, err := a.csiParameter.WriteRune(r); err != nil { return 0, err } case r >= 0x20 && r <= 0x2f: // Intermediate bytes. if _, err := a.csiIntermediate.WriteRune(r); err != nil { return 0, err } case r >= 0x40 && r <= 0x7e: // Final byte. switch r { case 'E': // Next line. count, _ := strconv.Atoi(a.csiParameter.String()) if count == 0 { count = 1 } fmt.Fprint(a.buffer, strings.Repeat("\n", count)) case 'm': // Select Graphic Rendition. var background, foreground string params := a.csiParameter.String() fields := strings.Split(params, ";") if len(params) == 0 || len(fields) == 1 && fields[0] == "0" { // Reset. a.attributes = "" if _, err := a.buffer.WriteString("[-:-:-]"); err != nil { return 0, err } break } lookupColor := func(colorNumber int) string { if colorNumber < 0 || colorNumber > 15 { return "black" } return []string{ "black", "maroon", "green", "olive", "navy", "purple", "teal", "silver", "gray", "red", "lime", "yellow", "blue", "fuchsia", "aqua", "white", }[colorNumber] } FieldLoop: for index, field := range fields { switch field { case "1", "01": if !strings.ContainsRune(a.attributes, 'b') { a.attributes += "b" } case "2", "02": if !strings.ContainsRune(a.attributes, 'd') { a.attributes += "d" } case "4", "04": if !strings.ContainsRune(a.attributes, 'u') { a.attributes += "u" } case "5", "05": if !strings.ContainsRune(a.attributes, 'l') { a.attributes += "l" } case "22": if i := strings.IndexRune(a.attributes, 'b'); i >= 0 { a.attributes = a.attributes[:i] + a.attributes[i+1:] } if i := strings.IndexRune(a.attributes, 'd'); i >= 0 { a.attributes = a.attributes[:i] + a.attributes[i+1:] } case "24": if i := strings.IndexRune(a.attributes, 'u'); i >= 0 { a.attributes = a.attributes[:i] + a.attributes[i+1:] } case "25": if i := strings.IndexRune(a.attributes, 'l'); i >= 0 { a.attributes = a.attributes[:i] + a.attributes[i+1:] } case "30", "31", "32", "33", "34", "35", "36", "37": colorNumber, _ := strconv.Atoi(field) foreground = lookupColor(colorNumber - 30) case "39": foreground = "-" case "40", "41", "42", "43", "44", "45", "46", "47": colorNumber, _ := strconv.Atoi(field) background = lookupColor(colorNumber - 40) case "49": background = "-" case "90", "91", "92", "93", "94", "95", "96", "97": colorNumber, _ := strconv.Atoi(field) foreground = lookupColor(colorNumber - 82) case "100", "101", "102", "103", "104", "105", "106", "107": colorNumber, _ := strconv.Atoi(field) background = lookupColor(colorNumber - 92) case "38", "48": var color string if len(fields) > index+1 { if fields[index+1] == "5" && len(fields) > index+2 { // 8-bit colors. colorNumber, _ := strconv.Atoi(fields[index+2]) if colorNumber <= 15 { color = lookupColor(colorNumber) } else if colorNumber <= 231 { red := (colorNumber - 16) / 36 green := ((colorNumber - 16) / 6) % 6 blue := (colorNumber - 16) % 6 color = fmt.Sprintf("#%02x%02x%02x", 255*red/5, 255*green/5, 255*blue/5) } else if colorNumber <= 255 { grey := 255 * (colorNumber - 232) / 23 color = fmt.Sprintf("#%02x%02x%02x", grey, grey, grey) } } else if fields[index+1] == "2" && len(fields) > index+4 { // 24-bit colors. red, _ := strconv.Atoi(fields[index+2]) green, _ := strconv.Atoi(fields[index+3]) blue, _ := strconv.Atoi(fields[index+4]) color = fmt.Sprintf("#%02x%02x%02x", red, green, blue) } } if len(color) > 0 { if field == "38" { foreground = color } else { background = color } } break FieldLoop } } var colon string if len(a.attributes) > 0 { colon = ":" } if len(foreground) > 0 || len(background) > 0 || len(a.attributes) > 0 { fmt.Fprintf(a.buffer, "[%s:%s%s%s]", foreground, background, colon, a.attributes) } } a.state = ansiText default: // Undefined byte. a.state = ansiText // Abort CSI. } // We just entered a substring/command sequence. case ansiSubstring: if r == 27 { // Most likely the end of the substring. a.state = ansiEscape } // Ignore all other characters. // "ansiText" and all others. default: if r == 27 { // This is the start of an escape sequence. a.state = ansiEscape } else { // Just a regular rune. Send to buffer. if _, err := a.buffer.WriteRune(r); err != nil { return 0, err } } } } // Write buffer to target writer. n, err := a.buffer.WriteTo(a.Writer) if err != nil { return int(n), err } return len(text), nil } // TranslateANSI replaces ANSI escape sequences found in the provided string // with tview's style tags and returns the resulting string. func TranslateANSI(text string) string { var buffer bytes.Buffer writer := ANSIWriter(&buffer) writer.Write([]byte(text)) return buffer.String() } golang-github-darkhz-tview-0.0~git20240308.6078a88/application.go000066400000000000000000000564001457770046000240370ustar00rootroot00000000000000package tview import ( "strings" "sync" "time" "github.com/gdamore/tcell/v2" ) const ( // The size of the event/update/redraw channels. queueSize = 100 // The minimum time between two consecutive redraws. redrawPause = 50 * time.Millisecond ) // DoubleClickInterval specifies the maximum time between clicks to register a // double click rather than click. var DoubleClickInterval = 500 * time.Millisecond // MouseAction indicates one of the actions the mouse is logically doing. type MouseAction int16 // Available mouse actions. const ( MouseMove MouseAction = iota MouseLeftDown MouseLeftUp MouseLeftClick MouseLeftDoubleClick MouseMiddleDown MouseMiddleUp MouseMiddleClick MouseMiddleDoubleClick MouseRightDown MouseRightUp MouseRightClick MouseRightDoubleClick MouseScrollUp MouseScrollDown MouseScrollLeft MouseScrollRight ) // queuedUpdate represented the execution of f queued by // Application.QueueUpdate(). If "done" is not nil, it receives exactly one // element after f has executed. type queuedUpdate struct { f func() done chan struct{} } // Application represents the top node of an application. // // It is not strictly required to use this class as none of the other classes // depend on it. However, it provides useful tools to set up an application and // plays nicely with all widgets. // // The following command displays a primitive p on the screen until Ctrl-C is // pressed: // // if err := tview.NewApplication().SetRoot(p, true).Run(); err != nil { // panic(err) // } type Application struct { sync.RWMutex // The application's screen. Apart from Run(), this variable should never be // set directly. Always use the screenReplacement channel after calling // Fini(), to set a new screen (or nil to stop the application). screen tcell.Screen // The primitive which currently has the keyboard focus. focus Primitive // The root primitive to be seen on the screen. root Primitive // Whether or not the application resizes the root primitive. rootFullscreen bool // Set to true if mouse events are enabled. enableMouse bool // Set to true if paste events are enabled. enablePaste bool // An optional capture function which receives a key event and returns the // event to be forwarded to the default input handler (nil if nothing should // be forwarded). inputCapture func(event *tcell.EventKey) *tcell.EventKey // An optional callback function which is invoked just before the root // primitive is drawn. beforeDraw func(screen tcell.Screen) bool // An optional callback function which is invoked after the root primitive // was drawn. afterDraw func(screen tcell.Screen) // Used to send screen events from separate goroutine to main event loop events chan tcell.Event // Functions queued from goroutines, used to serialize updates to primitives. updates chan queuedUpdate // An object that the screen variable will be set to after Fini() was called. // Use this channel to set a new screen object for the application // (screen.Init() and draw() will be called implicitly). A value of nil will // stop the application. screenReplacement chan tcell.Screen // An optional capture function which receives a mouse event and returns the // event to be forwarded to the default mouse handler (nil if nothing should // be forwarded). mouseCapture func(event *tcell.EventMouse, action MouseAction) (*tcell.EventMouse, MouseAction) mouseCapturingPrimitive Primitive // A Primitive returned by a MouseHandler which will capture future mouse events. lastMouseX, lastMouseY int // The last position of the mouse. mouseDownX, mouseDownY int // The position of the mouse when its button was last pressed. lastMouseClick time.Time // The time when a mouse button was last clicked. lastMouseButtons tcell.ButtonMask // The last mouse button state. } // NewApplication creates and returns a new application. func NewApplication() *Application { return &Application{ events: make(chan tcell.Event, queueSize), updates: make(chan queuedUpdate, queueSize), screenReplacement: make(chan tcell.Screen, 1), } } // SetInputCapture sets a function which captures all key events before they are // forwarded to the key event handler of the primitive which currently has // focus. This function can then choose to forward that key event (or a // different one) by returning it or stop the key event processing by returning // nil. // // The only default global key event is Ctrl-C which stops the application. It // requires special handling: // // - If you do not wish to change the default behavior, return the original // event object passed to your input capture function. // - If you wish to block Ctrl-C from any functionality, return nil. // - If you do not wish Ctrl-C to stop the application but still want to // forward the Ctrl-C event to primitives down the hierarchy, return a new // key event with the same key and modifiers, e.g. // tcell.NewEventKey(tcell.KeyCtrlC, 0, tcell.ModNone). // // Pasted key events are not forwarded to the input capture function if pasting // is enabled (see [Application.EnablePaste]). func (a *Application) SetInputCapture(capture func(event *tcell.EventKey) *tcell.EventKey) *Application { a.inputCapture = capture return a } // GetInputCapture returns the function installed with SetInputCapture() or nil // if no such function has been installed. func (a *Application) GetInputCapture() func(event *tcell.EventKey) *tcell.EventKey { return a.inputCapture } // SetMouseCapture sets a function which captures mouse events (consisting of // the original tcell mouse event and the semantic mouse action) before they are // forwarded to the appropriate mouse event handler. This function can then // choose to forward that event (or a different one) by returning it or stop // the event processing by returning a nil mouse event. func (a *Application) SetMouseCapture(capture func(event *tcell.EventMouse, action MouseAction) (*tcell.EventMouse, MouseAction)) *Application { a.mouseCapture = capture return a } // GetMouseCapture returns the function installed with SetMouseCapture() or nil // if no such function has been installed. func (a *Application) GetMouseCapture() func(event *tcell.EventMouse, action MouseAction) (*tcell.EventMouse, MouseAction) { return a.mouseCapture } // SetScreen allows you to provide your own tcell.Screen object. For most // applications, this is not needed and you should be familiar with // tcell.Screen when using this function. // // This function is typically called before the first call to Run(). Init() need // not be called on the screen. func (a *Application) SetScreen(screen tcell.Screen) *Application { if screen == nil { return a // Invalid input. Do nothing. } a.Lock() if a.screen == nil { // Run() has not been called yet. a.screen = screen a.Unlock() screen.Init() return a } // Run() is already in progress. Exchange screen. oldScreen := a.screen a.Unlock() oldScreen.Fini() a.screenReplacement <- screen return a } // EnableMouse enables mouse events or disables them (if "false" is provided). func (a *Application) EnableMouse(enable bool) *Application { a.Lock() defer a.Unlock() if enable != a.enableMouse && a.screen != nil { if enable { a.screen.EnableMouse() } else { a.screen.DisableMouse() } } a.enableMouse = enable return a } // EnablePaste enables the capturing of paste events or disables them (if // "false" is provided). This must be supported by the terminal. // // Widgets won't interpret paste events for navigation or selection purposes. // Paste events are typically only used to insert a block of text into an // [InputField] or a [TextArea]. func (a *Application) EnablePaste(enable bool) *Application { a.Lock() defer a.Unlock() if enable != a.enablePaste && a.screen != nil { if enable { a.screen.EnablePaste() } else { a.screen.DisablePaste() } } a.enablePaste = enable return a } // Run starts the application and thus the event loop. This function returns // when Stop() was called. func (a *Application) Run() error { var ( err, appErr error lastRedraw time.Time // The time the screen was last redrawn. redrawTimer *time.Timer // A timer to schedule the next redraw. ) a.Lock() // Make a screen if there is none yet. if a.screen == nil { a.screen, err = tcell.NewScreen() if err != nil { a.Unlock() return err } if err = a.screen.Init(); err != nil { a.Unlock() return err } if a.enableMouse { a.screen.EnableMouse() } else { a.screen.DisableMouse() } if a.enablePaste { a.screen.EnablePaste() } else { a.screen.DisablePaste() } } // We catch panics to clean up because they mess up the terminal. defer func() { if p := recover(); p != nil { if a.screen != nil { a.screen.Fini() } panic(p) } }() // Draw the screen for the first time. a.Unlock() a.draw() // Separate loop to wait for screen events. var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() for { a.RLock() screen := a.screen a.RUnlock() if screen == nil { // We have no screen. Let's stop. a.QueueEvent(nil) break } // Wait for next event and queue it. event := screen.PollEvent() if event != nil { // Regular event. Queue. a.QueueEvent(event) continue } // A screen was finalized (event is nil). Wait for a new screen. screen = <-a.screenReplacement if screen == nil { // No new screen. We're done. a.QueueEvent(nil) // Stop the event loop. return } // We have a new screen. Keep going. a.Lock() a.screen = screen enableMouse := a.enableMouse enablePaste := a.enablePaste a.Unlock() // Initialize and draw this screen. if err := screen.Init(); err != nil { panic(err) } if enableMouse { screen.EnableMouse() } else { screen.DisableMouse() } if enablePaste { screen.EnablePaste() } else { screen.DisablePaste() } a.draw() } }() // Start event loop. var ( pasteBuffer strings.Builder pasting bool // Set to true while we receive paste key events. ) EventLoop: for { select { // If we received an event, handle it. case event := <-a.events: if event == nil { break EventLoop } switch event := event.(type) { case *tcell.EventKey: // If we are pasting, collect runes, nothing else. if pasting { switch event.Key() { case tcell.KeyRune: pasteBuffer.WriteRune(event.Rune()) case tcell.KeyEnter: pasteBuffer.WriteRune('\n') case tcell.KeyTab: pasteBuffer.WriteRune('\t') } break } a.RLock() root := a.root inputCapture := a.inputCapture a.RUnlock() // Intercept keys. var draw bool originalEvent := event if inputCapture != nil { event = inputCapture(event) if event == nil { a.draw() break // Don't forward event. } draw = true } // Ctrl-C closes the application. if event == originalEvent && event.Key() == tcell.KeyCtrlC { a.Stop() break } // Pass other key events to the root primitive. if root != nil && root.HasFocus() { if handler := root.InputHandler(); handler != nil { handler(event, func(p Primitive) { a.SetFocus(p) }) draw = true } } // Redraw. if draw { a.draw() } case *tcell.EventPaste: if !a.enablePaste { break } if event.Start() { pasting = true pasteBuffer.Reset() } else if event.End() { pasting = false a.RLock() root := a.root a.RUnlock() if root != nil && root.HasFocus() && pasteBuffer.Len() > 0 { // Pass paste event to the root primitive. if handler := root.PasteHandler(); handler != nil { handler(pasteBuffer.String(), func(p Primitive) { a.SetFocus(p) }) } // Redraw. a.draw() } } case *tcell.EventResize: if time.Since(lastRedraw) < redrawPause { if redrawTimer != nil { redrawTimer.Stop() } redrawTimer = time.AfterFunc(redrawPause, func() { a.events <- event }) } a.RLock() screen := a.screen a.RUnlock() if screen == nil { break } lastRedraw = time.Now() screen.Clear() a.draw() case *tcell.EventMouse: consumed, isMouseDownAction := a.fireMouseActions(event) if consumed { a.draw() } a.lastMouseButtons = event.Buttons() if isMouseDownAction { a.mouseDownX, a.mouseDownY = event.Position() } case *tcell.EventError: appErr = event a.Stop() } // If we have updates, now is the time to execute them. case update := <-a.updates: update.f() if update.done != nil { update.done <- struct{}{} } } } // Wait for the event loop to finish. wg.Wait() a.screen = nil return appErr } // fireMouseActions analyzes the provided mouse event, derives mouse actions // from it and then forwards them to the corresponding primitives. func (a *Application) fireMouseActions(event *tcell.EventMouse) (consumed, isMouseDownAction bool) { // We want to relay follow-up events to the same target primitive. var targetPrimitive Primitive // Helper function to fire a mouse action. fire := func(action MouseAction) { switch action { case MouseLeftDown, MouseMiddleDown, MouseRightDown: isMouseDownAction = true } // Intercept event. if a.mouseCapture != nil { event, action = a.mouseCapture(event, action) if event == nil { consumed = true return // Don't forward event. } } // Determine the target primitive. var primitive, capturingPrimitive Primitive if a.mouseCapturingPrimitive != nil { primitive = a.mouseCapturingPrimitive targetPrimitive = a.mouseCapturingPrimitive } else if targetPrimitive != nil { primitive = targetPrimitive } else { primitive = a.root } if primitive != nil { if handler := primitive.MouseHandler(); handler != nil { var wasConsumed bool wasConsumed, capturingPrimitive = handler(action, event, func(p Primitive) { if !p.EnabledFocus() { return } a.SetFocus(p) }) if wasConsumed { consumed = true } } } a.mouseCapturingPrimitive = capturingPrimitive } x, y := event.Position() buttons := event.Buttons() clickMoved := x != a.mouseDownX || y != a.mouseDownY buttonChanges := buttons ^ a.lastMouseButtons if x != a.lastMouseX || y != a.lastMouseY { fire(MouseMove) a.lastMouseX = x a.lastMouseY = y } for _, buttonEvent := range []struct { button tcell.ButtonMask down, up, click, dclick MouseAction }{ {tcell.ButtonPrimary, MouseLeftDown, MouseLeftUp, MouseLeftClick, MouseLeftDoubleClick}, {tcell.ButtonMiddle, MouseMiddleDown, MouseMiddleUp, MouseMiddleClick, MouseMiddleDoubleClick}, {tcell.ButtonSecondary, MouseRightDown, MouseRightUp, MouseRightClick, MouseRightDoubleClick}, } { if buttonChanges&buttonEvent.button != 0 { if buttons&buttonEvent.button != 0 { fire(buttonEvent.down) } else { fire(buttonEvent.up) // A user override might set event to nil. if !clickMoved && event != nil { if a.lastMouseClick.Add(DoubleClickInterval).Before(time.Now()) { fire(buttonEvent.click) a.lastMouseClick = time.Now() } else { fire(buttonEvent.dclick) a.lastMouseClick = time.Time{} // reset } } } } } for _, wheelEvent := range []struct { button tcell.ButtonMask action MouseAction }{ {tcell.WheelUp, MouseScrollUp}, {tcell.WheelDown, MouseScrollDown}, {tcell.WheelLeft, MouseScrollLeft}, {tcell.WheelRight, MouseScrollRight}} { if buttons&wheelEvent.button != 0 { fire(wheelEvent.action) } } return consumed, isMouseDownAction } // Stop stops the application, causing Run() to return. func (a *Application) Stop() { a.Lock() defer a.Unlock() screen := a.screen if screen == nil { return } a.screen = nil screen.Fini() a.screenReplacement <- nil } // Suspend temporarily suspends the application by exiting terminal UI mode and // invoking the provided function "f". When "f" returns, terminal UI mode is // entered again and the application resumes. // // A return value of true indicates that the application was suspended and "f" // was called. If false is returned, the application was already suspended, // terminal UI mode was not exited, and "f" was not called. func (a *Application) Suspend(f func()) bool { a.RLock() screen := a.screen a.RUnlock() if screen == nil { return false // Screen has not yet been initialized. } // Enter suspended mode. if err := screen.Suspend(); err != nil { return false // Suspension failed. } // Wait for "f" to return. f() // If the screen object has changed in the meantime, we need to do more. a.RLock() defer a.RUnlock() if a.screen != screen { // Calling Stop() while in suspend mode currently still leads to a // panic, see https://github.com/gdamore/tcell/issues/440. screen.Fini() if a.screen == nil { return true // If stop was called (a.screen is nil), we're done already. } } else { // It hasn't changed. Resume. screen.Resume() // Not much we can do in case of an error. } // Continue application loop. return true } // Draw refreshes the screen (during the next update cycle). It calls the Draw() // function of the application's root primitive and then syncs the screen // buffer. It is almost never necessary to call this function. It can actually // deadlock your application if you call it from the main thread (e.g. in a // callback function of a widget). Please see // https://github.com/rivo/tview/wiki/Concurrency for details. func (a *Application) Draw() *Application { a.QueueUpdate(func() { a.draw() }) return a } // ForceDraw refreshes the screen immediately. Use this function with caution as // it may lead to race conditions with updates to primitives in other // goroutines. It is always preferable to call [Application.Draw] instead. // Never call this function from a goroutine. // // It is safe to call this function during queued updates and direct event // handling. func (a *Application) ForceDraw() *Application { return a.draw() } // draw actually does what Draw() promises to do. func (a *Application) draw() *Application { a.Lock() defer a.Unlock() screen := a.screen root := a.root fullscreen := a.rootFullscreen before := a.beforeDraw after := a.afterDraw // Maybe we're not ready yet or not anymore. if screen == nil || root == nil { return a } // Resize if requested. if fullscreen && root != nil { width, height := screen.Size() root.SetRect(0, 0, width, height) } // Clear screen to remove unwanted artifacts from the previous cycle. screen.Clear() // Call before handler if there is one. if before != nil { if before(screen) { screen.Show() return a } } // Draw all primitives. root.Draw(screen) // Call after handler if there is one. if after != nil { after(screen) } // Sync screen. screen.Show() return a } // Sync forces a full re-sync of the screen buffer with the actual screen during // the next event cycle. This is useful for when the terminal screen is // corrupted so you may want to offer your users a keyboard shortcut to refresh // the screen. func (a *Application) Sync() *Application { a.updates <- queuedUpdate{f: func() { a.RLock() screen := a.screen a.RUnlock() if screen == nil { return } screen.Sync() }} return a } // SetBeforeDrawFunc installs a callback function which is invoked just before // the root primitive is drawn during screen updates. If the function returns // true, drawing will not continue, i.e. the root primitive will not be drawn // (and an after-draw-handler will not be called). // // Note that the screen is not cleared by the application. To clear the screen, // you may call screen.Clear(). // // Provide nil to uninstall the callback function. func (a *Application) SetBeforeDrawFunc(handler func(screen tcell.Screen) bool) *Application { a.beforeDraw = handler return a } // GetBeforeDrawFunc returns the callback function installed with // SetBeforeDrawFunc() or nil if none has been installed. func (a *Application) GetBeforeDrawFunc() func(screen tcell.Screen) bool { return a.beforeDraw } // SetAfterDrawFunc installs a callback function which is invoked after the root // primitive was drawn during screen updates. // // Provide nil to uninstall the callback function. func (a *Application) SetAfterDrawFunc(handler func(screen tcell.Screen)) *Application { a.afterDraw = handler return a } // GetAfterDrawFunc returns the callback function installed with // SetAfterDrawFunc() or nil if none has been installed. func (a *Application) GetAfterDrawFunc() func(screen tcell.Screen) { return a.afterDraw } // SetRoot sets the root primitive for this application. If "fullscreen" is set // to true, the root primitive's position will be changed to fill the screen. // // This function must be called at least once or nothing will be displayed when // the application starts. // // It also calls SetFocus() on the primitive. func (a *Application) SetRoot(root Primitive, fullscreen bool) *Application { a.Lock() a.root = root a.rootFullscreen = fullscreen if a.screen != nil { a.screen.Clear() } a.Unlock() a.SetFocus(root) return a } // ResizeToFullScreen resizes the given primitive such that it fills the entire // screen. func (a *Application) ResizeToFullScreen(p Primitive) *Application { a.RLock() width, height := a.screen.Size() a.RUnlock() p.SetRect(0, 0, width, height) return a } // SetFocus sets the focus to a new primitive. All key events will be directed // down the hierarchy (starting at the root) until a primitive handles them, // which per default goes towards the focused primitive. // // Blur() will be called on the previously focused primitive. Focus() will be // called on the new primitive. func (a *Application) SetFocus(p Primitive) *Application { a.Lock() if a.focus != nil { a.focus.Blur() } a.focus = p if a.screen != nil { a.screen.HideCursor() } a.Unlock() if p != nil { p.Focus(func(p Primitive) { a.SetFocus(p) }) } return a } // GetFocus returns the primitive which has the current focus. If none has it, // nil is returned. func (a *Application) GetFocus() Primitive { a.RLock() defer a.RUnlock() return a.focus } // QueueUpdate is used to synchronize access to primitives from non-main // goroutines. The provided function will be executed as part of the event loop // and thus will not cause race conditions with other such update functions or // the Draw() function. // // Note that Draw() is not implicitly called after the execution of f as that // may not be desirable. You can call Draw() from f if the screen should be // refreshed after each update. Alternatively, use QueueUpdateDraw() to follow // up with an immediate refresh of the screen. // // This function returns after f has executed. func (a *Application) QueueUpdate(f func()) *Application { ch := make(chan struct{}) a.updates <- queuedUpdate{f: f, done: ch} <-ch return a } // QueueUpdateDraw works like QueueUpdate() except it refreshes the screen // immediately after executing f. func (a *Application) QueueUpdateDraw(f func()) *Application { a.QueueUpdate(func() { f() a.draw() }) return a } // QueueEvent sends an event to the Application event loop. // // It is not recommended for event to be nil. func (a *Application) QueueEvent(event tcell.Event) *Application { a.events <- event return a } golang-github-darkhz-tview-0.0~git20240308.6078a88/borders.go000066400000000000000000000023541457770046000231730ustar00rootroot00000000000000package tview // Borders defines various borders used when primitives are drawn. // These may be changed to accommodate a different look and feel. var Borders = struct { Horizontal rune Vertical rune TopLeft rune TopRight rune BottomLeft rune BottomRight rune LeftT rune RightT rune TopT rune BottomT rune Cross rune HorizontalFocus rune VerticalFocus rune TopLeftFocus rune TopRightFocus rune BottomLeftFocus rune BottomRightFocus rune }{ Horizontal: BoxDrawingsLightHorizontal, Vertical: BoxDrawingsLightVertical, TopLeft: BoxDrawingsLightDownAndRight, TopRight: BoxDrawingsLightDownAndLeft, BottomLeft: BoxDrawingsLightUpAndRight, BottomRight: BoxDrawingsLightUpAndLeft, LeftT: BoxDrawingsLightVerticalAndRight, RightT: BoxDrawingsLightVerticalAndLeft, TopT: BoxDrawingsLightDownAndHorizontal, BottomT: BoxDrawingsLightUpAndHorizontal, Cross: BoxDrawingsLightVerticalAndHorizontal, HorizontalFocus: BoxDrawingsDoubleHorizontal, VerticalFocus: BoxDrawingsDoubleVertical, TopLeftFocus: BoxDrawingsDoubleDownAndRight, TopRightFocus: BoxDrawingsDoubleDownAndLeft, BottomLeftFocus: BoxDrawingsDoubleUpAndRight, BottomRightFocus: BoxDrawingsDoubleUpAndLeft, } golang-github-darkhz-tview-0.0~git20240308.6078a88/box.go000066400000000000000000000377051457770046000223330ustar00rootroot00000000000000package tview import ( "github.com/gdamore/tcell/v2" ) // Box implements the Primitive interface with an empty background and optional // elements such as a border and a title. Box itself does not hold any content // but serves as the superclass of all other primitives. Subclasses add their // own content, typically (but not necessarily) keeping their content within the // box's rectangle. // // Box provides a number of utility functions available to all primitives. // // See https://github.com/rivo/tview/wiki/Box for an example. type Box struct { // The position of the rect. x, y, width, height int // The inner rect reserved for the box's content. innerX, innerY, innerWidth, innerHeight int // Border padding. paddingTop, paddingBottom, paddingLeft, paddingRight int // The box's background color. backgroundColor tcell.Color // If set to true, the background of this box is not cleared while drawing. dontClear bool // Whether or not a border is drawn, reducing the box's space for content by // two in width and height. border bool // The border style. borderStyle tcell.Style // The title. Only visible if there is a border, too. title string // The color of the title. titleColor tcell.Color // The alignment of the title. titleAlign int // Whether or not this box has focus. This is typically ignored for // container primitives (e.g. Flex, Grid, Pages), as they will delegate // focus to their children. hasFocus bool // Whether or not to enable focus for this box. enableFocus bool // Whether or not to draw additional borders when the box has focus. focusBorder bool // Optional callback functions invoked when the primitive receives or loses // focus. focus, blur func() // An optional capture function which receives a key event and returns the // event to be forwarded to the primitive's default input handler (nil if // nothing should be forwarded). inputCapture func(event *tcell.EventKey) *tcell.EventKey // An optional function which is called before the box is drawn. draw func(screen tcell.Screen, x, y, width, height int) (int, int, int, int) // An optional capture function which receives a mouse event and returns the // event to be forwarded to the primitive's default mouse event handler (at // least one nil if nothing should be forwarded). mouseCapture func(action MouseAction, event *tcell.EventMouse) (MouseAction, *tcell.EventMouse) } // NewBox returns a Box without a border. func NewBox() *Box { b := &Box{ width: 15, height: 10, innerX: -1, // Mark as uninitialized. backgroundColor: Styles.PrimitiveBackgroundColor, borderStyle: tcell.StyleDefault.Foreground(Styles.BorderColor).Background(Styles.PrimitiveBackgroundColor), titleColor: Styles.TitleColor, titleAlign: AlignCenter, } return b } // SetBorderPadding sets the size of the borders around the box content. func (b *Box) SetBorderPadding(top, bottom, left, right int) *Box { b.paddingTop, b.paddingBottom, b.paddingLeft, b.paddingRight = top, bottom, left, right return b } // GetRect returns the current position of the rectangle, x, y, width, and // height. func (b *Box) GetRect() (int, int, int, int) { return b.x, b.y, b.width, b.height } // GetInnerRect returns the position of the inner rectangle (x, y, width, // height), without the border and without any padding. Width and height values // will clamp to 0 and thus never be negative. func (b *Box) GetInnerRect() (int, int, int, int) { if b.innerX >= 0 { return b.innerX, b.innerY, b.innerWidth, b.innerHeight } x, y, width, height := b.GetRect() if b.border { x++ y++ width -= 2 height -= 2 } x, y, width, height = x+b.paddingLeft, y+b.paddingTop, width-b.paddingLeft-b.paddingRight, height-b.paddingTop-b.paddingBottom if width < 0 { width = 0 } if height < 0 { height = 0 } return x, y, width, height } // SetRect sets a new position of the primitive. Note that this has no effect // if this primitive is part of a layout (e.g. Flex, Grid) or if it was added // like this: // // application.SetRoot(p, true) func (b *Box) SetRect(x, y, width, height int) { b.x = x b.y = y b.width = width b.height = height b.innerX = -1 // Mark inner rect as uninitialized. } // SetDrawFunc sets a callback function which is invoked after the box primitive // has been drawn. This allows you to add a more individual style to the box // (and all primitives which extend it). // // The function is provided with the box's dimensions (set via SetRect()). It // must return the box's inner dimensions (x, y, width, height) which will be // returned by GetInnerRect(), used by descendent primitives to draw their own // content. func (b *Box) SetDrawFunc(handler func(screen tcell.Screen, x, y, width, height int) (int, int, int, int)) *Box { b.draw = handler return b } // GetDrawFunc returns the callback function which was installed with // SetDrawFunc() or nil if no such function has been installed. func (b *Box) GetDrawFunc() func(screen tcell.Screen, x, y, width, height int) (int, int, int, int) { return b.draw } // WrapInputHandler wraps an input handler (see [Box.InputHandler]) with the // functionality to capture input (see [Box.SetInputCapture]) before passing it // on to the provided (default) input handler. // // This is only meant to be used by subclassing primitives. func (b *Box) WrapInputHandler(inputHandler func(*tcell.EventKey, func(p Primitive))) func(*tcell.EventKey, func(p Primitive)) { return func(event *tcell.EventKey, setFocus func(p Primitive)) { if b.inputCapture != nil { event = b.inputCapture(event) } if event != nil && inputHandler != nil { inputHandler(event, setFocus) } } } // InputHandler returns nil. Box has no default input handling. func (b *Box) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) { return b.WrapInputHandler(nil) } // WrapPasteHandler wraps a paste handler (see [Box.PasteHandler]). func (b *Box) WrapPasteHandler(pasteHandler func(string, func(p Primitive))) func(string, func(p Primitive)) { return func(text string, setFocus func(p Primitive)) { if pasteHandler != nil { pasteHandler(text, setFocus) } } } // PasteHandler returns nil. Box has no default paste handling. func (b *Box) PasteHandler() func(pastedText string, setFocus func(p Primitive)) { return b.WrapPasteHandler(nil) } // SetInputCapture installs a function which captures key events before they are // forwarded to the primitive's default key event handler. This function can // then choose to forward that key event (or a different one) to the default // handler by returning it. If nil is returned, the default handler will not // be called. // // Providing a nil handler will remove a previously existing handler. // // This function can also be used on container primitives (like Flex, Grid, or // Form) as keyboard events will be handed down until they are handled. // // Pasted key events are not forwarded to the input capture function if pasting // is enabled (see [Application.EnablePaste]). func (b *Box) SetInputCapture(capture func(event *tcell.EventKey) *tcell.EventKey) *Box { b.inputCapture = capture return b } // GetInputCapture returns the function installed with SetInputCapture() or nil // if no such function has been installed. func (b *Box) GetInputCapture() func(event *tcell.EventKey) *tcell.EventKey { return b.inputCapture } // WrapMouseHandler wraps a mouse event handler (see [Box.MouseHandler]) with the // functionality to capture mouse events (see [Box.SetMouseCapture]) before passing // them on to the provided (default) event handler. // // This is only meant to be used by subclassing primitives. func (b *Box) WrapMouseHandler(mouseHandler func(MouseAction, *tcell.EventMouse, func(p Primitive)) (bool, Primitive)) func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { if b.mouseCapture != nil { action, event = b.mouseCapture(action, event) } if event != nil && mouseHandler != nil { consumed, capture = mouseHandler(action, event, setFocus) } return } } // MouseHandler returns nil. Box has no default mouse handling. func (b *Box) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return b.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { if action == MouseLeftDown && b.InRect(event.Position()) { setFocus(b) consumed = true } return }) } // SetMouseCapture sets a function which captures mouse events (consisting of // the original tcell mouse event and the semantic mouse action) before they are // forwarded to the primitive's default mouse event handler. This function can // then choose to forward that event (or a different one) by returning it or // returning a nil mouse event, in which case the default handler will not be // called. // // Providing a nil handler will remove a previously existing handler. func (b *Box) SetMouseCapture(capture func(action MouseAction, event *tcell.EventMouse) (MouseAction, *tcell.EventMouse)) *Box { b.mouseCapture = capture return b } // InRect returns true if the given coordinate is within the bounds of the box's // rectangle. func (b *Box) InRect(x, y int) bool { rectX, rectY, width, height := b.GetRect() return x >= rectX && x < rectX+width && y >= rectY && y < rectY+height } // EnabledFocus returns true if focus is enabled for the box. func (b *Box) EnabledFocus() bool { return b.enableFocus } // GetMouseCapture returns the function installed with SetMouseCapture() or nil // if no such function has been installed. func (b *Box) GetMouseCapture() func(action MouseAction, event *tcell.EventMouse) (MouseAction, *tcell.EventMouse) { return b.mouseCapture } // SetBackgroundColor sets the box's background color. func (b *Box) SetBackgroundColor(color tcell.Color) *Box { b.backgroundColor = color b.borderStyle = b.borderStyle.Background(color) return b } // SetBorder sets the flag indicating whether or not the box should have a // border. func (b *Box) SetBorder(show bool) *Box { b.border = show return b } // SetBorderStyle sets the box's border style. func (b *Box) SetBorderStyle(style tcell.Style) *Box { b.borderStyle = style return b } // SetFocusBorder sets the flag indicating whether or not additional borders // should be drawn when the box has focus. func (b *Box) SetFocusBorder(border bool) *Box { b.focusBorder = border return b } // SetBorderColor sets the box's border color. func (b *Box) SetBorderColor(color tcell.Color) *Box { b.borderStyle = b.borderStyle.Foreground(color) return b } // SetBorderAttributes sets the border's style attributes. You can combine // different attributes using bitmask operations: // // box.SetBorderAttributes(tcell.AttrUnderline | tcell.AttrBold) func (b *Box) SetBorderAttributes(attr tcell.AttrMask) *Box { b.borderStyle = b.borderStyle.Attributes(attr) return b } // GetBorderAttributes returns the border's style attributes. func (b *Box) GetBorderAttributes() tcell.AttrMask { _, _, attr := b.borderStyle.Decompose() return attr } // GetBorderColor returns the box's border color. func (b *Box) GetBorderColor() tcell.Color { color, _, _ := b.borderStyle.Decompose() return color } // GetBackgroundColor returns the box's background color. func (b *Box) GetBackgroundColor() tcell.Color { return b.backgroundColor } // SetTitle sets the box's title. func (b *Box) SetTitle(title string) *Box { b.title = title return b } // GetTitle returns the box's current title. func (b *Box) GetTitle() string { return b.title } // SetTitleColor sets the box's title color. func (b *Box) SetTitleColor(color tcell.Color) *Box { b.titleColor = color return b } // SetTitleAlign sets the alignment of the title, one of AlignLeft, AlignCenter, // or AlignRight. func (b *Box) SetTitleAlign(align int) *Box { b.titleAlign = align return b } // Draw draws this primitive onto the screen. func (b *Box) Draw(screen tcell.Screen) { b.DrawForSubclass(screen, b) } // DrawForSubclass draws this box under the assumption that primitive p is a // subclass of this box. This is needed e.g. to draw proper box frames which // depend on the subclass's focus. // // Only call this function from your own custom primitives. It is not needed in // applications that have no custom primitives. func (b *Box) DrawForSubclass(screen tcell.Screen, p Primitive) { // Don't draw anything if there is no space. if b.width <= 0 || b.height <= 0 { return } // Fill background. background := tcell.StyleDefault.Background(b.backgroundColor) if !b.dontClear { for y := b.y; y < b.y+b.height; y++ { for x := b.x; x < b.x+b.width; x++ { screen.SetContent(x, y, ' ', nil, background) } } } // Draw border. if b.border && b.width >= 2 && b.height >= 2 { var vertical, horizontal, topLeft, topRight, bottomLeft, bottomRight rune if p.HasFocus() && b.focusBorder { horizontal = Borders.HorizontalFocus vertical = Borders.VerticalFocus topLeft = Borders.TopLeftFocus topRight = Borders.TopRightFocus bottomLeft = Borders.BottomLeftFocus bottomRight = Borders.BottomRightFocus } else { horizontal = Borders.Horizontal vertical = Borders.Vertical topLeft = Borders.TopLeft topRight = Borders.TopRight bottomLeft = Borders.BottomLeft bottomRight = Borders.BottomRight } for x := b.x + 1; x < b.x+b.width-1; x++ { screen.SetContent(x, b.y, horizontal, nil, b.borderStyle) screen.SetContent(x, b.y+b.height-1, horizontal, nil, b.borderStyle) } for y := b.y + 1; y < b.y+b.height-1; y++ { screen.SetContent(b.x, y, vertical, nil, b.borderStyle) screen.SetContent(b.x+b.width-1, y, vertical, nil, b.borderStyle) } screen.SetContent(b.x, b.y, topLeft, nil, b.borderStyle) screen.SetContent(b.x+b.width-1, b.y, topRight, nil, b.borderStyle) screen.SetContent(b.x, b.y+b.height-1, bottomLeft, nil, b.borderStyle) screen.SetContent(b.x+b.width-1, b.y+b.height-1, bottomRight, nil, b.borderStyle) // Draw title. if b.title != "" && b.width >= 4 { printed, _ := Print(screen, b.title, b.x+1, b.y, b.width-2, b.titleAlign, b.titleColor) if len(b.title)-printed > 0 && printed > 0 { xEllipsis := b.x + b.width - 2 if b.titleAlign == AlignRight { xEllipsis = b.x + 1 } _, _, style, _ := screen.GetContent(xEllipsis, b.y) fg, _, _ := style.Decompose() Print(screen, string(SemigraphicsHorizontalEllipsis), xEllipsis, b.y, 1, AlignLeft, fg) } } } // Call custom draw function. if b.draw != nil { b.innerX, b.innerY, b.innerWidth, b.innerHeight = b.draw(screen, b.x, b.y, b.width, b.height) } else { // Remember the inner rect. b.innerX = -1 b.innerX, b.innerY, b.innerWidth, b.innerHeight = b.GetInnerRect() } } // SetEnableFocus sets the flag indicating whether or not focus should // be enabled for the box. func (b *Box) SetEnableFocus(enable bool) { b.enableFocus = enable } // SetFocusFunc sets a callback function which is invoked when this primitive // receives focus. Container primitives such as Flex or Grid may not be notified // if one of their descendents receive focus directly. // // Set to nil to remove the callback function. func (b *Box) SetFocusFunc(callback func()) *Box { b.focus = callback return b } // SetBlurFunc sets a callback function which is invoked when this primitive // loses focus. This does not apply to container primitives such as Flex or // Grid. // // Set to nil to remove the callback function. func (b *Box) SetBlurFunc(callback func()) *Box { b.blur = callback return b } // Focus is called when this primitive receives focus. func (b *Box) Focus(delegate func(p Primitive)) { b.hasFocus = true if b.focus != nil { b.focus() } } // Blur is called when this primitive loses focus. func (b *Box) Blur() { if b.blur != nil { b.blur() } b.hasFocus = false } // HasFocus returns whether or not this primitive has focus. func (b *Box) HasFocus() bool { return b.hasFocus } golang-github-darkhz-tview-0.0~git20240308.6078a88/button.go000066400000000000000000000132451457770046000230470ustar00rootroot00000000000000package tview import ( "github.com/gdamore/tcell/v2" ) // Button is labeled box that triggers an action when selected. // // See https://github.com/rivo/tview/wiki/Button for an example. type Button struct { *Box // If set to true, the button cannot be activated. disabled bool // The text to be displayed inside the button. text string // The button's style (when deactivated). style tcell.Style // The button's style (when activated). activatedStyle tcell.Style // The button's style (when disabled). disabledStyle tcell.Style // An optional function which is called when the button was selected. selected func() // An optional function which is called when the user leaves the button. A // key is provided indicating which key was pressed to leave (tab or // backtab). exit func(tcell.Key) } // NewButton returns a new input field. func NewButton(label string) *Button { box := NewBox() box.SetRect(0, 0, TaggedStringWidth(label)+4, 1) return &Button{ Box: box, text: label, style: tcell.StyleDefault.Background(Styles.ContrastBackgroundColor).Foreground(Styles.PrimaryTextColor), activatedStyle: tcell.StyleDefault.Background(Styles.PrimaryTextColor).Foreground(Styles.InverseTextColor), disabledStyle: tcell.StyleDefault.Background(Styles.ContrastBackgroundColor).Foreground(Styles.ContrastSecondaryTextColor), } } // SetLabel sets the button text. func (b *Button) SetLabel(label string) *Button { b.text = label return b } // GetLabel returns the button text. func (b *Button) GetLabel() string { return b.text } // SetLabelColor sets the color of the button text. func (b *Button) SetLabelColor(color tcell.Color) *Button { b.style = b.style.Foreground(color) return b } // SetStyle sets the style of the button used when it is not focused. func (b *Button) SetStyle(style tcell.Style) *Button { b.style = style return b } // SetLabelColorActivated sets the color of the button text when the button is // in focus. func (b *Button) SetLabelColorActivated(color tcell.Color) *Button { b.activatedStyle = b.activatedStyle.Foreground(color) return b } // SetBackgroundColorActivated sets the background color of the button text when // the button is in focus. func (b *Button) SetBackgroundColorActivated(color tcell.Color) *Button { b.activatedStyle = b.activatedStyle.Background(color) return b } // SetActivatedStyle sets the style of the button used when it is focused. func (b *Button) SetActivatedStyle(style tcell.Style) *Button { b.activatedStyle = style return b } // SetDisabledStyle sets the style of the button used when it is disabled. func (b *Button) SetDisabledStyle(style tcell.Style) *Button { b.disabledStyle = style return b } // SetDisabled sets whether or not the button is disabled. Disabled buttons // cannot be activated. // // If the button is part of a form, you should set focus to the form itself // after calling this function to set focus to the next non-disabled form item. func (b *Button) SetDisabled(disabled bool) *Button { b.disabled = disabled return b } // IsDisabled returns whether or not the button is disabled. func (b *Button) IsDisabled() bool { return b.disabled } // SetSelectedFunc sets a handler which is called when the button was selected. func (b *Button) SetSelectedFunc(handler func()) *Button { b.selected = handler return b } // SetExitFunc sets a handler which is called when the user leaves the button. // The callback function is provided with the key that was pressed, which is one // of the following: // // - KeyEscape: Leaving the button with no specific direction. // - KeyTab: Move to the next field. // - KeyBacktab: Move to the previous field. func (b *Button) SetExitFunc(handler func(key tcell.Key)) *Button { b.exit = handler return b } // Draw draws this primitive onto the screen. func (b *Button) Draw(screen tcell.Screen) { // Draw the box. style := b.style if b.disabled { style = b.disabledStyle } _, backgroundColor, _ := style.Decompose() if b.HasFocus() && !b.disabled { style = b.activatedStyle _, backgroundColor, _ = style.Decompose() // Highlight button for one drawing cycle. borderColor := b.GetBorderColor() b.SetBorderColor(backgroundColor) defer func() { b.SetBorderColor(borderColor) }() } b.SetBackgroundColor(backgroundColor) b.Box.DrawForSubclass(screen, b) // Draw label. x, y, width, height := b.GetInnerRect() if width > 0 && height > 0 { y = y + height/2 printWithStyle(screen, b.text, x, y, 0, width, AlignCenter, style, true) } } // InputHandler returns the handler for this primitive. func (b *Button) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) { return b.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) { if b.disabled { return } // Process key event. switch key := event.Key(); key { case tcell.KeyEnter: // Selected. if b.selected != nil { b.selected() } case tcell.KeyBacktab, tcell.KeyTab, tcell.KeyEscape: // Leave. No action. if b.exit != nil { b.exit(key) } } }) } // MouseHandler returns the mouse handler for this primitive. func (b *Button) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return b.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { if b.disabled { return false, nil } if !b.InRect(event.Position()) { return false, nil } // Process mouse event. if action == MouseLeftDown { setFocus(b) consumed = true } else if action == MouseLeftClick { if b.selected != nil { b.selected() } consumed = true } return }) } golang-github-darkhz-tview-0.0~git20240308.6078a88/checkbox.go000066400000000000000000000227371457770046000233300ustar00rootroot00000000000000package tview import ( "github.com/gdamore/tcell/v2" ) // Checkbox implements a simple box for boolean values which can be checked and // unchecked. // // See https://github.com/rivo/tview/wiki/Checkbox for an example. type Checkbox struct { *Box // Whether or not this checkbox is disabled/read-only. disabled bool // Whether or not this box is checked. checked bool // The text to be displayed before the input area. label string // The screen width of the label area. A value of 0 means use the width of // the label text. labelWidth int // The label style. labelStyle tcell.Style // The style of the unchecked checkbox. uncheckedStyle tcell.Style // The style of the checked checkbox. checkedStyle tcell.Style // Teh style of the checkbox when it is currently focused. focusStyle tcell.Style // The string used to display an unchecked box. uncheckedString string // The string used to display a checked box. checkedString string // An optional function which is called when the user changes the checked // state of this checkbox. changed func(checked bool) // An optional function which is called when the user indicated that they // are done entering text. The key which was pressed is provided (tab, // shift-tab, or escape). done func(tcell.Key) // A callback function set by the Form class and called when the user leaves // this form item. finished func(tcell.Key) } // NewCheckbox returns a new input field. func NewCheckbox() *Checkbox { return &Checkbox{ Box: NewBox(), labelStyle: tcell.StyleDefault.Foreground(Styles.SecondaryTextColor), uncheckedStyle: tcell.StyleDefault.Background(Styles.ContrastBackgroundColor).Foreground(Styles.PrimaryTextColor), checkedStyle: tcell.StyleDefault.Background(Styles.ContrastBackgroundColor).Foreground(Styles.PrimaryTextColor), focusStyle: tcell.StyleDefault.Background(Styles.PrimaryTextColor).Foreground(Styles.ContrastBackgroundColor), uncheckedString: " ", checkedString: "X", } } // SetChecked sets the state of the checkbox. This also triggers the "changed" // callback if the state changes with this call. func (c *Checkbox) SetChecked(checked bool) *Checkbox { if c.checked != checked { if c.changed != nil { c.changed(checked) } c.checked = checked } return c } // IsChecked returns whether or not the box is checked. func (c *Checkbox) IsChecked() bool { return c.checked } // SetLabel sets the text to be displayed before the input area. func (c *Checkbox) SetLabel(label string) *Checkbox { c.label = label return c } // GetLabel returns the text to be displayed before the input area. func (c *Checkbox) GetLabel() string { return c.label } // SetLabelWidth sets the screen width of the label. A value of 0 will cause the // primitive to use the width of the label string. func (c *Checkbox) SetLabelWidth(width int) *Checkbox { c.labelWidth = width return c } // SetLabelColor sets the color of the label. func (c *Checkbox) SetLabelColor(color tcell.Color) *Checkbox { c.labelStyle = c.labelStyle.Foreground(color) return c } // SetLabelStyle sets the style of the label. func (c *Checkbox) SetLabelStyle(style tcell.Style) *Checkbox { c.labelStyle = style return c } // SetFieldBackgroundColor sets the background color of the input area. func (c *Checkbox) SetFieldBackgroundColor(color tcell.Color) *Checkbox { c.uncheckedStyle = c.uncheckedStyle.Background(color) c.checkedStyle = c.checkedStyle.Background(color) c.focusStyle = c.focusStyle.Foreground(color) return c } // SetFieldTextColor sets the text color of the input area. func (c *Checkbox) SetFieldTextColor(color tcell.Color) *Checkbox { c.uncheckedStyle = c.uncheckedStyle.Foreground(color) c.checkedStyle = c.checkedStyle.Foreground(color) c.focusStyle = c.focusStyle.Background(color) return c } // SetUncheckedStyle sets the style of the unchecked checkbox. func (c *Checkbox) SetUncheckedStyle(style tcell.Style) *Checkbox { c.uncheckedStyle = style return c } // SetCheckedStyle sets the style of the checked checkbox. func (c *Checkbox) SetCheckedStyle(style tcell.Style) *Checkbox { c.checkedStyle = style return c } // SetActivatedStyle sets the style of the checkbox when it is currently // focused. func (c *Checkbox) SetActivatedStyle(style tcell.Style) *Checkbox { c.focusStyle = style return c } // SetCheckedString sets the string to be displayed when the checkbox is // checked (defaults to "X"). The string may contain color tags (consider // adapting the checkbox's various styles accordingly). See [Escape] in // case you want to display square brackets. func (c *Checkbox) SetCheckedString(checked string) *Checkbox { c.checkedString = checked return c } // SetUncheckedString sets the string to be displayed when the checkbox is // not checked (defaults to the empty space " "). The string may contain color // tags (consider adapting the checkbox's various styles accordingly). See // [Escape] in case you want to display square brackets. func (c *Checkbox) SetUncheckedString(unchecked string) *Checkbox { c.uncheckedString = unchecked return c } // SetFormAttributes sets attributes shared by all form items. func (c *Checkbox) SetFormAttributes(labelWidth int, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem { c.labelWidth = labelWidth c.SetLabelColor(labelColor) c.backgroundColor = bgColor c.SetFieldTextColor(fieldTextColor) c.SetFieldBackgroundColor(fieldBgColor) return c } // GetFieldWidth returns this primitive's field width. func (c *Checkbox) GetFieldWidth() int { return 1 } // GetFieldHeight returns this primitive's field height. func (c *Checkbox) GetFieldHeight() int { return 1 } // SetDisabled sets whether or not the item is disabled / read-only. func (c *Checkbox) SetDisabled(disabled bool) FormItem { c.disabled = disabled if c.finished != nil { c.finished(-1) } return c } // SetChangedFunc sets a handler which is called when the checked state of this // checkbox was changed. The handler function receives the new state. func (c *Checkbox) SetChangedFunc(handler func(checked bool)) *Checkbox { c.changed = handler return c } // SetDoneFunc sets a handler which is called when the user is done using the // checkbox. The callback function is provided with the key that was pressed, // which is one of the following: // // - KeyEscape: Abort text input. // - KeyTab: Move to the next field. // - KeyBacktab: Move to the previous field. func (c *Checkbox) SetDoneFunc(handler func(key tcell.Key)) *Checkbox { c.done = handler return c } // SetFinishedFunc sets a callback invoked when the user leaves this form item. func (c *Checkbox) SetFinishedFunc(handler func(key tcell.Key)) FormItem { c.finished = handler return c } // Focus is called when this primitive receives focus. func (c *Checkbox) Focus(delegate func(p Primitive)) { // If we're part of a form and this item is disabled, there's nothing the // user can do here so we're finished. if c.finished != nil && c.disabled { c.finished(-1) return } c.Box.Focus(delegate) } // Draw draws this primitive onto the screen. func (c *Checkbox) Draw(screen tcell.Screen) { c.Box.DrawForSubclass(screen, c) // Prepare x, y, width, height := c.GetInnerRect() rightLimit := x + width if height < 1 || rightLimit <= x { return } // Draw label. _, labelBg, _ := c.labelStyle.Decompose() if c.labelWidth > 0 { labelWidth := c.labelWidth if labelWidth > width { labelWidth = width } printWithStyle(screen, c.label, x, y, 0, labelWidth, AlignLeft, c.labelStyle, labelBg == tcell.ColorDefault) x += labelWidth width -= labelWidth } else { _, _, drawnWidth := printWithStyle(screen, c.label, x, y, 0, width, AlignLeft, c.labelStyle, labelBg == tcell.ColorDefault) x += drawnWidth width -= drawnWidth } // Draw checkbox. str := c.uncheckedString style := c.uncheckedStyle if c.checked { str = c.checkedString style = c.checkedStyle } if c.disabled { style = style.Background(c.backgroundColor) } if c.HasFocus() { style = c.focusStyle } printWithStyle(screen, str, x, y, 0, width, AlignLeft, style, c.disabled) } // InputHandler returns the handler for this primitive. func (c *Checkbox) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) { return c.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) { if c.disabled { return } // Process key event. switch key := event.Key(); key { case tcell.KeyRune, tcell.KeyEnter: // Check. if key == tcell.KeyRune && event.Rune() != ' ' { break } c.checked = !c.checked if c.changed != nil { c.changed(c.checked) } case tcell.KeyTab, tcell.KeyBacktab, tcell.KeyEscape: // We're done. if c.done != nil { c.done(key) } if c.finished != nil { c.finished(key) } } }) } // MouseHandler returns the mouse handler for this primitive. func (c *Checkbox) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return c.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { if c.disabled { return false, nil } x, y := event.Position() _, rectY, _, _ := c.GetInnerRect() if !c.InRect(x, y) { return false, nil } // Process mouse event. if y == rectY { if action == MouseLeftDown { setFocus(c) consumed = true } else if action == MouseLeftClick { c.checked = !c.checked if c.changed != nil { c.changed(c.checked) } consumed = true } } return }) } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/000077500000000000000000000000001457770046000223075ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/box/000077500000000000000000000000001457770046000230775ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/box/README.md000066400000000000000000000000361457770046000243550ustar00rootroot00000000000000![Screenshot](screenshot.png) golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/box/main.go000066400000000000000000000007721457770046000243600ustar00rootroot00000000000000// Demo code for the Box primitive. package main import ( "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) func main() { box := tview.NewBox(). SetBorder(true). SetBorderAttributes(tcell.AttrBold). SetTitle("A [red]c[yellow]o[green]l[darkcyan]o[blue]r[darkmagenta]f[red]u[yellow]l[white] [black:red]c[:yellow]o[:green]l[:darkcyan]o[:blue]r[:darkmagenta]f[:red]u[:yellow]l[white:-] [::bu]title") if err := tview.NewApplication().SetRoot(box, true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/box/screenshot.png000066400000000000000000000351331457770046000257670ustar00rootroot00000000000000PNG  IHDR}M1"iCCPICC ProfileXyTKnX%眓 s%Q"AEPTPAP$""   *(y͙꯺{v`' 6vtrM IWT)@ڟl+#ں>߲6o(/ K{zGy 4Wxd4~DL~;y {=::@"E@!"j սIv :{BB¶=ekDw|ndQ?c"?zgd.laC=-Lm-?nW+J3 xtM̎`Ƙ ;],Clwgd}Tlh鮝,?O}##jLu 7G0QA6&}uDXoqGwH}9$_i{,$`h[ÝO>z;`oP]n0]ֻ}3Ã-w3>; 7D4IyIƖcG[pC) ' ``eo> H|O;$OQio|t,|nfEUѦY9dJh?b X< 2x%| a0Ø K`m[rHsn`&ky; ZVC#ьhV Czk1脅'DGsk!Qn)iE 1>G3^$d. 쵧^1;`P!p> #*zX[ܐ!8L "p%p\-#0k$/ރyVA8X .Hd %H҃L!k P(CPtjkM A/Ih B(ŁDIPZ(-jJDeN*QWPͨ{Gaj fy`qX ց-`g9p1\ mHƢhq$7 vh/t 4݅~D/c(11 a21Ř*LY71+X,+UD֥6=-c;Ci2cp8.+]=Ž$ "!'s& %K#+&%C#95 7yy6'4x!OşcoV)((z)&)V QC8F&t^QRR RjR:SFSO9NHG Rb3)39U"U1 'T Ԃ:$ԥ7Gihi,hBhhihi3hާt.uӽ __decgg(e03 2131^gaÔT3&ss=0/n= |7hVQV+83ݬ lll^l9l^E٭ٓϳ/sprpspXd ,9EǥUuk[;w";!O Ooo=></_!_'"?~N t<,"8#,d$(tYhLRXC8BRVDI$H\dP%*//Z*D %  V.6GyO=q-Xi-%%%%{$KKK]z-M+m,&&UFTKT,ll쒜tf;7"f=G,(*cەWUTU|QW RU+gjj$ unus<$J)M>Mo*͏Z"ZZW>kKiGj7iQ9ӡ ӿh oda14175021Z4V4>`eB019m2e*jif236;a6f.`jb,,NXe*`-mߺdžݦfV6]]=}] GIXZqU.z.E.]]3]G v۝ʝ~QN U=<<tNz{kzz|U-S;7_p:`)0l `A]aaaCb*E&UQPԾhz5?F8Pdzli84 /&:O?y@@Ad))RAӤ Ҿ;epddL28t99zX,tV@@lvIRŹG<<*}c=> `ىBœEE}rgOOƜ8ezxiåڥeee?ʽ˟={ =.TVVmTVO\UXSS^wu9+Wu։U36kF\AtQ)jNh^lohuji|Mĭv dټxw#c߽N?6}~V^>^VmI)^ޭ@#ǚY9k h>}EKȥͯG|.sry|%deGOVV{~9[?!ff8)*#P:@7S{6*9PZǒȜw XJOL^ 0 )+ 8  hr.=S"$&I)V^:EJGMC VUTyQѢ_K[Vn^~AC1IiYyE5ƆŖՎ_wXs.DW}}nSU^%9> ~~rA<,!Tp[E'd6ţ|;UR\RcҎe$;4w2K "䢎>g~!߹c}mIS&%K˔eψ='UaR~~QՕZWT֙;4_~#`SZ󡖬ܛymEګn7;1qoosWow}}<6}1xn3:#Fz/^ "Z}=3ͽo'&̧Y`Qyifb6gNnnbB'dk|^<wΟlnn_Fó 4v &WS&TqhY301agddri[_|,t^8RD]L=%Hr(S'+&w+(Z()(r!Y΢>qREKPkM{X=4 ۍcM|L=,B,=,UmDm(#N\J]s%;z$= 9a.&*‌ `PJ$&#GDǔދ{?AdlԦ Cvҳs6i>xZ5 Ν(-,*+>v*$_i@YJݳ".U /j5k _(Wt_ϼqNPxL6Sm;w;xMuo.}pPob_GO yLHO^~M;&t<ɉ[OƧ OY$Y ՗F>v{r+?Wu7fw/ͣa7YȦȗ(J-3U*!Mz=@CgYYzpsׄw/_SM`UPHJ衰NZPX=^@\r ^TfF6]SUZ~A"b 2¨rYUK^Ւqr#ZZ/uu6u+,7334v5a61-212HTnUod#dζn=sğIKK NOzց;LI+NO;䒩wX4 <$9?wn;~0ߥ@‘'O=UPRqF郲sgQVpWʞ7z1`u#5)ˊWW^T@y]ecRScVm%[oߺwwA.>هx =z=86?50}u+;m5'R 5; :s;XR` PEb0o*Ra=$S$&g#S) jJ9vJ!khZjګttCC  O201`ecmcsc'gou;Gg_` QpBp5$deeȷ*(&(y+H2%IjiG`bno,gbnavʼ1{cS ZwX'sϜI@Q!Í#j1[œp,MaLOgZ>5{$XS> O5O3=kpn2ŬKA5_/WOӰtCL|ǶLtu{i<|,Da(Q+o&'Tew?zrqoMc+8@Q Ԁ! $lPjMbB EE9QQa./a&3ľpa2=VrIZ ]%a2HN,j@4q-tt0N13>d cfb` `g` cg(tbz]+_tCj9~S,O<]bd Af@6GDI~IbRrĽj?duruo2mgNpMYKpgig Wɬx{i7h@Ā dWF ƑuO!MhBI9u53>m4;:=q<`opLސG BA&.u37fb4fRdagugK`26153p:*\++:R\QWԈ \cN&:H[ 6KX\nձqq;_qwtvy!:?,iKLtR,gxƒv)*23/f=r7 Qoӕe V@e.W԰^I3hߘ\ٚt{n=zn= zU񜷏&Ͻ 1hlg/K,~_^>¾RC?~62F6ofvrmpl]s=~φFÍҿMMS[~|@m0㛛Vq)6l[-kH]()iTXtXML:com.adobe.xmp 477 698 1 'IIDATx}GyzDfrn0zFz+YX2 @YYw`< izm ij;ҍ*6bGf%N+qs^y+BOޯyy><#!@`N ̛Gm u/^p=y }ꆕ=]o~pœ\Jh&r 7,~Zl]|yZ''[ ;>q'N<{hV nȻxl6sg97o轃փ7]MKn7zZ'&OMwؿ%|ݿ:}k7waWk;WNjuw9(0{]XbE<\Dر2Ӌd[?ygLwm~few8,Y~zM=;7,[ZCOi?ׯ\j={3Z<{p=Dk'/[չ}Wnž}ڻZ{,YgNT[iNWx]7os?Xs{Ɲ۷yZǿ3y}7=bUsv]ac⊏гX,_Ԝ&1qldw}kx?r-oow3 4ԯٟ]hf>1j;W`q߲Sئ;\ <5nΌz 6bF.o.~6o8\~j;vo7\+&_mxPlщ#ش5W{R}jM1:!J L>0S} ͱ6bǎA_Y'|ik_ ,_ܵʯko?U0q˝02:ŧ?Z7{]_fiO>oyD ,ySUwgˎ[K_lzLn߹~+N~5 4s^y4׸_@cwOp;_ֳ[?>|(50˿N}WL?:vn) 0^= ݾgmuFaDB|S˫]~cڹ={Y$qkB0g]\׾_|%=Om619| ܴkσ=')-;%@` xva- t/޻[]]S/)}ΧFl|U{3o]9?Kw~mFnAz=n= 'oumo8iWfAs ChZ}qKb]'8N7={߀kx< /hjB51q#}iCӿ5a-3E0q/ M=%MG|pCKz' ӞYhQ+L;Cۯ^7<3֫FoW,tczc/';LK{h31'E?o߾ţvLRV~GO蛻d`eomcfyYh.8A (P~o~a3Kd (pG/FAd PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@BE&@5ue Kԅi (..]d PPj^  @@t  @@M@]y&@Μygp- p .|K/z  @Fy?iNGr pQ wfY/]bfq!o߿( @ @ @ @ @ @ @ @ @%0xGإIENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/button/000077500000000000000000000000001457770046000236225ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/button/README.md000066400000000000000000000000361457770046000251000ustar00rootroot00000000000000![Screenshot](screenshot.png) golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/button/main.go000066400000000000000000000005521457770046000250770ustar00rootroot00000000000000// Demo code for the Button primitive. package main import "github.com/darkhz/tview" func main() { app := tview.NewApplication() button := tview.NewButton("Hit Enter to close").SetSelectedFunc(func() { app.Stop() }) button.SetBorder(true).SetRect(0, 0, 22, 3) if err := app.SetRoot(button, false).EnableMouse(true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/button/screenshot.png000066400000000000000000000316301457770046000265100ustar00rootroot00000000000000PNG  IHDR3Y "iCCPICC ProfileXyTKnX%眓 s%Q"AEPTPAP$""   *(y͙꯺{v`' 6vtrM IWT)@ڟl+#ں>߲6o(/ K{zGy 4Wxd4~DL~;y {=::@"E@!"j սIv :{BB¶=ekDw|ndQ?c"?zgd.laC=-Lm-?nW+J3 xtM̎`Ƙ ;],Clwgd}Tlh鮝,?O}##jLu 7G0QA6&}uDXoqGwH}9$_i{,$`h[ÝO>z;`oP]n0]ֻ}3Ã-w3>; 7D4IyIƖcG[pC) ' ``eo> H|O;$OQio|t,|nfEUѦY9dJh?b X< 2x%| a0Ø K`m[rHsn`&ky; ZVC#ьhV Czk1脅'DGsk!Qn)iE 1>G3^$d. 쵧^1;`P!p> #*zX[ܐ!8L "p%p\-#0k$/ރyVA8X .Hd %H҃L!k P(CPtjkM A/Ih B(ŁDIPZ(-jJDeN*QWPͨ{Gaj fy`qX ց-`g9p1\ mHƢhq$7 vh/t 4݅~D/c(11 a21Ř*LY71+X,+UD֥6=-c;Ci2cp8.+]=Ž$ "!'s& %K#+&%C#95 7yy6'4x!OşcoV)((z)&)V QC8F&t^QRR RjR:SFSO9NHG Rb3)39U"U1 'T Ԃ:$ԥ7Gihi,hBhhihi3hާt.uӽ __decgg(e03 2131^gaÔT3&ss=0/n= |7hVQV+83ݬ lll^l9l^E٭ٓϳ/sprpspXd ,9EǥUuk[;w";!O Ooo=></_!_'"?~N t<,"8#,d$(tYhLRXC8BRVDI$H\dP%*//Z*D %  V.6GyO=q-Xi-%%%%{$KKK]z-M+m,&&UFTKT,ll쒜tf;7"f=G,(*cەWUTU|QW RU+gjj$ unus<$J)M>Mo*͏Z"ZZW>kKiGj7iQ9ӡ ӿh oda14175021Z4V4>`eB019m2e*jif236;a6f.`jb,,NXe*`-mߺdžݦfV6]]=}] GIXZqU.z.E.]]3]G v۝ʝ~QN U=<<tNz{kzz|U-S;7_p:`)0l `A]aaaCb*E&UQPԾhz5?F8Pdzli84 /&:O?y@@Ad))RAӤ Ҿ;epddL28t99zX,tV@@lvIRŹG<<*}c=> `ىBœEE}rgOOƜ8ezxiåڥeee?ʽ˟={ =.TVVmTVO\UXSS^wu9+Wu։U36kF\AtQ)jNh^lohuji|Mĭv dټxw#c߽N?6}~V^>^VmI)^ޭ@#ǚY9k h>}EKȥͯG|.sry|%deGOVV{~9[?!ff8)*#P:@7S{6*9PZǒȜw XJOL^ 0 )+ 8  hr.=S"$&I)V^:EJGMC VUTyQѢ_K[Vn^~AC1IiYyE5ƆŖՎ_wXs.DW}}nSU^%9> ~~rA<,!Tp[E'd6ţ|;UR\RcҎe$;4w2K "䢎>g~!߹c}mIS&%K˔eψ='UaR~~QՕZWT֙;4_~#`SZ󡖬ܛymEګn7;1qoosWow}}<6}1xn3:#Fz/^ "Z}=3ͽo'&̧Y`Qyifb6gNnnbB'dk|^<wΟlnn_Fó 4v &WS&TqhY301agddri[_|,t^8RD]L=%Hr(S'+&w+(Z()(r!Y΢>qREKPkM{X=4 ۍcM|L=,B,=,UmDm(#N\J]s%;z$= 9a.&*‌ `PJ$&#GDǔދ{?AdlԦ Cvҳs6i>xZ5 Ν(-,*+>v*$_i@YJݳ".U /j5k _(Wt_ϼqNPxL6Sm;w;xMuo.}pPob_GO yLHO^~M;&t<ɉ[OƧ OY$Y ՗F>v{r+?Wu7fw/ͣa7YȦȗ(J-3U*!Mz=@CgYYzpsׄw/_SM`UPHJ衰NZPX=^@\r ^TfF6]SUZ~A"b 2¨rYUK^Ւqr#ZZ/uu6u+,7334v5a61-212HTnUod#dζn=sğIKK NOzց;LI+NO;䒩wX4 <$9?wn;~0ߥ@‘'O=UPRqF郲sgQVpWʞ7z1`u#5)ˊWW^T@y]ecRScVm%[oߺwwA.>هx =z=86?50}u+;m5'R 5; :s;XR` PEb0o*Ra=$S$&g#S) jJ9vJ!khZjګttCC  O201`ecmcsc'gou;Gg_` QpBp5$deeȷ*(&(y+H2%IjiG`bno,gbnavʼ1{cS ZwX'sϜI@Q!Í#j1[œp,MaLOgZ>5{$XS> O5O3=kpn2ŬKA5_/WOӰtCL|ǶLtu{i<|,Da(Q+o&'Tew?zrqoMc+8@Q Ԁ! $lPjMbB EE9QQa./a&3ľpa2=VrIZ ]%a2HN,j@4q-tt0N13>d cfb` `g` cg(tbz]+_tCj9~S,O<]bd Af@6GDI~IbRrĽj?duruo2mgNpMYKpgig Wɬx{i7h@Ā dWF ƑuO!MhBI9u53>m4;:=q<`opLސG BA&.u37fb4fRdagugK`26153p:*\++:R\QWԈ \cN&:H[ 6KX\nձqq;_qwtvy!:?,iKLtR,gxƒv)*23/f=r7 Qoӕe V@e.W԰^I3hߘ\ٚt{n=zn= zU񜷏&Ͻ 1hlg/K,~_^>¾RC?~62F6ofvrmpl]s=~φFÍҿMMS[~|@m0㛛Vq)6l[-kH]()iTXtXML:com.adobe.xmp 307 532 1 }ٔ!IDATxl}y.g@.&\)+4f2bthk(EiDZ(#]"%#lԨi&"5\ #S#R&&{g|}au"|^?wl߾ @%N\" `Rtvv{! ZUu~#PkyZ#A0 J"" PkN" @ pQ9}GC-~1]O hΘ&IC #p&_>=Mw $L{U/=Ӯl#'gOOWx3I~? IR:l|W} 3fvzeу!t ?c<;L/ʞȄϽ:8x]oNLvK0CGGN_/<. >mݣnzV5E8f8e1kꂫ>,YTU8 'mKN:>YLj+./tMm9^r@@Z`ǣkhcXsg܇/w{2C RCnݝ7^~#u׋拢H={`{^qO9?\o{ݽ(^qۖi2?AdjWg7x?^t#Rߑ+uP nH=ؓZV.ʎh9R v~5Q DZϿ<8sٲIwm~:{':RKvٷk ղ˱t'toovsGDyGr4,VΛUoWmo/||f8;'^iwgPEP%˧ P=k ݎUPƴys uʹ遉ڮL\t҅m}+|qC?leH[ vSQ[{/?qFs2'<8颗)G>` Q6ymuo_^i{:?j(`_>sY}kD.A W+ ΜeyDR؎oWԙL&zUWmOdw3ɮ]Z7<ϙ?rcU}|RҽϞn?dSPR_qT?^=Ia{L#WfMуH+y*ÙyMx97Y7_⾔6٫cXQ+ay-psFw>> oWnO4,rھ~sE'i#Vp/;e8e/6qz0̽Spq I>׋7z?mNn9H{!~&-U0)磃l{dhG}v~2C}pMKt_}'Kw]왕7G_'؟zvڐz`3tAØ þvwJx?#UqM%/ 02Tx/(D?g ??}$ZFуY׆_׬}"dz'֛Iw? S ŗ_pUǥs~>s onuvهWsymsΦuE?GwCg/^'~="ݲ $oz+$ڝ;{ao?2>N͗f1 zwEH.6GAW/ Z#o؃kZH& @Y9df56'>^~"m;LO4sb?˝PD,/|S3!ܮhr 3^05'^K>a1\F.l_NQ]Ƈ0օQx9ۼEQѥ άZ;wr4?\&\[XVWT\w4^3ʟyl{ܿK7z/!d.1">{mFgg]e[SdLW=gd3=?j41hhS I{"1>}ˑm_LLɿ~9'G+3'O3ca "*<d%ж; 0ryj乊o :>Cicp uA݇?~M0soe2&:C D`lJrd VP[@9CΞ##j`<92 VP[@9CΞ##j`<92 VP[@9CΞ##jH#ȵđ@H4w?9F"E@@Cmiߤo߲6o(/ K{zGy 4Wxd4~DL~;y {=::@"E@!"j սIv :{BB¶=ekDw|ndQ?c"?zgd.laC=-Lm-?nW+J3 xtM̎`Ƙ ;],Clwgd}Tlh鮝,?O}##jLu 7G0QA6&}uDXoqGwH}9$_i{,$`h[ÝO>z;`oP]n0]ֻ}3Ã-w3>; 7D4IyIƖcG[pC) ' ``eo> H|O;$OQio|t,|nfEUѦY9dJh?b X< 2x%| a0Ø K`m[rHsn`&ky; ZVC#ьhV Czk1脅'DGsk!Qn)iE 1>G3^$d. 쵧^1;`P!p> #*zX[ܐ!8L "p%p\-#0k$/ރyVA8X .Hd %H҃L!k P(CPtjkM A/Ih B(ŁDIPZ(-jJDeN*QWPͨ{Gaj fy`qX ց-`g9p1\ mHƢhq$7 vh/t 4݅~D/c(11 a21Ř*LY71+X,+UD֥6=-c;Ci2cp8.+]=Ž$ "!'s& %K#+&%C#95 7yy6'4x!OşcoV)((z)&)V QC8F&t^QRR RjR:SFSO9NHG Rb3)39U"U1 'T Ԃ:$ԥ7Gihi,hBhhihi3hާt.uӽ __decgg(e03 2131^gaÔT3&ss=0/n= |7hVQV+83ݬ lll^l9l^E٭ٓϳ/sprpspXd ,9EǥUuk[;w";!O Ooo=></_!_'"?~N t<,"8#,d$(tYhLRXC8BRVDI$H\dP%*//Z*D %  V.6GyO=q-Xi-%%%%{$KKK]z-M+m,&&UFTKT,ll쒜tf;7"f=G,(*cەWUTU|QW RU+gjj$ unus<$J)M>Mo*͏Z"ZZW>kKiGj7iQ9ӡ ӿh oda14175021Z4V4>`eB019m2e*jif236;a6f.`jb,,NXe*`-mߺdžݦfV6]]=}] GIXZqU.z.E.]]3]G v۝ʝ~QN U=<<tNz{kzz|U-S;7_p:`)0l `A]aaaCb*E&UQPԾhz5?F8Pdzli84 /&:O?y@@Ad))RAӤ Ҿ;epddL28t99zX,tV@@lvIRŹG<<*}c=> `ىBœEE}rgOOƜ8ezxiåڥeee?ʽ˟={ =.TVVmTVO\UXSS^wu9+Wu։U36kF\AtQ)jNh^lohuji|Mĭv dټxw#c߽N?6}~V^>^VmI)^ޭ@#ǚY9k h>}EKȥͯG|.sry|%deGOVV{~9[?!ff8)*#P:@7S{6*9PZǒȜw XJOL^ 0 )+ 8  hr.=S"$&I)V^:EJGMC VUTyQѢ_K[Vn^~AC1IiYyE5ƆŖՎ_wXs.DW}}nSU^%9> ~~rA<,!Tp[E'd6ţ|;UR\RcҎe$;4w2K "䢎>g~!߹c}mIS&%K˔eψ='UaR~~QՕZWT֙;4_~#`SZ󡖬ܛymEګn7;1qoosWow}}<6}1xn3:#Fz/^ "Z}=3ͽo'&̧Y`Qyifb6gNnnbB'dk|^<wΟlnn_Fó 4v &WS&TqhY301agddri[_|,t^8RD]L=%Hr(S'+&w+(Z()(r!Y΢>qREKPkM{X=4 ۍcM|L=,B,=,UmDm(#N\J]s%;z$= 9a.&*‌ `PJ$&#GDǔދ{?AdlԦ Cvҳs6i>xZ5 Ν(-,*+>v*$_i@YJݳ".U /j5k _(Wt_ϼqNPxL6Sm;w;xMuo.}pPob_GO yLHO^~M;&t<ɉ[OƧ OY$Y ՗F>v{r+?Wu7fw/ͣa7YȦȗ(J-3U*!Mz=@CgYYzpsׄw/_SM`UPHJ衰NZPX=^@\r ^TfF6]SUZ~A"b 2¨rYUK^Ւqr#ZZ/uu6u+,7334v5a61-212HTnUod#dζn=sğIKK NOzց;LI+NO;䒩wX4 <$9?wn;~0ߥ@‘'O=UPRqF郲sgQVpWʞ7z1`u#5)ˊWW^T@y]ecRScVm%[oߺwwA.>هx =z=86?50}u+;m5'R 5; :s;XR` PEb0o*Ra=$S$&g#S) jJ9vJ!khZjګttCC  O201`ecmcsc'gou;Gg_` QpBp5$deeȷ*(&(y+H2%IjiG`bno,gbnavʼ1{cS ZwX'sϜI@Q!Í#j1[œp,MaLOgZ>5{$XS> O5O3=kpn2ŬKA5_/WOӰtCL|ǶLtu{i<|,Da(Q+o&'Tew?zrqoMc+8@Q Ԁ! $lPjMbB EE9QQa./a&3ľpa2=VrIZ ]%a2HN,j@4q-tt0N13>d cfb` `g` cg(tbz]+_tCj9~S,O<]bd Af@6GDI~IbRrĽj?duruo2mgNpMYKpgig Wɬx{i7h@Ā dWF ƑuO!MhBI9u53>m4;:=q<`opLސG BA&.u37fb4fRdagugK`26153p:*\++:R\QWԈ \cN&:H[ 6KX\nձqq;_qwtvy!:?,iKLtR,gxƒv)*23/f=r7 Qoӕe V@e.W԰^I3hߘ\ٚt{n=zn= zU񜷏&Ͻ 1hlg/K,~_^>¾RC?~62F6ofvrmpl]s=~φFÍҿMMS[~|@m0㛛Vq)6l[-kH]()iTXtXML:com.adobe.xmp 184 510 1 IDATx p}a(r`^Z& & MDBRƮ@cwDhx0㄄8P#<Ij`00@`:鞓9B >tJ֮]+    gG9&PQQaÆ%.^Z@Z`@Z@ih]tA4 @ i6h d iK͊"m&FLTt]@eͬ@ %]iC:Tݮlf;ڦG"_U ]=ycu }OSv깪UC^LG҄lU]Im~?Yeu}'H~YwA;,c@Iןoqb8󍊨A} uш5^UZkoOھ fJov 1[o^-Z y*PM,yh ek|&^jJo5r{;Bq 7HIYchkՍ_ӥ"fϞ۪uWm;=+tPSB#ITy (E7)4E3~W=6۾̮b]8Ô,Ф|)PkͿ9_+\K c[!R2@1u^ZϩPm)Z?a=qn羢A]T[6mtj~?'l'u:^3Ztjm{Hqڒ'-P(u2-g ׆"=L6(F-֨TH{\,:xo<0HcR^cw6R͞>-xFF/ΉDhXu2z$*h&Ս_/UT}^ſ6?lV5L9:DžQ?C[%CjOiwhױ^Cg=vv?lY]먒CU~!]h m ^nፆ;t^u6۽wZazD|>J}QFЂZ|İTCDjxWZvjHv2Nk/ j)CV}1p~S\WX[OiîU.ⱑKHURE+䥉pݚT4ʾ>n1a~1P~:/ВDPA3kۨ-͜dΞlpISGwƻaWvTq_aȟQ n_OP['km7lkKmҊBn#P]=uJ7ǧT}S*T(mѯ*<3P?;zvL&'ze S,׸ZSw}S+i 42[7O4D*WmꗫqjeZ7.qݡYy~TG*;Gh韺豙*{9\is'Jޤ^pڭx[B,Rhwa}I ںJ5cL9*a|w.YpSW< ;ά%!p; }U3 9kF%oh=q}[6nw Xwّ:1jQm3͘}j? ,o|ɖ vg1݇:xlc7.؍LqcS6!Oi֘pDZ[7rt:Ojwʅh6jd=0Xx vj0Kʴv%yRfElָ{ެ`9Z=Ù`~s j,;eW0;wE,oW^[t:}k^~gsIVM['pǝMok{?֎r6k:UJ;`z ,2и&7^NUg1<.z|nMY.99܇6y b(X){41kV@gM-+3]bi*½]o6&vJjӦ5=^ ё4oJSɖ8cP֨sy=E7׬cw_gRK~h?,]f tL_lz?Z}F 4ORp iXաٓnƬ@)vح07u ͔7 C͒P@}`|ܑ~t>4=j1İMc3DSY=5QZ-㪬bXy+uNg讻D;?4/3c+gŜ@L{&&G,2c.}t4ʃC&B nܕ J&z蜂8ѵ>51T`*6w &kVj% ܑ̚Yh-(Nk)P?oxfM_oQxMnlzNepI; 1]qKW Z?TO7''wDVs44lo#GO Pz 1\?9}gmj߼cߦ7M]][π@ 9q   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ݾNIENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/dropdown/000077500000000000000000000000001457770046000241435ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/dropdown/README.md000066400000000000000000000000361457770046000254210ustar00rootroot00000000000000![Screenshot](screenshot.png) golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/dropdown/main.go000066400000000000000000000006001457770046000254120ustar00rootroot00000000000000// Demo code for the DropDown primitive. package main import "github.com/darkhz/tview" func main() { app := tview.NewApplication() dropdown := tview.NewDropDown(). SetLabel("Select an option (hit Enter): "). SetOptions([]string{"First", "Second", "Third", "Fourth", "Fifth"}, nil) if err := app.SetRoot(dropdown, true).EnableMouse(true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/dropdown/screenshot.png000066400000000000000000000431071457770046000270330ustar00rootroot00000000000000PNG  IHDRTO7"iCCPICC ProfileXyTKnX%眓 s%Q"AEPTPAP$""   *(y͙꯺{v`' 6vtrM IWT)@ڟl+#ں>߲6o(/ K{zGy 4Wxd4~DL~;y {=::@"E@!"j սIv :{BB¶=ekDw|ndQ?c"?zgd.laC=-Lm-?nW+J3 xtM̎`Ƙ ;],Clwgd}Tlh鮝,?O}##jLu 7G0QA6&}uDXoqGwH}9$_i{,$`h[ÝO>z;`oP]n0]ֻ}3Ã-w3>; 7D4IyIƖcG[pC) ' ``eo> H|O;$OQio|t,|nfEUѦY9dJh?b X< 2x%| a0Ø K`m[rHsn`&ky; ZVC#ьhV Czk1脅'DGsk!Qn)iE 1>G3^$d. 쵧^1;`P!p> #*zX[ܐ!8L "p%p\-#0k$/ރyVA8X .Hd %H҃L!k P(CPtjkM A/Ih B(ŁDIPZ(-jJDeN*QWPͨ{Gaj fy`qX ց-`g9p1\ mHƢhq$7 vh/t 4݅~D/c(11 a21Ř*LY71+X,+UD֥6=-c;Ci2cp8.+]=Ž$ "!'s& %K#+&%C#95 7yy6'4x!OşcoV)((z)&)V QC8F&t^QRR RjR:SFSO9NHG Rb3)39U"U1 'T Ԃ:$ԥ7Gihi,hBhhihi3hާt.uӽ __decgg(e03 2131^gaÔT3&ss=0/n= |7hVQV+83ݬ lll^l9l^E٭ٓϳ/sprpspXd ,9EǥUuk[;w";!O Ooo=></_!_'"?~N t<,"8#,d$(tYhLRXC8BRVDI$H\dP%*//Z*D %  V.6GyO=q-Xi-%%%%{$KKK]z-M+m,&&UFTKT,ll쒜tf;7"f=G,(*cەWUTU|QW RU+gjj$ unus<$J)M>Mo*͏Z"ZZW>kKiGj7iQ9ӡ ӿh oda14175021Z4V4>`eB019m2e*jif236;a6f.`jb,,NXe*`-mߺdžݦfV6]]=}] GIXZqU.z.E.]]3]G v۝ʝ~QN U=<<tNz{kzz|U-S;7_p:`)0l `A]aaaCb*E&UQPԾhz5?F8Pdzli84 /&:O?y@@Ad))RAӤ Ҿ;epddL28t99zX,tV@@lvIRŹG<<*}c=> `ىBœEE}rgOOƜ8ezxiåڥeee?ʽ˟={ =.TVVmTVO\UXSS^wu9+Wu։U36kF\AtQ)jNh^lohuji|Mĭv dټxw#c߽N?6}~V^>^VmI)^ޭ@#ǚY9k h>}EKȥͯG|.sry|%deGOVV{~9[?!ff8)*#P:@7S{6*9PZǒȜw XJOL^ 0 )+ 8  hr.=S"$&I)V^:EJGMC VUTyQѢ_K[Vn^~AC1IiYyE5ƆŖՎ_wXs.DW}}nSU^%9> ~~rA<,!Tp[E'd6ţ|;UR\RcҎe$;4w2K "䢎>g~!߹c}mIS&%K˔eψ='UaR~~QՕZWT֙;4_~#`SZ󡖬ܛymEګn7;1qoosWow}}<6}1xn3:#Fz/^ "Z}=3ͽo'&̧Y`Qyifb6gNnnbB'dk|^<wΟlnn_Fó 4v &WS&TqhY301agddri[_|,t^8RD]L=%Hr(S'+&w+(Z()(r!Y΢>qREKPkM{X=4 ۍcM|L=,B,=,UmDm(#N\J]s%;z$= 9a.&*‌ `PJ$&#GDǔދ{?AdlԦ Cvҳs6i>xZ5 Ν(-,*+>v*$_i@YJݳ".U /j5k _(Wt_ϼqNPxL6Sm;w;xMuo.}pPob_GO yLHO^~M;&t<ɉ[OƧ OY$Y ՗F>v{r+?Wu7fw/ͣa7YȦȗ(J-3U*!Mz=@CgYYzpsׄw/_SM`UPHJ衰NZPX=^@\r ^TfF6]SUZ~A"b 2¨rYUK^Ւqr#ZZ/uu6u+,7334v5a61-212HTnUod#dζn=sğIKK NOzց;LI+NO;䒩wX4 <$9?wn;~0ߥ@‘'O=UPRqF郲sgQVpWʞ7z1`u#5)ˊWW^T@y]ecRScVm%[oߺwwA.>هx =z=86?50}u+;m5'R 5; :s;XR` PEb0o*Ra=$S$&g#S) jJ9vJ!khZjګttCC  O201`ecmcsc'gou;Gg_` QpBp5$deeȷ*(&(y+H2%IjiG`bno,gbnavʼ1{cS ZwX'sϜI@Q!Í#j1[œp,MaLOgZ>5{$XS> O5O3=kpn2ŬKA5_/WOӰtCL|ǶLtu{i<|,Da(Q+o&'Tew?zrqoMc+8@Q Ԁ! $lPjMbB EE9QQa./a&3ľpa2=VrIZ ]%a2HN,j@4q-tt0N13>d cfb` `g` cg(tbz]+_tCj9~S,O<]bd Af@6GDI~IbRrĽj?duruo2mgNpMYKpgig Wɬx{i7h@Ā dWF ƑuO!MhBI9u53>m4;:=q<`opLސG BA&.u37fb4fRdagugK`26153p:*\++:R\QWԈ \cN&:H[ 6KX\nձqq;_qwtvy!:?,iKLtR,gxƒv)*23/f=r7 Qoӕe V@e.W԰^I3hߘ\ٚt{n=zn= zU񜷏&Ͻ 1hlg/K,~_^>¾RC?~62F6ofvrmpl]s=~φFÍҿMMS[~|@m0㛛Vq)6l[-kH]()iTXtXML:com.adobe.xmp 275 596 1 ai+IDATx ՝ Q00" jPUAY%*1Y%" bX1p3y]}g麜:u=sTDB@@n]8:GhuP(8r?P  @[ R}!,* ЖJSFk|%^;}<;~tzAwa2b=EξHKjojA,\&26m9Qw#7BkK<{O7lsuzտ;(rϴ?iI="2t׵gMBbw_XԎF>zԪag3y[jt 쫗fk˭-y ߹wnLa1bͼ< }E>l ~-Ct,1@^T{3VT@ZV򊴏 Pm/MiEGvMG-2X_9-US}sȷUs.JT8<K54b {X'56V+ꐨMy5y:[ z,KN#@R3]{_FźyEh:]Y|߬%Ǒ<i?G)%_=wN4V&QA>7UZN됵dkvMtz泳Z.9@oJYPۢO&cuAWS'm~y+J eЁAonS;wS'8CMCI:[n5qEVRW3E>;mѮKY>9C@ue:vq{]kͽ=Y5e~bS PD;LGc\_o֔ȿ.o]A= _NL=K1y P:6g gOפRwA/c,g<÷GZ ,{=tZzf S^ t8-p⅛u`|qN>+ _[VvE:W EdO aE>f~csq|S=LKgߴ4>[˭K42u^_^X%%+ +:@u~j8zz^rפ~GkuIjl9KV,rOԣjz꫓4f=:nܨ93uͺs3f[e(fa*XUެBai<ȓ)E/US4cЄ[bSo}UA_S\|3k†`k _])ZwщE>O}:]׸?HE6uk(M} Zhj$;Մ/yCj`OԨ[1 u{m0e75<+]9'Vc?ؒ uuv]Pu^0g wڬ^_sEg>ȶsϻ)uilCS+(%hڬNuTvb+׈#,}=_Ln^:L38i&L rݮZH_ 2A֝'X؁o?u]NI}MQu~yx+yOݤ"S+fjHCIa[6Qs1A]^->Ìrh0DS691vښ;|ⅽߩ]Xc,)tZ<>=XK__XZ>0Q^'jAZqHL"@3YCcsd?6K5?Qvob@o L+uϺE r0LkU'-%-f.>JM5$hGuhHluNZ9?'C:T+!1Hvse Z#5B?Խ/O.r<=|ak cs%lnRm$/|-W_mj[ƪ6h$jbMEcʪٚH!nD]1ظ֠K):0bM3\qE<𴢚fQo߶5)EʔEfR{?`zwӬIY>ޡ/۰K-$`w﹙/7I*Zo;{pmӆևԯ)Q'2h*:F ;5?#MT1\}'!I[F='|MFͦܥ>/ASUi/Kx%FWr큚08X6ᇺf'[Ɨuy\ 'q&>^ |{72VlfXw>[k}*=ľ\e-!iE:. F"L)v5/GZPdFHnnӴ$mڬڞA-v76۴huҷf;h;OGLKg&ur! =m5j|]Y’i1(lUc,Ӓj4v 4ypZ&߳ũwce.n?ԞpsVUcfKN Q{.+bôo jct>Ԥb(s!w{,0}-{!G\Go!m) a~7!jti_!:Ӄu*2i0UlH R:^pA)|YQ{xR#;[={|[6hɱܜ6`:Ya5j|vQ4*,ݒWbeA>[eM"_w6F^m4,e.;= "_~{.l~:|vQ CidM\FǹPtdrbюw7J8 W`)L]Y|Cmw|ӡ:NU[o Oːeb׃6U͐E U`k+GƳ[tA<=m~ܖ[xw%j|{2 =5phZP!-iy 7֛٠ Ȟ:p kVpk V|AIy{-[\X 皯mžA{&Tz-m>NRpf;@U}{tf-k~'vo vSA?%Yy+R{vYz)ḱZǶ'Y}WGu Wp눮O/c=G>]#_Y1B=~`>37/V=vemΌBj#P)t{V;E=h@8:unl{WW-jx9@~q@~.r    "3 @5dS5ǀ,-K={=%J)  U{ dM vr4)lI iT/I)z~^r$?I:>!i9DWD{ۅ?!@ku@; Xk,rizwg% v _x9JQ,ɃGݔ5 u?JHcsH/H%[ek Zo< ҃i=[RWD&F)#\R=n;;^aᢚm_VK󤙒EyGJ6 Jo(+kYη0H=g\/_dM0[vt+>Fg&i+F8ҋռ"|>3ּ) ^׹WLY,m"^ڄ P>e#PoZl`v5 -=!MʊYFS9F4JJ@[S>^~Ƽ,RҔ:Q"66nOj;unݳ +E>-`ssgխ{Xjp/I.Qn"bR.`;npFw 7>Flsdvb6⟝;m-Qn֮<6 _+-RR6e%M|@fƺY !,,Y:M1_vj @#\iXre~Anu\Iv)i"܆V˚[ݥֵ̕|vښlh.'!P =H &`31/b^a/Cnb(R @E *  C2@*JWQoE( PQz, @1~P (GN%w0`o8 -m쯿G~/] oO{*_U 9ޔ^N.N~2m"|]2onܾwH7CC Y`t[2R!'͐IoH$dj U;!Xꦬ7)\dY^0VsxD 쑳˥n%6Rt=;vk,x.iv-Jݭ;OpO}R'9ة=\Of{ZNų$Y`",u%ݛFϷY` -=oJpJ W{4}i è`φCo,9?lX.uh PXFIg\XdlSaG>v,(v,^&a7M)i{bmn~Y;';h[~,07'Z{:/!\+ Kr({kYIJ&%1惖OMҁn:E}zίpc\;kJ׺M.Ec\礅nΚtd%\/Yi-NV+a˰E_ )e~y)=^ǻdM4K+<r,dZX[pm}{Ex:=vE2갷wED ,<[=| &@+%!P1ְ"}K/Ah,|k/ZXEAKŖt z.$is]|薼~4Ӷf  #?"`<~yF[<rnZu:@u@lJ5mDdV9_`z a9yp/$ PǴ#-~ (e)?~#i|;K}4Ym҇XQ$oF0@~7*DɮU'liʒ57]uuryᅀb i[mh7qYdx +dmKdu2YU?܌  dX^`k-Y>Ll8]`?%z , {\6N۫]`k,⁰bia8kش%߅]eOmC@BHI1@d W;gɮ4&엝gΒ {Ku%הA[̳F%kYkG8k Zxe.:0rm/gn0C`bB Pfu'-mHX8Q-" )ե簎S+N%fEJ)V`g82%PB86C\]_s-۳tl PJ}7 @W6DrXɪr4d!_IjX}(@  EV@ UQ  9Ȋ@u 4oڰS]jfDG߰yӶ&t}QEhQ@Co~iS]UuO1b}32dwf[{6կ6E(ua#@˯ix}sl޽úv6662rhQ*/?П4`i\ּiG]O;댓i26/J;s1n^vs @7*"Ж3~tXOk,}΢dnI ~oΟΝf ^,޻~_?q C,_ChCF{!6B",xEK.{lOm+ŋ/Y|%'ڒiߞ{ЅV/se>㸾|lzDAV=W{ !6'g_|Cz8+/}]K]޵{=vdytó/Bjj>E&6{6t-ӿVuu׺sY c1E lþ?Wv0^{Þn[PghK]zpg }=KGw wHWNv {|{rdk̝xhr שns~Y(Y\"_`)Jp_rjAqr۹ckp}v⺱aG uwEjo_ݔöN0@[ J PE(5CrZuMɥ?sk!PD?E3E!@ U16ڳaoynǻɻ巌ΚA=>7~ڸ=g<=ö#}upOk\;\vJ`AXjU{>eM ۶745v+>$1qȌKY@t{L Z.]wR r;DP_qT@k["PITRe֕s~YiXQ-¼ȍ P*x9@~y@ ԡ D* rw{n|x]}RF2z3 ,mɴ{f_Le#Mҵ{vQ~8Г.dhk7Q"(@ rtc"+J6i-eL 3d! ސ(|cڻ[]vn@{C}"Ў6_jXbc7ix$uډïF{"G0ۣnҳCiil +r=( K/ݤץmn$/H Ώ8%i^dϤ$셇 66jMVe8E>O3©;op; WqvQ>rcbίb:*@^~U;"XG>[nh[e-0 o>Y#,%t)|"" Ynb4fۇ-ڹI[e?2-Y$!P<Z~ų$*BFƫj7cOR&,%֓P:E i)^MXeJӰxEGkuslΎΓ"P _1) hwu_݄5|UЀv]=ǫ@ xѴ4F%O[/WL P_)J"ށ?$;g)3! ;^(iL#ioѧw`po)ZJ#qt?e~jm5|;rv5##0adW>@_iTRxK;g.w`W>X ~$}+.uWawk|IWTh@+\+aSܰץ$޹]ineW| u[ҭBO6d KEw bһ@kFEZFTcIb;Ώ ,&+,@Qv 7X.:rzDW!K1 ({W Vidvljd$_ϐ-笕c-;Y(K * Ȅ/`3ŪUb.X@=@z~rd Y~Y`X P}o92@,,0,F^_ @.ub)`ק۽]ן\ۗd@p_fl@ Md>/SqҔLm{U$I{DIV:=i13'`!OƔr\{I]Ǣ[_|bݓ *w#xҨ1@ǝ">ح;OKDig9w?F=#`7-MY˘WuF  `oLzSʞnu)7aMCKj7/JWVoA6_~#mh,LS l%֛-Tf?I/nݐ"0@I~%pOw~fWm0#yaWHgW& H9QItn+ B2(c\η=$Nœ!kـ[]/O!mvpo`xZ Kg'Y6MvrӖu7df|r(@ Xxx ~ !clx\lKi* vD7m/ɗ~k$kDnKZ  Z(3 +}Js~3sK}2ck5Ɠj| B2hAVZ6Zb}))[[3%I{{ bfdmvmov@ @s ~-(nKvK/12n_䍠Ū︫74 ǺmiYn +)/#PNʤ6Ѯ !|+lڮ ̘r43Ɗ:ZY|0iWhC]p_ O mPzi-|~+FyxyE {"PT=Ia  @w:"                                                                                                                                                                                                                                @u B"»!IENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/flex/000077500000000000000000000000001457770046000232455ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/flex/README.md000066400000000000000000000000361457770046000245230ustar00rootroot00000000000000![Screenshot](screenshot.png) golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/flex/main.go000066400000000000000000000013611457770046000245210ustar00rootroot00000000000000// Demo code for the Flex primitive. package main import ( "github.com/darkhz/tview" ) func main() { app := tview.NewApplication() flex := tview.NewFlex(). AddItem(tview.NewBox().SetBorder(true).SetTitle("Left (1/2 x width of Top)"), 0, 1, false). AddItem(tview.NewFlex().SetDirection(tview.FlexRow). AddItem(tview.NewBox().SetBorder(true).SetTitle("Top"), 0, 1, false). AddItem(tview.NewBox().SetBorder(true).SetTitle("Middle (3 x height of Top)"), 0, 3, false). AddItem(tview.NewBox().SetBorder(true).SetTitle("Bottom (5 rows)"), 5, 1, false), 0, 2, false). AddItem(tview.NewBox().SetBorder(true).SetTitle("Right (20 cols)"), 20, 1, false) if err := app.SetRoot(flex, true).EnableMouse(true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/flex/screenshot.png000066400000000000000000001034731457770046000261400ustar00rootroot00000000000000PNG  IHDRV6"iCCPICC ProfileXyTKnX%眓 s%Q"AEPTPAP$""   *(y͙꯺{v`' 6vtrM IWT)@ڟl+#ں>߲6o(/ K{zGy 4Wxd4~DL~;y {=::@"E@!"j սIv :{BB¶=ekDw|ndQ?c"?zgd.laC=-Lm-?nW+J3 xtM̎`Ƙ ;],Clwgd}Tlh鮝,?O}##jLu 7G0QA6&}uDXoqGwH}9$_i{,$`h[ÝO>z;`oP]n0]ֻ}3Ã-w3>; 7D4IyIƖcG[pC) ' ``eo> H|O;$OQio|t,|nfEUѦY9dJh?b X< 2x%| a0Ø K`m[rHsn`&ky; ZVC#ьhV Czk1脅'DGsk!Qn)iE 1>G3^$d. 쵧^1;`P!p> #*zX[ܐ!8L "p%p\-#0k$/ރyVA8X .Hd %H҃L!k P(CPtjkM A/Ih B(ŁDIPZ(-jJDeN*QWPͨ{Gaj fy`qX ց-`g9p1\ mHƢhq$7 vh/t 4݅~D/c(11 a21Ř*LY71+X,+UD֥6=-c;Ci2cp8.+]=Ž$ "!'s& %K#+&%C#95 7yy6'4x!OşcoV)((z)&)V QC8F&t^QRR RjR:SFSO9NHG Rb3)39U"U1 'T Ԃ:$ԥ7Gihi,hBhhihi3hާt.uӽ __decgg(e03 2131^gaÔT3&ss=0/n= |7hVQV+83ݬ lll^l9l^E٭ٓϳ/sprpspXd ,9EǥUuk[;w";!O Ooo=></_!_'"?~N t<,"8#,d$(tYhLRXC8BRVDI$H\dP%*//Z*D %  V.6GyO=q-Xi-%%%%{$KKK]z-M+m,&&UFTKT,ll쒜tf;7"f=G,(*cەWUTU|QW RU+gjj$ unus<$J)M>Mo*͏Z"ZZW>kKiGj7iQ9ӡ ӿh oda14175021Z4V4>`eB019m2e*jif236;a6f.`jb,,NXe*`-mߺdžݦfV6]]=}] GIXZqU.z.E.]]3]G v۝ʝ~QN U=<<tNz{kzz|U-S;7_p:`)0l `A]aaaCb*E&UQPԾhz5?F8Pdzli84 /&:O?y@@Ad))RAӤ Ҿ;epddL28t99zX,tV@@lvIRŹG<<*}c=> `ىBœEE}rgOOƜ8ezxiåڥeee?ʽ˟={ =.TVVmTVO\UXSS^wu9+Wu։U36kF\AtQ)jNh^lohuji|Mĭv dټxw#c߽N?6}~V^>^VmI)^ޭ@#ǚY9k h>}EKȥͯG|.sry|%deGOVV{~9[?!ff8)*#P:@7S{6*9PZǒȜw XJOL^ 0 )+ 8  hr.=S"$&I)V^:EJGMC VUTyQѢ_K[Vn^~AC1IiYyE5ƆŖՎ_wXs.DW}}nSU^%9> ~~rA<,!Tp[E'd6ţ|;UR\RcҎe$;4w2K "䢎>g~!߹c}mIS&%K˔eψ='UaR~~QՕZWT֙;4_~#`SZ󡖬ܛymEګn7;1qoosWow}}<6}1xn3:#Fz/^ "Z}=3ͽo'&̧Y`Qyifb6gNnnbB'dk|^<wΟlnn_Fó 4v &WS&TqhY301agddri[_|,t^8RD]L=%Hr(S'+&w+(Z()(r!Y΢>qREKPkM{X=4 ۍcM|L=,B,=,UmDm(#N\J]s%;z$= 9a.&*‌ `PJ$&#GDǔދ{?AdlԦ Cvҳs6i>xZ5 Ν(-,*+>v*$_i@YJݳ".U /j5k _(Wt_ϼqNPxL6Sm;w;xMuo.}pPob_GO yLHO^~M;&t<ɉ[OƧ OY$Y ՗F>v{r+?Wu7fw/ͣa7YȦȗ(J-3U*!Mz=@CgYYzpsׄw/_SM`UPHJ衰NZPX=^@\r ^TfF6]SUZ~A"b 2¨rYUK^Ւqr#ZZ/uu6u+,7334v5a61-212HTnUod#dζn=sğIKK NOzց;LI+NO;䒩wX4 <$9?wn;~0ߥ@‘'O=UPRqF郲sgQVpWʞ7z1`u#5)ˊWW^T@y]ecRScVm%[oߺwwA.>هx =z=86?50}u+;m5'R 5; :s;XR` PEb0o*Ra=$S$&g#S) jJ9vJ!khZjګttCC  O201`ecmcsc'gou;Gg_` QpBp5$deeȷ*(&(y+H2%IjiG`bno,gbnavʼ1{cS ZwX'sϜI@Q!Í#j1[œp,MaLOgZ>5{$XS> O5O3=kpn2ŬKA5_/WOӰtCL|ǶLtu{i<|,Da(Q+o&'Tew?zrqoMc+8@Q Ԁ! $lPjMbB EE9QQa./a&3ľpa2=VrIZ ]%a2HN,j@4q-tt0N13>d cfb` `g` cg(tbz]+_tCj9~S,O<]bd Af@6GDI~IbRrĽj?duruo2mgNpMYKpgig Wɬx{i7h@Ā dWF ƑuO!MhBI9u53>m4;:=q<`opLސG BA&.u37fb4fRdagugK`26153p:*\++:R\QWԈ \cN&:H[ 6KX\nձqq;_qwtvy!:?,iKLtR,gxƒv)*23/f=r7 Qoӕe V@e.W԰^I3hߘ\ٚt{n=zn= zU񜷏&Ͻ 1hlg/K,~_^>¾RC?~62F6ofvrmpl]s=~φFÍҿMMS[~|@m0㛛Vq)6l[-kH]()iTXtXML:com.adobe.xmp 598 1215 1 =7@IDATxtU/ 5N(>7Z&b˵wS[R:LMʐ.*,;0e粨x-;5ZQnS-2F!9fA_Mg}Nx @ @ @ @ @ @ @ @ @#)Pg"8y?j>BS1$TVUuqKKI!VT\9>x\6,UuC[si~gncUߴ=xiN8y3~WIu eUW߿LOXQ=w/<mhj9s|ucKwmxc3Nճ;ۿ2BNESGlNYWvۖ[EYբ[-zgmM'h)xNJvot>YF/{ե]aA;3OlIU/_TDT9w?s'HuO@B̯(Hͭ+?oZ:w{Ӱe GCVxFz=ht]<-5(=aN ={Hͪ\qrڤ>x䂠'Aӹڒ‚[$8Rw4]Ʋ=e5dFAHO?"eqjQTĞͭ}Iw{t`ԢwVR=]OU!;>R^51\<TE6î-~1وcqh|߮W:lOc}~Y%yÿh?% X>c-{E pV _Ag&+3'J}v~%{J#c9F<\,S#p]~˗L͜הSCػ_yG7ֵkY'پ7Nr=nm3k.d{GpǏv/Z@ot}g>r[˪W۝nupQyeAݓ77^KwNpFo07.,jQT6m:4~^ZINUT,tv|okn^~}o,zjxG䨏Ԋ%щҗZ-\뚠i`-N.Ͽ} ȾVm˙tlZM:zY!,[ve%o>~̬Z6wy񪰶يk.wh0nܸ_JjW~ꃓ򂞞מ XUkp WoM.ݐ`3|RwO^[~Q~xk?}{03x=?<:#i_Sj[1(9u][ۆԴlfI~ƹMǴ_9SW9ec@ҽ -)țPwH`բM o)+. ú.-:y}xuF9tz}W?ⷣ={0[D0Y|콗^wwb޳?;bTԯ+cPc Zya>< c-_ ]ӗ=_9}3XjƆ Kg-6+j׽ޓxҫJJ[(lQRT]ClG~}cWv a_?KEѹc0z,:F+P0>Ы9ض O. Jrgsmd+-35҃^Vqٕ/T3ʲ=ZȒuWM"hj J,8Z 'O{ן0X/Yn!lXL' Ya9=R Jw>R<ﶴw&N40.zj ,xKޒ|׽7\{eQp͍ 6O"p~҇8`w[?3`[ `b5tt;(`/lYG=H6{i#˼K8;J5w?df߶G 'OiKya:zZdÔ(؄1/.bó9utZ'GL\sMEŐk}z뭁O7J6~!=}羥Z*jV¬you օwttvͻ(<8w6_VNßSY~o{ {gNWF篃Y'l'G&wF CU7MrWWw.CO_[_xӲy kVi/uXQmݵsry a{G+'Muն]CoygO/)ɼyluQt>м?\Y#GcFǮ"?֯HGǞ=|OfiKPҩ nX8{䃽\݇xJ&Dn*.[,o&ہxѱ|[-[k羽Z7qm*Zֵe]=T,ttx{ qEE-r'GL<ƍ+tϨ(X.:po9xK^qMyk;0wsj>x{xޱ𯛚KM(l޳COeQ۹>wEc_Ng̎=KKWѶk o~쑏GY-)r9兗K&}0|s#o7GВֻOoŭunHl_IOֆu8Xtn9/ˮ^9d\}Pleuҗ@ݦ%bE*X՚3z2+{ }k;жNgU P-?808(p2,d6m({D ;Ѯ-GIM f5^wl{vӱ Oҵ51|ԯvkì`|gr{6Cy Y. nގ&̎Kn;ohkݻ' ~2ǭ، ..T 05l۵jN1,)<ਏW\b㵑M GgÂ>P |K.oLF?ݍ:E-1zj><Ҡ&A'49m0yqWF˘J?om*-(o }5=nF_t^QT^{r? ޼]aÿa{kËǡc~:8׼KsHUQg=MGn[ƕW/Rɺ -y S9=/?3޶u7^shh뮠 }{X'.X` :[y/p򿂾ِf۩@<+>X' 2<}㹇 8s]R{VVy ו1e=\+|}?YzxU z=tw'hZz[Y~W h҂p?:`tׇ'>&}*EE}aT䑁sj~ZU8\qQFGm]]}kI}'d4frUq`k{'ۼ#lR_jy^BHM@C}PGTOMsů!k֐KP \p^=B;Nid6t:|2zQyƲǏ./ p _A*"@x-?>=}'^b_?%lߖ{Y{<#x_S-Ǝ-H9j:NM谸s_: Z`w&p3/[6ք}ǩ?|c`Į ~c_Dsݍ ."O@?.z p\ejO4\5RsGP\tѵ{AгzFQ=;yA m9tEF;Wi y2vWi ;7R'? CGEse=~B$@ !WPBYb ?8bA5-U56'<2sNSw|-a%<كyC[>{'e,:JmNK msYmy]U5n~4<Ο8yI7/|w=x,;I.Ҝ8/n:7x5 AP\9w8rsR˪ӟzo jV52wXt WvjfwV^ܱ'jHGfY}劣A{_ۣz v>6wKLݽ:hiZtȁL{xWx_M6s!Uψ.~x#]~hJ͍^i 'iu]l8uo?{'۶,c=j?=J l)sfUW\C cry5޸87W5>v{Zjwkka|5cNeE"p+.|?'}j܌<"P/8rc+?n??_TW~tyE; ewߑ>Po\NGضy3l\Q1wiudm ՋάeǢ;٣ǸC9}Ǔt63QZݰufw߭azG}^90xm_Pp{&E_Xzͣ ,?<% ??6+[`s{o};SKgH58>/zdV?(mH>7F '&]RyyGzGg:,h]5ʂ/:{8m??%kSQkG=[BzO-(]?ST>e3dlcq^_}s34׮o_2#?a_}UmO8k3;a:ýq'wM轃G3jX4;C=5NCa v8`ޫ=&'xԉlst $`'’ZqМAO;⠕?=wO|<(ҙKN_><}mCc-w=pӇ*''Ϻ(?"hh~[*/(;.e֛‰G?1(I1nޔ%_:|%z?Kffy<{ggAAG^^aqѣe̕;3EJJѱcs+g.>>~hďEi߰kLGO?U[ OK?kZ~4>sKn.ڳuz譂ᬜ>-&|F>@^'vs J?vwU3GOËÓtBa7`4eg#zQA8T<fF*4<+B ѱs/O6wL__UtjOY~6-s…&cO9cQv#Ov^S {v //T~̛ *v";'-\W8N믠s 0D }^unGo=hܿc]cEŕ="`oAtC\W.}fOt[]y1ro^ܞt6+(JGǞ-m hxOtw:m03 '\Iѱks\x#l۶miS5,UUyYA:^q"p%WO8CZc,)]{!z/}eϮWhmYEP4~ۛZGۜ8?G"jN56n xqUQ?Ve>#4o-Y<VUY? 8;NWٱ v9kXRx#* մ$4m<+60OOpJ)KUo:O\)RMk˖=U LlSe􎶭)}X>\gmp" X쿂i 'pdӜA,emE5@"U)}LuYg93Dgg^[P2+;'ѩE1qѥy|ꭟ=﫹+^sL p :sF_MT4vI9eS/bSgvk·gx2O9{ָpV/o4,v8_|< m#WVqeLJހW۷>nC|4oC'7L dϛmI @`Y4gm0>-A`4v9W5 @  @ ]@zn @H @. =f7҂ @G @diA @ң} @ Hٍ @ @>@ @FZ @ @h @ @cv#- @ @@z @ @@v1 @ = @ @ H  @ @ ]@zn @H @. =f7҂ @G @diA @ң} @ Hٍ @ @>@ @FZ @ @h @ @cv#- @ @@z @ @@v1 @ = @ @ H  @ @ ]@zn @H @. =f7҂ @G @diA @ң} @ Hٍ @ @>@ @FZ @ @h @ @cv#- @ @@z @ @@v1 @ = @ @ H  @ @ ]@zn @H @. =f7҂ @G @diA @ң} @ Hٍ @ @>@ @FZ @ @h @ @cv#- @ @@z @ @@v1 @ = @ @ H  @ @ ]@zn @H @. =f7҂ @G @diA @ң} @ Hٍ @ @>@ @FZ @ @h @ @cv#- @ @@z @ @@v1 @ = @ @ H  @ @ ]`\&Z p ,X`6['='@N;Ӻ~+'p{4[iAAIFx)W  @d8b @A1 @2  @ 08 Y @ ! =f$@ @aaP"@ @ 1$ @ # =b @dH &  @ @`q @ @ C@z1I @HàE @cI @F@z, @1m+o6| ʪ>\S򳪺唬ꔬ,UuC[PRuϻ0Qˆ/9UQMTP&@\QM8)E͏5]KEԻ4x-S&v|Λdԍ_\2+?|am_rN@={8鱪9%M\aPUuSyG^e3,oܗKv=|q 5~r k ,Z[ᵋf $U=pؗ™ѐzfYS?oQNx*@~9AU;[>zŗf}PzL]{p'NNUgÿ;ň͆68|{;}K3 t:լѪ{ MenZΗk GFlv|c[s o\r.䦪 u}a//?I5fבMnֱax1:ܧ+l3^8=e  p U~լIGjhk}]v6nkנmjjkkYױ2NӳF}#o/礣c{ ’5NS#vy(+'0XC֘i̜>,w*'6-A3k.d{Gp3NwڳoسgowhLDs<~a ֟W\O`!@-] @ L=bC²5_7pmpMwk<=#îa78JsVaXGfٜ o^ܐ0jٓ+ n.ki|^vFO2X'WGcձ%׷Kΰg?ŶşZښV碑6>];p߿3/1r !k _mZus+&=G^?kkP7,/8~K<,s pvHg8gɵC_k*Kk.[0y~tG GYvW*bmtbaenynfeXX|еˇn0Vռ7ʙG;_Z7.?((ʝ͵+-3(x}Ww޹fL,Y]SG:GaBU%E6%%I558tS⁕L |xmڴY˶͊ҽچw"sG}4L޿96^:~Ҧ!{oʢ?lH!*p5TT -z뭱DsXuuxrq5M*ZמM[7޼ 2cL.Z"{Zt=cXCz5AҡW*qxf{h\P>FRڭ 3b aṷ^sM}-zx3.ݿWHZ[g ޲O-k۔/~k]Éovr_>e̶n9Aˢq !myڴnXIgX@z<#pV|<+PY).^mKÉݍ-MwZ]?|9w*J *W\bA`Ѽ>Pïck(/pJixnW;8{hRy05{[gwgF[|켢KTr ]NcAˆ5Yryx;b;rYQU4{imΞW\ ZFe1FhC oiu]arAp轌!ݿ ']ѷ;;P  aY*,-SY p¯]h}j],t7:œe k!K;ћ¨8|rfzin{lnƅ%3zC@˾Ubۜt=yitj_g)phi?`Swo#_ّ+;G-)wjݫ|&QyN8jw^$@O @ MK겖\ݿJAq`/~gY ,5ʓ67rpk,ؗ{+*\.vmw޸rfɄQ ;t+s6׏9@]kŖD֩Emyl!)?[vz|Ɔe˾E7GO^>s6-]G#|~DZyvw6"<9ܱwW/NGM.?Z.՛ٸ,֝ ]!]~ͅ?;0rZ 4ʹ70죪ӻiȓ}};6W%"8{<D9H@ERLTAok/Q<}iWCY :zga¦=AĬ [n;.nٺpO.h ?/f^90xm_Pp{&E_Xzm9~hN/|zuiAUC#@ׄ%O>缢'Ӵ*Ǭ~tl>l K?vՈBxGj!`~r((,Z;ꠞ!p!55hOk'O &Ϳ=yy)+Fs%3Ss_R9O8SAs!?U4ib`3bOOT,۞O7p1j#ځޏ09/??ދ8{Jj]]Iع'Gd s.';uҲjȢI%ر3gO+}~4ިЂY+g|2Pc_=;޼u`} js37N6w4fֆ=;cw2 GyO 0ս W}tfw}>}ݤ;=v?)eEoYkH߾a;cwǎْ`4-s-˛X=/>rq~?GWS {v O퍎T~A3ŞޕΒ^?81R۶m3#Ol7kyԖ0hW7OJf֟AL*/BZ+[چf*ᜮ=Op)T 7cb{~bM s{<jP~gچ\O.q8%oMmyU5WݿAӱM8#Ԑڸ5r?sCU5WGUe>$<޳[K.p6 dӜټujKwp$n 7kކs kMk|_RJokդ*-Ʀrir*=L, eRuLmtw͠W<%E ܷFo{XF8VI  @\?{L).(ZjnZ7N+^dz_lj!˝F [?w䢨wW潐笋 #@$ =F۶ @ gnۮl%:FmnշU\Y|{~jmё)W_p?XĶ0~ce#@9*0stsmsG ެ  [B OsIJ5&I`]g&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$y#,IDAT HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ HI- @ @ .1.y @ @ IcFK @K@zK^ @HR+ @/ @$ =&iJ @ǸK @$ KRj%@ ,X`z @Uxi]8M=&X%p qa\8{kU8ŭM砀s$ ~ƫ @2{1I @HàE @cI @F@z, @3@L @ @00(f @ @@b @A1 @2  @ 08 Y @ ! =f$@ @aaP"@ @ 1$ @ # =b @dH &  @@ PQ*˜gά3۝ @PᠮtmМsiU}ӝsJ .9xCVϭ伡{^ڋđ_rNv?s-C71QΠ@ƅggtK{\tClo\r.cKdmtMլ{ Mշ/?>Mhm8nY: +X>c-,e 6;'@9*pwG Lw`܅Iyy%?Uci̜t42Y੝_ع;5=U>!|ӵk=7_=40u?ٰqΔگ=^_;!w]qkU8f-[7w]6w3\Iok>GB}/4k恁iP7,/8~ ց*3+ GaQɔG-3(Ғτ3 Fp}3g()*/X>sْY VWuG٧>vuتkwwVFwB կX>V߀kNH\R2yFà *KC‚Y ](yٕ/Tr+ӬUyrKRW_]RR"$L<1\qꋊg-lxl}}Fwݻ#w͍x$nO8暊ZioVS? #|9!rq/tRqAt홾h᭑={7Qyӷ oTwͳMW/+'\ͩ,o{ {g K铂AOGm[V.<(qeqm?ޣ/rYqaZayN1kM͟\GD{n?ʥ3JYuN./}amh夢^C5U~yXXׯ~XgS5u<}=w5eՍZRXu:vW)ۻت%$# Y)YQpaM(j䩴TOHbhh)TCHN@Q!J5 ,4SE$CRBw!ֵgs:q/sy?9y k]?!f̘Qcgg㾷tnxcU'p~ݻw߀JuGԹxem¹݇vؔ9O-*77$[XԕO=ok;0Љ+Q ]?iw2MݯnhjXAϕ+܌XwG>so}c*7g}08cZW7lZqiVvm|=&ˮ77ZQŦ$9a6͋ϥ_g{$I[˾wX7DvwhcuUI{ґ#s@$EEһ68䧭>;mnE~c6Ӂ}/\L/~3u_mXP]1瑗nڊٱJTՖл}6dikPDG1*Ȅ]X?y폓;~aЌ6}yiM_O>Vıvp/$vtin=&wIct1m>ャ|/%.t:WmwdcGo]OS|O 6#q ^:u;m~g  @K#Ξ=m{vܴ曛JY!O&KW/Ge7`%,ʘYb蘾z3a9eFa4ިƦ??ݞ^ggC / d=TξkKVmKj'bWq% v)G@z p Blec*f~z4M!v[ɵZG %f%;sw; r5 _Mdwo׿K_;p(7n?gģ_]婽_?[?9f~,4O #@V  @f~&h{/ٕʚW.o> |po(1bzbGvۼy>PŮk&17n~u{_f<4/wņozlo۹a͊%_YT:(5#k \Oz7X7P۰UޟL')f\C:4nytv[fW>(Cy۞߿ʡqL~]'{u_oŶZtm۶t];g*{/fdiK:;:1bݶveۺ1GoڼK g" N(? @eMˑ# ,1[ϱ;lx`E럼nqeEc-GʹŏHŃb:vY9X=[peJ >[RP%co=^uf憖j%&Օyw9 =<㧆gP2Yf.?;7.sxzP[dYWӭXlݑ%ybsgplDVϑ-&\ @M"ƽ– ^>e]Cmփ=i{۲zTҵk;{ /Iw/)Q8VzTdbttMK.: *37BՖ~sϜڵk[ΎVTWc{Xٸt?r(g}%@+0JKKuttؙR "PXfOJުdWGdG%j_|L<`2%FsJԮ<쿧I2sGe7QW;^ Kc5YL/ܺJ4M'POs7ݔ4D>eeypM ~5O۞l,P3KjwǑھ푷L@*lOPv/, #թJOnR=O{﷌M|k쭠>Dv HU$@K`[;3-׫ƍoG{/7_M\sOwmj0-35K21*c+o @CjE @XXWN @) =V @ H  @ R@z  @bc]9} @ @ R[- @* =ƺr&@ @@H1Z @U@zuM @cHm @  @!ǐj @ @ V1֕7 @B H!"@ @@c+o @CjE @XXWN @) =V @ H  @ R@z  @bc]9} @ @ R[- @* =ƺr&@ @@H1Z @U@zuM @cHm @  @!ǐj @ @ V1֕7 @B H!"@ @@c+o @CjE @XXWN @) =V @ H  @ R@z  @bc]9} @ @ R[- @* =ƺr&@ @@H1Z @U@zuM @cHm @  @!ǐj @ @ V1֕7 @B H!"@ @@c+o @CjE @XXWN @) =V @ H  @ R@z  @bc]9} @ @ R[- @* =ƺr&@ @@H1Z @U@zuM @cHm @  @!ǐj @ @ V1֕7 @B H!"@ @@c+o @CjE @XXWN @) =V @ H  @ R@z  @bc]9} @ @ R[- @* =ƺr&@ @@H1Z @U@zuM @cHm @  @!ǐj @ @ V1֕7 @B H!"@ @@c+o @CjE @XfNիKKMM"0cƌv{b @k(o5Ĵk"0ɟq\p5iN)p'NLPo8"@oe&'~g  @ @ @ @ @ @ @ @ @ @ @ @ @ @Fr%j: `IENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/form/000077500000000000000000000000001457770046000232525ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/form/README.md000066400000000000000000000000361457770046000245300ustar00rootroot00000000000000![Screenshot](screenshot.png) golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/form/main.go000066400000000000000000000015051457770046000245260ustar00rootroot00000000000000// Demo code for the Form primitive. package main import ( "github.com/darkhz/tview" ) func main() { app := tview.NewApplication() form := tview.NewForm(). AddDropDown("Title", []string{"Mr.", "Ms.", "Mrs.", "Dr.", "Prof."}, 0, nil). AddInputField("First name", "", 20, nil, nil). AddInputField("Last name", "", 20, nil, nil). AddTextArea("Address", "", 40, 0, 0, nil). AddTextView("Notes", "This is just a demo.\nYou can enter whatever you wish.", 40, 2, true, false). AddCheckbox("Age 18+", false, nil). AddPasswordField("Password", "", 10, '*', nil). AddButton("Save", nil). AddButton("Quit", func() { app.Stop() }) form.SetBorder(true).SetTitle("Enter some data").SetTitleAlign(tview.AlignLeft) if err := app.SetRoot(form, true).EnableMouse(true).EnablePaste(true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/form/screenshot.png000066400000000000000000001625461457770046000261530ustar00rootroot00000000000000PNG  IHDRZn) AiCCPICC ProfileHWXS[H "RH  *! Jb/ ],`CWE;͎Y{_QPł]y+ߛ;Μ;s4O$\T ^H y9Ja/L%t%ާ!n@I3иyF!?jhB"h2 ˛(8 b;h#XLA'o郚<^ VEQԂD\3|J͒qsy31Bӣ!ցHd1? s!v" 68D3D! A 8@P,UBk3l?ϓ*}=$T>Q1bBQb;ElFel2<~+BqhR+̐pU%y6g8Q*| +>LS]Y :1ssǺ8IA W9HrcT07T[@_'3$18l^x2|l@k:){BHA&'30"I#8PH*z_Y d(z #rS@ȅ2(D2xʇ*aA&R<24, b1h~ Lk` O mDŽv ҟ ڡ~*?x ա2' aг;d٪Ya4Tvd2JB mh<ڻ/hwtltu:uctK:Χϣowumu9ٺ{t[u{tkm9K4dkpȢ!5Cyo0 @hPb'Caar:FQdFgzZ2лƨ1xV>SP:&=٦LvDfN=g1X\ZF3<\fżE\,)L UMVfV[U[ݵ&[3X~ockdΦc[d[m{ߎfo7ɮ=ўicPpup9nplF5Lo...\>b]\GF5~+7G7Ft ܛܿzxzH=j<=<<+z{xx'gO(QQFuZ|16+XN瞋M.>0~iYBSfbjbUIc1RQ(>=olc;SSSo7e܅Fs97`!-)mW^4חIHk/UnpYoƊL̕YYeY="hUvX99;rsr5u9扦Ll8J%퓼'+nG٣B'=E 1116 Screenshot 768 2 144 144 1 @IDATx]|UE^ޫb}k]{wumZaEMz !=y/Mx$QBHf3}oΙ3!@!@!@!@!@!p\Kh-(" K!pR#hBttt\\Qx*u4E$)MVV&**j|dBo!@v!+\pdggHh/F?_>3?bu8&'\@C#BJ111Nn8S4M"kɲ/syu`PKEEH%կ+#@L@|Z*r0.An#{Dy$BH$;ܹq"`r^WV1)iӦ *YpE!@4=`bP "}]sʬ/ܛo:?"K.Af͂6 fBC:T  x uATp ˵ 1=H[:rHŋx07.\pԨQZ?@Eرc,XiuϞ=/:€ #믿=+Wߟ7oCOO?AŜ;w.r!?~;Ć_|)m|h?&hjڵk֬wu CX ªU?|СC!3 WPsaHx~<3H*bt%Bh)!0ר`j&iq2k$ DFa;8qbnn?8iҤ{DG w(\Z\ү 2=( 6effv}ӦMhРAPF= @`K/ƚ={6Ǐ9>C_? ؆7ߜ{?1>9837l؀@L,61yw@{h6RW_}SO=-޻wN:ACǒ0) sB۶mڀ z9퀆a3i!y󐂁! B۶maRB N xW^{5¦Cs(d 971 '(? իW0PVLPkӦMy1A-0@ct `Ȇi+$A)  rC4n9s*-&t}aH2 Zx> ʘnqu@x GPy;t%Bhb񺆦9Gp!`n!*=u0> f`A 7nMp}Y/o˖ݺu#B dP "BW܌6 ^-A F?NXt ۰] IA`n!$r1}}bဒ|Pa^~wz @0|v' r.pҥˎ;8lz*փ$s`E @(!Ь_@_-C6N\C8,7=nQA.,`p1LE 'DBfpa/E0w! uAS Z蚠H EnN CP=!!8!@QYr@`pn WN 0h&_T- b 򖹻 pEիW/Xac2-[2&(\Ȧ8\pA`,`0:p -ڷoo?!@()x{FDH0#;6Xܾ[0r" xOכ~ǯ*Vj& "XXYY= :N;P@"ܩ@N|gBĠ"9 jpz2qT7#-e *w3?| g.5G˩`5`LkfѼ)B _=~k5(a 5 &,=c̟?/@1D^\||U^P)AzAF(h #ǰl)xuaq*&1c+pi*|w7%ƈZؕh 7թ xbf0r0Y ذHd@;DŽtR؍-@xCGݨ3g΄f*Cr+|QBEO:J?vFa5wܸqИ1j[ 6e˖GѰZcwd$~(Z:On BhaNp#J'wy #" ynAi\ǢnoF@yay3ppd ^db8$A@.Tᷨ`1stZa:"qL^ xd: B N A @Q!&Yp JIP&?&e>x(yXJQS<U(sMq/0#^O+ 4oϥEI4F@B}~dys\E IUE"I dp]XDE!{>G~K!phdB""]Jt_l6=vl*g \M|cNHPm@uCA1=&:F7I !@@f10Ԇj1^`=OGy]c ,u<#0 ByPQV5'O:S;҂y7t 04vEe&'Bq$15TX=j `dKeQS5]oG9N !zm|ޢjb2+iQ2尛DяyvT\ΠsJ1h jp3^M̰{BlpM*WV ODxj]vM")uB!qK&F.Yڳ KL&qnFcO>f[SդD//ftf߾*ߖ=zmX\++ crȈ7o Ѓ۵y6WU-[4طo3= CwIIszCzGw%;Ce XRŴda..aVC`+!@?N?4*-3 MdxJb.Wb p^}Հ4H eó7n\lV!?3uI5@ZZ]F7,MWtOaQ(ڈ<>ܐlu30R4:J_.)5`f%\~<|i*C;)1۠f(!@&NVTjVXDy={ijV]xS'u01@AqDWGl!‰`aC^uewo%}ާOړOx `+ QzhTkfT6jF(>Ks8D,s8dWVUL .JXAۄz!@@KG  Dۮ] WQ2n]^b[w=B²ČtOzUq|@FO05$c*D/)-Me>웑Fr 0d*!@@"p5ߚӸ=1WSj-&VC-~ئi,K~Qjh?22Y[L'0"SOT}0V%-&m$%,$!@-_p(XE -UH VT߿ t^z0KRm}ݻjt4cl/F|NJKݰojB{Ԧ5ǿ@(YºMlX͌_qtdD1N/"Sz\5QL!@@RkM&Z (YZ|qG뜓rgM,ˮRw?xEvv fEk͈b\8:3M?㞽ƶr{y 6s',~ Ȑxi3)c4H̽eI^ gi(W\jYEX<~ Nل!@4Wg /薔Bg [̓9;;v,K2cMۙ _V&&2jq eEWZAݺ%VUyх=MzfXuDB gFaGg/L`֊ ?HŐq{ f>t4fcy2KC%f7` B4 ++SA]; k a3W~OP}~)>M4pJ8mSO?NGZ0VaA7׆aIzr N`B} ?dHexa/\0k'&,f"ka'7jE"(<.y>]T싮Y;DB @0DA\_R.U8 ?/eeIY~' ad٤]D6fzCW&IKG:!@4Ia#B!UP]7Y$(C_{~EY1l؅h B4&O ^-I3i&XMl&!@l7qnI2َ&0aW G=>LAJ&B8>\h.`1l 4$HB ܴ2So!@@G?B!@@KD%>5 B#@!  B%"@L! n@! nOd&BhGH BhħF2!@x[#!@D[S# B Z<D-B Z"c M$E)7YQC@bnVU{v$1!{ =hSYƾy\ U>9/W8-8) n.ɱVծsԵ B!@C0$ٴ}3z%( Z MD,*>k2a]uQlx=à2j%ʓx+r+%'񷁆h$!! wճ2mVeW^F~l\S,;Sp~9kQ6T(}{+14tbYkDzs.L< H<`^qҷ4ԪDB #D"8!DQª+d-Gv16=>`_,oQcs'v= PAyy+z1$&(Y\կk^^`ߘ5F;E8;vHf$TXg%ri.&BQTT2&Eא1ҡ7huq-,6VD/\BzXTjtbZ[7#>ӭ ]xE{l3fn T Ot=?J*h{!1.瞙Z+V?xR |aI8cw,>cHK5WjƎ^*~m*6n媂n~ƍE\}R2XV2݁>X##Pwn6Ǝ]| 0_`kV.zuoZ_vF}zn@ϫ.QJˌ~a&:~/2LPU:X}_,X]yJg}/ *4lR"!@C1S)[eڻWRQBq.)F+XV/[Epi&#|3m֬7i=;$,fye!IxjgD U<( aƭ&l6Lwxڔ])w=9%-_ 3(-rb(>uì=z1С射v36:pp[_WʄQڴ}Eiix-DeY,gjCPN"J ̿|ВnYA5noprXZ6zT[};w3o1LmY?k!Fܥt0z$'a*aJ|Ծ"ѭ+{}LME B!pȢbQ U휓|`ח Dok ^#H@F߶|`O"{wIuYHLyooTߟ7i{UX cUxߠaWi?ܒxхPa/09텤>tuFV7 Fʔ{c޼]kAR.{͵ ]x~߳ lˋ3iu>b<<4g:Xw6=p0ŠY 6㏎QQgZ73Z/Ac `cBLdoqи!Ar- ܢ[X=D]+Z Cx<̵"$P&! 嶝ƮZ>‾2@vhbk`8+ C11ȦJFBŘ@)@!4s)~*+>v rcu͙k!Ĝ`-.WXy9 r9/㏍C{&`SESv;o*Z%*K9os=۾w>ŗή#3'd?gۺuMfT_DMxKIpb2N@kiL~Q3RkQQBZ*bYtem-˭KWjF Ը&#yGʁa&==Mj-1?gY_N:B 1i($f9mgfX oyvHnnЕW=(`ff,+BVLlNh:U; I܈(Z]xo.^8GYՅ[V:2vXd6R2!W(<망fS}(PɐאTfEQoJА+s礋.?a|Gj.[|k-Y(l[0`޳֫Ƭp5Gv.->pFiβߏ>gl擌&ƌR>8l{;wi8[ h IC+{B*#9YڽG[)@}!66$sQP !@#pL1۠"t~SiSBSzʚ+v-_uQhL9g}׻L벅9o2׭گoF }نtuu]E\HXۖ_PmK-|ewμO~˕]Y[,[ Q׭?Px`6lFlz}O? >ʻY28`6TW L9 >SB}Ə*l ]@y6w"Nڿ_Z`q+ CEs}R=w:-jˁɧd6lb0SCrat2S"!@@)@ᐔTZZz7kٛ7o﮼޽;\,2[(s)8LjLq^؞H"+ \Xs??+|d Jҭ UDaԅS4>6#w(GfՏmNtDŝt)vɅ#~8?GJg p4NaENYZ~dڡp]T;V0k,uyI\PGCZpo# NbyS bx *(NlOl#'F8W(5"C{Ž6e-F oZcvxd!yܖz?l?du$*-F¢u3s0(@Ep+VIS˫. o!I3B"@ܔE,aXחa`̀$-ĄBwu셱w:H-!@D+PKd&B Z0D-!@-"HrB p ~x$:!@@E>; B#@܂N!r nώ$'BhG!@\[# B Z0D-!@-"HrB p ~x$:!@@E~ɞu9I6[ ~`oa'DA u͢H-@wulEu[;T@@!>)K$NN蹛LizM/B@GenZbJQKP !@9JY GZbrTEH$Hdl|1 ]Q#"IF@#(bz׊K(Xj IIA}#x1BciەRE 0r WpcyFO==*Xt]e"G$$ƾ|/pHn7F ʪ <7fÍ&mS _E+"1bh>0(.\aHp X:zOO#=)8&Z$_1<ۇ[y=?UN,"LkdY YY|/ZlDNi  Jv=XnG2ڭIӀڂ 搹ZccE?w#hG=(5($%!@4Dv#N_oǶBpbʉCRbݞ Sx*(-5լkF[5$VWUb*.IInNof1. V6A%%ANK)f0ۣe̚fМ&(IfTծn*+*1@HvVbREH,YY>5d{_ešjVgaIKhpPg!ՠjC>zM!@@QEhj0ڬRiiPQ(%%J)QXXC JƯ6!yKGkJ>aAI j8UBKhk01TV>][ \_HRYzCp:k"\TEE.;,O]8T7.J!і6KrkyHoդ㕷𒎋me[@:+ ,}:& UB FX^eI^~ }vPI,~띕>$-\QNxŽb/[[gu/3 *a,w3;䒒l _Cca;ts^R~_KcYfwC_vtϞʗ^^koN9uRΞUsզaѢ=N0=ݲ aiNOy(n~Ln"qrk7s qqSHP\¥+#+`5:8R1D<]m-F*)c)*1ㅟu,Bh i3̱CpN[hϢ{ڶ{Sn?H{}{ߧ~͛'zYXX Uϋۄ %';bb=G)?ޙ''L.Ӿ]9+Wt: v9]qٽҢsw钋3mK/nwf/<7ZKKS;ءR.2j1ƅ 3 e%'In1 af8!V{xKglW SHW]Ɩ,sgO+XB '780LKJc/)e^~Կ>vi9)ݻ%z'ytn ] DB&hخy5dƆ%l݀v۫(pU#t1?w͜7?Wϻ`i|61~߯/khitN~ȸC<`j4^q}s? +XHGaC=ep&siq^t(*sfXNe#`6l*ij0ثoE1H.6lV)!@4/cZ,"O9ͪ$8ZU;~'w~W\gʂGerX}++NA%xl[Ee ',J8 qx41QS0[̌hqq6dI2g+;LV WeYIWAV$MFu}$]W~a\W%|%PZn@bd+nmYCn]e5ؿxr 6[wo6z;v۷k{)s*ǟRB84 +v kv-!Aag3߱ClEȄĸv6 {^y󓏏[VJ2 ;J+&)&( !WK!6++SWۆgfWI2f~{XaYzTIFJ\5.֒`1|hg(:?h ו RTTr(0J*483Æ(\cuMtDKmgXPY@48&%U,!@@A(X7ee!b[_Y;?%gܱ?@O<#ó}kv?;/uM^K/  11wb[. X ї96K9gZfJ5 cpal 9/BCjq)f8O=baπ3wK hɈVncf-3S3QWCuNOவ{m8;MqK YSB @T'AD[j"o^Wd+b1uO|󍃙+ O;Z<`nА97CPYvaqxw_p_].F?Bp'W,5겮Gg{& ^Tee3O75KO=R=dS#LC Ͽtbl/HzWB\@IDATޣ*l_6v%{V"ڙݶ]{@ HQ!@ CMx1sgRۧߛ; (;|vEK/o朗S)sKyzy9;":JΟ:&z^ $b4h4q=Ak(k6n<e |@_`ݺ‹.z s+Wطt;K+* mTT^^8)\viS@3mB nGF#.$_dl@Aھ|? C>323AJ8jR-n_|\nގ#*EdyU^}+ا$VT6hYAH"Bh}tMb[FYyxE`CX6;˺v},n )8IソgR#닀ӛ#s=v(U8 ։@O)[Y8 p1T]s4Y8` xA_{H5nDc NrV_FU5||LMRV#`rt,p4$BFhG%9fӺ9:T$F@Uƛ$Nfg)ɱ+`Vc?n21f!{@q_Rhx! jXQ9)@5N6w!@VBup4.B B"@\ E!Ъ nՏG!\ nO"BhK#Bh7'Cr!@j[!@4W!B Z5DB +Dɐ\!@"Vxip!@: >h̲f3~)δgx&:!N^ً"Jv (V#DD Q¹( 'Z$DM挀_ z؂B `тϜ<*T!n ^ٞhӮu|IB@z4 CV,>~$7seъ6, f2O`.۶]={uZӭ(JH:~V%Iew7;#$,"׀^Ukkx4ׄL%~gKpx-pA{N篺-o[* Be5Xr%bIvʗ1)4DQDEg2@0ޞRMMx;!"wr# L8=S^D# 0EL5,x;\x^^PViE;{p'1"a6 q1& NuQJNlpt|A_ʨr И(J68L|ĀoX S⾘0-St0̆`' j>CFy.wR,Ow䈃;2;`3KlO&$ZX5h('фxB®7z˖K/&:Jr{tvI|합g}ds /X=FBlNd!-.OX~=Cf7;Cv=g_v+c/c_<[7$4XPhX (Biq%=d?jugfQ7\eJOܺݰ cɆ[WWiՒ՝c}^;Z60[&,o=m }ov8%ȉB}kѵO,1 8j.* |٩S'TVEF99^^Ȉۿ-׏cbLn?7%Ś牏 ]TFEIbTRMJ2CvUi26FL] <h`n#AU//_cbp`!qe )-g:t6X_:g5#{?"<$Yb#B1bd!·|h(U7Ĭ,PrU)dzI"EN.ayׇ@@^$'&J_ABQ:C>\L0dLBv"@޹K ٥/*J`oEGcˠ:>Q{(#F{D"v; EblXNJvΑR%YYX 3*ޒU0g/spQB(Â&I ݭm{vz{-P[ @@ly&tHIv; ztKad{o@z؋OՌdsqq@@zOqE+5Ȱ]0NHP@(eUqj8V;23-%%@Jr4.m J6HW ZdTUZgwP*T',3z ZL+D WUQvbZpjU1&U`_pj9dB16A%+c8qܣ5bZlU5#-hLL QrqUf1ۀ$#򜅚`u5 WT&0Q;olۡ8ϟ'Z-!Wt<0Ictv t8A%؍3t3cft6 l0ctɉߨ|=x%)fFP0Ɨ$oF.q}o֗NˎN-e?z=_u0ƪeWmb_]F3 Bw# ۷wMlEw5;% ?3(vU3ػD2EIޡx̝דjZF쳺~[Zg}hQQ Z3s/MKJII&t׭kguXe} ⭍`_kpLo-Wio\hg& J;J`_0< fk3a $h &sPx)}"Y;Yeݨ .1ALKh|teEݫ78`r0Zm^(x;bd FP`Hv1a9_ظEǀב)BnbjT^l`#s0*3WT#By$cE>IJa3['Frr:Bj`/)6-B26@IO14daӲ #Ծ3ojv+R6ĺ>=A ?1%lc7~Rbf[ 5\4biͱ1aYEJ׵Rɂ$Gm$Rj-:6ltVl[0m1 ;"B8Jxlh$0~\G݌mљI]=ȸ(-W-zF_Ҷ}"^{U2/^=_י/7iR )6/}[>n4D|xn1jgnc/\nה@u^O<6!]<e/sr[|RQRRGYHK."^i ūmxß̰( ̘yYSɓLl%$x~śf⒢wڣ"]~o_|/w]cF%~COZ ._~zV{t̜T#Ɍ_M%ƅ(ǘ֬U32$-*n٪X]^mܬ^A_LzF!|%* O0jdݹe߫W<Ђ@>3;gF9̂hbPx mۧ|0AV6d.K:]wUwti̩}Ңx| ees!yHvqwbCjJv>&CܺX,#y嶛9a#x-cy w2-(u6gn_(-vl/zkשO='ء|y?t>Hg3/п& ābb,ֿ~?&:A5V9cIvjr.mu:- }Fu"aq pa&' 7\w'1%9R GT m6ILH BcȰL=]Anڿ|laR,"Tkjkv h%w-}sMet`̔|]pGy˅vJ=z+͢vP !p, JzfDު5k E;f̙9o}L9CI6oh} -5+T]p*YݜR"C2O[4cf.>ƴpJ/[.:wI|fĴmk^bU}<WKQT74dҿ2g^jeq ԫתx BU,ƛ>Jֵ5h?KkP:&J_N9 ~}e}m3Smńxu`z 0硍՗5lwO%3]X=e -YX!,Zb*nl!y&`P+1`ѧ?jXViڻ5GVAoAHj0S m«A P`_+6L8HOTwy_Kjbpz}j6>~):JLNJq`0G\DWo%oÐ]G<0"a(ܮ'#A_Ta6{L)왢.|!nr)+WȾ||/p-v*O ^l9oC`eiEԡ۔6^L;+_Iߐ瞗I|<`.( ~JI .ػrRxLI@~pŽu[ ׀ ʰ:lv,x`1 o%RU۽{ʿcG%x(fc!Ji/>} BJM@ϵ#Zֲe]{/bņl"$e{ss2 s޲}/Ϲ݇<g&;8a߻w3D\vy x egxcUW^9.DW36)KPX c Cf=m-- TY:20 "v^/P2aWz!xb'ͨ?$/,;Z^D1J|Ӏ06sCm%t8Ԅc7t5WrR.TWVCk{Kk򪃙6[Cg4(]"`]8X_<sA`7+Cƪ*qeS%$d֩$)>n ,_Zɘ`ߍuxQɌD%x9G@>o , nۍq㺎'';yk5O?_7a~Fʿ߇q]6ջF0iYeX"%YUk$FLI+[#yvD 0 <>s3Orn ڱtEG. !^ncKY4!R?k2탐.PZ KJ!n#$d[dw#)Mu5>Y'܎jAR"]4NI.F4DW-۫50B,"}xC>N_||;#`X!B¢ `5SVώ"@jB=>)D0`^4? @p#l)Ê<%v :_WQkyeVrM: qNgfOoS`q;|U~OrRfB`miis^Y?,)2 ,O֝yƈ1Eڮ-D}W^Yuqp{䋌Ƃ~*2J{ƓymF톏@>C< .|{>ƍ[;=xW_YgƌQB 2x7 Vbk3+!86tɼle?r֐V+Dz? x狁n=Ya^[*Lu`2Uó7\QVN`L\GWH,bG./9^vC Y(32Íj 넫7:9C!6UmfIK6P8\ŻR\n14`[K"6J-!4uK/? ǺWzcQ//a03@=~_:x1 I6O7t ːX:T;Dp$"ѻp k,7[s;ě6{o#)\YYwpW|Xm(?d1Fvaɹkו;+e%ZQ6oÏӿpΰɒ}`2URb }mԉ:[^0>&Og9{pcMoںHҠ,fLgJJjFTuXoKݿmrֱc\C̶9(<{a8o g*7z$%'  b Z$:u+pBa\܏~ƌ-Xd -!\8U d[X&8_ၜo˵wJcP_0lrK,g}뎛NZ`~vXKyNqxgoֵdioB\0cQWir&,# & >.ӠL'r0b\Y'3q4~?2722r a9(^4,sswh7^(.{uuW}8 ':t)`d˶ysgm>_;ݻ ߆6Z,@I; {N%5uObyXAz흅=iU˷05/*J.=guKwF+;0ӫѡCʖM/Xݻ'ڕ+JRSkV8G9jм)ɓz`#gfO޿o./ 73]ZG Wgr%m87mȑF\4KtI?߿&]˳i5:cMRE[>O:vp}H%>6Æz8u㭛}xjA)ӌ7Xrr ϻPv&[}kxT@ƣ&T]ng` 9`  3;ż\kv.+W0P;.BfJoT;Ga4~GThfk Ӎk;;yc0').ؔzk[jpw x8 6B•a!$GFkHX;~\zM/oL냫`4p5Fm jgxqQΖ-A#3.)u9q5ح [[P^PݶͰr^, Ou1aR4qXhV%SsIh`n%tn]Lo}2^51X- 0Ϯ\IL;kk SJռiXt+웕tx}ȋ'g`nY i\`r1p%50IvtSmq.5pTHѦ"FŐYLxHF_]2$ G2q$FqN'mZ.j"l_rS/?C "фdv$梡"9˨Pr0yE${ZLdL#Hbi@HLRL^4l:!HLu -" Dpd*Ǡ[r` ؍)]2^35q~Y@HRdh9rYնޙ=5]Ď)؟|u=%߮vއ6: s{ci"4.C3 ffEe|}AI1-$*YJ0Nn5^ {FuPGIC fRTh3,Tn2kG&Qd{#p5#C8l—$*nT^ 9LLƌ4RJ$̤&QElBlMX"1j+Vr?WdF7##ы $ɈGYn0AJ%P)/r`9^Mr-ce3i,V|muǬ\Rsᤥp4FhvEȆ1V_TFg NTf%ɔ -tNݑ;WjGIչsdSwB(5{;WazwkcN˴lNmb.QfXse_S͠ @ҼUBUiI{ ZBrKRKwq$r HoK (k}W;f8(tmRh5^"®&1iYUE@P%8|"(@Pڲ"(@#ǃ]WE@J^[VE@cx늀"(C@ 8vkˊ"(qpv]PE v({mYPE P׮+"%a-+"1JqLҦV /E_i!ܵE`C `b=ebtH F+Ӗ,-Ԥ6({46{:=sJ-6`?wB%捵ֆE`B dڂn]x&m:J-6rI0P^[]bMjC"#ۆGX_CjÃ+"]ة䊀"(m%6/U GBo hp-[ϟ߽{w"7l0j(lCݶm񄉇jjjg} U?Hf!NꇟP@)P&Oԅ 8fQdԏ)GC0tT o& G#gffRyII lJtf%d@$n1ȐsaiY,0"NABr`fha B0lذ<)HLt@*'L~~(E-! coب(@"K@qO$xBg]f;z1`[Hwy7d%MJ.JzEzuw8C(ӥan=FcH'&Yhʝ:%lX'I'_m۸`Jk/$^fLpXY鏘!c1_veSLyIe'X`=f N:mܸQf32* Dsϱ +1CR k7#:v(UI-ő_$?׮] M[wqq1IݻsάBׯ_O!3X^8c^{ b# , *3h4K&@j$3:p|@Rˆi<#GQ14RP]"PXϝpY L.1ѹi1_0sxzzW_\%%>{&%Tz ~ow¾meeuw޵J ;.cUKFW&:/~}ر"!΄ו)0,-=,jHÇ.Y >&egN6mZϞ=a&꧟~jZSf`@0D }R/,BH{9@0dʇaSȀ/\lBN"ɃtN-TիWSG}.Ƞ GF  Loz QJQSO=s );Gy$Oyw$+@<"K>lT1T(Hĥ[7({']SW}KΕ={PouIwЍA5!x Rc[{u(p |wQ$$V]Iy@dEvEH"-:(7oCa7|310wm P!!9vj20eJ*"t%[>$/>蠃ȃ)ay²p9DNȆH/}wa萓4 W" ꫯ" Oq!) tM21E)>dep } G+EW=,8&N(׿myRNOz$uI)x 7ߗ"uW2``Nw+[NɧsE #U.dNaQ}-HOws]fux[{_n@eZ'tʈE_o=oa7Oތ)~q?ؚoPjill=2iҤ /Gu&b;rBEMtJXB};w.ۮ^z)<:T(٢~)I yӐHuYgA0o0Fy+e˨[n3$M# +WڢaCS?g1A_;g%E<֑2HXV$l‹ȏ1|sbE\ZXq1?FXhE09n}р 1{R͡"{vC[it"¨^xyùr ;'^ˊN%w:u*l*K $ܵNՐb%9>RePȢ 1,]#kwȘ0]3o1"L`&0ƍ!3.; HY|VR%5I׿E>[ BP Ga)b /H%X nE Fr1f|b^hl ?Cdc ?# u"1,xkp} ~?4S- g-*$СYoS~ynY{MRUZ훑\kהDsO]Bw>!qo}u(+7u+H%jg$ `)sLEYډ0"UT)vjXh,(b jB$5D@O?6g^Uzݐ `GgMaq E=&q(deVNr~}! ~On1)n;GZHKPU]m(;;G5sa#\ mh#ϲ-~a5P hq[]E0֭q펊W_[k>_ڻbe++g;ctzݵǿ*+ldʖ_p" ϭ9ˣ1ClvQ3S`,Y"x!OуC˜A۔ޛh2@|MʬfEċ lS!SL 3Of@zݡtkY< V/ cMÊ""K,2=آ=ڕgg{wЁ;^Sz>܎M,熍շ6֬}ƍB=/^FN܏agI57 y(eװ" zFG{E4ؓŽM0aGDwQʌc*v%~T -5"Pn1bgSP3,GM찶\*oRQP{m7'3;ԋ?3eqT"?›Z~TDRvqLj'SI’{m! +E5 ;O-: h;lv2z(kζ@߫82"n_P &GJL{wNJ "0v.e`vd?{}3aְOj= y4IhcVdeїySp/a!]'*.T4Wpk;\]UFFNEnb"#5,/|I04FwIʼnq$uQF3SwZɺ02ìuUP / clH$$3ڵ+M#kXhmVkv딇yg%fnsa΀ie3C~#]*LCSFNT"i0"<9"$98#uY:KUD){nhIE D EN#FT$LWθE?a) 92 )հ1Tޭ,)C)XBbfIb% Jd$Sy0$nDa5Lj(I<2YGƋQ0a)FId旀CQ[3B9fR ef# "1fޑ1#_c CF%I4@rIhuٗpfq ˲GHSڨ*z֪gDnݺ",O<,h~dӑo*0|7M1gq@1#-uY((r9Eeu_z%G!;Q=GYY,5L>݂$j*{o$Q$[a+:Qd.1"|TV8<+ . r@#y-Zp<|BlS?DIŸVQ(3^Jl𨈢Lx6 Jlȗ6!`C<.u"ЪPnUa 7̪LLˆHS1|{@̳b斩l9a F$.j>W^y #$Fop120Qr1 y)e/n1ٳg3qHlϷȉSO=dc-p4Ao?H_V.oXv|0U|(e"e.EEviD² G =1P azX)Ξ%@C%)H"?xY@`Z' u~ʔ)R'a㦹իngp=<ǒ߰z #'fRZ 5N%d& >斣rpK!ljOQAd%#M&x*g\@ljNs:y$YbYޱ"U ` 4IJ$F3փp%aw4<.A?*nn +9Hbl/u>#T"M"Ys+,.$!|0 *2 )J T&h*8Ì'gS[eATRHr;gniŝu:%LtY$!d gf l d` RaU![P,>P.y'IސeI,&d\cfA!Ґhy~0BOSdOi в^ ,>Rj(Y [Q!QxEY(4Dq <1̈/,ᖩ 5Wf4PP> ,3>33's9L"VAjd~e,Wx ,$S0_6!$TpfU{^(faD :qȉ_lԆaA4G$LP 6]N4<>I1fE.^h01eUdU$; &򢧊l<5j`^؈.$eAUV7+؈,ҬJ -&%0ԃ#$ /H*5.|_ /FGF?aaGYg&} dB"10 I=|]w͜dp*TV9$/@ɬx*[z8P : e ]Gv'JqD0iOt;mba>br&k/ @o vB]&w9i7AƜӑ25HΊO@Hڵkf)0]C~ X%L;a6M:5NazDc*h"8aŋ– SV@&Y0 dbY< ztl ÀId\mEPE*E@d +%f{˼dL4$BBq<3:D6ds.Due;f[e2?R ،$DV(7lYTw+3&<LTQbU[3FTM}MVlosBKJ`Rf3(ES01Q@Ð" )_>] 2D _$.L #Lb>dzA)>u1pĉZ,d`4P;, G a%~ڦ&\o>K,O+x -(TB< >(p9\3L,ps[R :=t"~yNvYsڪP<:^ÉȆX: 4JZGHqI;VXa' #rgùn !`1S90&3"FOIUn2Eڊ` Ҍ&z$&G9̼@ 29Ȳ~I #W_ΚJ+c0Fv GJH"j )̿fM"#,.Ѷ#+#UEgƛUf$s(9.3 6v )mI~IXt8YPK)%DF_6ٿ3)f 0d/n5HH:vY68MRѺ I4'@ @ T 5@Gϒ(1h(!!rf$i ]"0UaҨ #`O "@$/MH A$'4HN),@MAdevyx:3EX N4c:q 1_J/(1<0O/@%TnK* 8U2{챼+aS+muh.E@}܊(#{Xkjn[*;FcLn@{ebg*2"|(7Z"Њ`Z[*"_A5[E@PVp+CPE P*"[@"(p|VPE JBPE@/k"(%V2*"(@|!_㭽UE@h%(P1E@P %o"(@+A@ ("_ZtVՖħk5 V5q"({ J-7o(*ZImIPE"R#cþIɽe ,kdV5m|'2RÊ"({0J-4.W׳~SG﯃q͆1HlO]C# "(@snЊgp|vx`+5Z6f)l#ZV[sŮeE@PZfHʠ;7םsPo.uu`Tu8[hbBlк`SiE@h6 }λ],Ot:ٮ"OáHHAk֒Ա{:ii-2IɎº'aCPJLTW4}>nIL<-p1%р"(@lh Cx#ޞ3@F:V֟ݱ+1іmz(9]Eulΰefљ;gtZ"3Nܲ˾5S:웞^m[}Ks?aC+Bn&*KUe8M;^^fE@P6@h.=}rnnrQQe)Q͛py0N(,z*1pi%蕔d ᇎ<().MOKX 3ùfm5v^KOٮ]✷ C3kZ?={/P` LA%Ni##úǀy7*"R"՝Ck.v\})' fg9aqW\6Iz|ׂ6=N ;}Z B}a "YYIP}Jjk Jp`߮]Ò7hr]yܿ:رc{gCrn]wnͱ~C|)Ǐeg>̿xIԬV("U 61J&p'7^:[N>im>ǠJOOXtkkCo9mԞ;VIӇQ7{sk m\Q?JIYSQUO:4gѢ⌌׻bE ֮OoU0wg:7yz-ٙ9F e?S7oZ"(@kD4i+KbÀǍ[4*UWۥ[:3o-$gzPٯ,8^]6nBObê=ړpuNHA{$c1q׿?mo6ftC_}I^2wuoO{#`_88ʕ#ePh?9Ɋ/}Wp<"(@ 0NUeeuK}᯾fGO >C쒟>Y!,uqI7/9;'v.JaW/ąrVnZE%u˫i,rdkc)`c8[Fp`.#^n/BhY]`~znBWE@=gg%jݺ?m})Sz6;xر]nuc޹ kB iM*bْ ֬:?3;%-͍UQw߅Mjcsw(X69.ؽ>Qյ׽?fS3>c|q$z!OA%O6j,þ>nl("/kՆ.ۯaםy>Xm]3L.x=>df?]9xfm-ℼqcW1a~x~%$ϴSB[owuQ}z{uǻzQj-- +W{>[}9ҧumA^CӾ>y("?H\ZܣWK g ]njqO>iȻ4:%nd $rOz^ٟ#srvXհC:uJll Ivn˫:eYY]Zq᰼g%LxA4p"G@]vh"v]lX??S&̝[pA/{ܖM9wEDT[n{HzErRYe]ĉ_S_ȎFLKaw:O5w~Bc8c*;߯[eYի, ,JUQ-{ɯ/Lx[i/-/ |m,\B(),)лЩβl.&^"({>;O,T+=HٲvkW(IMu%TVx*~Z}vRZZ$&:{nݒC'p=d/˩)sז"}z9LJ~b|V蛯6澿.x!*]}Tgc[{jVG2K{\~74c=#<(0ț}4d{Vg`}ļ:^Sn4Q\xInGD\^mgHIW͊ QY@o{%nㄬ/o?wQ¾Dbl`Hْ[4MslknzѧjyG+=sɲy%%mݡoKPE`OB` `>ȒO $']5SH.3ӑZfЧpE˗fեKzNn/@8-l RFZnSPERkmwUf;o#lmWSB46DbJ2qT".p>Qw֧E@P*DjTg2HW|P];yƐ~r Uڹ^7/;۱qq|OŽvûI oa_VUaInI-P )s@Y ?_ v&n*" < Mb}o@o./Eu[ 5K'5O\jY%dFQ3N _1Sз UE@47!cYO5$&9^vy)ΝjBO lߎo4MQE@h^FI*p+TL[p0Wl)NWVc{P(lhAy)E@PX"{ Y|S`:0E@P3H/E@PE@ha[pmNPE@0P@PE@J1]TE@PPE@Pbp @&E@P%`}E@P еIE@PE@ XE@PE (tmRPE@Pg@PE@J1]TE@PZc t!-Օc AkzD}9[UUUEE;(qp `e]Me5zڲ)YRRRrh"({J-46{z0P޵DZ=z ,Vk 5flPm}=`r-]gIMMǥIGW! = tZAߜQ3(4f~_jw-TQe=y[}>'fq8)))33NOOW6р"@.5-ͨUT'ٶ"FqE~G0lz<ȸm=**"(nnrdg;\.{q1<4f;¾TVhކ_5 4z'Y,;v9qZ~p cF;";VXvȐÇu轛6UjE7?O8h- -[|GlٖHWW"3B?wHl,ňoT&UlQ!W>MIc! !7UE %nΉ{}/xtj}[}QϻVIMHJr2ްY:$A^j3Gv^^aG55Mu)lyI[ԖWLO$u u$ӜһiQ23q,6ma;6\;=5]T#.94x4'-dq\$m%x, nKXogMI -5J:akTج$BR㵰JpRaI"[J!|m5jE@P"%f悫S֮22#sΛy6Y,RS핕jUS '[]]p͚355+UlI` BͤvEV.922|Ee`v;vt6mRNf5ML̳ n/zXJJ7X ;TgN>,lp0Po28ǐy_y3TOorTI_outlVouۛ7@p7D8q.1?SSp_uuS^NճϟBGS==ʫ?}ƙotDo&M#؜~8!W#ƛ>7!UTT#_~eEk^Ѽ58oIX5^ _;ْ+WGa5(:|e9-(0(׵ v6˲P CC-l M]X5VZ"cuPII('VUZIrTF5-ղjMK>a %ICrцk"~!ɋoӭmJ1lX-U"$;?ݮr;XKJ:BP= ]"z,z0()).hWz׭}铧eSa9ۘ1GW|䑽 &t0㌓g}xZ^YE+.}yI%$89oii|'y|\7C56o=Q'NRW]<ֵ Ogѿ_FIIل}7_^^|잝 þ>pgT{FʷAX/4E_nz䄹**BS&9?߱O?ˀspXvY繏84XVnr,oKBMKu K :7r;op;>Ô7^2q߃? GwQ:csf)#s;WY’ʿAOv3_Mޫ2{\$9_~鸍+Hzs OW,§:F=$@߮hG_=3G~yO*}y=a(cWWN9>Sǎ%j=u<:Dl0,/t58%[6vNX+7txljuEET 0$LM&%6ڷkn8xB  *ryyhDC`ux+tKDK]eQa!aCoCHC~߂Y;-3Bwuɷ=Z>a_5Z"(mf `H`͖-կʕp:iƠii ]:eq2æx,n> ;qj# μ\w^vpԨܸU$yi/;\XS`%g񨉧c?h֭/eb3 O+Lg;TOm씋k=wO`ߏ>]ֳNs hWV\g O;u6izz{Cp5n:`ߵKF u\v0͟] ݺ.Q(;vs>Aɳv+,4/Z"(mf `@l[\Nk N OCqѬef<߭ǿ 17]K^~?O?ŷ8hHnB$7}^}} <]f^{$"JKk\Ӧ MB^ٜ޽qWO,նj="OeA+W#+ȇ+6+LEF.vj]ns'3@=ґ`-wX1_hģeb?;uѻwH<޽}2^h<ІݬP wx?KN {rL1'tþٯ 1tI^;X''cg'&Zߙn/vCy+gqb3:x4 "EP5&\FcF8'$g\s̜љ3cfF3A"j " N -K4׫ SQu֭Q#Ut 5z!! 8!!hWP 䫬0 !\\]m 0f[%Kqvc_IIdM79wl5Ozj7M=:{c-Y } MUzc$?o&Mz XS?O5k".tĊ7'NߌmvF‚_]S1\=t$-X>Z46bFI 4a9Fg(3˝-yֹ9#y61b5D٣ϕ_`^oa_r.crffAؒR ߽^$g gOڪ0H 97~/^{OwDW7f;\cKs^._Dѣ)lAb";PgĤ_v!ϕ+-n6؁Kf+йNpSS 5HNa KP~6jNMC!飏a/NrE1ƍVPh v;߈!\ qI>Zli()$BȢCT#ƺ1 -nhĸbi_ ۺUO6df8ɧ7~(^6uӦ&$hGT/Y֚XcgǞK^$('~;@WJ٪]ѫbkh.~X;bᬨ[q#qa^ ts8DyM/ %%pw𭂔5''XWƘgϮQed$,Fi!V寭%Qz9x/:YU!wIq5yKMS*ix> |8PrsG^g0v54iђ*TK7s:(PZVF?qee FC-D$Oow]zrV$ {#7?\ܳ$ %d E7嫪_aϋu=@mQil]>5D&Oݢ9V[ؽT@iZ艹7&Z?AQ%cEsN6 Zˌ=VDYZg(anBv0H P^|pK$@豥(;IHHe  u^G @[LC$@$@Ny  hKܖ sHHH P{1o@$@$@m P2a : p# HHH- p[&!  ^'@uļ %@n˄9$@$@$1mWE ヿ| ߗRnt?b"aQ#՗}=mۈHZ 8K tGvc(y64Q48n-HQ'|XB$@}BiYY>f']9۶E+eY}Xouh$YfĄfH4P2k O EĖ*iZk VxJu_ xn/\   nvRONIPPHkp†)R/'' O,$Q4G7/CGk뤆&OSSL8,)@ٴB 4՚b'іN>Y t@BBF\8Gsj}g' |B U؂Qje~֪uJ-B_C F1o1(Sz BRJ8D  ^&7 mh&OT~.`}+OiLGTVt"k;GĐdH  "*,8"$DOykh~@fK.V/m\-ق!r|sI lphGExmAvrHH#G,K!4ȂE 9;G0Ht.tdtRSIK$;" G0ob. 1bTS$eSU2\~h]te Dˑ& 9~6*Ï@`mF5DIwR8",]Ė@.T[U>jSU'֞: @?$7 ] x*v5]ҰƍAx6kb/$׏22"rnƊUvRP6Ǿ!+^(>@Ixv5^1K,7S7S.W[/~i77ެx wrPHx6_a 7B4|>4M^JpHH!3:&~Ev1ӄُYs'2FPJnbbSQiV&S!E!]s5a(1%E^Ob6Qe5A;z"C$q,j :z2 &EN`v @BC;Tx$*+stM~da.g~˯BZ1&!Æ]y6rm {2KN^k_в,Hhjq訃lpI |ruSQ\>8d_GcB֞ aD_F0`Y&  A~>x~o0 ƪCsƒVA=rn1A]/Crp!f6JD4M&\%Ϻ~~wt)2b:MihT4z7oAykʕUSGmfzt2Da^/p#s)W( =<4}RI4trbaʜ'^%% W@a?b3nu@BFj pF< *9R" KL1J |Y+ !G,C.ϼwnj:YGSEwᑈrcV;+C>v[n; ^2\bbix.*k :|M;Qw -dH>`A7J13S~eec݉_􌾹Dla ћG'] (ʫai,ic }cP[=B$z: q&:?ru0L+Yx>gב{) Ƣ׮ Ĝ%/ %r$}vf\Ql- ~h @`!@KO5X 9,+I#tBG 6%0PBf0 rH8\Q, S dFdcVN3,Z ;9 q;YxQH9l)_7ڏ~}ba j{VUԣ]`iJ$;Vbm6BL\%YbρxvO$@$Г.cAp!0M~~Z"{>ۊCXgmIH . tGb@ MQQJ[qZY׶8 8y @=$@$@x@<&6HH P  A< I$@$o(Di @$ 7x{HH`@F  p=QC$@$0 Pcb#IH8ޞ(! (1$@$@FoO H  x#@'J{HH xLl$ @=$@$@x@<&6HH P  A@뼕,iIIIY   4#& 8Ʋ,tt=IHHZGac;`UU@O b/> @Gٳ'==f-֡>=sL8tRE2HHZ>C7kQоCt7n8z)SΣL   Ģэkv[?,bUyyy8&;   AOguݻwso^K$@$@g-%oڴ jjj:O t@JJJboX2yH$@$@$5Ju ମU«HHHHHHH``.4F6IENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/frame/000077500000000000000000000000001457770046000234015ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/frame/README.md000066400000000000000000000000361457770046000246570ustar00rootroot00000000000000![Screenshot](screenshot.png) golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/frame/main.go000066400000000000000000000014421457770046000246550ustar00rootroot00000000000000// Demo code for the Frame primitive. package main import ( "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) func main() { app := tview.NewApplication() frame := tview.NewFrame(tview.NewBox().SetBackgroundColor(tcell.ColorBlue)). SetBorders(2, 2, 2, 2, 4, 4). AddText("Header left", true, tview.AlignLeft, tcell.ColorWhite). AddText("Header middle", true, tview.AlignCenter, tcell.ColorWhite). AddText("Header right", true, tview.AlignRight, tcell.ColorWhite). AddText("Header second middle", true, tview.AlignCenter, tcell.ColorRed). AddText("Footer middle", false, tview.AlignCenter, tcell.ColorGreen). AddText("Footer second middle", false, tview.AlignCenter, tcell.ColorGreen) if err := app.SetRoot(frame, true).EnableMouse(true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/frame/screenshot.png000066400000000000000000000466471457770046000263050ustar00rootroot00000000000000PNG  IHDRT12\"iCCPICC ProfileXyTKnX%眓 s%Q"AEPTPAP$""   *(y͙꯺{v`' 6vtrM IWT)@ڟl+#ں>߲6o(/ K{zGy 4Wxd4~DL~;y {=::@"E@!"j սIv :{BB¶=ekDw|ndQ?c"?zgd.laC=-Lm-?nW+J3 xtM̎`Ƙ ;],Clwgd}Tlh鮝,?O}##jLu 7G0QA6&}uDXoqGwH}9$_i{,$`h[ÝO>z;`oP]n0]ֻ}3Ã-w3>; 7D4IyIƖcG[pC) ' ``eo> H|O;$OQio|t,|nfEUѦY9dJh?b X< 2x%| a0Ø K`m[rHsn`&ky; ZVC#ьhV Czk1脅'DGsk!Qn)iE 1>G3^$d. 쵧^1;`P!p> #*zX[ܐ!8L "p%p\-#0k$/ރyVA8X .Hd %H҃L!k P(CPtjkM A/Ih B(ŁDIPZ(-jJDeN*QWPͨ{Gaj fy`qX ց-`g9p1\ mHƢhq$7 vh/t 4݅~D/c(11 a21Ř*LY71+X,+UD֥6=-c;Ci2cp8.+]=Ž$ "!'s& %K#+&%C#95 7yy6'4x!OşcoV)((z)&)V QC8F&t^QRR RjR:SFSO9NHG Rb3)39U"U1 'T Ԃ:$ԥ7Gihi,hBhhihi3hާt.uӽ __decgg(e03 2131^gaÔT3&ss=0/n= |7hVQV+83ݬ lll^l9l^E٭ٓϳ/sprpspXd ,9EǥUuk[;w";!O Ooo=></_!_'"?~N t<,"8#,d$(tYhLRXC8BRVDI$H\dP%*//Z*D %  V.6GyO=q-Xi-%%%%{$KKK]z-M+m,&&UFTKT,ll쒜tf;7"f=G,(*cەWUTU|QW RU+gjj$ unus<$J)M>Mo*͏Z"ZZW>kKiGj7iQ9ӡ ӿh oda14175021Z4V4>`eB019m2e*jif236;a6f.`jb,,NXe*`-mߺdžݦfV6]]=}] GIXZqU.z.E.]]3]G v۝ʝ~QN U=<<tNz{kzz|U-S;7_p:`)0l `A]aaaCb*E&UQPԾhz5?F8Pdzli84 /&:O?y@@Ad))RAӤ Ҿ;epddL28t99zX,tV@@lvIRŹG<<*}c=> `ىBœEE}rgOOƜ8ezxiåڥeee?ʽ˟={ =.TVVmTVO\UXSS^wu9+Wu։U36kF\AtQ)jNh^lohuji|Mĭv dټxw#c߽N?6}~V^>^VmI)^ޭ@#ǚY9k h>}EKȥͯG|.sry|%deGOVV{~9[?!ff8)*#P:@7S{6*9PZǒȜw XJOL^ 0 )+ 8  hr.=S"$&I)V^:EJGMC VUTyQѢ_K[Vn^~AC1IiYyE5ƆŖՎ_wXs.DW}}nSU^%9> ~~rA<,!Tp[E'd6ţ|;UR\RcҎe$;4w2K "䢎>g~!߹c}mIS&%K˔eψ='UaR~~QՕZWT֙;4_~#`SZ󡖬ܛymEګn7;1qoosWow}}<6}1xn3:#Fz/^ "Z}=3ͽo'&̧Y`Qyifb6gNnnbB'dk|^<wΟlnn_Fó 4v &WS&TqhY301agddri[_|,t^8RD]L=%Hr(S'+&w+(Z()(r!Y΢>qREKPkM{X=4 ۍcM|L=,B,=,UmDm(#N\J]s%;z$= 9a.&*‌ `PJ$&#GDǔދ{?AdlԦ Cvҳs6i>xZ5 Ν(-,*+>v*$_i@YJݳ".U /j5k _(Wt_ϼqNPxL6Sm;w;xMuo.}pPob_GO yLHO^~M;&t<ɉ[OƧ OY$Y ՗F>v{r+?Wu7fw/ͣa7YȦȗ(J-3U*!Mz=@CgYYzpsׄw/_SM`UPHJ衰NZPX=^@\r ^TfF6]SUZ~A"b 2¨rYUK^Ւqr#ZZ/uu6u+,7334v5a61-212HTnUod#dζn=sğIKK NOzց;LI+NO;䒩wX4 <$9?wn;~0ߥ@‘'O=UPRqF郲sgQVpWʞ7z1`u#5)ˊWW^T@y]ecRScVm%[oߺwwA.>هx =z=86?50}u+;m5'R 5; :s;XR` PEb0o*Ra=$S$&g#S) jJ9vJ!khZjګttCC  O201`ecmcsc'gou;Gg_` QpBp5$deeȷ*(&(y+H2%IjiG`bno,gbnavʼ1{cS ZwX'sϜI@Q!Í#j1[œp,MaLOgZ>5{$XS> O5O3=kpn2ŬKA5_/WOӰtCL|ǶLtu{i<|,Da(Q+o&'Tew?zrqoMc+8@Q Ԁ! $lPjMbB EE9QQa./a&3ľpa2=VrIZ ]%a2HN,j@4q-tt0N13>d cfb` `g` cg(tbz]+_tCj9~S,O<]bd Af@6GDI~IbRrĽj?duruo2mgNpMYKpgig Wɬx{i7h@Ā dWF ƑuO!MhBI9u53>m4;:=q<`opLސG BA&.u37fb4fRdagugK`26153p:*\++:R\QWԈ \cN&:H[ 6KX\nձqq;_qwtvy!:?,iKLtR,gxƒv)*23/f=r7 Qoӕe V@e.W԰^I3hߘ\ٚt{n=zn= zU񜷏&Ͻ 1hlg/K,~_^>¾RC?~62F6ofvrmpl]s=~φFÍҿMMS[~|@m0㛛Vq)6l[-kH]()iTXtXML:com.adobe.xmp 406 596 1 M30IDATx UUB (CE3,椕/E)1$Fu׼Ň.]i$ZTPJ͒Tk> sd^5{>93agx~{{3@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@`[ņS ^tun(.ɇM+zƙM q=7h彷鍖[QP݃7ZTeHl=STC6G[ЁQhl>=l7,^ѹ9hi:tKW$u904wuwu;5L敳5mۮ`xFGSNhٴn8}~@ʛSHBLwu[mN~7jM56ifllLϜنa6|Ԗϯ[nڵkml W|eMuTڐ񧝞kl7޴hfC7Pӫx!{+nq=<vVܘr9`ݶ=w|Xf5} VgmylgsXs6ۖtfOPM]2q+7\ L!p jEm0N0x9aMN1Tɭ{衧t÷6~?8t6=䪋nS|8^ےzrb8e6~ohб̹y_d(Bo;jٍ͗Wn+fF^n9V7sO^~o}8ECoz .ІﻈL099*tL9sgXlGO<:7 I6quy__/Y;]ȀyťWKg_eo;a„/.kC.i}fwD-m\@[s'~ tZ.󵽴tᜳ⢻z." ɁU9]9s[ʹ>:%XMZ[2LyP.{…ͷj͵u .ZhѢwT0Ͽ֥sξeg³^}pk^۷vGGR^z7di˖ 'L>߽fgL8086wύL\zx+ 7*%/z0pPe]ǁ楺 q ]-]!x q=G;ܧ#Տ:0YlXs_|*}sK퓟@ _W_ɂ UtΖs;7Lq?ۻcΨO8{}cr_+D[K_C^C'm; 330)`@XAVO#s.;j3hklI#ع^{ ?־]gxSPIqzmd~%?lX|ݟl/.z6,r{pn뚇ze۶ϞqVy͢~dTa{v&ei^fj^ uUl>P|t':h9`;t;'>fkX87Ϟ0cT_Hz!'MU1/7 m"kP^k\2 j?NƦŵ kk;wO=0B܉u?K^g^tBTٷ,ۜh^zͧ.+ݤy\\+f3"7&w<(a\Cެ~nqN2? >">hQ|BݶuY_Z3'7fS{j{|Hu--s' 0⌹+?wFFuNիWخ뎛szk؁cGFw>n/l6Άug07W ܳצEN;dHm}H){&Z~soo}#Lw 9㺇 `C+.S"SCӲo2}ߝ?yXeE0`OmoܥslG2_Fx{aɔzIע|OZ +?'ݜ:6V-ܑ' 7$ΟM;JMS;lkrì{wo_Hq60^:PbE# h`@uڨ^}_JT0'|*mV=dnX~CO_us[:nyq+:/6?풨N3__.[>jꖂz7Nz𰺶_Zty2Zp¡ `nj>clK}K;qf}ڥs5jSPW*C%9 쩍 'Y{+jݯN~sY@@yr^?)fy w ηϨ1 ЛM41l`w@/{7Non@@@@@@@7!3=eH UR P:|-<4]oϛ]h|.gtq5f_i1_?TaK*9d@Ojzsf}<~fWa-WU()EVW !jDf"P=_,SI<'~_m1{nchv2W; KyjWJU$8^F{ jU8e@n0)ͲX }Dyn4q~5fGG5\K̾U>`T%F4JK߄cvLwlT'̦'#O safRkvosf>ߊ٩&^6DHd|nsVIAdpr\5{me3e] &I?C0̂9Ax&(%ݞd_NQwV<gov.Q~T+ߓev7[*Y}+l thfJɯmw7!coG̥x~VRnKn^ֺMPQ`]~^SWU?iא_C0S5H]f]!x4qWq$4(hm[{K:|QJ9cIMyT:uCDڨ`cvhb.M>FIP* B;v5]D2 RYE 'EA p-fEkNЇGswפ4K5_Fu[0otÅ_&|T]UT[;[Q آO6Z>?|#1sSb<^ Tb^ `@% RWR1$J,}:U>9I|SL1:ˉT&TW?2?&Ȟ<>{ PU+}į+:沸q凂S;ubFnT%TUV'uTR u%@,x#N?(vduwv5J"B%(͜wHbF攺}RO>Qmux^ދzfT_|{{9/D[C0 X uH 욜`j 3A:([2k咛紸ɏFw(`v~@M]єj{:-s#:؅o߇뽏{G\)an=5 Py@AuED:.*W1e fP'qN2Z<1{]-?w[lNs豍t1}uOvA}uv& HJ ֕'5'Uv_ PH[bATLp#Aj  Trfϻ=]ys{\AO.hC:L$xY4G%hl*Ap򛈢~{m;#OK~UA \ <3PP9#Zv4ͬ*vQg<Ɠh2X``||` .2LgI~ F{A 3ƔhgՓߕf}ͮ[{Al+y#CP foo6l{me_-?7,yUA'["@7f5zR5A Y X@D1蝍SjŅ3?9؅Z(̪T xX-f3 .Ef{U4+G6_ftsT%̞N3C܇I'b ͎p*Ri'Q%^|6wAO?axe7RA 5bvmY{%f-fiPd%N2{͞1l[ES"l=X`@\T uuY@B`8T,T^lu֞HNn/bSV{9#63&g`Y4îN¼w%^ |NH؊ܾg#Qu|ҰK5S /9v%}-S"FwI!-|_0 D(3Wy<|?|:{*]-P&\bv٣.35ym"]2rMfwK5KU/ ?VTgU s%ÿDO6u0]C}Auև,Gr~RܜÍ^/4]0-J{Sg*a u{Y4?XϹH],=>Zf ]NUPrJН&~P&PDxDU>OWp1:,.^9 aIPfâInD ϞgvwYk( >rǩ2?}75(%l?2doK}}V}:Z:*߿Mb]hWէQ1OE[īGspE n`! Hٌ"P@28ȭV7e`@b6(>AS7=+ 3H,k3>gdY)*(3ϙT;иtnzK!)OA w5{1~VAx#uSE'\])Kov`au7vHJw9ҳfeh !PyPW^q'GA/y~0߽iR]I3v IQr=fh.Mvb:U[S#7;$67:.P ?:Xp[%.s+00Me;T\-pwEK?|JR97$W3+V\uzcm*tO4ҶW,XƻG23[mzĞѵ  '񜟙zշgU F.pTKwf/' !G>%6 w݆zr; c+@ϯ˸*ߣN?L9FlTgU>&~Dr*̧uc_%df3nquB͌:S̔*1ksUAdUގ7AnBL`@XC5Yv:(3啟\>K~۬);uw"ӏixl6q.)d~g/US]~#i7:m.BeB5~Pžf(k"7?z+R#AR+2$@oj ŪǦ~e>=R_mQwJ}+KQnf3X[fHEgZbvV4)5T#U`mŧ8WLZKՠ.w?+n~0E^*wbHGl  Oa{Sg>?S=ݧnǚo0ʽ_QccE<ؽ)%+r?v>M&Mn:ٕ,Nl75|~SQd0 *{*>H 1#eLErūU0C^/X|!/qhb'xF231?m$oNiWhZFR9*@I}[;@P!\pWiJ)37̋#q11ox{1`@Vp' ?s3 %>poa̧Y@h.~/c"ֹͪ1ֺ.Dl`Ugqn~KO lr5ބ6q!&F.=\ &p?Jl ZDtZ:C>/92֣]ĵ đeFjߡLY                                                                                      Ժܲ [b*IENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/grid/000077500000000000000000000000001457770046000232345ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/grid/README.md000066400000000000000000000000361457770046000245120ustar00rootroot00000000000000![Screenshot](screenshot.png) golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/grid/main.go000066400000000000000000000020521457770046000245060ustar00rootroot00000000000000// Demo code for the Grid primitive. package main import ( "github.com/darkhz/tview" ) func main() { newPrimitive := func(text string) tview.Primitive { return tview.NewTextView(). SetTextAlign(tview.AlignCenter). SetText(text) } menu := newPrimitive("Menu") main := newPrimitive("Main content") sideBar := newPrimitive("Side Bar") grid := tview.NewGrid(). SetRows(3, 0, 3). SetColumns(30, 0, 30). SetBorders(true). AddItem(newPrimitive("Header"), 0, 0, 1, 3, 0, 0, false). AddItem(newPrimitive("Footer"), 2, 0, 1, 3, 0, 0, false) // Layout for screens narrower than 100 cells (menu and side bar are hidden). grid.AddItem(menu, 0, 0, 0, 0, 0, 0, false). AddItem(main, 1, 0, 1, 3, 0, 0, false). AddItem(sideBar, 0, 0, 0, 0, 0, 0, false) // Layout for screens wider than 100 cells. grid.AddItem(menu, 1, 0, 1, 1, 0, 100, false). AddItem(main, 1, 1, 1, 1, 0, 100, false). AddItem(sideBar, 1, 2, 1, 1, 0, 100, false) if err := tview.NewApplication().SetRoot(grid, true).EnableMouse(true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/grid/screenshot.png000066400000000000000000000451411457770046000261240ustar00rootroot00000000000000PNG  IHDR4#iCCPICC ProfileXyTKnX%眓 s%Q"AEPTPAP$""   *(y}|[S]UWul`5!ё܎Nܸ)`eii ?g[Fd`O(7f ӏ÷"#`[o3oag[ZHH?[c;D#6; QMA?DgOHH^@mH~/ۍL7 *<9g ^ GZoۥ0-L@p{i཭_/xE s@o deH}}y@. ޵ 67ݵcҳo`$P;|'zgᆨX?}F# 3T rwhKnh0:@pa  ,, v~Jpؾm@" ]7Jwwnv !hV:Zm5CVӏϨX=. a 3A>w[\B=f 3ݶ]-0f`翽C "h5?͈fh9-<"7ØʉD]#WVt5G俚p|}p;p+3v&z[b'eYMk}⣷NXxBd4pzIᖑV`ko:Yod>3E|Y j`G& ^{#ڎ*X'ˆ?2@MN qpA*8(Yp\Wu=<`F=`A(!: 1HR!=  bP: @ ݄A}f/"Q(A$J 2A٢PDTuՌzFMQ0)`F`v}H Õp܆</h,͍GrmBGO/]gI"7Îè`0?L&S4aubBXEd]:aI#rl=;.p8N g#q]S{O2 2.22}2gP4bZ;dO>S [{'_ o#B| O«mT)|?FAAKLaE@Bqbb@K%\ 1cjB%%% &3e41?tD ћL,%6?SS PiQQ%RSݠzB@MN-HCM>H]J}zzFƂ&M-M -VV֛6<}i:N΋.]7{z,} }.UEZ9{xR 0 c0cu_LLZL>LLuLO~01k20033bfc bgiayÊfebc=ͺFϦŖv;]ݚ=<{?2'G8G }NFNM@B;\t\\\\wOqwq/T )u-sJ\@I_@A!AÂ-3BBFBBƄ)5#+`EDDEEQOPb bbbC{0{3*N,>)(a*&"Y_Y2_G򷔼TҴim_eDedJeR&˶.ɉȝ{!O'o&XS~CAQ!RNaV_CLqT^RR2FY[9Y]yUEA%ZUq ZՙB{}^;ƫFRPPVP?>AҨԘ֬%uE볶vv:niq}^}?IC|Q##/EcE]&&Smf(3cfc-K![VX+KR{llmjmVlml_ uSٻpu(ppt<ȉ)l\RU5udо}}nnnݩI7<0$ R%iȳsK׼wOG_5?5~ :  v! J6.>QiYEjG^sccLƪǖOߟ 1Q?b:+s?TzLKH~br)8M* {Cz[GFJ!C3UBgd dfdy+[~ãGO<{l O!q# h  Oh..)^^W,W|$dɉSZKK?=\]Z_^]ܻ3ug9u.܋ J?\sQbMkUnFuh%K]555yQc.^q2xUjkx]E=c}nhiqmJ7˚rV֡7;TۚnIܪni/p;NƝͻw;;ݛt|}.nhUmSPa#GM7 ( 4?Q|:<6wS>{a/_̼ ~*1X7oEO(Lܞԝ쟲z=5=.?r}i՟s{?>Sgύ_4/:._\z˷r;-WBV~dyiUiïkqS"mM~mln"Iۯ0r|}Z t;n{H+1x,N̉<$[4ʘsqy.M<`P(؃=%AjoSddyd?ݔ?`Ȯ^N9^EKlo- ou4$i3/֙WX[N[clXlYau5'LBt܇޷6>AYUg (B ~ y!XtrLflS<:'c?8 xP%(%5&XzQF!Cәy-)r@.Qcy O8[4?eRbpZTL\YsR&'.U],}EnYC5765jjͽVtvF:v1wv?Ic'^>x.93b4B+3c/?6}on|{gf&fs&/-$~2LK_ݾY|7[\yWˆna4~>4^|״coLߞ5tj|z ١yOP}aio7W,'}5a]wcv7<vC`p%,nl|O":SR_ݤ`c d:|- xnm_<xMx;V  DE E?e-%$%JAneLefd8Z)r) o-3**UTY-I^!1ũժmR_gSRR\~C99JcWf"3s*>tKUVA6B6l+ٳ?ws4ttjrvwyZ|ߊ[{+R' d1US7 5BCB/ˇG܏̉f~s6;N0C$gos+~ԚC.zE0YϳKrss׎L}|f޹] TNX-)^|S%o>({Q>wfewy êVg_:RRKxxOu kenX6&556lUVr;}wt^)}ǠS#/cSsWV*p"P3 3%%% P~L}~@ ( `\@H2D!e8LHIC;CW^ FPHuM7}=dabU%5zHHVMFgS)X ՔrD5b-jC4ѴԴWtm,23d*aVcg9N):w$<:o_1^A ,OQ-1==k%IK5I'Hˌf}oU(PLPV6UReKTP/:ݧELŐ݈X4yW+>kc=h]L~FW}n<$O{19?*{C C?GF#b^Ƿ&'U>X˜H=|80k>'Hȱ|kNf,,?zreYU+j^>~Uaƙ֏mKwwx$XP賟WcgMyO?W+G>\~zߞRVqh @C` <@H٠Ԁx! ImG?* %rF\;|^@+3L*f })qdzdx 9K4e`3bg|J>QǛW=,!*$rs"7Xx~h)/iM̀lPy~q`S³aQ||,ςY5ZY?nрP#,ʯ# B>( *nC(r$$Tjf}hvt zyƩ!S( 02(MIM]BCDgDo`h̤,"Ζiemckgo-.%tTVWtviVYoz5EK*{15׵Mtґ10Z311m6b%alc7wjFAO?7CupYșXθIʓR~Udgr^̾{oA>KBߢ%4+*.(]a\g y]15ͩ{Nq]{8? 9->)7z9oMRMM{7Ac̹޹'R_tH_Y~|t}?V:l^e\\m^]+Wqf:ٺz {>ߛқ>6++`77 +`#ssrss 510 820 1 4p/IDATxl'75S#Q[Y6(WƭmMpņ jipE9ʊHH4(Q5Ͳ E!iJxk{glyy~|~g}L}Æp^so/0p썡%'CUM{T]+g}˪V w*{ vo۰jܪr_oUK}[qo+fwٻ*8 @ W2@גU׮sݺ>siPio֎w쫚5;ZkTww쭚y-m dVyxkOM#`+?IUsfyt_1_NԬ @\9 8G]KY"5i$y sꮼ!ٔ^<[q}拺ܵuW]895Jln[@<|ŮrC$ҋo;ް>wlSgns7d, e'@ /;P$˷<&Xٍ77b-kk󷾷r_jg^ AW}2_.;NZM^;q" awɗ'I>WMN-5k֜Vl_WҎtû?}m~/l2 ƅp6.vI 0Rw{3qK_xd᪇$o\Ǔ k.7=;{t˯ $Vo=}[sҷ>cgqFvA@8{8o12dJymߴ)'td/_; 5~szeH$Omvq{{2pPoR?8PǎߍRm\Nͤ8O![g_2Iz=mSSrSpqJ.W@O৛Ȟro?гsoN>SrO|Y{@ @@pVa pП P$ aX$@d- e'@ gE  @Y gY  @EYE @@Y{@ @@pVa pП P$ aX$@d- e'@ gE  @Y gY  @EYE @@Y{@ @@pVa pП P$ aX$@d- e'@ gE  @Y gY  @EYE @@Y{@ @@pVa pП P$ aX$@d- e'@ gE  @Y gY  @EYE @@Y{@ @@pVa pП P$ aX$@d-P"]pYJ @y!02wg煄'Iٸ-&E=o @`\ gr p g  @q) bR @* {&@ƥ% @x衇 X"=ösDHI?q>2ozF#a뽬9 ] @@Yz @ g@%@d) e7 @`p6 ] @@Yz @ g@%@d)P"{YHoQQ5!pVӳD8<$@L@lTO8X\_3'iz>󫡥խNqssZ7vg㜙og5'_ǎOo'pKS.1⍗U36-۶tlQ g; ƛs/Xwswn5Sih/NLW8jk;.5(L9Nt$9#IFu)1UXά8ޅK.iʣ? VJ%csmq^U$x}ò˖-%Oo>],rA`RaX 퓤r浫w~M.4MUY߲*C~[ʔک6.ٖ[_7trnܾh\yb0_ d*P8_sׯV^_|oaL[7ly_?'r5oxֹ3sK2pdw5whY[}xKϕ?=[~ʊޮsmiqrp#0cKG\ϯAۆUO$榏*} -zg qC}_^迢nVyg^b[Ahl$s"0)ߗT~'K#]]{ڛoXqǾY󾳡57)Heeum[zt׾[rUUo|xZՅO@$5sܻގ;VͼzյHE#_ ox}̪{6nzoڼ+spiloN)ںydz6~o?/?#];vӃF{'p6=6wOo]Ļg>Vɬkvퟚ^vV8/;IVlܸ-O=ۖ;'OS7ϣbi\S;^:w7"}Y몓g~ dڕ.4|pWGK[G皿=ПTN*Ž~Y>/n.Ց=w$<vnx<𘚖s%UoX|k֍cӁ'7_}Z҇Ύf;:֯0<-3Na Wnݽo+w4'%ϯk>Yym馝;;Qn:e\.Mo_8m޽|֌t̉Gt Ut/Xj?vY='R:gtgԭ!06=sZW,k77<=O&3/I~9$=zzEk.ɽU -u;C{EzhF~/+0%^ria%܆)[S`-yŷ?^YtCì*ōy׷HپߓL /yWKѳd)deH/"L} wh\<#hvCOxKtqɧ?>ښ{(~ ?V2_jHzrEUWs>Kx҉_cz~y՗I}r!xK%!o%:0C{znw>:7-G*gkso-_wj?lRE`SrW/_Һl/MH[}MIɤ)hmY{Ρ(CΫm-o_wNnhg6ַi[5_fԁr=i x/]k/{醖;F=b{2"0:y97\]?k?0=zݝ?J_/6nZ?oIߚߗϣЋ/2j꯿zzr= e=1[ ZTxoK>~Cot{_Og|u~ӲGv?`4Ã'ܰiʎO&]<:'D #ryw}ᶺoNO&<;so^yGع>_yu-Y5cwo\;/ݨʽԲsKW/yeck_hokZT~ƾsۏ<(1`oSΟ3ٜn޽>S[nk]ޞ9ԛT'9+$޴x`ͷH(;>y ܒQ={C_,8$O7^t^8ig4|FMÂ0K3b`+NKybJvyzϑ%|/uB*y3!I޻y:S~apؖiq{/>#K 1a~i1&GmU V  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ gQ5#@* @ p[3 @@X@8  @ g\pA)hF yztt^` pxβםT×LJ'ߓ&Mzkgpcٻ ggLd, e'@ H/uԨhOψ+a%׿$9%F?zqMF%V@8;F'@ljZ<*7.Y3Jo{Em|Ϟ^YؑOi5ͫvSue-ۿ߽Eݬ\޽pVnLdF14P}lٲuuvmݼكkuuRnq׎_Hwoڱ`57Uڱv}U}gC`ɓ*GwX9cE @ ;Wβי")_|<}Yrݣ8=uWemzgSjZeo;c4δ?ѐ$W'?}Ihr?ץv\ \VeGXA@-e;.sg6ַi[5_fԁOֲNH*>޺K~^EoGM /}ᑅ>Ɠp68?x߹~]ͥ_ݼ=7 6,>?HviQ]ϭ}oZޔdCvx%J7W[:;"@<iXмa/8&ǖx@v!, @ [˕lw>76)>{C4NSq |( @@A@8+PX @d/ è P  @ g3 @ @@Y  @@a p>0 @@A@8+PX @d/ è P  @ g3 @ @@Y  @@a p>0 @@A@8+PX @d/ è P  @ g3 @ @@Y  @@a p>0 @@A@8+PX @d/ è P  @ g3 @ @@Y  @@a p>0 @@A@8+PX @d/ è P  @ g\pA2 @y 02wg灃H81E=k @` gtǘ p~ g~  @q* cZ @) ݳ&@Ʃ4ꪫxq:Y"@L,[o瞛Xɳ!@ @ @ @ @ @ @ @ @ @ @{IENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/image/000077500000000000000000000000001457770046000233715ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/image/README.md000066400000000000000000000000361457770046000246470ustar00rootroot00000000000000![Screenshot](screenshot.jpg) golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/image/main.go000066400000000000000000002671261457770046000246620ustar00rootroot00000000000000// Demo code for the Image primitive. package main import ( "bytes" "encoding/base64" "image/jpeg" "image/png" "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) const ( beach = `/9j/4AAQSkZJRgABAQAASABIAAD/4QCMRXhpZgAATU0AKgAAAAgABgEGAAMAAAABAAIAAAESAAMAAAABAAEAAAEaAAUAAAABAAAAVgEbAAUAAAABAAAAXgEoAAMAAAABAAIAAIdpAAQAAAABAAAAZgAAAAAAAABIAAAAAQAAAEgAAAABAAKgAgAEAAAAAQAAAUCgAwAEAAAAAQAAAPAAAAAA/+EJIWh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8APD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIi8+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPD94cGFja2V0IGVuZD0idyI/PgD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs+EJ+/+IP0ElDQ19QUk9GSUxFAAEBAAAPwGFwcGwCEAAAbW50clJHQiBYWVogB+YADAAVAAsADQAEYWNzcEFQUEwAAAAAQVBQTAAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1hcHBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARZGVzYwAAAVAAAABiZHNjbQAAAbQAAAScY3BydAAABlAAAAAjd3RwdAAABnQAAAAUclhZWgAABogAAAAUZ1hZWgAABpwAAAAUYlhZWgAABrAAAAAUclRSQwAABsQAAAgMYWFyZwAADtAAAAAgdmNndAAADvAAAAAwbmRpbgAADyAAAAA+bW1vZAAAD2AAAAAodmNncAAAD4gAAAA4YlRSQwAABsQAAAgMZ1RSQwAABsQAAAgMYWFiZwAADtAAAAAgYWFnZwAADtAAAAAgZGVzYwAAAAAAAAAIRGlzcGxheQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG1sdWMAAAAAAAAAJgAAAAxockhSAAAAFAAAAdhrb0tSAAAADAAAAexuYk5PAAAAEgAAAfhpZAAAAAAAEgAAAgpodUhVAAAAFAAAAhxjc0NaAAAAFgAAAjBkYURLAAAAHAAAAkZubE5MAAAAFgAAAmJmaUZJAAAAEAAAAnhpdElUAAAAGAAAAohlc0VTAAAAFgAAAqByb1JPAAAAEgAAArZmckNBAAAAFgAAAshhcgAAAAAAFAAAAt51a1VBAAAAHAAAAvJoZUlMAAAAFgAAAw56aFRXAAAACgAAAyR2aVZOAAAADgAAAy5za1NLAAAAFgAAAzx6aENOAAAACgAAAyRydVJVAAAAJAAAA1JlbkdCAAAAFAAAA3ZmckZSAAAAFgAAA4ptcwAAAAAAEgAAA6BoaUlOAAAAEgAAA7J0aFRIAAAADAAAA8RjYUVTAAAAGAAAA9BlbkFVAAAAFAAAA3Zlc1hMAAAAEgAAArZkZURFAAAAEAAAA+hlblVTAAAAEgAAA/hwdEJSAAAAGAAABApwbFBMAAAAEgAABCJlbEdSAAAAIgAABDRzdlNFAAAAEAAABFZ0clRSAAAAFAAABGZwdFBUAAAAFgAABHpqYUpQAAAADAAABJAATABDAEQAIAB1ACAAYgBvAGoAac7st+wAIABMAEMARABGAGEAcgBnAGUALQBMAEMARABMAEMARAAgAFcAYQByAG4AYQBTAHoA7QBuAGUAcwAgAEwAQwBEAEIAYQByAGUAdgBuAP0AIABMAEMARABMAEMARAAtAGYAYQByAHYAZQBzAGsA5gByAG0ASwBsAGUAdQByAGUAbgAtAEwAQwBEAFYA5AByAGkALQBMAEMARABMAEMARAAgAGEAIABjAG8AbABvAHIAaQBMAEMARAAgAGEAIABjAG8AbABvAHIATABDAEQAIABjAG8AbABvAHIAQQBDAEwAIABjAG8AdQBsAGUAdQByIA8ATABDAEQAIAZFBkQGSAZGBikEGgQ+BDsETAQ+BEAEPgQyBDgEOQAgAEwAQwBEIA8ATABDAEQAIAXmBdEF4gXVBeAF2V9pgnIATABDAEQATABDAEQAIABNAOAAdQBGAGEAcgBlAGIAbgD9ACAATABDAEQEJgQyBDUEQgQ9BD4EOQAgBBYEGgAtBDQEOARBBD8EOwQ1BDkAQwBvAGwAbwB1AHIAIABMAEMARABMAEMARAAgAGMAbwB1AGwAZQB1AHIAVwBhAHIAbgBhACAATABDAEQJMAkCCRcJQAkoACAATABDAEQATABDAEQAIA4qDjUATABDAEQAIABlAG4AIABjAG8AbABvAHIARgBhAHIAYgAtAEwAQwBEAEMAbwBsAG8AcgAgAEwAQwBEAEwAQwBEACAAQwBvAGwAbwByAGkAZABvAEsAbwBsAG8AcgAgAEwAQwBEA4gDswPHA8EDyQO8A7cAIAO/A7gDzAO9A7cAIABMAEMARABGAOQAcgBnAC0ATABDAEQAUgBlAG4AawBsAGkAIABMAEMARABMAEMARAAgAGEAIABjAG8AcgBlAHMwqzDpMPwATABDAER0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBJbmMuLCAyMDIyAABYWVogAAAAAAAA81EAAQAAAAEWzFhZWiAAAAAAAACD3wAAPb////+7WFlaIAAAAAAAAEq/AACxNwAACrlYWVogAAAAAAAAKDgAABELAADIuWN1cnYAAAAAAAAEAAAAAAUACgAPABQAGQAeACMAKAAtADIANgA7AEAARQBKAE8AVABZAF4AYwBoAG0AcgB3AHwAgQCGAIsAkACVAJoAnwCjAKgArQCyALcAvADBAMYAywDQANUA2wDgAOUA6wDwAPYA+wEBAQcBDQETARkBHwElASsBMgE4AT4BRQFMAVIBWQFgAWcBbgF1AXwBgwGLAZIBmgGhAakBsQG5AcEByQHRAdkB4QHpAfIB+gIDAgwC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` chart = `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` ) func main() { app := tview.NewApplication() image := tview.NewImage() b, _ := base64.StdEncoding.DecodeString(beach) photo, _ := jpeg.Decode(bytes.NewReader(b)) b, _ = base64.StdEncoding.DecodeString(chart) graphics, _ := png.Decode(bytes.NewReader(b)) image.SetImage(photo) imgType := tview.NewList(). ShowSecondaryText(false). AddItem("Photo", "", 0, func() { image.SetImage(photo) }). AddItem("Graphics", "", 0, func() { image.SetImage(graphics) }) imgType.SetTitle("Image Type").SetBorder(true) colors := tview.NewList(). ShowSecondaryText(false). AddItem("2 colors", "", 0, func() { image.SetColors(2) }). AddItem("8 colors", "", 0, func() { image.SetColors(8) }). AddItem("256 colors", "", 0, func() { image.SetColors(256) }). AddItem("True-color", "", 0, func() { image.SetColors(tview.TrueColor) }) colors.SetTitle("Colors").SetBorder(true) for i, c := range []int{2, 8, 256, tview.TrueColor} { if c == image.GetColors() { colors.SetCurrentItem(i) break } } dithering := tview.NewList(). ShowSecondaryText(false). AddItem("None", "", 0, func() { image.SetDithering(tview.DitheringNone) }). AddItem("Floyd-Steinberg", "", 0, func() { image.SetDithering(tview.DitheringFloydSteinberg) }). SetCurrentItem(1) dithering.SetTitle("Dithering").SetBorder(true) selections := []*tview.Box{imgType.Box, colors.Box, dithering.Box} for i, box := range selections { (func(index int) { box.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { switch event.Key() { case tcell.KeyTab: app.SetFocus(selections[(index+1)%len(selections)]) return nil case tcell.KeyBacktab: app.SetFocus(selections[(index+len(selections)-1)%len(selections)]) return nil } return event }) })(i) } grid := tview.NewGrid(). SetBorders(false). SetColumns(18, -1). SetRows(4, 6, 4, -1). AddItem(imgType, 0, 0, 1, 1, 0, 0, true). AddItem(colors, 1, 0, 1, 1, 0, 0, false). AddItem(dithering, 2, 0, 1, 1, 0, 0, false). AddItem(image, 0, 1, 4, 1, 0, 0, false) if err := app.SetRoot(grid, true).EnableMouse(true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/image/screenshot.jpg000066400000000000000000001325421457770046000262570ustar00rootroot00000000000000JFIFExifMM*JR(iZASCIIScreenshot !http://ns.adobe.com/xap/1.0/ 8Photoshop 3.08BIM8BIM%ُ B~ICC_PROFILEapplmntrRGB XYZ   acspAPPLAPPL-appldescPbdscmcprtP#wtpttrXYZgXYZbXYZrTRC aarg vcgt0ndin >mmod`(vcgp8bTRC gTRC aabg aagg descDisplaymluc& hrHRkoKR nbNOid huHUcsCZ0daDKFnlNLbfiFIxitITesESroROfrCAarukUAheILzhTW $viVN.skSK;L>@>289 LCD LCD _irLCDLCD MuFarebn LCD&25B=>9 -48A?;59Colour LCDLCD couleurWarna LCD 0   @ ( LCDLCD *5LCD en colorFarb-LCDColor LCDLCD ColoridoKolor LCD  LCDFrg-LCDRenkli LCDLCD a cores000LCDtextCopyright Apple Inc., 2022XYZ QXYZ =XYZ J7 XYZ (8 ȹcurv #(-26;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Kmparaff Y [vcgtndin6QC&f\P T9333333mmodRbmbvcgpffffff334334334" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzC  C  ?o MSokz :FK)]!FֵI|/'&|#X?MaSN;Cm-+4af@Ω+FFk3/âAlL`ӭ8XablqH֋Vׇݼ\tEiNp¥RP<k7]IrebHR(%cʅgyi] Oy=+OܴP dKGLcy2}3_4[wt ^Kf'`xI1L >7c˩j . "k (b0y-8U$ Ho&x[B}6a&Q}k63+s4R9yU0+~>|oQM*-gYC2#;FfD$Pq;{Gsf%>h럃_ %4 'c%Y-gRm2ɵLċ8ȵ~մ Z\ʲBOYwH~K #[ ^$择:=Ao7JGmQwr@ 7F8zurRyd&le AQ`" }-/c^XM㵷k{4 YfQ_1B@.S/(V!NY$FRYI9$(~-8~]ShZZΟY};yrq5Eqy#E}H53ieEu8`E|_I\^/c8?dUA]Lg,<# ˲$w4_MTm бYt5:U1 E8&k](RNNsJTv93~_-ޝ`gy_>-/,-X&ThF##zݧ7ĊgqAؙWq߽uPR (:ڗ,i 1mnpzk|%kb4Rp *}V>%W VɆ\sW&ҵW ,aq޾>IT>tcY֏1,V΍8W;62ǧָd]RdCH?©X?uڳBV^bG jM};JJAW4*BKZA~WZcb3R8c FZm4b #Uճ?Y8c^ExB[)5ЋԷ &? X kTI0k˩ꎸ-ƏgH:$ H^[sWd8lWnFɳ'SG+8?m*kve#i`}F2ǜ??­&ߤ .5k)l.{lv)>+Ǥ?œv8?tOyhF F6&4 y'WaSJ6im`RUm6B Q]֜13Q&R7 #)\mG\B^% c5حLpO2*4- )%WxW,%#9>skᶽq<<GM;@b?]kx:n!hޒT1=ky$ecѼ=&P_M>hcgn G!#r2̲gaa~ ?G}?Qı<ݪypG2S!Y# ȥXv^axkֵz9{WmOg8p1Ҳ.YWhfmЂxO.2 1)F>% Bk@,0 ׄj7N8{fׄ-G;}+YOzdkgF`\\"1FKt85,\}5 :ևRaKЃO^ҘU+цIs@)i %qZҳ >5oYF.nm浊U=k96<~5FU)n1Sv:%^0ԩ%1*C$TmCtcY͜c[ 8kK)L)gT%IƫnwE"( ZKUxPLypN/0/jo`ctvP=}Yt֏8ž؆p4 TMߎjX#b2k~A8d#&!VreӡW'C\ndKUa0G5a+I! \˩rI&LuD';u2?ٯ,K"p?ݱ}aւ=I=+Ц R3 # Q)P`~U[^:M a8ܥ(m'׈n?5쓜^m C+>;ثxm34sڡ_]0A% *qk)!ZT+[y52:{W9"WE+@K1ԞU݌NduQ^<5V, #ޭ]W?ߍSe JۨvVlmR+vnqqױM{f2{nȧ}Uz\_WIq l.M${M=ύK$Ř埰/Lb3{kZ "mZ:cpTF='_vj0W ׺kgE⥷TcDym6ֳ/Q '$M|qôW6GO Ϡ*ek5>yNbLI7%63gsx~m^Ri2k({Yة/3TmʖONeFoVdv|qsZf0iGTeI5g>ݦ܈/ڥT8Fk:b.]r1[(Rd VqLɁ^V+;bywf&GOʩ`Z]'pjOlV_8+ztqqmi&%$ 犺K(T\,݉01*RqwhS/5F{)`:Os۸'~OO ɩ#S-#,u[rA==իܚ򈮄g'=+^"z 3ҪDR`]"h°}L{vwL ~)v?ajdWWIcgp&9296dp9yWF[k5g( Sqf~"0Q]M9cП],'ðo7y.uYp}>5p1We˷pݞxvIrl#\梴ґzWeL3qJNh\Gy10 רXkRh<<̑QV[7n7uktn##[xs_Vh?g}U+~*p0 ޵7{oByT|Cn:ӝsv-ik$M.Ưe-5ĉq3Fު;!RT5#xC5I~ +=b Υe 8PZ5Ҽ;)u9]iCݝO 3Xޯk-Ν]̰Okv%3Z-7Ig˪w9ӤG5^}L k9ұck0ϥoi^$H=k{ğ |Gm4.$(\~ E5vy/-}Q$%]؏zA['?J4}v>| t3oq51rIܽkkwI]T4fSӷONjڢdsS`dlcU\QI_ZG(LpJWE/|ֶ~~$$zū.Ijm?=-#xWli_&v9U[xn Z&fڜjwsGy]R1ҶGy2Zht^b6>n>D9rk^Z]g6SxVJI#XyRBZEp[@a@ u,9'Qr3 +c7)lqJ?K.mXw; q&Uۍ)ykԋcF.B)چjnޕ˫ZBśq=+̮5PNSYskV~1ߟ+_d'>ǩ+G#jYkΠ>G=yǧʑQiNɍU D˒'R\$?QHW:n$<>o~PfSkDM7VMƢ& YwsF[YxiXӧsgj0cڼNRB2.̧kh6빙m_.}Ƽ@ʻe"?-#w'úvMh%"t-NåjN̠ ѩ9Ol}Sšޛ:wjt|+GlzԶ+4I@YNZiwx"P(dei @Pp U]hF,gBX]ً#FZ=rA:%tZW,m&L;yln*/SI~ig:g?Yu\\ʫ$k;+5;[a>&Omzj-j0Pw rqU,Úd*K22PXϒ]<h~o|7(<|W0' z*%m2$s\TZ2ɖ94=XƱksZɺ7 /T.*9+U՘r-u&0iR%X捲# }~5j·Q\6W+ʊɭUv>n/xP ,Fʟ^7~'@A䃻>xKT[P)XAնŢCc hPuU8 =⪟^yi-2a™ăuE5K;HI~lr;fqCU!Gl/=z\A#K=le{xs^ Y&eR\#_:j*UOT\n (~dH7grOFx#:ֶ8i~=M|iqK dg# }NUmM*mxޤr}tRij-N^DUP>ӿ*Fq?)/<7ieFnץrH`⾪b'lh'Ulx^y'vB\Qw$H0]fW b+' {=esckf&6Gd u ^l9pGQsv5oK~ڝ(q#=j^c]<؜wvl0QqF.w7iAAfJ syةzyrB4g>Y%mi. mJhI*J[̺n|;/o3n8]ǃHdH#R.Fx4tcp+&yn^ը$d;\c"V$*4)E$2ީ5܇+th{p=s*5h+[cNe",1ӿz&mZh",g85- #[6KpN1 Y75 Y 88u0ϨS·f>$cc".:L$2 g?5A5@6@ۍFیc )XoCՔ|U J(#'0˳ׯq]Af{\W>'r*ž!}=x?jE%)cIpۙw9E?#x$I$xvzǽ|| ҤFCV;XŔeEA9?I _]7Z"PCBC=#~Fޓg^y6˫٭흾z}bY )V@)k$t5Yaּ)yXEj~TqmqܨbzwWǞ# F l音tï؍J߈ƌ.}?ѸiL&/V cPP4g~6@C0MygxKC׼I&{p^nq縱KbHc]ѸX3 Pß؊E /BxRf _rt_5|G&%[M0hHebAXh9C?E?kᔂۭ| _]7Z"Q _]7Z"P~_x¾ GBR֕-Kuk%JV6с95ž ? i`mz:k>&:isaY;Ugգ9H[Nkѿd˧T3,QEr2x02?άT--+_Y3J=I~#j@o&&v12ma$~IQ7uW34ڷΦZ"p&9?_֥դ 9ںiV(sZto6j!671޼gJu ;p1X֯iv!|t+DZz޵l jڰf^4ۓzƻv@rHֿgV~3͜ޗZ$|/\e秭d=Fp>zfOCԬ|B7j㍠-|GlbE(1<—,?1uzenıy8Z\x]0y\κo]9G<SXrN:#Nhh1P rlr`Ð={mBn8sWi~9Boy8ȮZI1?ְZwe=AC\r$ُgZRxcK-ndF |JR;[j;64<7e{nw%_G!ؑyؾA6w%G}듟lbodIzxJIz0#?hudZoYau$q.%s1׺ Ynּ>).F0?\]^"ǖOXZ߁Э ܬpLz]a/_9>CyE^P@9>;g\T@knP[8#OBv4B ʷ-2}NGˏ¢?Z]kQbH T>NJ;{4F{EuC;q::NJg,lHȨ=rk @m]Em&UVg^:NSPI]&.C`ۥa'5y(#jxHVtRTbm3i2։Χ)=ۼ7dk 8gyQ-?ֆIpF!HnZWKC/t 9-t,Fr:ZL Ϡ_Kiw,[$=.}N eJ#iRGi֮*P35Mm%T3һ)kxULxP5Eêr[2i#B=Oa'A ?F5L͟6> i#'%.Url)y_ ߋ }R .c[@KCrAȮ[_Mޑ⹼?k0$"Ma{oM4FHh.UL@d' ~xV=4" >ڑ$hNkT_W_[Zۦ42aufV2FU$#y p zZմU^keeumqs$QIqđBbAiB|6I:y͜[쬜J`濭 ?GAhב-5tf$D[i\7A 74'2h7֖vȷ7:Ρ S-ʈc-p2V?5O'','%׮H'#Qֵ]Zi.5+gy[{361$2rqJu'q~ Z`kZxƮ2eR 7Re*QʐK m Xd?5Ђ8۳v\s=;b|\|+x/[%MQDQ1b+92Q Tɯl4-GZk]DQu=MVw*n$'% Ew&NK ou-;j7$^uYİI l?#^_I\:RGMEOzeHFP'<$/x"RdDL@ۓN,ng~2m%̡Xׅ.}JUkr{qp="~\ǩj2Om+n6$h,x)-鞝k*)n*Qn$L=Ev0Co.p<fU'VђTE m$c=4?P0^׮RJ q;ˑyw]u^!5mT80<Aך-o,zV*nPld)=+Z4o=6xV=ާּY.ag @$yUIV,/ʝ* H ]T5[DlXa.ޥ'[eG w"eqs=5,axd]tpG ^(aٛfӴmdA%7cO|O6j +f$iݸ^[9=߾_ͮY=IvCWhD\~S5OϦxy%$9TIF܍>"#,Y`}k^Ծ6m.ӹs??g ZSMv \SpsڹY|%'N/WmK65 1J 5qq'5]IuiL q+wq8fJ߶wO-%OR=k~Wִ멵9E !1k;}ef tYĉ+y`~e6Pu;W؜DTv1HKB߈odl*F9z}-rK3a'8J͵ |קiڌ$*n!1jy6E:W/O"EN/5v5vدD1P_PXsSNJ\ڳȨﭴs,,`#F<'d^Dg֋2ꁤvT^_Yʻd8χ*";u `osvx(~k.MUcΈqg5Ҷȩ/*s֮ T{ 3Ut%b.<ໝAkLvʩäX3To4[$L v9;?1g@\q\^[ǧId(xlfj+#wjӷˌ jג1؇+?JWI/q31WðѮ'8>]'r+߽ҹsJ4:g?|<(*qlw4Q3vWkH`Pϵ};Ku|I]ٷZkE^~ϵ>IAljwv.R Mǩ3[_&wQ=@SV/FN$QF:ԲP rV&t;nhPkqX^hr-uvUURB_\?;}?wǨ(?u.w|M,4 [kn7:5En #qc+^,c!$&dU$v ~$AG&wQ=@W?P^n}p6zځ˷sY{юRx?fdO~팀9)_&wQ=G.?>PK~kaj]i1_혒؂rry~}~EGK94{yf#hdP%Qd?.?>Q guuе xS Y-)n" T>~Tr 9#y/4[;zid$+үyn<.TLJŽ3V7s_FxQ]aL9zq][gY+0>>xD{qW'FL;#oN3WyiڒCWgjk)<:b?5^jY-٦)$fݷ*z}k?CHAh]kKJx@mS;J⥎B\:0?-=Ѕb'c{Wh6~Jg_5fkjV/VUټIs?q m4kIU΋ඛuR&lnj#gֽ2%i'p?s-m%| 㒣TshB-8y9JNK~g3LCޑ:,*+dH^xډ.m@?F秡OK:e*28WGQ^IHe (K~k˳n])хMO~!ihەpb-}^-aEv$n;{]B ђ 0q_ ]@7=^ܱ?^+ݥHVܤ|9 =_>2x+X]}ci)lcx̜e}qVu=2 qϯ|Һ>l^g$޼tM?t7.v0H^cs/ܩ;.t4=WP b& ~_K^E s.4`sڼKV}s{UVmr,4:*=gÞ(L{>!KW#1~Waw(_-bxWN{nzђ]#$++83qeoc?ucT+x$Bոwa m`G_eɇ7s_YzkO1~qZ6uM7 s93GT|M-:3m|1]oݏ4/ glqeFz.kgIV5P1߭r:Ԥۿh^zuX~S3hO)>qs. y;OlRiR}nWۿ9܋ wu#Aww 2IoMbRuUcv9UGnѾvIQ\+9Qa}g9Rh(&wǞV2#_:cVv%H<ֽ^-\7$yoDgCz%*qǛQ.?4]fŠe_'ʔ!;)Ebq; O.rI[-'E_.kcI#3@ڽOR4%`m$rs$G^cJRܖ{;t:8uWTovX:1P᳴g[^>,m!@fEd sׂjW+%;=GoJ&";gSV);#=mG-U ? xjM[v+:_O'SEyo5n ce&gs^ʔj-w_ M-ip2rAּž %F5v84!lU)ZD+MoLm`A ol~χK+M*;rp: xe}R䫄uݱ]ڐMxY#_0\ꮧg n/cNq]Ekk|Zfm <*C$+:ιk5Lvc~֧{:mVg|`GZ.*f)#}[𵷙. gu= vdIUKccZY͂x*VWDA(I8W^[{c(&?/9\ `ױRu+{v=\+^G 4}cȭ*`$=H5W5cA'ͼ `z ~jR(\;RGe{ -Y2"㟕BxxF˶VκYZNZUL׏}g=Us^Ijꤐ2wA_w[ukuG xx(%(d<?8#Y\ܱINWWE[v&VU6zGӟ3G&ۻpIkk6w-eu=Oz屆06 J |jng,RU"8sys}[Wn 1~3gj S⟇'{|ŁMQ;>$,MF{=.d6I*z~7?uߠ"²:Hr+Njv*pwNGa ,T:ƙ2W_U{^tJxԄ{ʠ=jٰ\_lhU0lVR;Gҩ袊((((+ӾC{h']R^3}+k~\E c솹R9y1]|ru  wsT I盳VQ{:ݲ2g8Cm޼ q`%Bo,T\>b8kˌ)DZH$henG:G"ҭr,}C57"id緹roE4UK dk Uڑ).|Y!Upluأ2ٓ]~5/ Z4pY~ :q$jְz}ѹ0#plpk͕5 '.hY:V{=E@sprGaK,w <ֽ^:_9RҒoLۭdeEcz{d'q}. gšMma䃀yA==+oF&0H۟åj+-j`)rq3\/gӢ#Ia2>י6J*Oh֒$"k_Gu(Z1!V8?tŹTwpp 8+Mm..' qj.Ik}x]gJdŠ!zJmD>W=3ֱm<|VJi{!rVc4VYCpWѾiw< ^k\(Isۺ> {qӽrj[T]*wЧ ^C:Zl&2LET8 d{s^ֶ (` \pǥq:ڼ}qat5ҬOm,=yWhxe*9zKdžzK|_qsҽM5ewu:mFD Qמ\ʫn4ʹb>xyzVy4K娓:y 3 sKg<1#Enf NcSv֩cinUxjƲѵ},salcAOK]a71w5qBa1Y>!Xh՘+ nI-Έ$2-l|XڄB쥆@^$\˧1Hv^c^!~x'f (u'l^ uhˇ.9q{f#mkJI;#꘿gKfM&T)0 xo>|Fе{V:=5WMC23\Nkm~گ+mC ۤnAFW#MQ7vq«rt\6qi7NFϋQGM#GY#c]X1_tw(7t7_ GsH_ˌ$YAǨUuЮ$h6eI$:G1jP~SUȻ8Kp\tOҊRlgkߌeV.~\I=Ih-gٳrO\sU> r.o_CJ??cӴef84IV?3{wO( [yjO7Ö^07qH%ҟ}BC=(&\cW"[@|!y *#gO#GÖo[ ԴY~/kq763 ^y_ s#Նu  ~瑏sZ+{׹ŭFYF88{W;rF8z: MuyIjFfVHȬij``rkڢ^œ`yҰH#iSi9Q$A*-?>%)NՎWc誤P"}Jg3j^92ӵq{r4KJԴˣk[Mo()4o 9W5Ihe'J}ڙrM,4@{.o4V ޠ>Do25ϩ# }=a 1<;q)F;g袊((((++Fuόby7DxXy߻^U66i$Kz#ż6n?ڳ]6#%qVg/q$ סx[ǞijJCD4B'Ϛ3-k%J[Xe> ^h%&M?+p3T=K6p,zw3|=5yO4) |e*Z0{/'o_ u_<6Q:!!A<{E/K{ GѬ rqӥ|⏃~+6ѝ7ɺc!%Um<ҿKg_iN[𜋌EFTc ޾{QPdlz\4'Qt $y\ mmj-6p{)HRYqһ [gwoaj#6׍<* -\y-8c3Ou3J\w홴hwnq\56n1|6>Dkv¤Hps~ 񦳡y4QJb1 9#'#e4Thi DJO'&p R`s׏jrGr"7sg]wa{Ir|?M?a(˚/ARO?,ao uV sb4bD!yDw8U/ "HRo㎤:S̑k<4Ð ~l^VTSbǝ!+KᏌIxP6NZτ:~<)xpYRzPԇ\xQ[ ІvbaC:V.Ԉ_?K=V >0߂V'k>&K 9.rsU=bjgF'y+^HnLOoƼm^PGIT"vI/ Sޱ ?Z?g|_jLC9'5?jkRR'$bq>|)89Ҩ]WZa'{^%ps-OO&߷0c Ӕ}%U?t/[:ڟtdͫU B[&v# ұ7F6/r,H+<|ERh 9zdӺ*|y }>XhI $~ tv$j0W?(=GֻXnּ'i m!>ȭ2p1Z{wVK'>,lQ~~\ ]ekY1)yT(uwrH𖋡"RYUaV\zW.$«Oc >Ne*cGTJtGoį7>&ZoاpK$#$^\<'#}ʙo^dڽ;}iEwjpD2]wH1ݯ(giq CX9j-<-&Q7'>X V t$ikwS#6dێ{SJ u;?[c^] \ dֹKIFU$0=+׮n %]$t?슙%w$kp|>acx[͘gd_,ew>l]E@'?.qj|C[[:ֺ<5Ԧ/$o#;W2)/L63Mx$w.s<&]kSi.9Dp8-} 7\Pi l>nfm@W)Z,Q4F~ t{ӫh`7nB-N{uYXDd`R2y?)kJjdbpFA|L]c&Ǻo5;]j% s U(@zω1k{w(<ӞxbMֲX%w2H 41NN+o)p}BM: N7aϦkx3IEXsEY3OQËOwחsxsd(H8&Og5^MJ=z5H$FCyx$5wgنV; [ =1_%MLvֳ]N|ՒU!Pr3̭Z[nZ8e}'LWt[{Rn<090sηW=n>LrDD[T͚G;G[a6ă/ɒz{|Mo·^62Fnv>:? Vm3^FTBU9$gc|ْ[[դXg]Vg,ޤ ~^}͘X\6 IGC^iZy[wυuOJ.^Gž%|ed328;(t+4٘.Yi Qd뿆rje4<l“U A><}BkkkiQ2SJڳbW;K;mV&irqGQ=go  "X}wy;L8kOu6WRO2!JpN:{W6iwPH!W+n >CdW{+j5KI.d.Oo)-"F9<+-S<*%6\bN#"@>hrxWXJ)[Epwό]}l2xk.oϖM+Q> bB&6 F ݜxaWm61G@-}Ɲ*x]:Nݒ6m z%Ƈ=5px{"v?%PJ # !u4ٸv|x^|FvN'Tq+6R2l uz#zkׯOjv#u#pkWZM7 Fv܇,B#=Aݟ9F1]4CKS)m$&U8/7KP|mcw/nj%o,E9ـ0AV$'N1 0T*{Fy,~,_i6{ Ulewc?$Y4Kܛ7_эƛuD'XsN6>08#˸1&'%O ݟ5m +r$_ֶ|5%dTᕗ=}@~ |ηRiHv 3Gz _SU ncxdFQH>$m)}4VM2>0ouZ@ &l8\D2\IܕMr>֚ͼr*YJ|ZCx,s]Ю|.$S,Lm +5)ZU%ܾxíءdAz^>9e2)sg|+J4=leD dBB3w^C1p%.*s8=e-~\SWOVMN͏8ffHA\n6LFi Q^+ί.-F;zS|WkZ'm3ySD%%SqZ8Th &NNqۊ]:#,w+ `A _|Jn5]vѰy fh?eᛡu#+I]N׹o<1in% q_>EٖٓP9<ޝ*\C?O[~'0.|;X#<,tZu'Ġ;ü6=-jVSR˩.6߱τR'/%9qⶡa[ۑ7_}=bh 4:SVgx[[wqߎ*Qiޙ#TZd1Ft1V *qdR%TLM}?0L{U8eX"m Z"dX$i6 } B&ߋtǑ4E#fv#,Gt)m@kx R!,R}.#rw|v2:oxK4MQktm~!%@5m8H:ZU*%Ȑ7!{q~iLWmtFd d֓Yi ʕ#"#7F-R~ x5xRl?j]ᧉu&+$]9pmZ朱G&;ZZ֒Iyq!dv8ʾw_t,4(C}ùŴ}T. ɬdO$SGƫ֢]. W=h +P\:|b(sxA*O'~i xtw|mm_G\+2>1ֽX폧5,%k-$iÕYs:0Rv>OeYGJVr?ZE=k^TI=ٵMc> u\ZE/*ǥ~\VXxu]Eس* ?袊((((+'6gzEi*5Jȁ#_W?NkksHն90rGH=43J_?];\B <$ݲ8.OS]4HyIt$ 'O:Pry?G4}XE~2g?#cj%FCPc.֋=l!&1H\Wzߋ@v"mj.[ݺ +KQp3ii?&ݠVX>6yޛPx7aa|AtO{Z#t7Q9$dcKeدEYO i*CDX𪣠S:FAϧA4x}CT+0b?r:>tH| ~_įi1Ǐ\xɟ.6G5ƥnS\  W~ 4oe9Ty=zWO wou4M Lea`8#q^2V8;lbqtu+7pA#UYR4Uek_7rW9O*m;GzhPd9$u,ԒI<|-V><}g KLG?wϭtWc.א~y8'j\WbV% k^}B?ƿ;V:x=yWb*~'~ېH26lp鏓F_+ynSfdpLc" o^嘘x=3/TOhwAӹ9 | Z.;ƲIlgܒڞ4lcKƳo?lBa2 vĹ\gҾ38iX *r|8*ߵř)mǬ|( Ҫ GҍV|eaV ߈ڄqs_e9cęf4!Tq+jC'pC[ u_oG|tn!mWQ}Ҡ9X r)P,YHkO_*=qCRXL=C_Xxeɼ8?ݻqsU:pEIZ-}Ө Uu;dNdIikIդĖMmȷNr1~um&+[:33'Q^KFz2:KU?J5[(-#HT Ld޿#|UM0unˎ0[1ߐNkԴ(3E1wF;b=KM]DIv2q=Ap/V&rO6V3*]zװ?~ꪋkAFgqb@ Td 4isoRǦ8V3F 9=3HKsxg?g-qY;G N-hxMl*#_jLJ5n g@.u].T ++ksjZ--ԆߞթSGЏ$J~R3TbD[йƒ^tgg}S0VyF:Aoך.=0A 9sU+}?*X[PG[Q#2R;ٹ# =MU즖FdPW y_ ۑ=1A=>W ֿ0v/Z#u_q?%@?*^c'nk {g袊((((+ 8s]GDW},4sHeXc[m@cs?FiGGwi4>Y}x7foL|_xvT3: uyƩn~_!g4y/z\A{;dbW9#v^_|{-Z]w)@=׃ >=<%'Q:qH  #W] TᤎzTG2cq Tן(Sz+qha6k*KG(Dc\[L+e=* ?ZQǪ+w )|#W1;YWPe5Q[K=k^fxmFBFT⼇Vg*-o:I#. .?dȧwjPzkn\^{|-Q 6 *AE`UC7·/&ϕL(`2PgwMˌt]1jDzZo9>Q\d]I㚇Y iPy t>[ s3~=6;m[M86 FP5@@ ~z01gԵմ{V\ !r pAؽ{}MhυKf)q^|;05r+ ݘ' +8K"ϑ<+~ 7 ܅ |'ݳ8\$7v{澍kYZP"UF` =r6GV~&±YI|?5wskq:';1]pHqZ^bv~h_}J md@fH#[y' z>1|>|]m;R6,sH\@ϥ~"XymIG$Һև [,D2p8t#кv.X#= KSOer"%NkOz}e+eT|g}r,5 Y<<p3ubgoc.ff8#0mhв3~%Nm0uF2@;|3b*>:\۪jm-&>ӗCfą=?/zmBpbe!O_z%?妡5qo$@*IW wlfqȯ-.[MwBO| V[qBN6xǞr|g{z0B u&8Wn9Bu$ /K2t%i+(r0?Zo s/Rڤt=tX HS5~~-mco|5EXo2`A`*eFn9'_iێ+*Ӿc 6$xbI;?؛Ú>k"u{k:R#$pxa@þEڦO;`% bsЧ>yχEӵݪHg#DTcnЌ׶;]aΘqlZ~u>Hm.n%3Iql&TGV'7OoP[*\qYDW(+RK:.7u~ xXeJ>FyڸO:}tp@p;nZ_Ƴo@Nxфs-y>ʹʂ3*ij[ź /uGՁ{+Kdk}2kU`'@~oJb`f9@Nsy+r$r1p =knWԴoX a2Gguvo$Nt;y!?z #W|:E4KuWv~EJWd@# IQ:J*-o^ZO,g $scp;WCxw@ЙΉcodҀȉ"-8ݴ 'gދ+$rp:]:ݓZnis͵vC m̱2x 8sZ ]̐M#*.潖Sf@tV6m O6ȩ$R)!FrCN}+hI #x2O@ɓf6਷'v[`G\Ji:kiG,Xc}+_(cy[H@̺$x袊((((+ KSh캏i/Q8F?Er?FiGG*jMg9ۋ U];k̾` '>͋}W+Q\V60yrF=Tt>W^WT3=0Hi5xlm#< ,︅x{W*%\W7ixfw\̤AsT)ﭭno ȏke!r$.mW;^ȡB>R? -u=t\JrsxGVCr"$ecJrq_^4)ZBOd$}鴍"K}VD5(ͺam,J}5J>4Oa賾xϭ}_⯃ZvB8pѡFK }3ҼF)׷zZ2&r[] ieQ\Ǒ+bd2@ŜJ\ moyȲG Ш?*ZD׺e܇x#; 3Oogep8KX~iH=;_]/1}hZ$Uds*N15%ƛFH(kPh3.ݒL ү vqNp0x:zxjy <:TtԋAT!׬ַVLn>\zǿwV-^c·2ϙ "FmdBq׀ -s~jCO+mcu;[B-ЏA %mb(ȪMfL/gJG -vF !ͣBgw9b!@KN>ؼYA\ ^ku LRvM ݋M1zb\궺lIfdŤwo5h83ֺ]L2G{|OZ@4l¹ΗzSdq;x^zdֺ:*kіyV<ÿ5;UVI!UgEHϽm%p; rg"h42?L'+Gu?nƟgV O?L5ksYi-wr@jKH]x6rmg^_gsE[| w\xO}/?OaҀ9D?>T'*O])OJDŽAUъJR'ǿ>Ut;8|'Q= K܍N`ѹC #|K?3P^~2\lX㟲Z_/_ryw>O^-??$l%\Gv-kn'YWvаԿ}jJW 0xE5> ]ƾf$?ƾN&j_Ⱦ}_6C#%~&b\U=qˉsӿJc"\(SOH9=E{,lY5" gyc%#j?!b q5x ~O8^5?eȋ-) ϕ{ޙW eA}xkDkP/)iKf}MFD$`}Ԓ~؟{&,|ʟpS?i"~]ϣ?h(H?ij6C#%ީi}V/v}u]3 Yfb h/X K>^ QZ?Ⱦ/i.vg+&8Ls.v}s u.DC^ܬ돿M=5R]ϡko9/$F /{EWuDF>#lD~kx~T֛RE!Iw=گV{$mdlkg?xj_Ⱦ]ϦG߳ZqBOjh1ČqNfVkMxjW܃KEk6+dlk)?k/ ]Y|B5*xS/_ryw>hK75~'⮅k Ή%Tt b1sYtK_ux#WJ88}rj͟golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/inputfield/000077500000000000000000000000001457770046000244525ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/inputfield/README.md000066400000000000000000000000361457770046000257300ustar00rootroot00000000000000![Screenshot](screenshot.png) golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/inputfield/autocomplete/000077500000000000000000000000001457770046000271535ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/inputfield/autocomplete/main.go000066400000000000000000000166221457770046000304350ustar00rootroot00000000000000package main import ( "strings" "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) // 1,000 most common English words. const wordList = "ability,able,about,above,accept,according,account,across,act,action,activity,actually,add,address,administration,admit,adult,affect,after,again,against,age,agency,agent,ago,agree,agreement,ahead,air,all,allow,almost,alone,along,already,also,although,always,American,among,amount,analysis,and,animal,another,answer,any,anyone,anything,appear,apply,approach,area,argue,arm,around,arrive,art,article,artist,as,ask,assume,at,attack,attention,attorney,audience,author,authority,available,avoid,away,baby,back,bad,bag,ball,bank,bar,base,be,beat,beautiful,because,become,bed,before,begin,behavior,behind,believe,benefit,best,better,between,beyond,big,bill,billion,bit,black,blood,blue,board,body,book,born,both,box,boy,break,bring,brother,budget,build,building,business,but,buy,by,call,camera,campaign,can,cancer,candidate,capital,car,card,care,career,carry,case,catch,cause,cell,center,central,century,certain,certainly,chair,challenge,chance,change,character,charge,check,child,choice,choose,church,citizen,city,civil,claim,class,clear,clearly,close,coach,cold,collection,college,color,come,commercial,common,community,company,compare,computer,concern,condition,conference,Congress,consider,consumer,contain,continue,control,cost,could,country,couple,course,court,cover,create,crime,cultural,culture,cup,current,customer,cut,dark,data,daughter,day,dead,deal,death,debate,decade,decide,decision,deep,defense,degree,Democrat,democratic,describe,design,despite,detail,determine,develop,development,die,difference,different,difficult,dinner,direction,director,discover,discuss,discussion,disease,do,doctor,dog,door,down,draw,dream,drive,drop,drug,during,each,early,east,easy,eat,economic,economy,edge,education,effect,effort,eight,either,election,else,employee,end,energy,enjoy,enough,enter,entire,environment,environmental,especially,establish,even,evening,event,ever,every,everybody,everyone,everything,evidence,exactly,example,executive,exist,expect,experience,expert,explain,eye,face,fact,factor,fail,fall,family,far,fast,father,fear,federal,feel,feeling,few,field,fight,figure,fill,film,final,finally,financial,find,fine,finger,finish,fire,firm,first,fish,five,floor,fly,focus,follow,food,foot,for,force,foreign,forget,form,former,forward,four,free,friend,from,front,full,fund,future,game,garden,gas,general,generation,get,girl,give,glass,go,goal,good,government,great,green,ground,group,grow,growth,guess,gun,guy,hair,half,hand,hang,happen,happy,hard,have,he,head,health,hear,heart,heat,heavy,help,her,here,herself,high,him,himself,his,history,hit,hold,home,hope,hospital,hot,hotel,hour,house,how,however,huge,human,hundred,husband,idea,identify,if,image,imagine,impact,important,improve,in,include,including,increase,indeed,indicate,individual,industry,information,inside,instead,institution,interest,interesting,international,interview,into,investment,involve,issue,it,item,its,itself,job,join,just,keep,key,kid,kill,kind,kitchen,know,knowledge,land,language,large,last,late,later,laugh,law,lawyer,lay,lead,leader,learn,least,leave,left,leg,legal,less,let,letter,level,lie,life,light,like,likely,line,list,listen,little,live,local,long,look,lose,loss,lot,love,low,machine,magazine,main,maintain,major,majority,make,man,manage,management,manager,many,market,marriage,material,matter,may,maybe,me,mean,measure,media,medical,meet,meeting,member,memory,mention,message,method,middle,might,military,million,mind,minute,miss,mission,model,modern,moment,money,month,more,morning,most,mother,mouth,move,movement,movie,Mr,Mrs,much,music,must,my,myself,n't,name,nation,national,natural,nature,near,nearly,necessary,need,network,never,new,news,newspaper,next,nice,night,no,none,nor,north,not,note,nothing,notice,now,number,occur,of,off,offer,office,officer,official,often,oh,oil,ok,old,on,once,one,only,onto,open,operation,opportunity,option,or,order,organization,other,others,our,out,outside,over,own,owner,page,pain,painting,paper,parent,part,participant,particular,particularly,partner,party,pass,past,patient,pattern,pay,peace,people,per,perform,performance,perhaps,period,person,personal,phone,physical,pick,picture,piece,place,plan,plant,play,player,PM,point,police,policy,political,politics,poor,popular,population,position,positive,possible,power,practice,prepare,present,president,pressure,pretty,prevent,price,private,probably,problem,process,produce,product,production,professional,professor,program,project,property,protect,prove,provide,public,pull,purpose,push,put,quality,question,quickly,quite,race,radio,raise,range,rate,rather,reach,read,ready,real,reality,realize,really,reason,receive,recent,recently,recognize,record,red,reduce,reflect,region,relate,relationship,religious,remain,remember,remove,report,represent,Republican,require,research,resource,respond,response,responsibility,rest,result,return,reveal,rich,right,rise,risk,road,rock,role,room,rule,run,safe,same,save,say,scene,school,science,scientist,score,sea,season,seat,second,section,security,see,seek,seem,sell,send,senior,sense,series,serious,serve,service,set,seven,several,sex,sexual,shake,share,she,shoot,short,shot,should,shoulder,show,side,sign,significant,similar,simple,simply,since,sing,single,sister,sit,site,situation,six,size,skill,skin,small,smile,so,social,society,soldier,some,somebody,someone,something,sometimes,son,song,soon,sort,sound,source,south,southern,space,speak,special,specific,speech,spend,sport,spring,staff,stage,stand,standard,star,start,state,statement,station,stay,step,still,stock,stop,store,story,strategy,street,strong,structure,student,study,stuff,style,subject,success,successful,such,suddenly,suffer,suggest,summer,support,sure,surface,system,table,take,talk,task,tax,teach,teacher,team,technology,television,tell,ten,tend,term,test,than,thank,that,the,their,them,themselves,then,theory,there,these,they,thing,think,third,this,those,though,thought,thousand,threat,three,through,throughout,throw,thus,time,to,today,together,tonight,too,top,total,tough,toward,town,trade,traditional,training,travel,treat,treatment,tree,trial,trip,trouble,true,truth,try,turn,TV,two,type,under,understand,unit,until,up,upon,us,use,usually,value,various,very,victim,view,violence,visit,voice,vote,wait,walk,wall,want,war,watch,water,way,we,weapon,wear,week,weight,well,west,western,what,whatever,when,where,whether,which,while,white,who,whole,whom,whose,why,wide,wife,will,win,wind,window,wish,with,within,without,woman,wonder,word,work,worker,world,worry,would,write,writer,wrong,yard,yeah,year,yes,yet,you,young,your,yourself" func main() { words := strings.Split(wordList, ",") app := tview.NewApplication() inputField := tview.NewInputField(). SetLabel("Enter a word: "). SetFieldWidth(30). SetDoneFunc(func(key tcell.Key) { app.Stop() }) inputField.SetAutocompleteFunc(func(currentText string) (entries []string) { if len(currentText) == 0 { return } for _, word := range words { if strings.HasPrefix(strings.ToLower(word), strings.ToLower(currentText)) { entries = append(entries, word) } } if len(entries) <= 1 { entries = nil } return }) inputField.SetAutocompletedFunc(func(text string, index, source int) bool { if source != tview.AutocompletedNavigate { inputField.SetText(text) } return source == tview.AutocompletedEnter || source == tview.AutocompletedClick }) if err := app.EnableMouse(true).SetRoot(inputField, true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/inputfield/autocompleteasync/000077500000000000000000000000001457770046000302115ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/inputfield/autocompleteasync/main.go000066400000000000000000000035141457770046000314670ustar00rootroot00000000000000package main import ( "encoding/json" "net/http" "net/url" "strings" "sync" "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) type company struct { Name string `json:"name"` } func main() { app := tview.NewApplication() inputField := tview.NewInputField(). SetLabel("Enter a company name: "). SetFieldWidth(30). SetDoneFunc(func(key tcell.Key) { app.Stop() }) // Set up autocomplete function. var mutex sync.Mutex prefixMap := make(map[string][]string) inputField.SetAutocompleteFunc(func(currentText string) []string { // Ignore empty text. prefix := strings.TrimSpace(strings.ToLower(currentText)) if prefix == "" { return nil } // Do we have entries for this text already? mutex.Lock() defer mutex.Unlock() entries, ok := prefixMap[prefix] if ok { return entries } // No entries yet. Issue a request to the API in a goroutine. go func() { // Ignore errors in this demo. url := "https://autocomplete.clearbit.com/v1/companies/suggest?query=" + url.QueryEscape(prefix) res, err := http.Get(url) if err != nil { return } // Store the result in the prefix map. var companies []*company dec := json.NewDecoder(res.Body) if err := dec.Decode(&companies); err != nil { return } entries := make([]string, 0, len(companies)) OuterLoop: for _, c := range companies { for _, entry := range entries { // Eliminate duplicates. if strings.EqualFold(entry, c.Name) { continue OuterLoop } } entries = append(entries, c.Name) } mutex.Lock() prefixMap[prefix] = entries mutex.Unlock() // Trigger an update to the input field. inputField.Autocomplete() // Also redraw the screen. app.Draw() }() return nil }) if err := app.EnableMouse(true).SetRoot(inputField, true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/inputfield/main.go000066400000000000000000000007761457770046000257370ustar00rootroot00000000000000// Demo code for the InputField primitive. package main import ( "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) func main() { app := tview.NewApplication() inputField := tview.NewInputField(). SetLabel("Enter a number: "). SetPlaceholder("E.g. 1234"). SetFieldWidth(10). SetAcceptanceFunc(tview.InputFieldInteger). SetDoneFunc(func(key tcell.Key) { app.Stop() }) if err := app.SetRoot(inputField, true).EnableMouse(true).EnablePaste(true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/inputfield/screenshot.png000066400000000000000000000244061457770046000273430ustar00rootroot00000000000000PNG  IHDRE"iCCPICC ProfileXyTKnX%眓 s%Q"AEPTPAP$""   *(y͙꯺{v`' 6vtrM IWT)@ڟl+#ں>߲6o(/ K{zGy 4Wxd4~DL~;y {=::@"E@!"j սIv :{BB¶=ekDw|ndQ?c"?zgd.laC=-Lm-?nW+J3 xtM̎`Ƙ ;],Clwgd}Tlh鮝,?O}##jLu 7G0QA6&}uDXoqGwH}9$_i{,$`h[ÝO>z;`oP]n0]ֻ}3Ã-w3>; 7D4IyIƖcG[pC) ' ``eo> H|O;$OQio|t,|nfEUѦY9dJh?b X< 2x%| a0Ø K`m[rHsn`&ky; ZVC#ьhV Czk1脅'DGsk!Qn)iE 1>G3^$d. 쵧^1;`P!p> #*zX[ܐ!8L "p%p\-#0k$/ރyVA8X .Hd %H҃L!k P(CPtjkM A/Ih B(ŁDIPZ(-jJDeN*QWPͨ{Gaj fy`qX ց-`g9p1\ mHƢhq$7 vh/t 4݅~D/c(11 a21Ř*LY71+X,+UD֥6=-c;Ci2cp8.+]=Ž$ "!'s& %K#+&%C#95 7yy6'4x!OşcoV)((z)&)V QC8F&t^QRR RjR:SFSO9NHG Rb3)39U"U1 'T Ԃ:$ԥ7Gihi,hBhhihi3hާt.uӽ __decgg(e03 2131^gaÔT3&ss=0/n= |7hVQV+83ݬ lll^l9l^E٭ٓϳ/sprpspXd ,9EǥUuk[;w";!O Ooo=></_!_'"?~N t<,"8#,d$(tYhLRXC8BRVDI$H\dP%*//Z*D %  V.6GyO=q-Xi-%%%%{$KKK]z-M+m,&&UFTKT,ll쒜tf;7"f=G,(*cەWUTU|QW RU+gjj$ unus<$J)M>Mo*͏Z"ZZW>kKiGj7iQ9ӡ ӿh oda14175021Z4V4>`eB019m2e*jif236;a6f.`jb,,NXe*`-mߺdžݦfV6]]=}] GIXZqU.z.E.]]3]G v۝ʝ~QN U=<<tNz{kzz|U-S;7_p:`)0l `A]aaaCb*E&UQPԾhz5?F8Pdzli84 /&:O?y@@Ad))RAӤ Ҿ;epddL28t99zX,tV@@lvIRŹG<<*}c=> `ىBœEE}rgOOƜ8ezxiåڥeee?ʽ˟={ =.TVVmTVO\UXSS^wu9+Wu։U36kF\AtQ)jNh^lohuji|Mĭv dټxw#c߽N?6}~V^>^VmI)^ޭ@#ǚY9k h>}EKȥͯG|.sry|%deGOVV{~9[?!ff8)*#P:@7S{6*9PZǒȜw XJOL^ 0 )+ 8  hr.=S"$&I)V^:EJGMC VUTyQѢ_K[Vn^~AC1IiYyE5ƆŖՎ_wXs.DW}}nSU^%9> ~~rA<,!Tp[E'd6ţ|;UR\RcҎe$;4w2K "䢎>g~!߹c}mIS&%K˔eψ='UaR~~QՕZWT֙;4_~#`SZ󡖬ܛymEګn7;1qoosWow}}<6}1xn3:#Fz/^ "Z}=3ͽo'&̧Y`Qyifb6gNnnbB'dk|^<wΟlnn_Fó 4v &WS&TqhY301agddri[_|,t^8RD]L=%Hr(S'+&w+(Z()(r!Y΢>qREKPkM{X=4 ۍcM|L=,B,=,UmDm(#N\J]s%;z$= 9a.&*‌ `PJ$&#GDǔދ{?AdlԦ Cvҳs6i>xZ5 Ν(-,*+>v*$_i@YJݳ".U /j5k _(Wt_ϼqNPxL6Sm;w;xMuo.}pPob_GO yLHO^~M;&t<ɉ[OƧ OY$Y ՗F>v{r+?Wu7fw/ͣa7YȦȗ(J-3U*!Mz=@CgYYzpsׄw/_SM`UPHJ衰NZPX=^@\r ^TfF6]SUZ~A"b 2¨rYUK^Ւqr#ZZ/uu6u+,7334v5a61-212HTnUod#dζn=sğIKK NOzց;LI+NO;䒩wX4 <$9?wn;~0ߥ@‘'O=UPRqF郲sgQVpWʞ7z1`u#5)ˊWW^T@y]ecRScVm%[oߺwwA.>هx =z=86?50}u+;m5'R 5; :s;XR` PEb0o*Ra=$S$&g#S) jJ9vJ!khZjګttCC  O201`ecmcsc'gou;Gg_` QpBp5$deeȷ*(&(y+H2%IjiG`bno,gbnavʼ1{cS ZwX'sϜI@Q!Í#j1[œp,MaLOgZ>5{$XS> O5O3=kpn2ŬKA5_/WOӰtCL|ǶLtu{i<|,Da(Q+o&'Tew?zrqoMc+8@Q Ԁ! $lPjMbB EE9QQa./a&3ľpa2=VrIZ ]%a2HN,j@4q-tt0N13>d cfb` `g` cg(tbz]+_tCj9~S,O<]bd Af@6GDI~IbRrĽj?duruo2mgNpMYKpgig Wɬx{i7h@Ā dWF ƑuO!MhBI9u53>m4;:=q<`opLސG BA&.u37fb4fRdagugK`26153p:*\++:R\QWԈ \cN&:H[ 6KX\nձqq;_qwtvy!:?,iKLtR,gxƒv)*23/f=r7 Qoӕe V@e.W԰^I3hߘ\ٚt{n=zn= zU񜷏&Ͻ 1hlg/K,~_^>¾RC?~62F6ofvrmpl]s=~φFÍҿMMS[~|@m0㛛Vq)6l[-kH]()iTXtXML:com.adobe.xmp 184 433 1 ėC[IDATx pTf@0H2&@$HBUH'("CTZmʣ BkڊE #:@:Q"vxA 6d=dlH0 {='sM@BD\M?X&Ԯ _ԝEҋtGy@b &^,i\ :@\GzSyv^ 8uGxkWhέ ` QP>ڧϵ޸l 6i4cٱRwI)* RD-&-N45Vڒiѡ;hL&WW6Scl*h23VjOlZu(yx&: g4v)Ewh l*GeO*wΚM>x=| uՄ&gKXXV(1.V2CȎl}#"ڕP~yvMlh wtV%=k^ JgwӍԽ;;Uo1nr'-f7ct| Я} wԹ6IMtΚO}0yΫƻ#%)O{D ԏ[x'F{^}Bt}DIsKnIW/k`a^FOjY0yg<ͺ%DaIw28*uEbjB&-'0"N;~o>˒1?޿n-20mOg%q?[{ڞ@7k#M:lkNcdfzےgv矩ƍQRbh|lsǀ9ˑ*C@#)݉wQ@d]X:_^Q*r(1E[ƥ.**nzr j֚`YS`{)N)qԘUG) =1]ClƄ'{aQ}2 u<4;Ι髶Oc D|rz\[ my<+y*.Qa= [--kFSG֬tsbs)(kh $sgi{6+yMz-gWkF1Nǜ?-;>wo/4..@D݃y}z,c'Cd:_~ ٦j6xJ%2 }Pt{%k7ᦰ-1A~%y5x8B9f7W7&ț4#ef:L=~2[x.UUإ:I\Pfڧ t,uj{ v;Tw=ڄ@8}NkXW#9ǖ&汕a50buWm@iz]Cw֡6wtI?~@C# :migFڽ5_Xۍ˴mDe9q가bWN3zkOĝk4yDɞm&rT3%v:68O@byD*j~Kԝuc*xݞo!h@afNhx)zBblRپs-%W{+*?)a`Om.n˹~GϾl}܂1uw &;7U1wn- '@L@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@hs8VD9IENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/list/000077500000000000000000000000001457770046000232625ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/list/README.md000066400000000000000000000000361457770046000245400ustar00rootroot00000000000000![Screenshot](screenshot.png) golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/list/main.go000066400000000000000000000010641457770046000245360ustar00rootroot00000000000000// Demo code for the List primitive. package main import ( "github.com/darkhz/tview" ) func main() { app := tview.NewApplication() list := tview.NewList(). AddItem("List item 1", "Some explanatory text", 'a', nil). AddItem("List item 2", "Some explanatory text", 'b', nil). AddItem("List item 3", "Some explanatory text", 'c', nil). AddItem("List item 4", "Some explanatory text", 'd', nil). AddItem("Quit", "Press to exit", 'q', func() { app.Stop() }) if err := app.SetRoot(list, true).EnableMouse(true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/list/screenshot.png000066400000000000000000000734501457770046000261560ustar00rootroot00000000000000PNG  IHDRI-`"iCCPICC ProfileXyTKnX%眓 s%Q"AEPTPAP$""   *(y͙꯺{v`' 6vtrM IWT)@ڟl+#ں>߲6o(/ K{zGy 4Wxd4~DL~;y {=::@"E@!"j սIv :{BB¶=ekDw|ndQ?c"?zgd.laC=-Lm-?nW+J3 xtM̎`Ƙ ;],Clwgd}Tlh鮝,?O}##jLu 7G0QA6&}uDXoqGwH}9$_i{,$`h[ÝO>z;`oP]n0]ֻ}3Ã-w3>; 7D4IyIƖcG[pC) ' ``eo> H|O;$OQio|t,|nfEUѦY9dJh?b X< 2x%| a0Ø K`m[rHsn`&ky; ZVC#ьhV Czk1脅'DGsk!Qn)iE 1>G3^$d. 쵧^1;`P!p> #*zX[ܐ!8L "p%p\-#0k$/ރyVA8X .Hd %H҃L!k P(CPtjkM A/Ih B(ŁDIPZ(-jJDeN*QWPͨ{Gaj fy`qX ց-`g9p1\ mHƢhq$7 vh/t 4݅~D/c(11 a21Ř*LY71+X,+UD֥6=-c;Ci2cp8.+]=Ž$ "!'s& %K#+&%C#95 7yy6'4x!OşcoV)((z)&)V QC8F&t^QRR RjR:SFSO9NHG Rb3)39U"U1 'T Ԃ:$ԥ7Gihi,hBhhihi3hާt.uӽ __decgg(e03 2131^gaÔT3&ss=0/n= |7hVQV+83ݬ lll^l9l^E٭ٓϳ/sprpspXd ,9EǥUuk[;w";!O Ooo=></_!_'"?~N t<,"8#,d$(tYhLRXC8BRVDI$H\dP%*//Z*D %  V.6GyO=q-Xi-%%%%{$KKK]z-M+m,&&UFTKT,ll쒜tf;7"f=G,(*cەWUTU|QW RU+gjj$ unus<$J)M>Mo*͏Z"ZZW>kKiGj7iQ9ӡ ӿh oda14175021Z4V4>`eB019m2e*jif236;a6f.`jb,,NXe*`-mߺdžݦfV6]]=}] GIXZqU.z.E.]]3]G v۝ʝ~QN U=<<tNz{kzz|U-S;7_p:`)0l `A]aaaCb*E&UQPԾhz5?F8Pdzli84 /&:O?y@@Ad))RAӤ Ҿ;epddL28t99zX,tV@@lvIRŹG<<*}c=> `ىBœEE}rgOOƜ8ezxiåڥeee?ʽ˟={ =.TVVmTVO\UXSS^wu9+Wu։U36kF\AtQ)jNh^lohuji|Mĭv dټxw#c߽N?6}~V^>^VmI)^ޭ@#ǚY9k h>}EKȥͯG|.sry|%deGOVV{~9[?!ff8)*#P:@7S{6*9PZǒȜw XJOL^ 0 )+ 8  hr.=S"$&I)V^:EJGMC VUTyQѢ_K[Vn^~AC1IiYyE5ƆŖՎ_wXs.DW}}nSU^%9> ~~rA<,!Tp[E'd6ţ|;UR\RcҎe$;4w2K "䢎>g~!߹c}mIS&%K˔eψ='UaR~~QՕZWT֙;4_~#`SZ󡖬ܛymEګn7;1qoosWow}}<6}1xn3:#Fz/^ "Z}=3ͽo'&̧Y`Qyifb6gNnnbB'dk|^<wΟlnn_Fó 4v &WS&TqhY301agddri[_|,t^8RD]L=%Hr(S'+&w+(Z()(r!Y΢>qREKPkM{X=4 ۍcM|L=,B,=,UmDm(#N\J]s%;z$= 9a.&*‌ `PJ$&#GDǔދ{?AdlԦ Cvҳs6i>xZ5 Ν(-,*+>v*$_i@YJݳ".U /j5k _(Wt_ϼqNPxL6Sm;w;xMuo.}pPob_GO yLHO^~M;&t<ɉ[OƧ OY$Y ՗F>v{r+?Wu7fw/ͣa7YȦȗ(J-3U*!Mz=@CgYYzpsׄw/_SM`UPHJ衰NZPX=^@\r ^TfF6]SUZ~A"b 2¨rYUK^Ւqr#ZZ/uu6u+,7334v5a61-212HTnUod#dζn=sğIKK NOzց;LI+NO;䒩wX4 <$9?wn;~0ߥ@‘'O=UPRqF郲sgQVpWʞ7z1`u#5)ˊWW^T@y]ecRScVm%[oߺwwA.>هx =z=86?50}u+;m5'R 5; :s;XR` PEb0o*Ra=$S$&g#S) jJ9vJ!khZjګttCC  O201`ecmcsc'gou;Gg_` QpBp5$deeȷ*(&(y+H2%IjiG`bno,gbnavʼ1{cS ZwX'sϜI@Q!Í#j1[œp,MaLOgZ>5{$XS> O5O3=kpn2ŬKA5_/WOӰtCL|ǶLtu{i<|,Da(Q+o&'Tew?zrqoMc+8@Q Ԁ! $lPjMbB EE9QQa./a&3ľpa2=VrIZ ]%a2HN,j@4q-tt0N13>d cfb` `g` cg(tbz]+_tCj9~S,O<]bd Af@6GDI~IbRrĽj?duruo2mgNpMYKpgig Wɬx{i7h@Ā dWF ƑuO!MhBI9u53>m4;:=q<`opLސG BA&.u37fb4fRdagugK`26153p:*\++:R\QWԈ \cN&:H[ 6KX\nձqq;_qwtvy!:?,iKLtR,gxƒv)*23/f=r7 Qoӕe V@e.W԰^I3hߘ\ٚt{n=zn= zU񜷏&Ͻ 1hlg/K,~_^>¾RC?~62F6ofvrmpl]s=~φFÍҿMMS[~|@m0㛛Vq)6l[-kH]()iTXtXML:com.adobe.xmp 329 392 1 N=R@IDATx} xKJ``@ - "R"KᗂPhmAI%BM* AP?4RPT y3993''gf_^kw^  @` \̵[lif?Yuݻw]:W( O qL?#.1IL~j;{$gp-S_Z?N je(M_@kS%MEm{?\cG,+Wڲ6pAjj{HA9tLIJP3".ũ)W%jhPV&̗?;f*pm**6ogmm]߾QxhwEý9D;a$E uhуj.ҷ҄LjA-~Ak}ȵɗG E֔-vǾYSIE}*,ͷ޵de:c[!A@cZ>sznXӇ 6qLxfSSE_13bMOC]4Af\#pSWTS{F1kJJegؽvq1á\eT [.[+mlp;c&Kr3ޝEu}xqU09tM#S}}ͧNYI ,~'QRfg~ϰ􎨚V?C=фy_;O^c -:Ш$?!E߽d}4i۷}RFAɆ-˗oٴ~~vp~Jio旔_1WJ֗)YfMI'^ llUq%+%eAwKfj(OI6JȝWi}A6R; F8gԎWhs>WQ`"4ulCťtg7L(]COFcm_L@?(".C.XEAUXV_xQqxKL9A32*6eB':_"7&"jk˝uslDw JUV8wqL'xٹZnK7]CmR3mtkgxi\ߑhc}Y3\WtA(UNcdݫKN7gx_z;ݚ1'OE*jf^Z_}M++~ T:M긾U떧P->)}“tM1 )界ī4g]O)(3*K>w洙Jl?jB,UD]$[ߧב/Ձz yAL#ZE*|Â5|-q:y $}%3kv>R *˄綌h-+išy(##/:-PAlB1UѮCZEWQ<˧;fΧ*3{:6˲ h[GO8W^{ u*}DT58DJc6ϛ$UK(W4Gv+f R^ɝ1`t6PlNYVG,cW6669-ɔ"4},)Bفy~LAڭ| fqujQǻR^E:hʥ4-ᐚuǏ{u5Ǐ՞rE$}1@mu죢c45YBdPӀEÞk kIO?Ne*< 'M]K}.5c3'^/');M{σJNu X:&tГ|v鄇j 3 >iC3ơ,*-|8MOSK-t'wJ 9|Pӈ^nY8Yqvު(ށdՒF~lUx$si >BkU mq(VuxodIBAlCkSa$"@·ON}GsoX\;P'T%2X^%n)±?E1_E@X[لJq4E(q{ o{G5<뼺h)/E}p R}C_=}o?8]cT#=v RMPAl-{]y;JP4{wK)_ )`ʆ4]LdH@U!U\g * c>cY6٠0VA+Y[w@^ uE{vF+D@CT saWXB_*l%tӗraUyc  Iz8;2D ~i`aEZ>Ы{AΫ I[ 98+(/x%cn3zЖC#`P") Bi|bߨǿ/aV ~[ 1ky!jk-a3;}:T{d'z {ziɨrp(=zQKxb hT86ˬ: 38eMa("x ϘseSg/at 4ٿ3[JWٰK Xǔ8zSk8biUZUl'0A=g`[и1).~1uQ)inlgJ˙uWJ…[YҘPnkC*|! $-{ьxEQƠ!-=X/ "啎Ѣ9ޓg֔{q,=Uvݷ~mrTC_񗿹qwMm]ys+wHInNu MZ];+o.{}8C~J p1-}[k.Miڧih +iګGn# o#2l:_q~*̷-o|^~|Wq\fS~z%- ϶A?qt݅wJЂUr:UG5Gl!a!;^g;E-A =jC$MY4kS(22֢<߹;gC_1f]M/YVh5|VAĖԪ-(&£-[9rLERIw^ں|yb=|c}vz \t^|YCg:|)G2ޥl%#9<E8}qL5u5U4uz~ [@?AqtM䎡xпƖ&vMMNQg"/ǔV>K s!rK7&cV$j)!1J@1oB°Nǫ TYT2=5VN1eyI/Vq q-E%OORTͣfNbޖ7x%%G8< ̈́yI$K xR{ Forѝ9-^c -:Ш$ J;3bo ԝK;~JeS݇徿eQ+μO羺k66ت+V޽kk@w?ҡoS~3r"ݦ]5^c~X0 .BKЃOj{ӷx4 x^xΤPَm)/bmzqX-[]*ھ8's¬]sfhYPUyQe^7՝8RTm`TdMkɋ[eќtɦ 7Gwj*롩7N.J^yɝmUKn- E1}m{wGC1lߡy+{y:t;y.B5? -d$(:}s=GڵcƵGRоV[(YKi yױ״ݔ e{Z7}Fj [q} -6s]sJUWjAn䷛kn:"dLؔ~'.j8F-[14 Eď|n6ǝ6h4VQ5Ͳ#{RMMCF햁 Tmθj*6M""Nk J@ 1ͣr| ʨhѺWu?/X8W.>S@q۶@ jQ+*:m}mՒr+vkI+&>^y=+x\&Z2Տ88$J*qF@>RQ:'}f~~-&>!RފxS/̔>XOjGpiTzNه2Xh&q~`,43EN!|WQZx_Q|$wWƴ;VY(NJӹ?WZ'YH,m;ϫ^Ziep~Z {*iU=酲+f;m%| 3SZՁ8v15oNIZohvFx2`zv%     4cj:")5=B)+IAF#)߱x,DŨc2}&m_c2!stLijQD㉾h(8Suv#)g:=C (wlN{{ce~CKˉr Hh9ѵ5͝FԷulAwm~7A`u Ctv4åf0TX~g_oaSD&Zg*AAMDxFs<:RŤ.I{1޴Dt6Y`৊Vpj4Wfp? <9By{5 B_oh%+Jd&H4WbJn` 9fzJ[ eVB1 =gNx۱!Um!BAS=8mt842Peo<5ij\!ajb鷉&q[2j*l` {@xOFN|V QX{{i4GgdAJH|y6xfӒWKUedMl&کp柨w'pU DIgL V@KOWqy (XE+(uHN$Ve^?tA`b ʕJx3hrI@f@Gx|[mVlN uZ 1AOQ9(2BB?Xʒ*2U 逧YVs16<[MX@Ȕi3[/\dJ8/W< iU\95*aqLBHPaXȀjPcaV`{M]L|)a~oed,+ G݂q`ɃkCE?᧔_*:0O9/}Y Km|5mšSzC0o3g<Dw lA{aEVF6R QQsr)q7uv*;͛|WQf+alSV%aT/%O\#lj.8%@QcЌ<;a`B?Xh?DŽ''+ ,lc|}Ǚ^ %OjbEmUp/ѭ #= ͮPݴ%tYy%e9.A}5cܘO8bLVEsv1g˱*a *73u ~-QZʅ*p:NFL'P#,(da [?j\S4_O^P zøoccKP@_K Xq ~ CMxT6H ʢD|>Yء>˷.`x1*b;[c([ n6½ %Kx( ^o뽀;Ne唯⋆0eCvσ.&2$܊Ԫu.a 3SRH@1PƬy\lPEAnT+ v[,b߳Wpa"ŀ 9P'7œ>EVЇDi }` \A le&x~&€`"ts>ΎL(_@`aX<=`%*^t*|CVj)3 `$ ^ X́^,eȦ:XTHBAPƶ7KqVBraiZ'FK̎f i5ى^^"|gZi2&J@O/^Xwg /Nl2)iACii@SX<7^3fEً@1@k9DByr:M`%$K8D#Л'o;]y(:VD]b     H'N _A@bUl/xT_҃cug ʴ ;d˖-76'+;''jA l)q0=HCq)N*QDߧć9и1).~`In@i:Ţ:*6%M8rfݕpEc49 +㝔' -SG37N4 41}iJh`˷űTzh6Tk4N*3ND MML욚ˉD^)`}n樫CoL䡴ub(]$'k rg^2ڐ TYT2=5V&cvPd¨)IJy܌ҩ^]n2'Z|!ҥBhJ|S%]"ޗ2VĕWESD8*[akΤhT8?Sܘ-=Gԏ^\+UXAOț3蘋/Vy38[SQ-(S^ bllU1x-xW ԎWhs7V#wֿ;lv45=W}IaԎG^#Jťmꂖ\U9f32N)biUwm wu.)Z9~bgWOlpstǮƍ5UoW_18*-G{SZAF|ILx9zyqL'_[^l/bp%ፆȾ(#5t;mt[>HtQtz<\k֍k'2}k/P*ZciK)NQZnDi.5S*uHSyu?جFњ? >^( cދF>F4߬vF^(i d6s]sJUW 3Ww7}I]f]2&lJpҭ҅"G>ix]juK`4mY\f~qfnGUx!#l(-V۴]Qc յQ()c gliDw>A=|lx'&t1{c3^ }W^#Y@q@ jQ+*:m}mՒr+vaxjT蟳ĬjɘW?+VT'ڠsRQ:'}fZ^zoqlsfJWPfj,yCxgaTFW9QR,5%qfk5`,IntQ}57UԫVX&]L$wWƴ;*_:)Opt_iS+$pI`Mmy^J+3kXN˸-`>4\*&F`سڛ+]EIN'ԖT>A@ʩi5/:.fRMI>I  @zM]n,חф k%MA@A@A@A@A@ >H6M&G1e%)y$%\;/'A:\j>;&g8&<K4hS}q s"mDx' 4=bj<Dmk&Q F6l~  1.ŋ.'ZFt9x,"~DZr5GE7͡'$`d3 sq90M~Y_^G.5͠"ygҚ3TN/hU{7TqhHZrZ{]6a}/Dx 9 D7r%z"Z! պF$8`OPޞ?0B_oh%+Jd&H4W@Ga*SrKID0+V2]0,:I>tێj 3 >iC3ơ,*-|8MOSK-t}ܙ C/"4",3oM⢷Ue^U+ %@[yr)vg梕p2V0ڄ7D1߉7  9z߻WBK6;mKVn ws fW B7m ]V^ @sNK@twX870UܟtrJCG L]å}19h).h@(7V.T-Ap2B0D@8d:!aYGy% [xޚ7yUKz¼GxZ |C#\Rs4\j0S0~_07mlƒe°AM@ELXT%%dK}YUuH(YCXz[q /-+|_4D?g)xt1!VVTs [8.B.Џ2fpf* rȦ:XTi"f0 /׽H/(Ẃ:.0"w>$JUK/"a.33Iqvd*@ Ê˵, |W=WTsLqVP3%_J 'B5ngb-?F6 ŸER 4Q_2bזCH3:I7Zfv4I.u\N<a;JQ0Pzz ?\Џ#8yp ldYu`fNI gpL;Mdg_QD16˦/2^l2X1'Γi:x<.!A@_$< }yE!0g_^ z0\;A@A@A@A@A'@=6`4nй{)  b- p'mئLHxTKYN鍵Ɲ1<;;;+.삒-[[nۅ N{_3#)IJP3-. g G J8c;!vU-֤=4nСCo0[XdbSrf_ZXPnkC*L=) C H#(i,v,S_ZlZ42;űT#[HvڮO͡/ܸЮJ6wHIn†/@ M" HOD+a^MgFSDMXIk{V#7Pьm6|VWiS8bmlh VQ9` U8qL7x3R-M^T <ӎxzj4i{4eѴm"Oȃ[r}s?t[}_ j4|VAĖԪfuL곅G[Y=8Z d/=~ ^ߓ, miEJ]*J*M{LY^+U\BBB2~JTr$E%,x(b.X˛D~~۫___PP֩WB;lU {XJu+fvu5(c~([3Q(xʰs"Xn^۴׽WdaQ߷s V3ϟ.BRFY=C 8$]pwg+ޠ32xvoy.(-:WB Zr9vBKTd_kΌz*ʼnL;qW9lTdM;w?y6y,ӟ.4]%j-r[䢪oNk8d{/zJN_| ֿVu)agH ]x\ߨ}Oj2]>Ṟ#Wڱu#;t'oe|h9e"-5:2l^OHa+;AQ֢1[6t N+(I,47A < 3;¯x`oDyNؔ2jWAhJ<h/ }n0Fq;g`ܰjndu;o,!A l. ԁG |%魌vJg|Q e3/'3wwNÜ7{& X`>3}Ԫ|[?yz}:3c/#hyy"Z`XY_֓ǜKxH\ 鴬Yݿ[\Z?(YZ6(%/MlŮFw$.*eF+9blIDATpy?ɷ%WXp7AZ F\:IcZchXc+#Ш{{hSc~$uJe&7<=cbL$ny 5WT~$%)kn᪥S&6ԷTQYR1pN^QfЃ%JK'šRZ5 4m3z4ӧ(kVҠjظNT:6{O '1#wCzm1C<|lT-p<}."J\po7&vu:JyÍ[ JchJܦum;.mдidjre3EG WVⵛp/Y1PQZQT]hF|"&yV3')詒lW| (+DfZ8K .WTEDDǵOo.TZGQ踶UK ˭ح$xjT蟃 Td̫qpHj?*[Ubmй(>xq-OHdTbf86C<)ite&Nڇ^A p_#o}$Qutq Oƛf^ʥ4f't2%_ԟ!Ii}:>J˝`mȳVfSsajoV¯t󊒓& bY>VԒ4ű0ᅧߤy(yA@?H7o,חdYA@A@A@A@A@fC}Lͦ^B^SwLYI 4~I KpIώD})Ʉ$u1M$VQD㉾8׏uvÉڋ Û!vS F6 ^D1a2Ǜ >$/: h-?|?rk9q6݈)ݎ6͠qwysLaǚu!8R3 *w&9zΛL2io0Xɉ&"<9}bwǤ_@r: n,0KDSE+ 8B uX3Ipp&=`s7D.JV,P sM%V1hѯ:T .`Vdջ`Xfu,">Г|v餽B<g(t4|ӆhAg^C#C9XUx[&#p^㛞 [+O̕rx1/fy~h},Ө7^a.C<6O;3,c&C9wRa0JXEK9 o#>^!ZC cXe?I'N `9Qa6I!#`oȒ+Y!" qm΋` /'9 ?*xEO(8x 'B- ;$[ SX1+!4">] m@ 5\[bc^,ˇ [ SqPr( |,Ή=4p x%$>UQiī%m `٪2I&y68O;*Gdn$U3H+w%̧ҫ8]i >BkU mq(VuxodIBAlCkSa$"@·ONY7,I * P p, l7VXߢ"T sבֿlƒe8߿["NW T=y`mH_qir^yYJ'%^՗>,!;#3rFɿ08pJo起=fmgn}a-sO8&XfՁU9%-}14-}h GKx|,B8{5`-ǜHh8ON@L} Ghvz$-~A+XGÜyݪpKA@A@A@A@ ^(B\J_xf? 2+&'IiٿEFņKJ4.(%ϩ 11%ўť8Ugl'>%>LP8m]'gAJ5zHyKAOҺuwTlJ*xYw$\uј%~j+NA@hb,KW:FSxZ_KO{;"辅kYf*T{x{)JL4lJZwU︻ߝ#%}0F`Fw6nxEmaeӖnzwMy%-զz1KhVA5|18=|V]{ISM&)<('جt-UۄhW}eS~8g\/iA@hfLk6TJ}ՙ\Q""\+ItMč_;*lW BXz|_+%w&@Egj-$v?PSڢSݏfZ-՞m(Sn?#Uwʃy38[SQ-(SxDHNr5\BRne'M{Qu&]߲#Uov^YxLJ9]c}UyQe^7՝8R̞3TTU7g u/V0ƇHVѧ*`Aˋȗ"#ZB{}J 43>Z+S[hz5>~xK#lXXGٓ<' ӎcj]7VvU}"|m6ߐHp3ǷY~w]~2cPtNi cf]QiuO;ܴЬ/u۷G7& rSGakǚSC6 Q( A@8{qLU֝}#O^3rI{(eG>F6ZxWzH[2rLM25Xh Iz('eΝxsּQ$եppT.K{5 \j+iK +AaUC"*:&:^-9Hק(GԁmalVdeaYы0XL ,dCr|3Oe/'kih>Ax0ͧ8bΖ^4,t噴oB׿V"ζ9U܅^ߙ?Є;!gM Nji9$cDx U3L/ ^'LW>-Oa;Vhj-'Gs$ $^IԒ<l7q)^HZ'9n+tb_)QuC 373PB4S^x6 :ƴ>HuQ9E;7Yt}h͋˼ɋz93vKWvѕ^E5 Sf1ܰ*wSu.WR/'wNzBr@ ~kL^pZ5s&0 gAyD+-^bcˠ3Z^>9cEX%+^ .|Vgvs x Ic&, }W^d /~ M"$ߘ=xKsoa/1eJ署a9-BA>ЖhkLr5S7p $NaHto0Kiz!%DR^m"@S I8'k'R5a[ fػA+AO8%jc` LJ_q9?džL:&ZAfT^"6eWb vR/4AhQM#֘X FDKEj( *`s!_=X2xNg !"u4JetSHS0AOEPBYpuL?/_2݋>+=oٖWx%*3BX543wMm6e%)+cq 0B!ٟ.''c`j\}!F7Tԍ_%NrOCx^.;.<B  An1Oo G(=izMi$m<-sjs^"x@75IM\ޡ܉pMCG@K w ` 2.Mrƪ kLfY,|:8֛J*ѥM=\IAomsJ:}U>}bK vLzd#491Ժ́%)H 8Z KF}Ŗm'ڡ3b#~˼GsV 45l`upjw @^e Ф_ԄC;0 IJ7F&\-Uf\¡r^lqDq6jI#                                                                                                        g57QIENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/modal/000077500000000000000000000000001457770046000234035ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/modal/README.md000066400000000000000000000000361457770046000246610ustar00rootroot00000000000000![Screenshot](screenshot.png) golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/modal/centered.png000066400000000000000000002235371457770046000257160ustar00rootroot00000000000000PNG  IHDR,( h#iCCPICC ProfileXyTKnX%眓 s%Q"AEPTPAP$""   *(y}|[S]UWul`5!ё܎Nܸ)`eii ?g[Fd`O(7f ӏ÷"#`[o3oag[ZHH?[c;D#6; QMA?DgOHH^@mH~/ۍL7 *<9g ^ GZoۥ0-L@p{i཭_/xE s@o deH}}y@. ޵ 67ݵcҳo`$P;|'zgᆨX?}F# 3T rwhKnh0:@pa  ,, v~Jpؾm@" ]7Jwwnv !hV:Zm5CVӏϨX=. a 3A>w[\B=f 3ݶ]-0f`翽C "h5?͈fh9-<"7ØʉD]#WVt5G俚p|}p;p+3v&z[b'eYMk}⣷NXxBd4pzIᖑV`ko:Yod>3E|Y j`G& ^{#ڎ*X'ˆ?2@MN qpA*8(Yp\Wu=<`F=`A(!: 1HR!=  bP: @ ݄A}f/"Q(A$J 2A٢PDTuՌzFMQ0)`F`v}H Õp܆</h,͍GrmBGO/]gI"7Îè`0?L&S4aubBXEd]:aI#rl=;.p8N g#q]S{O2 2.22}2gP4bZ;dO>S [{'_ o#B| O«mT)|?FAAKLaE@Bqbb@K%\ 1cjB%%% &3e41?tD ћL,%6?SS PiQQ%RSݠzB@MN-HCM>H]J}zzFƂ&M-M -VV֛6<}i:N΋.]7{z,} }.UEZ9{xR 0 c0cu_LLZL>LLuLO~01k20033bfc bgiayÊfebc=ͺFϦŖv;]ݚ=<{?2'G8G }NFNM@B;\t\\\\wOqwq/T )u-sJ\@I_@A!AÂ-3BBFBBƄ)5#+`EDDEEQOPb bbbC{0{3*N,>)(a*&"Y_Y2_G򷔼TҴim_eDedJeR&˶.ɉȝ{!O'o&XS~CAQ!RNaV_CLqT^RR2FY[9Y]yUEA%ZUq ZՙB{}^;ƫFRPPVP?>AҨԘ֬%uE볶vv:niq}^}?IC|Q##/EcE]&&Smf(3cfc-K![VX+KR{llmjmVlml_ uSٻpu(ppt<ȉ)l\RU5udо}}nnnݩI7<0$ R%iȳsK׼wOG_5?5~ :  v! J6.>QiYEjG^sccLƪǖOߟ 1Q?b:+s?TzLKH~br)8M* {Cz[GFJ!C3UBgd dfdy+[~ãGO<{l O!q# h  Oh..)^^W,W|$dɉSZKK?=\]Z_^]ܻ3ug9u.܋ J?\sQbMkUnFuh%K]555yQc.^q2xUjkx]E=c}nhiqmJ7˚rV֡7;TۚnIܪni/p;NƝͻw;;ݛt|}.nhUmSPa#GM7 ( 4?Q|:<6wS>{a/_̼ ~*1X7oEO(Lܞԝ쟲z=5=.?r}i՟s{?>Sgύ_4/:._\z˷r;-WBV~dyiUiïkqS"mM~mln"Iۯ0r|}Z t;n{H+1x,N̉<$[4ʘsqy.M<`P(؃=%AjoSddyd?ݔ?`Ȯ^N9^EKlo- ou4$i3/֙WX[N[clXlYau5'LBt܇޷6>AYUg (B ~ y!XtrLflS<:'c?8 xP%(%5&XzQF!Cәy-)r@.Qcy O8[4?eRbpZTL\YsR&'.U],}EnYC5765jjͽVtvF:v1wv?Ic'^>x.93b4B+3c/?6}on|{gf&fs&/-$~2LK_ݾY|7[\yWˆna4~>4^|״coLߞ5tj|z ١yOP}aio7W,'}5a]wcv7<vC`p%,nl|O":SR_ݤ`c d:|- xnm_<xMx;V  DE E?e-%$%JAneLefd8Z)r) o-3**UTY-I^!1ũժmR_gSRR\~C99JcWf"3s*>tKUVA6B6l+ٳ?ws4ttjrvwyZ|ߊ[{+R' d1US7 5BCB/ˇG܏̉f~s6;N0C$gos+~ԚC.zE0YϳKrss׎L}|f޹] TNX-)^|S%o>({Q>wfewy êVg_:RRKxxOu kenX6&556lUVr;}wt^)}ǠS#/cSsWV*p"P3 3%%% P~L}~@ ( `\@H2D!e8LHIC;CW^ FPHuM7}=dabU%5zHHVMFgS)X ՔrD5b-jC4ѴԴWtm,23d*aVcg9N):w$<:o_1^A ,OQ-1==k%IK5I'Hˌf}oU(PLPV6UReKTP/:ݧELŐ݈X4yW+>kc=h]L~FW}n<$O{19?*{C C?GF#b^Ƿ&'U>X˜H=|80k>'Hȱ|kNf,,?zreYU+j^>~Uaƙ֏mKwwx$XP賟WcgMyO?W+G>\~zߞRVqh @C` <@H٠Ԁx! ImG?* %rF\;|^@+3L*f })qdzdx 9K4e`3bg|J>QǛW=,!*$rs"7Xx~h)/iM̀lPy~q`S³aQ||,ςY5ZY?nрP#,ʯ# B>( *nC(r$$Tjf}hvt zyƩ!S( 02(MIM]BCDgDo`h̤,"Ζiemckgo-.%tTVWtviVYoz5EK*{15׵Mtґ10Z311m6b%alc7wjFAO?7CupYșXθIʓR~Udgr^̾{oA>KBߢ%4+*.(]a\g y]15ͩ{Nq]{8? 9->)7z9oMRMM{7Ac̹޹'R_tH_Y~|t}?V:l^e\\m^]+Wqf:ٺz {>ߛқ>6++`77 +`#ssrss 552 812 1 p@IDATxtTUM*PEURX!$B8flf,I!ӗCxbUAWߌ ?6l{q/.L2n0c)|݌:x֊2jkRf)VQ[㕂4 ^#LzjTՂD=K–0j2Fma9j%a]QmBƨM0,G-ѳ$l+* ,DZQʼ%TÚ"kz*jh]ZZ`nl8&p /|l,^X߄weӍ{e~iJ EH "2eƸQMAV x, $Ea\X  G3qO'",4(*īYhi3F< TT284@̐SqzۅMe&2ᕢͭjxpNB-Ѓ3JǍdmzqѺƨ5J< +c< aabV bl+ƗǬy\VFh8F?]TRpF[bbu:5Њv3e@inl PyT* {H$ ̤@'e(BRTC.㊒O]8N7nO|G3H1FbHQM$Xa#+ +}!c\UĮď)âO8ZZ`.ۊM.ȵSnGնt2ұg<%;*GLtcY&L!{LW^1HL4ffTM@E ,=݆c "< $@  :j3ZķE@DGy9;cV)[|^HkⴈTL|њ)r=cX$擨ZO5VnSш вL$Yil6u]ӕ^1-d S&s*dG&CN2%eu48gZ@Q=`h@X @V F@"}R ER.x.Ӆ8iB. պ]C3G|k΢Zr`mEJ( wx/f!&<֩H/d+g?ƫ,;#NX.Ӂ ĢrFTYȁd&] VxT[aJT+V c 80" q$bU.d5a84hR>f2&`q צU@2Z߀r1/ @;ڦjZ*S^c\EL| |\؎y982)|"7#7槉 lG~ڶ`iLʝ[{ ucWCTC`NG{c*&NdQfbSV QXL'@L0 d(&:}.Y6x tȚz~&FG/=~m/vZvs^jAV<TJT;q,:?$g%3b 'H@;{6A֯XբT: OXgXdBr}?w?7k٥a.Vqɨ롧X5jV 4_ u>1hc$DE*s0-v7P"n,sއo6dދi^27w-7ǁOTo\liݨ>YfOU$iWe`7j j*L@-00|FQQ $ $G3V @4cDPo7kJ0ißh=&cY6kݯ~F=j_*fԣF`QͨG54ʣ:ΚQD ~HZwP$3F>+Z)2Y)̨JIQJQF r+W0 t#؏P:z<~깊FaqcTϨ#,qQ_cu51k gL 0&`L 0&`L 0&`L 0&`L \Fm a܎+Ζcpi$zd5rHœ`TWG `Ԍa X ՂcqE]XLZK->m~=gĎvc#6JQEh"F=g#rH㼶(9mGu,0jХ Qf D(K-c7 $s{v@HGwՒ.ǝp Fnk AiY(NGq1E*B^&V߈bA[,< Kf X"EFͨyT+C(XW":·㜒1eS6Xo»2ƽ2KyB'H "2G[q{]Yߊc)\l^TX?/n&Jü)*|UX;ctyKևgq'n5E8քxUZ?EBwU>Rji /☼i‹&fjV X>d]-o C}mQ"u`9a~]J-(/D!#Z%8/tzٜr5P:6߈b JGS ӸWy7Bxᄘƅ]xei 6abGiD$QlX+ 4"G:|#I=5=k7EZA;.Z7Aafi LpOQ8{P>9dF .uaxUY`2 X"#u&>H+(zi*3PdN҄f;0C &eɲGUJVS~ލ8'R샖\`'FM(xTa+ +c!@0hd4u Ig2a\1t 2ܸE?5 ME:zrY&=itո[QN>wGTe aԏPFTfԧ?= Ψ5ꘟ+ȀZq{:>vGN9( z67jB<= &)Wx`ɾ%rPh(E7Z7!iH9ӟTbYTY-B eŬ5<+8a]mƢj-Fa1K MVhga)@2Ǖv!d˛w\wC=*Ww}.Y6x tȚz~& ޴&*=~mR/6Y'w[_jAyQSP+}hıXFKfDJ @.Z FͨyT_+zH\0HwH Dw9E.G9Piv\׃6Cïک;vƍep0cƜ {Q#KƔf4^8 6ꭘʹ'"L Ï1-{Q1jcQHa](ԑo<⟍uzQ_TZ&MGI6˲QT$p}i܅2c9DMz@#ͨG51!\69Rx?$ޡqc;@$3F>+Z)2Y)̨JIQ/AaRO_j0#z&Q'3Ɍz&Q'3ɌzrL 0&`L 0&`L 0&`L 0&`L 0&pEm[̀]E gq:ڛ>Fܣ?6RȨSL4D|O?v:pOY(Hm Sa41 <C]} w&9цtL<]^>@L VrqMߎNG{,Gp%?NҴE3P%]/ X~A~ONḯaKG (U9!(#" (."8ebhz\DۃmԤ VOawHzTe;QY@XMySU2Qk0Aj +c< a DOHBOXؗ\c6p;Nr7b~aKұKi\΁U=䁛!pB-.V4xggLRtRm QȒK,smx/WLMZ = j6w Q:x%`^:J2A.Ao>Ǝ5bCmoP(U¨F8V'+ 4"GY(6@Lcd(Fi~Y/M%T284)&!iq&eɲGLxhsZ?^FP)6J.`1鸑;VTO;.Z7Aafi LpOMR8{P>9dF .E* LfKuJZ`ڈQm4X V x4 D 'Bı P x1-$ߍ t׳vʲ1$K#ih|Q̕*0u 2ܸE?5 V"Ch=H~Xጬl3ă6i\CD&6ƨMLcՑ $": ă 4$XS wStE~ KΜoSêr-Y8v/e)b/+fatz2Q2Y-tO꼳ZZ`.ۊM^܎_qGE}YZQ3FXHXW("V r-E0F,nl>*Tnu nSeYhY̏PFO;fԧ?E= ~?+ ƴJ9ّIX@%CG+s+sO5iUTֳzhy\n,i1j QD(jȀ Da2`\ĞLƚ&~EZb},PV?|A^*CdQK*ԩH/+g,m*̲s=rBρdEQp>?Q3Uri0HIsH#K̬^6YE7Z7!iH9ӟTZp`ItQȰa7 $$V cQ$]mvݰn.hkA]1=&qO ɸL 1?Mf2&`q צU@(f`6` <@NX``l)ASL륺Q}"ʔ 2xi~2F?A C%{=i=4 ͛M%bD9-aIFQGƣZ HOH4g@Ɛod*|~ 6ʚe(NC *x`\TF} ƯQr R5JF5HP&l E?;zX utƨSg0B+%YF>+Z)2Y)|Nr҇8a'#ԇ||rONa0dI,ǨSFl:YR)1&[N1&`L 0&`L 0&`L 0&`L 0&hEuW"Q#7&=œw35ilT+ɝl9F$F4Tu.ϨF N`Ԩ-oQTa-y}ҬNF_wF]XL5Ab!Q[(NҌDuj,RNEY7F͹TB?/ ؋cԱLNaIJUQJ0:iT 2T &]Kz8F$; Z߈xin[(<D-ѳ$l 6Dϒ6!c&Y&daa&@ 4UxgQ6P\քZG&lF=ls2,. qs,` {̅da4aե(z?wzI&ؒ6o^3w>4D|O?vZVG8y',^ Satdy07!؃.aw&9цF3tzj!0 +Xl6Y;:nt  8I3-_FͨyTaºڸqi-w aa)X{:sq jIkn&ـӆy7?:FDHUsP֌ɜ7PL6|ҫ%?];5-7赅,"!/oD b~c 5K岋WdlV'C&cLvnBC *t$QG5+ҙ-wqjhݷ/Zz\D\?`=5)Co1vDjKU/* _Aeax g>* ,DZQʼ%TÚ"kz*jh]ZZ`nl8&p /|l,^X߄weӍ{e~iJ EH "2eƸQMAV x, $Ea,X [Q(|D/s , Y!T1{WۂB؈4KxȂ~,L(SVi&@L#"qb 4FX/PDaa0ІwbD' f(=Y(DpLtLj* LfKyħ,_KSISdЄf%:0C\N6) L=ȄW6nlt9 bBj(7}׊7iEF2jc(&@0h1NX/P_EX-qZGO.+#4Lmm*@)V8#˭ 1:\hE;k2uƴf76LӅ_](<*=Wk|fRCΓX!d)!kø$S Ӎ[S#ьj%:DQk>RxT V p D D)@@/Bcs2,;»~[[pش\;vD-VK'Zd/`Y,ޖdU刉NZr<^2$֒)b/+f̌钵bȲhŴpZa1CG"a]a!Zg]mB-@ FZ)[|^Hkⴞ8PGkmucLSOvj=pfJ>ո[QN>wG#&B2U0g}(Q]t|LW_xŴL=$[N2%eu48gZ@Q=`h@X @V FƵS 憆 s^2/dx`Ɋ⿍ǁ9]7|M{rM67jB<= &[4P"ģH +8PXe $2 S."Gљ.v[!rIV\fCsi&<l&k`Q/zmZ% +#] )7b>m~lA_1=&UwW˅혗#q"+r)}C+>rc~xq_vm fTܹPW,4wXuTH>8KfNv wmfQ_mEu %jΰt^i-~ ~,o6QK ߁r=\ܭ4tQCO0jլ@hj}oѾIbbD+s0-v7P5{.vfL٘{/ڢcyɘRL|ށЫ>SsuDd)?ATcZU\ݨ'ad3m_,FG5+ +hXI?u*|~ $e(NC *Ӯu}QQkG55Ȏ KMԐċ=nuG :[`HR:c)RQ[,N Œ duJYI.ѐ'l𤣿~уh%jQڗͨxT3Q#0j 5`L 0&`L 0&`L 0&`L 0&`L`\;[T v\qEJ 'è{@ ̀ F/ F=j_fԬ@XWW dP-**b5޾18+R Oۦ?F$tlt ;oug1TGuҨRdԩLՒ.ǝp Fnk AiY(NGq1E*B^&V߈bAfԦ!C=藍R!F|LW_ji!z4U)4';25IdJFːCӣJ \GZvvlǁ:ZFn3gdb|3P3U*ߍr>YCx,,S zF-0.bOY&@ V +"t,(Hb=auj"҅ 4t5^fٹMɊ ĢrRFTYȁd %]>"y1_|@u.>ڦ= &T&$`)sJV:j΁>Y(~8ށ㽘Ux՛ȨuA£:$V +V Q? u $@" vW˅A#q"jj2WRV|4S1UIv^B]p#Ր/r7j)80AoGљ.v[!rIV\fCsi&+Z)2Y)̨JIQ_ Qu_V~CG>Oŏ2QͨxT3Q# 1&`L 0&`L 0&`L 0&`L 0&pœw3(6 ;r,hozd5rHa "Na0Nu exY}mѐ5xcKۯ;#,}_[å"kiw Ȥ@F@Q =Ke%\3TY*˨-,EReB\n7xȗ F 2j:~INU:UIgIJUQJp0´W2޺=x-גwВeyZcԖǏ%zM$QmĨM0,G-ѳ$l+,~_XM$ySʉCWY`!z:6߈b%Ԃjz4.*M^8!Gm^+FY3$D8{j[P^BGY%=T# fP4Ikw67jB<= &)Wx`I_|@uf:䎌z(N<!V VXā dH{' >f2&`q &l@/R7` ƋЎ)=jZ*S^c\EL| |\4y982)"7#7槉 lGQUJ8\k/XxJpj0ISp`DY!3]D3&>>>MyQ3jUSesKuDd)?Aԍetߏ1-R7*31-n0T׃6CïZۼjZ]B.vMu"2 qOyTkXXȨ)2¢Ri\7m Qd,FqWPU $CQ'CiDd`LF a#1Ju2FDfܡ&,E~/v]W$3F>+Z)2Y)̨JIQJq:ɅVV~CG>O*b0X>1CUĨ"4bzPUЈ3C1&`L 0&`L 0&`L 0&`L 0&5f%vq2"7}2q<! z7d_L]c[e#Lֻ8ٮ=p\fPbGIr 6#mi <87I1;]~ac uV\PA .ծ.YX_m;=}V,Wj\֛ G-ۢE`Qc8HFX|ORG'%3keQ.c[)c 8ݏ%PZ?JE w6= zˆ>\_/=iqJ:{b$,0`a~[S $EoIa/4n#i}wd| :D- ǫ`4R4[wYw(#KjK ,x{ Z=oцn]ۿyܙ2a,~,bn78?nwڊ~vX"5mDnܠN$׎ptxq 'zH7vZ'ǂLt8dygXwK{7zs_+`O2X 0"p=af^g3MR'-_8pP)RINkX/ڃ7۳/+zsvj$xԱR˞]V4;̝K̡Z5e&[M}jÿlyeۻ^tE1|mޱ;et8{\>+u}[Oz#%៻\A}n}ﭫEk?9!8, DFXiJ 6_AcMXZN_s6LF|  wZ$ܗy(-K 9( Wz5C/UMWr;c!̀Ӎ{@}|yWuQK /%?*,5/fkZ'a[G;^o+bp޼aNdd8&I/Z.c+?Xw?޿W•]89{>}?2ak{_~oo %:9ۢbhaK&sRmx/WLMZ =ڀTjE4w Qh7<[[S Sy@6v+տP[8 JU\}ȥdK)aQ߈b J2GS ^gq9V7Bxᄘ[]xei B?޻?Yr\m۶m߾=*O{)U;_X/k~8|ɡŘrǷe+4\Oz;=/~p4ypWn; w^ٵgWt36!JOJ8ZU墚j?yB/$]| Ϭ,wW<rP8(!߇YҕJe5T\ܳcsmyl!!SíO)ιz"Ot)ޖÏjOj\@ݡ,o 8-k)DmՎ֍pPYZh;Sz"ܓT+Sf,OHÍ21A\[xUY`2 X"#u&>(/륩$C%-{;0#]Ź.lRQD&RTwcI%zpݩtHkm92,|aㆄ^XMF`l|kcHs8[+-0!|r̟cҊff\MP??* LTE2熬hI#$0K!ϯF̽o~l}zǭpSTsvg;pP9wg; xwNG x\bpͷEq[ dtiD^h)!ѓĪ)e=Pr+CL\gA;k2uƴf76LӅ_](<*=Wk|fR2!d)X\fyqHх36NQ‘qH~M9Hц(y5o<1^aa>mih 3Ӹz U)&֯ɽ8B#uH쾃JW[>}ovO>sx5dH}ߗ}i㿍/-juv[LGՏ}(mW,Z`q~Z>@jipaS@ox)85܅t,,-yYABIbL(%S NbM2q73{xC=|8x Yߺg0lT]gME2K ϓl"~a:x f b=ޚ%Jɒӎ(lEgteV 2G9'\ˌu0O  MEz{+=uE!iN>4XM U٫*[jOQ-hK:!N%+K+A[˧Os_,M(0aݶ6M_.|[O@tSrRFT䳇b+WsHGTBmhx݄jݮ#xNMBEJ9X,! %_;p YT23: h╳]OmUaS7Vsb}a|NXr~L˚{R} c-€Яb}G=%<țMPw(W;zCvj͕_KzD? ÷WW/hqY _]xYt 6jf;|K;yX aMG_V|[_@2b^B]p#P´!Ս" q$9J &TaCsi&4wXuTH⚈%3BCD64ݐpw&hUVZ\|]hU5ɝa*Z Gq^=>QA6[j)V覿v=͖|5dъvz&Z8"ּ}O)tl {cb&L$Iܺb;ǥ.-('Qqө2ЮMK&^yE,I ,~䟟\!*iVz9{6Ο)9?>ex(/- Ł8| D УjaqHt#2}z1QfcN콨k~%cJy3yrC~LVfFb5S~'cwL`2S\c{:jÇAQ G҅wx&ۻ[^GQ|޻6 6vb!I8 ^Sj.O3mut`.HUL%hU"QQi2ҨiFyFBx&HEQ +H ĉ8ykl9[ko*}{]1qI_BJ>?- νrwZG_Ͳ&@_ߏ 0 wҽ[/  4MC0=V`os? iiڜ֜> `L`625lI u *4nː8glBX,bL 0,'=Pg.x/PA#yb21z&pAL 0&wƟQ/+9bn.`L cpY9 n&`L 0 `L 0&`6H9C&`L L & v\q376}h;4.b60[3P/f͸,& nQ6BA"J}_j"Z_#Z}6$s yNz~&-ΊvBΠqyO#hхR`TC k.=CRC3&2@jj u0E/%]JS~:P<)g7,,n:W 0&1RzW8e-%:DX(;X2<2y\&@BNf# u\V\]2:7åHV [ fqzx:cxꩋphf@$XsλsD !L?.RSԌA2ƪ`^`J@e;%t `* W680Ai֋3cU/{pJ?&\D,mpM;8d |A-zw3*A++FU>`Z^C)fYoacV4'%*m F)Y>jl~E \ Y_?Ў:{ 85q{εG{sZjAW"l/ǕB~Q)+Q س 8+hd>.|?1< AxM-%u`GE_@qMKjJ:Rs@T`1\~~kV ӎprT ?Fd (6 2>_<ꓥۇG:n?:d}.U <8_lu[EpV))x Ǟm%<*$2gJpNHSZ*I|߻!\{{qA l0&rw-'V Z򸖰HV=}حY)"_:"h?PZ@3vShMJ}[5ewH^a_djnpaڲ^0NyQ:壺dT`,Zč]zI+p 7]p+QeQi6ڍub WZo3&rw-ͿRhZ´Q0A4#[T`*Jۏ}9T$A8F\>6 }AGC7\%  -m]~"V7?8[Y&/ҧ#e ~*ĎAQ]%C6GʟL 0#"w~3*qSAV"=D|!G^KAɓ0|QwZd%ru2 hP Gdq4Ikml$ 9mӘ1h srF|:l:"=LfL =_@4ffp .&{Y䨜 *w-ǏD~(NQj{Ubng#I؏s}h3DNSsb|j5<ħt؞R1Ic$:vq&@6w5wƟb)h)0?JDe)QxҥzS*yԳ8\&o*'$ t%&4?Ȇj9\{sP[ ٰMux___Ҋ_Ѥ>pJŨ)3;Pwbū^ZLB~nq*W KTϖN|NRXgQCMN-'WJ\(G2ri*Cs[Jjqr('Gr08=@/v nT`$_*\唬9?̺׷I_nZz_]8M;0 }}.\Y8[7+Aۏpk -U7vv1#?3P*^&@Ȍw5wi@#ig0wY 5BS\>I8اw OHX6]ZUBr?j;{YMNҊKv,.#8WًϤIj6HaNezڠ@*)iGҔn|%^FMwtP!9j ֚WC`9D -jAD0te I^X]Ű*P"Gp r5&kh9PnZMbT&? Z̘yJ t .qI]"FS6kqܐo&dchUC 4Aֶc>m s4`L + 5&s8! $JpY m?*uYb'j|?"u,s]5`KJ_Ɵig1'l%~|gh8b؁V4? h n'`L OE|\[_FTľ4%WI`L 0'G"l:yn}/Vl93&`HŘ6Ց1Y`L 0&@XJ3&`L``L 0&R% sh0;lvJr^l&w>嘹a2оr~sO> ?'7C\S[>M1*a|.E* ]R 6Sק{Ã8vNVv-LsR=A߱1Gt݀} 7<.0[e!D id*`L phB7 K9(("V0nr\)픢RJIeǞM]EbPQEܞЂO'R̈́`Gkzn!(V_|TU!ʋph3;, C1z݊rXŹH4%Rl?u"V↨W:̣[5 =q߮8'΍khxej` p98 9*(f!9b=Dz }6U l g8։cCQyضF~);8!Mej&C|6hp=WsE)M/E2K9ϽMRp.gY%h&SRP=\F۝'kcT`}wС"S\'GӅjR @JC9-`L  pSnq $+%Gqʋױ-E ;;8V'n\wի'a7t9/.pZӧLO8*fWNl`ӇjH>1 qI_!S-Q yt;Hj7vzڇ5X[v YЏ[[ MqKrk9mJ@fSk,fL S{-Λ!jqE,›Ũ[RR"y, ŗC3 J( `GJ|qA O^)}`8568TE#1bs8FOHh>6kwB",Vsw-s4J.Qk/&HHńhEdv8 =[5xne(/'ZWdJcCa1_߈OGQ[mQ_Go rTO+Ģpa<#B㎶(ȥt뗑xLG#h >Z`M~D h&w)2[GBJó \ǹ>&W=s_q@d?QcT^S*:iVc|`L_% ^9*ÕU̐䍻}C P3kIa qAL 0& p8X3[B̖E>\S9SdqycHo u-Z]`\آ❨#$ ˇТ $$jic j|Mh-Z=)a\to2/eM%ѡI&sgl4 0L`C%!E%#PRK޸?B=;{l:D*Jzޯw_Se&NA& Thw$% `9J|w@̖9iɺ׷I_nZ_]8M;0 ز}џyvx Jc;BK2|0fatuBД <# or*}n9=O,xR6FYKSUbWSC zkp#%(gek&FEձNb̊nqHgdbT`O7vT=k#}4(ؔ!_M+FI=?$3.î=3}Be)M]ڒCJ`6R OHXdBr?j;{YM·FJh/ТNqAL 0&` ݢFbotsT Q@*h>'`D0h1c")X'1P,_4)‹at9^Sv oi/5 *C|'MT"UC?A3{\Xg54RQ -}=Tљjֶc%n&lF3[LgC8wP%Iqh]' -AUQ6ryG='ׁsz wu?Y70PͺiǗ!qˉ#؛BX,9]19㛙`BՋYn@VEa42`L 0&kbEng,3%ZN Yno!: !%"P/1. 0&]ݢ/F%vf6#5uԗc)8=m+Qig>+R`!\T橖 l_=nik ރ^\~5Rz+R$K *$Xx {pkV +p dc3:Ltn$vgL 0s[̖0-n Iukq,Gz --&Ss8ׅKt0і@qʋױ-E ;;da8V'n\wXL^+n2s^YrP 4]:ˆMGOv!xV ǀy'}N1HgU̓g-PIʥ7ꤚ`9LŜ@+ E8F\>6kvF3Sa᠐YĿph˅~>r7f1ꖡQ6@[rzR`2 %呺v˫RIS$'i@mX+qJ{o"I{ N`_FZr.Q'Nu-H8wS9Td#1CN_F1Eä0 y6T`Q|>8ׇ6CO*-fW$'o}tU1!>N$jEpe3$1y`-`7yP b -a&K$:4IFRSHИU=]4nb,=:D}=چ~́_DE# 1ֵhu^=rUcw<GB*/B2dǷՎ% 6u]xV1H&'aL 2txWs/pH -a&rPDs*D6#%'[ #pAm-dV4麆F0o}}}J+~=DeÑ*}bTS|AƝ l;"fPRK۸?B=c6RʹJ!y-dL &txWsooiHq,a~Ia(cStT 3RM9"\ c z"jFFnpQNì+p} 妥>Յ$  hWleՉx h1Jc;BK2|0fatuB; <#j~pˉybmeEp TҔy6Ս`LHEE#WŹ+ȯl  KHxT^mg/T`aIZqw]/5ˢNui"LڙVl 0'jc~my;\D}t+(J4Qj#h˰6HMBPS`!4魠/i#nP`Q9A Pe `p*&@nQ9-Q|T|Y` ٟmiK*ZM4N:abDSMNc0v#K0rC)\|4MMCSgt!>WՓb*&56f*MPmC[j| ɻ$K@\6' m?*uy`'j|?"uu67}NmϜ盙`N [_-.3Μ%"Ǘ!qˉ#زC0fl:bL 0&-[\'" ,B扃iV 7$O eL 0&[\|B|k}Yp&`-FP,Ǽ:r b`L 0&X3&`KFEؒ炙`L 0\&Ms(r;8[1mEO,7Cf`f5g`L`-hSC)7DI5`S_#k} 5=߳'B]dco&X4-'hi8r\Jhu<?P q(!x2 0&n1MQGM"L5*%^J#ВHQ<`L z\lSM",DgxcL 0&$0KԉTM <'7C\S[>M1*a|.EZ ]R Sק{Ã8TO]@=4"r pލXdC#n>\bqFSA2ƪ`^`J@e;%t `* Wǒ Z/ΘVKp )@/`L wQ-]bqE:D,yMqMCPʡUBC:ʋph3;, C1z݊qXŹH4%Rl~E \ Y_?Ў:{ 85q{εG{sZjAW"l/ǕB~Q)+u8&;lBm/S(岒ܞЂ3u cL 0x[RXr["-Gj&C|6hp=WsqM/E2K9ϽMRp.gY%hQa%tpjX*ʿhd|zOn:[d|*ĻqpVMJ7$ZB"nmY}& {ö4SgJpNHSYF6L 0&wKnt@̖02= 㨴\:-b2{[ dzR8D;.8+tE:V6ngI_ЮZPkqyba! ~ p8uC95Re% EaulGu$YX{7( #׻]2Wn W'2jI@IDAT2&@2[$J-Λ!RfFQ6a]a4Sb4L)I{p 'l/G؜+97A=5ͤ݃|П  ]C\.S Y7Q $Y ŗCdKqPi 4?y LDt:0&@B-@į,rF|:lta|C>J'̤gXEc7g$_ظ0GqCN_F1R3h="=i|MUљmdb!}9v3MccCa~6C`L  Lw@ď,fhS"T @&!Ԓd/*fHba~|2qgST`t 7)lu8$X`b?P9Mi'Oo}U1E6֖L 0&0-Fep8 l #;Sqw>R!|-r3zvڱ5>}n7 [`RKS*Li7D&VBZR4WQx z 0&fMŸ2[AzSn5kq\-8MAeOubM."cXUDžuXCρj,blBUB5aàŌ `@`bI4)‹atej;hPp8`L 5bu@"YXAǏ.(k*O`?jMh8s|,IΖ 0&h5p3[#s2$vt9qwE2+F='||3`L d0J4̗'f<8o"Q/z. 0&ҏwLFCS `L` kpgqՑYXn`L 0&҅ty\&`L ˩͍eL 0&҅yb>D Yn 젳LUkA [Lņar8[+¨L8 0&[T=׺E/K->}{ yNQ@}_M 0&rw\g8R](FY6.O%̄C`GEZGIf |QC! ngKWJRJr۲u@&@wuJ=]JS~i:KU|$~saL 0&[|ճO7 ƪ`^`|\ qiLpx5~l3&k8c:Z>O> ?'7C\SЙ[>M1*a|.E* ]R SWxÃ8vNVv- {y7cc&Jpnx]2(lu'{`L \@?D"̵GT|Թq [B=[W GFhDM4 %žM]E#q9ڂZ:D,yM-%Q*4D3BymFwV(U[ѰbT]8"3dTMT.2T$J\ Y_?Кyt+8T&['N;Q'NY-vg#HUVu~tȉrNӪI䐪wnvh*63ı表ҽ 2]xlhÅz7 [Ѥ2ިJVz&5?ˆ#UbpŨ)3;PwHQd>:@Ԓ7nϤaeة T3mxRLO}-O-N4ɛl8 -tN:vrB&@nn1H %LP] E9%G-f뗛WN*j4L`¢eC__eՉx 0bnmJv>{L0[::KqcG M79k؞'<^)E؊rڶ`KSUbWSC6aN$5eEd4j1Q-rhϨ@XTšeS`u^|&LV+IF{c'H16GCBMݼkd˽niDCr=2Zk9Aq+$]BMФ8اTmBF5@62Y+w?ǣ2&jVhnق:N8 0&3[nqڏ}Ib"1Rʇ?f*{mN1`S]H㒦YH0X`jS9 Y:Μdk`2$vt9q[JE2+F='||3`L`QzQ0Bu:0J4̗'ѠyZ]/p?Ģ=.Qg1&]hϑQ/j.(EdON*̪ǹԍ:r3&`L g-dL 0&Ґ4|(\%&`L ,|a܎+Ζcf̴>Fܣ?!Ct׃iCKEڡ^b\<`L  ݻE3Y=.{;iׁxFj{qvs Oۦ_ojpw1DXg1&@[T?EP _ GGJQ1zYn,7 0&0]ݢp^DE&T)RJmR>u(d$o̐d)K)qj2&2@Jߔx uEat< )!<:'7 0,%E{ڬ,? ?'7C\S[>M1*%uT ]R SWdHk`p(sXŹA7rEb+qBs(WgcnŞB=zMܞsk>ܸVZq{mTJ9o;lBm/2(Ye%-=Op OB^s AbT壪 ьP^C)&oaia->).)3qeL 0[Du@0~N:Q85l,Xs2>_8=m+Qig>+R`!\T橖 l_=nik ރ^\~5Rz+R$K *$Xx {pkV +pZU?`L >#wDY-ΗcdtShMJ}[5kwH^a_djnpaڲ^0NyQ:壺dT`,Zč]zI+p 7]p+Qjaf^'vٰpn5zJ1य)qlQ y4IFT%9`L ,Ef^jdPO!D_˼{0Z П  ]C\.Y7Q $Y ŗC5lQ.)ԕ8#ŸR*+P$'i@mX+͆qJ{o"I{ N`_FZr. P'WQNainQ2CP]H Ղ8㔱Za< H 9~|d͋$ydnm5yV ޶G[E<,i̘C4W ͆9Wp|9}#>Em ]a|z&@Rf& qR=!gUW4-5iK&C`-fI$&Ώ,w-@~܏O&(@q ,RNԣr$F ,0pf(Lfe.j5pt؞R1ISc$B\@ͫP ug/`L $&bb6ƘLQij)3%L5+@ML$:4IFdMCꁍҸGvh~PFf3~74p.Zע{U-*މ:L;  |-ʐABNTƧ/Mtq|  L 0&lM%Ѹг(r6_)&'ヨz'M6\@J:':omBklhÅz7 [ѤKH2ިJVz&5?ˆ#UbpŨ)3;PwHQd>:@Ԓ7nϤae:s&0nQnq $%k؞'<^)E؊re!jd-ri)1>EG0#Ք:POr`qz^DܨHmU.)Y=r~uo7Xܴ҇pW!vVa-Jc],7:qo<-&\ ~l[[hҿ],LN|NhRXgQ\M&%Y⊻E#S-a)>mm 7*gMj4ۢ!9~ G%m?j;{YMNҊ i~9ㅰfYt.m]dI;ՊmRQ>p̯ PqSb7r st+(J4o#h˰6HMBPS`!45S1&rw9-ΧI(mh,ª|埖DžuXCρ n,blBȉ6X'? Z̘yJ t .cqI]"FSn5kqܐoichNV3'zҀ-i7Pء6`KTfL d5[~Y-Qd_ɜG^^UhOD`9矡'CkfL } r8/i$'lZ\ː8CglC0fl:bL 0&-[\'", ^x+"TЈjX@S^ltDr8`L 0,#?Pa`X[4`L Gp8:y.cL 0&0`fBL 0&Xx,1`L 08sh*;lv2ݛqb0Y-̍-@0y^`L 0&fYyVCY'ިNu ޾QPGh7jz~6&H;-.#<PA!xjUи<(:C ,Fm!L 0&n[\'YN^:.JAf+M)+㷚C`L ӥ8Vf{8^2!̌iW 0&|nqHΘO|EYlJp )ÛsyOۏo66}+bT=\ ]R 6Sק{Ã8TO]@=4"r pލXdC#n>\bqFSTA2v`^`J@e;%t `* Wǒ Z/ΘVuLk 0&nQnq>" Zp{B靬O OiŨGU;WymFweU(U[ѰbT081dTMT.\Q$J\ Y_?Ў:{ 85يh@R>JZQƵ4<Ԃoů E-^+#hR4WpMvل^=c`L $ ݢ |*WD);8!7j&C|6hp=WФqM/E2K9ϽMRp.gY%hQaRtpjX*ʿhd|zOn:[d|*ĻqpVMJ7$ZB"nmY}& {ö43Q^&0n1E]N h $%l \qM?yqI9iG-j7׉l{[ dzR8D;.8+tE:V6ngI_ЮZPkqyba! ~ p8uɶSx0mY l/y}t~Q]2 z*CލBA|.qWJFNfL s[PqA O^)?(Lr͆Ҟ'QQ)0yMPL;`֏pr4͹sS#Lί=hgpP, e8 B?Ѡ*ExuPJ/eP|9\P LFauI:R[0&@,s[G9hڼdžfDc8v0!=@@!lfrXEc7g$_T+JU0Gru2 ȄJydnm;ު̶H2F;s1`w-΋1kT"?H(ySyI:lO}Z1M~ .&{Y WV1C7ffc瓉; P3kIal!|qmrijN[8y:n9 0&w9-΋Ih h]V#W5?6'3 0|$B!dvڱ5>}n7 [`RKS*Li7D&VBZR4Յ$  hW MS* 0&[̩nQB Ht++{%(57$3..`"9wv sPS`!4uiKi}H&oTNP>a#ai* ySx<*߫e ?69I+Vqj-gwu,.#8WًϤIj6HaNzڠ* 7%6N;60Mu&!b#|*z !oSr p6~[pK3:^X]T"B6aU>ch'a` ,fX*lqUMD0hL")X'1X2Pء6?KRgL d3ki;imYa\,+99??h[<>'&H@6}iaL d k0 YC{ZCs¦ ]NqF!+X$sbs73&($P,€ ^x+"T0_m%iu~D Fϗ[@vw=GFh#@v׈ 0&x5xsdVGn"`L 0&ͥ1&`L@`?&`L ,YLmBG",w]Javٌ -jb0Y-af&H7nq"Gh @?8:b։7*}韛6!&@w\INw'GJѳtj˃M{QK7WQp`L zO$و0z&:2pv 7g@Ҕ襔8g;ꔁ L 0Ywi7D/)j1Y[7HbpL 0&@NwA`wcU0/IO@)k$Əmpaqg]epOVNhބÓe )|tg w u"Y.l)q) j^s AbT壪 ьP^C)&oacV4'%U* F)bK  (7D4Wgf݊=UV艓^rI֓1&r[T?P _JFؿu~t9NӪI䐪wnvh*63ı表8aW!+IЀfڰV4gT L{SQL;`֏pr4}Вs?U#Lί=hgEm={`L !}Ws1 Zщ4LVM#q~[5xnI&fߗh1c4f_<64_;t%FwuDJ!L0,IB, 3R*t0'. e$ш*%:oiQP9fL 0I`i-f1u16€وCRF.\ ȹSN[e"j5xO%=bfh?4IZ2e2\Y IL޸Q>~74Y)*0Sy[4qjAL 0&0['"Fq+cѡ4%6\4gf"2o,i]E 쑫[Tu䙄w>R!|Z!^?D-v,AO_X~ULs(ҽ|6D&V̝iule 0&Xw5w@[lGB6Af4p^Am-dV4麆F0o}}}J+IϲHE1)j 6TRTz3~wH\m܈IXK!˱Sf~tZZh.7pr Z4霖uL 0&j#?ĴT LD@ܨHmU.)Y=r~uo7XܴЇpW!vVa-hi.ˍǬNO! ۏpk -UWc˜҉ X^+j2nJuT_M+FI=?$3.îBe)Mz+h+}H&oTNP>a#ai*JySx<*߫mf ?69.VqԊ`LH -') DkJXUb6:$A69O 6:e4.iSr p6߂45m Mj^UOGDX$C?A3{\Xg54A=immm;v=ަ%`L '\w5w~|@(¦z.i]' -AUQHbfzdqӹiL 0A =_-.گs~Qzu䢵7NA~|;8⌍CV`H 0&wuF0J4̗'<8obў`L`i phb >6`E_YU`L 0&Xe32&`iHEX>`L 0&gb0Lng1s-@0yc0Ll^,RCĕ`9J w5ws,aoTb':oWr\xӶ7%kg5N8λu",%s3&nqV u GnF+ψ. M^s o,W 0&R{Ws8ǼdG)z)YRJQBNN9aauӹrL 0!һ:)#nрl~P e J9^F9ϊkQ^]v%k61`T+B-UiD["zT5( "X*"6)8RTGJTZ!JJy`cl/w>gfܽ]{`8#;sf=p\&^\j4 f1\y:> OVv-7 c/pʏo9B͔Wt\]Dq\6M(@gU4[$jM5Y 9~7$ŅH.2q Oez/Pr=__2_7pFIjb9`c|,΁B(V+S2 +Q!I m$rE!@asT'V ܈zI4|Kq@qΏ hm߈[Nv`s9wJ\݃tc:`8e\^WǍu4 8KV_|TU!ʋo=:D@BAm|2&@ ~,\-52ahX|_-cS>V,É8H09~I%GԴA+jVc4zq^[>zҕ5(/#؇wZVEQ., Y]K񫥨æX W?) ޕW>!4bkƞT:2^c`aV7'? m[K9x^tǢ_-ǑnთcS[D#{jX h?ÔڴKu+)XxȢal#GہԤ48Cm1|ULC8Dš."Oօ=muQ|NѪ^b O1 *!aQ:߅ub *e݋j&&'ju+{mq 0&_MRc~,Z-bHd#Y'-0%8{1\٥17Ijz.ɾ^K?oGe XO4Gr^-F"aU(><·dMGHuy(! ;)J959)U-.S,(+qL 0&`?MZ bbH #G%eDNycxH拪GPQf. cȋYqȝ;7قrGO.+3uќ(moGuw2 ʘ6iCR&=W ͖8nU_$tZ 2&m<\,aZ rY9Ybl0nƓ(iOpWX}S r{2B CG)E襂|Zę̓TLtR0\]#b̔1 QxW,xc^Ǣa@sga|3ZZW^EF1|,WgJ P|>BJS+ͦe Y?4=z^6JV$*"ߢ>1oj'BNi6gfܘJh]V!W5( /(3BdmU)]LqPOq\`鱘ͤ{OD4'1Xew䄞 Ȋە">sx\&pt\{}J҅]֡ALT- ).yh؈&mB :fd& *E1*P׆pmk*ጟ 7L 0? XIP&{€|N4奸)&# /6Jw\ƨW%i&c[W 7RM9.R{)z0SԮ $"7e|s .nX8me8_Zq;N֓vx;x0ǶJ2|;Θo`/6~,X- 4&]B XrH25f*.aFd KWڛ)&;"M{-CRie&m oCOa'ҥtbB-1aU  4(̸h7rt.|.oʿo~@0"hcr"l[Pt \x cz,΅bd=NX]Ų*uEs8S,>r}tRqZM[!bƩR G@2FLk(£!tzi \Ö~78!ESG2XR?Ev깘 0&Dp?k_btF!@m28,0:iO%Y"܏~ w4]r`L 0Jcfɋ$b>/xS>[`H 0&sXe,z~AoO&on 2&H%T|`L 0&`L 0&`L 0&`L 0&`/lQA[Af5iWNl&w>˰X^8CusT¨HFÀQ<{M=^9H3kʨ+=-*q#ϝJ%Ҿ}}M#[_kwC]i290jQ2xTBV[Fm W.Œ:z2j[l g|mxT-1V̯Oȓ脌ڠΨӇ_%fF`NģQ'{)-V/]avBNڸ*WzqLE{:T6O+.N+%e1*A{" 1xNt1\y:> ZG+Q;hb8ǷAf+w.|" ¸N^6(@`4[$j%qt`yJQQf u5?'?$"n$VJXoԍPۃ= JVrTѱWǍuf 8Q-e*UUhHv"[eU+S׺hX MZ0xocԬ&1:K\Ə}bJ\e%8 Nqk@IDATYpp#v:%yɂr8BnE7S\s5?5jaºZJ~,  1 ~QX8ԁC&QX gt6o;W4(%nl=كY4=b2νMl7G ^LxDc&e(ziuSTV%kVc4zEn"d޼vy=^NѪIe> o%&J>lWՌZq/Q^ObnaUC`%LBt@޵nVcb!<nSNv{ N۰ݞ ztǂ~Q]r 2jFͣ+XW[!? m$t#̣lI(ҍ#E)?T184)&\X)n~,0:ERm hTN8}>pޜ?UXO]h5`i=xTYF?˰oJ.b-B)}yX/ ]QKa)aB(XWa ++sAm 6Qq|aCH$Yg&䝖Hq<$EfLUo:kF1mCuLZ`E~k5xݝlKv&LuH9Fm@QG +"Z>YXnܓS^WJF8hR6>d(o|Ze kɒ"*!'@eYDҲ73~¸O&Zئv>mMZXd}ŗ2 /R_VxTV &&dH V d<9 ztOX;L/ǃLf~ǯu%Z}p`\آjCmmUfi2a|3ZZX^E(Q| '!bF*@fX +INM42dhy](|ޯIagQSWruE9F=#$+Iu dҸH?d"̋IO]0B6lDkhZR֋T{uMb:P(F5$cM% J f]MDzJCq-~"Ү,3&v#+JfޮA٧/Ë2ȅ`1Ʌ]֡A#̬Qk}28VX[aJJ+yS I0gUhǸClJi^lO8+wrzN^ b`)hO-~c .-v0hKqi RF9# /6Jw\ƨ+%iu|^%PFn6\!~}J͕=O7vCmh3(YYE:pu(>ZI1#5/bPFZ}1QUdG(/¾mkb8uۉۤqWdFje'V %K%8 e&f<#+"Z KwoլviPE JѐDpzviPáZbvU;K P\ơ~tSU6-E@ȿ[Ok8"]ejiMU4 bMں9d^,z6=brIAn6y+ /HfM'!%͍,njd=f4xT˟C?@$V @b1mѳ@KOm/nh[HQv_~15i/d'Pa . K ڡgp,ꗱ)E ?U[ںG5)ZZL]s~0Ay:YQ!n]\'vpr\v5xKoॏ!F^<VLV)6kE dKFͨyTO#bа 1uv(t#LS׀q߾ 3Hg-wh"ZE(%(eP|xe =e*a4ԑ<Ai*:UL$MhvR +/m/S! E{,݆(^FZvi S]zFsFͨSFj1*X?Մx6`dċg(i8ee.mM%^d)&ߕV{Lz-1Gqx1u->Am 6Q80!I$,3CrTjq<$KQJJ\f. Qk )@ V !adYW3Q%@,dYbņq35ITئ|&)}8}'{dוe+F/8,ӅCvNjw2Y䅵dI\y,"iٌQ?:6y6Q$3@,uV V b]$,Ϭ ^W/#P^̒CsvttnEb.-z#=FM]uh)ry33n,YiɍuD쐫[Tu@p!qmŬjic jBzv \} 3Rt6OF-(1IcG dҸH?d"42XH FhvkBN9h..]!.dzm2ȅj9]{<`l؈&m :W*YuM*>˅UzbTSU( 8T )flWҐm\lu=fٝ19w>u.])OZb<3jXdR ?S~փ@=a^%H5Xx%.kߔr+pbU"8-Ce|s .nX8me8_Zq;N3vx;x0ǶJ2|{LXH˷tuv,/ť%xHuEZ/6 PaZsΨFͣ:'8@RXXX`+x0IwwwSZ`!|)2r@Fw?,6"8ilgr:IZ`O}Fݴ1GSŒKݼ.On>r-/RF[Lg\mDv0.GaѤkT] 5@62yU crCwGd_$R>yT1#H#y $’c?{ـpE?K,ZM~s@J+si^2Uz%p*[߀6d~N=%0X$1::{P@ϨyT Y| AHOd(i{YPG&Bam $[%CSM>˨{`ԌzۉxT3y#0o'5c:,&^mjM1HyF#3Y(ɨs}sF=%uon uٟo:#@4U?~s~F.y F=o$fF`NģQy;yC'bL 0&`L 0&`L 0&`L 0&`L N~:bjV @XWc9@l*UUh< ʋo=:DUN]va%>*6ix⽍QQBcX( /ʗ*:Q뀪Dsɷtg>PFn6\!~}Ǹ5Ǝumq&+aHG#i8pto1(#Q+T:9ffV 5@ZRhJ:"XƹWIZ`QơhQ+ ׎HrV?֤̒q)iciuSTV%kVc4zEn"d޼vy=^NѪIe> o%&J>lW.,C親bS[D#{jX h?>%Ц]J[lXxȢal#GہԤ48Cm1|Bx6,dgh± _Ʀ|TT l'k嶺(>bhU/k1wNdJ.llT40jB0]G 2JX V 1ub MgCMOT7a?#.QlΕ]ysROy컰Ѽk 7Qafi,þE.S,\WQda,tB3&Їm:nq˃0529d'e]X)3jèՀ/j+s!@0mP J2DHOr!9yɓ8J3t&x~P 1Ь8B4{Β,!Gq2SMz6yZ ^w'#L1ik=$esl??ËkjKZizN5`z8ɣ DV D3|1=mb\F3dI吳r\y,"iٌ;lQ?aL'- PlK;&.}8}'{dוOwTTU6>d(vZe3j6Q$3wZaF"ad!b $yioKM hFz,eו$&VjC=6JV$*"ߢ>Rc.|\v O#?3ƒ(_GJ.E{QG "5nèt0eQOBè%ՓE!+Ȥ Da2i\΃Itv5+~'1Xew䄞 Ȋە">sx\&pt,R=K]:4Ȼ#ta# I3^_dEm4P8T}(QMU 6kXS7xէQ3 Gu()E@V @R~H()E@l{€|N4奸)&# /6Jw\6yr@y[Jjqz(Afi 'SԮ VE a%_O`ⴥ!هd~bk510:٢WZOډr1T{ 7Z*APoa"-ϨuʠQ `2yuFBG5HEJH } U z$P䱭;]bua8˪@,Q4mgl=P_2X7P'Q0CŌS@ 9Œ4/*PGCʽp-oqB6d~,fԩCGu*G@ .@XDX|V'3_ΞP=ɖ`g GٟmɨgԌzۉxT3y#~YĄw%YLCoj} $#F>;Z92įIQ2/!H}pDbWM{,`C+'YF>;Z92įbY&`L 0&`L 0&`L 0&`L 0&XXCn[vZXh2]0L|a˱tyڛ>Gܣ?~JȨsL #x%S9]3ؖЖ[Uc=~, lѳ%l9IvYNv=[¶/GNx"FX-{"1t9F='QgCiNd`̦F 9a9a }u5vzPF6G>H= .x0N2Q\YmJp q\1S<>0^Kk8AU+%e1*A" 1/dNt1\y:> phf@,F{S~|!oo{'" 4enn [y"èFm +V hQ XHV2a7IqNU\J$E@&Ǝum%+a9؁F:HZ3yI2Q*4$;ByGW_ékN4G&.S1jV%.>\QPm%.2RX_2nFpzIޅӷ3u~\(@mQŨyTz"jc@?nA9{áZbBv΅w@!uP?*"d'5@&m|*iHm{2bd=,MX豌s@8ۍC&CW,^4-͚8NN-Jj^Z`7>n/v.-^y7{Ѯz;"8ف7]^ׇSjR&FM5n@NB[f]m~,C|[ v&vY! elGuOپ {ZȏU} O1 *5}4mv .%%鳻ՔM<,OԽთ>bS[D#{jX h?>%Цw[lXxȢal#GہԤ4ީ1|B6,d`2jլ@*@Ֆ!E 0@-v,AMH/.+U^1#Hg|,֕$&VMT24iz.l~HTEŨ%F-0ֿ dҸH?d"42nIo9tZNZȆhv M]zџ_Ѥ\8P%D*F5M ŵ!\ǚJAOxZD:ƺ Θ;uaYQ\xRg/d#.ͺ'vkyuh3Q3jVYW+2X\H'[-9|=ՋgUhǸClJi^gvx;x0ǶJ2|{LXH˷tu )/ť%xH55_d(}gx9O,xjXBuP`3vsɖ))5aENzEضR0.Gai,943~B#2@ P ǥL^qO,cwSZ`!|)2nz%GqvjdE2jF=iDaBdb]dcC< D_O9/v!bƩR G@@|1Uz%p*[߀/5d~N%tEX(S0SqU8cX*.#Au_ujFFmQ D('+TX\X, g2'RJQV28,0:iO%YXpizdr9(ܠw3ޚt`0jF u@fnzx[i3ҾL/K-!}L8vc93Y(ɨs}sF=%uoQ(۶JwJd~/UN|#OxԍL?/a2jF X̎,Z-`se)jjm+Ecynn`-a۷ͨ--zm_ j 2Fma;k-aۗ£ڂYA=WFXl,8ΈI2'A5c:#'QȨՌ}2XDFn Vb8Ƿ]C͔Wt\]DqfmtQ:ΪhaoAuK9R.x0N2Q\xF%8U8~ul@W_/]%5WW.\KbTKΘ |P"Õ8Wn `yE8Zq@35jV @LmjdXWcŰ@ĀO7PFn6\!~}Ǹ5Ǝum%+aHG#i8p%[ H/FU>АEط]"~ ~W ۉۤ%H.BԬ&!:K\Ə}be(Q `"HϷb|WjXZ`8ԍOblTۥyKxI^ܔB fj6-9Äp b"#d/ R¿̞aq>~P֊XTLtR N]k"/ SK`/+fI24$ G"ad!Wj &agbyJO)y,K֕$&)T&6cY?4gw^5JV$*"ߢ>Rc.|\v O#?3ƒ(_GJ.E{QG g ݆Qe`lLV;&lj]| ՗^1#HgdԂ4VxTK @&CV +I#L 3%2_I=e΅`1LU.dzmd~ MrPwuyX ٰMڮKux[T"6T| >ŨBQ\µqdQSٮ&"=c!۸?z,̲;crԅ}6]xRo>1jŊQaJJ+V XLIX1$'LoL KFs[Jjq#K{-MS+pbU"8-Ce|s .nX8me8_Zq;NSvx;xh1Rc[BK%z>=&][::a;<"W-tsʉr}(0sFmE¨yT[ǃ~ $XgB KJHd}wGd0v;{9—2H+湒Hxx X.9O&i"Zb¨86fhQq AE\:n>7_FtJMgmS1q٥ôZLrXxM.h+L%,Ј P>aQ&_5+V V˺4OIԾTpJdR,G8f;]pNh1T)Pup} u#K :rC.\aKpBFԑ VOUIϒ0ZHsEŨ GuꯐH*G@XXD^C.F6 oO',AU"nY\F=ofF`NģQr 1aO:a|/vyqzg ,ING:'|v3j;re9ӘQۡ, lgI?vC|$&onU/+c1jF=oD<1&`L 0&`L 0&`L 0&`L 0&ȁE0LnǕa˱tD}2fGzank0oMl~]0y5fºzֿV Fg=fTb+ڗiWuhۺmu͜}Gy;#Q(#F=9gsrL欞Qʙ::Yku -7&_t"_yRУL?/a2jF X̎,ZCmy2M6eQoʳ<ۖ C=[¶Q[1j Y[l ۾dv=[¶/G$dϓ{&}O!/Q3y#0o'Qͨhz*w:o E >@jʅp~ ~Y|qg;^S>l(":+pXVC@Kh%jr̀XP?C?LyE5O]AiѦQᬊqvӗ$?_]Q~k^tarP'(.Dkp N?+8_XΨF8V a`ºϑ"~uf 8QjAYŨGU,֣CDYկԵn'VBl)5IBcX( /ʗ*:Q뀪Dsɷtg>PFn6\!~}ǸRQر=أ-N=PE:pu(f Q DXqj~,⹳@(O6o;W4H+Ej ޓy&ǡ4=b2νMl7G_LxDc&eS6X7ߍOeۋ]f5KW^&ΟNvhiPáZbvU;K P@8ԏnæ(W'52Fͨihf Ģ/βl1Es,x $Q!]\'~p.)i(b7|G suBm+gӧڴKu+M Y4w(v;/pg 0WOՆLC8Dؔ"K0P-dm]أ<0SB)qD1A Q#Am 6\_Fh/.3Cr.Y'q<$EO& ~D 1Ь8B4{Β,!Gq2SMz6yZ ^w'#L1ik=$eslgԌZ ɟ +$+ ~I@_bhcyDv؎R1FZmwE$Q^9+'˕W"͸x2Ѳ6-inBkOZ`|ڇq_Z{Oy])_zKA5Z%5VGw!@L$@LɌ@V ɑaIb!ȐhI) fڱ5!PcX~? 3RMcH캒$Jmt`IӣuF܊D\[G ;{څh/8 IDATda{s5GВ>;na@J+s%i^2Uɨ'dj+V G>YW| H,#Bam 6Z%CSx2.1iaCwŨ3zaN־'DŽYLo*g ,ING:'|v3j;re9ӘQۡ, / jo>t8G"h ~&m|uQgK*g9F3l;`ْYQ0uX 0&`L 0&`L 0&`L 0&`L 0&9 5蕈q4̟anлoMU뉜l^;ɝ2l9~!:I%:kT 2\ fݞQg*WAF+3PMޢe-!0!ț.G<;aTb+ڗi4T: FmVn:7~6Z3jreԹњQO+Eo <) ƣCpK[ucD_~C:I%:kT 2\ fݞQg*WAF+3Pe0¤xl^IK^pۢgK6FmAƨ-0lgmѳ%lRxT[1j Y[l ۾d/ꩌ0 dg9fOQg*GIF#3Y(ɨs}sF=(s v{*ǭG}/WWcedqt`9~7$ŅH{ѦǕ^o޿? E >r=__2(B @Õ8WVCc^vVv-7 c/pʏo9d͔Wt]DqfmQf usXL~Sa8BnE7煺p; ;TťhDMRcj{GA2|X*:vQ|?L<G>j^ҽŠbT壪 ɎP^}!wpZ +Q!IȌ$FgqO T[K⺌T'V<;,^wdԌLt10ZG*!-dJ i]k/V`Hۋ,VDr_~15i/1jŋQ[ j 2"βQlXX+0TFX<*,# eط~>Jj1,3)0$I0E!Yt 8$dwz>41H$Kg1j#G5` @ @@HaB$q],ɜSńp b"#d/WݓS^WJWn{KA5Z%ncyHv؎R1I!mwU&,)rT+E$-q33'[6ئv>m1jQ &V &duu\κ bŨBQ\µqdQSٮ&"=c!۸?z,̲;crԅ}6]xRg/d#.ͺ'F=*Ff $"V @5 $9@3x”]Ki-ÜKpqiC*j4catEL^Ewx;x0b-~c .-vKqi RF`# /6Jw\߸-yֹr>@{Ք"P` ToZ@Qk"?jV `Ib9`bV ώI~/%Zh^WⰥ 8NihHYȪ$FK)Hct)z1 0VpS*u+W^K(*`"HAǴI_%7=T]ϯF;yQߕ* F$rJ<6?O]tms.piuMzeB^N'vE-j-Z4Z rV-"L",|V`YLD˪LD˪LvMfH; r$8&؟ 1`LO!DMۢ5MHY-j-5/IENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/modal/main.go000066400000000000000000000007171457770046000246630ustar00rootroot00000000000000// Demo code for the Modal primitive. package main import ( "github.com/darkhz/tview" ) func main() { app := tview.NewApplication() modal := tview.NewModal(). SetText("Do you want to quit the application?"). AddButtons([]string{"Quit", "Cancel"}). SetDoneFunc(func(buttonIndex int, buttonLabel string) { if buttonLabel == "Quit" { app.Stop() } }) if err := app.SetRoot(modal, false).EnableMouse(true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/modal/screenshot.png000066400000000000000000000442561457770046000263010ustar00rootroot00000000000000PNG  IHDRiRg"iCCPICC ProfileXyTKnX%眓 s%Q"AEPTPAP$""   *(y͙꯺{v`' 6vtrM IWT)@ڟl+#ں>߲6o(/ K{zGy 4Wxd4~DL~;y {=::@"E@!"j սIv :{BB¶=ekDw|ndQ?c"?zgd.laC=-Lm-?nW+J3 xtM̎`Ƙ ;],Clwgd}Tlh鮝,?O}##jLu 7G0QA6&}uDXoqGwH}9$_i{,$`h[ÝO>z;`oP]n0]ֻ}3Ã-w3>; 7D4IyIƖcG[pC) ' ``eo> H|O;$OQio|t,|nfEUѦY9dJh?b X< 2x%| a0Ø K`m[rHsn`&ky; ZVC#ьhV Czk1脅'DGsk!Qn)iE 1>G3^$d. 쵧^1;`P!p> #*zX[ܐ!8L "p%p\-#0k$/ރyVA8X .Hd %H҃L!k P(CPtjkM A/Ih B(ŁDIPZ(-jJDeN*QWPͨ{Gaj fy`qX ց-`g9p1\ mHƢhq$7 vh/t 4݅~D/c(11 a21Ř*LY71+X,+UD֥6=-c;Ci2cp8.+]=Ž$ "!'s& %K#+&%C#95 7yy6'4x!OşcoV)((z)&)V QC8F&t^QRR RjR:SFSO9NHG Rb3)39U"U1 'T Ԃ:$ԥ7Gihi,hBhhihi3hާt.uӽ __decgg(e03 2131^gaÔT3&ss=0/n= |7hVQV+83ݬ lll^l9l^E٭ٓϳ/sprpspXd ,9EǥUuk[;w";!O Ooo=></_!_'"?~N t<,"8#,d$(tYhLRXC8BRVDI$H\dP%*//Z*D %  V.6GyO=q-Xi-%%%%{$KKK]z-M+m,&&UFTKT,ll쒜tf;7"f=G,(*cەWUTU|QW RU+gjj$ unus<$J)M>Mo*͏Z"ZZW>kKiGj7iQ9ӡ ӿh oda14175021Z4V4>`eB019m2e*jif236;a6f.`jb,,NXe*`-mߺdžݦfV6]]=}] GIXZqU.z.E.]]3]G v۝ʝ~QN U=<<tNz{kzz|U-S;7_p:`)0l `A]aaaCb*E&UQPԾhz5?F8Pdzli84 /&:O?y@@Ad))RAӤ Ҿ;epddL28t99zX,tV@@lvIRŹG<<*}c=> `ىBœEE}rgOOƜ8ezxiåڥeee?ʽ˟={ =.TVVmTVO\UXSS^wu9+Wu։U36kF\AtQ)jNh^lohuji|Mĭv dټxw#c߽N?6}~V^>^VmI)^ޭ@#ǚY9k h>}EKȥͯG|.sry|%deGOVV{~9[?!ff8)*#P:@7S{6*9PZǒȜw XJOL^ 0 )+ 8  hr.=S"$&I)V^:EJGMC VUTyQѢ_K[Vn^~AC1IiYyE5ƆŖՎ_wXs.DW}}nSU^%9> ~~rA<,!Tp[E'd6ţ|;UR\RcҎe$;4w2K "䢎>g~!߹c}mIS&%K˔eψ='UaR~~QՕZWT֙;4_~#`SZ󡖬ܛymEګn7;1qoosWow}}<6}1xn3:#Fz/^ "Z}=3ͽo'&̧Y`Qyifb6gNnnbB'dk|^<wΟlnn_Fó 4v &WS&TqhY301agddri[_|,t^8RD]L=%Hr(S'+&w+(Z()(r!Y΢>qREKPkM{X=4 ۍcM|L=,B,=,UmDm(#N\J]s%;z$= 9a.&*‌ `PJ$&#GDǔދ{?AdlԦ Cvҳs6i>xZ5 Ν(-,*+>v*$_i@YJݳ".U /j5k _(Wt_ϼqNPxL6Sm;w;xMuo.}pPob_GO yLHO^~M;&t<ɉ[OƧ OY$Y ՗F>v{r+?Wu7fw/ͣa7YȦȗ(J-3U*!Mz=@CgYYzpsׄw/_SM`UPHJ衰NZPX=^@\r ^TfF6]SUZ~A"b 2¨rYUK^Ւqr#ZZ/uu6u+,7334v5a61-212HTnUod#dζn=sğIKK NOzց;LI+NO;䒩wX4 <$9?wn;~0ߥ@‘'O=UPRqF郲sgQVpWʞ7z1`u#5)ˊWW^T@y]ecRScVm%[oߺwwA.>هx =z=86?50}u+;m5'R 5; :s;XR` PEb0o*Ra=$S$&g#S) jJ9vJ!khZjګttCC  O201`ecmcsc'gou;Gg_` QpBp5$deeȷ*(&(y+H2%IjiG`bno,gbnavʼ1{cS ZwX'sϜI@Q!Í#j1[œp,MaLOgZ>5{$XS> O5O3=kpn2ŬKA5_/WOӰtCL|ǶLtu{i<|,Da(Q+o&'Tew?zrqoMc+8@Q Ԁ! $lPjMbB EE9QQa./a&3ľpa2=VrIZ ]%a2HN,j@4q-tt0N13>d cfb` `g` cg(tbz]+_tCj9~S,O<]bd Af@6GDI~IbRrĽj?duruo2mgNpMYKpgig Wɬx{i7h@Ā dWF ƑuO!MhBI9u53>m4;:=q<`opLސG BA&.u37fb4fRdagugK`26153p:*\++:R\QWԈ \cN&:H[ 6KX\nձqq;_qwtvy!:?,iKLtR,gxƒv)*23/f=r7 Qoӕe V@e.W԰^I3hߘ\ٚt{n=zn= zU񜷏&Ͻ 1hlg/K,~_^>¾RC?~62F6ofvrmpl]s=~φFÍҿMMS[~|@m0㛛Vq)6l[-kH]()iTXtXML:com.adobe.xmp 361 479 1 3$.7IDATx|"1 RF \ ATQbAhilZMtI+0\':'lONՎoUmfdcG Xg|qqUrʳ+.=5UB %K[rz~(֋F*{6NEyVWnhYƽs{;ޢO)"8}zO)-2sBL-ϔ_{-2N;(OZe]SyB˧쑵ަn7>Sdi;E4(YI Jӝ{?@Swj5;/5VlDxP鯆٣VىC+8kh+H@I3><ו~J=j KԪ)^KoہV\4E85x"י#yC/yK:>> WYYkEOl=l'SD),1||_ rY)k?/B9m,3GLWSkwjֶ?^*S/z>l+/(훬C{4갅!Ή;KVPiǛ+Bw-̳cNfQi8dm_[S<7"|kMW'(ב`O.NU*])ce3Q91ۣ7R6Q_~Zyc.80R T8dޤNaOL+:5K :'l_)r,{ݬSd-z\>5('_sUnNe_oMT*nZHDW8:"co!>s1.jd͙}aǡNd?4 _^@;AW}΁uQ-o0fW[X[U0hP`KNy@eRSw;MVJɊD} _2;yu`S}2)tU'ӺC_j?S#~TG.b 괥Y^7$e_z)9_*~MG'0 tޱBy2S﹏%G~.hB*?} Cd:~^V.5Ђ*]m"3LD'HϐM>^' oNKX9Nh/MQ5cE0#K̢1B?J9.'/#Լ~:'kF_dUo-:*Xs*" Weʉs3zf/j$T)-soߊaw`@84hV7)K/R_24]a?/|5e|YkUUmڧW?TXq{~GKE+z! :!}}.(k^lvYe(q]X5ùwõ~Xl䎐_)O\snUhmUF\),1Ή 3,[2E'ФlX@Eg5|Sq[Zn :; _[Zn`ͽsZY`CDnRX솶FԸJZz`=IB ;-* !; )QhI-tޖWSެj}dy[ƿ-k0 \7) ^E%vfC.Ͳ9*[Gkֻzݐ))7ZA<5(:@,yPXnTv%ޚP_8P8 PNw6&~=;mh/h6}C)NRa9Z&|u_ڿ׮l0)߭>/$"؅UC/0mqxSsvJ=V;AW 52jJSݾvwBjf~ɨ\=qw^]8/moT~Y)^cL~aNo\{_~z`e#B-䍻NZT9cn8TZPGS/N5Rrʳ+|ZVVHg֏ʯۺ8$q!DgW_]du~oIJMIx'G津^o{Nߪӧؿ,o%,2V=c>^$Sx~Mpi.bTi/7i-fi+Su g% ^stbr?:CX9aDq#" uX;UaO6zܾDk? nhO_8izϥ8dξֳ v_ M6YigQPGìjh>WAy/v[I88v[,B㵽J7ǨXmطR^IϏ"'A;{E4(Y/(MaJەͳ}wKQ|SK3G yPoΞjUn!~Tf̄Xt)3G>mZzUjyQȺ #ag%b}(ԵΙv/4i|B?Z}w:wNvbkSԣ_jjyUoS7P)2W4{w62evs'꣜mXDD~w}=J ߇6;/XKZu%"n׿3J9!pa0?7uvE1'd^'2EJ 5k崳Cژ!F5i W;ww; _!Fъ*'}4=qAxUy6t5"% }:$fSZc^)}[7VDW@Ǖ/S>.?. .;NҷW~=#*2':w[Mxew=;p9]{y 18O=Ԣt]ͿYh;;]ow,bncz7[s4e+b*=G_(!F!RJS }YN>ZC7<ñWh.ק#Խxvh~*es^ȕ^)  Uvh+1A,_c2wbnQ}[uIL>.w^hn#b+<;Ɐ杻9n>ul~Qysc0M2'nj\K4ZO~~['2^n1FʗQ"РsK|50WUG[vo}%^neL`.kuDC-޿хfZs=)}_,/H yYZ}&D~59>~Gxr& {ޫv2 &G y[S/ad`f Jbl=,xm_B~YD2"&6q%X$b+|%x}h״5l+ٝ4.`fE岪~T6&b5"pI;_RN2 8}bb,!|Dxxwyaˋ l@ HN B ;*#@i"PN D$d. :Ө2$9 :&" .4I @tNN B ;*#@i"PN D$d. :Ө2$9 :&" .4I @tNN B ;*#@i"PN D$d. :Ө2$9 :&" R\XgwW^w7z|N ~ -T ^o@ ! -T ^`sIq(S:))W<[V8rt'^y'ejẖ=xʞiRR|ؑ 5 JTT,֏&:4٭~doGBn,v;hy}lOSPVɹ.Z%fh.=~5u ZGy8_R:[fO٣ׯS ظb#1K<ŏ.+4 k*~ǘ{l[m#{M6U˺|JO4i#e -ZX7Q@= yhCKǫ,~ӭ!̿ᚖE5o\9{riՖҰMj9 ׁ vW]Yo3,n<-Wyzư2C!ס`2xުf4JnҦ?XYVSV#g}ā=lwyv3y/_]9u+5UtuuvYu:y`ϫ~ EΟO~꼙E:q 8{?4-[^w]Z>򴿦W6e\ g>jfڳzMȶEģyS U>eR0gCuWzgCN V ѩk)ʇffSq[w {TտwG_ظ{g:7n}ZMLke;T9Gx-=nʗӸ'gh]5N~kQo;w n*;³YRmV[K_p2kl\vT#>5TS9O\2"?9CO˱4Dgvrֻ?^95ڷk`Gʫ#Բ3&]5⊜B+vet`+×1vleOؽ5eXg2G̸6U^qe.cu'6S2Gtv_\av'1xOgqcq:%5)ϖPZ*|h&.pl5$)]ɴO۳'B+^*˟W Nz9FkcaQϚ>3:Mj8~ĢL%=w, +&Z:z|W)__x[ٟgc '"C̭wgjs~ߵ^K5S!sC[u6 oNߔg@m|jAQ\4T xyArnϬB+4w#i+&t)n{6رˎyTy  2'.X\ vSg=Np5Y2c;Jj? 3>j|v'HzPV=_ۭE=ߒ9k*V,]e`p`f彫_yR5lm #(G/o4~YNaXS)i`zp :ǻ?We?:ti]Lé%IH 2:"@i&L $D$h. :è.$9I:f".0I"@tN 2:"@i&L $D$h. :è.$9I:f".0I"@tN 2:"@i&L $D$h. :è.$9I:f".0I"@tN 2:"@i&L $D$h. :è.$9I:f".0I"@tN 27!;oR b`;o÷[D`÷9SWͨyP|B=ۅU&:5܎=].:Ht8(gO@ SHm؂ y)/@to@`CgO @xsx C'@t:{JF ۰:S2 ^ކ-                                                                                                                                       HBIENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/pages/000077500000000000000000000000001457770046000234065ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/pages/README.md000066400000000000000000000000361457770046000246640ustar00rootroot00000000000000![Screenshot](screenshot.png) golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/pages/main.go000066400000000000000000000014221457770046000246600ustar00rootroot00000000000000// Demo code for the Pages primitive. package main import ( "fmt" "github.com/darkhz/tview" ) const pageCount = 5 func main() { app := tview.NewApplication() pages := tview.NewPages() for page := 0; page < pageCount; page++ { func(page int) { pages.AddPage(fmt.Sprintf("page-%d", page), tview.NewModal(). SetText(fmt.Sprintf("This is page %d. Choose where to go next.", page+1)). AddButtons([]string{"Next", "Quit"}). SetDoneFunc(func(buttonIndex int, buttonLabel string) { if buttonIndex == 0 { pages.SwitchToPage(fmt.Sprintf("page-%d", (page+1)%pageCount)) } else { app.Stop() } }), false, page == 0) }(page) } if err := app.SetRoot(pages, true).EnableMouse(true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/pages/screenshot.png000066400000000000000000000453311457770046000262770ustar00rootroot00000000000000PNG  IHDRgh"iCCPICC ProfileXyTKnX%眓 s%Q"AEPTPAP$""   *(y͙꯺{v`' 6vtrM IWT)@ڟl+#ں>߲6o(/ K{zGy 4Wxd4~DL~;y {=::@"E@!"j սIv :{BB¶=ekDw|ndQ?c"?zgd.laC=-Lm-?nW+J3 xtM̎`Ƙ ;],Clwgd}Tlh鮝,?O}##jLu 7G0QA6&}uDXoqGwH}9$_i{,$`h[ÝO>z;`oP]n0]ֻ}3Ã-w3>; 7D4IyIƖcG[pC) ' ``eo> H|O;$OQio|t,|nfEUѦY9dJh?b X< 2x%| a0Ø K`m[rHsn`&ky; ZVC#ьhV Czk1脅'DGsk!Qn)iE 1>G3^$d. 쵧^1;`P!p> #*zX[ܐ!8L "p%p\-#0k$/ރyVA8X .Hd %H҃L!k P(CPtjkM A/Ih B(ŁDIPZ(-jJDeN*QWPͨ{Gaj fy`qX ց-`g9p1\ mHƢhq$7 vh/t 4݅~D/c(11 a21Ř*LY71+X,+UD֥6=-c;Ci2cp8.+]=Ž$ "!'s& %K#+&%C#95 7yy6'4x!OşcoV)((z)&)V QC8F&t^QRR RjR:SFSO9NHG Rb3)39U"U1 'T Ԃ:$ԥ7Gihi,hBhhihi3hާt.uӽ __decgg(e03 2131^gaÔT3&ss=0/n= |7hVQV+83ݬ lll^l9l^E٭ٓϳ/sprpspXd ,9EǥUuk[;w";!O Ooo=></_!_'"?~N t<,"8#,d$(tYhLRXC8BRVDI$H\dP%*//Z*D %  V.6GyO=q-Xi-%%%%{$KKK]z-M+m,&&UFTKT,ll쒜tf;7"f=G,(*cەWUTU|QW RU+gjj$ unus<$J)M>Mo*͏Z"ZZW>kKiGj7iQ9ӡ ӿh oda14175021Z4V4>`eB019m2e*jif236;a6f.`jb,,NXe*`-mߺdžݦfV6]]=}] GIXZqU.z.E.]]3]G v۝ʝ~QN U=<<tNz{kzz|U-S;7_p:`)0l `A]aaaCb*E&UQPԾhz5?F8Pdzli84 /&:O?y@@Ad))RAӤ Ҿ;epddL28t99zX,tV@@lvIRŹG<<*}c=> `ىBœEE}rgOOƜ8ezxiåڥeee?ʽ˟={ =.TVVmTVO\UXSS^wu9+Wu։U36kF\AtQ)jNh^lohuji|Mĭv dټxw#c߽N?6}~V^>^VmI)^ޭ@#ǚY9k h>}EKȥͯG|.sry|%deGOVV{~9[?!ff8)*#P:@7S{6*9PZǒȜw XJOL^ 0 )+ 8  hr.=S"$&I)V^:EJGMC VUTyQѢ_K[Vn^~AC1IiYyE5ƆŖՎ_wXs.DW}}nSU^%9> ~~rA<,!Tp[E'd6ţ|;UR\RcҎe$;4w2K "䢎>g~!߹c}mIS&%K˔eψ='UaR~~QՕZWT֙;4_~#`SZ󡖬ܛymEګn7;1qoosWow}}<6}1xn3:#Fz/^ "Z}=3ͽo'&̧Y`Qyifb6gNnnbB'dk|^<wΟlnn_Fó 4v &WS&TqhY301agddri[_|,t^8RD]L=%Hr(S'+&w+(Z()(r!Y΢>qREKPkM{X=4 ۍcM|L=,B,=,UmDm(#N\J]s%;z$= 9a.&*‌ `PJ$&#GDǔދ{?AdlԦ Cvҳs6i>xZ5 Ν(-,*+>v*$_i@YJݳ".U /j5k _(Wt_ϼqNPxL6Sm;w;xMuo.}pPob_GO yLHO^~M;&t<ɉ[OƧ OY$Y ՗F>v{r+?Wu7fw/ͣa7YȦȗ(J-3U*!Mz=@CgYYzpsׄw/_SM`UPHJ衰NZPX=^@\r ^TfF6]SUZ~A"b 2¨rYUK^Ւqr#ZZ/uu6u+,7334v5a61-212HTnUod#dζn=sğIKK NOzց;LI+NO;䒩wX4 <$9?wn;~0ߥ@‘'O=UPRqF郲sgQVpWʞ7z1`u#5)ˊWW^T@y]ecRScVm%[oߺwwA.>هx =z=86?50}u+;m5'R 5; :s;XR` PEb0o*Ra=$S$&g#S) jJ9vJ!khZjګttCC  O201`ecmcsc'gou;Gg_` QpBp5$deeȷ*(&(y+H2%IjiG`bno,gbnavʼ1{cS ZwX'sϜI@Q!Í#j1[œp,MaLOgZ>5{$XS> O5O3=kpn2ŬKA5_/WOӰtCL|ǶLtu{i<|,Da(Q+o&'Tew?zrqoMc+8@Q Ԁ! $lPjMbB EE9QQa./a&3ľpa2=VrIZ ]%a2HN,j@4q-tt0N13>d cfb` `g` cg(tbz]+_tCj9~S,O<]bd Af@6GDI~IbRrĽj?duruo2mgNpMYKpgig Wɬx{i7h@Ā dWF ƑuO!MhBI9u53>m4;:=q<`opLސG BA&.u37fb4fRdagugK`26153p:*\++:R\QWԈ \cN&:H[ 6KX\nձqq;_qwtvy!:?,iKLtR,gxƒv)*23/f=r7 Qoӕe V@e.W԰^I3hߘ\ٚt{n=zn= zU񜷏&Ͻ 1hlg/K,~_^>¾RC?~62F6ofvrmpl]s=~φFÍҿMMS[~|@m0㛛Vq)6l[-kH]()iTXtXML:com.adobe.xmp 359 479 1 *!+V0bIDATxtU[UmB!dB,QpffN"9p`XTɁY0Y@' I̚1cD&  g`M! HFtu{_:E:9ίo߮ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@` ̌lk$2(ko>H @ :A D8HTbP&#@# QEAs t @tD@ 1xi2D9UD`/fΗm]) 8X3!:_ \w{9_&^}"/sx!:AL'g- \t!D Q>+FAvF\ :K @XDpI,"a cg@%Kd%@t@.- 9,>vF\ :K @XDpI,"a cg@%Kd%@t@.- 9,>vF\ :K @XDpI,"a cg@%Kd%@t@.- 9,>vF\ :K @XDpI,"a cg@%Kd%@t@.- 9,>vF\ :K @XDpI,"a cg@%Kk]y'}C :G!O+mZ׊3oOgKknn-3b=t~"qU,ğ]. 5P;"SfnjjjGeW[1noZ^5E(b<,ԎW ^F9W+[[ge0b\'ęZ˗#'NFb%|GKѭ, Etٴ!rD᥾e\vv9fyUk+MuogJ/OE zs'Hm-ӯWT :Gk wGQL_`Z}Q1hkƨt}OTE/{Sڻ qUm"CsnO~^V웚j S>-t`w55,yLi.)Zf>~WKf_a7Mn]y/Qh^jeTEU T7yes,}Iw{'u|VͳﶮfRDc Eoz3Ky/"r }v⭢ Bˇyʝff[k6n1%N/l/N [0ښQ޶9YTSGSR%oxg{Ϗ#{|:]7Uu'_#B~XҨ;֛s>;4k;y;e6w(YCs=Ṵgė oV%[yh>-7XG+O3gr<{ػ֟<^LrJ}*4ZfCn{NUxD (@tZ\JT*ֈECF;u`s'bPSwPEZx d+џlW/޺^=ڪfwUi*Uۇ۟->(MAʛl? |SH$ 0wLA}_eԜl]!{=<7g Lٯ'#4i7سᛔ(_&QɷrHJ1>ҰFP+s` NbDPJ!W$Wd..(M uU٢*S&1,p`3}>V{L/".ɚt?z}߿-Hg {Rt9?jV'q"k(hV~mNWZS>q\$Z{>Lk@n<#O]+CcU+*B;7$h}Y>ޗ$R%敧' /s}Dn}v8{پB#N-dYNqw5D? DhؗiK +F\0GTh O(@_FBfv"(KYMvмij9p݈ZM{4mǗ;}gkHu @[bsf/ͮv 3BYmyN>Z;;E9MV# Gi_7VVM>kZ{͙#y{V{׿]*h>`y<VG Şj&,6!\CWڣR< dtpʏ刖~.杺V"7,Coie_8S`dハӭ8OGuezJ_a޴Pk"-Ւ%&WSqA׍2!qJL+9ߒ t "@9Zdo8~ftNdD2[kEBsFM(RԨu.F562Vtxگyy 4iZTR[~TCː:٧Bث U>ۦ۫/j̻t5F˔Q;4YwAY53yh本}>&d Q(Џ(l;MV:yر2f&,aB|-Vie`'0X+O6Ԛ;e/5WǍg< i棳-EN]Gi2WkKDٙcU_5h H'f];ζJ/ڏt{#Og%5`raq Z}Jk8b_lf&O^kg'[~Re&RQW;pّ :CBc\rY572V3gN\w;Bl cx`k[]:\zmw=3dÎ_5kᄀ8/UiE :_dL4êö2`g-鋎~ q%W@ <sx~#;7)ӺDh+iWz[V2@ 뎢eآٰ ue;Ѫp`kz&ZܴURUZ1R_MQL_WWnTzS;ʢskOnj/oݪRѩ[nKװoY;*Ev,z1s™Y?nk3{ÜMxVL+1Ngez!P実sVnNp;:'~RnczYQJuLsd^k=ҹ1@xrWǫfILVͳپ;\5వ6ZU>ߨ D^J3W*".[䝒c<ȉT=IR%op v~Xc ;:[O,iYyikx˸LT{lfoudyUhї;un>rʳV^_Cj4*ݗ\=*SpV7TΨ:?sQ!FTkFi(z^24ֶR&gfm:?sX<_DNOfSlK>毃u*u?m&Y7&[ߺI--SuB|wLџ:k 9¾xrQF}Zg]~^E wʓ :G0:vBnFɟצF uS~h9!^dZcZ{I T)0e/~whG/Ė+eW+o2NkQ|j]uUSyj:(obb%\!Nĕcu O}l{wlO~ґ;?ɡKSv BSXHG9:h:cȚm yۤ8;R_8;KTgot@՞,ӋFK&]/|Ozyz4!՚.Bռ5>Ui"%0z|}L]3U"V霚X >z,I"s̐4jgfxkzhc}"pmg{Q플܉bPꋾ@TtI`wۏU+*B;7$h}YֱNyk~@8c'Z[P_Y8!kаꡙa!Vjso=ֈ :G![EKC9 -{wdWS+:α˶RNkMͽ$PrQY5T?gnLgf +T ,&ɲDdMMC% a!znxǢ>V@{T8)|pAfyP.y\gUҔqOke|5sf@Cھ{͙N*?RmΙXyC uO5g>KEwu?@+}7?q&ԁO'kgUYQL?zZ-|#ͦ3 {9A\HƦC]Ɗ@5FsmT5>?קЬvюo Ok3aB@ܨW}Q70lm7v9_ELmC IYڜkŞY8+/De]:Rh5X|k`]ewKsWaAkpQGk&:lsAZCWߋB=V]h?"o#Ԥ1ᦚ^p{IЇ Uƃ;_s2A]cBNHF6"Qizsb)@tF@ Qi D9"F :G! Dn+-U]2}m-"UÜU-1܎ɾ[Ä^V: ] |?[ghkFBEA5$Jb-{*i`CwϩW[i}u= y_z*zڜ:٦JOdc- ڇ[ER`}Ylkl(!//ӏJVlǛwz*kC" 0qSscu's<[˼G XwO.V]݌а>mynV۴<S~ПCNOfSlȋ>NBb}?1.rfc ͢M/k(gΨګg/2cY0 y#N>tF*M3QZ;T4R|w:z땢BiZ=ʲ򦫘{eYXb.su?r5kڅ&d?}̱-vkE}7OiUZ]VW,N <"#nHlqp#2ՍyL=D`jop"JTifZ΄jUhtԎ ce՚rE]+o2N[ uU٢~7/]\B]Fyw!f34Dl C-"cZ-J5F_%] 5ݩ־f/angO9w $]FO[ԙv$^y8[G 玫 0DA?\-F^3vv}sَfj䭾2vNّ"FN+XZ߬6ѐc9IZZ]w٪sև$a&Y\V=gU\F$@t= ?sQRVQq}pl_{,Un٥mL]TXZۯs{J![?2vbH{c/]8yx7v4ΜI˹Y';)ۏlָ~d*ɮ_73%\ˇ:xZ@ Vx&s'M5#";{=ՈFf9__\rKsFԛͮ(V͈o.Dylh'._uc<^xߟ4o qp=<ظ)w䯮Qӯ9>=Edwz,1L>~ܒ'zhbcDq= e -,Z.kV~KHs[vBĂuuuoWo*(7WvK+ \}ڪy/S%բv~Son^Re[ZfkկZU&#N;~IɗG6CmYU{{j~QdeɮçV)]u%mGv+YWlf)9c2gʗm]˽B{ԇV/~|',)}J}*UUp-Y]bIq==G'L# ,yt))) T.0}z v\.dsCwj*j>Nk++>k;%s0O}QYUYQYQQQ)97ccA>Å)[yfEcEѮ7UڞNqP[ywT˄ݗDܣ;? /1`Sqڊj˼)*wlQ0l#?y<yz4)χ5ˮ:cE/6Cα= ԵKdHo&ڑ|O9k/yNK2)y!KIųI_S.Q~~,bQ}!7v JxC[vU.tpר+2͡oc&5lD9 0hР0<(Ф)=9Tyoes{bR9SRpu+^Uջj>q=fӍsrJ^ʋRXZYQT_Nxdst~y 2rٵW)Viܹ߽d?dbv89oɆ۷aQ6:岑V:A%W5raYdYt xϖ #IHL>q3LC'!o͖LNJgw?Ak/v9/cVD#v` 4r'j(=;@"FbŜ _|3'j"T4C?:[5uxk+TM:O<"#.% 9lB2@\ :J @D pA*Y"a &$@ d-@t @.% 9lB2@\ :J @D pA*Y"a &$@ d-@t @.% 9lB2@\ :J @D pA*Y"a &$@ d-@t @.% 9lB2@\ :J @D pA*Y"a &$@ d-@t @.% 'ȠO}JG"@ :_3߲.FI@mG+@tdž!@, cvD{lIJ9>mG+@tdž!@, cv@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@pCۢ-IENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/postgres.png000066400000000000000000003435521457770046000246770ustar00rootroot00000000000000PNG  IHDR&&"iCCPICC ProfileXyTKnX%眓 s%Q"AEPTPAP$""   *(y͙꯺{v`' 6vtrM IWT)@ڟl+#ں>߲6o(/ K{zGy 4Wxd4~DL~;y {=::@"E@!"j սIv :{BB¶=ekDw|ndQ?c"?zgd.laC=-Lm-?nW+J3 xtM̎`Ƙ ;],Clwgd}Tlh鮝,?O}##jLu 7G0QA6&}uDXoqGwH}9$_i{,$`h[ÝO>z;`oP]n0]ֻ}3Ã-w3>; 7D4IyIƖcG[pC) ' ``eo> H|O;$OQio|t,|nfEUѦY9dJh?b X< 2x%| a0Ø K`m[rHsn`&ky; ZVC#ьhV Czk1脅'DGsk!Qn)iE 1>G3^$d. 쵧^1;`P!p> #*zX[ܐ!8L "p%p\-#0k$/ރyVA8X .Hd %H҃L!k P(CPtjkM A/Ih B(ŁDIPZ(-jJDeN*QWPͨ{Gaj fy`qX ց-`g9p1\ mHƢhq$7 vh/t 4݅~D/c(11 a21Ř*LY71+X,+UD֥6=-c;Ci2cp8.+]=Ž$ "!'s& %K#+&%C#95 7yy6'4x!OşcoV)((z)&)V QC8F&t^QRR RjR:SFSO9NHG Rb3)39U"U1 'T Ԃ:$ԥ7Gihi,hBhhihi3hާt.uӽ __decgg(e03 2131^gaÔT3&ss=0/n= |7hVQV+83ݬ lll^l9l^E٭ٓϳ/sprpspXd ,9EǥUuk[;w";!O Ooo=></_!_'"?~N t<,"8#,d$(tYhLRXC8BRVDI$H\dP%*//Z*D %  V.6GyO=q-Xi-%%%%{$KKK]z-M+m,&&UFTKT,ll쒜tf;7"f=G,(*cەWUTU|QW RU+gjj$ unus<$J)M>Mo*͏Z"ZZW>kKiGj7iQ9ӡ ӿh oda14175021Z4V4>`eB019m2e*jif236;a6f.`jb,,NXe*`-mߺdžݦfV6]]=}] GIXZqU.z.E.]]3]G v۝ʝ~QN U=<<tNz{kzz|U-S;7_p:`)0l `A]aaaCb*E&UQPԾhz5?F8Pdzli84 /&:O?y@@Ad))RAӤ Ҿ;epddL28t99zX,tV@@lvIRŹG<<*}c=> `ىBœEE}rgOOƜ8ezxiåڥeee?ʽ˟={ =.TVVmTVO\UXSS^wu9+Wu։U36kF\AtQ)jNh^lohuji|Mĭv dټxw#c߽N?6}~V^>^VmI)^ޭ@#ǚY9k h>}EKȥͯG|.sry|%deGOVV{~9[?!ff8)*#P:@7S{6*9PZǒȜw XJOL^ 0 )+ 8  hr.=S"$&I)V^:EJGMC VUTyQѢ_K[Vn^~AC1IiYyE5ƆŖՎ_wXs.DW}}nSU^%9> ~~rA<,!Tp[E'd6ţ|;UR\RcҎe$;4w2K "䢎>g~!߹c}mIS&%K˔eψ='UaR~~QՕZWT֙;4_~#`SZ󡖬ܛymEګn7;1qoosWow}}<6}1xn3:#Fz/^ "Z}=3ͽo'&̧Y`Qyifb6gNnnbB'dk|^<wΟlnn_Fó 4v &WS&TqhY301agddri[_|,t^8RD]L=%Hr(S'+&w+(Z()(r!Y΢>qREKPkM{X=4 ۍcM|L=,B,=,UmDm(#N\J]s%;z$= 9a.&*‌ `PJ$&#GDǔދ{?AdlԦ Cvҳs6i>xZ5 Ν(-,*+>v*$_i@YJݳ".U /j5k _(Wt_ϼqNPxL6Sm;w;xMuo.}pPob_GO yLHO^~M;&t<ɉ[OƧ OY$Y ՗F>v{r+?Wu7fw/ͣa7YȦȗ(J-3U*!Mz=@CgYYzpsׄw/_SM`UPHJ衰NZPX=^@\r ^TfF6]SUZ~A"b 2¨rYUK^Ւqr#ZZ/uu6u+,7334v5a61-212HTnUod#dζn=sğIKK NOzց;LI+NO;䒩wX4 <$9?wn;~0ߥ@‘'O=UPRqF郲sgQVpWʞ7z1`u#5)ˊWW^T@y]ecRScVm%[oߺwwA.>هx =z=86?50}u+;m5'R 5; :s;XR` PEb0o*Ra=$S$&g#S) jJ9vJ!khZjګttCC  O201`ecmcsc'gou;Gg_` QpBp5$deeȷ*(&(y+H2%IjiG`bno,gbnavʼ1{cS ZwX'sϜI@Q!Í#j1[œp,MaLOgZ>5{$XS> O5O3=kpn2ŬKA5_/WOӰtCL|ǶLtu{i<|,Da(Q+o&'Tew?zrqoMc+8@Q Ԁ! $lPjMbB EE9QQa./a&3ľpa2=VrIZ ]%a2HN,j@4q-tt0N13>d cfb` `g` cg(tbz]+_tCj9~S,O<]bd Af@6GDI~IbRrĽj?duruo2mgNpMYKpgig Wɬx{i7h@Ā dWF ƑuO!MhBI9u53>m4;:=q<`opLސG BA&.u37fb4fRdagugK`26153p:*\++:R\QWԈ \cN&:H[ 6KX\nձqq;_qwtvy!:?,iKLtR,gxƒv)*23/f=r7 Qoӕe V@e.W԰^I3hߘ\ٚt{n=zn= zU񜷏&Ͻ 1hlg/K,~_^>¾RC?~62F6ofvrmpl]s=~φFÍҿMMS[~|@m0㛛Vq)6l[-kH]()iTXtXML:com.adobe.xmp 491 806 1 6@IDATx] `E4Mڤw9۔B(B)hт ~AT)"ЂrCiofv7d7MKPvg޼y͛ͮW&Fd_fKkǹb|E8 E-f;= Ktlr#853oM)Ovw$ȤE",RTUzkʪT*\S6HCRM<b8l[OY*[ljRM&S 6& RHLj5kBCiYjf8dRCָ*['gUx {0ٍp]}x4g☈^rWp'@L;mg=`QDs~]4|9^}8v@0?mgtgFE}&,yJ>h?kX'G7Y<1q=zSLx5ʴ/Ο5#Ӧw_ek(}KWgvxkG1p;e޾Ƽ^}e&N>|9QaT<؊ +NCH2/U"1-]QSWŽVÁ3ߌk@!f_?l2ޕga>_̲Qtq?t#?J }ν z~JM1y(nrSGկ"gn'Raޞi>W׸h:Xr8Yd=:(B.Oeoi]iЙ]mEIɐu2H&lHWOH9ʾtR%W)XC% ɋ~:Q =o)gO+ꀀ{r$YЦ#?}0_ Ux~aD=@;R#Q!|9Wsl#kݺyToXwoydGFvVLоT~=׮y`ǔ5+bVw H۵b~u^>?1\vJgiW!Y˽!]& i'\u}ѭ^ޫIJ:Xqۥci6:!ݞ>q$v{(U.oz k֭[lm_,vDNvY{]:~1$Mh3^k ʷȭ忀Mn?Hq7s =q0:ӝ"D7Ju= w\xg͎}z^9fM^yqA+9Jz]^ jKӾ׋'_$B 0++JM'?v!={ҖpRchJ;^ۅ(f2ӗy/j^b$olRUBdGa2qP4Y/]csWOVZa3]Ĝ l8%`*n/d 565rH0&0߻~Zű93*fc.r7 }ɐeyeS $*\ϴk?ld0 rv谡 m4"b>G9x`Yǣ~>Wcm 䕘Vѽde#x5%n䪁v-OzqȕS}gv M>Mey>nrTI9WNL9lZJLJn/\S_Y`KY-Ƀ~"JZDUQ,˖kq+pmw"bKa]\;>[(]c5F ^-@v3gD<|T:=@.X{p= 4 J :K]/Vd;[tD>cj>y}zoaL FC~f?( |n\3Pa̾I\w)$A>H#T& n޺gLZxGM(tL^;ݢ&ܳ]pvʬQAnԢP  an'=8x JZ$I8ݫ ^Ɗo/\ՇzCoʴ$p̖? Ugyf659J;̌oԽϼ pd_h4 0]4'O~T)<@;*J2?? ɢF-[bL2b >-$8a1 ҆ aÚe#BΝչG=?ImW$~R8dNO֮_?YjB9dvj 4˂hʶt>noQLLbtQpD*N7+\mh:9K[оT7Yz=}eboHVa'''K5:$Y!9NdafpbLJJLqs!$&2PI`7LGЙ_!½q b )L|2MQo(c@EEpmd1pySIҒK@"tn/SβeN,]e5 /дǚ*"Ɨ_Hj|ϑL<D拠|& b1$ҵĿj0d+hȥ-vcy5 k) lvg*s/UNK&y@@" X qx\L>Px bPfC p.IKt3́(R<}z׆U| .&Z)C5;gi"E%HcB.p7(/ME29pBVlx &fvQf@ Xf:X""J@ؐ!3%$U$ L(S\`H*.]Rr$88qhCB5*q =1 yL0€ c*|b4E,B/'aU3LH*k#q.c;VO&DO;^[aT ~pP+, +]?Vd y@G@5@ F0?2TTϼ ^p,T8rX.NdŜh0Ę8E)kJvҕnd۷**)0Ras*Lc'lvcLNGe\Vhw Ȃt6:#^^oDqJ. FP P+X-k榸Gik+baa-H 9!P2{$8P&BpN-vkה#Cwϛ=oM٘^l@?d UYpB̪-XCdҒ$Hf,WKGHQX?ثϸiAsc}iރ6ja}f=אvڦxBhԮF-'+r:ҍ|]}kc?{NӲJs͸ף._x'1|ھa^ Ͼ8?kchE`d18Чc$8&tGNX6agl| >?hE>Qpc`vyBk?BtkdKw^_t}߈s+bv;A$~ uZd9Hfμ"l%n$T߸J^ٱ^/p>]̟Իcu3! ;V.l cφaz dː> ?Id!_?~.ӱ+TB gүEˆg=u٧&u_pVn>x]Ѱ̥|DN+>\L^p?&h &e^DP9å c'G|׋| C iZ'w課^cڑ.hb+D;NJՂ^$M52~z6X@ JPM^ pMI^Db$Hp-qdF!z|1qAA=4EdO??v"EsV<Dů]O:彚vEBi?X=6S#eѹny]HF3a%KuXNy.u].ԦYH(D/'n9}& ehF F)F?D՗8dCЪNx:mi@(ձڵ@G;hj/9O}Pc%l\zts^!l,ܺuE&@ʗ< y@#큹s_ Q?'3 ~H~g 𩯅&ُ+_Sn,+n$mmEm'Ăxh `ݎ.iP.L+v_3y3+^d qDL19M$H<  Q?tqsC) ͅ$ LI$I&؆sԏ<[Jn%@9jaO擢4yzPdpw,`+c꧅ LSl&Ĥ7zP<.j-;#_ Fg#<.P}<E BawHv!%*o*d;t%U,♃1N8Cـ#dv0u=,zـ-'F` Xh ?"j2$qcގU|2!Q=1˩u /cNhВ ІSe\ZVּ{ބ }kmhhּ [hry"UÖ0)#t0" ^%(v"8 'h'%D2)̦2(\3mc]>hGۨH1Ot $G_ 3>*T5að4Ym; 1 ֶ22m̒߼{`)>VH=tWڳM`.Eۋۡu r?E5%n)eA$ПMLRDž<&fݼ4BPzKnV|y[.nĥ;ptqg e#d& U1= [ST{c"Z{ɱ-~_?n}i樥[#[F3u[#|o]iZ6TޟkƽE"}>#ݘW{ѥؗ_f%>a7o) w^oNAqO>"r6-|]9?@̹1a \뇗N[FPU>6ʨ%3_Y7+̍3-6>h74;;2#Dèt/9eEUvuC[g# e3]:˷{荗x.(%7 C?*w6MhOO7 O;#TPϙ'ԸptZ x/̐qex)ҕ̗ST_ nh,^>z+Cn>^ Np,zq ޷-`\h'8_zvJWF|R4Iv=5|;7*Ϊ~?]`eu^;~AJׅzn;8}X(_2u`+SGʍ>u{tEN >b}z2{  a{cd'C8~ rwzS8+~-Z6=};>upNұAWn;.:rm51?HO] ;)nFK~9x%>=Ii})gԜz}G,@˂d‰&)&G9nG?ٛx-_tiRȻZu rʾy~;ykRW~lC ;\:ȁ:pJ い3?w#vm?p!#fP]XRJ>)"th hZQy(RZLEy %ut3&_hlRo8-o~<ޓ{dMes&6([ OHW5UZN$9a@!]y||5cxT N^EыFc?ri=6 >r_'0!]<^{) }%*DBjQjP]Yz-4p1sl*IЛSʍ'whuȝOo#x0+ ω(2NĐ3]+/S]/lt*'9G Z{=sR8`t|[0VpG\/]53dÆ@(ձڵaV HG'5?!sdh:64eѹny]` d|V>y#q!aK9) kW[Gڮ+MkkJšcWw{3m׊g`;ZplnriB)P3jPDk5?|JlϦ3O?վG!A;z%y`ZCy/f^V5\9gwfF.1܄ȝ%7zj%mCYqV 5eV>$2852"Ўqup.;4S~8TxЀ@wm:f!+nh:lR(.ͩi9i/e7Bٻ|kᛚ Я?&J(5ns͌-Hq[%,Cv dmMx/cP\QH[ 2st2d 4g_f7.TNe=^z4qv]@L:?୆2b_-p tf92.MP^hCf'foEI`>,`\lyo9ܸ[,a90Fs-MuvY\a.@.9[мϼ?x,7P:ye0`T4In61,imS'޺n}֦82qy%8 NW&|jrmy9VDiU0)|bv eO a.ʈ#'u n PGרqRCnGcm5?oB6P+r< Yd^P@_)Sdqua}dl}u:jun^r2K׀sY%1-ظcA+aM';({Pe#~~oܚJ6 UIrz@[HenѰpkKAy!Fav'?bL 2l` dah(*8D!g cC΄[&ekV!ekGl#o [J;ñĤgLY?lACwǘyڮ!ӎwuqt:k4}P%;BĔ{⤽kxVA+1(hDF{OMWkɂ~!5pLQG"쉣N9WzB/6uxcL uڇ:yn5R2^Bޅm!4ו JݺϿ875 Ʉgڎf'I=x{QΟr羟Q"gg#o":.@ 9_Bas@ lFdy27xIN9Wd{Eĵd"w^E_s==3^CDl/dZX0㴘ѽ=~s1;2ƈ4{rO|zËpFgU+X‰vAck~:&8l0*vk熇7&¯Иzwb6!uV;i3scp=U&X>{H>A^V1Gp/ ƁJ"f\\>f B(^Nr2>"֎y<|ܴzIkOuW96|xIݚ` /Y5}P>1!8ٸTp"yv3|5-VÏb@vfYJ AsfOewW6q?huYv3%L0L38y-J`4V(Q=PdMBOn&gYbS!crɨsɶr^QLccb-SXGGPDx>K)GX~uӛkgЖC>{|HhXyfP"(#Z~#}ZynVhuAi=cp/Uf/bo,rҮ!{#[Z".4ܣ:9Thpa/'"'>u9@fd PziVe~~~T1aGح|uZx'=0 gcDvQmrwClgrKL7(1+ka4]{Lڲ0{1H a%KiV2 `X*;GE #t=޲%2QYY;&iBRH`%[5}j'}{njNk[8j`*q`Z(^;nW kKt zVq/Xq^}xQe*ts)[(/ceW9!\Zk_ЯжW'z%Gx[O ku_֪ WD·2GXv?Jc.v3c6;bWĜff H1حac.PVWGnpFQ7JnHDSbɐu61єiUK&KJ68g)fH%gN˩2UODJb|)wj.WͭGLv= PVPه^PRYFMl;d|XզϩQv? ;=*?gЯa -'ؾ֏{c6vZ1Nc _/[e\oenMxsg.ݸ>6 dN`6J4v&{:,Dp˒n!ҌOJ<;)@w`ûtaIJ]ЪU5p^U&ީ@s:x޿tgmIJhz;ŋ%7o`tFBNɹ~Yy]q|=c,h6o8ץKheqkVL&rjjE=i`UbjEJH< y{l:ca+b:\Y-@IDAT!0uT2v̟?w(z;9e_xg͎ea=}\n*>a]֣S=:PvZVpSL01C{6\e@ YiuMi.^PUf dY*,cɫ<+C&[$9ȑQPo 7 ߲Ni6,{5) N^\;(pCڧ1Bg:V0y9%uLyԩ}?b 4Iv2W5@c_XՖI$HG$ X>YI6+ L~sÿ7δ.CRX-ħYP2aކ+i.-'o,G*@ :3v׾5\d~`ޖ,O6%m6&>u9-߄/_p \H9u`HIډ>~9cܣ2(Z%(["UO P%]$Hrpw{li>KcƮ ;=9YNVlϻX#`उHy?NU!;a ?`_ۡ1&,!?o(/pqҰ$%4 xm"]0KrE|sT(C9B"$D ZV@I@lD}VQf)6:ʎQ &`/p\tS&~qwƭ WlAj6&>K۴=}?m$OpHY>ft$d+8:{^9wԌAD#Zx(-Q{jä*I< y=`BhkQ۵a^~X6ھAXz_μdbFsD< y@#x - E R`f1eRDvRy$36Ƙ P**k-k/,̖ ea\Ȓ r0\b$Sl, Om% ?<E /ǢTksx(أG`)Ԕ6 a̲)KU W\\\[Vvf'Id c^J= 0 O]L"(g  l.=Hs2ϭTxxxȕVʇ4W41-]s^ޚ+*]\5MTL'Ay %R'!>Lx g?aE aY0c4qț 4#'Tꀗ)R6x&oII6xJ*\i.Sm5e #XkmFc/kD͍OOߗuvy^ޯ Z&z0+kNEΉmo0u`ԍ%k/AΞ23V ij4b?gem(.n Y{ #coV u<Yڜ)8ɟZTrj0o6t`+,ieNΑqC~zed$ԼgW̹4Ř4g6Xsqx dԆP7 =~ep:O19RY_ww``_`q$ڮɩ,RJlX%u`ƃf| (%sx"iS`c"3f "81sYX^8W}Іj-wZƒM ah@6pCXlBr,Jת$۵,+%F3OK\8%^Vp!+O91T/rstxrV\bˬG|h/b`,k|G3~~Q`n Q#||n#Ymh`Fg!ֿXl!C4h|Dp`R;ed@߰V?yũ@J}U.ͥeR9IC(Cⲅ':=s `?)IhEm\T嵗B0PdqqO1N&`Vsu]\N#T>JA7|V" } '6$7c6ш?=+)cѽ &}K\ޛ92鮿u*Ci#bb-jJd^=LG]?qp(+{yW q}! < 9bllMMxT&M前xkﭫ:Mˆ (_|5ނWFyg\ |1Wx''}3Ƅ5j"}i ,?s1brSVf"G %U*ڴnn|..{xއtU:cwwȭ,w*La WHt]Ѱ̥0^0}ލ۵4ﯛA:[v\e8|I}Dz4/8mƾhuwhZVV3RFa4* o),Zh==w9F[..=>`Nx{Fr9lG?3"##}pG ב}XŶ@xxgzL(ԟ6t*((ˍ0*wa$ݞ [pp<6b3;>8<; LJb4>,¯<M.z{g!ԅTߝrv[# ]Bku|d|j*PS2tKJJoyI M:f.W͋h5}?c}By)oA荈|}C(n;6G$Ee -xx^N=YKYcT͚s5BvٰV&c6Ͻ>oABvw 7#n'6b=<ťBbldury^<e+QRS\eH.P?OCqs+IJe1o'T*gܾ.,| A#i_`$]23a`]sw25\ Dr qffcR"5֧ 0~jT>7;pPm9uPTjSM&; Irt6W6j jb۸b !s'*";9??nMLVOiim:3BVy aւ\EYs2B,EHYP3_++[ve؄MerX,D@PG7GТ|nwwh`\`1Y7#YņwǠ C Cwy"6;Z\VFSݣfUcz(5CKwe>yZ 'p i 9x wtHOr6R +f؃lӫ, @Fc]_puՒ;,biQ^9 ,â`P*5%<&&XFL¦ ]]0 k܂`i?DKґzj <>_RЂۅ+JGN zTD _\T)||Ɂ6DcQQI=>Akmrn S6!=`SP1aک yyMYvY`Zjd4F5ԫg >J9٢ "ӂ}1BEE鞞J)J#MhF{an5BEiiFשs4Kp_ra@J#\ϼX yy/ E)޷්5oPzedL_zz,@vf'*l?$G@ z'')dsE?3v¡LPb Dn׳\*@ :3v33ڷfѡx ԏR^ҽqko:u۠/{H6޺r,Z-zIډ>~9c;y1E6&8r!|֥OݧYP2aކ+i.-'ol Xv2 5*+a!WIv5Bt,1)ɻLY?'*KD}^$T%|$v搈ѳ?O ^zfK#3>1kнAhYLG(XjЌFㄒ ή tvGFh^YT*=(/3UXe2W𮝱FB0ayP9:V`}m6;:OkXQ=99;_5L?7aShUK=xދNvaVge;Bi |k ;0t v5V^ί֩RyMj'Nν"1︻ xkW̪R/B8[ ߬T.?uw_Y.JB>G/SVl(ҲKJ^&5^uQ& N+=ȼn?=ݡq+sVQe;IHbDP%y+=:{PO?0oފ7_S3s|b4ѷ}'/ė¢_^knБQ9I yc2xPJ{r |cMaC2 ?s>@Ii޴u(|d=xL4%Ȯ7K -ߑf x=aKϻ%t2#|u|/~=弧%eCLr owʳK/zxR99ME p| ޼##kZE\yԩ{HtӧƜt> 8v($?LNNCڑ0V8U#網gԍVGƷEx\'aGF!t^j7, >@ 2R8d\e99<PXOX;K]L@l|j\l<:\ǎ\:rn\-? HeB,භQbiW{DwRd-\0fDG_oF\y/x^oAEC8)CJϞ=-m~wĩQї d%XX1b+FQb|1ԉ띰I~Y2z-e (B>҈nv shD@PWJ2T a}p~4F8 r#=SIj_?&wOFfg{xת|0=߯RJT& DH%WJJ4@$w~ɂrr>\chH> 8m5UpNj|{GB\G&  gBwVsXRBsԩSR+Iw'|zGfh"4^0 77V\6'A Fs߅k3XErA1)e- bgĂ]'T["h P{!7l5(R4@Ц,def3Ldⲳ.D#`xdmоUKrlٝP)ۯJK߰3i-/\D[QWc| Gt4 ~lYQob1@BkpswA `U$PO(%W-)E[4 ?@F@rm/x ѮejV7p*WAw 6W͒ a%tGCO=drEmO ꌢ_\EVR*[➅fۋE(x5iŷ5:?:-MyDWnFO.ˌ Kjk'^BY dB[qD,`S3݅Jw4gWCb6wިYMTP1lHp}ЭaɶՙE݄ ^!"Մn6 a IPjKCPp]("<=s3&H՟I  n(gIz~3%RsXv NT3˓OA9)~6I:l"Z3ѳvs)8;)8tyl 5> DZu Kܼ:š/ܸUrp\0Y5iwl!=JҔĴ|=I×q\91:1` s"JbR4 褅 !3ة_,lbHecu EvQ.qILE3AzUNI3Fd2\Blsڎ2d6Y̯div#P"\d0 ? J7q$,r #&813r 4ou&"%njRx`RP!iLG"C<ɏtozux>[[d~Fs@-yg,7;p[Q=L/ML 댛GJ$uXȪIrSfHb(cI@A\q:&ZGfĎz:-dbʣ׶$]m^iH7%:A}jA3 QU9$# MGڄ% Y 7"%v`ΔۭJ'Ϫ7iڛgSz ]h G ! g`IެޱɎFaCdAFɆ7"ՋT6%-M ZK2CjGQ6w ]7uSIJ_fѩk\t[ vnJM.ےp#DIRGH 4/pHA4IT3ߐf',Kex=Ts9pfþ=gٿK+]|IETR+_|0GeUx5$SXFLMp̢k@&Apj{- &Ѩ34U5Xpz$.Щ EuK~bsI'HA>"`ɆDX ܑdʐTF %=o<70[sO·YM^6?sW3{2_A' ,rkQXڛӒ莘S2b;zk@$G.B- ZG6CCE> VB@)Rd_9iyӔqZR_UbNXFRƙS2ф8C|toW8pӎ (lK.XlqIw.'PgS+;$Kѝ_>Ȳ+Lo*]-K獛xoL*zF3ޔg<<4w;g, >g%#G En_w&TO#RtQijROU!ATI`E"`#YX(N^ ݖ"\:o $K0 *Ҍ|7o # s>6Q{IO[rיJKŗb"b"+cbhޭy|ގS'ZH5JFc?mX˱0wU׬^\q g]y/'{<~t͇#"1ԉ"#VA"hqT^97?Q EgʤWu!F`QC$FdGಽeHxK^$KJSʅt $/Ăb7@ "E$v\ЗVݒ36/5+n1/:Q[6}#{ W3dNoY/.)Sy ,__z>~>W1oz}鶛r8]>q;{͉0={6WՅ mBr BIC.\\XVjAv(,z(A&09zv4_7'[:tȞ5 dqs1O0k5VOrW+W;dln{mmr.] dCZչC8yI*22;H&%˷Zݣõk OW@Ƥ̐ % ⣽P8aq4-̗Hk{@ GEf'[%wA7E!degn >8  DH餱(p}c :D+m(pK.X,c$ ,xDyqNI'Hо6QĀȢg2כ\96`z:{-04tYzRʱ2?"**PO+l>KT$=ձF _Ȝ`?gh ecvMRI6ci(L]7Oe YOwE*0 ,rD.OpY =IX}+.*ኪ@+NZ:Lש*9r;snJDܒ ^mXRuZ$%fBHVG*TG a,v}T +3C#[Y?YC|kVBqzĠHQIRK8 T@oS- N9uKszpEf=13!MEJ2L?pq 5k;S(U3mr@$P>pinJNܒK&NAͯ@)zڕS4WA4t:(;ob[" CSgyPRϯֆV/ n[[vXdGh h\A1h1MSً@@7yPep#P""\L ?(xGhoFC[r16_xQEX޿b5T A)$$--9^jL /vtJ?&yI,G.<~ [CFa?Ku#P#\! ,{kR|@]pGAzY:r kJuJX`޺R>EgRb+H1,U]L5ۑD$VN.Q" 1͊MCrwBt>p:y <$nH)F 7.nUjIliy$HѢO:9r ' k o}e,(zMa։CZHUPJ 6w'U6GeMȪLo1pv9CWSIDşiKD6-WH"\"N@^JVֶۻ0:PDjB7Jo4to@CIL\':D{wou +R%ٲ^8?il7(“ܭ[̎-Kl$Jz)&$xWP&#!.m/H 1V)9!Gђ$Uz S8`UŌ[rA/=c@y7]IG>N x4-w+p)URGliW%B_LP |@/\ވC-Ӷ@eMΒ*VRE㋝<ɹckdOėfQYa roL3؏R30:-ǒR'ޞX1?Z2[9_f_lc;Tq[;7{ c~zAY)'T^ʀ NyWS[f6^>8kGL|_-@Ir98b?JBSSA[Ԣĝ 5.S٦z]6 ÃӨpA o<}= X|-:J w 㕇u NӦ~;>td; Z~e~m=sfyS^Մ6OF}nZFߑ>Y5Cm[Jxȼdg 1g|DsSDS=&/-}@tlspqdkb݆I `Ȭ^:J/G46oeF7^m{?0_cjjM :WnF Z+YƔi lC ݑ;qyyy6r P`u 7ى]Sdゎ7oE+wԨk?r<*&"K]Ektonv,:q֢Gbp:ӆ5 3|^zMt{Rrhն*c,_{ |+_*ÓVN٬Y{S"DE׽Ɖ-}2W'E?T$yw! DݒU0 ;>nlT;趥o^vGd# D~ڴb8[VXv'~_O[Lf'򎸷YS3m9WŞ3v i!Vp&zA~o}toe*fnّko~wo4!u5(#;/r 8ސ5_dH&*|D)8(<$B\0]m2VpDD9lrj<];sckq 9gC_L_z߆vΚꝸ.x\䮵oL]á+cnJ2c~v~b q!e"#+]w}Y^|󁈊b0gyH-296QQV2*i,Ge(Eyz=1~ϴi._Pm߲zq؟Wj#62?ZV ?w.܈.ns*h1SFi"l_h^w}~6Kp֎t.48åY=RNX/>,0,\+e6TJ5 y ᕙe>Xr3[oׇik%g.45+̋oꖍ_.lrΘ9%#uzzq9MΉѡ{x÷~.ǧ%{HǶ6~Y=cF;$ǭ]Í}/J~lT:~ˏ/ǿڗx 5H Z#2yqe0 rN:1uS #} +ot]cZ(N?e9M58^} ?54뤷7 ?p@IDAT_Zi|rtx-·0Ya>,^d|ͤޮ{%׶k1M*Z!*n Գ,boȠ0pq1 Yg|1}Rd̛ax'@Ice\0GN> \G`}jo-rl\uMZ{amWi05[μҡw&2.~>`u.:gwЂl9YZљ9pPABF sNQ=BS\fM׊6f-߀So-wn[chn;[6p㿾^Ṷ  * GZcχEV}=wu%i!s3=j oܒ ㏫I(Z*, `s4 xv&U}֠ID\mFu3GXs8PjV23;[R9G΋'g}6WZ$6nM6>X>*˥KE}'y*M[tIDq?kP9s$!9t~: ɸr\>{:ivJP2[}|a|g4g}|K$Z?L u6Wּܗt[:٠FDn5·Y&|0pEo_եY5n7ž+}D|5g 7\sr&ʄLc-4IMS':$''}/l K쩣xMý|'\a-Qˣb 7;c^~r:|䊧d]Ӳii~D%d'"D@3;'$ mUyyў}LGrQ߄` zoצtj [VN SFzU Ĺc<# ŷq=[K+ ÃGe/-n.~/{:Mpv5r2;H մ{má܈2ji}k*iU G)/yksopxż_?*bѨhֶ%ńDj.AO೴cǓ.f2l5dM) "L{T5/ܹ %?ܪVk1$ Owg8ҍ!n3w%ڷyac;w .ƒ *t;ߦ3V6!y\׵S~RTTٓezE|ֻKA|0,#FMKpb ?X lF\)^PJddEmMdID.ec8x.h-޴=Qog h[0 9(eSEvuc\ո𼰘~ݒ\i?6|O+>EsI{Tuׇ}!Ήͯ)G\_G✹;*_:U۽FCNb8^K(s)-ӄ-9{͙ڣ ]kEn"S#iCmbsmnq1'OZ& =u,dVu[[\UA=`,ש[ޡ#}GCa?xd;jF ^9^8q )nU@,g" H4) R$Asit@ $js$8 6%'O{_B~fW? ͚>oMaU-^۬nu[ܽK~fVunPS'MI0RCwY^pS?Ƒ5}RZǺ7m25ҏl^(bI*Xz!> юZ2i[QrF@={83EߺR:+%96ԲVjl2Y_ZXiMZDyz ڈRTԪ铧֬0k䇆bߑg=_X+|]QR/=/'-Zz;Pd!gˋI T;lٱGk_nV;1K39\rۆM v̯4G6A#W)qV ^+Sb+28_{ܶװjɌ3m/*QREʥ17Z&}Mt]Z'?ys6?/Ͼtx۱e0GR\|&vÌ ޙ9o{@`Qqyc[:?? n}}s;AύRF]]@X||<'9=K([x)\;tQ6H+ɇ@5Rzdp I{XHI qֻw/??P#%%|Wa$Y|OذJb&kE۾V܃ ;Q_SdIj_?&w_„AKXcGzpcSg1Cф0gUgq/s ii0^" Z;y!/yk%k{K/x/_wJOf`'q>\qW|POJ_q>~/rY,}CA J`E&]qYSXW tUTQFkht2LI/⼃O_zO≷:vqF&qɆurEizoB B\t$KrPIBPF3-\J`]$} m*χT eKj8nɆ0H~~ Y:q8#i!X!n/W*>Z=].^.)I'f1rIs%vqbOEKP(S*"@gVfi}u2egwɬLrLgZ珣P $@ UvS-IfsllЎE#c}Yw=Sbۻ-u /Ã6gTDT7 m "j2&`)03-2_iUr,?2m+EhHAv47 :BnXbFbKwd~Lʆ5sNSV jаIȴ$$& YbC␆{$2LBgGI7"hUNmYR $HEagrjƑ9cf.r-F v EA%pq>n%b s:Yd^I*0?X`' /P($[n$F@B~g^h+_oxˆ+c"!kyK #,KCB*{sbW;$9$~Za%WUgĊHơaԠ#ʎWlZdN` 4έ*F9z- Φ%q1Tg Ma "nQثh2KA"@uh0vT. fWHt+hEs3ۿ5Yy3+`l&0VbTub-~1gq8"\uO2qM<4q^ 2*9*;H ˕D h)کP(rQMᤲmZOlEdP]͠W\k1or<*#&'!- T@d4h߸UJ19Q·AT 'ÂAKqȘQs fX"fG쏃mo-)s"s qLFm=gGU ; U:vnx#R/ %=VG!H g%0sY`0ićv۔SQ%G\QO`Jpީ:^Xab̂PB4[zHNb6z[";`Dy,+nLtٯ"6Օ#V 8Q;)V1xHdw}X0 R" nZr_jH&T$T& iA əaꉪ1+23":PYeͲ~S/T}&O5bM1aQ幜.>sɥ(:C9 >aD8Hf/} &vFv4J@E%*>i؝sf&8r)3d3M1T@2͂4e!^ WtAf8im "Y^X0s-1\b ZrXOmK&1n1 B412+Aꩬi 6.9FC;vDtdHZ" ;cJ"]Q#9bw-Ly!.Vɠ]'QRXy&~.%8X .@A =d;k !֡U)iNH &]Xd lmx{/2}b95A ]xF▟鶥j~tgbK Iūlz,IVW]T@a% Q3&̸"@kRS8BijTҸ N}"ٗ`'Vqu[ud#DF^Ƅ?ϨgX2Ae:)\ liAcjOMfRz*B.4`7ݭdF2/`P`vPLz3EZNkGB^چf?Ĭn <9_;}*xӍ.b鼨" fOJ~DVM1L.qT (QuQ]⃝|0$Fb) ɉ"*lj/ aVD.Ə9{,] 0%YSNn@uuF7 4JwAn·/&Yi9cIՄz Kj]ҬcE'xNh#ԅ# K^VfuW%=aŚ5.LWR6L3]% w1x~`D.7) 框O6sEfspV9m6~'FJ⎀{KEAyLC`^A(eHd΀ 2 "MSգ@]k'x~C,Tg=7Ԉҹ߿1iv_ܡn,:{\d8ŞNc J$9M_Ǜ_Eᇃ3yҝtP>¡JD~脹To0H'& Q; 4?U:t4Q&O~DubKu@h*%ֺl;^zѽUÜ 6=^p**IUyRrhնE"DE׽Ɖ-}2WB_:⩯簲P0S5>. 7 _N; omV;8[^7Ebn~Vww싮պN$=ѥC߸-\=k\bg!'W=6ٳG\b1}- jt…\Ah,g؂)tA4{R0~l]_x$jv oY??{c>I ;k$=0$ }>ߙCO"FxrgS{ոMb6k.KRξ1v)T?wD-x{2,kC0+&̈́d^RRzU8Hzqڨ]UKrK14d"`a8^, "VLǥrun#<O"* .4N&ѢԸrIūƉsǘp,m?LtRkĻ\0|ZQY'GoM7]ҡq\rpy/iB.MiJOL1HsŊ_)_&T96+ils˨G(Tq@%CΚ @!zE.sJ:o$"0슸(%WAWr6Bsu(QcbZU\ePG-R8c,}jVIcf>ZmYNbu#~zXܽgTm3jڑ.׾O=xL㕑xZ {sl%wc_}} J6qtjm-v匷ql E逴`lra^LEıf6K>LRN0)j۶E(* 1FY.Ubs> C.`ɱ>*eBnJzܒ #)Qyx%}@jbE[L4%Ȯ7K |?k+ԕsP[yfoe`w ^|#kǺ7m25ټz~疌mmVUwO,4 .G6H?};VJ"/)8\q"?^'zg /ysKj9Q0gmFG-<5`axBMzend>~#/ł4wybOR1{22ͷ掺oΗ_G*LO7嬴N3K*;3yѓ1~DA=e:.Ό8 ]Z[WxvA.9R@QY'7 : b+ JU-jKjiad˺QZ%Oxke+ v$ G$sDDbȐ֐ T5 0 ]@ [r<"!$-'E 7`E# fg;?M;ĞIZd$=v^ShϗVlI H:[.GT#ȴmHLD$ n< U[H $g t1]$-Z[JE}Z̍TQ&Q@!Y E XQ F "^qqK 9ȏ!I8)o1Ɖ Ț9$ q.B;lnfg'@դ#dTOhx+ܣ5fn4)T!'<#LXѸNN;L79udRG*jLe&IV l .2aŻ<+b`YŇ n®ۂqbvӊ%Pn$G- <:4^ CX$-h`G$Bf*`༩JmQ).os4SVJ07r:nDnÓO=#EdU.qw}WGe\ݺز$+K縀i[Awǯ5X0'!28QS8`X6j#h'2OM̷ Z0I?x-)/eW! # B?,Y$IvX[wܖ*ؘ !"{4)FM)GO7/ ́OBx4JeܯMln==R~c6ts( A"A?ݱxp8K<:?jiZmIB$fj4Mn֙/&M+[ь##[uIR$%F-UJTZ< 7XxSc'S[/Z ~tA??Mr7tg9 첷Ŀv| Nk$q3SV/eڵG&:~u@x\)5R1^3;Q8ȈZ@O-Ur D1& NPJQ(i9BLx,Җfci>~B}9{R ǥp<: cqyxznceÿ:u2I?6š"2:v/IrPjevAXx0ZfDsg 9䴉M0ᤓ[tpTaʥZžqI2 0ra@^o;WT2&{ޝТל:IWK#\!*eGfB0Q2F2ddJ9GY AI(%*np'E$`6Pý% ?9(]7I1| =tGE Y|I[&Xo8㸘CriԽ^ydP Ifzd` EFa8FjQFQ˖-Yig]}]֎;bXk .!aS, F 4AH MFoЄ2u&%Y!?q!G֍=bȑ ([5oV!daTkׯ{Uo|DHaXߡo^0Iiri/NIyPz-|_ص"U&ƅ6 (rLY hI'{^]9~Wu[>a톿oܜFL]Pj3;>2tOYq)vg=\I:?sQEԬIch~>nvfՈcqz,RARJy6"4-6L2ާI[F=Y<. K5 coڬZ$ q"ErA i mP)aM"@A+k‰Ri2kxQ(&lquu 6aFd_}_2WIz+my#< kS/|UQ5?:7zPĖ>j?CimGD ʖ-Y1!!|37vQړVN٬iv<>og-x$w=`>Ӧk3|^vM<)1sŊZ̯7I}rPKKgvwFObAD i4J6] ":XciP%ruK? J߮Zˉ*4wtےyo~f{d#J]_xu b9 p>6A=ߤ/XҴ{짍k*c͚l=O nͩaUo>_ /ܜ3*^Jq{אRRh/_[xf֯YٹF;R=͚&D^G8B͚K_~H~YS3m9WŞz3Bχi7)M쓹;FA{0ݸgsIUΝ ϏE{T}~3WxWᘁ s>Y?/ڳv{,HwTyY.*67Gң B(TAqVe:a{u~{[7=|Č\@e`_Z/rD}fub#3hkM)r3\H+\ӆԾ&-<ǿW~?[Ƽn*3FN 8GD.]% ?6uSI.Pe <9\ wΘ95u|6uI1oHЭQFq 11eRȉ%/[}9k {y%K[}-9vys~#ωp#fa-q6*CUu9YGz7{`*\ 7⹿'Qo=voV0K^Ɲ|~qzOj\A-+vh>/-M> &UvȚ~nX}#~a- {۴e̝Ӹ׬ɷa17aMX$?xo$.+l )Z8SOyo3-6n;[5;'| gI'yѾ}gvj(qygOS;7:ӣh@F-? UDH"<0&/}#ܰ" ,LɾCaNF*D-RY+*cWSi{>Vpn u.;UH35P'YsJbن7!&A!˘vnJb\XbY.5%6֤'j6Eo>5=L>+>O(8y~FXΦ_; p"˔5umq6nF~嫽Hl]'9?I[>t њ Z\]"4;BZ#L4wLD`1$Zde;brB0cna<U`x@Q1 w>jܘpW˰,KZ.WXL'߆)]ҊȠ>qrIL^To`C D^QG*~QKbVdf!iU><^مܮIٮvɫF寽%㿬]BaqUbwK^߃`Ý-9uhc_}nGOB"q%Ol c7# v{<X_/c9iq\!V^ ҥKgwt~q+"'l=[ 9ΊoO7p7&^YN%E:^Kֽfpk>(XTw6/W]6'.S!Wg+'w|Fw#(r´51۾J^mw%8 jCީ5&ޙPs5ڶoP6oJQp!nd!wJT/.HheeeC)+, )U M<%Ȯ  -ߑx>e}8TSHmxϰ?NW3NY3&?޽m)CnCl^+5H7g? w"rφrrmz8cDW{TԪқRTaY?|Cf7uys>Sv }2zB 99=N5I;{k}s;9.b%a0I"& Y)X|*F6B rNTs'%uv-b3?_f@;8@red][DL]_?.zͅŚ4!dƲ+šb8AToᛡ*dž%#4lٮ~/xS{eۇ# WiK:+7 J;#x>ggza}(ݱQjߏz47/<]'-Lf:zC}}l-%WCyS$ty^A͏.T T1 0XG+b//-ud~iBF,P K T7*Kb⨜vp՗m]~\󄨳7ޠqƭ|y`-z3燬Փ- ,rpK" !PQsF*n Eya^"-|V%FVslh"QRl;tYKE cy6li32+ r#P%WC(|+ ,9 Z,JKaCud e.|"`)0.jLWsg>^(ApL<)ȼESWhE> .~G0Vʔ]nv/bh e[r?0ֲ-h$;,pЁ)T`ApӢ{!`b֥&$K)Z[\;[Vut#F಍[rp`CB^򂝮qN? D+!n\]jˋKAt Vn:Xbb8i3{+pY\pK1fUG7 .?̡e p>Nq{,-`7O&! vxJ\aM8p+nÍ7pnAD@x0p*ij!=FNjbb@btm(N2r ً(4 4QAwC"R4 SEf\ !n\pr<XElUEXh 66(6qԵ$eqH;F.52ɑ6hc`CFS+>./vQ;Xݶ7eܒ+aǜ*Me%WZNhIDZY8T*mW[Y^ g{""i$JRc"mS páS%/,b5<2&~L}3~v*GX1o_;gLTpqmN?{_XEu?#D@D@@qCXx B@HAZ1mfx:3@keʻҧŗZ|IZR[qVO\ d|闟na'ނ.fi?n۷MkJu^ֳ}֯wqyf&\#LJ"v3hnn@q5KX(6˕"w8Ndos\ǚOO}_38~ݑsqc&[ij 3ı-|0aƏEuޭ9|~tXpE,8)qed/3q^wթ߯yb[&\q2(P3X \چ` P2?'/)AQBif@`8 f]sw1˻髺g]^ynN=%y}2rё=|^x[*P߳Ox>{(|d6[9)?yb'z1e[>!k[ұ8w^O/}DZQ?+ qLKk/Ft^q2 ^m7]<2+N+~9.>r y80Ž22TVش|Y,踧'o";pHgߴȮ4kd,]2n6U'eNY)KcN %m:ln=rO+\hRuv{rl^r2g{n+)NcBH@+paW-g_`>"pjϮ-w}Y WoH:cUtkgmxKjy׮\~OSV^t)TtYhg?x3oӚ4MksI{ֽh{"~|EǎZfO靯y+bjۧgȞoB#N{֔;-szMo2ng%+WHySAffV;x5_gtEs{߷音/t-3?I0ꃩN]2ީK^~<qfSR 7ܛRQZ_$vWqN[i}RrJ7ldx (ih,R9 -Nu$4pqhS *ЋUO4fo=O8:Ѣry^_gxn:vqCu)^@T<ȓste .Ig>dg{\3jS;븀+V}OxV h~۟޵g^~y5e󥗟{eUl_}cӳ_%y#gDo:WYWNtJ X{ܹkg$ 88w:V;>-HQ{;Ӗ<9#G "d:K_yOԊM4vDz8^ @b1`m#/ ?dIH2DYxeV9yxkڴaxgW{Vk688N*M]'ɐnYPHTfͪ*F%~f`>^B|zx8:V)NaJW( u3^Ttv'5*+N~?e_'o#"Zy@ރH HJe6ǴU StJԐ.XaFSiZeNί٩|xOi$"9߹*Bx^}(<}ܟ>2ѳM|'^Xz*zo, t?zEV]12ts.UЧ?Ekv[4W~iC.6+cFU9D:Y$~SD[k$, <w>-N}Ţ2Ge8)au3xr_baۄ3Ңj@ |ZK}Eq(ZBL 7淅ï48$ZoMۜG^]UozpkX0jM &^B۸2\qK'|(HsB^xaeUD(0M&f GՓ&THi9Mb$-Unj]ueN| )6S 'Wf/o6?S߮z*o#Ȍi?tC.K * 3P %W $T8m[1x'sx0Ld;%C"i+ˤjN}V9XȨ KL@5[44"5^_N޸%WCO 9V1( #4TU++SJ da@J4T^ T]I`+u# -0ύek7k>RawbWR1-[Y< 1jBx }ib(~x3f @0a3\R(?R^'FAOK`^u??2@(V:tf @Z@Xr%^(JDEIQ@c1!˫2ԔW9 ɓ$FH%%P`Y+/>uI $ 3f @$g ,L( QpKWZFc4&&{EB'i+ZWY 2RLC~0a ^’+ܒ(8<.+qȎx kؙ5 3Pj wMJz=Scٵ;1%es 33>J߫"P`oIrV70HGk`I /?ÖO*/Zί((jHⴉK Ҫّ[*s홝~Nkm`Ա}Wߍiv䑙iYG?ٴͰ{whQM:9 BYf ,O6͌pU7kVZ1j.AE3iuTpH(Ƴ4JX$y3ʉz'暲wS49Zyɫ"߫c\> KKȊ՝ss{@+8!CC8zѹ352^uh>XoۇnOm1oW>EW/8ǟ~zDī O)is]ujFk= #@Gd=fbi#pG$%`V_1Z^qkUz m0뭠8vId,<X5U&^_׃Nac;gUx[G meq8Q8̻6-1q#u*w{IWy(쟕VM7@jc ǁ  :w-Z8&7.%IqYsG8NjZܛ)||Oѽ%%#DN9q qAUwbDz^ru΢IMؖ=ټz.,ݾWS(P#S.d-O>\8dF&hJ BeAPf"lK(4QC "`P8qB Vl@Sn#iߡ}Hc;:VR[u+|'}֤iZN޳Eiݜp}Vr~D7U? Yi?,?ߦGB)__.՛d8e58^YN`LL32U3!:3yZZ?z]GMK64KGflִ ֬es'r"-ڷ_Teu|aِϥOMWj>"itJ_]ʻ[aV7^{ /-> 2}h"O҈%ی'D?A<Γ!$0 _LkC¬L/d}s,]4uМ.8eeNu>)^0eX<7+~b':9hQc͹Ls IJ{t3yfS"a _ 4ъ^.8D܋Jf^+DDm)`5<2A_UȞO'Xm\5cFֹtYy}yZǟFYEFkUxfzqJπ%C ) tο㾂3Wl||0^ *[t]2yZJϔw?hDf ,?پ=ZyL RyaBM r{5ϯvfȰAS % B3bE:KLh deyǃ \,߾O9: 'HjŶrƮѾC(6z g{Zҵ{iq%ܱT/5f>!BU@Gj5LXLW`&ʰL=o' G E [6M&`g|tS["~bt\Njx O12c#Nɑ'I>6@DM2ϯ'^@j&SX" OYzɀ%l$xDKYv@.*-3td."e|%![5P$,%w^DBafm2$!29/.RZ}DUU%~x}5ok~} .ޝ~}M%tel*cɤ)8Z5B~UF,SB)K9G[̎i[]WhpMiY ["w l30NHٱvBc[Cī[l={= oZ|soU.Z] @YP: fVKK$تacA]/O6e -j 2Lp%/]ķ ̟* !HD @&0UDeӉ.Y,zL۱Qئ CG薩U):zQ1xR]?<ڵo{_ϧ ڬ))sy}}햽 1FO$dV DqT-E^j|ōdyPZ\u'_~C<22%p!?yѥCoZh'ZxG/vp|^7iZf?-icޒ9ʈ'5sewvaQfU8^LW_'w|c1YMj KS!KuݏlJoAm^$00T.1 (bLU ?~2KW=X^v?UTʇXv/ nGo+ZzmrqǞ zBs緹^C5^92PcV2w("[×4S2#2*C͈#8CLEsΥl7=y^s+NطtVO59e|bXT gÊ@bhwbC dj37P-ac(sp'p|nT#"5(Gf155^(;z"ѮZ26{Ҽ "$ɯ7߶%rtjۯg@DXq§\ `g aR4m._!8TM\q1TTB{Tn4 2TLP~K锕%VҒshta`tjA;BO%+tŘ bA˼˰ A20jeZoN85L`m%WͲ هa+ct?t`f!%-I^/P}p}N(g]q < -ܜ:҅$3DbT ԇ!x* m(և_q/:MKFHHh#ș{WiеZ\?L_*h d^gZPDH>J \ G23CV @C,Ӑ[0@[ "hP3OCcކ0:aɕ.ǟSG8)9"Bz_ApSy!!*!Q MҲh($̆pUP;1 ]E X*l1lSO<$MXbe8 3P’+f&*.J7̶b=Ku/شhb=~uSg 'bg #ku`wJLm3Ԁ‰K.# &=ہ2M ~b T]>"C3l3 %W9oomkAm Z2}M9 2LFEg-SAhz5d +=$g:"맔xgck Hi2 HJ’+`aRKy%Z 7Mw6PX!Yu58Iφ6}DV̈́K>`^S+CKC ^3 2\"YoiڶӌgRCޢ'/PRf/`ؓl̏'2 -̄0JRՒpIr0a {W7 ˯Z).RD*OlNY >YH~Cd}im⴩m'j[Xr%X+QQ.,M=utpr4N4!Ӎ#0Jonϯ8Ò+bYYsLz85bIG9őOqUa+ܲ[ذ92݋ID0̘ye?oVcԁWuL`Z,H^]^|?? g[1FF=8, [|%c@>cyɥh~)b\q݀!N`RH%^5M2#O,'QXh}!y ڳDI#|I|hr+'o`4M@x4 I-5C 5z̓  ws ĭϩ1  C2@z)6ca,E/J:’+P}MK1̀<[eKC$b T*b$<'3Z*OLbH7 $Lv"{(wZ _9q_6]8M3 j T$yb$\OMx"HLbgʆ9qRuFGUӤ < C^3# ESx#AĬ+^m+a3!Pc2-(rᇔkJZBR6RRDXr%0ʄ$*axBh&W`T_b.^IG!H2`ljS5kWVo͂!cT KX R &RQ :OCt@ -wi>j$⁠3QaA ミBPqS)Ϡ^nUHVAa{p+Jx K 9@#H}i#ڍ@i| K3\BK FEF^**ZߨDZ\5m’+SN.>p0:DwM5B9ᓒ\)>(LDQWp@L[;Rx4 LO`dV Z4L:ճ5jdYwMeA 1+[+Dᅜc`b@ [ DTWNSs+QL^@6Q$]$L ?ѮsDh++@Z!UޥApI~Ŕ%Ñؕ7%`FRE}-(l( 36h0[W :^fR.n:$q%Wy*(EՁu%fN&U4d[;!@ \]#"> 7KpW&b~1@qU,*9攲/C4ǠX`D% 'G;27pkU&z/,MxdWBњ.i@ZGl\LMpB<$$% QK|3:UiJ\b^ytVmcY ~Xr%%kٲ+蝬1 GFDxҾ ƥx-M4F7ͩ!02@/rдfAԟlP~~ .--B.96ͩn|KϬ/}Kh6bC1?NZʶ-R7RI f?X;%Wr D cO:E{< +AV'eg*fp #4ϴɝzj|1ZPQaQ瘖=2~$(]3sC(dIGW.]r~%-eLN{J?H:>,0b=4:"ge݇Ia8^p93AnRc~Q41r5 %O5ZlqW"bnʇ5|I?GsLt!$=h9(w"0骗M j&^`A)] E/w۪ Oڝ.8wh,؎;--V 'ߙۋeY]IvSF9vJa6=F+C$ҼԞ][tsސuI&ţ?j^4C_I/pU\p68bsx~i|rۻ2r`89on>?J:~-v~'_\eӣ{Mx`RH +` +VOOҎyG}_EwU_Xjʵ:S.Ѯb 8iIC{I֔1nP޴pcӗ-=p8g6O \ ׻@IDAT|~GVT:M)C: Ӏu3}?E}ɉM9_qŤ;<߲6)QdMh$1\R i,0)~2LҡuhյZ ZTg+8L6h,aQ8Рҍy}]B)!gt jwUm{ySR1hꢡ9]q;loҳ?9ݻu^&x;VO`8w>;!OŊ}؉N鏆1me+<4 S5& 1XL.ϸ {%}(ig?]u+]Jyu$5;gs|j̬_ L?Sҩ4?zسi *R5W>7c}h@IACk P!vasW(j;^pOW:ӜԊ7W/AWSLPU̠HgJ/86GUSzóGc)IzpְNg:_/ξg5NICRb&tIt>SޒMs)iTXr=p0;DK9T秦 jkbMT$?d;5Dn5\+6 gRKtꈁ9=++~xo{oo&O9:+b^ZDER wwm;%aGYޢ-t2[rvGxE?*s+A3 V OmO m$uxjɴrN#+~xw@eԪӁ 'ƨ.u[bM^طDFKdi]Z&k)? דdʭԪFU9@孯x&Wtu_ttGV4Iٱt<0ohif o8wfSݿKKV"fӓK/X0r^;w l؝.}GQg^pNoсm;r>Ӈ⋇]r}ۯ-|u^Cq{uBi]M@&,EO\u|Ø&=_>C~C䢬n"o?*~",RNW6;̚7!?%+ GL~A}UU9G Q)וD ,?Sֺ[#WN4ao!A M]cTbج amwfwYH [Xe9p+D>`3Rk~B`;? }H(Cʁ=Qw"gϧ׳eڎts퓿om_Ew-HYvh׾E39~G?6h;F X#NiytԪfZn9X9蠋FiuOmN=*34?ψ1|z;|2*{)|ØS Ӗg_Ys%?j OJJgm7ϛ5>]Y9D:庯[ֻ+=H U0iG_)v-RMeO>lɿy利yvVՏ}&;vu`EPfʲ?OV{݆/y\V/dW˼$ZҜo̘b58t=HoZO>Y/v]*phU`KKG.4l+SAy|FL\ Wz-6~Xǝ~B'ܔoEUd-*fݏz^D vDM~{* -8r/~A$nGo+R}GwX8u <cE*#rpAŭy\L-%lMH |/NvvA|ZQB!^@VpO-ttA2?^7k~R? ?G%B<W>_tq]eKIR3,Cpo\k0~Mp?@oɞ[p⠑'g<~Nj9MKxت[v]/L≳፤}⮬Ӗ }Ơa2R^jno곺ޥJ7/y~iWgkMHvGΠ2cD贌UppTҶ-8$PqW^y%pΝ;ae$kMF>w\0aa'=>mxڇmiNLMP2e?fX>gf:e%}E)-)v+{qR(#^ۿ+ϾNsFV'ͼ)&60 x!zht{gҧgcf &ъ+E"$tW Ve%ƺVn,nC&K`ĥ&l"'9oak1Zd#)|%+_֕mCgǴްGԕF.Y^j0bJuS. /8(\t(L~ԽϺVL5Uu'S͸uY [&#[Y؊ڄ+*bB=+5!^h T M=g1] ĻcR(-*{%%s,^~Y"Ç('F\ &vV<phC@+^To: __aIa`a8}&Dt+XS 0WPO۴rLakCE[ K.5qq8l|aM.diqx U ijY&7yy%^br ߖ3' s$* a` ʼ"d,F9BDrb[#j%<A0-2T4-,vm.`WbJsm4Lcq_D0c`+PLxm _D`e[63)m%HKhm_}U7d0pf@28}L TA"K.[Nc0ud23>>F_,P~e 5뎆(,%k|EI(r!-LXL5x'e`6UmaԆM hS݂8H#nb֢ⅺWqe>܃ &apkK++*E\Zn6H;-]?&'a%>0C7pKѡo٧!&tz.`Bv|4#paPjKcd؄u|K2_''9Ox$w$uH7[%JD k&b GU?DJxETԄXCqED \"ʳ%6:3McQl!:9LBG㢆x/)^$р|&s|Rbxb,%M1bH ?(> RuQdstufXI:_mnDdv!e]g7f\Poz[]xJhCE$3y? (VUIg.뛢ZWg$}`3KCC7` dN6 L)QNhWW; :T*_(2Lc͑ȔLsF u D%I5he&U'0.'ZaeM/SLNǬVZnsƖIyd %OC᥯ [12` as/ B"h!ARI%!衡1V+0DC$9? V; H?!^\]"os9Z ;/1O4D/5죫+Tك͐< S[j x+x.X&(rI{?Bs1MPdl(G$W+R؄ԧ⓮S>9±ۓX<%/ZRY l ' JNP2fE 49bɽL%@Id"b+>Q\^ɀ9؆z`*ijr*ӖneM KL<>eS4fw.nY6#dv!wN!4nT&#O0˓OIbN|&f锰,|F@(-2x= 7@MGůгaXDIrm`F|+aɥf#LyL`3l0J bkN ߕ!T?? +DjykXyԃd]EOCRݩH]I$ĥSAa]^&  Sb0ZFLSk[V)e2g0$zP4dx\)HX[1 EmNmA9'3A'Iႆ]t0Q1 aӭ-9"5gfy' .&W0נ`w_=%` eX8WQ[X̂ c 5:Q#zL]yҜuԔqHFCM8hdxhl8A1c$;j[ƽLJBMWdo +&s1 U*] 8 aT5FLrT?Qbfl#a<2mOTueEyRuҳuN!&"Kjh)]vM IbZ,1uYݠg0WEjX*D|諾Fn&2aef$p i>pć7A!(6ui(pShCvDp2*LVa_MRQ1e?<;X<0wؼNC ɌgqaX^tA: T$Ba)S >~Ph)<1/f[Xi,%Faa Q~͟??n` RF&F'#0mU3CҤr$_3Z?@,]{˖y SIL SmC7=E%:S:t=mYtp+K[t9rD%&uSd Gm8jg0OףH CyQON27%e9AE"FpOi:"ѨryؒQHJJ B0FT\Bń@lu0yB&4ttFy5ir^ lٳL  MTS>_})&>ŹazDHg)j &'P,t+7PLm6%qz&do!Yl(GRxOc.%@M` .ɮFT q=j@ܰRnT $$dN0%ԦУg-=%P4d7`w}m Mx8 ǵIt,S2qBXn@Θgnbl_nʐ/L $"S XJ Fk(&' 4G l<y }jJ-uKv'^h h]]>DUDnemmk512+6 [¸)M6@Wr7;1HCzV \cAe4h$zvF̫ʸ ;?-,u%5AʄU@OƸ|ids,Gӊ ?Td@]dG h`A1=: d7\6n!)amum'{a-g%wE<bf'F.э1U;km 0biusLD.%N$ -B^pR/CO;{CҘVXLey퍵תn`5&$"'"fTm2۩e|Q] 3zeK *f-a @!1%n}Fucr s@d(K_uX->cCt/ K` Ӵ`pD$NDc=+WiFǁ.={Bwr̛F*0)3MC>:R*F!Y Zt0Obaj*d'RbX qcanWN$/#ȓt?" ) ` SfMc%T"|0n|g"sAk>[u^pv遭:t!\2`Jy$Ms 51z|ń&=5zOMмH[a.@2yLng2`@B2{9ťö ]F kha Fnapw?.\ctk|9߂H_$94= y?lɑJ`DUœx4*5b89x_y=1Hnd|b7$1{G!e⁣@jKn\(%#" @N@ i`"XhF5cTp+Q8 FS(.W)% ,O6\(*<^10Z-܆A56#pUdOVFJ,tVto3*19n 3=\fc\1ǁv,4Co .QR#8r[D,_FR&+F6Tah0\ <\=TeVKY>2uo&)ӭ?ld]fp +dl6 '柔m~qn Nsm~sZn œzY[qqMqJydfZddd6mqD3l>0ZobSyN}Gξ ^-g ,`Vhu%=83g_ mDe6''j{q\ ,?z=mG]ujFk= #@Gd 0dy¯')v!& ?9 2`IF'UJ+‰4u*luDVԊr]o9ev':I5Hǎ-'R7-GN]^m?w4*w~]7/,C4h-|L4nx5w{ {d'diފ&U1>s22TVش|YhGx!zsג#/ٳjGIy(쟕{SM%fݞVr '{lw.Z-:}YN-Ң}m華ٞ|/'3yZZ}b3>d?.YEN)oOGZx}w'3iM6mc~*}u+nn/VqЃ[3_v)߳-̦Io77+":-('nIݿ~g+[il K9b醭 e`SI%cMcS!uXg{lj?~A!6n=ZTX=}#o|E}v6!h9%ӻf8;_裳c4;>^D?>A$+e3ޯ[KMw0-MzVo3{מ {s?ُi1tK7Sx. .7Uoܺ뒱*\q:NՁw?ix4 Oܧ۲BWO(!f@ff/ i%P;SaGYs/Z;wfǻAjŭ;i4| /@t`.b ؽ-')˷o`^o'#}K*J70BH`! N~Y}K  ?1ΝP>.rKUmZsucJ uaV;l2y+@E~Е@zX[f8+>p]Nvr:[6w ;x~y ¸"lN>TȱN6ǴUo} Н7&$7>rJ8߸douob1NjBt|y͆m^i*voٳ! )i^,*P{:pex=Lk-awjݑZ!?% /p[^+>Zo'T'eã]ͼ|ڐ Jyw>){7_n_T3^@{8ƪ ~qE+?:xXVMu\-Hyuc;[9V VZFYbGkl1nG-+1SBW,.5J@[1u_P"bݢs26)Xv|_s=}~s~Ҭy_//K _i+t~__g_?ܯϾ^w_ů???~cw-V7S{S_MS@կzwo}+C.p|w??3B>o_g_+_wQrS?{W~7O?u-_7[?Zq.3J9*I m~XiEZԂ׆:'gZE> c[kݿ`~S?/}/~/>3?K3#o? D|ѿ&tcŋ^oV|k C‡Oa >o}Wo/yO}e/r􎯣_~1Zhw b_Ї>T#_d < 7΁I }{ec<Ծ{auE׽꥟'7_O_lIW;DG{^#Z ʼNc_7.v;3?hpLggSMz~Np4b}moW;o?g~ǿJ^E؟/[_*,5[x/O}m{[?:/^ _n] 0V~8)ױ9V`A&Th|!ȃ.! 3<7t(mJXzF ݚ,eKIebøJ̥xOM4k8_C!!x+ x|y~O_}q9PVo>Oa&/miU.|^W?|/?}g>W~k^~ނQ=O\en:o~[`!M{ 벌jm(kh-3Hr,ŒW`,z G!KsC¨[] &\a.eM+'_3BmBL9#Swso7?ɏP|#+? ?\=Qs} ?PB(xE#XbcHN}cz"aDFl%U)I7Ӊ%ݪkl4gȉEwk []. |OKyd`\->R>z+ABEX*rV|Ru%չ bk(&Ar7!QV*y 9nwjw7/O^ejÅxZMQs\%_"VFRjo4WWmSm cE223Ja)DR?"-)i.3p`:mx)]0UqVV8:1xvM"@K_ b h)kl3\s_{,yJwet+++7\-m 厐|1_ZDs8#nQ(WFEv.S{r < lZyCOV*G-<,5>KS;[cɆJL`,F|eU =BUuinnykfº@p%&o ,je`e`e |(eI@e|p=.xl@Pl1431 x[;)2kP)İsh L\gofW̖lLDݥ֣`S3t++g`\tV,8ҨZ1"$l:ڲ 5'2yHۈF1d`V( t5iϷ"O펻?.,!ۚoI\6(HqkG c/h2NrGgVV?G8:FւO'U :!8#:xY t-{0)ki[x7.*&tÂf[b aK|/zgSU<3L[aK22p?X%< w | zeGS#鈄NxQQ-B`ӭ27D*2=:qvWulSpGq~t0m?52X%(uS3Ym,eyCzxH@\B< cT\he.sHkG\4Shwj%fpGĝ;F. -ҩA 220X%׉yV[X3)R8n VvJ1 UdiBbiTt$󛙐@  :uˆ:I]7"xXU9>L*4 UԺhw AڙD&EAGXܕ*eN.9˩Cn@1LXHt#.T5QhI;X4؇ oPvE7iH-f \`9LûMs)]+G Dfjvб6pbLe[is%ƅicYX<:X\3g7^~ 3$6 vo r1I5 ' %i^o@#vnw ίabmڰY.m$/ln-olǫ7Kee`edVu8qpɇ .Ju @-ReĢ]@y:E8׶v Bت'aA=~+V]Qd ĥh؏JNb= ŧPS8]=PUE@$9l5+Ur>\q5G!MR|W>4k1Ow$Clza#77ҷUF YM@?>|zB%{D-q4YAMEvǣa.MUŽ++UrI3x"OEl%bAA ؝Q،4kC&CP"Oe@>42yK*h5-]e?6/AS^1HkqAio[Z]g`\'s*'%ֹ4 ptm[Auծ N+yF|WwwZ /2=Fb2M X*Uvܞ(PS+d/t~ \F3pXf`\-4Ҝth=؇ *,[ A!7U BW8 ;m͔z`m@IDATO#c|ű#rvmhZ2 X%5;zkZO1t֯.87G\cCvR rdoa%Zf1z̮܆ y|M>q%q92E3l)~5Xg`\Wi?r![6F%6#3FH6T6=fQgAlȐ ^QBX2J39ܤ̀uНL1Wr ~9'8SaK GRK:T]\jeyg`\g_-BN5oye`t!, inC=Rr)&\t.n88-[a]X T~fK:7&*p')Ye*2WO+oTbWE -Yi?&Gߘt\zJKڕ*χtX1 ?Vr"oT]m^2p)%XΊ.K`! *gIskl 3AlwSԛ}|R[ِleA2Ji#Y mJ7~OĬ/2H8*٢Pwi=1q-z!7ss y=QwhZ]CIjƨycjyE\vV0:|:lI'PeӧJ Mhi˿ޢKs\t#ſ 4wʙ]?5<,Rtg>mЈ\1kl&ԵҌi+ _|V2I'okK20/oݧh<.TхMUrȅ)IԞ T)Z+дju::]M_}0G@O+x_QwF]i&ђeVyi&qtX,W!OQF*ςr+3KW{1Wg`^r}u3k8yx'LK(37b1nR|+g1JUItA*nQ$չn pΒe'p;5%mq`>Иmz$63"M6^ݳ~vSNb]z1A an23n;sB.@*jFqӏltOh:aWԸϜ${EMċ +lP4SJ9i}-R뤈еz,L\9-%m&ߵ܍Vf~CV<)M&rc횎R5]}D܋Ɓr`쮦IG+ӥ nݨGq- DI@w.1ymŽ!HQa.Cx␲`/d #B0e/_!0-$+"e*'6[ j{w&㥮GǠ:_U9؎ƎcDw&PAWnS9\Nu1W.*. ǽ 8=V6a0@nh}ɈэxId! ѥ6u㠃0E le`\[acHRO{}3O'WwA@@%sl+@~0En*ŵ>F[4}|.a>[* e+?CXAWY7ĬA'b mm}4" J-A[lP]nVu,!]NOh'd;Xo O8f}?*f'C/]5MTȀO8Q&T?Z##]80B[S ɺȠ`y% k{|ڢNjQ{zK4ٵA%< #W.\L#mUٯ5#vƉEE&;Vw m.яY` i/20$ *[LLյ"tɫR ~g^@m9,u{L m #3]–l>ʀd`=:`W6 ׂ@6ok+eM8 ұ&O_ r8a1!Xeqb2+>Ӎo+l>jsB,LAELyMԘf=~( f! hRQCcLP20ʘ6~Tn=l5Jdlحu2Jy -"gnݫ25!&u:jeTU9#HRhҒLj([1y1rf b@mka[?cT~?Y<J]XU3W" P`kk4\" N'& o^&wUrO/G @É =.{ͽ=0K^3O|;D= `ZJ .rBM A dJ^V0UM4W-K6i,gڈϕ" fQ׹3 meh׀2*:I9j=ae 3w@:I5x߻:ґMaTpD\l!!ieN UA,`%fD`L{uTߙ59%s*4Ƚ R4 qg/f\)b՝m(=-#KA0 HG+5Ң(7SvSKQz{ru7Ofk\=3 N3J67r ~F,cUu=VvvH_ s躭]r C,46 UrSw5oM$]2VJ [tVurzԟ \|Q͕>2 W:\LMnPtC#A+)ªKON240 r?d1l9V.(`7$bfoh+e`\gRh138ă??3Ζͳ@=&p-'!S<޿gՄUl~~ܿI']1EㆳcY#2r- @侉1Ƭqe}~X%ש9H$:x"*pԬTQ4 a&0ڡ߭:4!M~PU8!0}n׵*i%%xVH?}Kf]v"kZS4iG!Iuuma*`[.S*02J9HJ#@CWX49t u je@Hq1BִRfA  ض /n"=BDgƙ2lt&qToVS4Uu!]9/eGN\甁Urm;@~Kv*V]K.ln5  Ӽˌ(;#>:ެ66 bji)su;wv㺒:am< u9eD⋚Jpѓ1މ8x;8Y'),.vEBD|X%ɗ[Hԁ7|H*79 H}A³$xepg9u`_ݼrv hW uNQݢ P3  hlEّ nq4#U^Zg{;86SuRf= |Ӯ|~f<{Æ60<#o^8>ǮEK;7~59N#lE=H;]4+ +~ܕLWDk?Bbvq$5&^m<mzF[={>e`\g:]=OnRŎC'bR;oS ,GG1PKy{@Y AId.mtePI2'CTNcAeZh(&bU - Vc={45_#NIG\-ca:W6)Ni,be*g;V,-i<5bsMLnqjOƓ4a#{mznWLP]pbk;@cV3ڒ;N;N>ГHoA^4¶yJcDg_ҙwӖ|ĉ R'15$"bJǛ8FO6:?=y\ >H4gSk9EJ}vr֦$ZG)3;v9BC9UD,|y Yh҇ + ׀DBkw IąG|` 5{E Ǐ:]X%׎$m ڼYьv5 l\H15fnlOQîSZ Яc65'' Ee@BWȠ kUYf`\ǦpSWxm<tIvm:3rX"ĩM>3sS&Bna: њM,~{|"IΗJ2wMJ5CElaY9gUΦ4j=NpbՏک?L(=|MDC3aOBЊq~A0AL120*IagC{ 8XڸkmæMK4G2ܗwQK<|4@dbсǜV2ѽ|Drꈇ{=]Ì`X'(YQoM a8RCAV x%@{B0~DƪU%ƒZLbVufVЊ OB>F@tvv)‚|⊊fQZˍK "60A̧{/{shZwSC=;y|Kai5irGFceKs']KC6Ju*NN)ROi;`Ç,YwpiX d`ze{|Wp(=Ax~"퍰Msy7%.#BwF<vC2+,!8{ Q8CAp7!Q;';%z\sgU7yG-1[hKeQ'sM+b@z<{'J/4 Utq(]bԵE58 xW C,L )V'V&cޥW5?CaW/ي~l+,;-LV6 A :60 9Egry>l\WzAtD=l< 9X@?躓:9N5doP\xӵzQwxeצҀLRA@ubM2d)R^g(VsOo,kE})W"qJ~d]zD,wINYk)ƍ/U]q*NN V`+K"(ο|3 ;b:̨20OZn8rGEňZQZB(u =(YR j|>6Q Y4e*0)ZT-\5iƋFʻb !Y]Wu1*N#[CVb\ut"cVF8vJXaO,yr|ڄ2cf.k١ "~|ǭ,~U>ǾmBxbJ E3~80>F\C7F@>TW+j=}4ӛNdY$ CG*iZ$ "iΫnF("\*]bpe1 :+K`GܷQ(K:@:)j)`+]"ryy(c޼T7G;;s{x0hAW7̙ٲҞ &&]œⲄbW3DsMi&K~~ &ghԸ8%G,qQv4)HLL ֈcL2[Ͷ`k裂@xo`9ԋ)sh9}hi tӂC ?S6!nTR0\c_P⅛/I U+y3"|- #~Q{b][H$" CU΋v2pRgS:b6&QqskZv`Z WBl{뇰&I6pHdojQ{Ndf`LH%"5dmEFNa/s~#m6 !`ZElope &]?90L hrwGc1!Vu# #l U(jz|yɃ^&hBc9j6ZZqvXˑ wr72?Pf2 ]H@/A34kݿc1W1:P9lA`4EiN\'O7?4YFFSbr$[3Z%hloo[Ơ`ͮ#u6- z#߳d\<xհ~+2SE=S0 a;/+$߉ iNC ۹i㥭qgݑ0j^@f>8y伃ai.~ΰCP-pe>ARRh)6eŴ |):BgL Yg$t&MiAk w屟RL|~H `ӌ m3ݞpXJcj[&cZx1P)񡪿HZt&,rAm<Q-T {Pxtd40Yf()?iI; ^dɞ56Y\zzKT4I^NN@ۛǙ8/7ePĹ?460ƴCUr:qpZ,/[9&5c92KD+L0CA[hJ phz]1$evfJgg%x~JKn2޽[QYNzc4}6k]C|^* 9YYB8,o(^%i%G fEMA qRƑ_,√eAĤF2 KaYy7*{1VP9`]W;iً, QAإ"^ح"D! n1\u4/zU|V; P@]lGʫefȇOɠ%6x@˙?&/J~^>bx Mб.;td7¹`Ϋ.\<1VY_]TzTſji蓙AބZlújbɧzf&>H)C<6#v:K>K/C\OG0h& Ȝ}nIêӢVow! &0W5D+/b%=P'Kj8%$bCE_R&=7)s@Rs"{@vG.k/kơoTcb`|xKFp4$:sٍ:jKfWYWZ^éP@b3NwsB% **kuMva?=Quѝ0kP *4IGZHV\({< A+ z`Bd L#|ʾ&"ݥ3LխouG|\!H%+o ۱`F4CFR\%C`.Sݷ:Woހwo w QJc]7w}D\P7k^;Ax`Lg\קt" O]wHT#w,d*GCi=QBO]7h&fw뚢9 heI.BSwiC09xM"*EH *8qA&0!ipj̕,?KMb+~%fjVeE6J@E8t@Ar"l8#O2w:1R.utUrŬ{;k=Dސzv.:$HĮgF79/hiNkSYXvXpUүDQyӂtl)B2MiD[B:rKޱrP0^^J Sѳ϶9Vx-f(ȅM{I6{r ii tsP4fy6Nӊ,+y[0O++,Şع2'n);cgYOL 9V&/Ϟј6v ,ɤAR8`hLIګզp1°$m}"^8fe*}b;ɲ}oΌA56"_2Tg0&IN[X"4ބ)5T_r25V5'ΪpxB#!u2^ljxr$t2dCN3@9 JWBwyVxF+C Y{+ZYŁyfyh 8ZT8͊,6ꬼ3D a آ9]$I1z(EŎr@6"$ N*dM"jh @=&:(g&`rSѐ,VdԩCD#u_#qFvgZ:a6,ՠtHDiecZc@ uy=1? z.٦ڈ.  Zc!+'lg2Y7}dxpbj&X%Fo6ϩb~ض I?6\ _t[NpzlaS'\S5!>QVD7ڣnOӟ=+ 2ė^9!PsK&Ӏ|2RE?w>=b VlB[4DEaol삭Y=YJ6Y5f4C`xRqY)tZp^Rum- ]f]e`.:=_`޳{3Ùu Eƣ!ʅ}@!F u6Hm"Ͳz61! >+i_+/( Q/VuHǿK"q=՜ԟA;WjJ=${uY8B 6C <((M0Of`GJ7UAH =J=&@7;#(0f#oܕ: G <`),Դ:JrE_HZ~铻dRv mPZHP)bT5#螾& eS wd1:% FUr5]v7 3R֥o^L4N%HW9@ j,aX+f@Wh::XJ.3i<m<"X p6~^1Ѻ%%MizȢ8HGiP"N]AMzm Fސm.:t#)†)ph>}߁[yFxhvhI2="K+ƬsF GBb w~%VJ7A\D$aJ( / 0/$@WK9@!dMuc ]@@\f@T0LP՘ZEaU ~ud  %A茅*ELl8\Ѣ790ȋR{Aa^"w+7vMP4ԧK}.Xt}ϑTD CJċa4Ck^pm2R'NkSw C@IJڋܤbQ7h -Z!M_2[ހ@(<"SezLrtAWe)(+&D6̓M:yvą(Hlx o& /2E\Hqܮ#JUG4]ECj,Fs/DZ(H̓BJSuzlV\C:{W[#WOF(2 fv1p BWl(28Gtu8>@ʔ4-ie.`o2' ]wЋGiZ@1#:u }{ CxWZםN% /_͟czxnnuvz-^QbHą(E,IDAT J(O|baGc=r&)WNϩ/װ8 ڧ(Yvf8c"/kFbQ3ZVYE4QU!RV{"7]dݕU?)O+9C4FN@uDIYqK bKy$JqhqMغ \"5`d'_^LX2s&0UvxF^2V &mZ?J.KQV M:=0 V&$[f"lvpʼ8QIX4ǚ+:`3N ;i댔g΀lKUڴg 4g]c>O焧D{csߢ]Sז#)-3sGPS;8wAkYtiP 4j@@ۥB8Yd\?z ;Z7z̛mZPЗZf!\:$mMDI2`7!b Mߒ4)azJ`࠘a);rk]b%엤w0jEf}<†؈!d$eɍn#Pbu-d善t4[K* S(heBn8͐,R`JɅgWOKM1sxI4䡍4Bbϴծ? - L^M:AF!f0A4'#2MO+󠔥BMHq@"Ӻ X!A:* (nl{f`wpD+=Pf&S`)Ğ1xf4 b%I .jUx3 lهi5. ?!/3v P5awhEd0@fv1y, =m fbGV2 )`!Iɕ1'.g-p)C*L)$~05'KzN1:y93 VkwuY`qu/qr qk6Hk %G ߱⻃FV=~ <*7 O+d@} ;{As;R"XO W27nNδg{=%7rm*07 %#Ga $kq`aK"FIA܃`7'd5O4p_9JʵBs4P3xA|E=Q@ '#K0( C Ih%h$-nIP-Nm}zqHr+:o hb~0WhیeabB"@YCQ( BΥaDs>( yz-prQ."9.j'ၙ{D6(vϽ* t`4v ˼Ճ= &&Da*A0D\\./֜rM1!r m_ߌҤ$bV ҒiN#z+H3zA|҃hDD$\\oWǠy+;1p -W31R4M8,#Ԭ-B#yߪa*HH,RN$Xj,TxB t(bQCuV$zH)MV킫Cӆ$*hۜHm4Vݜ[; 2Em>M̥3L2vI)|t2@I}Ԕknr ":P8Z]z6Tqy> )CeծzdekLC FTD^Q S.2ý*cA꺶m@Px${QѶtufJ4ͳSҘ5`+7m$b:bNuo 'S"ـ*ȫ'yX\u̮hˬwyĊ!CDs{d3g'l(YKG=Ȱ8C|XRj'jD G_4h"Tq7vmX(o -xΣ>i,wD`ZX8݋0PϠe E>EN7KD>GkO7$tF.Le`d&R %sqojK&{l*@?S*,e['u4ӂw4,3Չ|!2d!faR۴̽/ )MC¨+(M|yI!"!B7vTHFʬ!utZFܘ3#hUG) f9sbKaoH'8T+@u,h5CwbQ:X%ut\6+8JKMoԇL4y**䇂C˘pe0 .dR!t-3 TgSwpVHDTD(&A2+gz 8Q(Dbp[ڧ%WL:,g;P1(ZYUG:" 3oނ%Njj e*Ȭx tQ#b\OduUle]ĕ,:3#b/Ź >~ՁvZxR$vegW&h`䮉9Xb[`X QǁI 6NaLgfEuSly9irSg6B.X] bYUlڡ8dNIGt^ hP6qJ-I\I$_+eԝqGFoEhE)3!RdK cOQ2;hq80-z`u k IXw,I8*R2&]4Xf OщubŅ)=0ۢSzu8kW2JX]=kw8&zF.rߘ1G@s\SsڻNzh7aebrk&4(MՅURR$;}mOaIǗƏkhLmM-urJ[) U9s*63xt+.疁u۱ϥsxqE|^ݐMzi C)7+``þ,\!CsTlo\<ns1g`yG tt8ؓԱI881t%t\~֎UN\ ?a൦rJ1ۑO4MtF^o4n QN;r'dꠍR#>FJ$UEO?VqU#.^;d߹<0Ez؜n./Hex6m=ʕ jCPBFK-=a)ˆ_j&P%8{k&>mI˦z[`:`ǴphM޻LDm?}Z%Z-(:%WDVdzs +d|2ev87n3.g1c"fVoa (u* bJČ̔:k5c6`9DvI@qˬt 2{X$}ܘ+]0 -DpDw #/́tJr1:<{;=,=KfNϊθc g6{`GNHK mI$GaҶg#at@peZ'5f 'Ix1\d"Zo)qy)6bӗGH挪O tEGNf0sEH>tDJ&%ɸYI9pIrBfz2ۥ_oC|a@s؍@zrU6̡v#\Mѥ*]p |s-xVqD\5]dz-gws^2o;s{Ƞ[غ7pf5 ȁd4e 2_#,z)6aXNi\eO,TXB),Uwlv`&9SZݩ9vd21K{e`edl[8XW* /*uΧSF}En']K#l&"&Z al2{%ŗ Ti" fV숉Sٶ7}Qh=E$ `^}]\X(׸#\4hl2?\+q<1*D*R89Ŕ nR8թ.SkB$A( d@җ3E4.l" UmspD(%N0oȀ [v` ^v@Ba3fHŗE7q9;kK8aFe7x7&}V)$2vLmDI:gv &NdENw|*~3 ]"ɓ36ۀz+Ɓ0S[}$PikEDE3[]l #<`u2#~ڐ2MhŁ8xʈ;ܵ^hVug|DiAҠ%Z}e$4 S`לd(mZ#=Ű$%[9nlL%f$-JDt_=I?!Vž6[!@ l;,5:BbFaV%X&dBL'# D,aRwhdz A;*PW@  HYdDm}_ -J̵입tG($X ʬ y85|f48Y&`@=ȧBq'5M+hODEsuQg^7 )̈&Dfޙ@|P!\4(H169?fP EkD }SPb(P*`a,CS]4 hh,JYVMoFBC JDX-cr8+`ϕXTёt4M6gReA^Dk/ + /91G1O4Z ܶj9!ak |$f'3t 1l]X \Oꘒl呍Su}Oc8)vwRMOh%@A3͸ ,ą!UU1 z*"fst0{:ciUtDzzhO/̥v-1]g] &Mr k.mC3"۶VWk9}>7m u6 |4N ׮V 5௝&10 8]Cr<}O @ bhO6_\i☓MOW[pjW(qi2*{ b jLsœh5dWMԜ8pK; :OvE:& 'Tfy(E:ZMKxn8D?>N9Dک7N#36DEwo |=[SY=V{Q?~PvV;סd:k{ON+g3G\X52p,A?هP @"Hڍ%:pAsDnr+C~sH"`O*[8O@Q^m'K:yiY ǸT ,R&GPY:=#'ΩyT'3}C%`7 n G1M.@x;]d9'!u֦;T*=Lc~J#*!P)8"=‚yʐ?d60죸-3ЭP?<6-=-Cd8|¿\% s#( N6M:[ LK;!5>>uB[,3N5;\Bi[i!˹mk7Eʶ3eZ %ʴEXdoɫzCX[cKK w&uwݹ-<(bw py@Vtwl/M]2-{Udێ3+zrt^7 גk4'$\{V^v i>L􅜛;|K-¾-;bi}4 "oI1Ae-g[F{7 @ p\&>CfNoeMs=W}of=E+m*ps)NTd',3SuCkM0[ ÷2s\{{dUQy Ivaw14cHZ5Kr]re̩{;@rb)X#LwcKrk ѭ|>IНX^s1< I͚aM3\:\ ʵW#'$]vea8D nYq&UѫX$9$5c݆lP^.=;/ǩoM\Cԏ`{4%OfC!zy5+e~W ~_HeRZ*oco-$? +(,c{!=W'F?S Į'FBGA|5$4͔r7g#V JKuh^vqciɹZ d@@rk%ZMDizè8Q+O<ߢ0^xM=8W{^|֫N߶fXl#{6'͋gnf[Wέ6PZ̪w3ACilD%~1?ϒ vŝQPk ו!&k6& _EJ 0^H`XNsE~٪ Y XۻV|^a)r2[Ѱ*ݪ‡dh 5 ^N!@#>SZi)ir˟g-=$^h<\bkWSw}dsuFh^yj ^+@EٕL7~}%V $)E *0-7D|*fԽad\2ZKR=̒AQVX<8XkwE_\?Vh;I*!&`wfh@-{j4~z-OxM2{5_kc=~m;B-ވ5t@5zR')Wx*%k&w,uG]hQ7Hꪹ6"\.s' ASqj),߾ETy-Zw(ӟ>̜re8+ߞYMMYMkܥwV7\v9fڜs.E.XYnw 5VBuÕ՝j3؝Q(]0.zXP/ޡ ӢF'[U 廊'!P [_K.dlgH܆xEui>3{wxt|ԡSʎΜɲJ zH^VOkYBt{$_n-Mg}4,Nct﫣J xg6b0N EQIqԧջ78FGu|YWcZP+*D Th?cWIENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/presentation/000077500000000000000000000000001457770046000250225ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/presentation/center.go000066400000000000000000000007541457770046000266370ustar00rootroot00000000000000package main import "github.com/darkhz/tview" // Center returns a new primitive which shows the provided primitive in its // center, given the provided primitive's size. func Center(width, height int, p tview.Primitive) tview.Primitive { return tview.NewFlex(). AddItem(nil, 0, 1, false). AddItem(tview.NewFlex(). SetDirection(tview.FlexRow). AddItem(nil, 0, 1, false). AddItem(p, height, 1, true). AddItem(nil, 0, 1, false), width, 1, true). AddItem(nil, 0, 1, false) } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/presentation/code.go000066400000000000000000000011571457770046000262670ustar00rootroot00000000000000package main import ( "fmt" "github.com/darkhz/tview" ) // The width of the code window. const codeWidth = 56 // Code returns a primitive which displays the given primitive (with the given // size) on the left side and its source code on the right side. func Code(p tview.Primitive, width, height int, code string) tview.Primitive { // Set up code view. codeView := tview.NewTextView(). SetWrap(false). SetDynamicColors(true) codeView.SetBorderPadding(1, 1, 2, 0) fmt.Fprint(codeView, code) return tview.NewFlex(). AddItem(Center(width, height, p), 0, 1, true). AddItem(codeView, codeWidth, 1, false) } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/presentation/colors.go000066400000000000000000000024041457770046000266520ustar00rootroot00000000000000package main import ( "strings" "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) const colorsText = `You can use style tags almost everywhere to partially change the color of a string. Simply put a color name or hex string in square brackets to change [::s]all[::-]the following characters' color. H[green]er[white]e i[yellow]s a[darkcyan]n ex[red]amp[white]le. [::i]The [black:red]tags [black:green]look [black:yellow]like [::u]this: [blue:yellow:u[] or [#00ff00[]. [:::https://github.com/darkhz/tview]Hyperlinks[:::-] are also supported.` // Colors demonstrates how to use colors. func Colors(nextSlide func()) (title string, content tview.Primitive) { table := tview.NewTable(). SetBorders(true). SetBordersColor(tcell.ColorBlue). SetDoneFunc(func(key tcell.Key) { nextSlide() }) var row, column int for _, word := range strings.Split(colorsText, " ") { table.SetCellSimple(row, column, word) column++ if column > 6 { column = 0 row++ } } table.SetBorderPadding(1, 1, 2, 2). SetBorder(true). SetTitle("A [red]c[yellow]o[green]l[darkcyan]o[blue]r[darkmagenta]f[red]u[yellow]l[white] [black:red]c[:yellow]o[:green]l[:darkcyan]o[:blue]r[:darkmagenta]f[:red]u[:yellow]l[white:-] [::bu]title") return "Colors", Center(82, 19, table) } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/presentation/cover.go000066400000000000000000000032351457770046000264720ustar00rootroot00000000000000package main import ( "fmt" "strings" "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) const logo = ` __ _ / /__ __(_)__ _ __ / __/ | / / / _ \ | /| / / / /_ | |/ / / __/ |/ |/ / \__/ |___/_/\___/|__/|__/ ` const ( subtitle = `tview - Rich Widgets for Terminal UIs` navigation = `[yellow]Ctrl-N[-]: Next slide [yellow]Ctrl-P[-]: Previous slide [yellow]Ctrl-C[-]: Exit` mouse = `(or use your mouse)` ) // Cover returns the cover page. func Cover(nextSlide func()) (title string, content tview.Primitive) { // What's the size of the logo? lines := strings.Split(logo, "\n") logoWidth := 0 logoHeight := len(lines) for _, line := range lines { if len(line) > logoWidth { logoWidth = len(line) } } logoBox := tview.NewTextView(). SetTextColor(tcell.ColorGreen). SetDoneFunc(func(key tcell.Key) { nextSlide() }) fmt.Fprint(logoBox, logo) // Create a frame for the subtitle and navigation infos. frame := tview.NewFrame(tview.NewBox()). SetBorders(0, 0, 0, 0, 0, 0). AddText(subtitle, true, tview.AlignCenter, tcell.ColorWhite). AddText("", true, tview.AlignCenter, tcell.ColorWhite). AddText(navigation, true, tview.AlignCenter, tcell.ColorDarkMagenta). AddText(mouse, true, tview.AlignCenter, tcell.ColorDarkMagenta) // Create a Flex layout that centers the logo and subtitle. flex := tview.NewFlex(). SetDirection(tview.FlexRow). AddItem(tview.NewBox(), 0, 7, false). AddItem(tview.NewFlex(). AddItem(tview.NewBox(), 0, 1, false). AddItem(logoBox, logoWidth, 1, true). AddItem(tview.NewBox(), 0, 1, false), logoHeight, 1, true). AddItem(frame, 0, 10, false) return "Start", flex } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/presentation/end.go000066400000000000000000000007371457770046000261260ustar00rootroot00000000000000package main import ( "fmt" "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) // End shows the final slide. func End(nextSlide func()) (title string, content tview.Primitive) { textView := tview.NewTextView(). SetDynamicColors(true). SetDoneFunc(func(key tcell.Key) { nextSlide() }) url := "[:::https://github.com/darkhz/tview]https://github.com/darkhz/tview" fmt.Fprint(textView, url) return "End", Center(tview.TaggedStringWidth(url), 1, textView) } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/presentation/flex.go000066400000000000000000000024321457770046000263100ustar00rootroot00000000000000package main import ( "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) // Flex demonstrates flexbox layout. func Flex(nextSlide func()) (title string, content tview.Primitive) { modalShown := false pages := tview.NewPages() flex := tview.NewFlex(). AddItem(tview.NewBox().SetBorder(true).SetTitle("Flexible width, twice of middle column"), 0, 2, true). AddItem(tview.NewFlex(). SetDirection(tview.FlexRow). AddItem(tview.NewBox().SetBorder(true).SetTitle("Flexible width"), 0, 1, false). AddItem(tview.NewBox().SetBorder(true).SetTitle("Fixed height"), 15, 1, false). AddItem(tview.NewBox().SetBorder(true).SetTitle("Flexible height"), 0, 1, false), 0, 1, false). AddItem(tview.NewBox().SetBorder(true).SetTitle("Fixed width"), 30, 1, false) flex.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { if modalShown { nextSlide() modalShown = false } else { pages.ShowPage("modal") modalShown = true } return event }) modal := tview.NewModal(). SetText("Resize the window to see the effect of the flexbox parameters"). AddButtons([]string{"Ok"}).SetDoneFunc(func(buttonIndex int, buttonLabel string) { pages.HidePage("modal") }) pages.AddPage("flex", flex, true, true). AddPage("modal", modal, false, false) return "Flex", pages } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/presentation/form.go000066400000000000000000000360021457770046000263150ustar00rootroot00000000000000package main import ( "bytes" "encoding/base64" "image/jpeg" "github.com/darkhz/tview" ) const form = `[green]package[white] main [green]import[white] ( [red]"github.com/darkhz/tview"[white] ) [green]func[white] [yellow]main[white]() { form := tview.[yellow]NewForm[white](). [yellow]AddImage[white]([red]"Photo:"[white], img, [red]0[white], [red]12[white], 0[white]). [yellow]AddInputField[white]([red]"First name:"[white], [red]""[white], [red]20[white], nil, nil). [yellow]AddInputField[white]([red]"Last name:"[white], [red]""[white], [red]20[white], nil, nil). [yellow]AddDropDown[white]([red]"Role:"[white], [][green]string[white]{ [red]"Engineer"[white], [red]"Manager"[white], [red]"Administration"[white], }, [red]0[white], nil). [yellow]AddCheckbox[white]([red]"On vacation:"[white], false, nil). [yellow]AddPasswordField[white]([red]"Password:"[white], [red]""[white], [red]10[white], [red]'*'[white], nil). [yellow]AddTextArea[white]([red]"Notes:"[white], [red]""[white], [red]0[white], [red]5[white], [red]0[white], nil). [yellow]AddButton[white]([red]"Save"[white], [yellow]func[white]() { [blue]/* Save data */[white] }). [yellow]AddButton[white]([red]"Cancel"[white], [yellow]func[white]() { [blue]/* Cancel */[white] }) tview.[yellow]NewApplication[white](). [yellow]SetRoot[white](form, true). [yellow]Run[white]() }` const photo = `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` // Form demonstrates forms. func Form(nextSlide func()) (title string, content tview.Primitive) { b, _ := base64.StdEncoding.DecodeString(photo) img, _ := jpeg.Decode(bytes.NewReader(b)) f := tview.NewForm(). AddImage("Photo:", img, 0, 12, 0). AddInputField("First name:", "", 0, nil, nil). AddInputField("Last name:", "", 0, nil, nil). AddDropDown("Role:", []string{"Engineer", "Manager", "Administration"}, 0, nil). AddCheckbox("On vacation:", false, nil). AddPasswordField("Password:", "", 10, '*', nil). AddTextArea("Notes:", "", 0, 2, 0, nil). AddButton("Save", nextSlide). AddButton("Cancel", nextSlide) f.SetBorder(true).SetTitle("Employee Information") return "Forms", Code(f, 36, 31, form) } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/presentation/grid.go000066400000000000000000000031661457770046000263040ustar00rootroot00000000000000package main import ( "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) // Grid demonstrates the grid layout. func Grid(nextSlide func()) (title string, content tview.Primitive) { modalShown := false pages := tview.NewPages() newPrimitive := func(text string) tview.Primitive { return tview.NewFrame(nil). SetBorders(0, 0, 0, 0, 0, 0). AddText(text, true, tview.AlignCenter, tcell.ColorWhite) } menu := newPrimitive("Menu") main := newPrimitive("Main content") sideBar := newPrimitive("Side Bar") grid := tview.NewGrid(). SetRows(3, 0, 3). SetColumns(0, -4, 0). SetBorders(true). AddItem(newPrimitive("Header"), 0, 0, 1, 3, 0, 0, true). AddItem(newPrimitive("Footer"), 2, 0, 1, 3, 0, 0, false) grid.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { if modalShown { nextSlide() modalShown = false } else { pages.ShowPage("modal") modalShown = true } return event }) // Layout for screens narrower than 100 cells (menu and side bar are hidden). grid.AddItem(menu, 0, 0, 0, 0, 0, 0, false). AddItem(main, 1, 0, 1, 3, 0, 0, false). AddItem(sideBar, 0, 0, 0, 0, 0, 0, false) // Layout for screens wider than 100 cells. grid.AddItem(menu, 1, 0, 1, 1, 0, 100, false). AddItem(main, 1, 1, 1, 1, 0, 100, false). AddItem(sideBar, 1, 2, 1, 1, 0, 100, false) modal := tview.NewModal(). SetText("Resize the window to see how the grid layout adapts"). AddButtons([]string{"Ok"}).SetDoneFunc(func(buttonIndex int, buttonLabel string) { pages.HidePage("modal") }) pages.AddPage("grid", grid, true, true). AddPage("modal", modal, false, false) return "Grid", pages } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/presentation/helloworld.go000066400000000000000000000016011457770046000275220ustar00rootroot00000000000000package main import ( "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) const helloWorld = `[green]package[white] main [green]import[white] ( [red]"github.com/darkhz/tview"[white] ) [green]func[white] [yellow]main[white]() { box := tview.[yellow]NewBox[white](). [yellow]SetBorder[white](true). [yellow]SetTitle[white]([red]"Hello, world!"[white]) tview.[yellow]NewApplication[white](). [yellow]SetRoot[white](box, true). [yellow]Run[white]() }` // HelloWorld shows a simple "Hello world" example. func HelloWorld(nextSlide func()) (title string, content tview.Primitive) { // We use a text view because we want to capture keyboard input. textView := tview.NewTextView().SetDoneFunc(func(key tcell.Key) { nextSlide() }) textView.SetBorder(true).SetTitle("Hello, world!") return "Hello, world", Code(textView, 30, 10, helloWorld) } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/presentation/inputfield.go000066400000000000000000000022571457770046000275220ustar00rootroot00000000000000package main import ( "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) const inputField = `[green]package[white] main [green]import[white] ( [red]"strconv"[white] [red]"github.com/gdamore/tcell/v2"[white] [red]"github.com/darkhz/tview"[white] ) [green]func[white] [yellow]main[white]() { input := tview.[yellow]NewInputField[white](). [yellow]SetLabel[white]([red]"Enter a number: "[white]). [yellow]SetAcceptanceFunc[white]( tview.InputFieldInteger, ).[yellow]SetDoneFunc[white]([yellow]func[white](key tcell.Key) { text := input.[yellow]GetText[white]() n, _ := strconv.[yellow]Atoi[white](text) [blue]// We have a number.[white] }) tview.[yellow]NewApplication[white](). [yellow]SetRoot[white](input, true). [yellow]Run[white]() }` // InputField demonstrates the InputField. func InputField(nextSlide func()) (title string, content tview.Primitive) { input := tview.NewInputField(). SetLabel("Enter a number: "). SetAcceptanceFunc(tview.InputFieldInteger).SetDoneFunc(func(key tcell.Key) { nextSlide() }) return "Input", Code(input, 30, 1, inputField) } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/presentation/introduction.go000066400000000000000000000015141457770046000300730ustar00rootroot00000000000000package main import "github.com/darkhz/tview" // Introduction returns a tview.List with the highlights of the tview package. func Introduction(nextSlide func()) (title string, content tview.Primitive) { list := tview.NewList(). AddItem("A Go package for terminal based UIs", "with a special focus on rich interactive widgets", '1', nextSlide). AddItem("Based on github.com/gdamore/tcell", "Like termbox but better (see tcell docs)", '2', nextSlide). AddItem("Designed to be simple", `"Hello world" is 5 lines of code`, '3', nextSlide). AddItem("Good for data entry", `For charts, use "termui" - for low-level views, use "gocui" - ...`, '4', nextSlide). AddItem("Extensive documentation", "Everything is documented, examples in GitHub wiki, demo code for each widget", '5', nextSlide) return "Introduction", Center(80, 10, list) } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/presentation/main.go000066400000000000000000000047031457770046000263010ustar00rootroot00000000000000/* A presentation of the tview package, implemented with tview. # Navigation The presentation will advance to the next slide when the primitive demonstrated in the current slide is left (usually by hitting Enter or Escape). Additionally, the following shortcuts can be used: - Ctrl-N: Jump to next slide - Ctrl-P: Jump to previous slide */ package main import ( "fmt" "strconv" "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) // Slide is a function which returns the slide's main primitive and its title. // It receives a "nextSlide" function which can be called to advance the // presentation to the next slide. type Slide func(nextSlide func()) (title string, content tview.Primitive) // The application. var app = tview.NewApplication() // Starting point for the presentation. func main() { // The presentation slides. slides := []Slide{ Cover, Introduction, HelloWorld, InputField, Form, TextView1, TextView2, Table, TreeView, Flex, Grid, Colors, End, } pages := tview.NewPages() // The bottom row has some info on where we are. info := tview.NewTextView(). SetDynamicColors(true). SetRegions(true). SetWrap(false). SetHighlightedFunc(func(added, removed, remaining []string) { pages.SwitchToPage(added[0]) }) // Create the pages for all slides. previousSlide := func() { slide, _ := strconv.Atoi(info.GetHighlights()[0]) slide = (slide - 1 + len(slides)) % len(slides) info.Highlight(strconv.Itoa(slide)). ScrollToHighlight() } nextSlide := func() { slide, _ := strconv.Atoi(info.GetHighlights()[0]) slide = (slide + 1) % len(slides) info.Highlight(strconv.Itoa(slide)). ScrollToHighlight() } for index, slide := range slides { title, primitive := slide(nextSlide) pages.AddPage(strconv.Itoa(index), primitive, true, index == 0) fmt.Fprintf(info, `%d ["%d"][darkcyan]%s[white][""] `, index+1, index, title) } info.Highlight("0") // Create the main layout. layout := tview.NewFlex(). SetDirection(tview.FlexRow). AddItem(pages, 0, 1, true). AddItem(info, 1, 1, false) // Shortcuts to navigate the slides. app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { if event.Key() == tcell.KeyCtrlN { nextSlide() return nil } else if event.Key() == tcell.KeyCtrlP { previousSlide() return nil } return event }) // Start the application. if err := app.SetRoot(layout, true).EnableMouse(true).EnablePaste(true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/presentation/table.go000066400000000000000000000314621457770046000264460ustar00rootroot00000000000000package main import ( "fmt" "strings" "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) const tableData = `OrderDate|Region|Rep|Item|Units|UnitCost|Total 1/6/2017|East|Jones|Pencil|95|1.99|189.05 1/23/2017|Central|Kivell|Binder|50|19.99|999.50 2/9/2017|Central|Jardine|Pencil|36|4.99|179.64 2/26/2017|Central|Gill|Pen|27|19.99|539.73 3/15/2017|West|Sorvino|Pencil|56|2.99|167.44 4/1/2017|East|Jones|Binder|60|4.99|299.40 4/18/2017|Central|Andrews|Pencil|75|1.99|149.25 5/5/2017|Central|Jardine|Pencil|90|4.99|449.10 5/22/2017|West|Thompson|Pencil|32|1.99|63.68 6/8/2017|East|Jones|Binder|60|8.99|539.40 6/25/2017|Central|Morgan|Pencil|90|4.99|449.10 7/12/2017|East|Howard|Binder|29|1.99|57.71 7/29/2017|East|Parent|Binder|81|19.99|1,619.19 8/15/2017|East|Jones|Pencil|35|4.99|174.65 9/1/2017|Central|Smith|Desk|2|125.00|250.00 9/18/2017|East|Jones|Pen Set|16|15.99|255.84 10/5/2017|Central|Morgan|Binder|28|8.99|251.72 10/22/2017|East|Jones|Pen|64|8.99|575.36 11/8/2017|East|Parent|Pen|15|19.99|299.85 11/25/2017|Central|Kivell|Pen Set|96|4.99|479.04 12/12/2017|Central|Smith|Pencil|67|1.29|86.43 12/29/2017|East|Parent|Pen Set|74|15.99|1,183.26 1/15/2018|Central|Gill|Binder|46|8.99|413.54 2/1/2018|Central|Smith|Binder|87|15.00|1,305.00 2/18/2018|East|Jones|Binder|4|4.99|19.96 3/7/2018|West|Sorvino|Binder|7|19.99|139.93 3/24/2018|Central|Jardine|Pen Set|50|4.99|249.50 4/10/2018|Central|Andrews|Pencil|66|1.99|131.34 4/27/2018|East|Howard|Pen|96|4.99|479.04 5/14/2018|Central|Gill|Pencil|53|1.29|68.37 5/31/2018|Central|Gill|Binder|80|8.99|719.20 6/17/2018|Central|Kivell|Desk|5|125.00|625.00 7/4/2018|East|Jones|Pen Set|62|4.99|309.38 7/21/2018|Central|Morgan|Pen Set|55|12.49|686.95 8/7/2018|Central|Kivell|Pen Set|42|23.95|1,005.90 8/24/2018|West|Sorvino|Desk|3|275.00|825.00 9/10/2018|Central|Gill|Pencil|7|1.29|9.03 9/27/2018|West|Sorvino|Pen|76|1.99|151.24 10/14/2018|West|Thompson|Binder|57|19.99|1,139.43 10/31/2018|Central|Andrews|Pencil|14|1.29|18.06 11/17/2018|Central|Jardine|Binder|11|4.99|54.89 12/4/2018|Central|Jardine|Binder|94|19.99|1,879.06 12/21/2018|Central|Andrews|Binder|28|4.99|139.72` const tableBasic = `[green]func[white] [yellow]main[white]() { table := tview.[yellow]NewTable[white](). [yellow]SetFixed[white]([red]1[white], [red]1[white]) [yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ { [yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ { color := tcell.ColorWhite [yellow]if[white] row == [red]0[white] { color = tcell.ColorYellow } [yellow]else[white] [yellow]if[white] column == [red]0[white] { color = tcell.ColorDarkCyan } align := tview.AlignLeft [yellow]if[white] row == [red]0[white] { align = tview.AlignCenter } [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] { align = tview.AlignRight } table.[yellow]SetCell[white](row, column, &tview.TableCell{ Text: [red]"..."[white], Color: color, Align: align, }) } } tview.[yellow]NewApplication[white](). [yellow]SetRoot[white](table, true). [yellow]Run[white]() }` const tableSeparator = `[green]func[white] [yellow]main[white]() { table := tview.[yellow]NewTable[white](). [yellow]SetFixed[white]([red]1[white], [red]1[white]). [yellow]SetSeparator[white](Borders.Vertical) [yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ { [yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ { color := tcell.ColorWhite [yellow]if[white] row == [red]0[white] { color = tcell.ColorYellow } [yellow]else[white] [yellow]if[white] column == [red]0[white] { color = tcell.ColorDarkCyan } align := tview.AlignLeft [yellow]if[white] row == [red]0[white] { align = tview.AlignCenter } [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] { align = tview.AlignRight } table.[yellow]SetCell[white](row, column, &tview.TableCell{ Text: [red]"..."[white], Color: color, Align: align, }) } } tview.[yellow]NewApplication[white](). [yellow]SetRoot[white](table, true). [yellow]Run[white]() }` const tableBorders = `[green]func[white] [yellow]main[white]() { table := tview.[yellow]NewTable[white](). [yellow]SetFixed[white]([red]1[white], [red]1[white]). [yellow]SetBorders[white](true) [yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ { [yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ { color := tcell.ColorWhite [yellow]if[white] row == [red]0[white] { color = tcell.ColorYellow } [yellow]else[white] [yellow]if[white] column == [red]0[white] { color = tcell.ColorDarkCyan } align := tview.AlignLeft [yellow]if[white] row == [red]0[white] { align = tview.AlignCenter } [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] { align = tview.AlignRight } table.[yellow]SetCell[white](row, column, &tview.TableCell{ Text: [red]"..."[white], Color: color, Align: align, }) } } tview.[yellow]NewApplication[white](). [yellow]SetRoot[white](table, true). [yellow]Run[white]() }` const tableSelectRow = `[green]func[white] [yellow]main[white]() { table := tview.[yellow]NewTable[white](). [yellow]SetFixed[white]([red]1[white], [red]1[white]). [yellow]SetSelectable[white](true, false) [yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ { [yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ { color := tcell.ColorWhite [yellow]if[white] row == [red]0[white] { color = tcell.ColorYellow } [yellow]else[white] [yellow]if[white] column == [red]0[white] { color = tcell.ColorDarkCyan } align := tview.AlignLeft [yellow]if[white] row == [red]0[white] { align = tview.AlignCenter } [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] { align = tview.AlignRight } table.[yellow]SetCell[white](row, column, &tview.TableCell{ Text: [red]"..."[white], Color: color, Align: align, NotSelectable: row == [red]0[white] || column == [red]0[white], }) } } tview.[yellow]NewApplication[white](). [yellow]SetRoot[white](table, true). [yellow]Run[white]() }` const tableSelectColumn = `[green]func[white] [yellow]main[white]() { table := tview.[yellow]NewTable[white](). [yellow]SetFixed[white]([red]1[white], [red]1[white]). [yellow]SetSelectable[white](false, true) [yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ { [yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ { color := tcell.ColorWhite [yellow]if[white] row == [red]0[white] { color = tcell.ColorYellow } [yellow]else[white] [yellow]if[white] column == [red]0[white] { color = tcell.ColorDarkCyan } align := tview.AlignLeft [yellow]if[white] row == [red]0[white] { align = tview.AlignCenter } [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] { align = tview.AlignRight } table.[yellow]SetCell[white](row, column, &tview.TableCell{ Text: [red]"..."[white], Color: color, Align: align, NotSelectable: row == [red]0[white] || column == [red]0[white], }) } } tview.[yellow]NewApplication[white](). [yellow]SetRoot[white](table, true). [yellow]Run[white]() }` const tableSelectCell = `[green]func[white] [yellow]main[white]() { table := tview.[yellow]NewTable[white](). [yellow]SetFixed[white]([red]1[white], [red]1[white]). [yellow]SetSelectable[white](true, true) [yellow]for[white] row := [red]0[white]; row < [red]40[white]; row++ { [yellow]for[white] column := [red]0[white]; column < [red]7[white]; column++ { color := tcell.ColorWhite [yellow]if[white] row == [red]0[white] { color = tcell.ColorYellow } [yellow]else[white] [yellow]if[white] column == [red]0[white] { color = tcell.ColorDarkCyan } align := tview.AlignLeft [yellow]if[white] row == [red]0[white] { align = tview.AlignCenter } [yellow]else[white] [yellow]if[white] column == [red]0[white] || column >= [red]4[white] { align = tview.AlignRight } table.[yellow]SetCell[white](row, column, &tview.TableCell{ Text: [red]"..."[white], Color: color, Align: align, NotSelectable: row == [red]0[white] || column == [red]0[white], }) } } tview.[yellow]NewApplication[white](). [yellow]SetRoot[white](table, true). [yellow]Run[white]() }` // Table demonstrates the Table. func Table(nextSlide func()) (title string, content tview.Primitive) { table := tview.NewTable(). SetFixed(1, 1) for row, line := range strings.Split(tableData, "\n") { for column, cell := range strings.Split(line, "|") { color := tcell.ColorWhite if row == 0 { color = tcell.ColorYellow } else if column == 0 { color = tcell.ColorDarkCyan } align := tview.AlignLeft if row == 0 { align = tview.AlignCenter } else if column == 0 || column >= 4 { align = tview.AlignRight } tableCell := tview.NewTableCell(cell). SetTextColor(color). SetAlign(align). SetSelectable(row != 0 && column != 0) if column >= 1 && column <= 3 { tableCell.SetExpansion(1) } table.SetCell(row, column, tableCell) } } table.SetBorder(true).SetTitle("Table") code := tview.NewTextView(). SetWrap(false). SetDynamicColors(true) code.SetBorderPadding(1, 1, 2, 0) list := tview.NewList() basic := func() { table.SetBorders(false). SetSelectable(false, false). SetSeparator(' ') code.Clear() fmt.Fprint(code, tableBasic) } separator := func() { table.SetBorders(false). SetSelectable(false, false). SetSeparator(tview.Borders.Vertical) code.Clear() fmt.Fprint(code, tableSeparator) } borders := func() { table.SetBorders(true). SetSelectable(false, false) code.Clear() fmt.Fprint(code, tableBorders) } selectRow := func() { table.SetBorders(false). SetSelectable(true, false). SetSeparator(' ') code.Clear() fmt.Fprint(code, tableSelectRow) } selectColumn := func() { table.SetBorders(false). SetSelectable(false, true). SetSeparator(' ') code.Clear() fmt.Fprint(code, tableSelectColumn) } selectCell := func() { table.SetBorders(false). SetSelectable(true, true). SetSeparator(' ') code.Clear() fmt.Fprint(code, tableSelectCell) } navigate := func() { app.SetFocus(table) table.SetDoneFunc(func(key tcell.Key) { app.SetFocus(list) }).SetSelectedFunc(func(row int, column int) { app.SetFocus(list) }) } list.ShowSecondaryText(false). AddItem("Basic table", "", 'b', basic). AddItem("Table with separator", "", 's', separator). AddItem("Table with borders", "", 'o', borders). AddItem("Selectable rows", "", 'r', selectRow). AddItem("Selectable columns", "", 'c', selectColumn). AddItem("Selectable cells", "", 'l', selectCell). AddItem("Navigate", "", 'n', navigate). AddItem("Next slide", "", 'x', nextSlide) list.SetBorderPadding(1, 1, 2, 2) basic() return "Table", tview.NewFlex(). AddItem(tview.NewFlex(). SetDirection(tview.FlexRow). AddItem(list, 10, 1, true). AddItem(table, 0, 1, false), 0, 1, true). AddItem(code, codeWidth, 1, false) } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/presentation/textview.go000066400000000000000000000116671457770046000272430ustar00rootroot00000000000000package main import ( "fmt" "strconv" "time" "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) const textView1 = `[green]func[white] [yellow]main[white]() { app := tview.[yellow]NewApplication[white]() textView := tview.[yellow]NewTextView[white](). [yellow]SetTextColor[white](tcell.ColorYellow). [yellow]SetScrollable[white](false). [yellow]SetChangedFunc[white]([yellow]func[white]() { app.[yellow]Draw[white]() }) [green]go[white] [yellow]func[white]() { [green]var[white] n [green]int [white] [yellow]for[white] { n++ fmt.[yellow]Fprintf[white](textView, [red]"%d "[white], n) time.[yellow]Sleep[white]([red]200[white] * time.Millisecond) } }() app.[yellow]SetRoot[white](textView, true). [yellow]Run[white]() }` // TextView1 demonstrates the basic text view. func TextView1(nextSlide func()) (title string, content tview.Primitive) { textView := tview.NewTextView(). SetTextColor(tcell.ColorYellow). SetScrollable(false). SetDoneFunc(func(key tcell.Key) { nextSlide() }) textView.SetChangedFunc(func() { if textView.HasFocus() { app.Draw() } }) go func() { var n int for { if textView.HasFocus() { n++ if n > 512 { n = 1 textView.SetText("") } fmt.Fprintf(textView, "%d ", n) time.Sleep(200 * time.Millisecond) } else { time.Sleep(time.Second) } } }() textView.SetBorder(true).SetTitle("TextView implements io.Writer") return "Text 1", Code(textView, 36, 13, textView1) } const textView2 = `[green]package[white] main [green]import[white] ( [red]"strconv"[white] [red]"github.com/gdamore/tcell/v2"[white] [red]"github.com/darkhz/tview"[white] ) [green]func[white] [yellow]main[white]() { ["0"]textView[""] := tview.[yellow]NewTextView[white]() ["1"]textView[""].[yellow]SetDynamicColors[white](true). [yellow]SetWrap[white](false). [yellow]SetRegions[white](true). [yellow]SetDoneFunc[white]([yellow]func[white](key tcell.Key) { highlights := ["2"]textView[""].[yellow]GetHighlights[white]() hasHighlights := [yellow]len[white](highlights) > [red]0 [yellow]switch[white] key { [yellow]case[white] tcell.KeyEnter: [yellow]if[white] hasHighlights { ["3"]textView[""].[yellow]Highlight[white]() } [yellow]else[white] { ["4"]textView[""].[yellow]Highlight[white]([red]"0"[white]). [yellow]ScrollToHighlight[white]() } [yellow]case[white] tcell.KeyTab: [yellow]if[white] hasHighlights { current, _ := strconv.[yellow]Atoi[white](highlights[[red]0[white]]) next := (current + [red]1[white]) % [red]9 ["5"]textView[""].[yellow]Highlight[white](strconv.[yellow]Itoa[white](next)). [yellow]ScrollToHighlight[white]() } [yellow]case[white] tcell.KeyBacktab: [yellow]if[white] hasHighlights { current, _ := strconv.[yellow]Atoi[white](highlights[[red]0[white]]) next := (current - [red]1[white] + [red]9[white]) % [red]9 ["6"]textView[""].[yellow]Highlight[white](strconv.[yellow]Itoa[white](next)). [yellow]ScrollToHighlight[white]() } } }) fmt.[yellow]Fprint[white](["7"]textView[""], content) tview.[yellow]NewApplication[white](). [yellow]SetRoot[white](["8"]textView[""], true). [yellow]Run[white]() }` // TextView2 demonstrates the extended text view. func TextView2(nextSlide func()) (title string, content tview.Primitive) { codeView := tview.NewTextView(). SetWrap(false) fmt.Fprint(codeView, textView2) codeView.SetBorder(true).SetTitle("Raw text") textView := tview.NewTextView() textView.SetDynamicColors(true). SetWrap(false). SetRegions(true). SetDoneFunc(func(key tcell.Key) { if key == tcell.KeyEscape { nextSlide() return } highlights := textView.GetHighlights() hasHighlights := len(highlights) > 0 switch key { case tcell.KeyEnter: if hasHighlights { textView.Highlight() } else { textView.Highlight("0"). ScrollToHighlight() } case tcell.KeyTab: if hasHighlights { current, _ := strconv.Atoi(highlights[0]) next := (current + 1) % 9 textView.Highlight(strconv.Itoa(next)). ScrollToHighlight() } case tcell.KeyBacktab: if hasHighlights { current, _ := strconv.Atoi(highlights[0]) next := (current - 1 + 9) % 9 textView.Highlight(strconv.Itoa(next)). ScrollToHighlight() } } }) fmt.Fprint(textView, textView2) textView.SetBorder(true).SetTitle("TextView output") return "Text 2", tview.NewFlex(). AddItem(textView, 0, 1, true). AddItem(codeView, 0, 1, false) } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/presentation/treeview.go000066400000000000000000000116351457770046000272110ustar00rootroot00000000000000package main import ( "strings" "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) const treeAllCode = `[green]package[white] main [green]import[white] [red]"github.com/darkhz/tview"[white] [green]func[white] [yellow]main[white]() { $$$ root := tview.[yellow]NewTreeNode[white]([red]"Root"[white]). [yellow]AddChild[white](tview.[yellow]NewTreeNode[white]([red]"First child"[white]). [yellow]AddChild[white](tview.[yellow]NewTreeNode[white]([red]"Grandchild A"[white])). [yellow]AddChild[white](tview.[yellow]NewTreeNode[white]([red]"Grandchild B"[white]))). [yellow]AddChild[white](tview.[yellow]NewTreeNode[white]([red]"Second child"[white]). [yellow]AddChild[white](tview.[yellow]NewTreeNode[white]([red]"Grandchild C"[white])). [yellow]AddChild[white](tview.[yellow]NewTreeNode[white]([red]"Grandchild D"[white]))). [yellow]AddChild[white](tview.[yellow]NewTreeNode[white]([red]"Third child"[white])) tree.[yellow]SetRoot[white](root). [yellow]SetCurrentNode[white](root) tview.[yellow]NewApplication[white](). [yellow]SetRoot[white](tree, true). [yellow]Run[white]() }` const treeBasicCode = `tree := tview.[yellow]NewTreeView[white]()` const treeTopLevelCode = `tree := tview.[yellow]NewTreeView[white](). [yellow]SetTopLevel[white]([red]1[white])` const treeAlignCode = `tree := tview.[yellow]NewTreeView[white](). [yellow]SetAlign[white](true)` const treePrefixCode = `tree := tview.[yellow]NewTreeView[white](). [yellow]SetGraphics[white](false). [yellow]SetTopLevel[white]([red]1[white]). [yellow]SetPrefixes[white]([][green]string[white]{ [red]"[red[]* "[white], [red]"[darkcyan[]- "[white], [red]"[darkmagenta[]- "[white], })` type node struct { text string expand bool selected func() children []*node } var ( tree = tview.NewTreeView() treeNextSlide func() treeCode = tview.NewTextView().SetWrap(false).SetDynamicColors(true) ) var rootNode = &node{ text: "Root", children: []*node{ {text: "Expand all", selected: func() { tree.GetRoot().ExpandAll() }}, {text: "Collapse all", selected: func() { for _, child := range tree.GetRoot().GetChildren() { child.CollapseAll() } }}, {text: "Hide root node", expand: true, children: []*node{ {text: "Tree list starts one level down"}, {text: "Works better for lists where no top node is needed"}, {text: "Switch to this layout", selected: func() { tree.SetAlign(false).SetTopLevel(1).SetGraphics(true).SetPrefixes(nil) treeCode.SetText(strings.Replace(treeAllCode, "$$$", treeTopLevelCode, -1)) }}, }}, {text: "Align node text", expand: true, children: []*node{ {text: "For trees that are similar to lists"}, {text: "Hierarchy shown only in line drawings"}, {text: "Switch to this layout", selected: func() { tree.SetAlign(true).SetTopLevel(0).SetGraphics(true).SetPrefixes(nil) treeCode.SetText(strings.Replace(treeAllCode, "$$$", treeAlignCode, -1)) }}, }}, {text: "Prefixes", expand: true, children: []*node{ {text: "Best for hierarchical bullet point lists"}, {text: "You can define your own prefixes per level"}, {text: "Switch to this layout", selected: func() { tree.SetAlign(false).SetTopLevel(1).SetGraphics(false).SetPrefixes([]string{"[red]* ", "[darkcyan]- ", "[darkmagenta]- "}) treeCode.SetText(strings.Replace(treeAllCode, "$$$", treePrefixCode, -1)) }}, }}, {text: "Basic tree with graphics", expand: true, children: []*node{ {text: "Lines illustrate hierarchy"}, {text: "Basic indentation"}, {text: "Switch to this layout", selected: func() { tree.SetAlign(false).SetTopLevel(0).SetGraphics(true).SetPrefixes(nil) treeCode.SetText(strings.Replace(treeAllCode, "$$$", treeBasicCode, -1)) }}, }}, {text: "Next slide", selected: func() { treeNextSlide() }}, }} // TreeView demonstrates the tree view. func TreeView(nextSlide func()) (title string, content tview.Primitive) { treeNextSlide = nextSlide tree.SetBorder(true). SetTitle("TreeView") // Add nodes. var add func(target *node) *tview.TreeNode add = func(target *node) *tview.TreeNode { node := tview.NewTreeNode(target.text). SetSelectable(target.expand || target.selected != nil). SetExpanded(target == rootNode). SetReference(target) if target.expand { node.SetColor(tcell.ColorGreen) } else if target.selected != nil { node.SetColor(tcell.ColorRed) } for _, child := range target.children { node.AddChild(add(child)) } return node } root := add(rootNode) tree.SetRoot(root). SetCurrentNode(root). SetSelectedFunc(func(n *tview.TreeNode) { original := n.GetReference().(*node) if original.expand { n.SetExpanded(!n.IsExpanded()) } else if original.selected != nil { original.selected() } }) treeCode.SetText(strings.Replace(treeAllCode, "$$$", treeBasicCode, -1)). SetBorderPadding(1, 1, 2, 0) return "Tree", tview.NewFlex(). AddItem(tree, 0, 1, true). AddItem(treeCode, codeWidth, 1, false) } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/primitive/000077500000000000000000000000001457770046000243175ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/primitive/README.md000066400000000000000000000000361457770046000255750ustar00rootroot00000000000000![Screenshot](screenshot.png) golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/primitive/boxwithcenterline.png000066400000000000000000000261721457770046000305720ustar00rootroot00000000000000PNG  IHDR?#iCCPICC ProfileXyTKnX%眓 s%Q"AEPTPAP$""   *(y}|[S]UWul`5!ё܎Nܸ)`eii ?g[Fd`O(7f ӏ÷"#`[o3oag[ZHH?[c;D#6; QMA?DgOHH^@mH~/ۍL7 *<9g ^ GZoۥ0-L@p{i཭_/xE s@o deH}}y@. ޵ 67ݵcҳo`$P;|'zgᆨX?}F# 3T rwhKnh0:@pa  ,, v~Jpؾm@" ]7Jwwnv !hV:Zm5CVӏϨX=. a 3A>w[\B=f 3ݶ]-0f`翽C "h5?͈fh9-<"7ØʉD]#WVt5G俚p|}p;p+3v&z[b'eYMk}⣷NXxBd4pzIᖑV`ko:Yod>3E|Y j`G& ^{#ڎ*X'ˆ?2@MN qpA*8(Yp\Wu=<`F=`A(!: 1HR!=  bP: @ ݄A}f/"Q(A$J 2A٢PDTuՌzFMQ0)`F`v}H Õp܆</h,͍GrmBGO/]gI"7Îè`0?L&S4aubBXEd]:aI#rl=;.p8N g#q]S{O2 2.22}2gP4bZ;dO>S [{'_ o#B| O«mT)|?FAAKLaE@Bqbb@K%\ 1cjB%%% &3e41?tD ћL,%6?SS PiQQ%RSݠzB@MN-HCM>H]J}zzFƂ&M-M -VV֛6<}i:N΋.]7{z,} }.UEZ9{xR 0 c0cu_LLZL>LLuLO~01k20033bfc bgiayÊfebc=ͺFϦŖv;]ݚ=<{?2'G8G }NFNM@B;\t\\\\wOqwq/T )u-sJ\@I_@A!AÂ-3BBFBBƄ)5#+`EDDEEQOPb bbbC{0{3*N,>)(a*&"Y_Y2_G򷔼TҴim_eDedJeR&˶.ɉȝ{!O'o&XS~CAQ!RNaV_CLqT^RR2FY[9Y]yUEA%ZUq ZՙB{}^;ƫFRPPVP?>AҨԘ֬%uE볶vv:niq}^}?IC|Q##/EcE]&&Smf(3cfc-K![VX+KR{llmjmVlml_ uSٻpu(ppt<ȉ)l\RU5udо}}nnnݩI7<0$ R%iȳsK׼wOG_5?5~ :  v! J6.>QiYEjG^sccLƪǖOߟ 1Q?b:+s?TzLKH~br)8M* {Cz[GFJ!C3UBgd dfdy+[~ãGO<{l O!q# h  Oh..)^^W,W|$dɉSZKK?=\]Z_^]ܻ3ug9u.܋ J?\sQbMkUnFuh%K]555yQc.^q2xUjkx]E=c}nhiqmJ7˚rV֡7;TۚnIܪni/p;NƝͻw;;ݛt|}.nhUmSPa#GM7 ( 4?Q|:<6wS>{a/_̼ ~*1X7oEO(Lܞԝ쟲z=5=.?r}i՟s{?>Sgύ_4/:._\z˷r;-WBV~dyiUiïkqS"mM~mln"Iۯ0r|}Z t;n{H+1x,N̉<$[4ʘsqy.M<`P(؃=%AjoSddyd?ݔ?`Ȯ^N9^EKlo- ou4$i3/֙WX[N[clXlYau5'LBt܇޷6>AYUg (B ~ y!XtrLflS<:'c?8 xP%(%5&XzQF!Cәy-)r@.Qcy O8[4?eRbpZTL\YsR&'.U],}EnYC5765jjͽVtvF:v1wv?Ic'^>x.93b4B+3c/?6}on|{gf&fs&/-$~2LK_ݾY|7[\yWˆna4~>4^|״coLߞ5tj|z ١yOP}aio7W,'}5a]wcv7<vC`p%,nl|O":SR_ݤ`c d:|- xnm_<xMx;V  DE E?e-%$%JAneLefd8Z)r) o-3**UTY-I^!1ũժmR_gSRR\~C99JcWf"3s*>tKUVA6B6l+ٳ?ws4ttjrvwyZ|ߊ[{+R' d1US7 5BCB/ˇG܏̉f~s6;N0C$gos+~ԚC.zE0YϳKrss׎L}|f޹] TNX-)^|S%o>({Q>wfewy êVg_:RRKxxOu kenX6&556lUVr;}wt^)}ǠS#/cSsWV*p"P3 3%%% P~L}~@ ( `\@H2D!e8LHIC;CW^ FPHuM7}=dabU%5zHHVMFgS)X ՔrD5b-jC4ѴԴWtm,23d*aVcg9N):w$<:o_1^A ,OQ-1==k%IK5I'Hˌf}oU(PLPV6UReKTP/:ݧELŐ݈X4yW+>kc=h]L~FW}n<$O{19?*{C C?GF#b^Ƿ&'U>X˜H=|80k>'Hȱ|kNf,,?zreYU+j^>~Uaƙ֏mKwwx$XP賟WcgMyO?W+G>\~zߞRVqh @C` <@H٠Ԁx! ImG?* %rF\;|^@+3L*f })qdzdx 9K4e`3bg|J>QǛW=,!*$rs"7Xx~h)/iM̀lPy~q`S³aQ||,ςY5ZY?nрP#,ʯ# B>( *nC(r$$Tjf}hvt zyƩ!S( 02(MIM]BCDgDo`h̤,"Ζiemckgo-.%tTVWtviVYoz5EK*{15׵Mtґ10Z311m6b%alc7wjFAO?7CupYșXθIʓR~Udgr^̾{oA>KBߢ%4+*.(]a\g y]15ͩ{Nq]{8? 9->)7z9oMRMM{7Ac̹޹'R_tH_Y~|t}?V:l^e\\m^]+Wqf:ٺz {>ߛқ>6++`77 +`#ssrss 319 490 1 ;IDATxY'6.%ᦫ? Xm#b(sZge"pq"E6]Q XPYR@ҎFK[0IVֲFC<ܦy=&|e}={g'7 @ @ @6]`r{.--mz @`#GN8]\\<|pL=V֕_6LwNr^}/,,w}ǎ[}= )_3gҫH 0bMB @ ,b&@{5 I,C!$$"f !X;  0bMB @ ,b&@{5 I,C!$$"f !X;  0bMB @ ,b&@{5 I,C!$$"f !X;  0bMB @ ,b&@{5 I,C!$$"f !X;  0bMB @ ,b&@{5 I,C!$$"f !X;  0bMB @ ,b&@{5 I,C!$$"f !X;  0bMB @ ,b&@{5 I,C!$$"f !X;  0bMB @ ,b&@{5 I,C!$$"f !X;  0bMB @ ,b&@{5 I,C!$$"f !X;  0bMB @ ,b&@{5 I,C!$$"f !X;  0bMB @ ,b&@{5 I,C!$$"f !X;  0bMB @ ,b&@{5 I,C!$$"f !X;  0bMB @ ,b&@{5 I,C!$$"f !X;  0bMB @ ,b&@{5 I,C!$$"f !X;  0bMB @ ,b&@{5 I,C!$$"f !X;  0bMB @ ,b&@{5 I,C!$$"f !X;  0bMB @ ,b&@{5 I,C!$$"f !X;  0bMB @ ,b&@{5 I,C!$$"f !X; V6.&ސ9$y*Z<wo~,_ S<|Cba&{/Cn|{ {~B޶-zƉ7M`&⿡_WwǩOğ%sy9ǖ߿Ĺ~k,/sOC~λ:udzWpk#ҧqwnۦ}8z0ܚ|وU':=G]}2tD|?=>?`<6ť8sqt/}k\g;K.%'u8O=zNgw]wĎW⯏_>4j[.L<8uu,~av?>jO><__~>:oۯv|%]K[xxz土g/(}3l:ξI۷O~ŜO'b8ζ_={bē/O//o,|>>sO__lY[s lF/Us?=8{=Oo_KqG'5n4szY,O®L +f?x>0WǏmˮ[񿉓k=}Kgxy<%bܷ{?cqߎ'nNϾELj/6v/1T=7{ٹ97wo.>:WG fw]n8:k真u}'p,_oqqq˖-gΜc.ܛX`淮_~5_j{/?q_/O^uy[\awߛ7x^O>XuY}KxO= height { break } radioButton := "\u25ef" // Unchecked. if index == r.currentOption { radioButton = "\u25c9" // Checked. } line := fmt.Sprintf(`%s[white] %s`, radioButton, option) tview.Print(screen, line, x, y+index, width, tview.AlignLeft, tcell.ColorYellow) } } // InputHandler returns the handler for this primitive. func (r *RadioButtons) InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) { return r.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p tview.Primitive)) { switch event.Key() { case tcell.KeyUp: r.currentOption-- if r.currentOption < 0 { r.currentOption = 0 } case tcell.KeyDown: r.currentOption++ if r.currentOption >= len(r.options) { r.currentOption = len(r.options) - 1 } } }) } // MouseHandler returns the mouse handler for this primitive. func (r *RadioButtons) MouseHandler() func(action tview.MouseAction, event *tcell.EventMouse, setFocus func(p tview.Primitive)) (consumed bool, capture tview.Primitive) { return r.WrapMouseHandler(func(action tview.MouseAction, event *tcell.EventMouse, setFocus func(p tview.Primitive)) (consumed bool, capture tview.Primitive) { x, y := event.Position() _, rectY, _, _ := r.GetInnerRect() if !r.InRect(x, y) { return false, nil } if action == tview.MouseLeftClick { setFocus(r) index := y - rectY if index >= 0 && index < len(r.options) { r.currentOption = index consumed = true } } return }) } func main() { radioButtons := NewRadioButtons([]string{"Lions", "Elephants", "Giraffes"}) radioButtons.SetBorder(true). SetTitle("Radio Button Demo"). SetRect(0, 0, 30, 5) if err := tview.NewApplication().SetRoot(radioButtons, false).EnableMouse(true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/primitive/screenshot.png000066400000000000000000000360751457770046000272150ustar00rootroot00000000000000PNG  IHDRZwv}#iCCPICC ProfileXyTKnX%眓 s%Q"AEPTPAP$""   *(y}|[S]UWul`5!ё܎Nܸ)`eii ?g[Fd`O(7f ӏ÷"#`[o3oag[ZHH?[c;D#6; QMA?DgOHH^@mH~/ۍL7 *<9g ^ GZoۥ0-L@p{i཭_/xE s@o deH}}y@. ޵ 67ݵcҳo`$P;|'zgᆨX?}F# 3T rwhKnh0:@pa  ,, v~Jpؾm@" ]7Jwwnv !hV:Zm5CVӏϨX=. a 3A>w[\B=f 3ݶ]-0f`翽C "h5?͈fh9-<"7ØʉD]#WVt5G俚p|}p;p+3v&z[b'eYMk}⣷NXxBd4pzIᖑV`ko:Yod>3E|Y j`G& ^{#ڎ*X'ˆ?2@MN qpA*8(Yp\Wu=<`F=`A(!: 1HR!=  bP: @ ݄A}f/"Q(A$J 2A٢PDTuՌzFMQ0)`F`v}H Õp܆</h,͍GrmBGO/]gI"7Îè`0?L&S4aubBXEd]:aI#rl=;.p8N g#q]S{O2 2.22}2gP4bZ;dO>S [{'_ o#B| O«mT)|?FAAKLaE@Bqbb@K%\ 1cjB%%% &3e41?tD ћL,%6?SS PiQQ%RSݠzB@MN-HCM>H]J}zzFƂ&M-M -VV֛6<}i:N΋.]7{z,} }.UEZ9{xR 0 c0cu_LLZL>LLuLO~01k20033bfc bgiayÊfebc=ͺFϦŖv;]ݚ=<{?2'G8G }NFNM@B;\t\\\\wOqwq/T )u-sJ\@I_@A!AÂ-3BBFBBƄ)5#+`EDDEEQOPb bbbC{0{3*N,>)(a*&"Y_Y2_G򷔼TҴim_eDedJeR&˶.ɉȝ{!O'o&XS~CAQ!RNaV_CLqT^RR2FY[9Y]yUEA%ZUq ZՙB{}^;ƫFRPPVP?>AҨԘ֬%uE볶vv:niq}^}?IC|Q##/EcE]&&Smf(3cfc-K![VX+KR{llmjmVlml_ uSٻpu(ppt<ȉ)l\RU5udо}}nnnݩI7<0$ R%iȳsK׼wOG_5?5~ :  v! J6.>QiYEjG^sccLƪǖOߟ 1Q?b:+s?TzLKH~br)8M* {Cz[GFJ!C3UBgd dfdy+[~ãGO<{l O!q# h  Oh..)^^W,W|$dɉSZKK?=\]Z_^]ܻ3ug9u.܋ J?\sQbMkUnFuh%K]555yQc.^q2xUjkx]E=c}nhiqmJ7˚rV֡7;TۚnIܪni/p;NƝͻw;;ݛt|}.nhUmSPa#GM7 ( 4?Q|:<6wS>{a/_̼ ~*1X7oEO(Lܞԝ쟲z=5=.?r}i՟s{?>Sgύ_4/:._\z˷r;-WBV~dyiUiïkqS"mM~mln"Iۯ0r|}Z t;n{H+1x,N̉<$[4ʘsqy.M<`P(؃=%AjoSddyd?ݔ?`Ȯ^N9^EKlo- ou4$i3/֙WX[N[clXlYau5'LBt܇޷6>AYUg (B ~ y!XtrLflS<:'c?8 xP%(%5&XzQF!Cәy-)r@.Qcy O8[4?eRbpZTL\YsR&'.U],}EnYC5765jjͽVtvF:v1wv?Ic'^>x.93b4B+3c/?6}on|{gf&fs&/-$~2LK_ݾY|7[\yWˆna4~>4^|״coLߞ5tj|z ١yOP}aio7W,'}5a]wcv7<vC`p%,nl|O":SR_ݤ`c d:|- xnm_<xMx;V  DE E?e-%$%JAneLefd8Z)r) o-3**UTY-I^!1ũժmR_gSRR\~C99JcWf"3s*>tKUVA6B6l+ٳ?ws4ttjrvwyZ|ߊ[{+R' d1US7 5BCB/ˇG܏̉f~s6;N0C$gos+~ԚC.zE0YϳKrss׎L}|f޹] TNX-)^|S%o>({Q>wfewy êVg_:RRKxxOu kenX6&556lUVr;}wt^)}ǠS#/cSsWV*p"P3 3%%% P~L}~@ ( `\@H2D!e8LHIC;CW^ FPHuM7}=dabU%5zHHVMFgS)X ՔrD5b-jC4ѴԴWtm,23d*aVcg9N):w$<:o_1^A ,OQ-1==k%IK5I'Hˌf}oU(PLPV6UReKTP/:ݧELŐ݈X4yW+>kc=h]L~FW}n<$O{19?*{C C?GF#b^Ƿ&'U>X˜H=|80k>'Hȱ|kNf,,?zreYU+j^>~Uaƙ֏mKwwx$XP賟WcgMyO?W+G>\~zߞRVqh @C` <@H٠Ԁx! ImG?* %rF\;|^@+3L*f })qdzdx 9K4e`3bg|J>QǛW=,!*$rs"7Xx~h)/iM̀lPy~q`S³aQ||,ςY5ZY?nрP#,ʯ# B>( *nC(r$$Tjf}hvt zyƩ!S( 02(MIM]BCDgDo`h̤,"Ζiemckgo-.%tTVWtviVYoz5EK*{15׵Mtґ10Z311m6b%alc7wjFAO?7CupYșXθIʓR~Udgr^̾{oA>KBߢ%4+*.(]a\g y]15ͩ{Nq]{8? 9->)7z9oMRMM{7Ac̹޹'R_tH_Y~|t}?V:l^e\\m^]+Wqf:ٺz {>ߛқ>6++`77 +`#ssrss 119 346 1 /!IDATx] X׽oAƦkJlMDEGmuZGvr^,I/RkUZ1de95nubÕnzVjy$SR3E`x| {s{9|^t" " "x@! Wl{=gɌ#pEg|5n01@oUUF<dzw|"}x}|vBi9?Riֹcza)*_KW,2 -іZSRax`t JG[59P͜!=?i"q'^]1> 2qR?Q"arYE;3f l2 xJ4Lai?xEEe:Lb6Ss}޻ ?$/MC+q4bi>]7zlǮA<~H@<)^(Nz.OUZL!zH缵/CV{òmua|9$ AXqҸ6-1!U窩ٱ.-ڦK<1N됔=P4t_m5m׍l0j$Uj0Q-juYpR=Mk0:vJZ0QVMvhrW:(5_3l[LDFPZ- L9;&tGF;u~cht0 'ŻglΚ/sM}kRW-<,/kd٥|>#2g% {ַ5ᙽCQAXi nm=gl̑i?N)b|r*X[`5[{pkwwskVL\"EDr-SW>6ƞO/$(e/<$2^i4-TP1/lt~8]&1gXWOZGWG6Nq`OO MΈK=b`tĵ'OQUfϧHv4՛n(Y$ h3MU$k79Ib= >͟%M]"]?Z3F6;L`{%5I"w]”oO2'c&C~1}SGudN#j(y= vP͉oZد;dʩ-fNv W ƹCn}>'8`2EUZ (Nr8IǠKU8Ɩr#w1Xgƾv;xI*%4:3a_i}ypZR[N`“X;{t ~; SzawR 1u*,M[4sw8mFWi h+CUo#ҶHضq1H}-+"orTuY5\{^AWγ9D 濘搶MKv vL{r^Q#U`p33gvӁ.2VIemd w:VɊr÷-btL2ͯכ͗ d)hJhw8~L,e΁جhZEjq#Ź] SYkZ;x 3#;ׅX$Ls.xxd1u?2L:J։xG%da S>:/ հFh `8=v+Hq@wDbctɚN/`z@Þ5Iɏj[[.b&$e:'0T̿ޒSHi}o IP"[`Z: L\z )'$6[T[[P&ShU0|ςN|ˇfdr̸>r\IESgE*ʹب(K޽سPZ$o87z)kڀ"*cd!â}$P5^lOG]QtCHurB :#ˮU#Wo@3Xv1CD @snOABFAaBD @snOABFAaBD mH)A}@ֻVhz>7PD@``K9qf WYxGP I!5bұwd0oD`,!9x" r(AE㟠dZg^? ~o -VIkJX+G{+!*(΁6X>Ö_"fx*CN8]&}e !1&A+ VP8ِz~6%9Z Ca _gLuB1lnx-`xh&ZiXK҈4DR@꜅3EX\wG>"*a]E s>Z9x:`S ~ؕ*y@t9EgIu_gd9$w1C;CTls@} 'y2!5onn燝|<RsBj~T=̐83\tJCʬ2cO9bIRֻTC xs[`d?>(?#d4%5OF$+6)/:7 MtJk9^{`[FaAk |ݰgF&.P"mt-k/;C|4%i4e75GA8~;F3&e8"m20.4*-C ƪ͹T`+ CN;6P22oIi45IX']Q UFv8 HV8R]< ,ݑ7OssSb0M-ꌜqWMA>Bͼ廉*nJujf\7}n,~/w;vJOA0QVMvԪH)6Wܒ/ *GJflΚ/#YI]Y7yV~1سnHu M.('eBGK;&;#Lzڢ۴㗻]w%a8MzFo[@\~ R8EѱrΘ@*]e6c :?l5 6qDfnGlS+WXFlünr\i [@>fYk\ۍNͭ,CWG֦] " "-A$jB8!y}%O l@bIk6 }ёCIbIVUET 6rf"2of TqBu./L,~)۠ns"y"Y"LTA۷,H;z)noCUV&QnڕY4p%w J#6ͱ ;g&Q+ x>n=m`a`)rՈm"`R"O4ABc*gmпSlFMRf̆]l'.4^!tnoJRibEp lVYRnwLO!"҃䒻p/' ]u#!È@|7ϨDJHi=-S2.T%adJt.Lh7^Smȝ;YwA4w@J>H f {m'~WuЌ&74]fQ7zx]r76\'">AaQ&YH{GkKKo/L?kP}s-Ug^_EXd4T %wGs K Wz~ٯz_+YS `RevpL'/SG\_MR쬮Ff8N0?wWhǮƀ(ʖd "":2{A8B [Ӱ~jC0Ul.-} o?G|Zff/s c^ƊC?!Xmoz@Þ5I|ɬj[[.b&$ݟS3;A M&`!ˑ~iF>0!IZ(T٠}lWBsħ|ti_' Bc #0Ja˿yfr&< OJ`_]ZS5f-H?YZ0DBv!vjl=?ΕӇ먢xU]Vz.IJiLVxv;8A;@.xRJ .]C#?XfܪL'#Hۙ D%Ӭ|6%'EWʣ"byc+mq뿊Ͻ@ _4ygt  VvWͿ[;<4B elAOsC x#+?ɉ BƜIdįɦ=V+~݉E*KE&( 5$qV;`H2^E V*h׫kN㈜W/!?Ƣ|5[&9VHDG-6wX"Җd;%#_lYn~4*ֺU@E''7 _`\`4qKe%w'S7a"adBtA]AOc\;F~߃+'H+7BYO s;(ʎ8A;AμY#%- u|T9Y/p8i9)B$wGPat#@N2?NKOFjX{wC7-Bà. OQY\U@njt?|胲v'wGt'Vx; qbuo~q'hFH)tʜ;Yy :!VY||8qo@Ӛܰ~~Oݑ7xswydI+2˚:I-w6m)pNO( 7]y"hni7{?-:7Yyn Y;s!D(@`˕*YDOxp6ZtUBLN$:\ gf'πNAbݠ ~+H;<\D 4je_&cXx ! t"~9g!!" D0"~9g!!" D0"~9g!!" D0"~9g!!" D0"~9g!!" D0"~?7߰!OyWH A5`Μ9!ID`!``=N0"E >7#" " " " " " " " " " " " " " "0B??~IENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/primitive/textviewwithcenterline.png000066400000000000000000000325041457770046000316550ustar00rootroot00000000000000PNG  IHDR@#iCCPICC ProfileXyTKnX%眓 s%Q"AEPTPAP$""   *(y}|[S]UWul`5!ё܎Nܸ)`eii ?g[Fd`O(7f ӏ÷"#`[o3oag[ZHH?[c;D#6; QMA?DgOHH^@mH~/ۍL7 *<9g ^ GZoۥ0-L@p{i཭_/xE s@o deH}}y@. ޵ 67ݵcҳo`$P;|'zgᆨX?}F# 3T rwhKnh0:@pa  ,, v~Jpؾm@" ]7Jwwnv !hV:Zm5CVӏϨX=. a 3A>w[\B=f 3ݶ]-0f`翽C "h5?͈fh9-<"7ØʉD]#WVt5G俚p|}p;p+3v&z[b'eYMk}⣷NXxBd4pzIᖑV`ko:Yod>3E|Y j`G& ^{#ڎ*X'ˆ?2@MN qpA*8(Yp\Wu=<`F=`A(!: 1HR!=  bP: @ ݄A}f/"Q(A$J 2A٢PDTuՌzFMQ0)`F`v}H Õp܆</h,͍GrmBGO/]gI"7Îè`0?L&S4aubBXEd]:aI#rl=;.p8N g#q]S{O2 2.22}2gP4bZ;dO>S [{'_ o#B| O«mT)|?FAAKLaE@Bqbb@K%\ 1cjB%%% &3e41?tD ћL,%6?SS PiQQ%RSݠzB@MN-HCM>H]J}zzFƂ&M-M -VV֛6<}i:N΋.]7{z,} }.UEZ9{xR 0 c0cu_LLZL>LLuLO~01k20033bfc bgiayÊfebc=ͺFϦŖv;]ݚ=<{?2'G8G }NFNM@B;\t\\\\wOqwq/T )u-sJ\@I_@A!AÂ-3BBFBBƄ)5#+`EDDEEQOPb bbbC{0{3*N,>)(a*&"Y_Y2_G򷔼TҴim_eDedJeR&˶.ɉȝ{!O'o&XS~CAQ!RNaV_CLqT^RR2FY[9Y]yUEA%ZUq ZՙB{}^;ƫFRPPVP?>AҨԘ֬%uE볶vv:niq}^}?IC|Q##/EcE]&&Smf(3cfc-K![VX+KR{llmjmVlml_ uSٻpu(ppt<ȉ)l\RU5udо}}nnnݩI7<0$ R%iȳsK׼wOG_5?5~ :  v! J6.>QiYEjG^sccLƪǖOߟ 1Q?b:+s?TzLKH~br)8M* {Cz[GFJ!C3UBgd dfdy+[~ãGO<{l O!q# h  Oh..)^^W,W|$dɉSZKK?=\]Z_^]ܻ3ug9u.܋ J?\sQbMkUnFuh%K]555yQc.^q2xUjkx]E=c}nhiqmJ7˚rV֡7;TۚnIܪni/p;NƝͻw;;ݛt|}.nhUmSPa#GM7 ( 4?Q|:<6wS>{a/_̼ ~*1X7oEO(Lܞԝ쟲z=5=.?r}i՟s{?>Sgύ_4/:._\z˷r;-WBV~dyiUiïkqS"mM~mln"Iۯ0r|}Z t;n{H+1x,N̉<$[4ʘsqy.M<`P(؃=%AjoSddyd?ݔ?`Ȯ^N9^EKlo- ou4$i3/֙WX[N[clXlYau5'LBt܇޷6>AYUg (B ~ y!XtrLflS<:'c?8 xP%(%5&XzQF!Cәy-)r@.Qcy O8[4?eRbpZTL\YsR&'.U],}EnYC5765jjͽVtvF:v1wv?Ic'^>x.93b4B+3c/?6}on|{gf&fs&/-$~2LK_ݾY|7[\yWˆna4~>4^|״coLߞ5tj|z ١yOP}aio7W,'}5a]wcv7<vC`p%,nl|O":SR_ݤ`c d:|- xnm_<xMx;V  DE E?e-%$%JAneLefd8Z)r) o-3**UTY-I^!1ũժmR_gSRR\~C99JcWf"3s*>tKUVA6B6l+ٳ?ws4ttjrvwyZ|ߊ[{+R' d1US7 5BCB/ˇG܏̉f~s6;N0C$gos+~ԚC.zE0YϳKrss׎L}|f޹] TNX-)^|S%o>({Q>wfewy êVg_:RRKxxOu kenX6&556lUVr;}wt^)}ǠS#/cSsWV*p"P3 3%%% P~L}~@ ( `\@H2D!e8LHIC;CW^ FPHuM7}=dabU%5zHHVMFgS)X ՔrD5b-jC4ѴԴWtm,23d*aVcg9N):w$<:o_1^A ,OQ-1==k%IK5I'Hˌf}oU(PLPV6UReKTP/:ݧELŐ݈X4yW+>kc=h]L~FW}n<$O{19?*{C C?GF#b^Ƿ&'U>X˜H=|80k>'Hȱ|kNf,,?zreYU+j^>~Uaƙ֏mKwwx$XP賟WcgMyO?W+G>\~zߞRVqh @C` <@H٠Ԁx! ImG?* %rF\;|^@+3L*f })qdzdx 9K4e`3bg|J>QǛW=,!*$rs"7Xx~h)/iM̀lPy~q`S³aQ||,ςY5ZY?nрP#,ʯ# B>( *nC(r$$Tjf}hvt zyƩ!S( 02(MIM]BCDgDo`h̤,"Ζiemckgo-.%tTVWtviVYoz5EK*{15׵Mtґ10Z311m6b%alc7wjFAO?7CupYșXθIʓR~Udgr^̾{oA>KBߢ%4+*.(]a\g y]15ͩ{Nq]{8? 9->)7z9oMRMM{7Ac̹޹'R_tH_Y~|t}?V:l^e\\m^]+Wqf:ٺz {>ߛқ>6++`77 +`#ssrss 320 490 1 ҭCZIDATxtTezC K)=f<0SMo.      @P\hQWC ^'Nܹs}o~~@چ@tJ/kp @6"`+AK%%%яc @nWXc *omH@ m [E(o[1 BV&Dla U"@[E#*omH@ m [E(o[1 BV&Dla U"@[E#*omH@ m [E(o[1 BV&Dla U"@[E#*omH@ m [E(o[1 BV&Dla U"@[E#*omH@ m [E(o[1 BV&Dla U"@[E#*omH@ m [E(o[1 BV&Dla U"@[E#*omH@ m [E(o[1 BV&Dla U"@[E#*omH@ m [E(o[1 BV&Dla U"@[E#*omH@ m [E(o[1 BV&Dla U"@[E#*omH@ m [E(o[1 BV&Dla U"@[E#*omH@ m [E(o[1 BV&Dla U"@[E#*omH@ m [E(o[1 BV&Dla U"@[E#*omH@ m [E(o[1 BV&Dla U"@[E#*omH@ m [E(o[1 BV&Dla U"@[E#*omH@ m [E(o[1 BV&Dla U"@[E#*omH@ m [E(o[1 BV&Dla U"@[E#*omH@ m [E(o[1 BV&Dla U"@[E#*omH@ m [E(o[1 BV&Dla U"@[E#.}mFh+w[w_˺dYJ]Sɘ%Bf:yfR<^$g9Z&q" ޛg5VIt^'6G~FRi;Jjt#G6˫oɩNJpɿ.UG6ukkpyDl/)=~T^]/ݤ*:KV.GS^uz)y(x^}o޼9yxe*0dgd.vw?ga/"N:|'gPIj7G~Ws=hy=%s/Vs~G ?i?_M|%+tg|>, GE|b9|IChh%N~S47|$4+_;6_q?.?!uƮ'"aGы3)8h7.oi3V!S˰UwJ !@|Gp0H"󟹽_"/T;3ʬ 2| wF/"&F? 82o>=8wlT\"{}!Э^0ߌ{|]=$QAۃ{4W,.4_~~~vΜ9c_RR0e,f~Լi_?9e1OS\]m F^w;^@6;COxG- y=IzԘ sm#ԃHnBښ:B= @1 @ ߭߰Y ~Bͥa@^@.wxWCo~͇sЮ;h8E3bcbO]`L|SNfsܫ~_ΌgaD24;0-2Pp{~y|sK&ܼosyWd\Í+RlҲ.coi sz%Xtڮ/<׎WwJN~dKي=/Ou{?q p}c\nx\ݺW'/).ɝC#>. 4QM_jb+-1TO|ZQQ)]uK [C7߀nɒ%MUTOt㔜f=+~v4,91kQi(y-/<|We4RߗB99L;|OjDcy s<~#oO.;J {\aSQcZԣF9gǚw,n^&^G4osGhNHR3rsr X977c3tB5٢9{Vٛ[IX~W7zo?X[E'I~&>~PU'{yna 0iwwK 93? vk¼lDx>/vEv]r".32k{OI FqSn~|vTo{kS/s@('+J^i>u#Qɋ_F`~~pOs<^<}q_ 1pS e~ygN63mQ>dv<ᧉ^cd;曫xc~?OJ)AՄ?橢7cY޴ni櫯[fg1vp;w=7̺+.7|h󸜍]KkXw^XZWpsq|geuO-B ;yG(3T@,$k: WҼx=NE*V 5xP\j~_W&~_t)O& 3 Ai oD"hO1CM\J@l$'v$ɘL $őxR)i=i E #d y||<@ѥR)qee9erMQ$ju!@=MG}e5AK@RkYZh4'6-ݦvz:^G?I@h׮nҾBc֙SSs@N.ENӝ[{HnCM/N/_onszIv'Úa11N3 \r})EՆG ;ӎe133o0?0!dDÈ+#4 15]7h275^il|7q2`2diޑ#FG?)jd`:tE~3sH3zfL5G{,Ab5,~gج 6slmRl}mElؾK=׾ؾ!aC5GcNȩ3,v10odT.4KK1nb͘1+ǜ5u]7}qnZ^;ݫݯy="<{xtznWgoowwOOM_xߥg~~}/gK@ngc nh  l ~b"aau  }"ÓëDXEdGGEzEΎ<EZuks}|w*]()F:?nbmc%q :~}_&'O$-aN™DF݉oB'MvHV$LNKy*s☉s'^H3ISwO vRdɥoLR4TySLәƛv ;/Wfd9uA0PJ4+0kUֳ=`QWW_Dly3w0/51H/ɕn>hzYZ*?c>YlO AՅgsl:{^vK>Z.]nqJWîz{7oܺ9f-gnSxg{{euW<0}P/5vzwyGw].yBRi3g{"z.>Qyob_KWK_M[|oޕ7~3S?>/_ Jy2SNi0.@>QMU'> !$ vuNPyO< Y688ap6mP/Bg~Jt|+zS\v pHYs%%IR$iTXtXML:com.adobe.xmp 510 758 1 M@IDATxE0C9A@Jp]5(+]}aEE5.(*+f]ŀ 9K0d935}t}3TWWUuS8?                                                             H dnnn['   'P$ IK i w-*F,/5Dd}{eGM>xwVR2 @Pʼnz&L$@$@$8ޱd   7LHHH;TqcK$@$@$@q#@'n0 wxǖIHHF*N3a   P-% čUg$@$@$@[J&  8qCτIHH#@;L$@$@$7Tq↞ xG*wl)HHH n =&  UR2 @Pʼnz&L$@$@$bމdwʗ/ڣG_~9a1w+Z:u*]x{bѢCŶm[t颖 ڷœNo _(Ƥ6y6mq𹹹bLavl_y9߮]D"3ƦΤ>~]70q.ˆn&I3UWU0nJJK߾[tǑΝ:N|~BBDUٲE/7n{!!bΜy"Ew$T $[`p~xcŊgfO=U/\PKfN߁+h٢Ee!y'V!ߍcB9&Ӧu^?XD̑˽Tq"!q=iXJJ^?u5_F)/%LIr3 ~˕~lq#DF#ilg,ڋ֤IFZ[[ѣ!_|Y|?]7.Qf:6`{ [g`ʕG6n # b7DģGOؑӿuK|ٞY@⊊ۗZot#(-CkU}vI+VVO lqTVmrV:|< |T<5ώHjBRkf=["ڼ/?jdH QomެY% .キl6cևbH97?߿%'%6&1iR3V0rYZtb3|xM ti+S&Y4nΥVb4m ϚD";1㬗_~};Ңf NjZ[jq-]:%>:&9?u{Z%l ޼=vMP_}a.e-EMݺirѮ]V{~rʔfV@a lױck]gO>s4hg@/50/{ߵ|7M6ݰֈ~sD_} 'TpC1cꅑ#͖-}wה){1[M[~s kȑ=6]V?z>}V-T7uiN/Wh^x2O?-*|:bH~G_xaq۶oM-6n\5FkxئͤIY;>wB+~#N4qbcoϝ8q>| *$T3vKrp8z~1?>u^[蠦G<OJ>S1n޺ϙ|V-SN?wP @E7k~pO"]o,9[~{5ϛG.,ưt 5 ZC7`ۿ3`L;>pu˗66,q~a*S6jX?P|jC~U`$0<-b&n?Q0k׶\H"}K\L6b_ycfj7_D'&OhA7\E/y͆9Vwў5*=/X:X*TZ_ \/Â~|ŭ:˷Rx/cD=]ώMXçL"voI\9;Ns "Q3=uXXq$ SzZU|Ov˥ѻ[Qw0ofʔWXā637] sr* EH\.Պ_|q;*J6Po:RfttV2FDaITεK^PA [eh2׶=PJJ  %HSOma11Kj"~G u*߷lx+Vʕ]aI0~vmuüY5x5{}7 EwY6g~JE" :]駾)gY^ #G6C3Ng‰>ҭhroJ/ 놽̿{4m8|5XrY㏛b/{z]x(yyO?۫?A9/AI  =:ҘyH%7#G/XZv:fL`^W'i |^gwA 6ϋ8w6mJbGL׮eqH޵,e sO"7"L Q=6YL85R!H2=MB?|޽C˷݌tnY޻BVP-m￟ըiX}CO:08bE,61[lIrK J  #Ix6I&'`K7\MK'u uq ^ yP`~=;d<̦Yh0٤o g;{nj_buyG['ݸh!:ǿFJ\}e6T`IVГLR uռn5L~? 4zʔBVzݞ@NZ*o]qr7e.{,0?n|:Sb\uIǗ??lڷ2(X6ۿ#A-k]۩…Ak7ŇVϞʡbe NvF.qh >8'68 Ya :%!WW64վ4JR;Uv (;]hxݞ5;z^\J+TUu&#x-UEw7|BzQI*#N \vmc?8j^P* ;_pAn~E尘\nMu+׸ sOuSQQ˦3@2uGy /,ۯR@aO-- +[ڒJ={hAEJHx=0xQ 8|6=Y 0*Ep-L?|=|'*w)ga of%KU=v,]NZAx${?B= w4H#x͝q9n\CXn=ntS 0mޱc߹s{M˖%?x7gaUbk/pY9ʛ_z0: `'Xd,A0h*2ã0I>}|Ϝ9-KɒЋ Nڞ=͕K9ydyg5H'L0U'3 AAġ84RVhxLj-9pw-'.k>鈜){~aܢZ /lJ< 0sɓ?0-3,]z>ƋΟd}1A+s3fIhif~x#TP/p2뮫|uzJ?y]NN޺M|IxOaH̠TÕ[Iߎر P l4AڕuX 7vE{FGaP8UUMtGH=?ߋI>}-P~Mg?U?xPv x..MG.X}sv?_~FeFskϳD}+a\1N |wA@N3q]|re;Ɂ'p5OϾ(=[;=V 6睷{Zcýaў=^G WGeGJK8`j--Vo$o]{f8i˸7~Q䉏]߲R,(y9%n͙>}_xeٰ nƲP~޽Ì_}}iKX^Ff%Q X>w۳^;/ יZ6mJar &C|?dB=h6U`*, `$F:E,d&bV&D$@$@^?aŊlIPft Pʼn.OJ# HAǮU`r 0鎪Tde2wT%z^? H _~oۀCIF9C=ˍg.O]+8<% CN *֘iIBآ@$@$ 7T[&"  H.Tq[   [@$@$@$@E*NrsK$@$@$`U[HHH PIbnIHHlc  $8U_- -Tqlab    "@'ꋹ%  E*-L D$@$@$\$W}1$@$@$@PűHHHU/HHH801 @rH PO$@$@$@ NV fHHH b#4Ȼb#O ח]\"=f~ã&|K+wl)HHH n =&  UR2 @Pʼnz&L$@$@$8ޱd   7LHHH;TqcK$@$@$@q#@'n0 wxǖIHHF*N3a   P-% čUg$@$@$@[J&  8qCτIHH#@;L$@$@$7Tq↞ xG*wl)HHH n =&  @1DSrl/_Gˆ bwtԩx␿wEy%',Dkϑ9aYX۶mK.m)… gtqYO"Κ5رc.!J_N$=ٴiÇCюΝ;/, (&`=G5h~$F|̛7O2`ڵkT8<"6++X3p**7!_}FF޷o߸# clHK֞$h|bd`z?~xd2;t1%Μ9ɓEӧLYZ 8ũ߲eˆ <D=G+?lϱi|~r~+V[5k|ꩧ3^e22gnF٥K4C (Q{333Sogw__֞#ɏlf]eyf/ Ϙxo'~7XbV@6~ަsxcʕDl٢n:bI sT&7. *NZ2)rF晕*[Pv0Ӛ4ɨU+}cV9z4HT-r1 p=zrǎ+׭[̚u 33+*o_j͚oC(,`0Emܸq:uV\q04[F5CB[bPO͛ѣ;v1nݺ}%+h߾5kx XHOOoҤIZnݺjժa40^,m۶b M#1۷ LrSVUV=쳡uY(>mIxQZ|Q0ET҂ 58, LKci0zK6۳ZnY×.ڳ$w|&uD:t@v˗DYgUDcDu9dY3 ڶm_vɎG+^q8jЈ5ooq?XN^Sd.]HF Msg4ܼg;'%64"~9-ULp@n=L]-e{o W;v, -[j0u 4HX^{!C }͚5(X,!7oތ6*K.dڴi*dҤI$вG@`c=&-q \zj衇>qӧ9;*N}yM7I6Js={ +PA3㈿4-RPgT ڵ{DZP|МFm6*U``e]&}]HDyҥKDIΝ;-GE,YSt)70}'|Bm,DToTmG;$;0QuVڵ q)o`DOߵ / {ʕTTvqݺu5j0ËJH77hdɡg2u^JrT?Xk _7LSEAU"hSvw}Xf_׮Ksr|*R$ F [Z޽lZ~Gn5np!q[o5j_50yd,C46=O <l?n꩟y7|#[ാ$Mvw!^x=4ȁnKሿ,ۃ%b/] @ |gQM /oJVј-o -8O,۳hfٓ]uaU0F̙#VV s A):>J~(c1ʔ)Sƌuefȟd1 2eJ%RQCȵKSt:N延T[tmrf.uyE>?eFϱ,óaÆ%4 $T)-zt!Jܠ i#0֭[cULhк̼aD.j &_mixӜ`(RwVCBG"FrT_.xxV )R(,r+ЉhIGDASa lϦU'f%ox^ٮY 1a]`~gV ՜l>-0|T`,˫tDcAD.^X_DE0/l W+3-hue#]NwN+>~ua9wƯ|>'R]qؑob#k*zMIt9G>mқ8^LVEa _qk?B&b198qDE)>YX.#!u^_}čP?0掁,/qc动0pW_yIosbQ6kDqlX r9~x]ҎE'IjN0A.: h`:bٞW3l=kdwzW_8;#VI8fJ[ꆁY?u9~y_YHUkj>)Y3oBGٖI~]f+Se Aߌ^Bdg֭Kl)`LJT?=S[Bǎ]˷D,>Ĕ:œ(B1[~AnX|cj/gY̙"ITc-AaYv4-Yh:U`FlYʋcԡ޽[f4/%u|lUbСOq_K 6e Z&|S>d ?&!Xv69y|sJtߞ7zZmڴ$,ġ! 3mڴI2d1,sU@觶-&#2PN}0W%*1bW*ZԧM+~\CcH5[N/uiĠE _ Zd 3%w{b&u}ew)ɀZB͂;!P~`Badžs"W_}5@{ PyN`IO>i-+BA5AծL6ߔigPQ(ϑNTi¡vSЬ,͚'}yK:u Kf~> ĴE9&qs@#_ !~X"HfCsWLM)tӐp хlv*UJ2h/]k,9]lX!+LN-Qa|d^R?__$1lfr;M={|ES)*`˒afr[%p +KM%R`cl<ιӐ:…vTW[t9|ou5Nv>g_?gN&baE۲<ծe,"t8s-vI|YW4cUx63yY\TLI~gcY_j<(1e肿8z8 bI袋׿%+"u#Bg]e&s#F`\90b|}\IƗv`rx~w8s0*eA>:FĠϞ8( =8\P*).*׷2[ƍ~Oժ6 '.-̀S25յ5I$u#lsÁ}}yȇy7Aܚ .h0]9o< NC]̡? 5-Gew`^x!zêc3rKjTR@YOǹGl479ZEKk>IZhq]˲gS#ĭaÆpn|C ֶ`ݻUW]94 >3^K( ec C͉9̫$ 0׎P)xq^8P/9r bB$1QlWNkqĦ=O>(b{l>N,(i{flÚS2ry%K..mg=OS"g Hׁ 8P.1v$-M8O` & ?0abћYtb?kVƘPÌy4_4ґŒPt't AG^~ʏ? * Lӻ}@%cذ 3fd%cӣ_Z0øp]r$bTf4%1!bY.Ō8kkq 8a|2ɟ)0|D;$x~ A} %J .amߘia#v"ΐG^4il>8D/<8 * ,^ q'"cf`nG٦s'y6SK):gs`qzxjB -?T ߺQʕX1说^c.#V]> g#C;U՜`yq4N%tҜ9k`ٲE;^U"*sǿWrZ؏>j"U>[W=8%aRdYkK†LJX7}{e\c.>}l+`$@$@$@P)םwVǴv_~߲ſ"G=   H1Zn8v|vcw7nS9 O6 m3$ !aȷpnr˖%O%q+˷$ ;yƾv}Şg _#OJVv*&IѭU.O&_'<r;L$@$@$7Tq↞ xG*wl)HHH n =&  UR2 @Pʼnz&L$@$@$8ޱd   7LHHH;TqcK$@$@$@q#@'n0 wxǖIHHF*N3a   P-% čUg$@$@$@[J&  P)憺E   Hp$x1{$@$@$@n )--'|D޵yZ$O1K5]ZqcK$@$@$@q#@'n0 wxǖIHHF*N3a   P-% čUg$@$@$@[J&  8qCτIHH#@;L$@$@$7Tq↞ xG*wl)HHH n =&  UR2 @Pʼnz&L$@$@$8ޱd   7LHHH;TqcK$@$@$@q#@'n0 wy'S@N/rݻwѢEWKdO{/lذ!&mۖ.]x…xHP=+EI!SΝ; /rLL$1yȧiӦFߏq7dRF|k޼yo׮]Ss [m'L>QE9 ' X^HJꮘ\ B߾} g,(<nO?*}zH?\bEHYSO=U28ũ߲eˆ \@x6lK/R ((@223rsϓW*< Dȑ#'1yӭ[7ҥK,q=/LJN7Uǽ"ɀGۮ];EԹs9Ld wA 8g˖Vwz'<$3/"DH\r*a˖-C \{FP tg X-zFu꤯\ydcaoظq5-:wP!CU[C%!˕+ro LQ漣Zj0uo۶mժUǏ_E6nܸN:+Wܸqc >^|!|Ŋm Ix:TZuڵ˗/2m޼9D=ztǎ0ԭ[>5k^jۯY7@)'J&(ޤIZjmݺ?Ze hZ£>lh-FKxsH޾}{(eoP| l?**1s5w}AKgb6Ar"d &tبPDyGK ژ̴キ mƎ"3W/}Ȑfomެo 0~{-[j,8NMi0q' ;fK;< '@.ȑ#̀{بW^=vX AEH%#/Ry衇Ɗ*f&O˖-: (V|c%H Gf,,^07o?srr.iӦiI&b[Jcǎ?]vzw-iĈ YYY=j` v&.2.]0㚓&7t* fٚ%AEBӧ;(NۏP$n)H$,E];cw<"3hի7ds`o5kf)"$eUCT0}ִXmTqx^ןSM30m[ʕ%Я_PР*y:Z[@/B۵RbS7b֪U+soȏd)ƉjrN8Rq0~ErʚUq,ĉիWXwH6G+G#j5n8e;qD}ADZTP̒%K,aղΦ_~0K4?O "w>RwqCz'E,4Wq3&0Sbyt4*^wi{!!SbxV5x7}"|ݨ85k-(gUܨU0{UhӦ$vluZnŊY-:>*N4DiYR%ۆ}Gy3?<͢an^.1yKX?+nLeUX)Nv-*v.F#f|ڴi XLM*̱mg0(xLPB;K-e)5t}F^_bL[KeA!ҧkHI~`0N *K`} (OyFRI9_QXYDQq22>yhaٿ?)8ZCkx)Č5xpV ֢nڴIJSgyNg4^ !~X/8rčToʔtŧ={b.\m?vv X+2s*8JI:aő{oz|K%ymR 'SLbn {џ^/S.lQꛢyҿ;lOlc_+vcZ6aaJSF W6|tn{Ϟ| *QvbIJRI=C[ЊtCø ι렃J3}<#L /*Q8 HKi~"i?XcfE{A DSM8X<`LTnҊ6ӌBwNGKg9;[ѵ @g W_mػw+3umscrsqʗ/`1 D`k*~%>8^_kfO*a|aԨ˖_~yÌ2eJ3r`,p6oE} gtv!S" 0'b "3m25ә6Oy,?iZ,8l0|Jl8.`>O>!G6iƏ/CH5P4aםr çM:١g %J"o@Ɩ@-U VbYh?7ӽ?PI'z:e=G g9oڴhBRp`?}i~0fΠIaOFDB]a9<1[QTġQ`%R btw SH_#0)h"36Q ##B:_Z_0_"{xVK/W}4jHŁA%')Z `lɒVfuC Z}|:{ٺADų@S6j8`f4lKl5"a\ϑ{d,)i9c>&Rq[EꡯÔG)06j1M74iHӁ31e&miov`Lp3 !|rQ~MB0h-_C\J,Kd^3"sUzל`yZ2Z|bU3 #8_@>fB {"sq0qPG*_w][q_Oά[73-ZdΟFcsnr]eP1Dȷjw#ڮy:Jf}Ł|Q/FAƻH,B/AcSr|Mⶨ8H f5 FO>Q_ETX!9 >! [|B ..wPZ>Z2U1 h`~KL㩒+s# ;o?q {8r+d>|;w93c6rI m OxO|ϣ8ȕ,E بCЁRt;q,U2aG5AtD Q} Vs<aYjU %C-tM'G?:~X[{4}{b!kwp ~#  ϏduiI QM+MDnzL3Mw4wTԊʹ4,\Fb ( /IHH $ 8RS' TqbP   d!@'Yj$  p@*X J$@$@$,$KM1$@$@$@PqAIHHUd)HHH8`1( @,5| 8 @,%  HTqO   8Š$@$@$@B -TFsssCݢ? %K MHjo◎Vį#HHH1bc,<wm< <܌AN; PwFgU_ū1ӊ/LHHHCTq̓cԭ[Y.s3-rڑl4 =@$*GYu_y}G2w]ZǏGW~Ң3QuUDj,s2#'sMs73LH`ĉW)ʕ+Ζ-9#S|Ǿ9h^.֭+}k֬y7MXo vhwyʹÇהK2E5m:w*Z'uk[ sȹfźO&;銻H3F}{;j/Ig` HF6lKV.z!0|p\tzHs-RG}v cɦtK_J¤kqW^a׮]ǑkVcK!CP6k,0{ zcǢ#  O<4W{t]t ަ'L'уJXe^/L8fϠ2,sAK-QR2Tl6Aoo-[hc}ᅬ~ {Jb&iUR~/.e׮]gj6h<Ȁm޼:srr.iӦ%N4ɒ^/i'7ի)D";1㬗_~};Me t;D|CS}*V,õ680V@iժ*/+4^_>sTC8uKYXX`e 68p`MQwuy]˿۠kwW_"̗$(F2s뮻ׯUWY38&OܫW/3<^:v8cƌ_~K-̬?.OfBV]+U"bENmyroxxWUs=}Q-[p\.^'[WL"TT =\?CD0`'B+_hBDWzuSqiS꿟~(:^ʩ~3iR>zֹs@& uͪgǎɢEyff߭+ֈ~sD_} '>zԧ pC1cEy㢂'N( .1BAfG XkD9q_bDK 70f̘H{|o9t L[o,.#Gs/^{OG;w.|N=_ ~΢=z>Z}yCgsgt3#{%_} RY՟;g|bƣgqϙ3G<,lv-$aO =>i>Cy +z2es/.hӧDDB| 6rhd"E;њ7鞨LTJ)3wUmsT 4hPuxG]cFZC7տ%)|" ao /3tP\1'qqHN&O$3QBiXFIa<Ӓn 's hHruSW^yEcfJ=Tbz:r!&v~[ty #G*VWuyE!&4p9Bկ#]g/39؁7p3nɉQiU(3<;CG:Q!r-DuX#W_}&a:\ZqL^uoV&;tXj_BoO3}O>oikeы/nԺ:0-Q~{NC=ORq8eʇΜg"`?|gQ_5pc8k0OK0wW-4!,"?}.VqFW8,+}\f5b=vzS̝P:h8vٲe0̷% ?Q8U_?:G.- UaŊr\jgjhps= YX#\XZff?nCwp;Z(VJTwT2 ;6}>?+}GaQ3aۉ;%#?#Y<#Qqz!bGs6?e9(13OZ۲@W!`m8:qE6SN[V=X>c{wygA5baphHџz+ik.]g0XD.3;,2Bݯ]v `\mr֫&E"mQ; 1_q%2s$$7AU<`o/TR4&}# {KUqv Rb%K^y пХčvkx4dʖh3g4u_ k^oF4X#VdIc:ŧ٠M!qt;uy#?{ҋDY^i&E6%\`B￟W{(oJmۖBx X?ǃeu0_;?e'n1 ̐6fL9 M1c&$ńOS2Xu,\fCat@YؖEד[??EBRE+$SK-L\- CE{ƒ'||`Ά/sv-$aq8p ,䰁>Z.\׶eS-?h&b$)|T*B믿~w[*4% XĀ_F,?Ia{^ ls֭"HO0EN(00"=駟iolZNRAzPIWh2ptxdJs.@p'KWTWA$@4b:*^Olnrڵ~ h`uퟟP!eg6w tpÇݯŪXܮ];3 >SYm58Ҍ.nDTK&4ԩ`ѫ,x]^5p^#TE VcW!:xO/ּ. !sToʳN-"뇃kJE9IfJv4p׎X87!Uo?N]KG駖ZH`E6*,]0UOO>YLNSb]pAnEEä'LHܣ͛'ĐSjč{寞btNם>*>T>|."ݬa,q)-G卙|,m裏p(^p֪[#ut6]ی%bal)fv+zt7]ʌ;>μw]vW䜞ADe }^lg]gS֖t$)X{s-6#SS7Ąv8&ҥhQi_|G6!wV6u+ӧO՘3%vq/YrxCTz('v={]v`D^,h j,QXbf Β%,r("DАs,]:Q"t8Y`Z8MasxSom7! iƌzt9fุ%Kviy0dEQCͣL-*TyQ_l:Pi&PBh'CM@ٷ lwX*yq|*h J>7T;)~{Ƅ;Vgl*Ƹe L=${QkS_2'Y;lg΁=ۖ(UxӦ}MY,oiS %l_IA|zg_Cٚ;`.-pחyav؆~/@;X0B2՗P Z85gBBW8ltGx]^cUq4>+؄CU.Qx{OpҺus ҎpB %^W)y>vebՁh+E-wEK7*Nݺ?o,ׯ2ܧ VN>R>L6L̪ Ą̕S7Bi66   Hy˔w޹_Gzmk s7 HHR8Zn|a=MAvQi0:@sm]ђƵ8"\r'|} ǻ8e+$GN3<%*NH&8Ux>u񺛛Q6hiGn(L"=T"x5fZqE xH*p)HHH ^ċ<%  UR4 @PʼnyK$@$@$!8¥h   x/LHHHCTqW=ɑ$ JRbɕmo"|ˉ*RrعsB^SP߾}e` pJN:]uUN'{xNT%{ 2 8ũ߲eˆ .hL͜9ɓEӧ$p$pyM{Z- ˖-{ qxNZt+0"dVv˗ۉRH;Հ.l6*bŊXM_|M]o5oa=c֭g͚5 /W\qE׬Yo RNj3GdRJ*-X ;;;|TҰa%J) `_4-G|J YS^H I7iҤVZ[nϑ6E 45k\h޽{CHP8>Q"D^۶%ssϓڕzw˓';]x(Ԡ#jnNfeAb:O4'x-O$#G0{QYï^zر8a~|h`8|G {Xtcf;}wX":*o6mڵ yܹ5jTZlAiu`1ܼyŝs%L6ML4I(^13nɹ^Fp1]v?8IQG.^x_p_5H'NCZX7I..]jy⏿;w6o툏%Kɉa ~yCc3uwUPG7CmcYYY=Xjz 2hf͚N *1Ukۨʢ1cxܸtLXmBb]xtڪLz_|ڷh=LݰX`t8`.\Ex/%WAׯ%ϖKnᴼkq9t,xͼPq,yցS1|V^]pWd[/#t8jN 㥥"p9f̘wֻo*TQw8!D% )K]FlSq09hc8q"^,*tׯdƲY@i sp!|n^`[Ǐw:ٰaHIPDQDY̮ kVTGq]YPׄYńT ATr~:sܙ9g9޺ϡߩϮxVyU֛c\Xhl8XkD`#Gdp]r]Gh0BvK,"Ĝr)n`>t a*Έ7{FT~lf 7ЍT_p_Ė3|-Yp:veB@rc 1ACGH^ -!cG92V}%oƍGjxAFTq>E-cgPj!(xAiY\)@rñ?b㶯wUTTB])IbJ%6۬^sωLhO?-I usUaÆI=džX*NP&)SkTlQuXQέDѣXQEߞ>ka+lUk?,>4ht;G}d˓ѫ: s#*(17Rǘ%?Ν;wМ9s8H/πSq!,r!Ŝ> _|\! d_WlDQ}%̈x74^,qȶ8d dMR)cy(n)oQF{J--/Wk7&A=|W*++a=ݰaf͚U1M֝81Z޹s#Oa\5Ƕŭ*f]|]tlnt:f{RM7T|o=~$?2/{9<捱%70d 2/BdOJEgS"HzYBbb' R$7=K]岠4kLp#ǐwiYv^$ M/}=89Y&TUB@}&Rm 8pqy /ӌYp̐,GFfs^ңJderڻL򩯚8hù`L ?$'y,BXl8> %|0 **gwg3Pn4PfM\R&fWfdIƘ֫>ҫW/Ӧe_ȶUW]qA^ziAt=px5.JρZ:_׳#E/jWr4o\^9/uȈ R6}5 )I/>-bOW\G3-W%F+q+8n}Aׅo/xq=ߣ* cdj^o)1/ />rI+)n#r rG,4nਣG C2wM6I/۰UXͧ [j`$TX?1>W<~A7|ﬢ3"Ikq+dNV߈&E;筶+}(xQohjCņ I=Hˀ<V)5%[7pchxQ}\ONrÇa^)g]b|}gdt7W^A_?>OrwR EçQlŤϖ.Qԕxs%駟UDu,6/?-ŤTz$'|/*W=CU1 qyTMм7:hsP8Rx'aϱp9^p̉;w[nޫ]w|A_yǩ '`Nē;߄Fl$Eŧ|z9o'5 Kbn!8p \h_8ZΝw)xޠ`9I"ԒP<"F8?B04#^{y=T MqrOh|HbczHR) =4W~xJ(7 21q\|HTĻs,Ib!vy%w/1ҊGğzݘvϻC\|T|l_Ĉ5_%oDEe%%8BSOlsW> א\ݞz2@M0ze|,aUqC&Fw؍[(x!/*G{ #ת5H̡e]kîg}1: QZ?)nww) (`HǕ_+> Hݘ?.>s8$a 18x2>AxOP1l_)=|OxC]'؋$#i.f!-|w~PVM0 I8Ԥukt/|E>7 g ''x"~[9W\KF9ID5@*p~НRًO~R`?#܃H!K^MYW8Sĕ_">. K}1@_ QqfBwPeT^wG#+qnᑕF?{1ǸM.l"C*q}# 7Wqs=bni8w~DlU7T G>ӽ{~ZtԈKǎ]0yr˜7A]}]5e R(+y QN5 GD1Cǭ*2:xHp' WF b.H}jp/Xr Xb''Zz'f C0 C"`*Nmz!`!P060 CSg*n!`fLũͭku3 C0,٦!`SqjsZ C0 :8uↀ!`@mFTܺV7C0 C"`*Nmz!`!P060 CSg*n!`fLũͭku3 C0,٦!`SqjsZ C0 :8uↀ!`@mFTܺV7C0 C"`*Nmz!`!P060 CSg*n!`f+ C0 C(s̊S d!`@gW/'w|M4!I.!:%,݊))-erlTj` @> Uj+V_>F*NVJV-M\жmŐرUW]BiI5h߄ :](_VK`am߮Bt*;Å^vy"O7WܰnT"qfg#C$6BT#ߦMH3C jԬ*Oڭ6?'qo [M$<>~[|?ʳ:X*ÿ6¿*NFzlҩSӗNxɒ+Gzuqѣqǎ>dsMoIO4H 6hJ%+f\6d]6~_~Ӧ޻m߾Ϳjɽ -6zZ?x,B۷dM% kiD˖c6=\Co,G#8BP,ƌc=s\~Jxb9#4dz% h!6mG}$e˖!ƫe=.9>ʁ (̉AF矯`8sY?%\"=b}t1 ߨT1^{;5_իPS}?i?d20Wx{챼e=c;W|擓O>_~7̋˟pIG$vm_y/_ vÆY,N*[le]q]믿>i㟌!MLŹ@_TQq.K/o;NA2b~}XύY_/O5Egi>ǣGz-ۀ41ׁ* :hm|æn*+Zyu+x衇ct'WaNt7|Üh1"Fъ˳XㅲbC9$@nLw<+jϿ[n0W_]eSǥ!#Q /!^ySJ vqG.$X^{mWx 7xdOU>4Ik(o^gՑ3o%7޸ve+CGh0 lI)TY/]C4{v_u\wWi.Šv-.H-5Wqrk~pUOP{?.nU!MW4qF;xpz1dH;xOŹNڻw{Ol\9IVBޓfڶm \g+ 3]~f G ?|…BEA+gT8r#yY]wqij3Ɵp XF&VqmLT;`n㖒gXxDy_ty}i<{RƟq=F4 Y'OጺJջwoz%(N@)NYkxU;~.X{gnn}wU +B!9r]-E?-[Κ5Kpg֭2{_ȸ1/a>R(Gj6yW@HUq{Ǎ3?zUz Vi)E5Qq&fmѸqϛIzKne/#d?Gh޺H:֥% 1v䬿vM1n_|Qq7nx>nLa6iZI⯃R%EtAnygL$;jaZuU{N⹳y%c5Ye$8Xݍ/hKъ˳X+ ^MRef@w!a_RUʼn>!|Ptn8Knc1124lWy4lͺVYѨD0o?OY\ yVg+VTa٧XӨg"gͪrh2gXvᅝ]bׯȑsܤWZzbk %.0$l|[h<0#<0>>&K8,kdg9cbigd"y,gEJA[F  :ܛ3yg+ߋp0^@O.OMOe+sݻwxY@MU=0_~p2URVKA7pA MJ3?`wsDLtcϓ*Nv 5k Mőĉb΍LY8fL5:voa39נH+-5Ȕ֯<c½[9('/.G6GLTUմnQ_~1͚e\z?w&8cr"#PKl]A7l3Np%v Do,]/kFٰ b\lɣ6yO3U[]9Λ!h$SEV̞[0qK, B; L ls݂/e^Rlvoqw<yK yts%z6dIan]$ᢖ*.k8%) SMn T&$ UPH/&c1zO<ⰩdIƘ̦WK MKbէ4=\mY Z@]k\zH'!F> wQ|B|饗z$I͛7`pԂ0 (1lƍ .pC$^(UK\s 8tW8&Ar{CKVGhsq$'ȼL+ 7|^L1燈?m䟺c4mU?׿f ?~EYq\\O?](IZorײxE*yOF֝SNܞe­S1)VP=^oȣ8t'hp߿pwJ/5c`4Kbmƣ:Jdф;iė*Y-Ɏ.录-u>yuVɽI8C6yO]š 8mmC<4`@3Æ%Լ؄N:}9|,b𞅽O;_"I'ۨ? "R-ܲۚ!}^\aY80q?kٯn3EzR;JZS=^P0sEirԼ)/RA xI򢢻J5&f^>՗_ BxY>|xШX=}Ȗ439!O?J<)?0먻V&{h7M|ߍzsn{9+8No&xa.Vul>]sMW{tTC|ALGr1WCs˟^D$;Ͳq2? ceb'1=,!ʧXf\;=r؛?~Rp!O57"e%I0Z-G˶w}w?w}穧z(~ I\GQ,&HFرh8uݲ'Nl)/3Xk6k}FJII9{=XC\'A i㟘NC$C1[~RE dh>*^8W\+'0oޖg]-Squ? LX ߉'F)%ߺ^86]bYCzs'{҂Dكi`25\-/^e)!Cݔ=Ǹ*YbwXSqǍ;^\øTB?^+Y&#t—^U4\5Bps5A⠯\q!%qk}"񑼘\Ȃj'/g燸*dIl "{שSӗ`}Ps͛qV]IBBK,t+?,2aN7>cԨQgqg\_{/M v &\ŏ/ *<5HznDdc.07_fʭ D(Lh(I}$. $o)所 e7 C0 rDTrl0 C0DT<솀!`!PSb2!`@'0 C0SqʱUL&C0 CSqв!`@9"`*N9d!`y"`*NZvC0 C(GL)V1 C0 C OL@n!`刀8*&!`!`䉀8yh C0 C0[d2 C0 <0'O-!`!`#r JxC0 C0yx!`!i hb3<=X?+IFk^B}á6|I/լ8ak C0 CdS2`C0 CHSq8!`@0d[!`!⤇q6 C0 !`*Nɠ C0 C =LI[l!`%CTAo!`@z0 C0J8% 6 C0 0'=l!`!` SqJl!`!`*NzgC0 C( z+0 C0CT5Ά!`!P2L)V!`!`8ak C0 CdS2`C0 CH6AM6;8%WJW]uUϞ=O>I \[Ge`}iѢWϙ3NjL?/]4d}_ E믿h"ϛ7~\駟n-.)^&F b{[S91e1b7Np~p ۟aò3FUAZdL>&MPF5u嵠$u97Z7a„:$2B˭?J6~|mۖ;^uUYi,U'O(flsv n@5/B (\4lڴwȐ!Xj,W|ޟc9zF>Y1WrxI-FŅf)ʿt(:wF`\uZ?a rs"\HԫD믲M۵k ]BFzlҩSӗNxɒ+Y\B\=>F Xd̙ˆ Yk?oڴ{۷W_-ޙ*[[\E4 4ѣG.]&M4uԐT?§QW2 n%P>6`,Y2sL]v}q%i۷W_}uB4ШQ={vi'OJ/Pw.}Jaǝ"g̘D,Xz O)ZAh߾&l':e"RQyV_c4BF-]vܹsLq`YK4Yj^^_Y+R@2|jn}KvHD[n%ϔ)S&N$ :nظq>$=_1?1 3%ӧImE.h /[o=ڼJ=7l.G˟wk%y!x*'o/Q,@oi裏V/p*G;8_W^e6m}T˖-c=^}UeOzEг=\4K.C1,hNGAafqc$8Y|VQ+Gq*2f !"0 R+cAd-8N(1t믿rkX%'_IzݤXHsΑB?sPwa뭷֤X%W%&Hd fOI;<*Tc=w*[~\=+BOTQnr+f͂~YK iW2e3U 4p k6dx=".d*'ʙ|y*.h;Koy{$}%#P <w v/+o>$${4H;toC=J馛ʐfR;<%,YFr!*@@V1b{%SU <8O(C\0sчW.\zx 7b%oP^PxjzKbq_}RT]B'p_Z.Ӟt~xM>l0rlj%{욪H ֚[忿~aC]=J$#⸿_?}'K.^/[V!U0IW\Bx[u{$G %&СC/R.Xu]{xѼ=X^奆?bk 7#F,\X!9B/ļ! E!F$TW^y*r\sMʀ GI}'dJ2bDƍ3R!+ߠAgQ V i*q'⬾z+҂]PN*co*r_kUES7 QZ : aYؒPXi#Jެt! rݻ7ZD[GrecDo?a sOƻ#1(lie+V{%―9E*Z$1hMOAK3ϮUٓ]񢸹 Dᄏ[ٮ@Ln'nk[_v-9l岒p\Qb/?P *v|e3wn>Իw7n*IX$@?҆Ō-_~{b bxdIZ]q1/dI[*~mI8Kxm;#u=)uԕ2kA+:n쿸j.fykF D^2y[Ai0v$p>PUU,+GkZu5/ wܑyFiDR_R IUqҞ9qbnXon0pYB3ao*81Z޹s#Oq9K8?HF…8|1kC9L]sU |wߝO:clF If͚ O'-0IZپ숵jQy:-_~ݱҪ8Yu>kV%ÄΜ mIl\熞I5yO~6 6dS,K۟sWK~xUr&kM-6l3N$|ɥ!h` nߋJVʛ A_yL'puW22ȧ1UU:;5hP=Ь!^]%}ԍһN [a2䝀HN'T 7Gޣ^UBn/.%Ul߭ $O/1bFk鮻GZП~Y8~J+ҝ[QPħ":{kNerHxgBYiʛݨ҂sfMNNAЫWf-W^2>LԸ]$c慬{ WvaòĒh{Y-.x]2\GKwcW#SJuױn޼2kl/5I5 >8`z9c5%WwS|s`t|qFn ŧ׷Le]jE5lQagp{3`"S7*\`>*tDQʛSWqa38nC):<8-dԌ}UY's NSZ*@BKx#ގ.[Աcrtnfէ~s>,oj'Igu0ORD)=En@򌋿f,@qQG!r|xPĒ'nƻu4^gDJ?'j 0:pp9呵C7 7&tNɒ NO(C\M L8I'gĔ,ʛ\?kq;sFwa1_z ?70v-ZT1&%<%n~ a~9q}cg-.Y@$O7+>B# OB ^ZY†)-]$ҕM(AanƎ]0yr* gl|JvQW0w&CqnYEē-y<ع/xm"ʁop4/*qK*$x,C\ ;w>/֭\iWa4J.NS6FF QPNSt,^a)[Z^ey1 G 'b'}8o5jΣ̽]*>u*V!`!`BTj?:-ʼn0))|!`!`Er7. ǕO^y2_㏟r31zC "ش#R!`@v77y㍛͝o8Dw1vk$Vݷ"Tv.8)*>Vox> &V)AٵHójxϴY{pi[o^mTq6 C0 !`*Nɠ C0 C =LI[l!`%CTAo!`@z0 C0J8% 6 C0 0'=l!`!` SqJl!`!`*NzgC0 C( z+0 C0CT5Ά!`!P2L)V!`!`8ak C0 CdS2`C0 CHSq8!`@=W!`!P3 C0 $4 T^N3OxFKL ]I2Z{jOzfI[l!`%CTAo!`@z0 C0J8% 6 C0 0'=l!`!` SqJl!`!`*NzgC0 C( z+0 C0CT5Ά!`!P2L)V!`!`8ak C0 CdS2`C0 CHSq8!`@0d[!`!⤇q6 C0 !`*Nɠ C0 C =LI[l!`%CTAo!`@z4Lq}UW^gOj_Q|ڴi;,βGDO>-ZǏ?g/ CN ʿ:QբTvO?IEnijZ|_E!yXwsV%ƍ'o}d*mڑ 6|"CU`Bۨ*0ukyijnҤ <1* <8se=g}N;UڶQuoQӍ6j6a¢βv*x)lUȅϻᄏbŊ;jԨ)-.m½cǎW]uUZ{oo„ guV|?Ǚg:`[s +ET(,P 5Ѱִi2]55,nrM3n\xbƔ'Qa@o+&\%/LڋBߒoT5mT2dH(Rj-B!z%,gY8{\-ڷo8eʒ*Bn@̘,X֦k;G i-ܲ}SL8qb`rɒ%3gеkv۷W_}uBG"I͚D55jԳgN:M>_:*4=&xFqzwI1cF.{|x̅OGYgUq8N;-kMY-B!"|%X )u9 BwzR}nsnE.d*+_~y7f-JˈГqРAsgUHh ok裏?^JLx(ͅL6>ecW_}U?nE`kҥK%GE~a/ s=@?_r%rGQ69kFn^w#zTI1cƨHx.￿d n7zq ',ɇC0R-X@+}\<5c1i#D__\篽w0zjl{L^CiX>z*u+CxW^^Xo]!JKatMCU9̓êgs!x4ޣƕ'V B,F,o\W^yEs 7$gCb'%X닫.฿| :[dUCq]Y`g.p9$jw߽nHsD?,}Y#Fpa. 7L_"ݫnI i}%y5a+ʐoe#G',^#~mUڸ]WI.^O?믿~ر0f:t襗^J Cg}6x{xQ]b4 Gd& /cr̝;Zy[]p! | ؗ}7ZI^{5Vq,:0_eUOd@xOp % ӈ+'ko~Ġӥ{9٥:C.n†!C-onbFF!k+ZK e?q?LK"'$? J5RqW_-=$8gu,C cū2 1XF#C؝'S!Z:4~b 9=h^ķmkŁ *ݻĉ駛na?*WѼy[Z##^AJ3@ Cv⮁э%va ]H$yB̯NxʪRb0Exeݭ k~ ${*kZ=o?U@H{~&kJdžp׵pϐ{噆: $aQ4@TgpVV2F?ZJHLKŲGåm%st-\p|ғ#vZB0c^RCL r}q9#PGx֬YWdXvm7eK/IwC'RNʡ(* W4jԚ_l%UUUY&21A1,ȐD^Ӆ@ *d͈F⹳U}RA IDATy%Skn p/6-/(I?/aq@=AID? /Ռ+닄I'7y 1E3 Oz9xUq ݈')N*N-^Iۮ$qj ;dj;ׯȑٿ쳿YϚUa]8cV΍wo dڴ '~OrjADm]uG}d Ϋ: 3?c~K';.1ެ0bݤ:.>NGΝwq bvlQi0@.q~Ǡg-۬z7 /Ѯ5ȷ~[4~ㅊ^{S]wV3@vKP[ޤfw ZR<@PUI¶Nq=:+g.-EWQ95\mVS9#a澬SRJ?ʓ$SgU6>Guopq$Ks!u 0#<"EZG:Zj+@%0~x#11C2rOt=Ag\lʣ;] Ǖp]*\6|sL)ŹJ@E3bDd 'Qq x'ֳg{vq =${q$_7]tQ 5/\z.-[f){[EƵ-XbbS:ЈtJ}StoWoMqx͹VNcz8"D2"at#/2kѽ_☏UZS]qbvڟVJ1;sp@:+7WgN;턆*Y8b[أTs)ʓOGs`3^V &?c6䏰OiCEGbLjKHYt,x3nݡ땍N dz箻8>v5]gK U"l:vc5?_L0G>;ݺ5??!))f7ؠ)G?l_/ (ȑ sWwSTbE3&U.\c_s:,y+\YbSlueC}b\O X"`&O3bƒ܈Sj/`3 LZ'eeBǨ5iԨQgbawp CC8kA!\_67kdJ훵Ȉx3)xjS c/nƈBwDZ%b5 E+0?QJ< X8+3rK~ڳ[+'O-n߂fL3Jfuڶ8a~1S5.&!`!`(uZ aU|_f+(0 C0 Z@1n#=8*@+< T4g4ʅvFUt22C'71Mm>~Sf< \Rjw{fSP3ݾ#oa2ܖUIENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/table/virtualtable/000077500000000000000000000000001457770046000260745ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/table/virtualtable/README.md000066400000000000000000000000351457770046000273510ustar00rootroot00000000000000![Screenshot](screenshot.png)golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/table/virtualtable/main.go000066400000000000000000000016001457770046000273440ustar00rootroot00000000000000package main import ( "fmt" "math" "github.com/darkhz/tview" ) type TableData struct { tview.TableContentReadOnly } func (d *TableData) GetCell(row, column int) *tview.TableCell { letters := [...]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'A' + byte(row%26)} // log(math.MaxInt64) / log(26) ~= 14 start := len(letters) - 1 row /= 26 for row > 0 { start-- row-- letters[start] = 'A' + byte(row%26) row /= 26 } return tview.NewTableCell(fmt.Sprintf("[red]%s[green]%d", letters[start:], column)) } func (d *TableData) GetRowCount() int { return math.MaxInt64 } func (d *TableData) GetColumnCount() int { return math.MaxInt64 } func main() { data := &TableData{} table := tview.NewTable(). SetBorders(false). SetSelectable(true, true). SetContent(data) if err := tview.NewApplication().SetRoot(table, true).EnableMouse(true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/table/virtualtable/screenshot.png000066400000000000000000001772751457770046000310020ustar00rootroot00000000000000PNG  IHDR8 liCCPICC ProfileHWXS[H ҫZJ AņE+*ZYT^ *+bAQTބtWwo̙;s4{I.@8_$u"$ < 79)9_E/@C nH *S% \jR] M6lFrYh܇zf/ h|Eq OC}x^dK 8Ɵ1f ae^*Iro˕*F+539Jw3bbWW"G&)Qc QC.΍V32EjA9@H KPlNWB2lJ+PR 8*~LP1bQr ;rT6# A<^qD+ȔǫKdb["N &F*냝q⇹`WbV @66z0 4L;B NJPJCsq$7Ne[r#z =d xr>\J~X3?a%;N`&0Xv ;C?OWSQIKKgX`Zb'KKEY|& ~L< [|}e |Cƅow^?ngtkBse<@|KhfL%/AbA"HapKT0% ,kzl^pԃ&pp܃=C:b!ֈ# H#H:92!+V9@#m҉A>JEuQ,4 MD'Y.E+*tZ@/7v%ڃLc`惱X, Ĥl+ǪZ>kX;օ}ĉ8gNpGI8Ɨ]x~ ?»H#pc YB9a04KD"A%zýJ& .!n$#6ۈO=$ɐH Œ|R ii8*ԫf&V+V+WۭvLs>ٚG%ɍrEbK $R)s)Zi}[uuu u_1"" PlxLC}Klh4Z>m)v֫Aph5hTji\xIִdiN,,98BJˎqcppUo9QXNN5NίFXHb_]<]r]sqZVvݝ>ǽcmOhυ-_^^Vo,9K /_N9_)}nր@f`z nPU``~,{V6kUK4p{9 - m K [0"<+&;3bFDs$!2*rE- ǩt5kԩ(jTBQWc#Ul:8&nLg3&&%Nx,^]<%Y3y|ruД)cG5bQ(!#g\ظ5:{/siO4;$II )?scUܞ NƆn_V gd|*S$,vآّٛ?MݗwD#l:y6D>oʚ)(" kׅ?vGS=M7e̹3b:1es:"v͙ͥ[KwR57_4ɂ5%%Ғ[ n^/-j]x⯥ e.ee\f.m]lrr+VZpUWխf.]nͤ5=7mhXgnoTT`an TdsO[D[noZWeSU`۳se;lTwunjyM{ PTuc_~__y @Am8L?\ZMַ76uѿοl2o~VnvB]zޓOeO?wF{Vy MWGK˾?ա=u%o |'}J{ {w}xSʧ}S?>W|5~ W`C33xZ*txnSQ_OXy^/jag76" >1CM%Lw7%oM 5E߷v(Ϡ !3Ö@a/?|]?@fjdeXIfMM*JR(iZASCIIScreenshot pHYs%%IR$siTXtXML:com.adobe.xmp Screenshot 384 682 1 2 m#@IDATx xŹ543ZFZY6v 8 !$v~>5 Ĺ!a? !l@ؖ-˲lٲ$k}$NZV4:gsꭷrqac1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0a@5nI\ #4HSݽzmWoɜ촐H]j[NY$>>i:HΚS]&D4Ej(lZd~lL^ۃf&Tn撮ʽm EQ&^IU.y[gh|C+Pnw3xg'r2D+/){{2tَ} }@4*IVRNtzBW(G[Y~ɺ֫o"8pmdfD[5d2}TR#=T~72Շ_1q7՜VJ/V}.' r6'yۊ 7] ?6V ^,Su]5,wgNx%0qvX}pWo)`blwg@x)pkA KTt74$JXU^WOݟ[\`9䅖3zT >YT{Kj/8dDžq~?KnOߣ'N ޶l8ߗK$M~p_VsGIĄsIz)8FBb]sڡnL ~wF|*CB{*J%8r7LJ jQu(y"=šv3V@= x84-sFB|{1@5Ù-gi9yܬX?_a? n:/]~s5|\#,ܧ'K6lUǚ{xr' B:cd(/ o6~&}?|k;":PJ9xK/?^'˭~57' dYɭd4>yUX?}dkYR\.H~ O'Tޕ%""]}}?PN/]E&"]#bHg?'Ҹݝ>SssBqStzGgx9.MHM~Qzvj6JH?<{UmL u^ZxI][$ iH$氛.^Rl]zwf-3iBx#`+³@oM5눋&CঈW(ɟ̏pš¸^EjG%B3w&k/oB|F}_.D7$'+C:q{չcVDO8zjB&p`lEbOg)4 x%0|$ >%yR 'R2d0^{,sWk ]\ilqE J ^?[+=Zxede{馈r{ [B7^eqG vWǮёɪ:x{vx2]Zlr"pkħ=TO,$N?b U8PTDHYtfmc)x? 6A ^p3|Gh+M_Ig6™4~)Wwn\c2|4w&c5Z]W{+qײ}>V-A|hݞ+(WS5ĠTؼVvD%ީdhػfd߿߃:xrK\nyl7J~$.y[WTwZ;ٻ`U& 75g Iˠ7]^OۦRmKO V~_&ˢCeɓGOiA2\>\?QTI%цW}4 NyqZ.T2O!%0 uKuZ hd0Qqg~;4 [DԿݚMrN?KZ4Tv7R;-:Bϕ:o|#^//h7Uq+WQo%)^7ƩՎtK@Uax3d'zP+ic0`*x&$t"^Fe6ju;ce%%^+' [> ;TF³F&}C "Ѱ>Z,DLš]x`d4=z7*AhҏiSPIZZx3 /Y` X[j/s"+5.Gny!垰.ߚ- t准SMTBQf؅O B, =* G@v3wVCf~j[ CԼ@QqEo `̅~y?N"lfq5^TZ3$7zTJ|{9_H:kIX!^PVS+.NNi8n*x#4vZ:kt䩒}$;Gc%y%ͼŦfϙAN-LɁ>#VPoۙ5@ضR'mh:i:^IWĔ%S]뜱dk\Pgvw(.G1|vȭ`X:E7-bǬ'xz8ݴ0xwX,s˦2x-3iN쩥 BC {^;[HMgyya;BVgaq_mmk 4sofc%B&tN??B+z@o_ފ%H~- N IH;^Rlk4G:ii$29-f B%&)C 񫰫jN4H>iU{w;.ީikqgtV듫.57u7+>B>IVeme݇,Y%rW(uuuY?Zh&bAB8(RMh!6נPx?h)zN=ū?gmC/׽=$h9UNRN?xڜ)=;ΫrC:²\ /]ugW-Єfȹ ^_y9;V-=okfn$~Q(-Torg;%80ԋUw;-+׊3+ܓyiŪyQ$Z]ϢF!V<)q1˟Mgt/W/9GIn6~@7Q<84 4c+PYj\!xebK& h9VL79Ʈ>ݙktJABjJ޻!<־ݐ|k$je+/KX:2T(VMg{-eƍ6Op6i biv-xlrg#Uq}ϭYۍ3_yݵLSk+{$lC1:|;cp~s o}xCgZa:J5C!x3tx[BjzL WlB6 kˋG,Wwu_ii+in=SwcoyS^_<[`@/O#+[;N_{sQaqxTD{€wO}nڔPŽ͆% FO/,xܟ$kf(?9c2]qd>,ɿBr >B{F\ҕR@l /[ ;8fDFsz{ņ/J(%ʭVi@b`**<-+oa7^k6t^7t~enth0@*0a pz\4>!I_9`ܤw*L^mjio OOL '::90|z9뛆L_7kEc 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0ƀȟ',=w`FwO]w8ҽ8' Twvn4MxOGGUosqg֮ͩK8RKjKC\Td8NxG8J=8hO`Nj)Y{ۦ~t2J*FuGo0R+ Vx=wv" '.sqDe%H݃]gQeZ&Ui\nO^wL4B9=bW L4^?~к^s:ɦ;͈L#>*)}d1?˶O|o8PG5PoxҪ? 8tWD8oRcnu+v8] )&n˺CWo)`blwg@x)pkA KTt75pcs4?V~ -g( /G|V=r8J?;bcYdb/^IlK)qtঌV[) .ۖLK^IBC]4ɃHBC37|@yEy0&y}$SoH3 I8R^q4h#Ek?dK۵C-\?|nhJZ?Mhw×z0S)Hpcrj|FGeǑm8<*7[S\8ԍE'w V ;Q>١Y!xM=f 5|(:P^$ PMfs%7+2!㉚:W׽u?D[*}Zz72_6r~(/uؘUk*[˝\'\ ?(i8W순@I*,pxG.rj|F t˟,7fO$h8UaH%ffJkr< +G&lW?{)ֲRD_ko.酷$Yⵗ1]줉Hg?'Ҹݝ>s|dĐѐ$C/ZώY 8ƿA)^tγ~[V` P'iuYŽEAh%֥g}g܂a8&W;8?)<&ċ/Xh9 nx2؛ y 'Qb:절sQRl]p⎽x'%־Q$5q|/nĈ8o>+RPP-"8c+"${:M/ŏ,T+sD'9)q:^ < }!߫EgEZ_^[h@? :(Nd͇^V2՝FxwZ7_wiApe\ܖipҧ"srzQ:nExCL>[_Iё$`۪^T+%3%t?ꝳ1eiv^tJ˪mרvpw'$xRvC9(Xn$֭rN?KZ4TΔ 0`~Ro$/-_Sooo;ͼ-̒s7'm7vX&JtKv'Vi ФN&`*~oХlO$T[xU8bC@1 mӉghGO2voCIs뮓gVMҝc-0 $ɲKIJ<(C/^'XD1ͺpJ+&zAо/o8QZx3 /Y`KԴkJpK:[^v>z' fOч ^7舵|_xU՗-x5xtb":TJ2+m\GK<^(sB6~Jx`l9]l>,J?ޟQvJ9M|1ͽ},Kǀm,Tuc O7J*T+P!xhv(`cE8Q8U >qEQBǞD&98Z|3Ʋ[9xIVa+ ˝PpՎY8z}zdXo^$?N j"sz! f_X>?v🩻Rk`xZqVEYW Qz?s#(_<v=\%jSB6 ^,Mʩ_X2>؅?I" &`KՓKrC\3٫;K'¹%О7tT1 xxKV>?vohpnaC/kr=-e L;\:i8{t0PmJGR|xuaMbM8hɨ_935? uuN8/-F㯳|c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1𿏁xrɂ {otuw)^meg M\vz-}4u>Uŝ5Z. XyKjKC\Td8Nxw|2zoSZJp|V޶LRmQ EJBU&E$❝ɧ\=&Mx R`YFeni$7Xixq8ݟ[\q -g( /\|V=!/8+R͈ JPvY_iQxd6 {!2}=}%c ^mfƦ!|(onv( ؅]ix7|w0 soˀiЄ[:auHg qV^r{'<Ə C@gMqlQ ^@״QV \K_LRZ?gߌ١ߨz}_HDV4**;Lť.+ /pyĸRFU{qukR v] #!8^?Wq?69(`KN/|b퇏 G%jo|-}ӆ[$ٙ/9/,~cjtP<>GIĄsIz)8FBb]sڡndL O1T +.-yLkoO'$4>yUX?}dk٪vT(ɥ䧯 ]tB/"RD_ko6rm^]ƍl#q94_G43,>.)Xwh|B3}HM~Qzv8A)^Aǝga8ynZxGh%7Z 4֥g}gG֛Eڑ~ 70R`#.,rq"^ #&2?h8aMa\Hb"^EIi5ޣtc46nOF}_.|TnGs^-<0ݘt$2^Z≥2q(VSYge"^.~le%&]aIqAxH%Ob`jyYFWM3t—8<λhUiU!ËVw=gk|eZqDqTgJ;fN<)?+%V!x%qؘg-cX飃I^.tqrE`8=FO=7K(#^; PNj!kPgqD\[QPtfmc)x?Fv^A0(f̌1sWM_uXd4DiVLj&AvĮQkYYI>Ŀl >VnO^-?NUb4RAʉ ;O>W Zx5QWV\G-x"U .% Zߪ{(ITJ Xů {KJ2G;svS^,Cu-ю ladX˯yվM׀TI X A=Z,ḐPi.^Nb2uX=~WL}^4GߴT$--?ZW,Q,ni-׀ >*SQyr^ 낯ٲSM;:b-W*2o@.0ZSDg ^I1Byx%lc$UG*>n'V.^(xq=g]VNnrP@/di9oKf؅OnW8w ^= .xbC/q^s/T AAe/v\gI׆S^åH3^F*e3`UB,xBä?y0`q [2kZ7޶`c8@v3wViࠎwWtl.xo QaG9?'Xw38xbOs E ʉ ^+`&}5(Eog ypԪdDM:; gX7BqOu`S%Z!H#ew*J͉3Jye%h>ŏ2-f9MG|vfiO;m+}Ba,N3?J'ٰ$t귴k3Zx c \(k_;^1!O[%N嘛T 0%Xpnci~j邬Pnk#6vPdNvv!軙ThU""\٤o->X> -]EJ'#F y ފ%H~- N iB]H͑NqZ u<@YIE Y'^̋Kɭ+4_m]A wTs?F!&^'?|" q@}uL[;=]\v|~tFVX03>[>9/ ab3'Y0!¹Xe%s(Rj98Q988x[ (R + [2Q^E.GbϹ6v5ZaӥΦS2USލ ,@[#I|T+X9x P}:2T(VMg{-eƍ6O|csOGw a _,[vEǒ֬鯼 ]ڀ[oz1tɁ!p}ZZuK>w(!//{D'R]043P-C!x3tx[BKw*l4xC4^pmcNŪ'@`>K!xǞD&9p΄cً 9?n%?ㄥNg*/wBU;f0RtdjgVlay:)Oɋ_ 99|xyauHe+-m%ͭgn-pC#{V?{Kg OKSg\9*~u`^0C97amÅ[6%Tqoj߸%S9 K0'IĚ3GpjXLrC\3٫;K'¹%О7tT1 xxKV>?օf&45u M;~p. 7|xTE)Tnp{{,J L[)X(zd~S|IGKQ&L 8 FׯE2nMxl|4ږoV{ pӨ}| Do2I_77 aĸ?NeVha ƼN%P^ydp24 9\T_yAYvU帑~PV_Ӏ:Fq/Z2b{hVFXntWL q#_/͉qpzz@pCJ-IG+KA_ /߯Mc֞Y{fDXF7L7_z?i-$k7Ëco݆Ņg홵gq{wwok϶חk³r9xqBkߺK 3kϒ&o}=[W+*)}dAu‹8*9rG58 U[B͉q$rܘvy*c؈ZxO]5,wgNx%0qvX}pWo)`blwg@x)yR ^4|nSnjmÍW:|̱zZ傍O^h9GixI⓵LU~VwDz^~+mSMܽ[S̷ *˲gSl2/"T$l=T/ܑ%Bns?@ /eG~soK?N&|cֿdB NVgg/EʋŖ(Erk$M~p_VsGIĄsIz)8FBb]sڡnL ~rܬX?_ܻNwzOƻABr@{M%"_W~\fASc̓Ce{ _(I₥V^?ěnrƬVz G*^>,LX)xM.]$?}`Ȅu_Hv@t oWI>,_{IN/ts+HN9iu$ڂ!>FPn:ֳcV00oFP#V28InZxGh%7vqo2tB!i8nxIu)Yߙ ++TKjo>nTZVw{`2l_~ӁVnO^ѩ׿}J{b ߮t-IlkKnvw|ծ9 ߭Y+cýzM*(@.y[I/3S Vi.^D ^rP4x}5,\-~lg /:-Z?R\b ~6\n*x=F0]V$ :o{ Ecx- _ꅞz,#C~›\?Q?SBg 9SVhL_jET.kv*`{yJ0o/hK o4>$$ng~;4 SXFÏrM13ôB> ;|y Ɨ2N3o$ 5GۍVR :tG<4wD{a40?.vFS+ _t)~IuKJ2G[,ٹch1FM.$x}ݿvd` $/llN2Z`H򳯕ɲKIJ0(C/^'XD1ͺpJ+&zAо/o8QZx3 /Y`KԴkJpK:[^v>z' fOч ^7舵|_xU՗-x5xtb":TJ2+m\GK<^(sB6~Jx`l9]l>,{JFr;L%"ʮ^0rs-V^3}Ҿ1`X>827]EJ'#F P[qOe9ĩ!4dn塅<͑NqZ ub^E^q_ X>%2IӜ1߼!+/qR3Vr;tkp):2 U3m+6Ȱa ޼H~ E/> kˋt8:WԹ|?ccߏ|O NOK[wg\t0#4Tg_v5y$gV_`v=\{ +? 8PN’.aڿnpdxnW*^}Y>Y֞jgt?Bh&^@?8 ][qIn6|xtG0OƀRB)taޕw9᠔9*Ū_I{*Z2b{L xi9 B` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c` pg3[^O.Y:za=ek- >"%%Df Vwt-m}!ᓦI^m.9uqI.Q}g, qQ +>jg[x Kx{pLDMR\UmGg*T.y[gh|C+Pnw3xg'r2D+/){{2p5j㺾l_Ck~$+ Jp{"S/=zdI u_:/0Yz|]Bq㿍lcٌh˼LJJgpkG8(,gs78АJ!a:Ə (v8] )&n˺/ -ŖlQ ^l=en-HxIq×<Vy1J9V^y*l|B=JK*Uf%M/8GIĄsIz)8FBb]sڡnL ~bqDyƔX`P6_8R^q E ϿwդO1}WbG@JR)`i>rW4[d1k}"F' WGl-14V ^KO_9<2ai׬~#/ҵ7Uf`,KantG:9BQoemxcs_J/Z/TZ;=0هaćުW ~z<~O |yJRpgß0K "V*fIoD+I A|e5XT`"둩 :hwLApSok(S5l:TVw["ͲTCs uIJ-K$~86mgCضRF ΋F4C*+ݤh! KB~K 9cJ0?&0@ @Q]b[8tnZxŎYOlBxdtʛUaf -)^`LӜ4SKdr[.Yc^?Μim? = 7IZ}} I鿥w\d{Y~aZx+6|T# ,85QkZ4~ZxIqAPXǓ8ZxFA+zHB|6&E E*Q͉fsɇ8,nZx՞]"+@^U$+x{3*;y1\vExd :qIP>wgTV f_%cʺ=zYJa/"ZuuY?Yk`éwDbip*m.F{ɩ0p5,xA_oK](8B6yUαu s_ȧXBrxδ&@a`Jq$L~ݙɥIVj4ӽQPTѩvsVFZNx(_hlBkfܚZŞM?#V0wJp`R8vZX 綵O-]XPP>9 Sum0 L ?&$\jO}SP9wQ^tߌFnv1B,`%Y4atßslѝkxyaӥΦS2USލ ,@[#I|T+X9x 0B1_ % l}e̸߆ &D&Gw a _,[yU\7z_fskVvcWބ{wm-f7~AmIXpֽGu d/?!>m]Z!R T }?"LYwQޡ>O7J*+P!xhv(`cE8Q8U G"O!xc\"d->cً닉ypq+錕\N(Zj,F >~BጃCۊM=\a ޼5@?&/_|hpN/S"]WZJ[[^)d'8>|MЍ<Mcյ82EA{b`x-iqv⬰ݛ6Gůã"(ga;'ھ sCmJfC}A{Ւ?mc$X39/U;qd>,ɿBr >B{F\ҕR@l /[CpOg[ohN64]o¹/8Ӟ43:F} IH67!6q։!׉WlǷ q8a1 !BBGGmjH#L7~晩+o}]g燗%O ZMR@@GcWՖ6K@_?exmA7OlV]얡`X:HpX2Ua.Q~Ӡw#t~nbng!:!@>Wa7r<c1` 0c1` 0c1` 0c1` 0c1P2[+-J*?^1` L|OD1` 03ĿU1` 03Ŀc1pWx1c@~SV"c1` 0 o V=c1` >`nZ]}5{JVwHjyLI䨧?vBÈ[iք#[+ ڪN4_r>E'faJk)H~qǧ=BF//ǺuL"ēS~J"G=}'I'O| RSS͛w7ϟ?_GwttgΜs{<۾b8j7UXgZdkXx?XX?YwGe%H݂\ѲW%ra"Jë֪mI^+}󌕪4B=ݧ- li*0k=.d/`^nA[DY->*,#} :1nls]$.ލcU+vX^yYbH*v]9mT ^j0|CYfvssg}ߵlwUV>dsuu}]_իW%)))%?źeqw[ʌ7Xfxx5 :an-IxIu<ꪑ*Y>Sn6J⡾ k 6>z);;=JK/Cl[S:.Us*(&2}KK` i);XXi=UQ-ږ"~󠹻߸ /$ǯ=8_tk BTZxGs۫W6Ӄ 5Mdd$(s``?>+."]\\&._sٳGN;/HZf3}@9N ͼǪ⵹]5_ r6q8ʾw|ෂN ?||___ss/#OǯM ^Wt ҽM/g>`;-*x%u畈>OKuJ /9 bwP 7wW`Uf~B gɋw1`{ y`m%O71T⫆e;A8fS䧤pwezÇc?Đ ?p=tb8 BN6n8%Si_~]zJ7/,>Z=OX7|LAtSjv^!KyI@XV*xC?ve^:VZn҇P9(ܑ ޶*~ as߰~jbWEu'X0 }c8]kўsɀ:Bm LIv&J^;eܝcOx8};ka1O  g%j1-BM qdk ;i`;]bNΟg c/-H_Ĥ&l ($!y _5jX!;jݜػCQHA*e_=rYUBGH90nXtϼ;K*_+d8쌙\ze[c:2H}|/ac"xs">tbNOxkاjb9ᡶ\1Ye{kͅMjj Cb?66na?l;:o޼|xvb?& bq+1U^A@^8M M-g_LְBd|~H!n 2:KW^Mk1gi;YެYx! s_(뭓m\s c>l[&ojrެo}]g燗%&KnN'UI\A@[Nٳװ8ɾ0BvІź;z;^Ua.Q~ӠwC>t|+{h=^ZMR@:^sAi>nUY1p\((ckR`0c&)d 0ƀ&l0c1` 0)`Hc1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1P(tܴ zj;:k::\nﰄM7z봈?^Urn8üfg!׿q>qӴIk]mU'/J8uQE.YRZ>jj׉bP&^Ouº zZa;*֙+i(*gs[c3T-ITx?X@?YH2V^i2ZL+24Wmj,Wה-`˹𪵪y[#Xg=XJ+}kܲIΆùڃB.m+D/LڶlGſoDCC2$\$TrzqKw#Іf}o+v%!<6&zȾ2 _xG̕enx8; F8vih-]-5+@L!ЄU8m)3 ċ] Xˀڥlo#+/PTW ] /.|T}mAm*)UcTTa%+kٶt'/Cz>quxqz͹ˢp[ZgJm^uwhF-t`bɪ5ERo4w7eb$ǯ=q\0m AZy#iᵃY ٰ!oփ "h5/@YJ WR z%i7"^tg2(EndCu4ɿ/][hӵ~G؞Id?$W[E@["0t*;=.^[K}/꙼7eOMFܨGr !!ig +UZ}*:5OY)]C!x>Zà_̪ߪ ?WU>W\%[pE~Zo~Z޹ 85[jWռ.ۋ+|wmQn-udt(==j%7ƅfLUtR(/j5ϟ(uګ|@Ԅ[ƾ5^j.p¡vc ʛ*ѹ$1uG3;(J9xvw_^#WX9xHtˏ,7zw7Yo"apBL#aT_|}ACj7<#]] thoU޲(,ԾB[BX<鯴wN+۸øЯN0A?3=igP|D ĩN k?0@ /@;/V~p_$fw.^Rm}fcvBxuC:S Ưտ>B_GH=@!LP!0ec"Q ƅv(XT[5AΘܑ @mK B)OvI.3DG"aH)NEߊ( đS h6# tJ iq@}J~S GR`oA,KW[ \m K@IDAT`Ximo KLbhU'7Q早s~G^q0iɞ:')5ӓE %qkVY&w2I@^(s"X}FX(ڱp|  %XN? S8w4L+P8]iDNᖱ}t^w+E-?j^` JG3 ^dׯ.: @ou9Fex%$y}2̂[ނ[%iM{` ׼<SFfs[cUxyZqqsβ.M /^#[} ].;]%I@c⌮4yN(IզmppfRg«.~Z,]'m%{T`1zů^eU7c-g8t*v 03a :˩T#xW"˸8k)-0s3C0R3}ճYx)YY{zú "V|P Hi+dC/ ZΙDTUSP_FȀ*~P(6jx ^q]jXw IS7؅j_8ُqc׵B 3GcTv6Y~cB Ya㰱REk; X!^zTU'۞prv@}IKDHlwW@-e$OK28xJ 9}蠅J0>&p@ oa@UbPS80-jG/#aP37(wyΫX`F -))j,vhģ9n)--mچWN M@z˓ۀT]YIdSq %1tN>?B-z 9(0-e ?|_>쏂OgL?c_!>vK#7TM~i5xu)A%HƋi^˜G? k$ռy'O ~j`MSHW }˶:撎C^9I+0uu?` FpʭOO@!xKw^F>չg1U㡋 _1gЁ4Y@ `rNS+ SE cnءh+oG/iP:B3\Mo) _0piCy5BVhںlawkiϬ\* Wdq'wQ^FM׾1@\r8J TW^YL[4r3kȾz& NȠ(V^4Mk#+}Ջ I7GV+Zr\SM'ׁ} Jt'{EO6c|I#wOok`"xhO3Q)_+t}ԗ^SW|pp|V\y0ﭿ[h-p = m2j5j@!x'4G Bw*

6GjR;cG.CaiO]$d-} HR~:1mH! {z`S͉Љ~:mN?Y}zArCm566[Z.WgXnE98tm֯ͫg6TQujb36F-ã!ZJP~(BP־߾#{ /{Ș&j4ζ}R27j ''D #?8BҕW"^yY^Y?˛u< 3ca{ euMNarl‡xzz<_pVMU Ֆ_Λ᭯ҰI & Dx_jl*nj 4=&J}tfr*k_;H~ ,c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1g`-]07-dxî޾ڎΚ=%W;$,tD"O/IDq],x#@{6iM;½DS^qiE'faJk)H~|rL.uASjWvlU3W0j7UXgZjө2*ٱDe@KL+24Ye[K5vD╆WUےhoW+UixzOq[27 ITa8R{]`_&݂\5 .,[}TXG:2O~H2/yz8 ~/.ލcÓWj!yYbp`7ߕ_:@3A/Cw)]{%W ͸;2M#zɖ(/vwc[uo%Z-/x,U"}gXix]5FE<`ΖDŽ̻ q??%#,.*S7"g +UZ}*:5OY)]C!x>Zà_̪ߪƍ?WU>W\%[pE~Zo~Z޹Qtvd*U5os+>b _r[Է[K wǼB@ƸL€BEͣN{uׁ.12ĨTf%L䪉3Guln1N6}b^u);cp/JHxFhHSG`Y\ 9L/~jyr7'qMsWq~HOM舺Um/k8`^6' k?r;J"SwX-o1;>W\iw1rW͏4zOY9xWyGp3Y-f G:l.44V AU^X44`+}s7ҕݵ@6=HEa9"vRH[Һޑ:UZSY '_'{j]7a>: L?#0yD7H'>&2M yZxGh%hEʛ KKOL~ ‚n8^HnHu;?.< Ưտ>B_G\5Y0EB~d|oB6Gb,Jj֠ gLnmƮ_"7[+CU #Q@U-&~Kd&hA=Ct$ CJq*VDI tv"^@YWNsS:^( 7uLB*x-!$ 'ӂYebT~J^t3a9?x| #TrE9c6a Uژ~vUbj?7kи Cw?9wrQ^$RLmCjãA /sAbo$\«ᇼƺ7ˎ|j+I7ƻ $uv ^ݐ""0+U`X3$'zP+i 8[;t)c{JZ6 [u;ގm׾f ulduWQ)9% },@Y\`֏IWJdY%"} ;iŋ<}Yn5FGtSd Zxީ.y.ZxKAޗ3| U{ZϿXy_ͭU7^C(2拯mf NeDMXU}YMi1-geWc!yz6+xGBVQc:=k]#9V6_Dz\+Ƭ |cȊ>v*dC/ dwS$VMΞå[K;NmlsX|mі4'W 9Y⿴Ur399X74Fnos-'^8jIwWh_,>0DgTf͎ ,:o$ݝtT\~MQsIo[? oX? mUr'A}F ^qMu'X0 }c8]Sko_j#^_SYVAm3Y7&Đ6b$,Lo9Q+ɶ3\ܫPG/Fd2#d~4nKo2'aI㧴ӗZx c \X(9S +vR?7 |5L oP W` [f+qw$l{>pnF󲯜<8R^݀#7mJT<7?o*8P?%CC/ii:t7אD4o?L ozKOA|[^c_@l9c_w_7/FRokPvDW.Z!HƋܲ1yZx(i4|Ww/(H4˛ʂ2.^[5gjb;ɜ$ϧEWm~W (bj:yu܋be[y\qKY"'){-k2j uu?`6|pʭuX&Iok/H>'x88l> zZ.[wQgV. _y~חI;E\Lz䠀OV=))H8UTd~C $KJ8ےy4n% ]VIG!x!R6]Ll|7]W"Bʂe"(/ܢa#fp0ckugJFb[  )|6ym {z1!jU22V^k:ϕAI·B6@b艴fO7i@:Bm LIv&J^;eܝcOx8Azꊷv0c.ϊK6=dWp:o qd+sԀBN? =h4t=| 34T^ W?x|l( vDDz B>u rx7ge/sr K' 1!)е Ҁlw:pƪw>ƺ 0m6J+ۤ;}*ŬoIkm%ʹxm;/d/9#%hm^ u`v"|c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c17肹i!;vvttt)Z!߬y>ֿ?vBWzh5W[ڶ>&{6iM;½DS^qiE'faJk)H~|rL.uASjWvlU3W0j7UXgZjө2*ٱDe6iKL+24Ye[K5vD╆WUےhoW+UixzOq[27 ITa8R{]`_&݂\5|s"DYm HgpCxyIG]EDc6SϕcۦMU=eb.ލ84C)'+]hy` ~^$L%W ^dlp vF*p[>ZkW2\/NxB  qRfW9$}KFV ^0l~c~5S]~>r9V^t֣Y8xWQ5,5I㆕Te5 55瞯/m;.{V2ض whB+ZN7/EEc-ُpE[QkT&2M@M -S$>Ld`4I0]d ,(3?uƭ\(_/}X,zqB"^B` ?2>D^7Rq!#x1%5z k3&wFzc_/L%Ap=79d@FA=0O.lP-6qa0Vd-^N|}r9 qn~:WwiAi\sҫ"^8=y]]֟oerG F+cpe axI-[遡Hn%,҂ZMk]}tfx#A:+< ;MQx'xtu L)W7md8l)No=S8ٳkn#N #FƼ 4~r÷ґ-奂7Yk#˟Nl&eou9Fex%$y}2̂[ނ[%iM{` ׼<SFfs[cUQ]}瑱u?waR3wQa77:]sBǬ*gSI-U1coWN ?tx;w&b3q'U{_ϚzUZ䦴˜׳ɲƫ걐LSڢ-iNs5*^ ?Y⿴U LHxz0ׅ?Q͍OC&q@M'KDε|LJ=L$CX*}5a?*8ͺ7` ,:o$ݝtTZi8IBَͯ$*x۪_}aԿ7r؁kKW:Xw IS7؅j_j#^_SYⵛX?fnL!7+l6Vj2+0ɸb.CudZTN2?JZ[POF$,7-n:eƣ^+:õ-V9CCNTôԏ:2$g1L oP W` @[&#RRXxшGsR[87#[ڈyWNck=g \pt-Z2 \8c2o*8P?V."^]!'xz`}GU˲؇Ql9^rk8S:ni$)/-`u.%x7 JE B2Q7q6Y´j<E ^z_k}|NTqO& [ms=W$PkDo@{-K:=xI2K$eVN2?f$r))rHq Htk$ ^{ Sl=xFu~+r܅m+TG 9}7ކz.ڊQK ?WHkZ^Ko) _0瓦 Iל֎ X?;k벅~ܭ5.wg=rif(be|󫗯N'uG".&fPWrP@=qѓR柤q*S%O {`ym$|kc"xhO3qeSi;V.ԩ/[o_xoD1Sr#~V\yԭD5o ̧k[j05@1/X ;i(oЭ?J*+P!xh(o_9:TU _=r sL}"`'kn^KKP.G錙\v(ݜltlF AЎ2L|Lo;~:mN?bެ0EPP?l|TMr8@<2R#rS@+ą(! Nm_{c~ȸ塂sx4DKʀ\ww}eoٔ]&ٖ/VJ&F#Ӿd|~Hps^䝥Ol vd<,ͿBrͺ?=޺3Vpq/^M njɫkyƹKf egz ݝ0 ӢV/f}uNZ NIFR|mMR-I;y=\Sss=\^)\;`6%Fh_GuQxkZ$ =ߥE]Yw LFOǕOȹ?.<{xKcqRVq6Jk?6W^sdcે<~.`h*oE :n׊[>WX-}:#@GM-$yl:U ^pשDEkywncyU īvU-}[Bᛆu͕mAcUu@5rJ$Hwҧ%kgV^-;1j{u=WA}ZDw(ODjʾ-?@VU~ۯգEHǑͅuD)Rc, J%-F\mJRo+k[P/[Z@, ˉ㵏"v"H[Һޑ:U C}?1=,C3cM~tzlf~uH'>&2M $9/@ B-#DZy~i?^A,F-b_QQIo ^{*uuA\Ȩax-3e1zD^7RqvPċ(kx_L8cr ^;%zc_/;LrWQI^=tws[K[Z?.,$'$Ђz*PRSѷ"JqMB]>H(%R ޥ4pJY@Y)"^o-kw pM\b= m|Y7J-j:8֜lF87LSLX ps=8J9M o.RPT_ ןou+b:Ѯ'6*ZyPɳ.u0\+3i(ƩPr  qSg?ʯN? R 1+[3b8l)No=Se,g_+wGy刢WPG \sޘng6ȁl2MֺqAH73־6s3Y2W<NjWځX*x-p݊ I%FXqYfv$ފ-MEVYL31XV#\kJYW ׸]_'.pyձJnRW[>T4t6ޯ*gSTeݫbƻm ;)ŋDwK~hu~s]iP듪M/gͶ=榅WGx]œSybc!+u̪[a$BWI7@%5e7iM # V3oܞ2?x| #T2,۹~g}BJ\S 0/xzIKUG9xɓK1 O-!;׿pA և,;O$7'ّS*xuC:ܗW)`A4A*nk$Rī֪Êm cNGIkl~z:O2G|͘.埏[2Ǔl_)1U98new'xD)jJ=z.z44-F5Bީ.y.ZxKAޗ3| U{ZϿXy~:~5X ^W{I/fطMl~P+A< +e\GJܔ^szvh&gXFv ;xm*1eq~~$g{Oϵ.i7gE\H^l3nɘ5o,⫆={3(dC/ ڢ-iNse!=YcE)&?p$ [{g6,;r2b)P;P+5J}"g3*x#X'x88l> z08B7V$gߎ:^^PufʯGTr9]5*|u([O6$_sJںlawk Ϭ\/X[w*Lo{%xSqѓ\Gop_I}Lt#·$=wKJ'+%1% x3\V9 a4~b Qhߵo&W:`9}CPw%a*K+,X&RB-V9Bχӵod_=X^Ӎ;V6b NȠ(V^4Mk#+}Ջ I7 ?edi\_624!WކӝH=Vی &H=]?B^bEs2N;wXS:l޿}-N5G'ニ{F5=u@.0'g(ƐO.HGF=|IVIG!xn}QP5]y +@sv@!x<ѡĎbP;~(oK(δ-}Z%ƀ sv)ި[S_xEóS6#P( \bջ2-F)sB*ŬEk*Z2b{J sm<ox"Yc1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1O7㑥KCv0]յbmg$-!$ß֭ F仅%_US}ScU=ME5Z:ya*jܫBTju}~[G2lX#ksexooTk%>VT&^IŨ=T9}uzKKTNNe*GIS&^#X3 gmh.Srw*f4jl*sI7[Yy{Hhguy/8ܗ+y]vibHSvݲGrOc静l&10v=/~NA[{[jzqtr+e Ļ^Zx!mM=}9 ^d&JSD]1卡^iU G*TX-Nރ.^X&:]OJgv3"L>*'aS٩I:sGp^?$r:w>|t^ڴ`Dbo-nj##נGtZ*4٫W@wosKQhD aϿ_v%}fV"Eq ͹/6"{lKcqҥ#l~4M1+B.h8ܹνojlG :vsTz{+yHFIN+Bt}$PWv㎼w$ÎWJxZJrCaΔi:+pdkQUn4VUƲ&ɟ_'ӃjJË\3+j17F߻Jo(u?o67ͭ}x\fuxb9Qg(-'w';]xcO2Ì8͙kn%-}Njhǰe8N WM=e_=tB:cd(/ ogy]=k ;"K{~xO3< (+:Ҿd|#׏fLm.q#&J)xγ?s@p?)Ov8*UDEť6K:-x%ʢ!^'bCuq+V{KZ8_ 9?O_]Y;3HO3cM~SrjlV~0+C u||өj͵i ]~da^RN-v:(Mgs8L/)1Y7GsÙBx ۉag7n =a :r9l ɤax'gΚb􀉼o&fp>"^EI>cs`B;6:F}Sx}/_U;x_&io7p d!4/ț #9xC7JQ/ac $y/kA$Ϥ 8tev'-T 6~(ѭ oTk_]"PfIy}\漢/c⮂o7n/xv~:ZnQZwIwlS ^ICy%"Vi c_'a2wB{$8yj7k326 }-LOΡ N4Y"IU_7V_5if7G*;Ƿ]<}rI8BuCL^ 57u#Muȏ+ ~~ST#~59|1LDBPiϒZ_Nbꎵz ^?Jl9E,d]54KwiJ?.mFRI A^!$)!@Wt,7A⊃ ެc `Ío/r-Dᵅ ' ^7飨36y5/Wca_$69isR+.u$1\7b\b_Z5d=hIȺVx*%ڬiE}3YW%(iXm3z[KŃ"3un:^I%UG`4,Iu^k21B ra|LR]ځ~Ӑ !`qaZxŎ^@pd GP*X,I¾e2"%}GZ`^ϧ01kҮ[J$1~~(>-0NzuȾ&Aha'T/iʃ8ęiôa_O/FRoۛ!쿈m+*E:T-W"vۦqq6Y´E ^gdnţg*qF,&X싵dulkYׁJf[D렎PǛyoT{7 Qa?rcih!}:6-5ɻtp\3&^K/+&-ł_+oN XKn#~aѡ 8/gߎ:^B>Ta|I [w%Zne#|u(~5_>4_wB@ ~zOѾqgnae{azjVx(4pqsKN}7$iع!y}By[ټqɍ:SOeO'(c8 au? 1/QXM[/tr8o%a*K+,Xfr[4~`tj֝kyc2(USޥ L@xGx%22V^笀%f7'C'9 <' @(XND}Wb 4eypeub/6fn]&8GE (PN%_/?h{Ͼ'fSB4YLm/VK&)r}[ *ͿBr_// TyrGEl˩׮&|؎͂z5u|Q}xtݰc@ x="#40m6J3V/f3 .Z ='PВQsWJl쵛@EWD2c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0c1` 0cno#K`?pkwήoJM)5qb8>8aT}Xog{UOSQGͱ~IqUjWdNxgY([C$ߠxZn.Y_:u2JF\CRZj>wtb6ھxTx=kOd?$WGUP)fQ?ow; I7_ ؘ%#^zcv|\R* gݷ8~+'/^>)7DIFqP^q0h i~·ja`2'!4Cs|1;Q|B0z{KJVk(ޗiWveN;F9xZ囓5ZuCagJ+boMVPE!x}ûJ%7ņ$ Xjx(:P^|DY۳3mØ≄K8-˃Klp\5i?:mˉ:tq{3onau?kaF;v440~Kk7=ه/j9O [^:Fy4 cMa{?uQW@!xG֮B̖796$?l/R#"W\Mw1rWj:Pr^du7X~tH,}\)xγ=4vIjʱSU"r _\_UVA @ اh>NjoIK\`@gFqӁ B`iѬdo%u:>?TZ48EaZxGh%~ci' &A/cL\0RkEqkxkO%'GY@ǘȫvC@ߌ>cChA0!΄L ϒkcnHJ pWoc$'ޡ\ )Io΁x.~da.^ t#r8!OI@_x0\p ]-CWˋn(5BA l—a8 4Zxu& Wwb=~+.&Ӹ8-]O7EӼqz QPT1+xֆvY&w2I`x%Nu:s*$,C[tP?]I\&S-§=uWo0Uy(n:^tY)^0 DNvz?[ƒ|ol 1.:hկ}12g5~'  ^dƃ !o~DfD}|O>nTN,D__GY 1V}іsV ׿*N5r;?3}u:&:O<]$ʗ˴ >&Ѩr pTop~_u ?tjԷ~dW<G4ioppqbl6.`G\  c9O L;D?ã2?x%3UTN,Uzn +0!aWRkU|J >g:h=̹3T2 ޙ?n_9f=J[xdVxؽߝz+BIs ޭ*㕃=(/i SHh#B? ?hG-u]F-z?^h}\o%)^8mS*x :/_([x1KtѬ:U$lI*)EjzxhLMVX."%w][k?Ej5+5# -/d5Ȥ\`ֿƑS.eȤ7R!x]x:4l )ިg/g7Jތ#fs 3TVJ<8-{1֞S QWj,n壷Gܵ4NP5XN=[EwU4e,V?LOX1;nTJ+94`=OKuJ /9y~xFPxxxjC<=up뙦c.ϲ^V}}=n0ރMg?|cV}XwKTם .Ghy~,e}DTuL<nppT ~a>abp_ÐWNQ_PT@$]ƍGl TGP~ZPd ON_Nbꎵz ^?Jd]5g^ޒ.-20_[X'?<5%ˋKhX/u⿼Mj=+/#yhͥ3pa3+frPf~jnRrw!jq⠂7X;pۋ`뀿K lxm!Mn[ T(0ܤd&ƅ3Ljx` bbI6*xհ$1\7b\bEq@У%#ZsX"aϲOCu\&׮qj}('۶gjܧPh2HP+nBĒ NapM_f::hQ.I+\;opa>T;Tp,Nu2L +C:4_qô輊`KoHɭluqqW>zՒQO勯ژ*vyf$4_wBw ~zO;s +;tZSC*(&ͽ.9ae%e10~^q5sC 3$zslv8 ߮2dt`l.NEkzsN!Vedלp-I*VUSHՖ=~d+'؛4Yd@;lP~{3eKJU1sx;3ҟ]ژx 8}YcxLH ğПm@e[E\WF#F&d?rs 4nG!x{fS1 o+tNT^'O!xOAv挾Wy{11>f%:]1PTݜj@^gIӭ <-K=x6u+@p 1$1CCl$Ecc1` VE 00}}}P5Y얌c1` g',,L o0kZ J` 0ƀ `q?dhz===@d%݌1` 04p,ommz{{C֦h0 A &h{6c1` 0f]AGDD`Mdg/oIENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/textarea/000077500000000000000000000000001457770046000241245ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/textarea/README.md000066400000000000000000000000361457770046000254020ustar00rootroot00000000000000![Screenshot](screenshot.png) golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/textarea/main.go000066400000000000000000000100671457770046000254030ustar00rootroot00000000000000// Demo code for the TextArea primitive. package main import ( "fmt" "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) func main() { app := tview.NewApplication() textArea := tview.NewTextArea(). SetWrap(false). SetPlaceholder("Enter text here...") textArea.SetTitle("Text Area").SetBorder(true) helpInfo := tview.NewTextView(). SetText(" Press F1 for help, press Ctrl-C to exit") position := tview.NewTextView(). SetDynamicColors(true). SetTextAlign(tview.AlignRight) pages := tview.NewPages() updateInfos := func() { fromRow, fromColumn, toRow, toColumn := textArea.GetCursor() if fromRow == toRow && fromColumn == toColumn { position.SetText(fmt.Sprintf("Row: [yellow]%d[white], Column: [yellow]%d ", fromRow, fromColumn)) } else { position.SetText(fmt.Sprintf("[red]From[white] Row: [yellow]%d[white], Column: [yellow]%d[white] - [red]To[white] Row: [yellow]%d[white], To Column: [yellow]%d ", fromRow, fromColumn, toRow, toColumn)) } } textArea.SetMovedFunc(updateInfos) updateInfos() mainView := tview.NewGrid(). SetRows(0, 1). AddItem(textArea, 0, 0, 1, 2, 0, 0, true). AddItem(helpInfo, 1, 0, 1, 1, 0, 0, false). AddItem(position, 1, 1, 1, 1, 0, 0, false) help1 := tview.NewTextView(). SetDynamicColors(true). SetText(`[green]Navigation [yellow]Left arrow[white]: Move left. [yellow]Right arrow[white]: Move right. [yellow]Down arrow[white]: Move down. [yellow]Up arrow[white]: Move up. [yellow]Ctrl-A, Home[white]: Move to the beginning of the current line. [yellow]Ctrl-E, End[white]: Move to the end of the current line. [yellow]Ctrl-F, page down[white]: Move down by one page. [yellow]Ctrl-B, page up[white]: Move up by one page. [yellow]Alt-Up arrow[white]: Scroll the page up. [yellow]Alt-Down arrow[white]: Scroll the page down. [yellow]Alt-Left arrow[white]: Scroll the page to the left. [yellow]Alt-Right arrow[white]: Scroll the page to the right. [yellow]Alt-B, Ctrl-Left arrow[white]: Move back by one word. [yellow]Alt-F, Ctrl-Right arrow[white]: Move forward by one word. [blue]Press Enter for more help, press Escape to return.`) help2 := tview.NewTextView(). SetDynamicColors(true). SetText(`[green]Editing[white] Type to enter text. [yellow]Ctrl-H, Backspace[white]: Delete the left character. [yellow]Ctrl-D, Delete[white]: Delete the right character. [yellow]Ctrl-K[white]: Delete until the end of the line. [yellow]Ctrl-W[white]: Delete the rest of the word. [yellow]Ctrl-U[white]: Delete the current line. [blue]Press Enter for more help, press Escape to return.`) help3 := tview.NewTextView(). SetDynamicColors(true). SetText(`[green]Selecting Text[white] Move while holding Shift or drag the mouse. Double-click to select a word. [yellow]Ctrl-L[white] to select entire text. [green]Clipboard [yellow]Ctrl-Q[white]: Copy. [yellow]Ctrl-X[white]: Cut. [yellow]Ctrl-V[white]: Paste. [green]Undo [yellow]Ctrl-Z[white]: Undo. [yellow]Ctrl-Y[white]: Redo. [blue]Press Enter for more help, press Escape to return.`) help := tview.NewFrame(help1). SetBorders(1, 1, 0, 0, 2, 2) help.SetBorder(true). SetTitle("Help"). SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { if event.Key() == tcell.KeyEscape { pages.SwitchToPage("main") return nil } else if event.Key() == tcell.KeyEnter { switch { case help.GetPrimitive() == help1: help.SetPrimitive(help2) case help.GetPrimitive() == help2: help.SetPrimitive(help3) case help.GetPrimitive() == help3: help.SetPrimitive(help1) } return nil } return event }) pages.AddAndSwitchToPage("main", mainView, true). AddPage("help", tview.NewGrid(). SetColumns(0, 64, 0). SetRows(0, 22, 0). AddItem(help, 1, 1, 1, 1, 0, 0, true), true, false) app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { if event.Key() == tcell.KeyF1 { pages.ShowPage("help") //TODO: Check when clicking outside help window with the mouse. Then clicking help again. return nil } return event }) if err := app.SetRoot(pages, true).EnableMouse(true).EnablePaste(true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/textarea/screenshot.png000066400000000000000000002572531457770046000270250ustar00rootroot00000000000000PNG  IHDR =iCCPICC ProfileHWXS[R!@(RBot"U`#$B 1D쨨6tUDV΢u.lI]͝s?gΝ'bq@@$=d@`\^`j^ g-|A>$4~>/CU<7V aXbP*NSrX6ĭU\IjW ,e@ >D|u&~y|S!6beidM3mXƊ 9H/N?KntȇXٜane˰*Ľh !FҰ=jgÜN|nP8Ćr"|Z01\!hċqJX/!]f)\ܯivK:SQcjřIS!(&FAc~v\fLq&;jF"oq@ %!Jb[3(%>PsD!AAc8qA`b,N(q3AN750N9O, R bqYܱ1x A`)i da{oc/S. JfhDGq  @! HGdpQao d΅́U!ÂLydYA0b7p<^`u=qy|'<%t: ]S%]P?Ds[AM7<Pgw~X?Y2nYV?hm= ʼnRt)G٩ r}~ =w6GKl1v;.`GFN`MXvLW+'o2TYW (;O<]",`Ax#.N..Ⱦ/0.~J<{B~㬏ׄ.yRIe|KÝ9q`0Dx &3:i`&JA9Xւ` v}hG)p\W@' WO7x;0  !tD1A,{D`$ET$!Rd&2)GV!mH r9\@:Cy|B1TFP+tꉲp4fSbt ]V{z Dh?0b'Ƣ,`2fa]X/'t;'<|*>_ow x+~ _ 4!M2 Na D"hM{1EA\JD'$vI$>ɞK&qIR^ UR7YlBv!S"r ||<@ѠXR)>e:e9erMjRxjuu=zzFEELKePez*U|TRSeNT.SݥzRfE hh5Ӵjt5G5_mZZUuKudb {5(Vl lJ#755ΚњK5h^|EҲ k-ڮuZ1t}>} [m.ާݮݧ㪓SSsL1Fc9㓮.KWDN{zz2zNOL`l p;q 61=goDو#v3 665fg1>ncB7319aSb03[}aRmff f%ffͩk[,L,"-fZZܱXzZfZz{x'g1ccvykKo`ebe t |fb ‚Bʂڃ7?1  u z22&Ljpz55\5<.|cIDs$96ru((QTc4Dc35qq1*=u{.7%nOܻwl -k'%J?j M)Ĕ)'=mb'M0`rcSԧpL%&I̍Vs8iUi}<6o?#, /dÒeN埗^? .K_־}7VܽJsUǫ#W7a)[v픵*\+Ziņ>oYXY_eX&6m1RV[B5T[UWl'n/tGs?{\`g/Dvncgy-Z+;q}A3ˍZz;dy0pY01)#->͇uuQӣt-?N=''{Oez2񧯷km?~ِϱΝ8{ G.z^l~ͭonnwooqו1ǯ_=u-::;n$ܸusͮ[[o~uݹkܯx`wܻ= z(Ǽ/?ܽ)i3g5] DŽ?__ gK o|_+ɫKmKLwޗ}s>=y/_ÿs%\+]Вu'/*G?aQ^7}Zͅ~:zp:ϕB瀭~2ԩǟ ~(3wq+ zVeXIfMM*JR(iZ ASCIIScreenshot pHYs%%IR$iTXtXML:com.adobe.xmp 1474 Screenshot 798 2 144 144 1 k@IDATxwm5R."E:(K*\z)(MAA )D A*"]<9[ew93+k2|LI_ @ @ @ @ @ @ @ @ @ @ @ @ ԊD@ @5jOoJ,{ m @ @ @ ԊV_}Z5Ǧz/}Kcǎ=Ә( 7b@ @ @ @` (+%}?RD!3@ Lu @ A_tEUf.:,{・^Z!~iX=Sj*<=$6x#F _=@ @ @ @`(#j;3ϩj_p'磭z23&b5 O<1O-o˅$L"=zn/9@ @ @ D5ƃ>L?;n)`nk}з6۳>+rK #Fu7ߔ@~U9C' hB2ob-:<y睷1b >k5ָ;}]o}'RI#@ @ @ ifC9C=4L3YZh!&A΀\z"1(V`#}[lz=/4&{￯B0d#fi.䒊@}|mЁ@ C*Q @ 0dly睷n;2g1nܸ{]va /|Go ?>ȱ#zUW]}>;2Ck @L0y!l4I\.bVN8@He)'6I} dd^y6@ @` 4ːpd$@ h47!S>}ȑ}߿{7h򺋠yGv +Hbowj%,p4nީ=L<@ @AW43T @ n0ҭG/M_DSM7TbM5T+o{l+ꕄ{!Ezv[<x@ CC9ϑ@ @`H9O~6oVQwi }w#wy TF$(TVp[og d6J^yD @  ҡږP8@ :"U;5=xR02|>O@sy0{j5{yPSQ63\#!ChGfp{{.4ѣG,A@ CθXz@ oؘޜtlVe]Ifi^y=HՊb-u]Wޒ^{*JEBGGo0pV}F CM 1ކ7"D @ 0H_/[C^,;Dׁ@ @ P)(KW7޸{lfcǎ7n!|9ҪϾZWrvaYi|1pH{ZGy/| %~U~ 5BD>\#Ap_ ߘFt @ 0pH.j[CF,;Dׁ@ @ P(\zқ7~Uen}뭷p& $T?j%N=F4΀XmX@rPsVзH(.|>ρO?͉(@ @`]tt\XVKw@ @.QD&|?Pu~_xovS l?J'U,I"w_IY#1rNeNH|seIW~o&6{(ZA@ t袹%V8dcA t@ A`ꩧ馛gy衇z~91pK. MRHć ^f~fU6GX @ xs V@ @ @ @ ;biЈW(@ @ @ @4JpGb@ @ @ @ 04]h@ @ @ "(@ @ @ "([vy @ @ @ Ԋ@L w$@ @ @ @L nم@ @ @ @ P+1R+ܑX @ @ @  .12e@ @ @ @LRkj8'|ԨQz{7aHs9d>sIq13<ODyKKH7ʀ1A}7ARD&;3<3n-ig I xtwwk QڔH6 WfeI'Łeggx?n.^Yxᅧf7hkZb%^yG}+ІW'~Kp{xW_}}Ģo6NJ_$|^x#4>2,ƍ{뭷TV]Tr{"[~zl@rkKc݇L2$dV=s1[6Ob-"|QCo}+ii'۾i;KGU2#Gr<;6b{ikߛw ngH9&Wi^{_{ XCҿ|\*cOۻom/yЅ OiÎ V?b-@m9䐗^zId7VJlb-:0 ?뮻eVb7~aNwqSL12@6l"kO~"Ģ{xhko=MtI܅ԻKD ~Ywu; e`hv?nz衢ٴ onj#4(>B r-ZX[q:~VUhWѸN.ySJ!i/[s|MyPO &4~=|وԷNZf*fvcT b'<6JHԢN4.I7(W} /$e%*}˞4 ť^{ar 7kKb& /gGBZuܚDbr;>bsBo}(\qw$Du%Gc_x3a+u:cZnO'{ܥDqM%Ȱ"6 |_`Ho.:[C.,5Z4 B,Ds9UBl&ʰ{2BTfCNGz衙fIӔr:k>V[mU觜r0ydL44~0ʙN}lu!9EUKwP޲ZZeLp "_|:[oU=p!lI?~Oefk_;LOA>lo驧ʒQu/~:_J+i,/r]3"V(?+#cǎ=3ʑp:!\_tE2ĚO@!|XkFp<׿oe[4J|oT} W"U߸\**2IԳۙgpj#+7_UW]cz{'I$׿ֱӟtA؁{NqL\CcQ|1J8Vƿ|=/ϰ.{R" ?\ҔpHp  a%`b̟mb.U΅O,^lS-}<]KB$ּh/2?W|Xy*'loIoYWf0 |2_^.$Yj[VKk44o.re@pYSNQ)6|Qc ?~X1 G +3*N׊Mo׵nOѷ|B0[!|'2ڣ[צґo]E]T0x5װGᕷ~a(3 )W}+i.{([{Oo_ﵷeM'vWB|Y9~оp dR;RJ*,^TD}}ߍM'uJ-=]E>]vt,(I ީAtcOOz{[ݴЅ>׋' `6(ZZBFԖ%G}ù^K~ ?яm?xU1?!wpL,xwpF98 4\~@뱎H&0d Q/{ =aU/yěM(|,uivEZ9|tƝ/F61tYT~+KgtۄPִηQ/ bm<[^{'r믯+Y믃b ~2B/*UJ_Zxվ6RU&Hi/K. 0"0>)>J3(_%"g`QV}.{"²)ѪH𡍈Xm򭡽0t|l^<|Mv-U>'e!w<[%~_+-vdwe)+ BBrM'a.mqV^*&1=11|^ql`v+E/!ѤsF ?2mH;O\"]CIb7s#خj;WWzZfJ%kӆ9Ip/!]O^4샸U6[iK˷dۗfRr m'm2xOߛ?(^oWi f=Zgc=c.|XeT9?!)r.XW뢒I$'QD{">RCVt~S XXCiNf0 ?pc j|$طBkj|*rS+sPnؿoB0c# K páa0G3'T>P{Eq-bꩧ&w_΍t;D;Sz:duT,&a=8)6n3޾jEk}nJa%JS]QDo/-ڻ} _rO^?5O_Wx\AGL^57!/,^oWi'kߔc{l[nY$i HSuݤU=U{|2ʷ"őh ofY{*ߊ}i:z(dLTNN =߶PߓJLIG_0;8t{R !Xˊ|NKXOE`{g%WHԭ=2&vm '/p9˶qSfwͦ)gMi[iKoBʫ ޽eoShSrV6|w뮻_?2Fy6Ȯl*"P{IIoWi^{bQtmcrS ȟ9Lf{QۋA%%j?[>p5¥Z9GJ~t-/%JM8:xK3\Qy{c2+H;vR(#+9PFj#t:ӊ.5nPM,$ 8HP89>0[P8M5ץ<`$QhY?[iK7{u or[U&P[]rtD&uf_r=NW#-?gQ6aglˋUZמ4;Cj/կInr-I/^o}2F(E3hK3ш@M(̏ѭhA v2 z̘1{lKCXo2uV1΋gyƮ]s #6䲡8zH4Lz8q+*4fn-)X|Oiy`7/ bi7%g՚y粖F.,g 'bv{/UtfFJ\ZprL$ǟS?]4=]{ۗj _vFn~!s?iv,;>:CDɮ)&F̳• [{dW_}'ZR@?_A܏I^&Vnny܌-^46S <5A4"zކs9"{kVXAqip/F/r!88.vdOhMDU+r+uY'QbJ[*GnO6HGy$t8Iqha1)]JLM[|%uYGh NUbu|T' H͎rZ1d(DW_}JΙK 1֮:{iIg?Û̊~[iK7{HY/u/Z;,"[9 ɞW^y}̊2"ӫC {ſt*-kOeZtX[Aw>./|on/=, ci쵄ɍ跔Κ(L]x G CKyWY TsIjEpK:Llfcǎ7nl9r{ ~+ L #Z%1 c*":!rN׋|]GQhvES~!l\ve,[ff)p饗6O ]BF5hMVBz4J#?v,?;}[PvuWfFff HjHzɖAgE%n@HzYp׭Hn|.$~ڼt3U߬|N7Cݹes\pN%l˔Μv9+K*:DvH"FL5% WC3[iKO_wWeOjȅQi˕@oMdRR Xk/m ۾,)W|]aF{,?R@E7P v5n ]|^R0lʓh/(YԷ $Xn;c==!n$lp(YU9|;L~#Ta(\ɑle8Bݞ± n1~{<ؒV(a.,1*r]M՞Yf>Yn& H0#2&VW8$s~(LܤUU^mN^] 0ݞob㲇=ǿ׋0;dV\hY+)@/ G6'<^AF`X_{"5 ԍ3ٻmtD mGa!z4b@} C,"0B"MڣpZZBǑH P6%Ć@ ; 6@CKi=z ba2euN9V|hW5(m G}̟vi8s1aaR5CUۇ7WθX9wv/87JX@gp|4̛oCz&7Cqޤ-[9}u٬-oH?[op\i)íyJeth:Nc%ˆA_=E4 @ 0 W_ꫯnL41cG aoB\8ՒpA`뮻}B@ PfSϟ'7߬"zNgaꩧ^s5鍊n19rJy晷nA\v#ӫnjB!0rtϭjx+Ѿ"Kd++l/_WYf~;χ'>=fV`ԟ.zz8,4KM4fmvoMjRu:=#j֜V\qEUW]~*)֠RK-YGyxP69螷s<ae#9V=7zn+(?Wʣ^Uqg>`/t{.*,ߧ"o죿By7}\Dyg\qK0>%8eFҏg 0KF~U}M"HW`7xĈ9_mA#^yE~L=餓."LyzkiC bƍXs'k ztnM3$p [\LS-< ,w)O~O?={N+npxWm6#G T;C*?EsύflDF>6,?}7 B{ַL++<=[=YH9{n1>/BX.W))eO|I'a\\rV9}^HBZ@0A7>QËKF*!gWGW {R>ǫs1,jiFye[^[(3#J+[['|wEW(.}*0T; #ϩkoUD¥s i iƞ߮\s LsPk/vڿw}#gyW_:+\j]uU*%ڞNKt[ED>?E^oHK?E4.kr_8kx D믣g/fGJ+Ȁon8jDfg$cV) j!"[T?-R$z,ˬʣFD{K%}l`"pjyB"V8 vKb]vAC`>Fo#_|3W7wnCJTIs5l1==~S^N=T*$PO8I[BO%哺am\^{Y]} _rH-9Z'/o DBh$7M(p٫؎ћ#^tppqI]bGX9}.<3sʓ!վ嫊n#ND=ȯ~+6uHy:Sdoi%GǎK !td7}dt}ko+u|t_t6z@ٗJY7E"dӸ\c/c?0`[EyL_sW>xGkw6ݮ&Wg}D{JMxׄ !RVW`c/ob+d>Nު7 oȑ`C};<曫:H gDj8} |&|r $tHw!p/-PzW QJɐ?嫫8]c8uR-^{m/"yYEA^Bv&8/ ,}+Bd7>R@JrQGI`i]yۍ7 /2I?gK=5Pt|[%I==VB&Hw}m^&,W^<*Bw#?}CzP5^{wU9Y$9*C QIl/^}^Li F'8d!U҉&U߼t]&ʫ>.{%^UlI1f-FKn~AL u|eՅQ"×et>,$r~ظ|K8FI̯[:jHgtcE ,YnlQakh[W񣦃T~ho8m-;(0\qJܯlt:[~ ' !W?\k{&jBRZf'E[$mpZamt[ ])SU#yOOl\)v9Y$XQERNo;n+)>=oͰW*ݦ̅M"h)_\8dƪt.6)M˷>Rƫf9^y{v:DTaT%ۋW_!o#{ZUя~$׵1D|#v q7} u>w) ^3q-W[hAtD@YZB1V ~}ņ|YZx;㄂;99XSW[)n9>N̯E?!$.>;X` :ߡ1,@&2q&XLsvЄs?y׷J׿VZ|m#ؿf_yE.:[~uoU'xJ`J+h0(0Bb%'>?"eiL%15!#9ɔ9y8oi5\z0'|bQ 'ٴJdvl+*dUt?9gL_cgʄ;G>3^t.:+gi|gIs ~q7يUWDlv PW*D;H+15M> ż?OѥVT 3RFl1&2š2|$lD\c\mbytb~E^RMWՃtnޱ٬L+`{ms:Ѻ !Y0l[*Q(32iȦuUǐlWRit/o [Hj/=/~]!/Y5VB Mo.}4GDi`yr$9B0GTti8;cBVAX%QhtxSOQEV"ַJr핈ao!{o=!)qf,xt,-ʷ-9\o>rDZͽ4H!%gvd3e~Qf9|ZyC%#m ٥>.{[K+\ gڢArLɠ" o:]KZW HS]+<:0i)QORQ5hY4 n"<>Ka MҍiC땝M6Q]沁VkH[([7GXP}!\ˢ{U?˷}ߒeo{4Nnfi|}oLO_w)#sOESTJwI-.r0$.9<"4:>f+ܱ=fW͠RG_|d NbCqs%u/.7#/Qǫ(2Kw*<̉#jh(hc>,_qCU.P9my y@IDATQXhIoڇJ!Kl}m.46JطA=ovs ڲQRm^ !=~?+)һGJ[y2l N;$s(>9昃-6t] հL"<0by}2Csʚgm#>yShL˖-_m}sOAdo tF{Dt$L‘CZI5ǕVi.eN1߭R3w'{9vah QܩQIA%;Z{k+őH{c2i2\Q;o6v/.goz28ǫ5G^{c]9l東6J:X:YC}vߍ>օO7'/>C}of㍟x^z饸!tvGrmpݛݺ2 ͆?쬪WN?[BT2ZzP|rku+ `(ʀȟg =fytmQi}'\c'FȖ-PWiK˧tXy 텓I&}ӟfwαn)Ԍ:g.%Kv~!Cfc] ȥ "'|q9gY7/.R[KWdがGIe \rIe/q1Mc_^tY P l}:d/G?L6lOb ^ҧ?Ou E7~FAiɊM]t|x+_{VO) ƅ 1DK|lh"">2{IlGK$XNۆG!Q׿u填ÙE* ?sg?{h8 hoPD kd()\ܬ;4QZ#[Bm_/-?ƢIp黌9FUucp*S T. CNcO*m9hDܸ$ %;"&=unZʮ>[ݨ%qgThqڋ>4f˟8^-y벻Sss>Vncէ0+%kF$ل#UG?zvشQ\tb}0^3q[/>^U~ {jX-mSb6a.rᗥ Թb/ȬqSON|YV >,#bqmz}F[Mm*_&a-.:N[e F&,ln)WYH˗]Υ6G t771U{^xLD( ?&C/kX=+&Yp8 - ʇB"o;vqa[]'Pzۗo)_S][?Rn͋zᱷpv򩆝<餓*^'+Wa_0ƘP4,vZ6>wX[/>M "+W{t쵇HWp l9*o'W \# Z*]xz7#]Ug(e폼kON.Of|x mo?YQ-CTJϨ?mE[nDơDG (ͶT!.|2[Dz핫=[eɅ.{P ̶W=BNd-AW뮻V${Jr]Ug$q2˞4 ޾([لfCfB$>!+۷y4Qx"=wI$11$yޢ>'fͲywaon)WYhBAB@t+ \ݞwm;j}ei>w7KcBBxYB8馛袋$&ܳkg ^*V:YBa믏56FaЩ' Ou&4.\`'Ə_\af$~4>p ַ.7hF2(_۾Ϩ?.)߼W{7!KxcqZImʰo.}>.'s=1&feg"Z!O^}knt{mh赇Js?qEZ#CWQٱ0^Ħ}nhp|oJ/:3P$WL2 ' uu)3!b˷N Wf<.P$+%ᴯNǧ1nJHz}CZ}[|5I߫Omd@"tim76)XȈƣ|[ I7{e.,N(n$g}U /OELr"3,߯ص[&)]vYO=?|U }ENϋea0 (L`߾"3>ӾARcbK7uCi>d(.iD.{!HE(ͅ>wLPN~7[Qr> (q.7`|bQ.-&;^˗ۅP^ | Ԡ IWYq'z!r/x;vpgu @!'b^$sŹtէʶFIט u R@xwK^!2nFzN+@ 0@9KK= PB@ d&Sp`)<( =A\N;4TLJP/?I!$; B!8X-1VLh#`g\,= @ _8$f[9oƎ'{p-hn7v(=BZRơ=bZ8&@ Яm,A_ju "_}Ս)a?f̘P4 dp#E}!W2q䖽jHg727~ FY .s qlF@ | 7|:UC+87ܮg%gk3rHnf%Z ψ֑r 'rQBը_^a ԆtFBwPθXCx@ @ @ "`@,-1 @ @ @ @ FH,@ @ @ Fܲ @ @ @ @VbV#@ @ @ @ \&\CG`'5j-I)9s&w}p^?`htJ E'=zG  @%61V4B@!m\p^{/5\o|j\^GE%IQxC0G{5ywK'XZBbSOimVogm@$Ud~dtЩxWy)hJG}~;f y晛niر34S>f馛2,;e|P\&?ndj{(<xՠA/?6 \uSOkcrӟTכoY隉}^Х'xSN3z7ft}+-1GB핫g¡oû6_X 0dCϥ )#:XzpdWwUW-DM[oqT:J-5iŠNGqD+~K-Ve2DW'Gy'x*x67x㮻"r%s[i9Wm=㦛nQx:ɏ^=:Q0'(E!@!֍rTj12LYZBewȂ9B.r&^m퍺!%)Q{ 0oK.a믿#^gy*^{5Q*]J˯_JZC ) @ }sEև4$LlF<9cy7n+])ySd*{_|q4'_x oJxO~whVNxWjXb >X6l g?J/N:|-p,>O$t8E|e2Pz-ؾ#o'[>^xakoۗNzXMɨMSlr}mޖ+_]`CqPh2^_t Zh!aw}e=ܓ--Mշ'7'mf䷶%z\.2C,ݟ9rV;${￟3mye.{^>0;Q)Czyn-fjBdOҳj/^3o۷*]y.<Ǜo_tQgJ5XBf©̶wy|J_דO>YTN!=~Z o*3ƾBvaLLpn+<&Wk򓟈puY=\y?~e~%wSLQo lo*8%J#*;sEZ/!K/)J̩pԓy|ph1Nȇ~ç$h\lYgȤ)뮻Y]_%^{t53QO*E-_O+f/UTu:E3/~g׷-_5L$VZQ=Vy-׾Z9ɯ"1qM:蠃T!xgzZQ,nRji ̤_K1Αu]WD;QDNl/g'Vw6hvvb$s#Q5>Ȉ/xozJ۷ {ntJF}s՟ n6}a'+mV[meE)oInL˞~S6Q񩧞j,2B?"](^{BW{k]͐7cUZj;>^\g_^|}诽xUX,fGp䯱+ތ|rb?;V 8 7D4g}67`q>W\q~Lzɞ]?Q1hPfTzu}5<%^'[2]啑?~- oV+53![?+|Ynr c뭷jTէ/F>[H`=;hOW"~ڄi>?Q esm?59Q|E+xrDXۏ{+Zp3 ?я -袋Vi*'Oz ,=`mI`Fm475/4dӟ Mu]_j2qSO=9b$p 'pe~a+.l"ݞKE{M~Sg돍e/!uYov{/XD}I]_ \g_U,߾WϚڋghv6N:_b;_wo]^q~Ǣ.cxW7R/~![XzYr_T6+&iޅ((NR=?~))>E26L>Ѿꧦ؞G&7'~6&R|uE&tO+UUOWP\&C\Li**eI.Q~Sz'VT V(ʟߢ/YJ*WU"k6+n&nQv*W;q$7d%߫N|ӶSCWIFu|t/mnPȾe+U},f6;ĵcci]M4L~C\ve\rI+HcXj 9*ӆn_mf|I\=9#I6)ʫwQ$pC7yQ1۞XI(y啘_sJ ~V "74Jߍ>)%5[ Е&ѾgEV*VT6Ǣk?{lUҦm]Q\Q UEӨ(ք9I+0eןDV;ް2S8L]W~0! T6\Xm;mqOmtiG* Js gGjDړⲇ|v~G?)yx3j/^[)Ӧ>}^u=;Yo+@KKHMu96&p6TZ' ߝp c=&*=DOydatlXq0bl_Jt :xA#E"_(8h딐uQ Hh +%>9i)[(Є/ve /!CFG^ ԕ&ѾgEV*6Pv)ES^(_MB!r,4< Va xq#GrmMMo'Q+00Sо%hojMt}\hJF?2uH O' 24)$>a(qc2>Wqe_Cwԇ:_z\B4 'mV_cŶFXpM6/NѶ|'n8CiǩPZADUHT<&HR4J+%k\LSx`&S >ZAt/_ZA׾2g+*y Dy^}(2W*Tol6U}{xp. ޿qEMs?*D*!odhT:Pgabٍ>OtY?9X{[lBF݆(Edvuߎ? Iŋ^MT۲YS¾U}R&T_aQJ@3̡MYg=# 1mɣ ڤqъKspEF*%~٩Ո&D駟>]?q5(S[a+XTR:,c#]l5VLQSz׸7KSZ>őݾIU>)i 4Z*FpЮzK{HeCE?J|O$Dݳ%ŸBN$w 样lfh?iCp?/Q]892QZ(*$'ړv$\(P'c ]b{~UDBRnIWfe_>ٙ@4trѣΠ=Zv,Iko5_=p[Rxuw-anUCpGRB;z G9k*Aw}"%IOB%ٸ"'YT2??YppZmmQh ˅ʍB\)-h_.{XC2)}Mz2@py:kֳ x'2+!ȣ7Vf ;` 880Zt|0+^vF)A./91sDg?{ht`Ya4Knj]NRW9XE !^|MѾ\D =G$'D5ͫϐ ]q\01񪫮poՈ]_te!K/R̔.G\5\?^ʟHxbgKiju|͒AΒe$$Cނa91;z^y uSIv{I̸7bĖ[nI7JY,C t Yp/7[{{|zl8S3< u+վqK'mG$O'\gh JE\] ǁInMQ[k *K/*\p}s6^ g7W$kD6BVwĔ1e*S61ۗ@+JbEǏ/yyǂb?՟VPȭ[ZF`itO:餙g qw"z QeE|ኟw!%rꩧ"ǰ/O-2U!ѫOĥ Uץe.d߼ sFg!|l'f-5z5(/&L<+(ĥ%sW;! wa?LkRĖYu]5f43V" VmKsμ2~,en?eO/ 3ghX.m+3 A :ȇ‡K h]2ڗמ؂N]XFI]gJȰWW ޶R2%W^5/]tfO["Ѿڛ(aΰ'ⵇzN[h.R3YW?^2ڋ ooK7B%z}RkO*e L%H'~n9~0}TGZ. j&J'. b?uKN{g^Ak*N6]-h.+HodثazEm_>KPNK*'~zSխ#8Vj>Mi e6z=!bz{qÌ+gL[h_״BrwC>-J"pzoF$J as^g | kxF{"ygsX jKWؘ-:3Js*l|2c5$4$RVeYpBav@%!P?08(&fRZ1g緕^kִܹJKGz^+p3FŒ>?W^yeS!E˦_fUp+N|#5=RJ|p-~(w)0pJSZ>Ypt{9GbM%HgOb'lTFm#+n^nŖN-uYs@W}K?6]|1NoH OJ~'H"Q~3ek?]U ZdA f9y=ݞ2cv~+r{%]l"ۚKO'~;WyIs ;DfU0`BM08c0cOE@ @pAl&87Đ!_@'yb B΁XZj(3g}Xc `8}PeI?&nt @ ߊ;L.ls=7Cx79.* (j X~;0A"FQC@`"`g\,=YOx"5!hH!d@ @ P΋m:0jS^?i)#E @ 0"tl[VKw1ʝwީsg)Ez @  W_8cƌ$;d-cYΊ$% `@,-1t >B.;^ H@ @ Do8׆?"AHC##F,[ m`ꄷܩJ3.s @ @ @ C;bi߈G @ @ @ ei@ @ @ @ 24ʐ)H @ @ @ E Q@ @ @ @` 0ɐId$L>F[{!͞dm9k}{.[<3W#mpQU+Ψo@ A'-/mOCD@/Xp_{5/8\sBPqɺ E=zt72"nԷ(P2ω@ [O\Q1@ h@G{;d@zV,.{VXa rltMGfevaRO?t ĢIL/XYΰt:[:V@+{;dX?cSǦz5\sn.W;">p uY_}Ac8XTO&w7+D{6n'8S33ov홇[W}+d>ob'y9͈5Q(/-(8Vx+{'6 MStf*):X:)@1⊒A~W]uՁҽe Zk)LaՑMc&l?M7t`3Q$yG$եZJpoCO >outC3g%o}bOrztd,iTg*˞ԩybZ?ٔ(gg"~GPgM("a 70;j>F&,6pƿ =C4]l_|'|'<$p lcXN"| s177ho+҆W.|2jXb G%S> Xf}g}'H?H╅^xi '~KpxW_}ժ]3? |@cFP, z-UUCȮ?*=-?~Wm>xkoc6'Y(TZϰZ1~Ϥ TGGs=7s]T;QKWҠvaLbpwmfXc ۜA@TٿM1;7QGfg;<>i'|N<x7w-*|A>li1cW^|*S7xcT%#(sqǁXӸxi\6b"\9眣[⡇@>^|uV霅,48V &(۞{ɼ> QKIݰ̃ڵz҄jF5[J[oW^yԨQto@Mhs:Dd݋mQV/!C4Ws5^d{:8@}ST:-JJמ- Aկ,/jJ >>6o &kJUpR[oV[mVSWԟ6WOP"-_W}+mjXݰ.<5#Q W}R~ϸ{Ou#~&~x[iK˯47/y'~뿼ť-rꩧKDO8b__hV팋*/վk×^zi / 6~e~D)[NC ovy .!|@Zv}XT}DM+jhlӜ/wyp80B!I&B{WS7|s)&~ǎI0ui8}{k$%%i0% !Cd"!eɔ*GQCȐ~g>{]\g}}qkkOZ{o/ly5ą~ƝL6a1ϳ>[Jde獂MA_ #EcT7l V>|zk)/vϥZJuW(xg菦MFO&pկeoP"C\] Q6t!)M3z ݻ~A\V]Ii6_J w(_^ؐA|A=?, chO˚BXzg6.ͦ/j 4uPcZXm8yɗuSoL$”)S_|ql H§~چWf?|*b6l#bf@!pÑWo}'O">6ڻ QH >2|+4 hYvUWi8vi_AWTԅ.۰[D~GHo7ZT>6G>|HKm0I8֌?6Ōߥ*L:_6E4~AWEڻڬ-ENgkFS?6ETc;O] k.=~OJ|I2DEwjy'/o{m/xcHA6/6I oIK^jS9#e#Lς9~9PGfb/.^p"ZQB+[o>Zslx{:|Jbr)l*5iY"S+s3,rz e"&n8VK.Di!**'|&4S<G+,o3bEM D[cgy ]$w< dn?u6=iK;_$)?mxoy&V+Zgz}ʛ9O-OU?|&ðxL -ϔ Һ473_J_PzrxQC>-zWm"2PZs+ʄ1|WuQu8لK|zn,bKA'Xz4ZKmI.h!^|\Yh7EIJtU< /ni?hBs"O>Yn2R3%B{9m 'G['y0\QݮT7jC':ןR?P?-?d=ѐ@շ^ b|Ձ~f\4hC|gN֛>"kвLYKJ_]\!0_rO\Uȅ/W{}Li/qu׭J{CqX@IDAT)276?8Q8YSP ʆsb,g_&sGl(Zb -&I^YCd$=B:><%Fұ_!¢Wu:z([]-bcji-0"tB*ZD }bNJHzJ[GY$=Aj@R"i"k1H)Ӂ~f9}g*"kDs7B3PVmϗ|_S _"g8,+\n"`Gў:fr8C=pE(7L Jń;*ʶnȶ6lya ׈'j(n wq%Pj ͽy3 a#8Y$̤K$Oo 6'ʓO=!T qPE3JqD*RLaA%,6GښN=5\ {pWR'Ǎ￿iC\xz8'J8W_]hi)ɚK&Z,Ѩ?.ɖ@> QF`mWɓO?9~ eYfvRTԩSNp/7M.xi^|\i.}N6HkbRZJBMg[Y(=^d2D2bx:C*uXZ? l_&IJOi͵m=anƤzguIl)ӥo/ ;_Mam/V4G 3pN]͓Zъ2Zgu$.c37cs޶i)k@]e%X^Tw-HN8ACX^x֓2v @.02=餓8VXA'hr뮻VW eE|4tbyJ]wE,[[Yp\$%`irsYg%I8sW@K _U> ҸFY# VE a c ֱߏ]pW/ T[xjP~v̡>~-W\>r)]_ Mx @p┖׫?|+5\\͟^ԼRoӥo*C5^[z{BxKϪ?:<3??tYIL7'K#l(R/ж 8?/QH͗\WI2RX^{ weh` \7Xwq͹,$0Q-) y[gakd.%GH] 4 -W5sX0L{h[mU=M,v^|lF4^'w^]$ ckj#O">bK4 W,'*!=#_pa#C{ta^jZ 3J=>l }Hn NRRNV)G5"+卌\O[tF Ppyma]c$ k~"{竣6~Q W{qm/"N~7JumghLlTKd|#@|$J~;XؘBZ6kL믿#koF!#q `1<#CXF1_Y+wwqB)|! ĖڋMNs}ٕ3bpM=.v2tyv3OTHO3g?C9c=Z/BuMOJIGm>?Q-uWGp %`756V\ٝ'hHZKK1T/k.p4fI0(3QHswg]͡!E.=]NUÁℂEt|4B*9cݺ4y$Sn!XhE'G z3 `L"! aɴ)S` @KizuO.}1 8\wTRn+?{sկ/?t6^dwWy-ƨd+hӅ@?3.PhFP!RhOK,A qJVr]Oϛx&Bgj/){Hnb6ksb鞑7 Ko@`d_SGF$1@ 1qR"M|`f#`DLsO(7u,<%o|]bm n$T@ 0}mO_"@ ?ǴB A5ń _(` E`R_S)[n%xpXY#Pj/Co-.r6.G-픳Q/x@ 0YstsXr%eb!h:V@GLj*%ZV0&Zr@ 0 жGA!C ϱx2 pmmwyk|d@#D`_lܓc9nUV۞@%$ @ Aˁ$,|"f  ?'[Gyf!f5cT_!jLxo>U푗~\:tJ%+,KKFaF:0@ "0>Fo>N:0ND@Ғ{l"@ @ @ @ {Œ2U@ @ @ n3J78G.@ @ @ @ 0e0 @ @ @  0c7H.o{^Wr|'W3~]S%X{y2cgêSf~,eԌ /l~ ʼn~_= ]o_W,"p6'$&{7qo~ t͹vO=߆>7i~޽xh{]{JyH+FiS%֯/Jk^ X<\N<d+kO-ICkF'{\z)loÓxc4l9elg.yzrk //V<D9HzpYf:u**t-dlf-ܘsbFZ<=k,Ϳ!랯 _q շW?q>*e,E[o?DcGWSCp*7Գꪫ­SL&>!hÚ|$Y{.ʦ!G?wy+IJ?: L',?х;MŽ*+_JW# CŇ[ YGp疚DFKPM-[nevyVA۷v[Gބ ʏl+1y(ePvWW?Dс(?pu^Io^|+I\EsI!2Ca>w~OJs=WkѳP.J+O~‡@m:Mڑν$WUaUnB}L@+I>쳏eE /P^qcȮG>I{>w/fF>LDIn6,V1:P3~5 7o7!<*3NyE+K՟[ eH{/*OES?<~d&OZ|sNVMx1 ~kT9>]Tb.LS#2d?_zJp@ 6ɏc2PtߋM"{_%c|qjP{LQI.-C4?_b` v?{.|2M Nϯk>*/w阌KLQ`|32Lb}׿yQk_1> dŒX"ۘ$@_WZX>hOD+W~d!wi'#a VL͙0V|0vbüe3GY>{wiTk)y.G>94gf{{k#ѻ D07Ɍ2Dtz7z衘hġ5r$yӉ/VMl)̖lv3]S&'WfJ3C/"@">$񁝏{m"XLWGm &NJ†l}Kiz\sEe`k<yqSZ߬)OQi1{)&og8#Yg)8+~Lp\a0r!$}U@X^:,y>1O3/0C=TDDqaN:$B2&⵱n?`f@&e_yi~2C#/O!c˰ۈ,6[>6G~\KN+qd曣)U+Ls|;|*B5?IԷQʛ_ oyGmx[T8N6W|po#84PMrWd࿟7FfxF/i}$J_-ҬqՐ?_$ga{{ôIʋ[o-Zj)WH8p/цb2dj„ZKg/Ժ& dD[mx#:1[@^+iDT|#-S d׏ Axf?=oi/Ѕ>meX]O>׋'w hR~Q7Wy*:4uYW+%Rꛫ?AM$+HXMkBkf _r%+?=Amgڢ֚$ W|`*ٸʊh|kcʑk8LýD6 RRpKy3m' [f)7|@#uf:D ;3+hQ^0: ϑGq2#;<W {9# $'Q0D|@<{'m]?Ϣ-ca2NJB'I 5%uzo}xB&WmJ;j0Q9 + 1qW/`,hL-1p!m% oe#2?ă ~(x7ˠX`[oE-QJ鏥H 8<)7tᓡoV:o~ 3;-C0bEc:u*BJ^:D.ޙxp1`L'}:ꨊ@e"Z\8k!_fRIKG;#)y"-* vH4(4w0RADȿp&gLbvcFIv]ws6zM^V{|2귃"%#Zt,l `Aaկ2lC$_fl fJ( bFqEF !+I6ewy c*s*FzMFr DOefh+GMNdוR81,pJ_3l]Ҟt_[Z!%k~5I Cv%NV͝mb撧^/z8ruީ\q@d#9x%"i9Jwt;j|3ΗʴXQЭjHTהxa' nF9C53+!tFU w=OcD*J9F%jm`PZlJQxdw+S k^Gwyevmt{Q|TB_Y3+sPdZDr8(I[%Fg撊ȪJx9 7p'rcPC]Zo/*A`&҂lR^"F߶G;68]@KkuQϞEJ`c6UHJ$MFKE5˿N?^;?ONA ?Oْ1ȐǕQi.akCPuW^"}9RPLmPye!]^EC࿖׼:drGCr^y ޞvꩧ4),SqE4`' _͙VqԝfHf]p6&=ˎOhT.c[)BG[_zOe*ir^|gȺr:]3oܓ ̨E_*Kfg>Ҹŀnm xzjyB%꧷+?3p÷m\bC7&f7 \KxkXa R%LYl gV#EdWtDv/ohG*1Cمf'DiK CϘ~"miZ汞ԃ|'>R0\WG(!xsaZ?k_w{ aCm>뫁Di:lOmXE9"pd2K+Q˩S+{!WN9aT+əh]{$[\4B=>"~K%?,[VpNG{Oe8ףћ4$[gI~z-!yNZ{ d%K4UEh.hO}SB_sqX, Er0JEf>p 9Ygg y=(Zxҋ-!tzj柍1\;?6%9b5e`mk-ͮ4<{$aqd?1*N>W {X柍‘Zz,|4V[oZKw㻡vD{<Lv: <ލFaK ޭbNBmLHrŃ} -I亩J|#°F#PX2B,% w``?&/_~&ρe{h+6DW's*Jr]w?hڈYZ d`.,U|iD&t̐O0ZI_Ʃ1CLJ!s13$3]Snh/y2'C*,XأLĭ/Z$3[mF;,t{ ǫo'l 3m4E`뻷~G1p,EdAgK 񚻜PR+9<1wq,8W eK&(B O͆3a.5U:Wh;-I0„u(Lubt3?#/ʼN"f.Cdu[zT Ͱ.k/e1l'/^)dC`6 <ۼFrm6QQZ !Wo^_hMlbdgz##z-Nz)Kϯ BY@"X(oD\ǩTc4DXo6{+FISj43rz 4e[!ZW'-%Y*Ylc@]W2J|w/BEx1b`p Qٍ)!t."q 7L,]%&qnyTt@ؤ5%Q6rfNL EhLuEK| kF%anC{٥?q/xK6a:'3|]G Yq2zL_K:ҷ!(.yHշmʛ)K~pPfT=70={챇;,ܸX#(,KuטBp6QG8`pG21 SdW7F?cz'_0` Ӧr2r'~壠1R'>v7ːGJ`%phzLXS.|2-lrg\RA;JQb[iEE*KKHҳ k3&`%gY)3 0k`^-|au"yrdzwf&@ov@ aݵۋ?^M`L9ʤe.$eG.om/haQu@y芹xU%d5E/$Ӧk n˫o'l 㒟i1ߨoSa͡yEὂ7L8_U O_+.+,zi=f%·z+4c[y[y$2 LrI%NG&`d0䱪oɰ$%fљ4+D?vXwB͛sͥ"pgWeCmxMM=.>1tU4$\J ZZBme~AwxLܑ8 Z"2O< \u 7`C[2ƞ _(` #)8G g7Qc /Lb9:uJ]Gd$V28ˈLWAn d]~ɾ*Wd@ @*^8O0fpWO}zI|mt@?D9Xiuld1 %n#`&Q{Yg_*r#e*+D @`#v=P-M7ݴ*p1}_C;bzb`ƮQI,̲bqq+V.0zN/zXW_Ύ͐[o>nG^ٻ3F :l~g3>]l_ek[d:@ @ @ E@,-M=c[!x @ @ @ t@Q;r @ @ @ E (c[u!x @ @ @ t@Q;r @ @ @ E`qo~L3̈́ߟ|ɡ!3ϼKs? 0 /OQMx @  8ƔLCjXdWe9cfo6UOGBIin3,!@o۟{9dx򖷔ayN6M/X9@`dXdE橧zӛ4rNwg K4o#GuLXOGI"A kPڦC26}ى9\smV6IЁ( 馛~0!C E`7s=>2gƥ.rNGy晿oQ?xa]}X 믿~w_߱)Xv\cG1,t g 7ܠ$'=WՀ7a-4fu֏~.4"U1>O/,G %?-`;Ӈ;+o{=7iϹ-I7Еe9/~r׽|Vo?VlK[i \#蔷cΈGHyg enw%w~Egz>0qqM> I0$"$֙>0 oF뭷tĶfq|&s7 .HO\.>Dκ"Qf>3ӔS$a؜R_/oZ`y}I2(ݣ8K%@䛎8H|oL3zC_o($ħxE NjĎߙ>0Kgg坾Ō%"sr6 /#^7W\q]v٥E?קkahf y׻ޅG~7P׼5-z!j9k_Zv(p]w/j 5f3Q3Έa.le%?^6r '6կ~6Wn5<o_H 7񍠊*L:-ޡ -{W%HO2{#WBW2P[\d=<9~o֯Qwٔlsn +^ OJ1u$ҟ |>߰+[ڗ-Ѣ"%ɧ``IbPeaq)oYfEw`R擑\wq~[ߺv9眸s`J _,c>`Mk~#6%e&E -:b݇١\묳،N;4n'</2΃{e}{9Bj~y%`xk_\ 磏>z7W7x#n /K/z3sIiݕ,@Q/b6p/  ZeUTǺ#׿g+~8Ԇs1&7WP)m'?/+,PISJW~<֖=v_Z2 /PlĘ/""G<=G}Hׄ2+b/`>R e b>ߺ+J`W}e迷ʒ1q'_TM\ y\\H.yOTD gVC\sͷm9"Dz=ܓ ?Ϸ'tqf>g3gUؓC'O9K7\Soy;n_ 0+kq-/f`R/kM+aI'@Z]j4+p<@ mnWy $ﷲ1kO^M+|jPa$]<2Lu3wfza- ɂ\1h82 DeMz7;5X$K(HڬBn֞S[ϮP6- &~9&@IDAT/yCK߼گCӉ >37?TOx[sCW y\ HxWGDŧZQu+ɧL>w?J},o(yݪ@;FIxѾsH y$a'ѲQB?+q֯5pIuEq +f+ N:vCp1^EeoߊB{gJe֧-;e0jHei i!3lTl}` { 8RBpTF+VM0"^*?^STc6] ]M4,lbBԓLؿ1!p GBTgB/6>s Lt5u#r-'Y`B"'ʖ!Rz+{7lBNG>[zasvlhW+~|6DK.p鞩ᓮo*eu.q4>ؾc[B}>B{W૯5[@jTJsó:+6fc6ӥ;\ZdɭT ҆ h&$/aadM0PqAĮ=8P'GTk6 bV*y=x1TnK*'hlDf CBH>c-{x}ο>TR%<BsK~˪ڗnM{"'r7Qb!Ѽ%^{w|f/-O{5Ѿ3Q2IDl yJV$K_䍉Kc͹o;ltx&km{"Y.q1 $#%H5@zFH/o#ʌB0rtf/Dqp'/0IᵶXU B4jtiG8l"N%qs0³+sQ0srHmgjE k1%d3D2+o9EJ_Nەp0: H]WXgD}#dY*h5>ϖ'CCK~GF 6/9 .I+[D>dĕ0JE3&iyoͼ5G"CZU{%sl敇*r]~!v ؽC=|.zQT͔YR(ejCt3ȐPDO&2l %c W"T@gNAO>L{3BdJR '`e0jh^jzpI&  O=T˄Ji+hNuT 畘 X-hҁl#m/?uwHRTW"\le(6t} )m5f;q3j򗖧42}%'R-O׳g|6]ԝ V$~=:̇X.XyG3J |#mhվCʌzH*2oF {#=#rh ӂe]&c6Q"y.*S2Qd uYYM>rM7I~+INQkMBV ~FjVg٥rZ$;V$ԿEk74 ^yZ/&̊$yliHZpDk\OTso}vɟ'uBm_Ƃ#Dd/oy\]l(6t} )kE ϸ5KS?Ѿ\I8H%^y&LP'rovuWMļ!G\>3/=/%WTD?7ٶXQk_ >Dk`zaŰkڴfa/5ȅ;`$xFТգ:`ħ1;GYntiQJQJb4:n= >%2,N;i:u^! /Pӄ/Tvy{q՗!b[$F{,R|ƋϨ_Z3ڗ?I'CI6+τ?gvP3<^~m0(1_e6@mGi/HxlGKsWwU.\-y:?_8∭ޚ#b/*48~Y\{,ιww뮻-C xV {7*jRyDVlGP1p@$@-q0q57`M9Y/$SW4AomsBĺZ5|[h|a} h f1W^ygAŸ-6%ui]wP{ʓ;8C p\ 矿R *q0cL +~5@L\-vO6N}-=ܳq*xLħ0=$E d #6fn=ߺʓ!%)?B /Er9kF~W|o`v3^>)\? t}ivm?kg㝟xSMOFsɣ _.y\g 6fӭJ})1~1jmƋBSN9E{o.UXUۑs^᪥H7h5I"aBTeN,oKEABtRQmTKk2~{,.X+1뮫]pbğE#/괘WoeE*yks`@GeFau(Vrb՘ M N'm?dGp2hjF3J=!4r8 X\ʃ 0jɘwH"g%W K~a^Bv^bEϰ a wcz}ehCy5 vzlaDte]ֳE昮nsI] |FJ~)-Oiվm%pH96&3aOT-7o߫Ul?Z'-Q9MB7R %NJyG} &b$}ET]$ׁ@7Jk ("G;1|~RcOEC@ @ Cd![ZB-ưt!dA@zQ@ mV]uUH6ip\K@ @ A (@ @MOY\qԧ1@ @ 3qY~"Gp=(w W\nÃ?x.t@D@ @ 2Q-= Y x>EʯL5@`$<|2 @ G@,=d6$ׁ@ @ @ @ -bi) c[<@ @ @ N3JpGf@ @ @ @ 0e|.$@ @ @ N3JpGf@ @ @ @ 0̘-k_9S?S߲YN7YEO.s1lIZr׿'R@3ϼKx?#$rD{o{^We48C&^F@SiV!vyg oE3DSǤ!dXiӦɔ/ YOWo@ 0dVlY xyTBFgeמD,D \x6lg'kr@)S.S#D"B"b*Q7Cߺ9r  @q,Ǵc2magbwݪaSK #f#[!X KvQ ! %?d7pqA| 2"|H?7mW#@`(bFq/!X*UVJ͑D&x׻EG}w]3ʱKp]w/jd2 ۹?r-"<8ַ{65 .￟-5׼f\z(DB =Cq1.o"͐x",Iex<'x7M{ j/^3ov>$l)ɇ[ /^o]t~կ}ٞq=>=eU^(}IygyehوNIg1g<I!B㑷}M1b|a-]G(w? 柮=m,W"CP**=Sw_/ĪՅ+{PVb#ADC >Wx?u Z+_J=+yO~.=LпBBXc a/}O/>s-nlOcl` 4fXoB #^޼Xot1y7:y)Oo.xIFK?x"yz\gx)xfd4NzC;i wI%\tt7P|ϥ?U,pHkd]BT,>fwɿF_הVⓟdX*#o[ m/.3گ8R~Y^yyag㦛nj6joSoY^KS/y˛ѾxV.i1Wc:>AZ(/\`鄫z.0xOxgF{CmƗ*U{!LROwwD3W?UDUt[5^[z{Mӈ# èki 7pŨpYgaO~O^ /nx?:5i bu%+r ]UqIoɈYƈ5\#.], N` s1pd7~ad9$k]vمkV s=9׿g>#>#vm:_5-+xdF8jM#@)o lGA;|͇.~&lN'sGoƒ7ވ-K/4/[Xj/?p?$ l?nO4WdmWDoaR5%zH[vNɠqx{+ xb֥oХH.o 1̳J}H8{$.|yhKB<c˒B?ˍG=8GZ0𡓹ԃWC v:%ǥ 1k?)m?E?SdqҷCxotymkquwM6Q60lkL%}z_C {?ַc=4=y.bzkK-+^ Eb'1TސVQv뭷#=P8k.O6g g$A| _?HD߲g3Ϭ!z{_Š&},!+'>++ΘN4 ^#f$bO5%OF:jF^6`$GϖG g*L!|:7غm_0d·z;ߩ&0E"$aGN!2o rUMK/0H8m(Xe t6_״֌ŽPJf?o6"s&ϰ + +]VU矗Rr^yp!٧fкsj#x'XC헤9JRNV'OjRq"E$Sk,&y-E?5N!|:ҷ~l۾*o$)S,=eH۟P)37OD|/kF?ˍGCl"[3JEK?lٺ࣓^(V)f .Ta WZ) ʿB/2-I:.o# sK2M='t Y _h.$~lلB_N8xM~9p 6pl ϑPF&^BW¾MW~($^` ͼO6C1ˁ oJ,6'YK.T mYށgg+< Iʾ(rˉ0&P&D6@W#zMƤCG9 y\U|{P¥B)Ϳ>ڪ^;G7-/ /"kEي9B?GK{i<|yی'O9|, teYhqO3Tnt́F$g0AunIul%eyo#?X1oɣ`_uCT6S4%fE+]%om^2eO>?[g-5k>et[vyI8}G70zx&¢Ѽh"SbJg 7D{NDa)İ+Ya*T˞\g=vS' rU!1B`8f\30U1d/&6|sAͯe¶~񡞣7{'f lȡr.Ug<+J#8 Gp1q^nץ! 朄R6)g!J^CDR7Bc l{6FH'ۋ.?/Wh#OJe*Ag˯(Sl= L׷ٯ3WQ~132_!¢WQeNbs7KSE"ClH{d%a={46%ovEv{/Tl#a L_cFN'!4LK.${p䨪?הYbKm8ȣx=H ؏!6aKU^o^oEB%!]Gn&ɑl}AN^qZ[2s/oFHN@U'd7l;'.}.o0;jiixf.|H)3OD|RdΎAgvq&M4e?W]~+Rk4KO/zSJ! O xo3LX yH#_ĶQ-z.KxZkI|>lυ>,qu%i(xIcZVo2'F6474U*I\ۭ#>2jz46'kPSlM΁2xDyi BDFa[^/*\tYDX+6D<tR&y <Ņ) 氞(+"f 1ʯyAO-oFBl*?[-c w^|<'D%5/--OoYn` ^q njZk]XtM<|ED>w喛hTO@ M EpozӛzqX?sկ~5k֬[p'᧝vG1̼λ;l3O~O~#LdNݧ>X $*Zwu<̨k_Z?='b LTUlFۚko8ć{hDq"1>nw>iq{7Ϝwejy|f1o۟_|qG cZ|gͺ:U*z+0sݟ>u_wgC?vƬYjZ\o߹3ۄ3ι۔`O&<1uqf`_Q^{헿/[ny-9H4"6%SrHpq뭓R=TowqK2>[{ȐۜH #?|E5? Ox0*sj*o|/yKrK,kWCo<>v7Cgq 'ߚDvݨtX_ӣN< }FuHo^w3v}39㇏|#scH+ڢoqX‹jYZøwXOn>sB)' }vu'>q#]+jn60 Vqۤok}5fMoΉۭ֑^{Ǵڢzv#낟'wHp /~oP=IeL7⒙901yL3|;yni^jo{nB!M|&9wޛ޳G ,<#-0߼RtXI[C宼wKLJ.nn`Usk5>u?ۯk>]x`$K`e% \vMwwiNlV\lg,zw^umwSXq -x7P.7szLEFWzjtSXOw)82r+ |FV:sz r]gMn3Oq4v)^zijg ؊ߒ\rʼ5/򓗈`׻v7z~s~&wnweZKEԲ3gӜ Ltglact^/os~.001G80FꪫZqJɳ#E}+^OMq9SɗW\1|+c׉d,Y_ 4'G>X*0c\Y2Mw-?r s)?2b~dF |~:O|ioh,b8蠃bQޖIp[׾M1Q~qU<5#G]P8/_ݐb{^6j0Û#~ɳkS$:?CHbOGn֘;Gf=yFmflmnou6;'O? sRSF?]yY4hzkc/}in<f<'/nb@9e޹tmK.UVmoHyݿW,?sv2Ͼ|]ȗv9ŖZt_OoY*|.¢ Ŧ-*747oēߦN闿:[~>Ϥ8.XCz#S@#M?[3c?UQ-qPjQ_(f\\X0|zgR0~z0ƕG%w T{<(:ی$GIOյ|'(Y0>Ц/g^ 躽-WڟZNt?W]uH6mfb0`9M^Q3zL=([ ψF~&"4|Ή '=)ŝhV_mq4f2B]r77??.QOT?YEN[4?b-Қ316_# X4׿a&LO4*:jfl1}E}Δ >/[QW=6M3OZQz?ͺ6?aYg<y|Ev1$?=]v8yxht7Ob,kn-q5G?f6={<ύ;ǵqX7q)놺oi:D ,i3ԗq+iH<\3ZadvX>{YgŰ=g<+>.{׻5r4MmqNq+ܸIu\-,'"}s j?,4aܾ4.ꉳ:-XqOܑOsI`rUq.O|E[||F.̅1u{g"I:|c2FŚLoA_̉o-xi1S%xwe5x977|]08nefrՕw~saȿ}E{՚9^s/sWXv'.kq='g4˧οW:[,8|Oz}3\pp_T9k^Kƅi 81CV-K~ D樣 cO}ת]w« 2=>:"1y喋C8b:TepՎ=sVx>zF^{t. VYepM7ߝ/f9%E5+(HH6^7͋G$ϏcS6l3<[w҉#T%ca9;޸-;-;[[1B$s=^=<~D=@jJ^gsUmT>>͉cTs1{{3˖>=qnAa$^]J 4:T,h[K\Ĩ(yzR(QHY:.G^j5V˫?k &*ލosΉ{KOdkɹd\@["LĂq%6>뉉>@*mc?y{cg>}@N/cɭޚ1JyyϋO?E0͉-gObhtX^=<~oki`Þ#m~q=ۯY2NSGǩDY]>Oƍ? 7#88I0n- i6 |?eϻ[McG?\s~ki;w;u7[wc&'cUqM794bU3H)FFn0FDN9Q1,4q-'&~kvU.oy vizwY8 Wu"Lcg.5P&WE;LLǜtTg9κ_vo1sB\%UgkLsU~_:R*XOW O1 |U:e4JӘmԋRŸ=Y\$#ezo?5~^mdjyтi:ŕ1'l6~_阈4;haC]z9xb-4cƂ;"[n/[~v]mZ^3*v?l6p(qb#_(OItQǾ@,O>͙1cE2%~1%.ƅ1ݵ_o~),<(FxD/(9qw`^'i|cC.ye˘[ыOÞϸókq{k܉Q2Fۥ^lerO;有los=mL?7gZǀqk_O)^1+)Z\q&#'gyNN%JkۜiVf12D8z~3o|NN:ظ0nN،Nln-qaw}yώmǟpr~Ϲ{xښ9Wmוw-ߵ5!H#לOM>&t.5~1Gn-Wuys22'42sZ~\[bF V{ΰad8 <̡DL9Mތ9>4rl/M @kZ JOtM#DyGDy ͒yfL۾Ød#4ȣG]mϸϳk6 LQDr<(OYp\6+H۵̒'Fן\~gZIsI{,y,[ u ߒ#4ݷ!Ό3B ~ 7ʹtW<{s:i+[v.?3}Ru1Jwp!0Ng?\s/+=>->ax7* @lB?W:-2 i1>.Ҵ?x(q{U@x_Mȓ{RIDAT#eb?zk6v3%di+hF9O8[rA5!.u] #2{l4g|#[nyX6kjw\ƍ6hFm><M:mBKk18%]ٕ\/]8g/?WT IˤNɭ^qX*Fƽ}k.GioO籶FIȍq[fy:Fd^Lw;v?~?}{=m{D޸S`<j=Hi~<9kf`m(<J,,ۛ?'>QJkΧF]gĜ\)x$MLNwmQ8E=魁N'&Ͽxv+_OH~L\{_W^G0]a>EcG&/m9PtmN]?_]w뭷^TG~0>_4s֬Y#Z1z%qJC'Ymc&l gYQ~rXKID3Y㣚.]}}h8311̿mj3q ؛޳Gxwԗ[r3g߲tXg,wkg ݶ1fŦ֥g,f:OiNzl^nUǨto4oO^4oYy7F-)=d|(FW T[L;Lލw:4vG,V=nWgw3Sr DϫNx|<+,#4y|.WsLbW}:|޳'mKOL7c/Xi{\OQ0LOLm(.H|e_~+Ot'j(-~'hqs:HmF9q̑Fv-l9Q{%636!o}k1V-s|ݣ@ޭ(x[ڜ*xr"=ゲ\9QQ~d=^<~oTW<ɨLy:5돺8|Ś_|'Ϯ[Sɖ>]at?>Y9}ީ+#5chiAw-}v%*0q-|QWk$s.On*u|ţnK[Ϧ1:<_17/ LD1C>M[ѩߣy3{K6e>%S22M5x}wIIw}rثjFW=[E39'&%;?[0͜V-av)?P~9'jyNpxN\팬J1cCK-T<1Vcn܆&.31'z궱f>OEQ2vȸQe花 q)N őeO{%q/~G+nxwQյ=3@CC"z 7]89)=Qm0ezlohO:]_>oXpV^qK-wǛo?*s*Cݖ+Ӂz;C-q_і9}+-Jp];g&Xӭvi')?"  0@-G7P^K s8$^[>xr`& @@E>hJ :T=oEq@]pܽ2=$& i.8x1Mji-.NV@3S_K.O}" P@C!2u4J:-xgM&k{3YX()0Ӓ.*TpvA@<~ᵓYux xRU6["L|b"Lvk @}Z~+H@[mRbI3nywE,q8U>)X G@|~/m7h9'H`ҿO+v 0/_{x[l%Xbx+ Qww(n{grH5 @ @&")xRdNi3f̈<^:$%(18dJ<*8Ƨ_̌;7\e"m`Y @ @`Df$#On ^xEnF!!wQCIENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/textview/000077500000000000000000000000001457770046000241665ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/textview/README.md000066400000000000000000000000361457770046000254440ustar00rootroot00000000000000![Screenshot](screenshot.png) golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/textview/main.go000066400000000000000000000045061457770046000254460ustar00rootroot00000000000000// Demo code for the TextView primitive. package main import ( "fmt" "strconv" "strings" "time" "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) const corporate = `Leverage agile frameworks to provide a robust synopsis for high level overviews. Iterative approaches to corporate strategy foster collaborative thinking to further the overall value proposition. Organically grow the holistic world view of disruptive innovation via workplace diversity and empowerment. Bring to the table win-win survival strategies to ensure proactive domination. At the end of the day, going forward, a new normal that has evolved from generation X is on the runway heading towards a streamlined cloud solution. User generated content in real-time will have multiple touchpoints for offshoring. Capitalize on low hanging fruit to identify a ballpark value added activity to beta test. Override the digital divide with additional clickthroughs from DevOps. Nanotechnology immersion along the information highway will close the loop on focusing solely on the bottom line. [yellow]Press Enter, then Tab/Backtab for word selections` func main() { app := tview.NewApplication() textView := tview.NewTextView(). SetDynamicColors(true). SetRegions(true). SetWordWrap(true). SetChangedFunc(func() { app.Draw() }) numSelections := 0 go func() { for _, word := range strings.Split(corporate, " ") { if word == "the" { word = "[#ff0000]the[white]" } if word == "to" { word = fmt.Sprintf(`["%d"]to[""]`, numSelections) numSelections++ } fmt.Fprintf(textView, "%s ", word) time.Sleep(200 * time.Millisecond) } }() textView.SetDoneFunc(func(key tcell.Key) { currentSelection := textView.GetHighlights() if key == tcell.KeyEnter { if len(currentSelection) > 0 { textView.Highlight() } else { textView.Highlight("0").ScrollToHighlight() } } else if len(currentSelection) > 0 { index, _ := strconv.Atoi(currentSelection[0]) if key == tcell.KeyTab { index = (index + 1) % numSelections } else if key == tcell.KeyBacktab { index = (index - 1 + numSelections) % numSelections } else { return } textView.Highlight(strconv.Itoa(index)).ScrollToHighlight() } }) textView.SetBorder(true) if err := app.SetRoot(textView, true).EnableMouse(true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/textview/screenshot.png000066400000000000000000005206041457770046000270600ustar00rootroot00000000000000PNG  IHDR# ?iCCPICC ProfileHWXS[@h@J-l$@(1YTp-X(Xiv΢bAEY vM 躯|oo39s̽wP;rQu`zrJ* 1拘uH+Rעs@!Ns >^ Jy")ha/L9t9#eA #@L'F'/o24b>#̿ikr8X>YQ r9t+a J8$V:g9äX>azdĚd,IH5`΀Ď[e'ALؼP *9qa EY!$V9ı|a\+*m#x_AV|x'  Ј$Y^@">/BfW{!-O a Kdc+ƛ Cw p#HW$! ^x83py|'a?[b v;5:v k:#R<VאXY<9PGCOV|:^/4;&Yt&"l!aEz#n :߹}lppw.{oY3C-\P %NF X87@ Q 0,`* RPU``7ap%p ܁  "4D1F,; a >H ")H 2#:d3REZ9 <@z'CUP-DG 4%t ZBڍ@0)c: f10baX V|8t<Sb|o+F vOL$L%*  ^!#:D+;܋)l bzb88@"Hv$oRC* ֒v.zHRJJJ;*]VzN {m+Ge*ڭթկ=MJvcYOΧ###qy{ݑ~|2kzz9z1S75k$wd}#o3 t  43136ZitԨטfc,0^i|9]Τ&&!&&&MLLMLQff+͍#gי߶ [0,,V[xoied򙕮۪Ȫ5zuU &f%[6˶jf'[o50cpTͨ*LB::M/GN|]s:9&tL1lNUNWAs_ع]6tF.pms&vwu7wOsvbD33z<=xY//{^Z:7{w'gO/ǷoS 3_=˓5u< ( L\x?4(3.?5xFBHXlC6]u.am85Xq7"RQ+E[EO>Cy;&vf8ZܤqIN$%%OM|Tԝ<:yVAJs*)51u[qw_: &?1wIj8Ғv}Dqj8~.[{+O33*2ezgͪC7fωٞ3ې"'M6Kd'*uOjJ8L-ɟ\;$֒_$ } ?LM4ᴎMZT |wFLf>Ŝy62;}v9%sz12/gŎo'o-1,[_JUKť7x-ظ_(XعyExe+˿,.>_:$cIR ]_|GFEQţ+WW|jҪs.WSVKVw _Ӽ|_eV_PmPz6o4X&77XTn!n)dk31~ݦ|;bw׺4عt==/l_~5"SZB[ZZr8#G-9:xq'Mjs2SaΞ:} ̱g5~ZޠK=y!zO?_Z<_=į_/~f[mއ|J//k|m`ࠈ#~0Xь ^o (?YAgV ψ@=77سx{ydJi!synT o|o8eXIfMM*JR(iZASCIIScreenshotJ4 pHYs%%IR$iTXtXML:com.adobe.xmp 1060 Screenshot 692 2 144 144 1 B@IDATx ܷ\DkPҊ](HE뿔6( -(h#D6(0̌mlc[yyfwf\gsuwq`ǁvq`ǁvq`ǁvq`ǁvq`ǁvqpK]jٕwq`ǁvqhq}%4wY{q`ǁvq`ǁʁK\;7芾sx^o~]<> q`ǁvz_O?ӊ'ďk\w=QpK^CO;wq`ǁv88__jopϹe.sN8q{+^wGuvq`ǁ>9p]җC+]Jo<bPnuţ^y x~2hZSӬk;_*|֊'фchax\@w83(w̲Iu8Lge/;8`!'~~эnv(3̺mm>|׊\[V_?83viO__N=*璴qʯߘ۾LBiMO33y;]zVvbMeEJ(cs3ϤuE[SkRZqt=W4䋯& -H/w|3G<=_߳oxs1(:$&+6\\W\ WlX 8ۿ|;dMM+`B9PMnRn8mdͬUM i!fPXt;bl sٯwiy 뿔{Y*|^G\?S?׺mq.'V$v)0Q5 +2Ged=Gyi0AhF{ee~˿\b?fN6oiZ 0粱9TVZTYd\*F}},|Gzfϓ$k_/4t=yOApsBɐWk PCd3lC*oձ5y ѴPX_%`= O3/B>*O6>lNWUb13q=3>ʙϗ|ɗ/ I쀿}5RϒPȑ*`yYgI@dRqdfg, D-1t (Sp&LK hFJ6#܄.Z_ڎ_x3PJg^=!f~vR&%ah 2 r„ww#Y%/N#__2T[nq[?#3-$PM<ꉁp0fy˯-꩏GȀX': IAe1Y=># ̫p@B3 8< E͌1߮#IV=Λv`Zn`h2/RpiGy5-4ƒȁO`a`Ќ}߈K``oQ JFCFf &ŹUx\d=B=u p2B !*`4z*d.EXfFJHJ3]G%h@ʮPb/CzO3>,Y}9"UP`/S=HnХ ?UH|b)uC?(0:_dZ F^H4`fɿۿ&P10ֺ--\УhHV(CtcM^(&@tDQ?YzS ?? Q$ wg'F 3\O<U׶趶0#?: li\V YLǤ {~\%X@aǞ6zз}Xl++/6J܍|bˊf!FRkW 'P// W޷p?WϨYR$ gruhƵ` Pq:k6ص pVmt`Kǚ.;AϏe Zf- \c)—}ٗsϪEfZ6BocȨ\65!f*ުbl\݄Z0L3M>jBylbc P4˛W]$ *Lc1//yځ*{,4%P`ddʯR9띱ŷխ$Szs?s׿%,exEHFpQINzGpb]\@L.2zPKdnv)[+9ug>i_ғZێ '<7~ _B( Wگ}7˿/}K,w^"S~Ik K7쥝 \5Qxkld; S?S?ʛ- ܒ" ԛnwi8\ s7B_rʂ̕"7)Ǣ6N@`:{)D$f:REYgțJ7___Wɣ?'|2Tή#f7C8$A?: 0P2jXJȤ{Уȁ9nFDn"{m)lpwDŝtWs)3|X$H&LXQ>}p~b^=Rǫq:BL̟6Bg=H[pzqLk_|/S^`K@v\RHQdu 5l1Azy菽p b*Ӟ4VSm{` NGݙeޣ(LxLi+ӦZ@y^?#}O9__cRS/ G`in J1ٸx19N7:t3`5k`@Ye"Х 1l$q8)g%*}-]lG%ys `.>c B< 4BP V97!d04zEiĊ?XdCM-gk3 > ʧ|8#~OxF8:{OY`q-0curc-h7T`'cA'rUig= CXh>i8F)7 OMۿ[eS"8J=׼&Aݽ̾ȼ@n}[kZMꏐSd2l؎lue9&|ڧ}V9!l7x=cLAK0ѨWt\)YUAX Ċ F^-TSb(> m4&]xYpCev)Z1\JY&8"GX@}{~x9 Zz>0Bpsu g)Ri,1ETpn &%R`6`!mD8i% tRjKҁ&PQZTF%pdjl9EOt~ũ>>t =q$d*G{DXP곸]bMNsӲ ^7GF?&=L`hz^Mp` 4i68E*'>QςOdalN'9Ȃ+>/O6ڨ;>Y{t !+O\'#}TBt(?UM<ojoVڅcTfM!E/br5Q0& 25•n0P+78Ɏd-1$Śpد<'E8f0O?"c,V2΀\ıc{njȫ?A.C!XR0 OȍW<li5@-,O{L %6s1p2zYd1u)xcAGbej"o^Sf&ZȗDXYٽ eg +oc^b2{G~G< DK<ⲕq`{.xnq{7uد^ƺX׮cT\I_9nl j, @ab96*xc@?Ua'j9R1C/{Q&CzEA=QnfK ImP$SUIE*3Z1ޣ@[|Oi#oˌ{1JE_`qDJ!X+^͂fewGAt[Km>ȳ4 !zG6ǟO}{1VrI3"1ǖej 6j cg8.}?f-Lornʲz{etU^YT=L!؃V+X=EnXˢ65 ͶhŚ(s,D??Y]{p0򀚪o.:5GH5nT(d"o[A@>|E OH&`m1~W?dZ]Ta@視M@ix>B]ǡH jAN!x~׸*/||Ks7B2e}4^JdW .r@-*qt=zJɯe.@h~x[<ͦMࠆh,gs7Ot낳Mm]uJMTa(3&i^so) ]>gl֯m*ה32o imѩ'6.m] s9㛥JT[pP8nTe]a'l#B+yb5)/0 ͨ{ h,uĆm95rԡ ,T)){LK)yGlR&[ LGCJ&{pATgʐ Rt?wKAҗ_u__é=0G R9_Z.ȉHȕoRZ@2x1k:PJwXD _צ4δu޿L~X(@&'M$p}%8{ܚ/Ǜxk !f"JVΙT1;(d@֪I2RhD(FM~3:33 drngbqƝ4c]+(ٓ”׬<F4g΍fS/?NKNXP?I!y]_R^>$OeXDvVi}H[7[ 'li[m*+?ESuM]gearw lCf!94P=Ʊ.~>S 8epLSǴuܙ $/,_VƤs</`H>V)RqfyzbUQ}bj.&h7pq,jֺx`gFAcB;xgmÌ- ╮DOlr,uL}+ekNg1Af$wMMM|К@ćO#XzU.y"=rh@^0n"sR5RYC3h ILM4D I /iDPlROݗρse#S?ԣ/ncpQ}Vځ(QW$9fP%d:;yrLpEgboF(4F!@F^M{|B Tv֣RONbTĦ @ф1ooxЃXyI*Ml*W0)" EK)O`z8bf#މ%mf).(GcMzWE;eEQdvJB5 R0F9\ka0G)8/ht1*-X#qPpZ/Ƅ F_f.ZB"Ѳ[^IF9$JQR[-bTNTHxm."D!^ʭ¡(i&5 `La R,QD9Vyǧ \bYVƶgJm '޾.$3ć̠{Spqc"2#AMiZ]a \3T z"1O'O B܁gKUBYn uN"h;|ste>;}\Mg.B-㉍\ E+]RQ-|, ݶ'644͌XQ.%MpX~@T:o26DLe"E} Ȥ xUAAPl ms3mywMn1ɋFKGT2#{*t5qцWJ_)(AI `/ ́fX!BKW5C^&2:/YG;ǐL;gTMgP{Hݡ@"iQ9T9A5dAId/G&at lА&y&gl.֣J-⿜LS.RaJ㉨c8r"!NWFt_m? [BێmқV~,U;J\ZdoG6|c, /10CG9P"AָZiZ&}֔ff7I$#Mg:/cy8,K~I`R:0@%MZk103b J= [zD+^ L9l|/Sw1`͕A>P\AkU0%!TO{Z$Ka/N{!/<\Wgoy3\YጁT`(;Jq>.5=r,mFg*䗜M(`lU:\| 5Y8!ɴI)вaTi7JzN1K7$ N/d32s9>Dz@Jd y6hdL4zS"8pqE9Sa<J A %B|{fL/PQk.*g7DViKHIB$:@[*F9&~/,`[ 3KAX\# h0m"SBҼrO)g($` K1Eit 0A;޼c׫,lCb)e&-@i< t$1 sYM ȉhJ(#SW V7U3TL~y,*C\* F\_E`D>0E-PA6T|QA'vJ)x% <<nyWL0C ɩGCo0ȅi ~Bv<㭭CF+mSr8I{E+ G&련0AGfZjC=X%H߰@֋5P021U#)PDVW7A$oMM}ZԊs7tΏ_?T 6h8Mq/<=Bpy{2- kQ}-55**C#JWf|&b׎+Yh3!ȢڢBZI&,gf}p!T`~ecΨQn!#/ayCw-n}Y F,w96j-Q<\-ϲ^ή`<q|y;wX8Zg}H!7нby2 ZVuX*P2VphA9VXxEx87 9w^|0k϶ y8Kk[SҚlr5q ,,Ӕ5 5,tk$EPDR5ٓ Yߐ1QQo} J=%G/ΏL)TIepp-3)݌tyZ__N$ V;oӤ-oۤʖx ~Z$G0D/Fyъg*eGh-Qza2>KNjDf#Ra8l- zPHS6 VC䡄LbƆPX *N !CQ 9`vg8k8p\ycID+ph V4< ͥfF  Ѥ:R$pwj慧Gh(v5*TuV2E#W@̇nHHv$S5Mf:M!O4ģZv5jS#Nb>KQ-1me̎o=6nxJ%V7Z0Pa``YnƒYAM6AK CcA i&|fꢩy) =(\Vc.$h22 Ujdp !Ir7$ـ4PT\q71|=yP WhkZc`b:QŽhaѿ#ԢMBsS!zj~4p2ZJx+;}u얚 Ox]ʴk@tpam1vMe0^ 9pn5ϥ^vۦ3s!|luXem?JFIv>px›t`8G宰#ʞ޺=m C-H3.6]l'l91DtaeːdsDޅҎV6]p-AcQxԁi7 dGx` #@oi3ylX[|=wdv>}g1fڂmkrLiW"!cj),&4ab:72I!1їaD֋Tzm刨cJg¦I k9bbRG dRڢbN Eガ^GȖ1N&߄0rS돑Pun\ܥoaۡ0(x auE1dtH|6uX[?O$rY+Tx+/F69v؎EQ?^鄧p[ߖ|Q8?.@y5_Yƌ'];ꐕeMMZ*ikv[[v][*smn_4m鶖̋HQ8wyOX!Yu-XzV{l&CٛHMzG=~Wmtt5/N:#(CѦz^mSTp8A ~4>T^E[I*KGμܙI7dNXy{? BU頡 ȋ]xG3 3(:u 4DL yq">5#~~0j#!l ٕ4ev5AVٮ5`^@"^w}śj:R9 {4JXlp YM=} M{}%yP 4n>(dvP5,K(j,AǣG,Wl75Bn 4P!Wm0}`uu$l9H>S}ɎEb g T!a IqIs\:]+mHl6OE[8f!j|H j$` 2=Qo9ġ6n h/̪;\< ѵ?CBd4p$ן JaTsp _Y`SsmՓů9GG-2WQ"Փ G<@bnDMpF73- F= GpYpxCLp >/~KO1GpAߖk!&/+gVnqoakh]pR}31pQ&,%U# @t~˼m,ME\ځ*G*ҜQ_ASGp=g0 Cr}HyɾkRBA h"D"$)Rp=n" ,@.$[*Qw<"n"r))մxW !|+3ǽ`V-źVF>2SC lM"C.4¼gH_wǾU;pNhS'L|P4NV<{a;zN|}zbeI%JW*CD~ "i۫M>Od!o;r}NTԥ/ZB}w|+|ͰBgg< O1f1t3,M*61V_3:xy0]c < -ׇw|e4ַ{ՙ8nE G.!֔tOeZo3 L&g`"GgR2`'J3Һ}<^5`irJOM'@ K}Q+<(lj S}| }"k>r2@ bԹ #b4`R!EjSG}BjeflH@ B8 8>"بO[>gĴ1W֍DQ>鐎uK%ZD5DZo-!&FxQ b:AU/ۗR8^ MiH`2Owp2AN@H(̼"5>D4>q=r ܑFR^{a~X Q1dL7$)e _뛻pF/8ZS8@pz ,eZ7tV?C=rH [F@|9}G:2vѹo&>DZ5t~$x,R("#Tc3]5<?΀3d#N|dl<4^ 5TIL+$G*]t}yV)wr_=JJ @#5Qﲓ&1C 8 g؛}wPF;r6QCKm6 h ee/3*o%r`lMv??t(ihu1&|6p`+9(nCn.dxhgHYV Q)ǐlEYIi Bya8}VcIr'o^)H[|E3`ۛ@S!鯀hoo8Y)9A2 Mv ʾ>*,. c-ҟ@ӄP$5Qڹ>3|p÷0T; /0(dN "R%:6ϓP  `߇0P\RZWcw?[vv?5`5  9jKs1ғ:I߷x8zw,h2ǘkENyޝt'֪?ӎ\\!4s/]n ]UwD%b]O'b4䂼3A"}h51mVù`%U lٍG+'={GI||7g޾fThm9ק-'0\ɣ9|8&->H״bf'',Y dzQ} irO}c2inA(k cPhu2p jsԻdCY&Sx[9< 77k)B\bZӣ2 @ިDEʂd#t opW<2VfqRLy>o?#gLwZ^x`9Vjʮ|wNpXwLCu,Τ(}<6H,@Jd2GJ8כ,K2\^P ,1?"WܴBpV3-;GۛL `u0@`q㵨uyM+CLRS.դ*1Afս}.` n ar[e8D'R艇fW}X)y_p+b쭁EB{1ll9-4is.dž~-V3Z$OB9VQNUc!OY4" ,EҼW)M՜#gǓ3B K|[:UK!Z-mF3'DA2 2~Y7o+D\T3vȼv/ mb3?3 ULuRUcq.W >3K4+MU`65Ip[S08T@`Iۓ$ǐ+ꋸ&EqϜ&ie;B?Q' HζI :p41A`*Aj>{YW`,n-%p^‰C5mw(\(# CBj%c}L!e'ոGxQ{ch:.J@n.]PW)sO Y=pSnԥ︁p6JƳq晗GsT+r≩IFm?eW8,n,9T k=Kxd,:QV7C`yUD$_l%'m鵿Gc@' Iz_y\'sQx|au6=,EK٢?/R}@IDATrb 6˂:KS GzCpd,^v/U),  z{-WD:}2&Lj Ob}bLjoHKgai-@ )}Ch鏔TZ|?brիٵh AvDS,?d*;Ÿa21&I-' WeHAk*/e *Cbh&=? O]ԔJԳRA ,T&uK qªUPfM$@Qzk`Dš( 63Qk\ K(}ȡ~gxU88؆ C ^:[#!uͲ>V 56`ཋOϪ̣1<:wGNX&XuLӭHcןvګN=U*-i5S|2,ޒ.>-ou7 ZaԋCX:s5q8WvG#TbvIoiz3>+;cfiE6moДsDx0YY 0/o%:ڹ Xyl YR-hog+'lH,3m\Ä3UBۼd T<1eMi ׇ03|2ҰkaDr6_ӵT`Mf3ԦGG1yZY& *-xJ"lg Jܥ5^.x ͇vi`AcrO>aعuj.) H|+RP \LEr:`mw:6$!]`:ؖg$:CvMx{G6 *VH5O'Um#DL;Tm!66A-M%&k@.,qe.,ށf_v$&^I;%ljJ;ҭC)w U=ʅt7MBQYa;//~??VPXOg8KSfBώ]55zc Viiv4[܇鈴RFfCjҔ3阥Qz(c?͆!OޓüTZ[U6/䢄{[iMm='>B7^ Mm ro2A5DZhoc-D؛m/K%.%Kjdo`Px^{Q:4s{ZajnoINcz,H4MkymDS<&ٗZqcG&-^N`YVM=}l('fp(D4e^&1` ̬~a=quLFw-"hb\ tI}B`%%<{10#to}htmŌo|Itk{3ݣ}5 'G3 ЏgHܫ멯^|m_ )m\kj^1J"\h'= @gQh"+/Ю2NdƝ-޻>r.8tiYpaTC`{q b 4۬ds<ǫwBױ]2!{ ̌@!V3vڋB-:8RJZoHMJ:*ő5κP5 ǐJ&/<Ψ3G4Pyx2-e7iiOvHisd _H}r ԻR(T ; GrL{)3P2Q٭=쵦^-jA2*lrQ* t),1 :TtF3~eZk@ PVm&_Ţ S&!;XOI _Cuդ98UnTXH's:Ҡ̛8RkzQ'ҁ“ŢC8. j!| }YbIQ-ԀȆ3 Gל'f [؛B`+E-_BCL^|1M*mIz1ѓiD=f2b˜ Rse'2s)(*U@:1$Lޡ꼉IQoh7o1u(tRvػYԍV""%1{DPbyi,pBTД?G9 fOϷ ֱ]JEa(|<%%C)IdaM3g ~XhIk΁X h5/?`F{5}q@YZ  94l7l(!$Xm ӷ9pQWTIʖ#"Hͣ)|Ե\}itqsͽ\Cbu]eRp,/cr!c^6ucOKg1r(CFΣ3;  3#cOPFl` 3- сsVQiqu˜`kD?:am7Gd4alj7d4)VeEi>tpC`;¤>MD"=&@6g̅^2u:fƻQ jbSb9m}Jdq`^Y/2A/@X==f`C{ш*pmLf_`Q;QZrV5%: cƁ_k8OY̗oAz}'mMCohQϬ80 "jx 1K',%%<3->@IO?7w)fq :p)! fSԩ6f(BK8"V?ǤsLhbQr(QN3M h8fM7355`H20(X[\A%F,j |Fjr;zfi.uT\Q0M4Xs5c8譲pI'!?%s"PrbײpMu>YflW!^\Z%vnch\?hjA̽έ&lG9Bcηr%@]/xvZghVIbArLOf4Q0p<6&u-:ڂ@cQ0 «c!~ h-`H 4Aɒ}nRx"k"Kf_dr^M,Z5S(tLaԃ RE 9.M=7b%6c{ΌfzTu\y<Y> Dw7׎GOk]pp}6ת?8"[ $_hh~9XPr"}=wTS&sBy[\(eHɟ#肅!^MXxCh/i6ߪpTbF q 1·Ǫlo=F{'; Ms6b7URX%sF9`Xc3v:BM "i{dm`n>4}tTKυRiה} 1#P6G>,-lص(k(IF(꨹  fQ rXR9\`Nds<sH|09cp&4|@q^gACtiiG j߫p5LW?(xS䞘!z;-TЂk(PQ:D8r`FLbK=3Ech"fkKyUTaJ!3 s9&bh aէmYM yC}.&2ƥ:svy+xkk:_ c>ɢr#W@)Q|1%n*g M14}%񐗕7~t^sxz:nїBءQHk+F׫6FD_?@~sO[Ж\~ ]"M-!pk 5 x 7;cCZS A,EҤ!~[{`O,Lg>H\?S}cD_Uq~h3ohmA"J/QhF8>J{Sr-A{Vc"yM&9YNAO(ڎь58>EtM (_Ii۱M%|3az2OS!{-=24au6]\RIk[ jGtRgLR`;s Xr!D>k^C~hX߄WM|0&)P|m? _Xǃsnt0XAuNּ=1?HK!1`۔G ,F3 ǝrB mQ@I'PL$ڒ6Vdm<≏pg#Y *YZ0GsQHB9>PnAg_O|Sڢl:PEMSevX!Aע ^.{w¥~}Yy9=f]RsOWw?WKea]i/>_i=9hpPgLO.EJOѸOUf~p8RL4*TX@.%5bGr/k~A\,H%Mz!Nd>!nܯ٠κ`H&&UlO f[WXF;MqelO:dȀp_7p_S f8G*=+NS[K/S8L5 m 4k1n8>P Gg5g }~|X}"vNyWbX770i~.\qU{K]rk$]7+NzM>6edUsTV]2e]e{P֙XjJ߂9/¥oqZ^}]R׸ /~ۻ_t8{ۮv_M3z(/};\O;~9v6޸"ż-1"46|˗G)%iHw7sS#Y K?NF.˖NR9N.&=9(iD8c,4.xN$ٲOS@('},a>I(M/j=qc^NWAx䮮IS:`z@]tʶk1hIB-Ђ,Y *N3 m Y+<}>rJQVZջECoŠir5WH+O-<`3ҡAn eBA_i:Z;gjﯞu0i\5 U|WXEl(Ueq*ÄT4jc^m5}C>\|sFb7X T(@4]! #/S8D?xUC{@>ݬ }0J}GpPLqf 55j0Jt8{чNI;Cdݧ19*MUKk{z|}_ѣ،&oW3l@ҊUuk<*)SW<31Ly44*Bm qǞO8 xq-\ 73n|7Fg:mՌVD=,u6p%21Eɚ˲%hēZf1[NHg‚?'%؀y|YYfV \9>c[52%sp=EhGxYq.~~ĉ@OWボǀ(*3%p㏦aw$}Cd;,"()tlЧ9Μ!ܖQ~KwL$Y6ğO? X)Q}KqtEEXzʥdLL/_h)F1X[U 2_>66Ŷ|^Ių,3P^%l-˔.}&8YUo߻3 As"WR+]{3XP4pf+|{VLW74sPIyU 98HS|7rϮmTfqZr7^GU &O>d@ #d2lGvP&`k* _-m5'n6hNLRPW?_?;mV_y=7?sswI KNWw\gL-WozWĩ"ƃ{͓.yw%IvGaqFo nO̚ %VrAn[-}?ߋcz0]<0[r\(U@:W(Ma9p8HM)/.q|nƵkL݆Y[X3Y9VW-t# c!qZt8#|z[SiƝ(*1\=k` M[vX[jrVc uO<A}DP'ҙ#֓2EB.V*뛽y+Ņ2c+yr4`!ZZhE4 zo%5L0LHτRm@9p0αȤFxo{S ϡic̯~q7c #ع&>cbaiIh1s" ̡{|>?'w%,n>J,I."Mj4 qn;.o{ HHjId˚@\x`#=JF9n喛cK'F=RK\P"lYLe0pgG -b EFٖ`wlB(Ih"xT. W97zͮ=Z[Z[{[\^JO[/.g͟tt]-;N^($@ ylVl>&:Hr|_j%6i63il;-mRUN%dFKNm̮V{[?KbJ"u?_+`IngVE EZd+Ӽy}&^ \&˒Ijr u*c1[~نB8!K㶞x%K *. ?˼ D-6vb&&`]c3V!%JZ gE2ي;m-@@Fz/C`mVol!ΌMp"2*#5ŢBBkb`)n +7 4v' uƦN \cWkUJEki{@jmH{`[A=tL򪢲GٽTX!RpfYT,x:[SD 8v$xCLk <zw.qq7ž@/uLZs& <9j^{] }E1~C8Bi@ھrmC2 :L{C\(A;g婒9 9tǺsA,ZzZO1b]HuLq;H3$|"0b2=*CXM|K p͈ 'al-Mt!!{HUarz `|݊9˯YnRD Lr=rryw|{݋a}'N.F }4:vVb 8URy`TXc`} |h'kV?ؚF/7 4I[5 ήFEYb5BC=pRQ(svb#Py 1<]IdelI;zhQGcPb;?p}V ~ߞnmv5ytV:Vʗ8R8mԳgKy 0׽2: T-czB\\q &1gX٩͋/g:.0!н}gg/'7ݥ}[H&XDDaعչG*Ƌw^FTPfi2c We@co9\X@!` mavRNVp֩#%j3]jTIJrq,!f4:). x&@?]֭)+TJ,!,J%ӑ ps̼!1k,pn7FM(5{T)3N}0>Rv.Rh{ sj9X};,vyzg|׻!!XmːԔ岑 CM"s9?1ZkZ$IV)&A}Y2R4냄E- [r2lsm7:°v5.-57l[Lo#![LOdWi)/{=rԁɢywLӮOmvHaRCܡ^T85K̆*ҋгyr{V5({[#E49wT |C9BP'hM#sժ " G''EM-)N&A;<BrKvUYH\Ckq2zAZӵ}{Usi-S2cc!""bKY\q%I"pp }mv  $dhY> ,(E9(łbXP#zYQ/{JӃt)ϜgV6Oy>d}%Ϭʽ~k[w}C^ɲJe9Jx^V 2dQtA)x*B."Y-VtY|-nyKONȹ=tYLH^0QT4塁8" Qy_ d[5"p(MfSm +方!?=a~΍% zW'?(_D8[5&NFa\HbdpQ<2:+tOE=gB/[}EPCHbmE/JjR+wعqa&y״okP?s볭H'{5Yhj`D Su9v6ߺ1Ja<"YO{eZcY]kn2Z_SO]8K\uKU 0dL4od&MI_o ~ ,:A7Q=klnm+o f]I'h_N֞wL"7v,2FU_ӁTKn:ε`u9{ʣXy5:{}Gnoh՟ܳn??kH~ |m}΃5W4hi罹-S=-=XHC¶/Xw&Wc:ʜwo`Z CLkoyG@f\'B&Ȕ ϗi@MiS.ʹUIx~I@zlΓ&T>9ؾpL=&O?suLiUJӤR'JV+P S>R@"@V/l2|ձy\٭ h0o"͌x!Lڷ-efkfEř׳F s8L,X ! ֋h#s VOxٌrx_.e䰢bz4Ube 2fQosTʖ_[L%*)шNoLD K,j^IRzboMP*HpCa ~Hg{‰'pH1|J\F?rvitFh$7XM.+Q zFQ^;]J[Gy[̑SeMN5ʡ@ƺ76W^}ѷ 7̇wcW=k˯}>Nyf|chkkcm,y4A΁-ZDV,!]4Kɒ RH˒L.EZD [ЖI('SW3rRp6UnMAih3E9xM-"q#Tyұi+QFȱx4b8CAc}*rBţ)7r0ʣ)tm۴s[R~o4)hۺ|>-bvv5R&>@iTgZ7iYî ` U3[8 8VU5YԔ S)% Ɓie噞7T<3L+J?SuTfZLy3hLTMkQN!rˣqPy5f Sl-c5ώ")xw 'ݠ:xz'W&;Yog\G* kf7uԖF:c(n)d1cuQY>˄;:T?u83TQh?yNͧprxLw8u|+u$0%Eʺ,ݎV :6꣆R-yXb $.LgY$a`3`킐 4 XF@L7ЫPo Vi]kt McS,lv UfuI6 \cu;x+Tn(az97l#k'Si("ҎA*l g(ml ʝǤn "*D F(4T+v=6vD@51(p`ug`|p$#Pg˂^4WHnk K9an0evMC8<QQCODѓV{.L^[7DG[FMe--5yH j'Y}{EIN;jKDH>΁.٩5[޿}W~=Kt'i~]5XJ\Dղ/dh!.R<L@8Ag_L*[*ڢ pa\%Ѥ3:^#q!T؜?lMG9eb顱4 %n_M3e++V8 /lY״< +vaGЦiڦGtU i{ 9nf[ӧK N8X´3%:$eZk ť IlgںNfF )t:m]S,9ylK_Fw8gƚG<ʛ)0Lwf>RƙyV3m*5SQ&,jvx6ނ^[v.ozS#nmrr  yC:bKg\KAJ;&J-&8xc˽@?Rh& R nE M^ПsO{1a>䄭[ۺB?3p-O=Lw, ' 0A^,7m{qxȼnE;43Z7g3i6%=Tb|j /1Ck W+<V#cpkl͋ޢ>/ImbΡyYE2ZJ>gHSnҎc'Ԇ x2M;-2Z7hZj?aF)M.[amQPҫ#f&' -Ngd9E*/z> _j;f\>f[ۺs:[ }ɺ|&YLooRnףjdܗ|(L4Vۙ޷<+;>k <;>nze@ /kv3 *, yYTdVQ St*kR9&1@f*g}`eSWO+cPLiy =V>st YHZmoYz"/N9t͔V^Ţ>f`3hln,d{ajK/gwMfHl并 [dZy1Z4YD6kj T]cEA30 YZ0 g 8,RG_q|#^+jЬ|?7C 1xsQh ɆEd lIO3Z483VDu&MJ.J*b  7A =шɩe!Z bl%B2LxaLDG8Fq%>> Z_G%mɰD XMH,ڛyGgq(,LxׯJ@VY=F+QkNJLK^#7ߡ8EZ':J)D`*%R)WSZXB+pkU%j^y&]( CXYH.$8[_%ȔV@TyHR C0_O}vM+d'e6B]}Ld|vP5I8i#@IDATeJ;zB o"sKm`"/>Yc,2C`Q'kLS  @&-9jt"_lT e.f^l'W*"o]6JiZxd2V~Mc_33CS 4ozT 2v> khmxk_x0p82] Ta̅<BVe9 r_fث;)$V*3ką5Geȏ*rm*mꅭ3F2Q!3ʂӳ?ykKVr=.tƚ8^x0X냱yy<5 }#6CI>F_0e`OpTȝNZyj4*i]Cdj2az&-5񤡈5 oͷ75f,,!Sy- D6 S9&ڭMM=Ӏ?8d7+ु0.P;6e> F^ѾVpH}LjF|PM<5_'j;y&Y3YMQ3jٗ_M 7w4Lܗ(!YyTZKiF1N;@L1|OOZ3_& 9N,r 84,UB;j:~T·Gl\׌-|VYtk֭xE>˝0q);B"cO f`:QV*{u uo~[ЂB68[}|HO;аqǘKOI@ i̾H<llc}P`"R_2G&l վ# I:CO}}X}"w 㽔q=Q_PL=_zұo9KA'{~ Ǽw##nsO}ӽ~'9>}VaO=< z @ ?cCbWpơME 0@aoVqv(s*R?`SNZuAL_%i5K'}PW IS]Lkw``K phRv Vò@v-B2u35=geq |ԭC|ɼ4eyxV(+bKj 1)*K5,O0[jkRs4H&/X( #>b|hX<>`]:L@k# EaR-Mq.[ϓQ\ԟjH+1N%5 Wٚ52 X*i~}YFfJK"4Ih1J}F d?~{&W}K_JG[F0.RҕƊMeP}OMTP"!mдnM1R\&P T٫Q?i5EZso&ޚQɍU<Ψ'JȺ:Frk5ݤBg8 XHs2UõɇJ/aR2(- |)l3=o94lu@)&'VZfdEcाN_էm{¢~OZ_s1/sI^w?Ew;NvxQC?;Oܹ]=0yN{էuՃ.3Njo82n+8O@IGݤj [HSΙ3+¡3)@Uđ]>\0cO,$lPv( {`9 +-'\ hC*ؔğ83kb dwbX $^=dtM`Yz3!c,q?TO(I`YMO,06F<"j% 8Rn&#̗Rl8$:aKKArT (@x>P?rbb2/<ؑŒvCiq jD#x4s]='?٭ я^H,LT.t+tQ칉n=Ig-I곰kX+ =[j@wzk%O7~7S*+\Z\ϡM~啲䘐S;0u@;H>ţ}ZS/}i)䈾3ϝq>Ȯl*ظ2#TJOٌ؎9߭"Xg'WH T3ws;N,& P݊L0 ,i&R{5iY9)elt -e9X u@4MgNrn,APp~Jq?n{;g\KнAw=z]?usNeBݭh0pDG9G Ļx&T8ӊva~k%S)LҬW38,/ԡeZBL+BR2315ľnDثr*rAׅYCFdi"L,bϘ42 pGHD> ùq4`@ɉr4WU̩]5 XeSO,St)#XؚГ`Yi;G§s?sB0$2䖯Q7:d^EJB.S4]q.:ЯK$kRKΤOkYe~V.Ng xt؋Bh1~5?&J%=ݬWf2{>YSZpztn=D-zhKRzv̌ gu$b#JYb!,aeR4j󛩢5\cڢU7<闵`E|LuN** x-GxA:+*9 AYjc:7ai7D~߾[vo}ˣݾyn5긣zIǂQcRS!skzWTǬcC\*JbԽ8W]-槨n). #tܪ"k?&DlVsS\zyaga i1P)Uw{tK bu!Fۧǚ4$g~!ۡ`|tL;Ƅ `4Bք)g@H-Cl<т &!XZ8Ls[kR`bq=_$MĦɼp?Y|p@{b" ~8geO } d)fЎMrckQqpɇtt5bsf>t۩^Gtf!ffs!;VrJQ :N1ɝyaXтOɸCZbfP*3<-=a'.|sP _vX^a&Gt>UബS`eߨ ]]'&8=w̲bfܞ0TZyMŪw{}- <[ ;m |" ؀irCFQDc5IQ$(3ho:@nAi'p,*aq1o0s^ Wo"Q*M>:SM?c}s.x/οOsֿlׂgi}Ǽ>>_{ϳμ]e}!$ȳx҂3u[c8 ʞ6hFL~c| )CVQG54PϮɋ)f)!ꛗ7)0)KL8a8e3Pg8/ݞ!Fd aarKw&ᛈWaqx28%e-Z|eH¹ٗ7~k9/ ^s2DZ9rٶBrlR<f5JWRM9FH^*j5`o1(#; ,!1D='L9Ai%i&bdԻeEܙT d[/׬Ql\61) /G!oҹ({P6zϡ`粋KoAn c /A""$G _׽{>;r^H>.*hL UPfl~i:t%%a|W`+=pI0ߚ&AW+BdT+) &> F!8_z|3 1 ecԘOh]٧uV?}~kk9ZK5~?."< NA*Z?yѳ6/$|Dd y2Pjc?'OjFOG>K꯾q9!&=lgH& `] n 4)G,v=Bd\ GNLgRIvq Ig~[)Wn?"h# (hf7<ٌci<,wf6)8]?~n\XkDR$hpXe.bĐY4ev9<ee8PKTrwKp,5\)WU3h@eXˣ kc Y+u)snKCfjn[pFi!~fL!g5Y i+B0v(3j* ,*H/$YT̈(cح_!٨:U^sj AJiyҎYFm+ji{ NyK@SI(dVӺ瓁lQ%L3cg&ofTC]\0҃!tAhLHצۅ`MSLJHt d:ഌQ!8e˴

ODB=C.oF+f<z@HK BF@AKZ 5A4O܉ުP܂.Q<A.+ִ0WDļD6 d@;DDlKDTwHH1U;qܺE5"/2#S62$G$?$_2q &o2'w'2((&2)R'*x.??,#dֲ.2//20031132'2/3373?34 G3$@5d.Q8B^ZP \q7DDq66D X3WZr]@ R T59T `tPXIEMrZY{UbE9aQ3RD|5`aT$/@6E.p%%@@!6J.iT`s UD4awrO`,4eψk \[D?6E 6o\ @…1 `sJEasH\`@@4P4pYC4 Չ0D~f5GC84^V7Yucy 9 DH^zr>XO UO0D_puGݤ:sp AJ?tB8@rAwOdĕ7@:Pi5Q>}|D t_~Gw>3~˾@>̟;D>?X @7 cc3nCƇ2(oR_ D9Mbs`! ,0 Hv䟓#JHŋ3jȱǏ Cц0bH\ɲ˗0cʜr-8sɳϟE6j@*]ʴӜ&370tb{ʵׯ`LN^سhӪ]ˑ]:exݻx6M-e K-7W`]Đ#KLoD3k޼69}1ӨSǤ=YOmE'5bNoy6μ91_kߞ٘,9@ӫl q>~"ֿ`xx>#>D?߃4@uT_AA t E(=Lr#!h`×gą ɰ@(?<4BvzOTϋEDu(P+`$?7H0K,B8 R=AdA#0q+ј'sָQQ8%AU&TW>FQ+d ޞ4L5t׋՗ mu͑_ Ą$T*k) QTx&QXhD3$6˙4! `(U + DcUCԉkA:.b@+PL0Z6Dl;pY'eA6Aʬka},F?xЕ&|C *$!JQWPՓ8ԨE M%]XxW!CcvS?<\1@<-nmD-L6WwmW`J1+b$E`C6 UP^d 3s-yWZC:[1o 1"?ԃ,ddB=wJdo3!tbG+ӹtW^VBK+ѼH/зxXL<_d@ЬGO rcyxX+e8n}#t簱| {!-[DcqV2 - &HdD#k(L"O5'ߑ{C+ATFPG55*a!)"A?ȑ .z0E su aM4(.Dyk!AzGf#Ѩ'vCȆHNު>5oBG RF"&mj?³}Q, 6ѕLDp(بF4RNҏ"H;NEZzR+"AaVp82IY^2!Ւ{ i1A| vt"BAo{$ǠQFJ҈8CTIGmAl1;8z?B"њT҈549G"?D%h0޿:KԍQ)LYC'U)jJ 11e@{iaQU<+H~ѵZUJgQ5ɡ?0xTha:Y)A܊o%/S)+@g 0rVѤ7r7Z#P?CsA뤃eBȡ9<"z/)lK] PMqN]_( 26@d!nhaZ].-h݁4jzAZ|Re bINSo[4+T\wq# IcBnӝ,-8X[wOݒ,&~nRyí|M ?S042HIA>*nBQ:՝v7@ DRhEZ`Z7OcK׎yS3**6$\_I۠M )E"DKzŗ-v5Gi*.f qƪE3JLi8& z˝ d4&.Q!WAI0u2kҵ.XԲ @6 \TY 9"M ft/hWZ .rb(5F!gQֆ>d[r 8&@&8碈(1ԠK3f17|z ʠnHX'D 3 Qݴ12=M4_x HI:v \huh{:X `G f6{H 0;KnR QF8rQ.8Ip?<݄X9s3 Wǀ]8ij( Q(frހ8>c 2 A 5*,jTU?6ؑ^5jp£^2ڈ?`8d9eh0((B>~aqW66;T?7qu c=*5"%d)9Jm1Ewoe3YQ(򗵃CQQ(Rq;љѐ'w8sH6yy;H(>S!S4J5o>3e_9[b>VGpY4HES 6_9>w  59D?jG, 9>Ш>0Y=MK pC=LRtp ک.m(F3X)=dySɛ(h?p0H) \4!GJ2nIP?sL](eTFq9Cp K6lI^JW #]֜1hY0dHC9Z* l|J~vʦ'zڨ:Zz:@N"9JR Ч K/x;ɪ:IC ` GxZzȚʺڬ: ZؚFm}JZ pM pj0-@z7ws;[{ ۰Ka*$ $2 ˱"2#"l  ' P *$k&! ,[8A*\ȰÇ#JHŋ3jȱǏ CIɓ'B%]`B͛8s ETxMo]lov=G?)ŭނL )L:hU ɦ!?8`,Wlgws 2;(,0,4l8D_[pB/?%J7NEG! , A H*\ȰÇp @!Ǐ CIQr%Ɋ&cʜI͛8s'md˝@  *]ʴӧ6P-g(CG)*-!t*@(P:oڃ")7GK˘#JL/:s+P85K8Yx_%&ߖa7C!10\ 6al9 4 pĿ W 8߉=McaWk;(@uIrO?a@?5-DH0 颒@hKF!P5RW@et? A`?7PomB\x\v1ЂiW]dy?f$ ut[2edM@@n\A-"J. C?3JPbpqcj $樧eSҀA<AG$@42_T4IBt$#@trY6d8[T%\Y5Оæ!KOG D$C!Kp\\4#jp)Ϯ @`0@E?`zǠA7 3%hB 4q@KFEnD1, 5*ب@6%E $1PPG-MO+DZSK4D,edmh p-tmx|߀.n'7G.WngnHll{cHActAFz?Vznە53R0H'iD7|SԌĊ:! ĕ@8t@$ ?yES8э"Dc0$>@Lρۙ^uk!+хȱ@J^6'/ YH;56mšq.ȴ!y]uI,3SG ….LXI, Fk:,B ҪL3&@`9$atD6+P67}*%OGrd @P-U8 л>m Z 1&]c] , D $@*)#~H='(Ȏm eDn3nkWQIؤIRIXmEJ`:#.\ZҵWMUDlky-I>QVdiEgaԿ E`g lnDNYg9_prwdWUėgGe5g>  z!vN'azP a0Ar!db'{bzM7>x[20!p$)тQ  8(P3 51gp1n .!; X2@z_8@Y؅[؅`԰`j| '8],  MH7/8хVha ?Sg #08(!0 qP P ;NaE/X qQ`W (`hpˈn!%AsEh  (hh_%0p j؏ُg  ѐYE6rD9ڴ6 iUAX @ cGvqwRؑ\7P 8&ØX2?Q_SA ҀAk` ;Ўp@ЕQXؑ((I@x9 3WRyhƱ=V YHpٙI)p(\h,M~`YBJ)d@(@y aDsP!203 iOAyI83mL@ Y"iț6N&cؖ$ TP0Ih)vI4q')29, ۣjٜia9хr([3:.=Qny)q@J _z8iCnj;Ru@xI)r lh?1oJLPc˹~h虞aszF?4T[Ap;f(jG$g8n C9sLZրLq >u(/rPPVSţSU `GYJspDdL ']`2Apu*1UA(Hr1t k:H1u(9ɲ `u2 48 ?j@? ,P{ȠHҰ#{JĬɧ !q}H)\J- 80:s$`BHk I Wp *A"ڴUr ֠ П`Y$ʜ89Z?૶SES+( 1 p[`jC! '+ z ;Z~yLaW<Or1tS@ID\EUS2|{]` pckПDyQjh4{2Ф@ ѐ UrS5T#H831@p  0H@~ؐĘ _p YXh'$F рt0iGy"\a,[x P)u<E ?n6T{ra Ҡ {p}ʛt~q<-Ӡ?|-` y9_{LBO.Uxinm CBIOC@& D < ^fs2Vp\7aC!s2pe,$QL K Aؑ+UTZRҕ4ů#^|so+1Zƈ&`3 FXT;@?3 6ē30Hd ^(r餠%̲QEM M{aLZ!2^zPFbխ_Ǟ];RҬy 9l"BMltSDP!ѕL@uY* Sؐϰ(ҍE_f1ghZc+_9'` (C 0YAb"DBAHBWyTSIpdlb KYxxҜ%Xd"$RBT%ʤQ'Ww>rT'w?KYL+H;l)u,%R$꠾Q@d e@?~V}}^`wC`'/(YLӘr(HV^@ C0d[O-\f"XP V8G,gY(B*E"5Ѕ.jl1?rl[?fpì4D *2w 7Qt$r=.4M nx\{+O&Kr:,Zb.)톎;eZ(y;`,hGAb\8R10^\J9&2i"0inqc؎Zi~,\Pm5T cOTΝND?)"`EQcX %6A\c&DRb9r'Q},&c 4Jb'E*;piD2.B 1% g( $$=򘅘 J{ɓSh)h&)U4"X? gF |7`", [(XFQ'bBm7k#HFTFF(PDfRQ\e"%pKSL#Fy: b!"-<_w݆k""ӭd"5@(k#u( -D4Z%AN=YFHZZdh) TF&2]gqD$1=ػQ]}<1$ךD. h>}Vճ pf!(iwF0+ xfH"f D %N Xc5ȱ]Ap *E0Eb8S0Jx7n_@V(D\ty.lYخXJZeh(iukS\`8X`<@ ̃61@bL $r ؉@qE j`d 6)q(O( !dPR :0:s%F랤@ڪl()_/*+202e`O5croWP#9 ;*O( nP l"8Λ@ P)/9'*K bƒ.P p@q10 ˆn=819h<*ڋ7lj<1Hd(k ?vjl =74qP'4xX<ӈC(aFO <1lѐ.`=P ٳNgF1Zl`>zAI2VhWXd-Z29颈5=[2s?ހi4 !>+ >ۮi$5hb-{7 fObP{Pɡ?㶘IhgIc*bX7:v𺒨4.BY`(4 C@ʃ+r2đ490\,0XHʺt 1≩C |or |H, 35K&d9«y13baj _%,(iwܯ0:Ja3L!`ʍxZxX11~?pp(ȉN!Ay LKs ԽV0ɠ{;\Ox : `9Àc' `paxpxa`<(  kd/ V{DhH*QL|,gh#5Rj15dcʒ0͍05a`I{(i Reٸlp !K8D@`*W ]x42s*@pT(qqYłЁ3  .)N184(HuTLhƤp$A*}d n<-alk( ~R'؄x+8_c*,Hj \KUNj! pj))DYn`P4eׂ0U-Dקȉ4+‡8,Ng.@,h  <Ыc8c$@C#РU_# 7Q`*ڀhˀJ͠KҴq+kl b~Y6y 2d*ZYY؀9˳؃@J!0R) YZ, 1j8&,˯|M WX[4q ԍB:̍ܘ~5c c(c؆xRpWxTӷ X Xݕ>laa ,,:B]-I״ >i.Wђ` dӥf - bn &u](y('XmRXF ?E N -c0f\h9-S\:^襈(y-YRI #SX )J6f,h]aދ&./k/z/[H.94}hHضᅔFjKO?V*qiedPZЋLiE me pF uGȔgB"cE(ڹVՉ ilct..,+>}ꒀļ B`1 N4v2E8]jg+b2ٔ0҆ qXv hl0j">Mɞ݀]|]`k|~Dl~+9 jO 86k"0"iH퉘go^gVm$7.~ڼ2,@iL>P`y^`c_( /8kҐ+ 9p gYmP_@*>qB cN*Tfq)g1np>Fw f.6hwrÉkc9Wa䢐PZ4_|^a ,(,~]09ؗti蜘t:T0tPDB.-%%BZVEoAQTa'0TrXȒ֣:I/Nbk @oȠMX.%̈LsGwWI!0ЩpL1 /=tɉ/ױW0dta<;'$_6ǑC/C*< Y0[Ti##رqX>nʉchY9CKy)ך=t!қf)(JRonMyʈXu5(,eJ*1()( Јc>/`g (i4&u_ra@ VIɁ&pw|-EX6&@ tO"g[`hxXxUW<܏/0Uhi/tk V ُh&{}"k웳}p8p@㇆H0W` ~9~s \$;S&I+h]y.4xЭF`*7rGVA,i$ʔ*W e^Jx fpˠB-j(ҤJ iX/ ;f0ֿ" sc>8^.U WݼxE.-lR (X`-Sl2* yzh 4A1c0˿OeQA9*8ڈ#_9tҟONy]ڷcU5B)p,׳?j'?0htٿlc&7T8 8pEEegW*atuXІr8%uF ,3DAsA"A d^ 3hEA6AFNP t$/@6"Q9pre4qy5mDLyPO 1杅zhQi6)> +CJ3WA+,h*&сP/ dz+BZЦ:T#?!0 8apгB;fk?v+)*)dkKv(g.ۓn_˯S<0+l:=Za1K悄HgZ%i>\2'2+2{nd 5ZAȴkAp,3I wnyiAD%(J-4?^$1-aP jظ0L@zT .’M~8≟?s<dMAxK S?W3A`.MӁ 6 *$}P1PG8eHx,C+ gI[AБY& Y G `@a(&\oAz₈iAO1?D $SUլ~c UA._4 WCG -1 b$;8XdAIYDRwHێqh^jPO/&l ʄ EG8j` b ZYz $E a"c3nqc|xsqkpnk 6H#$^?2Z@p bk š^sd1:ܼuTг^4<&IMߏ)wȳJ>!H؂I}i8\Vfs"5;mbm$\(^ክl Ft;;_X[bbU 7;XވNj$)W uJ V%Mwٟլj}8LV ^ PK j'jjP!BIViUr{F_>edJᨖaPAA?  &`.F NVZjAG E5,H]y] \] Ġ Q~I NIГI ~t<ܹmD ^!JA ݐM&C l!b5>uLӝO!FM AD8. IՎZA0Y\&OIn%S þ~MxZ9 T ) ȓ EQ86):Ř[qD8$a$Un`U/XA AAAd?ŀG/<hϡ).?A AxbMxD"z?2l+v5fU}fX6LI M!d+̼ljdA@h@ f~)ěDk)hAr"s:rDssgfUQ`yfI1ffh  v(FI݁H^|&NlʼghvED|Āq*œĀBP~c d y0PjĦy"|R}*BSB|IDE8@DpBGpqŀÁDp V&~?)HF@yDbA$%FXB!2)x֌e@/DhCIuj}q?:AhR8LiLF0]N? A?AY*U\+BxgA??4 P$AK1䀢r3Ъp!p4<|?DBI@CBpābsN@2jA4 n'-ͩ4ƍ!>,Y\2@6$=P ?@;!}t?'!e2@4Aܛd"6l@0AL@6TU <]O@M\a}/-@CҪ狲-?kHk0u.JkV @\0 dAxOi4mY?`@MtīM#LG0Lɤ@"pŴY",kXPK,G(@*/)v]˂јi9DŒxDl{|(B$-GP/$* dMDiBn|Ilc,GeEF`}z3E I,!#%kD,{$rQ ezҲ.[HIZi).D[6B YTG3Iri1g#ԘDIPIjR,2vxK2D286s Ak> IYGze@Gܥ4=@ D$Q5F4a'fX퍝Y\Mə@d<X 0i;р9'Ŗ'7LJe5ziAA48 .B?B3cUD7MJon Fp(xp5A0&JCY౗F;·,B$+D?4Cd :7ͤղ@)$)y1pEk\6 SRj? ,<ȏ|Q]Qr?"CPoIP©PdC"R"*P?@JýMMAPS YAxVA@84FȸO cAcG`kyzp~A AgBΩf:G3l?恴Q n$BgD!|́ R# fO>f`r([3nH}ZPiQ z@ Uii}Kjh*@7`A&TaC!F8bE pEA9dI$7 #S*t#˓?:hQG&UA$MF:jUWfm`Nϴ;lY oU'΃c*@ɠ!~+:`-pi)\JG  "ȃo P2Fy 8 ,JTٸc=?.YA&H[a fIIH@X傦3l=hf@w %y-<)`daa@5N0\#p ,QLujlV@/VH4& OdVH@m8><0Rf>q+P97d}TAvW=,XƼF{|)ܑ+hX`n vloN(UN^`\K_}gh- }*g?^- JH91A n yv:B(" QBO-t aC qC ZH=tRrDTDA4HH$1F$b8%>QLEB]Ԡr;V ݯhFWitF8QuXAE=q(#HD$!@*r aE.\F>Ns2PAEZ4}G"9ܰB~)}DAlÀ@f##Y˺A@< G@r7AvKm֋Ez5e! 0-Ird^h;OyΓ=O{~\F,PD.2𐮤L7yED-'Fwrh-rQ*}1eP'j΢+)e='Td EQzT&Hu 8U}!-=ȬncW:Ͱ~Ue%ARJf[*PUfYWux"7Nƕ oZ.K}jSYNN5H?YFd^+XfA f(5mกTqj_ ضmi{[v (A^zZZ5Uy\.us]Nխ 谛]n؍z]񎗼=yћ^ĄQAW};R(z^( G[8")B~` 擶$;a42v듷4ָOU#[Tv5&$hiāWTZd!;&9V"ՂhB|j䔒,ѝ#/,e):  Ri FZ)"\|aģ +RQ9~pQ= FRUoDM9G [*Ş shQT'8!FLgB+Y96䄜 - ?d^M&!w}o}@=")xC % <:;@y7XY%M&W-#\s*qs=ρt+9 ё~HxIw`XtSzYpuo]ve7ўvmwwܑp19DБ`&Q iB0Α>N=$DG|Z8) C "0a[/Lw& "|T d!b"B&9 i|BZplT 8k#IIg%7y>h5A3DI*" |<;.I/5h!@C "%/!t(EB"'Fg $['#a "6btk$UPBʍ!B" ' $! C!L(o Rt`2RIz`%#/"Vab2 F@82.!ZF>0  vb`&B>@ '/f"l;A B F )= 4 o($R6>`& ~DZN8#"!TOƄQ`'2B t@""@%7b|bLr0[bbp!zsBz/ |@tD.:Nr$4:z)> fnBL"U`% x1"ZP>? ]!//‘^q!"%n, "$5!$T{aLn %t`#zwO"(S!nڢU1%kQk F2,6M&#k!RTh/k`)]B`* GQP f F " !H"" fF -\+:0 / Wf' RP5& B5/[1![/`"er%6s M)_t!֡+B"@ |_. 5v"\)oB"N9Lit6X0VL!eDWbG !C>:#Bē3L0>!.4-bc $@'u%%K<) b"[eB 3"'o"#]%0m F\ 'O2/!r$J+A]' cZ!XB 4 3C tF .6vBP z%.'q~ P& bFVO x'C"nL0b2BpEiO@mcҢ> &`!:@bF B~&3~q+N3!LA akT ._0WE&fq03"KE'V,$DUT2!C-93Z# *`P;J-5"@80!4!m tAA1&Uk# P"&4:EUp~1W&6(ob9/4!c#08.cӧG"d9cbfg/bf£PPa Y:@h)h+h i-hViG3h!j5PjGij vh6iG6iV&_.f3?SXgkjVl6h6lph7pvppqog w6q,rpp5tvq 5j7sVrVqrpEWrWjto77wSv'i=lw7#<@]7xbyIj#j_ yn(! ,U> H*\ȰÇvHbC3jȱǏ CIɓ(S\Y0cʜI͛8sɳϐ0Jѣ;!]Ԡ2G 6J*R;3ekrKٳe]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ $ TȓoʣKˠ?0L-Nl8pfɣ_Ͼ4_u\~(h&F(V3fv ($h(,0(4h8<@)DiH&L2fT6)R@@31F2P6GQ\IRe?F)g\i着Ic |ɉMq)qE:hIN,1c,JBP+5jP;s - ĩ@bC a2@* v:#05<`+d@2sZB>{g8#6l3з%ͻУӊK-6ȫ? tAAڻ#P5@ ?߆M3O=?oPBCnؒM:0CMͻsУ+PS JC`# A{ N<N:=;}r)6@-͆P do4֨㷯s=193c+ήD?^D@dK2R1K,A@+y܇6ݍ:;?@>Px"#Jҗ L7Ḋ݁(P?):tvףlBd<Ӵ@ҳML4Xl= }4m02!ML1QzB-Q]i#f zw@; <'[O̾5vimV_¬oiqvMBz]AQ*Ga/R?P @TW 2b,F{Q~E? !]4?F34f6`XpXc'Vgh5u* pA x-0ʕRdrwsQ @&J(ocObGy]~)uc-`-0#2/gУ6&2Nr-Ƣ*$aglB փ*%AQ2$R-2C>b-/Vj#\)?EsC=N- „ 3%CRc9fMcSG{}f*3Ɛ/`)K3 +zňs%6rJ:T{CЈ"‹, [D)*HzcȎErE}bH!*0+Ps))tr9>)C,oV Y".؇%r'w}{ȍ'E['9"B+ @+ rpJr`ȎH{8Ƀ6LpE֓!bA+)3‡guyhuU>go>T}oYGsH$FS@B=D]F}! =\.\!_J>!NmQ þ-`PLx;hpxpv ! ,Ho: H*\ȰÇŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCf `ӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(;"y 9µ7ӎ AC`deCІIN;ݐ@`,8z΅ t,,M75SbP?B Y]#Љ;T#A<CXDn@v%SP:A86$yA?>~qyѼNv#6㦙- ;C@zäͤ*1 (QMv9P45Z"G+ Ԍ2(M1.9x#E 3+skNk6j Au:ЩT.>̳=x̙B$g5?KTXO4 5lP+jP2 @/of줣!\?$2p+MlhYgKDBB''c+rI`3 6$)]r@$2 =1JhohΓC@!,?0W߽^T/2HW,]C)xv&}0*_ }{$@@8hA IJ,B`,8UjWֺ f[6Kv[MrK[߀G<\W&E* U@GsUDI?v1T:]ו/H4rh7tL`>;xo*Cm* p@Cu%GW.1S[8ጮ*'׿o"?F.AXAB)H {h e/^D^偔9`sϬ07+HoHLHLX\ AЈ (̬zO\xhi?$<ء B0UquaYךֶ5wjzR@f{Ҳ6ve;ʆv]N3Ӳ@n{MrNvMzη~NO;'N[ϸ7{ GN(nOW0gN8Ϲw@ЇNHOҗ;PԧN[XϺַ{`NhOpΙJ< ! ,Q `A(ȰÇ#JHŋ3 l± -`邥IR.uxIs`TXDH9k Hnb]SUl*Dmq[STg,ٳfӢ]-۵8q<9}JV,0Æ#l.AHgVumd0Lh*;EJgEjlkf[vf.08^{eΣ3c!YgJVH1`]Gh_!B0bDBW~ؐB s#?MX@R(!jha ЄO,ދ! ,d? H*\ȰÇnHb3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sRFy Jѣ!]t`2I 6JՁRkצ|KٳhH˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺ5S`cX뺶۸W#͛cajƆAh@C318\Sw#^'nR_ M ۿ+_@]0nfF{5 "AO f]!%(h⋁tD0#HN|bKY(_p#E2ĠK%j%,yu䕩QR5S t&OnBP ǦJ5ɢ%Bx` 1 )@ ցw8lÑHtf馜v駹5ꨤjꩨꪬ꫰ʛ #;ʪky`26 ;30 {@,cT A[# kp,.|,F0@ r҄Y4(+P5Pk+Lw- @l㭷G95p0!43lSM F?4 3sAiLP; l,(B+<3SM60,Bj  @3p4h#`/!`GF011Bc(Bqc0)L, h& т h@9p P`Bcha@ i` [  5":iXPi Ck Z j`]BCx8 >p;bF۩,1(IҢrt?jp P?"DJJCfA h Aۉ3|X'"B" ,<Ί*} dd0@X@XW/Ҳ"9IYI)Wd̃xTf3@\Ҝ(^i})K)O @\6db&D) `)$|'A9HӉHm |<$QF:͌C ?)cP~hMVc 4"ִ!©@ rFэvt (A*5#@-YTou\IUb9zVx ɩ1ՁY*XB-5kAaAj0a^]hX G;\zXu4H:a3qZ5"UJ$c"VijD5a1 4_dӡ@r̃XV-82hY?p̳;iA{$,MjZcx5(?JyTet&PSBzp k$aIzT E1L\lS`@D" 쩗R$9 "@@?H,@ԘT_w(0WA[.}Hpǔ ;R*p/CO,A (W1[f8BZ2dP7ȄJL$R@":Xwr23ml6WgpGy#[lHa%vA!1p_ZkQ jk$wW4 ]AߩZ^Y=BjǨ܎ ʩ1 &jwnId! z[ $~+M7#qBC  hUG6 a@/#Jp!p]z:i?R^ahCi3paTH c\a7"(^X-=hp  r)P y--PH2Qf(9'xF BC r0D=EMež%^o~a#)'H;$h4vwO8A D @VIlLy@H#>λCG7ՙaCxfn;fAeT t}b CH,# LAtb[zZAH>-vayP5^-IFf2 ,e P2'~*B4G#Yk&0!fJE"I)a;1k[\cA 4y`G-fm P4uW4I `w!ƶ4f)~gǖxoal3)V2ˆ8Abcu [ %]DevV 02nVcчo|(3p }2vH7@"{0W|sanYHjzdf7}yC ؉s8' !yaʧӧF{2a pw x%xS q&$y0EaQbi1sY7{ыC: Ay@PQ ֐E8 Rq .& %] xyaQ]G㑀ppبhRp1 e1|fu%3 0 \4بC\`1Q$:`h5B>YH` )`JYQ鄍8 <@ P9- ! IB Q‘qs5 BHyIy pD Xɐ p!  A]Q " BY; U 8xAy)}|D1sfHNW 'T&Y)9щ oXT5MpGs Ypx iḀDzI`qw)$c q7VUv ȝD'sp1Q !wB")A }es1G$qO锞9 )R s "Pܐ 葘ch1Q$ ^A X, W2I P @VS$D.*aq pp+p и "QpTFSxt A8E<jp;b"d;pکdmdNTty (ĶۚC$h޵uSGLF; =+ S;bAk1`O ;QG7k$?cT Z ) ˹Kp$}CKW\ImI1 d3ZC.;MKEiC.Q*Y8ZG ʩ{zGr| 5HS,I G?DE`zO+Â'^`n Tl J*+&<'^@E,I$E{J|!G vpƼ+ oS͌$[ʓ~}M@MMP RHp q \ pէW0k po P `֛ ! n נ  v׆؂)& e Аߠ  xc=םM*) 0 qp p Ӱڹ`q`@z~}۟gE֬  {גMݝ2 Zr:- } rߓ>^n޶a* c0rr ml=Z &n\@dW.6.<`F0C8>A.C4NGnBEI1"bfHC}X(gb~cd~gR>13em^PA, Mwv t|¿7! G>a\jp6EGfp !f&  0t^ @ꩁ׺H#q"5# 1Kmb#Y/,[jx$>1鑪zNJړippQ<4"I .lC^9h1 a n !k1U$`1 a&%V O 1!\0K$qT6t#N"?ư`ۏ l#bMTQ`N^#6 X+q ~>2E{/eۭLuOF =2:yqA)-$gA!bNAW>a( YnLEK'Jr_C3lq?ܰ {k!d(1) 0aٺrgh i`Ijpw4d Qo @?(MO@ DPB >QD-^ĘQF=~RH%MDRJ-] ęSNTЏ!@TRM&u:ZTU^uVTs\We͞Z"FV\uśW|$Emv/Խ x ڴ&a%c +/pAҕ]" t,жHzpiæL`Ъ}")5ZȽwL 0w.;^^zl̮00a+ D0Ab@3ɉ>*`A 7+8XF:@j8+ChѮQM7SO?1B%TS?,=UW{4j'.(EW_E[w1 ׼a RVa*kKOf" >v i6(in `dۊya?-g<w@@IZȹ ,y}x(e+8c7c?9dadOv-~.F9f[@gf6$s}&'H W*j?N:;l&lF;m -ȴ zBm KDgAZA,z+yB7C:gqEE +]B,%Ig[=vgvo=www>x'xG>ygy矇>z駧z>{{?|'|G?}g}߇?~秿~?`8@ЀTP@6Ё+&M&PdnV"21)x<ǐI?4 hD1a Q˜D]F.,h M8#24@"Ap4|E@# cXKG x1E$F Y]wBlZ A%9 B` IJN+`"{GЙP@ IMҔDe*UJVҕe,e9KZҖe.uK^җf09LbӘDf2Lf6әτf49MjVӚ&^HGxk}۔R"Γd#* 9y7}\ $,uV":@rJUϑY@ga @>x9΂U#0g#H ж%((^P*D: I` (; Δit;-T h@yD^=a/S A@Dp; u"Y%*@W1jAf"6}Tg_n>ъ> 1vbSV.$i(lzǬ8Nҁ UehX,! ,}: H*\ȰÇ#JHŋȱǏ CIɓ(SbTH˗0c$柩8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞MmK-y Nȓ[vУKNس#;W1slӫ_/f -}ٞt~BO vDM}@4hG;3@^("Ed8P3 A 5TO:IHP,6?xD" 6(AEXM=?A[Fi! u!9218b> ehx9P:: W1?d:<a芡3@#+0|fO=O^V`ߧ0O=@flJ$3ꭷꐳ,sL+J+6 ĪPl|",J+O`A?~VϵS+-NK j[+ ?b 3;1ZOBsAy\ 1Aԍ &?s<@!?bs@S 7_+E2,4pbSLP7O2ACNAtC7 )ƴѴ"1L44cˆِK}6DB.IU  DL67L㱅,w373Ԉ:?̝ M5's2E4fh6-թT%Ō\fiM| 9_\Cp<ȕq T"7ΠBGV#b6G}ZϦbʩ@)cig(&l! TcO:} ~Py ȡv Ct4T6hJ߇Ӝ][`BjuUhBڒF >Yݎ"o.Yvujkb7l`}?-WL,t0 %k;yw0axeV"e d}l=|c`zcFB}+])g{/- `]7-7~8f?f%Hr& Mw4Pe%1/vE2c,jR1x.'w ~Hփs{Ba DH xmW{wT/71(.0o0 wEwW 0fxg$aEfcwH+ ۷A3_C,~|c|%_ Ӈ4 2?X5c,z؉)!}}f+b%A(_ȉ!(_Xxؘڸ؍8MpXq ؎ 8A @  Џ 8yA @ i9yّ yȐx q 9,y.i/ْ092)Iy!i#ُ ?y>BiDyx8I<ɔ>Քl(+`r`!.cIf)eykilm ngrAzzI}9 )IYxYyˆəA9 -#PPpY`yٛ™- XᚰY H;y֙عٝީǙ9YЩ'y #)︞E)O 9;ўI Y (FYz 9]:@@_A,i T_qx9A_q"*1<kX} >4HP }GJa d]Ѥlpr:tZcjz|ڧ~hj*ڨgeԥD::  ZzL঩ Ziqq:ZzȚʺڬEj:]Ojںڭ:Zz蚮꺮ڮ:Zzگ;[{ ; ( k(9i &Iq !  ;"nq0 3 11 p ˳ a 0 )k4T j@!uZ1a[f{hjl۶npr;t[v{xz|۷~;[fK! ,K [8ć! ,L! , ~A H*\ȰÇ#Jdx`ŋ3jbxdǓ(S\ɲ˗0VX1͛8sJФΟ@ J(4`b?}I  v"x1SkmNO)0فZ`G,붰È&`XVQnO Z"oC d`&?$&G˕联 Oy`3MXp,Czvvt ν-*<+I :TAn- `Tui݁]w?y%A Ef/d?$f $hba^`tr&lz?d4Í"'&4@ !A4 > g%,埒difQ8SS_Pp*#W'{3SLqBU3~$@cA@L g~1?d@ Ѐ@V)A'4@["P}uXjC!iA\`]4BweuӰ&V L(Y\xpR@Wl+.Hl ft*kfg}+,l' 7G,Wlgw ,%"gf 4mAB?&l+ӌ2/X ,Fj$CڼE8Gҹ& BKu -Zf2۪ _ȶAoK-OMS .4Q"-?<2u7P%Bb\A>1D}29ՏR| f7U 0, . =YAhRTx A7Q?d k\{р@HI/ 3+ B'ԉ @`eY( k*UaUh {@|szy 4! 0@` {2f "d2@"A3}gP2!e܀B  "(gJ`^$J@="h @@"a !pӼ7ҟNucQhsf`|`>%F1k BvE9.#!ɶb:0{ dyBC` c@)+X%2g6"J,o"9 N+d#Z( (+a؀ He9oR@2PA"}l^~i@340 g7y@\ʲҁ ^#?{A B"ku.APϨ (7DS6h`7g΁ ,$*0Q~Q]'} ua)FJ>ND-%K T,B`( *At؟ @@PN!(!Xcҋ|js1}jY,kNT 5?BbKkVf!Ge Fn괁 'z١3 A )>NruP?1,A 8UIJM, n(8V7-Ij aCh-V 9@ ց雉%#:@J02>_@HE&&+Nr?cԠ V9\r; :: -@Ef!2<_ iQB$2ތ@:0u3ykbK7((#F-$ݱۊ\DƄ:F!ڥq*[Ȋ/[9 Ή[ \ p% rQiS%92@t^0> Plj4$>k.V`k>6F/؆]YT5*0 i r B^1?ȫq53(3d39m2\/ہㆹ o0Hjͽ 1v y XVE*`,c @jPۀPvs LNo,JHlpX*4L&qoPF̟ d3!rH+BB ?'23U:aŸtL D#OW_Auhql}.Y ?g '8AycH=jh!"%2)bh>ghs p)G? d O-+8~~gW( 0PP ` ̀acA}D4uJ7?!\~~  0W7_`Mɀ$xq{ ~ ,^N =H؅(y\̠y~'a,hhk z}`X;RVkO 8 ~,SY%C4:{xa!H` 0H QT(mfh~sE(2g1axx14g#F|(,h|4XP iah 6FָFJh/x|sTHii؎xotX1N1wϷn@Lx2Uk~xϗurZׇ)7 va(P'N C.93=o;NH iH K\&; H)2!8V@qP)j'[ }斔f2 6" Tj6)> V 5Xh@*' s1#}h뗈5Uy Mᗏ21Ly0pZy asZL$qC7Ck7 u٘wqFC,)Jě' 258ȌuyI9a1W##_")2i9 7Gq)Y&EMfDǎ;iF1B?IVX=Ȩuyީ|`~bP! s Q3S]$U, %A?mU9FRH sg$ 7$sגEqQS0rD@rGa0 kj71I>` k@ |přP)H5Yj,0ls=d:>lZn  @(=GxÔFЉ@y<~tT לW))43 F0 } `k ra d=:<9W9ʘPw Sb"sء;v!M @-p"0`p4&Aʈ XC;g7=`z1]RpS0*# 0h1 wG#p~ހ;a ? aC'=K ƀCA 0q %k @LRk3o$-0"LFxV{"! G]:+@\q [P:Pǀ @iA mN+(J2 j˩/K*@  9DY0p `k`~s` A sd6150u"A6a ,vƣI00g! ںa#|j?6 J0|ޠk0ski \5A"VG8@0- c 4#Z" v:  DAڳN;t}SWQ[10p-)f P@,B??f?J2A|\{ O o{| Adb; OqHjTl,,F/:g!M7j BT=L-ų pɉ Դ@\#Q%;av"1:C%rt1,"_ӊ!ZM} G|݀ ޥ*YSINݶg / sj .i5g @ ySNרHlհ H * t ݀4Щ3; b b1R_?-aKfHސ*8ŕ]mǐ PvJMS2 |C:|` ـ x0 ,khsP'Z5 )(RK5@d[Ҁ`|V= |AKnശ P~3tG 3 p/ )!+UX--1` - t rXpmaQ-|nMENMPB>H|@wՒݏr24!4rѣe.<"<p Q:K^\s`pPjq@c$5 ]ZaK}x;|^1hQl9Ç vu9 P eNfó2M[(F(TQ[ނ_PX6ej=ә ڞqU몌5ߘM>wGʫ| P>Ck901,hzI;;л!xCa !aFU]<(s}s6@AU#ePt 5#ֻ%0+D+ȭ5xʼn&s3d&L2pGQ6HpMք>_p#7 \q q;tgku=wƐ^xWӪ7MB!Rګ=Frdˋѐ p2N;8\J]bĵz[5n>bO@ Z`P >QD-^ĘQF=~PhI-[AwSf>uswMrIMr?蟫 6 j!!^Śk&8̈+;YXA+AY2"׹}wS$gc Nc)WpM԰Fc;O]pXŵ5qa8M ,,A ^Iȡ OICgaMpBA jQfWdi񌳑ЉZ!P)Z@[HEPh"R :2Dxv/L9]t2҅j W>ӈG5n L~t' 9^\cE+.nj԰ -a)&Fcb3JGRZEu*elvS1 bA*)rC\D.DjTc w#&FzP,"h3eUBĚ)_4 $q: \'""I-LG7,Iς<#*@F z/N$\pJ7PPT!kMA7pԠ}4@&H g;9ed WiYwc@a(n 'A6 PSH J,9$pFPw} i9~d|uPAa9dH ZAGB55+^#x80xZUVU*@ d-EY .K&!A!&.g* 9\XDA8p_h'Lُr`q:aA"s S\6Z)HO̯:Cuw K&ǸSһ6$2GrBa?' z+r. dϲޒ{RDNr? qX n)&6Z4$MBZ0'+t]VR$5l~\z Ǹ!t $1X9=SD 21U @N 8@٪VvcE|Q.VZK +:J)OR9%Ps+EE?ѕqoLKZp)sė.u&7""Fϥ7\ TJȼksH\7R50A܌ Fg$9!kˆC}| 5?qH dʓ h\"HԠ%"I@!<Aq ~ ]b"iH&_d-}?::$5=1r% b2 Ɉ?(yԸX:qI  3Jcsp XY*J"wh@x/X TQdd(cܔ'* + Xd^3@/i-A(69tsTxUSzB@^C@4i [*UQ"^BKZX% =3c${ȝdP> qg8 ۣc0&sȺL#E!F1[T < C#c*CZY o)x "c @+(t\1Z !@UY&k=؛ZT43DL*j–g\@<;dk97㓈NX8)Z!^I@|~jBZr K&N dM,O Brkļ kd@ ! zٴN~٣EpW8TTOJϐh*_Hf(L9N5U=g#)6ūEdR;M&<5?1a ˜,͜P&X.pu)N% cjR)@XV= ʤ`,d@8`Z{WU& ޲\'DZGEٿؓ=cHS28hYhY;΂$XrҔ 6PjYp3ڪŊp-LԂ5VZ=Lehֆá?1fk:6;(4[-&,Pm#*=D`M0,V [nZha}kpI-ȕ}mHU(PT(F0j 寮FM (poUnVHWIEo>Z4hTn0 I&^p0qoN\8*bE ߣ 540 Ά_qm,o߅\.hpijV27"ao@PO ;؅LM?sMML6cx;<'SY*IéYpP8 ^xP74vvmmvlo3vpSU BPWߣ0aND02I b(V#^8vrpgwqoх͉';᭢LOoxo jk,q=*_pzz'p.nGY /:%pDU_ ,xK#ĄRiբ^7ikp,+1|(AY 69D^^Aix@Ȣv#A*`=%c0> chg7tKi7~8d>XpXd :8kd1d& wp VQškXk #SRЇxS<,h ZFPA1`?k;pw %F,9* ^k9bt$@,="% *Ұ:)AnX+ذbǒ-k,ڴjײm-ܸ0 wEfW (2Tn`),Ɩ4埍,-1&`cB^;d$4*hlH@$ֽ,7‡/n8)BʅVݍռ,#TPANXЁb.9&+|wWhST?UoEf 1 : J8X@&?E@{d @0B]f0 PYؔ%$Pg7S5WM9 t^Y,?1@,u@HP 4\G0E!mU@9A -B |{yCpM)%d }IP]yڡYYußz nJ$Ь+Š*rKJʊ֪묿*kl3Ͳ)V:Z[.-h (l@ ֫n/^;[p*ٶ܆U vQ!BQT{R8uqMԴP(mnM <਺Ωh#*"3<3Ω؜s;\A?LP*q0rIr|r՗P #v5rB:*( ܆2>Q Pr(6#BK.@N˪J߲*_<>h @L IJ?4x`?}$dKB,Bg?65 @ԺAN" M]SA Th7 MR8%0?Y@ټ@dX,K*SwBשq \F`gI$9Ad<$ %04/0G,Q B2(`6Y+0wC/I a3L&0C Jp }E,yXR_$#VY,AhI0$@K{* e`޾7ŋ2c腳2k!n +G1 YjK0Byz!d(D2#jԧ1K WEaꀦZ4uc}@ aׁB@44h)L9e `A"X&Z\J"+XmAz%ղ8Y4-6e*hAF2фh-rk$սnw]ĻŮx\i!_òZ]Xb`- c \~j" , SH\pyk V֕ *`pp7K`saA1c,XpG],U!9QBZC@HGnE@XhBY b0< 0)ԁrL<B4b6 ߴ *GƋlA$UA,!GT * ^ E6d`Ƅ!R(@YhAथ8]A]@}:@[ 4?@C  >-7e ~R/8Ay^(C(0| "@4hyC$@ (AP~IbAtH% Cd %W$a|"Xz/JjhRtUm]`V(K^O`_>ZyD"軹 c>9=\a D؋|>#M>⤃ >??'??TnSAs{}D 2D84|#mq@%T#᛿??O{O@mJ[@ &TaTY=HῊ)fFArqTeK/aƔ9fM7qԹgO5 dĿXH_- gÈ6 IV#v_gѦUm[oƥ@R.{$+gEV( 'VqcǏ!;>p e>ԼqsgΟ==Zti'2ukׯaǖ=;ff-Sm߿>xӦWB.G>zu6^jvܷw]|ɣGpuǗWkb, LlA O?) 1;r# A QI=',QYlErQi\qQy)!"5!cY"( HIPҕ@A%Tn<׏ ABN* b4-9c"N=A=؂Q $vo/9L]:=RPX XHȄ u U*{ω*.]iuptA-AͅHHa*_tT{ *B"p␪F)t;J!܈:Z0% Ja$?z 薊ydB{5.K%>bѠ[>`dӯCriþC(Em XFd:jA Cb1؟)FqcJ 3q!Z( L5lt8lG|gbz1EÕ%7Ȃ`J0 Z h}{?`mp?QD(CQnX,dA 0x,- =['kGPA~qHb3k$-)Pf~q h2r1GgM.1" -:̞;=uQ! *>RYU Uj̇xNGC%3B * RB=KTȂ7ADG1!SUfX%"H %HJ*60ɐYDUG1qR%x9 Il dOb(Zm@kUB/**nlOX4B mG?`eimk947dY=R9K;BbgeEQ 9 +0`dۈ׹#{ѢGVp?kRGK@pUb=;%qط^: bvt85C[nÐ$)d&L=bs/n4q* „<9N1(u $= ߆@9ʆVAsy1n|kLf) qѐ KEZS+` 0z 2`)CO1+4M$ j-jPeII7 J@Q3F2IN¹L5腰:UP`W'\d 7mH G2a׹@,38y-C ?@ѷK#?tI#KZz;8jV$[?J@a6נm4|5ms0gN@#!`E󞳂?9Ї.@y UD1:ё.SD|Q)~ _;e\ ]5N2;jr?f~MOO}hqnpr8tXvxxz|؇~8Xx؈8Xx؉8Xx؊8Xx؋8XxȘʸ،8X) 肣rQAXh0r?.jxQ"h! ,` H*\ȰÇ#JHEr\ȱǏ C)ɓ(S\ɲ˗0cʜi͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ ,t/PI^̸ǐ#gU%p˘3k̹ϠCMӨS^ͺbOhA[ERj7+RCTv#O|rC ]zr{;]t)}+UGGZ(`o~'`4 8c|r_ȊBarf``S岋6^{ Rx"}3P.Ƌ*-R8^?Cp"ތRyWBer[V`~)f~ıBA#P$bqT5 FIR)np'Qvˣ =#NȨEZCZPK1 u*jk*뭴*A!lJ ,(pH6?: ,Vkfv+{c_i_ /X,9Wޫ/F,l' 7pk>, SFRlk͛65E81At_*V!UtӦPJ}:5*իQ!4Bi L:ٳsE 7h2-.ZmvinHt")Ȋ)G#^1ǎ#+

G02dԌClrLě' \ B AP ei -ud\!sҚ1 lau e3p-Y5%oß*8B"۝B?w@щE&ߘ*%~O>7)䒅R0x#:CzC<ِC6l3pn;TḄ#٨<1 BuC,b2s,10̒Qs 11p_ǯ-K>QP_@jgI 8x%PG7r=,)wEZ+RԨBԡm|2P\{%,-laE+0@p_H!A /B2H ?DXuH%q 3KWp@*6Z62 (G2x#rWGYĂx5j>>21?ІL` :>YyxBqJ"yQ,Z ЊkcCN!%Fr Q2}2Ah|/+H?L |I8 r Ēݴً 1L{80(*a DIJ9B:oHT†CU?)KȮjwE?rdtCQ Jt)B-:d3H:\U ^ҋ@h3>$ ]fՒF81u#} 9u (3H;1{HcqH;b/*1(ح HĐM@@ .!=$fdz@ȱX!` qh(C8K $vSIn42kam:3{&6`͇l ⲡ>v(:g4ZBdnG} ɰS".A!?C9^GTZ!Ẉ%1aE't}9$#5a]atb&Dx,r(!+BhQ(c ELB&MyI|Ds 1?P!H \Pw!pHV&kcHlBXx+2A:  @`(iV& [#5H=IG;\KӈgR0hW"yBhu̻6F=^Tz#@|:-܉aѦtCVIث3V=Ktk6| $a&)Pl.O+ rbc\LU w3Jh@)­32NS3 lmR{zԉQ3롏S8FYeRQQ+& ֳAFMҍgp?Hg >R qqO0a {IBLp"+ӑʮa/cf??.c +>-LvKlh<w,ue2q׷Iupx!b#/h;J6ѓwTk^޽=t@$k`cD脥.X`!O:۴GQ&iUuUYpE%P3tf" Vrl&y5Dp:~/W2; g pu`3R`?W g"2'"ahi5Q"z" %WPUUX0A0 O Ig +bVvX8PG&y'z^H@8mbwqxF(AX3{ WW @x-sG&&!>x 8AhAyUQB[FQPڲ@ P s6P-(0 IFzh2.Q&#~` te#o0  r@e6AXPlXPP džX;W kpYҗd{hF!:[uV{A;s|)#'pNa`3[q SH0A95C>sW)@#)B2 @a bB4чRr(+kȎ'gp~x ddH^ uD,&0q<3 L8  x M؄"UV 0Zh, 'h' P1x%mR%lrc` !Q#"S@hw #"ɆA@%>q$42)R"ly <' 9`1:bhSIIXv{/B) H x4Qy2aQ5Ɇ}f@fPjɛ149sp ` ^%: WQyYdZ ЖdF1Q*?{l y~!%y)B)F au V#1AhNڣKД+p~@鄻> qx:Ք$$6 i> >S WP)fZĮ{*(%%0=cH @ڳsFD1w$p PTQ3jh{=@+h h:b Z%h++"50D}i;@HB {0&sMs+mXD@EֳkC!3JCQQDAI ۹%t?EM =iMpP4򼶋ՠ*] MDyYɋ^A| жrT `s&ˋdFW H3xJ#(d+3pTCO Gxk[ዦ%?2 % L d {MYT%b6'1 E[&>ZKԳ>zBD\I<Kd )ă4˛^ڳ`t6 pC=m+\JA*j^?;B>zBkC: S2Ev=u [q||0pL4Z+AKjy j1\0h!"95h ~bh\?=@Z ׄ-؅ٞڝM׬ Њֈaݪ!E- m]ԧڀ,ۛǽ=F^~>-Q ;h tt&gy0  q@  ܐ @ =~좍!QVـqU`~)y Ԫ @@E49Po4} /}  n-ЪR?ҾZ0Z!OP ŀ/1N}p) nrYJr>߾, @=/3G; S8=FYxPFT1ӭQQf3KEcSqbV(e_S  Ď>< @bI!#~6! #S6A3 p?F 5wQ߷qX>>q诂5 qACjNC]A. 1v D7卟0 qٹ 0 BPዱF` >QD-^ĘQF: ;l(;:?r6^ęSDWT(%СҥMtZCVgUkUWjXeb4z$۟x*7?aC=Fq8"+8Sdʕ5\QFҬHD ձ,p_{U,H2dn_1:Ur6Z V97zb7آ|18dG&dOF9eW _Y?}cf\gUngb$!:i˚9#]jSk;ll gLHφ;ɲ![(V ;ptpx'xG>ygy矇>z駧z>{{?|'|G?}g}߇?~秿~?`8@M,D?r1V0D,I2RtŁHM U0D!B`8YTzCBЅ/a e8CІ7auCЇ?b8D"шGDbD&6щOb8E*VъWbE.vы_:Ac2d#N09J^#sF9(cLJ :dBrg>@_>PX${L\ڔ(9m$GttRQXh$*R`a (8-oBdt2fN.{"|ِ8DQ" :)H(қAZ@Pd,dy8"~I \sț䦌݁E6 8*X~#ȫ?>ґz&%)H 4n ! ,fe H*\ȰÇ@Hŋ3jȱǏ CIdAL\ɲ˗0cʜI͛8s&$ϟ@]a p(pL

2,*-aޚkߠ x[?϶c4`j쳉v #h=O9l9:0<#.fc +kO9=fkOߘjqƪ*V[7p[=\6n'*-<̇'X/&j< 0.p^o,Ջbl̪yߙnὢc3݌7Bt0P 0OK> {޹#Ս]@xBx#8/ ύ'7G/Wogw/o觯/o HL:'H Z̠7z GH(L W0 gH8̡w@ H"HL&:PH*ZX̢.z` H2Fq=hiD"E$v1 6F8HY$ @rBG ??^Ȃ@S&7Nz (GIRL*WV򕰌,gIZ̥.7^R?# =A6YI'@ `d~_H:@ OBAnEDH&UR="x~L9<M@,93=ŀ! ,,#H Ç#JHŋ3j؏`@! ,p> H*\ȰÇ#JHŋ3j8pǏ CIɓ(S\ɲK4I͛8sɳ  8ԧѣH*]ʴ)Ӡ3  Njʵׯ7PHX]˶۷k =o P˷߿PÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M)k{k0a M_μУ3 U6"pMc5!}F˟ÿϿ1 u@^f O A V(p$B`%XhZ!ыl]Ԁ?|Ԟv χ H_!]5\O/cCYV0&GOUHΧ&^Qhg >I 6 D$G, BP D eShmWq2ANV)U9ycADa :UY,_gFP|a 2 A>1tMmkmD`}+PVůֵRD:!÷>Д3 D3(o(`B%t@y]T`~@n{ ذjF5/tӊarg?$]/*C@1lB"GA@O1(S]m[Q4HW-Jp pc#ZLr<|cTA (0PmXd ADW#į@R[2۟! ޚΦnPSҲ6c@,@ԁ5޺7/@ӻ|A0c9SP T>>!H3sk<2ʿ?l+'!P4+'f@"GD 4} !gX9|H'bq $`>7n ȚU A!64H5A;"ZQ4Q=2 s+ u؆l@w0"b.h:r1=w(^H7񐞩@xƂ )eaM2D h&BR!=H=0⒦tғH@NAN4G8ԣ032HE(yC: b`^AMz+C1T fì1  y#M dcUAn~Y?@Ta; !&`%Rͦd*Abq+Zčaen+dKPu?hyG7,cAlc ,i 0]cf@a%c4@ŊU fpcRzͪ c쒮]NNJH[vK*+F0Aǁ` cNTϨؠ1Qb6h4#nGa G54]؍!70Ubղ^XQU!EMeڃ`-]fi| e8B͔3R6YWD49:ꂸN:T#EȮY/(V 7݌G# oI B*lL!5.|/4˪7ɐZt)MCrmUv4V Bpb 8BN f#rްAX҃g „D`3 <,#Jȟ ƫk8TK\ףRUbu,lS-2v )G" _ '7S"C:c< )zA$.A2 XZb1f Y8l!jh!tuN9;~H;7qG 7V*PiK!?PCi;11z7 ""RRv?D(Lu>ýoOP#u[-P"f ِ~'vrTK~f;}`TVN n9$LP~ 54Cr5}G%Jr+WGs %Ns"|!!~-Q0Gi`J-ǀ }ؐ}zaTe qCtvc` D8|1xN)"34Q G?@zGeC&#BcF ̃?R"` 1Bv!5 #poؠ#"h bc vHVaXk @(v <%w "BHk rPs:StBe aV?HP5}Q(gw6FfE= K%UP-բ#QnXKo8# ˧ a< 6 06 0mг g cٳ<9fp8! %f!UQ&+jr 8zJrRW& n`;;T爎 5`!Ca3~1rya3Th9 NB _p 7(k4 3rTvljV fg~ Ԕ#1j4zVuiflY{AX"#);p iUؐѐbM=33 !(IxAe 9AѠs| P a4 0>sL--A*).iUI747u=vd dbP+t(%(͸?[ֈ X`WHW3 rq@#! c-y{ti%ß@hF CԹUװ4 qdBs?CD"P-5`QW) [5oZSyUWU0 s:aTI xnw->| t3 !PQl/af3a1eA*"'J pAqc"ؐ Q6T F h: FjtY@miq Uɰ9_cK)*;kHqDv54u 1_6 //NÆ.& TƟup;b zvTds5/1;P@x q,ʰ) yA7J J{Ty Pf+?c 1 %-PE,g F~p$U4hzP[E G-mʀ Y7SL .N~馣Ǚ Ba:֭po^ n>纞뼾 =q N`.N~֮^^@33;}d^> N>ۮ.qɝ cp Q a@־PӋ! ...G$*Y޽D0P _#Pp`&}= uga Ѻ4v P(HcA-vPTXP5橐 n_p_rOrmu{^vo^~OiOyҴINՎ..Na "-b&!G5:c+y߻|^N='ȀhE(1 > юC*13Q0+g_ ɏKe`0 Z]l? DPB >QD-^Ę[;vRH%MD`% TęSN$淪AJhQ %HSBB:kO]~=Le͞E!l]V[qεoAjX`…U5Xbƍ?Ydw) =ZȊhEYx褥IƝ[n^ Z!@X@`,aӭ_ǞP(T,Myq}`֜#$R|W $bld.&BL'.@6' /*x0: 0Fg`i8p^b&~Ҿ!<1I%(C d2J)J+<֙HK,3+Ih1τP1D+BG"2*ǟ3P ;iA*}o!t4/g5GCe:P9 F{бЃWWv85.[$ VNj\؉X]S S$Ij20hpb!聆!w$lQ` oJGx+( WIsS-M U=\;(O F x534*(agI#&PHބa\!2 ^bBoI^1o 7k $'P4bxD.z$Fl> `Sۥ؆hF;o)"M=wo/N5kݏ_yTj%Ѡ"WyDm5 [z'Ї?~~)O{?t3XB+HoИFxN)OP(!k`mއAсA^к0;`D0pB,H*HBG6\Y O!C"щO4H8E*VъWbE. ]c8F2ьgDcոF6+]pc8G:юwcG>яi( ҐDd"Y>\pd$%9IJVҒd&5INvғe(E9JRҔDe*UJVҕe,e9KZҖ%_ GҗPW01TLf6әτf49MjVӚf6Mnvӛg89NrӜDg:չNvӝg<9Oz3 +TqT`I='y R?yc$ 2P gJ\ U AH? =#p>/цh!(HA1:RGF !0MNCZS9B(-E/PFHSs[k̅Rs mԥ aP&Ê!PG.zU;v[K"UzB`!DF508lbXv5u+Z¾-h$n B>PA "Nf8rFN'Be!0~ P`D ǠB8$@AF3D 5l!R D9@/e9!@rhRdd}.p$ }t#.`D@B"M8h&eȘaOZׂH|td'{IZ! i#:+iHsP! , }A H*\ȰÇ#JTxċ3jȱG?Iɓ(S\ɲ˗0c )͛8s܉RCX4B`c ,< t 04eЃҫXjݚP@kAG0M@[6)ف{{&ʿ.prfVa|]̸gv+L F(6m0 hW!axm ^LFn Hdo+_<+7F(LیPt7g>@pW'[ AN'PB߯W dA@' T[C D`@ !@Ҁ?$pPK8ӅT*#4hDS}pCxQB6TIգT @@E@YXfPjmpWdih6gip)tix|矀*蠄j衈&袌6裐F*餔Vj饘f"p\g^~}ZCxdđjkJm3L%JȎDYo% PGܶ@T.2˖CuAv;ya 9c|5Q@eW FD.f ]oBW$D GQ P1A \ŐU  R!S{oUp?14#P6O\Š l `SPyجC; D!\$?nL$x@pT0tAx`?`]OжjT&aK)Ј=nhYVR$ B˰?yI9Hu HU@u3 mX#= #t`B0zHcE͞n}{ wt{ JQ B;2?}-L@;ĩ@N 7"+Hhb$:UiFhDT{$e;ktYZ f;^ REQ 1RTf @d 1 g(AJV̨kiT4Eh+U@ "\"x1ОM ! 0.V$d4 )c *PN* FKln<x@$>3#@`83AGh2!sA,#7[9l")(2@@'xW|-2PVLi4q"H!QW8rcgN< ^ HjlNpDaAA QLdBMaah˂,!,RƏ"d ҩcC~jp(&,ԧY??O Dj5#3GTmMH* k6Lxi=lx59 MB̢h,j ZT .53!0 Fɚ$ Fj9UFa=&W)+窨9!ACqXjBuM :ƥʌuI dځ0Ԥ-2^dijd rsY4z:nL(.Aa7pzmc0lbȑ;T X }(a%+qH%%I@ ,\WUNr)(uWHvg:/ NCr~ v"`H  f` '}s9\ \U9 ̰\utWUH<s y0 PeWEͰvȒ"р-R,2#bc(y (Wp6a]HN) a` W{b֜i>h͙k*p$[p` ! =f\ @WwY3 YC@ )~{ŘkP\m ya,% 6 MA)%my*q Ԁ I;)1WfI_y &1ѝ&aCCTh3XJi3P !m]`aa5RB*lJ7uqVop vD _O asGCkE t/*&i*yv ̠ƀ}y WT -QJV 1 )'y =*^! 麰|1n a ǀ_^@ `iYK phSPj$ a[Q-!Q-˰QJɅ )ԠຖEWϩ y=j@1ِ 3V:4?䖱mJ,2Eؚ kH8 W @ H8Ȱ+;33 9 !uK!-Q_ѹ @+b `zh(f(82Ɏ($BZ Agqc~XtH k=͌P ù`LqcxcI 9TКq. zs~hGTWg#OA~|il^<|uff9͸AQQ20?mZ0;G)B  Y,2\ &kݜzJ,kS *kʪO7 ]J* k FJ>B#HH`fvQP܄pt 8gk&1qa ӚI %RY S$5P=s#E[-V5!^`H 1!kfHLPI Bmҏ [K/~T1QRq = "I`YFKt=lS>v%r90aѐi1L`lm5l$6F,7a\0\,_aa:6X1q8QEC`T/3Cd[4B!62\ &z`1 9 _Y7Z3 >QD-^ĘQFHȢaEBS? hX2! M%x!.blS A*<椂7*sb8~V؍,JSMaۺavsآÖߵYzŝOm: 1)ldʕ-s$L49@Ȉ<AK!y^3( 5DK㰐KĜ8V2 =|[r'agzG{^~}, nO ZkqCa$;ǟ_C5N0ʡlr#zL{+B灄h  HBZ@B(K7*ĊNPY1G[(Rh!!J1Ok3ȉZWtJth) ̝$d"q2)37N;7hKhˊiFVzP$RF;T#  3RK/4SMzƙĆl蝻!5" Gѣχ,F97?!)Έڈ*!d\eY:"gxlš"5 c!Eyա[ew9e)pYA]}՗چUöf$H/R7rOO)fA~/Ϗ*thF& xSA@kY!/0*"ڠ+09<6!bb!SϹC:hQUW 5W&bh<W!(2dވBЋ]gֈ B禛:pf&1o.(2%n#hl@B!a4.Z\eE*nWncg!gjAYdysFj2%] ( AC Xz0+YB@Ύ{8 E"LjM "^e5X&%r 3`N8Y&eDB߅F$NF3Vc@Kn0%0%Df$p(ٱ$D~'ADTq!4rA$1@B9e,a$e*{Ȅ'kgWCU9]0v!T8'f2)H6 )Tb!]V0!T2' AC%y)Nv&2BpS!Df| q}\?,sxz0Ƞ\CPY8!.zhHJԣ<f1FB5N>(B@ XE^6_l:8NL=E\DqZ)T҄"UWqa#*q9ԡ%`aR5śe D:W'i R#T*b2 \bj+0rЀ4(]/vB|-r,Zҋu=V̉E-&iRCo0Bnvf,1#b7Nռ o7"*PrЇ0A-%Yh ABr;Ly@ p?*J>ӟR%|sJ. 35n7D\1ݢaٟkX1c-C^5.Rii6pucg*yp,nҦmi4{L'1SJ;e.{ɘXd% U Y6 WqŊonU2eDl۝vNXF 0/vr>͙QmZMR Th +3`Kb \^tB>& ,%rBZA3iы:[j&(*Umd%Bd^t`Gd1aW,&P?:"B ckȓy(sn謭@;!Jk.UA8Yj/䁚Μ*lQB NJ 5Fۛ n3i|aC\m2%\Z7vnyz!/%7ߛnN=g"wBȀ=G:Fdqy[,<"7rȩRNzs H~d {'RadģMP NVGj|? x۩ ?y+UoCTp0HlȀ 8<H Sp )xi{DUl1d"SlOPx'H[Ι'ԆP]'TD\k0pEBmĕk3 {;GHǰ`R[xLzGrl:8 $#H ȱLj2 ň x5(YpƝ89PL r x 0Ќ8DlHE&X" > GQd]$uRG [(i1s` RHipfG(݈s< {%8x^\hӄḐxӇ3)TIxIAp5S_`l`Qլ.h PѰMۈaRG/(Q<8HEhA^h6 ;D 8U!y.@X)jx%6(`ܕkS0- aCM\G8Ot@φ0 Pω0 } ȳrjl9( ሉJ P֊ZcU@Y%) ։խ䂛͈]{LEP[(6mXCb<~d@Z@ jH1,&h*09P3 ݈Xl'3`݈~TP(\b2Q\`TsPj XUVMH<]͖p۰ܠЂҥHЂm]u؅}ڕ]ۥMw|ѕ\^F@Ytb^h^^^^-҈XYAH:1:I?h52䋈lx uw/ش0mDnZEPMx1zU8];`@3D׀}(fط].Dؐ+@Mӻ%*/~.Xոӽ5FEĥuv<*5(1e)] Ghb0Y*4pfv-pffijklivf4ފg_ `X\VGzxGVz{|gzv(Nef^ehAmZR Th&VmHHx|T Ph舆6Fig-sܔ˵ݱw簘t`hh[Upi8jG^Vi UǟgU+eꬶjg8T[SDZ|Ю[`6݈{Pը=ddW@Vr ~oN;d.8\؁iB^䆆zPŦk\vgӾ~Vyi !0vTh8*6P/އ@%*x 23Ȃ]8xhp.p\FflN(8GwqogCnȆ<@em#] Yp%? 9B^N߆wpHhx"WV(o`VnrXShkHž>&&A7t piH4HȆa-NU/c᫈l\4HN0Lj@R>aB"Paԉ"wipin'h]A&^Xv?fiovwhmhE׸AۉaM|ŝDS`v (K쀘 APe;kwWdNb^npT^XT8کx+UyRjOyiOy^v>Ņ|S8)] qՉ A0I؇~臥w߇zzt8_?`~wo{{`{{_J@+훁5볯$X(hg{n_|w{_>d0VW[AHT[*L!APoփax}{t@r}rXn}r|__ 80'ɮ ubM~7\kPt<$x$n@|ipHtpz(q־x7$}&Rh"u#Ȑ"G,i$ʔ*Wly2p f?[iC%"7}, AeJfK'J!'h+ڴjײm2kE,7q?xYC'P hJ8#5l2t@g,Lֱ<*,CkSsǦz  .DOJ An:$;Q<{B篟`' _蹷6ߺ%^#G 8 X֑hMH|t Itd ґID!Q%TRg}DGD0$bG.tDbG@\Yl"9 3#{=S5ň8jϐܘ3@5 9s^?e%[z%we \n#0H ss)!?t$.B,NxdL %~֝=;| pu5gz7`EBO8ňIEMjbzJGII@W- @ÎY¡D@3[WI=O9˒-* ZmP@W tt.m17@<{:cM/<0| `i ;3x `2 Ю# ,[g~1BH`mezYSntDzals#Y8{ƛ @S7bJy%8ai>b.62ìRrt"gn{3V+\^ΪkYE4)OY@op :p˒O#*iJ4̂nz@HJzRz-QH"q5mZ׵Gk\ֹ6 ~6lʪ, 9`YVbܬIufE*xǻ7)x-4)/Ƕm) ?xq~8r%4ujw8*+@ʜ%'qyG`.$GA*J% x&mH%"":#e=K=|EW;~qfGΏ\HWVxߢ qʆ FXyV%)P] `@8&0І ^HȃgppR G6" LII! :@m iLn_r!!!!!ơ!֡!!!  "!!""&".bm #>"$F"XP?X"&V&^&f"'~'Z$bJ܂ )})GJ-ĜݵKbݍ[Bɢ1DuY[H^*,牄yD#76^#V`1.v7D.|#7#VB\HL.D=N8b:[GGAJ;$+G̔9@v/e)7+%@?d,bx! x 1k-Esᄙ8M8t ESTD?ȣtD#?CWmI[ˣn /pgCBM=Pb0!Ù0!܈c;=nwAp/dL+ڠ 3HS4Y_w>s8oЙLn{D |PD7)A8*x !}@B \@H=GCq "APcc) 6!2q8L*60ȁhEUHB\%N)7cBCv C+rLdQ#3CLÌ4yKH J3LZ,DJ/!zj1X-R !䆗UBT҂ +j6|11ʕ^ҰF4p`v a]>"uF I: c#**0XP86QzՋAbKma"[ h`C_?{J$ҭΖlr % dĺF&Y#I<‘Ql݁}Ճ YK? b@kqܢ]urkn԰2ÃlS^Ylq7Qj)LUE# 7ԑ5ɍW}m X[€prƛ06c\YX3AcP)so=db#|hEᏹiΎˇ˂GCm TڔtT%z#g/X|QqT5eE@ Wғ՘gliW y*CΚю7Bؠ蓚9Ҙ2Q,2;.g&1+灐D @8gR^P1i8nաb ǎf;lܺx7Ad^[;BHA:[\#Xuh|A,fTZ쉙01`)RM~rk/iW?ޅkUչUJOc@#(EUǭG9WF/`Z\@/#C[ck QeoV~ed.  A/R^51 hT>-#r4ށA/W Qb vTUsXsgu}UP  H6LU%CGQ -VGXWU[zg ~&(Y^}W W}q ZH-}Uh.8% 'Gw-]dWTaZAz}7r*\p aVpppDX 4M'f4q-ذ~FDq9$e a~퐀U~ 1cq) h VJ1 @Th@X\U L9"JeY8X{tXI$"Oxajh$4U{b:wIy`)B$h.6e^{Q[{g<](%-1tkyh@ $RbN \Ut9%"$IPa ʦ atɤifpZ(:A1S!Ҭ!#*1/Zz蚮꺮ڮSZzگ$X[{{+֙͂' , C [.yrv۱"+;*Q&*+}pq *1įmpp[!kArq %O Ĉ. g   @~Q"(  ൧C"g3{{& #WAKTZXSx+$z6bb;[>[rCҵKa;{ R ]{ƛȻ;0M`  l[@ Ż˽  q p; {׫+ 뱕 K q Lq@<»<"Ձ@j"(ap)+,Izy<Bj袊( 鞉Yi}: kC?穨ꪬZ: d(L3#72֨SN37Z)OюĖ kd&@$.@n?/s?IZY?s_?m~o@αo-DB@3-4@";  D@nsM0w9EͥuTBS8$%I 28 $@ńH^)I!.7( ↔$$3NhE" ?HZ$ؐ`Gb%đ .K8R/~䋬L22 m UŁ 3$MR#!A8Ȝ$$ ɂ4!!gJ3>R",%'!RO -i^r 0UxEarL&p$`G:!~8\ Kt 'Wlegr w]>k^g bi;}ӠG b/@mFY-/A0_*ݧ])kHɍ.m>sx| ;p DPn_~ wPŒΚ3sS+ By>jgA<-X$A O O֊}+ Q@!|PWӭh]0'#NX_qٜb#$a<.xA5W#IWY3r| a}q}rmVHN d/'oA}`}ruwjsP4PDMׁ6-6},(~7'w§NXJDҰ7؄ G[gmCX#(Az'B#T@ PNXr&1h&t A}Yx 0DL6f`S'h"1G4J\z83`B 0h }  6!77{ ш3S(h}6hPr0~׃ &Q' fb"G|7,$sqh.Gw'Hu,8[x+oG6;p=+qn`r9 ! dܸyQ } da5#@'Y+(P ,U^ Am6@l<9dv fyB' H^!)Y0@@ 0yw B^`QhcS /9-#f熝kuddd0PP)ٰ@ K}A ̐dE@QPg0Л%b m^J+A݀jǀjA s0q `FNF g0E%5dh& q7*pAmv83&yE[ j1{p K6F6ݷT# ;!Cf"%@3- d@# :a c64@1lt2 spj y 0 Qp v{ ^H_0 Jvi? f d m*o4{: U`FWbڡF`Hf1A)xA2* CPq ̀[Phz[ ˷U9dZY:ky1x)Cj#PY  [m@X~[}dʊ`«/KQnRwV %ݠj;A` 1 Gdp MjK$ *KVgZ ϻɋ wƂl@ [!%@P& ð0Q+DV < P t9k@|z}HVK ԓa W0bzI1u%S n qcq@"-Js@\ -GELՠ#<ؐ  MA>!(V a mCC<2< 5tz ֐ @)~ Yp ܑX)'Лd 0p_+#miK]=YHp uzozz v[0~ԙE/Rl %4lLPĀ퐜+ի9B 񭚧?^@ wKBf@mCK˜WT P*ap^1 w%P a;KkѠuKɽX&]YÖ F/ SQ `ʓf֠Q a RG0T^<UNuqFp@QB>}QG^w)D ( D 1 1aW0!WpBA:&wV}N1x\U[`[fA?$[ rso_pmșzoSmȱCNijg (,=;Ioð@f) NX3g 3E0\@*BƆ#sؿ.BrJO8d1   iuou n0$ dLI6U 8 69 F.bc :(a P0s!E /[b0 .e'͝?]YѤu3]8_Y: uG -X͚){F~iB0@RdA9k~"'Y$Ʈu'$J2L0E䭵<`mXBnE2:f03-Z(?ҠgK/ Q͆A&#$ 4 ̑N;.tjt4Dj 2`'db PXGOAfe-':@fhC#^u2F3^OR@O*djPV˖'_t^#k sPp[@f+^ȆO[{#O58(a ~'IXFOB)/3z/kv5:JΎYp1˺(D& iǬC VZ> '|U?ZfG!πyov6NDBP *3-?Pq\X dpF\6Ntai6K AQ,<`a.X\VXjj F+C1fAp)(-kl^l d$H2f 6:(Lu/VObrPӱNf! 4ulՐL:jNQVj gŒ͋>WNd-b#Ȯ w+`OэEIGܙ4+bfBh{ZhIFAJ9o]W'0 ^i ;Aq"ucG񏔯`*,r_U+^P$ƶf&'p(eť[Ep6("{\PcT'HO|"tCyDbEY|࿔`ۯp!" .S)t69lb&>/dIȓ-)%kӢ1}WbG:4?Xpxq.D gK!9MÿHkjrA9(Y:/`4x, P k jĠXFʺ, @G܌kH"(蘒U {^D$ʭ&Ǡ=jIAWijt,ي x+JBx0dq ד? r,H,Yh1jq,I)J!Jƭ(cK @PĴ̠hL&7 ޣjb>ԊYe3Ҽ̀L/,T18Ռ"&9LRMݼ0!IC0tT4&?|"ü,(hMG1,(9HԌ፶FԘ%1aȩG%o7w#Ԑ^P !> cj<D$ !SeQ ;z<9HȓH\Xm"MD ʴdu? a:Y(H`O#/@(mJ S*K7qD!0S0 u? WDDp&Q+!85" dTk0Xk(S 8QsB:Cĝ 0Uh1죥q 9P],4h[E'"sH`^e$ QbŮ ^HRa VdVyhoȅhՉa!q@@Uv@$.cخm ]&6FV&oD8u-շ9pHD.o\= ] ] p`Z%:ԉ Hܗi37NBM7> j/>1-`{_A8(uUSȂr'72)q" "9HB0HK l 0`N.YWHX$ :5Ӡ&gps0%? kri0aR'ST7uUGU/u+gI%+PSXaY81Г֜7 ` K'MZ;b T91K. x`A }Sdp 6hVvVپ[hxvxxWx wKq0]g27@"ȆA>HOOH>hwC"#~!@>(jW|.2u YF0ԙu " W] S %j`wȚWcaHD08(=@z0yA* a67 ex 8`U[^puY'{>289[g_`"հ:v~X07i HC沉S-Qsia͐ ZK ~~|~P#^zPg8/]"7 $8 ƒ 2LH"F4D"ƌ7r#Ȑ"G,i$ʔ*Wl%̘2]8`&Μ:wfUh@s\YaѨRRj*֬)RLTK]i ԍ%ҲDQָrҭknJ ýxMd'޼^@Dt+h6|14ԪW9 q&D|X+PCp3QeD4".mbg zM!j|X蚬5N5_[o='fȆ/ @&p0o DaNH%(NudG9*y!!}-7Y\Du,1_@5DiJDO@tJp`?1 I!]6"YjVk` %E0/Dt7BqAD~%X`ÄtO/]?FVCzTÎ,_HQz :* `[M$o @YkGtF}TM] FЍMҪ FBGI葥Z+XŵFPz쑛է\vwpQ+GF@.G*̒^RR/FciGdvHk.e2Z-P /-$#[kF,DLW1xLrXJ.mW/Efd"sd AR?C/JP4A.)3yDQ+ sQNDq7dsD3 ~hjXG DE08GKWDDdD{N T&Ck@6RPDN@/Ye`lN1NLs8 QЀMDC?ͩ܇O޻p#ً%Q6Y\D@bcG\& GL4@d rpHEJ$8OPcI8@ x1ECEq^$mD$\μg%,[0@E1A6& LR0NP xHEFȜb#@rfL L4QADJ3r",[EP4lIT#^D@ R@~ J8c wB8((a ,x'y5eֈL8k$W8 bTgڸ 0RDliX ʘBA V4:U}D>u0 FJiC#Ew<Yq)@W'xq[X"KE n+v FPBQ 9]5#hhG&#t_26G$jvoD8WAxUIQr!ߨ"_jvHXAY3p2n?d}rl\ \ 0 ǦD,pɢ,Qü 4BP3}F 0h-M\_\!>)>~]E+Z^뽞5bINGdJ, /a@FEAMDx aDE DSAZK@DM0x]'GDXA/ 1aUVd]b@_dH DЁ5>{'|§{g?'{g}Ƨ{~Ch'z(Haܧ=}58r=8?8(>v:5샇ާ?uh(r?.\ÌJ腢>(:h?2Ch?h<)鎚艶(HPV?ؚJ'Uh3/.,/?%Ѓ?Ѓ.(.4&5HC>, :0X?4 HÎr,4>$,8)7Ciw^; ϐ0@Z5EDTI55`_]Ľ3E(CNU=,5?>ă$ă3X74:C?J5$2H÷C3(!Ѓ2+=8,:H,C'5þ+؆DmD}$H6|B6vFUMHLHV?d~u<(=҃=:&{q*p>pC.+:lrÎ:XíB/LDE JDXm9䭑!E*Ep-D"Ɩu6)&)&op:bWy\X 4B00 0 0k     o&_jIc0l?$1+  ) #7;LD҉nf1J"+J N@q{ q1fפ LI~UpG$ #H0rh"KQ2 GFsDd`F '@8Ă:a5PD*Cr*+26KDڸ0#ll."@6ǛѡL[NJ4<.D?AXC@ _<mRɄ3E@LTGD݈^@܇`FgLeOʔQϔ4{/TOuၭSS5Vg5NVwW5XX5YG5ZוE5[[5\s^<5]׵]5^5ݱGU5`oRM<a$KcD5E"G|g6hh6ii6jcJ$ФZbO*y6A5nposqߌLörDq_ȏGBD2Dvsaowwsw7xwx<g/atD0@X 20Mpz_Dpyy 8*G{'xFd"s<@"oxIdX4DŽO<s8S+8j}vϸ8߸8︎c <8{o38oɊ7F*踕8_g9Δ,>9ޒ9yK8N9׹9繞99֜Ā9` /: Hг9CJY?`:77Br_D=DIGB„2SF,Gs*:E-*E܌ DgG-֭;F|8P /XW [{D>'/>7+Y?C6N\o>w>臾>闾>ꧾ>>lѽǾ~V>|KD)0UND,hD UE?OL+WD iT85AKgD U`A`HwD`yG@8@&T(P??$ 0„- PA IбdI9s0nAiN>:`?C`BRd cH( u>A'EeN(#TmF@W: w&4T+BR.s&, pEZ -z2 @?\{|l⁨ @ ;* |-:$u)$( /V @ADL;u,y :*|:|!g|PD"ѥ~/5*Ϯ p+$i'z )ʐNsZ3ؒJ2*4t0򉻁^HP0fpC)f(% 4젹@!:k.(*Ѣh,` ́l@ ABC1I<˃,QʤC%":J+/Eꢶ MMtHQ<;Όn bGڌ:53$n), C6ك-RGVH҄;V1zP˱h +TFtjׄN:A+ :Z^* E:/8 Vv@oBcx0x7^@S`U @o戸RXe|٩) G t׷9ZI( >jDI勷:7O-LJŋ{w.{o/џ|Ɵ;Ow?۫W7@T=@{R78 ?d Spl#!P6P*D!x3 'p4 wpE4iB;$Je~Rqa=D)NU! , H?V\ȰÇ#JHŋ3j,p CIɓ?\ɲ˗/s ͛8s%pWG@  qJRD*]Sʁʴիo!x+-`Ê0ٳX%ڷLKwݺxw߾n LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkν(ԫb| @g(>Ͽ(j hV&M#? Z=X5 $Lq6!E S,0(4h8<@)DiH&L6PF)TViXf\v`)dihlR.ӄIW_}eD|OR@` !:N! ,L! ,L! ,;+E  H*\ȰÇ#JHŋ3jq s0ءɓ(S\ɲ˗0c$ a 4X WB9k*]ʴӧPJj@9NYX#­ ٳhӪ]˶m;FYx˷_xج+^)X6LdO Jn̹ϠCCYӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(h& 6F(Vhfv ($h(, "-!@@)Di$uLhM2MFI[8#啰с\vH^)dy*%el`Pp9hw9$6K)cUB Nt1营-FE襘f馜v駠*ꨤjꩨꪬ꫰*무j뭸뮼:\+klz+hV pO([]J @dm؀@%|IId$ɺ+k,[}$pP @uð f1;Afܰ񑙍|dAf.0,bO*3H A;$(>@-@l4D"K A Qx@YBlifMMlvp-wtmw4ޮ7+V1 TxA^2d1 3PJI\ęU)p@ )S 鉰]ݔ8Qwݥ7'XF]k,- OxtP?5bL/h5CO|JB M=u@+@Nh L:'H Z̠7AŹo9Q; WB~90 h PA (PMG‚0HX`RH <EL Ȑ`Q2Fc,c F1 Sڤ0-@x  @r@F H@RK| %IĤ$#HN^.㔧G*QJUP%+eJZr+c%b q}nj%2LW&,)j@0a!8"08aIrLg+Imf$H 2zϠ?dɰ*! khA kۨ JѣH{I(ӧPJJ* ʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ְc˞M۸sͻ, | wG+_^2gCJνã%y_bԾy99¾Q@ @+ 2 u P HAMSz ͱ,_ BN0a0&tB 2$# )]Bc3FAK4bIXa #?;7dB%đ39 1Б X((2Ői'w`D@PHP2 wJ<m?ycCpTL2j)S B,@?9鰓@ՌS 50i)@e4;(׸jp볷#O;ΣB([PІ[iT&@O":@ 6$zKPL5?0 ) ـa-j B;?\k#SđZ $L3ѴOt:mO ><\)xfc>O1?KPJ)4R/_н۠x@?'!cf}/!hrUeA\}Á@@hS!7 ^g72Nq@jV1T 舀ɐhdNH8ON2lQaAPX0S!Cx -G?l ^A&mTJ|@p!*ép*DKjT H:d.rV!Eq et*oK xlRKvPY bxnM&',X$jk\w mAcqiC +ԓ?VU|\pZ̶L?a^OA6тxΚBq43ZM"qWj ]B*{G|!wH6;9!^GhGVr= G7r&?9GҶ{*!Ydlp{<=Yfu#q 'DCMx%YvuLCЄmF"8   ,:|v0A5eG>bY RJEB !RD5A8yGsBh 0{SlrVG1ֆRg{.l0%I(HR$lJw/Sz|0ӶE4ZSd FR0'YҎyxLl.䷉ ?%$xYCsm ]tQ rWg/hKXWoODw"|ȗS3N}$1~o{Y{7ت즰a %h7w#Axxz-<K,M Kw7ˈgcGBopuhnjus Xh0sb =W'gmv}yȰJ73MA7RGKh HHodrn!@5w $(p~)& u P F3p q @Pw̒ S@JHp T@%H 0 !H3gGX!'r H#Q F@18yh>TH/X|3X  #Q'~טC5Ohxs@KF; P' hIIӋG utuT荬%+J"Xx"4+* al b0GN'UFD'b5g9#(dàtW0-1%&AH90sYWUxx(XDɧ X:R LyHE t"Cp^gR m#C&Q0LW'4@g0E@A l5Rsyj"C @*ji/ 8@ ᥙtx2WITx:#'O *pDAVǐ7fsBz2Yؠӓ;Ցr" .mm+no &w $P %wz}t!j U@ >EgVwqAz ` )Q sZk WZn;J~.}T08 ZSL._L\ D Wզʒ\;fפǰL;|RJJ?+!0UHJL@ M'r"ZJU>]@ ̅5f qȇȇr%ss#+zWjD QQz`Q`iu T'Rwj0ΡF1#;&a~ F@!5#S @ aʒrY`` q18=ë0)=sJôSuw`9KMY3ó)ZY$:x*OhQJq+SIm a<** A`5E2 6Ad|i\ږgU\aBApL]ǎq  5i!ɉP An;1~gIF7QBa dbXl)LI+ ]޼ ַ!>%~&' `^2% &"&1<;;><>D~?;IJ &6!&7 ^]n\d^f~hSjC` g c~d^[|\UnđP  @]Np .kSqI?bdi  ɀ@u@ʀH.覾A P ˞ n] n  @Ҡ `ОSrdثL? ` \ P. `RufN9 M@ ?OP볾 .gP ` 8FGJ{#UY`@ Z_n^PdB")nPovy|x{I.@P?ODž @_p 4hOp>]4@?AP &Y1@U`oϯ? ٨[x=4@$`A@P$_/Up$/̼1@ DPaA rGD-^ĘQF=~p?@#HA(Kf aJM8PEEB>UG] QQ4VXe͞ma&L9% $@cN6q@AF4Ȁ >BC݂55hҥMuC5fΠeIM)$|iōPɄyqZ!)ǽXV8:ї? |qo @ @~'%o SD0AQ p$ 0 )pC/#@OD<WdE##*X B_1Gwdzf4% "|ҴJ+3/ɁH$$hH-)ȁDRL<ƈ>,N;Od$ |-i8 Zh[/J- 5NM7SO5с+B7<(B$K%SYg(ZU $Q>"l%6-Ev+ QЄT-/ `ځv؜^A'3J-Yq f\si-W9D(Xk,sD`y7_}Y#eH &(`.^_7SVJ RX!埑SSanaHao&.&z\@'d\&hdd^阋jGw*7l>Hi y>l rY撯@~q&f9HjFn'alq[k?'p/<\To;3G=u zu_gmaҸawEٸ|'xdhl?y矇>z駧z>{{?|'|G?}g}߇?~秿~?f8@Y3`w:6Ё`%8A VЂ`5AvaE8BЄ'Da UBЅ/a e8CІ7auCЇ?b8D"gwEDb-OdN =ъ.P#^ыF E/jX(65k܅6p;0.0An<@"쌁d$%9IJVҒd&5INvғe(E9JRҔDe*UJVҕe,e9KZҖe.uK^җf09LbӘDf2ЁĂ3i|D}HmZD*X$pKyUI$p>YHlSAno: D3!҂H Dj x"@ , UEkұ(/x(u`@! ,rT H*\ȰÇ#JHŋ3.Ǐ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧP իXj&`ÊKٳhӪ]˶۷pʝKݻx$ߘV +ǐ+:L˘3k̹ϠMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(h`jc 6F(Vhfv ($h(,0(4h8<@)DiH&c-+-fd,;mPT[nSÆ:Ek@d0k +ƒA?{Q;,Bo&V.1O. I.q0adNg,6t@$YHS شf%n Yb9Bز Ydx@ Q~A1(Uq@pl1@2LJ"b: C D GQ̹Dlp^`Ü,›VÉK\)RΔ >]MK7qӨS rVbT!$(G>236ug7fdF1帵C=@<H߻!Fhs #χbz?} dVnH{zٞȉ72ALKʉƩ_iA hG=xvk >6Oi:?& M/g( [wAs>O;wX6!֚y^Ƒv'rGxuGϠ5M!~2 s{C&xPr a{̇<`"M /A%# u xjk#wRw s1$ vрws3 f47 fWr;X0PT-@^'NX6z d&aƁЇaaW^&7 Exc82U6$#LkH1RF0YH6Pr{qf2@(/ó[4pꕉ 0(k 5U8uhVrdr7;''0y%w#ٰ& S!H*]Vvmh q'֊!T :L.T}Q0*aG0+bjfׇxy as fFL@%P͠)Fd!\x( p( &)S10"KؑAi yn~n=xh@f afKe"c,^唙skb ` oNgX D6 T9`%Wjk[[@ 95 7i\wR) s˸D d R W q vj'y`Dv (]9dfPjpI Eм8(;5 N 1` @K_"C&{9 ѕ_fYE( @:C1 YpA5 se[R!e 15`%q@J#.OچLja{{fGWLOg)wf#0a t p; 00O^ Q`NbEnj8*d  qNRupȇj :X op\{T8vhKyk4v2a 'l*5P{NKvT#" q_6PT5p F|D` a+*%]*F P)LQGS ЩjB qMc QJl谱3 %pIOAj`0F g Lo0yx`;`IP#*Ax%bavY1ZR'O CH< (Ķ$ ?<$EA%YDdo7!n+h^E]`|4S/^i;MbPyK ޓ)e ,:rV!}E]`w(]6Q!AGhsu{ҋVřPm#WθKa%Fe>+Af` <wIꀪˍA@0kʗ/v5 P_:A ݣ0G &k}i=0sܜd-S\[9䜹` O{ &^;PgjA*qvqWόQ,ԛVDW A~B*HM+{P魘:gg ptrη0  P P <(AaY(q pq8:TaK TTM6 L%.U=7zx¬: $$@;/:b d!bsU|dKUz eQ[CJO4 re 0{{`p P qع6b-o3 (lbh)M #!3a5P O0+ O+FwкEB%N9a 9lAD( `.*(AM" QK*M1Jp(83V0I ÌVæ6л6%D0dEl$a%)b#Gb2 #HA*t3@ iK߼HH&YIL/3󮻢9gW 嚄9W_#B4$0Ab WB9ƌX Kae 77pA D@1bDYv!,+܀;$^rb}⣐3ƌK9MCurxJn$_\A=s.yL)k@!Zty)No{1 յb6q鏈xJd д%BTf-s<[oXAo 1cN5B("%@l(y`Ƙ9.sB$pNOq)!"8\ES"ԌBeȗ^AF)h{=-#icxG'oDlP(ï QJI`QbbW8`rFXꪻ'm~9-:0DaSIdP@ `$@`lj>C Z`x# , AQ0/:-`@È,bT[_&i4>>˵"LG6j9@%+3| ꋌ`- "p/JA90K<5kσ 8­`1M1: [j@:7 83E&:*Dɀ NIp a`qLdŌBD(" 0B(;4l:(VxV9s'98K2ٹt1l&Pm`!0+@NyS>R%X&w\lLƩ 6 9ǀDht#chqĈD_5THPUHK:\8AH40n0ET'lBSZŕd"= 38@H&RJKPI# BxG1B9[bJ% T qǏ6"0zxj 2;" <졢` =dܠʐА, 1/I<*/)F(Ɲ(dLltF@ 8ͤY0@($ĦqC8NccX"N9pB"ȟ8~BMEKLƶ<$ CiKiOPm O8/H1C qa0t^Qύ\Y"@k! \K m("]HQ}"V[R"GLmHUVHH+E`0,"dҏpRȈ*4R^`M0.mS dH0KhoScTàdXs`hT+#+&8x\mY݅W8P(Ԑ9݈r8i΢^oS /ɈE ˎPӏ`TZ^MVVd5[g s` )lJUPx1EˆOSfF:3}UpR(׌Uuצ@}gخMI%,"艴ă6BD #ʈ>S+&ІHhX W bXVш0i ` (貼ҍ([R "e"H̷}I% p[ȶ۷+rY[ ¥;1uܦ٬ aܒ ՎX% 2 t8ݏxt؁Ȇ(c \JLJʈu-)1HXQЈF2 &tuXd˨H)8[UȌ`)HpJM&R~ߎ(.`kxߋ80?Nzx r:p'P<CAu>I ps'HWÊ0_Ziť`"/8ˡa䢈oз#v9Y0 5 2P{ʑ+\d$B 5ƍ3yjIE⢈hd@޻M8\H3ುY@7Wp-+]O.ޱɡbE xxF"8 0(%߭bJ~p \'xۋ(Q^BHZF樌@i*MΏ B[RlZQ52/S.[fǀr)[΄\N;RzVp[©|FxȌZ&sp|ghbdMrgnqMi^in铖i6iQƽx~&ų'cXЩM4 W)H8^n[.۬ꭾjj!jˈ!z h\`k迫ƈ8\8P8O vmHffNՋHe@D3hg0!lRylK11m^6?ź<ljpD:i E9)HJ 0lbPD ۈZP3!ƶ}tȈ8UEUԋ؅R5eoho`[.D+׋ g%㘉Oxˆ3 ϻV;څK&  H"c"UM*YA@;!Pm 3fX6rFN^zPNIxꙁKn<NTC\ -ڈksF+ MӚXIЉ1G]xYR4D(WD}l@ [8ȆSxҞXk ܋ 9@(kl刭ǔN셾ψd/MLKb<'HX.b9|P'pࡅ xK)@`,ޭF͗q@qȖYw"qSy1#7GWv2&as.U9, \#@2.tB@`xP_F GdXAK R`9*GxHe E%РB-j(ҤJ2m)ԨRp%?|:_\\(2WG>Xǵ>\@! b "H-l0#1W1ǒ#Sl2˚1v 1ТZ KSn5Jom6ܺw_</.o,q<_~س֎ܳ'_<כ_9BATH@gi|hfTP<أ]?6У]mpx煨>v"vw a D^ e1NDE!^7Tܰ PV%̀GܨP0AH G -@6;0 PЕpc7|<๏8zZ<:ց7PboڹǠ&g  IKN8Qk¦L#0B Q0\\eIP 8C6@[?!@K%M& 3Ґ_F%҃|C?Sθ|"< =C4%rs'N*- p'I$$ AR^Tl?وE0`?R?a^dQ LͼP/=R @BꐐX-oOڕTTc|c^Im e#CٜiB?đMBEmd1̐J ϸs+?\3OׄMC?aں-;PMI$e0ɐ eO^K2N/? ,ˑRIӌo!ȰdB !uBEXwEl-Q &`S CP4HkrPvJ$}P_Pӏ2/Bʞ!YBuP?)$L ]x ?d b`HFQ%[Cy@ Z@`xI K t~ xF( ^6,Q%Ac,*1P"Yo&% ($(C J 14#ix\{Re.dȒqF90*ꖧ8َ$33wiVKRYVJpbݨ-ELPǺCymscQ>7ZVy-luN1IL̅\{Nʍ䤔(΅*nhEBav7B;< E6^`#c,P>+|D Y`xal5\ؽ|?! g BRjhVj1W|۸ [ŵv-2Z;Ol`L !2$Fk5խk牱5n gu G֠ !;-2AGa}x,HvA-$.Clk)lfz щHdAa 0JXVlB.Xm&S{/xOHxи(7/_:xGp qΝn\o}Te>QH>|,@dl>05HX?{_5$OC LI%QFY)x^ƙ_n! h7,2X0',!?CB?đ7AǔO"|D,E~}XE+N$-=-/DBx1arΛ@\0Z @YDVԙJCPJm@V 8!AC|F@ Q܂%X!^'~"(.n"'b(ZΝ"+6G|- B̽1aQ,"M#U|BC4H BI,`TI04,S#1 0T\^3DDqL-0CK#@":@B#JCPX+CC 38_A)dSTHP?D-AP$0t1$+d,dSx.  "9 !IxĕDEQ\BPaBY~Y%ZZZX"Zh^G*)[*+ER)^VӢ$^+vrh 5|h++"`>+֫+F++Ž( ,Ši69@ :,"Fj8蛂Ȇ,Ɏɖ,ʞʦlʲif,̪,D8< Hdr F|Zh^,-Ѯ-*{>mF-h ̠hb,'~pm-َي-ږmڞښ{@JN@0.B] 0A2Ҷ-."-><Ţ&&kS0KBdQkr|:趮pn'Кiޮ..ﺭ/ECZuQj 0(@yQQKK5P8PX/r[U  d5vvD l@_'Esu%X BEMB5/E_4×$?tBX Fdgŀ?I\x,Rm/nI@L@4yK)0|C |F^g\0uHtxH@ (@*yP Ż2?D`ڻ cRdN08xY[V=_W|^lXE_ؔDJZ+E?vSSSERų@t _p … F8bEDh99dE%+BŇ_Nb(qXN=uhPhP>7hΜI::CWRt8P3'ѭj-tiX(fUm[ 9*\tͻ\=y³擐UIЕMO`:؟AP_%0B&?6ZRSa }c*무j뭸ku.oZ/ eױe>;EKmd^v+k覫+k,l' 7G,Wlgw ,$X*ǩزM^@/!4Ԥlq=1(O)AmЁ4ҔJ q7DCf̘c!Mmx|8߀.n'7G.Wn_! _ۡtA&! ,0_@! ,L! ,p> H*\ȰÇ#JHŋ3jxǏ CIɓ(S\ɲ˗0cʜI͛8sH`ϟ@ Jф*]ʴӧPg*JիXRMJ֯`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ N{exYaοϳ?/AzJ@zZbL*pG^׃sPUҾ?p"?@n=5݃fvaa|($h(,0j5]c{44΍<ƶMB($j;N:!9䒢c9䔤$;C喢#嘖hd:R $>&cO:Pf枉 砅)& i)5ΏG)5Wn3R͎rP>z~[0ͨiBljZL_AVE\:3VSJPPM'h9Hz,o\?8,>Ӳ{{7ͣ<P505l69@̐ 1`CL)3,1דqB 41,pAB&e -"˴?a?3qlZ! 4?{ 4Fx065-D? 3;$pfҵEAǔW@?R@d?,wWICN6LO("?94Bk-F+nBب@ƔGKy0㶵xB 6 >p] 4˭B_W:w19=P^魷[,C Jͷߐ7jϲ9 o7p{?j30p5 PaNZ~hW_y6gYێ;4H!pH 6e<m @&,N!A D*t8D2W5\(@np V$mngID5v(5'UchXmHnceLa2>&i 5 5j +1Ah4C )ηR4.DX81o9r礎lmk @b&EXFe8C0J**"!6`I FXCKh`!}ta0 ӌ #$702Ʌ$@ q 5D/B?10o8 IHĠH|I^!EB9l$3vrd a8ҁ @gBr@h> TL8fVEKʑH*9"qNa1(t!ZGR][@ h .4>-@|ѺTN.dFHF3XrhU 2AҁM>(@T^ {T&^LL5BY ;~2;ޫVZ3 a"thoY}NۺD3`B<,Wv Uh Q*~X[bܝO=?~ 9ržW ~ @#(H 6wڮ|SY#`bMG%ct( 2%7 8 Tp &~[ Fp !q}1rQr+ |h |733 ]|W`b=-Q"~l XF 1F5 x!-b7pSh_$~O8lz5xpab1Ѕ, @6 67P,؇zTus WmmP Y7$aA]q) pJUC?X`Y8x;P@x Qh@ C@? rlE;xkV(o41 % ב!h lRQmUԧ *R.ex Prz zp3ki(6R, `S b #05&38g6l ;(f 9q01I*9̀8Gut:숈h"i]Y)uCu;J{]#wID WE4~5(u~@ﶖ r{d2U`hLr^A4l# ?C#($4HtgCb? sy\By`i0>Aǰ38q]  csPL#aۣ:h޳>$8STissØ4Q3R2ș2Q;3@P P )i= }Sx%@KN43ǰ V d i cuE<r 54ɝe|Ƨm20134AD79 5H hLSs)昢KpQG0qA 41 ֙y950B =`D8y=69Fh?&AbA٥Ҍհ3EJ@)x9oJL3q%grj,2` \`{*5jz=x0j$Xь2`:3BRI69#H9qDUi:"Z 1QpQ4:ATz,Z)̪*yS/Z7\ ${Qŭ9NkӮ;ÛJ( 1;f !dP8cӘsФ2\PXK( GDrB%xIa Gpұ6{8:<۳>@B;D[F{H0[ɈL  VW\^`۵ab۵Y!Y    ж@0X[ x+zkw}{]NpR vKk{۹[q +@+{;;k˻ۻ n; K~ԫk˷q  .(  p @ W +8q +K ! .i-CBq .L-w y1Wa #nB o$|(!,)0; j \6É\Oa`0 `S."=R{ T@ kd e @< = =ӠӪK>=T]V!39 @ @Ӡ 0 D]p = Ӑe}֬ q׈~׀X} 1!T, 7ߠ p  B  } nÚ?  {ժmՖ!PϼKѐ= qӐ m֑ Ѐܗ = jm}݀q}%M <   ֩ M7 pm؍ݙڰ;VNp >ܹ@֗}=  =>}ݷ;n0~@(NP NV=q 0 P\ּ0 me P [khNje E^h+0Q"ym\]Gnq.p P  `^>ꋮ Tʅr.D  PnGy^n~~pP]G)k# n!ھ" ~"M/f΁  ;1 DD XP ^@#<.M@8``Na In2} Qo#$NxTT1o%a#.=1=qQt~".-_ўڑ7Z tx0[`0ؑq՗hQD-^ĘQF=~RH%MDRJ-]SL5męSN=}TPEETRM>UTU^ŚUV]~VXe͞EVZm%pW\<1śWޒ `… {Xbƍ?Ydʕ-_ƜYfΝ=ZhҥMFZj֭][lڵmƝ[n޽}\pōG\r͝?]tխ_Ǟ]{[Xyw]g畫kF>T毌~/hr/!R賏?'HI ĐRe.Tny0CH"%!UbAp E?:;!J@@q@ 0OCXDu%$VC<diVIH6c IxU aZ+քx\AR==U$9A`+X",b K򯅢@RD4 A:z hGKҚMjWֺlgK8ei P[)8e>?8?Z\D`Y m ۙ\My! ,0 H*\ȰÇ#JHE%\ȱǏ CIɓ5\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKN=@pU~ËOӫ_Ͼ˟OϿ(h& 6F(Vhfv ($h(,0(4h8<@)DiHFJL6PF)TViXf\v`)R 9yg&X*4,X2'[ZPO{~砀*h*BhNjV饚vʩZDjVmU&꫰*무j뭸뮀EB).%g0! , J g0:xc(ǾoM\0~ '[<  ZK!! , Z@ H*\ȰÇ#JHŋ3jlx`Ǐ CIɓ(AR堂0cD`#8sɳOP &5$KSn2 k>ʵׯ`6($ٔ6 L" n;փn˷߯e 矰-cu +p?|QϠCa̙`8hˁ4Cl4 ZM 7^Afy b]9^ν_`Bǫ_Ͼ{5ÿOϿ(h& 6F(Vhfvء$/O0&aG8v:Q6T^j>BTE&Id!PzJ gyXnaX/ds@k~g?#Ӂt֙1rvm}Y}`j袌v7 'fJ #t@j:2h:V:& zi*XHD@ Y  d|QHqª#Ji4)1MK.ǔpCT*Fζ8 jûrs+nqZ`f.,N$^2A x;mR@Gx1K.v:sﯝ"*ƹY\P % wD I C 2sL\Np[AɁ?5_ d ɂDBKpVC)VRPkМ2O(L28#N'TAs`c *@@5{9EMV70# 9 -P)s,EPRbdMRoVivC0?Ÿ/>ʼO+#Pf)_4b@?Z_`A54I3r^A~!?"PCOE@0@+As$H@bDx | l ;fŁ4c,c#zŌ"X@h|C!Q!AB9?e$4 DẎ>(4̤~xt\q K# O8FcL}XŁC|r'Q3JU=2AB?R ~,  8Z+ {@:%41 Y"$IS $7 )2L8ˁld> Xo%9R}T@`ψ4ʃ=#9˂Yb%r ?4 Q-:Dfb 72cV4_\7$S)4Jqq#G=Ч3ḥIAԂxéOOVjW!d%2e^%*zX)D!<`zA<ع#C6P呫c䊄x: 3ci%1(;wm\!@haPUG6zchDA(0,A F8Fg܈ -kU;^QIIzuk]mm?@IfH_!*W  ; I @ޓ#=yݔ S̛@CnxyKY47,L?G dGQ :Y]BhE;.D P q@  tHrR#amn 'x fij veFuAhp}~2c/tI~NAYr[a8 ӂ?Ӄ<9,{ !ȯ#A=" k@Y"XqNК1阷g4v#20r8V؀wBZr 9AP+sqQl1 ;ˀ!q#c$~@nmt):v HL1x4qht#~$790cdlbyxú31zDpG:F{c >omͮ*[Px#bx[C59@fl3?_!T'%V+"n g*/1ElB Aھ?QҜ zD!ùp F5YRy *~ Y`6RSpu7PDxt)kW/bٰtuZYT%&`\`oFW)fP:a8 Dc{Pa[!~qtkfwa@e' N$`zt"!5M1Py@ey Yq yL8E6_׀ 8(o 5AMD lV[!n4#4y PXp66# /8S7g$a de D5&t 3@~,2y~t\`t[ꠑ6eJt quXHibEpI4&M5#0B479#|  vuZ ?'-wTyn;[ΗVM)sw' s!<$T) x!xH :x@VHe1 bXʋY'(%qzDZ QavI=P߲h7 ӢcF0Pxw et zw}Jxۀ.ˠJ_Y \`!\cA|qP(JZ8z%AWw7@J caa3*2/|8g$qd1 u ` Mrԕ@9^&` %{9f[`K0 I@$?zB(Zuwǰ;{"F6ƀw]8M7 QA5@FkY{`wwV p {bi MK?` 1j;b1mX7QazA0-aOS [te 1{ǐk`LN;YJк&4S:*,cl+kAE>fN һwxe8A |M@ u憦pJq*DQmq  u :Lr,+9o{|sQ~[[׀*mv>C`qmDEIה[! ?$±^ DAdRm2dZ@q@z= t"q G{9k"Oװ u7l k@%Eܽ{Ve%̈ eC! ,4/gFɻXqUXA] G 0j=l:XsM``% 3 . L j(ERO ÿڣU@QH]cA~z< nYp'˓r M+꩞ʜBdkB|(I%l>cNp]@NZ \v\L064 z\/5TVM[fys Nea3? ^cw7t{0]ưQpv0\F4Ҭ%=1FB4P66 ;Khf'QG̠pDQ7 b^\ls@-mo1%T 0rs6CR>];]ǵq5oѬe,_6^mB2` ?1csr3cݔ=~b4460".O5EO5cfEy Ѻ]G[5=z}^>k]{6]GQY/!~]|*>:sSgoETfmCo ;{;>ՐVL,=[z01B ; `.fQ=.mvoX,uTЯ3DҖ30vVGS ?Z PL=`#ՀZ0WZa~l\\~-)Bq4ҟ~rn6 `XLYA_b&91:밊[7QX,ƌe#Q !P#4!z`n Xg1ܲ `g91}sNv4@$؟!Oܬ.#Q4@ DPB >QD-^ĘQF=~F#MDRJ-]S̃#P0Kc%ic 4ETRMA _|,TS]~Vz,'cݾW\̤z AWKJX`… %Pbgvdʕ-_>yf̝=ZhҥMV eQ0YQƝ[N|pōWF;AK ASE]$In! I>=%P#]vqR܈|{y1ˆ  o7I9rfJEDO$ESdqEUVJİ+À"h{*|fFF%d2"J2"xŬXHfL$L33*(h  `4p2s%*OB -PEeQG}QH'CML7 (?4TDuTSKETUGl?N_5֟V45W]wUh?pXXc BfSH9B :D6\q,3ڃݶY䨠1@6]u74I!,؄/$vƮU)~8bxO:Ix !k vZ'R_ - 1= jej9f(JZ ڢ"΋:&(7 %H 7L؈\(lf{[;o&0hDH!!V@p < Oq"`)2"%;x {i/(XP";/̱DJd%h /:i")Hs;uUBg~1M:|ƨulsp1ț(%x&pŠie $"IQA&кa$ [xFpKB܅Q 0!<KH ҹ\.FHX@` 0ꔑ%k W\PDAoCA>ѡ/D]R!F2hb C@D>dYP᥏xKL6#G,4 G.vWBTENj݂L%5yINn2mmHp@eBD`^m*P|I@Z{E7 М1 Hdg\[UV \U^i]ns" 8:OZZ`;A͞g>O|$4<:P$hB 3,&f|F\hF'SO)'W !hH."2!MhLBJW*|JLRM `҅3!@T&وT AEr:oeb s!@ gKȌ17!5km4X.ldt]a1L0d lK\6z ]H1e5&Pfg{g 2Ud! wK -AN;C<\$C ) .ܭTrۂ8ªN]G]#<xIuM oD/G=P"r[$(51d9+(Uz$׶6S."aKv0/Xܦ;rNpzyft%= +Z (5ݙ6gEGM)DCIeՂ!AY"_}z%:Z= ue\ ["赲U 8H#q6atmlw=nrFwսnvw=ozwo~dko@Bᵃ7mx%>qWx5qwyE>r'GyUr/ye>s7ǹP?s$B$=D9gq 9)v!_g?~Gտ~?$4DTс6NY L04zY X D+": I 6 쁁Ѐ @ XU챌XA`.6dkH30,"# /C $,4xH!ԁ(0 ;(Ď=$"4X, @lXk@xAe74UăC)9 a p0AdBB+'Ys c(?TQ$1(.;#<% ɔL̹̏h nL"HL 88\MkMDMDlD BqLHc$N̨ʏf画! ,ue H*\ȰÇ#JHŋ3V|"Ə CIɓ(S2 ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسk/`ËOӫ_Ͼ˟OϿ(h& 6F(Vhfv ($h([ ݩxV.Q`#4[!! /q0Z )HP[MP4 PUwD7Z(0X7?giËRy ꪬ-RȐk*R.IP$+k!&,rU>k KH?J))N k.n+,l' 7G,Wlgw ,$l(,0,4l8<@-DmH'L7PG-TWmXg\w`-dmhr?,R]p5! ,L! ,q; H*\ȰÇ#JHŋ3jh CIɓ(S\ɲ˖ " 6c@ϟ@ JѣH  ?IJJիX:$Sׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠM ^ͺװc˞Mhdͻo .|ē+_ ˣKMسkν'56"WO^T*8'`}%4_FN _u0ˬw6S!GEHc,oVlbwFL#˶i:><Fr >.3A M=8F^AD@ p+!P4\ LyG:dBCGCFf7\H3( !dW R@ K(I⪇ S`eA\N1,H5>4AY dtYHT' C,#[;b Íd˴ 9 TJfAT)K%r ;jm&##Ll($Ji(SRs DَēҨ>;=֋r p3YGL"z tb=cꪚBo !5!%#d4c :$ kDÝ |hQ4=vY3F 4CB3YX]2ꐜN{³xh:kchFo' Nm#Zg Ŷ -J]D6TW%3r!7VNN}@th, 0 ᥹KdzÝ`% ՁHl鷃% rXGy#Aƫ xbTV9X%*ЦR˂'A~Ђ`׈BȱȴBe1IhF,Qb #ȁ$_z՛ϭ6e~ՁqF e$#w d`V tZ,HzV ņWQ9SS+%mMe9nerd (2QYp"ՁW2{7yK61N-!/B)M( f4d&;~b 5%@Z/l;]bPg>;G+9$OPIx璙u:\5B Cc8Ü)0mʶ"$3koI\|2Kg46&d<)(A3[ fD4E lF1hoї?y4 hU ;#GOǥw2oc`2pAl= Ŏt $!TEDԝMQ,3 DB\\ Hhi !9Ba s-lQ/~g}$5l/*7y ˾ o.q{La4 0Fw̢>1Si4f/? 9ɣuGc!݅]4rbNupPnBC]4ngpp ƀrhG XfP `lQ612W\7R{`=q1/#%-A[ ` 2'aFcB 'vrrpV{PVum1s}^g%j|pArHU V  vR ĀM԰H81pP6Bp zIwDoÈE1o;& 7Px ׀Ob8<{a6l+( װGa`4 49@9|wv5$IX0wwV !1KBdlxk |Ur\ q YX#!Q/I E H JU(ĉ!}{h*y@4pW!`M dD Ր'$8Gh HI@b;RVy ,gx"r9RV<)V @4@Bq}&B\9 8ҔqWfBD @1 d\IטZi$R VїňBf f#G3]3 `)4xwR6 `$@ cC Q_::n#m@"KoBa Hrpiހ 4 !UT_ r/ǔLІe&(!!]3;1psybBXd A4VĐPG907 `4E@cNb{ n6$#] t$c "&e_a6ybCC2]s rK:w#*Zt 48iBC g;gR{*:Oa G] ^ ys`r{$&`JskPqbe"BQ=ѹR6Kqo+j&ۺ;[1"7 K(Phkʻ6J o xiXP=;1=0"b[4۾|;ۼˈ)qLPkamRAgP r &P}Np  QMV]ڢoL ֿwձ h0 a bz>v @!Rg#4 !J{+F<׽*Pz0p "q ?e hB % !ª|[; @p]LV=ftL/Rbb1'<3^Sb/a-ۗ!qw JFT^V~Rz1s0`Na>b^d~&Z$q mnn>!o)2  ^^k$ @ҁҕ1&MN{Bܠ>(A J0ҁ<\$( A$(q  "g~R"->^~؞ھ>^~>^~?_M>?0N/n p! .w ڠ %1 D<oOMDP}UOC-paf#Nlnpr?t_vxz|~?_LDBp=  ! ( |@ 7??Ѿ(`Lm5%]pƟ˭(  qd!oh;k?@O@G>_ QF=~RZd$I-tS̔(ię3":wi#>Et:cT*Q L!T]~ÅcdžZm|oeBV[},5 ! ,7: H*\ȰÇ#:"ŋ3jȱǏ CI2"(S\˗0crlRBilɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ O}G:1ЂY1  ډsB?3y# \G+2 z!׊" {+,4nh1V?`Å8ЇAJw 510`31C6\:#7Q$A?E2d2^GNA@?e+^AЏM3!Qn9P7 mIK4`L44 E*kw9U:^*6jJ<̣$@pyP3rJmc=}񈂽PyPi.o#ٺl>:@9FO=:6krgƶ:B0yb0Do y' #AV1+{_̥9z#A?^(xK@<{ еy\9׌3B8J Qy̡.x ])ʹa`$L(Ly`?7&W;z:wA$[jv3 ݌2[w@t~b3?( 琳Oܞ y1GσىM;.?yӻz1 ZO6#yx45i,3t36cW`-P1^yͭhA{>? 䔑1TRd9ԍY 6dO7$ 0kj?lh@ȁ*o\ b:xG bBς6ah2h_  ?fpM3Փ3X8[ Fx16D;qt'(FiA : /nF3q=nOC~5pAb< ?`H\vkÄo +łĊ GNBA dAb%  a@x{ńRB!A@4CCw0R{ Y 'RKg3ɚ#hDIAbA)HaS ͝tidB=l'47!D(8498 C;[4mH3y v,N:.ŲKhdMCC 攘# q ?!\,,f˘ à\r@Y`7HV-[Hϒ"H AvYy\ byeUZ՝EJQYhbG o`E 9bsdau8JQz,ybМް` :r т0 V$\,;m[1:r.Vl X<׆u."ם0m@7Z&f6" ] X} >ƒ/h(KV`T  @#؍6MQa#Z ĠIn@[ܸ&8§Ȩrc1`&$iB3*H~{<VY0{&h@.\b&Wd2>f_cEή,,`kTL'K >gxJq"bL5J-mpA]t`fV"H/," >̒7Fr RR@c/;ze͵MjIM%ܮMfpr@PܨZkRּ;3~NO;5F{xgVGzL3{ X-r .9]2 ;Q=Iޙ% Yrl.v]F ԑNvUϺַ^m[d\ˍBl} :ø^.+nO?D $$8q̼v|)ATb؅*r V@r DG$>=w'pvI?_w7e~G YO[9A}p0w%Ѕ毟- h)}07׮4 a0P ʀ 6 qy0GQ Qx` QAP1}e`a~vC?B8DXFxHJL؄NPR8TXVxXZ\؅^`b8dXfxhjl؆npr8tXvxxz|؇~8Xx؈[8Xx؉8Xx:(jЀThJ ==P -b! ,t H*\ȰÇ#JHŋr\ȱǏ CYɓ(S\ɲ˗0cʜɐ͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^Ɛ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOqHϾ}aE#_h:m(x~~qDG.Í8Kq#r"vX* <7-#$Y.q +LΓh (J.M$3>7JsGT) 74 4e.c~T啤H@ؓ.b G!@.%! ,r= H*\ȰÇ#J(Qŋ3jȱǏ CIɓ(SD˗.I͛8?Ɛ3= JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCEM O{ ud:/4D7#8W0@bCCK( kfNs3 BB@/ NO !"k h&ܭ2KnbUVB4]o&9( `!A7pD&n)a  ڸDiT # 679 X!P2D@R&‡]"@$f)g}].TEs矀*蠂:C衈&*裉餔Vj饘Z diLQ1dN~( 3N0CP:ʪbMAb!8<#Ц?ޚγf +j+qS? fl+Q>XM ͦ=>:^?D0Al1aFT8V\BYP>/<8E8",,"v,fP tO#sұB A etk<1[.JPGFŵ!2W3؜E.eciLQg0~SVMpp:YC!29Ze>CC<og0>Ҧ?C;鐱 幩OD4l}7 d+ Od4L5|P#M5 s3\>ULhAS<߼::6Ĝ38YhUqY001$=H"(?h(t -@o aD 1W(b  8vP%PG7x8$O C+X5Ej0|ѾТbX9cZ)?\ $ {ԁrGI2PD>,1iac-C #L15A@&'e& ?!=cD0 @jJQ럺j!ł^F1( UF@COz$_P*E*rBo! yL> CZpz@ B=21?ІL@ :(tqy8B?R A|ةhYBz9=YףC9d 8UV= $0ncHyȆ(5zЙ @pTRd f4`UvCfnZ Qg%Z]熐< Ybwh,: $a&^V8QBl;k :ފr!˂dHA *CP|ndT!`A݂D-t޿{PI PAJ&PF!2rO5| '%t5V)q# gExm M*}ATCG)0#@!2 @a f p3a2x m%h+ DgwSɀS $)Phqbf&25ipIFaSPIЅA y2c|' '&71")"  X!"hъU8Fh(9#!9(*^}yVCvbP C$FvN^WM9 nQ8c86a VN5BPeh.1p 9!V3TiVEE] yU8u"hE1QtGyDG{4I0IKt17e2j I aĉS4$D+{vgL@pWeh$XMe !d@@p7I@U5~iQuy dQYy""Tp@U6(23=_SKt;{nZ$]1 yz60_%"'s`!t%32&$ڥO3Xta*݉^2jvW 1#¦&sq2"%IqN3`?Z/@eR9fz)'y41xh~S*0=߄^3Y_ /P.e_&R Qa6WB";V5X$>剎!aU+d 4Af;KnkX!2}BfY1PARPB5@" Dlʴ%p ʷV1VD5k@ aEBtp˴ʳfD\h([d+b/ H$Hk>E;Pf3ݦ A aDA4@ATBS\>r@\uw@;'}u[J1VVCD gD 廮 ȸJ癿н"`St'3bP* TRP0V%JfQtN EB>Y댉꽊Ԥ#U,[KK¾b+kFfcFrI<E>3Qs>RBڽ+JKCCT>V+t1]4Lˤ_dgL} C/K阿`%0y|=L{CAd/>> K'~3 ۀHdK+&Eij+˼$2WR AMLƶ,׵OA ELܖ/Tݖl@Cݻs s`Lfn@!2 |2l_l !<;>^Њ5N-CЗJ! ͷF:62`]<G< ]d2 >*+G`S78БQ'jB5B:"L<*c`P@<1 xL8C6[\-fF0E)觢W Xe}X3XZdh9Lψ#|،- d!ҏ].Ԗ(60q" ڀ29!_r!٨yA] Kۼ\%ԾcY1B{V܊R--fT(=%ͮ7 DDW ّ в #Ҁ$*}=kkϽ; -Qv@mBd1Zـ#_Th0`)}y@E0@6A 9C `Aj- #yLL~6G!^r9uVn,C:NanggL@h#υ; : P {Qq> \88Ap@CAq't N0p@#.qj!1$sAM>^]1x h& #~1PN}QCq! ts=zC`wۮlоxM$`=³Mx-@pSp0;9l1 {1{ܴ@!">B`"&p  0 04}wuuw0'<]F.( PI  GNP?R_OL7'_8<~?J$~6>RfI[4%Xoox!zf9mK kIcɲAAxC1YڰN? 'Oh @!0V a:ސ CwhEo'B.Ry;u@l n\Ϡ H)Q O0}ڐ 1H9}o/7&BO@ $pР-TPD-^ĘQF=~R$"$hoJ-]_cA0dMEEdM."<ħI^Ś5c2) =Zݾui@\}3Ix ɆR ?"4ɕ-_L&Yu"Y hҥkN=x @LRۡ:n޽}|bG\#?]tխ_Ǟ]vݽ-]x:7^z,RY{n~?m"I#@1C$] &B +Đ0ۋ 1D#Cq b 2gCo V,e Vz\t'T~G)2+UJ,L%YQrAGorQ*ds!%JvHaem"r9.$P(Fݾpgt́4SOf "G%&G^ UTirT@_g\?xu X8!h"IU%I?TKm}[B/crLPX5HtAqKPX[YQ[}lW u'I'M!fSB\EQfEnH(C,ȹ#9P@”RdwJТy&hF:ifi:jj:kk;l&lF;mfm߆;n离n;oo&%SYx秧>b>|'|G?}g}߇?~秿~?`8@ЀD`@6Ё`%8A VЂ`rD~4HP ":ص B=@eVX,$@24`!L$`"" B`4 򁠭G@rł?Dz &b )vrv@h1HiÑx7N"Ҁp|,,!7B-qX*fbqxA  IEn'H"0I|`! TZ^A`XOBK FhI,E-bX@%sdn$^fM +;ds$ +[zH"<33L>ò`ZH > LaSs@"NuC! ,f H*\ȰÇ#JHŋ3jǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ J E*]ʴӧPJJիXjʵׯ`>$ ٳhӪ]˶ۑzKb j˷oS<L8H +^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(h& 6F(Vhfv ($h(,0(4h8<@)DiH&L6PF)TViXf\v`)difF vM! ,E1; FJH3jF-"~79O>var@]XA4, @SІ a~ u:P}Ϟ"PL@D3 pWF  Nm5xO#YN7O4˸+ JK$G*Eݰ/ ?1LK2*(܋'y(Ԗ=C?jj+^ྐ̽F6'WM2ld@1j82PG6Œ-hGE1n o iT$H8 YØU dDN[*6n$ӽ8*Ī ~: qŹh lF15J`?ɿIe;X7rm MVؤxs|2S,fYAMՠ&tQIl#S2 l$c 80x^%`QyfD g; M$>?G;drYZC b G<.H 't!4i۬8ЋllSLAAfH/pPF7 x*?Z`ҁ hRGio&Mop|AzVnPHD}5Fy $|ᒷε"M3 BfC F:(h9,&(N0 \B+Qe 6uH3݈@\M#U )gA!n㔀 ] y!@9!cS;/Ht ߌH Qm:];ӲbdH=Q{l7' 9 Hz ]Z==-8hS)BpI.QeXW,Lń:+$u=bp](W^g;KEމx!i1f) Qa$lj`wPd`Bқ\F, &Ȇ-,fwR]nR߂YG;5)OʵDXG!.IhD=Ab $~+5l8 ˲Y81&ES6t$9{\J}Wj(nb-Y2>%87Oʜ iƚ 59c9r et^`dZ"6HYҁT=YO$Z#T&Slm5ĵg62]X,xz"#!G ҋtȖ\Y ^;읾:/coކzꇒ^8*•S6Y8u F;Hw°>BH8/m .φ:NhL_d8Bf1x^N~+ZAM? x   0z&1 MA%!{ Y~Kp 0IJw w x1 {aV `6tt=QUh@m5KWL?CARgu .%7 `BgH`mA9  ]jriRcEzA74.VV)8W j0YtJՄm]=s<` -62|ͱ Ā v kwPrA;z$qذ+@  i1,h{Idy@Y 7LrjfP=plq4 N` 0kT50 CIВ!7-GifSZ: Pl`;7jaXsp PGPI{7 dv"! R3WxlgٙE67Fӵy,47z R Yc yTCy tIĐ $JE( z b9cٝyt S4F7 Lԉ瓇480)uN6.Y2zP;{ FQy)3{BOs Q OuTQ)0ϒ`$긞s#wdND6pN195 n4XA!i6:9ǰ 3Gq 6 S9 ,77QEj'48O!\P5~S yF6!ZT@i x9{Ԟ74pyfO IQ4)Gb<}*Zf,4Ys㌇U[(8*cQ џO' @th5yʦC,t9ЪcT4 zj*>jIB"J>*8KB: y8Īã麯^NȠ3ԛ2P $0V/ڰ a;*&hFNE`&> **I@ɑ0+ٳ`1:ZZǰd OP A[C78zj;[ !qPt QT;6%LK~^"k;[9 [6J4ƬR֭Jr`Xj۷ aj%3m%^բsHE19~;[{۹;[{;[k&ٺ2[fk#[;{-+ěۼ;1! {+1ʛ `>{b%{O$Qۙ1;`Q+a)aQ|=0ak/PNـ1a,pQ@/PI>* ЮѨ +pg +1@̝jINP|;<ѤQ|X#` PYa c\1g(jy>%C@r`|~ǀb|[q;ZS0h{L>l41 E Wq!Ʀaʥk$9 Qɚ2YjL͠Ҭu|nV^~\(ta` 9M'(*,.0>2^0(P㿡pPME~NNF ^`>b^d~fhf}P.ܝޣw=}{~.pFJNو->^N~锞ׇYSNؙ}盞霞꨾!u-ڵ긾뺞 aؿ^*! >ۢM^~ڞܾ~ yݏ^u=׌. z>z> Q?_O  +`~> 1> .PAQ~^ q _8o9!#ǾܼHJ@}s O UO/ $^`b?d_fhjlnpr?t_vxz|~?_?_O0ԟ?QL}]  `t/l"\ρ_j߼P? zP "@Y˟x@ĭZx\@! ,7/= H*\ȰÇ#:"ŋ3jȱǏ CIɓ\ɲK^ʜIM-b4( Ο@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(h | UD$ DhaK 0Ņ 3`%,jd CY1"#1sB@H@ D# \?dA|QYeP(1>2wI-1P)Ѓv8@\)P)1pf1'A~ S(4d2̥ bC16A&!vxM3(@1pI@D#, ؍JЖb0B <ͣBT#[%6:2҈ `>܃?3;Pg+_Oą=#;K@ Lf8#Pǵ@~+P(@7dL97M,6?'GLBb@.̨'S_*b @%1*D \Q#(>9ϔ 5{ BdA)-G4Γ 搮n _'AZO"D@dR1ԥVLC#qT1 PPi DK_ h~kDmjt*J_$Ʋ9$a̍GrLd %@[D,!rr:B{(l`Pe#p%eAbbCIdH XI 1lx1odCHxD%=F&/=?ՂLHÙ[ Pt=oU"K"H[Y V,NVvOlQkU7iN ҕL5~\Zt 2`[ =bt ΁l)T0HT`E*SSgA\BPu+K $(›+;%n|W'FmEj5b@:p_ejd3m44#C'U|T rpyK*EL8v*BiFyiaBLv#+-wλ@@u@yu5M#ӠtQԨN5C&UUv5y gYֶεw^MbNf;[̊{tki~ζ1m{Tt`HA6=|.(H} d KM8tA0A>)B6%I` `A@-bg+h~f - 6BN+>צ6җ$PԧNuGx}`aܠ艵?hDFvkfBlgOWgPk9>84م ^D*]b `}e o&0xE?zUD?Sջ@ڭc\'zޛD؎#O;dcWrA}Ͼ?K*?M?oE $?-^eP ̧D{ ؀8P1vlrA "'y' xq !e 0xQ7e DH IM&(vr$$HyR\mօ`b8dXfxhjl؆npr8tXvxxz|؇~8Xx؈{8Xx؉8Xx؊8XxX)pȀ>wQ旋øuHH=( fҌ֘8xo! ,` H*\ȰÇ#JHŋ3j8 ^8Iɓ(S\ɲeC.cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(h& 6F(Vhfv6BA0&v A8/X2hcQܨEBEv%lU!DcB5^d@M5-Hlp)tix|矀*hk 9 R A (kC?PP:;m394J=J @z*蓏?i:*A벨Z)ϭؒFjBt%{m>fkf+"@:F6@V N:n$ݺC&L AFl=4N5*^@A pBC,?KP3tO> t< j@ߵ5G|NfTY],Zi+[3!F6\ȅԧ126TJ;,@*M7B?dL+ M`@LhCSf/1q$$L47^m4~o?EW.-As't>H @ь' GPjjYok>^3Z*Ae2Dq$F 'vQ yEj0DQ8Ip!?¥X HqXi/kX_A"pH yn @L1)*#:bnDw?8#Bs|?qR`7kR!`(B+d'q<jDaxHv ͜?Zk dAy Pe KjK hcE\0C(vQu32v"z&¤#͂ ]!fxEF8$)S`@)bӏS F:)k=ZiXØ6f*,p͓2z>z6!a8cDkbvñ!G5yu!`gYp6w5$Qbsg(X9 qQ(*( ` 7]xAx67D2Fk$:\pBq DpSB{T!& @xvx`Hp tmnqu f &e@|7'E}WV'v |DPcWS OaV [-xEs$(bG@] xBg>h"À ."B! p:(}}GD Pie7a&t 1 ,}XÌR.x~(72b8Y:3q%-r X븃} C]=U p^ !kpy Q]r%c1|"-S]V VSE90C p8(=!Kh` V~$$ rP}srzY~2][:.YoLhu@B |B5 1U"W Q .tMPvH'@  Кk"S!Q qBp$t Xi a(dž PX7q x2Sa!\l22I|3 m'zh @ ՠqu߇@ }"!7PY(A Z M ʙP{f"Ԡ"@ [7ג1}3P%M {P tU8 @ ŌW4pp:P^1;4 W Xs`qp r P#$ik50!5#yᐴ1J1L`5_ a3G|0Za" R︆'" r=7z1C2SSZ2EfhS_bx {T^9{=1™$k|[ڛDRdx(?ASZ@ MQzM@~zBѝ@jB琄UU  ڮ-3B[Шn=R7py Vp;Z4rPx" 92OA4SDrV &"&My$EVT5$ `q:EдCRD4Rg 6o 𖷳"&Mj󔀐&2G|3 L(U]%EJEM XTB N4V6Rr r{;DDۡб{s.PL|D3$ưh$H-Eׄ|G㸋o U1P[?)CQBՀ"YP˯dWT.uIuJԥcM;)3Cp;r0 qPuU|C! I$NW]x51QrkT+R7,˪[t[jA;V66C [qK %^+i7`Ef[qEHn:OG_[Bx%'+60]JW۹eYnʯ#ոJ3lYz?*"W2VB bV|ŢbP &)f`c|uUNq4Æ!]j|.K6 La!ȋz:bb'gzJlnsə ɤ\ʦ|(||k zʢb(GKv'ql}"gc[/kiL@l1<Q )P^˔:S! K|܌t @!rT$T122qt&[F0bvq/D'ϼ,!W*Q#%9660?a+nTGQI pQYKXXX'4^oqh30k`=&+%q T# a (I!r}I`|ݸ\7 `&I|mrI׌aȠaXD׫Qמv!ڑ 6櫈m8C9bPҹ ,xPA ҚVڶMɮo!QK-5}&ҽTd& b5k8ʣ ߏkb~.Ϸ࣑>Qg}]$P]gwN;blJQ`1 nrǧ!`G$` 3Q?>^M>;ܪvql )y^ @    g+Y3^xP21m@oY+8)Q  瑮  ~閞阾 f`q?p#|"櫇n']NዳA7RG-!>!8J%~y<A 0p>i^Dp\0.ސ Q\h@9`Q`p~pv׆#oMb?_.y [ ˠ/1Wm7"@ G  0T+ Rq \@m.KM$~!} %qm&ڡ@*1cQqIihQD-^ĘQF=~RH%MDR%=q`D4hQԆS/p sQP&T>UTS^ŚU֐2m6T`NJ0ZҺuֿ"EjF\X`… AC" TJ\VsRn(fΝ3Yh~,. 8Gj֭Mv[l #hLڽ}\xōc=\r͝?]tխ_Ǟ]vݽ^x͟G^zO @>;ǟ_~У h@NPA!B #pB +B 3 0DGȅ\TEigxE'd$Fk !heu8n!Hf{F%쏀\rorEcK/s h`eK *M6t3N8申N:,#8AuL(6eRG#tRK%,œFP^,4MPJrTrUUzU-Wg]VXi2Ow9g2 ˒Bd[evYghGZ^ַ*|(iϭZu]7]etHn祷0S!%Q r.sMY7`7s#⅗p~+ZRb+b3xcߍ`Gl=Y,I_Y+69gr{n-sq˝F@X!it#8kzk!bh&5 lEYc,;ot[oz駧z>{{?|'|G?}g}߇?~秿~?`8@ЀD`@6Ё`%`02`0@CX5YFxl@ oT|@^!TnpqSD@C‡0"JluP"PVi/Sw.',d{߂, t@ǴEd`0 v1ƀ5}A?x"B?#_G{` 242ҼhdAP3!3Waƴ1@mhx#PI8Pv GK/CL6 3: #?tS̕ fB_8a 46:Xdx߁429hBDs@&D?_ #6 ̦j84*XP/hԪkx tϰDN55FAkZ3 9#P>cr2{*HLB *q.N7P8L#5BD{{?3(;Bdxg*%K]n/y#'x2:⃔iu]H`i4U$ʼnL3k[òӊ~)@(@48/d+0ƕp!"KFY1H$ Wꆭi6Zjh x~ a#GhËFCD)>B(F28:N"iD=dxHC>x/22ĊԘw(H־2؍mI fԣRD?j#i_ie!kL EVFfy lIKK Õ\MA|DeXW]peyq Q$EfAK3\7d(x=yfLBP1܌ҝ@@t!bs hACY$P 6hiDnx`vZFQ' ı&1(O7" Dۃ(C3[FH 2 vf=qJd1ɂBjU"*fQ}(BB R-kgdR9xBXPMEH d^;a~Z@syfS! c/A)DѶ;+eGLlM׀*S4)298ܚzr`ָ? P1FKBq6 )~@BFͬw ֎% @yK srW2yBHo#`;"V3B\,50GB%S9@Xv0-V_c6U#!0a%;PL*[Xβ.{`xX)\BfxFaL:?vγ>92cp4&kHNXF;ѐ'MJٮδ79 ^(؀ѢN5zBTհg=(.D[uWlC]оMbNe;ЎMj[ζn{MrNvMzηn&aMp iBp6 .^84uH Vx9k"@!8:XH$Pq x| A"Fgy.BW] V:ַ~k\Nvk})<}`;^v} 0-1%>xГO}W†SqTnJ.<伀Fww?;O?{&IGޏ۹^|7Oy_<⥝u[}*x_*lvwu7y~뷀xmzXzxW~mB}'wuW$xvgwt),0284X6x8:<؃>@B8DXFxHJL؄NPR8TXVxXZ\؅^`b8alC?0G=N! ,L! ,q: H*\ȰÇ#JHŋ3jh CIɓ(S\ɲ˖ " 6c@ϟ@ JѣH  ?IJJիX:$Sׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠM ^ͺװcZ۸f! > ē+=`W<_Ng@NԶν;i۽Oӫ__?1FO䗴pz&*)p6` )VhX])@.]#P A(7r'&T BSW(P~ ș() 8R'L6PF)eE3XfBA`taih15Q&11,4Βr6~*1䞆& 6㎣@#Oz)At*ju騨VgNJ9{);֚[ڪmklWvBArWCOOS @ M}1d/Vj\!aADjgiVPO^nt/M;-sV0d - G,+ 1HLU3@ D?Ǹ 'rx#ǁ??Y`-7L1 , F3C 3d?L#!|7$V -+-9oDV G1 C5+S4ޟ$4xt -xLv+q#;)ٴ c?_Ag?cs ? dLƳ|=R6M E|?+ ]3!@x̌z ʔ3>AK{/)a`1J'FjB!:8diVf/hF4A1@t !Axaȷ; 26Le;HWQ 6"jX0o$!(x<%c Ck<5@U8& bPM!ĖBy U*BюG>iPR=d(@7b`a,)[m$U؍ⱊ0hVun},(bdc H($iTSDha&tR4H G=#f<=V"6N֦" r H(C Op&3G)J*Vc،?/Ƀ$d4sc.$ kDևzǾJu0yFVC&2@LLZlÊ(vQ$H Ҵ`f5A c $ IuIQij4PNdPG aYdchX΁0hS1Ff<ABV.D3=ix,Q/vzD@EϹa !VPZlЩ2 X̶pWu`(8 BP ЌXKVIm=kA0⑃y5hҎ}"[Af(V-L!vX#N5)y f)@)|bS1y6L& XD|ۣHVx19Z#KV0A/6de/Osj1ya8sc?syҋ 佇H" Lgt*Iג" l0A@׎n0p נ?GQ/3t)G>p,\fdNԍaxBl_jjA yO  $ 9n'l\È&d2X1 d&A"n'yB KL?&~M8x4 b nj67E &!DBI6l@ aAށ>.T# 2eH(=~po+v0#C+ 9U|}q ha1 C úóh`E*}o?eC.Ȼ7 WnH}?#!!I A;aXBj!G}W%!4pWa]S 0Y/y wCe@B_H;An g@gn+p7T9mÌу=iFA0WrBԀhM񆕨= X q*A1pLna} 0(p%Tz#>Vl[|4s= p u#@Q" b6y!x@(Aig)mMZIa2/  :ms==sd$ro$$?sKcDqsGF X95#"y=2(R/L>7?Ӛ4S2BƖyn9 ;Z($9m;S9cJ071 15iY14i ʼn2$ @S>B|i4F#v:;<SVR92%99BqUxp)!qC595J+xJ#?j! 9-Kl0" YrCZkIi#Rؠ8z[3CA:SäT19 zF !(EAjq g1-*;J 99z 1>64 ӹf!u\bW `Y(/&AJa{;؛Ao;׽mKHA[pҋrb?rLa @ 0"$+g~B5 \1% o3A),8 %*,\@E&-2]5^7a!Qc;k.B|!i8 8[j5?qF=3 MT=aOA R[z$ Mlǂƀl=sȊC  k} e] q90V,kR[ɠ 7^1,uH1 8)!I0glFx-pF|{ 1Fү}Ҝ Fl+,͕a_+v 1=am/@ Eu;PT #1 ` 7W?zo-~B % !ܛ,Nͬ( u4vFMra_86~k8x<']1HPRYS)PW\9^&Tcrhjl֜ԨԷ q r=' ׀mz=P؁=}=X0]   $؅b/   .+PW2_! قmحMT? ׊ }2/.)q>}- }Jv*MAM߸ D@P l >^~^ 0@ M1 n;;N H4A݉Q0 ۪0TGNZ`ػ PR>Qְـ rt>v^x~]P h~eX؀׊.>{p .墮 TZ. qP~ F~>nŽ\f ~ P.~Hɮcܱ e nC!n^=몰 q?zQ؋>Mn}  ێ}N^~*&/ڃ=N@?_AF7A;VXWYOo(5/de/g׎kl/IO_Pp芍 |sy݇}?_{] #0B/_@_?_|Ae*ƒ?_ȟN-_> $ֿ}~ۯӀ 5U}ҡ?_O@ DPB >QD-^ĘQF=~RH%MDRJ-]SL5męSN=}TPEETRM>UTU^ŚUV]~VXe͞EVZmݾW\uśW^}X`… FXbƍ?Ydʕ-_*櫨.:q d<0p>.l#?vVҸ}|#m7{s,SW#FCliBB3F$h.:%,(H*({`Z |"H0.A @! ,7: H*\ȰÇ#:"ŋ3jȱǏ CI2"(S\˗0crlRBilɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ O}G(k-ڵb 51 p1 6HK"8Kz7?V2-Ƭ!v'(1:h? z7 5s aA4@=Y:ys6q#3 2CL6XY\7h@煭cdCL4 CA t$AՀ)P(x2(?DC)ڠԍAlS͜`~ -ԈM2{VL~?A:J3g~Z9O>;S?`łD @͟AMqj=3BbҨ#6JgZ {ì@:#ʏ:3Z?;yaC,P{ªAK@#;'-L9 +&32^1Ȫuj?,݊ 5ƄB }^3l`5# 4 d̲4͔?^EmN?Tc4m)@ wu 3A@͠4)r (sx^ɉ,2T?1T42\=Ȟ,mC͈6Vjmݜ@\3,M1f7 |ƑM;ؔ??"cC8v9Г?Wco% 4K/CH~mn#^ `s7i 8)ZAF٪`3kcj6>Ս~*$ZACX\oh6Ҹrէj,jjECm=jEMB iH -aQLqa\ V #@c| j£=†h"|rb g|Aы%%$~xhHA~&32 cX1xNA!卧Eq R_ (TZr PF2T9 0o|0 ,"rX aX a;r*r93GF2d̂,!>XJo :H#MՓ T&>%>r9 MP0ͅf#3Ĉ H0eRD4EtEQS,ѥ-B9l0Mr64.!<P "ؐ#z%$WE?1+bj7?op$Cfq.FGC@y%jX()p\;$RjQ9T!uȃ W~jf[U KC :BLj8!"dU#0Ob#sdU|J.9ؤ^$ AsJЖҔyD!D\HLx@n-Ӥ2lRvWn;)D Y r4E'J VMB,_N 2KZcD:B2Ü:rX/̀d&<9vDhe^Xa? W3C*nAlL_ mH#Ar0Fy Noފj*'T ~ fWnєtV Ls-fYq~f%4:Q'1AECoMe#1wmL;:#LPvZ1ԨF Dzb0έ#,jLA=_0Dه6d:$hc1AXFk>p cIvgǝ_<'A sD#Κ%Mfr@P(єbko&.gN8Ϲw@ЇNfpFߌ|ĝa:ԧN[Xzwf Yn@6|X.,+!>[`J A.wׁ_gЁ‘=4Zr'O/"m>0w|^tyћO}uw=2I $s|~1zqLb ҃cyK/ h D.T1[?}xL0 :?"!UpOۿw??Wg zLpGe ؀u(Wp ph|8$X&x (ha0P ؂ Xj`*g ?((T1qgVYAQz\ b8dXfxhjl؆n}v8wV ڰ LJz @A hx`u؈Xx؉؀9`DM؊z@ ӗH y@ǘOXs 3%}t8Xx明踎戆PHЌa 8ȏ(ُIl XS9}y!jѠ('ɑ8.0$}h-=ɒ>ّ82i"Ph q!i@ }w4`bd9f鏏EG9ptHȐ?}iX YyaIm9~!Q8IY9Iq" 鑆8/)If y}{ i*+`r)y)<雖9I‰ux Y`CIُ @y?ٓviI}iG;號!X%q6 PpPٟ:Zz*Wzp:Zzڡ ":$Z&z(*,ڢ.02:4Z6z8:<ڣ>@WA9lPiȤFNj =BZz …! ,` H*\ȰÇ#JHEr\ȱǏ C)ɓ(S\ɲ˗0cʜi͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^8Ɛ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνË Oo_"w4}6 `_`@! ,L! ,r= H*\ȰÇ#J(Qŋ3jȱǏ CIɓ(SD˗.I͛8?Ɛ3= JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCEM O{ ud:/H$@ 7PAo)Jףe 89xhS/PwX0>}{0߀hjJ 6U|VhaJÛIN\%"!A@H @&*0"XCCHFnD@+ E줛s?f*=Q>GJAT@;O =?dCAT#A̴RP3 A4O83B^@g,4 -v=r -Ɯz*3Œ1s 35s@CiJ$+ nkC-N<(dC7 DO A@hVʂ`5!O k Ah(@"_I /d>YY52VXaBh1B_ e2F>,.!E/{#@!If#׫q<<Ol1(idFe d<>C#G1-497K`%/Bk02+z|0Ãzdbd !% u| &…C??)uT^A/$ŀ $n)/K "Ne j 6; 2|_!4<.pd2@r:da[A"c`S!IR2CВrshhO: yH;<X-Uп2j j3RJFu+HftΪ/ |*1ьgTH/%pXaPAr<K\g:ԑwc8(vUOiӟ)ocP ȌdP j(H2`TL'A=юԾ4"#=T A>4k$n_90bz'.DN{!Հ~(~hŵNtalPҗz+r#T 5 2r]Y! IɈ-2#[`~ֵ<" @݌3 QX_ě ) 'au t !dCciq :2 H XuW^)jڶ뷸}Mgt~tw3A|93ڝ B@B4D 7C҅|q9Eܝ] s7^F<0ΑW|4[FN4FiюyQhJ "ulѹU5fg Ion -XC 2 G6^l'ћoaۜ:gI626H!'Yxd4ڄF)B%%3f" rf&tC:u*WW20; |g uVQ`:W bw!2!7F"dhh5!yz" ǀ~UsPGX@0 N Exg b*\vTOAxyZHzIl9~Y ѓ=8@f }a $9 tS #uzG MUT)Ő atd `QZ014g $ S 9{Q3)W:uu㚭sqjqQD%@ w "] /3[ O T;!,-$W-Sc!c <&xP`aLP!/2E_2@AKZ 1PJx0UP舘U7UEt!RY!QF5k!ĬI/6-PhD:MLYt J+ۓM Aac 3=.tń)g!GwBY1PךN3>۰|N Aj6g77jAL1`|= `DK=,[G>G|r!YPRC9>7=5*|_?*BU$>B z;Q/Kl"MllS??f믉[By* ZIq=԰Dy=TG8 Lڸi " (Q R{{9kK~t5WTAa|԰zƐAA+۶ٟ;EYI9T SN B@#9t<&˴K4W QA0q;GԚ:RKH4cV.=*9QAEA3`&R[D;ᝌ븊gTEJu#y!3B:GMF,#J\RL$ 1/ᅳ%{!,]\RE0 ݠ:+F==3mKNlG}dBLVL4t4" LGfps\0# 06P f0Ǫ1 lM+s&|)P#L 2 ܎݅$Փq ,?-M5}`=L ;6 ވA\t^ &+H9.C2'5">NɎ0k%Q=ώ؞!B9ͮI kpF%AA|x=1YҰ@g.@&h @!0O q`'ސ ; zhM0.L&7tB칭l(OM7o(< "1!O󰣃F/wr"I_! ` X)SRt a Rc\! [CFq hr-}.~0`!1ـM22}bͼ+0ap^+O?)ٱX(_UA ALʯ"̿/5J-/.Pr nϪn /_Q0  j DPB >\< ^\H F=~RH%MDRJ-]̆˖x!Ϟ\4}TPEEb 1THzt cS~VXev=0԰M @SUeV^}l UVŁ?dʕ-oPonu1hѥM_C4%}ZlڵmfZ7끩[\pōG\r͝?]tխ_Ǟ]vݽ^x p=yݿ_|Dnj#XPu/@$@R!rwXepux@ 7+^TQ.c\AEtH:FY zks9GsrQu9HI'3Ra%ΉpE}\eƻ+L0L24L+dM@F!w[#aL*?4BPE=MGmSF ~H!%O$PQ-RO55RWE14VY-ӑ5zG 9Sl5XUeuXcck|Yg譆8UѹeB"cuG}\si]ty1/RsLJōe߿TRhJV+ Ja#J|"_7~iκK[=j9fNaeo8ge.eV QUMTT{5K%:jW] PqiatjNԄkPIFh{Ii&^uS{\l7lcKi9Wꖞ2&rJ,6WO3hsVD'}tKGtSW٧-=>fg* PwJJG* yY^,=G)҃Zz{?|'|G?}g}߇?~秿~?ۃ8+3`TiQ%]e`5Xl5"y'Da UBЅ/a e8CІ7auCЇ?b8D"шGDbD&6щOb8E*VъWbE.vы_c8F2ьgDct.@`Vn @gA aw<=HƢG@ai@@%8$uH E!, < z MB i%t'-e8(h 8$ @e{̎@AJ.J&dLr8 el@Ҁk> ِDH4Yr,@!,, | ϲ@ \fpIx8h$ 1P(MHfaR=n ,C4(KԈiY2#t?"N%;0t!IT! ,f H*\ȰÇ#JHŋ3jhǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ :H*]ʴӧPJJիXjʵׯ`KٳhӪ]˶-E\ʝ+1?5G) L+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(h& 6F(Vhfv ($h(,0(4h8<@)DiH&L6PF)TViXf\v`)dihlp)t։e.v! ,{Q H*aC XHŋ3jȱǏh")XJaS˗0 ޚ/xW̟@=E4^}C[.P J\n~n:ZKV Ms\9`UJUnШfsMsuݷbSE '>1c…#۽Gmm|ώA{#o:x_84ѸE/F+UAkӰ 꾽<䁷x܅T@zpitOHJ`sWxmH/_0ѕ^ix%vdG Wc5'!sҖ iau7a{ _d&$"Ũ[t(WAݸb5@(CxaԤdIPrA MYUpI@|%bIcie~@Cqix|矀*蠄j衈&袌6裐F*餔Vj饘f馜v駠*ꨤjꩨꪬ꫰.*무j뭸y0Q@,E;k zAtϳ! ,K /GP"ȰÇ#JHŋ3j8QǏ 1 Ir#4J80#B+f̛ }ㅳ@Vz)puryʐO8.hnA׮` KVĪOA:mH)ӉQ>|ːЩAw\nP*ށh qTb+TdT _6cVPMIY+۸ojvC|P#&9ʡ3}9Xn1 ! ,#p* H*\ȰÇ#JHŋ3jXA8Iɓ(S\ɲ˗0c&$ ͛8sɳϟ <JѣH*]?ʴիXj*ׯ`ÊKٳhӪ]˶۷pʝKݻxM ⟘ LpOc*Fiðǐ#쵉^)̹%nh_S^^!^X`93[;g O!PP{a i~y>C^i#5i64%>m4tВF)PqS$B(jiVå@A` eT8 )Uy6x&=`)O]L5$OAklBz(N? * ZBƴN@^ xtm5٧}Z3UDcފG[ m(oBT,'j #L443v?.H@"T?9(O+OL4 W b:#fot= 1̑4vCD ؼ[ Ik%e@NC-c1`ǽ,̂b/*:2" @BO0I#y3 } 1`12OGNA08-s?@z"P(d_Qe -c,؝G+\t:A8IY$@ __7cC1CʳtH+Pʣ:۾X : 5У",C )sFF;'.hh1 z-Hat!@d|@y"Т}iEr7lL r<Ά=X\ _xazQ/^G7AVCH }a8j#P4B@\Q8 `0$Lt+1tZB"Qf Y!jaQ{vAa:ퟸ-́B!4P`)iXW!(T;:hUAV ­jW$Z(8q?,ʐzP;F!dqb;@.̕Dq6VlFLjjŔd-GL8.;FcZ.9%[PA]o 8f5="`*9}#6c8yCE3s4Eq0q P$q|g&LI@G0J2E P!gLE93CwCR` 2 Ww,(^$xU4q%@GD'y6 pt 0 ` $90yU- 8 `WMH`\0A0 pS]lЇs !#~$d|QH!LȄWpit(`x6~}(RG:d o:/96q&) t 5`% ˀ Gtڸ}79SCXJ (>[9P 0 IP x&ivJьiĀ !9M98M1^U QX%;P@x@ /iʀ wJIv=߸hC T $ftQ!PTLKYD݀GuhWi(.It S aG! Đz`.2" ۧE, XYQmf?o6 N 0S5ȗ9 h92كligGA~tA:pPz7!S8A @ vusݐo@>q t"A̹3Me%M$ Xe 繟":ާHni|ף;A Y(%''1W@YYB6:Mmt6'UsqJAG,BX'0)H9K&5C}tQ7 44gbs@c{Cq% ^lTAKdr<ǃ:qiRCrO<; sW\DJ'e ;WEd`rzC!RmR0$7z%ǰ k1K r k qG31:CXQLDHVruɩZQ? C ::8:ڨVI"J'zt6wKP? ڪm:::pYD)@dsOyOY rs*N:魿JAGj{:Z tR 28ɯ:YB1 ,AZ1 %+O#9pٯ,s^!K`2( [@$Iq2 I.LC+IZ'ذsvu7SR'TiiSB+5N)2 ic5Y&db;Ơ:+RhDK(8% 7Q`;?M3F T@]DF98C9x) _ ᪖ P@ґ fCy@TTD9md"~ކW7a LjB~Y ;{*Tx4ث zgVa6kRXRϸ/Ƅ*Б-a\|r!ƀ !C1uQP@ ,){ rcP1.}7O1H9,D\H̩[LP#Rjϊ a8U}L$q_dZ^G|p^~ ~w0==MlP !~$-  +#6p p  7! 0@ @ 4 @ K0  `Dn\6np>r^t~r]>~Jq `@X `?R Aa>^y!P߰E?.鐱a 0Xn-6-m f> ~РE^[/΁t 0. q  A~Y>!)Aq`>4O~NJ n+G .nm.O ?N헎z^qy.*_,.0?_ ~Į,Q+32~~6.,=nQ#\%9A/o'OP.dO.=_驐䓞 o__s_-NO ^ 6_O^h 9P0Hpp ]3@?!_ȟʿ?7+Io1 w`G1  ?@oDPB >QD-^ĘQF=~RH%7@Hʁ,MSL5męSΏSPEET҆@>?A^ŚUV]~VXe͞EVZmݾW\uśW^}X`… FXbƍ?Ydʕ-_ƜYfΝ=ZhҥMFZj֭][lڵmƝ[n޽}\pōG\r͝?]tխ_Ǟ]vݽO@VßG^=6Or K0$ (`.i "f, Xth4\.zP` d 5M*qBPР BP,CQckTh$K $V+]@IF_Jl,첰ܬ2a!3d- ! ,7/: H*\ȰÇ#:"ŋ3jȱǏ CIɓ\ɲK^ʜIM-b4( Ο@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(h | UD$ DhaK 0Ņ 3`%,0(46:xP>)DiH&)PF)ez4Xf\v`vF*cAk_!n bNQ<"Mq?p&袌6裐2!FB>qA@Gt 3@*y":3P?w*k&`ˬy5$˳Ԗw19+k覫+k/\,O+; 7G,WlgwfA$l(,0{f̩%+͝ _@- m @i>AAA6M'4SA0?2m 42c+U$2 7@1P9FW䨖gya`oY-Q{^,-Q@.yCp?yzr&2P6fd1EX|AE A-**}}<`oO& $(G$7@"L 28n}+`hDy$GHB^+ %ø\ؗ-{4̡w8O@P#Qh%Bćĕ(b ObF` PIIFKQf1#5pHGpqr IBL"F:|FlˏdrNzt!R d-VJ :'$+Rq U쒗PHr ni\–/YKD1s\2S&TiD5Mxp5)zƳ>͌߀=rAKhhg.Ŕ첡u(C% щ $'D JKms]>11F#\ãL?̓eNӞ; jO/zqLHF@rB#/QcBc&j<:Ѯr+Ze I=VYA$RQ (4u~eC# RHRR؜:}d!ҁ\jXbыu mGheVC%j=MO~lEgKVkPJڰjUOK:5H.\FDs! mtW [aVq+Q:xwJ>X.jkMֺVm(O=[\ڷō]u[]_"%,>k-H.+L ߄7s0Q'e)ZVǐR)TMLj4αw@L"HN&;PL*[Xβ.{`L2hNל$8RS# s&L! ,` H*\ȰÇ#JHŋ3j8 ^8Iɓ(S\ɲeC.cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(h& 6F(Vhfv6BA0&v A8/X2hcQܨ"mLg{/;ͻOVgrU߁7h!f]~[!uJNha^ar%$8(,B! ,`= H*\ȰÇ#JPŋ3jȱǏ CIɓ(SFD˗.I͛8Ɛ3= УH*]ʴӦ HSׯ`ÊK6&O46Z۷pʅ ܻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװcˎhw۸Q"8ln["E \Y0x20&N^a/1 hO @ Gf0>a^ p& 6F(fLh~B_3?^(?%tZĈ0:"M|H Gb1)$B54TE7L"u@!B@EBQ6{%l"D$B@fAt)PmSm~Y*J-ix|矀*蠄j衈&袌6$ O:*鐮TC9f*P8j**b N:Ψ·@ dN:tO^Wj*Psk>뱷qO@s> k-kz<#,BsI[-AԊ:а>+ᅰ! ? @γl1b`O:skA[8Xz~A+ ul28?2KT/ ^kP3A;?~gTe.}ZX *7_}EbKgcI`11F0 1"ă`q1pH ĎZ܋:YxB E+v<@4 !Cf8 @H&N?]lAD!%!G6F?~#8@P+2;ag$KN&52#XqHsXi/@kXBVaa\2Yaud+,h `@Ѥa.1H <i(],hM]sg8Ɣuȣ- Њo2с\#RF06GGPxh@h`-@A*Lx -94U $3()+}+v'#@L aA\6_bH8 R˂bTU "7ĨP1҂ u$Ш$(C,aiXÚ6H ^ (+1,A"sA6!CM ވ5rW VާӴRرA2<[cCXƒ:eN^tIQCal!r b V wF1`!r#Q) gtF4k@C!L|[,1pFN(ipˣLHc‹6l.!S$ iSA\\^,vaA4$@ Zٰv<5p C^8yB?eT:E&"η$x@ gg@t @v= /@^r i3!'V(pbWQ ~FTgcfw<6a p;>G'Q'&P7uh*Q7XW%.(&\B)cP+p vFB"o'gO_ӥ2Qx?7'B%)A% 7$yt&w` 76T x28A ?PA=@{"w~6qSZ8Dp uaI< ';`WC⃚8ςDg_E N`$uÀ 9rG! بϕjfİ G'z`$ h zu5%s_Pmĸ xa;CH=(7=bpHerI01&JSrAH ;;@^B` Q"kpy R%cArE Dip p 6D .X 8)IT":` V~ i# rPR}ykyIYKxGґu9 @7 <}B {QA/4Qe(k5AX)| +2%sH (dAXɐ p[e Vy3Ra%%lQWQ"Xyw EH 0&$P Q F`'0p88Y|4QL'\ z )[xYEN%qv)KvA ՑT0% ` YE{C4NYykTtCN{U+rU4tCU÷8TCmVEY ׫JEOG(C6K2{F)ga1JYS"Dv;%[jD˻qR|V kc*`m >JōxUqŷNYdDaTE)a{ 81k|5x[B5 ta\ֲ*NYVc\A,B oVbP@7 ")p@no8>(\ w|i<(\eQ֌,B<\ Ήy`glŹ,,Ȱ| eg!iWP/I` :ۓ M.g 9b`E% |"uLv!,ӹ2MPh\L:?^9=606@>m $T!CIm!21QMZ:X:X(4^Zqh3PH MbKn'@'a '1Kas=I{ xxҀYš%a yB׈Ƞa Hk!׬a׽v!ܑ 6$ ["3` lژ(&`E hCdàB1 BV\]||eTZpޛ ެe='ZMߚac+^S-_!  Qg}1c\XXq$qQ`.Q'he DfL09 ,dh;vql<anez>p  0 0 ru䵁 SԑQ!y` 0>^.!b %}NW(Gr"(i/!|r495מ+ދ$s?a9qJa%.(a~`D%2ސ Q'1ʄT P-` I-rb"#OQ+0' A\ /qW-Cd@@t/Ȑ-  R@q \@/K] $~"} PL Z"ͤڭ@0*7+UTU^ŚUV]~VXe͞EVZmݾW\uśW^}X`… bƋ7?ņqBYf-ūhҥN*xb:UAMlӽ})zs??R $EP"(xbU 8yW^x4|?ѹM#| q?dͼopG{{?|'|G?}g}߇?~秿~?`8@ЀD`@6Ё`%8A VЂA`PP :A|@ ,8#@! `m01 .¢+V@Cl-02-`` G@uNI f.`99`"1uAf,Ua+~#G ..D5AAWD} !,d$ Z()b RǍ`4#X"$yQvD 0[)B?N2%D0CВ GA)-9DK"[ D"*]KS""84ӊ5g$! =Ёpf% ! ,ue H*\ȰÇ#JHŋ3V|"Ə CIɓ(S2 ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسk/`ËOӫ_Ͼ˟OϿ(h& 6F(Vhfv ($h([ ݩxV.Q4h8<@)DiH&L6PF)TViXf\v`)u&,U94g ,Zgot?$衼<N.ZhBܒ-J*܂:M.O rB (n -|>O*26:4B3jJkmB*ML 4h8Β+m@nK7qLO -~: l?B.³ 4ړ F0BJt *h S .AL:TnIz/Zд<+?BLԞ#(m l͙sU5\Ц`c^^mP =-p./'D}m/ێ;롩PcmKwn1t rM⁷}Ku߸S:xg>tV:.6xl:zm* ,g}R7݌3o~d.5O]j݌^hF0@*Pv R ($@7r !G(B D]B@; ! ,,! H*\ȰÇ#JHŋ3jx`Ǐ CIIN\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_wӿ̣K6:RMzHËOӫ_V;mIx.(x& 6 _T`,FEp,bp؛"P,0؛h8<@)Dn`K1pdL6PF)TViXf\v`)dגfVR)ؚf_!9_vޙ \`m)蠄j衈&袌6裐F*餔@ԁ #P)LqbO(~j>ꪬ-RȐk*R.IP$+k!&,rU>k KH?J))N k.n+,l' 7G,Wlgw ,$gq@,oC/ 3hr ,lD:ÊĩܢѬ4AJ4):pC "VS 5+J.Es-)T7.77S 4䲴B@3=*:s.Ѩ7xS.P.O /Ӥ [3-uê]?R6-g6+Md7}sBml`f)p}+1{ڊGs !F(2t!0A#A@0"‹_!(A}"F&A Q`[D1WPz*Zq WH.jщ` H2hL6pH:x̣> IBL"ɜ1$ [—ZPp*?X@JzH ?t 3ꠓ\ |,c)3ˌ%CR.! ,! A ȰÇ#2фbh`* )W⭓xMo]0ˬw6S!GEHc,oVlbwFL#˶i:><Fr >.3pP/Sn!Eo= WW5Ðc \7M+ sxl2F|1@(s+Q>dL]ӌ2 l -y?\@V?74veMIOeL(MC=˵u+P̄Q<7i kMK+ǰP˅!y7$CU HՀwA>OO Ԙ_RjW5 3MK[ 6e<^@Paz }0"1>Kխrd7{AN1C @}.S=PCFFH31810@ ^ Ƽ@Ő %P[/LF L T7jlÊB>glT)$ Z5An8!H7ȭ ɓ a#(?XA##^G+^fOsBH @c@"v|`(W+H bQ$z8%Ld@4=/h?@ Œ,Syc%zt3`Gryc aJ<#!fA`  9JcgA.)Kq $,dQ$$ұ?\k k 6oBYM u^EžN%ц܄N~H9ɵ͆؂dg߁}[iN4[?KSViuSh KK7˂kKmB9Ry/ Jm7qUjy*Fs 9<فދ+ؙ#1P4H;lq-yc`mǮXkczm hMIO+ dSVyڷH-ɑBVImSAi!FBb+R]ݯd<:j7x>sR!an oiA"⁎#[:F.s xTmu,lcC>O · OiA/ g59t(  i SA &!DPlDAʰ{x(" p KX7DHy z@ {l(>ms^Nɰ:O`"8s`\>V· H74 u:CAŰc|8 lT?["Ip E05r*!y@4pW!_/ NSD Ր''heWk3 qwx[QƱ?*;ǀ,Q v/I4)?0%hJW 7`U2eACS@ h6 h3QZY`)gHC d?1 n%׃9%eYV$@)8rmwmcrY 0Cnǐ'X? ~ٜ6qG 7q71TUC5b~@"KnAA:sGAI#o E4Ny Rj((,Q&5dT2Ѡ7Pc1T}>'A>:RԷ? w YY$)la?8s\#۹ !6T?Nu53(qAg@9?= ڣ:X\X97YYBh>s{J?57;Ubb;\?Q#8CE*c—ry3: r@F|sȉj@"5YE*#i<>ع.5mJx&qc3aigJ>Z]P T .G: :銴 ;j6?L𫬅 `ǙӈKG8j%j,BCSjPx=>ie2 5OJ Üc:xE xN.:j.E5#>(Qa[6'$T jf ys㍿"\A:D;yH,dzNPR;T[AzVk_H` %LZs Z6[;[[FuѸ6m,kn'~q| @硻?T[6p %PD7+U/T'[#k1# E&NFwb~=  Q3kkmn P wKl!?0 j+F ®Ѿ"u ?Xo´"]p ÃRd5҇` @ ['%Kā1V bd`AP9GH!]|8fً+<^,akr<ǰ[nmJ|ǝa A/@ [QM).Q_Ȏ,)f٠2Q%4jeȕ$@Yd3qNp56z/qo\x,!wa\d4^6~8-d>9ANl P AD>?!0T   mܩp mgݩmq~ aP@ ne | \~kݤ@ - 謐} bin p߼-`~^Mq)g|ю PN@ ZP^ ^ϝ ߀ ڠ ! . n  ľ n`^ܷ а N} i > y. M> ?knq ? ^^Aܠ ^24oJ_m diޞa+@.T/zo A桾/oos ?XT >,D):l0!D=~RH%MDRJ-]SL5.<7*ܙ`P6ETRM>UTU^ŚUV]vT? 4`lݶVn\sUU^}DZFXbƍ?Ydʕ-_ƜYfΝ=ZhҥMFZj֭][lڵmƝ[n޽}\p3G\r͝?:'tխk8vݍFxWjwy`J;~0 0D0AdA0B 'B /0C 7C?1DG$DOD1EWdE_1FgFo1GwG2H!$H#D2I%dI'2J)J+2K-K/3L15'Q1Ԅ\ (Ⴑ>&N@A8DwRC]:K*=F:P0Q ?А"$$IS\"0UE"ӷZh*]H"R#ɏ_R;ck$7[!=,k?C pv\! ,7? H*\ȰÇ#JHŋ3 Ə CIɓ(S\ɲ˗0cʜI搚8s.DΟ@  ѣ+-="J*RJC`kFBw_^Ӫ]˶[U $@ַx˷+} LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(h& 6F(Vhfv ($h(VFW,0"&M4RH8<@)D5B;,PF)TVi)\v%vdih o  Yx"O{J(WN!<찢e:ڢMQO fJ]>)jꩨn!reFڷ uY+M#ǀRk&6 -~5$˴#غGyt\nz'K‡i+,l' 7G,Wlgw ,$l(,0ܱ2F5VVζ@-D яe Wtd,LU;cQ 3AUX֝.tpjvٮ߀N--xgMrhd/;.W!7$u3 z@t秲I j;ޛFAUB* 4@a>W00$(@l}$݇O# ]([_؟02Bw@ kk'H Z$c.Ȓ0x( P?4 &w%"6QPp$ 4d@5ѩAk%NH*ZX̢'yHFxlم6v>5*H?(R"rr }ܣ IBL"F:rby# ;qyxc yw'sA ȱK8o| 3H)OҖG.W*iPqx8^]d%1IQęAv_ Dt1UbLWRؔ!*(0u+*FU1v+Kʽ5FӰ.yblb+M&6Pld'+RdB. P@*Pt!Eg1"PplgKڔͭnw pKMr:ЍtKZͮvz` 3^.) KnT|K"E HnA> %y&.Lع&H ҁnxO! ,Q H"t5‡#JHŋ3jbV@簣ɓ(S\ɲeB1g˛8sS! .f ڳѣHSИҧPJE H ZB 9rׯ`fG+$4i)%۷pYI5@Hc*{&-ÈzGn]l h3k !j۪,bނ)Lװ[,KX6bѲkoHqv.`/8.!V}VN''_K2iHAw@FBd33%?O2FhA[Yj-uS=DN;^d#6}ָv|FSCE?EcH&6< (6Fgu X&f 3?Ht E2ʹ9qo=O"me13Gi(T)@+?䚛f?-`=HA,s%uO];(mS,033T;w}YBАo ,R'*Zl`biѢY>mO?\Z ki}+/O(v-HfX *R:-3Lk1,&Hr|@тC,$ gMvlQ g,3D9vS36Ngۘ#8DKXwyAjPK4K Pv Z&K8o|TՁ\]P/"Aj_sLP+̐3m؆֭DL2GrcA* AN8昷R $#L1€Ni9BS?>6cH㍬:C ;@>P1F0/sY ?@1Y[*?LMY 2o/ l.-[NB9HËNVc)GnYNF0p^Hpp(pȁQY 1$C5NxT*dP©`* C"EY9<*W Udt|A)QX;gEe FDH d+L"1xtT:s"k@! , H(TXÇh2I"T^2 MĆn \x*HUʥ Mt3I Lxh[(]:? 8h4i ETu3 buퟪ]f,38W~ T*q}*֡60eҴim*c$+VXEFtX&ؒ㖪xA2RǙ?Z9ㆩ2&ӳ_3ӷ}ж?=[v9 ! , r@ H*\ȰÇ#JHŋ3j`Ǐ CIɓ(S>$0A*cʜ)8sɳϟ 5nCu' ӧ!$?PjʵW J$S-˶۷p35:~ B@$qK3Èsa8^ ASEVy 3wMikO R0 VMӢoVB Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿL6 r ׁ @6fU?7QGg Æpm@ H4`p(h#C N(P>EwV"PבQViXf%tlYUti]k&9p: }I v*Dd2XCCHD6R ! 6mYZW?!hi@9d`kCj&~LF+K`2vʧ# DŽkLQ1dΛT( 3N櫢0CP:+bMA$^5hǩðj]$e#L;CT<ы˾{{̃JAT@|BKb rG>3n5Ճ 4!֐y1"`H'LB= .R hqH4>Q^`36}Pհȫav0X2{zIGfʸ{ Xc7gYn1| G]-|h!l;1v|h?0d,Ã7f+wW,|A&!'k2Mc>Ɔq<0ȯk: Үթ.\o}XC3Of 0mS3Z/=XKGs޼\emS64MJg&7a! !Xq=f A pV` /z$ ?a?5`g{=8c p bd@"knI` `2|%Cr5\D İ w&,s$kNxuQl91~" YWzYX'dT-t C Pr^a~bq^{aGr%u &E7-=Y1ZBVQ9QvYvX 4HϨ y-0 (H u([7͘BySjSaeZR,ek  Rh;sXzM[ qXϘX4nshr}&E  `O0 Ų \`:*#Q(% эphY[xH3-m dA Űgt~k'"BTy7Ru ?)/ G A z ?(\`` "7W%P("X9uxM̐A3 Es*`&!m*#R^7 P [o"&UY w{e$M(,()=2'qy2"313ѐH劕 Q(Pz=q- [ IAD }*&ʱy5kȞՠC uzr°[jo1 1X2  5N5uc#$Z"1p >!V3Tfv $spqEP:UuDXrբqpEbJ9@f }}ѕA/'b"Bqe06rŐ1JOP9%Lq A@@%>Y.[`IwMѨ7`F%@ 0V/nL`E=0<_sS-X-(V/N_6Q 7` $x@ `aLLp{jB1Oѫ;(4$ӥ57ua:RIER7=rE"+",(E|T2,:0Y[!"J)'0~Zx Nhx:GX> 1б1:'I #Rȅ ht(Z~  Դ.'dHBpcAt3T> āb렛d @SH䌪$pDBsY1PL[ QRsRz{R:?"HC ,(S1mU1 g d?x{E\Âb?ѵ9]]Rۺ;Im@/4'GT { t d`'İ IC3R 5W ?dFd@DG Z?2uoҧ J@ D[2A4CqdAD`B;8+MW''Q JMde uR몹;De9q PL j Y"rYY[,k9,>ՐC./+uG\+r,KL_fd6t(y A U\\J rGqDQ{ bB*5RŁz2t1|sLʋT VQ˞Lɨp!ʼ,2N{a qAT0`^ܻQs5f0ՓqkIguѠ1%܄ )pП-} =]~#8l '-c $S'ͰY7 {.gRl@+zfP <H2QHE}@\QO]V}5XS Ԫ%[ab (60[ „16" 7͡!>bt-nb@՜ ؈ъcYxBG \;dM"W[;d^fn.uԶm&@"Q_NxRp LбwpAN! f9 !<|ܝHq. Q D-b X n%)p&!E&Bt+%!*W~Sp  0 0cwjuwuec𒤢-YJ( 0  ?<&kq">bIS(Q<-[&2g~(BQD-^ĘQF=~RH%MDRe leDaęSN=}TPV ]UTU^ŚU24"(IXe͞E6灑A$ʫ1 aKZ}@ ` 6b?9dʕJY3P̛=@VMFZ@ LOH `}\p`}\?]:p3 Vp \^tO6ZUFgO`O0X/H=cAj, 0*vMjC0ؒ{0DGL:k[ IQ`*:*gWG!p rH'2-$DqJ2J-K/3L1$L3D3M5dM7߄3N9礳N;3O=ʡ>3P@TPr@SdQ(t4RIR@TF۴ oɭTE 4UUsq^ćJCz չTrenUEv gWa(mBxv蛇>}HdEeĭ(xjTu#n8]vh]^eV % ZXo_-xncyl-C=^Cl326I;Fgvq.4 |4PխqO3ݼp{9\Z9I4*'u|p7^umBwMtz>%a|]Tr g{lۧ]ē|Tӟ(UTZ6+O|gӈ83ȂD? f`A8B^'Da U%@T0 C=C!1G$"6QKiA"D*VъWbE.vы_c8F2ьgDcոF6эoc8G:q2cG$Lsu OHF6ґW$#%YJYd&5INvғe(E9JRҔDe*UJVҕe,e9KZҖe.uK^җf09LbӘDf2Lf6әc9MjVӚ5riDsQfrh< ĹL: ]=HO@"C i'p&yЉ @@҃8Z@cP O3+ zB')(F =FтΈ9 *s $aI)SDiQ<@AAPP| hLD=(+G* ŧBM Vs.JȌ,ʠ>KV C:NGi,E" o5tDv5|:D~,$E+VR 2v !^# рY,b%S3QeObDsIA;Zh(^ŒbR|9 t}ڗoT VM>׉vpJv`0 $ ! ,f H*\ȰÇ#JHŋ3jxǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ H*]ʴӧPJJիXjʵׯ` KٳhӪ]˶E\ʝ;1?5G7) \+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(h& 6F(Vhfv ($h(,0(4h8<@)DiH&L6PF)TViXf\v`)dihlp)tix> +y@+B(>(2hEB(. EzIC|:&-ꫨ*H PPvX! ,xG HRÇ#JH1]3jȑ#+C)@$S\)@,cʤh2UMsqϟM O;T ҥѧ$-\ JJjVW^vOlXd͎Uv۶mʝ˲%pH``_0` ++8fL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسk{{ {#<ނ ,t_x@! ,L! ,+p" H*\ȰÇ#JHŋ3jȱDž wɓ(S\ɲ˗0cʜؿ %Sڠɳϟ@ Jh^Z*8PJJի K4|ȿKٳh.!H5mڻx˗` :, +<@K˘et8̠CMӨS^ͺװ_ M۸sͻ Nȓ+_μPNu3N8.nh.Kg]˟Obw(4A~O>79O>var@]XA4, @SІ a~ Ϧug9m??*"2 $r\ttkBErd#sN7O4+flKTgB*TC$p2F|TxIy@0CωgF,`7><1A 1z)!9Rpb XIg3 DֈFS6iF25k婑ΣD(ҋ(p"Ond-0@XPaԧE37.A"EqBU*etb͠Ш#8[BVRDų[61rMP!+*&c,c L8 iv'N.d :InU eQOnM)T-2 *vYpP8;MO!\x &PdrHF2gWDz^%lx&CꑏzCHo{Ce0-k lV LX%-UX+ KM1HEK lCǺ4#%S :Q>5v#?'zXڥH2`#[@#buԃ fT=AWlG{B|#xD˷cDCh2hlb̷Ήd,H| 1@ܕ~_zh-QfB zш{!ꂨLsKJA-H1@yY0A/X̵y&6Yܹ8r᪥P؈@ B^A5mpd PLb_Ǻ^BQra7uRLKbT/0Cy-m-N*P۞,t>qĒj=jd̢6cB 3+Qlq_.UK@rJ"!?|VΚ~NHZk5߆iؾ.Wб-tepn6NxlZ .X0  i=K'$?SrZWH/\p#~XO;@ʦ #_A/E vw)ȁBЩc@8Ky/Ej#}s~hKǗ~4aY\Ãd |İ ^uЇ* @]@QXKa7ap k6q Hv#j+@$.Hq_8HSA(d]@sYb' >Dz> KJ9@%T ^y] peVQ}qq+1\p XnA |t- vӦ =E,"ͱ Ā iCwv*n P _e< RfF ΰ @ K3 T>AF_ [0猠133p?lg"ԍ 1xn\xĀ ljlcxgZ8o } P(L?oz rC a! @=Rk"'P'v3 p0a@8 -%I`U(;ѓz! f:*;yo0iUB>kfP cFE21H8Qp 556ZD 0C*j:23~č/B b>aCײv6u9y!B čqIT F)i5@d@ hQ z0J$Y@0i1W&:q:G"nSqfPtQv6Idv(Hj)ʪEjQ ծ`#&ӠqғD)0h6Qz L.´MaD@W ֊,&r8"h_4:[!]- m$L6*7+8 )Bs#TY_` ۰OPH 8[ ߔFv!U mFR P_ׂa@gS2/[kUmJ:,U۹;[{ۺ;[K79{/Rg˻[K+&s[{ڻ۽!  f[a ca^›KJ;{(?`ȿ<9 +S I萼a^ L}A2qـ1<,}/Pw=* -[ ,oqb6q@\LNR+LAV|/@ {Ť*;KKlhmƩi\C0@pl_|z|~rl`|l;0Z0ShyLJk/1ᐲ@6 WYsLƫAʨ;5s Qsv6I̓ ,̖lf6o*ZV-7 9pAa @Xp!L /1 P|&P@y30Z\V]bЎV \M\'?yџK(u ѩK++,$v9->B=DdPHJLN-uR=T]V}XպZ^`b=d]f}hjlnYo=Y9`xLs ~~6 P؆ . Ģ =ٓ َ .pٖة M,@ ]٩+`ҡqٔ ڮ @ ؝]تs۳} }۷-'qڵM`ܻ=ٵ݊ݍݻaۿDީq}Aq۩٠=߻C]N~]-.ກߐ ~މ-1(.q 467<>@.D!q1JLMNZET^XZ\^؛dο@ l mr> ]C~>@z>gk>@难%̋@@P=.`n頮>>nЀǞx  n.  pP ~ O+~(#p 1?2_7_4@3_D_FH/ALNPLJ_VXZ\^`b?d_fhjlnpr?t_vx@y{]Wn 0?|o:(@>"\Ł H̲joq"ц6rTNչr0/p͡7,;b{! ,7/< H*\ȰÇ#:"ŋ3jȱǏ CIɓ\ɲK^ʜIM-b$iϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ((&v4IVR=  pa! H@,0(46B8.tc<@@)DiH&F ,PF:IiXf\v UcLi@S1'm' ΃pW[6ahdDz !!H@އivBkI2k,:TBm@P&(YmJЏ @kfv+5Gń++k,lXQq2?8pp?Y;w ,$l(,0,4l8<AYx .i UDX(ЄLa$T*G',딨0NC)C"EDDc?L(CmLb.(żdcW@bp` HF0& A9v#c݊,?vd(76'VA$[1d-QNہ 7*! ,` H*\ȰÇ#JHŋ3j8 ^8Iɓ(S\ɲeC.cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(h& 6F(Vhfv6BA0&v A8/X2hcQܨ zhJ#qD4hI<80:|1h8V -Z8Ѝ^Ę@wm_߁t+^ lX'6Q!FM on,[0Z6I ?][ L6!7o Hx``^fmp"b=Nv_ n\Q-Tz X5pUCd0Qf3cѭ%w f5; @6؂[D,%$?{AjܠF0x2H!ϨO XQ``)`NFXaV}iuaE&)'pΩ*W:ͼu.7g5*5/G`xBBC 3[(Q0J, -ko A@ bX ؒ@VD]_.B6 \va,^L(8҈p`X3!5@<G"!7Յ4bHytg^txv,Q L 唢X`$`уAXXCS Cyx=]4<; >1ޛx!fMf\Vž e0 !X /!b"v(,8mj9F0C -?Zp<`<2D8& <4."c^bg!u,QEgAΖ 9JH7GS7щEܸ).5ā ZJ~xNxǖ- LMTv̠O& dP@ x0IA* $"Ac%0PF9PqT؃.@Lexf@@P\xAn  |A,!0>aFqAi}(4 BA Ѝ@zׁt! _e$ZBi=0wO8b(&2adO}&kE-yDSRx 0 W}Q%lL[SK!L9ʅ+J pEZ %!: أ2#J/k6Գlc5RMM{Xhɻ0ITVկ%'GlKP1?fT^pxaAin~ e ?RQb4]1`Iߟ%)0<`,,F ְ$$ 3`} 4 XV[رjE,q!A t$qƎR!tpYל ?H?|7oO:sa0B`!AF(5p /a{nEF海+G!S.#aQ&ьD F@ aD@g-@pu o. P_(ChGzXV F' kx 4Sz%ȸVU,# eB4Bo@-6 u0Lcgr1 -(y\QV!!ɰ8,cxDr IXC8 N&ФY!f03|x   *@0Th@:Qz7!sP±iX}eo,``0@Qx xW^x\жU\'dPDؑ3B yv" # IILd!NDB ʡ_X Ŕ*"q,8DE]^#%{0> Wvu^ hf,v0 30+Crgy0yry.e~u}#uPf@xmN ! ~C!d~pCP?+ AND`BPH-` e@Spsܠ1WD": LW"DQ~Zh;  I[@@ks 7 ;@JYƱ@P Lp %dENuFy҅s UgِU3*0 S#) p:! @ac VhXd )7 c R {Q ! I [Fs2Yq&lLQ-Ph1~0ro &\0 @2B6}Q  0֠:6 D1 yO*7E9!aQX@LC;$qSd@rvX[edSkyurg}3tZB^bpWe^cY F1y_-Tiyyugd fF[vq^9EYcYnT\ 95q[Av9 ` frL1P z B@OWp'ZyW@c#Phd MAiƍyvYFza A` 0giW0#|G" sd њC10C`_ArB0|E*zRP 1B. v70Y5f'!H*Qp*ݘ9-SIe'yA2 QIU \#*@ɀYrpqeO,C 1 `X*)r)N_2@0t`M$3@ NrLs-1& @QA ;2Q ]74s& F`  h Ɨ   -*  E(IJ<6v$Y^ɣ~BQ *p6WPz"AA   }Q J8  \ %g /v 9|?S*Pk˰4k  ΀|٪dB@'GWM9/7/1PQ7g%~V `0ws{'De HIJWQ,([pDܰ 6/Nd>@ PZa9PZ^{ۈIŃ P@筗 6P.ٰP@f`e9@*x@. !iP`  "*[ +D@Vv Jg ac!>Pv@Pqni &\"p_kq|S4Pp;LBd  t(IIL`#"Sְ0T О( 1@9`)EI_;uɜu9 f0Ub7[LfT %(U΂'"` @.~  GDfT) I{s=3K]@} 'K>v[zsEgo.ogo728  PIPVRlkNc)܀SVHf3 g!P`HtFEX)1j䛨 b. }Ey0L S.pB |6TÀTW "Df ~p: QQXN?" b/$s -i~.lo@P,TƓaB`%1C [@{X9IS3d1]*IryFP Cp0u@kȡuȇl ^Q G; {x DSpo0`.b˕s`4f 8 y}Rkt`!$+\zCPPSM~n QVTv)PrY\~=}0)͘`p)dX; }!<=F[)A_Qc,h"qaF wB v` mM-ٽ}`-۽𤎉 YuڨM !|E۵ J^_]nɔba_\VVQpn&~!`_+V`1S\Q^Wi-;XjasU9P  / 0&N\>'*2, -0T #2&-ǐq /W& i fW a/x( 0ypg"e?@N@N `^ b^̀b bNq.s.nwF0xBkE &+{  (Pprpt` F& ~&D-&@p P3 "WÛo{HtQP-` * Ne .$ Pj . Np TE/ ҰpP`LsŚ1 UnȠyRܤr?# R @`s%R` D00Xet` {RtQ Pǰp ~a _ }V PP?X`w W .4az  P~` :XZgM5q%o?-^ĘQF|RH%MDdZ~lRL5mA6bX{"?`x@a`- dtp2 .QCkM6sĤR 77!+fUY-G(֬AP[3$;|ƙZ  2[ ǭ~%З}aM{fm$W]gM`H$:t n~" Nb(dr đ,T IF knS2SZWөI$-t39N̓μ}hg{Vze?=jN"^`oR+Z *81I"P␜[B*G-Ji"Tg_R:s0(iA'A]E'WO}u_r4\oǽm2|vߣh5Y) XX]0!|/!A@"סX=x#РdS(.!XPT@\]Hؗs $ ](,TQ'*Bɢb#S I@C _5Y9!ЅƭE0I )b8HNpRAFT.0TBB$y_``ht$ )8jWX69xarT` HH?#zԈBΈ`Xrнj̓"H!FOn#s1.k "L]diLTGUddEOV(J\Heep݋7;N~AX}f&Ty4y打唂))i|T Ȇaxj:`@74+"f']l 4@:-tbk jj %MeAE$/3 dPi^fTUx'G'ay᜗oyhW-0d [FTF FX@(p!Mx/_q'mN o1嘄bHNbqS@Θ,dO'JT,kiT+X9S8ŊP5({.Z(ָJwoΎzNcg޾Ve84HLh]_#@@v *EsK|YC9$D9HKy`e߆?͔'S8dX㈇b?jl*p"@F'e>M6Q #7,.ЃJ1I4x7RGc-}+UT~I \ҹ& +\oi0fgq.ɑel4" CGF Ⱇ , l@8< İRXy'IVU[$_m/pc%Mx*2 +* غ1s5E L;C|"K8mH =J/4c/H?g]AִP3[q.:h>|>;elp'k|'Ez)Í0&Y 742љ-ć5pt 8Tl2+) b$a53 ezXЌp`X gX 02ڕECң!iUzcHL`pZ2l- cX;Nc+an9 Ydpd`OSB$N D&eSAKX+rtA"kX(ʎ9!Ȣ? CNh1U2FT!xHEґWԢIFF҄_ZƨՕqw$(Cu)(Uΐ&cN񓯼%iC@T* d؂&4 _SBI)p "dDMUqΩ`%:]'N9ڒ c$>4Kc-ق8$v$0~qM>eed ީshmhlnf\:QB P &^t6 cd0l  1<062pv ~qH"(,:Ќұ? HB T'cM*Wt klDzьդ@< Q$ ` (BXAgц  *` l!Ea:"@Rf|85 3t*P<Lr%K8av%OWf N+t]\⵺$[҄^Y#X,8 ` Qy'd Р!;?ܰ 8 ¥԰!Hؙ̀f(0+Z"`Dy.'=18-JZ77E;&BbVP!ق% #l@ZQ Ȁk ,h| :klc| :H i!; (|`sZeҋMc)f^;&u%9W8  6 lOFv(Q%MAX#m4:Aceh o W@AH@BzF@܀6.,9zYwyŁ۹sU&tHRDJ">Kdp(kkaL&HZNvxڭi6+rٛuQd[w~/3 F܋F8A \^emL 8_K~ΐ1.G7(ҽ-B!6:y#4F14V5^2$CKa,HM9T hLPJ$#6;Z#5<#=J3PT a $CtUYft7h uJxt`8{8JYQj@j93A<Ȉ~tX q: KhMHB3G ];@4 !pWvW~%XX%YY%ZZXJ$0D3p8ԞvG= A*H[a&b&b&"F8\#3D@ 8,@(`8LJu2CT @8A IKL#R,8@$ALALXdŖ F)@3P807Cm7l"#>k`)Q9Ub셒@7'B9:HJX'B_"BPu/,,c8LYqnIC[A&0`e!CCD{d )0zZЄ-@uO#![C&5|7<ӷ0[%BB"&H&EA= 2 70#߰@c"z"XC  dC2`8(t@N2)D<zqnQūc(L[Y,+HK6A;P^GɚQ^UTs h]ǵlx!UvKB(05 50@8|BM=67'XJs6$2<0K'wj0C@B6'B(C dCp-LsI B& t p(`-v-UF\oHP.U[y-<1y}~` ߯$< L  gpdD!qc@[=0E"'  >߳y|f$?^X>4@^|V~x~ $ ![>+g B2t s]ܻ5`k>5ݫC]-ZmY@`A 0@D^bWd(bI%Tr"/aLI ă HE8 # f4CGdWTWns"׮')`Ofo(Ucym;R'܋f;7kެi ư&_Ç8\qcKƔ E$.R̐!31$YǏ)1t~gpĉk`0ht@p`1d5*F3kEkܨn! iN^ug^ptE*RA! A % DxjHŠ"iSy򀎞*n\P!SC fIj߂fa.T  !|P;$8 a %W`q!@#n#k T%d2:@fPqm2  nMF&)Q Q雦G.(&:P zPD`ZXAt@:@%uLdZetHitRAh6[XZ;iYj9wQ" e@Y8p78 i[&Z-48HV4 $  ?iD*- (Pt8@E kVeZr"gf@)Aq@ 3%ף 8FؙYD1Gp."(=T`>%Zf8 .୶># c)-|gTɚw(msfG5%L=x(=_xEl9J;S'=N*V򕓐%F*)3cӕ]-6R25? e\J3]ww&`CLyZ@^d41R2(En.e2ԯg&o vh@(y Fvq_|%wm(NXzr-`x`Y NF8pyu}t߷PPꣲӽ(cK}pJ6=CoIC1$1_B#B$/# bD n#B n`" gR $!"z . "46 J :`_D  f$DD%E2:@|!&$f"c=p2.Bt!:a S @dt! "O!@ta7@YBP@c&ܖ+bjc# *t:>~z@LmL jKPMd'aP(`AA b8ATbj 9*Ѱ` 73&Rbi6F؃,>m=F`гb $eyO<cz$R*F(eJ@Z <b Ug+fV BxfRu1 )*9NRB U a|@-'B{Ko  C | җ$zN& j:c@ +H ``n@np1Q@s %vZ@< rt]!Ki1  zi8ap~j.#m@!W,@$# Yqv!!@S%!mG@WtڔA Vl 6rk"2|@zXut+~$Blf,Tk T@FIUTƀfD Ne AM fYQBO q63$#%Xk|kdS| gPjbn <v1@Cj ?@q-0dAWa_y%@,@A.T>6Rk ba@N0 A>#T A2 )!EwR{ 6D`$@cl8D&XpÂuj#,1̪`eF ^y@E@|ńI`zIBf"B#פ`,|%nHl1`$TcBb@ AҦ `>Rw"fJ]AmZ;֍G$Ma!^Ba!a˚Ǻ^ˡXa]E:lۺ `*p6_*jCp*.zKYgu!۰b"JMa0h'JA- ;Bxa +/dôV|V "` ウ *@`قb ƀketaUDB.@$izwBN7Pn"8   FɌZpxX"d@A+{#Ėc @$n (fa$ MR ) <{a @`{ZLf"G 4RAl%8brjJD P <*WH]FX_@IY fa AhfUa` hhrMGbMMvB1x`Ka*x  \ҶUȣazȥA䑻H~\\[4] <0ƒуc?ttIB._+p]3 #\2JY*Ӆt˔4:ٳ_о_ZiH8Yd˚=6ڵlp ܹt!a@ @k7.TA˘ fX 0VQt6N98%X)O o>L.ЎI$4)}] kp6jc8-{@qqHQ{{/k$S.8/邠.SJV7![37~hyB CPIqΚC5%-"EW]~]EB9F@/} %qIs@Xl,2Y@0HCX OTX :7c(s?L ar~8[A ځs3V BX w҈cHQ^z󡀀a~@(ċ=E%8?DM?H̃H:# u3Ɖ$Mr*r4f8 ˃ӔK#M輤ΰL?2":~xI -vdmvg// GMJ D@ à?ᴝcQCS8|w$#=M|e.o>+ D885(nX\ka 7e ,b4*Lcp4#4)ccqWP7H8 MC D(嬱o}zKrX-X2@.,aD Udq@Pp*@\lL<0#h?``nX~E# cX6LdZ.t P<ⱎPr,e(AyuҔl*GRҕt-oKZrde,k\2-k"slfv̷qPc0`Ȳ@s-Jt&ZE,~7?i_e5v%LwNsf5x1dz*O^9 ѵ%E/iLRTe?Hpt,2Rs) = 0 bYXGS24'ݤO ԠO-X@b.:SAJuT*f!47%@N ְU| TcjiXK4ҕNJxPU\7kZ0 ܊B@2xNQ[a':/7% ؁[ XA [8ӫ1=V9JdBH{-pIJY6hmŃ<R:2 >R0#:AӅ(``=Pt c.PpXHjPX``Y?1X`GGI 3eQA9!VQ8/ Jq˟F9JΘ#)#3:!MF3Q._HceW) lMBxXL⁊3p5PW䀂;F5J"[-XvlrAi1jP1OhnDꠀ~wS D6IXc`2:sC(c5@XG882a49D0[5[&@K7XP #a,Jn | ?" A]h n 4l?! khvh0jPB\dP b d80Xp@s6aҥ D\taBb00E30/fc;̐o& 4X1fQn2 Z: 2Xgb,`0E0fS|=BŪ1ź x7 /' u 0 l_b"_ [ Qcaf/Xnd(7MA3z 0ZGc%<Bp*` ~{( 3D Ϡ B&{K$j t`,g@Y \|⹷Jò5pQP )P =j]` ]`Ub; #.|@` @,os MIc ˈxS'r: y@)>xT23ʐ 6Pm[LPta z Bf @ ; s]P$Lip@Ҩ# qa{Jq|[ R" x@qΓXPu7?c70jp`~{,(7 qqC]EoqQ$3 & 1 '( `p͡=|@> 01 Y{n+ ;/9[PqwAd4ڤfb|c jR\n .w-|1|=d͠ U'$*d` 7gba @; apc‚ c RkE8P >(L ;c&@TXGȸVG|"E25`.Tavt؎}`@@1] gj. ~ dX! E(ˤ+EhF,$X5_ʮ^ׯسbw^=*ETH0Fg޸Q}F&n4G=9(F"3(µ&nȒ"(<)Z`ݬqق ۂ4jѺDR08/Ր;AsR",|J,=j2Hh(IN/S2+&WSFeư74 s=/#]=2$i#();{ó$(M5+& P+NySr:馋;"67r)4(_tH{ 6KbD@)9K/3EIPP:dk$`ڷNًXTkt9S4S-imL*3P<4]eu{w_ZP0LrTi頣gfP<=ty8hHeODgdwg݈]NÚz+/g$Ë!U;p1HM{fѵxr~!t8@t( 'tୀi?T`Q*PQ _/Ta(5kupkO E8!As*P$`fzB3g5qC0 A_ pQ z:w&Eg:DYx@3%]HL{YԒiI{yl#vǧE]Ѱ&%LKźƑ-(8@z 7 Rmd[ H XC !ka#:1Q#84GÚA i,PÍ1p 8&Gq#F0Q,$CYT:;g`,b2 RY EWPC#ئ5d 15R X T?xt*J_4 Hut`Fj;+iKI=>Fk#, \䒛AY"(vCPw/#@1`8p* 6$]!G6Og`AC9nbB8P tH!<qXɀD9f9g 2@Ud E!e`#V ȈPr"^2*'-) ܅Ҕ4Lk[7jWˇ@dRët1-wFpƛ;&zG_T%形?P xO&&-}_t'L8#ت/P/8ݚ餪 ~JwH0JrVp9+Q_(@P!p[i Hj s{)>♷ XqCȏ&= 耭TДЊP |)4A20ų#8K"PS.,X8÷P>B1\Tciz@=ikjQK&NyKx$XkP86iPC=KB,80ӡ]h؂aȆ7X@-Z@l؁i[XgP6 IߋÞ?ǀ+;zG9.<拉<;7Ё ȉxЁS!0Hhn(_H&n81C5a1'xEi0]A5($P!H9sI'I%SS1I1Њ!1ЅISt'_ QHs"}਽PBNz0}"2" ?f bA; G]+)B߁㊟,`a(@ : d<@)#+#LMd[!@(08f )@p'238)T42CDJ9*: 荢ʉlW{9#tq quHD)Ց :(A_ukP$@FY eh%JeP) ETψrPk@c!t Hg2J ,KS K8/}TxY P8b.b,L#L 2(.P18k#,`+H؃f\p8lȂaxlB+dlx0S`Q2x qp@a ˷<.{$D3Q2>KΘ 8.)H$ $ PqP9 i0i(yX_c IP8dp˕ked#]H(K0P aP 'M NQx _ !TZf(bPkeXxsBy 䨨Y ۊ-;X0 WnW) qPXX`+@yAio؀`TYi[ } hɠ_d d_PT}94=DJJU%7[*  8 1$9* T80 P<8R280khTp>1ӊ ,fxn2X 2✅|+ ^Ql" %P`Jxnxν@H=xQ(Rף0<7' ׎#r"IP%32Phd`5xNG"| `ln؁hkI`!Ox1l9``ۿTM-au0ڐrIx4bQ.~S$GjL t< \9&C[H9 ,Bdhg`,q#[ (T80uT,ȡX5ߴBV 7l+^\ nÀpD [0v bQdGMn^- Sk+ `g7Ҋ`xk0sʐ];xM2<+@<Ȇa(S(XȆ@a=ΆX ΆlʄlW[hQXԕ@˞:R].U$;8΋VLh /1;>t#+x2v=+_Xduӈ]eLdhPA)jAa&F{>dS] (܊ ɔ ?p`B K$)˔"D-װR?!Y-̃QQ둹?|FJLi( 7Bqy1-gsѺx6ֈΤ&Jݻl<ؾB' ?Xmܾmmmim)2qA⦷N[x8AS(2A6 BxÐCi4ꍡE]:> $PFiYΘ` ոu,HȡW.vafgY6 $ګ) 2X;*UVUWJۻVk!Ǎ3 聟23[ݟ>CE/egHIT X\=toh;Q4h3&] ҂)h_X6ds61QҊK,( d{@gI/TPwź.;L[!EUZN6޹m |h^UɟVxOJ.ɉ`60 ?x;L3$XqXPds_g6 CȴԀlk=~sC3#aP /!:psLS|3ᱪ{19g(XQ!)&q#q#t0u0ئj?&sqB1zw4rMb#7}ܿ"|50y>gH5NCiUEL 댸C8U)n*Ar2O{:0S+:LkHZ$i㘁XEQѲd#}W0_5Ce(q2ry!tFw TӒ xBW[A(iЅhh 1)C@fl+#/BItvxš>B=H _`v1?Y$@XAl-Ic-tS1huCCRG~@k_D8;R@FЁuZL#_Lʢ(tAk%m9 m̿>6Ϛr`bv-ZlNj~#g"l#Nlpq#BRK. ][~I;H.lJ&?nϸq;8&2&%N.& s˶⇑"O˛%x sq@# N ]cIQYP̙:_9'b-Z- G)t)t$A DD,O:lxaF$)pH7*@q@) B"?aXsP k*JIF!j%MCD77ă?5R(4z`A38# VC @MDH# cB! Xds}p.Ld?C H53* „C 7XMHAt7PP %K&?dHoQ"qh˫;'Ҕr43BxL ͼHHqC*1:rr mknʧ.VBC*j gK |J[v~QA7߸ďK-z^'u)P@bG|>ly*~?|0>[ʼq/~.b+ yaBjo6Da8 |ιNtVDƇ6轒 DV-" geZ/\_WNІ^HĐ(FD-1L )(HTcQJh4B}1#"#Y@(b9 L&݃iВhcqg_\N g`&G08nܥBkXJQRP Jz udYH>aY)$[#H*GDx0h# (HC^)`mttAph`'%t E0@VĐALA.Pq$Cjڃ44de)P.r8+f;.#>OnXDL2HĘ e$Cˣ4@,*  @Ii4T_:ӽ x1sJJX@a˿L|@7tdCX$ Ĩ@ lU(i,`q&STF` .)N# *p * Abxb\n _ezN x @ }2]5HBjCi0J)0/$* :|:(@ $PXU."[2t X :{V6Rq$#IM -y ֢rIX& 2! T i(@ hF g|XQ*wD2\pW@`ؚ\ G2h4C!4lp6b5%TNC}YtˈA-C3q@i;.$pw!.aj%ALzHDiH@(NQ@ADYSTA"8 @5UJ P\HB @ \@giAgTox9 jR\"\P@, AqޭtH pF6UkV pK HibAd)!I HIa'>RNtTwU!AP܀j6QtHXWt ttT XHvJv"DO:.=]ޥ6΋u˼X5ZMFR,8 4ŋ.bi+yU4)R9ib= W%T]·5GBӏb}X])Riq̐dUR9P&:Qe :)5ᘰ *[, [( jmٓ| IkV_Ƈ` DIPh:qelĢJ:% V~Ԟy)Q )d .R+iK:IGm~l߳.P@4kT 􉞶^Z\i$ӆ|@@D@E\D[j@g**ƢXk4`*D'p?Eˮ<ؤSWX 5bb'7 N 5(EE)! (Q@57hTS<_}T1\ Ԁ25\C@"ɔ4?YDdȒuH,,\=DG@DAH. @R^($\ 聣,8&kHt32 \AxPBޤa.`k .^v݆dX$R|)4C@dC|kZ}%xXQt6G dKRetvb*X)O,A s|p $.4^@ /l0zA,Y&qĔOAC)<B0 s2>R8Ek䙈!P^ l8HA?LȨ:(ul */B: E'%Fp8 Ale!$P8ŔlA$CQo(m)đt|q5J C2@?C'a!ʼnkTS#0 g^6,*󀊎E_ʥ܈@iOpxH7W ^Tq(ZP˼2SK<2I}IDC⌅4L̀2|Y3B~mQo@+ U\j0ثp}YhU+*SD_)@( 16a*qY0C e<2fr4(pf 8!`?(x@8<8tH[) +dí['Tl|?ghXFf1Y4@ EP$æ)EPԤOt@z (P@5$^0ܟB)j,\ lI,A ,EYrVR+VA~&BAPP -h7YED<DD֤Zg@Dxy}YIv FuӬ6Юsu|lkUQ̺bJ@г˗umN+ڒD *y? A)UOH3‡t#̃iRE<[RPXhPA8Ruˊ?0-l@e SpQ ʫ1+ HI.JDIg*;i3f &YE gQJ' eAj;l FI+,Y(+D4þH,*E 51Dp.eD AH@p@a)JX:؈$AqWt?n]2Y>؛KHCF-A"kZ3x:Yv 'bF5G =8H&M 2kjV\G'Usg15z֤](:`=${]!v?5 ꙤBօf4K3)d1$CGKE~tI' Iâ5!2,2$yֽۿ0:*uDTMz]DX6SdݿE/HSE%BYxqY>"A:!_$olMšvJ$47 ;У!0: aD&`q"A'SC Z 4ʣZ`)R0Rt@$!uPg.R` FqYE*gub1!tQ%ʳ,nliđFi!]':C9$k 76j]!CpZ , 2`t((@5|ްS RFTՐd 1Eʚ!q<+OǖMÐrb*|Dƃp.EqCQ$,rC FO"3/i M Xrzk@">a. /[ϠS‘H2hgR`*7(|`ଉ#$* EZAԕ#5!)nqi2"H4"h8.8@n.'(n|)ЌQLA!de @+J"qXeh"k^J'})Fĉ$L ʹHIlB $p@oa!,"{PI)5k_ADTl%^C&@" CD`k(~!0ibuaq@e!(H#F _t)/Tk3XQbFC3w2pc]JѾҌ(/$G\IQ/!AEIUnv%!RE("}b Le%f0n W8:TGؒZP0xDAF::$5A1~Z=@R?*kx/ t` J8 l :Ϡw2ڳm( ‚qH01у9 iͺ9֍8rnL]y,@sB'x* @$B{(EW}:-4Dz gI, *)SF>%@̀za8LǷc]|eb@Q_ܐ4tkݟa`!A Bh{B-zpB tIG'҂V?N|A& F#XD='#l8 Xʡ "RB~x $Pa6,:k1F !|aap(CN+R@"M,+F@ܤ*kn!$@` b!Ab{`A,**`TL)r g!!!>Q B%J QA'/ȦVx`!0գ~Z$xb:a#)(J"3q A>!,"~n%Lr$@Rt(w Gb4"+ ** Jdmz`j>pjn ךKqa A" H, (o$7AI`h, QaNH@f$<"@ABM"@>%tDg#<9V`!' (zG#p ,-q'ptGp# o"1#2/f\#/O* -H!) >`K B %t@+0,`^"" " Ҥ8`:a!e BKC6"E' :zk/E ĐP/@ҊZzpy $a@ #`AEn:pB" a@ ࠯VGNVDǞSulIJL4%i062ijkc ML#vWΔZl7"l#lRvAhŮ: HD)̌tCo#nKΊhCo0gVv4f,Jf+Liyl).&r cR>nq kF@VV% u# KJLNzNv($j,*x`056EbY'TPhЄ!!$M"b c%gJh2TCsԠ:mj@_ O$2N#@ !E.1Lj#BLҶв6'0"(ZClIv%,@2B&_B[n{"w#6lH;^g43 J$bL ,">R+ ? ጬO*n +au, !bL$z!/`nj24I@m&9$3r-` <F U@#.@`62npTV8(z~!%"R@,b~A чЁNL %%f;% 6Y42؎ 5J$b c!pr J`0G!͋)&3kF$A!;'E2Np,ćtGRK܄hM, @^VTPA6N @k:#|eZ(\l{Ɏ(@ꚁsE4F#&u{(a[2b!8/) 1 I"ԀezWxDe7Jbki4EtH)0DUE~A(0aR(8a ||u*"# "'eWXz p]ܪAzA["[#8!C(@@S0iL O"<"R`K "N" EZW%G aEH^B*!aKAOn`NQ-SpK|ce _|5:A9ƞG [b1 /2(`Jo8 .ov 3 5ˍFP^nj"6?` Lxx%rLnv.Y CAVw5x ЏxΚ vގ< |%y+GfPa|%eitajI9@J#\~ҬAIn` gZ$͚ ZQ #Y#/L~M#҄ ̚' d̈8s3'@ (G\3?5ʭa>4_t f$@dnhfMP9S*%tiQ\8+`9nq*v&s1&ӈUN Fӈ"ݸPڿIUIvC8nn{!eeXPC$ >4N7tJTHF>F4h\AH\'Y@\| 1q*g#p }L8(^v[G`AR)BdD7`?HPXӌ!a ']L)Yf`A-,L5 ;9(TQpt1([C-pBXi PiC@ ,9Bp }3’HؕHʔiN58QtFCɨq#NHOj^pC (HFB[:7f*N1{`.HI5-@wңRKT`xly*l\pnn,KU #٭5|9 W\8x% XVAr-L + Ii0|^mjRL&'A tZ}LEfANlAGuHQd>W95=%wA%;sA/44sTҸy4ƭʘb(šD I CX:|p(8 (# MI͔.蠒nzP4iO@Q8X# XN)3&E5ִ@ mAɔU8N2f3TN3ɔ]7tv̯@N-@t*,0iz@'(8@>xtP|`qGNf& )fzn EHJ (EA  *@\# AaipP-,cD TDOo@8_XLNQ:!XBX??KQ2Bv ýO'XNU.(#92:%C:dD:# pq+ x(ɤ81B9tAA9P$*zB3Z@P!Z'F"] b7 aǹP: < |r/. ߝ[`8 5AdIX@ GSD%Plp'Y*"AD 8 qz@ _Z5 Zp /15D1Z%LG*!<b@bq O%P?DW#;E7CU(CR* ( 7tG8oLmOXc] lK ʡ@`" BL.J@sN)@ *;3*k#PmVZ8 R +H&+X0]H܈̮r4LX   fCₐ8 wmDXr`!/265,~tFqC +I)& NQru^`X՗m5v0=Mm)?N/ 77$yne:re8,ۖ5'r`yuO\(x[(Oyrq]f#N|Mg7*/i,`. 0@{` D6ItZo{ d4ԿX$.p8B% 0]aYu-A7 }t=0u&=Pe9 PA'  QT B1 |ΰZP`*@0Q1 M% ./5,N aR'!Vv-~ `  p0Pwve#Pg֐yaɰEfRϱF &# DelU6 0f4*3{;A208N1QAeDSugN/X* VL` "+gu:7Ѣ@` `  pu 2,H  C:~P<- 9 g%Y!AuQup` @UͰp@Zߢ7a'4.:bJu*p8$>@(pA'q*NY! PnTL*Q='2 Ϡj z0!i!U#A,0O 9=BY0Ґb KP%q} IPiP'1'` H# t0 v$؊cFXIho <08rc> :_2 u# ( P0 b" c FqPd` a t&0H C$e< #P#Dp`aYaH`X B+$H jPOQbɉ/MU PP @j@3'Z7 UB:17i}/s9kI#Pb*@4v* @X sQEه " 9,j G]P "40!  @[PVVSLP0E@8^Hn s[rW1أPi%RdOpY p$5a*..`*l"Eҕ!.Qü%\r:1 ?QQa+@811^k!uq /?@Ab t ` H Ce7p܀^!j\ W !1 c[ZE'+BbbI ׂ8Җ,%]?Þd{|NQT199! ͠-u _ P 3I#YjTLF0`<Q?`g,0C"p a=͂hy` {JΐEq0!'0# HOXL Zi00aO%U)ֲYi>}d7bwT́qCh/3AfmQPd@H1` CR"3G2p|12p`!t@, P@!GR~7 sPp/G"kB@i7p`otP*'aJ+a$a}8k~-.I K/Ժ~f~ZAU ,-_SQq3jG.E꫾-5,ǙNQ9w .pNQrк̴-."M&G{+4H3IjNL33N0P`#KȈ{3#I"kN&;Nq.KQH ),) {Ptv4yG3q G)pBH`++'tW8R9Q-ڵ:(0;sd o;ZꍇQ#=x;U͆ l\R™xܰ `!ibBR p P L= Q@`K0 ـ'5ˀQ&TAQFJ PeR=$H1P7СL` 2X ~@0 -B3`00y CFt4EaFTtP2Vz7PP[P? DH6b2@B]pPti<7FN|{QN$''*Tk˿! ur0<^ 8PYBÊ"@S;pkcKſlDσy>ſQlP).'p7v^ƜYfΝ=aMZ t!@G:JA( D=$HU6M-A 7:*\̲xzEҰ$~`f ܸI-5BI#tK28GС"kŚl'rQ?Qa:ցÏO G3D n11 i~O$-(b$tPi&9o—¸)'aPq,69 8XpP'ȦXÖDF@njp@ kȆd$U,_:K[o5A"@Պ-86!>ЁX!lEi';!ʳ-(-X&5`4Hv* ]`#B`bvXƏ*0뚁tM8)aZˋ!8dhkŢ=Ek]ty_ϊBX~й@ss!OD "P6 pǐk0A8TMQ  6[H`5I8g4))@ yjs8AmH! XցzPB! APe@!\|$%n+_9u],av j 5.i"EThӞgznpk@8 x7<f I$'HC77CNfAiH F e8iFktE a :!.EHI(8!SC9a肘5<aPLU aȠA,O <ƀON A6d#Q@ @o k,p .G\iTebwx%d[ANAqKh#w@!*J Gy-BЗtFN8xp.9 AFKۃAĎ$88@*)6qRWIJl> @h,PdbZӢ 7|b!a ~HzO0 3 ]D=فtả-xB 1C f/*Chw(K7Ѽ z"x#p K@5 (ȇs"ȆrZ` Piph!fݕ0if$jڈL@"X(hgŤͬgXΌ#aQ4oEڹ8D&>4 % aU"!(R(Ʀ T _COͰ]|80XF!(9pu(A'%5"e JV2pHr(5T ,EfM@))ֱZAn؁(<UibH Sf-R`+ #2wB0s(1#ڔ5\CVT.W ] x դ x0YHPBH0t FCWTp@-::Ng/xCGS; x>F2c,[TxAmβ$51?դ?3%ȍ|WU[uOו[BK+5sMz#+y[)8>aL 鵚BڨIĆt5WQ1K C B̐ȉ 6Ă,s71/y=?GN/xr|ڵX%!mfhU 踞yi8MpFo1l KGЅ}3X'8| ӗ#@~aӅ֩08 BUك*J?#l{@)@)ℴ =$@B=pP@|S`(>$D聛(tt㟇nz,F 1tH?a?R@4$ܔBT- iS,ոr綼4s3fmAf?8]qU~Y 2aB\ L]B;VZ!  ATb 4(;3o9ҧSn=n k<;X?udaB zD@} WB#H7Ё*B9Y:օʠ4MU5zx:LD9BZ!xpZ`0!9 ܠL0X5-``8t(8jH ,*Yj㍜Ԙ.Dg]27 @XC@8 z iq37#HZj(s:2$qUEI:)Zz)tw޹h=?F&dEA!-A.pzOV?C8RhIW!4$¼OVm <dS-K8B#2RӪc  dCG8pt! UNc+.pYTeHbWT=5V5s5ἵUJ" a?PdcBa. I.%֜rBO!  =4E]twiT%}dQD# t*F=C &8%UcqR77Y?&p(-˵d0ەST@~ CHtL9\ptdfJl1‹1pCywoܸS8NXlibU=K0ܠÝ0@ӧO  MH0Px= PP$OY ְFS a8pH 4t7U6q?`BCl@9TPi@7Rrhi 28MK$ u@ QܘIꬁ<@@B~ftB;)O7`MeS թ>R*Uլr^W ֱa=+YjִunU+\׷ʵn퀳,jԽ1?/(=,b2},d#+R,f3X](cz},hrqHՎiS՞u-k_+mk궷-ow.r*E4fRAAk \`w ~5/yϫ]{ ʷ/}kw/ ]u3~0#, S0Md88 0C,bg.u0Spx+ Ӹ6rXI8A|`$*kuuaB (_`)miӛ!עZU(!p|2|hJB"gFH ڼŝKO׸,Zß#fqQ驞vH"w?tqt,EEZ+RT1Y)E\@EE@>-0]u`UŤ!iC\\Hy Bɵ >_Uluښ\&[$ijGDHymI[\Bg,^9!uZ BF8?_yȟi?pHi@5)\=Y(@t`U_uc^DV UU[s"\R |I%b*Dх*`-K\.>G Y}!T,I*,@H84\d9^CSӼMd@Iqad!NB XG% "B%C&?|YtZK`NS]]EM  d.9!glصM6OvM-#Gд$u e.mdOJ%C5BX%#]@4Vn?,M\h,VBWj%VVY.Vj5\Z[^Z\v%]%]U2Xy@M ac6fQTseMPeVfdbthh&i&d:! , }C H`*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI!Yϟ@9%f 0pgf4*E&"*p̿h8Lk׷pH_8T!pǫX[_Da !v.C@[$TM9#'a$#UC 60B F^pNp˿ UT@x a |̼M OAk7l'c8@] @u ^ ?aTGhdA?,W434I8EB&dfle< syAF ~D(r@Ч k!(*@#Fqq3wtF M7]SDm|SF"\CS<-0I=4l=˃Bx|tM߈7 SiCfa&ԉOhW ͍ǔ&ASPa5#,"P2\)'GjH4A]OZyZ3x7/w(M8>8ST-@874 km{3{$4P !Fq\A֦rpFa+pv` !y I62YqD8%gh !A4[ȞT$%'"Th!BĮdaK{d@PpB@-k^]pE,(B^$ Idn)HBnh,T+iJ0>'{ɓ@}I E)[͒Xq "a!?>D:٦@ٚn cn d 9IP hv{B"kM \AMBUVEDZ2Ģ " #EMJ@8@ gHU X8iG@L@y5$r@S:u$[@Y[dcHSlчIHH*$n:[R4N6!Bf7 B:O ,F, BDIawڐePqNS ytunFYu!喲8S J+ÂpC$H>b-{A'^D5H>ˀWx,al\mH xR"a 3n2}w(>Ǔ$ Ws;0&2 .cSYYk 78!4L'uR+dk$x@,dc7ؠnQ?8EÑp`Bheg DC@bh V?д dX|Ue Y"26) )Mkف:/^D`$a'@9]1$j.tᾥ*5_!MPx*y/bH8#jl>K&blk"2]8ښ? _c $7KfBµB,\Eo]CI7@ZRMSE  h8޸zO` ODA}?'_ κ>6B(M8u'7%O9". JXry.K$^~7o0 ^8$y-ac!_7mB CC dc;\Q8$O9HDGf<+ < Ѭ? }h(=6!$agSמ"0W((S:䙤+ r.pfR-OL<R[!H!!(R`xP0t ܠ /t@X_[>b'1k '7  A%kbqY1"H@3?1tsR`܎; tY<ijTдjaaB'* =HML4*KJ.>Q#f~h`8C\S#Px~ #4,LTy4{%QY0e.@%  ͢)V]B Z$^4$ Lpdokm^& T!@̈́'.~0 Ɛ~ fy`b|p:Yd)X}>c# 0 GTmncN×&0'DKR =XAdq Q-w/Ҿ0a0 06 \1,~),~ARNWE<5Ib<Dw!#RX!H}T8]: W&S9 :j2Go\\ku !aq GajFD1_Ӟ_Sh>k>MWQ0G.a4`:V_O U9-r;. ?&xET>٦v.K.`x'?Pp[tO9w?[uWFT- ?W!_Xk !T ĘQFF[QH%MDReNAXVęSN=}KGC&3uwԤ!hȩ@kʍ B:8PX:X Mi#X?fX`ƍ?3dR8JIBT8MA٢ Þ [8 磠5E87G6yr͝?]I;n={jNh8xGDz@{u<>yK%Ci&6Cop0B &;p:*o<"0 3!3lA'o680( Np.GP8j `fG>!( U'"M0*r<[^ @>5Hc 8Hlgdj#![ǓtъKEXtGBf ++*ITI 0ӿaD,= ‰a l6E D ^@F4be2*#a1!N᠅X=0 % w9v@@Rr%(\AdF V>t9;t 6$4#kض`փ聛pL˩aИ b&tģl^ hbl%P=@ph!E,Y@T\M-a0'QMwk&! .5%b%Z& B5!KÊ,ҩ2#L8*_1̈ k8 k_/>ϛZc݌P]5'h<29d6"`tL=VkPyÒ!{@94-M{ QX}+bذ},Mfǿ0@*MWٖ!ȇ#=ndEѕNq  #d>arCӈ( $ (-bć# ٠ $P &`Z36q('bZ+nD>Hո!w8G:ю)\F. ;~5[`3~V*}4IFH2|et$5"q9*F" G'oݨmp:H@NƑ] ,90 w#<D\ Ba3#p 8#JqJ\' eeB#@S$yE3t(1Ax HJe&尓^M^tAt)5[Fаd ɮGx`q2jMm"4cZ2ӔGBȷ")zA,3hR$i=5.hH3`A\eG!>(?< 7*!EP TB @i4cYpүpQîD h_P4h ?1lA[ ARr$eBdF -uBDPɘ&[ЃffD3R=$%y.X !p:l ?<A?*46܏0 {FDD9Iz;LO P( Ns8E<UܺG0Y\JXl'p9XJ܉Nt~ 'p85L hŒ `p@%ȫ%6(Ԉs xDzR s= MB̈h (P C.@!`6<ܓ f@уE«с@P &ҳrPpƒ=B]#[0k@芃tt|K~0 [ yd#T8 q|uh ӲhaA:;YQ"e#d 8,`}C wa2к}tBh Dr,{_GƨK:ҊFyX̖#G38: \8r e,H[ t8MfD DclFPѸ8 >R"Pr0p˜ȣِIB0&0& qG" 4(p,B((iȟ J'x͎ 0&<xH>TIX؇E _NdgvK@qi23Pf0ݰ_M` 0/PBeHx'+݌ 8 Pz`S}h95  R(0 9$IN{z4=˃X R58SSSŁMWGE3T[\O’ Ğ f)= A c5(U,V&Yja I9pHǍ\P a6LX oEl9P%22=_\Y|J] Ɏo{48cJX2 k|!eW8Ø)?;< G<Q T$8g¨.`+ <P. g8@a0f(k҈ÏIN=@w٫pЄ W!+d%=8*,X5j',ʜ@GRK0Aqȣ o0ɒY>Sٍ͂r)p0.b9)Q[+:pc_xPpXR9] j $Kڜ9Ѓu<9bA;qЏ aRp+ʭYx<5in<2xK_D\,()1 R:l͝ĝ|'|ْ-4ɀP= $y_lPCE,(h<$$IBP9d!V.7N$7̈BxS`t&8ÓXH'( cj `+XkH05؎PBp(-@Rm 8#(.SkPBHĒ` &jӃr"/:]kO$f];;:]),5i."W> \Sq6^ $lY~Jf#U `asH 8i GP55.lDױWWpiU8PU8r.ߍhhƠQ]e@,XJ. qIAF%jfB↟r` -kxN'!n."齟q  !H~aXyq Аk!P Pe;h)F H;I쎙tl2 0u.(H k C q@ Z,lX!GH,@NrD9-hΟna: __iaZ V9i! NH8-Xg1skՌ@&5p :?8Gr s^Y/q~hfCvn_s{C]`wLVD"$x5xYH&tpјrm]o􈁍 aH.Dd :5lFPaOsipyuΈr`8L3  / ikxD@B+(jլw=W7(:ݜ8D.{W{/"[!(S W*r$PtpWp e {ki/_gɷh F /o_aq,Yl[ ;r xV{p^DJx`sz/r)2 _to?X`h"ƌ7bFb hD$ʔ?I-a(MȍYhH%РAe(㳣(+%5))'M)֬Zr+ذbPaY d (r@ IZ؍*,e &!d y^8m (KØ-ea.'kU1 cl n87.j?ڼ:ڷ3i/_9oSn=|>>l\1[Z5v]pio feQ1WwBE_FXVRIU"V"IԷQ1' x4ΌUMqQ-C?%#G TC0ZtEHX#$WdYPcI !!LEՑCK)L`*mYC%C80b2u0_E`)yĒEt?C[PX ܐ:O3w)QRر k523zrJ^fa`ME~D{`RC#geFU%%m|ڲQY&SH˛ ݐEP50VbJ0MĐ5WʤrU" B2p]Z;Fr(XXj|!FlfeaZr)$F0 T4w}?(HgI!J[pV¼* 5]MThT(b|бޓ]yTG3b[ZD@\\b%-(J ,&0,E@8z y"AAQ@w,m]zwX+$aA6E2T%b3,T`sFeBFD7G*xY$yWEBB0+^RpN p- ؐ8N@aXC[8!X*I^ I$Y*XIHPOJ =$!iTppDCb8kt/#&9vDȖE @PE"k#;HGL"H%$R86b.1

:@AvQ"0X+eˣh)kX05s,6z )CE,~e+4#эӑo! LPn00O JSƣ-ǂHgX? -,_f,Ӊdpb=qIԠ-h,)-V9?*΀E5e²8Od (C $PP!  1_iRSV7¬yUΖxeԌj:*(0eV'2e*qgRz4+ͱX{y5}\TE^5#9V MsӞO[z 'qqߘbZ2d$y z\W,HPK1!B|h7G22RáA\MX>6vQ)tT*]EH"fWYBK<|՟GB4\]Dbb0,|4Ch"3T`!> dː.H2#*Ujz"X2uW)lЅT%$d{[]D.I $eXT-ȅ4ľxD\0 O%XRW9T?{s7X[PzHF A0D'tm I$[h\B40EC8`i?F,E`!CՂExl1ĺGOCy̑/,Cjt! '`^N}mmEağ@1"FTk#ћȠd^,ޑ@H_\"nȡH"S=EiGUlbGs#X01-#e[3džr[153^#E@PFxGǥF9B-Ry\őuZe>mYe̙Ɖ*2d㈄.)mD[oYfHVd肛Ta%3F14C}DyOX0Jj[Y"-b@9Ld܇l,?E8@C¡APP uAM^чL(@ f-"VH!]z5d0@d 9IhvYҙvhhE |X/lWiiq$V&g jr,xx&׀eJt`)C| F'VlFHH9@*eرXh@`eJL #Ca,= JARx3W=C.EB=?XJ*Gȅ)pvI) }G Ѥ7#O'pRඑYR)gǬ-eϋq9W.o'6" _no׏ |/ֵpTPVrA=BZ#P›Q -6៞j=X1E!l!Séɾ-n2rxRbB ԚPʄtj/HfE#C $H3QN XDԏ8ԀRI)%0bШ$zbBs7 n"PFH; zMuA Ġ¡mFޜdd:˨#3(!'+IdH4U(!„.0Ӈ@PÁP'_!b^ ao];O.-J2ko)xJAܭ z8)G:`R檡@,Piy)XuH1^? >hb*sYa6=]sg"*Nc\k1D82N( nGsˢ*2B%.k {/:/;S2Sc=αsL!+\qHD<Qg]֕o%'ܙoؐt=䥯 HKDHkDGD[Cs454 EK83thl Q_]6w D }YwE=a3N Ćw1*zkB2P> f p 0W$^9I(B)NE!A$52Y1rH}`_4q фBt3C艡|o!@8B3uBK 5 !h+K ( F@gx0(,FvI: 28)| =3.C'qZ,icYm $J&ԸEdBNYB.M' $\ML0#:B`d (bPqKf2p3@΅KTJ9 d״ԢA%AFJ x.L$$ TTFHA!~Xj&@!9i~`S qS(VئiFAd w^2hal,ꙴvY+$ҨxB !{ϦUxR"_V~ulԀN6j&SHW$.)9*{ 'iv QRBFYA2hS᭔*"By ρOõϱiTRChŇPN x ږ °H'ZHCp.J#O g5OM*dHFP g\BW|nW^'D @ޣ9Ԋ*a$!XS3+3B$P:.hT"\HTNu 0?pycq6xj˝$ w8W:g?zÃq aoi<=eO}>4ܕ5kfQu| s#@}4BfFH=ȬCnO Y+و!4=HI{T9* ME{V46~33J0t,O^ Cc -$'&' @n彠x(+0yt) ob)8eB67Z@XX%>A7*TI֨ȕҡ䶍 R $L9V*Ⱦ1=DV'F){ G,21A SG-clYʕ@ >A ` ,!!CBABͽ LZda(!>bE[.=t"^ /%$zc܃^3`An~a~Bav!^a8">N 8 fD @ ho /"%$SD n0;Fg$Pc/ 5,iɴ*&/<<,^Bbh>j*0tA3vRD J CP9, ! L!@T#@ ap]؇.IT&Ү+BJGm"ƚFbm $=%ڑf`M&gOT2>bB2 A ̠! !^ԁ!0ʰ,q-q,z ?g%d$"2c ECT"?pb"$(2D: D oJs΄ L PjdTG(Qz!oR?NMҲF@ Tb@B@G./S^p0CuhBQk!JjNb!.=Iޤf/50?b0OÂ!,B4 s!F  B-Dft&s*:.j N"(^m=(* ߊ"aTB'.)2!!l"8@O [AB+&.D 6!C G->*&,(#H(` P"4ha R"/E@D-D"k S"&!*r#D9-e!hW>cf*?wC>hf"$4ca&H$0QcHK(2*S&ZqT*2"T3~/&ar8RtV)!$B#9%#NuTh].Q® _s?*~NFFTֲ3nvh='^8F-0M jN! >!TqmD@V??e9t!FI :,"0>UVth"t!@Gb*5s$$B5 "$B;=0"(VW.B~!:<kzbn"!;/eI,Q,P]QMp@\:6b=Pj(n'D~B`ߣbDkG O 'uc R}ygU~pB'(VDgW(Q54A ecVv P0%{R`[JS%6m.!zC>Za,! 6c` [@ǔ 5Axlnjmݵ?đvX{Pc+oژ%bb= 3@CQr?sR:",D K9dΪ@&zb'%A,=8px3T>q4Yӑ@  UD%9Oy8Y$ϖgh=;%jW"![(T3R`<0N(w@⤙D<!觍 9wRL !rN̈OqF O f"x;C~"ډ-:o =A=/cyRP!Z$Bi2BO"}"$Cc]h8@0Bl=A) I?-%U.@D3$"6:-DΥ{P-y n~bN4} z @~&MVq AA" Z"|B#n"P'ˠw!@! Dx ~4Du& >%B2 `n)Q,BmA"z_T2K' NʁOr=D9"!ps?f84 5j n|[m!>,`B*2n b"J7"$/>c=@u(=.:/r <@Syr;#lJ-#-AYA=Q<'o #R2 .<û7=5P s?@!z!m!#T g{ ĂKCFژ˨!h%bN㓲ӵ= @ Cڳ0zJ0i>*k݃D"N/k%Vkոѹ"<"ځ>uwGC.Q!z, 2P }o-][5VZ!."=!&>XBB݋Y R kDєqC#UXxV! q>3]> 6jR=fkcE^ 8SI38b~wC.~EZ.Br_ÆiySJ0>WHu4r/"㑄] "B<$@XIz , {bĿ / tXĉ:L$CBuXd !(Ƃ=:\9@i!X(O 5(A;TvHt|0*Ϩ? -4Ňby ǎ `T8, ˺m0+a*7.`oa=p<ՠ@Fn꭭^jz_ rzjb ήNxAٶ5r?z n!&.Etm}렶ֻmBT|뭽Ӷp  =|A~@oIo)q+lB|LrɡirU(rz2L! , |A H, \ȰÇ#JHŋ3jȱǏ 'VIɓ=Cɲ˗0cʜI `6 @@F$/@r ]ʴӧPiXL$0pJՅeH`QoʝK݉| BI},?>cy(Nǐ#Uۋ 3yjLz )[\œpM6LA[֨ d UC- OXt3!i={HCkkDӫ?a{Jef \uAYA +E0W;]ރQWnA@c0⇉ OGjeT2h3HR #(DiH&L$L%TViSFև WGx@}Q4)E" 3œrP-\vGz5T|&a6;@4Aּ 2!Y3F,7pRXZژY7 -oExZrrFA"1ѓC6KZ dX3 7lxHC<:ԞYTIV30ʔfylPPN$an,=16eO?RWmcxS R]rm!rup(4q;S),􅮄ХiD!L/)rÇ-BVibF":K`TA ԇCLD~T xMP2PN #},X9$ܠwsv0Ad12 aQ4>N.iH3tBrܰS6IAg?d, G4RnAE-C SQ[.#cD\/IɆ`!?ĐՄ~ r'65ީ* /(`1넓BDL"!4Ur78KАfR"h! $GjD!z@$ ]QP!Ĉ *si+D4"$=~&aFc"MЄ%TAL$ъ.HL,EGJR,K "-)K@Җ^`j{\ҚMw>Bb/RP+^S1ãr`# x*DM8NĪ2VIGfQM@dpAX(ٴQ\ &?~L?)Ykm0c8"{ثAt8>&3(i#:]l['%^SoOjn!XOϭP7%Ct сpDr+^n,\7!Ij}E+ܰ ?</!n*jC\{Ot)SHjXwB06pxL`H&pSS;){≂L /ıs7LӾf)(p3(Dzb Pa "V8r .V#Y%M <$-C`Գ&ALxE%a8*L'DGiAP*Ab5DV\:Ce:Y< R&F 1!\$T yL )yKrdt`*V8a-$a%ָεw^-%aHb[ɬ%bfcA̼jv "z%v +?ۀ3c!~ $V*ʖ/dC~% dr xC|eyW27؆u) Y`r'w!ѷ+ Kd aE7gN<,KϦQnK5vtc8=b#1bs0*3}4HNŊKU FFFMdqzIJl.^4CF %yujZ"8T^IyBΛޑ˹Nֻgu21<7ƽ%i3%318:ꓤ+BR'? r|NG ZnCM)OC{ 95,E#2rRZ 1&F@x؁Tvwu w 1F#zjr X}&ǁ \Al!zQQEUsglp2A@ qAe pܐx+P7xJX#b*N_8C\gFa{JTPT'&9!XЃ,7+4 *` e`x!+}~VR؉E/AR#;`&a=L5@0q; y%r co@!9a h P!%8kPE@?R#Ւ +( ;(-"b "> Y-Q:03p:QdF#c.AFܡX R8A`  YWPy\p8A؎=2 [EuEёANQD /7U q)%^w/.X/E\2 `Q0 }]IW "1s7!_!:"#DUi0 fOBBq F-I2>qT b*HK"@"!,W"oԜ#W16"c&W7D*y9<4)ihAzsG93~1u!Bq JGaE!9IA1+sv % QE3p!2agVxSb jfQpq@ PmyV2C6i `Eaf&)cQgWr5Z/1r[S A? ($ X)"Zomz:`D:j\d,UF3|RmS+fCtu\$( AC;esPs9! ppOsb NJVGu  y۶Q5&Nfa$j%#C#24q0!:@xzڮ5:С#-  \ fW Z⠃.!mGX0QAIQ 8cS(0?(41 j ' ^$'@2A?q519QPC…0!a oYu9;6` H)@}!9ѦZk+jNH]prwK! bq! |S;ZXFFPJ)@MZ KaTnsEZ$Sa7 yia'$J@su p+>x[v#QjȻ4!a4pм;awZP1DPP0YTLH3Iz$B+++kK*'5(@A]D[QW[yzz{%qP-PQhe%C+qZc1Q鱛05a !vd 3p,.'$D3ܬ+cRp \0{B !W4ed0O![a_xγ6 .o!r! k Q \ dݪ<,Em#-ၿQZX%|0%4"Iz;32W8"Q~Y$hl$gL%.3nP@&Q9-Ծ:=!Z ;\J '#@P4c ,P/k5<07Klk \8?)Pb-'}%x&*) o# | } j0@-lL{PN2ş[r W*{Ɍ#j$]ݱ(0k+׽8"x(;&/n@L%'pBn !m = \ LϤ4iZ|j||Qt!9=4URS^u0& A ]EVZmRV\uskW^}X`… p~?Yds{ ,S≁eZaWrS&Zj)*;pA@ڡAֽY+;YcrIr@fՋ]:isOρx.hus`\"t"R,@8G:l)sF*"ºhQ/MKD:L Ӎ#;h(*g"b,r2aIň:D'* ;1+I"2/%FE,!.j$H#[60mlB޾ h EoT@Vp!2ɨYT//;/R$R-MT Ț0}R`7x5y%aajS$Z07"BA((`Vb>p{p_ E-/ cC^ށۮ;fBڅF#`fl§߆%HfﴨRb򒔜.W>=,ޤBȍͶ.1\ulT AhA2("''I8#)*ֈ`Ƨ;&/VUuO˪v xT\1d}aq^ώoTj$4y`j`V'2G}UGw_syR.{8Pq'A%(%h j#i* etpOAP\‚g9d C@BY."ܰPt)*BV!K+…A ]. X0#C?`h-BQ E9u@p5WYmi&Lè0 ];9<݀ĴX!ppKC!Cq`>n%LUTEP # x -k RX1 j+ (DW15]ь hǠŴx:!s,05 )dxyGz6}, [G`20;t 4 -!̈́ǸNθ@2J0U5bl+Q- 8(UѶxި OѸ+O D9xЄU؅e؆uKH ɾ݋SÉ"FfIvl#*L >x%Cb KS!LC&<<`h?LȪt :2 <|o2D?%kֹFЕKYS4h4+ApR㺖T({7G X[J 8XhCLjKZ#Q~LR%]Xҍ"QN= X]M( =8ǜeݶ0Ġm2*k҉x]X]cɑX8")dq(] $]P- |ډ^d¬b? 4Tt{U)5UHޟE k d;m S杊qb`(X+q{=!T Y1`¢@nM% !&"6#F$V%f&v'()*+,F/v5 {B *Q =ӈxAЈ ƊXx%n.@, xaP(hىpjW̋dpx$F L=;8p\ (h 96[Jc(ˉI57` ;F&ЀjnDXFNRD`:h6L(Y eKu$%.xL izYԡ' ShAwjx`~0\؅EHiX@ɐغ $]Ի豈jx\j  ڠH Tg rS )9ʉh $<8UDn+_1 gΉ(. F9E9 Ջ9]H(#@6. h0;l:6` & xlx*bc Nnf Sh/N `&!XH"D=ell†nSK dV/ >"F+ wAu)x^T.Xdz ! , a: H*,(#JHŋ3jȱǏGIɓ(SN"0cʜIMnLSϟ4Jѣ)@j2KP*"TիXu#`Kٲ\NPۤoʝ ȃ@N= LSm +^̸ǐ#KL˘3k̹fCM-ХS^瞖c˞M[s-W .7ȓ+_μУKNسkLykƞ{ҠE?siŻ~X'`fټ0 FXB_Vhfvx,("FJ?#B%t0X=h'ѓ<@)DiQ-J’׉RTVBV[2L7O'YN$)HYCh*iBgׄLuIϓF UHfhϐҎ(tH?44y9ꩨꪬXꬴNfgۑ)UBXu1p)m*YPc%YUΜ~׬tKJ-R4n0Gm~:O]t2肕da i,JqH̨ ܠ>مP<` Fd{y Ȧ5oV R$1xzA< f(BϠ0gY=P( ` i@ j7SV~ ,UIp (Fvg='*F*M} 4Em/ nT05n Җuj8LNjj= 8pt(,"tD :`q.B(4(Ok̳֠h8z* , ] n(,~qєh2[]bZ T4Cֈj+u^VH!SPF0Pz n8rs l###;ɩ,'t9 !8C pP\ v!H^:!! prR61 ,d5`!M,h8#8g0X7m; a 5عC7 kD*F{U*)h!8B, pskR@  rF^ЅhdxCd!䳕oalk04GJFЁTcFZ U¨h%zNXqX")꼎6TnPyvHF{f8p@B4aO(hS֖ 58F V\-*СRH7.JaNCA8Q(Lknj) 6Qam>CP63[:q4SPVtk "zPV79]*BS֬0 n6y+|%kD[p3Z &@:ѯUP婽-Mx*Yêz'g<RoZ)tPB }?_ BK ͗?'P~, o?W_7}g~]}[77}''8(쇁xg} 8}gX} }+hG~ 8~CQ38:<؃>@B8DXFxHJL؄N0F&c @Zȅ][ȅ _9 hhpnȅ{v?(ІHg(Y_hxzX`8x9HP:@p4cav Y>HpN p tLhj 0˜CPg t@` 0 °sʠ Xm҈9Ѡ X0=e h$K0\PHtW(P@V` z @9 IЍ( *I$Y ( gh u "V9YYp`p1YOQ @ك̘ډ 5 qhEyv HpiC0N؝@( (4`-e@J8` Ya 6c8ZzP  ШdҰzzE XZhWz:r8 ੰPzɠ `9Y{( :xj@&s zؚں@hѕ z`z ʠZz 늮:[[ڮk;K`{嚮˰ڱ*:媮 +=2;#0ɤ,ijWuB;D[C` C@'"vU״F{XkL1j,bLV /j`bYl+`G3,PmkCPKiTW< )P6e ,G PF7a1Gq@A pp(iPaIB|! GKyR/hQf.p,;[{țʫRbX /9.KOĽ;[{@B=D]F}HmILM8-ԏP=-4I3o!|=3p @J33s[ֈeAǰ[J|߀.n'7G.Wngw砇.1Kz\pd4c T n >\]$bKcX1?+rKO9CŊNc͛ѐMH8fPcf Í0!Чb@BЇ?(nH D'  #Z 5r҉J$r qCn\^Zb*e1S,oL;$ 0D#h6bHcD,## ?$ >BRT>Q;<X+n,JT= oH! hCFӭLT̤&7Nz (GIRL*WVnҒ$ӟ+gIZ̥.wIXL3 Q3Y̅,-[0Lb 1$Du]A1cӖ 7p@]8w"30e QŀMl65ܠ:5i4L5Kn !Y@Ot!qNQZK 4U !5MaH*J)#aaĤ t@. L@fe@ 2 u h#!(#@3:Uz P'|QYÝjUM?iSK f@d"U nT8()ptFc( ƪZNZ4  XC1[f!f %Uq`ب;á 6a!Cn ]s*p!:Q٩d Ё nh- Ve ҊLn,4ܰ`|* VnH i൛5 kSx[r::˜a#qZC]( a _m ʎհ%aMv 3eq @#S̪~{T@9"/đRr" .#,p'PS ()!eJw,|ɕ$O-"8b0 -p1SkMdPA!E])\ե+<0jQ !|jy(m=JpCj_Sa @ WBbE9) C`RHi ہʵ/61 XLaaۆAS$D1mpl*`1 GD3,peC4 -"8ϹuޘU5)`Η1]?fn(!W/ق.Q4՘EpP^A U,7J Q%Y:i JcڈOlbr:N iH|1ys5?чOS gL}/=K`OڋwG?ӓ~Dgz,_"8ЏO[Ͼ{O~f YF?яx_O>}~WX @|@`X (Gx  ~0*@S;R|6||P} ` ~ѷ~g-(GK(} XY}bH3;[}J#~ з~ ɰT }g`| sW7 ְR;"7 ` TH tէ J|_( 6臺@堄a| `耺 ȊG3rUGh LJH߷ȇE b|-˸}Ph ѷ 6H~0#' AH`p~0X}ӈ ~0#p렏]f`V |0 fh@`R6Xz~ Z -5K((&- π"jx} Χ ʐ' χ AB[pPP `(\| `뀒|0T*  `AɊ9PP`|밌6 88~mUЋ*Y}|h pT7p Gm؏0]7 #T`πH R8>GpP(')Ә 0Ұ6hОy}Y- P 8Q}"% }|Сp)@H# D`۩rI8XHFJGZH:S89yK^G*؆[jҠVڥ` rKO(YqJJ8( WZ(Q~ }~ʹH2 1 ک:~0],sa[*RX:Zz*ʪʫZ]úªP૫:ĚjjzB2liRbJ%'Bq%6Ճ X`;{L. A\E ~FSN K)c["0;X{D؛ڻk#=edaS1kι'A{$] S‰|{`Q^L8Vz;^3+' :S: k:'+(':ؖ帇+17ѷ̫HJLNPRȗceAd/D BOhB!UmЂ ċY6mpA690d(sD=3}&L;$Fi ܊w~H\bP"D:h.Ǻ@o#idXn_* aY+[e4@b,kXNHK kRvq +"X@yqs t;_BϖݓD9ODBfX3ͪLz wAq󬻝%%+Hx%4ڬ]<. v'Y-el"$}5CB tTi?sNH"Hiͨk$3E# z EnR}V ZhuBta gTwo3K H q gy] q0)5 r3hm,LzFU 8Q}MkH"q ـY>Zk#a M&}1 I.p]Q q.1TaWx+#@7Y;*p۲&ށ ~G`aX8:GNƈyQN q":\୺5 3^iG'+_qh!9Jp+E!eR3'`'u&yr!3 pSqq oKmS1l4¤0;o }1Rs tV  BY 0R`< 1RaWLf SJ-7P;an+( p!*r܂=Q5A `#f.+%Z&0 (.Q[$O{;ru>! j/ e4Qr:+*}|jHzȍ25?LO7jqtۂ)ru|2W (pA6d-HQ ~Mda K/AO$̀,AGK@@Oq@KXytFQ8JDPC35:A+;v,=/ p7la ~@(AxS2E-q#@S(AQ#rLU q?a0` ⟡5A=t(_0ŵASL5vJt49Ą6u1."UtرȎ P!e <?V =WMHZ3f3)|8e2Mۏ9Ŝy,]$;00G'<- G@\)@s@V[u^76&@!R`RO+B,)dCJJ3%ř: tʼZS iV08N :hjE)A@<<(£! S*2*3s˄Δ6,|WaTRx4d9HWC '?!Q=inMhmu5la@鳣$%e VMuBQ&n*Y.ޒB ֠-ٖ C2~*p۴ ~Fze \Ab#hj+;et) v kܡ[,$ϡ zl06me%a^fV8,&["hRAiWM*?vZ;lNrH!Ј:qDy1V;"u):ъWβ("VkUE2Zi@42r4 `T=@A$Ũ/LxQ[b<հ6&j?طiElW996B&{sP:3j&0UFPɁom*C0EnG X&q@crB*K*V+b> HdM`Î̲:."5r aq0 ;C1qFT YPr 68Q e (10K {\Y7Ǒ&hd$Ҙ P_3@k$!fצnh BCk| Z@̶53LL[hPf/ $1?XTmzp`˜|ء.`HfKC>@-Q;@;X ^-=I7aF\o%Eb`ةԁ5xܡ!d $+bb9>P@wrBК2 'ցs/*mIiGg4ܙJ<3 JCȚ\g}T$H-BX&Q.SNP(\ҜxPW*Bp PZ#PT0kSJc [B<.48 #[t*dp<ׄP 1P!Dvi +@%W$3g|TM} ?*C:/URkEi'$$CLCҷK3NpeAɠ<rEeq)m,5 ЇjnqKT!,0ta!Үr0d۶q%\< ,jlS'\w"a҂!A|\E"t!\AO!;!搃f*!_@' "u;X0tf{ )xÄ" K" $7($m|zŐjLȆӤFfc 96 a뷽@4@NX@( ,@0< Qȴ"< AiA !t6PH+(=M)0u7"%W󈙨2ВrLڰp7E񇳈CMYJ{'يi-nPk3 ډ3HT*<PkP] i; TXxh3,2 L $>\; ?}cTR.8?W# )Fr)d,כ<0C0 hB) T|uGݐ) c+?@X {](!E.F0X8@p2A!LJxB){+T'B<<“+];(ix2H9t&p p c"2cP"ChXEekp) B9Lx&\qxdz؇G2DA)@! Jq& RxI RAO(29>d)a0 T $#P  ]A> ) Rkx,2D725DAGE)?+.؂΁xL 49܊l~XXȋp0MAJH $fϙxL9Z A;’Ё( hX+, #26q.0 loB}6)x肎L2А Uy=J*Ŵjdg #! RHpQ)ݨ з  ڰ H j 1s|da"S? qpӱ#]XI; b n5܇phh(LYU3aCꯕYG1>?.gUݼq!X BXК̓@E 0lD ZeS M;* X *.,8:pK."{lJG*mr#qhP l&܍װh*_Pnl](=d ^1x )XY30mؒ\V^z0OT3? (PߘNaj1 q\I~+ zهOW Ve ;( Tj)X%6;~o#p"RK И`h_!L (շj pN|AkfS9TyɊU=0ϧp#rO2\8֖"- ,8!52lC`Ң ia)#Ȑf8QȔ*W\h˖Ȭi&Μ /0ΠR mꔠ cJՇ(?[O! $%(d-K(=4;p-Zָ CLÒ'BkЬRnEp-wH-ڡ4,dp뇿3J @97M e"0m}<Y QZo'>cA\`CHhCtI:d@VHAU.$!E%XSl[t]y &m&9'uȦADGhP&YcE(ZBmtT$x:SF bw a_FPs!u1wIA.tri5c AwA9˱i9 AfWd馼1ĩk'H C|haG2Q@^X6;3.GKZ[aG:ZƐ)A0t@'-վ$Ą-Dq4׻yf.,pv1]R(7^V,C-At5%z煽ēAz1dq!Apظ.}x% gzVG(~! w"%\R#- V C蛭y7Vx&2.'F!Ec k 6 rA4`@$Cw} d>Hc k+bTa iX@Y#A`LkH2.@`)|Ȣx"%}#8g!L):$ A ,vP^VDh ځDv:QZz+CZe/Ko41ĭRՒA[A%8A؆!Mx",3JhىL3]pd2&;NF//Anix(é*ZA aAb[6ΌrJgބ#4b4V5^#6f#$ DD6FAX^94:2t^( UObCe#)ͭ#6VFD[ 9-Rq"(x+i8PaAxِ@HD ${-Jyxd,dI9SV )[P[CX2vTBdDD_9zBGF8G8\DdGH NƸȫX?D@b DAvmP =$`?\P8?%ZpKk\gFy@D҈=`@AF K$X&Dp A N@0o@Xܓjz>hAccIL/ep9՟p52')Ju^gqcPbt-Ć  OgBIr.L#Dq{֊@;ÅEL~gIBCH'H?-?Z4*Hxfhxh2-nUr$a]3vDh[dA8?C􀐸i+ZJ(m3HAbQaehCᩄF}XQCSBdqIhI7LSXCnFgHlH3pr_dzS?4Gl2Xå JHD?h[t,U֌D19DɄÁDx"Y?<@ۇ-ًihfDXY-alH,J#-džѼAJȩA3H/8*?8qgx {/tA0%Ad D(D(0C- Dr+ AX@ S?m0E-mdRvqQcD[!kXhf@)A5``Kæ`M-GL ?dCxA : d@ԂA Ca@? yNVDʥi]FiYD a`PF_) ܩh9C|5VhWC.AA ?\m,("D`I.$C 7?|`Dxf41J, P|M_WQx7E#Cx"OD4 bD3hMJ%!;ODD=D$Ad<D6 C@6(? CiQhp찈YN$ 3DjSIlNN\eNTI1E0 I /C @X)/ 0pBsT)y>S5,DdC |._A0XtK|G\$xs6udj\Ih@DX"ݭJQ-ΰvo`f S)f 搈/XMG4d/2]~0VBH]aKB xdH񉈃йhMSmWHl $.3D:9/46:H1U9ёA@\8@ģCJH4$Fċ2@#\'O[xGcCԢPp. Bt@/ 0@\A?nAB{L ^)I^A,HB 4L5^)pNAHE72!_/u.#H608@X1@peAX~cxpK@Wm _H\?E-S` (%WS5堇D'A춳Tp#Uсr2?a@X)"Y8e:DQ50pR/ߎĀ_OtzlĆ0;'kG UH@:˴M蕠2J@.I/{K}6HɈ^6QA4mzh/H(A4ޮĤ2zƺw  D@]Plf}y#8߽,XSFs؟!7)Mt@ D̀`?̀X`Y@ӿ?H@7`A @aC!F8bE1fԸ@"z8dC-TeK/aƔ9fMo8 O' z3&U??K+(cj-kWD߇Czhh7zW86*,(ӯ&,L4$#2L1_Ǐ!c|!uJ#[#"0\远 ~S$7wdǑ=P@P'H"uᖂk~Vd83^ܱ2'ZU?'׿LX 'I!ꂀ#8a ) c CԌ0n,hA#IfHÁʓ(hh 㰿%lr"A(bȅ~KĶ@Mpgtk" |%/ zA(LTE #@ҌEDRы2EABR:UȭNks#5luhUFy_K?X-cMVemgVikVmo Wq-sMWumwWy{W}ksW ^eP/ևm2`Vj!".JVI@@"7uH2T`旦ҙ!]c=>1,"P"7*.BS., B(sQ:)*ڠ~)?5qF@mԅPQ3+FС(U"JhJ>1B(|!VI*2 (: 0tPx"{T(\lUrG:}(<R K/rNp! 2 Oa>QȮH$ R~ )BFE$2FΥ$¡>s!  u( ^fƚ]!|hr+ h1(X#@6k(} ǡ"&x( ( zB*\ "6<`R>!@DH8օ)Dgl)NPPH*t"(@p daP$ ?/dGtH( $7HB|V 0(G:r!eC9=d>U.tOP5`VAP%cbrV,` RN pBm< @](+" O ]FN O{ Y@4́„H Gr<}s3,RƃO"~ɖR,B8phʂjz}cHʘ :YՈtf}: $~ɁD@ e6yLyR$[HI<HRk\Ɋ 6eF9F)1ҸP#@HC1>iCdt v#DpJ&$+;':dW7CHՅ.HDŽH®"1cW? j2A:\#'칬dNc]<`2>Ո=R:݌Yg. f%2z1hjQU.ģ/#<`7UhҴҍԖy%/l̂hllȁ4)!7PmbƆT+hH46"#gYD\D5Wd+/f<){߫u Qe vdI#7W"&nF(&<:E@Ƙ88y@=v*[8VNyE@@(DH(a B Xϲ",,APs&OrfAb!BL\Ʉ*_@b< wnsw7tYǫB0d*8>vWa'с"x<S d=q}Ld\ !8d&wGGq!/#B0u$$ k)8d ֐0xN9D 7RQUAш A2Jp#R&gE$ cpV1Ku'"e>DO NHbZQN ",jA+ ϐ5 lٗ~wzr 6٘kI )p .17] $LI{`? 2.d20b`=SvaqL921x  c¹a~!t8m9ةC9iyjmlI扞—2)|9|ٖ٘R9Yiu+ck٠:ZZq7P]pcI`!7` " @ 0d XТ@qpkId2pyP CЗHПL23ÂU&Bpi i,#4wX,9-!i3t 0niip- 9t B ]@¡p) Ґ*g@ Zp Á Cp)1GfZj ° 0 j"*2 1 ppPؚ5 @@zb P& ְ 0P ZZ ۧ Z]spA~گ,k)pB -6?a w*v1`@H - p0Ԃ| 9Z k R)`(*g '/[#,0²71X QHt ך@ 8 Ѕj A:͠ l  k/ P '* H@pi#H?PQ'bIr)8Bܠ@* wypt IP8Π 0̀dZzPtj J,z[3ܰ@@s** k׿jU8q:i) tPG-! #Obxܐ5C@0R 7 1 e@-  t` `Kd@RPCl Xc  @8-{@p 9; nC KX e̘' ÁR f+ya˙á W# p01W¨uBi@rARar#} P Lzࣅ ]Pc [R@"2* € O:\ߌ0? DŽJt n*.KV, ː\ Qe`r>d^B{|8ܙ<߉P<}cw' HG}JHIR=T]R PIOMmb=c\}YfdnM[o=^Qs]r m/}؈؊،؎ْؐ=ٔ]ٖ}ٜ٘ٚ}=D pةm`ة۲۴=۶]۴-ƅڴؼڨ۷=]ܳM  `@MmM\ }کfܻ- F `` ʇ:9 }` ْm @`>٩uGM pm  [ , ٩]>. ⠳ ` ܛp||B H۳ @ ] 2n @  Tn] -~*`` P ` >蕝P [٩]qغ`P@# C  }Hl PH  5BP/Ͱ 펽 HNҰ߆ j"> PV.]޻ꓝ 0닞UTU^ŚUV]~VXe'ؒ$6\uś.]{۾X`5Lo_a XrȒ[^tf=ZhҥM լ ,feZ]_~ZxᯃZ۸m @YQ#^x+xS -<ڃAj΂$Dn= ͪ>?1DGj KC ͐XFdt*Gg =9i$q!!Q<CI)(,2,G)B:1L3b L7=+ >z`+D:eʃͮjSPEzAB4T2K"D8t'{+ 4TSϲ~JUDa9M 0OREr֧16YFMFeQtWŧx)iDXgU#<E+FX҅*f7_|/0+@`1{%8:ٸKwέ* *Cm3rGVߟryeixvg%0?@'|G?PR}G\WU撅ˡ:GlC`$@)*X $ȕ#R!$7.}cr*FZVpl)s@Zr.Ԭ4ְVd2n쨄^ T:Sxm<{_NhJں *XÊ= ,wBB8!`)ӂ֥]SP ,N!y1CU c F.h+=PPiP t-IuJ_*:1bhluLtunp;\ZNq r%՘.OUnƪRN:QRק <ϖ)P6ؑ ,a,:tf7D6V&DҔ NĢ`am p^*Io- t%JM8W&^g<05fTqAHBRu %Q{p?ea ezŜɺW"~)أcK?psӺHT+{Mm*NvoUm"slwWK1a\4w ~(a$%o @{%w@{2kFCl=DOo8@paX`:ҜVE[p ?ЃvE[zҿ)qg{&XQ~ϧz^G_*Dw?ä@YHBMeX#`Y0s,h=x Yp;<9ƃBH3 n { k<7Ih0i P:&A{)BEi (!?Ӑ (&*)*BBCAX]ѭ))( P7.,P8?Hu'/qC0%7*|#>@hȆ(p0`Wb Ap* kC AH48@$ lR6Ml`DDOx` .s*b htP18I ^1QŧP;9@TOQCAЊx-b@3'ņusiE0DPOyZ%cp K"VԘxcԨIuax,$.kC,ʧJ`SʷpXBAXqʫܭҞ{) MՀ>Z<< .jLj>n.PJCKrpc)qKSw2@Lϐq,SpP͍y@转s $hR,:LF@MF,y< sL x47 0( pL ²8 5$JNV G`D3waCX"J0d(P:I\EY M^Zu͊`DPҠ?=DˉOpNJ-XX0EH&YLI[.)ƫ@Y*QXX|t2 PQƧfɘ$خ!O\8:"G6聃$ݎL0aAr6(y2nXH`R ZKc;?V= CK0 JTJ nDRmԐSSUU'eUKUOW좆q*[ͮHP@5A ۭ枫춫]+[-5ZCTڸ/`4Z( 7G,$pg1X,pZ1$lS,˗. s< dedX3mK D?C=L0> RE-R!-@Ӊ8X`2H?҄#Tl4G#?T $mR#?H3?\7U"?d-m4Od$3mo#xLPG"'Qᄅ AO tXTAqpC$5)0G!#0OӸCkЃ_D1p:0H" :gPQVPⰆK@.OD%)Hf1 yM`3NZ:I]c$!:_$ܐ2 k$=`#d8 aV75@,KFPJk<%٤C$Ht.pX$CH.QF`? ]p2@z cv 0A) 20F"<`3 b =qQn¸i"a! 1M`<G.^U!dba8$LF&?@0@[0P: n㥄G<8c ʀ=~JE 0=C1$+MYWƣx?`Nu eTsAm2 =: WСYx= 1C-"D`3qZz,i0!V% QI#@G51\x4kr+ {X( ,܆rvb'H_#l?u@P"1L’MRpXf<7Cx* tpXD96 92(um^cQe؈h.2:D8x@A>&$ױ2q!7"W8`5tHl649p+}j ,P#kF3ќttȍ,r?&YCn<1H#!-R:H{$UGGbOzҸ6uOݏH@xt4$=.Diq׭L5(}LM Ki 5O顕Mrl9 :[ y[X7~w-|&x{ ]8 {Kϸ7{wo&xdؽ0gN8Ϲw@ЇNtS8I][XϺ֓<]pS_}[O^L8@2FKd/kd áY::qry( çx`d$P3N@=CO5B@ 0(}w>q `dP+e=b <)n pw܀p|fa'z;0' @@ f@D& [CL۴NqP+<+gS+\۵^`b;d[<"*ka%jK۶xQp;t[v{xzz۷~;ۯ[Q3 "30fPR˸۹{R]n DA:,{]ห+뺯 i+"າ/0v+g&Rrm; #aR`@k)OuZg軾۾;[{ۿbZ'"Ph&p!N7)c!< @,,-ChKJ%CAEq{r;'*Nm4'-k p6! , {A H*\ȰÇ#JHŋ3jȱǏ ) 0(S ʗ0cʜI͛8s3ˏz Jѣ I"]ԣJJ՚#MrkQi  ş^Ӫ]6ghtݤu!߿*`Xw篆e`" ' LyxR3IK 3]H(}7F!C xx8֯kν-ՄON.Cvӫ_eO,(]&K|XF\ƀgBLTԗHAѐ Š቟ rQa Di$! Ibj[cW,BOQ|P~1C4vTAA "d$BZ\"B5?0Ѕ;t]4%C\h60(D"Jd E-)M dg? gA-$D4Ġ+QǑB-JT7/)Hjꩨꪬ꫰:UF?i&j^Yv&+0q 5@@SI[*-Jd@,MRDgg?We5v47~CBFABCCAJP@0Ul P{5BHDǢlC&)"?&f !NZYB, \GA?@ːu' 'AuEqRxXBk!crC PuU'q7d]a! .Ač@WxwN:rjN8AO.E'9(W oG6.y\x][|'VtIP'0kN'J y(oE#PTytk,G5ү.O?Dg@P?]o?h88#4  B'P!}Ⱥ"G^ bC=p@ GPd"@2 >q){FR%}BM*a,!doB?7,n"3q1(z.${ņjPi(z#H:*Pd5`X iA B+# x"rx$J2qh ֘֠p4"xK~H%ŇYH2ˎt#cD呐hH9r {UVNCҥ2%1D#Ͽd["BLD #QLgG7vK!<3~o:E6v„J5.o[B?f!HDyл ;9UCCVQ}` hѮyЍ&,G"6ZQaT@ Pڞq2ĨDiFJ&5lU8sHDtTA2!U{h8@ uJr tBD;WoEd3'0ծEthjnb"VlC,t"OeGKO; iWֺFڏ3atͭpd#cH0b ÍnW%2P6&rvkB2+&vǻ#Ҫ,6֖( P;xQc'"1{^ !eH f2w(pV<7*YF3OL!zXx?SoEX;R7(F#xx''@12cu AUD(+ڒ|;C(Qp( [%?mOvfv!'X&q6q2:Ÿj `2.DQMLp*ąKV"$(%=:<-$2QWF$q& ' l P&4QaI# H@t!Jѐ'W[R@0 =q2sA$J$!3 7qE(#TsoXoyx _$7-0%iS@G'Q#P`q٘q@)G /Y- yP0XĘq6阣I7hC>Y՘t*@b@ ,U (21u*qiR XX0ۉRީ)IܩPH] H[ɟ9Yzi X ɝ0艝9ɡz0ٞ0ڡ)*ڢ%:ީ4q9ePFzHJLڤNPR:TZVzXZGJL`EhzigliZܰ\Z@Ff E܀u`@n:oPVʦ Gʦ`vQ0vd *`t@x$)f$!BxjKJt @{*ШXjj `ԺN  ` X* tP P €Lʦ` 0 `  XE`ljm.$!* f.h1.$   %`'+ D` v@F U!* ~J: * [ tj Z\K:+<[ڳQᚤb^#5)A qs$@ d@ fH apYj XSJ @@\zFZY tZ`E }:$@0<x* e˦жc*[!Fa` Qs ֋J `` 0+XʐQ 蠰@ ̥ʵEJ `{԰]@|ڰ0Pa+l 7lmaȀvP  k t`E*uڲ˦Ы`IF t Y+Wȭd xj DЫP`x* Z9ͅ! d:-0H)p xа, pa <Ԭ@ ~* Ґ;` `|L뽺 \|,/iր\0E LL_<<{p* 7|t{s#L|(~.02=AҰ I>ӟA< F ]f--wˍԛ،؎ْؐ=ٔ]ٖ}ٜ٘ٚٞ؈]fy7И )dAdڰ۲=۱-_گ @ =4۴]MHq#Aܮ!X`ߡv}ڽݻ]q ݱ ] _~m XЂdPH0ђ ЏEz:wX Px iٔ ̍&~gR}e gPgs(.}/Gp , CⰐ Ϡ CP H` p@ /p l0 O1"/) a%ܹ -|CCN ְ1߁ `  ܰ& =R @@@bj@= $ 3 ` #&j[ R!SNޟ*- 0*gA <.T;ˁCR! h3S] d-p!~#- }B@=RS7H -~@-@#`~@=^7!_@ /b*Iَ MCJΠ 3Գ?:) $KV,@~'1$"/ p j -8T`7Ґb - O  z:N7/ˁj zˀ߁i!@ݗv㜽@PxjЋ9J7Ҡ(Rt` (u~M1!s[ ќ. C@@ 7 ye!p` ['d@1XfEA8t S -^Ę"n I{&D85*X&ܬyИSΜÍnNNg4 7þG~ Ľ(;̑0Fgkn1GwhGRGt<IhD2I%b2J);($, 3 "<""HG_2U.U`󩅈__Z P 89&XfUЂ`5AvaE8BЄ'Da U NIYS +qLo7p59zP$qę1 {D%٢<,dxq1QJDjod ~FVD fh_"`Sc4!Gr$ 1LlXβRQYE yd5YN UVn".\׸EnrV*7d>-csFAa4]T?Z,eGJZeb}'.޾l-r~*cFj00I&apnrc M7 9/;5(-0Ul$lA#5.:DHa/PK34UGVTK䩮I-8og0149"[$ zi1A.pU;=h&1_gB70@ "MiaHџrLZ[Κ0溠T̉jZCʰVH{0Rl_(q%QZ[^LܰdOiޔɍd$ Y2ifAO4örs ebmEXt)v=k=wAS |FFn :&{(|/k6n)xxF-O߽m_ 4I֔T!fΔ8ͤg=ĉ_\N ji$mT2K`)}*,°Nxs W>ɍٳ"j\kNRK/[0f33|U\*B]OXyW| ZgaPw0*EM8It:Nk)̘E:vTǶ.*^m/ VG5+Cw8ݧ/aCE?flua|7x4ధ&^iW%2G[=^Ӛ@I Q<Ӑ N+>OY.Jˆ0DӀ OiA>0, i@ :$a?S  B0'  <;w!zxP4d "'*T # n%3@Ӑ_] ]A1 :2?'qi%y < \%j@ \Xp>=6 _JOCO2G=XþH`7/#,!s.]  = K ­CB3X9®ۚQ]Y&( 0D)udvtw CT?x4#{|)yj~-(@ ѯQlG Z$K[LA©J5,KC 8Fi.x H Ԛ"44  ;*GĠXi ԮSDIB~¢dʦtʧJ=;Gax:LX>u*9Nu  Ҡ ڂI~D^q:̎< $i DǵTZZD2˥@IK8Ԑ)ۤtL1ၘÈYJxyp\m lLY @f` G*TdNhNܠT -JD(ەhN 4|+ 4g(ɅDO&F聩 Pq…Oϑǽk$ A,x!$_ݕ<<Зl@>%*O uJM3"3#]L.H@ǐESH(%X*$<L;u,J*V)\鋂pLq6݋A@}yMX`&P y`2.) T3 P q PPY n1D"ӾD oRl>Ug)nPO!L 3)NȿK %\ʽhJUPq ,c02D80)Y &'L{F9;u=!exҠE)TǨϽ`ȂDPqZ[-@Ǜ A:S" *8m a6a7L,˜F P!Yj ϑ!j֛ڠ1ě*RA@ pS<*h7ꐪZ ]pxԔ@M#T2ڿHhܮmB,XLbݔqx| [X9%ZXҨŕh0)Ʈ9RҵaH0Q345 Ѐx 2AZZO%c[Me]Cݕke(lp̾Sͅ'm- ( m4teOP0d( FJʣ ?95k_f`9m^ D[%qO W݋$!팚}<$ с8Y ?.  X@IqD{_(,ā_ 48AXWַ(.`H־%y$(ŽȐ (y3'nQaLf䋒Ic VudaJq%ğ_ϾWGӑ@aI3đ3HWqP E}3]`QmI` ^e"!BBFP H 0EoG/xVu~X^A(VfC F$M&e@ hK" PcEVB$ AX$lބ'p9P3Cr2Dh}ӝ~pTzfFjܣVjv駠j*E݀Fep7X@y!5C`Fg`$vD8BJŌ  JCc25y_D~XT,Ajk0BQ % O}W{^bB D(ur=P?Lx}S\#A @ vI~Xq{4rIJ4PG-CX7q\w%=u*0)x$W tR(5<|Ux8]:'as_}$ELt<iK4U+ ޛ K\\By67:i2.qMNt7oc83Wo=C ׷ ~Tc\E T~F R7$$ݻBQ2(eQ1N 5BI (F` p tЁNxr!gB4 ze|9 bA-=͆@ "H8!JvFLF*Hd]SbBvEİ\0!H_$7-`ABQ3$tI *x"EuF|L @HHU!dH<=^OҷOu DGzR!FB 3bq#X@ Ij$$R<豕^ND/2qWIWPOYnLrU:k{\ٲy0Li!D95)s!$g`lhU5ɳTfx.Tc2tqІ:u A'ЈZ!/մbHB:)JK,H=I' :&~r&҄h;#8R2јK%B/v.fuBa!j*P` XUTthMZֶIhHֺDG 4װӮ5d"\BTc uIm@'^f=r3U!rH ܶbHi ӺV#MY_K5Ao|mE :FE룼i܅ %'EkBHQ7]14R< SBvt,b$ -f V0#؈d# D{;5_pK.'LaרpZ1 P !,rۑ k&heiه)rjg"*f@$i)pA9(Y"Ud)[H 9#o01WCxIyM3+"J D٧bXp7j0(JAV8=8VIsHem͛Ua m`zw2aeὓX,ۉmL‡Y%N!PoJp`RNL7m)\;q 4B~txCS$r$t,L:P 0fN+{oMROqVQ4TH Epb  ~Y-IXJEsrx%2?X 37kD~Q 1.b6nGUTdҌ lNқAf7?"ubѠ=J`ϗd˸ZÜ&UB`ןs;bWgܖu_5!rc.-8CɄ\ + fE('@nk2|t"JyZAz{QIU5p 6 RGM_b2~P14Tz q1xA|r-=g^RT>R[gwDMA|RH5V5Y!Q<?66*xA><-|k[ `!]( a|Ϧ„y!}e ha @rWHA=&؇ C<\Z 'r(F6Vp`$vX@uP{E mcrp0naQ,=,/ 5~jg޸(y/ A0Y"auA% 7rk6zQGuHx*-`!TSG AU „ !1n/f[JaĈ[ Y)-y0͇ 4i(YVSP=Vi!6]aHP}ON10/!dJ@hT hx ဪkEPϨ%Љ4iofوHFa!V ^!u2(RR8}|gz"q!A` ApN4xSJ$3m"PY 9d րR(F KN;i*'iц"1{9Il]y!T$*] |)d)H' vvE%O cIE<W"q U)XkS g)XXsMJ&P)6~ٔ(.ءc(ZCHvB/Ix)<j((%@11NM-qAQ 2QCp)@PG;N?zAh:(mY)}SVgGA/!! ar60(?P q`ݙpH`8P  ځ708L#2 1Y3pLA-*?Z1"%@$t7* Zy [ I BvXw!Uk4i@ԥ#:oE̘6Dc(L$Aq)^'R<|=;b%6* :?#9jG+Oر |p+GQhq([P~8A\56"@q7[nԸ K:qF0rhSá]b Х*RF1MQ_7-a_$ * q^Qz}eCEr{۸\gk1PS[? 4` y,3rN *$H(=xA DqK (5] 4:,{BJ^;O1J~C(5q}171Qy%k`n1a~"ɽ72@d>ӰnUF5 ` tEP5B[|d-`LN*$'t{ei{<'$Qa '<H]*s:)p]$wHQ Uᐷ! 2 KVch-Gnx* d@+ A -@B,a3av;5v:}Z-k5M/  X@HxcG*;l<֋V])}ر]Dmjxc!Mgݧ"M1 qjDK\1 ߉a%5K!25A!rr~2c< = ?SWMwXSq7mn(B`11q'߾D#콤4/E-PR-@=5(_\}G)I{1BђFO7PQ=kJ7A^"!Rs!c#nJf^C)_&-vOOO@ DPB >,8D-^ĘQF=~ qAȁp!ReB? SL5mę!: ԉ@PPT҃*4TT xC- 2fI}6,Ӥjn]W\00 V_Pэ؁ J?Y' C8hHY5C,]Y [n޽}SoōG\r͝?<tϨ_~ٽ .RRi f.޲cYK2o5"p{, \ 0CK,(>҉ 2ej0 gѸJ Y@.*8(,2:p)'{F)(2K-mG.|J0kDq̘4s s2͛GI2t9<,hѤKBT ( DwSCȬCb=l gO#h`B kզt!T h "6cRq*B1 eݸU蓅xuTpfzlL@_B "E v:lje:JW@d[ ǠZ=a©>)nK(d^*YW %hBZ@$@ݫM:PsG!RJ5(2X^PV8ߴhF5Q)$!E)e%-MiL#HPDʓJAӜ))izn6P3T#BJ'CH9I?Z*9PHU´8jaVƥh[aU9y}Vկl`;XְElbX6ֱld%;YVֲlf5+.nֳ䵧[.%R%X1mB:+iV>9LHl2Ng mmP*!z$?i QTA TXC#dS[K7$J@ Uer@aQ7~uPuT_c#/OyR݂s@-'s7DM?nn#-n(fH}y ? %zMqyEB n. @Ļ@ xA6z?-e? @`oO1~Gf#G00fy@co ;'HA)b>]`P 7@7=fH{p6 qCP: CЈ8̡=rxC&P}&&@#zE#gb aYH:3:qdIBq F:򑐌!B#HFrЅ0A^r1Z>/`nl$ GA~R؇? Yf9t iQ$ mfe_c=AȰ!Pz: fs%=Lzģ:rlR(;ѱPcG8O~ӠԧKP&>lRt&.f HMC59}XcL9uA>܉2ē{VdcG'A8p7r<#q C m)txC&Ua"h&7A֜,1Nzc 0[a}$ejYFCpT?>I>Üaa~գ=1Kd1ixFd)^!Ex8 !B/6ٌrܧ4}ţ8|aNT|T ,ކt3Z~E!F> \ⴵ2dazB:J]nb#6n I_q\9Yxbw9O >F,CG7Jq)A ӃJe.>ZnP:1TCrXp8diZ7n]G?4(p!hB D*ǥ׏ ji?CAC&fs2qX0~#dfx°F2>2"ɖ=hB*$(iPiE4Jn{x$!s@2F Xfu(9z7_B3o}jQa W6 Lz#ozҸ E29za}SÝxtHkjcjG{˲[4^= ]9>H7]G+y7A/ [3q߂l}7{10- 10|p@̷aiWN֠2jWy7 Xz` ` ]P Hܥ:-`W ;'. $Y2D7` ' .Ȁ+ 0` @HS  Ox+7 PHpp}@ʰ]k z@{g W Xt(`p~ ~p %Xz0 Ph ( G7 |(y+C°xݳtHz ! Jxĸ2B 1 7@pϧl 0[PC Ґzхwp Š ܰs]@ (z<~ BP } J e5y+`% ~$h |pl{ # Azo+j7]0a SϰxX 2Ҡ*8@ # <:Yz8C{ Ҁd 0cɊpw`@ ݃Y:MF(G NMIzg T Dx#xH/ n9? x `~ + pS范"~G7yI⌓ɛ*HUXz |@H w$ȃ 5"zC - Bpj( ~ R-p'+<>'.(l͈~ { AIz9 `f#  i=) IpG( (z`-N ISRz7)h@j'  a|Рr0')Z\ڥw)?#+{+ӡH|gZ?5Ypxlqi*y8^Z{Wu禦n}ċrj3sj;y4{J`ݓy:ptP8d7;pzt" O#z"" xǏ*a@1:v67"q7SfA;@C" SO|%2k1 aj=b'I-'9 aa#=:9  "1=;16";$[&{(;*j1-#S!2ࣳ?z7sF{HJL۴"NRk,SMR5aB\`b"j0fP{j#k$X 87Cxz|;)۷e;{# !")൒ !{!!{qB[{*XB# |c K(+9 &s;țʻ'GмÑbrЛ(1# ڛ e[0 "TA [ ۼT*Ek!K)K-1=@ k%^2#[&3 ' -$\&|(* 0+w'WzBC+@:<>@Qo77,ĕA)N'DR ,]0Ʀ"i\4AȌ<*жqQ."0P<ʤ\ʦ|ʖa4(r2\YL+#ʕB: (L)O!˕QLȜ̃{ ²2t Ya|W Zy|<\!{\`Ħ̼"©R<в6( :HH5E2#,}uQ: ҕ1M1"-EIM"<:9"a`?:Fʱ { 惯*#s@ ;}ϱL"! ,9 H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜIAɳϟ@T ѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(h& 6F(Vhfv ($h(,0(4h8<#~(dR< $#0Hx``?`Xf\Z,@!r ?LH?]i?0P2 ?& ҸI?ք睔V?(O )# v)DQb@X$ @t2)HcT2fV5YA/5@fKг\,MpUK-fd.>mA:,,pν֛ plp/> WL  ˍ8 glr(c'7X>#t?h>f}e!xwO<~]mM,$Gn=XSNҐ6ے.zk[#M8fcM8icXwߞ?4ZwHѯj=ć]pCT4`6t,C0ؤd#s! pr`78υO}08PQ4zj2S[2X$#*Ex&^Eps8fx+]踴/ n<F2`ɶF .0;\~.C9`aq0B4xkX9a ]A֐D<<>Q8,~A}h2v~tA܀ `` Ewm pwyVրq&o prwRB7('m#` V{tP@p} `tƶ w~ p L o,m`~p` w @& ppwҐowLxԀ@尃dn`nݢn# 7zfP`y@wBg ᐀&% ~"D+(Rw֖nyVP1@@sSH{lP%tynJw KHp }PP'P0qwҁ2@@{>rwqbȌ6to ְ'f,vm}pfmwVx$ tvqXJ h:dpst@}AxJ'E~ x&  7}x7+THpvʀK~ pm@ V1 rd ␄7mZX~vBpqP q(*(92,֐u +4tƧlk T{mL^A Z$Ķ䚵wD́ԌaZ7'Y)y:VToMNd 蠖BFv47kqFgBSF  cSE7D5tB*\Q6f0(P8]-wWQCcH a1P)q!'AkEeD|\yO K'[ nnQr㐗rNDnBc.E'*Y D%5yy^(XS]@I?@$ '`GL|(S;Q47)V)qCwYCJ D}/I~O-AToZyu r $ \qp J'hiE p/"Jzee"ZUp],5:1@~QA-,ˆԠ7MdiGgZB@¬ҳ ȐCߙ~:pTI"9<|314: ƆAWH HHYb!E:򑐴H̸k(M&!ۤ&(9F^ E\D,p!^ xQ2I-$\^RB?P@!<`ʋf9*5+ k\H1Z4S4MtRk!aB#tѤ/̀#U\BZv#g8ziUD?+y ()=(o /%%IG*b=XhFb"|hfK hRO^DԪOHVծ"HW:P. c (>OLi ." U$:Dq%* 'XkHpV85Eu|Hrֆdq"h5EhDZxIEjBmD:ӈI pKAꄸMr.gH(ȸZyh !,zİ iͭBĜ r2q 粛;,a@VY[.Rt [F޼0CbG7JXo bQ*aW,pdXf +Ny55B!.#bIFk'*جl"WKeny&$,Tce4&Fd8 \ mt >] 1A4BdM5 QiR##tgI.mO)BZ%1A=ICKk ,bqz#N][:zp"ɶ$#b@Lknm&-'kDJ I6 %`B\@.okXG!toꭐeaT%ImaDP D,8 9xVXB FD8|@9҂B{S^pMAT@vl6\o1~(&(eR2lNs gs PTv'POl0!" {LDHeĻb|jN  4g\#~% *^r(&n|j"/s{j@SR$p6~ &5dZ8U <JBsIuz,X.j.o$z W>1}pP|/dZq5&1$ *1|A+3bxCSGY^' BU΀O_x{<90l ou3lH؄ !zG`'@ XQby  Ąх(! Ps `EYogG"ptX/[x ;`X` 8&H1m DŽVsM=@2t8 хFjE! gG&qHp[ aa _p8"7B']Fv(S88oe:sO *!H G R6` NP,: eqqIX`l`6Qh:!N-So_!!'<Xs"QD8 QUxq8 ђNXF-3"_vU1p55ʀ)A8LXVa a 2$j 'Wa9*q~e!u/ ~'1&1`yJA &01Wߊ>-ID_XA-7?V 7='.bZ@u4p9*&P)1Q_$a1`I+)$hTOiM$8\tw1A<(sBzĩqqhOA 1 : ѷCۚ*У2qb"T "А  P1}C[0ѵ a U ^K8! 4 qV QБؤ"kIJ*[++pCʠ"p1PjQBԾ0*|F΀b0l50 q j4[r΀ 8aA@ #7N*]$aI;D @C#tQ qZ" SQ/c+lA_?e?<Rnj( ,7@GOCq ѮNJl ^:`(u zǣ (107(|4cGlA% a: .*7 13b|/"$^:5{rϬ149],8s7L9 =b_K^" o}hXvKmȢNUo뒉DEZә4-0*<‡9M0.CR$i|\&K7 \u rCAw|!x4DlFw@R(1Ft!tnH̞[a C#np8QHT!UL7Π(J] bE`y´ HX@j}T7Aϓ2Ղ рqb F*`"[x<{s/̃hq\v1- )FSV#&}1QwV/[" %,'%aW]@k0 8U jsQj== +q `}-׃^ᕫgg*I7!fa = , ɝ()9@Ya ;?' Zz0B}P>* "pc`Ca=@ ~ Q5)AКU 1AD u. fm9<( D1 1L{0LHɁ!Z>|r9;4!&cT̀R>( `]?NWf{Q-E<4C9qȲ)˲aN8`yW+_$1Kp 3~! x~+aZ$.!i?l-dR׃47P#?!9_rـ*Q/VFQعH%`G Z$* "U,&%Rܔ@#UGQQBW\e ɐ ]^G4SrBeqNٗOǯ?UߏHڝ8zr1VO@ DPB >AF pPMH%MDReI$+]SL5my{*̘B΄FT@X~.m(dvBŚUV] z 1(A Q`X`e'uoMe;`FeY$4u<*.l*v['[: 4/)BX Pp7ѭi;wiTbGšp* x\Щ__|zoݽ^x͟G^z?|/d Ǐ\5Px J3_tZ2Ds/,HT:+ ;>pEEHCPp* cf,׸AI'1ѠǂAR~ .r,1~4!H03Ëa( @&/#"@C!*8;+3DBJf$i"LđNڳ.N"hTUWe5dHk5VYg5# V]wWºSzC_EvH67 3?*5)["W .WPRp dQ HQ7<* 0\]NU VARHm_Ō%c! ?k/'Vf箒U $IRK߁$*vX!QKEGnP9ehVj9)+ &r俐 6(,6Z:=%ne[Ѓ=/NmhadcaX^; gP!0VhkZh m5iPr^]eo=wwwߩd[ۋGNJ=>y矇" zb]Ȣ| d8EώAǩ[> wH|m ;td1ZN~Ăt!tى<$Kc(oy&q I@$'KCNQ2LÁ! k%絏GDbD&6щO"^C&Y)ΉzP Rv,1$ س Bd$b|ֲ*#:P#l֣9,yP p,$>HĨ8ztP$$:BH I:E)r<+e\`h 9*59B?VKnQL^ LăI])PTˬ(X.D3(`z)qvd\8URsӝgX$\LqA%DOw >G?E0.8 4k`PZИ G`%;[=)G`7A#)[2&7'?Ay{KT $& ۊTax!' np@ܰ'D 'ٲ kBC۲0 3€@B@î’(۠-nBx(< "}C[D8 ((ď0QNdVtWXYZ[\]^_`a$b4FcTed,A n!gCFT\ S"Bˉ8dƘPi œr32dž;@ !I8vY0 (-¸~L 87>| x0l2@T`.x `{t 0HP= [OtLi!F+?-ԙHk t0IpFǧH,)8J\a &wA6X˂hALɷ30˒K!D “05Wj+d "x iT ;j!ȄlpI;M{ hԊUIa@IԳ `̃  ȓl\K.Fa5h8ɓ(S\ɲ˗0cʜI͕oɳϟ-JѣH*]PEQqիXjuxUfӪ]uR $qCn g߽ vH_daKaVVF!> Pi}S>ͺuۋ]vǃͻqH1KF^T@,iU92سKl]4C!I#=_g>`L tɦ5Tw_'`V SD\r5Q$9)\7AX*5GoEkqD-4DB1:?H t$xZNpxZ0(tHG# A$.T/ %LJF@ƖhT\BFPiƹ)KVL4n%ݝVEO!(Sv>*餔V `ZR~Q~0@-gY!ƆvO*t@8#N2O|X@'~T$!5y5r#N97X,"Gzik"E@D~@Ht4p n@1 ŕ{#7PpK91MxUnDH)P p3B4U4+PkN!3M~X5ktd0TY6Ps`s cdKzoc14jt_g$cM20+whn0l0*0L{Y g9;'sXKv$6󷥨ãCaɂzU:t'7ԷSճQc|@gX3H{HԚ )CO%˹BD;O8Zu/π;L(A\F6* 7AAd @(f!! W ɂDQ T@@ @!H;"A(a`.8n!GȚ.DrQKt@ыE e=hE^t#>rh~\_ p4?H@x%qQv@.ē|; ĎaBI3< XI;̥.wX 0+B5 1@ŖFR#1B4AE@I)A>l+5bInR3νxs팧~JZ%BĞaDeR TTUpPM Hđ.$5QTҖEtLK2󟐜)V `өPe:s/fF Ԧ:PTRu|R)j*ZIxb Ba ހVIn=Q]]URNJYUH&Z~aeHN2NBXvBcCR*_B2Qe R]E$P@zņAgޤ,:pR&<e !$0G?]E$^$, .8jH#䵬z^ V|l|KM3RQX5-Hc9vbAsi J 'Fԡ$+h/filQtB &'~ &( 戀-rL!iSl_3Ay!ys35&î]2dDG\%cЁ"\/WX@66EFAz΀ǃ۩0-9K8 T!;4 N@i&yZqt..+B?AR54#G!9V]pp#@!x @` 8m`:aqZm؃)@Cw2Hdnc+͔]#ŧ^-; _~ջ/p\nF0/%}C*b\Rmq gN YMqWwIe g\L5D9C $VK̝*1)ȊՃIymz$RKAF[o \nC<'u@\"-F5KQ)[>vJ3t!kӹr$xzAV>$9O8zy(}XhF_sMC8>f;WI콓`Ͼ  ߽f$D;U` NQ`7B[ |RG"Q.] DK?STwDq{w}\)$(H rfjo.bWM43ry!:>v'69h9(1cA@w~!]cG~JL؄N|Ox@GFOt#VQ P G=D dE1+X߯PKY v0ٷaݻxkV@l!l;7O`I*8?nCJF^L܊B +!,270װ~ɚ#"[ؖMN6-GμNسkνwc:(,ӫ˟O:,J ǟϿ= ͅfF A Mb(BxB>$Q t4RW- [JxxP @kH !bNeDn$cG%yѐEjH5) I唿1y.`)&f%U@pA:~T2@ MY#:-PVJP8WDiCw!J~+ X 4i)"@]F`)Z,15j@O"9xljG72۳fXS\?eH4|Jzko`?PsNPwD I#l(|~2 #$`o)Om{9w9%C.FW@P D@2L5&`vu.PH \mXc5p#?0-7[gA7H *9߰pY(=fMQӤ-RE*H#lg4t8Kk]:-E Q3K8ҜWew[zOFXCiuM ԅ.\E Quu % pvc^N] Y]B-С: ~TDW3Tj[5ق.]'H4{XyR@ z ~p(^ Iv#H3e8\0] sVM!ء(*CW qy.Jn! q'z H rE(hLX6V )]tH:c:+r6k?xӟ"@N QAAf0 $H3a-ϒR*#4PLS VX1,g[m\EZPr)$>9AXC$\fu 0"ZdI3t MFԤZ'. :v<8#8&=,&3 Hnς ?CF-2QD #9F R:@4(Q$‰a6cRulB!|'ioW0Tt)Nwڔ>oPѡx1 d"DSEtZG[2#ԈUª b(Sġ"BnԫӑH42b%[W &k*/LL{@nز(hNde]q3a2BKBf;t$4+b'H6%-XZK @ub݈w-r7BoA fV!I7I{.ې ^|YXMGЈ5ıp@G` FyFna{`Ԏ$$ݕ>IaAX왅0n @ְ5"M("~.lnjZbHr[R ,+G$\65|cǒK6)(#šc-|憤s#ɴߢe\$B#('qAd3lgRB$+: Y4n0Yt:)u[l);HOu+!"Ba6岣Mj[۝= >fهzjF\صUɭdHd5$$Qg\ =({o =~́C( ĪspH aXR_m 'bNq\Dx8q-ÙID@ЇN!I=Σd@YϾ+s#KX4C{ϻL"4}J,f*|@w1|@p1Te` .wXd %u~Qau%aaA?b|@z Af>!{$1~PyWb:X0(rl <`O*i!x$ 86~%q_ {xW%u}w6ׅ`b(F݇F&4t#p) ugȆAowpx}(`F!H@V =30.|9QS_w1T2 @P" xX6J$n,f3ᆨt#*PЀ@рHU%\o#*AI. p&z:8B$R©hzgګ.ykd骢SѧFtp њ v0IބrC0#!XBBPpͪ|#VH|Źz(uf0h)@a!wPq-1{p C~jzFBb29-#0[1 ( 1I5 (b0c%:)d=jT%z&1%jTD*੃c(pkhz% *nhsĂ~|@ GP06?kİ$ {& -l{L°PQ;4VNVq L;#BPh yKc'Ew B mKРk  Ӟ0сVj4^|᰺%#DY+qx 1YK4a(qf%Y1ȃk.#`Fa7[:K"P"aPE:*dVqLX<K,.4mC e3QSCSHj\cp1(I=Q?򿗋A&GyjrkXL$AѾ)s*I'L>t|E^ Y%<P!3vO1M04`oH"p,rY,8rF03JURC\H!P:)uol^d/])J;$!(kG`Bִ53R cUZ' 8=u]+ r(\{aj>ǀ AkW1!QkZA{US' ] 8mЙTbܮMs]6.$j:XF(GS\dOf!Baˣ$u:Y"H0ɄVN-@ QP pSg?N&_0^A"qw-T~^~븞뺾ͭ#v(-!ks3O*(}((ռ7(,ބ1o7]$Q=q7nw AQq!-0EdGŨ1g0Q}`r-9]7IQ! J 5A"9VpQ@B)b.!ki!qq^6bpHj0<ﶷ1x*a*Hu b0F! , N HJ#Ç#JHŋ3jȱFCIɓHCɲ˗0c$"L6ɳgGk> J(L7IӢ[>JUܒ^Ո ֯, ٳh lr{݉P˷_*${Px #̸ǐ/*`*k̹ϠCMӨS^Zdְc˞]5۸s.g Gle󐼹})cνËOӇo] 'LoX}gP'Y`AX ǂM]ᅫv ($h$‚,N$K(</4樣Ib 'H&@6)PFONiXFYYvI#7P^^i ! y N3#!jii5̑zvU-RbY2E@IAأ/%] KU~e eD L(L|z7LZMJ$bhA͠O Ӡ[u٦qH1/J-r|իR  + X3<cXA3HiC:#L9q8X5 7bɿqE*<(;W_ a 4 SQƌϒF7sm-$ts8}:ܞ/ljuZ>mhlp-tmx|߀.nc8B0%]ẽ_g/`n5VcDM nQB ""VOtG/WogvYӠ7w?,ߚE a|e>Fqcz[Pgϐtj={<(y~%L:4xxD'JъΓФE3Эs_ ,GOwOdw'Ӛ8)?S=ō5zҠ g X3s::PI.@lvOJi g!L_d %4d af Sd=1P7[`P `K-.Mb:d'KZͬf7z hGKZQ*jHq9+l"#ŤͭnwhHoZ8k_Ir"! , N HZÇ#JHŋ3jȱCIɓ!CƸ@3kP?҇O_`_k$'IJZg&7Ɋ,CRCIRL*2U IT b5ҲJZ-ԯ] 0Ib(E3f&eh Y#TQFӼ6nz@b! N":aԌlGFׁz )='JѥI ]XPZ8+Jc/"uS@ PJz: R# ĚKNЁjG Vծv2TiAA#Xc8`!# jPax!XѰWMb:d'KZͬf7z hGKҚMjWX0\|m_jE2i=as pK\A)c m r RBEhsB ! , {@ H*\ȰÇ#JHŋ3jȱǏ ) 0(S ʗ0cʜI͛8s3ˏz Jѣ ITiN?9Jիpkq%#MrXӂV0̿`K]Z 44Cpx0sCu}װǐ*h?55ܠ.?GMPpq'zk+OEVP*Yxwo.e$KA D o}E2GcAWI93?ɜ9  yEa4_5 C%@."A 38j@Sd~Hq`P BS+/хnC:"[pʽ>\DaqKF2d-${FdjCi_HeAB܋!B?B&VyBCų"اa=u_uwfd~!CYyUY@,$(E: JDDnp2J+S%V22Ҁfrv^|2E>@@U,9"%tߍI\W#4c5 ҅ifvE{IE!,C6v@_ DSƌ ]O09 1$`DWP$U)Dr0Y3cJSt7NMrOxSĉ?ek +*`Ä<^C($SKhcn$k(‡,vB3Rf7*E> ףYUիDWȕ/]0Z:eiJZ:ZZMbV hĮBF2 J$qgE>?!ѐlrTܑutl# cEI/ nI./ E3Z Dy rވtS{Kj05@U+l!tKMﲶd# SA2%L-C*>us'roR1)(WLc$B\,j!@ȏLd o&_-Lf_%e&tJy:Um<!א72L̶4#.KV@>p^rJ"$TTg'FdNg ,3G2a35M{Ӳ1d9iP&XV"c-}<."qd'mf=LDEBLP+hhy0RL€d&@H "bcqBD!-2_Z`sLO &PL@#d{6C? x 1_B$9Ґ@@0' B2҇z+!LE5ބB&@#ONr uz%F˲R !䔷$#-@5B4W apX A (gsLwD NZ3OD)$ "Z!ReL _QC𐏼#c3y,@,=  6*Pg%4LŪ &7 mFj& +hYVf4.YD(;ؑrEx(Y;1p^mSI-9/)1fy5)yze59/-e+:-9)/ yXC(~J%xȔew+܀RYfqNIH &A0T!'ZH,_cyVQAK)Gs|#b;1iB@`sQil2 FCYH!ĕzt%X'p4[=I8OCm# V Sj'j` +D0Cq #I ev:"5S YAi0!(y1G%& !]!~ЃLyy;s$dÀu1 P$f8“VurqQzcj8qc4*<+aiJq*؈VIQIظNpH` 5i^"ZtW}RzdB1By:q:fHd:r#-r]-xKzQz @r{9DiQ=Ht)R) >0X܀ Etm*u6sB :@sQ|q"q p%pA}TA.aPk QU:Ϥ8 Ҁ*6]Mqa% dIѪ(C(A! |;A7 b1_MZ;7pl-a "a ܀h@cN*x*Xz;{4Ű=Mw+:jsq%-Ks "@pѦ5 󵠦0Q @ ![
EQ4i1 ziҴqG ~0'1  {B r)FxB9!A:2z[p&P1+(n CzJ:$ZmTGgY]1?`61da qJ$.B эFT!2A7H' AD  Zk]\$+  amӂB!V1811#3cQ|r8=sx;6A XM eYJa[]!fm#k e;RGO:A[ɀPϡ 1G;'l&[%I+_8֑: WL`e ZҀ T c<B|'*t FPP .C ؐa0?# -O5=<7Uk#.?<+P03-` :Z~`([]]0%ҏ{%P>V~aj ý#US%q_]X| =a}IstTBP!'KC[n/%wA)%DWB%H|8 P5%R4O:.KƜG!F VS̫K% q0%%鵄A $"'3A@]XFn*'*rz+!*Af҆QG!fԡZҨ?ݺ\5nP%X c1x(`m1!Qe 3E9 2V8 R-"Z|!}>y@Q3s};BAAW\zk-0+$ n:6_:'@ a0'xݸEt%SNGK ?0gW<+.tO;<$VM]rHSG?a>`='0lj8dH!5:~!m㱠v9u.cSp|Ow4D~_ 袅8,sŌp+qRmc 1]JɰsJ@DPB >QD-^ĘQF=~RH%Mh(3$L5męSNThI (n(i Bk7~U@)!(B@~@J 2=hE܅I6-ݓjA^\>IKpDnm^0r -'r# pJqd7FT.KV*!k%(!*- `ё`XJFg 6K|\:ɧ&oIyf)'LRW%?Q c !e1N"*B贃ñX!:;BZ!>D10k ¶8qFwG2H!$H# 28Cʹ>GK/J/" H%ʌ( >.㤳΅zP>`𶁪kΑ QQGb"RKD( Jp.l8 }tCЬ-HS 1kԹ1"Ot8U2ZWs6S% UڂT#n7\q%\sE7]uy!- kŕp]7_.=\PV_I*R#S`/A$(ざ`/A Kdc"`R"Rf^;KheP @it$`iN|j񟯥ziULAx`;;'n * n(G<"5'Ѕ"͂HB HCJn.;^$8`5(:nP:c^=8x ?(p"q?7!]F`qGÑ[=[ۤ( B<$A M {x*0!˒@ XVj7kG-J c4I 7/=f!j!?p܎~!I"! O'ˈ?'e3F'29R!d@XPG6чU`Rx2s⡌r|HB^D])#TE1dDHTq x0AJ4- !$_*rB? *DY@:2 q?Ј3tVr"t1ɣ RB Jp!(Bv n,^DjV={::XTɮOZ:acbQ"!H3 x-tχ`8O}%C;C+CE.@VePIe=p-:5$ᆥx$YCT!S@T8LMv(IRL)@._ BB7@b ŏ|\O"olM|6Bs7yus?zЅ>tϜEGzҕ.KGQ:\'݋չIKSMV`]h&3r{ T [#:[D 麓q}gH$ c訊t \Gzt HQFv Eq9i RYDI3Kd!&IüC~$`~RC*)zT,'=O@ބ#[P$N7%Rxp"\-|_A9==oȨ!5~&w pZ+< ؒ1@(R))y:H-8 d,q1˖wQ C(<*>7È=`r Hah>"0! Ú(ÎØ1XC, P6uB! , }C H`*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI!1jɳϕi0 |၃D~$pSXjʵ1^$طpDfᅄ քCr2 cg'vILe骊Rg*=l% he^!f7?( <3ȓ1Wߣf馜vJԥ EYy4}ieB㫴֪e;^# so\ Gp1CP7jA>NWEkd#BR4#Q@( Tb5M_lIoK99݅,,DHxP%\S^3&P[P(Q\t~Ȼe( ,N;P6I'BhGP_/p#D D"ȹ ʐ_$+,-cm7I|rx" c֟p@ %A=R :#imc{p@l)}M>Nˮйu5Bo*B;E.(?I<#D&Hm  t*P /Z <H Z0ij̊]4X dCBFdKX]1M AUx.Oš+)` 1 +&URư! +RB8P ( Vs4!H1 Z!1 yT`$Q:H:q@ {' XCR0;!p"@og֞ .Ѧd%xIx_6 Ҿ!@aFPJ"F:aNl05XcX!1sjPJA@01.B gF1]YC2وEXw"qԈ$",c" RM$H#UN:, @8  FEJ@_HSe pm JPMB #r4Y WGeeͩjT ,`qB(5aA 7CXH2LR_uСD9fc-oa:n aQp#l! Q[h5z^5`Ɨ*PiSo )Qy@ } n(07 i~NeYoVC$|En7i'\ }~oKIy!cL4fZRcn":Cptj H c dp@xc08 8"xj h+&xfE4GGrlЃ>@B8DXFxC!7XL(w&cP0yX`_(`@a؆n hU 0YoM8/)r`zp? HH CC؇8Q?GEAU=<ȅЃ( WăҰ Hy  f` > W\h = Ș׸e `e锥rׁ+s6 i|1 ] EO(8/ `Q=:&J #@  \qp` `` `r <A @>if- eP r)0x1YV )vR lA vDT ` @ҐDְ thɠ T` Ft (pɀ^*qqK#o"qdh(*aS񊗸|ڧFh (  =u)  ਏ*jF ꨕ*FU * ` ` :0kJ6)j*s _z*¡u>zzy!u'  @|ízXO hSN٦ 0 ({! = wZ. 7A.R !Hm. ȉ)K8$Xa er; &G: s` LrX떳 ! E^~ NKq֍"$>&^(~*,W+@<#vΩBKL,d !(㞝JLt4^M>T^Jn_ʁ.Ҝ aǛdWt^Tx <Q! yrAly;qF !nD71Arl˷`zSoG`-,SPS d>_#\^&@NAB A/=LRq.S~گQװnwt쫉잮l'P\ 1SNQ.@dXv:cl#5SNu]&^2̸t. D_3;6n/!ګ!J~E `y m2YA;Y~(Mp#2Pc #elt$a 1|-0=a .t +yPqOa!d@H# + 0 q JAYЃIA@##\s-_Ygx'PA%PCPEaFP/,dr3LJ?5T#>(4 U_  qV[Dq Q}:k!:6(U# ejz@.'ʔg1`hOGEGkiRfaךg¹5_-F&eHgRgX%X #WG ir8Z?tx.Uu f?H!,޼ȚdĘ":pN\eznbXYz԰g:S_U1y(JD8$bpԐ)}QY0nV{ : oN٩h.N<` | geE.2^GIƟxtuiqt|ukߧƚ!2d 2*X󟑏o He,p6dTAǯ> [(Pq t$ H Y'0 ,,ACN2}i; |>(`[.EB DUzFHG![E7PL!Ѕ"] `d6ee-VX |3"k؂ȍoc8G@ n,^He4?.@T L0XڤFѓ57>`|d(9Jh+!,,7ʨr CnL )X[*cH*"""DXȺଅ$!`4f@bUA |#/lfF &ԑ! mGh584Q'T4/وшnsbf h t%/md' 𒖾;NiTk464S*SD<ɪSU9+1ҁuይiQ8RʇT \I(\?"؁vH_X6ֱjdXWV֟@"W/=@>p]=' qĀ:APS-A1xHbW j" CC nE_Xb IX "5pa`]!}i'LR]A~.F!Cr\+Iּxֲ){ )'C4tz0V΍o#Gp@FFankf7|]d HuUJ ָkl} vAhƈSF]$'!b辱px,X2` 8Hy$ܐp"}lFeE`M#:0 ^? ! ›XgUr. ah! e Y!v4PC9/" wHG2< 6H¦w72ۅQRm$0_ a5<aGۮ0/;KH#aх`8ƭWPlz#|! #ݕ"OP-2?P%u5},CE](ǔ+0uZċ%0NDp<,Q @n@E 83K-FЅWp=7F2=e-0J;C@wq*vtp5< YuL.AiX\ Kr '3_&8D!4ITyʬtH$ p 8}@{X tP?)az(DCM~-8<(4/(h""x" L.HТ@LaС<0ѽX_!U'=:>$~(ruRnzq?yq]ek 3!Q82Q } LNheo0  ."  W!qxAxh]@Rz0 R9v/Y] S̍NLЅ!3S๋_>͙UìD 8aN`7d;NNP΁8V!Yѷ)Q z{eHRC@xZwL~P8Wx_IB#Vp4U-NS]݋hXq!Y"W}XàKT@0`̋QXH8$]DxcRx_ Crh8$ \AoEZ;]IYL,(PpV\ ܋^ʂnPDhOm ][Zۋ?Ca_‘_mpp1] u BȚ~bZѕ`2 ;S0 _ACPapBË`@] r$ L~R-1 2x,uE{Gݷ Z rC0(X5=^f:` YXckp֋MkbV lXT6~BQXp]3~=RT@Rvi)CKhnJn`"hJ)ؿp"h⟿f(t aܒ肓n# i`+3Yw@_+c0H#_9A%N;Dd_zcKk}HXan,i]p]SS!kQS  fZHXK[ml-۬b1e쑱ml]D}ņ]fx mϺ N~/<DJR}䡒JVL4qXvdymF(neno&![iE`}YK Fe ϓNm(n^~e`psy4) P$ ОS3篂cI:`: :j*֬Zr ǿ?\@(.lמ}q53Y3X葱ɞf[K'S(NQ(W9kܣtDUϪWnİc`Cu D}!C`ǾOWGC:qgOWs[ОMi-k& o>~ OPPIERE]Y?t$a9tO?#L݉(MN)SXO'xmPd8cP3zgCX$I&Y'BBW EFA7Xރ?(#X<#IqO9#L#R8dTS dMAaD%c'd IU:b5I!pmG K?谴GLCR<3)3B!DpU EBO}v@iAd7tU ?bMJ;-DG--3 Db;V4){X9ng{dr_o^5|0XfzR!DOrL_0[enDZM2L.]<47|LpO8VV,JZ˫-#͎L4\U-D-]5~\]-QKIԌXL4 EGpL9Av:#GÍ5$LDy$0^b{ʕ eK#Tp3v֞ETA޶E^Z=铝c5ҘD9xK\,fCBG%KjSZTՋ.]lQ*Xԟ *Gn^@ՑZnY_K:lD @Z* QC|wI RVn4lTPr6PVHcR$7@:#8!pؙ4a%g40"g(S€'A(҅F~Z}JU6<4J+#k=aPI>ވ4$.e%m tG'7n 2!!<9*Җ@^ p*0DVW*x/4HwAh}lƶYt!m_Ų~hwG+ɽM$^Iep36N7U< CG2v!M AD ,{P%cha&l6t/&*7f8 `F9eIJ,sBڭY+ʜNT,eӷ=MJ [O[w(8 2f4_U, t#F6ˡ<#;5lGяհqdv_\8M>գ_8]m!,BM#*\e'<RYo*|^wjN뙎;^XRAƱk4@clXY/"9s._YxVpV+j8'zUj*t"-MdD@G=cSpc?~<l&]ΜX:x?{?RC6Dz;3= C] f%qJmh%[j8n|9OƋW.*D'"EN"Kp$k$6D`Kre WgጝҐFbkzCE2TInBKh: i .@nTǵy'hB$R4ɕO! }MH-INēA(@8PB G2d=$cHC8X:884D*?$^?0R9ԍuLP=lěU](/`[AĎ\AP`լ^C|XTGpuE$e!G3H`9@FQ W"P9D rG4O_)Bک?UNĻQYנo8DTP\=` Jw$44l5 (ZC8L4(0 LRUa_yFU[Oފ L."T-T /R!lb!5JKIPRn\FD?l>|=GC:~3`੔C9::n۾D3D #tʐF}BğUC (D `!GfUw<]GqߥތJLIؑϨ gN&\OTEEQeOO6%TV LΝܴXCdMv?DMTzF C~}B la @GHXDI)FH`HЃ8dFpI͹i%Mx^DTAA'8S1P!V<%YF/TE ȤPTJ7N/[/  'bҬ= 8` %aw8AOBj>3E?0" e* dNDH!D@D TU?( r:= 4C8tlL30nZ4D#K@D^r?x$kPp[@%@"EE , 7D' H(V!G5'x4_4Ct$9HGn"g5@Z|VVPEStv(ܼcIEB {ݚAHb VXɐkrECdS2J#ƫ&EH@ lA?pP.VH==(=Fl>@.%)ЬWkWp+DDZRU]PPA 0bX8B Z 3&qK^/H?7("Ja]8x`1!H,,Ē!98 =Cp{I#&HCJG~U1J,M>gTbmmDpC PY@`A&Tp`27E8bE1fԨQF1*9?&y@YeK/aƔ9fMZ 3{`d3iXl7,F:*CָY7$iW__&.m[oVĩO X=#`f@zZd褭O,p$QA0|y֩qֽܺ px " $1D Gtb9!p/ݬk>C|$'z|œz@_8Z8M#U(IBKLPA}:zP6*ze; ƟxtG2 pt_4F3zHb$'逜~(~@` (C +zTN4EneAgEzN2OѢ 3ʑ’$ %TIoi!CQ |9cix[*X FG3;jf(S#:D|':6bXvZkU h6!?­tˁ*^8+NaPVI.\k2ʖHy7UIfVn5Ԁ]5`ei#]kpĚݒ-a®)qE^X8fW1?tC^}/ Z@r?&_N"?"BLis#G<B.'H\F#UA"BiZr$:A_Fd|Q>-u="PD$jI4(n=Wd(? PF( u8H3E&`@G8 icE C `P pH~ڤhpCo| "x Bޢ`c,'f%$b;PyAxP٬2yg,2.,'1 HpdƂ$k2O*T:6{D̉`l#6+fkL?CN\Ö%L#1KJ|)Mmꇘ_QfʵmÑ3° rNOnZ*:;.yB?@&g">MHkGpx ] yujv2A`n@+)AZ"bh!H<'z|X챎3S4ʜ<+ 0%lJϙM%m@u0 qU,yHO  S0H,ip;2X`MU]c`Ć6GjUɖсX(s0]R)`I z\X8L2ia R@p_cb~[SD5nRXtA?bhB23"I1̈́ek'0'Πb $FPI\,2q AGr'Ee 윝n7NͤUIe+X azA= >)+C ȢՖ#X3̓h hD6ypr$=&EP i&~ 2+7WY{X7n[bW$1X5j?,УJ$xqթ^Dɂ [20߮fN{]+ hDOց?€/ G:}أ吓/tq:PY =d܈.(I ("He@䈋]EE+c?A5"D0lF`( Bk^N .Ekkt8V> Bi&> XC4u-' .Kv<""7;l`"0\A !N1$K.QG/G/#z ^OAB`AbO .JVQ~D(H-d#)A6B* ٘4"$ "L#ڀ,zm$"zle:t ! Ԃ+|M&"c,`AG |taB+Z_:*D+^&N+l"Z8l"Qf5!%*6 .BF!n" q2 AP,͆) K"ՠΈ>PAaN J%5<c[ I.)"5q}"lO'pd|чE튏_5") ۶i1> Mq& kDF.-§x*"V 5&F5"eV&*.!fE,l!l 8W8]B87.Db#@8Li%mr"0)DT 7[G OB0b# +G(2d , w#`"c$\$d 3"1"%@=7[y5$|B Ċ8N +i"@RF#-6/,RJI%/80"%j"pui-&Sɐ"_s^^ۊmdh-#_"Z`$s owHwAUi-B̼-̲"諣}0?&C$(ZŦCK"KU""K"YB <&LÃ&A1.*Z$dS(Q2$'r0%!L!a<LIpgA98$q,p=B3S$/`!؃Q?|!܄Db!YCF![*X͵kBQ@5́!+30I!Ihߏ$SkKL "|pAS 6!hǼq\aK[^:`3p?~(i`^w O%qR6hAwPvbE !| ]Vd}H$c2hu E TDU/eghYc\#$|\FRu9Z4N&P[ZnQyǁef&TSwm#YI(vuiќvIg. 'I'xgFci"fGjf(Fiv_H) ꫲ:ꬶފk%Z 왝l! , zA HZHȰÆ-JHŋ3jȱǏ C$H|Z͑LB &G`ƿ @$D}pHA`C<Gt[A@ǃvEIC#sG 1o,*8I3,R$PY`A,dKq e@ Sć=pPZ wTViE@NQX H@09IVҁy}J^N^nx橧fWw)蠄j衈56ꨃQmTW!Љvi]hGt~5,jQ2-$rMHUj=qFs rd;pTR$VUF64D@G7U2  pREarT e.CA5š"e6QW??/@$sʼnp[YЗqF&eiOfl M9@3QT AxC=4xD ﹜=\ *S$?e?~J [Pk@m1 Aac,6T[NKބDžHP}t_^xH^!d[qWy褗覫S_cUǞ ޲SN#PMK}Z*'o_6\(]S7"Eyvs#l'FOyړ7">njr<'1J6C.C,n9T,,"3DHD@=;6q 46/,ɷjA7FF$AP02$HJQn$@P "j&dY C܁&A^bRZZD"@4RƏ\"S*H=*IaNB(%NUa#)r%i$E:=kXu]Yw3c ܫc JB;H R9S"]׶&b/;$IpxEI֬؁67҉ #*x vxF`bF!--DpOx ;-cdNŝL?ý/J&6"e?<`(g}Q#L9C BN^[u&!yCQn}$> ʼn h~1pqXS&d EAHZn քa ]H҈-=a O>2x $8BbVyvŐUBiAC3">lč U*MEɈ5ar?*. M2)N, #X^錑%,5*qd/PbM$?Qi~@:s˲H7 D{g I5>@2&/8$tQQuNBX(#=DاuPyRxQ"iPP[21 m!NQp'\/+HvK1 ?>#DHS>k0IOאwj[?!iK]>O\4 ͕N{#րCkD9:~q< F褆&Rdl ~gJTP<+EF?%Y@ZJM*?l81{OI^HXu`A\T8zd)vq6Dqo#7_Oj= ?"{GYy(B/~W_(BbݻD>R :$ -3>!PQK|4^'/>tF x 7P=g U>U$oQP8PzNxXu"!aJ5*@NK 5ෂ+83 `3U}. Aiy !mgw{{=\Jp9P^s-Q7G * g] A}Z^`N" ]` h9kh ͥ /Ev+3&890%c5VGkV^4#.6i@tRA0<8#txbr/и'(ְ@RN GUG~ʴ:7ҠP{W(#HA'c6Ս5ASsc" A*!qeux bJNC[j~a^Ӥ}i}A<4P.1 'q0T(qg35eV87 | *C!pwZ⒓q3\hUs0鈖npr9N3%atٗ|B%~YYcnb/ sf%X7y#>U g'>Ef;BٰR_d~ #pٚr!X> !SA[$AP!^6@y"G09//' p ؉O W6F]g1 ep,8xfaٟe:Dv1saG} ZP( 18ڠ5f\5Q2uȊB`:ZsJc=塜Т.)e+Qm)y9f[CJ8& ܠHp\y !@Ymv> j9vtn혥A[O*0P'S*t0J{7WbLuJNsuzzAکor9ZљC@m(D*RZ'tXE2PGq0 iz5Egt3!e 1 SC)y ; <9GjA #w(tBH5  1 E0   J|s' ;0 G pCF#447YL+jX  00 *&Ay9pEn2 k 2H XQ*9 E0 (  8~m3 q0 %[C t#bwX; pKA/J1&<1 HJ21m*1 %[ ` {6W7BSCY*$vRꊤ0 u^:{5Jps@[9YP!!$=R _9F0@(- D ۶JA1M4D*!* esqJ1!9(I%SJVA`@MTqlq+T"@5 ~ ` t0   nlDĤRʻI!X If^Lq h_(002z(Q]sji(J: a\: *@e9 X Ia #Apnmq}nlUpeJ|'?t(Эb6' g HyX}(RI= Ϡ 'mmk9u}&Mx7T@d ɺzm*M{J"U;Q'N]U"TW4MWW[=4! !/ l`ź5kj ) }`2ē=-a \`X-]c= ÿS !4x(a-Pu"+Muqq=!]д:'6:S٘K߸rAS(`QHTR!"iP1m=֐,T}eIڿajK&-; J{B@ '%m`wsߍ)or^s:Ͻ'4^@#1=sN~犞y@na!Љ"$-MTra`')40a3뱡 QW넂 )Vn" ! 6M!\8MZǭ;.qyP7 ^yCd>9[$lN#|~1E[38w ѐU8%XN]H0\39r>&+'"Bt+  xRώ's|Z94M'K/+MJ!}! iSܦ!Q%@ " ľGfD+gVd]3_-*pp4 b^U@"ң/y{"Gp`azR奿wC_3ݯOq sEQCN AVӚ|  -=Aj~`n+&ˠ企; xT4e05M=a@ DPB \ +pq] LHHDy[J-]g̖h2A3TsaPXR.ՒJet ZDP%t&v etVZ*$&H riuA kރ¶:"0" kƩ /  НGfX2qlHaY0-m޽0(h넒R>FY$u(kC akG3BB=.&AD,Y~`=ME韨lʊm I b$ f 5:  LJ`'40 S(ػ  ..:r"dI'!  {  lDy+ʂ43M5dM79 ͋ДN;3O='EH @(3QEybQGDQ 4SM_R!sSQGuEH:]` ) DH qH>5]$W¹.Ty-"e G(8erdhg˚fFeu  lȚF$d|kaCAv eƽBuiDi]d 'l\2 !q%ƒdHerLH" A%c8k ^e!Ԝn %}/X V#ah\( ZڏvT*v #VB fsk~ȘVîMal SZ#~r=IaqPiSՃN*?C4Уt-!f r :JjD"0?H~QzU[,ۢ% Y.Q:>)ۯ>'5_0|gEoZv}Gm~?kh9KZVp 3҅|YB6V q[pA,$Uv A.P r#bԅҲZEI] @Ԕ o`G oyRA?GX<i3uˋxD6ک ԋ$Bt!:᷅fyA@fcAZS# BI~ǃm4 k ID.& 1,)5tX!'49 K2P633uQ`B-$N6[nx 6)AG!t e*@$a検 Y'K^ؐm:Ӟ^2E|,p%:P.= bDC{DDI$&"n|˸"*=ȍ%}P;a<5Ð>=O,V B~IG Ny$pa*  3.dkN6 X}7aL F9<6$, AZq&Hbq֍$:Q<"$&^ u:%D)5Q HT+LH\ق\ 1F0!E?X9f~$.qTyJ79zB)cH``?>AT5!' "KA@ Ѓ5D  dA(+*I]{3 ɫRV2{ ap{Hr&El2"ITmT)Vk+ &rZ䁈nϬd*WWFt! eRG+=it6^r'j⃢"ln&*B5g>7CV>Ppݘ c.Tx  ^ У4 4l;4v@3o> ra1z6G_ $ր4:"R.z>:YaWHC:+}CHm.H! '6mfpY %lg"] PP YBj7N3i==Gi4z_`KU> O~<7PaZdF \2%:yAXXԐÂ@Rr%VMGH>EWz7u~Gվvo' P nݟ.?ּR.)A2b@kԏW]k4>Po"i$"A* ӆq6'q8J5O{+4*$Zpv8V"CzP ZʾuhS-Q#}bPRxW2C?&R2d6u&:jDkbC k!_6(x~Ph+n kq z# ˞(4Kj1b&scP ]%# Ȼp; X0k 99&@? lR| RDG@f|NȳD(CCH۪"^2`7Äp8ɺ#(4/\JHD존J\DdIz`x'L4EDI4; 0$^U [;a(v4†()hm G$s0 5IC=Xo4g@\ <(L9`9Hdxi| *bkC &y380#C`!>{qH'n)9LYS1+kX zH$ĉbC{t Q†Xƅx˯F53@hɩDK:dqL:&tH Fē;" hx$hʪ菴â&Pu5qE!PP< ʾaɤʴ9ʂnjF|%@ X @i(J|͇HB8x\AH0$ lT&i6l! |ksDbLFBx kM@khX+؛(-(3|⻈7mRf| u!'h! w, , K!رېPͲ I;ذ[[(Z;?%5\Ga)ϜW7 \e#[l;γ8?x7MUM V*&2 )nf!ےfĶx4NnEYZ6 Y^Y5)fI`ᄘ omu1iq~ oE!ᑗ@ow zD9PiL w dh9x,`Yp&:T.gʵ@֞pf ^qb-ΑSY@u Df A#I^r|Q&?Nu- a(\dWX9),ĕtǁ\{Oж~~ oڠN"c!m9NjЕ(XPP",kFHsQ% *>!蘉^ qEt&y L-XX&[Oՠj 6p!At<g'j60(/ ]Bp*-w= nEgnwϟ ̫<' >6o^.}_(Ix|ӋfPiO.TXܾSȃ1q#| 1x}J&<*H QIo PtNJ5-2lX0l,d05`O7xXzCxXYbb߈bV 8spOw34aH dA<P 8a 0G,i$ʔ*W\ F&Μ:wi& yU (ґ b(ѤRW>hJ "%x`$/Y||i%کrҭkJxKx|R0jE: n8ǒ'Sl˚B3Gd.N B80i@ӾvIeb[Bn\3' J cj~:rId,,夎6-F@)JWߘxۢ4p(?KQ@8EMAtVNpԌ]WQYN@Ht?HfPu#q8CY4)d!IEбMAa UA)tbNslH&CAAִ:W^Ab^n^DX6c}b 6T?x'f'hJJ*8J A묃jm{!dOq#v30m@8QAI*4DJPJ͑U c}!zF}BE$Y ,IRh.PH*LޢK|%a]gx^vzӧO?;|)|mɔE25|L6TYA])06'9Z48l{^$tK#i*Ih3?vN$$ma&` 椂4f7>!ȓ\ NVȹ@!$(C`)[R WLDA?JdA VG8 LTI M 0\vh e(y6AԸXC%nw)20J # .0Z"eWSHZ1d*;IA lKT()BK k3%@I]L3EkD& ̌#BX$!LS=Q@;F6S %'%|;IDӝnh} :y*ԡF=*Rԥ2N}*T*թR@,Uէs^*X*ֱf=+ZӪֵn}+\I9#teOƬfkK3 -4',ADc\NJ*䮂V7dI|@1"g:k)@VH*I"@`(o=5H ..I5tY imlxfGPspn*$uWWbf*EJ82cl(.I>9)E; fav_Jp}p&%gI,)ͻXW&mK cc RD#tXJz QẐ&]zt _taq j\@8Y<8 Nb,L(KDAAke%TJKdɇĘM*(lK4^'! IAIBijd |UdQL'QCȌ~@l:@HĤ9.Ny L&{gDD>H>|͗|cIa$3I $pd$PfuL%_>('kUigR >&U?7K$|cxA|@Ij {0 rMLΘ<婔M |b-%  f:ѱi>(H `9bB|3Ty! ,Ysei HPpÆ#JHExǏ Zȑ(%\ɲ%B0Ie5ssϟN5HugȞ3n$_dW$Kh/[ jڷcKP85(s߿ .rÈ+^̸ǐ#KpAq(%fq.JSu5=kڥصsW@tD"e2Xu+@ąSfٺ ~P35n,#p= CaMˑ}F n=gp *Ϝ `GpCGoR43`a!J\3:( ک(L 78<@)DiH&L6PF)TViXf\v`)dih&N! , {C Hp *\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI3A"c!5 JhAӜ̩1B 0M݊ւZD1B\Ӫ]Vc[e۶.JU(U!@v+^ spD(!9!K߆ pL2=1D Tم2!Ҹsy5XM`3 g!k 0\MpMPJNY$ [m N},N3H ĝ@f Bf 4?4L6qV/ 2PܔNQ%@3R՟X<ҷ?7@{@Du1d ?QG^fA ^CecB$$Dx cAtقpYjH|3X57 qhGЁL@P5R2|i'M$>$*B tKXY.frt9?&8Zgi0쨐%! ƞT5$  bM"߹\c':D8p|rv/kȊj ңx.L!BwgCA  Q!Ȅ_ @ 3Y4u1@f!-A@;U5 QU9'xl I@5 1* r0!ְ^#/Sbr0|o|@ %q,(5&D"8L?@- wsdqD=Xlɳ N2Ki opA@#,ftf'TOD#(AG4W* d fy3Ya0t@ĆB3DA) \ؒML89 * # @R@#*bDžHx{X7Q@!|%rdX߶Z`?LKn" N,hF Bم ?8E;M6jКcY]țҋYDE[$ Z|/%H%h"HCb ȝ0OX-p?FvIo B I:d5fǔPt҅5 XA2 !i@K"+uՂ!96G h B|;HAŇ9رKf-ZIeArFP] H2Sm^D 84PXPŃC`6nA$11LS8\kTkHNN)CAL/d@8vjA,\ DZȭ ́@\q#Pf/M!CzJdnmCPC{wm*@\S/dIvk %Z3'c)&oucB;Pv0Էs4w>mw%ڹRWܛ:Hm脴ҧ0;BexsB!-;#RhF /A焨;!DDd2@^ЇEC! G Xs;'1Z<VzD}J: a}SGdb'dRVVc)o\ @T!?ͫmr LLP7!WHP'"u Qw7:, u Vf` NkzPH36rpyx'$ p?˄°_ !ya2 {0az _-wuuGTiC#s !V!P|7Cߦ-ҀH 1vf'XF@ͰcB0TGX8 fV486m` g a{AV(ˀ|J;z D /g^PEmi~@R&m1C Tчl";HWNtl5{b^8:nm/q$zWCC;7`d( bXZXY]Fvl8maru@ Ў_Ma+37:`q"Wa4a qʀn{ C(Tc S^vy΀ Vp  "*r%gԁy(x* 4c@};X iITHP 5xfa:'͠ $R_s 41H1{ruB v1`8A+A4)$ l$rz1|ACq` Y l&뇃#%cl1F<? "X9CdHIOWpNX%rQN QQ7p[ ;KC{lv~ q" ЂBtQd) 'va ;.R\ٟ¸Yp?$\~YCaEj FY5xO H6cFHe%'_Z7|NOp$lH"0 р4grGxTC) $b!R%lL)`U2<|'cQ3͠I9 &w:U"$/!Fk31a ~*xd,W*'R@qiAA}?R9X BPmr)xʦ G X@ | ah4P  ca#;!ds '0Ft" W G;DXZab%p:\Y`>q@r>=]с.WQ b+i= Z boF$^F7I;+3g @` kqA- I{iNZg&tɲ-ᅡ梵%ςVTABJۻ\;dƫ@&/yK'B'~TD3yfCDrymo0& e Ӄb-iel>  @-RH@L P;{c$Kzc#+Sw;  P+PZUEZ[,*Ͱ:8->Z A#~]~a,h0!)^!i:@4 ;J_qXD$QmPFWN !=tQ@]gˎ֐PД 84g'13:e<À: EѩI =o"2,]J{?bS;ZA7q '%\P` 'Y)7 lLb }~=N$L}bQ=ܱI ߫]Z%W,`%1 61ڐMTfVp7iŪx=Cy1Vjm| 4a^N@͑Ҁ:cZ8A1ۛjɓ [$!x%fp ;<q o)ݰZ(G۝UMZ:Vg Q! G楄 06Ȁ 3 !"-(FhP9p*]2aT$C*l HU'T31nOաqh=+&qvĒGOWq!+# g^<x\ǵv㱝! }\0p]ѲC~\_ʅ"!#7[>/):q<S'AZͤ0A'Bp(MV %_:d6nYW(/ \N7HBg ;bNQI߃ =t:*?/P],`6-`zG0H`;t4pX尴#za RI7tK3i12(<N>@g^'Öm2oпK4! Ex1' ux2DQ G) f =̩qa :fu=`mNV\K97`%Atˈ2CC ?L Pm!=eĉ kF(Q;'8ȣ&0$(q (N GOBu*Fk?2/bM_ KL EȔD () Jf4Ԋz ) : AtȐ:"!8좜J(2 hAE}Iv?> @dcJbj3QB+ DA~@m=Ht0 1K]C Bj/:-i#`Ӂ@e=:8'jP-s]^YF+VNn'd5t$K zpFɰ0,xQf:)F2XfZd/D LOfOz D0 I2("ք*'d^>(㜷cN.Dk $A-ڸ`:G0D1n0 q+2ĥn4QI/}$W|?}WΟP؝}ų?޿$7dzLk`(%AF0AH#wN<&2qI;IAf)P+`1PpZB ~ ]6!p" H%J-!*(Iˍ81kB$ 5f#xʼnOth@} #IT+t X ")85f #ʼnp?t*` @ f0D8 ƀx]hpHJPɖbHDrE K ӶFEY pDf|7@(  #ECVHDC$J0 BXNp}KȦN%9 A LDC.d (E9=JF QY@I R dVgmpj@4e<q䱒),q !7fvatC5,8f&;Zuh[_`HT} 3-#Bj 0҂,\#.>c41r`p!s*KAф40IAXB ePaIT q{:B@i =ex k2PS9q:B&9 3q<nߪ P? P&R1zvRd}@C#q ;H”HqaPāAb;9:*tZIp("#/خf[#tEnn@Ad1 BTq&I@3btR(:JP 8@HFH a Ƹ274o .H`1+Cэ( O)k =' =.Z*r/ 8P1 8O ҉id06Y;I@,=)& ΁[ XC ixfD ғ-2xzH2BhD ӈbGAe $T`ʂkHMA!kK ᫞txpxtp J@Jx8L (!8/Tt숱 (L+5Ŋ-mqA,0503!ߌ19GhbgB04y4O8xXVWa6kB4`ڲpࢁnO?٘0Ȝxs<@x !(y5BbDSrX4۸*8I %RpuNL;! X*ʏ~ҏEr"@PxP@,R19D % @QUx_tR尋5q 0,IʋQ2m"m(E"\yX3,ȣH`B1MU@¹1ՁnMe2fXpThl VUȼn`<הhUlSs͊i6ՎgE'0PkX졃ghY>>@ P=cQU2eҥkU"0( )@;$=)/M`3F4VDI\]hc|"JIF"bZ.!:`왎߃ (Xf4vgG@$[)-@f8Pqi`N]4E0]k(d^ʌ0bvZ !=W)uۜMD& E"! =FZx Ҙ֭5ga#gPً} :D3f $V3F,A@DĆ| ḏp$@6mNmlվ-Պ %heh.%64/9ҢNB RM`m\F:hiE(o:^c)0 ǕG!Th^@ ~A .p1ih;Mϼ'2"4 5銨%8@q@m}@2t0!lVP P VVe]T"Ǟ$+rn=i䄋-:h"F!8k`0 $ b5.BHh0r =G0ppEd!Hyd8җD :qp m3TK=LnL1@n& qItFC>RZEIO6i@Qgn4 X-C6!PU? hFC#1mLP)hhvG 8wl>7m"eB?0ցW$xͯޤٲ7 (Px犨pSxvUXo ryĘ\t{y~nCu,x(?= iE`zCxzX飱r XZ.(Ni4$t 9ehj@5 >TШyh0U$tY%xA"Tʦ<xE yZH^gE NJ;V!jbH:&^ ,M@ &xX4>i,h „!ĈuIh"ƌL_h"uW(ɘ27Lh5R翔C7 z)ԁؑ9r/k^-k [(,)+)-޼误L|*3V8ƒ'I23s3g. Q` 5KVmm$1F.( {GP;\c#+:2 P#B @9*x`8y B[eg 5-4P3P ACD Ziw!qkDBNXS[ru [98cQX%!DP9A $`!Ԕ52uuՅ y8]TYpSAAr]?RPy_A tDd  Tz*t@XSd?DDICsD5 h3U@iXJb:'M~Zj*B%Bo:}qUA u`8$UU`_DudԐę/@kA:쩍Y}-S@ j $6A/A,S@Ig%dcppӉFd#D(Bkеۖj<꞉C\Ӗ _ wg9';e4$4M;=-U[}x]{5a!q;NSUL- q6y% ZnM$AG핍rFYtpxS)AdցAt A?H+FII:&*Zz&5E癸ihg| uA9" ?c_-VSu{#Դ#I4晝@(@EԨXg 8 %z3D34np ̰xgM/PNs7u2;EJ3 JJ&i2pN`fW@z?. B4g{faha7Kb 2 R"sdAF!#.W&BD0/DD|ZE&sE pP$T0`,R^B pbyo4 J6)(%L$gC94!akEKԏƼ&67B0Ѵ#)qjx1ܾI5rNHy5/ҫnV:Ly8{"$|`L\ *dy̶nSBȎ iTH H VXr, T K22zf#QAMNz%"xRt(( "6$XEAp LdpwfhyтY B^X$d F)-, YVUSq\@/WEƥIBoOFm8"dzAIddyDG&edQB/ ӧ& AFIYzh" 9@JŌ=v4z ucQ5kLRt ~UTC zHHGbG2E;:b j5E YO3:!1n1At"$B- K1؁Ƀl{ 7̉ċ6Jׄ {2$j, &tHY( %hی2'|83D%-5pfXקSH86 +)N(R%J -2U qB8-" !)2O벣#-IS1@58xnWqJ$"q.5 kEtT[l 3yD1M?=SZ"e}I xӾ IʪzoxD:^}ƿojR`A cΦ\~COE4؈O%BZhx|od*n QڒHO>\ B\``YXB@0WTHƵ+nD`qVL]L.d.8(A!xt6F@5W_,CC5yeHCJ@CăHDbH,HM\ChL/zՄE*bmD' *!b3F$ B#(D FBy^Ap A@tD3f(z =șv>ĵόL^8g$M"DB@=A?Ԃ!ڄV=@~ KEdB(:LDR&mJA$`pQIJ#d8C|ʄC9LUz@8XdT@9@|A ? @? k)5@!^$ŌVAaJlaiLK4fF.d lvͷ2 6@Jkx@NL`"<<@<A C@6`Ux'dK6XAC-)Pr~^K %FZnMVr]t+Pb@@0:dVnDM85dKƥ Om[,à.EolTg,Y5#h<kAM DZd+*AfA I)4%AEH&ـ‚mTTHCf`8FRLIoYUĬ~J C -kTVxm5˜! :EDQ,f잭N@xHBEA4FH/1g4_5_^ddl6A+ _ H>H®;YY]4T]_ !bTAO!eav*d:Ԕ wC"VE \*@  pPƠxs"aRMhѹ8"J52D|hA ѐ9]Uj">vyOQ-ٮ>Lc`/["i3x` (.U:>o֛]o4 w6^$#`,<{規ʉ2#&jRXC:ď Z,"CPi7aDXi T,$!ň&'z&A&,Ibk  )3 C8֡" +sѧt(0Nx=pÑ' n 8DHDhPe J+N&6xD 9Za"(Ln THP"24 KL/ 뇥t(Vau-\ (6"I 3C$nBI1/ :5D`z(JӁT^ hWK9B8 ^dM[ mƞ[2[ / gqZrǁlq/Gor! , s@ H*\ȰÇ#JHŋ3j 2CIɓ(S\ɲ˗/dy`͛8sɳϟ@ JѣH*u @J@իXj:j 2׳hӪ]{UV]C˶YNiLÈ_ 00Đ#KL˘3k̹Ϡ'z_K^3cZ˞}0m^[LRHӷ /p+_μ9rb3ſ2k'jݽ+r2j,yY񟂔/ ˲qu3 .@QFZtK.NgTAB$Xg\w`-d&thfAz2*G )@߀.ntۡ:ڌljTiDn9Fv R۞| VR>知/Too|M,7/2 Woؿw/o@vG/O|H?/tL x*Ё |#HAZp 7f0?4WIÃ` WЅ,| c8A]HCX[n@51"FL"&2N"(*RV7.b^ #(2ϐ3DJa4 Cpx̣> IBҏ@ :X!'IJZ򒘤$ q02ohCk0>X/JSC :ByRZ0Ib1f:{QlhIԄ J Q53# c&'qb 8)9tdД;VJiҞ;4'Okc{A@vԜbP؊ c _i }4$@6rO>A(DQ4LbVZcyE,RlȅIC AD10Ln+hU>!R.ɀS-D>HZ'$2&բ@jR'5~^H#]= A_2G-2 3]h 727:KĖ&KjWHx*bͭjF@M"P1kOѬBcr@d"q =Q4!u0u@b]Zdݥb.{}VC RҳeLaE@B0)J@ŽF8Fhbp$ !I (*0KŪ.ƫ5SVFp}}N#HNr%;PN27pL۸8S^վxq8a5tLNf#psaHA E#Sb/2a,1ȉ10_ם i<qLҘ4LTYt̉12i $8#U ")4G$MM2 `U< .N'Du^,P/xVC XyFqf}<!X2 npB7o2~ՎOFIT(XM$w.5i ᰇ8xc܀m`` uV8b S` T [P:*A!R璶<`Ć%pHY#4xÔր>rMub m8ogl"`8E.% /E\@[/Ɲ ݏO?qѦAFӋs[ϕr~nin6wGiFp?tXg{&c!hcQgup#n9WHFoPlX5Y6'5G7w)\g JdPs!Xiwc:]- H (Z 'h5~?'cP {`G EvdrkȆF IgXx"g 0KSZ'X`4~ 1n+ixS kX`  wҠpCƦ z €{%hhL'&4[O'#+2Er`pfpi@QF HwMV  r` P  Q, J 6_1(5O&A7vG&& 5& &)/xs ƈ 0 XpG|#j؈޵&OqZC!/"apSp0i Efj t~ptP@ p{B` ] m $U㐪%K` *gS!I`Y#{pok fgF)pv 0iP堆d0'Аy7 EdbZ@-mj'K`ygFՐ]Ue7IɃlٝ6e|6ve&TX ߶ҀNa6 :piw:j x jiujo]& @ 靤9NV~ b0H 8'GnC @k*Grrf@f)fd049eP> lHy0d HI#p@i @cHp$a:PF@2P πhFIt$7`  8lܠ & pB'8P'U秝R3"Bi&v!d@Ib9ibdxd b:i Hs  pw2l>:e zXjT9nPJڑQ`GRgX [Zi n d F& u6e1 &c 9@ 9A7lR/ #`تK!a7=1]=7* Dpfg&k G& &/oE `N s:B@蠧ʀpt`> *`8р'rd!< /pq sIgƃshF rHpHP x#0~$#XluhU{a@c@@:m{:B UBy PQ?!~U10vY (iƸlk@@JtS{| 0 ·˭3W e KɳE7%Δ Q8ʋуƽ2]q,@E]GK& dЕ P}Vc\Zk wC=2lls X[Xv76\S Fo P0v1&Bm5m: 2!^rHֺS | zjڧ]N,b ]I93{`I'j5!8HrN G :  wp@Mq]p,+تҷ}=#!>U   dN+ ܝ}<L  /;PXjbؙA<!pp$ @ ͐r $:jpCAM. . ̀^H0-ȫIBRސK%!+!AOh)! `UmkLMπr $&p{"B``opЧ, c(x$ &`lv]e]kB*[rK, ŗr  J E )@> _]qmH]dIj :ga5Nms܀ nArMe>&+X`" :i'3 )sY ތg g"RV@"Vх拆*;AueծtuLN&p9݉ ` ]ﬥj@lJ . `dfv3f PH`@jp wa| Q ppJŽSy7lz7PPM l] 5)"ۍU! ƿD5 Soop 'KπePHB]R ^6=p?XeϺ9e0eaot F, -`Í X H1⯣~1U/| lEKglFi` ,p*@D-^X1$|#OH%MDRJ-]SH8L=}TP=İf '^xCoլƣUXe͞ϟ5a(vB,!ddXD@xhXb/kvqgcʕ-_5if>hjIVmj֭[6ɚ7%Ɲ[Zpp`ѦӞF\5 \?.t>ԥvoFw?ng:q[Wnk5 o O(/;͚&[0B:ߒZj8A_AKu2άuQ !,T42FF< *Ѳ DRG#<[VaDz1tJnĹnLSD˲dBi_RB"!F]b10 Cˆ,QPR. b%C]ᄞr@8&u@+ƫ`\s,AaDk$!ut8QCXnHF,HʁS,%!\nRw7Ļ Z<#XA`RT&,Q&Tk+ap8it&,*PE`HNT"i⦃_ƗFF(q$ ]{j+)t Bj}R~Q '=:)lXW± ] t1 8JFP&2qc"!9p N G$|/qցEFl>TjR,kiyk֡C`T8nnU3:xh g7KzF'<ݙT(DsʬOIuM90"- })糚(AGJx'D];`ÖC`x@L}!ǼP`ە=|'\j.Bpy5N B"i3֨Аg` kđ o]HC2{P#XC w?-vBJ!lj6k(L ٴNqMY n T+tx~6! 8퐐( (@M0`d^Ji$sH0 eXnXN@D!,"aXGXƍA͍*Z`BVNL:t`dP!7~qJqc{ca Lr f4tA(&z[ ,ju/I4 kFX2tX^II?"#H"ֈ* k/ 5PƋ,nH5` eJU̘EI1BQ#oxcTַ(J*ӣ Qh˜vD@8 ~PR'pL&{Wt$FK.dl*J?}$fy2! Ȃ|_|ьsEFJ:x3b}c>8ӍC5s*F"(¨@ibXJq1pûIu>xbipL/Xį Zsx_ z[ w"8~"+$@Rd ](n {{)Xإ:. .A3#$k1ݠ]@;{i<4)`1ӛ0diJ qXB q!% C)@Ġ`}!i)xBa5khH,@q0qx٥7vC<4LBR`4(4󰦰@PՀJAd5x-(4ꈻxÍeP,f$ RDܹ% e F$z@h@IЛ F! x]p CT7|JuDQ;iT1(1A {Xp2;<i‹NG  =0벀!-3GL$H#0/D < b-dNXS ( 9R%$dA!XODBљKt uX*xd0+{13yzr]M5 ՛y?,K]u/%*Y4X"xC <ўYQ%NVm iMn kpJ*<ǯ '{@@W,y5ZR _t-iTr((`B1xk` ;i>'$rq*(H@:xDvTT T 5m h4iP|i /gU(Nϋ-|ERdX`pNH?@{PeB.qXR;RK=D CxbKwer@Z;Z%pU zM3ي`PD+fD:IL9.-`و-5L[#Vحr}hEzHTzxxئHiUuUKuu;ٷ.pGzuq8E34QYtX PF atpr퇦}(_eDaa{͡E2YG$[+ET{-7QV)`m=& QLC0.T (ڼ Jn` ,ZmEZ=ihaZAᣨ~] &0 -`#i@. n@xX 8PbX=BFi[L5, ԕд~HpʥQe_GC ,q$@?贱Nuh6Ya:JE H=GfwZfH\lK RกS{p8(X zC),nO) !ha#i8]l+tB­2BসH;ZH:gAC1dZ@L]Z@ b_3<XXd q t=/I܃Wci`4IGPS Cx$I9i~ `Z[p2*@(,擂! ĬHe[Vs޾. nCrljUF/v[=hBˠXza ˜m٫ F>@]p8@6P1NjH i4U-l)8EF8@\0dP\D&mv y/nATprN5@pXcŝCXH](@* =XgVo=LjFoW8L'H d&yEqH @(m5Ȁ%{t8Om GV .C0p}P |戆.-(ĿgIl' n0 I#хu Su` Bu0z(XREEnHtd6&ZjN([ݒ_ZqV!Qz/6`Qnuxd,Xi1Dq(( !USTc9ᆕ!Hܖ!SGPZp0X+'_ZbN:+z-) է]xGDt#nNؐD‡w^Nbugыo>#_ġ'Κ5z6r#Dր(!-0$t 4 b'РA-%ҤJ2m)ԨRRj*VQ֬bǒ-k,ڴjhaMP9u+7z7"7.\Ċ3&ӿ_`Sl2bKyEدiӧS.}_ l89Ѷ}Ats gyn~.ov=o ZVi֚%{w_B l3IC wU3I8R[u{j!RU'u7.COB >.8 1aq1BL`@L*taAIt?t$~tsPZy5bcSStL<c 7c*U{UN{-q& R`@ <4O9FwV5!M 67PL۲` SPdTqb[|TZ (,%Rb3:cC ,;^u"M21Y 7B2j\`#5!#%0m;?U4NWg *vPsp"zЬ45tD-P# 6NHANK ZWt~Zzhj4=9aňI\ט{釋GWDjO`}ǴO;^u~;j|yrڑ鲡^:@]D ,=»|A!u/'݋?߇7& ιRD:i4oDgi)ߥ o[P HEata8V)P 2DiE :I N ']PSR`D"1΅vE@JqI,=@S"P(\q)Q)@APcو0XHOo7a=O~ t F`N.&" D 9qI9j8$i*t bR_b|#= 0҆*+c(T@Qe+EhFa `4 y~-,!pHJ6`U`_t!(=4$VԒS43È;<){XBGU&HdPc#gKHm(`/~A@c}͢IS%rJ) , -:kTG$<$!`aN&'n7w|WZz+^Io|Fc0S@I:ζҋuzh.&^B_ ! x$5Nv":8}3iU/1=RN#nT@bPjT]2ѪpC3؊I)B1-PFZ BO@őyEy=IϋTtL*CB,A5c8 WUH;, yI K4\Cnn-){*R`P­ '/G$i4F? <23Ic_,U)1Ч2Y<b'[3nV#ƪ02 zcpЈ2<8aa qitBF֩! choxwUt!kzG*EэISDC?hF<Τx0!AaFl!`mj!hzg3S~o/ @-Z&)x9ۏ:eevWԩ^(Byw9Sb7& G7qߩ`cx=j5k/6-)IZqxo5 ?n 'Uyo?on_akep! G8Xu^RO2ޱ7(_y~C+QAqK05DDE2@T8H*E8DXIN5@AC0XCcAE]U2(&==PG,:5NxĀ&T\^JLY]#Ԥ=C9@ A A8:4KXX#p A9pA7To_:lRaxSDb|T2- *!$4\0pDd*FCe9 3@5epgjNN4Gy&EiWNFNhzFЁ 8Zh3,S?DE//:UDB<$QV I@94CMؙo 4P\6#52&A!Sjhl:E A#,BE$3g92X$:i$5 ,fiHiLQDD\4. :W( CΠ`R!LZ鳨VVtlS,Cm@~ΈGjGijpOx&\g*K{dR`SS(F*J6fTZ$C=+:T>+ѵNv~+vGR+֜ +d|!].fHk`v,P!,~"F&՜'|«F,NV,^,:nhɃȎ,ɖɚ xzz,T7 A ,ެl,,,m&-.6:->F-BNV-n-v+^I7`ٞ-ڦڮ-۶۾-ƭ-֭--۾٥\q•~[&.".6.NVn^.bf.nj.vn~.覮.ꮮ. \ n\T.Z@n/&*/.6/2>F/^fon/rv/~z/op)fɾ/Ưo///%70ZK,-z^7F& _KH@@_ˍu0Ypp,x lEUX|0 FE) ;GA> 0$]{H XYE D!k}%+NH0w1|qM\@_<?1R1q+ xqZ! , |C H`*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜIn21 IѣH&MRy aէ`1P15s8/KʝKn=Fv7ʵN v ׅAB3k2D$"a,&YHUϜ3DžXz˿  "Z RW6bQ\>K̿ dY}N /`Hh3*a6.Ͽ$I3zLH GT&zq2,(( sPŢ8(8R W)S"< X@ O/d$AH! sdU6H B_IA,4x 0<@U?Ln hHXP EDCDy3PeYSL&y5T}t ꭸ-fVzQN`@gOq10UU^LUv-]1k覫k$J vQĬ>UD#CUj'w.5,-(f>@$ C : YsB Cp;Ia4FDfCC2o@ ,J=> B Rl<R!t#Bk.T)b==W\ S:?diE];t.=  7P ˏ Is |oqt_u~|nTa fY$ q-G @xi'l="4`^,c@C f K$,fP6IvPD Tϥu@?Godk3 t# $IX  }'p/\g Ir+I?AaoC["v9R$ CBܤ7SaXP8Ր!!bP% aPH`g"!(x[ ]X7 ?+=m!422:&d@q7rTv !7I1HYoXD0щUɁ\aA"gL H@:F!Qm  JȜ0HQUz47aA^!8IGzΜHdpC52D P%R@C pf 8e*L<%?2@EAB%Pd(.H y+$opX  0dH':^C ,DlDɬU(q JBrlF1%VY$sln҆5ZBOhut9Z\F@8"y)d'6 6NEGKe7<&b҇>ΰd o@Xv9 1}غBZ草zVN+Quب\9J{_dR _(`NpD+,:I)E| q  0j%H8")F )$ASH" c,}j;E8J0Y!J*SèQL 4Wk![ 1QF=`CHӧԘDD٧)Aٛ! >΁ Ypk'2rĽ̑9&-kaf})+bM!X;#KZOL"Fp![D[G`9( rB<lldբ075dX3MDi*&ISuqzC3n^K)B*cPa}Ha6oGt`q2;MA1B6-B9d1W#!p@ nW~ޘ$`a g3\j0 q1 9gf, ] 5nA ̰ nע["s9x :gz8"82DZ֤4aP0ٶ]{?@@:gئĹVQt *4)'D "M<I\ $!:8'$oW kԔ R|`x,mYo f@!6ד$ ɰWc wr G&}!S(oQ3zWP0:GݶDsO !rrHDqdSB VDr1} !! 2DCsxE#nxHy#_(cᇩt.7 FPkos#SU0iFG(X l8fhov `+yʠ Qp3 qyawژ'KQ  wR<ϗQ

-xh10`9q)nIqyeah9sgiH l+qݩ`u8CrJrĘ z{p&Iq A'.1/Q~t!ŷ _a$$ɢ!6Ʋ%.Ua^t' %1"\gj'\h F[Ag3$* !5[ec4ְ52p Q?`K5"2 q TaXRۛ 1dwbjW1ŚS5X,#U [UtԃP`w4[?b$#rud-I# G#p`+/,sQt.\Ea-woARz#lSDcY20ihw>K,dq5P|i*~1VQdayqc` EPַ릮ߙ ( !]Ȱ\p>| ֑A hW1 T@ ܱ;0 !%Qֵی%.X[]1oM,,0+ C17A# v K!Ң#^%!YU1>7q4`qZQ 5y+PW-G!|M@yHp ٰR&@Dݫ 0 pD,>.r@'W:AD0QS"QC]h#]>ת*6,&p pA,`8A!H-#'q' MBt1 `dG2^5B\Ex8qr f|(ˁ'+&7Wn4 2b=-Cd|.cxrN @+%ITO.BM.V{c_^:Y_p$U*FJ0 +d_cb|Rztko) )nYr'#:p^7A=P _+Kܠ6e`Gf~Bx&C@a , ϋ".ƤMCAѪk\&{- P^uKfGJQ\~"GE/"_ c.Y  4!`I=+ A$ H px 0)3 p/qY&JL,=OAN3 F\qC?$PCA D PD7rBF=~28*0H?PYx5S'E$ ((%vh ` TkFm(ER#$ƀ iC?`ݾlڌ"6D -p\dM-!J@w)D悗;sM0aȡMFɩ]|MsjT7c-22f [;mƃ݉dǯ: 80@E"|Pbt([#(~B(Zs仍q cȊ{:JFc ŏlH‚t(BˣNc ȩz ʐ+HME! Jx _TJ<fFpNC;*., R"`2!Jʭ> r nMpJ g,Ђ10rJVa?B$"5P=9" "IL|A3g 0ʓ33,2[G.ĎT}'*HL#nhM):<5t0f0 XV~k-23q(h(M * ?d K$G2i Hm>\% (fq#d?+H:,fH2z +3'% Z 3.03."5݊9: nEZ+Gng.nqEc/ z)|̒BKtlGC$'kgK"q$Dxb(\j9 Cf%AZ|Bvr;~   dBЁ]L A"`+f?I:!öD́8tAJ$H םv` &bf`"i`jH@b :L* wA! cCܠIд H%`2R [`f? 2"rbł̌ )IS*2lTՠ83bMQ< ]֭Dl2EpX{b4yXi D |x9&OXq5&pÁ0@/X,H 9L"ְ+V$m6ht1Fp;!DB9$B$C  nIv1 1C^,j۷(-H0`2#icNdkYJI /iړd$fnHNJ 3 ĕc a3yN؅5@!<` bfF9pܰ'' ɵWFB; #:Hv<4kWn%R]o.@T=3 !TC ) ^nc!VNլi7#-G|V#!p)N9t(ds#AvL  p aDHCӐRIP3YYL2EAyNE=TeRg/#:h(pńbE0n:U҅0hރ4KOdH7<$Nk>H#5kp04!i 8وсɷ~t3< CH)= )zP H11mk0k̖˧ѐ|bqP0i ׃P@=A1vKq7aN 1e‵=X <B,ߣ8ch넓H>JBH@8_bVڐI 㙏ZŒ` 1A9!xXĂ,C JқyÎӳnP()+(`Da 9'̨QtZ8㠣뵏0mQ8ԸS` 鵞@DѸ ĂƿNй?8ÄoJ (в_j&gк$IB" cJcɘI(XC2 vKJl:G˂ʊI!aܒЁȐ=IpɏPe|g0D01(Lʲ 8gP* xxD?z {c i'qt3Ԡlj! c@Ý0ܳ4BI"pJс dY>kPظJ2JꊛВFi Ed *<̈9a$sl%б` O#0<Ux ` |~e৿1N0R8HP#?@6ې|.*\eP [Ìpݐ@p (I X נemђYN0LȈII1`b00@\D\ No‚7։pomiL@.PΈwe;>N 1^oX`TH!TiIgTpX[CppR ` XpbYG  BYYbaN*A(]چX'Hƈ iԳ "Ȋ9!/O.MNXt@/" ݉+2 戫 UƨNMyģ8ێ^svbGv0dO_WҡfvCv8VpvLj\QҊhp\ j GO( RҠP㗶 Nn爊:;)q8^9[1i8Ր k2+F‚ȉe\ 9 pw@r\7BtShI4xde|pytLnoue8pDZǴ z>P%HP6)Ͱ{tӐW*,`#({8n@a Vf;Ë)ᐄ)*8;ΈLpX&iU*&w<ݼx=>AYL7ڄIP}fC&{02. h@sȥX .M;sǍ&,h „ 2l!ĈaG G$ʔ*3lKi&Μ:wl8'P"vY0E.7r!(ԨR:՛1:f+ذ<[|PUu]_[(T:P-pB)LຽV)PA8Y4PpA%/dIC|p;g4@ Y0`" *!NqbSl mJ:b ^kc_/pD0n lF_{N\`AUu:WR92P9?<NIO@.'k=#|AtAL!HA BXm! u"P2$D"JunAE?% =?&SbǓ/#@O_8azU8El]@RYPlut !V(h5]VM%$xP@wDd/$y54@$T2$ͽfЅYE:Pj"h ae#(.[|!Py?"la*d|sH\-J'[nLߪt(jk`[л|#.Aze@jx`/" {K<1[|1>hq Al)I*B洏C $h^5.@Ϝe&*vk@ -3"3 $2L!jXB~aq iЉȸFq`F@@- _Ai `W Ga ␞ xWYGԀ Z$e Z̈́| y B<9|Y8 Zi4++5r($-#Dtoj0*IB‘|Xr$8g T@PЁ/t3"ͨBaՍVA/FFft)EHF"H TQ%Zkw#{P݅ SH2P6:ls ֨.Uܱhi1IB2#(U_#@(d=EMx^+Q5VNHCD@BQKGK`@% /TtT #`BD$CB#CDHTds HHDR X!CP!6.Mn~3|"˹v3$*G4Mi<1 uNTAh5*#=qHP M?&M?Udt4ζ0&RE0KG ి*G/zJsajoҳּE[vNj1n?tne`"D qee` օu$|S4uDwU[$p+eqٯX(F7BxHL-IUCg`1A:8'hAXP'^" ^Sv~0XKEoTX!ְk}X"FAP8Dy= +$0R1E{Swۡ`BLW*[6"Cqs"1$kƂDĶ+|WvNT|#/y9xCW3 J&HZ0_Zˇ64mkEHtd ? ²\|u=#υ %Y@ RP=.gcG!H+Iz(HŵJX-hSnq@HC Mxĕ@4ul%=alJXp,@HÞT^VϝٜJG4R38JG`p B : Uy-D!ĎWFM/DlQM7$ B>o:U&-l܄k9a |`D[zHD$ HwT0௴WM*&V#!J8qeBl?Q.8'XDXkh-XV؂^  CJNyR PwP0ATĀuC{hDh\V &XN`@'|~Ɲ|@JDPKD4~g ި? 'D& A6DAC`0@XCA6D,ò1NLp&AdACdNdu%6UDBptUj `'27d 7 A0A\? C )l'vp~tD-dA\jЁB)AEBuD%fys2qw^gxN D,B3KL8ZNlBITȑ\ߥMDFL 4Fm[w^\W.`2&DmIYɞZH5flPXæD3̉|?m B,A$׾>>>q9?'/?7??+GAfNL}BpT YDILCx!(W@C+٭吏:IM '@8`AT8B HP`BP|qc<@G !,)GBF.peAOV0@`͓?j0É@?BA%R6,c%2)ɳa.MP? `)! ?0C8HA7Ī[!ڻN"82 夺R5o"3SH? # q#,$̲9GFm.>j Ra%x+W2KȞ ҫZ" i:@ l> L,O,DpӤz# Mz)b6M )25M7 `  zhr2"Yׁh 86X4 83϶ӪłTHmO~ԠF%TȐzX,!^ rtJA@j"~]vZ3ev='CyzH"wϪ̐o,(~Շr7iaၚ?|W?#w?~~E #x#*K`wAiP7AB`QB-H@! , |C H *\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜIAVxFC5 JhC o**LZʵ׉1KZ0 I׷8}HH"Dv6C²*.DRe AC2G+@X .Rg]H۸?P?$ Q(%#g#0x/ ݁7& Q7 g#FN.l~ֽ&:ac1?4#l5? "4|ՄWCy@~ 1C|Zla(a("b/4@ D߁mppP! $ *^Ay g%CH7`@Mq33~dAj  @К 0?WKDq sWDu0 1y襘nSv:ԩB >ԑ 4zJQ물)5Vj&` ,BuuEpz$i ֖-H:چnuŧ B<'E-ԘkA{Iči6 T@ICF@$(u;OHS."GP@6[a7BO+]K.,& :$`mcxƔ`k ip$]RWp;.\C@Y/:"H@tBmk_7B*r 10X>!yCFr?}}!\>*iqX bYtcB(0# RaK `u4CP[7FZ z&nn#r37"|WFwmlam[>N08WC6378FaݳBBFx-Q22yh' TX&O\W nfV}V'|6aa$Eʠ]AzaS06F b8Ff(3$qw^s) KQ` sC%50 wf)'H^8Bt8`7t.Z2_9noijx@h xHm~ a]WXvPc&9z; Gu6|! C^!]WV"7V^O86h2- (GepMyR@# 6X|PP X9$ dPD'9\QUDxBy&IlƵAO9m r,ɃW)UpB:fq >#Pdya_ijVlt}ffyy][H3-"C wd`JbB~pm[za la vAe/GWܰ9Z qH d@ a%t $;ZQʀg&PCiW}tl(3P( .iVHFql"+YGx f j.5+ȰK :-@a1b 9HOnњ "@|* 9> ! B7}.󊷱 JG ϐ$7` $19EE` 1' A`` (>abE%sR ѓCJloI)Q' -F3%bWLq pXuYqxD1eXpg;y2 l9BvCrV'nvO:Z#@`  !A E >k0*I{wqC歞'aڮY"Y$()ȯ!zQ=|Jqa[Vh2 W۱[ XE+͠^"  HP 5HsNP IU0;Qt%/Zuj8e:[.\Nd1ZUutaBR0z p@&±V+"3Ӟ~T+y)o7L8ЉP!L kzRR{i=Y?@0RaZbara _ѩ5T|AB#4ħU:L!Jv3ۮzG[CA6tto[ 1rT/ >y:l g}wM1Pd Ae` l0ûa u3c+)zxppIh :mafƮD";*Qih5ALKX*!\)R!"r 3 %6 ; Gڮk==H=iD=/Io P>e۵]-q`y 4%s Q f9 "z@(z5&ɓR W|I *vbU1>-%%l7w9_ 8/>+ћィ>ڮM- ]@I~ R>T^ j 0 V>d.吀 ǕRe=Wᳫ ->1jJ䩒}J#~芾zI]0#>>~?.褞k> >~ #0PZ/?pp_S> .@  F0 0}X >^^{IFU @I*|'l7L> P ͠ iܾP m` ^p.Ub}`E `2 K֜P{'MRlF1%Bp܀1L4 @`  @i@lp>Ga0yb, "Ĉq !~ fя|7iUB&H : YO ҐpX> P/ @h` Zc󴆨4!!zh. HޙQs-0 ͻ,"@@>/DLX0 !kIA2BD-^Ę]gdTn}CGO>5męSNqOPCJFC5UTU^Ś* EXe0*.QFLEO,U*@./FQ {'@( Hz߁M{* `~L-f;_:\狛?zs).nz͚\rҘ}S?B% ]PbG^+aso5f13P):-J)j.:(8dPB @?4 *&:`Wd"|Y.FgTΧ ;\ DÉv*$R+:A+G{ϙ 2Jr1P`%!E1/zџ~|LLLFjH)Ͳβ*;=Ī EO eQsE.#H`|M6'a5TQG%TSU ͢1H-,g#P')H"XG)N[D/<(Zmܶ[oDJA2 PH+~ iXJh-gh &j.]y eĥ}֡IӚM7yYgőFE?GΊqK&9e*/CBa$-]~ٌ 9`uQ!‘fPm`J%#)GbAVߤFd/Id78F؛j ܖSrrU<ʚJdJANrP;e܃ ]4Ĺ1nnpXGBk6WC :"Aşdx@n_.ٶk'p](n%:MFzupC)hHTᄣπfp*BMܰJYHd07&Ҍx95,bH٬ i(] (:!0H d..,{<!\BD|1] oI(R#7[PYhpq*FLbV*LjEsc]S@t@b4`Byj,0*0`Ç@*y `SX@YYf`^ bomUp0 <UQo 9Ԁ?M(7ضSXɓL]͡zKt)`QZ).a҈.RBVKg|ڤfjO*9a%KEkZպ֫+$"SE:UB)zmjX$֞S[>4z+$b@(-J:#HAxgF$"p@nJXcY4620D!cEָ9VJ FA f)J屌7F= !RAtqHH; 4<`S "t8hI"GoaնM0V`ieb{dJ>F?\YniÇY0ZGXe 5G8"#p5:r"hA9~2PAF` B܈=t!5I, 5qԉN3J\R.>~;lrV 0X"lUh$4}-*(*L͝Ci_fj`3F`١nuY8 )Ld  I&gf2B TR%o`䏔$~F4,f4Se8J$_tPByNX@O1ʡmT;*t,܇EcxNyQ4#C}0dtjpc@pfG_lӝ;p p8qrc[ $ 2B#a$%CnIbȤytS ~r7Eq5?' g߷U  Q E\>xpF'*tS(I hF0|:Y D8JH M^o#Wq|1b)я_tAXҘ}!h+ 7LO3ud \)qQ!v(p0oh-YSn@X ᡂ S*VO#d.UP`PS~nƠ" Qߡ$Phy!j 5Q4~X:*",P? ȻFk,y ; ؾ|&ܐ@|C<1:4"¸=140 4t)?CzSC=B&۞2,C=>.H$A'*:.a.8&zqn(0<!$D?$1šXp+ iE&H ͢,@h)ؕس-P^˫Zk2e@_p q(~@8DBEI3Iš`Fl`!ƿ9 Ƹ:!dG Xnpa@e 6Cl şpX< +c+ƈhL+#"q080>%"&X#͢ Ɋ 9rnhp:("p0u@+]H&KHNx}P4=kűȐ 0J|⥦XǩxA&AXA CŴA ,DA@ Ca۬PHQ:S-i,LѸP j {6,"k2uKd ,OH @*0 K.*7c/0i(Ũ@šP<PXLYd@ E9Zv\xiT8Kn89i|rXn *ۇDCx0RN˱NANɰ3x0&ѣAC "I0P*L ;+@(9!MwxєtͲЁ@)g@i΢kЅSTpe[3c{G2}{h\lL0sD D(R &xEH%dNr1Ëd2 Z}'pEP4,ɢh _Ĭ.cøJ:{5 N=Nس?)*zw/bW@-IK@`69ײYÁ*MXGQY|w2y=Ñٛ誒wYݞpЯ! zƜhUU'΢"?CH5 S̑Ձ .. :`MJr4aLkP+,n봛}mp&%Y S,,9y]G%`sd !$ȯ/ha iH] Ueؚ2<-X 184ܱ( q{kH«Н 4WpVp ?XҌ c"'1)5 L1#ƘnxqPrP(,,xpj53 %ȗ6ݰ衃ti YVne!J)deh5-(G@]` @nbu]kpP ̘ P?1g#U@^ _@ Q :)-e^ABJd@lϙ !J`S Ѕ ^`i*}jK{ᆥm˻`` .r"X4FO>NICɨ15t6 9X̊.0 ;~嬆֫cٶW L4{E\ը(ab9F|Xjh: ůcgzY+Z:Y3lꟺ.Vg|1LXlzgXI~ {l"Ha^fRaʱ&DDRi8_[Z.zp!m t`a:yM5 L)pj=n؏wfmjjV;[ ̥ Ag(0\4u(!`iTD5GXf0la x<>@y8)Gv}pF05(Jc?? % Е!PphTI?xٌȏd8 xQt x@pяh6 ũ6 ֑-S! V˦,IP(kkX2޶Ze]epH\yJ C.4iPUF JG7ȌxuhY.uN~ߦ% w,)0@:k0kTZo>K-hYjAF\Qv6 ?v|l, 5@[@~z˘HOnjRp  K,l6 Pyk_jÒjx ^؋cBfӾvy@ M~ x9-qhE?4@fwk9Yhy( #H!^((@ n`/,iHp0zV>#>lq xUՆ /? H5oh1_]0s9| X_8h&20GQE N{hb`^`xXnQnaCME_x:"0`Eho Ye\ߦVuI t t8%:` iX Rh"Eѓ&>$tkrX+ܳu=CǍ[h1'РBg*(U)T]PRj*֬P%)MUipȀ-k,ڴj>UF〭@?VS0Ċ^z*_Jyx q! !o@""]ɬ(@m-j斬Ӻ~WΚ?i),7X)e͞=a hѣZ2Uh oouYo5P+[6!wTV2W駆Rݷ i]0?-|{J]MT*SXX ]7Y!  pQy6$D":7iu5#T5GT_ Q)i@Mt@ ؅D@ @X1,$ cE@G2pWInЯbI%a}~%J ܩg!LdؔBeؐցȘt15RF*nbM){ L.p.d\r4.8: 35ӚM2WRmaVʃC_ T/a Xf:;eF3mƛ?^x-qs&N>^m_,%t1KaINL5%!N!W6S?lʢ<0UlR)}:(g.Z<ϋb6B80P5:0[3!cwǩg#֏kQHP3qJŕlгoZЌ,W\:H`6a E3kbB $N9J= Nh9Q,$T$#(G0Bxhg\"i3S >y20Vi*LiO BcUk'!R]k2L>,`P85(K$pP@81C a1 a:pXf-sX$~U^Kx?HאOd[o'9MTpc/E˼T]r)}zP#7B9ae0DOQÚ[1Ira:؋?h=C,)4lNm R0:^ BO"Q%P]lS_A 識_LA௒HO)>),cW9>tH4l^ $]mљpöLDCQ$ 7XC$2(7?@!RQ p 7YXpڎ?V'x@5.IȥT<UH|8[SPRUG^@@@!tD`A'Dщ w>=?!-:p>C9 :C3c)U1lj~t_{,`)$Y ?!MUAB)E'&*G)B` VU(C+^48ZbX M8N!Xפ_AVaQVƴiF)`M|#569P9#Xbـ3E|ۼ 7^0ŊL )(F AB2b/6 D߄LH 5L@NxtB54.dKIXC~JBQ~AiBa,m"뼐p!7Ī=IO7Q0WI8 |C)B ECZNB^+dDU(@?8t$!5@ C C2tST,:"80hR?dWE)W #@"@?xHQ1TTTL"1@~t; 5~ ЇПV|@pbfx |Ft7$:5&dU?D :dûC8843gC LL_X^_G2\VHC8,=X %*q -,a;^x- REIdئL7x@bFwPpCsCP3 pLWYNLRBŞBYfV%$~=RK (b]R,)XME @-d0(CA(BtCOp#уYO`'rhsD~b.œ%(ZT aUIPe@lT؀b||@*\(,(AHԈPm(@Sz@MҩFd{V١ZO:0 ^KBEJIM*/ ذn\%+"H)o?~YVŸΫ"P-DiTX@DbƇ,0\-k죋Q̤@H<dz6-kLvU@^e YFkܣ <|D =LxەѴΉ.ш@fTŧ4Y DA~k "H ,4H3$hl+IN95,X3XC:H'ELdxMuF}WY a'VBZ# /]R?THTE@d)XS<|{VSQxDH8pB4EFk A09*NmA8܎r؛rC-GGXqEWS|`|/T "b*Q }Ϋ3R: ~ 'pT+T(i$.H 7(@' i$PPЍC(5k\<=$V]eh/>H=(: U@j* Z`z'bb$a.X/TpJ)Gfji2㥬!D/du)h!8C0X44%!PrD8V*'82 ri fQ xDz.F7GYVE++l}#ĠUl 0k"w{HV([Agt=-Fn40e=7cM<)մsrtd\q9fkC+O/5SN UN:W|a ‚.%(63؃ &uQK>75}Wda P +)nxE D(BgCOIEtAZTUD1[Sʵ.bE\dgqx*HE3^AwcKNC3:\,E7w6Ń4DuZ@3(oiPٵic D@uAzB7x:8 8j~/l 'CI=C>pOF~8 )xHrST.Я`Z&kaW;w̄ Z'"?Tٟ+n 8BB !肱(*A7DoiODpG8=C89?uQşT߈:HAN.W e󴽨"*@.-Qu5RRw9X=G^ͩt@CeL׌Md|Y×}|:ɸ UU8AVdZ λԤ1 k\@8ⴣ#QU=ЃKԏo]p=9c %>O,#R/lwTA\bk ~ۦET| \M7*85x7w5,C[qOн2 D4PDk!J"| X`ׂJ"ha6`.:岡7`"#MkEJݗa>݁i-mYy{:*T.ZecNZuU觡Zꩩz.k %q~ bG #埙3:e鱧l2nm{>>uw|P/|ji~M~uj>\q,b8'^enLn^5\hi!@Zo)ءkTFy("zմ eh&"HFЩEڗY;{N&tY'[qAugrF A ~n 7.p`ːAPLLZDTЏ ;*?|a.7dZ{}8쁄xtR ?}R]84SX:EAttDrxF+8#I?`A#@aI##.|!~-]:# &L 7~"Lhϥ 2E iRW3B~b4)w-ɀq =pQ)X AȈyG0DQd z R@G z# 蚤Q T N'r+bFP哟J.D pR3Z҅XHteစD'∉5xBfyTL+di4 ?Ҩ@1H plTX- :=u#ͪFWȖnv{̚ h,OU0ku+M,d#{]Cøm5){EJ_J5a:aUH WgXN-Alm1pYhëС>6(Iiֹ8tȲe[6[W, ҂\H$4bUZACQ] F9thK3Ki ΙXC{#A`AB} Jkt"I2|,<С8 HC(|+ڍ(^Hiͷ@ 0,A=TDs6E.[Do*2_  )U)p}g4-}je Ph*.F x < $Ap8m:n\me‰F@҉N+" t)jkp0tYh"R@U8D  O^@`:€`aˊ'%A`a@Pa!;IgD a b 22pP ~G0C*<@H4`maJa@\mЯ;(aR+jd>셨\ 8uqP/hd,3: ~a#ZL7 00mi'nA!Rbb0n&p*R:f0DvsR@ bb 荀|b ´H&()aK A'  P+mtf1p ~+p"2`q 3 k` € TԠ ׌ zb8КRR%=QC~g-jp,|q   bڒ1~ /rwQx1.3X"'"Z(f 33as6rldlH7O7 9@ Ris5s.')o*k~-&i-BIB"@JP "6 !%:(3fX!F)" .3-@,Ss;7-Bi@ota{Z `asZ|xXt'a{\n'KM&|zbz"ב r+T)pҔTjJPJD " (^b Dd G6~*P )ya )t AL.@!# z A,B:Lmē '$+.Aʡ A)%$ΉjB'>^. -Tbr " Babޠ jah@644 r_kBW t ڠut3Fd*@P)0+@;!A!8舏4b Lo`aRR FCvѧ$a aA}'lV&(_1`-:u:b s Yav |v aJtygێcy[g ԍ +pq*F p 5" !@8L#=E&v& e@RB[4A@F 5ָ "m F6hl T1.KrvF@N1eX 6\ #J$i27M!C+ @jD+N 4`!#Ȁ/"FB!K~c&$8 )RTUK66wqy4BdA_ 'kT +@+\bt=xIk@XCU%q$`#vx#R#p.]T&'`0nj)FpC `/‚%uY<+@HUJlTQ:kLeV4I48>k83-Mjx2~^ o?.T@ z eD[ad95i/)A.k,9g-pjPCX% _V/>ഌKlR:!`Ax@o5eA 67hj+oewUƋ p^i "*alo# l2JA4&ͺqK쁢8RZ F/lo4Z&yG?fBI `Gv-\i  x9*HYlGUǢ1|Y` :T!h0e.q;l x:Ȁցz9_JuġĀ¡ xs.VaRi63!HNa7& ;nK]W.t,B urM?執_HE~~QࠑǏ!::VK:{@AVjf_| PÅJj@j "~0Tѹ x R.*p@N`^7_tD6'~_[:2#@= taF!MRYbšA O&0yR1>۸j =*bjNZ[U,Pዺ{ "0["aY+sw +8|k#?4*@! !XKr!W%M^yr yr-bsLcabAa Vk;=Evg:1S`d”(.-ϔ%affD۾ԜHFjx$ ?56&<7B{-qn*x=|3a=QaOؕʍb"/ŒCBn}aq))R3tg0O,M Bl_`Z,aDOs$J}![Υ8P%\ub-v,&2ޟF"ȱ09N(?r r`zaQJ#b"#tpdCj@|A-W6~ jA?b Ч&  t䥆B] b xGA  V$8$8K! Ϋ';Gױ;U8"Q|* `̞j4[ "1  U# A~M}L&!؞C&PʚfbzDʠ>q? !g4j  6`10 4JV>-/;NF 2 Bn-f :|1"珞xϟxЉg$}5;)2̙4kڼ菛}z.{1 H"g^Fą <8Mϖ| ҧ:n42RXHLΓL7#no<_{&\&ۿ?POD$p N~>8`J!^ Bnah_&.D(` H`5f ވS2}Xb<dBI~?$ (@ Md(>:,H&FɜWdjn 'V"SPT(D@ata!4@4Th`AV& @ #L=X'Hfʓ}Ɖ.rFH#Jk}uՃzE7@A#tr-<3@Gx>SZV4:># :҄*7G22Y36fk?,P:9qR̹044dpS- Hq.,t2,$УaH#~! J#L94Nk#ad5<-ȓ5-`S8$NSj sT=) PAv۳*ٮ=aLSrͦ\!p(H,]C$p:8-.x *4FKMPCuAuq5Hv^cPg7t?Po`w!lO?Y ∦7B.B]H#b8<D !=t 1)7Cx#TRn4c(2"3 {C.0uHHkp0qb #vdC( ,zb#>Z 84lmz#s d2EP 6MrЂ,Q҂ ,IICDFTr LJl]lW*xfh?to/g"H\,& tc\2Ltģd3lBs6 :!/ωt%D; =GJOPi΢$8>s-A7d̄ @CЈBt(E/jьbG? Ґt$-IOҔt,mK_ Әt4MoӜt>#SNF.O_aacb%kmQ&d J[玥}FkV.Vx<=3rH ftDz@EtϡHpN:h0x0'䠐'brMyJ"Z@:ՋVOh@Rݞ/@IʞyE2(We6 7N4W:1ސ>V[ `Zœ6ChnO)0C1bPh({ǧ^'i=F( yY)@҅655JK\y6GU[6- _RhpA?H`I1NG-o( {D0R퓻xnj(( rN ? C)<q(@Р8xx1Q!ev{Q6Ɯ(H.mtL0/|`L<x(Q8xW}\뱀 cM=l`hfBdpvP|;:P 'e5 {u9 Ip6ê-˲̃O})q>eAg* AiΝr|`b|PrC{EA+M<q~/oݯ何LN Bow߸ٿ۠~wZPf|X>HNHBP!(oihwBtlAWƁ%T#}&)H! , |C H`*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜIs!jɳϟ@ pMϞE(ѧPJy0WHfuX:Ug ʶ۷䴰lvq[1@cđfJ*^x|ulVlS0Z)h\@5 $r3!hZᔑͻ/i]_ ;(L `1nOHz蟎(RA ,0Xleۀ?I$rȠmQ Apo#8U0y A0IL!`Alq105q# 2)̞@$)(ćB"8xJ ?Ȝ!}zD0i O= (kYBA !.! FA0YCx%B.ddQ Bv,X :ʘS8sDlB3zS_Y@p\G 2]L!)v ]tJRND%zZˎ4 0+a$ø_)D@-Վ2!?()&F6i?upҭE 4R6lG)- @8L.D+CذF#O$rQV?PZˁH-ѱ 3j4#װAXJVD! n`*[Gˋi NhNZ%%Ve(n)1ӧ> i(%KW.ِ7( E ښؕ0$ld'+-H G9R!0=(KR؈1c}28eOU uj Ee! m.H"d&勯RN˼ .C :j sIn9YCb,EkYN(>W2RpJ([nĿ[?YF( iXH,hW $sXwBBFD]BlؐvRNy_XеB)0XVXs\CFF|LSP7bF %_UVPJ2h擇 2㨜4g0<aĀ? >ȕIs7RS5)`x*%p@qGl5DX|N7ژ"&IGR@Say>D5QVrp` )2BU GHYMQB6rt?Ƨu |Mܝt#ܼ)ԁX @X@1w i!m @ glVϾoG(S j|Ir^pdHdO.AaE o Bi8 ?.7 ` {'#DF`RH*rV {ũQ(:`0qt-*wllw@~ϼQy{`"0W?`]O7ɣH~!Xp69 8Xx_=! e^e s2{!mL,ٰ7i4698 hW|a`r /5x,1} q 2$сH adxKh6LR8*q\ae#pBnJr8tX+a !ivBO}݃~ȇ* _WN!f Cp9)N_(ZHlpyf$akmwFfa ۇyɀFR6d ^g #1_b|!|+|$G%R0<F*>bT)8(1xf4,PӸSp ް86L1R}qe9Q?~v` B(GBNg&*nq[,Jwf )G<2!{a& |5a2T Eb5(Ua*{t.q ?QW0)wN d Δ4$ 2A%BU vCa ,NHȀnbx#B2a|Y?5Yf aXׄi}P*B`[ ءz7 7GA EkYh|C0($hy`Qn8vqEcXH9$!6BVR`$gub3 7ZP&a):TA >[WG8 #ԢAzٜZ&3Gf3H0nz:Qwx{cJY jJT !2Zܰ2rq֋KWKy9VEs@":071LW !aYQ!Q֠+92R$= m Mʠ!7l<ذ V( *1'y 9q#"$Y!@aNQjj2]$5^3'r1; -%6A#Z]NB(-p&#!|T" !:I!Dwe ;c]]7@],~ F`!GP< rC޹<ڑJlPKq[N{3KdQQGn؞헽70ƘS 1]ڝ05% q ndO8᰺OQ;,$q\L۱Prc"@F (b*!?7Aupܾ8к&2} xO"jh($d1;\)&<rwR> 7!y#ot PR@J7 :pkQjЈ]PN`(Cԕ%4_`qrmy  vC%DebΠ`7p/#a<̯:{mCb+1$JN *qڮ$U",- ǰ!|!(hp #}/@:UB.@ qQ@(aI "wO@28WB >`E=~RD#MD`I-]d`5mĉ2ApR˩ RM>}Ya #[TU+LYVXe1Vڂ]a َz`'}8(a 5* ymHypAOrZt ?<,סkX%Pq{g )o0.'R4蔐_:6aB7wb?@n;;RD0A+H+hkͶԔO0$R!. ^#zQxr:HHL9!* cp ↡`,Jm p]S>iXl@ZgnM*,MڂZpKS-Z% hk:?*t h +&L: ZOD.-ABR>Y"!2oZF *& ^g'2j UImei0:$~JϚ.}{2IphDu5!F_CAρ`5AvUKIjBcY?RiE4d:\3b8z)Av#)@NE@wQgiN_29ި)d? ܍ #wUdp @n i%ڒ?#!&4ia\f?UXP9͸HK t 0Fpqу.|I9ЛJ$V!hmq9@aJDT IbQYE|S ]qE@!Wp H2Ղ"Hi."ɠxcX@'a8CSpF BWp-drG⚐m05"6U^(8m ٍv)3! q˪=JL890Ib ;PW=0SB 27_B"dy ty=Oa}ZIryI) t&ر 0`L!(j%o" 4AOTH[ao_`&_'FPk92[GnA"0?Ӈh "pR*?JDjU$̖A*A+!2BY oDb9[ HҶ=l5iNfJg6R\PH :@3(InR/(^_V4(>MVQOH0eM4C]Jw\-P "TfHT8b#jn,y0S[@mrm,7U@fKFA&=^D  _+@n|9XxkV/6%"6$ _&wg=v 4|g&l{$gLLМŔوT!b!`)x@ЏЎ j|.p_p< hFLZZ@ Ǜb" wb?%,@AOv|+wi\wһP" kKz֏Z&RO,ߊL)U!\ Iتp!4}?}Z%cdu[Az'Ql#&|l? <?ڳI7(x87S %k꠻!p-Ṅh6 /(3n8-t x'x1ˉ=( :1h/4)03k?F[1" 4b[kකz+2YB/*Z.$<[̐S7Ak&>&髊&3 K$ P~P?t q‚(gX# i]8) J83gAqś?c !pA;yc+c Cx [@F V<Q\G>YgƱ;rtGYǴwz,;RR<.7D{D0x=>ըۊ/9DŽ 4 7¶ۍx諉_,pxXh1SԴK`kS96@Jɖ Ij**ȜBqqT i1(Hȧ03 \ odH] 2 yuHC<(ȜA8I+ l˲2ӔС \[ ȲX &hڃ4 &ˍ4 kR[ 8'; f#P 2r,MPCP+2'L c4F$w%Ԋd<@!I|ЄX% h 4 4 PAa ÔJ|BSI| n>u[#' B1B*̜`  Q/ 䈅H˗]P+- C /-)l Z/nЖ8qeP{OBR|ЄR9 `QӁ{6v4L )QB:Jp =LR90EPN%38,Hܤ"3؈*!4A _ T W-ƙd!O0 1HAԋ o>%49`IP`DQÚM?m EY*$׍S;L#sPMQOL'􈝪#IIݟjҁ ё5ٓEYdR$űWz0șHQܰW kֿ֪PQ ZD\5k B(L"Ӕ KˆЎIt: -S䠒!XNp @ҏJP Z9#`!B+E@tU2?0,khˠG՚@;\0-mÐM%Лx!+2Q(O:58=,@H)#2'iئ("\)˖F*܊ b3t5 g套\<Mw̹Z؉أA A =6Fׂ@ `|ʪ!_M^9:R(e0_茉}X!-. >`Nx0DX/ j5 RĎ#aZ舒"J9 pY!q!~բlIX@MI2m&,%N.b^9GՔh8Nd oZ!Y }TpX`ˏ9[#=dpNZd[$1s)HGLɵ[OQ@e]8%]>eHߎ( 5nj6V3 ЕT,;}P wljl>3@?:TGuY\ rPXsrLN/EB07X75Y"$  R V~J<(Yj.%f!`f 1D* 38Pz{- /@I@x`uЖH  "O/sgi9G0o x7Rp`N*Ơ:E} rxt90ꦘ[ݥΊ Ͼ}葨80PpȆ(X/`ʳ n h „$0pˆ'Rh"ƌo \!^߁)b38gJe1d)ӢBhhr,ODO] 'H(j,ڙd"iҭ1ݼz͋R LĊ3VV# < E0sA.m7{5زg&-Bʵ+̐ݤut}D(o#O by^џ).aF:>cЖ_*Bo{ ?LD A,Dc3@BC ^aԛb7WrBU 5GqH^ !T"BF`_1Gd_BS'ÜL+,qixc1!CJji Bum%A0T?>(ǍiPORDjNɩP3 UY0Y'EGXI sD|vPp3AS_9OjtWIb5B\i!z^t@n TgϦgkQB,QMJ$GP& ?᱃~ {o]}j-x.zѿ?p 0 ;05V+B-@X 1[Z2v(D-E:,0Թ y0[0e%M};}]]L VR9'zU:Pٟ?٨ljMWe0Hu@k@Eu Bܰ43>y_D)YvB"@@2$h2Oud]@2fZo]c:3@wP4uBQO[ 0:%pÞS$@iu9cub73ց4 Y4s)eO/?$joiBV˶бŅ'K=Ƅ,|! c(Ұ6!s>!(!F<"%2N|"()RV"iQUv]". g\m[c V2FTeơA$D0'1"~٘r9?±Az@| cD.!87I"N}(ň[E@JEa ۙEx03p`(  %M@RI5΄ 0"˜xX4Ftb(s4]cppE|KHSt/#},RO!Ĥ?b:!Q6%$%L z e?Oa tw?`(? iE ##С€ C l d @ Ѣ@ Ky>ɁsP0J, ACKAVd5/b|2ԙ3! R0/!!6bf XR %?*t-q3@˗@~@X-"M +9R墶3P$H҄ *JwɌ!DoaD0@/u3ҤVRY$,5 [Q.\@R;^-?- U}{ 0LEHd-zJ!$ i?;Ď"^1哳$ &i^Ҟ..h/&`%[Qĩ*L 0]t005z@T2U4WPo ^! , rW H*\ȰÇ#J3jȱǏ Iɓ# 8ߛ@I&ܩ'OAQXB ft؃.?$ӡ5[榜~4]P3@aM p#0-5̔nA Oz"4 =T8ߐU茦F+D}8JrCҨ!5 q[N6,G*WN3B:`(7F3bi&0Bb #aa ,p' DELG*cM?z?:G&'w@=Њ$3p"B+⶝obet4-}_pWd7q?SvIMoklw}y#K _{‹#!!!`mwo4#5ZqأwJ"j8<pJ $I 8L;"УӴ0C|pl<7 X'uc{HRH~(y-=ʸ */43,tpBe#N۪@cM p#!!tHXP`aP~&)A*^H,x(G^6$P8 l C|ӌDϨ/!1tc/wQQҰ3XC(T̀Cqix qiH F@ ]N K" TwG•| k?2q8cYu bWX\]g$7Z?c &6>D|zxn0v+t1I$I"6l&PLt'Z3 2rЩ~Bh!AYj{?/JӃLǂ*V'$B:R78)T@tH̪Rlδ`IF.C̞.pk"QHdJڮ0ʡi,e3я_,DָRL?հtEָn`i$L6"4K |+~10D9AlDz?(OVԲ\|-]@$u!>qTҘ -q@a@ܻ!t"/#oUW\F##9QW`$#3a. NHm&S\VȤtՄ0{8C!$ޱfn5 A9YbD`#H#;ojs&p}uy+=xI[&O`(T*筲Xf_E0$Fr]v(YZ?$:{yMeIki$PBpFh9! C" &FO$HٯiH: &)4Bq#y'T@=Lu`paIqf_ _c$ΐo:HQE]YkmL6{HpH`n<!>H,{YtLyg^%n* A"P\`tưaIН!mO瘏H栣w$~g!x>j)[JmTs)+k|=BnemZ}V![GV:\;/+D yMQ=y$tT?i㝕,H(P 3*ebߝޱHb nH #T@lbnp:dP(HIcHF2i`o?\as1! ݅ jkx\#-@❭x~حA/qd)_w#t;ǘ4Ȑ*)d- 16&*!#A UP(UCñC( |w|7 p 0"j A;d@9e8v*X61pk$ !)I (Rj#H5 TXpZ4l RRT Ex? 4K"fLbM'GwTuSXusudw}YiHg4CO'Nx 6@4u_Ƈ7Zt(tiGGJguŧ6ӡ րv U0Q'01dS PH hP<j^v#! <sx<4Sb(Q(4E7.p&# Cbg °(8#~LpVP`` ] 8"9B X0 e '/G?" 8c0E*3PeUQ-d-Z H38jD$(/3$* +r'MYEW-] jjbXTnen[ #0.GFOҰ13$hT46h9VvPNTvq4+(y/ꁋ?{iщh]F%Qv+0ZX1SWXÈxRD6yM!*uؚp Q%у( %j EQf 3t P*֐#X`pEj ###Pbxf8R{KLv9vyBɚ޹R`Bt &p1 tPp pp&4 pH*p9 27yq pB @ ZXrܠ rБQmLGB F^±E|؝:: 0t)`A pԉ% pۑ  1;`$g42/ 4"PE{i#}3[ZXTP9%p0@`8 #@u Wb PdMh< $€=*1`P mHjpbմN*SKe8@q0802  c 39A2,Sp9o8Q XDjԑ"#7xWV8p;k?p4S~I2\^c8: pU; K@5 *P 9H  v%Ubp !G+ˠ,K !v{z;Ѯp&& a5063ax:p>hPٛK!J93T<}1ɠ3p4 t@$Y«NJۚ‚+c0$!I0j#90W@(!҆Żҷ49 [1#p*za*xzo샺IO2\֐ h͠ %?4õf&ȹZ䀺 * j #-a@hf{ @ct e$^"H"ZQ-6H* jp;f H &hpt s#C0QaC" [^{{O}]Ȝ-aIP° W j?:1y`Lpp%@0ABQITyP`ivP6H96=-8nvE5p02'V,ηX3ENsiUFdK̚4\4QA;|LJ3vSN皭xZn:a+ tW aStִ9w! Q¸ #ǡVƬ)#&ܠkAT 1 h"#tu$׉LPKy$[/?=NVtYPkD 0ke Ȃt98 PUręɅmNacditD&Vsv @ {! p$$戾-`H0%h B1EPHhk AՀF2WBv%1C3Jkb|B ޽ 1ptrHI ROl+  ىdpъRX9|W^0=ѩP }Bw*ж0+ƠUO{ X~0luɒ=I1d >`ʽvSnlZ~.pd^sY%!MKQc` d 3x &- ɠ~3GaPJFK 8ST6o ]h;+Lt8]VGs%1jflOx|d~ր~O|i׎~7mn}QHHI$3@ݏ9 ~g^1-P-:69FciSVjgGր7KE&DI@a3|E$3@d@`9D kJ   >@87PpK}@A?TО4tSf ]:GPF=r?LDRJ-]SL5c$ 'k- 冴.ܰ\ 7HŚUV]uʈN?aSZ}ěcf$uX`…s-@S4qS`ݐu1`IkKWIӵh\JUNW8X+̟.zR'mCqC1ȒG\y`]XB9Et %#:HFO?tD'?{p w67#Z@D0KӃ0B+@ /kC?\*jA %П~~#F6C #C_$Ȯb(#r7s/ J+oF{ūb@H aM%q$Hr+J<?|R!8:@?:֞Y ʋkI㎟%:fD#za:tGWn˰ipTIcu~5d\zWpMZЂ:x* H,Q+P д'xx~3z~2j>zfoF\ ?<ܼvl=%_i=xpWuwRd0qӗtF Sn8=iUG!F%RѻJT|y>T*ph0,Et tAQ!^ψY4.!3ck%$_@hH$k@B8xa*xBF,DăzS"72"e)^xvAC @(X#z ,a k VaY: ,S#ȕSЋ4Np0tq1E jЂC`qy`!N mPXFT5l4!A)$xA]υT& j*~KD~T2Ft5x$ ֈTp$5iP[tA*4hU+{#5Lb,X8aΤbP"O4u'T`_4>Q7IBGM~!ı5/&f5©PAp0.0PiLԅ9.jY!DNYc?Ȫck`/$ RQ}>qEQ6XXn !K/Me+2 q6TƌxِxEk7 ) Ϭ z%0 ը{![ *⢙r[!qSqkI82#򭘖;6Z @ R0W `A*Dm|/$UF~vg/|L[([@Vg-j8!a#pmݮT 3X H*<.0HK[[kd{H=b8PT*N`eH%|4@[!:ī72 ƮckM 3ѐ~N腫mpXC ,\t`Y@I[R9ಏJ㥔t tBc,18Pp3ƊkJ ~:yD#78}{g =d[ ꣩.! YlC*F @jE& 8i/ t!"M9BbuHjnW!felN=tquhxc}@)ԆuX^(N6X8uS!s˼ }8c{IN7:EY^ +X(BPʩ}i p(ztKghBpg `Mu\Q7 '!hS xփڰ"{$i2"܈=i =KLiK#ңݧE:OA]-E^M7X]ڥP E^U4 cMM iD_HhTe_ۅ%`&6FVfv M@ a&%FVFĉ! , z@ H*\ȰÇ#JHŋ3jǏ 'v1ɓ!Ytʗ0cʜI͛8ss"@ Jсg|][JJ՛Qz3կ8_heEqf]˶mL$8Fnek߁~=H`ÈO6_FBY^|_I[Z"DSװc f^2Șm؎=ȮT+_* <o'oνa^r|ӫ_Ͼ˟qL _9`߀U'Ru@nPd9(3 АkR!~(?d(QtVQ!dMhE8XfT Ub,DH$bPF)TViXfZZ])&A0K3Lsz~]\,4C9W]9)Wog0kڳi\S3[(˛&KDA@8yEp7`L-"|G0J|'H Zp-.A6LڠPVщ 4f#UT  Z0l썀)  t%(!2*ҡP CT+CܢH2hL6"$"B|?7wB&gG]4+^D(^HYpŅ'qYF#79 r (GIR̛XԕVoH\I"!kKD!i'{I̜Hrb:#% jZ̦6͝,BwFXp< -fqnRN((eO lH  -DI͉Z'hcM Ys44it$-hF>&TR1eJ-zgYdp\(L"@t?&8MPTq/VBr:y>?$tKOፈD5`c7#MT!I 7XcN2%DOJX(2!g:Z*rxNT @H:Oz'+I@gMߩR"J`2!hN+',Ra1C:AYƌGC Ġ$H,B+RYId;!pJra0i ԝc :ع~// (9@A/:?P .32kBxŨ*1,za⥂7&{*O(B ҡ,"@V 7" yR :kl 3!$d;-jF^Zq1@bWxey"pMQ4D 7# >)UQl+C ~8=06<34**jzT$I71 L#` @)fH{;kGaב: 44FW+1z #qJuq 6+eho@!Gp-Ԛ'z%O)c$X 0 ("uhrLK_;%j=n!ۜ7!(ѰO1aMA! "J;"K?9 _ \˨ Vq !![5w9\' v8qP\VL{|+"\\mmAuN2 abk )RQB-Ha % Dj,\ %3B&UX9LKQ5q~Q!Z8}c[2 Q6FMr4Tww #w Ov1Z3:}8wM6 m?!! Q X{1cx0>6~Xd$%1s|d1B$$nz᡼!qqIȖ(1Ű]{!6` 5֠0a 谢u@;=Kh#1m6U9 *谉bS~;kv A.Dk@ uq_PJQ ϰR #=Ʈ>L!ֲhl=@q3^VI=]'zm!kuԄz{x>@@Ҁw6< . ]*#MN\5(ID%11 7?;!GuJ"4(}Ft9GNAkQ[DM;SEICѪ^6/%F@}mlT{Nf H%a` n?@I3 Ff s\<+V[ DL'^~^.TV%P_&qp u>]4, g5n=V[8 cBC Pr0ELPրP`B!5uT냀?nLG O-8x5:}`y@˾B`t<0CMO@ DPB >QD-^(D =~RH%1aRAI+]aeIQN=W,JrTR 4@tʦ^Śua TܒeZ!ʾj$xfo ,k˝Ԝ'L *X eROFy  sUbPFtDKK:u:,&s vJHۧ) @PoֺYzYN">J_Ξ#ԓ%d J ^D0@$@D0RA0B 'У 70:1't-D{2zCV*6`Ho\<ۨ&Ra MZ*_gp\ʙ OAJ-KB%2|,]ȏ-Tk@M9IN"4;, 调ꄩ9Mģ =yaQ(tH3@2EgQS(tHndQشTW@GK WM$z &jݵX[56ٕXe=YhZ[[oAo%Q"9fu (wql̎uN@۳~r` C-x2>ߣJ$(4)@2׽P$ii) B -zP .`#(A  O 34BdEI2!@C Y|y7 LIQ! u6Q!VB#,NE&}aM! , |C H *\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜIS၃ +Dl11:IѣHn qTX5":̿g ,ٳhӪ5XOk:vRg 0 DCr+^LTaO-(0+nڐ]ioȢPѸs&0X_`ayߚ\G!m@M`G@AT]-3OPAq¸Ͽ!WAt 4DB P3 5'd /Ƣ dp p\X$L!YP,2Coı,` P]G ?{!23 $@ zXP Q,7yfxVPqE?L0Pm Lnf δ1=ad_V7BmcQN dcB-Y 2e #e1%D>Lz #@, Ր5|+$)BPwDA`jA ΍2T,'p2D] #:B# qd<| $Ko~Q8A-`CB`F-|C_k[¨H' WG0M!7CH1B'_ <0^X #\Cnh*{A&$ҩJjF" F?ӤfH aL?dMHf[HĆćW+}ZLKDlwYVCF5x\ 8>!>ʖ1dxu"т5GrS#UD  1#q@T9I,N>! OF!B dIcDbP@;f!I`t)Es+5d32TQOlfDUqA`, ɦ/.Րp( :0dI쩐_v@5(u  U (+ Wr!PD<2?|8*>? 9̓JUB‚$R @! ki`I0 a<& _// yXb~$pD8a#`0`B X=@!ϧb -Cn A;G|!8FQt5!-?di{`Ux;]L5o`+1PC0Ǩ@ET/#V' .P2(%k.eT`k PJ lgfs;ƕռd-xX,F S$%HM\8#/[ D-\2c3&|+&}Ldd,k"L X uBH٢ MHcQ!99(G舍hx! B9$#AnMG[e C?k3kc@

Y8OXhYDx9CXiG5 FJ-@ 7E-R>$2C /. ?aX!S3tqNm wNH88=RJե{! @*;P/dΓ )0kzoey8 H/ DQ727XH0*y 5j7Z"+0+a]çb )y$2#H4/+d3w '@ZFNRI~QT^%%o6{"y" ?С*d(YGBDwrFl =@ Ie##ΐAn夵Ud̘"Yx y3~30+I *<YEC.%uXxA##"~cq _`y sC ENdfޡ}k A~"m7G9# uzx0UG;,C!% e^0 QJEsqEPCD)MW-]UxKu! z~}a;?3TU4 ."GJ%n q'd  &C2" i2ǀ'! mE7$zX~e ` (w&4j:r X3 |sT4s sA/TJ 1=0]Z6yL37%?l0vGngD"$,P1pJ8  q86t#5(faF YR1s38IwY5qnc/ `YXT8/ˠ9%gL2Ia Gx7#P 8a-1)XS=# F7+8Ԃyv܆U?eW9x n:)p }r&juao(H@1U[^Iwш[|i 22,Q aƲ paဗ Av|UI@n1I)kK& NpY~=4hPH wIe?15␝$ ?r:-] kJPeJiq`:BHi(9y7ȱH " Bw+sA"?n Q APD .ZDayoc,ڛqF>,:4* BVG0a5 R-4jg4[ 3o&sB ;`IQG,Es+Gv aq-7Cɤv!>R( Sk Qh lGaq[Ya!hG bS {IsQq['vADd U} @xt` ٨-0Sᠠ eȨT8@3 6. b(yJSq1VB"CU).: 5` 16jKsA敥{x Pq[.)A1!+j :9. [p Q:ZYC].:-H؅ T}:$  r z0U E:P:$10#Wj:>.Y J )x YPiiPKdf17Jz1 A1#C /T)WB6#v*)"Kg |@;B8W!Ҙx#Fzp i'KBK(ϴ1"p 1#+ 3Z> #=f˻ Eac1;gWݛ60ۿ A{6*?~UK aG°: x@/k B.Fd1Wa g[6$u/ y{'kT|b7ČW o=,# 8Znq;@)p,S3 xQ \]r &%^I|K!1 %EF3AC%<. M*<# P Kf"4FѢѱ;RC! W ?5BxB " @A *E% /q\SL5mϚ8aTP7%` D>*ĒU^ V]64p$1_ mJPETB`x@Hi>8$^8n LOXNtMc┕lY=-,E@g:RJ@.@T޽'M˔|BlCn!s-.OI _T=*`r]n+ Da:ɠac(0:G}!Ğf {`g]QÞu'^, i!2@pFPÚ gMvIϪ:**$((o2ƼҀ񲡸 s!ʇ0rN.$ḧ ,B ; (B\şr'Gx%i_Z1UfCN1 L6QC(,$I'χJ’ (3@i :z+EM ]0 i&̉=Haƃ6ޒz` ,**Ⱦ5Ĵภ;IaCISYg_qqtPGUaInf!`}nnG5|4QX>Gݢ6KJfJye2: kT*% =sۊ* g76(R~Ni ]21CEq1eYgdI\A i~!\xUR,NFعI(-n*":@;?-qfYI*vGi㽋z=+Hkd B,xy{G!u[&_՜F}woo^G8}%~^)`q]ĉ°rlM!j`@ BȉK@8dK4?0u[ ZuD;xg? @шG[0(g?E9 "ъWbxBd8XŇBN.lBXP&hI HN-"/:@ (boƨ>-6R:C9IJ$IDbg!;HBeC:BV&Z8GψC-"0,u#,  |H,RJ& @H:pjv SBdL #.oC @ADTr8C)Kq`f2pI<[Ҳ34n\4FQ! ttPb9f63I}@PHI!^2D RxԧzpFc@zlR8< D#hQgW:\?P{PC֑"Tmb8r(xA =F0k*S0J  H=?!:UeO跃#:9Ա/j;X%d HRL) @r 9)e,y+\c `E R҅큻L^8|!<)Z #@  \ q>א׊?I2-$ )SX.yL<@{EHnKFptg"n,@ uW1D<.-VztRlW?icV1{#pЗ1zhQ1@~6!} Ree|e9Lhc9XMl'2"W#An 0A,:*y sWe j%C=U&)P+Ih0* M3]7ۛr6LmiqR9 atHBmKW pfe/{(=&hJ⼧,&z* -mDS^e 57Pfax` si$1(aN\3h#eGi<BjRS `JMiYӭrg<:^[DspxJ+H3\hX.=c@,c{УF\0]=:zkЂ@ Ky4fz! Ik 8tS@A IuU]_YAGrP ,euL9S.!IRE48 Vۓ5>E Z T<Fv !jUy˂=x=KI?!oxY&XD$R xBxkpCQP Pjk=:+0HȁjSqp,'k_0 %9so 4YË8hj0 ?]*'4.2ۤu; ˈq&_n{Bs?hʁz{f]82?xQJ1uP+:僅( (X$A "Êb+<#7h) Kky3?@(hW#kB PZk:h h S(@ Pi]:R 8~2x#OqGK hx &ia ૒%n((82q8C"Sl;F`'FkP8)e"_⦥8)-nKfL8 -<Bs !=9G\%l {pbR !xRPAhAH& HHJHS/!z1"̊<|EH>@ʑ \T29b%8t(cLfT"1ȯD WR% Tn;҄L<$br;s+Hɂ̅CKȂIC,bʳA:SZ* N`G)3_ʐ#t*B NQIkJM(ƃ@Ĺ`kx\7l#Iuһ0CNZe'di dp R)k(!] 4edA,-젛)xʈx c7rA1*rB,!(;( (5@5X(+˔!X Q؉q@} $O:ߛ?Њ)9vۂ -_&(C8H˃`De`?e$B8S- ,.$[i0hE5I猈(h GcT{{ k!:i@O<i/N5CpȒUla0!Jҁ`?قHP^\c/10T]q(`!XHX@3, 5a2Xu_ `4-Pj,}"/͵nj0BUpHuÉ`U:`xsL:  G㆜ @e (H`>nPĻRd[咄bq𕁈hJtA B@,ّgcnH3<(9b:|v*(5F UTgqtȍ3IXW=_{+BhSPA[z!4T $j35̼oY2h8とF%Ȩ3 .s3US"X  g_@a0W_p zxv{ AayN56I ,^T]JQv m <W?(b$i(x`xR2p0_H),- ~k%3g!( 58@HVI jHQuN*V%hPn@in&Xeok(nݮNI؈+{uD O>00d :1J2ZH m`I(]a~J"}ۇ=V+{臰GRSW)&)X:@pXЅ# ]cp ҩ &VX$a=ܵc'8MSea0<,0cġ0,OBI:ݠq:n;H p;zX!qC3qksN60 J pu]>lKPdKaiw՗"T綶s'҉`h]Itg4t,d\xTj7с"ޅFP&1q `zp\~9ڇAQTʙU$80r!,@\WhD&}z/D7e-k5\0: uF$k ]X{T[Rn/C"!ra^ d^Qv c݊:bm<bf\|iE'ES@!P(&oIưaruS@5 Hl=Rd/qr?ȨixꪀH!;4gH(M~ك)I= .KYAu~(IlZb( _N7  2l?&R  P#Ȑ"EiҤ:M<׿1'gҬi&Μ:w'РEt'Ad-Dr$e*r7BЙ ˚?ɖ/?i _k.޼z @'iBBkv!#dOȭY?()gƊD0QزgӮm[ ₧"E [V+|_]g_}i߇^x/oX1D x@ bf (V3uA yFQ9E5XTt`Q ]5Q?p!8"%VN[b-X] 8#5rf"9:VT> 9"v-"JU#Qbv#UZy%EF%]zikΤ[1StwfXtsݚKלM#*,D@ E|&4B }! {RHIS#,( kj:"<rȡ.^܈c'c 7!4# ,) Ҧ?ө8~eHh<m~G(D`S"BK' 4H&V!vNXpL9S5ڡc=^X^3aM{@ Xr1H#2zb;$bOVYL<7S8  !+sY4Q [ЅG}3÷B?rLљ iV[)C4dE9c,֔O9Ϡ=͔ 7D:7]a *p7C`T7X2+.rʙkSj!"' AN2Lh:DS.D>Q8 @-U51lH:`S("POrrp<$ ꪨ,)/5B=!,N/*@qp]2`$ bF S*uAIv$J6Df4k"G2Ȁ*"DH~pI#G;|$ V\e+p 7>p#(!Ve}E`3ta BU(Ւ hEPRFZ@f1p4pAt,)0$1Q: $!Hʦ cC",_2F"!|GF(&tՅd$z@i /$t``"AȺQ#]׫A84e.܈G3 e(NjzU"B:i(X0/nnD‚!.\diD!kcJb"hA(Y0o âSQXV)B^nIj"9V"eI%o8Ⅷw&^hN:=I Cul-} |J)Ց$;~8 P lֵdu *V k?bԧBbB &,b5$22+diR%GD4rCU5UʘO@!1!5It$njče\Ҽ$e"I!e'J8~$q`?1֚E8@lҀn|+Y/~mrc (@L+-`h! b(6 ]!@pC@; dT֐? 5a FA( WXd٨52PI(%= UF̎[ *DG) #l g4-|?%4np6Se&& ,$O6O^!j~@|%lM]F&r!mji5&"S&m0B88pF9LއRWhq n m "g 6F0>[i$ bO^'$RdAh=ږ _x}#a"0! C8X9hg`/{X4RHHiHi͐'Dؐ}BA1vM IyڛȦ.%DMcc$hm-b:tcQĸp/}s$ z+۩8M>+T3Dz+E MlE0<=I(R]! DQ` 0 mKrl)T3>]*OI 3Cʭ*Cv =B?Ё Y4XpC,̘~ۤ"5UpDK?t,u!GCVq\H!OD\HD@LU` H@uD).C8<J9H8YAJ3`!G6QB7 ?0p^q*PFSMՄ5Ml8΂0bM(bExDDaezOjV>NDp/Y M LTu)l4D(?uЍ??85t>DZދ5p[ĊW2GU]X!p5 /@M Cѵ7*TP pQWTnzCDQu}z2"J M%WgX?\cU템уvxu؃8^?X:tG9Òv(/6C^"I \@pЇ@@LlhiF<VtMQD=5U!A~(21_ROT,(HH@V(JD3T9ߋ`O=EIVdLfE RΆ `-(Nd\^l^{**t TIԫf*҅eDRI۩j,} p dW 5[/V4</(5,Bl`HtH& U@ x< OcDlh%tNvv70\څ8B$Any 8o@p茀p>1MyIBQ(h"<ҀJ .&aaR0\92߁Fd(em=!o:O-]/@id -\?=HB2HCZd4PFaFt2G8x58ҦXĄjdbN0TfHNI$!k84~AHжUm@9 DhAoC'bn3K2Ш=C<P-lyޛ%5@6Z H"Tb*6IoihIƴkUqEpM?߅OIFXXM4& |b) x@C܀5(C*MnfކmΪI*A xH TD!SnG@tnxHHDthIo=,>>$DT4\'_5P024R<J X2g#&0I<[0u*c*(ÈV"C+.l8r6fMDNDJ6*]I'Cb.@U1F29=%V4 H(+&RK qB,嫄@ng WMQ(3CHdp MuNUĩENICd/D-5>@ρ 3{3L_sN@hT ъD[cy7<~y)GM`Clhr=,5/>@ ;.‹*HBƁ;|m#VIݫVSXAJĠUI\cΑfG/N)rdB\AbL2)go:㩖 1GXKD({$X6NLHģ~ 7=ꏶ}S<l?hotC;i(["@@SQ a` tt=kj!OsޚJ8` Q5v"8!K2ج3"ADaP0!' aCF(@21z#x ar[4& Kn M0 P*q?4nSZhxԑʡD.,NXMEa O%0EH#-iE!_(R0“dvQލ ҃e$0Jr)!@P._4]xP?!Yj Kdb-pc  @e$#p51T(#erg1r,b7' !Bܪ#)RP!Ɉ.xAG+٤14AF$pHpPĘXs`٣}aֲ_X,?~! 7 2büC踀&Z׊*".:IґD \$ȪC͇/"l<#S1RI$$#!I>dOH!k_i*q>څZ,=6dBP ZbO,V`w5Ub# A;-"CZj2 nX#ZeB DܰOQ{P3kA>B@qܑ0=&o(L)B9kP[q:dȬY?|z,Cf.i,␆v\F ~A38M|QWq˺T&;f|H!>@Dɂ9R4tDRCKf -vXۇ#5$ă/a}` ]7.JCzXv!5. k8A_O%Ht-1/;VkN9qY X7P]ҷkpcR88a $!*P5,+6$Ω4g%H{"$7t1ߓYM,.!n\!! n:X:8xЃd,5ōh n,aE c6FuJhXFqlzjU*_M7*QB!%">hH`4a~;ű$kЅ2c|/BSH7&׍F,èd\!kQn|yrѿdQH<ܼx4 >ERNEt& "nO\ XX +".pYd!0| RP_upYEy$ `i|'*"]e-IBܢ@ a(CALPs ؉ɐ' 0DCBCz"aᤈLo8A ^Anp"0/HFb.iPd2Ip!D(ƌ9€#\fBA,p)@ tX A`(g&chVT0Qe"-4$IWΰ4$:!tCk\#"\4"b|/؆bA-0n@T  Aa DAbg[ % xˆGߺQ)"|dKG"4)#`6&b|"Ҹ| @DH>!qQ(rrxl#rQ" *vHp"n#HdB4!5B'b -\MmЉ A<x @taaR[h'6AnaLB6 +UR" 0#G(jW*B!P# P )hAJIGňI0;tņ3 @n`M(a! }s,"$#QBg!ye3W3jKIBd-bAD >A7?DAA{5 $ӱ ' YB`JD "@r4aa a p HШ´:IL KJ$"URMY!kfeT(Jd$0`">N-~!@Pa!bLJ Ufrɺ %c**[9*3`W=Fp|AT*@UWPJ!f^T%&!<'n5`EBYo2B gPAg ,4g2#1fbT#K^q$ CB.GR!:G!42]lMj!<80Ml . UB M1n0 NfF @ ,LoEI+hB!rvoOBǦHP.$4ḽ0#-/fFd0be=}bVd`! H bғ "6jAFM^kU3FrҲ`@P`4"Ń V"$n ~!tAʁAAkP.F &3!~$ /`ԀNB8'AobD-7!J-eL#"bb"h@6 """Jœ4t@oCzwEjt`Dro "&"f "hv&2.vD<^d a/l%g$P2ô\% T1%z[LaUWxP"^ B!ɧ!B/F"7!vӑE#b 2#$"V!  Q8 Jj!bHւ Ol Cjod ĸ!i%c*@iSV"=!w&$<  VR)Ubb," 4!vexnC)@UqvnW^g7dD @vu@\nA9!bVxt)q&tqۈ$rH0 ;@ `!:@AJ0Ddh" "̑WĤcdDn %L@b"!2<#x "j8!4l$lb( ə' O5*&ҥ$PaIbEP^Ɯ^ B\4%{jH",Ob„Cp3*+"I"ف9^[["PۨYxR*D>I#/ut b]*EBqV&h{ IxoP=%&: %@|4V!ϴ-p-HieaC9 AZD+C$5€],DgOh!fPT)VWC MAV 1B\\≹%!BB5>3y#$AYa"2HnIáB=B|I gPv > SOmۻMF@'7(p!3U !C%Pt %3b -'mEBBFl' &01POYSC(#Ht? (  0%A)T`P3@4:VcfS/5 7SV(P){ni4eE3p`~%`GBfb I A *fIe)' ġ@<+eSKxcZ\4&8ܫ=#BGC j l RlQ_fζg0 ^^gl&QD`,ر|t@@hg4F6ȍ)K! k!RP -iZ9)F RD" -!?臈88'e;vMQ$*aȮZD Q}QQ8cET<8ueь2<` 8H?8]Yl J6A"1І{ UnmgrѤz%ZӪIoϡN$SQe>&2kIuΔ0HnYJ 4za+P1zr#r]QƢ6i.aFc(:XV#bK^c=֤pe/Y0zU%]bPm$bGW¸C%08Viyb[3eXCwZ FG$ fv*Ehf"#D6!MJubz0YѼĆC|< gHsl3:-E  dSt(÷HMF̭pt@hS)"( J:R IJщ fC YˬQ{sq.T-7P/`0X]@*QҽH!,| apb_qŋAGr, gX Nt Ғ@W _Jcr ʓ2)_ D,/=E)8&ȱ] X@ 倃8Ȁ9$-`ā1`| &slXcNB҅pH-LlTLO$H ZA{5 ŕC OPFW A Q х%Z5H"HO&:xX$z<(Fco&_x? z*8v8J0ֳ5dEѰ`1Ct(" \F}Re(# .0rPL@<5Eܘe;B%:#c52ݮgrD*Pp@X#w\}8nA;wz Q:gDh1v^7ו}q$H|ߺ@:)~xq#7|K?ѧS|O؄,e+ ~82%I3"cc~DoP]*_8rh2aHh ȀOUHhȁ!(#H%h')+Ȃ-/1(3H5h79;ȃ=?8~\Y4R{gaE,'3,0ZsJ\+Le2wp„  <@&QT4b  JW{=qA%~Å7uG0ZT?-αQ(J8g=(1*xr$%Ttl vvwr)1$;8y6"+wxprE%s@h+ .tFJsvrV#ޕ%= !=a"Q,vA:asxyx36{3JlmAN]I3y!qIqrI-HI@# a OK]qv?:GGwv3aθ8@=(J(l!b8o]'0Y#"]ѱHQ$C*gI<Q6k#@%c #EI #)}*'D(`4(Е6@JY!#01D1L6"4QU6Fd":A)=181& Y4,vMs5%O21{҅$ - P?`bь(9!ٖ#4(qՈRI/xA)W 7!yx!\RI@a9Hp9 Pqskr柔BRI)0$y')(M*yAHWxl#AҞGT{* ax;x]${(#]jS$!#('{+Fݩ P#GxrHA!O$Y$ a[pjZ$ $" ]q8I)9wdA~JªƢ~zM Y(Z a+!!p MA!**z튮蚮 ) k*Q ;j{ǰ)0Gr$ @:;+:ɉ Ѫ,+7! ,).>Y` *\ȰÇ#JHŋ3jȱǏ CIɓ(JXSʗ0cʜI͛8s/@CJѣH*]?5LJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ˟OϿ(h& 6F(Vhfv ($h(,0(4h8<@)DiH&L6PF)TViXf\&]>H BE&圉S)ER|@Pp矀*蠄ֶLBi^CL!y駠*ꨤjꩨꪬfi[j뭸뮼+k챣JSP8"+KNGVkf܎f)݆+k;0}9Josm̾,l' 7G,WLňOhȅI(,0,4l)b@-DmH'L7PG-TWmXg\w XDhƉB’vXRok]|߀.n'8kXpwː2 PXaBLB/Ss褗n@KC/8zQtp2cLJ-J"o'y(A;)gw/o觯> w!)SA{'6! , |A H*\ȰÇ#JHŋ3jQ -0ǃH\ɲ˗8 ͛8sϛf48ѝ4J]B vիXF|כHJP Ahַ_ D2iC)!h ߿6P>o CXG3?3*f'C#dA0$3 Ēa{p8eD N@3$.E % ZRm{ӹ_/h`ԑ˟Scv`` 07CT)IA G7hN=KMB(&7#$@UMXu8+>5=CI PAr%DV!eP>)$FteB @@&0dse@0[Jfsk)眡mHp z矀*g#ju Y`'H&#C&Bj饘Jq‘QB8$n 1jP(sDq*PIЏ =* sdCWL*PP -4?AW &0@ǒ4O԰hjaQ"ε DG"m1%A5.c 6LZddfAMP, {P 1pM_PE R?hO8 2 fc@IM(%AR O=4DA13:Yd:Њ c#Ei@]?2pC@P-bcft@kItê)Ck Qz(G.9E|{% 4|4SOD4^΢:A^'?h]Rzq@WKMdXV|V*}MG/T6 @#L-&LvkN!)kl@  >i! !9P#k!AWCe`󋈎QnTဖȤ5 0zd`)L6Ps!e%"=R).KHXX D9a(OX0ȵ "fp1Z8E `(LA*M1dHb,mSA "7H=q(QGْ/!0#M A$H}UNrYjF:l 2h' Sb BX)9Ay `7 pGN(T3C· ƜBjaPKkDІdͨ~n&UQ4JҒ̉&Mi|j(ߌ,±XH*)TȄh&BQ8xav 2iƷ!NU:7[DGY¢#"\(jĆ3C5n5 RdCpd5ę_CNTE5 Qǒӫ@Eq!jATL+CPNx40^KG2aXD*цq/CDJ q!o&D%aTqYZH*Yf=L65oN Jԗ(} I؛bB1ͯL٣4G|24#&G'a8k?^bC!+AGPmanEY/j(uxH'LAňrrCHq<xHb SV1LB3.S5*uFGvn( b"!F8zX!0=dCF-yq"+)]1kZ?&) T:qe FF >ȁBFD`:emQ)nvD (l-|$E'@L-֚ j> hbғALu)4g|9!^gǼ\9X#}?r<#L+r-p|DqjM4^xICڂpM<A"[!o+/ 'L"swAsp戝q> öγ"kpګ B!u{IM&#[qAT X/B8侏G# u] {H$_`A^-+ʩ懨1`!֎ x;):?[V/hU}5U_ah} )oII/PȆԅs^bA +Fn˗`$fȲ g{Vh\pTp%x̗*#Gj@W+b ٰ;]va rBfR=Cp2*xh#w 0,8HGlɀhb\†n:B{pXtByv؇ }Apܢ!R_8臩(@& X{}&"$1xa$U`cypay1x 1mv h6 AvQ^-czсQ|؄XF*>a HcB%"YR'+҄ȸUQu y PkQ[ ۥ %Y`f) շ.cc9'* *q|%$pY(*U!NВ+2Ra~C )<9gXrc =" [K7~#* Jx2$Q-((.DfAA[%r`Y:3P;`jqvҐ A%X voAQfg66f'H9프Z$K2d' Wq" `y5'P!gr,1}љwkmG4 Q@hvE 125e!B穒GC( 1cjl21ay aUr d2 O" zЙ!-H|z1-Cd` a0xф ዧ'*YU]=f1#R4( ׉^]0c`A p[`:BFb!lҰ2XL Ljb(ɚ9 p?hTIrc58}ẒfU5e<1@qPo7\a+yw#΁91$Pda$Yt)iQv #Ar7, 9d~;+; 1ِx:A`Y4Q!11L ߪ]U.h(c KQ8L`D1ѣɎA& 2nzJ&S)$0@އ_kiyG$A(;PKZ!-h%#TB4g2 oQZҀ500 Ч%qZRzī!A4ԣ  Z393QRkjl۶%Au7m-x} P$R0 E t9 , k+{ 7 QE9- QPNQmr&xB~/P Y/o&X3(c-!&WTgr=5&! ۾  0 | #̶ \wi'yc;'lR+(02,P3|81LW>l#a@5RP/3X)BI} 0aΐ  .ڳp` P@ p #{A?M/a"h(̀  < 0T߼mBxTCm4õܶ:M0NRyM]T|ū]^`hLdL>|YA*POn VV3\~_~7)ki>6,@ Y7 QJ `;lh=x!;,@R'AM}ppڅ~ / OANa mPX  fL O ǰ+- -'*a W@$."=05AX` ^R$u)@= j-N$ @PȿŞ  / }¢; m Ҁa lj J֠lˠIF;".t~q~<p^NR) >K2:{f}Љ'N?]Y 0ZgujRJ*Y`(fA !A:,ZXRM>@R'ߙu ? VZmݮKP[iū[B܀ \"`… E"HK(_ƜY{St` ?{(n}RF]r[g; BJހ\!?d!DHTV Z:N+|,c/@2:p@d 3&B qꦒ*>G$.JDQ SS g"tlǕ|Bܸ2)"@IL2D)"F2K-K/QGtңx' 'Đz&9:,sJ=L/4PAsPC* ,B!EjRz|Ƹa{rPsK3ET>\f beOU`2 5W]whtu<3H_Y$卞x#g!NT@xJCP 5VplbxWiQe@ !ުrdV$g GPDŽI]) nJ:Qs$pgX'n&15ktkPg*iQtT7ix~5^VĦ{3Tj F1S ,~ZhR9{X+FA-CXM?!dtHMi;ZGHFzG FMaؽiR,d2LЙ4./SO njL~D¡`M0i-"!|to<3Y(DG?dFX/:ek0EG2iHK!R qaD#R|*qJX*@$qHajTe ih4 1KRhOfqFX"E _KZ`Ze ǿ|YPqC21rHHG)g)R]8P؝ \F n$҈NW!`!R=H#ɡڤAÄ(As#LJ4Xӂ=>J ~V:聒% 4^͔cG63UH  K 4%pPj : u B @F^f͔-efz8*MsRVK-# 0h]̈́BR#$iLS*c25IQS䴉? N:T5-K88(єTeG&#&0HB=@$ uO#P*xcJڢ׷ si0|K" `RH ֐, `qUO*(: .Hq.-}J1Y(gd$7={!e nxHOC PLpXxVJ@p.@xeE_\1C[ w@% "  ޫK˛ P D8F`@j}Xq !8G܊(Yc"P qgn< uº. hQg]Š^З3e05`Z>Aځ@tIM"( M )D.rRT ~B( `Z8dcˉC&.x;$$p]24PplXJ3<᤺4P 0GFPτF3Xpd<*Y(c: uШfXd+ {6nL/R'{d9M,r"?}?`Aج* 3l7q̛#@$>/uaxw ] $^-X0`4ږ%C^Q?n: jAOͨ^- 2l.xpc"9J ƃh(&9[*#/ACsy-ŏ0S--/K#SQ eqXk9-}4jaRTɱR}JReW1O-~A"|R4ۥhBq'b&b=զ `NKzRp3Ş. ?Z \LJ~܀:jzO/('sN8_N0ar%Ӈ?S9| ?Y<).} ئ> _]н%i&@c6΀;A-Y3+k XNkn0.ix@H`0\`CgB.=(/k8Xj9/Q" i?%yy? H p1t?8@{P,z EB nC 񻪨.!HHY 8` pAi(-p88px1kSS;Jc QtPdA{ex`F"85 ( khqZhp!ؤ,6n=86\`< r0:>Hú@@G!Aa)& d؇fp&X3z zt]7 qkpњ&!z`r!K{=x~S=X8P+Z C8H) B+JAEI  k1q}i} @sxXhHĂk1X]( )x PH2; ʘK#4̷@"XC`T@LLRˡ[><7ǣ& O4R**d 4+E \|OϬtEP 7ċ@(I eE[Ϥ!s-,PPiż 5 kq]~j{8Dkxl R @Pr:5xW|T-ÌYd tpпh9nٍ~ęN_FT)k(' {N ,C5 w\?B(:\䒂(   OʹͶ("LdLtX7ю8 !ih}y,p(r@C2?)[s . [ P6U@8"q х3<ǰ\f)m>]YHgژ  .t] ԑکBG,0ɒ]=CP_P0o (M{3+RL =QB9U#3{\3< ~9Np2@C(]=u pa>ia2n@uԡ f@TƁҼe@y3+SP;K=kH5`мaWln`dj"NK qN] 9<3 1uX`DӠzhbS()ptpq|611^ aP݁+\Ze4xi2?)/'tf0Q ɵ9_hAJyol"@- ϐ[ii5(*Ь&C@1]˅ 't tq4>TCv!4]kuk]c A#-tO8n2nYTnIcWo<֌cѶkqeodQʐ.P@[&*l| ,"=ԫXdPe &7Spĝ,60 @Әl@PSpE _@AA*2 s%a<]<_e;TRs8<"&є::o3tm>BGXǘKѴHK!_Ҽo tzH22C%P2H`\'蓩PfS] uX@ fݰ8A CC?G$"A΂,-J:Xtc}ss ?! (:KVA%A/% w`ށ6Gqqr~p7bqC {&eZvI砃u NHS g5+>X6^N U ,E?ȝ"f~zĻmk ^2n|6OG> 1}ի| I 2? pyL\]47a߼/5~.I> J~#Nb\_՘Lg並Ώ"oIgh=InN OR ,h „ 2l!D-",G"ƌ/h@BDbA'n]4S/>µTi&Μ:wk΃8X*FX0R!H 07PitPA+ذbw#ǴjY۸r5xAĴ" d"P0 hK!iI㖬=Xܞ Тu% 4kf; pҤ#q; 2qHٔ5.Lza};}/o^G F5)oAhX` :?&cH4QN?cJ3 K2X@ PNosE:s?H,]Is)CL\* 5?0Y\ %\RPA)ɘH T؁5 б:ija0t8)OJ!,,G0PXwSt3"]m :Zt {Z@17ӐG4C:BCvpXvYPcc <"d(Bd)Uq3 /A '32cj TAA*LBB Ě}- I%Pua2O^ICy|ABDدK&4K-sJ넃JlhpSC56jT@DTz5q ĀP-w;Gf{LK$flvjwB7,t"iĉ >8w@3}D5磵4X!%:U 1zl'aK[=LQuE>*?h >U?Ou`l@`"Խ<:DCC0MFݯϙPFp!q+! S8To' `229]X&ɐT=TG. [,bϜ΃kNe 7G B q S(GiKD0h C@nC|@.ACq3~ӒYf$CC77qHA^d[s ]mmqA1A @ DLl8y$ٙ Q $e4g Q\fm-2ppR)PO:)pI&BF@VȪ#O!w\895đ SZ nx fI"M>DH0AH)""auN9[ #A5{D%~AYABdKYV QCƃu=L(Hwܠ)F%o $]6`Ҕm@EzLYE ɖg]^^b91"!@0 N!D=&_\wQ( K  ls@xG.lAJ`\p%}+] d˽.vgnt;=/z*dZD+\'>tI9AA}}x  B -oThp z[a_!rl*!"f*,m ATYcfur07 fgPFO6g@3hF c3=\34e}B2A, ){`R| a A"`a9@PXf#N?L-,\Y { T "ȴDh$q<С{C:@ у?Qe63:тhGtQ1X 6"5iS\lC~:nDgQ[}~/qwI]%*@M?'>Ii }kKė|]tmV 8.EECKbWix ƠCtHD@55xX\TxܖXP >! 耱 |ޯ8 Tݑ/@: ~U4h m!EaXC p9ᝇMaAԘ Eǥ|HA4Qu/ULCaF2XC3Hh\4t(D!*pL0pfH553?CT!\XNHX0a :DA?"3Ĩ:?H( ԩnA'' 8A J 5bARP%^ʸQ #E`~bZ,E" ?\ ]dA|D=dc=X0Dc(j 4C@7epC|Rp\ 74ݢK@H , וPRD P@@B=cA@܇HB,C8C9$XHXC20(D~@@8h@C 4 tm/,:#`80h D &(aAIeC,A@dY PN^X:7Hʽ}XC8|b]^y.!I-'lAQ$,U"P; $^ ܀d}ۤg\TCf)Lg ?L@Aa $Eܧ FPdxJvLDRVVQ|i!J~琈Ns(OL5(# Jnu|ED4 }~N~AWAX@rd܌H)H3CGIPL,`>8V@7ADe(\ E2_/=nɴ4@kiɞսV'H&\ AśVZቁеuݐNyxz:D?pZ8B`HD #G0 h!%=8B~ɞ[*($5m4i0h 2\EԳ@LD E hʀV+ 6dD*A@$e\`IȸX7K<kaiC FٵR C`j%IC--eD ea\[ @IKyzC^Dd(F`Lf1x?BxBp%]Tuqd6S"KGREŌèU0L/8Œ̾t8D. py\i 1\9p,D8,_\i“@yBW |FD~$*٨˽*XFLê3(V LEFZQL)>0IzLCm\XB Fh *A$S8,!^\CFF,EwV#!, j~i #KCLl:liO$X@h/U@( {mmgf G@43$ƃ=(1 A:]82fttBj$&`4,@=?Z5Ú 1D TtA&i D a xpe8*.uY5hNO [l(sXeK_bbwg7u| wg6jTg0E':?/Ԙ!ЁIS\`6r?xO8ɕNl*P Š8W@HR!? Vg_8nro(`NO#B,pHB':2:4 vsp!ŵF1:h1x1y!u7AA 3:D7 `_$!LFK!,:?pZӐfV J١k!B3["+Fk/8a Z vF*DCLgCͰRGscx@M(%8IM<8ذEt.RHLaSBp Ȏ@c1eDGA?DD"78=\뱞3HC/4-7(9L /l@: B]C ' <)Nu"zxPns 3ND KPP7`HLF5CL$4C4ƺr ,0h7 Ts,D;?*znb4PW`8̋2uB̎sgs,F^j3 sD ~HY\mY tAoɑߌv˰calvBx}4^qgCdR{3N0o@7thETI2(@uqaIG \AIp2A*Ć6& :24þltTM@ <@ n<PaC!Bl_-Scǎ<9dI'Q3$Rr0bԹgO?:ht `0 PHZŁ? ":]tׯ){|[Kn]wM!_5|H! @3)RID<2v^0Ω=SYgӧQVz5>$t(]Ǫ%:XȔ`q맗zӹqLf܄@ $@G$k+ǗҕT?kHN2fPԾPlAgk$ Gv":ʊy+tǟxQ,鬹! 0<ƤC7LfS## 8ڰ-Ȱ4̲*4ָR1,ӤBRƒ̋Fh2(+? TНD N8BDl4Q:R"tRKtA9OA UO8*tEb.E\Ut) >]/SS$Ь/E-2u*mVr5)2qŗu.[Gx]՟r|`t2uEpJsvL2!JR*$@ *C&.Uʭҁs.Ѕ(xTP.t2`)G((Hè `A#L"R~ !OR{蔭IuHɖ R Ph Y'9ZblHx AASiaMsyhqːV^TVy`h( 8&h.ge!xe)xv2CRk'~Bz^6ʫH %ճ"0#xZΥΜ:?pw֛@D ,< 0dLzsD@Pi(%b 71}p脂#_ _2e$C!xƀGT8"@s17T5?L$/d A=J`J2 gh=xL+IT:>.pc\9bV"?$t8F0Ā"Z3t$32C˛ALg/7}X:[0d{A(X@2Ic'w񠕵$U øb ⬁ /hGҎ;aIPBU$V.5Q*/4$7ť.v .q(G eLŎ " 2P`B͘h3<Ow(0va`#؃<;RA/ GFr=& HvRt"G}qXƜ%g xɈ1=!^SpBX7Rt)b; #o hpޟRz#f%G/ _A0 `&I9^EF/Jq$uN+ymĬ}dpʈߗ{//&jڢg ^ߗ3A6C{*!B93D4lTVhYq~hݟ;AArKNa2EFNtDyf@'~t~:3|abaecQ!@n@Rl!4H!t;A8"PBPIfKjx!%G|aEbCs@ !1jt{|# *\c``8bxv1H+L" +@ +0OF! x+~a ~?K(< LCi&iz Oc2$SLz* q!ˈzBNx._b‰ZF$Q LA rJPZCx@*.*`$%t`Ό@8 1a*/0I^QNp#03(f*dS.A^2]S$ eQURe3&E2BI]>"5KF5+8fbfF@R@G ~B8;A,%AF6S9Dž'!BvV$'2f XȪL.'J;y$;TLoEN.A.BpqnM # 2TC<@gft@7@tJ`A}GC>HB}0"4b~8A  @e $ GAne,u& \G" s]:BsBRO/5P)Ɍ:IbH%fE)L"*d* A-P UGF̢4GD-t<+9҂ޔW7l"|#z.6a L"rPb1+P$t0Q#,RЪ:B~>C_>\|!a X(=aAatc9ף\rT#4#"8rg8BP+Q")OuR;'_@udc7*~a)e,:!q! E!(,\PV6x qt :@/Üpc$*$vn7"A< Pdv(')O6J-EEo/")F`pbB~dI<C.E&~\b[s'm4Rs-p\EtE tKtIwtSuQuUuqd;MbOsy7!="ZVsxݫxYS!EssJywz{zX/{o{{{7|w|l7S7}w}ٷ}}7~w~~~7w8x U x4FEwllDg@lmbSWEb(8'1 45 8xTUwIMlW45(P2$d3(V<"" I'$#N'Fxb4$x% s"GK)DjH}84ƆXCdubCPCHe9p +$ؽ88xic_85B8"EVT B77m~*tTB,rC> 8A3D:y'FlQVB"*r$8_N@yl("BB59Z$}BATyBx-#t @c9CB>clZH@#4$j'8J'R@EBM}J3D 3d׵MbZ-d* ADO$38£r7CMMS5&)KrKRY2$:(~3[3Sby;$( \3J '[o+wI!O.3!8SCc1\$ ! , |C H`*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜIS! -DAC5 JhC$%'.K/Z3C0UКRhӪ]kҁ^TۂXxjv2pE5"ȳ#KF@<PPm<92* cX}=ޅԚaA Cg 4D?3 dYrM8DP_#TPNQO0$IfĢX?4xP}2?3CoqBP \C1`6/FRhk8"SJ0#@I:Ha ? O1r;s!8d0(P-P!CX#|1t@Q柀f t#?2tdg=Y P NPyswM?;c+10EAw*{IP>tꮼ u]Z)S@v3@`@!<-GEv+݆ېA*-2ukM5"nAl'dE ,Y-%wgCQ0D: HJ"Cw $L3-\HD@3U}#گ@,Pk2ĄϾ @P&NÍe~(cYȗ# %L@B d8}rujG5 q%B"ֵ6A$I8H $I$IQޔO IK7CAd(=P'@*(TGJNpB>#LBDH\@Q޽lnsA-$R5mC6DB#$_F7IL @ $1): aI_PLd- \e"+)h ѕek! k Q) 4̡7Gx/ Ӣ<91=p)8l2YMg);΃HW]!܍sy oGݐtׁmI^'ZG${K_*z5zQ_@7dq槄!!UcD$}( I` 5V^XHBX @liG @SA3 ㆀmVR1D 8dJF(0E!$ pb lrYF !|"'2l"VDum#zt@e ŝbt q| - :r l{ II6dܐ7FdJ@ @Ce '>Cځr&HPkpcbD}E~zXӗ", g]1yVqpnבH\zG݈ N"C.WTc 9ĵ;,/t҄ͺ[q}"߶zB:eFєԠ6>J酀{#qAc"h3\Gl9n޶NO0R8Iۡbg؁%D 3䩰AMc!W b/{:;MnN "prY<9D/Om8 Y-&T  ڏ|g/b>!z0_x;`^U+j Y"@zˑ*?o/Vȧupgm NJܿ}#H?|b1;SU6#Cv*dq QHpum{oUW[q?'2~p,!\#r8a 77lzGLO$xbFc3C6@IBw!L*VAQWU j !E \q$*M!@!0p@~ujф\貃}xɶȆ>ECBSG.0i Qd>qWLEf! imuf/p#P 3a.EfŅ;<GRdր VE iGr rDv1f5j #3gs @ueW/~W'!|QmvhɈFo!y3<AMu=2W("5sw:s|0*Za~ '(exyOq?{p:AI31 s6%`'*65G'p@ )^谅%a(QQi7 ! heB "c0SYPs'`lU5AKBe]r` Ac7pmf{CrvGs7{boęI!ٚAW䚴) b3 HE:"V3QQYxٰP$TT)*Jq'÷pkY664h БQLA2uGJw=Gp F'@SQaq tIua  $q gh6vy !xk.a`C09r(& - :jc VEU-z! b? π81!d '6 zẮ[w 19 !/j|)'Ѧ[x+3 1k5U;>@C&Z6ARSA?HJ[nN*L) ' 8klO  0REpf SBA wVi gQ@( ڶ{U0*- =dDtHP;zqDSqr5pIq֐Jh1qHP0K+""0@4!a?F#Pg;Z^c :V G;[Kꚾ6r P! Ѻ%X<*, m1Taq`v$ `rz(0H2J(Lv \t&9V!/%1pt\ 2 {?IV3!Dj (Tv=6vX'MIWL ѭ  1+ U8;s[7>XJlyPƑta H@-7saXpg̣2\S>eQ@dU<'w*kg,Do8Q (\;`y^$U 6s'>^Q=+P̒Ѭũ1?qmES{T91UT2` /4[LRG@+HQ!A`F4 E@- qA!2AT)<"W˲i`<nu!oI!c0E@ p! %FM* t<ce+}Ю{{) ` tc  2q!KW"-Vq%<.T8,UH n$I 8սESRŬS] eRJPM$ w# p7PZq/p2RxA# _ &ZR`׈D]Mo$\jYW24 2O+ ,ek1 Mܽ*ֿ\4@\,p1RЋ,`]0nV]8a}PF4, gD##p0!7@.!:6u&e]dG`!}ޣq.*un) q {8 W!5R3m-u.,\X6UczWn⩓&PьǀY{_/g\/ (` GHAr.fo>/YD!z"o0>R'Y(mrf|!\J^$:PP9.s$pFjҰ"3q "2kt ewQ>-˖L=@WK~dlX?P3d:81jqwt#a   Ay1u>rX_oa\ao5`(q9a Hdg1!+[ȒA Jc,7Q"q"_"SJtaW! `(3SYqk5ޘA? b F~` }/3۳#G47[.A$9.]s_/d>P\iɘvzEnn<8iOZ ēO@Dp_B ;c`7:rQE/lRH$9DRJOL5m/Ș聁)Ji(ael0YMiܠ  əZO6l8:Q{L ŋ,VZDPnK7d43\@"g,BJr/s 7vJB{dx w'n/:5~)]{ʺ(:w) cEYH!ĸ 9gٱOJ e k.k LWH T !C2䊰DPZ  hH8'cH*j1!!SN G>:2$r u;haFҦƄdZ1=r83DR"QisB8`h<3*R ?TT-zjlћB;5 2DE+5UU"u4KKSWgV[o=YqW_62 XcE6.,Z Ӂthq$,7J>$1,[e%Hpj ݼd:!". ըikũ <طvUsdP . V @Z eH ;RNULT}0R61h~;HrDpJF"lR4"fd=;YFC`W+9#37J%۾餝4"0`:؆  7v4K&P*3E>Xiũ M\x;H7鎫6igh1h ?/ . 9 q. "] CAHmq%UCėhX7J?%I/%Xh0}IAķ`BW 9@՞  @d"v*P\ Ջ! Jdre({BUO#T2vw*!`Fck "Pb?PE.E2ьgDcqYOieQ@l1nTQUaS)EO쫒1ֈl0 aD]rQP=hgd ej:$#bI(Q *SYIvDȒ7gKQ6bCRMlF>`HF~XA3Ts2HȐHCu@~+bkK-|{)@`8c R<,r@iaI"!s"@H*;vT@ M Q#xIJQ~Z,HnL!GFr* D=lE.$'估s2x: snT1;%e|,U m鱏=i#TZa>ų|3\| k1HFkn$PJ̤(n 'Nl4d!nwQƖSǹhR8H/$) K-kXc&v3Tbfu@AkDV uͦ&J0h!T͈4 U_y!̮FƲx).Cͬ6|dPΠ4!Ƌ@#7 t SxaNH FkeI%@S%neDg?jp9$=,? UwY2~X!֎2D,3R>n `!" SG+l !^>P<ຑ( 4?\RJtJx2 ӎ` tѶH <] P"s#s{9)n VRuAr[ `-4)Tێ`1#! EPBAIhC3؝;Jqc) ,/;) G &JqD<(d KX[J0Bsu+c{bx Dp 82Ц0xCtЅs\2CtA@v zL9P_L {ȱ|KTn K2 d< YEU x2iќ9)8A!)ĉ0g*ZQK> p =tl,(- AhL4zL.STB. )LXE 39H"1S ]hB]qAXbK@70B@J~L'kCk(q uQ!;z+- H: Mw!*|4kQcH%:2ӸEҤE-.Rp;Lr$456N0֋g@KK/eS t>/ p{K; EMܼbuDKS ̼CSʠJC Qx(GH賆 ȫ+ًR0N(7 )נT.N0 `Ԅ ܋I4#AU%YUk(F PЙVScAe d3He88lN0" H I4@& "IJY.:D km!+ڝ#Ad͈DR4ЧJ y Zg@] E<HiϚ@ˈ :͈#A4lStİ;Z 4<ק ^!ڰ۱%۲7EH< R)K5e|\X1a双YC ҜgU^JHɵ ONܑ0\&w+04h 5nIp$49 fei-ڄ-X9 &;ׄ#=2 Tсh+i=/۸8Qoq@! B4Ոw>qY xW{PBͩ]3MQ_09iT r7⥝JY#Аpp#xSX%s҅;^m VU QZ "3KՕ#.I0F$ ρ1!A#. ʭL3CPóLa B *öNt. "!p" i[1I u$[2`<[CTRV6W>O9dRW\68Ļ@vr@Z0b@ +-0x?hssM0bȸpsX8߾);,^0`!h(IL͎o"  `+j6ֈ Ԍ`ZRu@zd K=e|K iP␀}1.!>q5:2((6 z`;T0-9@*ke"^gJ4Pv+ֈqF`\`\hR58Mޗ *VM)iY.1-qЅk "T88Sag6xk ZUDmR ڋ$b%d辢K;n`랾; 9f ;n^>H it ~>2㖾3]͡-hϐ Vrޝ6@ʸ ߜ`?n(P1mg=O"1ݘ,k!M 1^ X#K" /1Qmzp"0ABXE3i!ωNhc (ݐ?t֎r1 }Ig<ɣxdyI؜aZ$)p(ipZfⰆ!H镰%)Oqq4:FoPQj)ڐxIa8Mzt]Й;2KEe 8 e 6p"npn IyV@ edPiQr3*MV'o/wvQ gx6gga{>ν#NOm[s{6 [/vxz?OO7䙟kq(dOҸ E" ,X8 fmgBِP8f_8;Oki)Za !53Pt؇O=9[~c$vv(+ƹ襛>֛MGQτ~-p 2Z&Qo,h1b ?Kc^sAHԳ{?,CBZD n*Pu5(@E1;^u BЅ) $r'A}9Mn*Cq85P ō,[P0h*3 &2 PD) QFՑFd%v֕ X R"8"܈PČDSiQ05!5~=|#D`B|`p,'!DRx#D8ADP,VЍ+n슻;9Y(r)Au@" zRH4d :YZeyF/K]I.e2aȶb7gzl¨t`~J떏9@еM_:㹕hD(@x!xlL*9B[2<0"ةan) ?x>E+Pt8J/"Ző*%Ap'a2Ö)WŎ,< Z)os=.reU?`7M.viMލq+"'`V3ׄ7;4Wݍ~Ue$Dr;O.$M\)XBlt/]4 Q Ҙ0D -/XʙmHI@%[BDdŧpDՃ$qQY? ܉x`F0@ĖQq)rE)nJMfW #£J*$JQ_]KTD⥭1i_B׫"UfJrW"hEN^Dz`Y\ +&dc(cŏTMcN`Q Q.}rIR31MDsH “`w a[`A Òr/s5*جiZ.7ӭufwrICXS3朳@ZGPcHx'spټsE`\? IS(YLȘIpuuU)b\!B9!b A< r?7 ٖLjЄ)hANh[|ׅQtT!k(<ŜsI&@f`R0?q5(?@7@"n)B/+KI~L9&将BNEhH bg=.VS/VH)Ƹ0ȏIl ؁A/chgiR 0&WPؚȶD: G܍Q*5.}#(\])@,@B^lq qĞP?XJM1 =B?^IhE_ČpUEp%ĀjdO$D[F ĒB$?|?&uT$BE`M,J)7Ӥq=ED&HtF - \ A^UCMĥGat'Ţl!;@ll)z.AAyDAԧBHGDAEH,\\DPMOB,||@R21VcW]DXC|aK߆DFc?$+$ENR3öl\e|@D,$Cy8KhRe Ω&v))a3$O ~(.)iXXVD@Dnfvf' DDu&i]H$HNҗ)AƄAa!*b֑WPцh^xЕ {vEt h\DTP' `02EsBQ,PQEB 7$T*D[ʝ~cb*|?h.Ѧ>.v* E HJGI 5\a~E$V*U" BN']Ln/C$X\ƞ TW85(-\ahA6VVoBa0+[ pFD bWjszjO͠@Av@@p,]Ȅ``m#خ-3*2-ݖ > m~IM|T.S_~@O h_@L\EUCQn^ԆsFdD@,D,E:CdrE^ aj ӆrEnnKAXμE| IŊEFDEpm^YK FAT()DV:.OTRhAt`ǘo]\ lDoLX>gF @Y̙GRtÌQâ<F@q$Tb0V.D\)"7Dfpv*)j${5M_tN<+[ǢX Q $13:Ccᅩ111`u\6K*qV1ű1  2!!2"'"/2#7#?2$G$O2%W%_2&g&o2'k#znNFQQĚDrB]@|RF(o<fșΘ2QLiB8O|%@Oz+/D| a̲K+؈rE#HgWlE QK&jF!LC-tA>ם VAL4X5DXqRֈ_Q"AcM iݲKFNE)@^,n895XM6GD/o4$S6FnQBIr&L@V|$ pL<.PA6 Q%QnoHWXLrulE@3{\E3]AK/D KN0ЛdFބ;~DiMG2X fNauRsً@N.DrmH@Dd*3HX NiHp,Ac<.u1-{QjI}H@|jCK TV Wzp[?jBG?/L.K$r@\V|wo( R1D`KxMo8KGlQ톚+(AOOt[C#y@@ܖVxXHb*Mw_\P)񲪣@@N:zTakqnr\@HGQIc~ ;K{C;+ǰ{O'/_{^-WݩH`D ;?;"{!{GwrD! , |C H *\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜIS၃ +Dl1AG5 JhCF-xg(8nIʕcd={P`]˶p_:T]u7bPRH].! JL%ފ5r30lDdd( ,B& oe,HZ @)1[.A$W W gD00@`fW 2 ; y r7w!G\]` $T0\(C8%eAu3H 4[Z*EB4L6T ?/0p? Dm5`MO6 `B58UD2^ph䑒?E.@Fd BL40C";?Q|{ጘ?!/<@Hd jY}@B7{ 9XДOZ֩lI B4f3@I(w-&"@ C4<2Ȱ)PZ5]2 &xNA&R~zP`NJDlCU?ݠS!@u fS0ʒD;Ҵ+o&@+kD׼,,\#R^0D$WLSEBm$G,\rʟ.ToV8*t5~<L-l AD?Yб.I"JuP6fLqAL0@ӝ5- q"Pt: pV :OY0E S6/LŝwBD(~4 մb %$Lf/T'5 8eQjfLҡ!PIOGlLy6|R<9ϝsܫ5"BdTJKtݫSYQ[fY*7AX`BaBT e(m/t1͵mJKoXIc> THJ/*q"?Y,ٓE$śK˂%{1k] mExaCT2Pj8B%F#Ԯ.NM(a[!ȱi0p$Ohk E'!CYHȑ"Z ðҐ(Ŕ0 ,b' ! mt(G,,3 AAN0!F@ .ب!Y2D!( BVljo%ӗb˅G! BX a\>j(um.M `17xtA( `l*nH  ' rQ2( 6$,|xG K: aDj9snA@p  , pBtU t(`4͖m p R |8GxH`iWw q)uF" t <tBg&P` @AV6jm0%"6e уv5]D'UhkV}(vdʘ#$a VCyBc0j !"(NݸW(r`t@sFR2CQ  pM Gz~ "xiIWyj#1[my(B&lQgN9%"WȜibr/n癞`Ij9_1tX!(dDpaqJWRq < W*J[CFJ @pd!*)tAhG xeN>',ӷfBh 3,RaBX)ƀh7%, ]5Q!Z]YS 1aNa`aÉ5N1UXAJbs,Z$x:<֢ $C34)N#!>NSг.i9ǜ€ZCJ﹪EXC,4'Sx~< P1)7d@/n$ѳqk'3'm@ɒBUFzӻ 26F a1ptp`ۋ-p!n}B`f1Y͜); #L1!9Sf_2=,ٲِ!>Xq-,PRPIYur~mkU&{s/0 CK1 q-ҥ;un8@QPmkCC u` h\8A 5a/pO q!A&P&z=  >*AB1:Kp[mXQQbW81 YA #<$&ְļp-HoPƃ4 D#@S1 \ p<%Q C!,*X=PG* qW&pMm@ +F,܂)  w rB_0:!!I=̍knRtA!<aA- =K pr]0"x`P{+@0!nj"W .[(?>ɝS+SAWl Z Ԙm:+ FzM-䡪q-=1< oy!.{Iٲ0*\a vj1v:0I'FIS.\! .W pP17E:[I^Xg A p @ (Aq .+U2px$I^wyktݳJ=(c(! >0=:mĭd|'A^5<" )P8t%+1RYuXS u PB ک'0U O,Bϐy/ QG.J= A: rr_s>--%F{0P,r,~ tD@ >_ci5.mX_Qx!-A7| ׸08 C7-29p7 L ! F= 0D)="ݿa,qy !AA+0Jc0Z@pBhBN\`HtIlHp!MpRJ-]W@L! &Ce  C:WΟA$/Ȃ颺V*A]NVBB 2PӝsfM=”WXVX-M>y V偘5P"Пs6PJ;-M:n޽]Vyp.K.ur̝r\NIݽmG^z?_ SCJ,E?$οDA D ,N)${$S@JICfht=,ւ#FbFjk%X* gR&BIȬ  7iz<'p5`(2RGb``9kqIz럨~Aj!?;W-P,0ogBk2L`'2LAC`tL2 Ɇ@%hӁ 4a}CG: Zfxs5'kЂYn6] 0䊿*(\7 ڧ }Ocg L8t /GC  1I.Ul޺ x S#ЅhMT]8hSZr f߈3!ef&miX%dJZ0 g 'lۂH]ClM:"4R< ;-3FX:y)V.T7aR?]G|2tUS}T|ug}L/SwgjtL[{piz@!vCjF+GfW .Ȃ:붲Y'(z$`?owmC, QL HY B-\ N,D c[3H H Crąq8iIi@כ $ pZɅ#~QIT8>(7l͠Tes 0 BCA&gY^\:edK `1DjztHHЅ'C F78B^'2hI&O\M929, G &:tf_xl!)Z@δD m {ý8 }V{^jjXd&E#r '" ".O E#<GLBqiHfD0z42Ȑd}5 2-!>&Ѩ5!2)R:ĝ[ DW,I (n8I-H \ FФ4٨xCH7%H]wLDj 0τ*$jw@xg%I xBY:Hs k^Za­^;Xְ( zXH:}0v.d&.ؒ9"grF \0 s#^4w7 k< a\ڠ#d -bgYv:inY&@ V`yR^;mf/V&YsAj0]mQ ,euQ?>ܗ/AڸFĜkvjPX A3NL].f4L!Z & 2 ;B4IQqNKlEdp؞@ [߁A߅T Ѱ}. 2#Ha/  3¹ 2y-$]T.H.d *+n2h̕ Fq:h]+ .a]Xjc#ƺAJ)+@@LBr ?j aAr*TjCc ABg|re0?JPbEH Ni!)8#ACi )H>MOjV"{&^•p!QUnd$Ȯ;U 7,'U~mdN;j% aB:ΒEUfN!3iRv2WK7b* p/:lf4%UzĮBA&Vug1 stޒ (S| tɾ{LGB؋#uM zz}+ bh$)#(jXCZh7? ItFf KA:!@W5xpA _S h *f*ʎ@![>b)6*@HB_#,Rq85ea#i Ѕ-h '2pa+ 빁uXGYB@28#:)+ X ĪyIވC[ 0 sax:>@@@¯0X?ש@(ܛ*ҊFT f ‚2,L"IEfIǁB`_7hiHDyHG?,HhI-Il,=:HP_HaHd<Đ,:,X4H/Qłh˳ I@D 聡. Eخ~8b㎥F( dKk8 *cdJ9:3+G\{>pyJ߀ltYg`ɧN,"ЄFq[@g@ (aEZ_[i޵Ԁ[%\]p[_0=hP^VbòU3`)+!a1HʁP83 { s T*i%{](N0H2@P͖8_5ҙexKQECJאP]L+݅ (fȔa؈Y0Qݭ2"a)$Af 0lfS Ds 0 5`h t875hi @,.P96 ]Lک]i9 si"ړ@uZȪb~fvP .$2-h(a.Xْ^~ E p}j1Ύ|p둒ߴqM k(g3kh>gU\6lg M+H ^7iphnYk =Zk%_u̱HzȔpn) vިilS )< C'9%F5( q Ntf(qPž\}V2%uɈ`(%5 2Psm ^ A<Ё<%N.+hd"䀅T&R\6Mrm!"xڃpB] fwcLQG i0{E{|!!kx{Ҡ8 D5 iN khtymM w9> 'ˬ;.ОprzxdV iPȐwX 4T5Z`ˁ4 QP_}ojٌȌ{kx*XO  t' `\}PP`@`!Ĉ'Rh"ƌ7rH#Ȑ,i$ʔ*Wl%̓V 'B)JCtK, OUjbZ܂P٥Yl!\7Deϳkr:.^~/Dl ~) إ@ #8b4ݘ()ak ztԳFX蜮0 >.0xL X:x:>[ ]!=FgSTEKآ- ($QbQ4˂Ʉ?C8@B $ZjUaX|D]6P[d3Bjp [,!0D7wQa4B86wDܸQcd2!UD('x@ B}ПD"$(zMIB T@$BcLH2K̈>6D7$q l(1GWZ*)@PiXpMcYEV"@ZT\[~͸hB +\j ;A,f+mvZ{-*&<j;.{.U?UQ%.^$+4ouF(~D.EшGbD[qI 꾵 }wŽREBmєG$?̊H:0Bt 3VTk%ѷ:Q^]k}Z( QfM0Hyb9Q -D=7Y$ c^U0u5uC[#DD5ⶔ)S%Y2roߦ "Z%zp@4[?r !W@4Y/h[CI6>}}n)Ibd 0W˯b 3I3Em IXB_O±a!̗cEd:$Ɠ 2"t\Szr!$ۯ",!M[L2C=n!HR~)$G7W;b%F6q?F6@pQZDg/Ud*W5v ?P@$Re,CB6~#D-A<$"+>Q%ùYȘnhKcԣȓPEMrDPb0)%~$vM#d4%J`).`NQ D'cd +Wm$̌ %G @!(Ri& 8Umz_i$A 2DV, ,DwwY׈'DPB0G(!,"w2:l"(bH "?B\f ͙M3<R(ڊhj2U",ɭi3#B_Bu qn8XPnuԁPByJ!XאCg4 sPӤ&raDo%/d'B>wha ~I0(BlTo"$ G*K4M5"Q00vgKZ *l"xb=K c2B(@f Ge8HBsMEh8֮w@:6PN;tp״)?"E-JtA`"+Q8~IM!MoLfg$ +HӁhy30"Q;AH*S%шKd{ǜ|"}4b*d"W:1:0}ĪICnȧu2jʂl ` "T ɭary 6S" Є$OЖd12x&+<3xmliiX,L xs9io|ZEnD3Bx CeƑt?EDdA"0 x<@V.F-̃- ,)p+U,kA f^x+HdH. ͢DXi@ P0lZo~ cߪ(@[0@hlK4>A@ LƶoI/^ٮDzZoh AF@.Fhd$?%Bӻb[;h!u5zZ8).AWQKHB$ĕJB|ʡ(Lt)կaiH3j`?XHjfHt`82dAWe,[XC)SFİDBHqL2tD~u8En܊8Зm80<,J*@\z'HD8qpE`s\8ȋ C@1D(xX[@42$#g]m`L q^4P܀EBrD D, ?r7f9ҬD$G 0':. M,{&0BDéF7SuQ1FXrDH.ThGA M1DD,Z  P7 fDXvB]3_ L3j b5:Y8qGsFt;Ge~ 3MtdA(]nZHXZ[:ݯoL| Sg PC>'/>7?>oO>$T }yD)h^sk0ycFB D_ Έ~EB甒 d`v4lӖD˜HrBD>V@P`AD0AD+Z|_ƃ6H<@uM4ct3@m! ,~L H*\ȰÇ#2<@@ŋ3jȱǏ CIɓ(S\ɲ˗0cʜI3%8sɳϟ@ Jў9Fwa@aA}*ׯ`Ê[tkͳhӪ]˶mAp!@ n4'D(A` n#KLe)%,XϞC-4ӦS^5׮cÞ엲-Am.p~.etYk ?BTѬ4nQ V2‹Oӫ_Ͼ_B.k(h& 6r3 Tt8 `prCN a8H" 0(4ָ4<}c[1< *~BH H&L6PF)TVi啁$a@7|T8tHT},WrH 7s`矀*P5Ҽ㏌6*S :*BCHQ" , ,RdN0` ,aL*AtX}+HJ& K&6F V;}Y@BA?HY Hqj8@JK.f*A*ͷg1LpCf=,Bub)9q}wPMՃP`E)-|ܜJM̢( fQp.v 5D2xu>!=3"@"1z 9X1j,N(bp%FΈ5Hx]8O:ٲM~l7L2D]` a fQb% 0Jøc0F/ 1XL6GvǯN_}MB0*&'O|vϭ0&m]A%q3eg׸Fc ؠ4cxgu xq \jعyӵ'^\u+͝{NV-C .Pol"ҳP^-%kd:{j~{zX'NDۜ' ;Lsw~Bo>lAWOݦUv7Hcafa5Vd6oEh7RvpΡ: P&x(*,؂%Hnց2u11g;@~,34Ae9 pנ P\RȂQ 0nWLg3^g1q.ccs&pcvbP~ ,^ e` 0Vѷu\7%V6p @cm pN l  f@b0Hn(XvyihcGc~ѷiN55|` Lp$x`%w8$yJ'#nGS܄]l29EsoCac:$PpP0 Tuq !5L}ƀ\gc0 i6rrpfZƏ2 6q7rb h^m \f8Hn cFcwr_@,V06 _ czװ #Z;H7+ r4V0&yPHٚ W xhoté+axDWsc?uE|QWp;6yg oGq࠮&qcv (sǐNb1#&P.fc_PISKmYu cyh Ɛ(  ɡsx餓8EeTRRY! %x pꠄ8y JpXr@% yUOj8؝I J U_dKEVIi ݐfhx QqJRPpZ_0: jJs7 Wf_exyhJc5qXAtZ[DA;@I3!9Vxm8Ț*5KnwSWs1Y5s3> r#[ PX0)Zw h_P77n`&^P%SZ^Y6%0+V _r60x6PqSy'NLf뎄{'A3 3@j[.؛q&!K">rcZe5|8qy,5dMSaKy4I}I\G# #.:1660 о[ [  _-Ӏ ȻZ`rUSt 5;]=HEL1eS*0|ÎÎ6w2]T\U7cH|'у2 `)+)?µjCb I@ye.0!0KoeJLBV|ż_{wNQ2es5Ms~yPsE$fKA3>7o/6H`=<V*P$QU\dwrs|Ax{c{FkIp6Mzl]WA>ƲS2ɧ H[0[[XQjU0 ]ue?W>QD?rEtV 0L'6cP>ISQẜ$S\[r{S?FUC)Ё`l+-   D$]ZT?BD40}uDQ{}ag0o9=WRcJ%Y-J-$w ]́fwU]OѲEty6NCEgg:Vs:U >K0ȩTa d:QuAKoǿc7bMsǀ]K̂GXu`]Ȳs62μyI \:`LDWEӔW\ELtWA`V*ב>5$P]KkEzo =wfU3M;p]6vthZwsTgL,0.+fA7_pAL_e6K#H7|oZP#%QS5=DރRI =^leВr'\”60]av>ֻ!<*x'o2JNYMY/OC>)6; X3`^Up ZQcPp2^ tcA]+pǬ%c.9`LA:"(٢S}=?K_=eP77CeBЇή,Tj1`2qpC mͺ>փ<^#apc[(1aLPQuMT;[TUPdWnD/4DؽWPyM.>)30Э1` ` [ P P 1p. )qT~a3޴-xG/ߤ䗥 KW/  ɠ -`?po>>IK7cP PĥQW3E]VS[6syF KEa0 Ð P; , ;f ; QPҀG C MYx|+յYMkە~ap 53 C m@@A01d=p DDmK" $a V#Cg iA~pbD?Ydʕ-_ƜY3䆜{;F: ZEQ7`X6 E lW(Ӆ"-UsdK5AwG<-6d8`N@IAR!)dZ&>fFfȏ:*J&@@-*H;f2&r4==S>T=>r>H{ FRk-#z ⯢L"XK?s/H[o5W]{lHB*-ZաL$`t* JabXTדtW(ˮp{t4h60Y祷Ʋ6_}wdž(F`sUj? vҖj-t(zou/mvXL⚂rc*[gغߙu(oB$KUfoV|e%#gǂ _Y^JDDG+f)ܩC Q=~ iF~x(C>tѬ %W1 @Wux"1"kPUNΎOӎH)-)Hn01a?a!bcuyҩA'x[A. ;DGr遖Ia:AHsV s0.d@.0:zЂp1N#`ƆXjhA8d$RXEv!4E\L@H(хu8${ z fxAy(Sa5F R0gei6h@Qȇ Q! )@*ȡ; RFF`/e\ AB H5/  ;D5i!›.*`o tƕz @N,@$<@I= `@P\`@V/0$% ^PpyxvP> 6NE XC ,{M2@IJf2Fq܈Ngea׏Mf$1Uu KϝX b3UE}70r:|ٶfUH(C'J67/`hZbi}Ga$ana<8έd%QV8s4:r^Ys^yC_.9FЅV"ME!g\:Djw,yǞ2\)ʾ$# kÀE@C̠D&"j t>B Z*)d{i^%_H}y$qԧ~ ;:7ѿ~ gPt@̀DȀ i  Hb:Ȁ*H4 G+ d ө+r仂 KX  X"lCk`' ҹqAB=ii86dC_ &9% ҁ8>`&J +hxF A   @8O  #3EB偠<$Z+!2  +X dˠgҐ! :#L0 "lr XӁi ‹L*`P< : P;aTȹEx,_ȉ|Dã7Ij%  I)8jP K! |XK  L? 3q\,[쿴3axʆOП+(UQk^c(-u[5/ӜS@kį4@~=v`bh\l/X\Zuf݄9(Vc[V[@؄ IKɕQ, x*视2 P``WXve]S'XPp:@/P ڍ.ihF aq/p3(<^.n ņ%pW hE1L@ }RT5%0lQ.X}S@ս/Uۡ=c %x`aQ1˲R]U])` X7:T*"g8*qt*a(p(ҩ @6k`JmlPb-)*m{q#i!c@%9h\1YPYXgx3[G<\ a-h%% ߍ8&-98=#(U Y0cc$MՋ殞0$Ƒ`'} g]@ ]qi!*x5d" 2`PhY.9u+^3cl;0!3.pY/UcU1(ek ]K%۔#C &Qy0:nݝ >O~ qSa ] 4R)xہi.V%љ|NK`Q[Ukpp ft{N#qQ`; 0XѷPEDO MیO *"P %ߴ MohuF0tW2h .4i$*R5ȡ#==<9 #](F(2j1uk0' F?,UߗXzx px8΍G5 Q;L[_ 4pIkhf/IWB"$Tʃ Fud %P@PW@D J](WG8#` i`/ @(zo/h[\ 1Y؄&ӶIT0x'0UX {:f%Eſ%`aeq(.a(|Av`8T抎 ie8{K]qn TppXn`a(zuI*ʆncXh'*8~kвGlԢR3lw{؄c@/Z9o_& S_=X];=2ZWKfͪA࿄H !Ĉ'ư&Č7r#Ȑ"G,i$ʔ*WDِ5_,i"ܰp %AE6'."Ai k p+f† ˿0芁Ţ.e6{sGX0@6fNdaxbAٲE (0pVD,w@MJ$ҪU2YN;<0KLB8V9r 7Y%6e jr;ǓPR'6Uk'3 NdQBJ3'Ppap0c?t. R(0:Ps@tO;30PĒ 2  HEW[d ٘ŌyŲ7fxeQC(,TPK2K^5rQo%STpT+r\SM#M' !I]j)zJRCXzri?*XA@,\ar|2L SG?@#аCY81,ƗReBh{&a?@• 0pؗ;DW[`t$d$8PW @b0DöЕ.| 6,,p PrbRgD5`CLT`C,^D/81hD_'"E}4QK=5LB}AvDseC_"pZY PJvDa:47N\s5Dj+RC~9r&Q4!lAӖbT5睷9衏t^zZP3߀vo؏{tVz7t}M|~{Db>ֹv[lg=QTz͓DXDjl^To@:wҳyiTH2| #( RGmς C(ZUX?7< f8XAB8̀ I3 Aꊣ#O V, ٖ5# I@ T j2c D F'@7)cNXD:@ȁ u8f9R2< U/RȽYX"hEa j1  OACP b%o@1]X@Y)܀m1( 4}f`@AXg3(F0 %a> [L si^&#$S` 3 \ xc0#8j9(!yn0,NSce]ӌI™Ҵ62ܴ>)P%!t+RX>E=>8F6`kbBE&2 `c pRp' Y#F20T AAYvce@F,d` klѐ= #0j, xdi cI)h`#2 0Ж6r6z a B*vgQmApd5 ?񒷼%Ġ5h| L~E5U1 JfУlK 5 ëð?f OEj:^ZC"-5 p%pxb JUhCB!YA8̃y9_lI^>BBOnSF8NAlx@KсBy5A!W؀5 -l "Fxq&wZD3>^>4} _!W'SĢ_!<X+pPаAC`!bO oZel̠,<,~,ad:,G(P ؋"0p*stYctj3U|Q*ɜD`j(n h^, xU=OR|%^ z[% U%#@0A E#cȄ)PPeJ~U824:Sp78 ZGepj^r!$d8m Q^jKH@*$am4P@^ȁ)N Vq[:w @< -3!3@?'`N1^ f}=JbQް Wx {`/G om6Zw 38 \`A0`CZK$D_:ƅ6(kUte@0<DAIZ`LVn|A@t8 T| }(p` IàC,0C |q!vLt ݠO݀ ix"GGODGD$D|aH!w!СItPmIءjG!GH!-*M-"D@D8"&aFd'C4Oܼ!a% @ $1%DX"Jl+aL (v ɏ+a+D-^bbB eH㌀yt;%@ DX $C)O"@OF(!9#O sFaCLcBVD{8 wJ%}Fb,Jh-:,&$dx@d,jP j|M%2d%!ER)G%|M$+ \BN$KWCpó 7F LXH(A@bBd }/CHÖ4?35Is#|޾CD [TDL[n&T(@8^0P &0ař$y&ŵ^J8P0ޠ%bcdz&e"ZL2AūX"| L.N, ?Ԧ}"haXC9? (*OB[Pd +@h_:N @Z  uA8@V !9 L Ɩ p QBA BYB DQ ȁ+@n("%fbR$Hp$m&FeZ$-ha(&9c2-eH X5dAYAԃT@%X3 C XM8DH7\*54S2Hi*$!0Dd]U2p-AC<4Ckf ,%L=G-0X] ǚC/BɁ,Cm*(WB!5|x ɺ)q(j?^D`^NhGTTpd2/(HN+^`GdXeY5B HS~Bli4úd8 'Y$ 8/XC(4'0E سM8CxC.% fUA1@XBrȴ ́ !CIq1L+Hhbc>+Ek6^k؀P$z!RE-POk"$7lId)X XlhXCBn.$hu&$UCC< @-[ A 2>,0XfCQ@ Rn;p.*,mx6 ѺA! WpވA`b C &ꝭ~Ҕtmeiض-zvO̘0 TBNL_MB20C H^5kuH( 'H32,8Qx \X@ CEALBU= A(@-O\\: "t.Hn@m +5,GA|5IQpA6HG m@ qm*kDpCi!HZfx!^+Bfc*+nd(#ff9bn"v&, ׼@.=2 P,#B4Rg4 5ML52X`2B)d/D@l+Ϡa ͆T,GaBƒA6FV+졢0FBDޡ=#?2F-!"G̍SAKh@D޴ިl#ZF־^4LOBPL?vD)**"2+3YrIjDBSrRhgr Q0bG2?7s0CJBZ.Ղ\YdbA>D0")ZAL NلQ%bc<HCC|08TC ho\j!A (|$4<`"Z&rfTWdn+dg>g6u!/=2Wwu%۶Dp?8tT@3ϑ$rU.NQ|z\?5 ,xDe&O,wjD 0bGb~?'hA6L KGn.fKDm XADm^BnT@ϝ4LVHo{bF5q_rQc"w?wV8 VcrV Cϸl2`dÖSE2@dteŊAř P 9pC7X%1 @q ؁ \l#YXm( 3d)pE5Mǖµc8yEcfۜ :VI WNl+Qժ*T dl~h @(H&OVbϛ?_=فg׾{wc/]yyW~xǏ}b3?zy=+ ˡ7h$ lB ab!n0kk0 ,ev_iZ[og`u{9hbgKh\e畵\Qh˒պ+X%cۜW>Tߵ=V(Ue7읺mn׹N)1YO> n;WNnМ/o@fϽ/gyV ujU@ѓSx6>GxX1+@XCA`5$NJ@Z,eSv1fzXMK֟A!+t A%7`t@^B8Z#8@ `%@jtcT :B :p9S8`g N1|e";)nWpe=vSOH-ETb3I#{@! b FZ4b`0 D] 8@I4m) "+@nd>#V1ռ4 oDD2+ > [r EJ D-q rPu/@@ЁYmjpBxX J0 /D C/d1lbAZAFFeN؃O0OYU ;;k[ 'vFB%"b!W`TB3pd&*f8CiB2Jt9H5?0'Rl$z@,aAA<x(> CsA/̐ 1';LN{5 @UÄjbY$` k\W`jNP;Q8D.btլpqwlns\vhNP7 4Jw򂾰Ds¢c 1x-6bq @ xThF9n] ,+-#upJ,2 3 ,aW:2R0k8Ms$o +kЁ^,$\ȽЍh(8@!swV]ɤza# 󟻃2CsQ =r'8c9mV T`0~v(ȉ a; Y k itP -:AB `AnZ@v `vf 8`Ba`dXڠ`̠T V.C^Qrb6A4c {Q* حl@ * * Kkİ@x y2JWr_? l[Yh [F\F9noP>M82&tc-cf2NrTnOpxoqt iOjQ@bqVjd@)kYmlp1^mj@) mσhOVj&hY̬ٱDV*,@XQ|D ` oq<@ \/陼{002U0R!@, RN jLyo6.X̌4*4'GX̤+ܱ@ b 8!B!DjP@`F t cZă 4 +!tAN X`` b1P$pGVA  )bwP uʢ t)1Z @^ KB :. , $1 3> lf> X*,29Ġ2T: U#R" b` a kI8h3ԉ0=e'fR4&k4lXLSn3[5ckhZd3 7u<mlB` D/! \aZD*AGt) tA` tA @F -&R,.¶+ B ,̠>aLa{ a*a -*:4l6T` 4T(  a @ F+EoNGMj`&'p1/IrsJ{f)l]EJmqy$nKI!x  "d!!d R ܋/,!*P͔A!xI|(AfmB"KbaDb bĔ- `6F,@+j*h `T ޖlZme\#ri5r#[˸E\94_ҵqzo침R]u2U2xqΩ_PUjNA(&!ANր"BX{`!,ā B I =ֆc@7n0!!l\6\L%v3STz6 X^ M2N d3[,2j 3Am]mA7Ls<HǨnOrf:r%q ʌȃ55赃uE_('r VB+0D&"ԁ !DEZv`A/t &c!/jMH- \a[ L8A: zBDA@ņAaW4Ri΍RT Ej@2@ga`nHdL77Zo ɳ%q`3yqVx\/ q=xfv| IOn'LZOerPb+ ?J`{TJF ^" ,<)CZ`|d y[,<@mF_e \$-9@fo v`LRh$/ubZ)V.Q&bv sn d(!eyoq:u:0^m'`pʃ]~"kC!rkڦ+wzZs9(SEvYZTHoi5[Ov!%H7__e $QB*`^`HZ71 L 1P!,ymX^c [f@3 =o R哈DPaZuI@$]OIj,:V@d C v:  RVdE @s'zq]ŻTQ7AwX@ j#gDB znn-,ʃ!by&3)&yB+` J PEj aX fAFL]P~B ̢ā u/ǭ{]oȮK_oQX|2&] 2(jsgn+.h lJ /%Av)9`EcQ=Ֆ rdVR*+bT.  ! "J"IaB!6a`[gfZ@ L؉ 0Od/ɴz,Dc@Cv6W!T;WnC SX50.zWUoݷ|Ѡ,XQ쬄`Na"8S,v"!Uw6`E&n¡ L@@HI,a"v ҫv -a/ NA^$8?t:"@i k `7zAkMCPDS4B4GaoIR~X0@kmm3ZmO4} F,bf0n@b+ZbBRq#ŠEǓ"[| 3L#O~1Νlh5aYJ(1԰Dwx V_ȶzm_.Qo>z袏~nؤz UV9b뱋y"5陛kv٤_0OQɞ4N*z]N`K6F6V+S\O.9xRݟ.)Zhw5g9U/)x{I}U%#$~ӊF*Det Vft-oz:5|P^\q̡_E-qs tQ_GmC,st`E/\^L AXd%÷R#\JWq]{bAIB=2\ 4!HDcQf(:V<tR-_UAw7d^.ԪWs0l^U 0kՖj=íOヨ$6FMOWp:3DÜ LdcPiE0 d BD*cXV9"XGfۊڄ*&]Ztjo):bWlM*,v 7pXM@@+F@Z C؂ V-X"Fⲇ(PE`_t!q8n3CHg-fNH'9:rW_o-;~:v_xta@?P`4eH1 2.Jm0v \c;47^&tCЅ54C4Ё! 5ۅM.uIm$90nƴ2\cꮍ]C2.a-c စf%\ :@i<0`-A[|b`Dx@7@!XPƣ yع-0YIy|l &#JzeLN<!"X620Xd`?^ i Q0 S?"/7,zֵb nhD&C3٫d{ѭr}!|Oan"F'qQMD ])oOb"& AnMMPu!gpy a 3L l5dո#^@ aq0'[8tgSs!6)P- '} &h(*^1A+:&Qa"HBE@@7v'Z-M9*"3JSc־v;.h_}f8RfUdp ),mU m)@@BtX{XqZ3y7\w!|]*0S ] !4;Z  ~WKJF?7ELE;2(xw.WmKgKgB5 Z FU B5H}2dC4Pp "&0рzvA0&՗uIq5R0(:H<|gHSx(EXy[\rxJ, l\ 5``IF``#P%P 1xPz@^ZHC Q] A  ¦0Hi;=L`p`Ռ臿#|EQG:^;c h,0$Adk Gv\b;PΑ ` ֎w ` Tk@$V1t `e& @eYƌ"alEa(G|WJyTK8N;KI@CȱA ސ /A1TH:Fo`Fo Е b &pd )fÀ]i` aܰwY8܀&fB-a 'uE5?(hdDa?Md;jWOf0zr20/3 ` Qp1d0`wi01   qcMY:ϨǔIn(w;m䌣֓ NwFsB $Zk`Q  E$X1#$ ^'0IO) [0pB %c?7f{6%TPT#I9/!"v}GCń}-TEIw`p/c/1130if3$2C0zn &# Bh.BZ WT:x8QWJKH/GLG/mgW͗m7Y*3M*mE7MWIl"?>6z?sǒmhOCwwEA=u'z5D騪%lrx$@:>&B9r((ssa IfF:MN:q$Z$C8Po6OYE4ڪz[~:xuK{ +G47y٘[AH T;Ntrwlj9HmwTNV4KJtJ4JxzU0wԃvH[R\[FJRԪ7SUNX;mf x[ECI'R $*@>4{JQy:T &He;l˷p?: uR #Ε;Oa[|7zG5=z&&-7T׵$sAX+&Kxn[e?Y7`<4XYEKh8?@_jpprBdxvZ18Tp7IۇԪ9 Vꃸܠ5Sf\EB2e1d*Pc9c4Y310s`15`c^ PyPc= iK2WBq~뭜ӰV.[!q` Ga @`{U R@~@IS$\; &\}P#j )  G  Q] ~2d[.zG{@46rl ,lR̬- gl,[-ְnth^ WH t ` $c1  ]J01 0AU dm\$pW1i( @ABp akEmOFD' [ Y'ÐXu" r0;jaZXNiGf1EҐWd1ְ҆JU{_K>ԍ kmփ,AlTt6! @!@P 0p_[k1, xp‰AdQP0M$L(1Ao P]Y? ѡ p #-ϐgY FDWe̶˫t4̃w8R~p#nCd2`d@*Y}&W 4` ^}pu*W0m*=i<Q 9Wp0GY1ЧҠUMKTzE+T2B7|CS ypjU2Yu11}!cn+65\^ɨJw ~CLRF[;@z9$|"\9YU}3U>r33#/HNd kW{ުl|rS.%r5X~0niE 0 xq엵Ǜ%=7Y;FX kJـWJD%t8l6ׇ*yro PV8 E0ؚ`1 0a70k\ 0{F# i 0{_B_0V0/n/~( 5N:A%GETcxXCp`Lo`rdj0o$p;&U0yH` ( e}" У-h ˰0*bEqqx}̓b{ pf ;mŸ^BzXEVq;yjee#VkKזlj+i,BA&ZgAPwv^ePC{9aE3G)S̾wssď\GT/;q%p@&({Ğʣ{8]J=5WUtXuh=N:{O修.`!@;``$$ 5N@%(˓r9˭iT,5APm`#l0k:R@ L7vo7x2rN\#jNd3{hmCe)-riֽ9eaR4![$g;isq(~b0G.J\4`KTTʚ83t}y@ǥo@>UpT$wA]rZ%NwqLAS9k #i1by m^z< F|h>Wҹ%?\%EX>ͣgѥNT)JɽrQ9%&_$5VTReBj56\SW8(=Q)=JRrbnmd"=m Oj$+%Ʉ5>krPj9@RK3@Әb.+)9~6]FsTrQ:,+M8>Ix @nƖvmW{֖ ć[FrSt"o]vTJ[4D*` nJ"R=xE^4q.;HsZpW+ЅUV` F m[3" _S^ $JZV*z8"Ql!'Yϒm܊Ӣ8lg{ioVZ$Q*hԎI%θKf۲3#*Dv^ i FoZM bUڹvAMD3Sw ]614y,?'ͻ]THH~?5$Vԉ:%4'h`ֿ&|&\٦A3蒸UTAf#?6L]e$x^rZGz1-e/u|>* S&;jvԛnQTjgΨe6ox'^Ucw\kIN@Nu9{SuIW\W ާVU=_"N|..yqL<mpkV@EtMԌmѾfqfY{ho[}.ksjte֨=؆VۜZܣ8j r=dL/ՃY.7k8 xf.mFj-WB| 5JK+Yc0 j#s|>{6"c7'"0c8\"S D2S 0?/#"˼-*.[ BS㪈;/l3'{C< +@DCC>\#Bc$Fd4!DKlS? DIDbTS#CSVR0c#c@j0d<{ںcQE˃3*@:#f1 3e[K+{s;;(A2t>CFJBNAp37wGxlB>;,aK-F{a-,IX*ySS:*CɛL$BwrۢBC#|ʓۮw+,Fs3^;sP3r|mJԔLȆ0D)|6̨=,+{{ˢuk\), )YLB4C3ɢ%!3ôLٺ>L)ì8LOt/zt{8tqԥ@.sIu\L$!䰢&MkcG NM|9Sl+Ȣʔd8iBw A|N ޔ=SAD2:?ܩիͧ9k+ %AKS|*,Щ/{FI-7<7Tv{O.lF!ȡCL,E zL3PB4Deˤ ̽RǰKPVR}qylT ݷsLWό(3 {đ[ʊ-7,R,,L5 Dm~@V/CEǗZ@,4t{<]e<aM^ٍJKS4K]DSH{19̖rUO 0N;ڵ%D5%K V*]Ż?؈ZYG"x|/ڃ[=C)TR=[p*QL",JJ+#L«BGsjBd3]w,lk@ZULlY%V$h$]۽THD1X۬(L+mA 7SI/XoTDܚĩ+K T.+TZVu+eh#Vs]^iWspL+ǁH[^NjE5J(%.{QH*kͱp5,i,P -x f q^`~o6w^ ZxD`}MNs"tUԜ*2aݢ%CEa FeZND\O?ҴL}=Qu:]]\.6ҽ-Shё 䚤1[E$B[ ZBD{[L.dk OTDY錩dASS2¥pE:oA&J}S9kRm:AxWn2Zt5R["jr;ZSXcID#I{Ƶf;1y )9ZI^W>)KfP}lB|ݪ݌\\^lVy8MjgK/Xa~U%F ^^8ofV+>~`+n\_~_SdmXadmy: ,B:Ҵ/ .mnԓXSVfݽ>B3{?爑!,F^#sSaof `FnuA-"]}bOb,Jm*6.#ҤNql/9ŚDk#4$DdδCkO,r/r0s1s2/s3?s4Os5_s6os7s8s9s:s;a'=wcF"Mt)ӦNB*uUG`ͪu+׬=x 6زf@u-[! ,~J H*\ȰÇ#.$`3jȱǏ CIɓ(S\ɲ`< ?-sɳϟ@'ѢH*MtӦPJJuժXj-J@e3P@C0 4ulзpʝKݻx"qXN@T)#@A8qX4#K,ʘ98BTyA Zͺװc˞M۸snK{?8_A1(bf)A Ã/<ӣ_=ß/P .(ׁh߀H&^v 6R AVh?ex($X(2B a)(4&g#Є8"Y;&dN3ɢ@NtEF?D??CD'Je+>3dGAeAtrAir&$N2="eqEu褔JwC lC@q?Dd^uX ebA!O8aª eA4|L@@~*B<+ t@pז$pgt@4 @p e Bgh.vz~pG{z{ 2Am "6W+ߔWv@tA?jKX{@0U Z.P0@^4@N^177a=G^?B˻opjo ]觿4 0B4y41r}rL@XCC7x`'@   b Zp -dv!WB̀!9rlb+G 86f p~kb"2AH감 eتg"O!c S1# h ֣ % rרDoR% djdF\l`b7x2 c̍a1 QuD!&g6$jDT)kA2}ڱt0nʶ_ `iMm%!JMu@w  7 X\:P7co dN%ބ7t #NSi|y#twe̶M ~Qo#ֲ@` G-b$Fr021-3n%`JWpnVEu3c@#2ցTAd"wByvu 0dxap){ rcF5a!Mo,Xlua V֮$.O n%[# 0AO0AstoK;Y#ja)}B b}d]T65'>,Cu  w~ 1r}e8rQ =/jr, A~A񷀍m7:W}t3'(xwkvuRi7v<3bx'#1(׃vA^8"Z&oE1s6`&'([Sgh'؆phm1Zk,n(v;s pX w(#_bgG.0tu1oI+"k4<ƇY|X+ I `RGf_O@G/X+i0`g7R 0Cl2 PQ7PP ;@o@473}#2  (lǎ1 Do 7/`F/ `0 p0Nd@Ӈnw'3{P+RpVXZeAe`-p nA(l~p'xp  u1 x@f'\‰b I,X/rXi)bdž\R p!A}7}@W0 'L8x1@ E4藊WByVz)C7Wpˡ)<"2ޅ' Ӈy `3hfc.y3e~0aDpOb_ 4Gxq nBBdGiWPEHv83yoA_v@Uum֠("7o !<e-0& F508z, a3Ckx P&9 |`.TJga "`2bB PtŞd % Pg!m0ѡ'r# h)urU' 2?֢u+4#bv&s#Yjx%o'[A[&,1r?EZ1F*Q*h߱_BAKyhzv%/(ЂCud/0Q2UgGV)nը:0Q, i0}F`$"zcJ)Yd'! xrB.b[鉯[ aH ]5V[cQ6"9Wa0uv!cre$!rS  aDN7@L"p& 7{|~hv>k! R 1wp$i#`X0%& ^c@!Ȑ YB Ts5\C%0(bDSCI`X3 %\M7 OqY2q(*aB@ʎ[y1h b0f  |/ u"WX"Xb5WT2K&F 4 ZY a @{ʠ5` u9QU # ZĉnYЈP 0Ps7'"J$XİbLx15uAqpp'o&8(8iF/ dA6Tbsb`gQ!O dUs;<0. l"[e0X .2\!0 "SR7O%XŠ03ZN2 &`$@0 5DEw 5[#5?60ڳmJlܚc;foð.Ur>#F/ -E#ǭLs#Ϝ![ ڼ|07ě6'yc܄x)  A.-$ $#61b.q aXJ4koo1pE u&B :";à`ln4  Q{_|R72 03It/\ Ȕ#10϶:R`8q 8" ;P%f`0@'@u Ȳ='DKy:f0& " Y}"C(cJ[=D!X^@90[s_9(q #UJ*fTz_o_xt` >yJ%cOFkXsg4 IUpzUԐ,4 ; 6uw-0M 9M9_FÐt6 J$krS4{NCpPIW Ofz@SRuP>*p&nA]T*Mk"-)>~}У߿ <8P!3f!xІ˿ @hoL/8 RaE&(/.9tb Nj*1BETRM>UTU^ŚUV]2apA] 50Srǎ,R\u5I%`"<ɱl_?Ydʕ-_,7ն=ZhҥM{6`zHZ2a0QH>(c@{Zr͝?l*,picxsҋIǟ?tޑ ehjdDP܃ Lʿh>,ZCOB  dʉYXb$ABhFP9@@z/H!$ȧPRE,o *\ģ>'dLte(YS!DJĚ^dH6iO/0fnS;#7SOAS$,@:fRhF'^fcn(pŃTp*䟩BY&pX4r %g w&J5y>8âqN:s7'78/B <\!_`3ɶkXA]%  HPQK: 䆮 &$0 P Tll"s'? -ޱ}nk$LӚX_i@ЀR_Ԡ,~GUFYF"$ġ()N?Ѕ/Pf-J60,]1P<r9H`D&#HcL ?%bI?`Qc ;P ¸) w EXXn1iST`BJbD08IJr& L>HG$!@$YXx 70:cF)d #A)r ы f. /̢*ѨB $(~f\e%9N#qdN ]vka5Ќ,TdwiR.BFԆZ$Ԩh| jf> 6ړr+ -Ġ9%iL*4i$ 50dB0|bH (>H  Pb6) 7i?a*0.9"rJ (8E\ %ԯPKf4b'F^]?HH$`5W5@W`)JE82aa,[JZt$ !mR1$R ,ErBr tt!$P.4.w-R$@&%pE0L[p\3 !]rW$]Ēm3^ ;a `f$#1dnځA$(R.b)3`Q aZct f>6)V M]t ƨA(`!& qԊ0CQB)%S$-^/@ AX n; ! Zq 6hQH+Q6{l<8҆`4lYDt EPʆ'v/2C dQ;&8q iĪ`g9TjBQp.G'P#0E@`h23T݅gӆ790@܆\woJ/p΢^`,&u>]H) $./8_@m@d8FaR`\P&B,(D52HH \󏐛Nr4A[c AJE Q TlVt /%Cx 9Gђ^HxM1W|/ K[^_,l–*A#F&S ,J28?X1 Ю@  ꍑISS]HP>i7삂-s 3 pJRCS ` D1[5P2R/KYHΈ@,,A*zZȄ$ p*F00h%19 0)[n ZSQ;-BK!`L ug K *Z7pQdȃp q:R3l "hh^hOh4.[a0Q2A hkƋWHS^x >'f~@`}ҘP4Q 'byh`8ְ ,6  G<Y}"I'֧iQ$ X_ `X cݛ`䨶&6FVfvP ZS *e`नTjp/hMP 0 nZ_&g9!1,ǁ/F/Z|R6B& ?0 /lK_1<mdΐ06A[ @\(Thj0! n6 RїHeD=TXWMn0rˎm+6ԄGE֕Nuh;ɗɆcTVz xXhk`.q**k f(fȹ`>@9A0ڱX H159W5Eut3x'"Ȅ!xn`?RڋT/{Xj%]Sm.@(P^sFl(lJnsQp@(m; (hpK<ш;'rTZvx mӅH[n x(I*2gp'L?F0FPTuBYprKq>q^޼9阐,r E V5Bwv$6PNi(WApq0wS.C}7fGQwWl*} :dWut[_JR^_6X``}%VHbNQgw,.W@$y S?⟇k7}WϤ osؤzgW|zg?isTkW&GWgw'7GWgwLJȗɧʷ'7GWgwׇؗ٧ڷ'7GWgw'7GWgw5OBr ,h „ 2$!Ĉ HX"FC2r̘Ņ:Bp I-\![ f8;^܉АϠ YQ C2ԥS-zURėBb5HQĿ[Œ 0j;cV mˑ[ "QXa!܅< _P j(lDm%2 Bla 5KD"Rc=(3|IvnlT. %M9vD~#]A:G8z^ Y\!iH|:ሽ|Q81Ah0N==OHZ2Ϳ rHXGA 84 !9vK#t(AdO%P42Pz %B3'`ZDu?p\("jDr1E' [7] x㎰10}f1@!$TtФ<şTRY喟eB%e1iQfw_‡}t9LH`矀rV@P LhԤ6 h2 @%D4v @ P *P!հ'B鬴9BiKkUJP7Kk@jLTU,09Pr6Z^+Mer )T@n:P^櫯e^p@PAl'| 7l[/Bl1wq^1K{Y,1ƔP0{Y1PcNu*Ai[,Lʁ#7Wr2@ ہ wBH @ U@ĭB^F@AZ;T-ኞbe `r1RA!b2%P@}CڄegSi0?_Zs.1! L?vÄea%8 6K\SH5r%@̺i|r\#F y[nt [N]*z!Vld u@ >duc YO#y\un z9a/,j0 u;Ns( e$WxwEҊBo,@?J!"\!/[a^}J nE7@D\ȡ/cf\sr p /`j@DlL1yJ $)lLHTB@A1\ck?zq cxR%Ͱb]U 2}b;] Z)6M Tu0H~u` I R f:'dRjĚB. `9BY1`lbFS: R_iӿTA Dxh6$Ԓz~ƫj|ʞ(<)TӢKTT ]JX:kTG!\d+ R40T`KM,b@ݜE Yuf7z hEVHl 5 jn5kvliW Ϩ BĶ -`ۿJ llmfປ.o[Ɩ Ўcz:uI@*6}5 d S /g 4pn7`p{d m @-}5K_ m>[bٶ-a0U@6.\PȘ.=׾Uh1 [W7#2p)@=Ae̳Ult#g6uL:~]pH…5JBPy"ȴ4Җ lLGWӚ?MNǤZVb;E髣TZ_B լ@1\ZJf5{p3FUgQjA]i;{H@C gZ]h3[2,z8&m{ saF$`*hڐƒ^ri!H,-` ASȤ(khaTФ @$ LrTa(dUxq G55Nlf]h>T] J`(m) y`RF/7 Q mJ 0 xP+j ;W!C0 !!M  5=U7 SAS &A 0P7 0 wGhP!~pY=wtG"9J_ 7U N!&蓨9!/*%KP 1 /P ANJD@T yoD*oz '`;b q "z4I!thƨ 㡢 ` ё?{*j@Hq s <LةcWKʫLJ!Ns|+p8. d.F}-MRqa&z&1*0ua {r[-)g ma!Y Q ɋQ-Q}t$%9h)qAw*?3q2Q@)ٰ(p%b6E7z@*W@a}ikRPH2ZvȀ0e5'2N:mk4ۡKa C{TQ3]z{ F{7/<Ȣ  pBRJAUС !W;Nn DZK@7Z2%`)o40u/"8|ځk(!'}`5lS:sr"V 5շEQ).LR%([$.gگ]uBk0!V00QK<$jr D,{NN!%qo#3'4K3rb #n(?gQvKX=h"j\b JЬl rI#1qt`TAx` ,K=H_R++bNBf y ,0& F" 271D /ސn{#Sg_p S2.dV^~*sόQ2 @P 5t:M.q.%g1}n_Sp,1)?tWAc6sĠA DRJ-]SL5męSN=}ܙy ߃JG6Ce WᥚV`pcA &V!؂x 2HٲY߬KR(!mA'Ի`?Ydʕ-_IAP04ʍ @m.,Qzʱ r#cBW;%l`]tխ_Ip+GoWI潋G^zݿd|3b̦I~p7V.3+V&\3hХ u%?1DGnC Š"db %GRAD fdqjҊD!$}) h\ʢ `!@֨ARk#DJ V< 16 U9!22O=XDIвPAZx&yDPB)L D7᪠@$fZ"c34 LH>wW^qKS4%D6b!+* ǂ%gT eR%<̰(T `V dRѕ0YlȈA^\}_C^H zX@pZb(uXRT.[2Xu˒PB6b ZQcRS/@vglNIthTB[ ?`8dh#`d5H)Fabp F/ h89pDZ7C-; qjS[7i8Rc[3 16 G=uWLt.Ec=vg' "v;xɕv 뜲c>9a팱yF`K *Vrx%֥>1ѭz/B0Ql\*;C` c}K$]tQWA&a4xH&o[m[X"0&ͭFyc-?$Fh&_"B2T JZ šacK_r;;@M"%Zn?❂.'J j=*GX`.H:%nv9CZNpF,aY[( gϫTy6G{R=]hFft/NYҗtciMwӟuE=jRԧFuUjVկue=kZַuuk^׿tՂxsFvW\` ۂ2!(ژHepB7M "&^P6E׆wM<&d"`DYK±F8,ϖ8E<|9`**H"\`٥@>vIIFwB\hq! BoGNG!kDrqPm\H2霅>>uWKU:Vz%]gj >8b!dGHG]291†L iǻڔ;%nA-[@4'V 6Zwl, 7>h'-u7h,;` MOAAHGcV-b &‹H6aȘGAhd/?{wO U̔ &d,>%~l89VV|Scp0C9ZN;h $4D45NS []p?Ab l? 0d &< ,2B!B>b @@`xp%ɆhP‰P8 ix*Anո: @ <( &x=8TA`J *C@t@2Y' 3`(pAEAI DBC+؝ )# 9 BR ̉0:ָ7 FQ|jCjno(>0ş n䍸FK A*Hx _z}Xg_z nl0 ƈtAPH-{ظFxdH+28hڈwn`H>+I *耇\ϙ)ȌFʪƛʬʭ ʱt&KJ-B˶+:$K p}dՐƿ$4LpTdtDŽȔɤʴ$4DTdtׄؔ٤ڴ$4DTdt$4DTdt%5EUeu %5ѵ: ږ r-Z WºG[ dE] @eƨC,KuPh>[R mܕB.TR g݉G ʼn4&iڝ`8Ǩǽ ֝h(0ĉl{Uz]˵x՞ ^DU !ZغPH1 -#5@]սQ} ؍e(%Z@_ H`"* ~  a+] 4ԫƂ )`S ~@m-\h^UhRGP TȠYёhbݡQ`Pư[3oIǙ4 ̘~ c (5q)+n4FQ\II8  Ⱦ=Fhm}ݑ?6X! ,}J H*\ȰÇ#.t$ŋ3jȱǏ CIɓ(Sr@˗0cʜI͛8sJLf%gtBh`H*]ʴӧP5g -_7JٳhӪ][HB>;Ң!˷߿RP`Gǐ#KXdެ3ϞC-4ӦS^5P?2 +B CcGBNسk.3Vg/:~y|H,ga.~r( #A P0]6g\qu@pUS$Q-O@u@tQAH0?Hh["#A3 aX L!AP43P sdBzN)' @% )@OV@߅%ЙsU' YK8f^$@A8Ч|J{R9 )[4pӂSF_s٩DUw hfe,_{V.u(B UgjWqիv^y/`HH'geVP/r EggR YS]K31@_BBFB+k,43$A_E7".-@DH'AȢQ-1qW/rij@N ,P p;@a{,G*E@sTTAqn~@)+V{TP♇.z訧m+/tM骣NxO"e}%,fo x ͞X@|A |CG'B2JgPCQߟr c !AccaɄS b!D9+B$g!?b%B#BNj ҈ ΂9-@4ؿap8î1y F[!@G 4 !P&W"da?7uRKԤh /B 93umsp] K 6- h$JIfaco)s׬ d-Wzz+<ʀPl_!(]C}&zO6Df6vEc8n697H`$0y'4K.tyu.w= b~/9[*S%]lZ(h Od8d>:wxo ^;A| M tEyK |<w=ĆQL^a-H^ZXS)Bl,H#Pvu5T9ws^7x>| =89ox7rn8rfr'w3=EsH;:qCAxL @y1-i̅qaa_S13ASw!.I d7-2Var-aà Q\0Q+ (G) v{UV.؂8S. h ex@ /Ѡ:!'aN!dV\gCb Sj1qs 0<ҳa^qhA8Ӊ3#xUh&%$=ZH*uhx&i5rbeB[38sVz0q$a2IjQ/`T:q(DBV!cGdA 'CFs/$x$ h/0S f$@8 Y*GggTXq ZͶN,6zP-#->'O~4JsJZ%QϳkW?. E_e$ ۰ák8R {P+8i °Qxq='o f0q{pq&׳#h%J, jqAGF 5)-q]kNbB` 2Q4sy3<r?6=M?f0 ! ! u1 v+y % 3WG x `*MT+I#;+ $Ns bJ4P2"뻒QXq?)Py#IjavP&P6EJ%@A1/u Hk[߃_>2 -aPc G9. JFq u` r+W7 b,WGU[8@, UvfkV`nukW:96V):ֻ2$C;.8k|q\sȐ 5Ǽ(O`kW|̱QA; [kqQ\1 ]<ِ5[c d/WO"ϋ0e `,뱏Ob Qi ZAЛ y k;Oư>Ē`O4S48̅{YlG3{3-:̽^HޑIp,L aH}6EP64ns45`AJeЪ`*"4]Q RBUDX1aa @Z> Q:zbA<-^ 0 }йx߱ y$zq(ԝ$E) Wna{:$p _a;aS]M T2tF(ي|v_3XAAAy\P9;EКLߋ>v p-b@IdGA_Q#04$KC@[-/ȸײ#d%w>l)b(hxxֶ3V}9!, -MRZ> 2eV\W4#>̡" {$&[P#:9H۳6.0q` ̫H#20.5$_# QS.1$e `fN$2H3Hc- aE. x~ЄA p[ Ð,2 ~p1 ff Ӎ2;]МQYNͭ12@< >}.2'eS.:1 'G 0]$FD%xхؒ#Pգ;)Λh$(JNPH4AppM1~8b a [Pԩ E 9#" /; Q@,ԑD<0 xٟՈ$BHK=SXG"^л- <ñPx XQP +T C87cv & C[v/fà΋t>)#2sO2MrMP0616P\5ekW7Vb詪(P~X:_&%_~+(_QßU"'k0C O|V25E -s+N!cELsWeXAarڈV Siꠉ;!TZ>O@ DPB >QD-^ĘQF=b 00&"$•"74a"L4yX"N=}TPEpĨ16 : Ac;A 9u`/'- TXe͞E+V+AKG"+hߧ!@SPk`3>&@+-?ٚ> І@'t `N!sj ,dX-y1i}\S=%\,i˂@-3HҌB)* &a(T47B /{Ͻ+;Cj/ :5tC?1Ăa c JĠ3L:5&H>+<3"3bțk0P)Wѭ lC'𒠯*l!DdM7߄3ϼlɄJ6--@ɁA H 'д:LJn3&(,n @CHs+z1NcE6ΠO%(a-PB G%): "5&(T ZC Łj\W(ʛjЉ kxata=uP:?|+@k2x?Ahl!a$C V!2v0p ! W(~i 0 (6I1ha7(0 2,Doxsf05O d vX f-m)$F6'd !| Q %ib} D#LTYj`I`= <9@ y Bt1=(b PJ @,HFqu@QA!} <\T []h݄|-=H RUn{ Ti~.B2NdE+P{6 (I\Wf$x{jm&pU{+MuI0lQl˭.lHII86հ5V"ʗQ NH#fYjjD,QbpEmj}stS(}aLzTdQmp!ti \cpVBD QlDd!zbን)f!-AtrKc3S4kV ׽ a#,!H=f 3ĢX0e/Ȉ.cLdA0 G7:c\ ( Q +J _x"u*H*0$@ C%ɘh=W0L>)@3 Ejc2!-RaDHET%3x@~j"d"r@ HQ"9|Q@? OGQBj)6b4/f6 ëb ̯uA\YdXRR]0H2 <*S#SdebxS y\cfngBR\n :XL'ޕ& frZ\j%  d@XIA=`LդMQp d4XU 5 `1P b3&s=sm_+c% ,kʢ6_m!Y0y/ͥ>K&䩡mNvT&i:>vLo*֊~M7&y/J\ȊRc"rp d{C LX2=dqyJ ss|v&d%<>"ޠZTéݙ7A,X|I-ž$I!C]#SYpR /MB!sgJ  yxsvwѾƩWcXMc|Z2@ӳ%(SBRqK#xS "_bPA)#OL+*<%h5# / B*y " [.?0 [hi‡#$q`_Ke ERJ !@PI1K$@`Q8 %2!K&hlx Rێ'm q1P ;u"7 <R(a(u# xvX:EnR@Й@@"v. !ɢU0Jtxh@\ٗ"# $!'`1ӊIsTjɹ/oT*9*: ڰ၉4ں1tJA޳ ˼шrC!yq08fЃ{ʵĐ9۫HԲk&Jڥ0(T̍YE $ SA$l`=u2) e߰ DXa8D$PH pTCk*`v {*'ꀌ0υLI+!)'\/c1 FUV6ɬr-C(* 1J X }\ɨa)ЖJeךt,K ++~5؃u/D؅e؆u؇؈؉؋،؍؎؏ِّ%ْ5ٷQXc%uYΊdF*MT.|ٜ=,,c#;9 Wx.eZ k 8?kYm(٦۸t,tXR #$[hęn) ۽p< %K ف hCF8LY,iXqhn*:ܶqAN𨕰ABiٗCS7n`̅15̏z@z|T$ڦ,֍\I$Xu^Z3{myl\H[D:Ed1m Q@a@ DCɼ܁`Xx ȆbiO!?q"#Dh';>Z 6R' p)؁j==K`ᩎUo V%# NHihu–lB&!'ul)=uJkG%N+P]$V0BE=CX`U] N\T$kY5F@ mH};鍮HqTTCD6e?^u)ISYZ[\]^_`a&b6cFd6,% VVf%PݤY ߌHgNR/X)v\Z zC8xڗ1 93 NP=2h6tpS:C2pa#xABbHgF_~$+`ayh+36xєL8'P1kSVA H ?h޻%zIlZf.qfX~m x5 Z26ZKi0bE~ɢ>%ȕO@R30r2$e0dyvnM?ᆕ@;.t.E1k@ɐUﰅ <xa"7xxj` `޵O* 5TXi8 %qYXPHBݒ!Q$0ohYRcf 'a0r0'3G4+#d%lr5gIX @is,5 'ks&Z(1 b@Gf!F3 Wt::-I?nPVMOR7SGuuTgV?fkXhWrZ[\]^_`a'b7cGdWegfwghijklmnopq'r7sGtWugvwwxyz{|}~'7GWgw'7GWgwz uOt֠ﬡ_(g Љ H_hpb?ˎ ( kLX F\c{ܖZ TK0 `W.4Ρh3ʮ  z *U B^@}_t>o {XF@ް}V_Nԯ8hЄ=p qPၹ`H]Y|˯ 0 l!>Ca cCRhx$z4TE3sy߂9Q0eI@q"@ S`) |H!L*}*Ňw2Tr̹Tj*Q?6ԑ_%}0?A(qru0˗7fD!a<+B. ,А@taEUԁ灚Șd2Mǂ4=nUGg2_^F8>j.Dg6|2P79\I.4\B H`4cCarDs`~(_])y0YE? WR4R_eÆsQd @ġDAU! "5^JL:DQh-ЃKIQ$ٶx 0Us q?` %u@#@W>nµf4 %4"oeH UJJ9^і|9)МE?l1WZO F[Uؐ|u2T1%) O5 T))Epe0 զ%Yp)I•lCHR`81@\ڗD#[җ$H%;I+_BJf#QK@$%y- ŲD@F'OpF!(niI/Cʼn_ؐլ/EW@JD\z9꟫.袇.꧋.ꍯxЬks<]+& I@DKnK?C-Aks?7>䣿>! ,^:E!_*\XÇ_(hE \ȱǏ C  }Lxc% . ! ,L! ,%S  HংuS`YsJHE^ .)XL8YjyG^fu6W]@^\A@9dS(.ifdK2jl&q LxUaP p@ < @gW}(Vh զ>4PL^XV(ڪP*B buk 4N$+jހ{zIU:`U404 0 4d6ppu* $B"[E*@B" \Q 0$L2@?Dz@P7M@g#-@Q\-WA]A#l A `OrjN_upSl@C* l^p4bT1X#l 4MULC}l8px",<@mǻvN(4:d0*9\z:NK0A>)@@Lf@<~,K +C#Խ&JSM?IUZQŽ 3 dS p}u2$^D 8xe ؇Q.bP #@"WFp ~G 6Hl8< 4`` dc@H z$ @ :r$!!  Z!ZjF\@t"H9e@ٰ[zINh8Nj;N?4f53wH uGz @bs `@b@A+$"oFfڇf &@Њā$ PAVrvNAJRQʵTH&%!7+t/&gji~[~nnk r[t=y%!0EI^ &/N0` .; 2l0F0`=BGDISE Enj,Л` ā O\X,|An[6*D$=OPVNl0,d" s_;S`Cd:J>3~MBCƆN~#UI[ҘtTRDd 5մi_xzԨS6Tz=v~gMkָ&L2\1HV_% 3A@ڣ n A:&TA솼 A*8SCd%9ӵ2 `(!@W9 ^~l#Bu/DiuF]Cs&z}|@.[Hf7Kb`'H|C!`#Ϲ0FvKV~dcSMbbHc pFCIC!VdGv x|=Q ` @~La `pa6PXpW0 }-vo,*hqq8؃>o5bu?P1xPEtWNPMHT` :]U opM'ǃ^hKYUmw_&H(|hAZ9xa xc hcˆZ3 a(X/H{LGh‰w vcj1%`]b752<PSk@B9DYFFwJLٔNHOai#GSZ\ٕ R)pf1I zhii VkhR 07ضwxXG5.H{XYy٘9Yy"yXz Q|0 =[[p"` ]KTs1 Ն mLWɅQ0L|5AR.(NYh]y<ٞ)dYx9ٟ) :Zz ڠ:Zzڡ ":$Z&z(*,ڢ.02:4Z6z8:<ڣ>@B:DZFzHJLڤNPR:TZVzXZ\ڥ^`b:dZfzhjlڦnpr:tZvzxz|ڧ~#z j)02Z'7yQ$3;qU'/@Z(  (R߲_ :¨kZJdo=ѧ   Z{! hS2VI7\jZV: X:`+ S @AaoBV)VQDVktti ! ,W H*\ȰÇ#JHŋ3jQa3CIɓ(S\ɲ˗0cʜ)1?:ɳϟ@IѣH*]a JJիX^ YdKٳhn۷p%J_y˷߿ɓSbÈ+^@vWrk^;׮CMtu9];ʁn2^ ͻ ?]#os]Ι;z9YaËYBc]N:?^N_ms^^[($?r\39g9=\u{c?݂V("E t<;-&eƙrm6qw+&+:v]z5Ygfr});^c2ih]%ۛ̓dti\x&l2a!ƞBh*' Lg!5馜駠ZjjZjJJpU+HP, i cL ndm1d覫DG/r=Vl2z@ \ہ -Pl 垻W, S4kګi jR,\3F sbĵ0F/ƈ;K0m4h1%L-145bpL 8[ɲlxu N2cL?QSЮ(E ͬl|A+0 .!j, QB { ?_ 'y b5\CRtcr`crK:b3G ,=^XN@ b8 _|QA-_8*lL:=hy3QF|ᅶD7-bNJ51`_86@oS@N;I7 zsyަ*N)%G7V0[@ DWB$F@ P4a 1! R `A̢27\!? l`hL#VBB(N|6X  .)rL:v~ @JЂMBІ:Izъ AiюfVHGG:&(MJWҖ0LgJӚ8ͩNwӞ@ P^C$Rd KjB*UE!5VBǭz /!JV^ eMZֶ*\JW> u/*5+Q*Mb:d'KZͬf7[Rz hGKҚMjWֺlgKͭn) pKMr\PЍtKZMQFKNa N8݉)˯t|Kͯ~L`Bm`?B'L [ΰ7{ GL(NW2Ɇ-  (|ȃkl$%kxr$C{]P20^9KrN]!󒽻8ݝӫ>_;d^Owc^=A(dH@;'s6&ďXyv!d3 4?%^S"9W"!t1ω$߇<cΐ]9bt' 90\v)o2{N(*yi 9rhxUA{矖E' Jl*be{%I2JТl"O!*ReV?&j (@@(@*Pk іjv&d zV@[iuF+Np$8A&PtjK[pӎF.L{7.4" i2 RbT yCU@s%\D2KLQ.i@4%AbAN 15T ǘd\A Z# qBsLyc\@ a,Z{V`sAT #+@ ́e@cqDB{t,bsKTgpKtlL͓0KȆP M] 4 T,-{4D܍Q]p_Lu7-` Իn@ ?%te=c# uC^G cA5(|m ]`CoZYkX]b 8"^𴗭0jMS 6!L ,!/TH WH'xFn4/Y[BU<q] @@:gyx`AXD1"0D#zqZ4?мc҈A9|H*4 5)_ zH@ }X#`bt 4H3-z(R~7G$ 'ho|fDA]Hh` U30d@Lj1dE樾Z [c5i)M(* BVϜLRbG ј RP,- 9A ?fK h@"P5LBφJ -obQ6EDӅӣDgPF3RQ$X ?c sa-7"viV95H2qY(^ X(w  !̻O-jL?|l!? MkϾFNOr1 Ъe1$A?&t %eJQJShsoc?FPOm} (-tfWB@u ~.@c'USUe CJb q n e16Q$fM@ G} q  E.dug|f#ҀtlawES1fM @Z! R%7~ eSxPc{yO1bl Q/-(Aaq nU a3`cea:VHpV1nf}Eu g T& g  c' Fq7Zl'Uf {#PqVZ)' ϠE  Z` *N  t  tlK&Uvlt !c? pV 0 U a&R U1 *p`WCNQi &7)GpXNA ܀І.WFO$&@9R@O  gXPp7@pX݄Mqd:$h&\@.  Kf^Yn@@i~g [Z h6Fm~ s( tOL&V`~R€ .yrg3 *P6 dʀg(m `p ԙ`pƦ @tVs0t4*px О jhM7 'Oy aaY7"co P d_ a`@kh j`iqhZ pMb[xj$fPf!1|3eg@ xtϠ ( pja7Ga @Z΀ [͠"X`@BNeP=Ix%#zFFtbܰjP=[0dLC6!c N1P7gac7Nh pPP{ C5@d!# 7&H@Zp0 HK΀ w*1 HUf`:TTH}.Y*Y`_Q#C Ta*P 5gZɢ #e70$ Yd pc *j {` y[@ЏWU#P- *R!Q@ yp ;ʐj P|iz- c;@Oqr{(U-;1 B R7cr|^|nзA1p K502PT23 ^` 6-#޲^@ rP% ^0;NSbTn]LLu`<6ZcD3 |s"!^ Zu07P|1` p5N r p r `35P&=Tp _@_ Cڳ ؀ KP Lr@ \ \@`/U 5p K@|Sp u˾\fn49̈zbǽ e]G\%P4?rP7,)}]r0 DNԳuF Ǜ0@F` F %=QƗM}Ѕ נ< bZ p t%4 ;\| "]Pɡm6L%U} Kk|ؔ 7%nd%AVn7eSZr@אSP5` ؠ% sp ɳPs Ӏ-rp  EA} 9ƣ% /NД|Np ذ MқLgLѬ~55}-P6`+?56=,ش@Dp%VRTsN`%` N<1-@4~W1gSmOaayL5,ŷ6 0L15>T~9!ڢ71 p壒>"P@G0Uf1ʴpS|-B q_n恁>_4^I0 +4nG0n014@$*6Mos@@ p{GU@D< =}\`qhjz`*@$0r0G#P440$A0:64y>y0A[K3 ֶXZ[ ~ 0w\ppAEr3@ꢮDSukN64@pN.`$0P%#pܾ١i aafv>TFVAA~@9`>V/p~GByˡ0\Gt<M 1 1EF:эþ~1=p @GR ^0F> lNBގN>?iu{@Ճ 0Ъ0 JKAk5~jS6z??@YV|.*\}'~ZY17L~4m?h\)O? g @#@QDZĘq"č hyŐ%MDRJ-]Yɘ5mL ?op7RB8=RM>UTPuZPcҊ=!r<"XBfDP3֠t5 \!xknUƍl[|u@xZ-xB3`b3W+ Ƨ8r3DG{x `M0#oٖ[! ƹ]Q!e\/N9ڠ`S fYJ `бFFuQaʱff֩! pZ 5iJᆈ<Ac|9Ap6="@:n-ci|Qde,oHDn /pq*>  N,b@F%@h[L% &U,;%iVd?J!⿉f؊$>tH?` i20` xx2C#^ oHD0qB x9D ,da0bk\";5y N3%X8%ni#SyG@ό3$HgySo)@NTF(u$aT"HD1Qnu ͡[PZRxr:K"ϕDKADNI<:t 5, LTδJ賆BH&:go$BlS*XXiq%g-?$F ZSҏLb51bΊw W  >*PNp !BŠv?* >dUkQ@1jq<r!EŤƍ)S$ 2@c\Ph?Jکǻ+Ip@@)Y0Gidv@g<({@0o$ \0Yp9XcFG#pn<@PNJcȔAtǎ|'T<Ы/H/)iPP(-(9pn 1ȦBk #B9@XB(B&qMA!9E<7@cȶшGpJbK9F"*.8˿ic(/X4YG/9XH^X1l\/9cpmR葃Ǭ ^098/8IbU@J&Bic/M8/YPYc/LdNXB`ĈkGǨ̨N/ , xEur,r)Ć%^^J̡pȍ1,@qzp/XHOMEtu,10D0\cX9(W 'P9 UtQ2, 8!8ߚ΁ 9<L pYkX p(8'҄@XYq9H<҈ *u%(%,eO9ppcMTc(U!8]zPx>3ʊs8@嚈 Tk%&k(@YRW% <L%8koR@Mp,(Bt^u\l[V\DkYkWZwoȆOԈp ɠXȳa@뜩M} Y<08j*:O \!ҖG  T E HX؍DUl QU ( $PqWx רpʼnE\FPÙ(L(?0pĒ崈~JԞe[xYT yZ[U<ջm۾۶5Q+͹ǿev4xm<  @* Hz;< ȝM d[]; ]¡8ވ"p̝eG(ݢ/]`))PZ. \ ׅ&E 9<QD8Ol䉨(m4c(}UF (3!\dcY; ӝcS, 8ڠ0Y otHhV+]~8⪐N ɕfۤ !PRs?]xUf'_6FqdhqB_қM ! +5Fh)H@!`Ό JVYj@ŏ% 58H`"!4z:,.,,>-U g$8*}i۽` H2ݠ0 (#(,HFmxY[k =jԨe(:"GF0n0cȺC$r48``ci)Fy06( i C9h;`ȏV)Gᆻ(o#kvn5Qܠ+}>uSgDi3 ;X<(.37, BSDK4F;4(@ pC&Tgt@8-8 r6i=wSςÒkSH/:#$@諌ppqn!}A1HvӗpAE{&8igpp0<ZȂap<PXmXR'!]mFΰ$ _ f-Bep71`lw  q8ix%$2nik`!kek V8Q6X0n5gl1P@za.p`rMt51`189 CKBe 4vB䉰DkSp)NۘO 2Cu1*?HlJ cQ0ǖHi k!V)tpxٖg81C_k8BNGD_k$CbEpC5D*o7n5׿`Q!M 7)Dl%̘2gҬi&Μ:woO,c2`aSAФ.0pCi^ ۿYr`xY!Ubj KBRAT߲-t'faψ )ep IbD!\VఐǞ-r$)#*m]8Yj.~ 7`Hˆ!JxhGr8H@Pӯo>C#rQ ; O2XS(`U;RKQf1?\O 6U b,EUS k DH#ᘔ2_tcN@#EydN@7dPIӂ5MiӓT)Z`4L/^ZcRXeSkRqҝ9p奐| :gx蠀 䨞Pz):*F>M1tafAAtATLۅ7>kK*7BAg:,1=R;-ZZez~A5޵$L2 dChgIF9h%[lKEá <_  1 ,xjΤL77r U1@LX vA jXtdt@:R|HUIq3ހ V^b @K%[K#x0 1хD=4$1cA8ldqa̪hzpye<,XBr%&K>MhQ;^yqyNM-p#P 뮣H/I3H!tXs\-!.@/$C<:l$8Ǡ87t /CTV2~`/HR84#AZ8p33CbH eRݭ' ]ldOl5mыY,%N> tI b`,$y `se T|'OTcf>Yj׶e򅤯$EibcCFlYr[ YؠƐ Ғ `_8U} %p,z90,VAs`%KP#,6A0!$p96ds>"0`%VB zoBP1VA'-' ]pq '@+ņV1 a.r\/|`y, xKp׀rEg]>% r8`xza=r/^p] _M?‰UN}@KƩ|LMDOPL'#" *&`5\|@ h Â\l SY,|5۵ ˕B1 ?0@/5 `؀1x !;?dD2^DȖDİلɑXP6l6@ @ ݹ, & nBe@_]@ ,ۭb̝11,C 8B/˭B"6:"DԡL4!XɓaRXMBDqXN.ʸ቗I@1B@^ÿY c|]>r\ 5C@g}l1TVC>0,\$]5%*V@=$9:L$K$BKLXD5 BDNN Kى1앩0g;jU Wt$TWIWɕ宴ZjՀyL%_uKTɓI_BяhJD(OĵXZ d~ VX­>Vו ^~&hf}4fL^2hjK lL |HmZL#D$P&qqBˋĉ,0 @#l$LE蘷?蘫&b o2@0UHɜtfd@uFDq~|L0 @LlPL ? DLNUd@v @g o2nDl2 oh,8(2f訐& h:0@4N)4wYn6Clhda@VA R(P(P 4zB`@ @An l@d}n $z2@*[~(B6iE@$T|hAV`ifVjh>t@ jY @Aӂ&䁉*qzGU\jf,8+dHɌj.I|.(P y檗( \,荲j*L $d"h)(Q"@D( @@h鄔E42@U$d2ZRl0jDi( ੇҀtLjW"no~l* (i|h P,o,4z. $|I8D *,42M@@ @ m|0f-6f+Xr^tZYBʟDDzrf*'i[\":.nKA0.ԼILL0ʌ0RJ,>/RNh 3Ȕ\ɡx Mmjv-fg/ӭ DH`/N$Wt@@5LXElF5 “āOUŒń$0[`AaTD(K WUY~A?A @|E wbF tACA~)@|ZFtQL!@y&K*ǀAtAI4I. /͌pMATYC \A2z=4 xP74K0<8A94$)Cw/(C :$A5& C8l8.}j.eDq)0o&Yh̄C/,QL-:1!XZ74U CsDXC3Uّl4$u8 QH8<1U Ũ35 2AtNKPLB5C%@/8ɒ  2x<4Ar 7F3,@!9M3C@18څyUCrAt^bKdMeDB/BD,NBã3Cs4[$8, <#2*@3(?:?tw]L3 8U7HܘqXsɌ/@X)2R:HCy7d.(#Ւ,pu %:LT#u }<5D8D6RnK/eJd xR8tAߐ| A<XD AapF(@Ɩ~)a`AEaDrx 0I||( gԟ@ CX$4djdj?pµK@K(45AOun\L7~؊#x:mGmDŽޣTI |pʢ|@_։8xO(os^Q@*8<#RB_uFAs.h  pLWY8#-ȸx\+L¸)TT/њK'Bdv/|$4C,’RD,xFzu9$E$e BNg9Fz$ivl. v"H@?YE3DWXkŠ0A<8,\&=A,B9L 4ZxWap,4B# X Q04QJhu;,tZX5|4D8B[ZCr8& 3G8ԑ2Z)GiƷ{{:BI [_C,CND\Mx_8D-cL? uEzb(C{a4tA-_F,Y(@ O +|h6|S0N @(OD`|MXZ%[-B8K K/;l5B@19JB9\0 N_'E?D7o׏!qC":X}4={yʠ0JTKJVY*M|S~h@S\:G0LLƾNo岤n?M8|3K??8^ T^TdOxLcGxTi#=j\e}>AGy?@w_A)ƱS%ͪacGF8dI'QTeK/aƔ9fM7qi7 iX  Ā(IYr nvˁ9)qm֬%;`6D 8ƠZEnz]o,%ˑ]*fQbL V9f׆bd+KN˗1gּsgϟAw~tϤVBcn&KY 4\R%N$/%kp=hɱs 6]^*4’B٤{*/0k}h׿%G;(@ DB !*YejH:p9!cs勅 CfBJ7{KD!r cl0ƋYd&)+efs[\)-Wd *XItKN9)렆kHY*hNFb lcvJb:/CeQ %YOA UQE &+ŘBj A/&r28bp-#/ǧ$#(d9a'^pY" ^*(9 #UumPX-؃"!cI 3NZѣ{-V݉)-뉦 |_I.Q>HS5{(aYi,֒0Ic _Ebkn9{ jF%<<`A@_ |@R UDa`[˗@̤9 (\ WcYÌrY,\&` i*fpYoNf%AF(k6Ek!%^Op覗6٤`hXۨf)$dmOO_bQX_T)@8jPcP{RՀR?kÓP[Rl pI"-B1%+J`&氄P6 aHp5˕0]s uK!2^P Y8I8ĘoA3:@#1HY pń$ ,c_$j ',FJ%Aq0 ly0^G(JT^K/:钘;򾂴Az<K%45MR7I4p49љNu)Xk?\=M p$]AJa|BاKy^&5XPno I%i#0Q4[A \$ɣA8Rf 64_$]<5Q3"MuSUNUEYNU!WV2F|Ӳ(VΕbRjL"?W5aX.uc!YNe1YngAZю5iQZծuka[Ζmq[o\5q\.us]Nյu]nw^񎗼5yћ^u{_Η}_`6`/ v!a O1a oAb%6Qb-vacϘ5qc=d!E6򑑜d%/Mve)OU&qtY.D@@^(JLx [~I\ITɨo#IL;bԙA*BKz授ㄳP 6@O*e>|`QA炤$qL R-(` a6QL#7V( pMdD$U,)3gL `R87.~B'Є?2.u}f:v򄝔T"!}j.vmg/Xwm Bo+{$ ! ,`I H*\ȰÇ  3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJUjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LX%ˆ+ǐ#AA3kbC MӨS^ͺװc˞M۸sͻ全S ^;w߻vkwسkν7i.emRY{O_gp`~ p_}R e?`fJVhY V `(fK!Q,v'? T+_H5ׁ@Đ5(MD9 #1t̋82UP hA6L0#ltњ%pg`c|矀*蠄j衈&袌6裐F*餔Vj饘f馜v駠*ꨤL)êT*kbuj뭸뮼Ji /SƖCPby?5@~^`e*i{Tz?›b֫\S K0PV a GR ,A KJ,u $l(ʄ h,õ^?dZ ÀȭA S ҂C;-?APuIpuj :fZiFtmM'x:ݷxGIRP=R, 8Ax@ZL ?$HE\P@u@ 5% KyC/xK'8 _UP3NG/=Op7uZ9&DC3;0 @a4 -:-1b,g Wc GU;$mNW>}HƐ, (0[C组hI #nsk(98T1dCՠV3z RAֲ\Q_3/l PЗ(\È 2)fqE& )#03re6YW`ÂQ>vb"CJF a# I+ ugqaKjnL*WVBWx%diL O]˻ ?@L\LŤPRȒƊ-1"I!T>O 8IrL:iB2~#ݼF Y(ЂI,T "\ReLxPG0$ًcIk9 4tPK$EVρ|)NwӞ>*0BLw2T.& RhR02%d &FhT;ZjiJE!nH#ΓH1a"śiGi5ƃkQWŸ `KX< eT6"gbٔid}3bhH#Y@C @QCF{,lp pF>sCtad|,ȝSr* B- [`\ cI0݂ ⍯OQ*Duo 57P+7πMBЈNF;ѐ'MJ[Ҙδ7N{ӠGMRԨNWVհgMZָεw^MbNf;ЎMj[ζn{MrNvMzη5sK0)k43|b'bepDBYF?-2!rMH g_fJ4d|C| )k5lBFF@c$H:f馜v駠*ꨤjꩨꪬ΄J|A무j뭸뮼+k&6F+Vkfv;W tX! , I 878XȰÇ#:$HfȱǏ *HI!-wK))2T̈/)ArլJUaLqW/9@s6OG-$1QgNT 6N8AN5~ )TಓOڕ0?tJbD Њ8H/"."D`"X܈bmȁ5DK"dN>R6٤RSG8?`)dihC\ ?לS5Siy&9ȗTGnF9Y'ch)F #&(oy?׈˟C;*cC }&9K`ʑ5;#f?iN/ fz+FJ t, hwJ*'?bS?vm/ 6.2*g7~d/8{~q ȑjl'ϺzMqyp;&#9qI@/CL}l1+M0Ǫ*#aG/CmEG &6?Z60At0uVwR[PO-uduh{MYc5^tV`m YftVRts8w~wеa0R!^Ѡ-t 42 qw>G ܮ/o'7G/Wogw/o觯/o HL:'H Z̠7z GH(L/0|G3! ,~J H*\ȰÇ#.$ŋ3jȱǏ CIɓ(S>`Qʗ0cʜI͛8sꔨ⟲dYΣH*]ʴӧ#P(Ta ʵׯ`Ê+PHB:]˶۷p4$- u !߿ )Lí+xaǐ#K@˔3k̹ϠCMӨS^ͺ5h(U rM6b' "*@1l{2ځ[|00av@ 67i.pYҞovA{"8^0/i?,p?! P4]a_\'P6B #_ A~K8-\q4 @@?#~]d͌*?Iӓ06eay)P喙X, Ht7K8"%gWi`f^T|[ij衈zU ÛF*-!P/@%(TBuR*wv1y? ?K"6j먛câyZ?aP Zd@3 * j{O7NdKl,lħ KɁ.fF[P5"*!Qs_U A1* KV~1K4ջ9Tf LYtəpܱ0,s"lsX3 | )I,1 =w1V`1%DV̲(K_tJmQOBBcL:4ȱJ TC v xW pr6/0x`g @ b]{:4@AǔA#tv'B.}P+Y,%b5n2, .<~r c5K"9 }{A@R4A@5A B&4@|$^P?a F[ J4j倍%\c&2F Lֱxb( xTl+w΀ g q!Dmos+嬃A ` dm"mbWcؐj&\A'b/ ÜvB":A} 9a x;Yp 9C;&WЏ@H` dX#x[ B|sDb^9HKbQBNSԯR@w u&T5؀r5^5FW"@sؘ:&:v?}Fc:, XSbhi+YA#wA-pD{ = C8R\d)2T .1CEOgE!2FDBɎ٠ {SadBHAk܈ D`!'Grp-AP\ 4 ] HhSX'D9H9%:x C 4a>VQ1B$?DÄ@A 9Ad%(*@AyHx! EMэ-a dZ ,3"ϒ$.?LѠ2мيP+$J ;B7(Lg'uAO jXy1d IIPyy z~W1/gwA{ 7Wgt HUP0juWw,!S40$q02 I\@J a#: CbB3bb&n'ftF[XV#oov|؇]#!$AQ"{8S1~-( v/X!8x&s r!!2H?3hY0 { T'qg!hx !qj!!>a s )Xu'hx W|*H gu(l!ġf11 ֐ }&( ,@Jя9*HHW %H]C :Wi"#P %aOq,! ҀH' 1w+"W%WR Q) #~Wn|Xy5(xwЂQy7i!Xq jHj|Q#v0dy9(1p,ˆ Aɀ"37p#%p{Bq(Q RUQ"g uIrv w((1d0 'ZBTaf@TfWg ?ב pIq Pጞ/y` IXqv9X& Wma +m{uR Kؓ lT)S(0 AI$pPSuYUc0?y J$} ТjOxP(Dw*@;mb1wP!#lȋPII,`qvgoC͠ px!'9f01 l Dr`u  pkE0\Xӑ ۖ +R0Ϯd79Q1H9hDq<%\@m3ooJ!p@|#C0,#20 QU ?1 1; @T0 ݪ2V* 6 $Q&J-G^ap@%p8 S$n*Pw01 M} <)of@ EYz' ; Bxf_9e&0R{5A :! 77&͠i-Tao% Cj1-B Q7 {T~VYiNO&P.(Q'1"B!&0mʒe.1 !E*q SL@JFP( MD8Qֻ+(Їr&\}T/ϬCdžy*U!&Z-c2 Q?C3Co|h:3[ɯ /m$ԝo}$aO*..bxų:;LaA )/HP1B9A #-14Z 笍ģ`x M 4L_> яj/boa !R0!ui a Dq_3h (* aBNQD]3 lb 0$nS[EcQЦG=}TPEETݰjd?m?!HԒt +md0KSU+ f,=0HČ*SAl5\2qzu˸_G+ /@J ToBM fi\L#~b큰 Hcb,Oȭ@a!W!ݽ^co0?{$ܓ@D&?d<bp"͆)b &*b\b ' a cJETl &e Bx*GNnn! #=⧂2$Li(N2Ȧ&:Ѓ(1N9礳Ο蕴y 8 ?F>#ي&CI,\ϵ^l d"8HK$rqY+0(6|Aˉ1pvMN:L`I.# Hk`M'u~bL`y4 Fg7^yoyi-!Kk"ut|-Ȍ&L3!aI֚?D PA2MVDP61@ ˁ Z%z`CZ85YZ#2b ߈i1䖧蹹&CKH¸nx`,H^h-o4NHTHx|""сvC`.荼6C$ӻ'&\  Ѡ U&/s.Wg/L@z',]> N"k H|<Ɠ?v'v>Q65}g`% i #/Q΍ėQ/!x 촄9(` e8äYLCOh8 W,aFi1zMO̡9bp?ЌgDcF~L2KYQ e0*#+?[ 1\ғ3bH AA l2!sFaOZ% =@ӸK^#x ^DdPuW" +!Ҁ5Ԉ+ c iG"dkI-p/wיHba?quk^{=lbzy@@qC'Ț(#W"' șM%r. W1ij%l7!4Q=dd3lpuҋ2b 2v浈kt3MPy @ZOH6,IDn$T Қt-t1Z_O0o,$H`ᇆ 7r :N{5FqҁNdLJ}ipFp# w -F̞x#C/>Jƒ'rbm'R vL@3 H#6 F$W&wd rZm +5# 5xF4 Wx*JHOr?a` ,5wa͈VISbr"Nv7s@~ӍBcuH$$ S>{ z?2é☄Ќ oຒt>1 X- S:ќlQ.ˈ>"?< 3a Ih3X0@8 a:hA:a&p:`D8J/  XkBl酑AAl6 /c39!4?4<AQP=6*DiF诉8Z{QS> yɖIXCCLV vɵE68[T5dT( F&⩷x9iF[^;:*?A %$bq H> "q4! 5 , !njl5@aȠ0z (5H }ҲEGb jEk Zh0Fs_90閄xB26̈+ ,`-@?(ob3Ac&hUpk(ا'SwH0Т9=̄(3L (ԈD9H[J4{HfLBJ)CX+?пM9zWdRLp嚈^V9Θ'dHsX` +J ȚJ @ .ɉЋuة=i8H(78JPȄF |h,X ![2ëU-F(]$ k@i qL# ֹɮY.iEЈgxi'd,h8Ph~)-Rʏ8J Jp"K|=YcMDx *Hci3hΙlnLшGOKl8B81G0IЄP81CX(jY4ړŌpHǠXHO`rd[N(.``pG `;NɍHmUђ]Fx&8R SYG v9Z5)mZ ͼ;vS[ 5=x,Epp`71 GkPޮ! <8T@0bFXWBBYP09 XNyoK9 8yH029'\[ՊUĦ97ߑ E6"%c %9@0΁9`8&ۈPʱȏ|Ȁ*c{cGgd@ݛgS~񏦈*oOY߂%`0ڞH-uz*S@Ӂo(n&;qUO*lE#d#P;/Ӡ[/a8= )/ 21XqB4Lkc;뭳9AMOY.LsJ7yl@\hNlka@aʮ3lHƦ^ XG ob|6Ƀ&d& ,dL28!&'?Hv^N7(P;O(S 8K/`?Ɉ]SӋFHY/R x}F֨&G\׋a@,C: >ؠH'ph.°~n!Ȟ(]m-v?,,x/EG3(g_A*4$@_D G$\h  ipKCLq̓b'РBj')s<)ԨRRj*֬1: O^8V+ڴjײ-ܸrҭkݼz-EOELكE3n1Ȓ]N0S:)Wg% D)0z2زgӮmꕡ6\AȀ/  /"L m<%D <^'Y0π3` [3'Qt1f-ETB #!za &^v1ZL|hF`jSGa0 V 9$EV#ZA/AP%AV_J}T#rTU(||D$ю vv$uy%e 3DŔE!R$P! u*A0xz*VM)ZK ]tA_M%PYc5 KPk*,ͪRFi[Th:-z^ ACQ5-6BکDH P%ZI3U lR$A`ՋECH.dgTjZL B,g@P1#/DԉJAO24$ PJ?@DAA47KH]xYe/A109 TFsL5R/,TfH=F9}Bso{t)ܑ[%(raa-L O)7*OAcJ 1tyQ46}7x$ HH@MHj:DъY?}:+S:'a/H"?O4` E,R=_C] "Ћ$~(_L=TKHjX#0ȡ!XlgD f$ Ґ\xbBܠ AҡT1`h@LL,bLIg(5Bal|e^Ch # y%'sˉHr~P"E+%8libsw @u'U1Pc5(?#E(=ƅ@|1ܠp}6&FJ2x0fEH,?BtA$OU`V6lN66%ILK`U\T!Q6D!\]d$T)USOhAH'!&JQGD(|D&(EC:^)8J&"\!$-Ƅ7<2GOEUAa!,&0@55 Bd Du|@0EY2c Q`8づ:#<6dl$@&dE (BFA0%Cv2J$G SAV+QGd=yEJt @$ML$NHldNO$PP%QQI!%SN5%TFTN%UVU^%VfVn%WvW~%XX%YY%ZZ%[[%\ƥ\%]֥]%^^%__%``&aa&b&b.&c6c>&dFdN&eVe^&fffn&gvg~&hh&ii&jj&kk&lƦl&m֦m&nn&oo&pp'qq'r&r.'s6s>'tFtN'uVu^'vfvn'wvw~'xx'yy'zz'{{'|Ƨ|'}֧}rkF Y\LFO:$MJD pJ@KeODkD$WO\@ AKHi!- P#PEvlT\"O+@Y(@@0؎I jJDKkg-J֫\, OM)<șWAEQ|MlHna,@USpnM7@Q H:D (P?hH=^ݶ:kQ(iTÆJjEY,Q͒\OLhl-kHa.`.*I8B1Hhi*%_ a(C_㔦w)Db*rU "(sJTx}0?N]"  ;ǻ. F3^͗w{{kN,G ߃gVtgamȡy Fh≖@ SwS`pwI0 x ^D6y 0@J@wd@  !d" |wtGB/<0-8ia@ aW|FY$e2PAl0u`_wT(4TJCuP)$0C$$@yt $S4@ zizE0UHI0 @\AfG A,g PGAA@P#4 C6@Os,4g@B m#\@Td" pf# [2dlXodP ўa@Ȗ!4:, , nZ 6^1@ó2BVP' e|XWeVr0n \c p(r*l!D!x\(p XsY.xR aZ.E /y.P-DA$xd#IzD>P؞/|W ok`:+G/W5Dt@ w=J~/o觯/y`@C\B ʲ$ * H6х XDܠ6(' `A5DЈ/" qg Ocp""J=ġRcOlGHE)BqXbE-V[h(v1|6Be H:x̣>^%tq>~c/xvxd$Iib/XG(<;U1+JK|"Miwe)xQRL&QD n•|5V ES|G&)kBr7YI?sװf)D*rtG1GK~3O5^#&+)T2r5(Js)yyd{i4S &>Gyy$TО5 7jn’%3:hs=yke [bt%iw Sd+EVW_4pk2Քc"+IJQT#o% oxP$@K 8oyKw=Py󖷿%@+p׼5o|K`w宄76N‡IBa_x "f ?V0 Ze a(E@ [CB p# &{IH؋X 6pH :Q cYNUڅ:1usL:xγ>y)Mhq#I," -YĨX'MJ[Ҙδ7N{10 ?|QV,yOi]M뉌 6pϛ5k&b6 ;h4[[lchϯն6`Э] $7~L,`6kJxeη~Ak V{'N[ϸ7{%G@핻:~Jb.s553ss?C¶}8zAp\j>P~P}5[m sɵ(8(#hNvNs¶sCD'6Lw;񐏼'O[ϼ7{GOқOWֻgO7|qr>OO;Џg[Ͼ{OOOϿ8Xx ؀8Xx؁ "8$X&x(*,؂.0284X6x8:<؃>@B8DXFxHJL؄NPR8TXVxXZ\؅^`b8dXfxhxl)f&>v@oH;wZ! ,")i(G*\ȰÇ#JHŋI(ǃ4zGqG A 3#@@AmYͣ <0A/JU(p!8*(8˛SUٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸cL+Lx휼s -5;mZ;׋BW]pm2\kC{!ϩ#qL~~&9 e =PWrʒ3E@Yf%TLndf! < 0k`HPÕ@t6,֥9Ʊ%`J%ySC &@RcKhB372 ̚XP ar(BF1S? G3I"hA ?(1E*2)=b7y@z$ l3Axl;ǹ4Z] A rA  pOA ]YJ׺dVI@z W!>^gw4 jj-sCrD<@TTQ$Tnq-*Rg(ScdAsFXmzvd f-M`bpT)HN꬧ͯ~'qHc428!сYoM !$D2u fA@Ĉ?E:p$[Ab!  QBn0`y Ur PM'.1AdtBl!n.K*<'CtaorC A u D+? #`r **4؃'`nAP֎h QeXBP!h d!]u8Z CN79U @PbCw ndJ5+%_%HcGe@@K6 yGF@CI0I郸y?LX!W02-*reO5(B H&! I@J|b ]XiyOW"2kb3}eBx7d{D~}᠗ѧ[uzB+Lɵ@6`0П5՝Z<>#STEz!#MN7/7C/T dRTty,(n]*s01 gs9EE aFm %2|- VC%P-5 *?q"@*qӤc#5cCSb* %up:I& z/ZQZQZ " U811:Zzaz&*(j Kz'js " vN?9@2U0SV*p-mͪ(c` a >F Q%cn&@0 0!l&079!t#{ Oφ-SPaɁhV>iPrp}#P';}0B 7| P* lEWUV+UkA4|rB){y$pTYy$q;A/ke aiB#1apWf0٠` f; SHhBƧu gpq&G# @IGU 0A аm+)g)YU@3gO2&e a = $I ɊE`X@U à+(:jCPа",]AClű5Pаjq}Kz^sPppÍp_zK{/IV Y}@YOnv4 TԞaE( 'ݺ@ +K۶D@m=q)/}ϋ}&$XQGxryPy"hTyG;UY2Kjwuj 0 l\/ uUQ+Pn1!'o˩mB llrߕɘJ%| ŧlu^vrW[ Q+nK:2%&55anJ⧱b(v朮-l- _;A&9⩙jPJҲ9 r!Җ1ҫ8MS3\/ؠa.KG_a3B0;Ԇw R`}mt!EV`2 ƂRPb N' VH%=")%ЂLgl\ׂA1a*F>t~4Fr1- a*_l/( )(Ȑnx J<4+ƀC≜Q+$; ܐ \Ӌl1!jXzQ|)x3ᭅ V6 ]̊HFP'T= 12A[ lQ˅U -4 m}m%=6~eYAu -d ACyeA` uF׹ q1ז3ٰ?B! !9Ax*( A_M$R"sH_P 429-nM1 gf !pkP Qۘ% !je5˓rÝ@r F[*\` Ep9$ha (bfl@wIހ ِ\ w`E slXCj{@9; ^>8P3 MeG 5 `o5Z2XkDQ\'jH=#(C[pG}Q')[YF)ƭ^|J$ E@m9Qn,;2*i}Dx8P NmxQQzm .1P5{$*] Yw $5$aHLsv *.fL85І)--s>u0!s5o}Odu/Vma0chZU<0p3:S/88jp3Ͳ9)|&>|R 뼣uoN (c-b?4™mdsmO?n 2p`>T@3 0BM d1x@'K d)da䒁. qmyThA {L !dYR_,D(%%RB]k[&@X8Wa3khX`… 6@&~ZN`="/HDU럭&KWK-N.Kl} cK-0Fb_ʅO0%,=k_{]:zYU )bxB]zdNsC?1ĬjH#X5{hlD ih±g:>u'\kK`7o^Pb% ʢĘC 0*/a ljPȉD"*ȟFDGM@:a(=5E q ǗG?ojJK!]6mZ1W]wW,L YpD&K:XPHZR|*RI(B!|B` |"(#JB(fG*$@2r \_J1U( R ]Y u@E\!:)ry \j)N UBn~*$_\8if,* T[TR X, 5B~YGf1 @nn ;k@ R~R$bI T 8\Q#tB'[BF@ˑT&j3j ô.SiDV(J2a'Rr, 2(hzzm&q6@h9%f bȝ&g#^Hhs;)d":@ J`)l! S%! A`ް5T/a'0'*<]B25x Yh":qQt YtR;" 3cOJĂ+n!W!"# $"›!xynAB[jEtxR/#`1&!lhe7q xsIgjG`ǃK`GV=Hq*زjqykpU2.(YxSVLND<~jn!5VH\))F郉f5Q{>;ߦ.% N1+kȁ%:YnTͭueRu9mIb6 ,%1?PՎ3JKz,tOcYaAPQBr9n'E·\bV2J#) &ґN?D>X"9U ?cz8L3f7:IbpC*5t/Mp%:1Ҟ's{q9nd| \^Cf ɁJQ#C$ykbt\}GxU"@>S5I52BF0 yүGAӟ~g}Uc_6Fzcrօ?ݑJcW:)ָ(@$~}+@8 ߯}s_Ǿ~?K#4D%=bQ+'6J@[ # ;>/'`+@ &;*[<+@#s _S!\y\!x AQ;.l+p.x *?B d85RSBĠb56<2͋ 80 @ k=Ј IV De~-4b C tFNQ'9OY^a Q'=sh#]4&;1Iq҅ M BL S&-"d&Q*= \I~ QNlY(B096 ڴOiD"`R}ā L X0ՎYեHQ``R>Bk*}HS.@HK9`[HE؏ge:xPFTk0kJ:}64kHȢΒ`#ӕ>ŁU.=9)Ւ9ѱ0|`# g€D/!PtƧ!F3@I- Ij{0blƉ8Y( pA]h0+)EXE|EXEgU9񃺽p:'(_h8Hـdh"MU@H |S=2xP L~!ڿB a 20y9`L . 2-%V2ƺջhбX; QPOXPآъ[)Zd V\reXy2[:%9 8GcEi> :qF!4f Èn 2|.`-s[#⤊Rv^CX{F-XCїHh0AjynIĥ؟,iC=P}@ޗ؇ UPUU^;V"Ձ]qm&5*P,0AtFDHY/D0ATV+erRaq|BՁpd*TNdNU+XX ぐɊ`gXk&jS!丣ll0"a_D a<e(pw Gx0* cZ\k+!PBh eہ.+܉M[I$CЅzd,QQ _vQ P8Z2~Xi.oQ ƞЧ-EKG 8GЃ%s SPd= 2~lIM~~)0o- nhG@ZM d0;h|P8¬ TS Fz5Hpg%jUbJUp WETP-`KD$9nZI\s)V($+1Ȓ'Sl9㩂f(dXm(L!КYD=-ʤ)b6Ssퟓ'V;+ܞ~9⢊^z]_\ǜ+5c?u x 8 xD0?=Ѓ@4EE!NcS A[4Q,,TOXUD(?'jX (2f?pV5HP $WDwE,ΙUDBtA19vI3K/R :( 2P? S BE` 2 CHD CXaPAd ;?6q0JaB`Ӝ"!^A@5,tPB+*͵DjDxw%b&E:R$ХI,)?>It/jU3IDEpAd2?$D&: 3IX&/ipD\AѲgO|\YЙ鉐wd \mXT֭TM,ֲ+via֡Gse}6PO$B6KU=z7ؓpa=Qv}%JNj([1$ټJdamyp6饛~:EYn4Gc>e~;;sB--R:+<͗?=?Eg9u10EvC<>$m?$zdR& аA,=Bd 'd 1| }D!_D,Ȉ @>l +H\a:aAP$!Vs_6?*f nF`S؍D!$HX/" AX1f0^qS8dX$#,ෂL# #Ҙ+G!4x`d hu~H $:B\nҪC(Bo$0)LOmآnU< )kY6Ձ&8y;ib{Z 3xO)O jA67Bys2g?kX%15kx35(&*0j"A" rr (!$`q X p ը0'˱lYxA-'[npH&ES)#H>%rgɘDaa ɈՈ`3T%)C)Nټ#?Q "x$EPaRnCىH*G Qv"Tg䄱h9@Pʀ+HC`HDDlnd]k-#D.UCH1pDvrR rwL?\a.V1  mD?ۇ%3+vB; XR3tbx6p!hEL?0.deF]H֥iF^%N# [qVSE!$\XD|c !2J .T .S1±fMudZvĩ# F` nH} β"$A@pHPIǑSH93:m4;I5҃3*foJM{7%5 d!!JbW:#Nuh]TUH6j[OD¬|DȼkTal! Kaes۰BtD+#OoRA D"_д!þh8!'0:!Jd \;=%1taEd%(郏 X)B?hp"pDDZ8(/Bk}7#UorK%0Evs'H],T`BE- ٓrd>6AZĂ`Z?YH.ՂWskM0Jj$L"D~KD_|Gj_^ZjOD WJܽ bEH5oF1$LcEi# 8I`&o6/拧MS%Blگ|B=1Z7II|\hJeA-l~]N?daJ8H9DLE0HD ,1@` K80 ~MAE^, EB,}VK 8@RIAœIvJOY AL1(^E!`ey̐TA% t Dp H} r_!AMp Bv F`N`C".`uD, Di&HEahECHAD aT0 HHUX`K}HGMؘ`S 4#7~61v8YP 9zAZ Fc:`RaD@ ֣0ĕQGG` = E!@ҠIHA#&^p!AjƘJE蝎0?+HʪH:٪(OMǵFlXq5$O,?LaFP5Qn9א`D$E CUx\x0ܐd]QĠX< F@4UHQ*;J2 AX AME 0:K€)$@ x 7Jx ILX9+bEXX^#^2܋Q!td:]6XR A6BI8r,?|$xdÉ Dv^ PW ]R! :?D PDMlZMX?T H ա @p   d ( !^D HD[`($ z^<3M$A- Z2j_,iF,hM>(_a)a٬U6lrnDnAtXdAЄ:2Z-g$r%ED_׆FC3]ėΩkyC( ̪Q)?`)qmfD`F.^o?ZAABEčFqYD[@$j0xLGDl%A gA<ŝ\HD0DHqFOpPKJ1AF}Y1^0F슶$+GK |b4JJuHfCl+!7<20 A؍.E?ThN1ŒB-Őzԏ^,ɾڠ5 TXJ( Gbluk K,,2--&-u6>mV5,V;fn-v~-؆؎-ٖٞ-ڦڮ-۶۾-ƭ-֭---..&..6>.FN.V^.fn.v~.膮.閮.ꦮ.붮.Ʈ.֮...//&./6>/FN/V^/fn/v~/////Ư/֯//~ee^HӞOCŒ$pFDr0AG-!_LG@?0`dDcwe:0dȰ`j.F@Bt[XFl { SFLEFԏa˚T91BAe D@HuDh`P (,e[YLqD|H1BDD@HG@,E3 O@N:#@DBHFW3HpH<\,G@DMtM(Md$s,/Qny$SDD|HhEF5)WRƐ wf!.3Q b|mII<IV1J@F(8eG)$6I&C+\$G(^QIsCn HiA>H :̢xhdLB L-E=8$l-0pP8(j@N.tKI2DC6DG&IN9/ji 6H "bar'@ bLP% - )+?(^Nvpk'H ():?RAKn mv^7gV|yT(e|Tr bKɋ0\cJ Ẃv4_I^?$捐 =i;z 9:sunr7K%X9"7 ?+~0@~1 q!|R:G>0u ?3 _ vRU wz!g ~}ǂ}@r@z Ec ax4aP&@SP02ჽP{on" E8%1M]$7w" Xy!X  P=&Ya~ GKW+Q\azq w(7i% syxF1DHvQQmSŌ،HhÈ &ݸxL zQX"g؎AX`yD!SQ pY6A` y.LUf qy"" x/7.]^E"r5: `hf) /0  ,;@]EJ?J';q1057)yy8[Va';Q| !)i'PGA0qAxaI 9u/Px6\xDK$)NP( Aw&F)efL!g3WDQSa Qْ'%1ds< 8iF>>a_P^BћI H;aiZDk ° ͠" :o ,pԹxgy$6 Akp i )pL)vr [PF jtPY 5l3qiE)re )< D4 yx7'D)0QjP\4Иa+ ϓSYpy ! s>;PC>C& 0?T)h(DD ra/>fɶ)i -A-7!zY0ڲf~hjl!mKA6*.]0PnR~>^~n79x_ fCJO͙Le>^~ꨞꪾ>^~븞뺾>^~Ȟʾ>^~؞ھ>^~>^~?_ ?_ "?$_&(*,,ؓ!!ޑs] #qWf.7@h*KQSت*찆Ia" b̲ 09IN|K/,qL,:|56,JV6b/x!6޺9^չD%k:bwxQ^%|l!q O/w KP,rH'-W1Mu5-+6Td(_dŢgk)@xcpikk*" o-:e-5t2`C?r# Lo!Mx51#qYS`x3ؿ墀9?uPAxTv`@xUZnGzroAOgO+@+";?Cc??TB B21p9Ghj Tf!)1:`@A!8!JrkwY 0!?$ :5DH܈F3 #ES6 gbk^(عC/lblf*;A@ģM\A'؉ $G"" *EN#܁-Hj/ĉvV21|8:[,!/hAC/-l Vؘ 17F"(Un'YThapWPN @foaV u 3F!K*Y`Ǽq q2HH5&d* +1O}[&XEXyXݐAIdɔ%j  Y}Z6 jhs i%/NE v4 bq!T;.jZ?&4WJi Fu0ODG [8، k5a[[L8@N3⣫=m7M7Q+AfE@,BlֵR5sȈ6Xm`*كD:[~.u,g] ̀S@ 0H(Xb=Ͻ SHkr#u N+l'xmN`3eXĀ` 0؜`$3]u A/zm] I+$0PxPx_2;e@#$b{#u"l $`@2`rw eXcxAfD1}`L4@yi)lq10I)2 d p1_eccZ')` $ s 0&Ux@22Y\fq]KL !3L%.W=,|`B@*Q@nS^&-h80k8Rs 0uĘ|Zbg-, @9{әb\ Yq5פcC _NϸX`\ oT s2&7M9q)/ `! э4ѝE ZB墌|E pE{D4@f0e,"HTgIAB8E$)IkJ3Gc/MO-i' e|46OB' KA Iy/E}##DJ. G?;;'>?;$m +1 2r t4 u!} Qm'O*QBA~QP x/GpahA au Bk qU!uPA8w>aQYP-@Y  `kTw{7g!`a xEh-yD /`Q?BW1zgtpJq, [1zXAsXlP~Sh"JS79UO#i(xeqgqTo1W`I5'Mj!fX@pj&0фI)W N0 <7u``] W! P XtA 1%0E˸_`T 7Q` Hi`  @f AVp/1V;# 0iO>Q-ApO_A r8};AO q %Ӓ< Ȁ; Ð5 à kVH ~׈ C PAp ~` s ct yD3UQlF5?'3q($50 9 @ ;Yu > YpF0 ;Г} Q@P 7q7j ^ kUNeKPQq(,ɛ3qȀ0 /ְ  \؃ ;p  b BcFUV  0NUb4Va1e 0!b N&hцf[L+[#˻\ /";]b@hIĻ5XL\ܯl$\qܬv! ?k[]3Oű] ֡3Ӵ3a[r;G=c3Z\'O|vpȚ?F05̄y$;4;;S|9:ϰ12X}AnUv&ެŜA$;IϑEZZl{ UuQ7kYX\35_VT > 20'b@L7E;S" G> =Mn8v˰aLqsiV! ehjPkT,G>YpZK1 s ҧK )1 ۅ@A5 0 +͌K"<ŁG KME_q\7qwP B\G A&7 `d #8 d 0Xh7 ГY Ȁi&`Cd `Q x ` @#3 R6P4*00p +6)t}g<ŋԖ3CAB(̗&-\ a!*1j*P@~ )\bu-*-ܱv>a p@V yi _.,`p z x ѝ@&q*-(}rP$֠ZT,Y+||XaQ )Pt[xgZH! wa|h&Dۼ XFb 0o`  l! 0 )@,Г@ŦÀt/0 &vf fP > !*:PB%` @.N 'H<'ֺ7̝]@` }j@HrtU(hdpit@X]e2@D+)tP 1@P ~Pca  pf%x0W, Is; 0 7xsg6Xs$" cJ"܀j[s Eq 8: #GyT4~'|*P_qpv1 (drTon  Ͱ@ `p` , pk0k  Ð ax0o? aC0%* )QcV*TYJH3X#@bCmLYNsdOEE4%M>U*S^ŚUV]BN8iДU[rQgp ]-͚MxQϡl!͕!;uWҥMFZj֭`33\،-w/laVfNcf>@_+lpݵg]G>ݿ>4]Gw+8 4 C,3 C 7C["!%d, d&`K(@.`:a?ĪaA$7rjxnFe^'fc?B!9pafpR.s` ;@?0JATI''|AS^J /06(YJ ' RLӂDd*c3Ӏ"]{"ɭQBɄ;!1I1vN%&J]`JP?&qIp #Qs&:~U*ln,%3~ pXJ䌤W wp6fs?n1qN&CP "asH9qJݝG8c捞%tCxusYJSBtgP RT4$Wf/Ρ,WǺ{nt ZXc ^rv|ma8Rpns"'M S2(@ ճ>x»' Ir A*e  lxQ6B!E?6<чK@|)9~/~v{N.~'JŽq Gᵿ}AcsJxYNɼQ^X0?I Dȉ=b Q8YȾ^KsxKKy s0k>#>`y8l>DA.KL?ȄA1s P* ڐ-AH ^! e^뵄XWŸ06c,0kCj lH 9Ȼt>~ ; S;[ClpvXLAAa `PI< SA>@ dX9(ȀxC <@x9KIcWЃ($ (A >3ȉw0ß>  s؈>D>I$lFʉCo3H7X(!YJ2XJK ȆJp,aK@ =4d6&;98k @xL[,3`b'['b x&DY<6 a@!^,)B5 Ո9 `k/WXcP1/W .,\=UCxex h%*b%'ao sFU{+SySMp`D P![hp}pCh0z.I2 qЅy D@X!P`>@٘(xP,Շn`X0hp28>:`);9fpT-"J&p p*/`bH75 *r2ဍPcR联, de) o% xN|lgѝjBS4xk9z+R'"e*ЅWFdHisfa(KH-+@(O@D}PK^"X (Ā %c J-|"a ,`y0؈)m$cB1 0L i酇PY*p`։˲P|s8z{rvA )wb 8  .z $'Ad嘉08Is#˷!6sm7Rpy܌e  yJɼ| 6pKsዛTY7XZeE\t/hCQjUp.g1VZ73FdE$[%7xQŒkAAaٖ`J^Huy'yֹC82\€pcB6,PY C@<0}&h8@ 7 $d3-$t!p\7p&I60 @e0c6w7$C0Q2& c5YE61aP)Ӌ^\#r\Xò_RL^S sIt1[,6J .TNBVWf[rh%#&Mq F%qٛm<35|Z`ǀ-`I>|BdC PO QO&M}44_ 3A 4RPXC\ P/ 0fqـ%M n@n^, H θ$1K!԰I/r8@/,ra/;ɨJ7b5,%ą%d7TU lR> $IB?HX6#`L_E76EH!^BGiVP՟8?ș<0̀ oCLXd{7@[}O$Is`Rl-I@:X@DU! -` ؂)!ÚT&i\s(w\VOLXX4\VTX𢗿S/*T(p/wҕ=}򳟟&@Mj2\)ZvbMQ~_ 2j*OlhZ:̠i&dyҕNsERQBʓ@|e `²ΌF=*Rԥ lO4f k_ecl MZ0c.hM!Ą{iiXH"yZ =1EQZN[-[e bP-L1`C( (tޝY͐-AKZ)e5܊5x*bPMqfXTjbF PdyPbD hD-h?ޓF&r \(]M(b!E$_0PhF'?-)*g*i.R ͌o+ 2$̘!Eu%u4]ҹKƢN rv" HK*Wbu/En2%oRn0 ˨3]R/XCMK1sF_]I,瑊',XHw*B@&2f]MAϰ06,EP mD4$d:0-B-R9 %IX*-]X f²P 22=v2Rm^,]X23qvf08-@T '@ $ ' C,lEL?>d?$B6$AlZD-c Aq [B 0?& 1?Ta xH ,L D*QA8UE¾Yct- "I bHE50 d[,KnX. p-dB fd4$4T!4CҘ ,x4C'5 /*؍VF5BP Cm B#@&"LMd`0?Mz|QZZ-BC%B2xS@@ C)E XV!6*|A`T?tr.x8xC+$- Y85@*!@qUfF@II$!J2D LByEox%@H02&*tXC| 28/44XC G ̃Ct?|B%n0h 9A0h0 0h503x 18H$&.5x.˓?Fd 4لq!CmΌȋUH+VdX,h,1#qv˝q Di7<JjA pm-@jTnAqlE'<,CH585ZH!C(ĢA8L@((Z2|# <B- >X0X@ C XD7l?xPU`˓a1lLK\@ ,‡*`MERHRXgz)O$AX *EdK%#@hNC%3F2?X4,禎 HC8 E4D,@BH[q8,D/v 7VdAh ?dA5Vl~Bjz0 Cp.2OK“zޖ ED =*h1B C]4%EЕ]H~d&Q'Ҹ0YEQA0R!\9]HESYPnTӶ} tv@Vt9T8V\] 'ӏT"T X;9)߇i;)B":T/UeN@DM$''>'cIfJ0Dh8b-@pA6("A8 -XC`j/ÐY/XC Å2t: :|@ⅾbE[a#?iQ*&ɶcM ۩""'A  .P0`թP>0_EZ$uik6[DmK[kM[v\{rnՉ#V>;@{P\Zk!f!\rm[VSSn0_ܯ]y-8n_oIE^byw6UC5^y̋?s͗7ϗ-FyR0xŗfKf'o}GOtb=KC18{zS¸}1MMW?sS^< zF|}<z!-:`;Q^`x$kxp#'T\b8Glm=[x)}GBc]fu WE&BDّג|8E 0C̠ L9AFo}cT?Ғ4.xJUұtvk(7׭-q 3ԅ$w"9G°ZQV FbP_x q٨HC   L3d#Lx_ +P !a' X _3A` ?=t[ w1($ t{B48rcy@6aKe 0 !7 چ0HkB  "HP@aq8/):3:LhnkNnPXXP5bSn",XI,1dF80L!@@" <qjpk A.qh(q;"W\Sܴ:P. P%?q# fn(`h rd0 &0lb 0l 6 q ;!5C/AF4 a833lb= ?,fAӬ"G MҐ`!e7`('7 @&  JqleV413e/^"m@AG*h6͗E3h жVTBN؏*0 bu{̞\T2ח(* @$X`#/[+\dq4.,aosБ-d#J6Q?^a!@F=cWPccǓF/~+@۪ {b/p׀myRk2(#"! LW`G҆G#Hip"\20pE<$@2BQn4@ wAKcv҈2pHm{J /4"@( $q`"hcq3@lcI8¼bX X!vnfl'f`Z@l o(8` Cmc\&= yb8H0߶d&+X@ lc$"K4oѲ!jAJ K>%#!,@v@L"z}<@c@ wf%j! `v Ip %`K(0PbabR,0 `@le~0aLy0σjf#vB o1@o,-TKl! d@j%Jb>j L̠9`v"@{vD q/Ʃ=oN= `'j_8\J#\d%!)][IZ3x^*bK`T#9-qcu %I0Z\ȥ\xř*hg%/*)"!-zܲZ({p"p,l~ 4fAҠjp.!/ /@\g8e2يょbjtT9mƍcd / ` d,Q"s.CSTh(4,3"*~F3'N3;Jd0Wa@  `a`M@j`f( \d1胞ȓ:tASȊH$B'B+BAzC"a$eMn̢M\DzA3. J:tH4AE0@jHIeE@8@N)T/J Aք-0=@a` G1:5H=HH4OgdB+L Gg/GfKpa 66 xTNASOٌU9S@K+ rԄV>M vKoK b ( `fTHs)\[UUOw%3ktRbN*]#ITe~o]u_dn%Hob^3\>b+"Va!6/C+r@\ojӟ*`vo*0| "ea.`g(xW 8y:`I0 ,<Bl,>V!-RT%`cvk! ' @<Z~n`s!& F ln v`0"@^``l\# n * l?Zj ,kM]tD0n@ KׄD@CB@X jl! l!@oa>!<`$LN!lAWA6 X @0"et2k'`PaƠAtv*k7d%X@@X  9 W$ `$  a~yGa*>VA  ¡ Aadh0b %&w>! p&AgŴV+" 1$CZ.{9`vb!w^d~6KVIBKǢ`>AYbAlA A +`%܋!rߋ@ t8/AF F,k'Z}v~XL@|V_`laxyN[(IނF6@>KVa@bCv]6Fm`6g#ző\,u3z~Um)f/t'NaGo bd6j@FsVa{X>D`@c:/@"clF!>IR@VA p'`wJ5_a (.cB:ŋ3nOA/2b`6%%(o`Z@$AV.Ta6ԇ:!,`.HM@0Ɨ!V/ ¡KnЦuy EZZ`P A}2^$ Z']L@qN.6ȘZa 4B!{pF ZPRSvF8PC'{};! |WM@` !P kC-J4 cF I ~܄%B @ĸA FvV$j)*@ؕ=QA]Rd&\ie,kv:S}Y}GC/)m"\wE\.=hց]К[Xla"lЗ=@:=l@/Faٽ=Zl%O4\ *,&j xQS~}uSmaHbя׀&=M,eexᴲAf{.]9܌Zƽ^ /L FЦ ήeن__`* 0 Xuf腽bnfGH^.O}rqd~_N~89u~*@'~.~B>'N:!?%)-1?59=A?EIMQ?UY]a?eimq?uy}?????ɿ?ٿ?? <0… :|1ĉ+Z1ƍ;z2ȑ$K<2ʕ,[| 3̙4kڼ3Ν<{ 4СD=4ҥL:} 5ԩTZ5֭\z 6رd˚=6ڵlۺ} 7ܹtڽ7޽| 8 >8Ō;~ 9ɔ+[9͜;{ :ѤK Ӭ[~ 4S00>;灡oYyb<6.(06X] )/7n-ϼqx"ԏ!{O=jAPV?U`R(t Qp\0с?,Ё %?) :D?(Vz%Pb'Œ]h 'Z4?) C(F&PW)@(\`#BHUi'C贀 CrpP,2Ue}ntx )rENI#&`AXdWo{jD@E0"HJPQR\?[ClJQfgB2*ԁ#F&jH E[E?IBB }l]" jJPdDY!"I`pG`hХ*Y |'@NT_z %Q=0^no9l"Q @ E ҧ~ Zx@cKУ6QIc\ Q Q {A]Ž:M؜uk3[|d(_Bd͖ͷD! ,'AR  H*\ȰÇ#J_3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPSիXjʵׯ`F#ٳhӎ<۷pRKݻx˷߿ LÈ+^̸ǐ#KL˘3A`ϠC3$!ӨS^հc+ zͻw_۷ȓ+_μУKNسkνËOӫ_Ͼ˟ONk_('%E>u ]7‚"T% Q I 5P0G 6#hZ;c<@֧#B ԋ9daLt9m9OsN9:d_v&-*?sMA:bϚ[~)JR>t7%ɏ@W$B{*9'^FAg2?CҔ@c~Q  9.t(1 N/̲N`QlFy8!p1N g %|'G70&_ S |1 p1xQ^Dz01%0"1,q2G lr!F58Arny͕%Ӌ1s1R@TX`xL _1_x1x1^LJ ́M/6j] ~s@!F s@1KJ@jWBbC#u{2XhN@,Kz~8r5KT jW1ÂAZW] $KT@jjOV,CI rRX6P `b5|Ģ,ړr6rԐ0s( 6-q?ܖ+ @2YCD enYPNցF+onK@ڇv(8+xW^kvAQ4GC>cy9)~W@.3w9ENn<0 70p 4`<D\|o $p=Ad`d~[\3`A X Bh`@ T}#>T 6@ P% @pFl>{s@Gw"|@(@ 2$> b`vxZy0a@W?ՏPDEG<ձ{pHLjTQS %=}# G3r@H PU@II>2ʛ$%1HB)dk(R $|a? Ppf |+2Zĥ\r5r,_@! , nH H*\ȰÇ#J`ŋ3jȱǏ CIɓ(S*l/ʗ0cʜI͛8s괈j@ JѣHg ӧPJJ!jʵׯ`"w@]˶۷pʝKݻx˷߿ILÈ+^̸ǐ#71@˘3OD dg͠CJ@AGͺkM۸o8p5 Nȓ+'{1?, lNU/?{D Ͼa)\/F`N*?`'SBށ@jO/yw VhaaBH8P}D$(P,N HAr4ւ"v0D;T3~t@&NRPFVE" X)wUÓPˈcl"&4K p|:w\!s?%`` ^uRANZt q)@)ϭV1d%BCYvO!}_CKA+=)MO?VzyZ7!᰽JЌ1 ,h%d'btkZcO^UؐtW(j+Z7PY!>Td]W|\$EEjQgq ܜ@3yLKz+Pe7(Ġ@A  @!0]bSЀDlpdBeB5t8S.?օ]$t?WD@oi9|{wqlp@l+ n jSxB4Tߘwl!!r`]$ B4,@7$QΌo@{?wUP =P tUH(1D2s@߹g_-/Ľo%BIW;XLռQ ׏X.5(%QFBȊ  #sH׮EP@2(  #P‹";.2B FOȧљ@"$ r811{ǀ7(9"hrc\L`2$;C57^5 0A 1@ ?3pM]j<0s/Z! 9FV@7ri `Dh?<$c`#@ jO8b>%0 =0@D~[D $ Pf:MY1ǩm1G:xלՀ ZJj#99y38 c!WH=R{o""` 9CfP|A-B0 ,ρ$ X@Л N?( '8`sΜdi.-HDbԠ%pB0s*,0դ(52 G%Nd32#ʮBdi VV[*?:< x!LA@A SĝkDO/JH rGBV@+Q= FV'BQoؗ0;8AO1kF:I HS{q6 'M5\08֭z d J54`a/v5 H32!zPT,<VQ5oﳠ`jӓ@LVjq]H !FYD.KD+A(LIWa#\,>Cr/b7A^(-?4s!;AJ6A9htPSqف#C?Ծ2 zLo q?v6_@Ho;3/ Z62>"!bxT/BUچw &UClr)rzx6~qJu! ]kf1,؀M!d4&6{)~:*:aJ! GַyO'GK7K0$25f̕0!827NP& P#D&1 89`ae4 /3'KaM$21'($*wWy (ȴ@1A[Eʣp!cV1G3XH@;X2!zxA3zQ Vu6aGG&2Fp`I`oEu#!j@1y I07(rևء%gw#( ȨH!t1Vac5p~$CxahdAtq=UKSXR ሿ&Vf/$#")/3k nr[cĖ$A9&G(tjA'cTPQ )ѫѢ !K1a6"Am |kAe3D@A7 q5a 8(L #uk u C ;Q$@ o Q7 4k@E TzZ WFgY];5'3/7Uڳ"Q:(U.eYZR; 11`< R' e)A!Q6jU .K8KH`%0B 0ַI چi6@rq=& Bw##<1DY"415qa@q`  kk$ຯ;.8cAs=N]/ʢK05ߛC#¨B!8;ʿ26_(eJ&ۺ,xJ?}1 Qh7vFkhT?" *gD[]U[RQK$ׁ3%A7B/E{k8` |Ix8`b*ri鈺0 ! p |C`aB8` Rs0e5#T)aDt 1l)ESl j-$_ QP1 Uk G`G'7o- ]"9@,%$Mf_pǠtx 9Ua6Lq_ ?GQq|(!3R75M8'C~KeTd*Bfr]zZY5V AXh+E2rh#8NGCّ<LDf?Vfc4 ]9;;ăa=ˌtr [X7A@쫬8NĶѪ BO ` H`)r'#0K'֠ ׳3 hP}Yb_+I]4GVtȤO'!̀\fE rJBrC1|:`h aP=m#-4 Cx#E 0(` ,-ǩp4y5jDfȏ[? 1UG=1yMa O[\nJn5qql)AcP;:=t(r!3/ X3@{)wS3F;g+(&iEb@. 8ʍ?a)5|1!mR9L`z sB:)ѐ7(a l%k{j7 yx{ Q f` 6Ru5 t 3qKgMK T&Q Q%Tq7]ɯې,lc5Zˇ\<A P Zy$SE QzP6-*xp % +5#M LԄ1Pэnd[phS F)buf{^oj"ml&d nJ#i/1xV#nR1F^1Y.f$#,vrvQ)9oL8Y; @5QE P@]FSg5= T[s}6ئ8QKriu9`޺`Pwz TM6 &w.p11B8;BRQ ` |#|F:!! 9qi qqvиז |3!_T _]?8{9'+E^ZMms|v _;(0O 1 PAA 0 A-C=~R$p$@d"@L4@Sʘ4ETRM>dÖQQ'Օ1*9Xe<0W*V=W\ukm^}zW`… FXblYdʕ-_1Z"$hҥMFd>n:(Y|,9pōla!HN*6sq^q?5ϐ^•*WJ[3['ǟ_~̒2*UƷ:R: k$>HhfYg5C?1/  *ABrg3XmZb>s1D2H!;!D2I%dI'2J)J+2K-$rK1$"X0&hƻo

ygy*-G@ejT@az󯄭ĦbَuVn(lPQdtJ6. c1d`Pǀ]ad#Y@ļZ#lЊ5 +yZ`C)K8'1A!d7j  |lWx\$hYXrEdo9dlZd$eJҒA#T$J^ғjA ODefC5KJZ'cb M}e@,UKbϢ@!ńe:q,-@hv2TNoӜDg:չNvӝg<9OzӞg>O~ӟh@:PԠEhBP6ԡhD%:QVԢhF5QvԣiHE:RԤ'EiJURԥ/iLe:SԦ7iNuSԧ?jP:TըGEjRT6թOjT:UVժWjVUvի_kX:VլgEkZպVխok\:Wծwk^Wկl`;XְElbX6ֱld%;YVֲlf5Yv4Pf: 2fyZR+!(H>[հ# Nڏ Ai0k|w@FvnOp͒fw,:!ہu@r ,Ķ:H!rj1|X2K("hP`w)\rA! DeiF,#Gܷ! B%H=r.UJNߏ,+%ql"`q,5$)̐Gti]ړ*@ ^"|ZE" (1?N6?%L63*v.(`U~E9޳\2XƒEmvȗK:_lSJ(#!B_U7*,!@|]ə#̭H> ڳ77/e/V"3;$gGCX!8* dJLٟ6_ +edywHdG΄`SV Η7*b*f]M!NƲge* s,]Ǔya>8 L13s[E! ! ,hG H*\ȰÇ#F!ŋ3jȱǏ CIɓ(S\ɲ˗0cʜI̓Tɳϟ@ zr,]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷p>Kݻx˷߿ Lm88+^̸BL˘3k"s!5Өc`V/cˎ9$ͻ+c T&{+1\_ݭ+<2WμbbzH%G~J 6Qy uVhaOTA5$P"g1!RX&ڴ5Z"A%@! 45TqOF5C#.AU e!EH1h%|IPSJQbi8|Tg*hL3 @ mD]2j)CAg^i@–O~TCtE=ԅI30?4A^6F |I 0X&IirMfv QN ؂kn`vHGnu+O*w)/Iۊ]Q#0Z4"$gl'oNj} $lYO'۩"dEI8ӐN۲L,;C&|E1Kհ!}rgCٛ!+aҁ*R; KP{0c4.5/}-P(Yg_Ħy]#m78D=>.9L16P+]t~,EZ@_s:P 5NOd@4tCɥmdJD #g3--<%襖;$X=췏0 گ~ k"@Z̠t k×5P/HX~'H8rd.k% b8"F v'hH R!0",&d4dF!(E?(u ّ b 'h2$k] #l.f$Kdd! "FK@qˑPI*" qTA?Ggdx~ Qp&9D9<+(Rr|dCѼ,S!xGPdH(1&'XZ*Ca"40<,L`E6dY粃c ޔf] @zs^$l ?~kϮX@؅p 6(tARv` sQy5A"pG [Cja   GCn%&A*ܗ *k H9*8t rW$LcUڳ%EL"HJd-(U!VJdL*[+>i<"`/O1@ LkE寴?R`+ LF&S2`@d j^sBEN^7Cj $i`U p;S52 ȔA%i0^aT B|zd @"|zjS Ғ@# ]=\!@Xy@` H|h@6 d3g6]Q?6"V95 T 800' FUw{2O{ƛRރtѨKhٶ!EDڀHPjI3'sIkUg?( Y" i .tK &6ifSXhMPeSԎv"G&3 w(E2'\V~;a.>EG),!7ɂNOEE>R1.FtL0鵼;(=Di_-P| gl ׾bd= BĉD© Q(P q3æ8\u=Nam`q HofD9myIv,'&67XKA\PQ s" `1} 41qr$31uwEGf%(yT1"v'abcA.?e#9脟QXd QڴhUX$aOUPt}AQ8àU ҰDWV;5Pb `6' 1  7o Q *Drtԃ 1M@W#sU!J@Y W?U7Q:zQG LpC3T= (0U PR|14pw"0OY Ɗ27na~ A`D Ix88wHqE7%B[H87& \7*[qt&-3gyD-Uluqrgw<Xq1Qw#Ras(Q2^ R9_PTISVNW YɕZa\ ]ij ]i_]9c9L@601[Q=?x5 ٘9 Ȉ 0YI퀙@;i ) 򰚍)73#s &Qp`i^p䐘p p)  ǹ p y ٜީJ ٚi1"P0gH ֐y p `` yy)9::ٜi)pp⹟^"4tdfN8r ,.`Ǡ(Zװ 𩞉I0; 3Zi yʦ^y)OIUp %}A= " X*`K`jiYi?ʘ?ڞA ) : aU Fم_V 5@ &: 1)J*꫽F*3Zi`Z ʞ Y ^\0@/V E_!Cb"˜2;4zJ"֩]AJjb~BG/6['> y%DbSC@T۟X[[T `۟CBWcg{!0t f+Vk/&QH0 0P;W;[[V sK{ A[{bQ30i|bqb+A'!sGS+a[ۻoV&Di̱)u6&&5uC-xwK!Ip !7!& ۵Q+O+:+y;@dH 7H=5er?A*1Ulg%*UyAs|\Ayk;h;j` 4o?"F',SL@ު;6 :!X&1CAHbDuD@ ŋin|˾1Ȱ (j:S*t>55P8 0<qq f!p1%MlqHce>dsjlG&&mgF&cHsLi&LĐ#nLӳL?Ŝs͓N˰>Y|R*I\?\|ll"Μl2#̈0y ˬ6pP<`ɁVzRx /PvfW{<]m'bN⋮f~R hpCJh"a y#g HӃRyV?=EHARlGՃ2V]2*BZ![IאY-(8b"e-(l-8m ,D#7!sm$q{׀؂ $=ر̅wk7mQ(/ ٩03#0 zٗҤ S ԧe=۴]۶}ǁ5A .XdՁ1k-ͱ16xQ@-=}؝]ʽݗ5Pxm)bm'Lͽ޻!Q_ MC\>^~ >^~ ">$^&~(*,.02>4^6~8:<>@B>D^F~HJLNPR>T^V~XZ\^`b>d^f~hjln>ϰ--" V犱-s& P~Qq qu> P(0Nh1. a&a]1٘qp6(+)-%(PӶO?\ ?- QGAwc5yzs# DQ! ~n0!)qnSa((`/ !r# ! ,r= H*\ȰB#JHEf]G`CIR +˗0I͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]{?]CetKG*; ,?&"{8Ff2a@exNAe'V2F bqC$ `?Zp7BD@L0 ]S_. A<˟OQ:>~"'hw ׁ G%8L!Ā}6bC' E@39! !|C|2pc}OW17?W,`!*^HpL(#,^'G7x% "`,Р{`snb|tb ҋb$L̂LP q r@`lE 1N0l"̒|Ql"x* Ӌ 6nE5@rNTr94ys2rx,s,b-򏻋( mNㅟCn8,_-N7%(2_$T?`S P̡@) A2Wƺ ᛸt$ K\3"|C:+%̡h%xp4 _ b4Ö015Ի,;,DEfc .5tM n,p13@5h$O5r&b1g+O~1-P yi#v.$ ^s~wh˻g"|,tǼ $OH `h::'H Z4HT Ff %P d)@p(ܡ|BH k7B#ۇE Aa }M\ H _ #H.60~XBd4 &RWS} l6QtH#b}4X# ~I$?GZ2,c)X*1~AZЂ L$%o&s ,b/\1tSHT*JthGQ) 5qX:V #%ge^қBX9G/4WB |e,W}$MO )a@8:dÙ_˃tgG. ѧ;,LGyRxP;JRA$d Xְc-+Z͊VUk+[J׸f@fV޵fY:$D%n0 lj,ACt",ceIuXNN;j؆6PMS3 QDDNԹd8MPoH-O03@Bf \d yAfb] u)HnX=X oIp^$ ! ,$f *\ȰÇu`H0ŋ3^<Ǐ]q4H1 S .\mZ͛+<ϔ*PϣH*]ʴӧPJJիXj瀂`J0 ÿhɪ{@PѨ! ,lH H*\ȰÇ#JD(_3jȱǏ CIɓ(S\9E!IJ͛8sɳϟ@!KH*]ʴӧPKիXjʵ!!]JٳhӪ]˶۷pʝKݻx˷߿ L2a2#KvJcB5wP/@Ϡu&I|@(n^M$$s$׿rR @nt+#HBĂ'Ֆ/uՂED|yBJ & 8O%+ SX`@= , ^T˃WZ!QVrPu,z` cV(FnX@J/b(cWGuM5@J B1D!4^)Ȑ@T( iX 8KA@bX#@ 7%Cpl}$gē#PFBPA 0`8@A A"92V˓d J/miލ`6IN3),:u3-)CL|n~J@ᒈ @ (`Q@^NՈ$/U zyNFG (%R0d6ES.H⁚rDPGӂܓ6;eI9BI8nA) i*yM0jI,@ӊX L!\Iے(XC[AZr$ € $I8,d%H ł7J؂><ˉoIC%N'las%GЯ!,dX`aju'ٙXZ,Cn:W#^^yQojÛϣD !@sZLp)mFzIFI%2P𰐻چ  ކ|άly6Y9:5@ t 5D -?:Xh]4s5Y.zUਏ Vm6us8e8`=! XO>HM/2Y OBzys33sKrs¥xF˵^̳,4TJtg):Rn0s(iYtP=)/hb6F$AkR *`1\nD(SL PO(MAΑ. dٞsaB$%D?݇F VJ l#!(B=Cɋ0{D둂 ssRĮ1*(~I@v nD,?kL#B%|  7ghPsO @mq p 2,wUxQPg %9R53,a d5{ 0((HxQT1@%D?S] 50 $I Q Q qzqb:pI` )-,6y&o#\fR*q&3#%dl P&Wq6Pa$s2MkAq\0h{tAEυsS\u C؈LRcX#HN`x3 wjau$ 6q]o91q61@)xϠ 1l~7 5O:wUQɘlKq ŖEPV<ъ&/d2!IWaƉ!FUQ'u QcWAwx2X\y} ~B $PAVo3XX` !aqQBluaonp0{9 (c2Ac^M_ȓĒ] ct]CT!4?Ye\6Y?FeR0(G |7A]Yz"%laAn,AECssQ!JsQ!vMT-FKٙ)1a6!B9:`6؛]>`ҋsa1+5)Ԏ)!T a ^Z|)T%G@G@i B{7 1YĆ4ƱG;y!!YA-'Y? ;H7P m M f(qSEB ,y-F Aj"+AwqyPC3Y%1d  a 79%4o6pAf pDDk]67Qv 1Ae9'RP/PbZ2L!(U0[;Qd)QDxٳ8J#[::ROEcJ=2pG PBЫ1(,qx(+d NBJ'DP!$ !I 'e yPM9U܉(Gb{%Q$ipTȗaAA" s0~H)A;d:aL֠ 8`mJ#P!.b;23YD[}lA[` ?NAPr9C{S 8zEр` .W/!z1bg+2 c)+0mg%!7qݺ2[7lrC)am٪1`PC3n 4eu!hvbEE3CX^Rz;ۻ- ay T1#QKND~[&61(mǪKq! TzMQ+0ހ) q ]V R A)1e#b`%0 :u` =Qh)W x12 :qT5 RF "Ŗ}r,>j q a٠} vKG#=>1pi't69Mza /qxWx(CV.f5A{q)A {&NQO f&X]<؊59C1("׽h(:aA gapaـ*`%z!(,S 6)q /F`vͥ} @p" A ,ð̺Q+Vx]1OpxO 5fq *K@͕,ij̋dƑ/ 3MɖIbd%˖+] )Ǜ8!|`O2+Q:R0"l38RM5C4`$`X}Z\^-SȪG򈌘["6MzH,00;CQqy?O0_&AWu}RٓxcA}epdόp P=-ACUPaAu`ŭב0W-M@UR;`ٺ `WF(aMmU`qA  a@4E:4EK QWWZZ$ QPKR~‚(c ["h&PU0a$UP⸍3 %^M5N3-:A SWZ U|].m-8~==a>ܴ--UP,^})?Tg`?ʆ;ĄK"in s\8hɛKxRIcqNoK73WQ~ 0(ͭ>nV֌^%V2d6wc]wDusC\E"sp2 IJB鸮 i v am1`cqKqMn}cnc֡~&10̇pCXqԮ %8ʰ%"aO7H,1-=+'?4_6 8>h1QD-^ĘQF=~RHDRJ-]SLyC' XΚEETRMYz'9%WD\ATXe͞ETrN PTuśW^ VKBFXb]Wƕ-_ƜYfΝ=ZhҥMFZu]dlZlڦ40КyQ ,("&THZs ½H@!AKR@AN}h(gzPX=LH$"KҸAr>L a!16?0pPXС3*DH 7F<&*L%9jD(E ^"ƉC ,A"!=4sF )!b]&M#ȿ@"L0&Gb1\?f6kʦCK8 oZ3$C6|TH(Nq~w97Q%e ٬! ,CR H*\ȰÇ#JHŋ3jȱ?,CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧ$KJիXV$0@KٳhӪ]˶nʝKW%kb0e  6 XeL2`ScF̹\?MӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_ϾO`b^Rh&?  x!Vhm9vH}EͲ,$l=⌸u04X_l2j#S" Hv@{IVANPViXf\v`)dihlp)tix|矀*蠄j衈&袌6:] %ĕ7 Ɍd"JSd#q7H3ϓ C:T#@DƩ]@:zUq5- 4H9C Mm,;7;`?pQ sNzۂξWB _x^(̰3^8K0NPc'M6O"Ni ?8<@-?f4tO-t8Ss;#5-b}ЁK`s5YNV܋m4ZN@Ӌ<[tH^ Ǽ]X36R9״N/hó,< 99_#GX]5v99?k#:?M ],u51*D:5f_3X 9Ma<6c9=M:Xx ?׷sA?r5Bڅ6MNgo{tvrqkYG@,m[μ;= ox{R$Ff`@FD f@ȘT'-iL_T0it3p%L_jRM< NPS0F9Qt @ UH@&Ub櫚l$I@m:g` ^ ܪIUkR3x[֪Zg*`+ЀP hp fiJU^Y S m< 3 @j0@BnAkP eZ $ @ VU4@QKV A`g Pd )h0`*U BzZ*h,\P !(5=pm#la$, @Ep@ AAXӠl|,I 1.d@St@(-UƵW8+ Fn@ɉj~1-,an&Uv9@i[_ {/28-!Oa;@3x$8Ϫ &o.`*0:Ow]$RTac kV9%ALd&yy05"'1 w 0&&u-j.-kaJox_"k`V#5 jSIk= Y5k VLJuhw;Lƕ4VW:$聬ق) `]8՘|-=މUJgϵ;۬Ѩ]8:U>mR 9T3hX qqR3G3W@j뻺~ Q) Г·h )w2`_P[BXY cb XC7FZ.dYgS5e >crziBO;ЏeIϾcoLͨ״OzY<ԟɕϿo\8Xx ؀8Xx؁ "8$X&x(*,؂.0284X6x8:<؃>@B8DXFxHJL؄NPR8TXVxXZ\؅^`b8dXfxhjl؆npr8tXvxxz|؇~8Xx؈C8Xx؉8Xx؊8uQzX!'&! ,"w H!\ȰÇ#JD3.$` CF % yQ wəN$D +O5~2֘(A c.4ja/uKR ٚjڱ]+vkC6mڲҮ-(Yogތ}  \@ Ê*Xܸ3bWWv@.HhԒ]c@ꁁ_]cU޼&7߁\p]""g0^ G_x\ͣї AL3=|'Agw[{F)lu @CU1AWC p@R@] 7EA$<4C b"nV!π 4 3@U@_AM{ HІ "eCM@ 9,7Qxy&ў| $gs!:hyfR@! ,L! ,~J H*\ȰÇ#.t$a3jȱǏ CIɓ(S\PD,+I͛8sɳOɔ @e~rӧPJj3?Xܨj@` AI[Ӯ|U۷pJj@qj&7ZXSÈ+^d[I UhƘ̹sICBC26w__эžMmo.k۹MCZ@Hg`#J$<CL _q?N8ܼ{.4P1czn߰6r&6Nނ 6L ,5\k,AxLЁ |10t Lh7,GP RX!8Aރ@9P"B&M^̂M/6pcb5t1,q&i1,PBu8,`?%`ѠAP@d})C:U\P gTslas?6SF/FY,Q.Q+f ybk%2?"DkA7@DQKBЕ UzWkFYp55Ԁ _zL iⲉ 51^?DvP-02 :H<7VO|gL/.žҺD|lY19kLsjC`Ck} 7ֱ1?4lP- C q= ? 7-(N+Xet V-ֲP~=lۈKeP@q̀XDR,PD&h&%Pܢ\AjAAOбޙ{Nsu`mBaPh25WB*xVwħ1szKtr z= Đ# 5idp - de 1TF.(1 Fi̺IPr% W`Oli^)MsX1kd6A4,ǽz JWTx5`/B pӾYdX&cF΂> UhN` A9Lhz!qE} ؠ׾*H,(P٠ca#wKXt^JЁ^%,2T-5&aD{=r*wV@ck^/*,l2:{\_Qr9:8kt=tM4r!>!RbB'J,t$йGgЊzO!Af܀H2)9_"Qt!kC'HvQ zȮ,,@%Q]H b@ V̀b @ \.!'sD ( : [Н;E`W"-e9AD HAdwg|BAC S l=  Ў4 02`xa@"H`@)TkI0 2CDk FЭtcr*d5:, 2D& @!nߪF MmdK֤|1P  `@PZV!4lM %:|.:@6Pj j<)g Rq!䨳XoBp~LS IN@N% $b B2pl A@nKnxkp@5[謀+H1= l.Ү 5\3䭂 0,Utsw$ 1cd@udh O`YZ" dK$læ=:ѕ@ 0a@Mg 35f P*"VL e7< W!~\(ܶX@ wЮ(frS1Eo{A\( 8M WG|5Ll}稶Sn/o;ZDr# C\7Kҕ 㧙]m? 7#!l{zOXaͱ\uG5yptX 3ϙD)!HGikXHe^`Jt?S!G.X:T#|s{_ Jvr'=ӿ$~X# [o0% BPP~C6~0 AC0| T 1` ( 7 ;W1 < 1 0pF9e1 F!~00b Pۃ1 2# t`*`F"   E1,_a #*y21NiP6-@`7 mH(# 6$x.] "Pã=@ ܀ C@PX p` z <- d @pa=f t @  0 ֐ B `k Y ` shk tp(# R {@P8{NpuH`p` H[ ]` M @ E p] ( ;᠉7P lQ- @0 p  K  Hpy;w{a F @ c1 @P0 < :XXPDj<@t yWCX#)  Șb X-X 0 p@)qY!2֐6S\ B0 j @ a  f Ѡ `  h1h# Y   i3 p` @$i遜)R ` 07 ( Ee@J9}q2Ei27Oa``p0E𐳣(5([x\Jxц(9}3wI!2}Ѧ~j':ە=S %91QeEH%FQbi(,L3oc 7; W,m]7 RH$grfE!Ǻp|'w"%xRy'S-y󴪈2P$Nr{@&- `0{#7@$XS ` Xe) sq(Rige㮔ְ) 6wY  "Bî"j )` ˃#%y2 8e3PI  FApyZb07  NE ?p07P ϰ# J( ]&Ѝh: 9W Vְ1 𲵺]V0 23 W^I# p ]Ap ҙ 19E6 k #/ 066w6[= p1p @  W10=] _!1` f sa1 PP7i`ц'S̀ @t ^ZYN7@ Ȩ@ zѱ=z;0g8b ;Xʺ[) Yp`H Px 7| L#u| P4+?BxP9[#Ӕɢ p = D" i _HFb )HE@|(`)(p2B ܠ # i P @ ΐ0j چ* a#5p(ܰ|jX @ %,  d J * h 1 'S7GF` (`so  : d!3 jPj AdЂop_N*@K 1iPb*j1P FIh=yq;;S :#  ZPρ`prJ(*"ca9B#jc #Qϝp #1 ه+k)(}ȫH` CF# 4X 7Au 13z2X@4H(p {2 Ұ R 0  Ҁ@@k- hN]h eӒ'% 1pR-p0A^(h #(@[P͠1hJ `πрa g Xg* h -| X `$` @I 1 `yw0oE5$a fbҥ#j#K qy{޽n~>Y 1/Rj40: B/NPRECRxcxZ7Z7]6/U21'xdz!14")yy>;ŧ뼎넷y :~w.1E1=$q%0sk.w7wP%bL0!qC1Cj77qP7kGޞP  ?P)5c0 BAT{d` #@"^X%(6&H^2~#Og|JKR9Stm2J)]oU w Ϣjw@؛kGzڼ?Sʾ*2G?Hȓj]+,>꿧>}V:Q0!pYCBDB@ Zt-B4x Y,KZ m ۨWWP,0fuC)V{,0lpÐa|! Hc`Oaѭ֨Vz8F )eq p4@J00{GZ;6}g =z^P1CBєDefІ#) B ` 2`" ,0@+ S(*XDž58 .1 ~% b c^aTR4.l0@D I g@Iq I@ 4I`p@B %@H) U pDOS'_9UR f#hQ eFD8bA8j@2lb0>AF9ְ I+nA0/tqVa%cKn!t(@$]@E0@ B`7|s`Wu đ4 >0Q!0u JRյBaj,hl bpI 0XD!D-0  n6@6!2.`b!\5%1űVq1D` [J"Oz6WO:PeXU806@g9E4H1f-R|RZcb FZpVdmy0Xk*J- ?!kP_K 3 h:>X\ )` ?=W@`60ŝZqIV|UZ!{ z TBD- @ IEs'_~K1ni  q ,hS  @Xd&C g7ÐZ9= L0a8x`PWxʌȆOn0l pJ $3`1dЋ#X _ KT0-SptlXaЅ҅xY@X.*5_C;_GCZ1]:=@gXN -@4 (p;C] x `dD,2`Бo@"$@[HZ(+޳`-8+FeBZ\(Y۩_^. ZA&2Wx) {c3Ȇ(Z'atXGP+ΜI`p xD@n-X)55va&HcXhfPŭO  (خNXKRAk$,؂|sX hnYCNT8F . QfxϲV:Pa3H=7$P!8`Jh?;MV)؁d,ȇElE" 12͆yC'4ȃЅ``@,Xj 08`HSQX0{*!1xBH$h;H: 8u 99Q@@v!@d(d@.MnhrX/e r8@ @Pe TkN1ܲp:0Y-XOC(dqreM* N  4qC˔VtG\>FuhXrpg_-YK5aYSRܒ <)p @iN "ehXN=lи "}:D0i  <(HſO8( ! jXVpɜp7Ѡ1A46` "4H00# drnP 54ꞨY&:t'9{TOmg>Z/q[幒q`x֬eMG'g*s;:w$@@e2p?)ݣoo<5>c!E'jDkѵvC0BzXQЂ/VZL%x O˽y 7J,TA 2kM|97*"I Zy%Yj9"6){[>A|Qj 0MgaZZTYӈ-'J:ixg6gOtB 3rf}ٖedf¤R>F /*gA,a?٨&"bK01viګJci){{v{Dm8K %" +&(QvP Gۇ2hx!+!^/B|iq *j% z||%0QCN؀[+6ޯ( #@Lx|:.\p; 1$S6@JnZ_  5~E!JP9h1bah0̥PΪ `*9ʹMk_ z/<݉0z(?1 ت*P?ȁx5 !49@5/|KEM*@$8ai; o8Ѕ|a#)-(YQ BlzB* DN55jK6H-|%,9CpcTu<򂼮gqb!%qZ8 3ba!1&x /Lcci 1 [uHհ` /gIyjd IehjTk# '%Boy:| 4- C (f4.fCzݓE7x +0ExSEDыTns,ILo~E/f D@/oP%T׋,*`8v6_ ׽Doh"J3e6!(Z`d5~J+Xzrq)P18A( ;l <jl3`5Xkut 1j0'4#21T /#E"-3:^Hz \xnڗ% BT>qPsIa)'@tqe0 ?0}c1r0ic@bIttRc3, ,~{ܣcQ[m$HJ|""bC OH< _^7S>(l.bM&`eד̦)l@NaKf bdTaHe#R- 2C߹ю~M25A 8@rg#o@ 4p ?` H 8 @ (`3-R^XV17,Si5.,yB!NQފK!BiaV|!  A T ?0<@ząA!ܝmVqEi(\`ȓy\U@-P,\ZO@zTe-y<֍  l?HaGel(Fޑ)!{q! M!)"{8GS8;ُV̂ \ޘ.&x (ӡH@9`(R^N5c%]rJz~X$ K\| hT#=yqH\I 4; HT@PVDk=}cԌy@ƇOMKH`x#ߌI nXýJXutj\cDˆ<Ƥy)CT.IHD` Y_U?DYEڄ$UVeRDTNiL$!ZndK@3BoIzl"FG{]Z5bJJ}DG'$(cK3(cEf"*F9Lqa-մOs.мpC(0h sT8 /<5 pB27"?<'\`ۮ(ViA \R-r|Tfxؤq hYr", q@$G$nV!?IɊC׸5(΍V܌h$W:Ip^X#iLn e>-a[<~K3-}JrLfT^B,K ӠBɻuLs$;Q£05ޕא5qNr)] ,Iϡ~ƀ; W޵Mf$;L+*%*&.4 jĸ궩XcTfPx5 1 N46VRWpm+M'+SZZ Ri>ū^!hvޝG/Wԃ2.w5SIUŪ\`2Wf~`=v#5N$\+z 9n[3I8uQsC267$+؊pekEˋ&6F/}*,1.wZ,eX>Ԩu@j͢@,\C25_RIX.ĉQ\ט1?A  h3<45|>T7>%Tr؏>9}O3:Vmgξfݭ [qa1miO[}%+Zy)1tqO8o\ xEk܅r`͝UY~-1|nH*je~ؗ\&DP =(@0tFW@>;]UzӃ'GgzӵtO]`?:ٓw̹w\|#]3LuJLT00*@@TR]+qY{[y0]?2nW$IZ]58#y> Gt9l4vl` n@ Bbt!B0A"b !a7! 9_ @+DBIVB6Iz * `?M(~ʹ0,L& 6!h-H o z` 0 i.7X#N2`hC ht)#q*/P   /I313$" 3S~a.tOd\~LAFaa`vL 9aPuX`O!`Qb!<"4  if*`?  AG,@$MR&pJJ J yt``)g,`)|R&3@ 7   XP)p)dH5Sd" C H hUY-@(}J!VmOnVD:E Vd~b@"b@4 \lZ .bD e*Pa!N+M;l8` @9!v`QS"`XlJa 6`ng@ iC"nlFHW-BA01 6 XR /D +w- a .7@\6Db-i7 /sH vu@ @h</ 6bYA"rD@-BV`"Akt!"@@<68aO``^/Z#0:C^@ N2Rl:̀JҢO8*l* :*@-!oqH)4H5Bd+ÏPoCoMy-xrYNHFJW;bj`yuDF6@!hI A "D ^M7p9YzG x*-e@.oBH2+bv>/ &. jn ^C0` TB2@ $M:_H$B$ Uv1"$xE {K"d C]" Nڵ"JJm"7 "BL`.npA `zzG ᢝa-/Gb0-@|:AAPU O%,RAZ< <AB 7W ( ĵp#9fS{.Sza) t3hY@"AsZz "`z&"4%"pJbB/ A" ߂h6U:`n-ĀӜp!kFZ (;+Teܢ@ ;P zZ ʆ\cС ex e}@ /HF&`F'Z & /,;Bѻ`&$Fp zNid `Ae@KI"N! E\6&99A$<|-$@v`>>%bBbD{V oܶJ<`*zN@S+,- .Oh2lo Cb'@BE<cB2D5!&"SO&|0:A;VB:aJ'n3慨d AGP$!= C! ~|F؛K}=gcV="}~V"۠bdio~"B,4S%fWzӰb!A߂B<@ V7 ƿw `f/IJ["f- Y%n;~Nd! S;h;*d!A$s%  Q );aAgR;jZ`Dn ']їƺ@E@ DC:@A^9>?HlJB >+̞ i +A+>.FVd+"ڿ-'V|*A3XA@ص 62Yb^/@Ȃsw5)Z@,PD UONI!ZRFH#,MX#)E *X,KƂ]ZPmk B t"۷GFXk/xkH Ų οPե { <ċ?d:`3\Zne^~ &oQ_pJawPAj&DԚ9U tHU1>ɣdAƣZ L`)~YnjݚBymiS*mdVok lQl'q۝(AX۳dIj:۬tkU?Fʬ>ڡN dB5oRrl pʑ? gCN, Wçcpe'D#u@%|[rT"<S; 8J:/<#,R U? K@´%h>Y$]5ZouAA[?Ar-hj)YF@(35.m?FLOVL, "eEV02,`O H,J";1,50%2,Q,K4]a Nc&I?-an7?]x [W7 dT@`AHr t1@@A XLEnc=;IiKym lwÍEE<`aa`A-<[`ApX| I20n$`a`{*ࢼ `ց18'l%1   m> ` A:Xa Q ^68 !TLYD&` N`<KXn Ǩ@l YxaZ 1 c,AdPBON7#@8 / AA9~!TX. NH3uHc,p4atYTfpG2rij<OsnX4#z vS+  y#-,1` q p8r(/x̬7r"@,_hgMfx؆OdȘAЈ m0C8"X?a֔Fy ` è-@^" 1JЊU̢8+0NP ыk($+dA*֕%8N)| Ypp#`_F"ְM$aШ! Ԇ:T X @-p_X1Pd D2(PDڒK@UMJ,yϛԢِ2p 3 xE:t`Ԃ`րR"(B3:# #Xk\@ @4_"-5 >7̀u@ :>qX CDAq B (נ00vp0.f.E1lbbX\B`c&S1*s 0 I 3fJ: F,px϶3㵀#,\#dV ܍0\jA @m` 0{"@B $$[r_ R(w׼5og2Ea@@agT AW(rYv2! -  lC,0<$; Q" cJ@Xz ٠7>C8|%gQxnC1%鎡X^p05(*7l\q:?|v-Sy`,\:pHA,') ZdA;Hm@Hd0"~z63Lٱ<#3ֹjNur}sf.d<`K|JFA&" (8xD|h0ׅu @ <Y0"5FZdE ̃?&h4Q@@WmD⠟FcɎEJ*-vkeaMlyUf&q®] *~@Ԁ- d(cXTsJSsBLt]03jP\ 0<)C0(@se`%< Q-Uqq~!D#eOx)?xxEhd&&fW0C\%Q`Co/`&W&&- q8C`p@I87@C Sx0 R nY'0Q!@/pkE@ zEm΀BVR2N2@tT-b6H$b!6!1bNU0I Yr1V8ÃGH5l҈gɷQs-ag-~&'"nHwB*긎,19‚/+:5"B.P1 .q(sCx2PP qxj0 P2"% T#^, 钻(+y#-3#j*91@a\0 1:Q=2 sΕ dC @>p`@n zÐP k &Pz,`P888 U+v *sP}KP-g:6q r:f% `zY p 9g0gװ1p:3&1/C=PyA=(;xV*rR)q)*R ᥲ<@ &hl"z9+Hf}T 35_'kr&-H28jG=1;[!ՂgҤ-HA>3 8,dѾ弱(N/i.rr,/h/^N/Ñvn7 I~&MӒZn~t#`rBkDgZ*` y43HC֑2舮fKI0 i>-uip R3{fk52- !xyP9i&XHҰr0` c82bt &;{VҠc}, hq x#;0 W>%TqNꫮ> ;(րNT `yBT FM8u@.Àb85 ЂaIAc8)B qՊ. *f`0j('Vme \EP6 KG&-k 7:7T_OxϑfmOV; 9pQbXT @àbÕA [ \j@K:AiF--@(P ;0kP bQf  ȀǦU^0Q)04b?0 YpmW% Z͚Uc׾_-V똓_f`x`6¶逘/r8GJ1elxaɬnJlHYK5 ĪcAO*4/ǼxOe1ĢzlZlӘgծ[4Υ[]y_7Xa^bPo23Q@(@- _(( kkH4kjM bp#7? NXaX '[䱀 mFbx&ێp;>!+~X,/qɒA6܇ 5 ~8kFdYbb9hBb1ŋcJ`9J n/`kd)ᯯ(EEk'9JMj@YXb0f*E)'/J@".R˭#4s04TsM6tM@gy@cy*"{i83:, b`hJ, CCt iJM,@:/OLnXfOba!XT3n@(a`avPX@^tij WAY>bB! HP1 F/djB j: cjؤ%r\- l8,&X#J(_/`/"L.yggzh@e3dp}{FPzjY(7!PF8(X+*F&ZXxn?>"ślf¤^X,a0' \"  Y^!^@p^6<98AmcWX•,J*a\+!nhh ,j%#<zq9b%YzȬ*z?^Gʠ <KYl3̀ @FP| R5 Hp0@&y <qaa4jDSn :4 PhJ! `6$qNqX<0FD BC(bQU %4!2|2鉥%0b !w  x p( ʆf`p^. 83a pIx (*5ɕ %*.!0$f1yL )N0a,94 sT9{,/2a+!@ CQ|UCy=q'^OqBR0~'֊ @OX&u%`z9IUS/qLT# 7 S-u!8Wj!iqgH$ -zro-r<9S~(iQ@u|}jL`"iWUN9.MUY! `$fO%R.\",WzX&VnjZPlm@L"I"Fݱh/^EdjSe25- tyEr(!F?`+M1 Jq!+gCJ0~^Af2X D8 L7%YK3-Vo} k|b?`A x}`wSI@xIq`XGf@B(kOBC~x<}/ᘪ`@lm }  x2 #AOāܓ\cB/t $ AJdq Yk@E*1qu%K,o }hdF>}1 u m A,`MW0:iiLȈ4aX@@?`d܀? ea.,#ZXԨ pa u8j`'2Z" 0C8cd#@@=DaWA|v7VV (A+! !! P l0bج;;z YЈý渗\ N!Z#'9@ m`AF,@Ϲ՞bbiPkEC`R ?¡ XC3ta. s0 >o%l.0rcFW3p `L6(0 c kL @e .c`dBY(? #堘o ؞iXnuds^?r"ZIjW b}92=o40ta]ːqe4$B~ kc'X3Q`ͩf`@sIHa(ػl $p"#(B(c0\Xq03 ѫW?P868]@=A #hERz尅IH:lSxPӸ*,x85i@Ye5nghjy<Έ P6`"y@9g9pXp + k>8(a$@2YXX\ Ƴ\PB9H@82Y787SA_Œ @YcDxe"8ȱ&3608 <ʃ(xkP+,(P5PB5,: 0r܁DH`F?1S 5@xθ3ȀgʂDPH((P(X(A!9Mj9$!1D#p|.wr025:a)F VŽ2;{y&qBf+hR* R9KJzzK* LL|\)#k%h "I-X*.jBLL LLМ + Ȫ)hk i{2!ˆ(|㏌0LN--,&`$P'7c= qЅ 9H tY;qA LO"-B 4[Js2!h>`:3hZbCZF@ kN1PIH.E琢 3ځSF@PDI-<#(x 4p%[v1<#~X/hXXņ1PQ0ȼ``8<.r^A#VjE,$ε`xiyϩ(ozpP+lqcgn_Pf]5H 3`43؎Ȇ刂Sb3 dIA8DkxAhz`/r3eΓ((bФ(9YO,L4cU(%Y ``3 n 2 jZ%^d=8äAXJfHDd0HI@kgx!x_k]` QS?UX;:g oPhaAe,Fu`>(< @0ஐ(Bȑ^; `"A0ۈ52 (ڰ^-bJ _@ e ʆ-xP [K HZFشW("_(N,8IQ IkPCl"A` }PaȀmD KCEGXO| qX4<IFguYXT' w!5$a5=`3 Ri^-b|ЊVlVx`Hf@]\;uo<hjQ(?mkǑih(k(1 `kPy5Ѕ YI0Xx s<vi"#8*b6@# etH7Fg^2Y8Y`<@Xk 9 )'9\~WXlQr]φ2bo\(uJRIfde+!j xE_xͳ جA( (u O.PK$bGc!ejX螉@Ur,[%U* ~ (鬬$Q:g(HK/60ɦhN ]˔j "Qj &LL9kjk+0a5r?'h Z#a +Pj1PH"vAx~ۄcq1D}٧Je 8J<%о0qXp x|8@dx8v.Ya x+ xp,2hf(:8ȆXxU+`4fh5"7@5Fdq(Hep g@5И9Ј̃J^)ټc(0ZYK؊}S{;Ås (p|Bʀ qPR Wȇ8,hpxk.9ȇ P ʕ2M!@8n(hpnXk_@(8`(*Xf1._y팕4n8Ĥ<qّ}28ґVxYsp)[ XS:Qx 9@~V(Xj"@. e"n(ʴ5]`aW2(Gx)؂gGNXqeHh[9W` k1k fQ0ZȬ܉5 =-@PMʆ߯uhHш緙k|?9eQDU(T¯Ɇ`B<` ) MivqI1:,XzW}%gx(0oa󆾝[Y_tlT 0Iφ ؁ڄv<T/7-< !AbʨhVc ?i~!Lp!ÆB(q"Ŋ/b̨q#ǎ? )2$L0<@6,Æ9pJ.=퟉fpXX{6iZ뭙*"ˎ$착ʬR[mϞ*rۭYg(E~V.ۮyBi9y!!1 C֒M(CB ÂBHdV MwCBH/vRB9lu p'Si2!k4C8`B6,ĂAa?4MRX_EBp,@?tX3{7N:˜:O2HCFAxP dLk d'Gg#PNRz."5 ScH_F$B4P b/BG8 d@韨30 4 1Ԣ-l7_u?#OH~C? !00Q$ )*B8Fp)Ff1,dua`?J@ 1m~t"p?90R#B_pw|0uB6b-d2 1@(.<J.,ѐ) :C!U nG)b2rEP!Bu3l /L Q < ,P -@HCf:C] H&i^;]Ȕ tk36}\';5`D@2MxJgE,0d/DXDNڌ)pvB4M,BZ7$ |@8X6PA cNlDI7 Q4 A7(8H=VZk 'aOBc kD!ȈB1 . nbdN5&yb $1= #R"6m"2H: ` . PqE 0.ٸp<0C >`6x50 Ͳ,5ʍߵ ih4tQHp8!qT,uވ0=~>U@> { @,1  ǀ^|eV; xP`̀nhh@)@xBb8hD]dB|24h@p2?tOeA, V,,f(CTH84O4,tC !%E8L F,dPC'C{ Ԅd |P C'$ C2$fH@a' A2)H0S@ !@}Q\ fa\ 0\fDa蒜h쀁CL 2?@4P yb;~K7 $A"T\I@g@(J*d0FDa?.I6%41ͮExC$/I$D?dph& Dd$v°G$ X:LEDqESHI#c1EB@0*DAT0BPE%/.0Bn2RD( tD@A>D( |FH@/ ǒl2.H<&Dtp&0D( rB,`gDD@@$CDDtqbAtkq#.kD2F:0'_$! #D@@K,ȓml30#?D@-C؛ ?H?rG@[17D8<:hH(# D BȨu0p'DxpD LHEF,@#S3P#FiI^1ɳDT=#.l C FFl$`A.OHBCV=@!ONGp (/HoDE/DsEhC625H,|,v8D'hDC(SD6C/gaSDZ D_vϋT;sR?hKG cʔFrI.DF4sR'D;KODB,A8p;n+CCX/6cpC|@,`/S>DqXכu Dm3te0+'eC gyw{[t @@`PmYChCCDAvwwEt x#D:BOSDSG3+wcoHpn8뉽&c>Vɏ.KjxvV\/j(v~9CC,Л*y9s$B6zC9K9/s;zocHzw4wDwGF7 |+p#D:F:f @dx[@! ,~I H*\ȰÇ#JxPŋ3jȱǏ CI?&S\9QYh)0 ˛8sɳOJ*#(%SѫX JKׯ="O8x@T+;5D$ric&B W+(hԠUWs? d*H^8A (?FJC(r~~8;HQR% adCJ,7 BA dgt@l$#kBg d` B HcCĀCl&r tPv9=Cs%&yj&B/}7B7pk!RD|GN0cb?lI,lZlk')L~wc0J,fT%xAD(u(J/ NAJg $Y@0IAu‹5M.&)B*ro0ՂD Pm՟lx : ($*`zi c, ^EbUR"XJX$`hud} w- 30|v&(L!~8̹҅JbP9Dz  0@A7,M4I-@($^H7;B0%99E]*b sF400'Ѧw! Qhjqhi#a'O\0BCe*}EE+GNr /8$"8dwWy)˃ȣ;)s|-5Rkt \xp,R@P:Q 0@;)swY0`(s 0FP.ueYrS!t;00 %7ʑUmx  r'( 4RHhu27ф/bPM! ->4LN]yJ1s-!A,j,X|q1E!xU#Ac f@`S8гdf7sAf4#fzag8 ?WjGi"@[q q=2$>8 ` `@9]Qjo*T7?pb>? 7ql ! ra a/W !g&(F.7S̗է;×_|(Q^qp/0;vD*_ӆq $XGaHY";Vk PK Q0/4Wcm&v1 J@ڵم[01qxxxm T@SQ'BX:9A"r Os񉔈?Pbi d;!C^U%* `:zP +6P*7r`+q;q%98v-304WP&#p \!Gx IrQ!RHG2&%@(;0 `@!L "h/';$\L3*"Æ!w/ SPq 9Ić{G\ҋXb ~/M\+tz WoGƯ! R8:UQ) qN36n#2TC' h,zq2SrȻ/@Sӄ 0I9LCfS!q|&Q#0SR&`T':Gza&μ2@($AR4.'̈́30~Qe;2Ia.<#0ZQ2 UFyR$s 8 H9p#]QI%ZTh p  <1rW4']-5~ 3]c:s͂~Lv=*M*dW@/X3qf^sS5e7\l-K8&m "O2桪E"ˁQ7x@C/2Klm}!6ܝpvQjuӒC^PȽ=+%qvMA1' `@a30! Pi 2> :ܫ<VXѰST0.CCRA܀ J.95* QnXPEK[s6ˆ_1P<͵:{ہN^N.(yK qq_ b Pb3pm^kFD- 7+z];9^_VS;2ʕdM J0w!W\uEYzի_L 5y 3/AzB,p_ƅ- 6}4^֭]hlHY&pō=AU萼lqTƁҏp=wI$s ݿb,ҠLjnTh @:t P:> /Kƀ<<,hO .8:0,IϬ#i  &ȇ{, ̓Ȏ i K/s$%m 8YaaB%N'pʤM f9N>hfgY;wLb=,( 7F1 3ണFڀFgծ) %aYW+qE> X #k K ,^ :!!cDi%*dt+ۭ^{F%$haGDؓXd҄QG%IhₘQLe%f b]+:R(v$긄^g2J!HÁa7["X"d̠xj(Ag *ac$$Glf>N 7F x7M# "SR9}LPXp/c ;PoUG7t;I2ז>7t_ZݦBg'ějkw'xዯI +r7|d1'!2kafyϦG?= KxK[b!Me R'פ HJteH$ ]HpC2 ֑8 hԡXt20qHPb:KR u @0Da@N_AD 7JnqF | Ș!m&B  @MR8VGR-Z+H 3#e&kLQb7B@Ad`?*>c (øJ̃K,cǾ#Vڵ IfhB"@ɂa8 !HI **)A0(}|r%݀ 9@vTTGs%!1&D"'ҟ;y0>A` (=e7#O1JE}v$ف- x4Û5(;?A"a!,E!X$(ME8F6 լ6F H'Jpu SLJБH(i9՞ HfMEXĢjÁ|Vf)|lad)TnZ=jA0 4=Ne:X@0#+'U5Yր؜g Tɩ*FAɊ*VŮ%擞ؓǀZ哳ǕK4 ~@I4!.rݦkAj^+&^ @lA_%ߊ8F7 /&,H _| P 4piH00Ѱ ]$@`D`Zdd|-M\بf1dy2S/FٞqAƱ!2GX4 fu B-AaI@BCd@HڕF2R"6PI"`SX'\SE;Rg >i,=pa\ hfP, #%3Kû\~4x@ẓׁ#HeԎ| ha|18t#K@̓љs9i8Q2 G::r`1fx@K \kCxMnAp@+aq1| a d^L.D#,8VC׺nޛtJ)cZf<;xp8qwۊ&Ӱzַ^)w}쑮(I>A} :&=&ȝUV:q9lϓ(,a9DfAgNldeww ZWA$BbQ"mP w/EPU!E(>+/h380.f= + t+ ?""< #d*9c:;x8 $px,2R;b(0ǘ9@B834b腳؋ Fr(3&$ABZ  Ap1#- +N`!6:8y@6uu#a#ã"Q iH5g np`^DT kE;8r; ?+R^XB8#03 g.Aa'ȗЇ 0l`K(d2(Zk.+g쵂0n* '@b Ѓ>19(.:j+Bf$Ix"l4!l0P+pœH!8%;"4#@"oؖl0(`0S;E8@H21x7Sˆb5ܫXƒ pxٜ`#-R.K;IlA ӜD -aʠB~@8KU2C@D͕P% ҬK";LB ԴtD"5 a-1U{ "\9cCBEC눢D #T6uU+|a8͂ S *!l#(!#-LD)PiYDρ5V T H-7KWeW+ja8aa 7Xo鈴8ӂHW"$F^HS"9URԊ01,XE1 ۚp1 lׁ˼xvY.̔, NQڢSI{YRiY~")U;`OL\٫%Ȑ5uWA )z/p]Q5۳eQRFuQ],Jʔ ( ۷%\;Jah< 9s{H/z2 I#dԙkP%,ǨУ!c+:4"e#H2!a2S i&0BZ TOhҕ^C*% m[(EzkTj`+ L%8"c#d!6-(3J-t@(4C8e`jQyՂH08$>3.JC`\Ul"#%bQ猁֩CakHh Ah.ߊP Y ʁcȈgY@; E_ǁco3DH6y8\v Ǖѷexϊ0yd.c^O3{ 2DŊH_F sdѭT"[_ 0̡eϓ ҍU\`Xq6s@4ʠWpf[LYgtg(^]<@X^ @y燆 &AӡNX(co, Gγi[7iKXЇ#L] }&hFg@ceF7˧kb*ہxbGdFc]셲l9l#\P96k((a`ݗ`+@%#>xDDOH3HOZ>ρP+PQ“ʖ၈kcXi.y&NRD "qk@n  gFƇľ?븣@#osi;&ĊQ@99eA,fA+"PPʆBabNle븎k0B8YHS1(cH"ލPQws0Q.R8^!`ٺ.?KśPrg{o'7GAg|YƇ|XWxȷi]z})4B,ׁx;-  ۇ νmj& S[w'.C/d8ȃ0ɾ(,평dH]g`#0-cI @nC\I$`!U`)  2l!Ĉ'Rh"ƌ7r#Ȑ"G,i$ʔ8ˋTҬi&Μ:w'P-j(ҤJ2mFǡ[ZpῙ $lINNǒ-k,ڴjKڸrҭkWglUH(XMY_ E,kw7s3hp$Cܸ6KED J{+Ȁۿa&ZH!,T m8w;( MjY @}cǓ/oZ~ }rAdy _=Gr|? 82=BM&!JU]E_A:CM4Cⴰހ!8"#-L" ZaK\t1$Xq% 9$EfĒGYF:$QJ9%UZy%Yj%]z%a9&ey&i&m&q9'uy'y'}]:(EXd:֭}EA 飝zz8C $E\0dD P6 H 5,c00 B)vFBϐ!enMQ   w7*,v?R8hA P(XPF@6oXʡL$Vy Qi@4Lb } xIA eXw K!?2 pD`}a 424D YmA0TDBd\- *$T\]{QL~E8E& 'ȩݸ@_}6M}7:ь/y7P6$*NwBdh'J4(C\Q~8qł/|!"& )9rU2C&C.դ )3JzŻ{H݌!YW[Z5v}.[F 7Cn;Dt= YүZj XD HBHLW)j,A=aT ">(@*0C bf.|:a0 s{!;-;F s(A$qY(CC|bҒ$p('jJؼ(1f<#Ө5n|#(7ov#(xO~# )A<$"E2|$$#)IR$&3Mr$(CY8g<׸U!+cYP0$Tj%2< /B`')pI-EGJ7etnWS#{IJn e-9EN#d:@9CH|:'D)fQrSl ?Sbjt|%DB?Pm&Acc-IF*60Pi IX eC܂z2ĢPR"VDI(]HF}najC '(E"`Gփp~@A?:@ $z<]H@ ⃂X$Q r/ĵ HKB)P.ȷW DNģQ*G"$3; Q_@KQ&)i)GR SAB(G4p&PXS*TZUl,)85!ap1B&q~ uGY? ܓHbhRa$?AWPYB#`` UFy6BhؖW>=/V[Y'J 2@(H9."-[3*a-" dapL;S3%-%F\.V!h8u˶LSXdE ,ZQ(sC{bT8%mqfڮV4aLTKV*d-=a/` "Y0XASjV \$ ɦ"(4'$" !흥]_ђb]NmO5b$d;nZqy"}d'˺=JY!'H[ o9! %ꂀy ! ,L! ,L! ,J H*\ȰÇ#2$3jȱǏ CIɓ(S\pD)ɰI͛8sI`ϟlFg/Q]ʴӧPJ),*8a'NUÊKg`5˶5BD!$\۶߿!C LP@X Dl˘Wv!Ϡ?MzҨONzְ_ˎMB!i.Xr?8}gNq>9УKaسk\vE8?fWϛ>@KrMbwoGUp=PO<o?D7Md y[#=*9Z]G2 Pn!]r1JPҪ!RCޥ1a!:@`9j#GyGAL" r$ hĂp4j  @?}6!K%xG `5QM{_ĒB N>n D X=~Ň  4+LXA81$ t YYXFsE *A%O^F' @1Hib4H6%2:?ݘł%2LbA:tP\Q)1yCP$I%'ueȃlK 4HJ*cx9@rr 􏨚_%' kgsBpdYB@"tihrd@"!S btlMU$H< 48= XڝL$5.LYA?D H b$ "&pC *ρ@@RPM6O"@ OsN`, j Mo7`@0h`1q83@J|:@Z0U|nZ\!DBF* ]*> stkފ̄rlA|+w߁|S1'mJ`uOs#ּGSxy(*E.^>-mK+H<"eC #  B,@DrR B> !4T A e A$VrԁՐ #n!?LHR+q { *t,H)$5dbXMB/Q ]A(1Lg#w2f~ !,P+De !HIDY R(GLiLn}<i,#2 X[Y @XZф]^Kg1AgA6?"|B.ui3a髬WVYMr#> 19BI$eNHws%+~D VHVP(YA+ו+p vF/78  Ay&!@ 8Hѓ,9Ӆ@ 者cn 03PeZ!V!WW[㌕"A!?!bh-2v!Cob0ȃ8=% lX%p4# /$+~.l Zbo w SمgN[8Ӂrх0\ SO-Ѡ6-&AO b0A2~MA Md2xXB ҂/D=rCHQig{Ay1po#? ! $`{Qm$`]`bcOfRoDI0 7m ~%Q;' h)[jPqtz !lJ!'OJ,vj ܰepa&uY$mR&cv62$434/DuyI8'J3$%]$p@[a\lߥ~f#!u1=\2R1Αi8omV_'*@Ѕm0V%ሉ~xmA"ъ>c'm&ҋL6%$x3~B Rem'spX@V !!@jd0"Np 0O%X 0Ǧ ,FgE%im, À܇ !QF5P0Sp CCw2B4eKFHK+iN+Wy с0*C6qxpF '9;d%} }sF.=(!rV<@9>9aAFf8 ABjA0|4tp[ej 6fJTf`8# (_PtP(%u qG_P@4L>p$` #Iyywtoi) ͘Wi,Ib(QO'%_6%`QRN3Q2gC%ޡ9Ց !@ iIa=~ Е08=RAZohvr ?26F_RPp)X"lбAA T,f S0&tȨafr8g ; p2V3B l-kA {GX  dE!\01ѻ&92Ҡ5]Y։":1!bf \> Ұp! {Ղ  AAq#e?Xљb q~ Z;ـF?A)!0sjҬЩ&f ~Ѿ5!KFbV!\i0#&=[N QUCʲ@32%< +-&X` @j$w~1hJ&\mb !qa?xLat7eh1 Pp@XAY Io,IԾ %7@$` FulL US fV:`gtA8P2, W Qxw=>psVȀmѐ &m @JA9KbQvAzwqu# u9=[ HQGv}轂!gD|҃J&1SYyt=! QXBJk;J0DZ̍Q lW'v.=$ob lMe_XY<10# #%pb] -x0 ;%`,iW /pxPQV?Ir93=qQp;-eV.B Ah=l0_q1aE t@b Ҳy a ԼfpA}Y)j-O` ҹm}0хgnC@Ӎ"a{ Ӻz 0إ[Ze8 Ғn anQ%%`#lǰ=aZa]!%p!! e&;AF^mm~)b q^>BE4cHu`z%v_8#o@s i5X2Va %N !oEd.*$g?*+):$ 0W/ _/LP8I #_Y. 1urb$ /$$% K'0K$L5*Ll<_0HlGtG |4 Rm \&=7 }qC$M`@ DPB >QD-^ĘQA&J'ĿPF-]JO@e ʘ=}TPEnKI4bTԋ(P܀@O~VXe :i¬1Oӕ+I:5iVޚ3 HxnAWbƍ0?a?,L:P%^m: +}HWB(Ȁ@YeG\f[2}O%$ (@;>UI0pU@v <(8/@$0(:FfAk+8@kS@ CH(,2b 0Fg #hzp #h  "' p:PI#2K-KS3@-Ƣl(gN:ij)$l sPEe4D32DhE,1,RQGeHG1´!8-p!0zT.LV_RFV] =%4U7H5l]PH)(ׇ,g T!5 ,]!݆'|H_2q5_ xY-kL z Ghd &rhX Pty:V "Ha<0H8v ݄`PJFfnc'EG/vkԴt,B!R#v҉!_ͬ!g~ 2e j"qBTw φf( ,^m:̩S Xc$;ZxAC% H':v z/khjo"zh\$ڠrVvՈfrUޠSǃo60w8>Ӄbs\~'hR}ٓ"{^6 cz}L<>l+x)^At*ik!G? \E0>@El l@$Y*e(ZPaAZ.)!$[2P=cRln# t<%۾PP! R]ITe,r!D':0DF:NDRXl@H HJ}h+?dUUu$R2ƆP,%'I"AJR+e(EI7QZI”%"A /Kb+/=R!BKb, y y%9 iCI~%z Cfs 5j29r b}P1l&"_tQȷp$p$!F/!0"GJ\&',& 'Cde8#/BiN}C"$ O԰ЅN9--&d 7H"*D(UOFE;gLnrT*C@d )NA. SfAZςxLx Q @ " H !D$)J%DY~WDD !2DMN [_:ҮVV:Λ^z<;1!LM@%dX6F h@VBts @|J0(IˋyU i }{`lXrߧx%AJ@aD^S 0 ^T; K ȅav$d#d;&wPx ߱bx1C,xr0MGqf. gOq5d E'D9aekMr Fr ?z7x"h|yN^sMdPl"5sp!J5ldӋFu 9C.Fq`ŴfH; ~̣49NmIд1 _U7@e1@h =琅1A z >pM2m 4Aahk?~Io ;1>p.[&ގ7!~R C8Apw/E>\zK(@ࣥ_ڞ З)@u3-|LHR| (:uR7$JyY0.} "Wd&0h3}JN`/$#%9š]*ޡ{u@xYwzgeu"Co_+@CT7V8"#dW'Rw#!$fN Ex,8bH(? B XWA$}ŠrƔ34@fOE^i MP3IKou@YnB:݋<BaȃA0ixx (@< "؟#ںл~@ xC#9c:>1??R@~l8`@,\< 9ʞ0 0 :@y˜ x  #a+Ȁ3! <lÆ"!1tP@`` x „`(aBx-ړ @ёY$\E#1; P 8A)`:,)`Fj+ jȏ D،6!\-I8 3d( /[@,BZ$\!,18u[>EMQ Hd\ 8`a|ڼft? *XÄU&#΅8J8pD#MH ȄЇVu$ņP"EuPUlP6A OdT2ݍWUH8 XG\*b@?9`r rЅԄP妄8xM!N 8TsX< 8 a5с%pD=؁(x8;!>ZpHPUp pYX7]ZBĹRj dLYx# LQJKZŻT:<#\أh:W7:D0]VH)8I\ڑ^rΕ#e ݘKb25&#ECO ɍxN[ m޺Xp@GUɁ0IܼFr%1 t1ނ׌O5"O!p P u;WՁ0﵈ Y]_Ja҂`C HX0T%NBՅ@ŁpNY$MQxS,E`"azaL5lȯDʓȒx؄Zxo]<" 8Zs0<0k(xSXԌh.!-8=B0 WO2L¨|ea+a@{ 0lhaGcئ`Ҩ /ؘd/ 8'J6 ﺈ8o/٨H$YаmXDWȄ[r+35F;kX0(؁ =LeDWOȀ$Hp Z nR y!΄-Rʴ`!QJ0sVZǃ)e"ց kU+M a0ND|~7<WHSP6ʹ9%4Y8kБ%ʘ(I4 9N;?.2hH?ǧyh`jT̑@#@ xj.x# (K"Hp PNHD=]~:4b8O"\2Z ذVoh`ȘeASPVWDHnITE3x@ Fa؏ Z4Opǝ.5 1ZB%xKԨ :-Mtk[ DOpxRr;w[W&Wy X?}&BNIF,׎uOW `a`zKἐ3.SASQ&m>.4lP#-Xx7Ba&FBE# %kdXpTun(Y j Ad|<41Ơ(ڷsF㫲C7#Uq5I˥o0);@@V +-=URIQdwJ8!!t}}5Cq[$FQV?:p 6?8,LT8$EL 25x@QYD\"NPEBkT@ PS#D0@&L0!0mLKF,!LJNAQ/UzQtA<*tCG:*RTBLT&H$8qDx?2Ce $E9L,钠M?EK @rl-1S#y2٠Pnpv iэaKs?/{7ϓ'e_LI;\Ka0*Fa5WF<3l˯}BEcYs'S(G&H@̓3K$j Rga1PN9Cxa57ia=vTR4?K@wc=4S@Lb*:B D4M7"55Ed@$ 1Q%}D@90&81Kp̌>?]0uA_U -( u Jd;!k50C/H_Tq-y#e0(W' x!ebE ~!1-V {-Fi1N'+EcцL0 v 8H:E1}!{ĤȦpr.aĩ1Aځ_1 莓)6;olm)G6~5Onp([H҆d( H2 !0';$h0xG`r%t',2FB(FN(V^( zb(vR}z( ?و~yL B |%gXRXia3Et@L04+MCE E@C♗?C F,ds W'EܞBUn)VuKVd،e@LO@8D)ޙ/?0gTϿ9$BLK6DAeh6*蘒z y`C@઀4FdB[rD '6>+ .ȘuafSjP`?)D=}DI*m +PV C:5f 4\I*> eCłX73~c?y(IiB"PM<ɝpǼDfʔ`HdM6Bh@m @JYT6̃BWb+q?5ϖv\E,0@ 1L6|/ r)I4¶?tW*Ĭ-NFgڌs& Nf2Htk↮q X|҇B.붮.Ʈ.֮...Ȝ*/Rtg=ȣ2oV@Q"(VƑEzʫx,6/%$DSyȐQQdn 3c?*P{DxhP@jV*0Ânm]6.f8Q|N%L]B͊ ğXkn8(yDUR2,t+t=Y5CIō=D=$Al?hE,@u5@_ Dψ 0VdUs+*IoĽGL Dc:?W\@LaJDqu%vlrr){^y)-K-2qp+5BdN96H2y.JSH-FtHrE,BJ,?,{?HAC|ČG?wG Wws_?AI~Tw=۔D@ !RԇW+ND!w?;F?TmȢT򫧦@ċOİ?YQ]{/@8`A, `0 <[|p @ xaZPˆ*_Œ (ɌD2豩CAQ U1pC#T4AeCa\ F P1nQT5 R$@q]XfZ(􍸎A;$ERUM=6Gjv;wԼw-7Ņ2,*N2Zԟ}cP A"PB2DNK0P:_<T/vH%zHHLR%l'R)4С R- ! ,3R H*\ȰÇ#JHŋ3jܨ Ǐ CIɓ(S\ɲ\ʜI͛8sܩ@@ JѣH*]ʴӧPY.3իXjʵׯ`Êz`ٳhӪڷpʝKݻx˷߿ LÈkǐ#KL˘3k̹ϠCMӨS^ͺװc˞M۸sͻ Nȓ+_μУKNسkνËOӫ_Ͼ}s㯆­(G& 6F(Vhfv ($h(,0(4h8= totalHeight { return 0, 0, 0 } // If we don't overwrite the background, we use the default color. if maintainBackground { style = style.Background(tcell.ColorDefault) } // Skip beginning and measure width. var ( state *stepState textWidth int ) str := text for len(str) > 0 { _, str, state = step(str, state, stepOptionsStyle) if skipWidth > 0 { skipWidth -= state.Width() if skipWidth <= 0 { text = str style = state.Style() } start += state.GrossLength() } else { textWidth += state.Width() } } // Reduce all alignments to AlignLeft. if align == AlignRight { // Chop off characters on the left until it fits. state = nil for len(text) > 0 && textWidth > maxWidth { _, text, state = step(text, state, stepOptionsStyle) textWidth -= state.Width() start += state.GrossLength() style = state.Style() } x, maxWidth = x+maxWidth-textWidth, textWidth } else if align == AlignCenter { // Chop off characters on the left until it fits. state = nil subtracted := (textWidth - maxWidth) / 2 for len(text) > 0 && subtracted > 0 { _, text, state = step(text, state, stepOptionsStyle) subtracted -= state.Width() textWidth -= state.Width() start += state.GrossLength() style = state.Style() } if textWidth < maxWidth { x, maxWidth = x+maxWidth/2-textWidth/2, textWidth } } // Draw left-aligned text. end = start rightBorder := x + maxWidth state = &stepState{ unisegState: -1, style: style, } for len(text) > 0 && x < rightBorder && x < totalWidth { var c string c, text, state = step(text, state, stepOptionsStyle) if c == "" { break // We don't care about the style at the end. } width := state.Width() if width > 0 { finalStyle := state.Style() if maintainBackground { _, backgroundColor, _ := finalStyle.Decompose() if backgroundColor == tcell.ColorDefault { _, _, existingStyle, _ := screen.GetContent(x, y) _, background, _ := existingStyle.Decompose() finalStyle = finalStyle.Background(background) } } for offset := width - 1; offset >= 0; offset-- { // To avoid undesired effects, we populate all cells. runes := []rune(c) if offset == 0 { screen.SetContent(x+offset, y, runes[0], runes[1:], finalStyle) } else { screen.SetContent(x+offset, y, ' ', nil, finalStyle) } } } x += width end += state.GrossLength() printedWidth += width } return } // PrintSimple prints white text to the screen at the given position. func PrintSimple(screen tcell.Screen, text string, x, y int) { Print(screen, text, x, y, math.MaxInt32, AlignLeft, Styles.PrimaryTextColor) }

smbFsE,aއBj,UiPmАQV2А[HC(w4 ysԭ[N^h)_,6_Ƿ4\c/џC[|+gW=`HPA'IZK@|Kd j V5 DcXOJS.6JI,lIp ԇHHo~ c L!ϗ ԟh+e"Sup8J+:&P*GCL3!r 2 Fgy$5b&cE6Ҽ~oDF0-e60*Gvצϗy = WHٱИY .̯֥^嘆׌ yǞaBZ֨1p~)֍k6lQP]6do@賰`OYbԘVӞ4"ـG0ǨMa ө)[gʎ-9eرq`&s =7/ fd7dm5|@;٨.LU!2MRdB:ݕ$UVXq`lwNv--#ɿ-3&Vͨ٠`kXFmMbwŠ8+i6C8i/Զn/svbQp/Bm9"-4cEk{?4f=ݎݗNǷl-vw3Z l\Ĕ(E/ҽ1@{0?6i78[}p``t:]3*c-ڜ Sv{(`=t~BK"AÀCqO\G*a¤ '8u|(bcdgy*D@zZ1GwhLR[ {ap6ҕ:mfA2N=s*[s:24:{-LԖ)BhR7z,dmcN#b{ٜzfT*<=zyՍ;3Y#9oe0M=FaL @0(,ܸ4"XNZ \a`C[ΌP'&t{Zъq9dUXr(*ml_u)nmm6剆@kwB|WG`,9"ڤę1v`,Y!сcn/{0TW,#\=B_R .Nߤ . đ% ns9c=|N4 RxH۱“2(1/ևbL*[Z=s^HM:PI"RD6nPПbg4+pl֔>ĺ&fh0հt E:ASv }P棈H^?FitOoSD5۩I&SV-ЅX0bnM37*][(¬!70L-# ̅$QA>z/h|=IAMԣVh3oz–Ԙt[DCc΀>I8_t0ϭ:O-'"⻹_CjzfM8hB2ʹ 7U3]Вi2-O%^\b/>NQSi=Þt2d}90풒iʭ)GR"5`iMԍ̕TrOY~i930f O͔gZrLG1鰌ېN ! 1AWQD@>>> Lp!tZ c:JNE?yVt 5Cj>lx;.cP*Fr0}5 b\wj^(*4?jbI}&~FIC|Л2Zbp)1/:r7'3v<RT~]&a_ V;!/ ꀏ|rsXcu\ӑo8yO?݇O}C 5b4"@׾ ?R߂ۑs7 N2l whbODC4z'$a˨}W9383⾎eSpzNmr0 齿33u GE +}?O=|'A8P,+(ڞ-Cz_=P#gP\9 thJ* ˵hBdl6|vʗA!|FeH[+ 0}QP&ш|Nbky7[>/gh%_#q$M0FEd]&2X$.~醔_5O:5|BU닃n1ëkl! bl CboF}VO0|92s= VZ _Dj'F3)BD %!k9,b$Ͽ2LHc$>&"`S%R4S=g$k!t@=B+qf̋XyN|$߄O o<[C8@"B#?)R{38?@"Fӱj9eJ!4{9DиТ1X= bMg?9{0n敯zTҐP'_ħm1P?jLnK)498G 8)R؝?}}ުHao[Rn_UESXl~9(ɖGڕjnT6  3X)SqMAv}FDX[Wh4$P[ŦQh׍3o/syRt.3 ԛt'aUB6H.𩏋+wkJzQ)-@u܄Ft-jeK: >j\(BѨ?\wܨBkJS̘XMǼEYBC.>ԙ#!268hu]BCN B\"T\6 Ṟ=X1[:C:xLEf5/$A2Њ2N|/6hȎAvDc͋:e}œ%'k2]јs|lU.7c:z+$FAUe5F ƅn6ʄ [lm|.gғ2MrG!㗆ۅ!jĀ[=NISt%&ri>8#MA,[R׼Fm\nR$WDO+6޵:KC|BJcR&5zƭFR) +Aj-U,xCۖ@ч>nk'e:䦈?P$=x 1j cN4v} gw)ВVȱ쪉^ȖD)f%M#1\Y+ӊ-#dHtW:q>67ă_Ӂccy2T92.!Yт/ yRYߢA$caє,Kx|+W1r̜Xr!_S&p%רgnEykQ]^Az-( Eex4滅^wH-q#W\. ROMl gJ6ͮ1GO2IDtn?a}G)r,eԧ gC'rzu m r*ͣCKj9-vYH%pֳcb!|)9}d3ײ֊0s僐LQj- QfJNIJϤ:SζwZh-^3|I|A$3GJ s9cM1rJcnt\* ^`*s,|u,}B2*w@:H‹5 Hv<۔Z, !ZF.@zx%#iTۣ=ǒWc%Z$B^ƪa,VL5b C% E2=Qf⇞\36"Qf)&)h 6*/Մ?Lh`sy^lIQ򞶹 R˘cQ#l"4  c}1_R6EJ-@RILZᶸڤ\%jԦdZU`W_lS)Oz򓝰 βK-uJX$SZ{~ oLC\\,/pߩzqnk:SM⋀A-d1Vlގ8p ˊp^aU׌y_hstYmSDzCc5[y٪p,X9S{v]$*SdžAV+ g'^v?24 LX:GN I(=xRyJ%n;9jJ,qLOAIPQ&qrU4EϪIUS8B/`VyA^;eH› |.Wz, 𰍄Ol8mAubv h¿*g~ R5W0g(V&kGK3[) nl\a -`r6W%񛏘©L<ybDk^_l]zv/醦Y9+j X]Ą9IFb$ko`Tzi~:U]4Rrl @:س'VC@? +cnng+OpFE)W8L+8, TH jxL^$M`Cݵ4Al/B2]צGHЈb\T-%K%%-OcqULDڌVz헾%YKDř}fgpF$WpS^ 5->-R̐dkw)ȱˍ {cruK!>iX`^`L8+O77e^yf_S{yxm=F2U6B=vT,mXbʔ5$X3)D*ۺ)܆4 (RPC~9#YMKe1oz|4DV9pIL`B)N[(WXv[hl*X۬됬t#s0$n; - G?Qoz,+oҀZ\%|&Vhdn")[,_eZX[83gDEmAXK.aV2VVk Vi7A2jo[飋7g] "q,GmG pԞ<>(3/W%6l|N (zn7'!XWK8Ͷ4YXbNM%T=Y[5~~!&ZmFbL~SIB; ->=- jƢ,^L d4X=nc)5@0b%/qt֡Xi\/aC.2 &J7#3gk͉E0SHXb&PLeO9R THhmJΛu()UoGpQ_Ȯ*9J+P0^ }Ymm1ɿ1|2=tHdP$5unmcEpTh Kއx!le\ˠ1\/i HJ;`0qD(Rg:,'Mjb'pv'I.ӏ! )Hr Pꐕ~ճ ůg0˪n&*"]K0?ZbHΝ| kZSqdU}XkI%eLh%LJP1a23Ԣ&zC}5\&Qy ʮ;xéDBO^,))7z8Y W9G"FR4mLԠ18 sH(њN[ #"t#SO][L'\5LF_Pf\5+h䈑_ 0H45uQcjD$%a?D$4{f,u PlS>1tr KJ&qo, ,R xOq&()UR(KHsh*fd14 'I1EHl%50Aht`8]]، pG:=[}By^& ̄,>57' D '{d٪ @cSVەO6r'iA>Wmdyc&dŧ80H0-o}x5[e aLO7={Al{FhQz wҜ4B:Mim٠uq]r}u-y?iGSJ|K ۱%m{%>.z#ˣrzAD3K9 Mm+e,fh{ٌ}`O@u6i[^J(<h?S8 DU%C>Civ_D]f*SЭZ/JѧG  oӝaan03´QmShFL3n; [-#Gj@g䌁nUUG͈ Σ<3smP9Y^l:-253>@:5Z8fL8;eE8Qtj!Cv'TNM0FVd7[Z`+%C6.XU@&nn\ʤ.*0l&;̝MH槃`iΣrZSa Xjvh55VJ  =-. !BYyC7* V8+8pr`@H^q`ŁV8XC/+8G VVXq`ŁCρU>2Xa+8pr`@H^q`ŁV8XC/+8G VVXq`ŁCρU>2Xa+8pr`@H^q`ŁV8XC/+8G VVXq`ŁCρU>2Xa+8prS!rZ7+VhOYw_\@+VXqf[e]}^_ <8 DV8͐־|SWozӛny[{öA [nC-V4M8$4&/8Jr'cg=Y{ ?cZ>>W@96fޤgqWқ"-ۺ;v\cK5N<;N\s{)+r)l(Jw ?M=7x؁̦8cٶmu]7#ֽ=Pʐ&w e/=C:ꫯ' yn߾}O)2aO}] ~ 5K6C!'pUW]]6f{O|Wkٲ[\ ?[>kSnl\V)]nrm:I/+8\GPr 5QԐe \j #R6/mo{[V<5dfNst,_vY3Y>jd2))r}6sV+5$&gЇ>|@hp;lN:I/9vfcϛ `m ?n˖{Ŏ-O:O;$Mq!{2y1fb~׾/]WXҗE/zѿ_Eُ\M C~&`#1S>Us0v{oo~bK,6|~^򗓈Y>NwꩧZ,_!~g}%yMKM/2a6dz8[xCjD0X,ƆnIgC?z׻s532Yv˩:}og fD_;r-6 'nzَ>V_rڭݱ}ˇ-ٱe2ͯT>Ą<-Fv+)3jL5-df6/Ϩ b0qpN̮&観r2E88`G~{]:bS$n&5Mf3Tpjp饗~|\b? O e6e}f.i: `py+,b~M Jӹ3<}m}zv 6y;ޑ@g s5T4 ~; G;2l Slh!՘z *a>B nWg`ƙGW?3?SH;Eb9X+*\M C??VmI`œ,ΧXke)8SܥmfN{$ YܐDL(vhJWN>M>.u}ܸnlnu0x\];$^ۻք5kap׶mNK<1Feu )إCԧθH{O"ȃPG77j$g (QWWV,u7/r8#5ϲ_^Ҥ3?0iJ$/hc M 1u-6(h5H&We`]aRMܓZ5ݑl8L-6ǯ̂:UoVdl|rhL9pHOb ?80A0`ź#`@ͨ3}R*Q.)`(}SJ LG۾!>弲 U^j [ CpvY`B2 ]O[5@Y+>5 Lf7鰚:{0H؟??y{ۋ.ȭW?L aHӁ2OoeM 7ͣ5d uz;_6ߩN=ụuS{]Ok;,9޾?-?3?3,(n?#?bCmדɳk˦ T"r>t޼Va˘֏2ڇ ~\ex`,PAeS}32_Aq f0b(g؅r|22fjf:LI3*|_rnw<e#: iT8Li!)>`GN*Oy87PQ? 32 |c!<5G?Qa.'}jw`-u,$v &%cR24|Œ&a:p^(7r>~-2[gp`}k7>HDʯeā(mUZ .w ~9Lj// H?V*nQۺ5`__<2bjN, oxVG}l ==93! \.rk"|КL1{!3b{ 1zIo9s&(>C! IcpEtIRB!BwV[d+RPfxh,Y!mT__n^*'>!8L|8X4E95h pS`(]EJa``8q@sTҍ=iRی ,[Yg";0??6V"{o&\D$Ч<)hy[?$h7V̷U_UV# %߮ޑ)>Coo"? ،G_E|K^B}4$MxԂ iv ygkX*Kr4xƝ8$>M:/puS[YpL;{?(|i-z6:ݱ뮿ƝGA}g O /☣~o=;;vx@' θGxߵ=yk[gZ}j;G@BQU."qW\SW]Qs"PH`]ZY8HǸ}zߛ~823mt҄Boi ub[r$_f $9Q?tu3duJ(hYH0J2=pS2R}F4SLwe/{{>\E#.%I*f#)'Qe˹;4=ʯJvZk"&>G8-eo׿"zCKnme^|q`ԼC8\`<@jh#TA >@aHUH%%pC/$ei^!MI$po|#&r3=QXv!$a EnL@t}.uYBh͔0s-J?7? y#!@>[I뻾+Vc/$ p0פLu?ڨ/.o{ a!-Gb%!{4WH3x3;Zc7[NCe{.\Ev$+ W9JY,('L>޽햕?>7M7 M ܡEb(1%8()g13S12#с$^UfD eD#(Ȁ bE\g~߹5 souyֳ\^{m Vyaee $Y-š[6Pݖ+Dў,MڼV5Z^)5*'! x"e"؎ -mp [6c0~n'3jJsb )_<*c{<,4LЦRtNGb]^.5Qy/~t ܵ-{8m eR$ϚG!-]t//.6",P6]6_Z\Di]h./T=D6Q'_N<b0`*GL~yDu-qD@O"4pY nA"-}q% M_R/vbB]XcKö.6!j&Mжh +^ @N6*bQt aSfhL#ȚDVqiXܙiWEbϤ͔6Ntv띔z`J k7LN% H-5 Wm 0,ș\!?Wn~˷| D Zh%xOc{bJɫsxf`}f,)lnuFTV&$4{K|=Hg3")t0^(nX{NP[}Ԏ#{Nn5j߈SmGX"3OeznRJ/x GH9BCiWVϺ5.sުuL"BkbH3h4~G@̃/R 5+b;q7j97?Bi+,4#\6!)B92DGM  &NfS_85て5m6rHGLUYBfg34"TcQC->T+jXÁ*"`Cϡ|0񲗽 |+Xqh׌%4G26S֯|'e +q@<)K_Ղp]2۵H,3"4} &oZ`xɻ$t[nkYCkS҉MM!ZKz &=h xf$7pPa.d !©dX&i 8DF?k_|~=8aHͷm\q{[Ϻs T5ANr~ٳ. hߓO=Y 1G:h5oҼRcμPg9LB:,!x#Z #* h "~,^A|Mh|U"TȜu#, TbԊy L Dx . GLN9/o$:wEQF>yX}ʓly3a\aK+%s3 Չ.|hh[ZcphήA j>iO#/NlskCW)z&BJP#!h0~6I, [ot<:gbgܜ6%̈JMxjUHN 7K@FMUʖSZ$iuX +B%b LJW+ ( ;nIv]e79*:]x]y^A c َt:A.rP݆9H[8I@a,FӱEB*K \7 N?B8|h!~:U"N##b|j TfP-=P-H[ΩDa.T8: n3z vzի^*^>\At0(Z /%#MZA[݇l2,_:Rdfia e3(/rڤ{.?{vX}D`QeUĵDH10Vywn˞)Xݐ- 4R8`F.j%Srgm-|H""_lE20 =9X)1`C ̡G-T*ˢ w~okՏ=~/.6/;_ګXtN[ܯa$Hm,A8aبҵlʦU7-k~"-\LT45Q䳂n=Ho=b-tp`Dͩ) n4~ T-\h5.^a)mBV87M;d "@ 1KiVG5Ş 0[~q#-O=pN+HG@O"bNz0UG=rݎlbpLi@~ь3[#pJjk8306|n&ml PkE)lRaG/lHD#FQh,_'DXsWIkR!XVED+WMEa Hjc!S\}>8L-GՄ#^G^qy{~Chݛ?[w}bh~cOk|E{O/?`_Azv{$%l*fYIe8L[ڝ|R50N^9);j$0|RCfP#7XR`mFZe:RV {y/1 C!8P^0,.-DQ shroOTl16^cA;~Q )rE8-=xx"I9 ^Ak1y&DsE!xck2ydǍY]@ $y""@0'M^PT0)mt]6*FzBh[G.p=}mb,ZHՋmCMES "0FbL|n8bfkT(FGßNkAjymiHQ*SS>iw BY;Ҭ&Sj-gZn!N#H01^>2$T H%8F3 H'v$pZn[35Gwű\iQOc:MUh\3B, cKCJ?SMjd R"έ;|09PV> 9@.DM s/ {H}U_ƐH,etNpZ ` ;=v\[p{hSե{z<ʓχ/ώFD g{w7s,E_|iȈ}J H&F &sMii Z@8!XݸP2oBCI[qMlo) ln9dncj-U7@ &fTa0xR]54D"ւB <~4Ask"S>  Bj55(AGDd ]E;=CLM[ߦVhGdS2PuFnF\㼡"=no賡3B%'؎#UT! `EFLWk Õ/Z9HN#Td]|m+jilVn(Z3YR9as'pjȲjEZvycXXqM,&a" >gGvV:&ڱ^vu\Xˏ Z{yB=J%MLq{tJY]FԳ^:=dzӃ "0Ӝ!T[y(c~^h sЈ/*C*''\Zי̗$o9&L{ɉuE}Ϩtj՜1M<0ȧ O}VkdbFa=r/y vÝuÿҎ9—0OYL6r0ݻzLuqXOc{7)cE^::CR0DCI/@U3Ƙ+ِ Y_nE,'7/񚛟q^pOY6I¼IwRՓo:$q(#i[LONFI.jTa-su6}W賾`^ۺU񤿧M^t/iu'zn=NuiS^E֑ZsvM!=괹6}j(AcUvl#RG;; [Jj_ٮݴ=:g &ִ)6.hj"u`^|ֲbΝ*(5񚳋kϞRV=qM 5& T;ݸ:ByW*6[1_u`Ó*T_ FV3 Xk5;]d*ឣ-K#AEAi!dɱpctcx34$"$6j#yѣLZ9^++Mo%D$ѡ|r.hiTEɖT6vI&t )5=Jw 9g\X9ߎK0m9y)7Gc.yoOqx.Uڷ{>|t-U~ acw`*ˤ7 J&&*P=7D톩¸QNL#wAv ݀0KX9u}C#`7?fxdY?4._}ӱCp.3رe@!0"x-4*/!½[ԅ9՞v [ J2 Wk[:LWT\ 0n oBbuJ4fpS8~uMZ6pįOZ&1@'B# y'pd'3@Ũ жeC+5Xt!U(E ӷap|*F8ͭyi3Rv?\Μ 0RJdz;KّFb1L0 }繏%:@:':gcհ]ͿV}C\b= $˄Ϭh䰸"5Y-RM#<2鮸sVm4A瑿Dؚqk("fMj.f>/N waz5x}WS jgdIbx`L"9=FZ3>*&)Ό2)ڮŚ_WFw-#a,$(r|+ c2$ڒLN?˟)iV'&TMx a檰Tb;mƐX9m>SXGY~Qv u@d?)ln)^%{*qW ɂksӛ#j߼3JatCZF&#"7MPb<Qf\igFrHɿoO 'jj]D:QvZ+oLFe]qZ$'LmQ=#.pl&S =R_*s=`k y–'!yT 5ȵ;fJ@a֧hX%c}(!J(ETL94E2aZz򖷼>3& V7@ oxH#9];Rc}+tہPt t$V[H-Aa&]a/.u@$I"cAbTzc Ÿ#Ԛ8+TGKI,4HoxaRSc݌a;ye\g̮JLLhݯѯ:ҢǔuI5;V(_W*r_3-L:}j?]3%: Kp2's>^>kUM}&WfG3[('al6R$UD]{ehR0pWƂFAX܏88u:6SAV!T4B#arJ:L3L]EQεs;: q Q_QpS |`NaȜ>~ ^zt<vц)9%g\/ӮSi׽bqOcO폿?7!q05R.# 51 4:VԔq4t$=W7.J1 YE[N{Œ> o|uȇz-Rœ}텋X7<_|<%o= 'ӯGd?kE%OC KL3D fԺR 2Vwbx;L < Z5{:F(z&Js Q*{')bE2IY>qEx LPn M]M)spnk2NQZQbIaNVff6bXKsCW:y }=fY I4jJhlb!+FRP269Ҧu15>}3ljE$37q!RfT@̳t L;,6ؤ+Fn?{NC2'<5|_S'8Mptnzut~u d- 䯷Z\1|+v.d'Fz|-E}=x&&|zm )ؐn͆K6Óu3I_Wa\ {-9#b0l mx__ā>L)ޠA~>uA^0+5K M!Ÿʴ&%,,ON@pթmv]$KIj+AM!ЗNu:b {E#nl[̢<&jq ]1NJק U)Na)UϢb?`dȗpE=@)K L#G|SCEؑٮs6gU+$fj裣ٹ w!1!NG oa>Ĭ*[dA}.&oiڐ`*8uKAkDi¯I6V)eu9&W7|~[~n)TZ0}qL" F27v5x~i׽b?gNgy/^VcE~,߾.P %Yro \lfᴰ%ikA KM96™G؇-ߨH +J31Op1I K#f!ul]NT؊VCE uBπ#{]py3|yqe}o{ȅ/r3,Hv?^ABpF"O崢&!QME9GK_,!Rٵ6dholzia4$D޴\n-'RztO`R\̛6I4q(]QXbEC*nh\:/mt;>V,pUm:&))`NaEm,ro{Af:3O#d itX7_ |! _^"ҭ &@ZdU[?cS.b>D ? gJ5rEF$-q*Š|^BWdڌN WF )!_x8iH^\,b!xWC d8j-8dq!V+P~F]K *RG|@6KנA&@[[_0b B[*4&l>j׆0w[t3H7SzBPl4iʬcKX+:-$EMMoQ7#6ww/7?Ma VMo;zL{r<鯺~}}rJb9ā-LA۸0Ry@}K[AdSctrRҹd%h)GI`'i(yoP<@m_hkV@{ѣ}J3/=_]]uS.~?y{6<0<\M MYzNPs_=!w~w%Lc6AЖ𢋞'eBvs-,ڔiR}g#bVOv'D$!~+`Ndt) WX̓VXf q%SE=`6jLVT\:xuVMAI}fhJBaqo]vt1[/&IҨ  m@h`a}9li62e×ݚ h}=Խ&uu0ϢPj/7gcPt̜4a~ͨ Sʔl JhabcXݵA4ʏjoR9k8LC`=+VsOr 0+㹯:WMͅL˹G5N΀61 m*Ԗ2r &_#wMQml?YWJPčn ɈP}.D \:mMLu)**'StZa"F^3_2dp|4iGiˇz!ZM!VCs~9u4:L~vX*̀ Q~Ev0d! g-sa>X}:2(r?N JW@瓅A\|&kqb2\ C47g~%# ӡNt%d.ƋN+J}Z`U͋™<Ԑ@1Ky!qJ7qMI7ޠHK+j|%d{hb 8pφK6e+\5SfMׅzP} ӄpKo Z>u|'/*_I[oc7ʏ=?q'/|ErS٬.CsWe}k' lOIB? I9@U9=hՓ4X™-v _#5L%y̿$f [п뻾}y=ZS[|= =hNQR{yPs#4faam1%D)fg_OzpN33&#XJydE`BJO]M+\@~gQQ꼍hoSD^|u1~NGF N-u:$_4ss{ {UBmrC9kM rL*x5PzJtcDΈ;߁-|Yۑ?aVA>&i:S 5FCM$X*W(1#{4mG2a :Δz dT Xɴ׈m~._>Ơm@I150[F|{tbVl]v]e66X߭ud2Eyi5q;0`T6h +u4vsb,ys[D@7g)tb'_FA( xh~C!m(6X2-9Z)t&T10= h-6CBcy݀o^ib]A:$"c!pZmH1l!nPZ1B!=ZIoVѪF5GqMChiS+2C5M+`k#k qGD,=fM( 1?<c QMhT.æs:.dtCSQ\)=}> !-)"hr i(mתi#=ȨȄJ38*YcP$'{ɬ"6H|y,=*j4Mc .֭u:k+JPCi;Tiܲ rb`y!ў['EAB7?~ce7["t'aJƺ-SP'au5EzqրO:qw: ă!47Jߦk ?9ufvX!S4 H:1 8 `U0QOtFƭU'@)3̀w[,HN&z?k[35[P-R#ʌ^egSM5:neXsc:kLt;AOܠhVd)#9lu]QsPV δB3"j5+=EX+HLp.gt p3miMQ ն:H{Lp;kvF)t̀wֵr4E`%S!s:-8* n5\,3Ta;HUV60ج-Ⱦ:eYiit@zV6h5kJ#D1wK`'3S9"Mmr;uJw[dfW -o!0*s^zVtN+S?n!EJ޺VWNîb;ѣk3M+$a;P6oeJ5)ۍt֭)i C@"{z5U @Ġٽ=#l:tJ<xxP4(г̖ֆ4ri|n:˳3{8Ƴn Fae=9'Ӏdv e;EUsmWs>"{$7$>#n紋9"K+@rڣ{Z \MUf,QoU3cqԊttLgEk1՝Cwlu&X_B5\iw4| U?7™OD35j{r @NSĆ?%vN>> vs[&)ځo.' $igrܞM78a3Xu7(+曛8tc} <g}~`z£K>D+V!!A0BS̉PsģO\Ӆ| BS4G,P+bX|8*@MINVvJ@dI[ sCrR_mZ _B޸rfCBssQA;J=ygt1k2~f|4V'?ݶիpVsj$cI7(Uh=<_x?]o>a%63w9>[=~Ϟ/\ޮi~"FݪC3z3kƐ)%K+Q9 #xEZ bTK@֩[*۫7VpxK8dT۰Q Car^~mGiI[`i:XQ4M29-iz@@.sd+mo_MhH2 6Hr6$S)٧0\t(e v ר3&N""oPCr9Pc 2Y&~SƓ>mPXH,4 lmJ8]ᚌ^Ї>IJsSnrk$بg hvtXf ߨ=m:S~rl@pj5m;93OIDNܥOP53ie_d.52%*ݣDtvFa*5Jwߌn3S_?W!>fdMӚ&4u1qZaTSP#=g7?tiH}{|R-[xvj>sB:81Ɣm|>}"V$b8ޥ9p43*&.cH;Ʌxʛ>1c3X4)c//3߬-Oޠ[R"r|^у7HffEjRNR`?/SP@WS H{e s!qi\O$uOM~Pw^# LQXu6'2L`_#~`}20/2,vٍVt²mrh0r|_m:\KQpP>zN]Jh#΢1Xy{<4s#޼8yItb TCM7 BU0L`umہLMC0CF59@[{PCd:cKg @h-;RSA lZ!/I dA ;/%B<=鰚j6=:qEN«0 ȋU_P :J)6# tȊ't}kP/&i}>^ Q m@%xi6w0CK\^Մ ^@9]xMȨLd\\Vj^&#{Fڤ}8[3HIe؆ʾ ֌lfօai@Cv^Y1CBؔ@[u}Ł_,0/x=G?z_D䗡Uw|ho<<{Z,&M]y{u띿v=g_QԸޥvy1:^WǯêФqD Dp)sG{EZlb? |̤ 8z#N!+?w5J,a|L]NS0tR(A&QQ3JI8>:umu'yN-  Ǐ[bUA,+A=p 2{1JyC}sC,IfzYܚ%wzst$5(o -P_@[0K7<9 ۊ%n5:廹QjޙR8n]Aݲ|bJYu~fy.nvʠF=! qSa~44)~Sօ&h( XM J Ӽ2 0-ͩX,J"clFWS՜*ΤedVq|7v4.$5%.A+FD"kPa!ުxٗݲU  i})Ų4`0jeͶgTyLePC5a"je G*̌aMwEG>½`GF!N)GG#(@:b~-g}w7K ̕έc,.jI!` thQ:rTߞSpNstihhT%`')^LR,"'SMRjM8XW$~7c! EXHuں8oV3|mC@Z*5׆td`x )2 ^LESSFzZ_k8ӥeœ~qːt@4E=O:%__ט-MO{OQ` Uos2S0|)HtܒV J #\֛,0OJ}:EF:!Oygj} 褕@XTACVr](+JXKgkY?Us px҆h7N<#>}t才QP71 $Aɚ #]#E>x[𧟷 o1>oU+Ѱ8g}[_X 0ZTq(yni91ҙS3`jETQZu_}x[ Q߁`C[lvy̕C&Q* ZB4PS̞ѮUNEn3]zk*e_iWTôFUxe49\ ȤI șY&*o+ *P(FA&_L{,S\:L6.ԩda _Lwk;CO[Bj"7Ȋ[xhuY~AǚRAᅚoglBVj!/ن9\4L>1X$GPU 쪭Ҵg_ڤ+4fƙzTXA_kB^WR4#dM Ub2q SUl!iP&U"6tSDg wP`.ޛʸZ H5@h(Py1=^灟JiOV'8ѭ3]iِB7͓丢g*$+hKVcWb4e[ǁ2&J3;Ɩcx{ gVktXfPg K]*7Nw/gG=f^Ohįw-Ўw{tr~|gG^ :AG?I;8pDKy(Lp(j2ŭ4fvzC%YS,E4jqJ&,нExL{{iFPgK1\ Tc!W4%Hͦ5Z[l !pv/gVMGA&))OX:$껕ͺDA EZfk\Ļx$T4m0jΠm4, 9nCd }"ţl3u5ؔ&H @khщ0r*a:Wt gMC 5Rfd,\%I8af"~bґPZ[&4հa%q-mtT^|L)ڞYX\i be5) x#(΍w<~Bk6FlU&w(%f2 qYʝŠKԎw,+CK*T$UIdHxe>-ßN]Oyڀ[-$NdL >(NLXz:Ҧu@ۧ.O=ڳoW:xs$ܷG󑻏x=~?xomr۝q|+T$q*;.Ŕ Э` 4O#Q^@]m\:(yʁxz?[ /Õ{ L~Ib.PAp0V#=,7\+2lyKuQ1y[Qo3W6iR~R lgh̍ T}!Ҋ:H #=ha~I,a(& v6ayFˋ2e5SQݙk(6Ye}ntJ_=촰 aԡ^EZXtcx'+2 TG_e\&)ȿ#c}N+uim>Y/MBQ`+ɋ&3YG3I DXf2\Gh14(>Ʒ7=qZp=Z_hʳLaYP c}Rh B[T!غ52 ?Vq[.4X:a %b03+l^|o8."UܪGw1Cej1 [j 食d1d3kiooxةc}jejVuc9; nZCjU4ڋ5={n 5dH[>pݏAw;7c=?5c?߻,BC퍟|%UYE҆3)&K)P6d9>D|—Rek^us!5QR0FY@v YR0g!$sԬUt!j<v]@IDATG#Si5b6ʫ"E悆yR@>X#p Mo7gp3Ҥۑ`G; 9fDzm4,df9o2VPs4eZvhfT7pBu:M+]6r uY b 6hF%)BF"Y8ڒҪh&u:VdpS8߃JiQTHUYA[S1&g gQ)/w*1eZ4: sZym[ԙͧnBY>fC勪U"ɇSKgLh +}r|hXgUMsfhZI˧Ca+ny J]Q0$cj xA*k^jGĀ2)Q*GQ€Ѫ )acT`;he  Ő4ोoF ]XM`oa%h:d.@-:t= BBĎD/2QZ+@vNܢs"`[lk]5S BzDdV1\Æo҃lh?3>;~,Xpb1S>+o02aߎ3bB/=&6׵_O[9=~JX"mBZfbA.J,_ғ(\#SPGˬYkDX7Pa6Z˹tAclszκՋIL(v9$ ٺ;PS札p03+vW(l>lֽ jCnȟGH@Κt.::%cVӍ>l6tњҬEӜS)Q߮Mwg ͽnπ7RWYys 9eCHxs>ґӖ rSfn-ZG 9놐;,޺!\^;Y+}PxbdeR_~xȆL[uf=#:~t$V!x qx wb+ۗ9}Gj LacCq!+8=׿\`z촱n3xD{Ǥ`fEޛNKY5@'zbzq9wi foc6s $dy9^0+fR.A[3S.X[$Sv9)ZhMeNw2:rhO]*ݮSfNnyF `Ugn5\KQSw`:)@">R Zzڱa4E.EXz\ re__%BY]`qԂΩFCd\ m7k%8{YSڔ!vxF7զ4\;),R٭L9a{2\ SMDNB aׯ,OC2Cov )4Nl #9_]хjn҅N [©  1ؙ [$ٻ[D%+fMy64h4OH4 E&ABQ4"SDd W?~=wۿs9纺zg ]y G i.%Ͱ}YV >UY܌LAjipڂ15]2%wtYBH@;)|9BGi~mZ0u$(P!`P @%鳋^f} CS!3vk5BDf+zInd'xy:Z̷{H2ʘ<[R!`e#KIA_,DuJUM?;B@`j8H(< t'i4pJu |bhmoDȴlq6l# UW_X;ӠpJ[}1J.eOG NnltJvzBd|^`ma7򭢄)&m$7c|8{K7%^|@,? }S{S"ęĈL"5w)eIԵKy ֵjuoQJe[5j@ҒiEC pi˗3bD:\~bbϮ$ز-B-?5qe{QJ21F vD#}ܖuHwihmCt SA>L`+ǃ8J+K:ZW?{aszˉ$uR=V^h5mXcl |Ѕb']( Me"9hYL5ؽ .e^Mcal2IiL2ЈJNn乜Z H5?\Ý|.+`d-ҊDJtF下 C(ڭ@!Lwۢ3غ9@z d\Vt.H]v:Zsq9CQ3u֣G8 7\t[D'(OLԴa$ J~n@HSKפ'ԚʻQWhT op!nܕVK+Y s0g8uUR ]%LRʓ04ad3v]t^0mᣲrNcqS1CՒ̍:Ix,?\~9V0\#`kPq}ň)xғ"`G?#K5?Hn N8[Ԡ!BAe\M!}(`CL_l,u$ "N,sX漽6$]&@6Fn!E 5 BCr)f8n $p#ƄC` uAT e"a;2jF7`(2rޔݧ!c 9NZ?do1F7^HOp(Ϣ^ 5ǂߐAy@ 0g J4E(IAXQ4Q(7#cs& 1n K&`Q|AY9w+QHV`et.fr.t@`"z4.W1 U5 e ehUg%Gć-:jk6H)W+p;/#o@)n†:G; L[CJqS7WV 8l ]E`*"KԸ,FbhD0Iڑh%C1$ E8 eҘـxPaѥ- oX#QI+,| 4%-({/M]~Ľ3"hKLtQD>TJ%N~AP\+m tI onKd 6kȞ3n944FN#'򙹽ѥև1)[V(2gRˬw5 nAUá'V{kXSU,PAQUݒ t6":McMC b\;3`B X}=( CO黇B:@ą~b9LI)5f-rKz` Er2ga0y\D tXm]FH{\t:̧I,qóң1i4@ *mdtS9l#PV* 8b8hznEI)}AƁ(ZGB/_|^L*oZ/BїRS2?qЂ߶\, |Rt^(ʢ1#԰ ңQJݨ%W%}BwTB[l^Oz4a;:;ha$5 Anhl.> jIΫ6qTHT` f鼃:̦j c+pwH.A b'C iR*M` *i! k2z!=#BYA>}u[ cqkvx&V(Zxug=ѻ ۹De㗅Z!d'?-f>풓Z4g D5J)͒rZIq#cf+ָ,_dgR)K~>Tfq2ra5WML m[^Z3cxx!37ͪ2~2oJ)}I)j,;>6qq).^LڦgCp GAfI*\xR??S9?:,|T0$yvg>ؽ,6B@Q$SEYu:-A;XPZZ'Qg~$7 v m&Ũ{Ö8Syv"fOm q5Y9u,)j|E3[ᨤSԪ2jCj&px*8V)kU M!Ƴu~ m 8ʋ5s?"<~E2PҮDpYP"Ut=K딎g s|-'͘N.),EVtbRukO^Ќie8 +F00,m9A?)PH3T-h} &epI gQi+ kʰrօ}/) -W٬ZjYhcgtiuiT|BHU.0~Y-οnC`fĈ6 M+Nm\BbЂ|0θ:aYbG?xG7>*;-'E84g򚬃EzoT UޭSĚ@C.NBư=ȏnvjX6/-Z4b^M|N4;q B~騏LS7{f%z#b?ߙk\AG"H)ꧥ \\N&y`;J/ZJːZԢ( mA[jYňrJ]/ms;oɼj8{K#(h25O PumJbhR)vkJ0*2du70) NLf* r2ֽ_[]jP5 ]$chnJ,w]NJca.lc}闎˜9J {,2Ib"Ol0 AD[(R0Fٵ\Z6K^r>+޲#G&153Tw㜬m}smwXC lS!5pX"dwh1j< — W|bEÄZc!$Eڪ;1 kz5L!#TW&lIOB||c|X.GkCT/h8raGNHb07u8lC~K_Jw;#li>v\R&TJǵYVSe D"*aDuYihcF/z}&Zv!e#xwʉe9~17.^ B3%026C8< 9ښzW2.x\]B<>Y艐|c;s٢M$/&_eItHI"q V. QYRFVPI |TDQb:T9B}0Je)ۄÚ' j#d}mV`Shn N3z9SN_OC{ >LK7 Rbpd3CFmYSDn%36;¡wlY%lɡ[Tgtb;Ze9|B@[G=QL& [Vn͊PF!I%}lePt%&c˚'h8|( QNČZz$ąAl'^֙ 5pZ$mBmu1]ζ B?7'2;Xwk~ի\0b2d9$Gm QcI HN03V&Hu%f _ N61 zBb0 愰i_M|m089",nN#a(kJiնE|EpfAbN!enuy4p6kO.g,L@gˁ!,F!,xUH8H!ogE&Sj)QbTy&Ei@;iO*rqڒ 0@W)6N5ۄ/)z,bd; Z1|4#UKB衲Ln[ܠ4SXCʧVf-(AJ\pefMx\s ZH]UQ mMwTK}.jf_і %O?j͍n4uSeؗGwA^?J4quќ)W1;GϢHjKL#G'xt(PfB H`2K39PHMx#EFjQ8ITxJJ{ޑN/x[i"4AERhR;Bm'MI/QCت(eI#$~гբXq9 Ϧl4P5XvMvpZNP(M"R`Lst PA"^/3GD>;7D4UudW8=rnO\k`GeHt"6GCŤnk; 2SȮS=bkv:A,Z1*gJm6kkҔ.l q he2FyѨ3˻򉟄:Pelv&ڗ;1EAXL0 qE>gHH 5*X,s K%J\@faP:ɳ/5W*ݐirrOW f=qWmӈLmflNqg٭$aAt=79//;ߙs4lUpl$Ae%Ȭ0WCc ۿQٹ(JwYhBU"9W\tb|Z%uaBCi-c&vqX.oO68I3C1`Zd &e xٳQ{A1#ŠPFs LVH/#x <>"|0SGIu)bT` 6%od;& !&TiST&1[F!2Vⵀ:gɖ2!e1Z81px gd҆5J!U.3id۰::J7M&Zb3ԄšeVWFeLQZfD䓼IK,1YK&́&,KQ0AheoYy+mtm<8mU9Zb*cӤSI8|0bYSOz+咆eVQتw򏥭:G|6 L[MQ%&@׽ۄDRٛyDhzY^J2=m%҅Ѷ{Ez]s\V{?5LDo%uxNT婶K'P}b[s8JSThkOXGZRoZ] ӚE!Q(j ͊Jt{ =RPjU(&L$" BghQlFpWHZef6B0Cx /`0yc/MAy#fN !AFSX4: Pl2=@ i&yif@%'$)=@J#:0Ls Φ  `ꡕOX#ҩ) L;248%EF_Q sz1|BD[[Mգg\,PQML2 0 Ti,C0U!ug&!-RGM*$lj  P`IC7"hBɟʠ!K`N}t*`YA@IPB(-S4qs[d1LXj) DHHfL ZkENrԖ0 jbDZ$ČDX G` X&iKK\SDs+Ð6R#imDuQk5 ;J7J$Gsi50h@bb F*#O K $j\Fd HFX a \BZo{?:뚖A;F$XF>dBĕiB>A* DmAZY㺾,vgsdHحyT~55jα9XX4bpT8 %s2&V=^2Zy::c$-Aio %3> [\bv/E@N[xs,[49ʗ'9u|NGmN遶au2 56;`-#wā_9e%VwQ ң*?F,{[#:#gvqFAI- [BU~X)R0x30^/C;^\öL-ǭ.9D}sv%smM~OU|dHBwu hRqc|=y'Sv }LÓ$G(S%(% 5w񴕫NjMvk9ggLek 8L}k:劖y瑏~}F\I?IAL(mMx)w]o\Z{` ӟ٘y?!?Ζ?S rricPEO"e'm|QM.9Z|tg!F"' ιq,kk,?q c?TCg! } [gy3Y_dwKS$"P"?w))\..w$[>Z)}ox涷z|Y5YIˣWtTR65 씴iav/sj{T%ԩ$^V[v^e:9/+ ZB^&,>*|ZTMH6ˁdp>s$Nܜu 8E횈\ý?QۖAjKZ-[%7<]OA`!s̠~gCUe uG["ڲp8au*Ӗ;ٯXn9i,[$H!iK]hr8kQ5_цf`&{>0qf1[䊕dq H'SY1K.%oM'nf6Bg r*lKbvrM1x,lYzȜR}9:v- SzˇqEIMGÙ<}EНR̙:ĂtjXw3'pj<4iа,f C-ۂ 7-ޟ HLSdФ!j&Ov _9(6/ɤw5o ́Ow!z ro k,C쐙9&!0?i!HuhہG؋XԠt٘N9P?K4\nw Ґ(d`ks\ gT2Ƃ>gwqGM:ƒFba0!Rci$m&‡WC~,iBX jCKCh}(3Reh,C-J @Q` JS* 5]0Q$5ShH!چ!kEA?Sֽt!R05XQtXR^T,\_&apZpHD׼0`^ښ7Ȫ#e`/9 v 8Pv®3K8娰-[SMM)S!>Ci[FS &CL Jܔ4l%̜& gYTZر v*IdJP> g/m1F]Kd볉Lhom!rg}迆`[kL2-V3R$Y a Q(CȒ1 ʹX@]P DX oY:hG>Z$1 ڍʆi$9{j;LCq@5x^`V"DTrS])(>b^]vpDs̤kkB%nܒ%Zg TM2vDp(PƢk2FeF[Pj5Ev`4\6hb lY9RZP,'ph 0cC(H]`NnYQC-Xz__Yft&k"Vvt0(SRa8 _!EȍjVatOMXB/M,BuOȿZ"`u11r`eRO`9y?VsnHRmm.gd"CߖiBba$t 2Gtr ? L+-eVDٸQKd:wn YUrE}2B蓜a Wg1:2=$A( ~UZ5Y 2EK:^XR&[ 8M XÖa[3 r7F9>@r֭ԀN=X?H]§$/Lo9DOZTI2>r56.$l0|do8Qm#8 YB~$LF[C61Rx*t0H+[K2[_N>Ok\[I3BbHpq<;O)!2eK1UmPW-a#6?5JSM)k&JjoDȨ#CUeml.P@5F'Z?1e+89Q քALd}m2UE V tЦ8h0&cC|ɏN Mp3q"8 m oJ˘>BᙩwhYЍuԊ Vfa>TF4B|Al"wt0YPßÍ04/">GQ%h܍e$i;O(7m~?5@t' FY;H)vjfG>_W)2%.1*?vs*0>;!R:2U ,aowҬԧ=-#SSPI)dRiǭJL03r-WSvK̨c$Haw(MAv{QÇaGHBX`O0 h,# "|[@VGL??}*&X樭Aj zO,-ƒoRlmQ9Z> Y|DLH/+RNP*a|Vfk[k/sp0'&&+G-ZwΒƸH'?хpH{$<}M`0kQ[d[I,l53*Vn~rR|۫U3TҐ mȥ=* YW+ 9s!R"5yr(4|łq9p,lrM ]7ӤweHtEZe#TzV ĕRw,i|A2>p3 򲐬0B5j%DT40,>wC(bT; 3(H$y,Xd(7}k=A}ݾx}ocD@BE62QJIP`|Dc%:%$E^uz"xϔixԺ(7Sj@rrl(mSDcD !.Vx&$hY(d+/ <D`hnN#rԱ.^F ?Q\KƬ =\vل@feoHGpJ܉ DUhy5 yRG%p9 N;* b2a8@LXf&gyk cN![m})Nb'&@Û !QDT>"u!@@K 32)zfȈ T x x f\=l?J0Eh,Z쒋5'|@xu]f#Y$JЍA ORU_ys!c\B @IDAT։a kz/qִ2GQ,_3^m>{/DHxMŊs7U lə:|FċLd&FjzY֧U[9o6J兜 :3RD(xQ(!!LD_/*(J♢IhSig$ ꗖ?%@HX+q] 0RѴ"1GM5m kG=LDWVO=a"dQWZ# }kq~U5rj0X4"6 NQ$ ZEcPqqSO 2}o~ˏ RRUSߢJˏ[رԷ.KCKl}ﰣw``m`Жim7<sY^vsЖ.K(귏%ƴlRP{"z9XTR ʥe](61Σ'l1ҤHv V~'GԼب72=茌-HzQm5` jxRz9g=!N9fض7-ȰFtLĎt%ݻtޫ9rha8C`aNCﬨEHg)`MwD'N }l1&bA&$m/ "$"3DPdтd4D;81vv>$;bi0VDs uS1mχmz鍛-98v\kRlzmnm5΂U%Ԩ@u4#QxPL_&lQPBhųSf2t滞ZʶJm'¬KùEQ^dn=eb"UY7)`2/,$uYx7fYҦ92IQB|KvͦuprRI"JHDoC)iK{N0e3R(P΢Q2*͓9m˦(zٙfe 6:MUH "ДPCG*0JY%&y4ׄM/_3k݌QwYNNhkڡ>l;%#cw OTlԊfN ;1'e*R +%J / "+lʅѰJS[hѲa=V%B0 Rv݄R%#"j :hILZ+9l=& 5H=cliLU\lZ^=qFk"VVds˱꓂H@dRR#²}@!жdU~bF'*g"ݺNrBk$稿>G9`Lz3ywb#%RD& @ 3fn }Č/c/%o\< q#"kG-y۹ 2X3Ϋ)xLj|7Fr;4$֤T ;," n]K>22Ql4at.e/RVLh3V7(1U[@:WvE!(;hȻOG|P`.:9dh fw m<#B)E$A^)0;yǃM ^v˫e~܄ h 2uQشOi/oi:NW9„[E"?@Tʳ $͡ʷGGpAOD( 6^w?A4X^("%!T":&2 OQ}1_QBV<&I~n9BƈϋF}hnmS ׉ʩ ف}ы_ yV8<c4T b5r{ύɭ7#Q1B1Y&Ned#!4ts:5l&ȱO_m$0RmO,43I!:G۔zL#""UD;Jkr+{%Y* ٦b)1NSG'HK /{9w?i<޾]p sȬ,l ì&l~]LןWS$qa*Sկό@ȑ9rƻ5%h{F̨@XMO%2u:E;mQ;֠v, Lcy6ξ :KT 2"A%OLSJ$\ж)V>wpc|f$ēa6EXqNQ4pTKpzAmG=Ҟ3!npvNO{q!1bg:0N@4Л#fKZc-Skx=Xk $ӑY!cpi>ehE~G4n9!'ߢhaS+c`KS͇/pᣋKiURnq z×F]9p"p76Z׾ \b+pt#CNa|hph$гB4阴VHc?PJڪmN G>\ Jz/kY[9G}ZkZVQթ%J(eJ< eAĵi5RHj2DgX*Z~H\~Zn!NbKb 2== @獵 (j8>YID]Z}]Je-[Kz'$v$DP0háG0sh60-5ipS-tӮRYRǥf)rHC^pqNRǸL{|S'M<}Aλ<)njx+}9J˹_%gyF)}1!ܧz(Wn'}MpUD4oj~nݚ ֟>g.J+V 8 v삣g;X.p:n~Qǟ(.fߪަ7Wm5qVtüYDaZ_;NVwY^JJ$X}֣FP'$ϟ.;LB|ukbJ+V 1KMR+,ϙ{pSt|HbUۤ]\@-. $Ɵ;k2:M+FZ;.rPR%i<Ԗ/75j-3n4-\୧FPf@Aj"!+V X)p8`,r]ak_z~GMs<.7;\쎴ܰk#x*sY9ZQq{ oL=ybWqnwo[:-97Ao~իXWRV]_o-Y4nuveNn W~]M.Sa* &wwDjoy}mMt"!wd瀇iX)R`Jm XXw]jԽOO7$~߅A7楖E|^?жZ6Cmj~ ݯf& Z.Zvf%hwYiWs y֐9K|wk;Wſ?Z9_˃6-PZ ݹ݁)êL!/?7!`_2X:Y]6uW a-f7n]k.q?|>e/MhN]B7gX)R`JSQ3`y,j[ϑoiM;fMMVyg|ZU4^jvM<>9Q̛Z> R@̀ }zuto ź(µm̀iooN?A}rúGr:5Y+V X)R`(pZ3`P~p9j+&ցm ;ķН OI6U5u_y0oʥ4Sv&=/ʣ;å;~ROThzݴnʝ/BfzCd_ p3da_p!`W'ōwrJ+V KcMq·jèi]&OZg]CsU|\onYed5l%&| ՄSܹIuԗ0K;̜8w,j3~Zeu->0.c\6iI5R`J{)p6ղnM&7?黎{A4!{ݎ6I-aVKg)ϿyMd 3na܉e曘k4y@N+A:n.mnsSvhq_+i"6&輾9&V X)R`.q\aN69=jAl5ĖT;VaUuЇ=dԤ9$eV9f/NMIY~˄b9eyoƭo}k>:c6q{8Pmy}R`J+Rb˭5"~=<1t+gWʕt&3e,//a95a{ӛnwO{^يZ@cqVKwӝiUU+f|-_ϖi\}C[Y3 h{`h`vR_ӧak਼>+V X)R`8`я~~뵮yMg}{b. #bKx:G=HoghVQ7g~g}|ϗ%܅S;5'[n; uoLyM_=p39THK-du7wG#A욑{jb+?isڟ?ap8lg9[s{n) ^)R`JGR?C^*kҧCϙ9|.>5o\y;A-瀷+=p3o9re,!@4_+V X)RNn22]uc^+V X)p,V|,NT0ٵ:mֵY%h=)ڭV X)R`V*l+X)R`%1q\k+V X)R8 8 +V X)R,P`ug+ȕ+V X)pV|+V X)p(:@J+V 8>BkJ+V 8 XY rJ+V GG|J+V  ,uR`J+ꀏZR`J+V|\)R`JQ`uQh-_)R`Jg> D]AX)R`J(:(X)R`J@ W X)R`qXqZW X)R`YQW+V X)R8 \ gWk_k\W?Uz׽t%^WUG\~7{5Lc4y|\ .xz а5y 9[,e^ZBd_W/<#w/~_gUzUDxы^ ^ꜩ|M--MTw?C)T --q ڛɛh[wE}׼5c  p4|~kX~7~c4ߗaʳsι瞋4ጌWIms=ּUM)'ۺUI ٪p@`#&}$:] =&H7 }WƖ"e_.{? %0\2̗J > sc ۼͤ%npxvӢkh7$]Y?D-g]P{)v3qKsHɷ/_%9:zæ{b0HpwQ yzK^qqwCg<y~V//f]E*e_eZ-IK^="!?)3& ]S>SL~x8u:`O_WNw"-?S?u7cG>>79Az[[tfdZ}G}c=q h+4I0W zHhSj'>L }? n6N2(Ngc5?9_Es6M ~k{{}cw]S7z// gMDģRpFmO?>hԸ2e%!Tx{Ϡ}14V7M靎tg??M)vׇ;fv}~//?/bp](2hI/?'[{X__ @rjbkSb I!*E7*= V_t2O&qlc+ ˿ˋF??#څs2naw#MfxӣJ7.s>stھ۾OZL)VOV~%?2/,[@> __5V LF=Ti*,f2%YN|9#ooKv H<:OySԁ9G"9NwK_lZW9 `]  ῿[fMt]TB#-?Ae%MߴA''f&b3Pt d`'_@TmO4=&}MKX|;;g|t @]tZ3`;UbIQI~'}cH('fZBMդìm=F\/"DsEHi9|;]]*&~ i:=»& B?#Muʩ| Ǫ C]zM5ޡbЪ?׸oz6L.^H+\5\`2WIv~bfI%FVnD4)80RmX% ??]"wT2Zz#,*;(6'PnnIyA 5CG& &$!3DWm3O-MHjQ~E`D nw~wtaȲ %!յȤ%.,!\҄ N{: <>tw0)oi2M>t?S-$Vi۲̀>MJ4U4 ؓ)qlcYGz3Q;9 B9*a~PNj'CLcYajJ4:U4\[/"gxQҶʐMA2AG2Eo8tNeC^xDliEtSs;9[ _y>g% ~d~ sOfάOl]6ZYQ2XUSvyxIc_6=TaYlr85ʺS45 Li`6Wc>cԉڣGַW{tW%lLY4GtOFxpG(*4ƴ0_֏R~ hxȤl *=!2>q_ٟN dm }},a iij89)|__kLM^T(Hbҗ::5;0DLۻOSvm//1 1{Wjb[^''c1fo ۿowPۥm?5祥C?Cu, j<#"W.ZrqsH ׾h=]P\e(t$tbrq'}~R,K7 1a-*Ͳ#.00r2fׄ^$Rq{O}Mp ]9-,KpS>k$" --XGǗ*;TMCQ%DQh%]"unZ'?[iTtܲ4(vݮO qu0NA=4c9制Da=VzDCp-R='w6 74a{{S?qR 0 ! :p6%*I44WbF'2dIz^h2v??S?S$JXDi$?Ƣ6Po6cgD]VZ>Й 5E$ ;Y.Q[vI+o2S$rtS5ƍT,>ެ-nA#eyOV񖷼%7υ]zWo+%-o)Ș/ sEDG=#>#dzh NY;PlOC軾0LK[ C#9`&ɋ Ugq@.\)Њ.y[N5G/鴢rdXgJEǼH!.:urŠC&z:1ݮ*=:L0K8nYuL6B}|??@}.ZAɧijZ:ht q{448 ,3IznuE:F%X: ;*3" ۙS/)@iU~ж(aD۾ۂ&Yd/1VV-<(0&bFMh), /|A{ 3d|^ #G&K$zlRE7O|Wi!?@D;Q!S~_E%k:`yJ ‘"mthӛmf2wZg~gc_&^MRofؙ!e!m9:-i18l'ib 2 Ӄ>W~W1Rk|Xdxe5SeILe*B UrF|n`P7dVRD2 HJmߊ|]鰴 "8H)x+JV\y|$ќ|ή|ɗH?aĈ)IJe,NtjR:MJZ#?#}9Ya,)BbrxbOhf]ku sE:vo〡qZ an|c>Od:sk!8B\2\JPkw6Mbʳ6K̽2d% 7TYe9*JBZAq]Tr@vnU"*4QyCy:'wāw(9}!+]WG/ 4pj=A>7Ssz**!QL&? |23d|[ls'LP,i?֣L144!Ǝ;!"BH\e+]*ޮ fsD8ha<,^nH &Z$)=J{ndp-@lG&L O :s[mhLMX93nMFCy+P؀?H^iCCg%^d`:έ&$Mˎr\ b l^ e'2bl;+e OfGcvxw.JmvѨa-Q$Kj*298 V!Յ]&@s*<-'OCiɟ#5Q59LĞAkGb7& .,<2̱aRQUϓ@$ T2of5H _+^`AVİ!DZ2Bۢ`>0M *[@|QWC!tDorMGVKvlu5fPifE!ы_"1mM"ӧtsJD!i `aȣ R3WD[,rڤ &“Y`@5;5_W`Ϛ(7"N${ZoPNC8QyӐY DҀF_6> PV[ 2;inM22˜#Mn ! *SC ȬsWH@D(K9 `7V$ӾCX[ pKڋQT"6`qu{Ʀ'X5j#Φ3$Jƍ;>vP)h )Ů9ʜ́"߂%B}q6D(4Ľ!1@X%a#=ȤdF2c1R"QЗ)M^7[%S;!LXMy,jwց -&[IMEsX^._ ֈ.{AV7"lţ!UzQD餰i ç* g@x=2 nfbLM0{5ĹXC-- [%y΂\ܖYF38ODs&Q$%h cԆ|#]w>E8dX0AQI@e *^̓9 Wބ&:PxzܛHH<{JGr(\ES:EW0yx3(>IJ34=Ɇ4Yzɀ?1F\Œe"4_aEv3CU^qz4pN8K(O&[fSz Z4Jۦ"$&e ZO>FܾajZ7[Y?~AgbFovog<",m9ƣ 6D<-$Vv Q/phz ˯Xrľ( vnľ)*+{iǯ<~y5= .ț/tQKÓ}i38yRMR8]}l}z{n`%`mh8bhe !OAn&v1idKvcf%b$!:a#;D-dqکɷCgH4bk%њ=9] &]4MN !& XRyXVaXy$Io= C\7Ca%D')[Nv{Z Gf(07-um_2{,Yʢ U|>0 .dQ` v,DE :N̊HW(J UѴ^N XTV&Gx(rfRk6wm͊,'EU@v;0NY۔ϣ=;F5D*g1Hջpv9a键YgEwOYWnh Ԗ9;vR@8z-BhX.kzyp@ B&>K Nx_Qn#G[/VC WLDrqE·8hcEr1)\OWh\ d;E,D\P5 >p:[G@fi;f tU3Wԉ mt?9ѓ/MhR!h"ykUj+k-1M Xv~HI_3ޘ Mor&~hTS9&/ ^M+%,TN)S$[G]7&\wL͠LqpѴtlCZ!vȌZ45iNIb}"FyVQx "QejKϿWć"&6nN ("ʈ*lxARF=~j)D3v +_ElL2` }$litb}|N:f$5.hrrǰ 1kTZ<|'>D&8浭e6q U##!T\&NK PU@ѯ;}ΊRKi}tǀ5Mm.pq4Zԗb2}_5Zz`zB XPY<\9L&Mn4s0~(M$q "K~E {̈" 6Zf#ƶI@t"M_euSx1g6 պ@Ѕˆ~T߂4HkP&nE0'VYa/m"Vp6k5/O!ףm~R9.fE|J兄w^h1DOQdX'LԄ!SFYu5i%BW/pXa( Ri"h)@E"%t15hٿFJGJ/g-KM%΍SiuFCY (*5J:_T}0+4R\N@"vxԗ|΀Tii'1)`63;SZ&V$k~itH^&+M:b9`G(5q;+OڍLp-^" d>t4<1lH;̲@ ɗXM`MX6iOHb*$ENUj6A_o@jLO{=R`g kŃTRRTC3<'q&.)G{EN+MN ##2^!#6ڼnz40REZ/g31 o2R[[O3͑;530V\LkXe U}$kjuIjzuSmb Xp5+P#RE<:ՊN9\FU 5<%du|Zp9"qԪ C;3EfBLOʦ}Z%(g CI-<4/eHLE= k\ ų cfm M+j^"V\q35˕ 2ӌV`YHp ihExPdWB-]]6WϘԶ;Fyă v`K vmڂ5!@3NrڠW *K.l0d~µ. >0qڂ^Eov9v;T?&Ecx(0ͷǼ_tr,#>_8aʰ B -t]XE[҈^Phf䗔=g,hZ%!`t$,PWxW)Q#gXEuTlWs=nFU@R#Mgת}K落ys();K:`ol՘}G'.#W-lYĝmsC@*@s<+8qI49l1Ngd3L|RޯKcs-iΟu>wrWUݻ.5꺪ĸ&e1Q !UnhpF_{ax6b'ƬR4TmO>90Q#G%׳WuA~Gev%jRѷFBBi`;vB/hgpI0[bijQE97G5WۇwPMai2`;cYch5qZ9ld>Ŝq|N9+'imABVQk*r!M28mofk_eZI3}Ou+ |w̳/וxVKJ} pѷ5Ο_Ǿ%_od]!}I/1SrD.ct,ɡ{noq&'X?:Na0*>38m: Zg,0 S\ qZ//fԟź>&tA)Ð}"`lG (Zi7^)Y8BJB_~)4u´XC/9w,k8V}ԣMHC>JEp4MLV!N3ۭIF1,Rkݠ 3y3F%SX  SSc 64!8py4r %2hH(ԏ`S_#2쩎c \er]Q?\x]g :uy[IAUU@jA+aaAn\<,W+aٻ_΃oA3aR1dFηZ܈LEܣđ*E"NHt0fScVUʴ Tؕ3@dCHZ%ϟ{ܹu#}﹇\wRrqi7\O_$9˯5?sw𡋸]~npCx%4 :y&U=Dث1P v 7K~` gI"tps2~bp"_c~2]U`50'$G)12tǯ̐SNLaWFU*4moawl~GZwƣbxT |"]C˦\kàt8ɒ>Hbݼ"nx^ci!ukJYu=vIaIZL;E2fJ*{®nb78ʏrk&2~4=C?fcI$Wto*AK$ %N&^* Q/iwOZ`u!f`_zz~<;UJ\wX @Fm\Vz#2x#26%D<9j1!)Z@u9{1u}ىtεQ8ThYCʨ՚rRW(2 H4Wl|JvZ`$W0O>>ygSpyX%>yxI?8`E"sY1!^0ݛ$ ;upuTMD&"Se#Mj<X\`>Dj׮ `wvIH¹H0JW{_]뫬Wޮ1Zu[\MԆjNU+k}7}k}N_j[o7A~Ӵ;irn"YvgQ؏'#x=`0@e |]vWJ9'HW>n\CίXHqS^sGtceϟ{+_IxbLc0"> ԘG3Q=B2JȒ\+c6~ܑ}ERIdKnLTJܾЇ`Y#ϋ?`y_{o'y⣟C}_o(cO:}|_ǂ]ϟ7>򓵸ٽnʙ @i.uI$2btn퐨Ɂܪ+u>)~k^CxrL*p ڈCtvu]`Չ4Av(J6́Js*r7ór,Lb5(!Y1oF] ЊUd\bDO" jM|s0OsCģuE°KO񐓔 NeQQi.8nUg/+0>buEm7$I`p醄U'HXQ mšl`WhK-7h].PF4B 9߱3 ^鵫7t -CNnR2'.uϠZq,)K# C 4!HۅF cjq+Z%`] c["_JުDc͹&SW3&mr-Tn&+͵. I=e-\v"S` Ȍ5&yWxI~G^FBP -`pzȝooҌ6yqo~-yI^춿uSOv2gvO>ym|En8[~_'/>o|<8 _>:Y34i0ll`bo>L0RƄUC8XPUV tTQ01lEggItX_h̃܈[[/91iaߡ!c4f=go|ǴMdMsY9|)w_Wr& @_, Ԓa5bb`ؓJpn{*lzkua{.G7=?'꯿?w<ÛُNP㥃)`Bg/nd[&!R'.BLlTcz3p-i xXqq\ΈRPrR>cQF͠D*d74~}FR=IW<մ&h#U@ME*$dIo]`.u4=g}–ܯ,suDQy> en\ H  "j#K!暾 xV3Few^EXxm8GBW+P pNp_Wګ[NPFAW?hIXD!טNIMO5-te1 W=}^ 61PBHF2]{ҽ"Bۤ*S!LusE(01M)y VIFJf^oݟd$4BHEA Ӆ@DݱE5EX5@Y"Cm18ShmL ڃNi ̕?k_lf֛.אu_+ ,z O1G9inV*mz FUψŵ zeEȡ W:/-v ڧMOфGo3 i|ǣ?&SozɩI4LZ|á @U&`h;Yդi(n LWts4+1oi>u5.EYf?X m jH m nUWbO?Iău1MsXZ38k~^$LdͪSQ|rfH+b]`n!ꬻ" fY0t}W4G&sHAk_82Cg5O8haE tJy4O6K`q0Y=IBk(jsg$)%`Ք*_K%헆l ,GTzdkVyO`^3f.'gRg# " ZOt'qr6ih^ rAːؕI!~ tx) M":Z ҴIWGjUŚvy}SbCCGjaQkJ]h؛p[(A:yTԟn6ɆCk2 O2{hQ!YaJGOL;Vn5ls\D\vo}ۖsF*Fp#(EMjsC3k8VpӒi`~SWRڄi IV>ݠC`: RIf+λOn]H{]%B?r=Oa_po|s=Y?0u4h bd3ѝ,vQ~K:8@9MU%UP6Kl!i6fے a x6 rerZvʌvD"GTtS[sگ8u[wWKD-1^ ֭;CT0Q+%5 qdMA |d qRaSuU]Y~Z8lOT~ !#ʺ#(%̤e֑ j;ZRDp!yVTf'EBt뭷R-x۫,Q, gaAãNf[5hK 56j4|`wS1VcZbm2QNḃ*qXK"-58iJkwB'QЦ Mw*5/l}U$C, N|Oڥmߋv1WEl]fuqRIijB&bb^C@  |zJ- ko~0|?"GKSI5:ȍ&݀ZuۜD'[gsLAZFM)k.8(9Yx'J}<;61Ҟ*[RYXZ8C#j+dZ,ŵmԍ~,'֠<+ u8M4D-yU&B/܊eLD GUjoM,)T&a&8)3U_!|GHN[`6"# G鯵Y`m%O8O1CРo]C$js}7<~y@xT%M,{Xrs@F$`Bl^I"Yx4[lʢg>!}s,N(m}JPm''G%Q0ZGIDaMclz~JK4'u/ßN/J#iE !n0tN5ppb8ib-'yM#|~D%&Ő| |RX8Hfɷ Bӕ5RY[ׯ 1aG9 V2q>"ESc֐-zvNsYQk!\͗iKip>~z:zcgҴ&Gxh+ 'PrFy.a_El5[D8sLi]Ɉq o&K6kαk\i=w1&=2U0Ԓ85\%e#L<0W%-ȉVg =Ϟvnx?N~wwc`j\*=ˋ7=߸7hۥZ'+ڇBRkn `u/eaB78q^xO (_)~^|ژʈh <-]9B47ڰL^[&ը:s\<ECM:޶? fiI(۩.#7!@C#&V J,=5a\_;b2!ؔ`#<Vj/E 22Tꗢ4 )e[+ mUxb `BVE ).f(gJTTRbiƏUs0s^tv(lSϴJcIGͽpbH4#!V!# S*¡Yd0A’aЪh /9@~p=OSZZJ( ) u$N{t)dhKя*?}630+].F`%UBc $qJPF$-Gļڑ"t>_񾫬yǟ'|͓s;YOLT< =|WZ-ZOj9T2ǭoj $4Ц"9ަBM#^Z!(M$ivOP<9{D6ڤFᵘJ6/ؒ DhJJ4(=~&ZT7`,jUN;fSslx$`Zp)SUlR88'☶aNb#GV<)k$~}χ~?;'+䞟G_]KwG?7`?p}鸓>:!d[F6@D%~t 46Co970'GOXiˢE t0M##sIIŷ}:n"$`~8b&Wnb,2X'!0)Qƨm0# !ڽπCGHNi,3ڝ]sWLh~?~ PN7 kEi&lRbg@<1{W uJ~vߵ 5}`(׃ ^%0MuFy*f6k Ih՚F9IW}5lCx畠ug^Uȩ"F77hoop*#귢hd4jhA>^MQn0$ѱMm΃ʼna폸/у㘒@O3* uif~f]C0Q0dd]-Qb}/:tg^eT{s}yڟ}[|NmIӘ}:a~_>Z3<C0(gS>Kh1-ZMwۇjypwv?;ZbW h= Z1MZ}ؽo4Z>|ùLH]&ED_g{\5   mWg1>?ͳtbQpsn$Wfſo~kx hƓUa6*`c *u'TXn- ivju{< 0y>:b7h!kCWׂ0ꆙ2oxfF[>Saʥ!I[=usYQm^G˶|/26:'}}k~I8 uaQt0Z aS`" CphWQ#,lC#=ÛJ|@>$ꂌ~ðVit8c+Ttڛ JsH@Mv4Y4$kpM|Ns|- ┎a>[Wj&loYEC4P.Yz $2"s> Gk7@%B=|q;OW馡k/Vz-wOeÊ׃ˏZsxm; c3n,n4Ž3*JPc]=D~`aɗ|b.c3cnS~rrR;_K-ӡ^(DAst9gٸE&Z4̝y;{!d‰N!Z< -+=i9dbE*}Sj43w+?0=Lh0pu<i4AМ|kg"+ mE9LQZ-Cdi`1ܮ c$fqLl09q4T[C٫:T1Xd0/~{Qܱ!j蚎k#ѰQBGGWU|1U(ѕ3GKu[BR[g-p4Pb IkKB_ ^RaUJXh&>•._u}_KLoƏS71Ou9JO|RP1f @fgEUDьZZ۫J];@mKɡM(SDvMD+ڐjeu-ōBTّ!Z C&z(b x bkLp  .M{$̡ }Q:fg~!-Ң .1Ь"yD!8m(׼M'Q=&\ v+8ׁ$KtYIa:5 b黦9Ln//0 _Z+I|ٲOTdM`e6G :m0X1'&x>:,JC-Ou<#!EL/P]"*4`c"=gXtuy0[DF]6vs3nJ[.XVj sU>6,">ߕv2E9A Zl  9h sӅE*bx֨t+`]\Cp fiq 7`[CG)`Ũ9+0Yǣ:P-ﱀ#7xU4\i| >#qɧΘSOM_<󳖎JX%09+ޝg{ቀ[Ԯ݂^Q %]9Z="SYEF/6 i=UdD]5J7h/t*& yDHN'p|~;V 4P)f!h" bT*qaֺl C~F__yv}zF'Xv (xkXv Ӫ1Nì8V3=&P}^rt 7`2*$Hdu[gzm(46F? 35ydibw ht.e `!l,ipʵ=Q[``rju?PWkG+7o~<ыTa`H8@s\).r`"9zQC60`z&,WНw2' S> aHFX{|&cQof!e pӞ/INߋo6NH讦vwCw|AԊ_AꢊYh0l拵/ʽJ*n%e 6;A>va^)T)nnD>tX!X1L\AbGC}n iXm A',ᛢFu0eKl,[R p*0B%\ބ.R!UDi3r }9/:rp6 RA8"1|kqrCOCuKjrsR0gښrq#I'HDz`VTQ&^JezMN m)~by͉ qB;u6ہF&dbfL? bǦSr o:/yF_芨QYvOsrz B( 1"trUx?>$Kt[ y ^v&Ȅ^)uN[nj-BdO[wmb0b|}&]ms "k|9֜'9 WWs8b@IDAT)AI=? )D \?*8ҫ+oI `.Pj,a9 .%`,@ӗ)%QK=>_d ZJy6CRMw^Q&p=l`njܕ&ftK9R_HK,I0R͕8]B)kd-ڵ`r XSs@LDiX;A"r#$ G~U %)=4'fpƢwO`PGv`9>4uЄ0`LQVܢlyk]fZj8Lܦ/"*3 ѱ&FxE耭+k` M!)Jh0Cp"$Hz& rNgZSYZ͛=A4MÑCá2)Z 1k%]T5-D6gUjx[|fQ7?(Nn-E FdTk߼6pύ=&BE9GU6##?:mJ y!7f ?V VZ3j Jo-lƨ.s#enp)II ѳNHԦ ,̱lؚNѽZ 4A$h2 ۏN6gBOJS fI0mlxO7vrhT>NFҴJU`顉 G!$5'ME#]*~d`-$-vP1 `JH&TڠPGi띸;BWtRսZ L\iViam`pXo414~6mV~~$w~"P"Ѥ1oVQi< ʂ4I_ΌS+FeSsP182Zq`HxАNxҹuVA\d1QZyF&Lvfz-C*('q½u8wN]Ȼ /B*1<&BwcDso0֯bxbaϘa NnWg>L[aB .&gtٯىH10J/nAț_IXDݬZ&ʜ+|H2()11v|c<}*a!m8dHbR0 )QWODlv_y"隉'xX#Sc5\tHfrn$0< "Z&"4r|9ɵFl V>j!2J'<}(tP77eoaZ =;-,y;Ƃ ֱ &ē֯AIHB+S m]S6XeJ - -/ lǛ;0/4Qq8s@^f Ei^L^{W1QE:0وtP)5}yL2<;^<tJoDk}g=z*v-êli#>* DC VEh"If'V\V& '> I~_]OA$hx6kQ=g\Ye5kQ]Z]H'&4GpEc8bg ?^͵ˆ30L MNScS^EƢfi#LR3L8B-'Z\mj. )yT JYe!3x& 8a(TN9Ib]}IEKOE0vt1 O݀J{Y;VbMy6/bUVyz+U:#`~d0g#܃®V0W,kk2 |w[-\cb0biLv_!_7 2P A"VF*k֨[uv"nٍJ`&y4m=I(**g϶HeyĠB Or| [8fB"J/D.<@f!;tuȔPW,^T^ ưW+ Vy%M&|Rۧ:!π=}ۓAS!&17AO,qlI"`Ȉ~YNKLv+pMpZ? ?Ee4;7ƅRcK%/Is{OʛIx-TL:+3E@' 2F7I줫 |vDC Z co u5zN6^lT[r8K.}7mJ-QFj豭C:L]L^鐕dk!$㪥i&wEH|29U?0"44磨(H ~%z$D_0&v`UȄc 18)iHȤM(b JP-g~~y$`VcvUq6q`z1"#2K$zxO9v֫U^;TU"O'9)2)QQviA't+ګf0# ld#pSʆhyx\ e,ӜX'6dGJ{(9iŀXp{rrv)츙! Xj72u< &!9M*A9WWa,_魱4_#bi\M۾MnoCN)ͤXTE^E$NML2)"|aGN6V?b"CEX! !O^JMkYuƢhf<`:y OOhcLn:U7:)sk^״ձVPϙfu2t􁬓_Z` VŨJs|q@$kxM4xuLϫl%ë^:+1%/|AMS\vŀY by$̛/0{4>ZB]t[P &⡴˜a: HZ"JhN)jȄ{o0+uHHn u -^-JgoA`N65@!ufy P,SUC+sE0600*,7;É!-p)jcYcCR~a gBlzL :5^)v- 䕣G`^_&m*Þ>Je2k}5zCZb!9 6RX"ZӖ:cv"y ~uw4zi یF"cH Ӵl#ĩ&N#IGeåBɀиZ*L##HFU6ȕ'`=Kf$$F̏LZۄM83%^F>ՂG Hn7W'! )@^ C$"仫H̴(E!̐ P"I i_] ɭ@XlI̥D.aP1F/O Y$5!8*3Q 1h4HIoN`]` ŧp)/D6S bW8$bLb"C zcoLRmQ?4epvkKy"Z!~|Fe19HE.é8SKrѮnR!Zt&G/˷ihZT]7A{YE*3BCyx%,Zst~'?يa*L֊ Gp H][D-euNI5EL&S2q58HӘ&xP^9"5 I_434D-4aZ6Ԡq7@x8u W?hHgχzzr4{/w8Kq(ͥ#t[ 'n‘Ǵ@̑c>GyOpٲ^+YMH*i^+ μh1GiUF>Vq-f.Ȏl;Uy#-;?8e[ex۩u/:_FWyg@c),'PwKc`?my <:uдnZv-YEaimfm<ֻZD"b`tfS,h7UW>i w%X&8 fozժW"Ze|Zzp40ߙ?s@w.7ky\1x53 ZA+'L%,hgGi̓*9j]Ri*K{Ձ_gdr^ xXEekԙ]3b{'RQx[G+dqk_O##28I_yBFWNUʰ]sDC ȥmpuP:yWҗu%\^}D[.ZqξEBA=ѵV+ۣk5H_4}MAqҹ|@UO >>9zhs(I&C35:6hTԖW'__Al ^Ȍrc*||u%h {|yWfW<1o']gǬ\z3{:Rv7`I0Ptv ɧ*F˭ϫNM Z&skEkNGF w+G>%,g`$vXpmbܺ0kNtpQt\ah}hJB]^ўs-C T4 z lYw=#SlB ю^ZY{NbO*T\+/Z_Hκ3VI;O'LW׆]J]y7Hxtm^ZkuJK3 3SzOӇr.׭5MK 3`2s:m33 OIEn"|gB/r-3"z驋t8P9',Adsk|oKBzO.8X{"ME8'ZG(^Q^iM>_|α>9V?agnzbd>|[iD_*τ`I kєW|c4ΰVQ8#4ĠUZ |٠#H 2A"G5QT{VJ_Z`ƴm"TZ~i,ʄKCl6;S&TЩL&\> arUWQigH:v~E,ܴJN a҉ ̗ iW>?oỳ泞{?|Nt_il<龢Z,|Rq~]80q-*m{ɤʱAnuMVKClFDj$5gń6 J Z$g̙?Xt}QzolL^Kh1[,Dk`XJl FTi GO脶-۸xV_tiE*}WTϽLQ^?O=Yi +C1OR3a—}ٗ)AKSgej8$Ә|r}GIG i%kG'`L }A>UrʔJ M)ȕ 93x8ϡ 9UgvD4xI/E+1*e/Zo.=EܝfkݪBfEQn*5h ƆU`Ca.s57?w} GG)0:瞯gxc+7ŘϾIO_L2~F:&3AM$OD_mO4кrR᤾%,,i8{M pmdo u &1z+[vVjU?|4̮hN߼G)j!VAZQekb#M]Y{zݣC=+V,Gs'>\_~˷|3hs*x!9_Ch3A{ܓZ$n+]nu!Q)߸q{v$3U L7DhI (!d?W R`$=E'HrZ7l#׾Pp< $YzBa}\"q""SpzPuLKTeL- *q)>; sy??xcߞ՟l =^GS7>qpuZZsBsk7~ɑ㞑0$q!,c$5]/ S1dJ&XH}d{< m۾]GAxU*颱kwQV /2HəDu 7$aq8(0AT1`7%Ij vH* B&i^iӧX` 4ef/DU lP UV0vc5)XnD0e N'kMb*B:͓O=Ő.[FI1&FsJG)7!;X 4ea%6WDBN3ЊH?/I6JA}-EN)~~Oj Eڥ@(NXE:Xk[ jpǧZӣ)Xw&կ%=26i#]MyTQeJC$kOFB Xn4xYM/}ޘCp -qD3 ŝ^a+XWaƿؓ7ZbPY⸬nD (Џy{IEDnReyϗ nȮB Σm#vqI¤(t㍄' I<{.h0")CHСCyAx EEDxt GU?&Gv`^b I 蛚۷3`y4 V `,}S ,1TY @EaVO 8908($e#ѐڿ_?^MXa@ p--CmŒjZY|K-oaQyIe5uA)<{ UV^2DY7.nA:L$<:3)F<xR]1E(!p 4G DI6/@_`u6+Yjp Q>J"$%eFCHS&ƌJd2vU!"!&jFGoIɃĠO>I{GշXe^e3Mz/=/ЊKi*U~5:3B!NápA 殺ѱ/@*V.xD58s,ϪcrⰠzguuIv|Ui=;+Fԓa5kʯ ?7&t]Ye_o{7L () 7VnDEXU0].H W <@ ̤,ccpA'(dLՍ3FGА Ip$R|pJNN!?=afuPa8/ae(b&6*@ m!C#g#ײ\iETC,U):@ωѲxejBf">m>0([DWV%r ֛{TD!ă@=f <{@ L-(yLxpfb!D`lj 1*:DR<><(߯E`ڦ&#m% k%T_&RVI&Fv^j &FK N0D,eqju ԏ92?`j+m2cIf.`Pv B`ؐFG(Ԥ5#1" K6#)%tY/T2VLoy%'/L0GSoC#iQ%!L,C`NUr A (r4 [ 傢WG%ba>xiB59"!C(!]AC ^LZVAMW`/9:'Bf'V'A6z. % "DE0)H ++.HeQ*I·UlX"^ժ{D(-09g,1QTCE^E!GteJ,bH|; RY;C7Y: !;{+@rL-&1r`Hyw*~C>Jbc1040d@PQ pAF֥Qhs dcni̴yU«@Ѓka ZYƨū)y6lʪr ;Tl`7cpBMR Czqż<+UOхR4 U~AM#`CN!P`~vՠajj=tV)h`"*^8k4 P=9`4Eh =: ,䄭HGr VEqDB'BA| S'@~ /OAVЌ*BC/1J4e5}{iCuWm1@8dH|  ZzWV$(^cM |P) YģB t:HE_1Қ]b6LJuрeKBcYegF&_ VpSRKUr5)@:E ԃ&*? 4$62XˡizԖ3  [~K5^p󺥢չ"lM) +S3pYcP@cb f B H\$V4SZ}Pg!&IӪj1` 0lYt̫{ (JNRC_c F#I,1*1R\IXM:-RG( ZP-+ @cߍJ Rbo؊jۏ4IGAmQ@  VerNI@_@.IHI5/=A%XμB @/(8EA$$FK]^$-`g/GU0Y'h*4 HvL TXE*HϮ |NIp;xLad<QeVu"T_JBRs Qf°%qc{/b1}?~ëyK%IּʯbipTq#@' H'XbpGN XtI$ c P~BEc駖- M>>grwM ߀j$=ZfՆx&Zf!B&%8LqB H~P#mDZnO+!Kzf&,9/L]o. 8&<y>Vq DKLM=2 ? !=yS@ItK&O>q,2xxˆ|`RA$G()0>cZDS"aR܉oQyId 1u2(yQBcI M0nڨ^%p((q=(2¦@ϠZ$YV9# 14J G$# >Ռj)#" gx|7#8RVrcK 2RԐт{ؒ927Ң\U]-9x^ݒb6~hH'O ʨj iU䞙78&fJv>[:[<ЏU.El_YuQz1Ura#_B\ }@[k D?`؍#JiCE@`2VxbQ`˒SG ^#R rԬ_馸~طщ5#GY=AL䡓Гcǒ1 ;[ 9Dā@RI+D~%57g_'*hٖղk)U^[+d0#PvWe]*_tO8L_Wczdude[!} eȸ ' d PXA`9FYkȵTj, XLd2H(F=`@AQ"dTkHyXTש-C jD i ً!3^lʈ0H\ qm70>CL XV$'J .+lӨ.?Pos&RO &SJ9hf㯄0*l-Q H(YHASg$t* "_;ADٱS͙z_.nd^HgW+ǘ*@6p׫jq/r0=Ef2y\9S3E) HpHثg)B@j7A,U-M8$;ܘy$9;ye%K+!CdꭳZQ8,H9$*=ؼ*7B|J*ÕshΰP ڦ/D5^7~תRア  MAdbY(TGJ֌d*Z@‰N*k^_ R$CЙƣP眝q&VEsB lMWGHxo 1 ChX8$"1$IEf#wHT!L@&A@jPd|@dJ!٨ ѕ &GpQ$^%(v߹TW}Ы3Zq>o*3+WgYW Vscqs5J+T2Y^KHg+5;V2|I%#-Oc͒g/nyUx`NCιz5ś xIDW~RAhJ袊TI"< 4J*aÆdof Ïu=DSd׀#޷}j6c KK)g!6ciƼ:LU1CܭNF i_hjN.8dg["  QM X[kv3.ڠLpHF6v rY&Tx>[ .#[ X!&:jIiĒA"GbP.mpRj"'?hh&hWek2_lV eKDaBd%?OegDHUVp !Z&}r(?zW9BoQaeQ tc A}! V'pmA/G6ǘbpy#6qC;\pC͚S J '1Rx2;<0K6cPb# Oﭐ6W}LIrӤu#q23:'bR^g6fDXKTxg6ͩ36H0.qɀL)bL%ٜ  diDž  B_M -[ZPY (F`#FqbB]EbNrZh!h!\]&(UJ wՑaC\/@\"cl=Zm5|$|xl};/Nݙ<|8>(0J*ƈs vA0͕;~\ۉ T@M_<ɹy+EԌ<\LU)V0Fq mEA.ƃzBLw )X^9BK/qL30(+^k0OzH \nI*9p^5 uI@`܄G  gȞLDž mҀpnTbmOM7L.@CUŒ!D 0u p(&hRt L3Wj ϕ+ &1\Vaҁϝ9doW0Ҟ)~ )>_'[Yi]P.ӿ=5|e_{Ra#f^ a'+բe5 ~un]wD"])ϺjYJRQs4(IsMɣI% eINFBa^$qBPE bf,#@3p!B`_Ay _ 5_?^/,VC{0ȷ;+A{P=hɋ&uە^ # JHW$5r UcQ$J*y0UJ H5JV-ՙ(܀ۡȀ6-/ey@0lkJŀ>w cef_l|W$̇ 1PcfIOUu!B~@ vj O?4J㡭5Ϧ#NA;yb|נX$; =SJ,fqDah(LMh>q{.Zi99z$&Ď K #CIB5TqKۓ^\]PtӆL\N;jL + ǽ–-oG] -M60[&BYha}N  Ϝ!ӰM@J0|6Aus% Ů1|_l!p0ȡCpن49M \=l7S8d;`@ B&r#]p! dM) ǃA{,ff J `%{BDIĔ }iNR~ TUCbw$Υ۱q^iWxlIl|mpzDeD9kUm(kE%ٕdWk*vVהUhT='QSC.rWe-o`h7ʩTSjjlVߤn4b)lQ YũJ@C;7}S]ƾݐˊ<pe$ cXļi _u.\rA:qJoP)PGZ9 e~r #D1£ mG6/YDq N0`*F"T)sp_xن${~X4ė>ȉ*m*q bmS 5W޼(RՖ;+zP_}؛k-~Q .ֻnK?֊W+v^]M#[#1{# 3L?O  w,š^S.rÄ$g& a"Qmp|yFwUukC!pgB%kSٸ={*NX0]jCAfv ]aƿ7߄i=x$ ̞:a)p_wM#F`HǴ[2`u"1L0i$mW( F x(v @].y( n . |yA_!F$8Mܬ#l~T`LvtT@0`<ؤB'OqM @I1)r֌74:a3:4%q}d(d뮻x ƿ\stXЯ=2¯js߶F\1sj7%D{gu9ۿޙ8Q#L|G Aw4cѭN8 `BqDuj:<Ք!l™LYZ6ų%LoKD3+qf-M[&k[*8p #5|Qz̘1I"L=LY4{gwB/sr]p!!м4`Hd.8 # 6*.*L5S3"2@ 4M׹JQZ6G@ 4kd)ŋ4`JiL2B _)Cp'bD#'h8CCa t.\p!p G5=ʂNvOt.\p!_=8a+X ױ4swC .\@ǀу6,4v;B . pw!B .\|`B . \l@\p!Bˀݖ\p!Bˀ (܀ .\8ppے .\0pp!B .>pv[r!B .6p.\p!BAenK.\p!B@en .\8 mɅ .\ ؀ p!B 8X-p!B P.\p!p 2k%.\p!` 2` 7B .\SnK A!wTTUӊ}e~~+kjP}G-b *j^:(l0..0<4 Q;KA?:0$ m^GWݸ{ÃBkmm=GƲg=;l\>HTQQwe"Eo=cqAH2`2oʕ`ƛm{%7*ʿvHJ Ωܭ~BacڣGoFUzXiY5xh;G-'~+ ޭ3b+ʫ[o˖S=:eֹ[~{+}䯾j@\\XUUmpP _}KM -,ڙW 4ZE##C~{R2Ӎw!  98acAmZysItW'H%<6_V5+&4h`~=F()z?-YT2is9DzNm5Yt3837 p )2=amn)l^6ߙSUy-}NK<_g>t-Ԗ"lB kZjqᑑFl9Twq]}W_;[ ⃢j6m*\Ӗٳh5'aVC6n,;~#G|y0UT~}FK艋 :Svm.o@c|N-))m\|g>x%7Zf֚&`,j@}~}y>Njul曬Wj_C.MΩp!iZz=~MYNN [īfUͦZ`cB 0Ȣ }"c"v,{_bcvZV뷙.5 y!ys ǥBVBi./fܤ`LZnTXW.+(Z6SL *@Z*v4fLNrre3|eBLo_ZT觭0аʪڄ0lNn9m2a!=rTZZO7e+=ڶ ڕ:ƍ%Lvl/ݛ^ufoPz=FoUwmVNkɼ#x>$%E-[ʜjhLL <۶]I[AZƅ|&}nDIILEx Tc _yy-;bŕeU!~)ѕ7aJޭ0fS'iGZbb'$Gܫ,z_ǝ +gY).l (ȟt%mB2-Ylԡ2}KI n;G}WcɧyAKM fǑu[TWlZ<&66 ߲ %l!z҂O9Wf}7m3c9wtt_XEUlFERF_WVVٖ#ҫJ¶l)Xё֗0.bP<eET<55$*2d֒`r`3BC`ؓIQCűpP vV5Є԰0rQuUgua=-MIC{}l hY[ʼ,F A11!^]][29#{IaЪ 7|WWsz˳K7o.HcoCΝz5fǎW_ B">~޽S**~ow}in _眳{ņgn+ ZYUcG ; :;K{^_l/[T<8;g 4^￿>}ի_{ΝY!5sgwsL:^{ Y[ `_ntVԲU'G>O?}l-|񥅯dvv҄0&rQ[n|r#攞} ֪d^I}z^{U]gxQJu-7m*ޯa$yЯn=2G!!?;?un-s^^ʫK#~ܱbpJJTmM_!yTkj'"saB2 O /`@XdoWފ(RK@OYiC x*nmu ,)|lV#~úuM@>}ۿM8ԿO>ѢRf}=.44Wv7TD}^= o֜Y[硯0{SN-i͘`/;6]=QpmU͍!Kf7~x ~OWNdsAm|_'?qthH6v;LFġ-=W_5𔓺>yLY]Nz`d^)W\z'&FAiIٓ~jQ~njC8.S?`ڜU~ Դ~ؼ`Z=/Gu E-P岲g9Vyfgjk],[V ua'%fر=Ã.;b԰B7L8, [:gZϧs@GhuXZR?ٟ~sbN ~}o)&CmF?,wNm6kK//-Ëyd"Fގ쥗>/oA"7 R`ŅCfL6 XS0`V V.CwnsF͌~عSwq[:lZ}-#{L>7vAI1?bhCdFVSRBdzjNÃeJ!ԫgJ~ ŰtҵK") ǎfU gXi+W]?a}/‹=eyFFXQQٰ2SZ֭cl EGZ 8<HPK# :enuXi{(xOHH@p~~0ovR۷~D~R9ݏ>T>}R{kXvҹSBIɔ_oE~=Q#]!Ȗ-e* *qZ="=߼e|x^(ZmݜKM%|QGu55懶1='؍7-((`ΜM#ǖ¡@{B<ls 1ny5C1nE. POllhi-bBǞĈiSO?y6Cd@Zoƒe,tiOb Ⱦ7e̺Wv閾aU† zES'w3ZK<Ə?:Cw7_}M!91=HA%*w7O%'jJn!}w~i1"+q߬FM:~ޚGSp!\=#XJSBvExc63e(<,."*仹~3Sc&=0kS?B)2u/CPW|䤁0eQA6".!g1#OW>Y꺅K1[n=d8#_o_2̝yeC}c^_\l>HkH|Ҥwoq |&&OZ8}JzWLv{sulQ:#+Iuw v+cb?ꘗ7߉^ʲ!~yogohg=<#IM0mƃ!bgm{><&.b;#&.ftetc8L9#f~$]|р7^_ 7|Z^NIW8ءmr[MN:۸`~xS[=0-z]ƝɚX}<>w+mzt՗ܳPgGu7yʩ&+>\nG>zj_ Q-?< k dtB&+ 3)AhگPǾ]r]0wE' J$h{݄hn)|yAzZ$F[ MW?R-Ȼ'4"c- =ã_ue&M *M~$11Q0%-E/6*"[9Ȏ3i(\<!6\k7fCAN׳잖n A>cN/,hKBe4p@Q njwƌn~(~5,O_%[N> -I ȅ(XrtML<i⿛m䤠['~}ءCQ\iC 8;5LJ 1>?>h?]vɠ-TmCA+*dݺw玟:md~Ӧr *5,$uk`!tbIw[vh&Loɒ_?*ؒvZam.#S>.$ɘvpذy$ Me@ZP5f?m;=-rK/:'T0&ӿXQW!idm*F5qά`Cƛԟ|; pmM-M0~fzn%? ŇXw5nC 0":{Fc2\KNLpx{u]qs6\u'. U7tءe:3e1E++m*а#l.gGTR meAWp=e%h\ZeSIp()g[zVC6ɵ\*ؾ K DSaWA1.BJ~PkŒImU6?dؾ%oo"n7= zK;v~A򡂅EUnM/1`wN=N&b[l$4(Drr?׷w4<725e[oNl,oSV^M?1/<쉘韝5ꈮ?{Gc}nq瑱*s̗Q~c1҄3s ̵l6CB%Ǒ# 41x›g998BгI3VW "&--g`,1!𨰬yұCUſhbe׶>fGv)"ӥH/n]1bMRbčl/7u^, ѣeLth@p୷ Z%VbTh&۠ N'tҩS ]_t)9UgMwt(@~m/ndlKYGm˶E]-صYfma&%Fj?+sbbȎp5b=['N߃xaO]z9VQR w3Aj9sA,(커YU9wN䒥9H;h()$AAWCy52c;~/sak/6,#:\|AXDԓo{e`ƉqIYAJt\܂0 UBۯN`i||8z).^-&~ꗅ*G\R3l ^DX9i SԯɨC5xCR̙>ty|pjzr[ƴ/1!^'xJʗ9 X?O"S-{Kb}dHWn3O~?rDIa2}_X0{s7ϛseks/\7 E2Xڪ5z>q(өϖ@P.7x趭E_>/ng@=lԚ8\G;!!=dGjy V4e|kjOjja]H_YU#v_mUܭd8>Kr6}p$|gmv^'AMOM{vUis!"0Νbv3 *A矯9m<gq{#<U;UA6 3v=D邋> oq^C fI_ZR%+Xhw/ڴ [R>i 0$DžY/fl`m|]fK9ƽ1O9̳cOT_͙j Z9X)MRtYf4(ȜS*$jIIR|AkZ_C32bylSdwmbкWy;y}%5e*qW\5?0D--dcP͜9?GݭIIVvkwo^l0T/QQZ6w7nH$9f`K˶b<֣wϰ̖Yw^;K5K hK e/yfpq d?C^;'tˁͷ/d F c~W_[LfCG+'՗ںUmLwϿlֹǞ]I?t?oշս OIf:>ƎR/dį]76pVd˯8'}Y0YU^22E^([_v+ @VssCBLJKklKv(EIDAT[0=Rs,9^R)~33׭+]fgg˿}9׋LX ^h!iB8ƞ>DdR]*TUnvx<:`#}<sQ眳<؜ 'Ɗ!4C(>:C8l1փ lF*Nb]HHxbOǰ+m{E+kvxgO=رƜ#+Mig{<82/>m-.40?fۀVƏZaYJX%*3n͛`T0ʝV|y.5ms⪏f ᄏl:ᗾa;e. @ЫZlaj?;n.-E( 80oG鏿իs hszHƇ-`Ⱥ5(.S;i,;^4sm+ ޏ͟.Q2RJ]DU#kd +s}t۶Dm`x:[ӵT{q*].ӗ/ͺy/n^u'nl8TnI[Q-B?lڔȈUyȔU'c q] !|1y1_C8H?wYY:es>uJFh.ܴyF*~1.J |_1|=sTV\K֞v&~,Z¥?(g=^>[獈 |/6RSYѱ/޽B?Hdv/3Ņcpz#𦛧Eȅ=>m0В :&ϛF;P0YZ>hpOsȶDdyh> lh`!Gq*6;1+1Ta"~++.) j^PhV(U' nŤh6u-X`q}SOtn驧v;莌R8/>%21Y^G4p3ŷh)kӺ"w# lu?Y|ld&;$ۮEY؜] xϖpc:[sv%2ͪw%5=..%2B99E3~̙kp<!6@B.r5 Ge`̋T:=n;'.dg[gú_„mwhT/_;"1 ݹiˠ(Q{.,]8Q25% W\8uvՕYuc/?'N q"H%Kw ~\pGPyO_Yn5U9 Fټ!C~0kbٓ@) $ѷ6|Рt;)M{ iM%cV( EOޙ֍ z{ 1<$yɹ])UsoBsJ@tLgV˳/ ̎ z$[J>ŗ|c&!:|o0xP$}s8Mwsud^nwIJFc>,QǼ?$=+R `SƼIm-foL*w8W^u`A@dI@ə7:EL9[؊'?#25P%lQu\[tya4-e*q1ʟx|5}4f>V$''nA8cǎ3,jرcG3$2Wl%>hc&VvUU@>l¾ zf޼t4Q0Tg(ج5yL߼:ܕë*gX9!IFnSW/"aӢm]NҢWHA'|Wg쒭{Yll+o¡*ߦFZ uoyȣN~蝳0rID)C˖l0LQ< RU/U ۣdHUS]Qv ,"`ը Evv:F앇s8 lбI&O2[O|u2GbН x`rQdvD \!(۷[>S-Ǽji"9̹k|v긡0-j!JR˪ xgy9.2kبOrAd'1;ɍ74&}MG O$kd 3x!ڣCr*,cy1š`שmsIM^ F1i 1s ]@Ws6GaD%pe( 0ㄳ:̢0A0d5'=( SN QFr;ípo4V6 QӇݍ%sZЃ_lBIJ6)85˲7S`W'|8O9TQ =M"iE0'FXscb JعSWã\@=G.\)Tч4Lb8 B\ Oe^7 %T"Y?}$ ?߰LQ#iHCySD"VCM'wP65 03Fh] E1^:a$[>%`~tPq=b\-'ŅQ*vzI|QPu%ϻ'RN2Y/S:Jʍ*v̡4ϥDIw Py!Kdz9sQw-$axq#2:*Z,~gmrxV)xa#R']3൵5 L3SSv΄%U_'IefRF/~A<7E^+zD~=A B["BnLmRe\xi/dc-R "@1dDU.6y8 Dȅ?tRQ((s]*~PRi{9 ml%[&Z-!hFp T(V#" .{̀Ux?xXo$w6WL>3rW%&KnWR5;d~O$tf8aS(dbs' .};EO|%HPK0dmƈ)<͌\mv NdA\4 1 Iiw1w#Of m`ZE\*oWd.1=hl qO,@ULɭ>L",[6tNU= VL;xwAzLt;]:#`1Xm #`{x:{K@[0F`Jm0F{{R.0FLgff#`0C`v6d>C߼I팀0F"p|| U0\2qzl#`0Bb\e^]]Fɶ0F#p3 ޓO~,ag0F|1~ zZ4C--bnųWjy`#`@c&kmeJ~<k۷۬Yar[ϰ#`M`xwwwggLLRV #`0_%e9^.k+++^|h;?#`0\`8h$04IENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/treeview/000077500000000000000000000000001457770046000241415ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/treeview/README.md000066400000000000000000000000361457770046000254170ustar00rootroot00000000000000![Screenshot](screenshot.png) golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/treeview/main.go000066400000000000000000000027321457770046000254200ustar00rootroot00000000000000// Demo code for the TreeView primitive. package main import ( "os" "path/filepath" "github.com/gdamore/tcell/v2" "github.com/darkhz/tview" ) // Show a navigable tree view of the current directory. func main() { rootDir := "." root := tview.NewTreeNode(rootDir). SetColor(tcell.ColorRed) tree := tview.NewTreeView(). SetRoot(root). SetCurrentNode(root) // A helper function which adds the files and directories of the given path // to the given target node. add := func(target *tview.TreeNode, path string) { files, err := os.ReadDir(path) if err != nil { panic(err) } for _, file := range files { node := tview.NewTreeNode(file.Name()). SetReference(filepath.Join(path, file.Name())). SetSelectable(file.IsDir()) if file.IsDir() { node.SetColor(tcell.ColorGreen) } target.AddChild(node) } } // Add the current directory to the root node. add(root, rootDir) // If a directory was selected, open it. tree.SetSelectedFunc(func(node *tview.TreeNode) { reference := node.GetReference() if reference == nil { return // Selecting the root node does nothing. } children := node.GetChildren() if len(children) == 0 { // Load and show files in this directory. path := reference.(string) add(node, path) } else { // Collapse if visible, expand if collapsed. node.SetExpanded(!node.IsExpanded()) } }) if err := tview.NewApplication().SetRoot(tree, true).EnableMouse(true).Run(); err != nil { panic(err) } } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/treeview/screenshot.png000066400000000000000000001436311457770046000270340ustar00rootroot00000000000000PNG  IHDR􃪑#iCCPICC ProfileXyTKnX%眓 s%Q"AEPTPAP$""   *(y}|[S]UWul`5!ё܎Nܸ)`eii ?g[Fd`O(7f ӏ÷"#`[o3oag[ZHH?[c;D#6; QMA?DgOHH^@mH~/ۍL7 *<9g ^ GZoۥ0-L@p{i཭_/xE s@o deH}}y@. ޵ 67ݵcҳo`$P;|'zgᆨX?}F# 3T rwhKnh0:@pa  ,, v~Jpؾm@" ]7Jwwnv !hV:Zm5CVӏϨX=. a 3A>w[\B=f 3ݶ]-0f`翽C "h5?͈fh9-<"7ØʉD]#WVt5G俚p|}p;p+3v&z[b'eYMk}⣷NXxBd4pzIᖑV`ko:Yod>3E|Y j`G& ^{#ڎ*X'ˆ?2@MN qpA*8(Yp\Wu=<`F=`A(!: 1HR!=  bP: @ ݄A}f/"Q(A$J 2A٢PDTuՌzFMQ0)`F`v}H Õp܆</h,͍GrmBGO/]gI"7Îè`0?L&S4aubBXEd]:aI#rl=;.p8N g#q]S{O2 2.22}2gP4bZ;dO>S [{'_ o#B| O«mT)|?FAAKLaE@Bqbb@K%\ 1cjB%%% &3e41?tD ћL,%6?SS PiQQ%RSݠzB@MN-HCM>H]J}zzFƂ&M-M -VV֛6<}i:N΋.]7{z,} }.UEZ9{xR 0 c0cu_LLZL>LLuLO~01k20033bfc bgiayÊfebc=ͺFϦŖv;]ݚ=<{?2'G8G }NFNM@B;\t\\\\wOqwq/T )u-sJ\@I_@A!AÂ-3BBFBBƄ)5#+`EDDEEQOPb bbbC{0{3*N,>)(a*&"Y_Y2_G򷔼TҴim_eDedJeR&˶.ɉȝ{!O'o&XS~CAQ!RNaV_CLqT^RR2FY[9Y]yUEA%ZUq ZՙB{}^;ƫFRPPVP?>AҨԘ֬%uE볶vv:niq}^}?IC|Q##/EcE]&&Smf(3cfc-K![VX+KR{llmjmVlml_ uSٻpu(ppt<ȉ)l\RU5udо}}nnnݩI7<0$ R%iȳsK׼wOG_5?5~ :  v! J6.>QiYEjG^sccLƪǖOߟ 1Q?b:+s?TzLKH~br)8M* {Cz[GFJ!C3UBgd dfdy+[~ãGO<{l O!q# h  Oh..)^^W,W|$dɉSZKK?=\]Z_^]ܻ3ug9u.܋ J?\sQbMkUnFuh%K]555yQc.^q2xUjkx]E=c}nhiqmJ7˚rV֡7;TۚnIܪni/p;NƝͻw;;ݛt|}.nhUmSPa#GM7 ( 4?Q|:<6wS>{a/_̼ ~*1X7oEO(Lܞԝ쟲z=5=.?r}i՟s{?>Sgύ_4/:._\z˷r;-WBV~dyiUiïkqS"mM~mln"Iۯ0r|}Z t;n{H+1x,N̉<$[4ʘsqy.M<`P(؃=%AjoSddyd?ݔ?`Ȯ^N9^EKlo- ou4$i3/֙WX[N[clXlYau5'LBt܇޷6>AYUg (B ~ y!XtrLflS<:'c?8 xP%(%5&XzQF!Cәy-)r@.Qcy O8[4?eRbpZTL\YsR&'.U],}EnYC5765jjͽVtvF:v1wv?Ic'^>x.93b4B+3c/?6}on|{gf&fs&/-$~2LK_ݾY|7[\yWˆna4~>4^|״coLߞ5tj|z ١yOP}aio7W,'}5a]wcv7<vC`p%,nl|O":SR_ݤ`c d:|- xnm_<xMx;V  DE E?e-%$%JAneLefd8Z)r) o-3**UTY-I^!1ũժmR_gSRR\~C99JcWf"3s*>tKUVA6B6l+ٳ?ws4ttjrvwyZ|ߊ[{+R' d1US7 5BCB/ˇG܏̉f~s6;N0C$gos+~ԚC.zE0YϳKrss׎L}|f޹] TNX-)^|S%o>({Q>wfewy êVg_:RRKxxOu kenX6&556lUVr;}wt^)}ǠS#/cSsWV*p"P3 3%%% P~L}~@ ( `\@H2D!e8LHIC;CW^ FPHuM7}=dabU%5zHHVMFgS)X ՔrD5b-jC4ѴԴWtm,23d*aVcg9N):w$<:o_1^A ,OQ-1==k%IK5I'Hˌf}oU(PLPV6UReKTP/:ݧELŐ݈X4yW+>kc=h]L~FW}n<$O{19?*{C C?GF#b^Ƿ&'U>X˜H=|80k>'Hȱ|kNf,,?zreYU+j^>~Uaƙ֏mKwwx$XP賟WcgMyO?W+G>\~zߞRVqh @C` <@H٠Ԁx! ImG?* %rF\;|^@+3L*f })qdzdx 9K4e`3bg|J>QǛW=,!*$rs"7Xx~h)/iM̀lPy~q`S³aQ||,ςY5ZY?nрP#,ʯ# B>( *nC(r$$Tjf}hvt zyƩ!S( 02(MIM]BCDgDo`h̤,"Ζiemckgo-.%tTVWtviVYoz5EK*{15׵Mtґ10Z311m6b%alc7wjFAO?7CupYșXθIʓR~Udgr^̾{oA>KBߢ%4+*.(]a\g y]15ͩ{Nq]{8? 9->)7z9oMRMM{7Ac̹޹'R_tH_Y~|t}?V:l^e\\m^]+Wqf:ٺz {>ߛқ>6++`77 +`#ssrss 530 533 1 =xE@IDATxTSWg SF&6tit^K2bF޻rdKh{͌6L@Le26i DZI?0g.>~s$ @ @ @ @ @ @ @ @ @ @ @ N:O   |sjAh)B4  Dc~4 | H%$B@ @ @ s=wB@ @W   @$ @EaYRNw`.@`sgUuCTGJ jΛ-Nr{X6@E|H?R UsǏsuXk: pi )Wd@6 ̻G<܎oT* Ȁ797=}r"3K.piC4me b4D\.@XRrekwm6}rgQ}?Qi, ݹ@_2lR}5C;V #Vd,@̐@G8^uب!7M4JZ,ђtr;bũ K 3xʒ Jk <9&FT @7_{*/ɭ:tm,o J3!0U ϥƙ3yT@"0GS'5SW@'07Wn)8gٺ ]G+VmD၆gĺn1) 9ʹ[LvX"7j! dsM`~dm+-zOQ{X"XO8t70b@@ Gf@Osj~@ q?g@ $#r@ 8yA@46ԕ k pW %U^=<Ӯm%(_4yCՍw?T /^%u}v/gϫhy&c>\(nbǰt eyF\t:'1@3 W7xbCiulO{%/;Oukw7~LFha4#چJ*_.\x66iZ-qf=@ h J訴t_D"}>jeCL/(5~GMoHX)ìI*.شTw:Vb19kJ"mJY6CV>K)P~[+b\e$"uxI|W $L/0׭#dO@qR2_9.%E(@`R?fy }MkNU6h5iv>sW|B@ZP֧m"׭4,/^x <7]tCeWC71qpűd31ҥVỨ@&nMf߫ 8y|$;rC_Sw{Vxpn{ZWeMlI"?Ԇ:@$@rs9ꑾ-=di^|Jկ' eܞVmbIDkV;qoAx.]^%ګ0c,2',)(?Xu~g8F ]QbtD~?E&⣯>4EU)e6_ЩGPVռfѭ/d)zۋnϿ!sp*@ R?߇<ڴ/goAm^ǟAӰj_[pfE&h6пghR9sKtThtA32B#bQV%lRmǣĊ?]3k MQO p fZ )c 2<@NiWU8&|K~\O9|}~F\`%рm@OU^$E}ݬI3%IVX%xx ې"hP=pDeqG3eY瓗տ7_-JzDF|@bD:zK3!mp-]Tn,oﮒU;~[*&vrǗU<¨G lv}Ǐ xN}<󳚟n=\ Z|b6֙Ur8Z5<ij{0G}b' t{QHVt$l-Xl4' !Zhy^W(ˊw=>|#!zHef1 \H>5p\@(-pոռ^I0=ܷD|Vy?Ao߷8y^O[\Z]ʓ3N$X6GA,$@&Yd7li0ܱkҨ$ d"RTy&FPC\šĬ{RD=k23\q++ 33yG1 AmQrJM,Q$#) g$|gp;uuoi0c SČm@Y'gbh RH R3h  f٤  BπIl@Kng@$c6}JMCkkC]u1sXֽ˺z\_}բm+_q7ΝD(U;_7KtHگp %j43ckZufG@FY5g2}/\(H wmV?7H7x!% {nJ@m!wOKCU8B[XFNz4ʄև#6(@`HP^N}F~oӾJ+:8UMo}We}դg?XwY6BbE\.fGQ4ɾ"ʉlوFF /A^Nc 50΃dmܜ;=\˔k֪dT[~?]pqd3E 0 |3R=݃AبqE iWU$[r:h!~v`u!ӸVuLC38Uj*45'~Iǰi'vd܍!׽F7vӽ$эwif6; di)ķFmn pg5HCPcέ.] {_R}!OZ_>yK-HIl kQU)_RP+`K ײ"gV>ɍ+lc^ڹ-[iڵ+OGPhw9uU(ֿ4 0o?=?(mkb:y^8%Ȳ]{&)_DbjYRD&c]{aZGAҗܷ\Fce\J?" =z8T&8.ѽd6Ik{b+$#sXR:L/|DJ3@S$Vh}Yd~eZcotHOݎĔ`+ݟrW%NKKC^ēk)HT |K̴tk^O̘?G)((,V/ݮkr_EvN ϐ㙟5(XlWIrEEv7xXJs;l65qʆ ^ .~ _C g85"4Am[6/9(l~0΄{@p @`!Ht!YRрmcOOU^$U$oPݟ٧03SU+`[;%kJW<Xx?m1H^VB.#ۗa ,٢yB(}d{Th4;:Nkq,V/uL |/'g@` pSvcyK~w'(:R1]o{U<F={v5)_gG_BR_ />]+㉷6hH4 ǞL{ZI.5%$\_*O(0c?͞g+ $U5}+d/DZ"~1ȸ6}Nc(sD*'ˆ=L]Kg;‚Fs#`P—z|GBo-2|f @)}0e%2yxm=-+ d ROGC@@B@z"@`!E@ 9XR}~.v4T7Y"jj_Xq-a+ԺTyY^OZ>}֚g2&CP'z\Ŏ&$W7xbCiuEޟ~%CP^Q)RL;99Ņݍw63> @jL^xt^!HJ_ 5cyAHCymq=X\,xYҕR1_QZH2Y7Ky竄t҃]-j*)n** COmv/P  :z-o;G jFX)4͌=pّ-ljV]t eWO=?oьBMzie[Ѱ8H+4;~/Bt]oAqHX"sp( 3sא !jx k?}E"Up&/6;)w=GZJtrK'V~=!Kz'Њ[HS4TwEy>=tdVkn7Tl"Xy"KJ jΛ}g)5L*9\ΰ!JP H?bwLz9}sM{V+}v5$]anjҳsLk/!^0֒&L$AIdTn x9^~>v[#ī@@@"o΢YP{?U=F >h%+X)02"xYctWl|.P)a'ZPXMSfg6 :6}VCC %uLyy<'^Kx¬FXp@ݭNq*&Mg*p=R!^]@*SBG# ,d5?xR$Gx3̞M~Kv7ۅCVՔ3s"TͿtJrN#.{}M Q5d H.\q{HL e٪j^]`m 콻]$c VRM~$W5 C^i=q]CPEHid/Zܬ J{h$+۫SC,\ ILeoYĚ-q.4{.;3!yutLry.Ȩo,oﮒU;~[*[[F<2G2?݌<~rtwy%_lYѦ?p\sq%9|&-"$,Xl4w%tr8x6/->$[pzԵ,UUwTch@ 0f ؉㣛!I`)) $  /cSa2 JdzZ6W,8ў8x&]ܸJbm|fZ?_(;:|@MbƘ܄+XM{ρC;)]q6v޾טVC$Tv#@t?fanfR.WP+gO\3Nuꡬt&M減"T,t:dT-]<~2Fkj fH /_K`@LiQ @ Ӏ@  #2@ 0 ? D@ @GgJMCkkC] #);1ۖR%\/sv c`^FHQZLdQ.s:$jl;[S5 f?7*]}Af{k{Z8-nHPAlوtr@yL ZF&ϒ HW=WK#>cr8pU@gF (ʕ -`)j&ML\VJH,}nhPTT< yxͯ  f@jC#'EZJ[XreB@Sᱷ{bYM!nQ`8ϖmӄ~_Z| [W HU|\NF( UgS N{d D/,mm:cWlj;1d6{~V SՇx'.Y-b65v:*?g^e !YނTh^$FlINSJl^Sߏ\y`F,eW}ȬP|{->dTmP(Lr4{pW*|:oj`BwE9o= ?Eeֻ^z%u=kCXKH;7B|vӽN>6B8mwGДl@#I?7'@O۽eR1V*IlHzBϮZ/߳Uʑ®J/~>)4|Oe0g6|}e]$ Xxv:,MwՊmCp \ BYA֢{Iܟ2Rx,ֳʡ 0ϴԙⱷV$߯#= ZNnku¾.ǬI [#+ro10ؐ|Y& E@gs? !H"3ZFeE2tdIϓM/|`o%k6dl4(M85|9*!z1) 0fSmt'ڠiՈ2=_vwM]n<_G> 6Ps% yjds?f|K$xS}|<Ul1 *͡K8)Eh<+eŇ=$2 @ss;ṗ•kɏxaߘIMG㡄îХr[(pM^$Kyx=Nǐ@o,Q/ű!X56\L d1e&) 3t x+B%v㋈ :U  `IftJVN+`;rJ5 pq~i`2@ u|*u]@ $&@EE_6t D?T "?/ H"I w9~|VI+}v-Zlj(@,LwTk7v]o(@zP +@XWlyzŒsFC0qԃb x evyƭ[k r9BfBݸE F%R(5Ol]V %$BZv2VPW #<.oѭwn2gV6>Ro "WVl^}r}a4c[@;7YW4rZ e2m61Iy=Z- o7LI88Y_Y{@5K m7lՑ0gÇ tЭZ+q_:;h1[ 3 |3fh(9={E!y` ۏFx&nl!] E6@<(uWp;Nm vnPo 9]#,P  0ZH,21Vs8wWr&+>]C{&T]'踲Q{> EnSZO5*Gs UWtaO[J*vMM5|ZUBcd& 42B\/?Sbqs2,T!K@;@CKB}{vqH! ~-:ª/|JY+@R\E)Zl=[ǗVels;}Wq wOf*ל* %@K Cy8O>SѶvmO.[ll3"[61kf*J-#ۻphuk<ޮ,+^$߷' )7 l HB pfJMϠ[~2-{;+~\3,nzeJOn %7}JS8xGljv ^Mqkl>rțyjK8$-5ߞ0Js'elH@Y#Ǖkn]#:ǟKGAI\-s@bpQKgD'B;%ؾ2'={m:6ްs`!ai*??[K‚F.}~08WM_ҪW*M`G rx<}ww  Ԏ?Mz|QNn.v`P&ȕ׿X$6>;40͎hrJ"++q^4g$r9Rg+FSȜk;q'( -xlO73yyr@HcVsj}q۶8Un8Zh& v<`JFO G̣[d|QjG`Fu Y B&c߮=Fa`q:7'Ѭt7OxRX(~B@B 9@,?7 @ր \??~6y#O5iEU(Տ?t[ )#G֊uraSLJ2#Sv <)6վ`CXWw8rvr NS2ųWQa:slw+loZ@ |;9Єzb[LlyzŒsFCLXBO/V86<@ (enƮ}lnb/?ึ"d3[2[/,M&WqP/F㟝[TW.E5Mm^ V/J^TTP/v+DB6ȕWߟ\_-M!8 r9Bf+qŽЗ,FK@q}np9BL0mH @`AHW MwoK~+N! o%$C+௃]>jKCՃwå x2]@gvnp~Y\<ܶ>;ݗM/H[3Bqh{Ond~0<U5@. k*G#cu#uk3g?\ (wIu Z,Kۻd|ZԶ;@"Y[e)i, C5~}ܶEx5ݵgN&b!^G:v^l# d32оUf쮔[^43%tg%q>vJI[ght\ĺ/iCl'lCDPB',={VPMIqA@+nU6mi iYo#|b2i{񤑷 nXrX۰H&DhB* 9o;򵄃_ykcߧ?+8㴯:tⱠ `m6mO .ɀk^Yw,g0Na9(~nz'(qnx*{0vxq%v/nӆt;rᦏ}PХݤ؍,%k\kT yM'lK%d(:dn[?wG Id6hpxdB5?+zV%U}arB0톡 @jGp}&\ڵ-;Gu.#de/s`)fK6!xV,{Tu,+^$߿tܸpH^} ϥƆ4 jLi̬e߫tLqr2Jݜ~%|W˸7}2%Mz.l9 qAe5PםثJ( uEfO]@lqI (F@ekOpƊ/i=q]3|Ńkl>rțyjK(6Ķ pgH57~s$U]'tɣ2qȃـŗ4ww\J$"zo+cegz&=mN >vVk ͱ}eNz8x΁]/}cřJ){IHHtQ>zH/ '._Z|Isz3ݑ86~@-'ww1Y yh1o=cRb<U6Y.!Up@Q@jKsqiB똔ўI-O0Wͫ;~#dݩC8 s3LjmoF'GU۪k5Up;z{aaqկ4[_B;P_O5͌z{h y`攮vGOHZM(*c8~FBTWmj}ўeTg|8΁aȀay$!vp 0b_%}[w5+sTq|  oPRnyIXΔmfBB==Nn([r&z0@:dͤ+ӏj; 'Za*fe,ga'5ɰр?[4W ([K͝9?6}ǧ!L9\ RAPV~~~(SʣV'6u銥.S23||#e8Y~s\ęNdbb.MFք\8$JwL">?vK٤uaZe9{9tEW*M$́@`3<;D!3)Vlr@d3Ni).+6n* 0=U N ]B`n?Ѻiyb/*P(PFmoԂ`,rmE5uKӹ\<fw\m D _%.P쿚#@=~P pq~o HBgxDȵM}ی긽Bm Hy{%Bd @*z2<ׯo@T'5 H Wx]WB^sa6Kؼ ni2JYk&֩YrJb)<3Ԛ-uM 3џ[MӲ0@)R{ByPu@L'}ѵlI^gaɵ]ç0G+a-;+1U|;~#$GN] )eCX@ܕf ;`߀ӎxU')kګhv :GX\+ jh$K +Hy<<΄3Bqh{{08L;86*@&k*GkߺWo! 2u.h\I 2cw'򒦱cͅb~qU%y"ȈxOo7гN*1 r[ܾB^#cbl 4@ܭ¾\#4û'3T\v?g#1J+zm$Aݶ<|w&J؆m- '0'4vw:?sS2$xbVi)5r}M#.{}<8al=EI6@޺0꺗 %8_IqI>[j x9$Js?K2Vш{h$^ UҬ?xGljvgW^AwzGyC;Ob %dC@dw)y8GF"=<6_moa,(atlADX@|b#d?YiYEfBaڷUO Ƶ!&\ Fs0 9O8鶴<7`1M}PJ;s<[(y^c܉qzx§v@,]uwZ@1<#!lv'Vohc @CI囦 _ JJna~<.];s7Ӡ{v$B s л~sSXXͬ(V43DPl~].+6ngy." E@A`\ѳ[LvXVިճ! uYJSksӹhiwJ,Zp @gsj>ۀ@ A?b@ BG@ x\3T<"ZO?AA  !y{%R=EEBЅ_n }c<(@Pr@ 0}ohX%B>a>|!T\(@`R;뺂ECFlB\y\\!7-L%J jΛ-q|ʊͫ@/&#{5&hOqŽЗ,F~55[t]̙f?OfnC| Sss~- Wi`Tk>9{ֵwdv]y#.Rk?Oӗq8uv#|6܀C'G]ahDN]k1mX <%9 ;`߀ӎxU1&Iˬ$mtMSfQШnnx_#RִWtb]aqկ4~ixym}vM/k~_!8}s`'72`j?pvqmn XWI?$}FB@^quçJ4LbkC;V X^n`<fd}s%bRnyIXβ32Acg$eQ`^%)%[u_6wؤEYO؆( @1@` IOZZikS[WX*xp B4O%Ci(S*EPhY#>m~{zL _GAy; ƾO+$2~;D8GQ>F=8{mՇ #0'W _Ӂ9\f~*xcvriXwRKG$+T糡;IOi!k נV%x yM0 _ |$k"{N$4ݓIK{/W6Kr2rB02@yG`nK <ɽG";KMd Bo1WS,+dnIZ Wn\HjQˈ>ac:PA 0}\]r^+S%~}:H4D䖯+k)67;=QN"!Rc^;7Hq_{3V)MЦq|Ńkl>rțyjK(6Ķ f@fB;m:۽~d+kn&V';^N]Y-V]9nf3OL!U/!qJ盾"^4۪'mi .?<CN2;jkR31Q | ;6h'kۓ(dM{ρ75 <#C3 bX zSy'j* CA8M21z/BlCH1#!lv'oԎg @W}EAT=$LGW}FDAF#-QJ.-Eb ȕ\q&8o4GYkRPx(]; >xZ^Lm!c}ե$r@3>)=='~hʢB>LOSms1 G*-oV,E*a7jy@;YmE5uKӹU ď_@%@ 5~Uj̆V@ 5`Uj: 1xA9@``Z@`V ̷sP}z>$l2! Ӟ}rE ƀ. J`G֬qe|JC9@`wc{~1,@_)8 kX'B &o#ښ.B_bha6@NWZYCӔD/yCM?FTs>Fl6LFΰ@m(ўj߄ۤ+nڻm6|@ >F^ |(gL[iHF ,S<\?–\W%Kg9VzQ^H1 $p"hoYZ C>/ԷLl6+Q-k_ck44R6q7L{듫`?/Ėcj%(zmU6YQݰNE߳7=J]կ!,mQ* +#eI ]']֬ X$-d?nI񐉽? hJKʬE~֮I-a\r&h& vÎ$b%O8Թ^7'vVw?(! -^'f ac0@H ~*yz Df wo<ۨQzis`*;՚]+6mwHvׯ1zv W?# ЛbCP]s<|i%? LH(6tb3U;qx z͖ÇCj4b*_@q'0BJrXt&?U"\ܸAY BqbP dі[2gΚVҟL O;j-Ɯ' /k6>ݛºzVv$ts:-C ӭd`pSdz6UJ=* ^RBywZv#4%GSd-ӗ[iWCw_gc)^* $F? ƂNn<;NaM Եw긵b`SI/OMKg^.rkwv@(+:5"Up,0Əle[Kk[w!RE*3:svOKxeKMN(LE}_25Zn{[{{8;F\'Rq6GH 鄏?Fa?7V^tB.}lciy 􁞏l !  j_ ,HD%}O2ny%sI~V{vS_TL ^H2@@H ff?b.T7;t\N-^fTG}H!mat*oj,%˰% yb>' D/@H`<QYd|>|Id݆5Q@H`V8*?P@H a ECH L)h?"$FGP"$"0ǗIS ;V $0 L߰;Qb@S| Wv,@H`c3 $"q~*! `[! !wز; ~]ۘ"1>B"d^`,@ԨZCH xǞ|DUXpϽ' Q`]>f!&H- :!wB~5!@ /^ֲ:x"(!`d|`0bas| cp7Pclg/ vH;@H D k-܇Lw&y(PyKװ7!$2[oYAiA+'&$5!X?t=\B` O H $@$?l&$`~*:Ѓr]z@H ~ğjDH ?Db$n {)9fq# !~_ E $0 $W6_wG`xCtGf`Wg9!cSc}5Ұ` $ %X1>/ύeBf٦ N2UB ޑ@l{-L2*xFvTc"`Zxeɻ.$ y}!/Afa#$ۏ1cMUOԳl x}pby|]Hw%GBA@C"Q̮Ww2̬Ex1pD;@H`*H\!~7D~hU ZLP'#$H\m}N|)̖'vOqGH ']|E}Eo;)dK! $!ˮ`U՗SUpX &.r5[!B`+F@dt fxg|Y&$s+ $z ^A!(0  $I qǯD]48#$Hpp$qj@S@ۏQbb.X]$@_=у@%#]L^'V_xtfvumR&77mqj2-rπhVeIueg|j~߲6T&c/&'"%u޼LF2 *Ьρv3D\?_`&nB9ħX;< ˯]1oC7d/ʳ֭`fҞ6l܂h6-܃{h8$"u:$&#}+jo]Tٜpl`!<Vs0d6uZMY-#. \HZ[`/5evm;2B[6Rkz, upZPlGӫ/Ư*CѓK$`Lg4|uMW-X>#$~&c݋٩iԥ[u'Ӑ Q$X+swO =iYKy,ΧeF{b؛vaK{ml2F(+.؉Ұ=0 @퓰ȃYCq"d3j4ZOZ#'&F}P|cs !+KwZAwoOMmWfzbVS%7n{[sSs{tb(d1 N q$Z֥SMVyokTQI9ꊍ%!yC[h;wΪ>NCz `gTM]wg(ҷl';?{sI2E {w;~u{IaU4bێʆ  )ҡ8/n6FHUH` H陙q~Z3U(jfW)cq`y//ϿgBzJ`dݸDXv$%v:rqv^*rxƹh\0o^r1 IMLjCݎI4BN*,jWbܞTAWj$=oA26eU܃'!.m%tޅ3IO6_"4~_g20%.Y SԮ:ҡ.tH L81ҷ8WkQo'rC4A"3=yzFbJC0\מK^ 4?uGKC2*X F+5@ FǭPk!]jA)7dާ/53twi<8?)4Gi(}.N<~[k'HR4p`4sfqS( %߭,7*LaIR S_UXmVlte}[$[⥇et8%C$ :Sձ'טlW`UfwRن$&1IV R\Ybhe 23ӔRd-ӗ[p|B!i4b=n^50i)7h`+XEHM5ꓥPkoiwt9+CH`g#zMh4ְ˯@QF d&WũZZ#Qi L$#Waq@ڏ "H IF${aX\$!c,@H`@1^ $0A /dp80|駧#1΅@~2ݶ ҤҚS:c^H [$W#$(UR6ܑ@%c`u^o~g6~;h(zr鴛5D\ݲy3o"hC7̛A_(Сrj ,k#[E^SxT+n~aá <{f,8筿k3I">L0VAH 1 rx`f4 ԠUH؋ƚ`8ŬT6惻 +1Ew1?U&DQպ4+BhG]S%#{ 'η~7gdwUg<=iݬ xGH AՀ.r u3}?Թ^7N" $%0TӇpnv߉ zs:Y[+,2 gp~wH%J@!/vBj|RA$di ƈbCQs]sS!MQ3* $0 VAK\\W*h8O!=f %wҨ{O~r69bNΎ"k*+q:Da0{hh {6R׎dnN*6p8J`x҅a@ `#2!c7s߀{v ,(>D?gdp8N$SzlLP$|A+k(3j`!x,ZrZtv]ߍQ9 #!^cH%loƞVR [ ^xЈz)#%7uV|h2>xJ>cz$2nCIE/Nbgh?fc[1FH`*WS-c@'#LQ#@H`*@12 $8Qk.˻WN>9UQ&Kz 8@G j悥Kl;>CH  ' D/OW7V~SZBH`@1a_Mlqu}{Tk&՛V-S=r;m-P]zc qaEu@SۭN>wղy+g+,%ZCE?9lpX"Gy5|{q?9<(IhrFζ˦/xy˩577\]giSsrwPӓަ%EF$4Mn9}n uO?AX ]eCitRw~oNW]U0K"8OOwZx%5gBU;~hK R TPy{ H!zsk(D (p* !yp;NiӟK j Oo]%mr !Db;y:sU>3#Gt;xy֖\ GE` j<\ݨ}P(AZR`D&f<\$-D]7 뛵v;;^h7}Ixke?W-Dj@yHM}[7ښxD}(H 1_ߚ@lTgw_eВPOYA ײ˾wex)}ļ} ^{9,;ތeVJG`jyyS9a']ۊRQ~-CH`~jUa}M(a<&<⴦GTtLx*5ezB|@ IJ:ֳ\4V[:B/"|53R (H  @qvi!=E*Wf0~wxN>mu'm}.xw'<ݒ[DҨ$jMHT*ib rQj+nf2y/l1tHdx^fI2?R%fg4=>AՀ.Ԍ yV $~ϠtS׭XP"HW{~ʈu_K]i2)7?e<_\AZDHǣDzPI/Kg TߊWc~0%cD/Vg̝aVZ!=-zaR*χZ[?smVduFb` #gKI) EM!6%QK|Va^CfoV8d'(DjB4t(Dnw8#z)!1 LqO݅cf'ouD`mBY a:q$<0vB/4:517f =)ﮬ4{LUN8^c Vl{ Ng*\AL=coT>|RalNH ! xa1xJ( t>!- IDATC+s%sT*[ۦ伱L~Dqs][8h-R3OgW+mxT1rK Qڑ鴐'N-u"Å&g dgvP*Bo '4%,XSd-ӗ[[%SeRI*U %MzNԛ2l5 q\nQf̢kl, *> $? ,| :DLURqu^oڝn<;rAO%{~Z|~q!3j?&?iG,gJمHu+W@y'me[Kk[%RE*3 8ii$x;~Q+J>~?dʈng,UH+}^X İmJU\[T'"$0lK1?W8ktEsO?\/W .}l -2d: ݟC>~]CbŐD!C9Kv:a.Z3K@7G.kȅ-Gη-րemrzuX[gWHGīCSc@Dƛ:ʒKV7;t\N-^fTGDX5@hC܂ޑNǯֈ{Z-K2l2T(%"Ћ@~J ƃw{;/4꜕oMSgLO/z:m(o"9R՘ 0mTh>cEh@q! $Sc@q!#.Q @H`Hs8xN=EϦ #$ƌ@?MB"0f(1#$"p>Fy6 !ɣ O1H N qǭ;؇kWU |RAH Lv8I!?[rDoj-׉B`뫄B@v>'B v% .p8!Wy]H['$&_,:GB~Nȫ{x_egm=1gA0_/GTH5"=%G" ˰U #ޑ@@_A1! x!((di2_ C{T]oaWKA$ H H`q$L/4BΣ(*JXAB`}_ŗ* IðEHy'A$tk` ]DEH LTl?23>^`:;>~ԳހZ>%'cx|> @ w7q\ !v=1"$&0ĵb7FB]P?R C@cB q9]=x*$ d;;'O-z@@ڏv!d!am|M _EWnm^ L=) oZϝCnsQ@ڏ῍etxJr2IP+B>~vºqpWgC y. [PQir5NQxnǁ_0cVo^"')g[`4=mJmZB5524qvID\8+GuH Lh?F"\Wle, ٩9'D92:-,Tx.Zmf-o0חm@!-Rd5=:;=CWNZ3F{J EO.v󳆒Q3Ѥ[i7]]z!a@FLjh7/߽6L]U+y< @UJѾ2']~Ԁ(Yړfҽ|Z&@h$ǟ.6i6Jq~&ctZRm" z# $0 > WKߺP~*0mxm!*)8G]D"$obhkmG_Yԇi5B||S* Eygo~=Rhanǯn/)ߜ&w6UlRٰ\!#7!pC:rm79[a5b@B Gfff_LJd*Z|_X+*z\.o/ϿgBzJ`dݸDXv$%v:rqv^*rx$Źh\0o^r1 IMLjCݎI4BN*,jWbܞTAWj$=oA26eU܃'!.m%tޅ3IO6_"4~_g20%.Y SԮ:ҡ.tH L81ҷ8WkQo'rC4A"3=yzFbJC0\מK^ 4?uGKC2*X F+5@ FǭPk!]jA)7dާ/53twi<8?)4Gi(}.N<~[k'HR4p4sfqS( %߭,7*LaIR S_UXmVlte}[$[⥇et8%C$ :Sձ'טlW`UfwRن$&1IV R\Ybhe 23ӔRd-ӗ[p|B!i4b=n^50i)7h`+XEHM5ꓥPkoiwt9+CH`g#zMh4ְ˯@QF d&WũZZ#Qi L$#Waq@ڏ "H IF${aX\$!c,@H`@1^ $0A /dp80|駧#1΅@~2ݶ ҤҚS:c^H [$W#$(UR6ܑ@%c`u^o~g6~;h(zr鴛5D\ݲy3o"hC7̛A_(Сrj ,k#[E^SxT+n~aá <{f,8筿k3I">L0VAH 1 rx`f4 ԠUH؋ƚ`8ŬT6惻 +1Ew1?U&DQպ4+BhG]S%#{ 'η~7gdwUg<=iݬ xGH AՀ.r u3}?Թ^7N" $%0TӇpnv߉ zs:Y[+,2 gp~wH%J@!/vBj|RA$di ƈbCQs]sS!MQ3* $0 VAK\\W*h8O!=f %wҨ{O~r69bNΎ"k*+q:Da0{hh {6R׎dnN*6p8J`x҅a@ `#2!c7s߀{v ,(>D?gdp8N$SzlLP$|A+k(3j`!x,ZrZtv]ߍQ9 #!^cH%loƞVR [ ^xЈz)#%7uV|h2>xJ>cz$2nCIE/Nbgh?fc[1FH`*WS-c@'#LQ#@H`*@12 $8Qk.˻WN>9UQ&Kz 8@G j悥Kl;>CH  ' D/OW7V~SZBH`@1a_Mlqu}{Tk&՛V-S=r;m-P]zc qaEu@SۭN>wղy+g+,%ZCE?9lpX"Gy5|{q?9<(IhrFζ˦/xy˩577\]giSsrwPӓަ%EF$4Mn9}n uO?AX ]eCitRw~oNW]U0K"8OOwZx%5gBU;~hK R TPy{ H!zsk(D (p* !yp;NiӟK j Oo]%mr !Db;y:sU>3#Gt;xy֖\ GE` j<\ݨ}P(AZR`D&f<\$-D]7 뛵v;;^h7}Ixke?W-Dj@yHM}[7ښxD}(H 1_ߚ@lTgw_eВPOYA ײ˾wex)}ļ} ^{9,;ތeVJG`jyyS9a']ۊRQ~-CH`~jUa}M(a<&<⴦GTtLx*5ezB|@ IJ:ֳ\4V[:B/"|53R (H  @qvi!=E*Wf0~wxN>mu'm}.xw'<ݒ[DҨ$jMHT*ib rQj+nf2y/l1tHdx^fI2?R%fg4=>AՀ.Ԍ yV $~ϠtS׭XP"HW{~ʈu_K]i2)7?e<_\AZDHǣDzPI/Kg TߊWc~0%cD/Vg̝aVZ!=-zaR*χZ[?smVduFb` #gKI) EM!6%QK|Va^CfoV8d'(DjB4t(Dnw8#z)!1 LqO݅cf'ouD`mBY a:q$<0vB/4:517f =)ﮬ4{LUN8^c Vl{ Ng*\AL=coT>|RalNH ! xa1xJ( C+s%sT*[ۦ伱L~Dqs][8h-R3OgW+mxT1rK Qڑ鴐'N-u"Å&g dgvP*Bo '4%,XSd-ӗ[[%SeRI*U %MzNԛ2l5 q\nQf̢kl, *> $? ,| :DLURqu^oڝn<;rAO%{~Z|~q!3j?&?iG,gJمHu+W@y'me[Kk[%RE*3 8ii$x;~Q+J>~?dʈng,UH+}^X İmJU\[T'"$0lK1?W8ktEsO?\/W .}l -2d: ݟC>~]CbŐD!C9Kv:a.Z3K@7G.kȅ-Gη-րemrzuX[gWHGīCSc@Dƛ:ʒKV7;t\N-^fTGDX5@hC܂ޑNǯֈ{Z-K2l2T(%"Ћ@~J ƃw{;/4꜕oMSgLO/z:m(o"9R՘ 0mTh>cEh@q! $Sc@q!#.Q @H`p2kBCFB~& (k{*@t dXLG?, u,#䛄, D8b BH LlS~]9 #guqU!$ƔcJ3CH $&xu7!fvq0ʴvze2K,kC8~%YB\N^`,Z|{&G !/H*w<,| A=_(!fyI5"#aJZ.(ͿXN"$H ǯ%gf<`c`Su 7hO?Zj4siMO3y~1 . ]n< /X(4% fɗ<`3$r$#M7x+oaIv2yH( `Q~'<w@6Rg0T<B&\ ,c67K` FB:vӲEH "æ/H &pVf`A \a)Ӭ9=E]IV"3`̰Nd8$| &A?L= 9,o'"#$07! HFp#y}-fFh`<W9 oN%Vxz0 ~ 7`E@B7g p ;3v ]!H $p[8eƨ,7Y,VB7 *@tZCMnXYph1fY8B,"$&Z1"4S AH H񫸰A%H $ڏl0 $@ $@xh?³$OGx6@ c@H kA0x wQ9Ofa$\3yc'j ۿc @H` s#[f>I3l&f_輻0$M8~ッpw0-$e=IH(x,^?c-x2D=hXFW#o>{P8 tABG|AH ĉ8ۏ1g> `] j -/O{3?Π/?er 𳪾ʂ@uA Q a~ɔu:!`0@A|f  $0:n>,a`ph(ુQVm!z|L)jYY5р̰q*O/ItS^$H8 ,RFB]e(LBa9p0f~!$ƃ@@w>F~aH<ͧ+"$Գ8~ dq6`:UL߰+^@M LA2Gr j"H <B _{2ĒŧNaƅ…x#$ƅ@#2Rf *6!_GP/|%|R(p`L4PGe~"x!jl 0v]WG! #$ƕd+9CαB&_|ϫo00ĸٽd+J+ZYA0PYv5]p- @H`u,e jv8!f+ֆ$#W%$\.!\!yb@H`BH+c-~3bzƩ_8K"gN3#$ƛ@"_s'c;f1pGרʑ@H $@̘1nz/Ia@H`}Xq˒IENDB`golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/unicode/000077500000000000000000000000001457770046000237355ustar00rootroot00000000000000golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/unicode/README.md000066400000000000000000000000361457770046000252130ustar00rootroot00000000000000![Screenshot](screenshot.png) golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/unicode/main.go000066400000000000000000000024501457770046000252110ustar00rootroot00000000000000// Demo code for unicode support (demonstrates wide Chinese characters). package main import ( "fmt" "github.com/darkhz/tview" ) func main() { app := tview.NewApplication() pages := tview.NewPages() form := tview.NewForm() form.AddDropDown("称谓", []string{"先生", "女士", "博士", "老师", "师傅"}, 0, nil). AddInputField("姓名", "", 20, nil, nil). AddCheckbox("年龄 18+", false, nil). AddPasswordField("密码", "", 10, '*', nil). AddButton("保存", func() { _, title := form.GetFormItem(0).(*tview.DropDown).GetCurrentOption() userName := form.GetFormItem(1).(*tview.InputField).GetText() alert(pages, "alert-dialog", fmt.Sprintf("保存成功,%s %s!", userName, title)) }). AddButton("退出", func() { app.Stop() }) form.SetBorder(true).SetTitle("输入一些内容").SetTitleAlign(tview.AlignLeft) pages.AddPage("base", form, true, true) if err := app.SetRoot(pages, true).Run(); err != nil { panic(err) } } // alert shows a confirmation dialog. func alert(pages *tview.Pages, id string, message string) *tview.Pages { return pages.AddPage( id, tview.NewModal(). SetText(message). AddButtons([]string{"确定"}). SetDoneFunc(func(buttonIndex int, buttonLabel string) { pages.HidePage(id).RemovePage(id) }), false, true, ) } golang-github-darkhz-tview-0.0~git20240308.6078a88/demos/unicode/screenshot.png000066400000000000000000000265301457770046000266260ustar00rootroot00000000000000PNG  IHDRmiCCPkCGColorSpaceGenericRGB8U]hU>sg#$Sl4t? % V46nI6"dΘ83OEP|1Ŀ (>/ % (>P苦;3ie|{g蹪X-2s=+WQ+]L6O w[C{_F qb Uvz?Zb1@/zcs>~if,ӈUSjF 1_Mjbuݠpamhmçϙ>a\+5%QKFkm}ۖ?ޚD\!~6,-7SثŜvķ5Z;[rmS5{yDyH}r9|-ăFAJjI.[/]mK 7KRDrYQO-Q||6 (0 MXd(@h2_f<:”_δ*d>e\c?~,7?& ك^2Iq2"y@g|U\ (IDATx|E&TH("% )r6DvR[@"x`9;)@)J( !ml-P..;3w>3nta  >GvHHEHHP=hU h xMJ$@m  "@bWIH$@$A(4Y* PoH<Eۃ&]% 6 h{d$@$@  m,vHDP>VϏ/_+_YH`H[K[(ݚc;}& G^X3R/eG]zlo`ѬڈV+|`If^?J9g^Ͽˢ)9 ~YWR1 p&"ڝ^'U-.MhL5D?`:͑P O 5r`.†Fa%;CRmHK8FtU Gz Z~2м!D[c܋֜GBkZ, ]AvW S bPpOk99p1BMNA~;}#h1ȐUjQouKnr=E;´e/Qԝ髬眿uWuK|̂xH7XKgM$@M_i ? DHS Uc8b~X?3oCHlfW#BpivmGp~8XW/wW7ڌ4F+~؟>$ռXܪrO[J1X 3hZF@ִdSʈM$pvv%c; .{'ȓ4 o >tKWiYHvO0hllUq^Z=rY|4(Z}i8u%S ŀfV!/..ɔZ)>HX2hSg!!Z,"QXD c<-r/V1I%m;DȖ# pmuy r& ܶ=f5GOtlbĨ(ϗ{$n> Y&#ѵY>ɁN9 aj&?ԀƓFY{hh=9;VG|"Iepq'%NskeOQ~ҎWד͗.iĝk G$? F1uddÐA1va| t94PzV{.Gk+Wٌ,G׊s=-Ӷ,r˂: (`KV|N`| :RW+KZC*?+;RHHhfn63^E?dmY3 {w£=|]v.p F<:Zt:m<?_ *}"tsd @%Xn+CXis\ÖK[|"iAaHh'=K㱾H,*b5??S-ťb  :mI' Pfb4 $0~$TY6)j+B^ E^w2X+?J8S t^6bW_ZrGAT]QY?SH$PvT.XHE۫!vtx s|$@^EWM'C$(> Wh{tr0$@N3 xWM'C$(> Wh{tr0$@N3 xWM'C$(> Wh{tr0$@N3 xWM'C$(> Wh{tr0$@N3 xWM'C$>=þ:#l~yb ,_L<; (E#<ߌ27wދk䗞piwҋxq; X!}TARo-?{=L /$=ȀY4 q rj2ZI<5BZzMX.h2Kl̸GmiX@`@'/P ȗ<5֝"W;_"E$|@?ߕ,K(+ TM# ~> p!M:0{눘өdB1s~ԈԉUZ^(v 1CbhW%\",S nHB;V񈔮>[Yc"}kow4YqtR_ ́ϜD['ט'^[)IbC i3[$5v-* pZ'~H޵HyQ/` &GDH=.u`JAM:a&1l\vDma_l#bmnv(> j(j+c@Jb%7Z|;*E gҗRw  wPK.fԝ0 }\`[Z0؇M9daT:s}Ɯ;;^HzKɇ*W{^Q> 6CfQ @* HO^)}8LD[NdW6rb*pX[݈}[6SF䮑['nq? :_rGJXxbG?hږo; N>E.`3Q*PI|&!!ip>T(_vGqHG!XH w$X mۏaf= h"R,>? C zv{-ߧ:53*."kle܎c3GS7lĻD P'/qA⦘E^ZAm5\qyv( 8R9<Un(ҿ/UdH x >>-%Y_rhԧzGFTx.~|i/|L"&z=;/YDO|Q|`+DahU3 [R"c=a=1& q}k\bp `"*&]B0bQu6eq[%%n&XQ΍Hf[Ǣ|O_{T?/ݱ~#[AS[9cS$0Rm[׆ա̈́-Ԥ%,źWwQ%xS`},@KwSad x,:Wm|1zŝ]+KIT09RK;Zk7Rv DVmE3r9έvtqb?rr;$Vl7T_e۬i~ x>7t<3 &,qMny$o!͡jsi X*&9ᖄY G`ӅdBromKŪigcquJ z";H y9GW΋zuh@X՟Joב@c)P1AME_=eQ[0gQ|NacZ'(Ud낄Omm(ĆON­,fd5$$vcbMOaB'bQ=D.NC"h9eygʪZӿ~\VrX>(>_VG  l9cW#0zX{ k1; 0g bDw)\u\_E\Ηl+{w˂#ٹhӝJi;0Ԏi丱ҹOܸ5U557]!Dc:QKR=ln@w=?qhI 8'# {t`H4N'# {m{ P5>A h`H4N bHHE۞$@$qmOG$@(4' hk|= '@Ѷ8 hE[ == IH@( vH Pi0N$@'@{$@$`OmOq 8'# {zW&p??ze,A$phi_=;$ 9REۿ}ذrwJ8DDbkOv0=|ݮs1nts%31|u;V^p_mEf }_[{&v1"a4YG``Lxv۲~8Mq)gcؑq:8Jv8,k2 W/`GroiiIX>w5 G \/n}qxJy5Mj~i9ʗ   Od€Bm6c3aL,_,.P". WוUXwƍ.}Gb6hӯ.z"ۉC5&HHGjM_4@h9 DB #MsbMר%Dwޣ}_Tm_BuHMHÊ_c(7?o]ECʀ1tSWT S̩Y8$ؽ܊Q˝H<ݼ/0#NL2BQ"zc<smp= (@#,]jQ:x|s VL[T,h•0)K7pHEwS{`xQ"HXw`0A$@Z%"ڟQn TAVR6@k C Y}k wځF;-`R~۞.!7#h05!=`<6:Dmf>3R6RE{L  >$~k`YhljwdFk\muػ:E qTM>G6GO׷?vڻoվuO3:ꐖ:aj\B,D*HmDmU*q1])bu;>9\ NJB%l . sG80&j\Berb u/ -:ӽ#7|osljSb1g LGѱF4AA7MR fW\.k}YHBE̺_M| >Y; /;o MH)S:Pڐ]#-^Z" Yh/VV'?]#pnۃU.yi/&~O!@F4h$[±M_V4j"y-HJE~qʖ #/|XfqY| $͖C{/9M,gDFņPox~'0hdsJs1y.ɮ?Pf}K_{Zn6C"=!R.ǏE 9oR%P-E$q.)O[.ӆWe6\ 3"B% -VQkqXGVuZUG# K;#_h8b A6>^xmAس ׵L!/=Y-L\RbL=ckG \D S3jyơ΄90tl +0}#o$k`ShiXQYubRowoo)A/ycZ]k9~ vY=WOe9.nCnGG#+W wsH wtaklIH@c\AXf!\<8Z 4# Gt8`H4M# GmGL P5== 8h;`H4MaHHEۑS$@$imMO;G$@(ڎ<" Mhkzz9 p$@v hE[Α ##HH@(ښvH Py0E$@&@s$@$Hȃ) 4# GeknԕKl#_\$ %@Kjɱ T2Yڏ/2c;̃Pw(vP }{"ß;j( X1۝Wb냹+|@gN-%bܦw=̞TI;TI@C)1A$@$pyv\TP}!V܍/OI^|7"0:|^_a> /H4z Kꈑ}aI`_,($@$@e!Ƨ k\ k6f=Q -[ d. zbOz/}jkJoڨ7c! (hoG@}L'? ԍ>ԟs0wE}|OCKC"y>hbk|49#{֝Շ#T|.wi$@$ppujGG[_~@dIFi/ p"̀X8ݍҊwpL>y@kˉdl] `#Ĉ XbEw;P#% u%RR6][c 'a$B#Bs*0U ȷ#>=t@`S@*+bo ?+PQeۜ=<v pl"p`*2OEW0|"6VoGwÌY$!nh?40 "<ΗP0$c:#~8$Rꠔ s-oy"f>Np(UKm";< m!GU3jAK&\s9"\ٜx }:I:ٚu|/ED&F,7n" 6I<\. g̖FDֳ&$H qepH$ԡH[rK~+Ĕ/{Y"or)b9";DSXoVy$9|j=ͯLiiyo K }Z $@H຋vIbf')4EY#w:@!P"$b{E*-VPiK-=lWYʽXIJnt,<^zc2N""jϔꉇH\w>xCQ 9 ">Y%yGgR`jGhcޑ7⹢,?ʔY󺐶^nr.7a@ei/*fISβXW"lRV}Uz3 3[N hHk;WS ح3؊H$]]}iluoğ} (PW DXDC˿-Eb}Z<.ʂ1t# "׈|} rZf*Psg1~0Uՙcƶ'rjaRi"E@ۀ\Y\~ hύAz YP] Ǔ@ V-ٱ;%.!e>Jp * %[IZ+V !X(c=աCDn(>[9QH<=w};j]+Xd}\,0ekJ1BܱE:mouIEW*o}J9Sn?;I8> ?wzZQ\EmA+i 9%QV7 8QųOZ",/e_\* y~1Jo_jUlJW[>xx.ur(73+O,9E)7,.w@V'*mS ILQ"(_G EDT8!"&].ؗU'JTﮂ7I+Z։j,>-RƗMOtdJ+E=ϺiM^j-H:::] Each of the four fields can be left blank and trailing fields can be omitted. (Empty square brackets "[]", however, are not considered style tags.) Fields that are not specified will be left unchanged. A field with just a dash ("-") means "reset to default". You can specify the following flags to turn on certain attributes (some flags may not be supported by your terminal): l: blink b: bold i: italic d: dim r: reverse (switch foreground and background color) u: underline s: strike-through Use uppercase letters to turn off the corresponding attribute, for example, "B" to turn off bold. Uppercase letters have no effect if the attribute was not previously set. Setting a URL allows you to turn a piece of text into a hyperlink in some terminals. Specify a dash ("-") to specify the end of the hyperlink. Hyperlinks must only contain single-byte characters (e.g. ASCII) and they may not contain bracket characters ("[" or "]"). Examples: [yellow]Yellow text [yellow:red]Yellow text on red background [:red]Red background, text color unchanged [yellow::u]Yellow text underlined [::bl]Bold, blinking text [::-]Colors unchanged, flags reset [-]Reset foreground color [::i]Italic and [::I]not italic Click [:::https://example.com]here[:::-] for example.com. Send an email to [:::mailto:her@example.com]her/[:::mail:him@example.com]him/[:::mail:them@example.com]them[:::-]. [-:-:-:-]Reset everything [:]No effect []Not a valid style tag, will print square brackets as they are In the rare event that you want to display a string such as "[red]" or "[#00ff1a]" without applying its effect, you need to put an opening square bracket before the closing square bracket. Note that the text inside the brackets will be matched less strictly than region or colors tags. I.e. any character that may be used in color or region tags will be recognized. Examples: [red[] will be output as [red] ["123"[] will be output as ["123"] [#6aff00[[] will be output as [#6aff00[] [a#"[[[] will be output as [a#"[[] [] will be output as [] (see style tags above) [[] will be output as [[] (not an escaped tag) You can use the Escape() function to insert brackets automatically where needed. # Styles When primitives are instantiated, they are initialized with colors taken from the global [Styles] variable. You may change this variable to adapt the look and feel of the primitives to your preferred style. Note that most terminals will not report information about their color theme. This package therefore does not support using the terminal's color theme. The default style is a dark theme and you must change the [Styles] variable to switch to a light (or other) theme. # Unicode Support This package supports all unicode characters supported by your terminal. # Concurrency Many functions in this package are not thread-safe. For many applications, this is not an issue: If your code makes changes in response to key events, the corresponding callback function will execute in the main goroutine and thus will not cause any race conditions. (Exceptions to this are documented.) If you access your primitives from other goroutines, however, you will need to synchronize execution. The easiest way to do this is to call [Application.QueueUpdate] or [Application.QueueUpdateDraw] (see the function documentation for details): go func() { app.QueueUpdateDraw(func() { table.SetCellSimple(0, 0, "Foo bar") }) }() One exception to this is the io.Writer interface implemented by [TextView]. You can safely write to a [TextView] from any goroutine. See the [TextView] documentation for details. You can also call [Application.Draw] from any goroutine without having to wrap it in [Application.QueueUpdate]. And, as mentioned above, key event callbacks are executed in the main goroutine and thus should not use [Application.QueueUpdate] as that may lead to deadlocks. It is also not necessary to call [Application.Draw] from such callbacks as it will be called automatically. # Type Hierarchy All widgets listed above contain the [Box] type. All of [Box]'s functions are therefore available for all widgets, too. Please note that if you are using the functions of [Box] on a subclass, they will return a *Box, not the subclass. This is a Golang limitation. So while tview supports method chaining in many places, these chains must be broken when using [Box]'s functions. Example: // This will cause "textArea" to be an empty Box. textArea := tview.NewTextArea(). SetMaxLength(256). SetPlaceholder("Enter text here"). SetBorder(true) You will need to call [Box.SetBorder] separately: textArea := tview.NewTextArea(). SetMaxLength(256). SetPlaceholder("Enter text here") texArea.SetBorder(true) All widgets also implement the [Primitive] interface. The tview package's rendering is based on version 2 of https://github.com/gdamore/tcell. It uses types and constants from that package (e.g. colors, styles, and keyboard values). */ package tview golang-github-darkhz-tview-0.0~git20240308.6078a88/dropdown.go000066400000000000000000000455651457770046000234020ustar00rootroot00000000000000package tview import ( "strings" "github.com/gdamore/tcell/v2" "github.com/rivo/uniseg" ) // dropDownOption is one option that can be selected in a drop-down primitive. type dropDownOption struct { Text string // The text to be displayed in the drop-down. Selected func() // The (optional) callback for when this option was selected. } // DropDown implements a selection widget whose options become visible in a // drop-down list when activated. // // See https://github.com/rivo/tview/wiki/DropDown for an example. type DropDown struct { *Box // Whether or not this drop-down is disabled/read-only. disabled bool // The options from which the user can choose. options []*dropDownOption // Strings to be placed before and after each drop-down option. optionPrefix, optionSuffix string // The index of the currently selected option. Negative if no option is // currently selected. currentOption int // Strings to be placed before and after the current option. currentOptionPrefix, currentOptionSuffix string // The text to be displayed when no option has yet been selected. noSelection string // Set to true if the options are visible and selectable. open bool // The runes typed so far to directly access one of the list items. prefix string // The list element for the options. list *List // The text to be displayed before the input area. label string // The label color. labelColor tcell.Color // The background color of the input area. fieldBackgroundColor tcell.Color // The text color of the input area. fieldTextColor tcell.Color // The color for prefixes. prefixTextColor tcell.Color // The screen width of the label area. A value of 0 means use the width of // the label text. labelWidth int // The screen width of the input area. A value of 0 means extend as much as // possible. fieldWidth int // An optional function which is called when the user indicated that they // are done selecting options. The key which was pressed is provided (tab, // shift-tab, or escape). done func(tcell.Key) // A callback function set by the Form class and called when the user leaves // this form item. finished func(tcell.Key) // A callback function which is called when the user changes the drop-down's // selection. selected func(text string, index int) dragging bool // Set to true when mouse dragging is in progress. } // NewDropDown returns a new drop-down. func NewDropDown() *DropDown { list := NewList() list.ShowSecondaryText(false). SetMainTextColor(Styles.PrimitiveBackgroundColor). SetSelectedTextColor(Styles.PrimitiveBackgroundColor). SetSelectedBackgroundColor(Styles.PrimaryTextColor). SetHighlightFullLine(true). SetBackgroundColor(Styles.MoreContrastBackgroundColor) d := &DropDown{ Box: NewBox(), currentOption: -1, list: list, labelColor: Styles.SecondaryTextColor, fieldBackgroundColor: Styles.ContrastBackgroundColor, fieldTextColor: Styles.PrimaryTextColor, prefixTextColor: Styles.ContrastSecondaryTextColor, } return d } // List returns the list item associated with the dropdown. func (d *DropDown) List() *List { return d.list } // SetCurrentOption sets the index of the currently selected option. This may // be a negative value to indicate that no option is currently selected. Calling // this function will also trigger the "selected" callback (if there is one). func (d *DropDown) SetCurrentOption(index int) *DropDown { if index >= 0 && index < len(d.options) { d.currentOption = index d.list.SetCurrentItem(index) if d.selected != nil { d.selected(d.options[index].Text, index) } if d.options[index].Selected != nil { d.options[index].Selected() } } else { d.currentOption = -1 d.list.SetCurrentItem(0) // Set to 0 because -1 means "last item". if d.selected != nil { d.selected("", -1) } } return d } // GetCurrentOption returns the index of the currently selected option as well // as its text. If no option was selected, -1 and an empty string is returned. func (d *DropDown) GetCurrentOption() (int, string) { var text string if d.currentOption >= 0 && d.currentOption < len(d.options) { text = d.options[d.currentOption].Text } return d.currentOption, text } // SetTextOptions sets the text to be placed before and after each drop-down // option (prefix/suffix), the text placed before and after the currently // selected option (currentPrefix/currentSuffix) as well as the text to be // displayed when no option is currently selected. Per default, all of these // strings are empty. func (d *DropDown) SetTextOptions(prefix, suffix, currentPrefix, currentSuffix, noSelection string) *DropDown { d.currentOptionPrefix = currentPrefix d.currentOptionSuffix = currentSuffix d.noSelection = noSelection d.optionPrefix = prefix d.optionSuffix = suffix for index := 0; index < d.list.GetItemCount(); index++ { d.list.SetItemText(index, prefix+d.options[index].Text+suffix, "") } return d } // SetLabel sets the text to be displayed before the input area. func (d *DropDown) SetLabel(label string) *DropDown { d.label = label return d } // GetLabel returns the text to be displayed before the input area. func (d *DropDown) GetLabel() string { return d.label } // SetLabelWidth sets the screen width of the label. A value of 0 will cause the // primitive to use the width of the label string. func (d *DropDown) SetLabelWidth(width int) *DropDown { d.labelWidth = width return d } // SetLabelColor sets the color of the label. func (d *DropDown) SetLabelColor(color tcell.Color) *DropDown { d.labelColor = color return d } // SetFieldBackgroundColor sets the background color of the options area. func (d *DropDown) SetFieldBackgroundColor(color tcell.Color) *DropDown { d.fieldBackgroundColor = color return d } // SetFieldTextColor sets the text color of the options area. func (d *DropDown) SetFieldTextColor(color tcell.Color) *DropDown { d.fieldTextColor = color return d } // SetPrefixTextColor sets the color of the prefix string. The prefix string is // shown when the user starts typing text, which directly selects the first // option that starts with the typed string. func (d *DropDown) SetPrefixTextColor(color tcell.Color) *DropDown { d.prefixTextColor = color return d } // SetListStyles sets the styles of the items in the drop-down list (unselected // as well as selected items). Style attributes are currently ignored but may be // used in the future. func (d *DropDown) SetListStyles(unselected, selected tcell.Style) *DropDown { fg, bg, _ := unselected.Decompose() d.list.SetMainTextColor(fg).SetBackgroundColor(bg) fg, bg, _ = selected.Decompose() d.list.SetSelectedTextColor(fg).SetSelectedBackgroundColor(bg) return d } // SetFormAttributes sets attributes shared by all form items. func (d *DropDown) SetFormAttributes(labelWidth int, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem { d.labelWidth = labelWidth d.labelColor = labelColor d.backgroundColor = bgColor d.fieldTextColor = fieldTextColor d.fieldBackgroundColor = fieldBgColor return d } // SetFieldWidth sets the screen width of the options area. A value of 0 means // extend to as long as the longest option text. func (d *DropDown) SetFieldWidth(width int) *DropDown { d.fieldWidth = width return d } // GetFieldWidth returns this primitive's field screen width. func (d *DropDown) GetFieldWidth() int { if d.fieldWidth > 0 { return d.fieldWidth } fieldWidth := 0 for _, option := range d.options { width := TaggedStringWidth(option.Text) if width > fieldWidth { fieldWidth = width } } return fieldWidth } // GetFieldHeight returns this primitive's field height. func (d *DropDown) GetFieldHeight() int { return 1 } // SetDisabled sets whether or not the item is disabled / read-only. func (d *DropDown) SetDisabled(disabled bool) FormItem { d.disabled = disabled if d.finished != nil { d.finished(-1) } return d } // AddOption adds a new selectable option to this drop-down. The "selected" // callback is called when this option was selected. It may be nil. func (d *DropDown) AddOption(text string, selected func()) *DropDown { d.options = append(d.options, &dropDownOption{Text: text, Selected: selected}) d.list.AddItem(d.optionPrefix+text+d.optionSuffix, "", 0, nil) return d } // SetOptions replaces all current options with the ones provided and installs // one callback function which is called when one of the options is selected. // It will be called with the option's text and its index into the options // slice. The "selected" parameter may be nil. func (d *DropDown) SetOptions(texts []string, selected func(text string, index int)) *DropDown { d.list.Clear() d.options = nil for index, text := range texts { func(t string, i int) { d.AddOption(text, nil) }(text, index) } d.selected = selected return d } // GetOptionCount returns the number of options in the drop-down. func (d *DropDown) GetOptionCount() int { return len(d.options) } // RemoveOption removes the specified option from the drop-down. Panics if the // index is out of range. If the currently selected option is removed, no option // will be selected. func (d *DropDown) RemoveOption(index int) *DropDown { if index == d.currentOption { d.currentOption = -1 } d.options = append(d.options[:index], d.options[index+1:]...) d.list.RemoveItem(index) return d } // SetSelectedFunc sets a handler which is called when the user changes the // drop-down's option. This handler will be called in addition and prior to // an option's optional individual handler. The handler is provided with the // selected option's text and index. If "no option" was selected, these values // are an empty string and -1. func (d *DropDown) SetSelectedFunc(handler func(text string, index int)) *DropDown { d.selected = handler return d } // SetDoneFunc sets a handler which is called when the user is done selecting // options. The callback function is provided with the key that was pressed, // which is one of the following: // // - KeyEscape: Abort selection. // - KeyTab: Move to the next field. // - KeyBacktab: Move to the previous field. func (d *DropDown) SetDoneFunc(handler func(key tcell.Key)) *DropDown { d.done = handler return d } // SetFinishedFunc sets a callback invoked when the user leaves this form item. func (d *DropDown) SetFinishedFunc(handler func(key tcell.Key)) FormItem { d.finished = handler return d } // Draw draws this primitive onto the screen. func (d *DropDown) Draw(screen tcell.Screen) { d.Box.DrawForSubclass(screen, d) // Prepare. x, y, width, height := d.GetInnerRect() rightLimit := x + width if height < 1 || rightLimit <= x { return } // Draw label. if d.labelWidth > 0 { labelWidth := d.labelWidth if labelWidth > rightLimit-x { labelWidth = rightLimit - x } Print(screen, d.label, x, y, labelWidth, AlignLeft, d.labelColor) x += labelWidth } else { _, drawnWidth := Print(screen, d.label, x, y, rightLimit-x, AlignLeft, d.labelColor) x += drawnWidth } // What's the longest option text? maxWidth := 0 optionWrapWidth := TaggedStringWidth(d.optionPrefix + d.optionSuffix) for _, option := range d.options { strWidth := TaggedStringWidth(option.Text) + optionWrapWidth if strWidth > maxWidth { maxWidth = strWidth } } // Draw selection area. fieldWidth := d.fieldWidth if fieldWidth == 0 { fieldWidth = maxWidth if d.currentOption < 0 { noSelectionWidth := TaggedStringWidth(d.noSelection) if noSelectionWidth > fieldWidth { fieldWidth = noSelectionWidth } } else if d.currentOption < len(d.options) { currentOptionWidth := TaggedStringWidth(d.currentOptionPrefix + d.options[d.currentOption].Text + d.currentOptionSuffix) if currentOptionWidth > fieldWidth { fieldWidth = currentOptionWidth } } } if rightLimit-x < fieldWidth { fieldWidth = rightLimit - x } fieldStyle := tcell.StyleDefault.Background(d.fieldBackgroundColor) if d.HasFocus() && !d.open { fieldStyle = fieldStyle.Background(d.fieldTextColor) } if d.disabled { fieldStyle = fieldStyle.Background(d.backgroundColor) } for index := 0; index < fieldWidth; index++ { screen.SetContent(x+index, y, ' ', nil, fieldStyle) } // Draw selected text. if d.open && len(d.prefix) > 0 { // Show the prefix. currentOptionPrefixWidth := TaggedStringWidth(d.currentOptionPrefix) prefixWidth := uniseg.StringWidth(d.prefix) listItemText := d.options[d.list.GetCurrentItem()].Text Print(screen, d.currentOptionPrefix, x, y, fieldWidth, AlignLeft, d.fieldTextColor) Print(screen, d.prefix, x+currentOptionPrefixWidth, y, fieldWidth-currentOptionPrefixWidth, AlignLeft, d.prefixTextColor) if len(d.prefix) < len(listItemText) { Print(screen, listItemText[len(d.prefix):]+d.currentOptionSuffix, x+prefixWidth+currentOptionPrefixWidth, y, fieldWidth-prefixWidth-currentOptionPrefixWidth, AlignLeft, d.fieldTextColor) } } else { color := d.fieldTextColor text := d.noSelection if d.currentOption >= 0 && d.currentOption < len(d.options) { text = d.currentOptionPrefix + d.options[d.currentOption].Text + d.currentOptionSuffix } // Just show the current selection. if d.HasFocus() && !d.open && !d.disabled { color = d.fieldBackgroundColor } Print(screen, text, x, y, fieldWidth, AlignLeft, color) } // Draw options list. if d.HasFocus() && d.open { lx := x ly := y + 1 lwidth := maxWidth lheight := len(d.options) swidth, sheight := screen.Size() // Increase the list's width and height if borders are present. if d.list.border { lwidth += 2 lheight += 2 } // We prefer to align the left sides of the list and the main widget, but // if there is no space to the right, then shift the list to the left. if lx+lwidth >= swidth { lx = swidth - lwidth if lx < 0 { lx = 0 } } // We prefer to drop down but if there is no space, maybe drop up? if ly+lheight >= sheight && ly-2 > lheight-ly { ly = y - lheight if ly < 0 { ly = 0 } } if ly+lheight >= sheight { lheight = sheight - ly } d.list.SetRect(lx, ly, lwidth, lheight) d.list.Draw(screen) } } // InputHandler returns the handler for this primitive. func (d *DropDown) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) { return d.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) { if d.disabled { return } // If the list has focus, let it process its own key events. if d.list.HasFocus() { if handler := d.list.InputHandler(); handler != nil { handler(event, setFocus) } return } // Process key event. switch key := event.Key(); key { case tcell.KeyEnter, tcell.KeyRune, tcell.KeyDown: d.prefix = "" // If the first key was a letter already, it becomes part of the prefix. if r := event.Rune(); key == tcell.KeyRune && r != ' ' { d.prefix += string(r) d.evalPrefix() } d.openList(setFocus) case tcell.KeyEscape, tcell.KeyTab, tcell.KeyBacktab: if d.done != nil { d.done(key) } if d.finished != nil { d.finished(key) } } }) } // evalPrefix selects an item in the drop-down list based on the current prefix. func (d *DropDown) evalPrefix() { if len(d.prefix) > 0 { for index, option := range d.options { if strings.HasPrefix(strings.ToLower(option.Text), d.prefix) { d.list.SetCurrentItem(index) return } } // Prefix does not match any item. Remove last rune. r := []rune(d.prefix) d.prefix = string(r[:len(r)-1]) } } // openList hands control over to the embedded List primitive. func (d *DropDown) openList(setFocus func(Primitive)) { d.open = true optionBefore := d.currentOption d.list.SetSelectedFunc(func(index int, mainText, secondaryText string, shortcut rune) { if d.dragging { return // If we're dragging the mouse, we don't want to trigger any events. } // An option was selected. Close the list again. d.currentOption = index d.closeList(setFocus) // Trigger "selected" event. currentOption := d.options[d.currentOption] if d.selected != nil { d.selected(currentOption.Text, d.currentOption) } if currentOption.Selected != nil { currentOption.Selected() } }).SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { if event.Key() == tcell.KeyRune { d.prefix += string(event.Rune()) d.evalPrefix() } else if event.Key() == tcell.KeyBackspace || event.Key() == tcell.KeyBackspace2 { if len(d.prefix) > 0 { r := []rune(d.prefix) d.prefix = string(r[:len(r)-1]) } d.evalPrefix() } else if event.Key() == tcell.KeyEscape { d.currentOption = optionBefore d.closeList(setFocus) } else { d.prefix = "" } return event }) setFocus(d.list) } // closeList closes the embedded List element by hiding it and removing focus // from it. func (d *DropDown) closeList(setFocus func(Primitive)) { d.open = false if d.list.HasFocus() { setFocus(d) } } // IsOpen returns true if the drop-down list is currently open. func (d *DropDown) IsOpen() bool { return d.open } // Focus is called by the application when the primitive receives focus. func (d *DropDown) Focus(delegate func(p Primitive)) { // If we're part of a form and this item is disabled, there's nothing the // user can do here so we're finished. if d.finished != nil && d.disabled { d.finished(-1) return } if d.open { delegate(d.list) } else { d.Box.Focus(delegate) } } // HasFocus returns whether or not this primitive has focus. func (d *DropDown) HasFocus() bool { if d.open { return d.list.HasFocus() } return d.Box.HasFocus() } // MouseHandler returns the mouse handler for this primitive. func (d *DropDown) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return d.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { if d.disabled { return false, nil } // Was the mouse event in the drop-down box itself (or on its label)? x, y := event.Position() rectX, rectY, rectWidth, _ := d.GetInnerRect() inRect := y == rectY && x >= rectX && x < rectX+rectWidth if !d.open && !inRect { return d.InRect(x, y), nil // No, and it's not expanded either. Ignore. } // As long as the drop-down is open, we capture all mouse events. if d.open { capture = d } switch action { case MouseLeftDown: consumed = d.open || inRect capture = d if !d.open { d.openList(setFocus) d.dragging = true } else if consumed, _ := d.list.MouseHandler()(MouseLeftClick, event, setFocus); !consumed { d.closeList(setFocus) // Close drop-down if clicked outside of it. } case MouseMove: if d.dragging { // We pretend it's a left click so we can see the selection during // dragging. Because we don't act upon it, it's not a problem. d.list.MouseHandler()(MouseLeftClick, event, setFocus) consumed = true } case MouseLeftUp: if d.dragging { d.dragging = false d.list.MouseHandler()(MouseLeftClick, event, setFocus) consumed = true } } return }) } golang-github-darkhz-tview-0.0~git20240308.6078a88/flex.go000066400000000000000000000203421457770046000224660ustar00rootroot00000000000000package tview import ( "github.com/gdamore/tcell/v2" ) // Flex directions. const ( // One item per row. FlexRow = 0 // One item per column. FlexColumn = 1 // As defined in CSS, items distributed along a row. FlexRowCSS = 1 // As defined in CSS, items distributed within a column. FlexColumnCSS = 0 ) // flexItem holds layout options for one item. type flexItem struct { Item Primitive // The item to be positioned. May be nil for an empty item. FixedSize int // The item's fixed size which may not be changed, 0 if it has no fixed size. Proportion int // The item's proportion. Focus bool // Whether or not this item attracts the layout's focus. } // Flex is a basic implementation of the Flexbox layout. The contained // primitives are arranged horizontally or vertically. The way they are // distributed along that dimension depends on their layout settings, which is // either a fixed length or a proportional length. See AddItem() for details. // // See https://github.com/rivo/tview/wiki/Flex for an example. type Flex struct { *Box // The items to be positioned. items []*flexItem // FlexRow or FlexColumn. direction int // If set to true, Flex will use the entire screen as its available space // instead its box dimensions. fullScreen bool } // NewFlex returns a new flexbox layout container with no primitives and its // direction set to FlexColumn. To add primitives to this layout, see AddItem(). // To change the direction, see SetDirection(). // // Note that Box, the superclass of Flex, will not clear its contents so that // any nil flex items will leave their background unchanged. To clear a Flex's // background before any items are drawn, set it to a box with the desired // color: // // flex.Box = NewBox() func NewFlex() *Flex { f := &Flex{ direction: FlexColumn, } f.Box = NewBox() f.Box.dontClear = true return f } // SetDirection sets the direction in which the contained primitives are // distributed. This can be either FlexColumn (default) or FlexRow. Note that // these are the opposite of what you would expect coming from CSS. You may also // use FlexColumnCSS or FlexRowCSS, to remain in line with the CSS definition. func (f *Flex) SetDirection(direction int) *Flex { f.direction = direction return f } // SetFullScreen sets the flag which, when true, causes the flex layout to use // the entire screen space instead of whatever size it is currently assigned to. func (f *Flex) SetFullScreen(fullScreen bool) *Flex { f.fullScreen = fullScreen return f } // AddItem adds a new item to the container. The "fixedSize" argument is a width // or height that may not be changed by the layout algorithm. A value of 0 means // that its size is flexible and may be changed. The "proportion" argument // defines the relative size of the item compared to other flexible-size items. // For example, items with a proportion of 2 will be twice as large as items // with a proportion of 1. The proportion must be at least 1 if fixedSize == 0 // (ignored otherwise). // // If "focus" is set to true, the item will receive focus when the Flex // primitive receives focus. If multiple items have the "focus" flag set to // true, the first one will receive focus. // // You can provide a nil value for the primitive. This will still consume screen // space but nothing will be drawn. func (f *Flex) AddItem(item Primitive, fixedSize, proportion int, focus bool) *Flex { f.items = append(f.items, &flexItem{Item: item, FixedSize: fixedSize, Proportion: proportion, Focus: focus}) return f } // RemoveItem removes all items for the given primitive from the container, // keeping the order of the remaining items intact. func (f *Flex) RemoveItem(p Primitive) *Flex { for index := len(f.items) - 1; index >= 0; index-- { if f.items[index].Item == p { f.items = append(f.items[:index], f.items[index+1:]...) } } return f } // RemoveItemIndex removes the primitive at the given index from the container, // keeping the order of the remaining items intact. func (f *Flex) RemoveItemIndex(index int) *Flex { f.items = append(f.items[:index], f.items[index+1:]...) return f } // GetItemCount returns the number of items in this container. func (f *Flex) GetItemCount() int { return len(f.items) } // GetItem returns the primitive at the given index, starting with 0 for the // first primitive in this container. // // This function will panic for out of range indices. func (f *Flex) GetItem(index int) Primitive { return f.items[index].Item } // Clear removes all items from the container. func (f *Flex) Clear() *Flex { f.items = nil return f } // ResizeItem sets a new size for the item(s) with the given primitive. If there // are multiple Flex items with the same primitive, they will all receive the // same size. For details regarding the size parameters, see AddItem(). func (f *Flex) ResizeItem(p Primitive, fixedSize, proportion int) *Flex { for _, item := range f.items { if item.Item == p { item.FixedSize = fixedSize item.Proportion = proportion } } return f } // Draw draws this primitive onto the screen. func (f *Flex) Draw(screen tcell.Screen) { f.Box.DrawForSubclass(screen, f) // Calculate size and position of the items. // Do we use the entire screen? if f.fullScreen { width, height := screen.Size() f.SetRect(0, 0, width, height) } // How much space can we distribute? x, y, width, height := f.GetInnerRect() var proportionSum int distSize := width if f.direction == FlexRow { distSize = height } for _, item := range f.items { if item.FixedSize > 0 { distSize -= item.FixedSize } else { proportionSum += item.Proportion } } // Calculate positions and draw items. pos := x if f.direction == FlexRow { pos = y } for _, item := range f.items { size := item.FixedSize if size <= 0 { if proportionSum > 0 { size = distSize * item.Proportion / proportionSum distSize -= size proportionSum -= item.Proportion } else { size = 0 } } if item.Item != nil { if f.direction == FlexColumn { item.Item.SetRect(pos, y, size, height) } else { item.Item.SetRect(x, pos, width, size) } } pos += size if item.Item != nil { if item.Item.HasFocus() { defer item.Item.Draw(screen) } else { item.Item.Draw(screen) } } } } // Focus is called when this primitive receives focus. func (f *Flex) Focus(delegate func(p Primitive)) { if f.focus != nil { f.focus() return } for _, item := range f.items { if item.Item != nil && item.Focus { delegate(item.Item) return } } f.Box.Focus(delegate) } // HasFocus returns whether or not this primitive has focus. func (f *Flex) HasFocus() bool { for _, item := range f.items { if item.Item != nil && item.Item.HasFocus() { return true } } return f.Box.HasFocus() } // MouseHandler returns the mouse handler for this primitive. func (f *Flex) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return f.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { if !f.InRect(event.Position()) { return false, nil } // Pass mouse events along to the first child item that takes it. for _, item := range f.items { if item.Item == nil { continue } consumed, capture = item.Item.MouseHandler()(action, event, setFocus) if consumed { return } } return }) } // InputHandler returns the handler for this primitive. func (f *Flex) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) { return f.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) { for _, item := range f.items { if item.Item != nil && item.Item.HasFocus() { if handler := item.Item.InputHandler(); handler != nil { handler(event, setFocus) return } } } }) } // PasteHandler returns the handler for this primitive. func (f *Flex) PasteHandler() func(pastedText string, setFocus func(p Primitive)) { return f.WrapPasteHandler(func(pastedText string, setFocus func(p Primitive)) { for _, item := range f.items { if item.Item != nil && item.Item.HasFocus() { if handler := item.Item.PasteHandler(); handler != nil { handler(pastedText, setFocus) return } } } }) } golang-github-darkhz-tview-0.0~git20240308.6078a88/form.go000066400000000000000000000654571457770046000225130ustar00rootroot00000000000000package tview import ( "image" "github.com/gdamore/tcell/v2" ) var ( // DefaultFormFieldWidth is the default field screen width of form elements // whose field width is flexible (0). This is used in the Form class for // horizontal layouts. DefaultFormFieldWidth = 10 // DefaultFormFieldHeight is the default field height of multi-line form // elements whose field height is flexible (0). DefaultFormFieldHeight = 5 ) // FormItem is the interface all form items must implement to be able to be // included in a form. type FormItem interface { Primitive // GetLabel returns the item's label text. GetLabel() string // SetFormAttributes sets a number of item attributes at once. SetFormAttributes(labelWidth int, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem // GetFieldWidth returns the width of the form item's field (the area which // is manipulated by the user) in number of screen cells. A value of 0 // indicates the the field width is flexible and may use as much space as // required. GetFieldWidth() int // GetFieldHeight returns the height of the form item's field (the area which // is manipulated by the user). This value must be greater than 0. GetFieldHeight() int // SetFinishedFunc sets the handler function for when the user finished // entering data into the item. The handler may receive events for the // Enter key (we're done), the Escape key (cancel input), the Tab key (move // to next field), the Backtab key (move to previous field), or a negative // value, indicating that the action for the last known key should be // repeated. SetFinishedFunc(handler func(key tcell.Key)) FormItem // SetDisabled sets whether or not the item is disabled / read-only. A form // must have at least one item that is not disabled. SetDisabled(disabled bool) FormItem } // Form allows you to combine multiple one-line form elements into a vertical // or horizontal layout. Form elements include types such as InputField or // Checkbox. These elements can be optionally followed by one or more buttons // for which you can define form-wide actions (e.g. Save, Clear, Cancel). // // See https://github.com/rivo/tview/wiki/Form for an example. type Form struct { *Box // The items of the form (one row per item). items []FormItem // The buttons of the form. buttons []*Button // If set to true, instead of position items and buttons from top to bottom, // they are positioned from left to right. horizontal bool // The alignment of the buttons. buttonsAlign int // The number of empty cells between items. itemPadding int // The index of the item or button which has focus. (Items are counted first, // buttons are counted last.) This is only used when the form itself receives // focus so that the last element that had focus keeps it. focusedElement int // The label color. labelColor tcell.Color // The background color of the input area. fieldBackgroundColor tcell.Color // The text color of the input area. fieldTextColor tcell.Color // The style of the buttons when they are not focused. buttonStyle tcell.Style // The style of the buttons when they are focused. buttonActivatedStyle tcell.Style // The style of the buttons when they are disabled. buttonDisabledStyle tcell.Style // The last (valid) key that wsa sent to a "finished" handler or -1 if no // such key is known yet. lastFinishedKey tcell.Key // An optional function which is called when the user hits Escape. cancel func() // An optional function which is called when form items are drawn. itemfunc func(item FormItem, labelWidth int) // An optional function which is called when form buttons are drawn. buttonfunc func(button *Button) } // NewForm returns a new form. func NewForm() *Form { box := NewBox().SetBorderPadding(1, 1, 1, 1) f := &Form{ Box: box, itemPadding: 1, labelColor: Styles.SecondaryTextColor, fieldBackgroundColor: Styles.ContrastBackgroundColor, fieldTextColor: Styles.PrimaryTextColor, buttonStyle: tcell.StyleDefault.Background(Styles.ContrastBackgroundColor).Foreground(Styles.PrimaryTextColor), buttonActivatedStyle: tcell.StyleDefault.Background(Styles.PrimaryTextColor).Foreground(Styles.ContrastBackgroundColor), buttonDisabledStyle: tcell.StyleDefault.Background(Styles.ContrastBackgroundColor).Foreground(Styles.ContrastSecondaryTextColor), lastFinishedKey: tcell.KeyTab, // To skip over inactive elements at the beginning of the form. } return f } // SetItemPadding sets the number of empty rows between form items for vertical // layouts and the number of empty cells between form items for horizontal // layouts. func (f *Form) SetItemPadding(padding int) *Form { f.itemPadding = padding return f } // SetHorizontal sets the direction the form elements are laid out. If set to // true, instead of positioning them from top to bottom (the default), they are // positioned from left to right, moving into the next row if there is not // enough space. func (f *Form) SetHorizontal(horizontal bool) *Form { f.horizontal = horizontal return f } // SetLabelColor sets the color of the labels. func (f *Form) SetLabelColor(color tcell.Color) *Form { f.labelColor = color return f } // SetFieldBackgroundColor sets the background color of the input areas. func (f *Form) SetFieldBackgroundColor(color tcell.Color) *Form { f.fieldBackgroundColor = color return f } // SetFieldTextColor sets the text color of the input areas. func (f *Form) SetFieldTextColor(color tcell.Color) *Form { f.fieldTextColor = color return f } // SetButtonsAlign sets how the buttons align horizontally, one of AlignLeft // (the default), AlignCenter, and AlignRight. This is only func (f *Form) SetButtonsAlign(align int) *Form { f.buttonsAlign = align return f } // SetButtonBackgroundColor sets the background color of the buttons. This is // also the text color of the buttons when they are focused. func (f *Form) SetButtonBackgroundColor(color tcell.Color) *Form { f.buttonStyle = f.buttonStyle.Background(color) f.buttonActivatedStyle = f.buttonActivatedStyle.Foreground(color) return f } // SetButtonTextColor sets the color of the button texts. This is also the // background of the buttons when they are focused. func (f *Form) SetButtonTextColor(color tcell.Color) *Form { f.buttonStyle = f.buttonStyle.Foreground(color) f.buttonActivatedStyle = f.buttonActivatedStyle.Background(color) return f } // SetButtonStyle sets the style of the buttons when they are not focused. func (f *Form) SetButtonStyle(style tcell.Style) *Form { f.buttonStyle = style return f } // SetButtonActivatedStyle sets the style of the buttons when they are focused. func (f *Form) SetButtonActivatedStyle(style tcell.Style) *Form { f.buttonActivatedStyle = style return f } // SetButtonDisabledStyle sets the style of the buttons when they are disabled. func (f *Form) SetButtonDisabledStyle(style tcell.Style) *Form { f.buttonDisabledStyle = style return f } // SetFocus shifts the focus to the form element with the given index, counting // non-button items first and buttons last. Note that this index is only used // when the form itself receives focus. func (f *Form) SetFocus(index int) *Form { var current, future int for itemIndex, item := range f.items { if itemIndex == index { future = itemIndex } if item.HasFocus() { current = itemIndex } } for buttonIndex, button := range f.buttons { if buttonIndex+len(f.items) == index { future = buttonIndex + len(f.items) } if button.HasFocus() { current = buttonIndex + len(f.items) } } var focus func(p Primitive) focus = func(p Primitive) { p.Focus(focus) } if current != future { if current >= 0 && current < len(f.items) { f.items[current].Blur() } else if current >= len(f.items) && current < len(f.items)+len(f.buttons) { f.buttons[current-len(f.items)].Blur() } if future >= 0 && future < len(f.items) { focus(f.items[future]) } else if future >= len(f.items) && future < len(f.items)+len(f.buttons) { focus(f.buttons[future-len(f.items)]) } } f.focusedElement = future return f } // AddTextArea adds a text area to the form. It has a label, an optional initial // text, a size (width and height) referring to the actual input area (a // fieldWidth of 0 extends it as far right as possible, a fieldHeight of 0 will // cause it to be [DefaultFormFieldHeight]), and a maximum number of bytes of // text allowed (0 means no limit). // // The optional callback function is invoked when the content of the text area // has changed. Note that especially for larger texts, this is an expensive // operation due to technical constraints of the [TextArea] primitive (every key // stroke leads to a new reallocation of the entire text). func (f *Form) AddTextArea(label, text string, fieldWidth, fieldHeight, maxLength int, changed func(text string)) *Form { if fieldHeight == 0 { fieldHeight = DefaultFormFieldHeight } textArea := NewTextArea(). SetLabel(label). SetSize(fieldHeight, fieldWidth). SetMaxLength(maxLength) if text != "" { textArea.SetText(text, true) } if changed != nil { textArea.SetChangedFunc(func() { changed(textArea.GetText()) }) } f.items = append(f.items, textArea) return f } // AddTextView adds a text view to the form. It has a label and text, a size // (width and height) referring to the actual text element (a fieldWidth of 0 // extends it as far right as possible, a fieldHeight of 0 will cause it to be // [DefaultFormFieldHeight]), a flag to turn on/off dynamic colors, and a flag // to turn on/off scrolling. If scrolling is turned off, the text view will not // receive focus. func (f *Form) AddTextView(label, text string, fieldWidth, fieldHeight int, dynamicColors, scrollable bool) *Form { if fieldHeight == 0 { fieldHeight = DefaultFormFieldHeight } textArea := NewTextView(). SetLabel(label). SetSize(fieldHeight, fieldWidth). SetDynamicColors(dynamicColors). SetScrollable(scrollable). SetText(text) f.items = append(f.items, textArea) return f } // AddInputField adds an input field to the form. It has a label, an optional // initial value, a field width (a value of 0 extends it as far as possible), // an optional accept function to validate the item's value (set to nil to // accept any text), and an (optional) callback function which is invoked when // the input field's text has changed. func (f *Form) AddInputField(label, value string, fieldWidth int, accept func(textToCheck string, lastChar rune) bool, changed func(text string)) *Form { f.items = append(f.items, NewInputField(). SetLabel(label). SetText(value). SetFieldWidth(fieldWidth). SetAcceptanceFunc(accept). SetChangedFunc(changed)) return f } // AddPasswordField adds a password field to the form. This is similar to an // input field except that the user's input not shown. Instead, a "mask" // character is displayed. The password field has a label, an optional initial // value, a field width (a value of 0 extends it as far as possible), and an // (optional) callback function which is invoked when the input field's text has // changed. func (f *Form) AddPasswordField(label, value string, fieldWidth int, mask rune, changed func(text string)) *Form { if mask == 0 { mask = '*' } f.items = append(f.items, NewInputField(). SetLabel(label). SetText(value). SetFieldWidth(fieldWidth). SetMaskCharacter(mask). SetChangedFunc(changed)) return f } // AddDropDown adds a drop-down element to the form. It has a label, options, // and an (optional) callback function which is invoked when an option was // selected. The initial option may be a negative value to indicate that no // option is currently selected. func (f *Form) AddDropDown(label string, options []string, initialOption int, selected func(option string, optionIndex int)) *Form { f.items = append(f.items, NewDropDown(). SetLabel(label). SetOptions(options, selected). SetCurrentOption(initialOption)) return f } // AddCheckbox adds a checkbox to the form. It has a label, an initial state, // and an (optional) callback function which is invoked when the state of the // checkbox was changed by the user. func (f *Form) AddCheckbox(label string, checked bool, changed func(checked bool)) *Form { f.items = append(f.items, NewCheckbox(). SetLabel(label). SetChecked(checked). SetChangedFunc(changed)) return f } // AddImage adds an image to the form. It has a label and the image will fit in // the specified width and height (its aspect ratio is preserved). See // [Image.SetColors] for a description of the "colors" parameter. Images are not // interactive and are skipped over in a form. The "width" value may be 0 // (adjust dynamically) but "height" should generally be a positive value. func (f *Form) AddImage(label string, image image.Image, width, height, colors int) *Form { f.items = append(f.items, NewImage(). SetLabel(label). SetImage(image). SetSize(height, width). SetAlign(AlignTop, AlignLeft). SetColors(colors)) return f } // AddButton adds a new button to the form. The "selected" function is called // when the user selects this button. It may be nil. func (f *Form) AddButton(label string, selected func()) *Form { f.buttons = append(f.buttons, NewButton(label).SetSelectedFunc(selected)) return f } // GetButton returns the button at the specified 0-based index. Note that // buttons have been specially prepared for this form and modifying some of // their attributes may have unintended side effects. func (f *Form) GetButton(index int) *Button { return f.buttons[index] } // RemoveButton removes the button at the specified position, starting with 0 // for the button that was added first. func (f *Form) RemoveButton(index int) *Form { f.buttons = append(f.buttons[:index], f.buttons[index+1:]...) return f } // GetButtonCount returns the number of buttons in this form. func (f *Form) GetButtonCount() int { return len(f.buttons) } // GetButtonIndex returns the index of the button with the given label, starting // with 0 for the button that was added first. If no such label was found, -1 // is returned. func (f *Form) GetButtonIndex(label string) int { for index, button := range f.buttons { if button.GetLabel() == label { return index } } return -1 } // Clear removes all input elements from the form, including the buttons if // specified. func (f *Form) Clear(includeButtons bool) *Form { f.items = nil if includeButtons { f.ClearButtons() } f.focusedElement = 0 return f } // ClearButtons removes all buttons from the form. func (f *Form) ClearButtons() *Form { f.buttons = nil return f } // AddFormItem adds a new item to the form. This can be used to add your own // objects to the form. Note, however, that the Form class will override some // of its attributes to make it work in the form context. Specifically, these // are: // // - The label width // - The label color // - The background color // - The field text color // - The field background color func (f *Form) AddFormItem(item FormItem) *Form { f.items = append(f.items, item) return f } // GetFormItemCount returns the number of items in the form (not including the // buttons). func (f *Form) GetFormItemCount() int { return len(f.items) } // GetFormItem returns the form item at the given position, starting with index // 0. Elements are referenced in the order they were added. Buttons are not // included. func (f *Form) GetFormItem(index int) FormItem { return f.items[index] } // RemoveFormItem removes the form element at the given position, starting with // index 0. Elements are referenced in the order they were added. Buttons are // not included. func (f *Form) RemoveFormItem(index int) *Form { f.items = append(f.items[:index], f.items[index+1:]...) return f } // GetFormItemByLabel returns the first form element with the given label. If // no such element is found, nil is returned. Buttons are not searched and will // therefore not be returned. func (f *Form) GetFormItemByLabel(label string) FormItem { for _, item := range f.items { if item.GetLabel() == label { return item } } return nil } // GetFormItemIndex returns the index of the first form element with the given // label. If no such element is found, -1 is returned. Buttons are not searched // and will therefore not be returned. func (f *Form) GetFormItemIndex(label string) int { for index, item := range f.items { if item.GetLabel() == label { return index } } return -1 } // GetFocusedItemIndex returns the indices of the form element or button which // currently has focus. If they don't, -1 is returned respectively. func (f *Form) GetFocusedItemIndex() (formItem, button int) { index := f.focusIndex() if index < 0 { return -1, -1 } if index < len(f.items) { return index, -1 } return -1, index - len(f.items) } // SetCancelFunc sets a handler which is called when the user hits the Escape // key. func (f *Form) SetCancelFunc(callback func()) *Form { f.cancel = callback return f } // SetItemAttributesFunc sets a handler which is called when each form item is drawn. func (f *Form) SetItemAttributesFunc(callback func(item FormItem, labelWidth int)) *Form { f.itemfunc = callback return f } // SetButtonAttributesFunc sets a handler which is called when each form item is drawn. func (f *Form) SetButtonAttributesFunc(callback func(button *Button)) *Form { f.buttonfunc = callback return f } // Draw draws this primitive onto the screen. func (f *Form) Draw(screen tcell.Screen) { f.Box.DrawForSubclass(screen, f) // Determine the actual item that has focus. if index := f.focusIndex(); index >= 0 { f.focusedElement = index } // Determine the dimensions. x, y, width, height := f.GetInnerRect() topLimit := y bottomLimit := y + height rightLimit := x + width startX := x // Find the longest label. var maxLabelWidth int for _, item := range f.items { labelWidth := TaggedStringWidth(item.GetLabel()) if labelWidth > maxLabelWidth { maxLabelWidth = labelWidth } } maxLabelWidth++ // Add one space. // Calculate positions of form items. type position struct{ x, y, width, height int } positions := make([]position, len(f.items)+len(f.buttons)) var ( focusedPosition position lineHeight = 1 ) for index, item := range f.items { // Calculate the space needed. labelWidth := TaggedStringWidth(item.GetLabel()) var itemWidth int if f.horizontal { fieldWidth := item.GetFieldWidth() if fieldWidth <= 0 { fieldWidth = DefaultFormFieldWidth } labelWidth++ itemWidth = labelWidth + fieldWidth } else { // We want all fields to align vertically. labelWidth = maxLabelWidth itemWidth = width } itemHeight := item.GetFieldHeight() if itemHeight <= 0 { itemHeight = DefaultFormFieldHeight } // Advance to next line if there is no space. if f.horizontal && x+labelWidth+1 >= rightLimit { x = startX y += lineHeight + 1 lineHeight = itemHeight } // Update line height. if itemHeight > lineHeight { lineHeight = itemHeight } // Adjust the item's attributes. if x+itemWidth >= rightLimit { itemWidth = rightLimit - x } if f.itemfunc != nil { f.itemfunc(item, labelWidth) } else { item.SetFormAttributes( labelWidth, f.labelColor, f.backgroundColor, f.fieldTextColor, f.fieldBackgroundColor, ) } // Save position. positions[index].x = x positions[index].y = y positions[index].width = itemWidth positions[index].height = itemHeight if item.HasFocus() { focusedPosition = positions[index] } // Advance to next item. if f.horizontal { x += itemWidth + f.itemPadding } else { y += itemHeight + f.itemPadding } } // How wide are the buttons? buttonWidths := make([]int, len(f.buttons)) buttonsWidth := 0 for index, button := range f.buttons { w := TaggedStringWidth(button.GetLabel()) + 4 buttonWidths[index] = w buttonsWidth += w + 1 } buttonsWidth-- // Where do we place them? if !f.horizontal && x+buttonsWidth < rightLimit { if f.buttonsAlign == AlignRight { x = rightLimit - buttonsWidth } else if f.buttonsAlign == AlignCenter { x = (x + rightLimit - buttonsWidth) / 2 } // In vertical layouts, buttons always appear after an empty line. if f.itemPadding == 0 { y++ } } // Calculate positions of buttons. for index, button := range f.buttons { space := rightLimit - x buttonWidth := buttonWidths[index] if f.horizontal { if space < buttonWidth-4 { x = startX y += lineHeight + 1 space = width lineHeight = 1 } } else { if space < 1 { break // No space for this button anymore. } } if buttonWidth > space { buttonWidth = space } if f.buttonfunc != nil { f.buttonfunc(button) } else { button.SetStyle(f.buttonStyle). SetActivatedStyle(f.buttonActivatedStyle). SetDisabledStyle(f.buttonDisabledStyle) } buttonIndex := index + len(f.items) positions[buttonIndex].x = x positions[buttonIndex].y = y positions[buttonIndex].width = buttonWidth positions[buttonIndex].height = 1 if button.HasFocus() { focusedPosition = positions[buttonIndex] } x += buttonWidth + 1 } // Determine vertical offset based on the position of the focused item. var offset int if focusedPosition.y+focusedPosition.height > bottomLimit { offset = focusedPosition.y + focusedPosition.height - bottomLimit if focusedPosition.y-offset < topLimit { offset = focusedPosition.y - topLimit } } // Draw items. for index, item := range f.items { // Set position. y := positions[index].y - offset height := positions[index].height item.SetRect(positions[index].x, y, positions[index].width, height) // Is this item visible? if y+height <= topLimit || y >= bottomLimit { continue } // Draw items with focus last (in case of overlaps). if item.HasFocus() { defer item.Draw(screen) } else { item.Draw(screen) } } // Draw buttons. for index, button := range f.buttons { // Set position. buttonIndex := index + len(f.items) y := positions[buttonIndex].y - offset height := positions[buttonIndex].height button.SetRect(positions[buttonIndex].x, y, positions[buttonIndex].width, height) // Is this button visible? if y+height <= topLimit || y >= bottomLimit { continue } // Draw button. button.Draw(screen) } } // Focus is called by the application when the primitive receives focus. func (f *Form) Focus(delegate func(p Primitive)) { // Hand on the focus to one of our child elements. if f.focusedElement < 0 || f.focusedElement >= len(f.items)+len(f.buttons) { f.focusedElement = 0 } var handler func(key tcell.Key) handler = func(key tcell.Key) { if key >= 0 { f.lastFinishedKey = key } switch key { case tcell.KeyTab, tcell.KeyEnter: f.focusedElement++ f.Focus(delegate) case tcell.KeyBacktab: f.focusedElement-- if f.focusedElement < 0 { f.focusedElement = len(f.items) + len(f.buttons) - 1 } f.Focus(delegate) case tcell.KeyEscape: if f.cancel != nil { f.cancel() } else { f.focusedElement = 0 f.Focus(delegate) } default: if key < 0 && f.lastFinishedKey >= 0 { // Repeat the last action. handler(f.lastFinishedKey) } } } // Track whether a form item has focus. var itemFocused bool f.hasFocus = false // Set the handler and focus for all items and buttons. for index, button := range f.buttons { button.SetExitFunc(handler) if f.focusedElement == index+len(f.items) { if button.IsDisabled() { f.focusedElement++ if f.focusedElement >= len(f.items)+len(f.buttons) { f.focusedElement = 0 } continue } itemFocused = true func(b *Button) { // Wrapping might not be necessary anymore in future Go versions. defer delegate(b) }(button) } } for index, item := range f.items { item.SetFinishedFunc(handler) if f.focusedElement == index { itemFocused = true func(i FormItem) { // Wrapping might not be necessary anymore in future Go versions. defer delegate(i) }(item) } } // If no item was focused, focus the form itself. if !itemFocused { f.Box.Focus(delegate) } } // HasFocus returns whether or not this primitive has focus. func (f *Form) HasFocus() bool { if f.focusIndex() >= 0 { return true } return f.Box.HasFocus() } // focusIndex returns the index of the currently focused item, counting form // items first, then buttons. A negative value indicates that no containeed item // has focus. func (f *Form) focusIndex() int { for index, item := range f.items { if item.HasFocus() { return index } } for index, button := range f.buttons { if button.HasFocus() { return len(f.items) + index } } return -1 } // MouseHandler returns the mouse handler for this primitive. func (f *Form) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return f.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { // At the end, update f.focusedElement and prepare current item/button. defer func() { if consumed { index := f.focusIndex() if index >= 0 { f.focusedElement = index } } }() // Determine items to pass mouse events to. for _, item := range f.items { // Exclude TextView items from mouse-down events as they are // read-only items and thus should not be focused. if _, ok := item.(*TextView); ok && action == MouseLeftDown { continue } consumed, capture = item.MouseHandler()(action, event, setFocus) if consumed { return } } for _, button := range f.buttons { consumed, capture = button.MouseHandler()(action, event, setFocus) if consumed { return } } // A mouse down anywhere else will return the focus to the last selected // element. if action == MouseLeftDown && f.InRect(event.Position()) { f.Focus(setFocus) consumed = true } return }) } // InputHandler returns the handler for this primitive. func (f *Form) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) { return f.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) { for _, item := range f.items { if item != nil && item.HasFocus() { if handler := item.InputHandler(); handler != nil { handler(event, setFocus) return } } } for _, button := range f.buttons { if button.HasFocus() { if handler := button.InputHandler(); handler != nil { handler(event, setFocus) return } } } }) } // PasteHandler returns the handler for this primitive. func (f *Form) PasteHandler() func(pastedText string, setFocus func(p Primitive)) { return f.WrapPasteHandler(func(pastedText string, setFocus func(p Primitive)) { for _, item := range f.items { if item != nil && item.HasFocus() { if handler := item.PasteHandler(); handler != nil { handler(pastedText, setFocus) return } } } for _, button := range f.buttons { if button.HasFocus() { if handler := button.PasteHandler(); handler != nil { handler(pastedText, setFocus) return } } } }) } golang-github-darkhz-tview-0.0~git20240308.6078a88/frame.go000066400000000000000000000141541457770046000226260ustar00rootroot00000000000000package tview import ( "github.com/gdamore/tcell/v2" ) // frameText holds information about a line of text shown in the frame. type frameText struct { Text string // The text to be displayed. Header bool // true = place in header, false = place in footer. Align int // One of the Align constants. Color tcell.Color // The text color. } // Frame is a wrapper which adds space around another primitive. In addition, // the top area (header) and the bottom area (footer) may also contain text. // // See https://github.com/rivo/tview/wiki/Frame for an example. type Frame struct { *Box // The contained primitive. May be nil. primitive Primitive // The lines of text to be displayed. text []*frameText // Border spacing. top, bottom, header, footer, left, right int // Keep a reference in case we need it when we change the primitive. setFocus func(p Primitive) } // NewFrame returns a new frame around the given primitive. The primitive's // size will be changed to fit within this frame. The primitive may be nil, in // which case no other primitive is embedded in the frame. func NewFrame(primitive Primitive) *Frame { box := NewBox() f := &Frame{ Box: box, primitive: primitive, top: 1, bottom: 1, header: 1, footer: 1, left: 1, right: 1, } return f } // SetPrimitive replaces the contained primitive with the given one. To remove // a primitive, set it to nil. func (f *Frame) SetPrimitive(p Primitive) *Frame { var hasFocus bool if f.primitive != nil { hasFocus = f.primitive.HasFocus() } f.primitive = p if hasFocus && f.setFocus != nil { f.setFocus(p) // Restore focus. } return f } // GetPrimitive returns the primitive contained in this frame. func (f *Frame) GetPrimitive() Primitive { return f.primitive } // AddText adds text to the frame. Set "header" to true if the text is to appear // in the header, above the contained primitive. Set it to false for it to // appear in the footer, below the contained primitive. "align" must be one of // the Align constants. Rows in the header are printed top to bottom, rows in // the footer are printed bottom to top. Note that long text can overlap as // different alignments will be placed on the same row. func (f *Frame) AddText(text string, header bool, align int, color tcell.Color) *Frame { f.text = append(f.text, &frameText{ Text: text, Header: header, Align: align, Color: color, }) return f } // Clear removes all text from the frame. func (f *Frame) Clear() *Frame { f.text = nil return f } // SetBorders sets the width of the frame borders as well as "header" and // "footer", the vertical space between the header and footer text and the // contained primitive (does not apply if there is no text). func (f *Frame) SetBorders(top, bottom, header, footer, left, right int) *Frame { f.top, f.bottom, f.header, f.footer, f.left, f.right = top, bottom, header, footer, left, right return f } // Draw draws this primitive onto the screen. func (f *Frame) Draw(screen tcell.Screen) { f.Box.DrawForSubclass(screen, f) // Calculate start positions. x, top, width, height := f.GetInnerRect() bottom := top + height - 1 x += f.left top += f.top bottom -= f.bottom width -= f.left + f.right if width <= 0 || top >= bottom { return // No space left. } // Draw text. var rows [6]int // top-left, top-center, top-right, bottom-left, bottom-center, bottom-right. topMax := top bottomMin := bottom for _, text := range f.text { // Where do we place this text? var y int if text.Header { y = top + rows[text.Align] rows[text.Align]++ if y >= bottomMin { continue } if y+1 > topMax { topMax = y + 1 } } else { y = bottom - rows[3+text.Align] rows[3+text.Align]++ if y <= topMax { continue } if y-1 < bottomMin { bottomMin = y - 1 } } // Draw text. Print(screen, text.Text, x, y, width, text.Align, text.Color) } // Set the size of the contained primitive. if f.primitive != nil { if topMax > top { top = topMax + f.header } if bottomMin < bottom { bottom = bottomMin - f.footer } if top > bottom { return // No space for the primitive. } f.primitive.SetRect(x, top, width, bottom+1-top) // Finally, draw the contained primitive. f.primitive.Draw(screen) } } // Focus is called when this primitive receives focus. func (f *Frame) Focus(delegate func(p Primitive)) { f.setFocus = delegate if f.primitive != nil { delegate(f.primitive) } else { f.Box.Focus(delegate) } } // HasFocus returns whether or not this primitive has focus. func (f *Frame) HasFocus() bool { if f.primitive == nil { return f.Box.HasFocus() } return f.primitive.HasFocus() } // MouseHandler returns the mouse handler for this primitive. func (f *Frame) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return f.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { if !f.InRect(event.Position()) { return false, nil } // Pass mouse events on to contained primitive. if f.primitive != nil { consumed, capture = f.primitive.MouseHandler()(action, event, setFocus) if consumed { return true, capture } } // Clicking on the frame parts. if action == MouseLeftDown { setFocus(f) consumed = true } return }) } // InputHandler returns the handler for this primitive. func (f *Frame) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) { return f.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) { if f.primitive == nil { return } if handler := f.primitive.InputHandler(); handler != nil { handler(event, setFocus) return } }) } // PasteHandler returns the handler for this primitive. func (f *Frame) PasteHandler() func(pastedText string, setFocus func(p Primitive)) { return f.WrapPasteHandler(func(pastedText string, setFocus func(p Primitive)) { if f.primitive == nil { return } if handler := f.primitive.PasteHandler(); handler != nil { handler(pastedText, setFocus) return } }) } golang-github-darkhz-tview-0.0~git20240308.6078a88/go.mod000066400000000000000000000006071457770046000223110ustar00rootroot00000000000000module github.com/darkhz/tview go 1.18 require ( github.com/gdamore/tcell/v2 v2.7.4 github.com/lucasb-eyer/go-colorful v1.2.0 github.com/rivo/uniseg v0.4.7 ) require ( github.com/gdamore/encoding v1.0.0 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect golang.org/x/sys v0.18.0 // indirect golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect ) golang-github-darkhz-tview-0.0~git20240308.6078a88/go.sum000066400000000000000000000107531457770046000223410ustar00rootroot00000000000000github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/gdamore/tcell/v2 v2.7.4 h1:sg6/UnTM9jGpZU+oFYAsDahfchWAFW8Xx2yFinNSAYU= github.com/gdamore/tcell/v2 v2.7.4/go.mod h1:dSXtXTSK0VsW1biw65DZLZ2NKr7j0qP/0J7ONmsraWg= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang-github-darkhz-tview-0.0~git20240308.6078a88/grid.go000066400000000000000000000511711457770046000224610ustar00rootroot00000000000000package tview import ( "math" "github.com/gdamore/tcell/v2" ) // gridItem represents one primitive and its possible position on a grid. type gridItem struct { Item Primitive // The item to be positioned. May be nil for an empty item. Row, Column int // The top-left grid cell where the item is placed. Width, Height int // The number of rows and columns the item occupies. MinGridWidth, MinGridHeight int // The minimum grid width/height for which this item is visible. Focus bool // Whether or not this item attracts the layout's focus. visible bool // Whether or not this item was visible the last time the grid was drawn. x, y, w, h int // The last position of the item relative to the top-left corner of the grid. Undefined if visible is false. } // Grid is an implementation of a grid-based layout. It works by defining the // size of the rows and columns, then placing primitives into the grid. // // Some settings can lead to the grid exceeding its available space. SetOffset() // can then be used to scroll in steps of rows and columns. These offset values // can also be controlled with the arrow keys (or the "g","G", "j", "k", "h", // and "l" keys) while the grid has focus and none of its contained primitives // do. // // See https://github.com/rivo/tview/wiki/Grid for an example. type Grid struct { *Box // The items to be positioned. items []*gridItem // The definition of the rows and columns of the grid. See // [Grid.SetRows] / [Grid.SetColumns] for details. rows, columns []int // The minimum sizes for rows and columns. minWidth, minHeight int // The size of the gaps between neighboring primitives. This is automatically // set to 1 if borders is true. gapRows, gapColumns int // The number of rows and columns skipped before drawing the top-left corner // of the grid. rowOffset, columnOffset int // Whether or not borders are drawn around grid items. If this is set to true, // a gap size of 1 is automatically assumed (which is filled with the border // graphics). borders bool // The color of the borders around grid items. bordersColor tcell.Color } // NewGrid returns a new grid-based layout container with no initial primitives. // // Note that Box, the superclass of Grid, will be transparent so that any grid // areas not covered by any primitives will leave their background unchanged. To // clear a Grid's background before any items are drawn, reset its Box to one // with the desired color: // // grid.Box = NewBox() func NewGrid() *Grid { g := &Grid{ bordersColor: Styles.GraphicsColor, } g.Box = NewBox() g.Box.dontClear = true return g } // SetColumns defines how the columns of the grid are distributed. Each value // defines the size of one column, starting with the leftmost column. Values // greater than 0 represent absolute column widths (gaps not included). Values // less than or equal to 0 represent proportional column widths or fractions of // the remaining free space, where 0 is treated the same as -1. That is, a // column with a value of -3 will have three times the width of a column with a // value of -1 (or 0). The minimum width set with SetMinSize() is always // observed. // // Primitives may extend beyond the columns defined explicitly with this // function. A value of 0 is assumed for any undefined column. In fact, if you // never call this function, all columns occupied by primitives will have the // same width. On the other hand, unoccupied columns defined with this function // will always take their place. // // Assuming a total width of the grid of 100 cells and a minimum width of 0, the // following call will result in columns with widths of 30, 10, 15, 15, and 30 // cells: // // grid.SetColumns(30, 10, -1, -1, -2) // // If a primitive were then placed in the 6th and 7th column, the resulting // widths would be: 30, 10, 10, 10, 20, 10, and 10 cells. // // If you then called SetMinSize() as follows: // // grid.SetMinSize(15, 20) // // The resulting widths would be: 30, 15, 15, 15, 20, 15, and 15 cells, a total // of 125 cells, 25 cells wider than the available grid width. func (g *Grid) SetColumns(columns ...int) *Grid { g.columns = columns return g } // SetRows defines how the rows of the grid are distributed. These values behave // the same as the column values provided with [Grid.SetColumns], see there // for a definition and examples. // // The provided values correspond to row heights, the first value defining // the height of the topmost row. func (g *Grid) SetRows(rows ...int) *Grid { g.rows = rows return g } // SetSize is a shortcut for [Grid.SetRows] and [Grid.SetColumns] where // all row and column values are set to the given size values. See // [Grid.SetColumns] for details on sizes. func (g *Grid) SetSize(numRows, numColumns, rowSize, columnSize int) *Grid { g.rows = make([]int, numRows) for index := range g.rows { g.rows[index] = rowSize } g.columns = make([]int, numColumns) for index := range g.columns { g.columns[index] = columnSize } return g } // SetMinSize sets an absolute minimum width for rows and an absolute minimum // height for columns. Panics if negative values are provided. func (g *Grid) SetMinSize(row, column int) *Grid { if row < 0 || column < 0 { panic("Invalid minimum row/column size") } g.minHeight, g.minWidth = row, column return g } // SetGap sets the size of the gaps between neighboring primitives on the grid. // If borders are drawn (see SetBorders()), these values are ignored and a gap // of 1 is assumed. Panics if negative values are provided. func (g *Grid) SetGap(row, column int) *Grid { if row < 0 || column < 0 { panic("Invalid gap size") } g.gapRows, g.gapColumns = row, column return g } // SetBorders sets whether or not borders are drawn around grid items. Setting // this value to true will cause the gap values (see SetGap()) to be ignored and // automatically assumed to be 1 where the border graphics are drawn. func (g *Grid) SetBorders(borders bool) *Grid { g.borders = borders return g } // SetBordersColor sets the color of the item borders. func (g *Grid) SetBordersColor(color tcell.Color) *Grid { g.bordersColor = color return g } // AddItem adds a primitive and its position to the grid. The top-left corner // of the primitive will be located in the top-left corner of the grid cell at // the given row and column and will span "rowSpan" rows and "colSpan" columns. // For example, for a primitive to occupy rows 2, 3, and 4 and columns 5 and 6: // // grid.AddItem(p, 2, 5, 3, 2, 0, 0, true) // // If rowSpan or colSpan is 0, the primitive will not be drawn. // // You can add the same primitive multiple times with different grid positions. // The minGridWidth and minGridHeight values will then determine which of those // positions will be used. This is similar to CSS media queries. These minimum // values refer to the overall size of the grid. If multiple items for the same // primitive apply, the one with the highest minimum value (width or height, // whatever is higher) will be used, or the primitive added last if those values // are the same. Example: // // grid.AddItem(p, 0, 0, 0, 0, 0, 0, true). // Hide in small grids. // AddItem(p, 0, 0, 1, 2, 100, 0, true). // One-column layout for medium grids. // AddItem(p, 1, 1, 3, 2, 300, 0, true) // Multi-column layout for large grids. // // To use the same grid layout for all sizes, simply set minGridWidth and // minGridHeight to 0. // // If the item's focus is set to true, it will receive focus when the grid // receives focus. If there are multiple items with a true focus flag, the last // visible one that was added will receive focus. func (g *Grid) AddItem(p Primitive, row, column, rowSpan, colSpan, minGridHeight, minGridWidth int, focus bool) *Grid { g.items = append(g.items, &gridItem{ Item: p, Row: row, Column: column, Height: rowSpan, Width: colSpan, MinGridHeight: minGridHeight, MinGridWidth: minGridWidth, Focus: focus, }) return g } // RemoveItem removes all items for the given primitive from the grid, keeping // the order of the remaining items intact. func (g *Grid) RemoveItem(p Primitive) *Grid { for index := len(g.items) - 1; index >= 0; index-- { if g.items[index].Item == p { g.items = append(g.items[:index], g.items[index+1:]...) } } return g } // Clear removes all items from the grid. func (g *Grid) Clear() *Grid { g.items = nil return g } // SetOffset sets the number of rows and columns which are skipped before // drawing the first grid cell in the top-left corner. As the grid will never // completely move off the screen, these values may be adjusted the next time // the grid is drawn. The actual position of the grid may also be adjusted such // that contained primitives that have focus remain visible. func (g *Grid) SetOffset(rows, columns int) *Grid { g.rowOffset, g.columnOffset = rows, columns return g } // GetOffset returns the current row and column offset (see SetOffset() for // details). func (g *Grid) GetOffset() (rows, columns int) { return g.rowOffset, g.columnOffset } // Focus is called when this primitive receives focus. func (g *Grid) Focus(delegate func(p Primitive)) { for _, item := range g.items { if item.Focus { delegate(item.Item) return } } g.Box.Focus(delegate) } // HasFocus returns whether or not this primitive has focus. func (g *Grid) HasFocus() bool { for _, item := range g.items { if item.visible && item.Item.HasFocus() { return true } } return g.Box.HasFocus() } // Draw draws this primitive onto the screen. func (g *Grid) Draw(screen tcell.Screen) { g.Box.DrawForSubclass(screen, g) x, y, width, height := g.GetInnerRect() screenWidth, screenHeight := screen.Size() // Make a list of items which apply. items := make([]*gridItem, 0, len(g.items)) ItemLoop: for _, item := range g.items { item.visible = false if item.Item == nil || item.Width <= 0 || item.Height <= 0 || width < item.MinGridWidth || height < item.MinGridHeight { continue // Disqualified. } // Check for overlaps. for index, existing := range items { // Do they overlap? if item.Row >= existing.Row+existing.Height || item.Row+item.Height <= existing.Row || item.Column >= existing.Column+existing.Width || item.Column+item.Width <= existing.Column { break // They don't. } // What's their minimum size? itemMin := item.MinGridWidth if item.MinGridHeight > itemMin { itemMin = item.MinGridHeight } existingMin := existing.MinGridWidth if existing.MinGridHeight > existingMin { existingMin = existing.MinGridHeight } // Which one is more important? if itemMin < existingMin { continue ItemLoop // This one isn't. Drop it. } items[index] = item continue ItemLoop } // This item will be visible. items = append(items, item) } // How many rows and columns do we have? rows := len(g.rows) columns := len(g.columns) for _, item := range items { rowEnd := item.Row + item.Height if rowEnd > rows { rows = rowEnd } columnEnd := item.Column + item.Width if columnEnd > columns { columns = columnEnd } } if rows == 0 || columns == 0 { return // No content. } // Where are they located? rowPos := make([]int, rows) rowHeight := make([]int, rows) columnPos := make([]int, columns) columnWidth := make([]int, columns) // How much space do we distribute? remainingWidth := width remainingHeight := height proportionalWidth := 0 proportionalHeight := 0 for index, row := range g.rows { if row > 0 { if row < g.minHeight { row = g.minHeight } remainingHeight -= row rowHeight[index] = row } else if row == 0 { proportionalHeight++ } else { proportionalHeight += -row } } for index, column := range g.columns { if column > 0 { if column < g.minWidth { column = g.minWidth } remainingWidth -= column columnWidth[index] = column } else if column == 0 { proportionalWidth++ } else { proportionalWidth += -column } } if g.borders { remainingHeight -= rows + 1 remainingWidth -= columns + 1 } else { remainingHeight -= (rows - 1) * g.gapRows remainingWidth -= (columns - 1) * g.gapColumns } if rows > len(g.rows) { proportionalHeight += rows - len(g.rows) } if columns > len(g.columns) { proportionalWidth += columns - len(g.columns) } // Distribute proportional rows/columns. for index := 0; index < rows; index++ { row := 0 if index < len(g.rows) { row = g.rows[index] } if row > 0 { continue // Not proportional. We already know the width. } else if row == 0 { row = 1 } else { row = -row } rowAbs := row * remainingHeight / proportionalHeight remainingHeight -= rowAbs proportionalHeight -= row if rowAbs < g.minHeight { rowAbs = g.minHeight } rowHeight[index] = rowAbs } for index := 0; index < columns; index++ { column := 0 if index < len(g.columns) { column = g.columns[index] } if column > 0 { continue // Not proportional. We already know the height. } else if column == 0 { column = 1 } else { column = -column } columnAbs := column * remainingWidth / proportionalWidth remainingWidth -= columnAbs proportionalWidth -= column if columnAbs < g.minWidth { columnAbs = g.minWidth } columnWidth[index] = columnAbs } // Calculate row/column positions. var columnX, rowY int if g.borders { columnX++ rowY++ } for index, row := range rowHeight { rowPos[index] = rowY gap := g.gapRows if g.borders { gap = 1 } rowY += row + gap } for index, column := range columnWidth { columnPos[index] = columnX gap := g.gapColumns if g.borders { gap = 1 } columnX += column + gap } // Calculate primitive positions. var focus *gridItem // The item which has focus. for _, item := range items { px := columnPos[item.Column] py := rowPos[item.Row] var pw, ph int for index := 0; index < item.Height; index++ { ph += rowHeight[item.Row+index] } for index := 0; index < item.Width; index++ { pw += columnWidth[item.Column+index] } if g.borders { pw += item.Width - 1 ph += item.Height - 1 } else { pw += (item.Width - 1) * g.gapColumns ph += (item.Height - 1) * g.gapRows } item.x, item.y, item.w, item.h = px, py, pw, ph item.visible = true if item.Item.HasFocus() { focus = item } } // Calculate screen offsets. var offsetX, offsetY int add := 1 if !g.borders { add = g.gapRows } for index, height := range rowHeight { if index >= g.rowOffset { break } offsetY += height + add } if !g.borders { add = g.gapColumns } for index, width := range columnWidth { if index >= g.columnOffset { break } offsetX += width + add } // Line up the last row/column with the end of the available area. var border int if g.borders { border = 1 } last := len(rowPos) - 1 if rowPos[last]+rowHeight[last]+border-offsetY < height { offsetY = rowPos[last] - height + rowHeight[last] + border } last = len(columnPos) - 1 if columnPos[last]+columnWidth[last]+border-offsetX < width { offsetX = columnPos[last] - width + columnWidth[last] + border } // The focused item must be within the visible area. if focus != nil { if focus.y+focus.h-offsetY >= height { offsetY = focus.y - height + focus.h } if focus.y-offsetY < 0 { offsetY = focus.y } if focus.x+focus.w-offsetX >= width { offsetX = focus.x - width + focus.w } if focus.x-offsetX < 0 { offsetX = focus.x } } // Adjust row/column offsets based on this value. var from, to int for index, pos := range rowPos { if pos-offsetY < 0 { from = index + 1 } if pos-offsetY < height { to = index } } if g.rowOffset < from { g.rowOffset = from } if g.rowOffset > to { g.rowOffset = to } from, to = 0, 0 for index, pos := range columnPos { if pos-offsetX < 0 { from = index + 1 } if pos-offsetX < width { to = index } } if g.columnOffset < from { g.columnOffset = from } if g.columnOffset > to { g.columnOffset = to } // Draw primitives and borders. borderStyle := tcell.StyleDefault.Background(g.backgroundColor).Foreground(g.bordersColor) for _, item := range items { // Final primitive position. if !item.visible { continue } item.x -= offsetX item.y -= offsetY if item.x >= width || item.x+item.w <= 0 || item.y >= height || item.y+item.h <= 0 { item.visible = false continue } if item.x+item.w > width { item.w = width - item.x } if item.y+item.h > height { item.h = height - item.y } if item.x < 0 { item.w += item.x item.x = 0 } if item.y < 0 { item.h += item.y item.y = 0 } if item.w <= 0 || item.h <= 0 { item.visible = false continue } item.x += x item.y += y item.Item.SetRect(item.x, item.y, item.w, item.h) // Draw primitive. if item == focus { defer item.Item.Draw(screen) } else { item.Item.Draw(screen) } // Draw border around primitive. if g.borders { for bx := item.x; bx < item.x+item.w; bx++ { // Top/bottom lines. if bx < 0 || bx >= screenWidth { continue } by := item.y - 1 if by >= 0 && by < screenHeight { PrintJoinedSemigraphics(screen, bx, by, Borders.Horizontal, borderStyle) } by = item.y + item.h if by >= 0 && by < screenHeight { PrintJoinedSemigraphics(screen, bx, by, Borders.Horizontal, borderStyle) } } for by := item.y; by < item.y+item.h; by++ { // Left/right lines. if by < 0 || by >= screenHeight { continue } bx := item.x - 1 if bx >= 0 && bx < screenWidth { PrintJoinedSemigraphics(screen, bx, by, Borders.Vertical, borderStyle) } bx = item.x + item.w if bx >= 0 && bx < screenWidth { PrintJoinedSemigraphics(screen, bx, by, Borders.Vertical, borderStyle) } } bx, by := item.x-1, item.y-1 // Top-left corner. if bx >= 0 && bx < screenWidth && by >= 0 && by < screenHeight { PrintJoinedSemigraphics(screen, bx, by, Borders.TopLeft, borderStyle) } bx, by = item.x+item.w, item.y-1 // Top-right corner. if bx >= 0 && bx < screenWidth && by >= 0 && by < screenHeight { PrintJoinedSemigraphics(screen, bx, by, Borders.TopRight, borderStyle) } bx, by = item.x-1, item.y+item.h // Bottom-left corner. if bx >= 0 && bx < screenWidth && by >= 0 && by < screenHeight { PrintJoinedSemigraphics(screen, bx, by, Borders.BottomLeft, borderStyle) } bx, by = item.x+item.w, item.y+item.h // Bottom-right corner. if bx >= 0 && bx < screenWidth && by >= 0 && by < screenHeight { PrintJoinedSemigraphics(screen, bx, by, Borders.BottomRight, borderStyle) } } } } // MouseHandler returns the mouse handler for this primitive. func (g *Grid) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return g.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { if !g.InRect(event.Position()) { return false, nil } // Pass mouse events along to the first child item that takes it. for _, item := range g.items { if item.Item == nil { continue } consumed, capture = item.Item.MouseHandler()(action, event, setFocus) if consumed { return } } return }) } // InputHandler returns the handler for this primitive. func (g *Grid) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) { return g.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) { if !g.hasFocus { // Pass event on to child primitive. for _, item := range g.items { if item != nil && item.Item.HasFocus() { if handler := item.Item.InputHandler(); handler != nil { handler(event, setFocus) return } } } return } // Process our own key events if we have direct focus. switch event.Key() { case tcell.KeyRune: switch event.Rune() { case 'g': g.rowOffset, g.columnOffset = 0, 0 case 'G': g.rowOffset = math.MaxInt32 case 'j': g.rowOffset++ case 'k': g.rowOffset-- case 'h': g.columnOffset-- case 'l': g.columnOffset++ } case tcell.KeyHome: g.rowOffset, g.columnOffset = 0, 0 case tcell.KeyEnd: g.rowOffset = math.MaxInt32 case tcell.KeyUp: g.rowOffset-- case tcell.KeyDown: g.rowOffset++ case tcell.KeyLeft: g.columnOffset-- case tcell.KeyRight: g.columnOffset++ } }) } // PasteHandler returns the handler for this primitive. func (g *Grid) PasteHandler() func(pastedText string, setFocus func(p Primitive)) { return g.WrapPasteHandler(func(pastedText string, setFocus func(p Primitive)) { for _, item := range g.items { if item != nil && item.Item.HasFocus() { if handler := item.Item.PasteHandler(); handler != nil { handler(pastedText, setFocus) return } } } }) } golang-github-darkhz-tview-0.0~git20240308.6078a88/image.go000066400000000000000000000612161457770046000226170ustar00rootroot00000000000000package tview import ( "image" "math" "github.com/gdamore/tcell/v2" ) // Types of dithering applied to images. const ( DitheringNone = iota // No dithering. DitheringFloydSteinberg // Floyd-Steinberg dithering (the default). ) // The number of colors supported by true color terminals (R*G*B = 256*256*256). const TrueColor = 16777216 // This map describes what each block element looks like. A 1 bit represents a // pixel that is drawn, a 0 bit represents a pixel that is not drawn. The least // significant bit is the top left pixel, the most significant bit is the bottom // right pixel, moving row by row from left to right, top to bottom. var blockElements = map[rune]uint64{ BlockLowerOneEighthBlock: 0b1111111100000000000000000000000000000000000000000000000000000000, BlockLowerOneQuarterBlock: 0b1111111111111111000000000000000000000000000000000000000000000000, BlockLowerThreeEighthsBlock: 0b1111111111111111111111110000000000000000000000000000000000000000, BlockLowerHalfBlock: 0b1111111111111111111111111111111100000000000000000000000000000000, BlockLowerFiveEighthsBlock: 0b1111111111111111111111111111111111111111000000000000000000000000, BlockLowerThreeQuartersBlock: 0b1111111111111111111111111111111111111111111111110000000000000000, BlockLowerSevenEighthsBlock: 0b1111111111111111111111111111111111111111111111111111111100000000, BlockLeftSevenEighthsBlock: 0b0111111101111111011111110111111101111111011111110111111101111111, BlockLeftThreeQuartersBlock: 0b0011111100111111001111110011111100111111001111110011111100111111, BlockLeftFiveEighthsBlock: 0b0001111100011111000111110001111100011111000111110001111100011111, BlockLeftHalfBlock: 0b0000111100001111000011110000111100001111000011110000111100001111, BlockLeftThreeEighthsBlock: 0b0000011100000111000001110000011100000111000001110000011100000111, BlockLeftOneQuarterBlock: 0b0000001100000011000000110000001100000011000000110000001100000011, BlockLeftOneEighthBlock: 0b0000000100000001000000010000000100000001000000010000000100000001, BlockQuadrantLowerLeft: 0b0000111100001111000011110000111100000000000000000000000000000000, BlockQuadrantLowerRight: 0b1111000011110000111100001111000000000000000000000000000000000000, BlockQuadrantUpperLeft: 0b0000000000000000000000000000000000001111000011110000111100001111, BlockQuadrantUpperRight: 0b0000000000000000000000000000000011110000111100001111000011110000, BlockQuadrantUpperLeftAndLowerRight: 0b1111000011110000111100001111000000001111000011110000111100001111, } // pixel represents a character on screen used to draw part of an image. type pixel struct { style tcell.Style element rune // The block element. } // Image implements a widget that displays one image. The original image // (specified with [Image.SetImage]) is resized according to the specified size // (see [Image.SetSize]), using the specified number of colors (see // [Image.SetColors]), while applying dithering if necessary (see // [Image.SetDithering]). // // Images are approximated by graphical characters in the terminal. The // resolution is therefore limited by the number and type of characters that can // be drawn in the terminal and the colors available in the terminal. The // quality of the final image also depends on the terminal's font and spacing // settings, none of which are under the control of this package. Results may // vary. type Image struct { *Box // The image to be displayed. If nil, the widget will be empty. image image.Image // The size of the image. If a value is 0, the corresponding size is chosen // automatically based on the other size while preserving the image's aspect // ratio. If both are 0, the image uses as much space as possible. A // negative value represents a percentage, e.g. -50 means 50% of the // available space. width, height int // The number of colors to use. If 0, the number of colors is chosen based // on the terminal's capabilities. colors int // The dithering algorithm to use, one of the constants starting with // "ImageDithering". dithering int // The width of a terminal's cell divided by its height. aspectRatio float64 // Horizontal and vertical alignment, one of the "Align" constants. alignHorizontal, alignVertical int // The text to be displayed before the image. label string // The label style. labelStyle tcell.Style // The screen width of the label area. A value of 0 means use the width of // the label text. labelWidth int // The actual image size (in cells) when it was drawn the last time. lastWidth, lastHeight int // The actual image (in cells) when it was drawn the last time. The size of // this slice is lastWidth * lastHeight, indexed by y*lastWidth + x. pixels []pixel // A callback function set by the Form class and called when the user leaves // this form item. finished func(tcell.Key) } // NewImage returns a new image widget with an empty image (use [Image.SetImage] // to specify the image to be displayed). The image will use the widget's entire // available space. The dithering algorithm is set to Floyd-Steinberg dithering. // The terminal's cell aspect ratio defaults to 0.5. func NewImage() *Image { return &Image{ Box: NewBox(), dithering: DitheringFloydSteinberg, aspectRatio: 0.5, alignHorizontal: AlignCenter, alignVertical: AlignCenter, } } // SetImage sets the image to be displayed. If nil, the widget will be empty. func (i *Image) SetImage(image image.Image) *Image { i.image = image i.lastWidth, i.lastHeight = 0, 0 return i } // SetSize sets the size of the image. Positive values refer to cells in the // terminal. Negative values refer to a percentage of the available space (e.g. // -50 means 50%). A value of 0 means that the corresponding size is chosen // automatically based on the other size while preserving the image's aspect // ratio. If both are 0, the image uses as much space as possible while still // preserving the aspect ratio. func (i *Image) SetSize(rows, columns int) *Image { i.width = columns i.height = rows return i } // SetColors sets the number of colors to use. This should be the number of // colors supported by the terminal. If 0, the number of colors is chosen based // on the TERM environment variable (which may or may not be reliable). // // Only the values 0, 2, 8, 256, and 16777216 ([TrueColor]) are supported. Other // values will be rounded up to the next supported value, to a maximum of // 16777216. // // The effect of using more colors than supported by the terminal is undefined. func (i *Image) SetColors(colors int) *Image { i.colors = colors i.lastWidth, i.lastHeight = 0, 0 return i } // GetColors returns the number of colors that will be used while drawing the // image. This is one of the values listed in [Image.SetColors], except 0 which // will be replaced by the actual number of colors used. func (i *Image) GetColors() int { switch { case i.colors == 0: return availableColors case i.colors <= 2: return 2 case i.colors <= 8: return 8 case i.colors <= 256: return 256 } return TrueColor } // SetDithering sets the dithering algorithm to use, one of the constants // starting with "Dithering", for example [DitheringFloydSteinberg] (the // default). Dithering is not applied when rendering in true-color. func (i *Image) SetDithering(dithering int) *Image { i.dithering = dithering i.lastWidth, i.lastHeight = 0, 0 return i } // SetAspectRatio sets the width of a terminal's cell divided by its height. // You may change the default of 0.5 if your terminal / font has a different // aspect ratio. This is used to calculate the size of the image if the // specified width or height is 0. The function will panic if the aspect ratio // is 0 or less. func (i *Image) SetAspectRatio(aspectRatio float64) *Image { if aspectRatio <= 0 { panic("aspect ratio must be greater than 0") } i.aspectRatio = aspectRatio i.lastWidth, i.lastHeight = 0, 0 return i } // SetAlign sets the vertical and horizontal alignment of the image within the // widget's space. The possible values are [AlignTop], [AlignCenter], and // [AlignBottom] for vertical alignment and [AlignLeft], [AlignCenter], and // [AlignRight] for horizontal alignment. The default is [AlignCenter] for both // (or [AlignTop] and [AlignLeft] if the image is part of a [Form]). func (i *Image) SetAlign(vertical, horizontal int) *Image { i.alignHorizontal = horizontal i.alignVertical = vertical return i } // SetLabel sets the text to be displayed before the image. func (i *Image) SetLabel(label string) *Image { i.label = label return i } // GetLabel returns the text to be displayed before the image. func (i *Image) GetLabel() string { return i.label } // SetLabelWidth sets the screen width of the label. A value of 0 will cause the // primitive to use the width of the label string. func (i *Image) SetLabelWidth(width int) *Image { i.labelWidth = width return i } // GetFieldWidth returns this primitive's field width. This is the image's width // or, if the width is 0 or less, the proportional width of the image based on // its height as returned by [Image.GetFieldHeight]. If there is no image, 0 is // returned. func (i *Image) GetFieldWidth() int { if i.width <= 0 { if i.image == nil { return 0 } bounds := i.image.Bounds() height := i.GetFieldHeight() return bounds.Dx() * height / bounds.Dy() } return i.width } // GetFieldHeight returns this primitive's field height. This is the image's // height or 8 if the height is 0 or less. func (i *Image) GetFieldHeight() int { if i.height <= 0 { return 8 } return i.height } // SetDisabled sets whether or not the item is disabled / read-only. func (i *Image) SetDisabled(disabled bool) FormItem { return i // Images are always read-only. } // SetFormAttributes sets attributes shared by all form items. func (i *Image) SetFormAttributes(labelWidth int, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem { i.labelWidth = labelWidth i.backgroundColor = bgColor i.SetLabelStyle(tcell.StyleDefault.Foreground(labelColor).Background(bgColor)) i.lastWidth, i.lastHeight = 0, 0 return i } // SetLabelStyle sets the style of the label. func (i *Image) SetLabelStyle(style tcell.Style) *Image { i.labelStyle = style return i } // GetLabelStyle returns the style of the label. func (i *Image) GetLabelStyle() tcell.Style { return i.labelStyle } // SetFinishedFunc sets a callback invoked when the user leaves this form item. func (i *Image) SetFinishedFunc(handler func(key tcell.Key)) FormItem { i.finished = handler return i } // Focus is called when this primitive receives focus. func (i *Image) Focus(delegate func(p Primitive)) { // If we're part of a form, there's nothing the user can do here so we're // finished. if i.finished != nil { i.finished(-1) return } i.Box.Focus(delegate) } // render re-populates the [Image.pixels] slice based on the current settings, // if [Image.lastWidth] and [Image.lastHeight] don't match the current image's // size. It also sets the new image size in these two variables. func (i *Image) render() { // If there is no image, there are no pixels. if i.image == nil { i.pixels = nil return } // Calculate the new (terminal-space) image size. bounds := i.image.Bounds() imageWidth, imageHeight := bounds.Dx(), bounds.Dy() if i.aspectRatio != 1.0 { imageWidth = int(float64(imageWidth) / i.aspectRatio) } width, height := i.width, i.height _, _, innerWidth, innerHeight := i.GetInnerRect() if i.labelWidth > 0 { innerWidth -= i.labelWidth } else { innerWidth -= TaggedStringWidth(i.label) } if innerWidth <= 0 { i.pixels = nil return } if width == 0 && height == 0 { // Use all available space. width, height = innerWidth, innerHeight if adjustedWidth := imageWidth * height / imageHeight; adjustedWidth < width { width = adjustedWidth } else { height = imageHeight * width / imageWidth } } else { // Turn percentages into absolute values. if width < 0 { width = innerWidth * -width / 100 } if height < 0 { height = innerHeight * -height / 100 } if width == 0 { // Adjust the width. width = imageWidth * height / imageHeight } else if height == 0 { // Adjust the height. height = imageHeight * width / imageWidth } } if width <= 0 || height <= 0 { i.pixels = nil return } // If nothing has changed, we're done. if i.lastWidth == width && i.lastHeight == height { return } i.lastWidth, i.lastHeight = width, height // This could still be larger than the available space but that's ok for now. // Generate the initial pixels by resizing the image (8x8 per cell). pixels := i.resize() // Turn them into block elements with background/foreground colors. i.stamp(pixels) } // resize resizes the image to the current size and returns the result as a // slice of pixels. It is assumed that [Image.lastWidth] (w) and // [Image.lastHeight] (h) are positive, non-zero values, and the slice has a // size of 64*w*h, with each pixel being represented by 3 float64 values in the // range of 0-1. The factor of 64 is due to the fact that we calculate 8x8 // pixels per cell. func (i *Image) resize() [][3]float64 { // Because most of the time, we will be downsizing the image, we don't even // attempt to do any fancy interpolation. For each target pixel, we // calculate a weighted average of the source pixels using their coverage // area. bounds := i.image.Bounds() srcWidth, srcHeight := bounds.Dx(), bounds.Dy() tgtWidth, tgtHeight := i.lastWidth*8, i.lastHeight*8 coverageWidth, coverageHeight := float64(tgtWidth)/float64(srcWidth), float64(tgtHeight)/float64(srcHeight) pixels := make([][3]float64, tgtWidth*tgtHeight) weights := make([]float64, tgtWidth*tgtHeight) for srcY := bounds.Min.Y; srcY < bounds.Max.Y; srcY++ { for srcX := bounds.Min.X; srcX < bounds.Max.X; srcX++ { r32, g32, b32, _ := i.image.At(srcX, srcY).RGBA() r, g, b := float64(r32)/0xffff, float64(g32)/0xffff, float64(b32)/0xffff // Iterate over all target pixels. Outer loop is Y. startY := float64(srcY-bounds.Min.Y) * coverageHeight endY := startY + coverageHeight fromY, toY := int(startY), int(endY) for tgtY := fromY; tgtY <= toY && tgtY < tgtHeight; tgtY++ { coverageY := 1.0 if tgtY == fromY { coverageY -= math.Mod(startY, 1.0) } if tgtY == toY { coverageY -= 1.0 - math.Mod(endY, 1.0) } // Inner loop is X. startX := float64(srcX-bounds.Min.X) * coverageWidth endX := startX + coverageWidth fromX, toX := int(startX), int(endX) for tgtX := fromX; tgtX <= toX && tgtX < tgtWidth; tgtX++ { coverageX := 1.0 if tgtX == fromX { coverageX -= math.Mod(startX, 1.0) } if tgtX == toX { coverageX -= 1.0 - math.Mod(endX, 1.0) } // Add a weighted contribution to the target pixel. index := tgtY*tgtWidth + tgtX coverage := coverageX * coverageY pixels[index][0] += r * coverage pixels[index][1] += g * coverage pixels[index][2] += b * coverage weights[index] += coverage } } } } // Normalize the pixels. for index, weight := range weights { if weight > 0 { pixels[index][0] /= weight pixels[index][1] /= weight pixels[index][2] /= weight } } return pixels } // stamp takes the pixels generated by [Image.resize] and populates the // [Image.pixels] slice accordingly. func (i *Image) stamp(resized [][3]float64) { // For each 8x8 pixel block, we find the best block element to represent it, // given the available colors. i.pixels = make([]pixel, i.lastWidth*i.lastHeight) colors := i.GetColors() for row := 0; row < i.lastHeight; row++ { for col := 0; col < i.lastWidth; col++ { // Calculate an error for each potential block element + color. Keep // the one with the lowest error. // Note that the values in "resize" may lie outside [0, 1] due to // the error distribution during dithering. minMSE := math.MaxFloat64 // Mean squared error. var final [64][3]float64 // The final pixel values. for element, bits := range blockElements { // Calculate the average color for the pixels covered by the set // bits and unset bits. var ( bg, fg [3]float64 setBits float64 bit uint64 = 1 ) for y := 0; y < 8; y++ { for x := 0; x < 8; x++ { index := (row*8+y)*i.lastWidth*8 + (col*8 + x) if bits&bit != 0 { fg[0] += resized[index][0] fg[1] += resized[index][1] fg[2] += resized[index][2] setBits++ } else { bg[0] += resized[index][0] bg[1] += resized[index][1] bg[2] += resized[index][2] } bit <<= 1 } } for ch := 0; ch < 3; ch++ { fg[ch] /= setBits if fg[ch] < 0 { fg[ch] = 0 } else if fg[ch] > 1 { fg[ch] = 1 } bg[ch] /= 64 - setBits if bg[ch] < 0 { bg[ch] = 0 } if bg[ch] > 1 { bg[ch] = 1 } } // Quantize to the nearest acceptable color. for _, color := range []*[3]float64{&fg, &bg} { if colors == 2 { // Monochrome. The following weights correspond better // to human perception than the arithmetic mean. gray := 0.299*color[0] + 0.587*color[1] + 0.114*color[2] if gray < 0.5 { *color = [3]float64{0, 0, 0} } else { *color = [3]float64{1, 1, 1} } } else { for index, ch := range color { switch { case colors == 8: // Colors vary wildly for each terminal. Expect // suboptimal results. if ch < 0.5 { color[index] = 0 } else { color[index] = 1 } case colors == 256: color[index] = math.Round(ch*6) / 6 } } } } // Calculate the error (and the final pixel values). var ( mse float64 values [64][3]float64 valuesIndex int ) bit = 1 for y := 0; y < 8; y++ { for x := 0; x < 8; x++ { if bits&bit != 0 { values[valuesIndex] = fg } else { values[valuesIndex] = bg } index := (row*8+y)*i.lastWidth*8 + (col*8 + x) for ch := 0; ch < 3; ch++ { err := resized[index][ch] - values[valuesIndex][ch] mse += err * err } bit <<= 1 valuesIndex++ } } // Do we have a better match? if mse < minMSE { // Yes. Save it. minMSE = mse final = values index := row*i.lastWidth + col i.pixels[index].element = element i.pixels[index].style = tcell.StyleDefault. Foreground(tcell.NewRGBColor(int32(math.Min(255, fg[0]*255)), int32(math.Min(255, fg[1]*255)), int32(math.Min(255, fg[2]*255)))). Background(tcell.NewRGBColor(int32(math.Min(255, bg[0]*255)), int32(math.Min(255, bg[1]*255)), int32(math.Min(255, bg[2]*255)))) } } // Check if there is a shade block which results in a smaller error. // What's the overall average color? var avg [3]float64 for y := 0; y < 8; y++ { for x := 0; x < 8; x++ { index := (row*8+y)*i.lastWidth*8 + (col*8 + x) for ch := 0; ch < 3; ch++ { avg[ch] += resized[index][ch] / 64 } } } for ch := 0; ch < 3; ch++ { if avg[ch] < 0 { avg[ch] = 0 } else if avg[ch] > 1 { avg[ch] = 1 } } // Quantize and choose shade element. element := BlockFullBlock var fg, bg tcell.Color shades := []rune{' ', BlockLightShade, BlockMediumShade, BlockDarkShade, BlockFullBlock} if colors == 2 { // Monochrome. gray := 0.299*avg[0] + 0.587*avg[1] + 0.114*avg[2] // See above for details. shade := int(math.Round(gray * 4)) element = shades[shade] for ch := 0; ch < 3; ch++ { avg[ch] = float64(shade) / 4 } bg = tcell.ColorBlack fg = tcell.ColorWhite } else if colors == TrueColor { // True color. fg = tcell.NewRGBColor(int32(math.Min(255, avg[0]*255)), int32(math.Min(255, avg[1]*255)), int32(math.Min(255, avg[2]*255))) bg = fg } else { // 8 or 256 colors. steps := 1.0 if colors == 256 { steps = 6.0 } var ( lo, hi, pos [3]float64 shade float64 ) for ch := 0; ch < 3; ch++ { lo[ch] = math.Floor(avg[ch]*steps) / steps hi[ch] = math.Ceil(avg[ch]*steps) / steps if r := hi[ch] - lo[ch]; r > 0 { pos[ch] = (avg[ch] - lo[ch]) / r if math.Abs(pos[ch]-0.5) < math.Abs(shade-0.5) { shade = pos[ch] } } } shade = math.Round(shade * 4) element = shades[int(shade)] shade /= 4 for ch := 0; ch < 3; ch++ { // Find the closest channel value. best := math.Abs(avg[ch] - (lo[ch] + (hi[ch]-lo[ch])*shade)) // Start shade from lo to hi. if value := math.Abs(avg[ch] - (hi[ch] - (hi[ch]-lo[ch])*shade)); value < best { best = value // Swap lo and hi. lo[ch], hi[ch] = hi[ch], lo[ch] } if value := math.Abs(avg[ch] - lo[ch]); value < best { best = value // Use lo. hi[ch] = lo[ch] } if value := math.Abs(avg[ch] - hi[ch]); value < best { lo[ch] = hi[ch] // Use hi. } avg[ch] = lo[ch] + (hi[ch]-lo[ch])*shade // Quantize. } bg = tcell.NewRGBColor(int32(math.Min(255, lo[0]*255)), int32(math.Min(255, lo[1]*255)), int32(math.Min(255, lo[2]*255))) fg = tcell.NewRGBColor(int32(math.Min(255, hi[0]*255)), int32(math.Min(255, hi[1]*255)), int32(math.Min(255, hi[2]*255))) } // Calculate the error (and the final pixel values). var ( mse float64 values [64][3]float64 valuesIndex int ) for y := 0; y < 8; y++ { for x := 0; x < 8; x++ { index := (row*8+y)*i.lastWidth*8 + (col*8 + x) for ch := 0; ch < 3; ch++ { err := resized[index][ch] - avg[ch] mse += err * err } values[valuesIndex] = avg valuesIndex++ } } // Is this shade element better than the block element? if mse < minMSE { // Yes. Save it. final = values index := row*i.lastWidth + col i.pixels[index].element = element i.pixels[index].style = tcell.StyleDefault.Foreground(fg).Background(bg) } // Apply dithering. if colors < TrueColor && i.dithering == DitheringFloydSteinberg { // The dithering mask determines how the error is distributed. // Each element has three values: dx, dy, and weight (in 16th). var mask = [4][3]int{ {1, 0, 7}, {-1, 1, 3}, {0, 1, 5}, {1, 1, 1}, } // We dither the 8x8 block as a 2x2 block, transferring errors // to its 2x2 neighbors. for ch := 0; ch < 3; ch++ { for y := 0; y < 2; y++ { for x := 0; x < 2; x++ { // What's the error for this 4x4 block? var err float64 for dy := 0; dy < 4; dy++ { for dx := 0; dx < 4; dx++ { err += (final[(y*4+dy)*8+(x*4+dx)][ch] - resized[(row*8+(y*4+dy))*i.lastWidth*8+(col*8+(x*4+dx))][ch]) / 16 } } // Distribute it to the 2x2 neighbors. for _, dist := range mask { for dy := 0; dy < 4; dy++ { for dx := 0; dx < 4; dx++ { targetX, targetY := (x+dist[0])*4+dx, (y+dist[1])*4+dy if targetX < 0 || col*8+targetX >= i.lastWidth*8 || targetY < 0 || row*8+targetY >= i.lastHeight*8 { continue } resized[(row*8+targetY)*i.lastWidth*8+(col*8+targetX)][ch] -= err * float64(dist[2]) / 16 } } } } } } } } } } // Draw draws this primitive onto the screen. func (i *Image) Draw(screen tcell.Screen) { i.DrawForSubclass(screen, i) // Regenerate image if necessary. i.render() // Draw label. viewX, viewY, viewWidth, viewHeight := i.GetInnerRect() _, labelBg, _ := i.labelStyle.Decompose() if i.labelWidth > 0 { labelWidth := i.labelWidth if labelWidth > viewWidth { labelWidth = viewWidth } printWithStyle(screen, i.label, viewX, viewY, 0, labelWidth, AlignLeft, i.labelStyle, labelBg == tcell.ColorDefault) viewX += labelWidth viewWidth -= labelWidth } else { _, _, drawnWidth := printWithStyle(screen, i.label, viewX, viewY, 0, viewWidth, AlignLeft, i.labelStyle, labelBg == tcell.ColorDefault) viewX += drawnWidth viewWidth -= drawnWidth } // Determine image placement. x, y, width, height := viewX, viewY, i.lastWidth, i.lastHeight if i.alignHorizontal == AlignCenter { x += (viewWidth - width) / 2 } else if i.alignHorizontal == AlignRight { x += viewWidth - width } if i.alignVertical == AlignCenter { y += (viewHeight - height) / 2 } else if i.alignVertical == AlignBottom { y += viewHeight - height } // Draw the image. for row := 0; row < height; row++ { if y+row < viewY || y+row >= viewY+viewHeight { continue } for col := 0; col < width; col++ { if x+col < viewX || x+col >= viewX+viewWidth { continue } index := row*width + col screen.SetContent(x+col, y+row, i.pixels[index].element, nil, i.pixels[index].style) } } } golang-github-darkhz-tview-0.0~git20240308.6078a88/inputfield.go000066400000000000000000000546171457770046000237070ustar00rootroot00000000000000package tview import ( "strconv" "strings" "sync" "github.com/gdamore/tcell/v2" "github.com/rivo/uniseg" ) const ( AutocompletedNavigate = iota // The user navigated the autocomplete list (using the errow keys). AutocompletedTab // The user selected an autocomplete entry using the tab key. AutocompletedEnter // The user selected an autocomplete entry using the enter key. AutocompletedClick // The user selected an autocomplete entry by clicking the mouse button on it. ) // Predefined InputField acceptance functions. var ( // InputFieldInteger accepts integers. InputFieldInteger = func(text string, ch rune) bool { if text == "-" { return true } _, err := strconv.Atoi(text) return err == nil } // InputFieldFloat accepts floating-point numbers. InputFieldFloat = func(text string, ch rune) bool { if text == "-" || text == "." || text == "-." { return true } _, err := strconv.ParseFloat(text, 64) return err == nil } // InputFieldMaxLength returns an input field accept handler which accepts // input strings up to a given length. Use it like this: // // inputField.SetAcceptanceFunc(InputFieldMaxLength(10)) // Accept up to 10 characters. InputFieldMaxLength = func(maxLength int) func(text string, ch rune) bool { return func(text string, ch rune) bool { return len([]rune(text)) <= maxLength } } ) // InputField is a one-line box into which the user can enter text. Use // [InputField.SetAcceptanceFunc] to accept or reject input, // [InputField.SetChangedFunc] to listen for changes, and // [InputField.SetMaskCharacter] to hide input from onlookers (e.g. for password // input). // // The input field also has an optional autocomplete feature. It is initialized // by the [InputField.SetAutocompleteFunc] function. For more control over the // autocomplete drop-down's behavior, you can also set the // [InputField.SetAutocompletedFunc]. // // Navigation and editing is the same as for a [TextArea], with the following // exceptions: // // - Tab, BackTab, Enter, Escape: Finish editing. // // Note that while pressing Tab or Enter is intercepted by the input field, it // is possible to paste such characters into the input field, possibly resulting // in multi-line input. You can use [InputField.SetAcceptanceFunc] to prevent // this. // // If autocomplete functionality is configured: // // - Down arrow: Open the autocomplete drop-down. // - Tab, Enter: Select the current autocomplete entry. // // See https://github.com/rivo/tview/wiki/InputField for an example. type InputField struct { *Box // The text area providing the core functionality of the input field. textArea *TextArea // The screen width of the input area. A value of 0 means extend as much as // possible. fieldWidth int // An optional autocomplete function which receives the current text of the // input field and returns a slice of strings to be displayed in a drop-down // selection. autocomplete func(text string) []string // The List object which shows the selectable autocomplete entries. If not // nil, the list's main texts represent the current autocomplete entries. autocompleteList *List autocompleteListMutex sync.Mutex // The styles of the autocomplete entries. autocompleteStyles struct { main tcell.Style selected tcell.Style background tcell.Color } // An optional function which is called when the user selects an // autocomplete entry. The text and index of the selected entry (within the // list) is provided, as well as the user action causing the selection (one // of the "Autocompleted" values). The function should return true if the // autocomplete list should be closed. If nil, the input field will be // updated automatically when the user navigates the autocomplete list. autocompleted func(text string, index int, source int) bool // An optional function which may reject the last character that was entered. accept func(text string, ch rune) bool // An optional function which is called when the input has changed. changed func(text string) // An optional function which is called when the user indicated that they // are done entering text. The key which was pressed is provided (tab, // shift-tab, enter, or escape). done func(tcell.Key) // A callback function set by the Form class and called when the user leaves // this form item. finished func(tcell.Key) } // NewInputField returns a new input field. func NewInputField() *InputField { i := &InputField{ Box: NewBox(), textArea: NewTextArea().SetWrap(false), } i.textArea.SetChangedFunc(func() { if i.changed != nil { i.changed(i.textArea.GetText()) } }) i.textArea.textStyle = tcell.StyleDefault.Background(Styles.ContrastBackgroundColor).Foreground(Styles.PrimaryTextColor) i.textArea.placeholderStyle = tcell.StyleDefault.Background(Styles.ContrastBackgroundColor).Foreground(Styles.ContrastSecondaryTextColor) i.autocompleteStyles.main = tcell.StyleDefault.Foreground(Styles.PrimitiveBackgroundColor) i.autocompleteStyles.selected = tcell.StyleDefault.Background(Styles.PrimaryTextColor).Foreground(Styles.PrimitiveBackgroundColor) i.autocompleteStyles.background = Styles.MoreContrastBackgroundColor return i } // SetText sets the current text of the input field. This can be undone by the // user. Calling this function will also trigger a "changed" event. func (i *InputField) SetText(text string) *InputField { i.textArea.Replace(0, i.textArea.GetTextLength(), text) return i } // GetText returns the current text of the input field. func (i *InputField) GetText() string { return i.textArea.GetText() } // SetLabel sets the text to be displayed before the input area. func (i *InputField) SetLabel(label string) *InputField { i.textArea.SetLabel(label) return i } // GetLabel returns the text to be displayed before the input area. func (i *InputField) GetLabel() string { return i.textArea.GetLabel() } // SetLabelWidth sets the screen width of the label. A value of 0 will cause the // primitive to use the width of the label string. func (i *InputField) SetLabelWidth(width int) *InputField { i.textArea.SetLabelWidth(width) return i } // SetPlaceholder sets the text to be displayed when the input text is empty. func (i *InputField) SetPlaceholder(text string) *InputField { i.textArea.SetPlaceholder(text) return i } // SetLabelColor sets the text color of the label. func (i *InputField) SetLabelColor(color tcell.Color) *InputField { i.textArea.SetLabelStyle(i.textArea.GetLabelStyle().Foreground(color)) return i } // SetLabelStyle sets the style of the label. func (i *InputField) SetLabelStyle(style tcell.Style) *InputField { i.textArea.SetLabelStyle(style) return i } // GetLabelStyle returns the style of the label. func (i *InputField) GetLabelStyle() tcell.Style { return i.textArea.GetLabelStyle() } // SetFieldBackgroundColor sets the background color of the input area. func (i *InputField) SetFieldBackgroundColor(color tcell.Color) *InputField { i.textArea.SetTextStyle(i.textArea.GetTextStyle().Background(color)) return i } // SetFieldTextColor sets the text color of the input area. func (i *InputField) SetFieldTextColor(color tcell.Color) *InputField { i.textArea.SetTextStyle(i.textArea.GetTextStyle().Foreground(color)) return i } // SetFieldStyle sets the style of the input area (when no placeholder is // shown). func (i *InputField) SetFieldStyle(style tcell.Style) *InputField { i.textArea.SetTextStyle(style) return i } // GetFieldStyle returns the style of the input area (when no placeholder is // shown). func (i *InputField) GetFieldStyle() tcell.Style { return i.textArea.GetTextStyle() } // SetPlaceholderTextColor sets the text color of placeholder text. func (i *InputField) SetPlaceholderTextColor(color tcell.Color) *InputField { i.textArea.SetPlaceholderStyle(i.textArea.GetPlaceholderStyle().Foreground(color)) return i } // SetPlaceholderStyle sets the style of the input area (when a placeholder is // shown). func (i *InputField) SetPlaceholderStyle(style tcell.Style) *InputField { i.textArea.SetPlaceholderStyle(style) return i } // GetPlaceholderStyle returns the style of the input area (when a placeholder // is shown). func (i *InputField) GetPlaceholderStyle() tcell.Style { return i.textArea.GetPlaceholderStyle() } // SetAutocompleteStyles sets the colors and style of the autocomplete entries. // For details, see List.SetMainTextStyle(), List.SetSelectedStyle(), and // Box.SetBackgroundColor(). func (i *InputField) SetAutocompleteStyles(background tcell.Color, main, selected tcell.Style) *InputField { i.autocompleteStyles.background = background i.autocompleteStyles.main = main i.autocompleteStyles.selected = selected return i } // SetFormAttributes sets attributes shared by all form items. func (i *InputField) SetFormAttributes(labelWidth int, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem { i.textArea.SetFormAttributes(labelWidth, labelColor, bgColor, fieldTextColor, fieldBgColor) return i } // SetFieldWidth sets the screen width of the input area. A value of 0 means // extend as much as possible. func (i *InputField) SetFieldWidth(width int) *InputField { i.fieldWidth = width return i } // GetFieldWidth returns this primitive's field width. func (i *InputField) GetFieldWidth() int { return i.fieldWidth } // GetFieldHeight returns this primitive's field height. func (i *InputField) GetFieldHeight() int { return 1 } // SetDisabled sets whether or not the item is disabled / read-only. func (i *InputField) SetDisabled(disabled bool) FormItem { i.textArea.SetDisabled(disabled) if i.finished != nil { i.finished(-1) } return i } // SetMaskCharacter sets a character that masks user input on a screen. A value // of 0 disables masking. func (i *InputField) SetMaskCharacter(mask rune) *InputField { if mask == 0 { i.textArea.setTransform(nil) return i } maskStr := string(mask) maskWidth := uniseg.StringWidth(maskStr) i.textArea.setTransform(func(cluster, rest string, boundaries int) (newCluster string, newBoundaries int) { return maskStr, maskWidth << uniseg.ShiftWidth }) return i } // SetAutocompleteFunc sets an autocomplete callback function which may return // strings to be selected from a drop-down based on the current text of the // input field. The drop-down appears only if len(entries) > 0. The callback is // invoked in this function and whenever the current text changes or when // [InputField.Autocomplete] is called. Entries are cleared when the user // selects an entry or presses Escape. func (i *InputField) SetAutocompleteFunc(callback func(currentText string) (entries []string)) *InputField { i.autocomplete = callback i.Autocomplete() return i } // SetAutocompletedFunc sets a callback function which is invoked when the user // selects an entry from the autocomplete drop-down list. The function is passed // the text of the selected entry (stripped of any style tags), the index of the // entry, and the user action that caused the selection, for example // [AutocompletedNavigate]. It returns true if the autocomplete drop-down should // be closed after the callback returns or false if it should remain open, in // which case [InputField.Autocomplete] is called to update the drop-down's // contents. // // If no such callback is set (or nil is provided), the input field will be // updated with the selection any time the user navigates the autocomplete // drop-down list. So this function essentially gives you more control over the // autocomplete functionality. func (i *InputField) SetAutocompletedFunc(autocompleted func(text string, index int, source int) bool) *InputField { i.autocompleted = autocompleted return i } // Autocomplete invokes the autocomplete callback (if there is one, see // [InputField.SetAutocompleteFunc]). If the length of the returned autocomplete // entries slice is greater than 0, the input field will present the user with a // corresponding drop-down list the next time the input field is drawn. // // It is safe to call this function from any goroutine. Note that the input // field is not redrawn automatically unless called from the main goroutine // (e.g. in response to events). func (i *InputField) Autocomplete() *InputField { i.autocompleteListMutex.Lock() defer i.autocompleteListMutex.Unlock() if i.autocomplete == nil { return i } // Do we have any autocomplete entries? text := i.textArea.GetText() entries := i.autocomplete(text) if len(entries) == 0 { // No entries, no list. i.autocompleteList = nil return i } // Make a list if we have none. if i.autocompleteList == nil { i.autocompleteList = NewList() i.autocompleteList.ShowSecondaryText(false). SetMainTextStyle(i.autocompleteStyles.main). SetSelectedStyle(i.autocompleteStyles.selected). SetHighlightFullLine(true). SetBackgroundColor(i.autocompleteStyles.background) } // Fill it with the entries. currentEntry := -1 suffixLength := 9999 // I'm just waiting for the day somebody opens an issue with this number being too small. i.autocompleteList.Clear() for index, entry := range entries { i.autocompleteList.AddItem(entry, "", 0, nil) if strings.HasPrefix(entry, text) && len(entry)-len(text) < suffixLength { currentEntry = index suffixLength = len(text) - len(entry) } } // Set the selection if we have one. if currentEntry >= 0 { i.autocompleteList.SetCurrentItem(currentEntry) } return i } // SetAcceptanceFunc sets a handler which may reject the last character that was // entered, by returning false. The handler receives the text as it would be // after the change and the last character entered. If the handler is nil, all // input is accepted. The function is only called when a single rune is inserted // at the current cursor position. // // This package defines a number of variables prefixed with InputField which may // be used for common input (e.g. numbers, maximum text length). See for example // [InputFieldInteger]. // // When text is pasted, lastChar is 0. func (i *InputField) SetAcceptanceFunc(handler func(textToCheck string, lastChar rune) bool) *InputField { i.accept = handler return i } // SetChangedFunc sets a handler which is called whenever the text of the input // field has changed. It receives the current text (after the change). func (i *InputField) SetChangedFunc(handler func(text string)) *InputField { i.changed = handler return i } // SetDoneFunc sets a handler which is called when the user is done entering // text. The callback function is provided with the key that was pressed, which // is one of the following: // // - KeyEnter: Done entering text. // - KeyEscape: Abort text input. // - KeyTab: Move to the next field. // - KeyBacktab: Move to the previous field. func (i *InputField) SetDoneFunc(handler func(key tcell.Key)) *InputField { i.done = handler return i } // SetFinishedFunc sets a callback invoked when the user leaves this form item. func (i *InputField) SetFinishedFunc(handler func(key tcell.Key)) FormItem { i.finished = handler return i } // Focus is called when this primitive receives focus. func (i *InputField) Focus(delegate func(p Primitive)) { // If we're part of a form and this item is disabled, there's nothing the // user can do here so we're finished. if i.finished != nil && i.textArea.GetDisabled() { i.finished(-1) return } i.Box.Focus(delegate) } // HasFocus returns whether or not this primitive has focus. func (i *InputField) HasFocus() bool { return i.textArea.HasFocus() || i.Box.HasFocus() } // Blur is called when this primitive loses focus. func (i *InputField) Blur() { i.textArea.Blur() i.Box.Blur() i.autocompleteList = nil // Hide the autocomplete drop-down. } // Draw draws this primitive onto the screen. func (i *InputField) Draw(screen tcell.Screen) { i.Box.DrawForSubclass(screen, i) // Prepare x, y, width, height := i.GetInnerRect() if height < 1 || width < 1 { return } // Resize text area. labelWidth := i.textArea.GetLabelWidth() if labelWidth == 0 { labelWidth = TaggedStringWidth(i.textArea.GetLabel()) } fieldWidth := i.fieldWidth if fieldWidth == 0 { fieldWidth = width - labelWidth } i.textArea.SetRect(x, y, labelWidth+fieldWidth, 1) i.textArea.setMinCursorPadding(fieldWidth-1, 1) // Draw text area. i.textArea.hasFocus = i.HasFocus() // Force cursor positioning. i.textArea.Draw(screen) // Draw autocomplete list. i.autocompleteListMutex.Lock() defer i.autocompleteListMutex.Unlock() if i.autocompleteList != nil { // How much space do we need? lheight := i.autocompleteList.GetItemCount() lwidth := 0 for index := 0; index < lheight; index++ { entry, _ := i.autocompleteList.GetItemText(index) width := TaggedStringWidth(entry) if width > lwidth { lwidth = width } } // We prefer to drop down but if there is no space, maybe drop up? lx := x + labelWidth ly := y + 1 _, sheight := screen.Size() if ly+lheight >= sheight && ly-2 > lheight-ly { ly = y - lheight if ly < 0 { ly = 0 } } if ly+lheight >= sheight { lheight = sheight - ly } i.autocompleteList.SetRect(lx, ly, lwidth, lheight) i.autocompleteList.Draw(screen) } } // InputHandler returns the handler for this primitive. func (i *InputField) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) { return i.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) { if i.textArea.GetDisabled() { return } // Trigger changed events. var skipAutocomplete bool currentText := i.textArea.GetText() defer func() { newText := i.textArea.GetText() if newText != currentText { if !skipAutocomplete { i.Autocomplete() } if i.changed != nil { i.changed(newText) } } }() // If we have an autocomplete list, there are certain keys we will // forward to it. i.autocompleteListMutex.Lock() defer i.autocompleteListMutex.Unlock() if i.autocompleteList != nil { i.autocompleteList.SetChangedFunc(nil) i.autocompleteList.SetSelectedFunc(nil) switch key := event.Key(); key { case tcell.KeyEscape: // Close the list. i.autocompleteList = nil return case tcell.KeyEnter, tcell.KeyTab: // Intentional selection. index := i.autocompleteList.GetCurrentItem() text, _ := i.autocompleteList.GetItemText(index) if i.autocompleted != nil { source := AutocompletedEnter if key == tcell.KeyTab { source = AutocompletedTab } if i.autocompleted(stripTags(text), index, source) { i.autocompleteList = nil currentText = i.GetText() } } else { i.SetText(text) skipAutocomplete = true i.autocompleteList = nil } return case tcell.KeyDown, tcell.KeyUp, tcell.KeyPgDn, tcell.KeyPgUp: i.autocompleteList.SetChangedFunc(func(index int, text, secondaryText string, shortcut rune) { text = stripTags(text) if i.autocompleted != nil { if i.autocompleted(text, index, AutocompletedNavigate) { i.autocompleteList = nil currentText = i.GetText() } } else { i.SetText(text) currentText = stripTags(text) // We want to keep the autocomplete list open and unchanged. } }) i.autocompleteList.InputHandler()(event, setFocus) return } } // Finish up. finish := func(key tcell.Key) { if i.done != nil { i.done(key) } if i.finished != nil { i.finished(key) } } // Process special key events for the input field. switch key := event.Key(); key { case tcell.KeyDown: i.autocompleteListMutex.Unlock() // We're still holding a lock. i.Autocomplete() i.autocompleteListMutex.Lock() case tcell.KeyEnter, tcell.KeyEscape, tcell.KeyTab, tcell.KeyBacktab: finish(key) case tcell.KeyCtrlV: if i.accept != nil && !i.accept(i.textArea.getTextBeforeCursor()+i.textArea.GetClipboardText()+i.textArea.getTextAfterCursor(), 0) { return } i.textArea.InputHandler()(event, setFocus) case tcell.KeyRune: if event.Modifiers()&tcell.ModAlt == 0 && i.accept != nil { // Check if this rune is accepted. r := event.Rune() if !i.accept(i.textArea.getTextBeforeCursor()+string(r)+i.textArea.getTextAfterCursor(), r) { return } } fallthrough default: // Forward other key events to the text area. i.textArea.InputHandler()(event, setFocus) } }) } // MouseHandler returns the mouse handler for this primitive. func (i *InputField) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return i.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { if i.textArea.GetDisabled() { return false, nil } var skipAutocomplete bool currentText := i.GetText() defer func() { newText := i.GetText() if newText != currentText { if !skipAutocomplete { i.Autocomplete() } if i.changed != nil { i.changed(newText) } } }() // If we have an autocomplete list, forward the mouse event to it. i.autocompleteListMutex.Lock() defer i.autocompleteListMutex.Unlock() if i.autocompleteList != nil { i.autocompleteList.SetChangedFunc(nil) i.autocompleteList.SetSelectedFunc(func(index int, text, secondaryText string, shortcut rune) { text = stripTags(text) if i.autocompleted != nil { if i.autocompleted(text, index, AutocompletedClick) { i.autocompleteList = nil currentText = i.GetText() } return } i.SetText(text) skipAutocomplete = true i.autocompleteList = nil }) if consumed, _ = i.autocompleteList.MouseHandler()(action, event, setFocus); consumed { setFocus(i) return } } // Is mouse event within the input field? x, y := event.Position() if !i.InRect(x, y) { return false, nil } // Forward mouse event to the text area. consumed, capture = i.textArea.MouseHandler()(action, event, setFocus) return }) } // PasteHandler returns the handler for this primitive. func (i *InputField) PasteHandler() func(pastedText string, setFocus func(p Primitive)) { return i.WrapPasteHandler(func(pastedText string, setFocus func(p Primitive)) { // Input field may be disabled. if i.textArea.GetDisabled() { return } // The autocomplete drop down may be open. i.autocompleteListMutex.Lock() defer i.autocompleteListMutex.Unlock() if i.autocompleteList != nil { return } // We may not accept this text. if i.accept != nil && !i.accept(i.textArea.getTextBeforeCursor()+pastedText+i.textArea.getTextAfterCursor(), 0) { return } // Forward the pasted text to the text area. i.textArea.PasteHandler()(pastedText, setFocus) }) } golang-github-darkhz-tview-0.0~git20240308.6078a88/list.go000066400000000000000000000553171457770046000225150ustar00rootroot00000000000000package tview import ( "fmt" "strings" "github.com/gdamore/tcell/v2" ) // listItem represents one item in a List. type listItem struct { MainText string // The main text of the list item. SecondaryText string // A secondary text to be shown underneath the main text. Shortcut rune // The key to select the list item directly, 0 if there is no shortcut. Selected func() // The optional function which is called when the item is selected. } // List displays rows of items, each of which can be selected. List items can be // shown as a single line or as two lines. They can be selected by pressing // their assigned shortcut key, navigating to them and pressing Enter, or // clicking on them with the mouse. The following key binds are available: // // - Down arrow / tab: Move down one item. // - Up arrow / backtab: Move up one item. // - Home: Move to the first item. // - End: Move to the last item. // - Page down: Move down one page. // - Page up: Move up one page. // - Enter / Space: Select the current item. // - Right / left: Scroll horizontally. Only if the list is wider than the // available space. // // See [List.SetChangedFunc] for a way to be notified when the user navigates // to a list item. See [List.SetSelectedFunc] for a way to be notified when a // list item was selected. // // See https://github.com/rivo/tview/wiki/List for an example. type List struct { *Box // The items of the list. items []*listItem // The index of the currently selected item. currentItem int // Whether or not to show the secondary item texts. showSecondaryText bool // The item main text style. mainTextStyle tcell.Style // The item secondary text style. secondaryTextStyle tcell.Style // The item shortcut text style. shortcutStyle tcell.Style // The style for selected items. selectedStyle tcell.Style // If true, the selection is only shown when the list has focus. selectedFocusOnly bool // If true, the entire row is highlighted when selected. highlightFullLine bool // Whether or not navigating the list will wrap around. wrapAround bool // The number of list items skipped at the top before the first item is // drawn. itemOffset int // The number of cells skipped on the left side of an item text. Shortcuts // are not affected. horizontalOffset int // Set to true if a currently visible item flows over the right border of // the box. This is set by the Draw() function. It determines the behaviour // of the right arrow key. overflowing bool // An optional function which is called when the user has navigated to a // list item. changed func(index int, mainText, secondaryText string, shortcut rune) // An optional function which is called when a list item was selected. This // function will be called even if the list item defines its own callback. selected func(index int, mainText, secondaryText string, shortcut rune) // An optional function which is called when the user presses the Escape key. done func() } // NewList returns a new list. func NewList() *List { return &List{ Box: NewBox(), showSecondaryText: true, wrapAround: true, mainTextStyle: tcell.StyleDefault.Foreground(Styles.PrimaryTextColor), secondaryTextStyle: tcell.StyleDefault.Foreground(Styles.TertiaryTextColor), shortcutStyle: tcell.StyleDefault.Foreground(Styles.SecondaryTextColor), selectedStyle: tcell.StyleDefault.Foreground(Styles.PrimitiveBackgroundColor).Background(Styles.PrimaryTextColor), } } // SetCurrentItem sets the currently selected item by its index, starting at 0 // for the first item. If a negative index is provided, items are referred to // from the back (-1 = last item, -2 = second-to-last item, and so on). Out of // range indices are clamped to the beginning/end. // // Calling this function triggers a "changed" event if the selection changes. func (l *List) SetCurrentItem(index int) *List { if index < 0 { index = len(l.items) + index } if index >= len(l.items) { index = len(l.items) - 1 } if index < 0 { index = 0 } if index != l.currentItem && l.changed != nil { item := l.items[index] l.changed(index, item.MainText, item.SecondaryText, item.Shortcut) } l.currentItem = index l.adjustOffset() return l } // GetCurrentItem returns the index of the currently selected list item, // starting at 0 for the first item. func (l *List) GetCurrentItem() int { return l.currentItem } // SetOffset sets the number of items to be skipped (vertically) as well as the // number of cells skipped horizontally when the list is drawn. Note that one // item corresponds to two rows when there are secondary texts. Shortcuts are // always drawn. // // These values may change when the list is drawn to ensure the currently // selected item is visible and item texts move out of view. Users can also // modify these values by interacting with the list. func (l *List) SetOffset(items, horizontal int) *List { l.itemOffset = items l.horizontalOffset = horizontal return l } // GetOffset returns the number of items skipped while drawing, as well as the // number of cells item text is moved to the left. See also SetOffset() for more // information on these values. func (l *List) GetOffset() (int, int) { return l.itemOffset, l.horizontalOffset } // RemoveItem removes the item with the given index (starting at 0) from the // list. If a negative index is provided, items are referred to from the back // (-1 = last item, -2 = second-to-last item, and so on). Out of range indices // are clamped to the beginning/end, i.e. unless the list is empty, an item is // always removed. // // The currently selected item is shifted accordingly. If it is the one that is // removed, a "changed" event is fired, unless no items are left. func (l *List) RemoveItem(index int) *List { if len(l.items) == 0 { return l } // Adjust index. if index < 0 { index = len(l.items) + index } if index >= len(l.items) { index = len(l.items) - 1 } if index < 0 { index = 0 } // Remove item. l.items = append(l.items[:index], l.items[index+1:]...) // If there is nothing left, we're done. if len(l.items) == 0 { return l } // Shift current item. previousCurrentItem := l.currentItem if l.currentItem > index || l.currentItem == len(l.items) { l.currentItem-- } // Fire "changed" event for removed items. if previousCurrentItem == index && l.changed != nil { item := l.items[l.currentItem] l.changed(l.currentItem, item.MainText, item.SecondaryText, item.Shortcut) } return l } // SetMainTextColor sets the color of the items' main text. func (l *List) SetMainTextColor(color tcell.Color) *List { l.mainTextStyle = l.mainTextStyle.Foreground(color) return l } // SetMainTextStyle sets the style of the items' main text. Note that the // background color is ignored in order not to override the background color of // the list itself. func (l *List) SetMainTextStyle(style tcell.Style) *List { l.mainTextStyle = style return l } // SetSecondaryTextColor sets the color of the items' secondary text. func (l *List) SetSecondaryTextColor(color tcell.Color) *List { l.secondaryTextStyle = l.secondaryTextStyle.Foreground(color) return l } // SetSecondaryTextStyle sets the style of the items' secondary text. Note that // the background color is ignored in order not to override the background color // of the list itself. func (l *List) SetSecondaryTextStyle(style tcell.Style) *List { l.secondaryTextStyle = style return l } // SetShortcutColor sets the color of the items' shortcut. func (l *List) SetShortcutColor(color tcell.Color) *List { l.shortcutStyle = l.shortcutStyle.Foreground(color) return l } // SetShortcutStyle sets the style of the items' shortcut. Note that the // background color is ignored in order not to override the background color of // the list itself. func (l *List) SetShortcutStyle(style tcell.Style) *List { l.shortcutStyle = style return l } // SetSelectedTextColor sets the text color of selected items. Note that the // color of main text characters that are different from the main text color // (e.g. style tags) is maintained. func (l *List) SetSelectedTextColor(color tcell.Color) *List { l.selectedStyle = l.selectedStyle.Foreground(color) return l } // SetSelectedBackgroundColor sets the background color of selected items. func (l *List) SetSelectedBackgroundColor(color tcell.Color) *List { l.selectedStyle = l.selectedStyle.Background(color) return l } // SetSelectedStyle sets the style of the selected items. Note that the color of // main text characters that are different from the main text color (e.g. color // tags) is maintained. func (l *List) SetSelectedStyle(style tcell.Style) *List { l.selectedStyle = style return l } // SetSelectedFocusOnly sets a flag which determines when the currently selected // list item is highlighted. If set to true, selected items are only highlighted // when the list has focus. If set to false, they are always highlighted. func (l *List) SetSelectedFocusOnly(focusOnly bool) *List { l.selectedFocusOnly = focusOnly return l } // SetHighlightFullLine sets a flag which determines whether the colored // background of selected items spans the entire width of the view. If set to // true, the highlight spans the entire view. If set to false, only the text of // the selected item from beginning to end is highlighted. func (l *List) SetHighlightFullLine(highlight bool) *List { l.highlightFullLine = highlight return l } // ShowSecondaryText determines whether or not to show secondary item texts. func (l *List) ShowSecondaryText(show bool) *List { l.showSecondaryText = show return l } // SetWrapAround sets the flag that determines whether navigating the list will // wrap around. That is, navigating downwards on the last item will move the // selection to the first item (similarly in the other direction). If set to // false, the selection won't change when navigating downwards on the last item // or navigating upwards on the first item. func (l *List) SetWrapAround(wrapAround bool) *List { l.wrapAround = wrapAround return l } // SetChangedFunc sets the function which is called when the user navigates to // a list item. The function receives the item's index in the list of items // (starting with 0), its main text, secondary text, and its shortcut rune. // // This function is also called when the first item is added or when // SetCurrentItem() is called. func (l *List) SetChangedFunc(handler func(index int, mainText string, secondaryText string, shortcut rune)) *List { l.changed = handler return l } // SetSelectedFunc sets the function which is called when the user selects a // list item by pressing Enter on the current selection. The function receives // the item's index in the list of items (starting with 0), its main text, // secondary text, and its shortcut rune. func (l *List) SetSelectedFunc(handler func(int, string, string, rune)) *List { l.selected = handler return l } // SetDoneFunc sets a function which is called when the user presses the Escape // key. func (l *List) SetDoneFunc(handler func()) *List { l.done = handler return l } // AddItem calls InsertItem() with an index of -1. func (l *List) AddItem(mainText, secondaryText string, shortcut rune, selected func()) *List { l.InsertItem(-1, mainText, secondaryText, shortcut, selected) return l } // InsertItem adds a new item to the list at the specified index. An index of 0 // will insert the item at the beginning, an index of 1 before the second item, // and so on. An index of GetItemCount() or higher will insert the item at the // end of the list. Negative indices are also allowed: An index of -1 will // insert the item at the end of the list, an index of -2 before the last item, // and so on. An index of -GetItemCount()-1 or lower will insert the item at the // beginning. // // An item has a main text which will be highlighted when selected. It also has // a secondary text which is shown underneath the main text (if it is set to // visible) but which may remain empty. // // The shortcut is a key binding. If the specified rune is entered, the item // is selected immediately. Set to 0 for no binding. // // The "selected" callback will be invoked when the user selects the item. You // may provide nil if no such callback is needed or if all events are handled // through the selected callback set with SetSelectedFunc(). // // The currently selected item will shift its position accordingly. If the list // was previously empty, a "changed" event is fired because the new item becomes // selected. func (l *List) InsertItem(index int, mainText, secondaryText string, shortcut rune, selected func()) *List { item := &listItem{ MainText: mainText, SecondaryText: secondaryText, Shortcut: shortcut, Selected: selected, } // Shift index to range. if index < 0 { index = len(l.items) + index + 1 } if index < 0 { index = 0 } else if index > len(l.items) { index = len(l.items) } // Shift current item. if l.currentItem < len(l.items) && l.currentItem >= index { l.currentItem++ } // Insert item (make space for the new item, then shift and insert). l.items = append(l.items, nil) if index < len(l.items)-1 { // -1 because l.items has already grown by one item. copy(l.items[index+1:], l.items[index:]) } l.items[index] = item // Fire a "change" event for the first item in the list. if len(l.items) == 1 && l.changed != nil { item := l.items[0] l.changed(0, item.MainText, item.SecondaryText, item.Shortcut) } return l } // GetItemCount returns the number of items in the list. func (l *List) GetItemCount() int { return len(l.items) } // GetItemText returns an item's texts (main and secondary). Panics if the index // is out of range. func (l *List) GetItemText(index int) (main, secondary string) { return l.items[index].MainText, l.items[index].SecondaryText } // SetItemText sets an item's main and secondary text. Panics if the index is // out of range. func (l *List) SetItemText(index int, main, secondary string) *List { item := l.items[index] item.MainText = main item.SecondaryText = secondary return l } // FindItems searches the main and secondary texts for the given strings and // returns a list of item indices in which those strings are found. One of the // two search strings may be empty, it will then be ignored. Indices are always // returned in ascending order. // // If mustContainBoth is set to true, mainSearch must be contained in the main // text AND secondarySearch must be contained in the secondary text. If it is // false, only one of the two search strings must be contained. // // Set ignoreCase to true for case-insensitive search. func (l *List) FindItems(mainSearch, secondarySearch string, mustContainBoth, ignoreCase bool) (indices []int) { if mainSearch == "" && secondarySearch == "" { return } if ignoreCase { mainSearch = strings.ToLower(mainSearch) secondarySearch = strings.ToLower(secondarySearch) } for index, item := range l.items { mainText := item.MainText secondaryText := item.SecondaryText if ignoreCase { mainText = strings.ToLower(mainText) secondaryText = strings.ToLower(secondaryText) } // strings.Contains() always returns true for a "" search. mainContained := strings.Contains(mainText, mainSearch) secondaryContained := strings.Contains(secondaryText, secondarySearch) if mustContainBoth && mainContained && secondaryContained || !mustContainBoth && (mainText != "" && mainContained || secondaryText != "" && secondaryContained) { indices = append(indices, index) } } return } // Clear removes all items from the list. func (l *List) Clear() *List { l.items = nil l.currentItem = 0 return l } // Draw draws this primitive onto the screen. func (l *List) Draw(screen tcell.Screen) { l.Box.DrawForSubclass(screen, l) // Determine the dimensions. x, y, width, height := l.GetInnerRect() bottomLimit := y + height _, totalHeight := screen.Size() if bottomLimit > totalHeight { bottomLimit = totalHeight } // Do we show any shortcuts? var showShortcuts bool for _, item := range l.items { if item.Shortcut != 0 { showShortcuts = true x += 4 width -= 4 break } } if l.horizontalOffset < 0 { l.horizontalOffset = 0 } // Draw the list items. var ( maxWidth int // The maximum printed item width. overflowing bool // Whether a text's end exceeds the right border. ) for index, item := range l.items { if index < l.itemOffset { continue } if y >= bottomLimit { break } // Shortcuts. if showShortcuts && item.Shortcut != 0 { printWithStyle(screen, fmt.Sprintf("(%s)", string(item.Shortcut)), x-5, y, 0, 4, AlignRight, l.shortcutStyle, true) } // Main text. _, end, printedWidth := printWithStyle(screen, item.MainText, x, y, l.horizontalOffset, width, AlignLeft, l.mainTextStyle, true) if printedWidth > maxWidth { maxWidth = printedWidth } if end < len(item.MainText) { overflowing = true } // Background color of selected text. if index == l.currentItem && (!l.selectedFocusOnly || l.HasFocus()) { textWidth := width if !l.highlightFullLine { if w := TaggedStringWidth(item.MainText); w < textWidth { textWidth = w } } mainTextColor, _, _ := l.mainTextStyle.Decompose() for bx := 0; bx < textWidth; bx++ { m, c, style, _ := screen.GetContent(x+bx, y) fg, _, _ := style.Decompose() style = l.selectedStyle if fg != mainTextColor { style = style.Foreground(fg) } screen.SetContent(x+bx, y, m, c, style) } } y++ if y >= bottomLimit { break } // Secondary text. if l.showSecondaryText { _, end, printedWidth := printWithStyle(screen, item.SecondaryText, x, y, l.horizontalOffset, width, AlignLeft, l.secondaryTextStyle, true) if printedWidth > maxWidth { maxWidth = printedWidth } if end < len(item.SecondaryText) { overflowing = true } y++ } } // We don't want the item text to get out of view. If the horizontal offset // is too high, we reset it and redraw. (That should be about as efficient // as calculating everything up front.) if l.horizontalOffset > 0 && maxWidth < width { l.horizontalOffset -= width - maxWidth l.Draw(screen) } l.overflowing = overflowing } // adjustOffset adjusts the vertical offset to keep the current selection in // view. func (l *List) adjustOffset() { _, _, _, height := l.GetInnerRect() if height == 0 { return } if l.currentItem < l.itemOffset { l.itemOffset = l.currentItem } else if l.showSecondaryText { if 2*(l.currentItem-l.itemOffset) >= height-1 { l.itemOffset = (2*l.currentItem + 3 - height) / 2 } } else { if l.currentItem-l.itemOffset >= height { l.itemOffset = l.currentItem + 1 - height } } } // InputHandler returns the handler for this primitive. func (l *List) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) { return l.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) { if event.Key() == tcell.KeyEscape { if l.done != nil { l.done() } return } else if len(l.items) == 0 { return } previousItem := l.currentItem switch key := event.Key(); key { case tcell.KeyTab, tcell.KeyDown: l.currentItem++ case tcell.KeyBacktab, tcell.KeyUp: l.currentItem-- case tcell.KeyRight: if l.overflowing { l.horizontalOffset += 2 // We shift by 2 to account for two-cell characters. } else { l.currentItem++ } case tcell.KeyLeft: if l.horizontalOffset > 0 { l.horizontalOffset -= 2 } else { l.currentItem-- } case tcell.KeyHome: l.currentItem = 0 case tcell.KeyEnd: l.currentItem = len(l.items) - 1 case tcell.KeyPgDn: _, _, _, height := l.GetInnerRect() l.currentItem += height if l.currentItem >= len(l.items) { l.currentItem = len(l.items) - 1 } case tcell.KeyPgUp: _, _, _, height := l.GetInnerRect() l.currentItem -= height if l.currentItem < 0 { l.currentItem = 0 } case tcell.KeyEnter: if l.currentItem >= 0 && l.currentItem < len(l.items) { item := l.items[l.currentItem] if item.Selected != nil { item.Selected() } if l.selected != nil { l.selected(l.currentItem, item.MainText, item.SecondaryText, item.Shortcut) } } case tcell.KeyRune: ch := event.Rune() if ch != ' ' { // It's not a space bar. Is it a shortcut? var found bool for index, item := range l.items { if item.Shortcut == ch { // We have a shortcut. found = true l.currentItem = index break } } if !found { break } } item := l.items[l.currentItem] if item.Selected != nil { item.Selected() } if l.selected != nil { l.selected(l.currentItem, item.MainText, item.SecondaryText, item.Shortcut) } } if l.currentItem < 0 { if l.wrapAround { l.currentItem = len(l.items) - 1 } else { l.currentItem = 0 } } else if l.currentItem >= len(l.items) { if l.wrapAround { l.currentItem = 0 } else { l.currentItem = len(l.items) - 1 } } if l.currentItem != previousItem && l.currentItem < len(l.items) { if l.changed != nil { item := l.items[l.currentItem] l.changed(l.currentItem, item.MainText, item.SecondaryText, item.Shortcut) } l.adjustOffset() } }) } // indexAtPoint returns the index of the list item found at the given position // or a negative value if there is no such list item. func (l *List) indexAtPoint(x, y int) int { rectX, rectY, width, height := l.GetInnerRect() if rectX < 0 || rectX >= rectX+width || y < rectY || y >= rectY+height { return -1 } index := y - rectY if l.showSecondaryText { index /= 2 } index += l.itemOffset if index >= len(l.items) { return -1 } return index } // MouseHandler returns the mouse handler for this primitive. func (l *List) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return l.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { if !l.InRect(event.Position()) { return false, nil } // Process mouse event. switch action { case MouseLeftClick: setFocus(l) index := l.indexAtPoint(event.Position()) if index != -1 { item := l.items[index] if item.Selected != nil { item.Selected() } if l.selected != nil { l.selected(index, item.MainText, item.SecondaryText, item.Shortcut) } if index != l.currentItem { if l.changed != nil { l.changed(index, item.MainText, item.SecondaryText, item.Shortcut) } l.adjustOffset() } l.currentItem = index } consumed = true case MouseScrollUp: if l.itemOffset > 0 { l.itemOffset-- } consumed = true case MouseScrollDown: lines := len(l.items) - l.itemOffset if l.showSecondaryText { lines *= 2 } if _, _, _, height := l.GetInnerRect(); lines > height { l.itemOffset++ } consumed = true } return }) } golang-github-darkhz-tview-0.0~git20240308.6078a88/modal.go000066400000000000000000000145071457770046000226320ustar00rootroot00000000000000package tview import ( "github.com/gdamore/tcell/v2" ) // Modal is a centered message window used to inform the user or prompt them // for an immediate decision. It needs to have at least one button (added via // [Modal.AddButtons]) or it will never disappear. // // See https://github.com/rivo/tview/wiki/Modal for an example. type Modal struct { *Box // The frame embedded in the modal. frame *Frame // The form embedded in the modal's frame. form *Form // The message text (original, not word-wrapped). text string // The text color. textColor tcell.Color // The optional callback for when the user clicked one of the buttons. It // receives the index of the clicked button and the button's label. done func(buttonIndex int, buttonLabel string) } // NewModal returns a new modal message window. func NewModal() *Modal { m := &Modal{ Box: NewBox().SetBorder(true).SetBackgroundColor(Styles.ContrastBackgroundColor), textColor: Styles.PrimaryTextColor, } m.form = NewForm(). SetButtonsAlign(AlignCenter). SetButtonBackgroundColor(Styles.PrimitiveBackgroundColor). SetButtonTextColor(Styles.PrimaryTextColor) m.form.SetBackgroundColor(Styles.ContrastBackgroundColor).SetBorderPadding(0, 0, 0, 0) m.form.SetCancelFunc(func() { if m.done != nil { m.done(-1, "") } }) m.frame = NewFrame(m.form).SetBorders(0, 0, 1, 0, 0, 0) m.frame.SetBackgroundColor(Styles.ContrastBackgroundColor). SetBorderPadding(1, 1, 1, 1) return m } // SetBackgroundColor sets the color of the modal frame background. func (m *Modal) SetBackgroundColor(color tcell.Color) *Modal { m.form.SetBackgroundColor(color) m.frame.SetBackgroundColor(color) return m } // SetTextColor sets the color of the message text. func (m *Modal) SetTextColor(color tcell.Color) *Modal { m.textColor = color return m } // SetButtonBackgroundColor sets the background color of the buttons. func (m *Modal) SetButtonBackgroundColor(color tcell.Color) *Modal { m.form.SetButtonBackgroundColor(color) return m } // SetButtonTextColor sets the color of the button texts. func (m *Modal) SetButtonTextColor(color tcell.Color) *Modal { m.form.SetButtonTextColor(color) return m } // SetButtonStyle sets the style of the buttons when they are not focused. func (m *Modal) SetButtonStyle(style tcell.Style) *Modal { m.form.SetButtonStyle(style) return m } // SetButtonActivatedStyle sets the style of the buttons when they are focused. func (m *Modal) SetButtonActivatedStyle(style tcell.Style) *Modal { m.form.SetButtonActivatedStyle(style) return m } // SetDoneFunc sets a handler which is called when one of the buttons was // pressed. It receives the index of the button as well as its label text. The // handler is also called when the user presses the Escape key. The index will // then be negative and the label text an empty string. func (m *Modal) SetDoneFunc(handler func(buttonIndex int, buttonLabel string)) *Modal { m.done = handler return m } // SetText sets the message text of the window. The text may contain line // breaks but style tag states will not transfer to following lines. Note that // words are wrapped, too, based on the final size of the window. func (m *Modal) SetText(text string) *Modal { m.text = text return m } // AddButtons adds buttons to the window. There must be at least one button and // a "done" handler so the window can be closed again. func (m *Modal) AddButtons(labels []string) *Modal { for index, label := range labels { func(i int, l string) { m.form.AddButton(label, func() { if m.done != nil { m.done(i, l) } }) button := m.form.GetButton(m.form.GetButtonCount() - 1) button.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { switch event.Key() { case tcell.KeyDown, tcell.KeyRight: return tcell.NewEventKey(tcell.KeyTab, 0, tcell.ModNone) case tcell.KeyUp, tcell.KeyLeft: return tcell.NewEventKey(tcell.KeyBacktab, 0, tcell.ModNone) } return event }) }(index, label) } return m } // ClearButtons removes all buttons from the window. func (m *Modal) ClearButtons() *Modal { m.form.ClearButtons() return m } // SetFocus shifts the focus to the button with the given index. func (m *Modal) SetFocus(index int) *Modal { m.form.SetFocus(index) return m } // Focus is called when this primitive receives focus. func (m *Modal) Focus(delegate func(p Primitive)) { delegate(m.form) } // HasFocus returns whether or not this primitive has focus. func (m *Modal) HasFocus() bool { return m.form.HasFocus() } // Draw draws this primitive onto the screen. func (m *Modal) Draw(screen tcell.Screen) { // Calculate the width of this modal. buttonsWidth := 0 for _, button := range m.form.buttons { buttonsWidth += TaggedStringWidth(button.text) + 4 + 2 } buttonsWidth -= 2 screenWidth, screenHeight := screen.Size() width := screenWidth / 3 if width < buttonsWidth { width = buttonsWidth } // width is now without the box border. // Reset the text and find out how wide it is. m.frame.Clear() lines := WordWrap(m.text, width) for _, line := range lines { m.frame.AddText(line, true, AlignCenter, m.textColor) } // Set the modal's position and size. height := len(lines) + 6 width += 4 x := (screenWidth - width) / 2 y := (screenHeight - height) / 2 m.SetRect(x, y, width, height) // Draw the frame. m.Box.DrawForSubclass(screen, m) x, y, width, height = m.GetInnerRect() m.frame.SetRect(x, y, width, height) m.frame.Draw(screen) } // MouseHandler returns the mouse handler for this primitive. func (m *Modal) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return m.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { // Pass mouse events on to the form. consumed, capture = m.form.MouseHandler()(action, event, setFocus) if !consumed && action == MouseLeftDown && m.InRect(event.Position()) { setFocus(m) consumed = true } return }) } // InputHandler returns the handler for this primitive. func (m *Modal) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) { return m.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) { if m.frame.HasFocus() { if handler := m.frame.InputHandler(); handler != nil { handler(event, setFocus) return } } }) } golang-github-darkhz-tview-0.0~git20240308.6078a88/pages.go000066400000000000000000000210231457770046000226240ustar00rootroot00000000000000package tview import ( "github.com/gdamore/tcell/v2" ) // page represents one page of a Pages object. type page struct { Name string // The page's name. Item Primitive // The page's primitive. Resize bool // Whether or not to resize the page when it is drawn. Visible bool // Whether or not this page is visible. } // Pages is a container for other primitives laid out on top of each other, // overlapping or not. It is often used as the application's root primitive. It // allows to easily switch the visibility of the contained primitives. // // See https://github.com/rivo/tview/wiki/Pages for an example. type Pages struct { *Box // The contained pages. (Visible) pages are drawn from back to front. pages []*page // We keep a reference to the function which allows us to set the focus to // a newly visible page. setFocus func(p Primitive) // An optional handler which is called whenever the visibility or the order of // pages changes. changed func() } // NewPages returns a new Pages object. func NewPages() *Pages { p := &Pages{ Box: NewBox(), } return p } // SetChangedFunc sets a handler which is called whenever the visibility or the // order of any visible pages changes. This can be used to redraw the pages. func (p *Pages) SetChangedFunc(handler func()) *Pages { p.changed = handler return p } // GetPageCount returns the number of pages currently stored in this object. func (p *Pages) GetPageCount() int { return len(p.pages) } // AddPage adds a new page with the given name and primitive. If there was // previously a page with the same name, it is overwritten. Leaving the name // empty may cause conflicts in other functions so always specify a non-empty // name. // // Visible pages will be drawn in the order they were added (unless that order // was changed in one of the other functions). If "resize" is set to true, the // primitive will be set to the size available to the Pages primitive whenever // the pages are drawn. func (p *Pages) AddPage(name string, item Primitive, resize, visible bool) *Pages { hasFocus := p.HasFocus() for index, pg := range p.pages { if pg.Name == name { p.pages = append(p.pages[:index], p.pages[index+1:]...) break } } p.pages = append(p.pages, &page{Item: item, Name: name, Resize: resize, Visible: visible}) if p.changed != nil { p.changed() } if hasFocus { p.Focus(p.setFocus) } return p } // AddAndSwitchToPage calls AddPage(), then SwitchToPage() on that newly added // page. func (p *Pages) AddAndSwitchToPage(name string, item Primitive, resize bool) *Pages { p.AddPage(name, item, resize, true) p.SwitchToPage(name) return p } // RemovePage removes the page with the given name. If that page was the only // visible page, visibility is assigned to the last page. func (p *Pages) RemovePage(name string) *Pages { var isVisible bool hasFocus := p.HasFocus() for index, page := range p.pages { if page.Name == name { isVisible = page.Visible p.pages = append(p.pages[:index], p.pages[index+1:]...) if page.Visible && p.changed != nil { p.changed() } break } } if isVisible { for index, page := range p.pages { if index < len(p.pages)-1 { if page.Visible { break // There is a remaining visible page. } } else { page.Visible = true // We need at least one visible page. } } } if hasFocus { p.Focus(p.setFocus) } return p } // HasPage returns true if a page with the given name exists in this object. func (p *Pages) HasPage(name string) bool { for _, page := range p.pages { if page.Name == name { return true } } return false } // ShowPage sets a page's visibility to "true" (in addition to any other pages // which are already visible). func (p *Pages) ShowPage(name string) *Pages { for _, page := range p.pages { if page.Name == name { page.Visible = true if p.changed != nil { p.changed() } break } } if p.HasFocus() { p.Focus(p.setFocus) } return p } // HidePage sets a page's visibility to "false". func (p *Pages) HidePage(name string) *Pages { for _, page := range p.pages { if page.Name == name { page.Visible = false if p.changed != nil { p.changed() } break } } if p.HasFocus() { p.Focus(p.setFocus) } return p } // SwitchToPage sets a page's visibility to "true" and all other pages' // visibility to "false". func (p *Pages) SwitchToPage(name string) *Pages { for _, page := range p.pages { if page.Name == name { page.Visible = true } else { page.Visible = false } } if p.changed != nil { p.changed() } if p.HasFocus() { p.Focus(p.setFocus) } return p } // SendToFront changes the order of the pages such that the page with the given // name comes last, causing it to be drawn last with the next update (if // visible). func (p *Pages) SendToFront(name string) *Pages { for index, page := range p.pages { if page.Name == name { if index < len(p.pages)-1 { p.pages = append(append(p.pages[:index], p.pages[index+1:]...), page) } if page.Visible && p.changed != nil { p.changed() } break } } if p.HasFocus() { p.Focus(p.setFocus) } return p } // SendToBack changes the order of the pages such that the page with the given // name comes first, causing it to be drawn first with the next update (if // visible). func (p *Pages) SendToBack(name string) *Pages { for index, pg := range p.pages { if pg.Name == name { if index > 0 { p.pages = append(append([]*page{pg}, p.pages[:index]...), p.pages[index+1:]...) } if pg.Visible && p.changed != nil { p.changed() } break } } if p.HasFocus() { p.Focus(p.setFocus) } return p } // GetFrontPage returns the front-most visible page. If there are no visible // pages, ("", nil) is returned. func (p *Pages) GetFrontPage() (name string, item Primitive) { for index := len(p.pages) - 1; index >= 0; index-- { if p.pages[index].Visible { return p.pages[index].Name, p.pages[index].Item } } return } func (p *Pages) GetPageItem(name string) Primitive { for index := len(p.pages) - 1; index >= 0; index-- { if p.pages[index].Name == name { return p.pages[index].Item } } return nil } // HasFocus returns whether or not this primitive has focus. func (p *Pages) HasFocus() bool { for _, page := range p.pages { if page.Item.HasFocus() { return true } } return p.Box.HasFocus() } // Focus is called by the application when the primitive receives focus. func (p *Pages) Focus(delegate func(p Primitive)) { if delegate == nil { return // We cannot delegate so we cannot focus. } p.setFocus = delegate var topItem Primitive for _, page := range p.pages { if page.Visible { topItem = page.Item } } if topItem != nil { delegate(topItem) } else { p.Box.Focus(delegate) } } // Draw draws this primitive onto the screen. func (p *Pages) Draw(screen tcell.Screen) { p.Box.DrawForSubclass(screen, p) for _, page := range p.pages { if !page.Visible { continue } if page.Resize { x, y, width, height := p.GetInnerRect() page.Item.SetRect(x, y, width, height) } page.Item.Draw(screen) } } // MouseHandler returns the mouse handler for this primitive. func (p *Pages) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return p.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { if !p.InRect(event.Position()) { return false, nil } // Pass mouse events along to the last visible page item that takes it. for index := len(p.pages) - 1; index >= 0; index-- { page := p.pages[index] if page.Visible { consumed, capture = page.Item.MouseHandler()(action, event, setFocus) if consumed { return } } } return }) } // InputHandler returns the handler for this primitive. func (p *Pages) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) { return p.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) { for _, page := range p.pages { if page.Item.HasFocus() { if handler := page.Item.InputHandler(); handler != nil { handler(event, setFocus) return } } } }) } // PasteHandler returns the handler for this primitive. func (p *Pages) PasteHandler() func(pastedText string, setFocus func(p Primitive)) { return p.WrapPasteHandler(func(pastedText string, setFocus func(p Primitive)) { for _, page := range p.pages { if page.Item.HasFocus() { if handler := page.Item.PasteHandler(); handler != nil { handler(pastedText, setFocus) return } } } }) } golang-github-darkhz-tview-0.0~git20240308.6078a88/primitive.go000066400000000000000000000056571457770046000235540ustar00rootroot00000000000000package tview import "github.com/gdamore/tcell/v2" // Primitive is the top-most interface for all graphical primitives. type Primitive interface { // Draw draws this primitive onto the screen. Implementers can call the // screen's ShowCursor() function but should only do so when they have focus. // (They will need to keep track of this themselves.) Draw(screen tcell.Screen) // GetRect returns the current position of the primitive, x, y, width, and // height. GetRect() (int, int, int, int) // SetRect sets a new position of the primitive. SetRect(x, y, width, height int) // InputHandler returns a handler which receives key events when it has focus. // It is called by the Application class. // // A value of nil may also be returned, in which case this primitive cannot // receive focus and will not process any key events. // // The handler will receive the key event and a function that allows it to // set the focus to a different primitive, so that future key events are sent // to that primitive. // // The Application's Draw() function will be called automatically after the // handler returns. // // The Box class provides functionality to intercept keyboard input. If you // subclass from Box, it is recommended that you wrap your handler using // Box.WrapInputHandler() so you inherit that functionality. InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) // Focus is called by the application when the primitive receives focus. // Implementers may call delegate() to pass the focus on to another primitive. Focus(delegate func(p Primitive)) // EnabledFocus determines if the primitive has focus enabled. EnabledFocus() bool // HasFocus determines if the primitive has focus. This function must return // true also if one of this primitive's child elements has focus. HasFocus() bool // Blur is called by the application when the primitive loses focus. Blur() // MouseHandler returns a handler which receives mouse events. // It is called by the Application class. // // A value of nil may also be returned to stop the downward propagation of // mouse events. // // The Box class provides functionality to intercept mouse events. If you // subclass from Box, it is recommended that you wrap your handler using // Box.WrapMouseHandler() so you inherit that functionality. MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) // PasteHandler returns a handler which receives pasted text. // It is called by the Application class. // // A value of nil may also be returned to stop the downward propagation of // paste events. // // The Box class may provide functionality to intercept paste events in the // future. If you subclass from Box, it is recommended that you wrap your // handler using Box.WrapPasteHandler() so you inherit that functionality. PasteHandler() func(text string, setFocus func(p Primitive)) } golang-github-darkhz-tview-0.0~git20240308.6078a88/semigraphics.go000066400000000000000000000504131457770046000242100ustar00rootroot00000000000000package tview import ( "github.com/gdamore/tcell/v2" ) // Semigraphics provides an easy way to access unicode characters for drawing. // // Named like the unicode characters, 'Semigraphics'-prefix used if unicode block // isn't prefixed itself. const ( // Block: General Punctuation U+2000-U+206F (http://unicode.org/charts/PDF/U2000.pdf) SemigraphicsHorizontalEllipsis rune = '\u2026' // … // Block: Box Drawing U+2500-U+257F (http://unicode.org/charts/PDF/U2500.pdf) BoxDrawingsLightHorizontal rune = '\u2500' // ─ BoxDrawingsHeavyHorizontal rune = '\u2501' // ━ BoxDrawingsLightVertical rune = '\u2502' // │ BoxDrawingsHeavyVertical rune = '\u2503' // ┃ BoxDrawingsLightTripleDashHorizontal rune = '\u2504' // ┄ BoxDrawingsHeavyTripleDashHorizontal rune = '\u2505' // ┅ BoxDrawingsLightTripleDashVertical rune = '\u2506' // ┆ BoxDrawingsHeavyTripleDashVertical rune = '\u2507' // ┇ BoxDrawingsLightQuadrupleDashHorizontal rune = '\u2508' // ┈ BoxDrawingsHeavyQuadrupleDashHorizontal rune = '\u2509' // ┉ BoxDrawingsLightQuadrupleDashVertical rune = '\u250a' // ┊ BoxDrawingsHeavyQuadrupleDashVertical rune = '\u250b' // ┋ BoxDrawingsLightDownAndRight rune = '\u250c' // ┌ BoxDrawingsDownLightAndRightHeavy rune = '\u250d' // ┍ BoxDrawingsDownHeavyAndRightLight rune = '\u250e' // ┎ BoxDrawingsHeavyDownAndRight rune = '\u250f' // ┏ BoxDrawingsLightDownAndLeft rune = '\u2510' // ┐ BoxDrawingsDownLightAndLeftHeavy rune = '\u2511' // ┑ BoxDrawingsDownHeavyAndLeftLight rune = '\u2512' // ┒ BoxDrawingsHeavyDownAndLeft rune = '\u2513' // ┓ BoxDrawingsLightUpAndRight rune = '\u2514' // └ BoxDrawingsUpLightAndRightHeavy rune = '\u2515' // ┕ BoxDrawingsUpHeavyAndRightLight rune = '\u2516' // ┖ BoxDrawingsHeavyUpAndRight rune = '\u2517' // ┗ BoxDrawingsLightUpAndLeft rune = '\u2518' // ┘ BoxDrawingsUpLightAndLeftHeavy rune = '\u2519' // ┙ BoxDrawingsUpHeavyAndLeftLight rune = '\u251a' // ┚ BoxDrawingsHeavyUpAndLeft rune = '\u251b' // ┛ BoxDrawingsLightVerticalAndRight rune = '\u251c' // ├ BoxDrawingsVerticalLightAndRightHeavy rune = '\u251d' // ┝ BoxDrawingsUpHeavyAndRightDownLight rune = '\u251e' // ┞ BoxDrawingsDownHeavyAndRightUpLight rune = '\u251f' // ┟ BoxDrawingsVerticalHeavyAndRightLight rune = '\u2520' // ┠ BoxDrawingsDownLightAndRightUpHeavy rune = '\u2521' // ┡ BoxDrawingsUpLightAndRightDownHeavy rune = '\u2522' // ┢ BoxDrawingsHeavyVerticalAndRight rune = '\u2523' // ┣ BoxDrawingsLightVerticalAndLeft rune = '\u2524' // ┤ BoxDrawingsVerticalLightAndLeftHeavy rune = '\u2525' // ┥ BoxDrawingsUpHeavyAndLeftDownLight rune = '\u2526' // ┦ BoxDrawingsDownHeavyAndLeftUpLight rune = '\u2527' // ┧ BoxDrawingsVerticalHeavyAndLeftLight rune = '\u2528' // ┨ BoxDrawingsDownLightAndLeftUpHeavy rune = '\u2529' // ┨ BoxDrawingsUpLightAndLeftDownHeavy rune = '\u252a' // ┪ BoxDrawingsHeavyVerticalAndLeft rune = '\u252b' // ┫ BoxDrawingsLightDownAndHorizontal rune = '\u252c' // ┬ BoxDrawingsLeftHeavyAndRightDownLight rune = '\u252d' // ┭ BoxDrawingsRightHeavyAndLeftDownLight rune = '\u252e' // ┮ BoxDrawingsDownLightAndHorizontalHeavy rune = '\u252f' // ┯ BoxDrawingsDownHeavyAndHorizontalLight rune = '\u2530' // ┰ BoxDrawingsRightLightAndLeftDownHeavy rune = '\u2531' // ┱ BoxDrawingsLeftLightAndRightDownHeavy rune = '\u2532' // ┲ BoxDrawingsHeavyDownAndHorizontal rune = '\u2533' // ┳ BoxDrawingsLightUpAndHorizontal rune = '\u2534' // ┴ BoxDrawingsLeftHeavyAndRightUpLight rune = '\u2535' // ┵ BoxDrawingsRightHeavyAndLeftUpLight rune = '\u2536' // ┶ BoxDrawingsUpLightAndHorizontalHeavy rune = '\u2537' // ┷ BoxDrawingsUpHeavyAndHorizontalLight rune = '\u2538' // ┸ BoxDrawingsRightLightAndLeftUpHeavy rune = '\u2539' // ┹ BoxDrawingsLeftLightAndRightUpHeavy rune = '\u253a' // ┺ BoxDrawingsHeavyUpAndHorizontal rune = '\u253b' // ┻ BoxDrawingsLightVerticalAndHorizontal rune = '\u253c' // ┼ BoxDrawingsLeftHeavyAndRightVerticalLight rune = '\u253d' // ┽ BoxDrawingsRightHeavyAndLeftVerticalLight rune = '\u253e' // ┾ BoxDrawingsVerticalLightAndHorizontalHeavy rune = '\u253f' // ┿ BoxDrawingsUpHeavyAndDownHorizontalLight rune = '\u2540' // ╀ BoxDrawingsDownHeavyAndUpHorizontalLight rune = '\u2541' // ╁ BoxDrawingsVerticalHeavyAndHorizontalLight rune = '\u2542' // ╂ BoxDrawingsLeftUpHeavyAndRightDownLight rune = '\u2543' // ╃ BoxDrawingsRightUpHeavyAndLeftDownLight rune = '\u2544' // ╄ BoxDrawingsLeftDownHeavyAndRightUpLight rune = '\u2545' // ╅ BoxDrawingsRightDownHeavyAndLeftUpLight rune = '\u2546' // ╆ BoxDrawingsDownLightAndUpHorizontalHeavy rune = '\u2547' // ╇ BoxDrawingsUpLightAndDownHorizontalHeavy rune = '\u2548' // ╈ BoxDrawingsRightLightAndLeftVerticalHeavy rune = '\u2549' // ╉ BoxDrawingsLeftLightAndRightVerticalHeavy rune = '\u254a' // ╊ BoxDrawingsHeavyVerticalAndHorizontal rune = '\u254b' // ╋ BoxDrawingsLightDoubleDashHorizontal rune = '\u254c' // ╌ BoxDrawingsHeavyDoubleDashHorizontal rune = '\u254d' // ╍ BoxDrawingsLightDoubleDashVertical rune = '\u254e' // ╎ BoxDrawingsHeavyDoubleDashVertical rune = '\u254f' // ╏ BoxDrawingsDoubleHorizontal rune = '\u2550' // ═ BoxDrawingsDoubleVertical rune = '\u2551' // ║ BoxDrawingsDownSingleAndRightDouble rune = '\u2552' // ╒ BoxDrawingsDownDoubleAndRightSingle rune = '\u2553' // ╓ BoxDrawingsDoubleDownAndRight rune = '\u2554' // ╔ BoxDrawingsDownSingleAndLeftDouble rune = '\u2555' // ╕ BoxDrawingsDownDoubleAndLeftSingle rune = '\u2556' // ╖ BoxDrawingsDoubleDownAndLeft rune = '\u2557' // ╗ BoxDrawingsUpSingleAndRightDouble rune = '\u2558' // ╘ BoxDrawingsUpDoubleAndRightSingle rune = '\u2559' // ╙ BoxDrawingsDoubleUpAndRight rune = '\u255a' // ╚ BoxDrawingsUpSingleAndLeftDouble rune = '\u255b' // ╛ BoxDrawingsUpDoubleAndLeftSingle rune = '\u255c' // ╜ BoxDrawingsDoubleUpAndLeft rune = '\u255d' // ╝ BoxDrawingsVerticalSingleAndRightDouble rune = '\u255e' // ╞ BoxDrawingsVerticalDoubleAndRightSingle rune = '\u255f' // ╟ BoxDrawingsDoubleVerticalAndRight rune = '\u2560' // ╠ BoxDrawingsVerticalSingleAndLeftDouble rune = '\u2561' // ╡ BoxDrawingsVerticalDoubleAndLeftSingle rune = '\u2562' // ╢ BoxDrawingsDoubleVerticalAndLeft rune = '\u2563' // ╣ BoxDrawingsDownSingleAndHorizontalDouble rune = '\u2564' // ╤ BoxDrawingsDownDoubleAndHorizontalSingle rune = '\u2565' // ╥ BoxDrawingsDoubleDownAndHorizontal rune = '\u2566' // ╦ BoxDrawingsUpSingleAndHorizontalDouble rune = '\u2567' // ╧ BoxDrawingsUpDoubleAndHorizontalSingle rune = '\u2568' // ╨ BoxDrawingsDoubleUpAndHorizontal rune = '\u2569' // ╩ BoxDrawingsVerticalSingleAndHorizontalDouble rune = '\u256a' // ╪ BoxDrawingsVerticalDoubleAndHorizontalSingle rune = '\u256b' // ╫ BoxDrawingsDoubleVerticalAndHorizontal rune = '\u256c' // ╬ BoxDrawingsLightArcDownAndRight rune = '\u256d' // ╭ BoxDrawingsLightArcDownAndLeft rune = '\u256e' // ╮ BoxDrawingsLightArcUpAndLeft rune = '\u256f' // ╯ BoxDrawingsLightArcUpAndRight rune = '\u2570' // ╰ BoxDrawingsLightDiagonalUpperRightToLowerLeft rune = '\u2571' // ╱ BoxDrawingsLightDiagonalUpperLeftToLowerRight rune = '\u2572' // ╲ BoxDrawingsLightDiagonalCross rune = '\u2573' // ╳ BoxDrawingsLightLeft rune = '\u2574' // ╴ BoxDrawingsLightUp rune = '\u2575' // ╵ BoxDrawingsLightRight rune = '\u2576' // ╶ BoxDrawingsLightDown rune = '\u2577' // ╷ BoxDrawingsHeavyLeft rune = '\u2578' // ╸ BoxDrawingsHeavyUp rune = '\u2579' // ╹ BoxDrawingsHeavyRight rune = '\u257a' // ╺ BoxDrawingsHeavyDown rune = '\u257b' // ╻ BoxDrawingsLightLeftAndHeavyRight rune = '\u257c' // ╼ BoxDrawingsLightUpAndHeavyDown rune = '\u257d' // ╽ BoxDrawingsHeavyLeftAndLightRight rune = '\u257e' // ╾ BoxDrawingsHeavyUpAndLightDown rune = '\u257f' // ╿ // Block Elements. BlockUpperHalfBlock rune = '\u2580' // ▀ BlockLowerOneEighthBlock rune = '\u2581' // ▁ BlockLowerOneQuarterBlock rune = '\u2582' // ▂ BlockLowerThreeEighthsBlock rune = '\u2583' // ▃ BlockLowerHalfBlock rune = '\u2584' // ▄ BlockLowerFiveEighthsBlock rune = '\u2585' // ▅ BlockLowerThreeQuartersBlock rune = '\u2586' // ▆ BlockLowerSevenEighthsBlock rune = '\u2587' // ▇ BlockFullBlock rune = '\u2588' // █ BlockLeftSevenEighthsBlock rune = '\u2589' // ▉ BlockLeftThreeQuartersBlock rune = '\u258A' // ▊ BlockLeftFiveEighthsBlock rune = '\u258B' // ▋ BlockLeftHalfBlock rune = '\u258C' // ▌ BlockLeftThreeEighthsBlock rune = '\u258D' // ▍ BlockLeftOneQuarterBlock rune = '\u258E' // ▎ BlockLeftOneEighthBlock rune = '\u258F' // ▏ BlockRightHalfBlock rune = '\u2590' // ▐ BlockLightShade rune = '\u2591' // ░ BlockMediumShade rune = '\u2592' // ▒ BlockDarkShade rune = '\u2593' // ▓ BlockUpperOneEighthBlock rune = '\u2594' // ▔ BlockRightOneEighthBlock rune = '\u2595' // ▕ BlockQuadrantLowerLeft rune = '\u2596' // ▖ BlockQuadrantLowerRight rune = '\u2597' // ▗ BlockQuadrantUpperLeft rune = '\u2598' // ▘ BlockQuadrantUpperLeftAndLowerLeftAndLowerRight rune = '\u2599' // ▙ BlockQuadrantUpperLeftAndLowerRight rune = '\u259A' // ▚ BlockQuadrantUpperLeftAndUpperRightAndLowerLeft rune = '\u259B' // ▛ BlockQuadrantUpperLeftAndUpperRightAndLowerRight rune = '\u259C' // ▜ BlockQuadrantUpperRight rune = '\u259D' // ▝ BlockQuadrantUpperRightAndLowerLeft rune = '\u259E' // ▞ BlockQuadrantUpperRightAndLowerLeftAndLowerRight rune = '\u259F' // ▟ ) // SemigraphicJoints is a map for joining semigraphic (or otherwise) runes. // So far only light lines are supported but if you want to change the border // styling you need to provide the joints, too. // The matching will be sorted ascending by rune value, so you don't need to // provide all rune combinations, // e.g. (─) + (│) = (┼) will also match (│) + (─) = (┼) var SemigraphicJoints = map[string]rune{ // (─) + (│) = (┼) string([]rune{BoxDrawingsLightHorizontal, BoxDrawingsLightVertical}): BoxDrawingsLightVerticalAndHorizontal, // (─) + (┌) = (┬) string([]rune{BoxDrawingsLightHorizontal, BoxDrawingsLightDownAndRight}): BoxDrawingsLightDownAndHorizontal, // (─) + (┐) = (┬) string([]rune{BoxDrawingsLightHorizontal, BoxDrawingsLightDownAndLeft}): BoxDrawingsLightDownAndHorizontal, // (─) + (└) = (┴) string([]rune{BoxDrawingsLightHorizontal, BoxDrawingsLightUpAndRight}): BoxDrawingsLightUpAndHorizontal, // (─) + (┘) = (┴) string([]rune{BoxDrawingsLightHorizontal, BoxDrawingsLightUpAndLeft}): BoxDrawingsLightUpAndHorizontal, // (─) + (├) = (┼) string([]rune{BoxDrawingsLightHorizontal, BoxDrawingsLightVerticalAndRight}): BoxDrawingsLightVerticalAndHorizontal, // (─) + (┤) = (┼) string([]rune{BoxDrawingsLightHorizontal, BoxDrawingsLightVerticalAndLeft}): BoxDrawingsLightVerticalAndHorizontal, // (─) + (┬) = (┬) string([]rune{BoxDrawingsLightHorizontal, BoxDrawingsLightDownAndHorizontal}): BoxDrawingsLightDownAndHorizontal, // (─) + (┴) = (┴) string([]rune{BoxDrawingsLightHorizontal, BoxDrawingsLightUpAndHorizontal}): BoxDrawingsLightUpAndHorizontal, // (─) + (┼) = (┼) string([]rune{BoxDrawingsLightHorizontal, BoxDrawingsLightVerticalAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (│) + (┌) = (├) string([]rune{BoxDrawingsLightVertical, BoxDrawingsLightDownAndRight}): BoxDrawingsLightVerticalAndRight, // (│) + (┐) = (┤) string([]rune{BoxDrawingsLightVertical, BoxDrawingsLightDownAndLeft}): BoxDrawingsLightVerticalAndLeft, // (│) + (└) = (├) string([]rune{BoxDrawingsLightVertical, BoxDrawingsLightUpAndRight}): BoxDrawingsLightVerticalAndRight, // (│) + (┘) = (┤) string([]rune{BoxDrawingsLightVertical, BoxDrawingsLightUpAndLeft}): BoxDrawingsLightVerticalAndLeft, // (│) + (├) = (├) string([]rune{BoxDrawingsLightVertical, BoxDrawingsLightVerticalAndRight}): BoxDrawingsLightVerticalAndRight, // (│) + (┤) = (┤) string([]rune{BoxDrawingsLightVertical, BoxDrawingsLightVerticalAndLeft}): BoxDrawingsLightVerticalAndLeft, // (│) + (┬) = (┼) string([]rune{BoxDrawingsLightVertical, BoxDrawingsLightDownAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (│) + (┴) = (┼) string([]rune{BoxDrawingsLightVertical, BoxDrawingsLightUpAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (│) + (┼) = (┼) string([]rune{BoxDrawingsLightVertical, BoxDrawingsLightVerticalAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (┌) + (┐) = (┬) string([]rune{BoxDrawingsLightDownAndRight, BoxDrawingsLightDownAndLeft}): BoxDrawingsLightDownAndHorizontal, // (┌) + (└) = (├) string([]rune{BoxDrawingsLightDownAndRight, BoxDrawingsLightUpAndRight}): BoxDrawingsLightVerticalAndRight, // (┌) + (┘) = (┼) string([]rune{BoxDrawingsLightDownAndRight, BoxDrawingsLightUpAndLeft}): BoxDrawingsLightVerticalAndHorizontal, // (┌) + (├) = (├) string([]rune{BoxDrawingsLightDownAndRight, BoxDrawingsLightVerticalAndRight}): BoxDrawingsLightVerticalAndRight, // (┌) + (┤) = (┼) string([]rune{BoxDrawingsLightDownAndRight, BoxDrawingsLightVerticalAndLeft}): BoxDrawingsLightVerticalAndHorizontal, // (┌) + (┬) = (┬) string([]rune{BoxDrawingsLightDownAndRight, BoxDrawingsLightDownAndHorizontal}): BoxDrawingsLightDownAndHorizontal, // (┌) + (┴) = (┼) string([]rune{BoxDrawingsLightDownAndRight, BoxDrawingsLightUpAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (┌) + (┴) = (┼) string([]rune{BoxDrawingsLightDownAndRight, BoxDrawingsLightVerticalAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (┐) + (└) = (┼) string([]rune{BoxDrawingsLightDownAndLeft, BoxDrawingsLightUpAndRight}): BoxDrawingsLightVerticalAndHorizontal, // (┐) + (┘) = (┤) string([]rune{BoxDrawingsLightDownAndLeft, BoxDrawingsLightUpAndLeft}): BoxDrawingsLightVerticalAndLeft, // (┐) + (├) = (┼) string([]rune{BoxDrawingsLightDownAndLeft, BoxDrawingsLightVerticalAndRight}): BoxDrawingsLightVerticalAndHorizontal, // (┐) + (┤) = (┤) string([]rune{BoxDrawingsLightDownAndLeft, BoxDrawingsLightVerticalAndLeft}): BoxDrawingsLightVerticalAndLeft, // (┐) + (┬) = (┬) string([]rune{BoxDrawingsLightDownAndLeft, BoxDrawingsLightDownAndHorizontal}): BoxDrawingsLightDownAndHorizontal, // (┐) + (┴) = (┼) string([]rune{BoxDrawingsLightDownAndLeft, BoxDrawingsLightUpAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (┐) + (┼) = (┼) string([]rune{BoxDrawingsLightDownAndLeft, BoxDrawingsLightVerticalAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (└) + (┘) = (┴) string([]rune{BoxDrawingsLightUpAndRight, BoxDrawingsLightUpAndLeft}): BoxDrawingsLightUpAndHorizontal, // (└) + (├) = (├) string([]rune{BoxDrawingsLightUpAndRight, BoxDrawingsLightVerticalAndRight}): BoxDrawingsLightVerticalAndRight, // (└) + (┤) = (┼) string([]rune{BoxDrawingsLightUpAndRight, BoxDrawingsLightVerticalAndLeft}): BoxDrawingsLightVerticalAndHorizontal, // (└) + (┬) = (┼) string([]rune{BoxDrawingsLightUpAndRight, BoxDrawingsLightDownAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (└) + (┴) = (┴) string([]rune{BoxDrawingsLightUpAndRight, BoxDrawingsLightUpAndHorizontal}): BoxDrawingsLightUpAndHorizontal, // (└) + (┼) = (┼) string([]rune{BoxDrawingsLightUpAndRight, BoxDrawingsLightVerticalAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (┘) + (├) = (┼) string([]rune{BoxDrawingsLightUpAndLeft, BoxDrawingsLightVerticalAndRight}): BoxDrawingsLightVerticalAndHorizontal, // (┘) + (┤) = (┤) string([]rune{BoxDrawingsLightUpAndLeft, BoxDrawingsLightVerticalAndLeft}): BoxDrawingsLightVerticalAndLeft, // (┘) + (┬) = (┼) string([]rune{BoxDrawingsLightUpAndLeft, BoxDrawingsLightDownAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (┘) + (┴) = (┴) string([]rune{BoxDrawingsLightUpAndLeft, BoxDrawingsLightUpAndHorizontal}): BoxDrawingsLightUpAndHorizontal, // (┘) + (┼) = (┼) string([]rune{BoxDrawingsLightUpAndLeft, BoxDrawingsLightVerticalAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (├) + (┤) = (┼) string([]rune{BoxDrawingsLightVerticalAndRight, BoxDrawingsLightVerticalAndLeft}): BoxDrawingsLightVerticalAndHorizontal, // (├) + (┬) = (┼) string([]rune{BoxDrawingsLightVerticalAndRight, BoxDrawingsLightDownAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (├) + (┴) = (┼) string([]rune{BoxDrawingsLightVerticalAndRight, BoxDrawingsLightUpAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (├) + (┼) = (┼) string([]rune{BoxDrawingsLightVerticalAndRight, BoxDrawingsLightVerticalAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (┤) + (┬) = (┼) string([]rune{BoxDrawingsLightVerticalAndLeft, BoxDrawingsLightDownAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (┤) + (┴) = (┼) string([]rune{BoxDrawingsLightVerticalAndLeft, BoxDrawingsLightUpAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (┤) + (┼) = (┼) string([]rune{BoxDrawingsLightVerticalAndLeft, BoxDrawingsLightVerticalAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (┬) + (┴) = (┼) string([]rune{BoxDrawingsLightDownAndHorizontal, BoxDrawingsLightUpAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (┬) + (┼) = (┼) string([]rune{BoxDrawingsLightDownAndHorizontal, BoxDrawingsLightVerticalAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, // (┴) + (┼) = (┼) string([]rune{BoxDrawingsLightUpAndHorizontal, BoxDrawingsLightVerticalAndHorizontal}): BoxDrawingsLightVerticalAndHorizontal, } // PrintJoinedSemigraphics prints a semigraphics rune into the screen at the given // position with the given style, joining it with any existing semigraphics // rune.At this point, only regular single line borders are supported. func PrintJoinedSemigraphics(screen tcell.Screen, x, y int, ch rune, style tcell.Style) { previous, _, _, _ := screen.GetContent(x, y) // What's the resulting rune? var result rune if ch == previous { result = ch } else { if ch < previous { previous, ch = ch, previous } result = SemigraphicJoints[string([]rune{previous, ch})] } if result == 0 { result = ch } // We only print something if we have something. screen.SetContent(x, y, result, nil, style) } golang-github-darkhz-tview-0.0~git20240308.6078a88/strings.go000066400000000000000000000464201457770046000232260ustar00rootroot00000000000000package tview import ( "fmt" "math/rand" "regexp" "strconv" "strings" "unicode/utf8" "github.com/gdamore/tcell/v2" "github.com/rivo/uniseg" ) // escapedTagPattern matches an escaped tag, e.g. "[red[]", at the beginning of // a string. var escapedTagPattern = regexp.MustCompile(`^\[[^\[\]]+\[+\]`) // stepOptions is a bit field of options for [step]. A value of 0 results in // [step] having the same behavior as uniseg.Step, i.e. no tview-related parsing // is performed. type stepOptions int // Bit fields for [stepOptions]. const ( stepOptionsNone stepOptions = 0 stepOptionsStyle stepOptions = 1 << iota // Parse style tags. stepOptionsRegion // Parse region tags. ) // stepState represents the current state of the parser implemented in [step]. type stepState struct { unisegState int // The state of the uniseg parser. boundaries int // Information about boundaries, as returned by uniseg.Step. style tcell.Style // The current style. region string // The current region. escapedTagState int // States for parsing escaped tags (defined in [step]). grossLength int // The length of the cluster, including any tags not returned. // The styles for the initial call to [step]. initialForeground tcell.Color initialBackground tcell.Color initialAttributes tcell.AttrMask } // IsWordBoundary returns true if the boundary between the returned grapheme // cluster and the one following it is a word boundary. func (s *stepState) IsWordBoundary() bool { return s.boundaries&uniseg.MaskWord != 0 } // IsSentenceBoundary returns true if the boundary between the returned grapheme // cluster and the one following it is a sentence boundary. func (s *stepState) IsSentenceBoundary() bool { return s.boundaries&uniseg.MaskSentence != 0 } // LineBreak returns whether the string can be broken into the next line after // the returned grapheme cluster. If optional is true, the line break is // optional. If false, the line break is mandatory, e.g. after a newline // character. func (s *stepState) LineBreak() (lineBreak, optional bool) { switch s.boundaries & uniseg.MaskLine { case uniseg.LineCanBreak: return true, true case uniseg.LineMustBreak: return true, false } return false, false // uniseg.LineDontBreak. } // Width returns the grapheme cluster's width in cells. func (s *stepState) Width() int { return s.boundaries >> uniseg.ShiftWidth } // GrossLength returns the grapheme cluster's length in bytes, including any // tags that were parsed but not explicitly returned. func (s *stepState) GrossLength() int { return s.grossLength } // Style returns the style for the grapheme cluster. func (s *stepState) Style() tcell.Style { return s.style } // step uses uniseg.Step to iterate over the grapheme clusters of a string but // (optionally) also parses the string for style or region tags. // // This function can be called consecutively to extract all grapheme clusters // from str, without returning any contained (parsed) tags. The return values // are the first grapheme cluster, the remaining string, and the new state. Pass // the remaining string and the returned state to the next call. If the rest // string is empty, parsing is complete. Call the returned state's methods for // boundary and width information. // // The returned cluster may be empty if the given string consists of only // (parsed) tags. The boundary and width information will be meaningless in // this case but the style will describe the style at the end of the string. // // Pass nil for state on the first call. This will assume an initial style with // [Styles.PrimitiveBackgroundColor] as the background color and // [Styles.PrimaryTextColor] as the text color, no current region. If you want // to start with a different style or region, you can set the state accordingly // but you must then set [state.unisegState] to -1. // // There is no need to call uniseg.HasTrailingLineBreakInString on the last // non-empty cluster as this function will do this for you and adjust the // returned boundaries accordingly. func step(str string, state *stepState, opts stepOptions) (cluster, rest string, newState *stepState) { // Set up initial state. if state == nil { state = &stepState{ unisegState: -1, style: tcell.StyleDefault.Background(Styles.PrimitiveBackgroundColor).Foreground(Styles.PrimaryTextColor), } } if state.unisegState < 0 { state.initialForeground, state.initialBackground, state.initialAttributes = state.style.Decompose() } if len(str) == 0 { newState = state return } // Get a grapheme cluster. preState := state.unisegState cluster, rest, state.boundaries, state.unisegState = uniseg.StepString(str, preState) state.grossLength = len(cluster) if rest == "" { if !uniseg.HasTrailingLineBreakInString(cluster) { state.boundaries &^= uniseg.MaskLine } } // Parse tags. if opts != 0 { const ( etNone int = iota etStart etChar etClosing ) // Finite state machine for escaped tags. switch state.escapedTagState { case etStart: if cluster[0] == '[' || cluster[0] == ']' { // Invalid escaped tag. state.escapedTagState = etNone } else { // Other characters are allowed. state.escapedTagState = etChar } case etChar: if cluster[0] == ']' { // In theory, this should not happen. state.escapedTagState = etNone } else if cluster[0] == '[' { // Starting closing sequence. // Swallow the first one. cluster, rest, state.boundaries, state.unisegState = uniseg.StepString(rest, preState) state.grossLength += len(cluster) if cluster[0] == ']' { state.escapedTagState = etNone } else { state.escapedTagState = etClosing } } // More characters. Remain in etChar. case etClosing: if cluster[0] != '[' { state.escapedTagState = etNone } } // Regular tags. if state.escapedTagState == etNone { if cluster[0] == '[' { // We've already opened a tag. Parse it. length, style, region := parseTag(str, state) if length > 0 { state.style = style state.region = region cluster, rest, state.boundaries, state.unisegState = uniseg.StepString(str[length:], preState) state.grossLength = len(cluster) + length if rest == "" { if !uniseg.HasTrailingLineBreakInString(cluster) { state.boundaries &^= uniseg.MaskLine } } } // Is this an escaped tag? if escapedTagPattern.MatchString(str[length:]) { state.escapedTagState = etStart } } if len(rest) > 0 && rest[0] == '[' { // A tag might follow the cluster. If so, we need to fix the state // for the boundaries to be correct. if length, _, _ := parseTag(rest, state); length > 0 { if len(rest) > length { _, l := utf8.DecodeRuneInString(rest[length:]) cluster += rest[length : length+l] } var taglessRest string cluster, taglessRest, state.boundaries, state.unisegState = uniseg.StepString(cluster, preState) if taglessRest == "" { if !uniseg.HasTrailingLineBreakInString(cluster) { state.boundaries &^= uniseg.MaskLine } } } } } } newState = state return } // parseTag parses str for consecutive style and/or region tags, assuming that // str starts with the opening bracket for the first tag. It returns the string // length of all valid tags (0 if the first tag is not valid) and the updated // style and region for valid tags (based on the provided state). func parseTag(str string, state *stepState) (length int, style tcell.Style, region string) { // Automata states for parsing tags. const ( tagStateNone = iota tagStateDoneTag tagStateStart tagStateRegionStart tagStateEndForeground tagStateStartBackground tagStateNumericForeground tagStateNameForeground tagStateEndBackground tagStateStartAttributes tagStateNumericBackground tagStateNameBackground tagStateAttributes tagStateRegionEnd tagStateRegionName tagStateEndAttributes tagStateStartURL tagStateEndURL tagStateURL ) // Helper function which checks if the given byte is one of a list of // characters, including letters and digits. isOneOf := func(b byte, chars string) bool { if b >= 'a' && b <= 'z' || b >= 'A' && b <= 'Z' || b >= '0' && b <= '9' { return true } return strings.IndexByte(chars, b) >= 0 } // Attribute map. attrs := map[byte]tcell.AttrMask{ 'B': tcell.AttrBold, 'U': tcell.AttrUnderline, 'I': tcell.AttrItalic, 'L': tcell.AttrBlink, 'D': tcell.AttrDim, 'S': tcell.AttrStrikeThrough, 'R': tcell.AttrReverse, } var ( tagState, tagLength int tempStr strings.Builder ) tStyle := state.style tRegion := state.region // Process state transitions. for len(str) > 0 { ch := str[0] str = str[1:] tagLength++ // Transition. switch tagState { case tagStateNone: if ch == '[' { // Start of a tag. tagState = tagStateStart } else { // Not a tag. We're done. return } case tagStateStart: if ch == '"' { // Start of a region tag. tempStr.Reset() tagState = tagStateRegionStart } else if !isOneOf(ch, "#:-") { // Invalid style tag. return } else if ch == '-' { // Reset foreground color. tStyle = tStyle.Foreground(state.initialForeground) tagState = tagStateEndForeground } else if ch == ':' { // No foreground color. tagState = tagStateStartBackground } else { tempStr.Reset() tempStr.WriteByte(ch) if ch == '#' { // Numeric foreground color. tagState = tagStateNumericForeground } else { // Letters or numbers. tagState = tagStateNameForeground } } case tagStateEndForeground: if ch == ']' { // End of tag. tagState = tagStateDoneTag } else if ch == ':' { tagState = tagStateStartBackground } else { // Invalid tag. return } case tagStateNumericForeground: if ch == ']' || ch == ':' { if tempStr.Len() != 7 { // Must be #rrggbb. return } tStyle = tStyle.Foreground(tcell.GetColor(tempStr.String())) } if ch == ']' { // End of tag. tagState = tagStateDoneTag } else if ch == ':' { // Start of background color. tagState = tagStateStartBackground } else if strings.IndexByte("0123456789abcdefABCDEF", ch) >= 0 { // Hex digit. tempStr.WriteByte(ch) tagState = tagStateNumericForeground } else { // Invalid tag. return } case tagStateNameForeground: if ch == ']' || ch == ':' { name := tempStr.String() if name[0] >= '0' && name[0] <= '9' { // Must not start with a digit. return } tStyle = tStyle.Foreground(tcell.ColorNames[name]) } if !isOneOf(ch, "]:") { // Invalid tag. return } else if ch == ']' { // End of tag. tagState = tagStateDoneTag } else if ch == ':' { // Start of background color. tagState = tagStateStartBackground } else { // Letters or numbers. tempStr.WriteByte(ch) } case tagStateStartBackground: if !isOneOf(ch, "#:-]") { // Invalid style tag. return } else if ch == ']' { // End of tag. tagState = tagStateDoneTag } else if ch == '-' { // Reset background color. tStyle = tStyle.Background(state.initialBackground) tagState = tagStateEndBackground } else if ch == ':' { // No background color. tagState = tagStateStartAttributes } else { tempStr.Reset() tempStr.WriteByte(ch) if ch == '#' { // Numeric background color. tagState = tagStateNumericBackground } else { // Letters or numbers. tagState = tagStateNameBackground } } case tagStateEndBackground: if ch == ']' { // End of tag. tagState = tagStateDoneTag } else if ch == ':' { // Start of attributes. tagState = tagStateStartAttributes } else { // Invalid tag. return } case tagStateNumericBackground: if ch == ']' || ch == ':' { if tempStr.Len() != 7 { // Must be #rrggbb. return } tStyle = tStyle.Background(tcell.GetColor(tempStr.String())) } if ch == ']' { // End of tag. tagState = tagStateDoneTag } else if ch == ':' { // Start of attributes. tagState = tagStateStartAttributes } else if strings.IndexByte("0123456789abcdefABCDEF", ch) >= 0 { // Hex digit. tempStr.WriteByte(ch) tagState = tagStateNumericBackground } else { // Invalid tag. return } case tagStateNameBackground: if ch == ']' || ch == ':' { name := tempStr.String() if name[0] >= '0' && name[0] <= '9' { // Must not start with a digit. return } tStyle = tStyle.Background(tcell.ColorNames[name]) } if !isOneOf(ch, "]:") { // Invalid tag. return } else if ch == ']' { // End of tag. tagState = tagStateDoneTag } else if ch == ':' { // Start of background color. tagState = tagStateStartAttributes } else { // Letters or numbers. tempStr.WriteByte(ch) } case tagStateStartAttributes: if ch == ']' { // End of tag. tagState = tagStateDoneTag } else if ch == '-' { // Reset attributes. tStyle = tStyle.Attributes(state.initialAttributes) tagState = tagStateEndAttributes } else if ch == ':' { // Start of URL. tagState = tagStateStartURL } else if strings.IndexByte("buildsrBUILDSR", ch) >= 0 { // Attribute tag. tempStr.Reset() tempStr.WriteByte(ch) tagState = tagStateAttributes } else { // Invalid tag. return } case tagStateAttributes: if ch == ']' || ch == ':' { flags := tempStr.String() _, _, a := tStyle.Decompose() for index := 0; index < len(flags); index++ { ch := flags[index] if ch >= 'a' && ch <= 'z' { a |= attrs[ch-('a'-'A')] } else { a &^= attrs[ch] } } tStyle = tStyle.Attributes(a) } if ch == ']' { // End of tag. tagState = tagStateDoneTag } else if ch == ':' { // Start of URL. tagState = tagStateStartURL } else if strings.IndexByte("buildsrBUILDSR", ch) >= 0 { // Attribute tag. tempStr.WriteByte(ch) } else { // Invalid tag. return } case tagStateEndAttributes: if ch == ']' { // End of tag. tagState = tagStateDoneTag } else if ch == ':' { // Start of URL. tagState = tagStateStartURL } else { // Invalid tag. return } case tagStateStartURL: if ch == ']' { // End of tag. tagState = tagStateDoneTag } else if ch == '-' { // Reset URL. tStyle = tStyle.Url("").UrlId("") tagState = tagStateEndURL } else { // URL character. tempStr.Reset() tempStr.WriteByte(ch) tStyle = tStyle.UrlId(strconv.Itoa(int(rand.Uint32()))) // Generate a unique ID for this URL. tagState = tagStateURL } case tagStateEndURL: if ch == ']' { // End of tag. tagState = tagStateDoneTag } else { // Invalid tag. return } case tagStateURL: if ch == ']' { // End of tag. tStyle = tStyle.Url(tempStr.String()) tagState = tagStateDoneTag } else { // URL character. tempStr.WriteByte(ch) } case tagStateRegionStart: if ch == '"' { // End of region tag. tagState = tagStateRegionEnd } else if isOneOf(ch, "_,;: -.") { // Region name. tempStr.WriteByte(ch) tagState = tagStateRegionName } else { // Invalid tag. return } case tagStateRegionEnd: if ch == ']' { // End of tag. tRegion = tempStr.String() tagState = tagStateDoneTag } else { // Invalid tag. return } case tagStateRegionName: if ch == '"' { // End of region tag. tagState = tagStateRegionEnd } else if isOneOf(ch, "_,;: -.") { // Region name. tempStr.WriteByte(ch) } else { // Invalid tag. return } } // The last transition led to a tag end. Make the tag permanent. if tagState == tagStateDoneTag { length, style, region = tagLength, tStyle, tRegion tagState = tagStateNone // Reset state. } } return } // TaggedStringWidth returns the width of the given string needed to print it on // screen. The text may contain style tags which are not counted. func TaggedStringWidth(text string) (width int) { var state *stepState for len(text) > 0 { _, text, state = step(text, state, stepOptionsStyle) width += state.Width() } return } // WordWrap splits a text such that each resulting line does not exceed the // given screen width. Split points are determined using the algorithm described // in [Unicode Standard Annex #14]. // // This function considers style tags to have no width. // // [Unicode Standard Annex #14]: https://www.unicode.org/reports/tr14/ func WordWrap(text string, width int) (lines []string) { if width <= 0 { return } var ( state *stepState lineWidth, lineLength, lastOption, lastOptionWidth int ) str := text for len(str) > 0 { // Parse the next character. _, str, state = step(str, state, stepOptionsStyle) cWidth := state.Width() // Would it exceed the line width? if lineWidth+cWidth > width { if lastOptionWidth == 0 { // No split point so far. Just split at the current position. lines = append(lines, text[:lineLength]) text = text[lineLength:] lineWidth, lineLength, lastOption, lastOptionWidth = 0, 0, 0, 0 } else { // Split at the last split point. lines = append(lines, text[:lastOption]) text = text[lastOption:] lineWidth -= lastOptionWidth lineLength -= lastOption lastOption, lastOptionWidth = 0, 0 } } // Move ahead. lineWidth += cWidth lineLength += state.GrossLength() // Check for split points. if lineBreak, optional := state.LineBreak(); lineBreak { if optional { // Remember this split point. lastOption = lineLength lastOptionWidth = lineWidth } else { // We must split here. lines = append(lines, strings.TrimRight(text[:lineLength], "\n\r")) text = text[lineLength:] lineWidth, lineLength, lastOption, lastOptionWidth = 0, 0, 0, 0 } } } lines = append(lines, text) return } // Escape escapes the given text such that color and/or region tags are not // recognized and substituted by the print functions of this package. For // example, to include a tag-like string in a box title or in a TextView: // // box.SetTitle(tview.Escape("[squarebrackets]")) // fmt.Fprint(textView, tview.Escape(`["quoted"]`)) func Escape(text string) string { return nonEscapePattern.ReplaceAllString(text, "$1[]") } // ReplaceRegionStyles replaces style tags within text regions. func ReplaceRegionStyles(text string, getStyle func(region string) string) string { var ( str, regionText strings.Builder state *stepState region string escapedState int ) for len(text) > 0 { var c string c, text, state = step(text, state, stepOptionsStyle) if escapedState > 0 && state.escapedTagState == 0 { c = "[]" } escapedState = state.escapedTagState if region != "" && region != state.region { if regionText.Len() > 0 { fmt.Fprintf(&str, "[\"%s\"]", region) text := regionText.String() if tag := getStyle(region); tag != "" { fmt.Fprintf(&str, "%s%s[-:-:-]", tag, text) } else { str.WriteString(text) } str.WriteString("[\"\"]") regionText.Reset() region = state.region } } if state.region == "" && region == "" { str.WriteString(c) continue } region = state.region regionText.WriteString(c) } return str.String() } // stripTags strips style tags from the given string. (Region tags are not // stripped.) func stripTags(text string) string { var ( str strings.Builder state *stepState ) for len(text) > 0 { var c string c, text, state = step(text, state, stepOptionsStyle) str.WriteString(c) } return str.String() } golang-github-darkhz-tview-0.0~git20240308.6078a88/styles.go000066400000000000000000000032241457770046000230530ustar00rootroot00000000000000package tview import "github.com/gdamore/tcell/v2" // Theme defines the colors used when primitives are initialized. type Theme struct { PrimitiveBackgroundColor tcell.Color // Main background color for primitives. ContrastBackgroundColor tcell.Color // Background color for contrasting elements. MoreContrastBackgroundColor tcell.Color // Background color for even more contrasting elements. BorderColor tcell.Color // Box borders. TitleColor tcell.Color // Box titles. GraphicsColor tcell.Color // Graphics. PrimaryTextColor tcell.Color // Primary text. SecondaryTextColor tcell.Color // Secondary text (e.g. labels). TertiaryTextColor tcell.Color // Tertiary text (e.g. subtitles, notes). InverseTextColor tcell.Color // Text on primary-colored backgrounds. ContrastSecondaryTextColor tcell.Color // Secondary text on ContrastBackgroundColor-colored backgrounds. } // Styles defines the theme for applications. The default is for a black // background and some basic colors: black, white, yellow, green, cyan, and // blue. var Styles = Theme{ PrimitiveBackgroundColor: tcell.ColorBlack, ContrastBackgroundColor: tcell.ColorBlue, MoreContrastBackgroundColor: tcell.ColorGreen, BorderColor: tcell.ColorWhite, TitleColor: tcell.ColorWhite, GraphicsColor: tcell.ColorWhite, PrimaryTextColor: tcell.ColorWhite, SecondaryTextColor: tcell.ColorYellow, TertiaryTextColor: tcell.ColorGreen, InverseTextColor: tcell.ColorBlue, ContrastSecondaryTextColor: tcell.ColorNavy, } golang-github-darkhz-tview-0.0~git20240308.6078a88/table.go000066400000000000000000001510161457770046000226220ustar00rootroot00000000000000package tview import ( "sort" "github.com/gdamore/tcell/v2" colorful "github.com/lucasb-eyer/go-colorful" ) // TableCell represents one cell inside a Table. You can instantiate this type // directly but all colors (background and text) will be set to their default // which is black. type TableCell struct { // The reference object. Reference interface{} // The text to be displayed in the table cell. Text string // The alignment of the cell text. One of AlignLeft (default), AlignCenter, // or AlignRight. Align int // The maximum width of the cell in screen space. This is used to give a // column a maximum width. Any cell text whose screen width exceeds this width // is cut off. Set to 0 if there is no maximum width. MaxWidth int // If the total table width is less than the available width, this value is // used to add extra width to a column. See SetExpansion() for details. Expansion int // The color of the cell text. Color tcell.Color // The background color of the cell. BackgroundColor tcell.Color // If set to true, the BackgroundColor is not used and the cell will have // the background color of the table. Transparent bool // The style attributes of the cell. Attributes tcell.AttrMask // If set to true, this cell cannot be selected. NotSelectable bool // An optional handler for mouse clicks. This also fires if the cell is not // selectable. If true is returned, no additional "selected" event is fired // on selectable cells. Clicked func() bool // An optional handler for mouse clicks. This fires whenever a cell is selected. OnClicked func(table *Table, row, column int) // The style of the selected cell. If this value is the empty struct, // the selected cell is simply inverted. selectedStyle tcell.Style // The position and width of the cell the last time table was drawn. x, y, width int } // NewTableCell returns a new table cell with sensible defaults. That is, left // aligned text with the primary text color (see Styles) and a transparent // background (using the background of the Table). func NewTableCell(text string) *TableCell { return &TableCell{ Text: text, Align: AlignLeft, Color: Styles.PrimaryTextColor, BackgroundColor: Styles.PrimitiveBackgroundColor, Transparent: true, } } // SetText sets the cell's text. func (c *TableCell) SetText(text string) *TableCell { c.Text = text return c } // SetAlign sets the cell's text alignment, one of AlignLeft, AlignCenter, or // AlignRight. func (c *TableCell) SetAlign(align int) *TableCell { c.Align = align return c } // SetMaxWidth sets maximum width of the cell in screen space. This is used to // give a column a maximum width. Any cell text whose screen width exceeds this // width is cut off. Set to 0 if there is no maximum width. func (c *TableCell) SetMaxWidth(maxWidth int) *TableCell { c.MaxWidth = maxWidth return c } // SetExpansion sets the value by which the column of this cell expands if the // available width for the table is more than the table width (prior to applying // this expansion value). This is a proportional value. The amount of unused // horizontal space is divided into widths to be added to each column. How much // extra width a column receives depends on the expansion value: A value of 0 // (the default) will not cause the column to increase in width. Other values // are proportional, e.g. a value of 2 will cause a column to grow by twice // the amount of a column with a value of 1. // // Since this value affects an entire column, the maximum over all visible cells // in that column is used. // // This function panics if a negative value is provided. func (c *TableCell) SetExpansion(expansion int) *TableCell { if expansion < 0 { panic("Table cell expansion values may not be negative") } c.Expansion = expansion return c } // SetTextColor sets the cell's text color. func (c *TableCell) SetTextColor(color tcell.Color) *TableCell { c.Color = color return c } // SetBackgroundColor sets the cell's background color. This will also cause the // cell's Transparent flag to be set to "false". func (c *TableCell) SetBackgroundColor(color tcell.Color) *TableCell { c.BackgroundColor = color c.Transparent = false return c } // SetTransparency sets the background transparency of this cell. A value of // "true" will cause the cell to use the table's background color. A value of // "false" will cause it to use its own background color. func (c *TableCell) SetTransparency(transparent bool) *TableCell { c.Transparent = transparent return c } // SetAttributes sets the cell's text attributes. You can combine different // attributes using bitmask operations: // // cell.SetAttributes(tcell.AttrUnderline | tcell.AttrBold) func (c *TableCell) SetAttributes(attr tcell.AttrMask) *TableCell { c.Attributes = attr return c } // SetStyle sets the cell's style (foreground color, background color, and // attributes) all at once. func (c *TableCell) SetStyle(style tcell.Style) *TableCell { c.Color, c.BackgroundColor, c.Attributes = style.Decompose() return c } // SetSelectedStyle sets a specific style for the selected cell. If no such style // is set, per default, the selected cell is inverted (i.e. its foreground and // background colors are swapped). This overrides the table's SelectedStyle, if // set. This is useful if you want to set multiple selected styles to multiple // cells. // // To reset a previous setting to its default, make the following call: // // cell.SetSelectedStyle(tcell.Style{}) func (c *TableCell) SetSelectedStyle(style tcell.Style) *TableCell { c.selectedStyle = style return c } // SetSelectable sets whether or not this cell can be selected by the user. func (c *TableCell) SetSelectable(selectable bool) *TableCell { c.NotSelectable = !selectable return c } // SetReference allows you to store a reference of any type in this cell. This // will allow you to establish a mapping between the cell and your // actual data. func (c *TableCell) SetReference(reference interface{}) *TableCell { c.Reference = reference return c } // GetReference returns this cell's reference object. func (c *TableCell) GetReference() interface{} { return c.Reference } // GetLastPosition returns the position of the table cell the last time it was // drawn on screen. If the cell is not on screen, the return values are // undefined. // // Because the Table class will attempt to keep selected cells on screen, this // function is most useful in response to a "selected" event (see // SetSelectedFunc()) or a "selectionChanged" event (see // SetSelectionChangedFunc()). func (c *TableCell) GetLastPosition() (x, y, width int) { return c.x, c.y, c.width } // SetClickedFunc sets a handler which fires when this cell is clicked. This is // independent of whether the cell is selectable or not. But for selectable // cells, if the function returns "true", the "selected" event is not fired. func (c *TableCell) SetClickedFunc(clicked func() bool) *TableCell { c.Clicked = clicked return c } // SetOnClickedFunc sets a handler which fires when this cell is clicked. func (c *TableCell) SetOnClickedFunc(onclicked func(t *Table, row, column int)) *TableCell { c.OnClicked = onclicked return c } // TableContent defines a Table's data. You may replace a Table's default // implementation with your own using the Table.SetContent() function. This will // allow you to turn Table into a view of your own data structure. The // Table.Draw() function, which is called when the screen is updated, will then // use the (read-only) functions of this interface to update the table. The // write functions are only called when the corresponding functions of Table are // called. // // The interface's read-only functions are not called concurrently by the // package (provided that users of the package don't call Table.Draw() in a // separate goroutine, which would be uncommon and is not encouraged). type TableContent interface { // Return the cell at the given position or nil if there is no cell. The // row and column arguments start at 0 and end at what GetRowCount() and // GetColumnCount() return, minus 1. GetCell(row, column int) *TableCell // Return the total number of rows in the table. GetRowCount() int // Return the total number of columns in the table. GetColumnCount() int // The following functions are provided for completeness reasons as the // original Table implementation was not read-only. If you do not wish to // forward modifying operations to your data, you may opt to leave these // functions empty. To make this easier, you can include the // TableContentReadOnly type in your struct. See also the // demos/table/virtualtable example. // Set the cell at the given position to the provided cell. SetCell(row, column int, cell *TableCell) // Remove the row at the given position by shifting all following rows up // by one. Out of range positions may be ignored. RemoveRow(row int) // Remove the column at the given position by shifting all following columns // left by one. Out of range positions may be ignored. RemoveColumn(column int) // Insert a new empty row at the given position by shifting all rows at that // position and below down by one. Implementers may decide what to do with // out of range positions. InsertRow(row int) // Insert a new empty column at the given position by shifting all columns // at that position and to the right by one to the right. Implementers may // decide what to do with out of range positions. InsertColumn(column int) // Remove all table data. Clear() } // TableContentReadOnly is an empty struct which implements the write operations // of the TableContent interface. None of the implemented functions do anything. // You can embed this struct into your own structs to free yourself from having // to implement the empty write functions of TableContent. See // demos/table/virtualtable for an example. type TableContentReadOnly struct{} // SetCell does not do anything. func (t TableContentReadOnly) SetCell(row, column int, cell *TableCell) { // nop. } // RemoveRow does not do anything. func (t TableContentReadOnly) RemoveRow(row int) { // nop. } // RemoveColumn does not do anything. func (t TableContentReadOnly) RemoveColumn(column int) { // nop. } // InsertRow does not do anything. func (t TableContentReadOnly) InsertRow(row int) { // nop. } // InsertColumn does not do anything. func (t TableContentReadOnly) InsertColumn(column int) { // nop. } // Clear does not do anything. func (t TableContentReadOnly) Clear() { // nop. } // tableDefaultContent implements the default TableContent interface for the // Table class. type tableDefaultContent struct { // The cells of the table. Rows first, then columns. cells [][]*TableCell // The rightmost column in the data set. lastColumn int } // Clear clears all data. func (t *tableDefaultContent) Clear() { t.cells = nil t.lastColumn = -1 } // SetCell sets a cell's content. func (t *tableDefaultContent) SetCell(row, column int, cell *TableCell) { if row >= len(t.cells) { t.cells = append(t.cells, make([][]*TableCell, row-len(t.cells)+1)...) } rowLen := len(t.cells[row]) if column >= rowLen { t.cells[row] = append(t.cells[row], make([]*TableCell, column-rowLen+1)...) for c := rowLen; c < column; c++ { t.cells[row][c] = &TableCell{} } } t.cells[row][column] = cell if column > t.lastColumn { t.lastColumn = column } } // RemoveRow removes a row from the data. func (t *tableDefaultContent) RemoveRow(row int) { if row < 0 || row >= len(t.cells) { return } t.cells = append(t.cells[:row], t.cells[row+1:]...) } // RemoveColumn removes a column from the data. func (t *tableDefaultContent) RemoveColumn(column int) { for row := range t.cells { if column < 0 || column >= len(t.cells[row]) { continue } t.cells[row] = append(t.cells[row][:column], t.cells[row][column+1:]...) } if column >= 0 && column <= t.lastColumn { t.lastColumn-- } } // InsertRow inserts a new row at the given position. func (t *tableDefaultContent) InsertRow(row int) { if row >= len(t.cells) { return } t.cells = append(t.cells, nil) // Extend by one. copy(t.cells[row+1:], t.cells[row:]) // Shift down. t.cells[row] = nil // New row is uninitialized. } // InsertColumn inserts a new column at the given position. func (t *tableDefaultContent) InsertColumn(column int) { for row := range t.cells { if column >= len(t.cells[row]) { continue } t.cells[row] = append(t.cells[row], nil) // Extend by one. copy(t.cells[row][column+1:], t.cells[row][column:]) // Shift to the right. t.cells[row][column] = &TableCell{} // New element is an uninitialized table cell. } } // GetCell returns the cell at the given position. func (t *tableDefaultContent) GetCell(row, column int) *TableCell { if row < 0 || column < 0 || row >= len(t.cells) || column >= len(t.cells[row]) { return nil } return t.cells[row][column] } // GetRowCount returns the number of rows in the data set. func (t *tableDefaultContent) GetRowCount() int { return len(t.cells) } // GetColumnCount returns the number of columns in the data set. func (t *tableDefaultContent) GetColumnCount() int { if len(t.cells) == 0 { return 0 } return t.lastColumn + 1 } // Table visualizes two-dimensional data consisting of rows and columns. Each // Table cell is defined via SetCell() by the TableCell type. They can be added // dynamically to the table and changed any time. // // The most compact display of a table is without borders. Each row will then // occupy one row on screen and columns are separated by the rune defined via // SetSeparator() (a space character by default). // // When borders are turned on (via SetBorders()), each table cell is surrounded // by lines. Therefore one table row will require two rows on screen. // // Columns will use as much horizontal space as they need. You can constrain // their size with the MaxWidth parameter of the TableCell type. // // # Fixed Columns // // You can define fixed rows and rolumns via SetFixed(). They will always stay // in their place, even when the table is scrolled. Fixed rows are always the // top rows. Fixed columns are always the leftmost columns. // // # Selections // // You can call SetSelectable() to set columns and/or rows to "selectable". If // the flag is set only for columns, entire columns can be selected by the user. // If it is set only for rows, entire rows can be selected. If both flags are // set, individual cells can be selected. The "selected" handler set via // SetSelectedFunc() is invoked when the user presses Enter on a selection. // // # Navigation // // If the table extends beyond the available space, it can be navigated with // key bindings similar to Vim: // // - h, left arrow: Move left by one column. // - l, right arrow: Move right by one column. // - j, down arrow: Move down by one row. // - k, up arrow: Move up by one row. // - g, home: Move to the top. // - G, end: Move to the bottom. // - Ctrl-F, page down: Move down by one page. // - Ctrl-B, page up: Move up by one page. // // When there is no selection, this affects the entire table (except for fixed // rows and columns). When there is a selection, the user moves the selection. // The class will attempt to keep the selection from moving out of the screen. // // Use SetInputCapture() to override or modify keyboard input. // // See https://github.com/rivo/tview/wiki/Table for an example. type Table struct { *Box // Whether or not this table has borders around each cell. borders bool // Whether or not to arrange items with extra spacing, just // as setting the borders option would do, with the only // difference being that the rune used to draw all borders // would be a space character. expandSpace bool // The color of the borders or the separator. bordersColor tcell.Color // If there are no borders, the column separator. separator rune // The table's data structure. content TableContent // If true, when calculating the widths of the columns, all rows are evaluated // instead of only the visible ones. evaluateAllRows bool // The number of fixed rows / columns. fixedRows, fixedColumns int // Whether or not rows or columns can be selected. If both are set to true, // cells can be selected. rowsSelectable, columnsSelectable bool // The currently selected row and column. selectedRow, selectedColumn int PrevRow, PrevColumn int // A temporary flag which causes the next call to Draw() to force the // current selection to remain visible. It is set to false afterwards. clampToSelection bool // If set to true, moving the selection will wrap around horizontally (last // to first column and vice versa) or vertically (last to first row and vice // versa). wrapHorizontally, wrapVertically bool // When set to true, this flag will cause the selector to wrap around the text // instead of spanning across the entire column width. selectorWrap bool // The number of rows/columns by which the table is scrolled down/to the // right. rowOffset, columnOffset int // If set to true, the table's last row will always be visible. trackEnd bool // The number of visible rows the last time the table was drawn. visibleRows int // The indices of the visible columns as of the last time the table was drawn. visibleColumnIndices []int // The net widths of the visible columns as of the last time the table was // drawn. visibleColumnWidths []int // The style of the selected rows. If this value is the empty struct, // selected rows are simply inverted. selectedStyle tcell.Style // An optional function which gets called when the user presses Enter on a // selected cell. If entire rows selected, the column value is undefined. // Likewise for entire columns. selected func(row, column int) // An optional function which gets called when the user changes the selection. // If entire rows selected, the column value is undefined. // Likewise for entire columns. selectionChanged func(row, column int) // An optional function which gets called when the user presses Escape, Tab, // or Backtab. Also when the user presses Enter if nothing is selectable. done func(key tcell.Key) } // NewTable returns a new table. func NewTable() *Table { t := &Table{ Box: NewBox(), bordersColor: Styles.GraphicsColor, separator: ' ', } t.SetContent(nil) return t } // SetContent sets a new content type for this table. This allows you to back // the table by a data structure of your own, for example one that cannot be // fully held in memory. For details, see the TableContent interface // documentation. // // A value of nil will return the table to its default implementation where all // of its table cells are kept in memory. func (t *Table) SetContent(content TableContent) *Table { if content != nil { t.content = content } else { t.content = &tableDefaultContent{ lastColumn: -1, } } return t } // Clear removes all table data. func (t *Table) Clear() *Table { t.content.Clear() return t } // SetBorders sets whether or not each cell in the table is surrounded by a // border. func (t *Table) SetBorders(show bool) *Table { t.borders = show return t } // SetExpandSpace sets whether or not to arrange table items exactly as // they would be arranged when enabling table borders, with the only // difference that all table borders are not shown. func (t *Table) SetExpandSpace(space bool) *Table { t.SetBorders(true) t.expandSpace = true return t } // SetBordersColor sets the color of the cell borders. func (t *Table) SetBordersColor(color tcell.Color) *Table { t.bordersColor = color return t } // SetSelectedStyle sets a specific style for selected cells. If no such style // is set, per default, selected cells are inverted (i.e. their foreground and // background colors are swapped). // // To reset a previous setting to its default, make the following call: // // table.SetSelectedStyle(tcell.Style{}) func (t *Table) SetSelectedStyle(style tcell.Style) *Table { t.selectedStyle = style return t } // SetSeparator sets the character used to fill the space between two // neighboring cells. This is a space character ' ' per default but you may // want to set it to Borders.Vertical (or any other rune) if the column // separation should be more visible. If cell borders are activated, this is // ignored. // // Separators have the same color as borders. func (t *Table) SetSeparator(separator rune) *Table { t.separator = separator return t } // SetFixed sets the number of fixed rows and columns which are always visible // even when the rest of the cells are scrolled out of view. Rows are always the // top-most ones. Columns are always the left-most ones. func (t *Table) SetFixed(rows, columns int) *Table { t.fixedRows, t.fixedColumns = rows, columns return t } // SetSelectable sets the flags which determine what can be selected in a table. // There are three selection modi: // // - rows = false, columns = false: Nothing can be selected. // - rows = true, columns = false: Rows can be selected. // - rows = false, columns = true: Columns can be selected. // - rows = true, columns = true: Individual cells can be selected. func (t *Table) SetSelectable(rows, columns bool) *Table { t.rowsSelectable, t.columnsSelectable = rows, columns return t } // GetSelectable returns what can be selected in a table. Refer to // SetSelectable() for details. func (t *Table) GetSelectable() (rows, columns bool) { return t.rowsSelectable, t.columnsSelectable } // GetSelection returns the position of the current selection. // If entire rows are selected, the column index is undefined. // Likewise for entire columns. func (t *Table) GetSelection() (row, column int) { return t.selectedRow, t.selectedColumn } // Select sets the selected cell. Depending on the selection settings // specified via SetSelectable(), this may be an entire row or column, or even // ignored completely. The "selection changed" event is fired if such a callback // is available (even if the selection ends up being the same as before and even // if cells are not selectable). func (t *Table) Select(row, column int) *Table { t.selectedRow, t.selectedColumn = row, column t.clampToSelection = true if t.selectionChanged != nil { t.selectionChanged(row, column) } return t } // SetOffset sets how many rows and columns should be skipped when drawing the // table. This is useful for large tables that do not fit on the screen. // Navigating a selection can change these values. // // Fixed rows and columns are never skipped. func (t *Table) SetOffset(row, column int) *Table { t.rowOffset, t.columnOffset = row, column t.trackEnd = false return t } // GetOffset returns the current row and column offset. This indicates how many // rows and columns the table is scrolled down and to the right. func (t *Table) GetOffset() (row, column int) { return t.rowOffset, t.columnOffset } // SetEvaluateAllRows sets a flag which determines the rows to be evaluated when // calculating the widths of the table's columns. When false, only visible rows // are evaluated. When true, all rows in the table are evaluated. // // Set this flag to true to avoid shifting column widths when the table is // scrolled. (May come with a performance penalty for large tables.) // // Use with caution on very large tables, especially those not backed by the // default TableContent data structure. func (t *Table) SetEvaluateAllRows(all bool) *Table { t.evaluateAllRows = all return t } // SetSelectedFunc sets a handler which is called whenever the user presses the // Enter key on a selected cell/row/column. The handler receives the position of // the selection and its cell contents. If entire rows are selected, the column // index is undefined. Likewise for entire columns. func (t *Table) SetSelectedFunc(handler func(row, column int)) *Table { t.selected = handler return t } // SetSelectionChangedFunc sets a handler which is called whenever the current // selection changes. The handler receives the position of the new selection. // If entire rows are selected, the column index is undefined. Likewise for // entire columns. func (t *Table) SetSelectionChangedFunc(handler func(row, column int)) *Table { t.selectionChanged = handler return t } // SetDoneFunc sets a handler which is called whenever the user presses the // Escape, Tab, or Backtab key. If nothing is selected, it is also called when // user presses the Enter key (because pressing Enter on a selection triggers // the "selected" handler set via SetSelectedFunc()). func (t *Table) SetDoneFunc(handler func(key tcell.Key)) *Table { t.done = handler return t } // SetCell sets the content of a cell the specified position. It is ok to // directly instantiate a TableCell object. If the cell has content, at least // the Text and Color fields should be set. // // Note that setting cells in previously unknown rows and columns will // automatically extend the internal table representation with empty TableCell // objects, e.g. starting with a row of 100,000 will immediately create 100,000 // empty rows. // // To avoid unnecessary garbage collection, fill columns from left to right. func (t *Table) SetCell(row, column int, cell *TableCell) *Table { t.content.SetCell(row, column, cell) return t } // SetCellSimple calls SetCell() with the given text, left-aligned, in white. func (t *Table) SetCellSimple(row, column int, text string) *Table { t.SetCell(row, column, NewTableCell(text)) return t } // GetCell returns the contents of the cell at the specified position. A valid // TableCell object is always returned but it will be uninitialized if the cell // was not previously set. Such an uninitialized object will not automatically // be inserted. Therefore, repeated calls to this function may return different // pointers for uninitialized cells. func (t *Table) GetCell(row, column int) *TableCell { cell := t.content.GetCell(row, column) if cell == nil { cell = &TableCell{} } return cell } // RemoveRow removes the row at the given position from the table. If there is // no such row, this has no effect. func (t *Table) RemoveRow(row int) *Table { t.content.RemoveRow(row) return t } // RemoveColumn removes the column at the given position from the table. If // there is no such column, this has no effect. func (t *Table) RemoveColumn(column int) *Table { t.content.RemoveColumn(column) return t } // InsertRow inserts a row before the row with the given index. Cells on the // given row and below will be shifted to the bottom by one row. If "row" is // equal or larger than the current number of rows, this function has no effect. func (t *Table) InsertRow(row int) *Table { t.content.InsertRow(row) return t } // InsertColumn inserts a column before the column with the given index. Cells // in the given column and to its right will be shifted to the right by one // column. Rows that have fewer initialized cells than "column" will remain // unchanged. func (t *Table) InsertColumn(column int) *Table { t.content.InsertColumn(column) return t } // GetRowCount returns the number of rows in the table. func (t *Table) GetRowCount() int { return t.content.GetRowCount() } // GetColumnCount returns the (maximum) number of columns in the table. func (t *Table) GetColumnCount() int { return t.content.GetColumnCount() } // cellAt returns the row and column located at the given screen coordinates. // Each returned value may be negative if there is no row and/or cell. This // function will also process coordinates outside the table's inner rectangle so // callers will need to check for bounds themselves. func (t *Table) cellAt(x, y int) (row, column int) { rectX, rectY, _, _ := t.GetInnerRect() // Determine row as seen on screen. if t.borders { row = (y - rectY - 1) / 2 } else { row = y - rectY } // Respect fixed rows and row offset. if row >= 0 { if row >= t.fixedRows { row += t.rowOffset } if row >= t.content.GetRowCount() { row = -1 } } // Saerch for the clicked column. column = -1 if x >= rectX { columnX := rectX if t.borders { columnX++ } for index, width := range t.visibleColumnWidths { columnX += width + 1 if x < columnX { column = t.visibleColumnIndices[index] break } } } return } // ScrollToBeginning scrolls the table to the beginning to that the top left // corner of the table is shown. Note that this position may be corrected if // there is a selection. func (t *Table) ScrollToBeginning() *Table { t.trackEnd = false t.columnOffset = 0 t.rowOffset = 0 return t } // ScrollToEnd scrolls the table to the beginning to that the bottom left corner // of the table is shown. Adding more rows to the table will cause it to // automatically scroll with the new data. Note that this position may be // corrected if there is a selection. func (t *Table) ScrollToEnd() *Table { t.trackEnd = true t.columnOffset = 0 t.rowOffset = t.content.GetRowCount() return t } // SetWrapSelection determines whether a selection wraps vertically or // horizontally when moved. Vertically wrapping selections will jump from the // last selectable row to the first selectable row and vice versa. Horizontally // wrapping selections will jump from the last selectable column to the first // selectable column (on the next selectable row) or from the first selectable // column to the last selectable column (on the previous selectable row). If set // to false, the selection is not moved when it is already on the first/last // selectable row/column. // // The default is for both values to be false. func (t *Table) SetWrapSelection(vertical, horizontal bool) *Table { t.wrapHorizontally = horizontal t.wrapVertically = vertical return t } // SetSelectorWrap will ensure that the selector does not extend across the entire // column width, instead it will wrap around the length of the text in the currently // selected TableCell. // // The default value is false. func (t *Table) SetSelectorWrap(wrap bool) *Table { t.selectorWrap = wrap return t } // Draw draws this primitive onto the screen. func (t *Table) Draw(screen tcell.Screen) { t.Box.DrawForSubclass(screen, t) // What's our available screen space? _, totalHeight := screen.Size() x, y, width, height := t.GetInnerRect() netWidth := width if t.borders { t.visibleRows = height / 2 netWidth -= 2 } else { t.visibleRows = height } // If this cell is not selectable, find the next one. rowCount, columnCount := t.content.GetRowCount(), t.content.GetColumnCount() if t.rowsSelectable || t.columnsSelectable { if t.selectedColumn < 0 { t.selectedColumn = 0 } if t.selectedRow < 0 { t.selectedRow = 0 } for t.selectedRow < rowCount { cell := t.content.GetCell(t.selectedRow, t.selectedColumn) if cell != nil && !cell.NotSelectable { break } t.selectedColumn++ if t.selectedColumn > columnCount-1 { t.selectedColumn = 0 t.selectedRow++ } } } // Clamp row offsets if requested. defer func() { t.clampToSelection = false // Only once. }() if t.clampToSelection && t.rowsSelectable { if t.selectedRow >= t.fixedRows && t.selectedRow < t.fixedRows+t.rowOffset { t.rowOffset = t.selectedRow - t.fixedRows t.trackEnd = false } if t.borders { if t.selectedRow+1-t.rowOffset >= height/2 { t.rowOffset = t.selectedRow + 1 - height/2 t.trackEnd = false } } else { if t.selectedRow+1-t.rowOffset >= height { t.rowOffset = t.selectedRow + 1 - height t.trackEnd = false } } } if t.rowOffset < 0 { t.rowOffset = 0 } if t.borders { if rowCount-t.rowOffset < height/2 { t.trackEnd = true } } else { if rowCount-t.rowOffset < height { t.trackEnd = true } } if t.trackEnd { if t.borders { t.rowOffset = rowCount - height/2 } else { t.rowOffset = rowCount - height } } if t.rowOffset < 0 { t.rowOffset = 0 } // Avoid invalid column offsets. if t.columnOffset >= columnCount-t.fixedColumns { t.columnOffset = columnCount - t.fixedColumns - 1 } if t.columnOffset < 0 { t.columnOffset = 0 } // Determine the indices of the rows which fit on the screen. var ( rows, allRows []int tableHeight int ) rowStep := 1 if t.borders { rowStep = 2 // With borders, every table row takes two screen rows. } if t.evaluateAllRows { allRows = make([]int, rowCount) for row := 0; row < rowCount; row++ { allRows[row] = row } } indexRow := func(row int) bool { // Determine if this row is visible, store its index. if tableHeight >= height { return false } rows = append(rows, row) tableHeight += rowStep return true } for row := 0; row < t.fixedRows && row < rowCount; row++ { // Do the fixed rows first. if !indexRow(row) { break } } for row := t.fixedRows + t.rowOffset; row < rowCount; row++ { // Then the remaining rows. if !indexRow(row) { break } } // Determine the columns' indices, widths, and expansion values that fit on // the screen. var ( tableWidth, expansionTotal int columns, widths, expansions []int ) includesSelection := !t.clampToSelection || !t.columnsSelectable // Helper function that evaluates one column. Returns true if the column // didn't fit at all. indexColumn := func(column int) bool { if netWidth == 0 || tableWidth >= netWidth { return true } var maxWidth, expansion int evaluationRows := rows if t.evaluateAllRows { evaluationRows = allRows } for _, row := range evaluationRows { if cell := t.content.GetCell(row, column); cell != nil { cellWidth := TaggedStringWidth(cell.Text) if cell.MaxWidth > 0 && cell.MaxWidth < cellWidth { cellWidth = cell.MaxWidth } if cellWidth > maxWidth { maxWidth = cellWidth } if cell.Expansion > expansion { expansion = cell.Expansion } } } clampedMaxWidth := maxWidth if tableWidth+maxWidth > netWidth { clampedMaxWidth = netWidth - tableWidth } columns = append(columns, column) widths = append(widths, clampedMaxWidth) expansions = append(expansions, expansion) tableWidth += clampedMaxWidth + 1 expansionTotal += expansion if t.columnsSelectable && t.clampToSelection && column == t.selectedColumn { // We want selections to appear fully. includesSelection = clampedMaxWidth == maxWidth } return false } // Helper function that evaluates multiple columns, starting at "start" and // at most ending at "maxEnd". Returns first column not included anymore (or // -1 if all are included). indexColumns := func(start, maxEnd int) int { if start == maxEnd { return -1 } if start < maxEnd { // Forward-evaluate columns. for column := start; column < maxEnd; column++ { if indexColumn(column) { return column } } return -1 } // Backward-evaluate columns. startLen := len(columns) defer func() { // Because we went backwards, we must reverse the partial slices. for i, j := startLen, len(columns)-1; i < j; i, j = i+1, j-1 { columns[i], columns[j] = columns[j], columns[i] widths[i], widths[j] = widths[j], widths[i] expansions[i], expansions[j] = expansions[j], expansions[i] } }() for column := start; column >= maxEnd; column-- { if indexColumn(column) { return column } } return -1 } // Reset the table to only its fixed columns. var fixedTableWidth, fixedExpansionTotal int resetColumns := func() { tableWidth = fixedTableWidth expansionTotal = fixedExpansionTotal columns = columns[:t.fixedColumns] widths = widths[:t.fixedColumns] expansions = expansions[:t.fixedColumns] } // Add fixed columns. if indexColumns(0, t.fixedColumns) < 0 { fixedTableWidth = tableWidth fixedExpansionTotal = expansionTotal // Add unclamped columns. if column := indexColumns(t.fixedColumns+t.columnOffset, columnCount); !includesSelection || column < 0 && t.columnOffset > 0 { // Offset is not optimal. Try again. if !includesSelection { // Clamp to selection. resetColumns() if t.selectedColumn <= t.fixedColumns+t.columnOffset { // It's on the left. Start with the selection. t.columnOffset = t.selectedColumn - t.fixedColumns indexColumns(t.fixedColumns+t.columnOffset, columnCount) } else { // It's on the right. End with the selection. if column := indexColumns(t.selectedColumn, t.fixedColumns); column >= 0 { t.columnOffset = column + 1 - t.fixedColumns } else { t.columnOffset = 0 } } } else if tableWidth < netWidth { // Don't waste space. Try to fit as much on screen as possible. resetColumns() if column := indexColumns(columnCount-1, t.fixedColumns); column >= 0 { t.columnOffset = column + 1 - t.fixedColumns } else { t.columnOffset = 0 } } } } // If we have space left, distribute it. if tableWidth < netWidth { toDistribute := netWidth - tableWidth for index, expansion := range expansions { if expansionTotal <= 0 { break } expWidth := toDistribute * expansion / expansionTotal widths[index] += expWidth toDistribute -= expWidth expansionTotal -= expansion } } // Helper function which draws border runes. borderStyle := tcell.StyleDefault.Background(t.backgroundColor).Foreground(t.bordersColor) drawBorder := func(colX, rowY int, ch rune) { if t.expandSpace { ch = ' ' } screen.SetContent(x+colX, y+rowY, ch, nil, borderStyle) } // Draw the cells (and borders). var columnX int if t.borders { columnX++ } for columnIndex, column := range columns { columnWidth := widths[columnIndex] for rowY, row := range rows { if t.borders { // Draw borders. rowY *= 2 for pos := 0; pos < columnWidth && columnX+pos < width; pos++ { drawBorder(columnX+pos, rowY, Borders.Horizontal) } ch := Borders.Cross if row == 0 { if column == 0 { ch = Borders.TopLeft } else { ch = Borders.TopT } } else if column == 0 { ch = Borders.LeftT } drawBorder(columnX-1, rowY, ch) rowY++ if rowY >= height || y+rowY >= totalHeight { break // No space for the text anymore. } drawBorder(columnX-1, rowY, Borders.Vertical) } else if columnIndex < len(columns)-1 { // Draw separator. drawBorder(columnX+columnWidth, rowY, t.separator) } // Get the cell. cell := t.content.GetCell(row, column) if cell == nil { continue } // Draw text. finalWidth := columnWidth if columnX+columnWidth >= width { finalWidth = width - columnX } cell.x, cell.y, cell.width = x+columnX, y+rowY, finalWidth start, end, _ := printWithStyle(screen, cell.Text, x+columnX, y+rowY, 0, finalWidth, cell.Align, tcell.StyleDefault.Foreground(cell.Color).Attributes(cell.Attributes), true) printed := end - start if TaggedStringWidth(cell.Text)-printed > 0 && printed > 0 { _, _, style, _ := screen.GetContent(x+columnX+finalWidth-1, y+rowY) printWithStyle(screen, string(SemigraphicsHorizontalEllipsis), x+columnX+finalWidth-1, y+rowY, 0, 1, AlignLeft, style, false) } } // Draw bottom border. if rowY := 2 * len(rows); t.borders && rowY > 0 && rowY < height { for pos := 0; pos < columnWidth && columnX+1+pos < width; pos++ { drawBorder(columnX+pos, rowY, Borders.Horizontal) } ch := Borders.Cross if rows[len(rows)-1] == rowCount-1 { if column == 0 { ch = Borders.BottomLeft } else { ch = Borders.BottomT } } else if column == 0 { ch = Borders.BottomLeft } drawBorder(columnX-1, rowY, ch) } columnX += columnWidth + 1 } // Draw right border. columnX-- if t.borders && len(rows) > 0 && len(columns) > 0 && columnX < width { lastColumn := columns[len(columns)-1] == columnCount-1 for rowY := range rows { rowY *= 2 if rowY+1 < height { drawBorder(columnX, rowY+1, Borders.Vertical) } ch := Borders.Cross if rowY == 0 { if lastColumn { ch = Borders.TopRight } else { ch = Borders.TopT } } else if lastColumn { ch = Borders.RightT } drawBorder(columnX, rowY, ch) } if rowY := 2 * len(rows); rowY < height { ch := Borders.BottomT if lastColumn { ch = Borders.BottomRight } drawBorder(columnX, rowY, ch) } } // Helper function which colors the background of a box. // backgroundTransparent == true => Don't modify background color (when invert == false). // textTransparent == true => Don't modify text color (when invert == false). // attr == 0 => Don't change attributes. // invert == true => Ignore attr, set text to backgroundColor or t.backgroundColor; // set background to textColor. colorBackground := func(fromX, fromY, w, h int, backgroundColor, textColor tcell.Color, backgroundTransparent, textTransparent bool, attr tcell.AttrMask, invert bool) { for by := 0; by < h && fromY+by < y+height; by++ { for bx := 0; bx < w && fromX+bx < x+width; bx++ { m, c, style, _ := screen.GetContent(fromX+bx, fromY+by) fg, bg, a := style.Decompose() if invert { style = style.Background(textColor).Foreground(backgroundColor) } else { if !backgroundTransparent { bg = backgroundColor } if !textTransparent { fg = textColor } if attr != 0 { a = attr } style = style.Background(bg).Foreground(fg).Attributes(a) } screen.SetContent(fromX+bx, fromY+by, m, c, style) } } } // Color the cell backgrounds. To avoid undesirable artefacts, we combine // the drawing of a cell by background color, selected cells last. type cellInfo struct { x, y, w, h int cell *TableCell selected bool } cellsByBackgroundColor := make(map[tcell.Color][]*cellInfo) var backgroundColors []tcell.Color for rowY, row := range rows { columnX := 0 rowSelected := t.rowsSelectable && !t.columnsSelectable && row == t.selectedRow for columnIndex, column := range columns { columnWidth := widths[columnIndex] cell := t.content.GetCell(row, column) if cell == nil { continue } bx, by, bw, bh := x+columnX, y+rowY, columnWidth+1, 1 if t.selectorWrap { textlen := TaggedStringWidth(cell.Text) if columnWidth+1 >= textlen { if cell.Align == AlignRight { bx += (columnWidth - textlen) } else if cell.Align == AlignCenter { bx += ((columnWidth - textlen) / 2) + 1 } else if cell.Align == AlignLeft && t.borders { bx += 2 } bw = textlen } else if columnWidth+1 < textlen { bw = columnWidth + 1 } } if t.borders { by = y + rowY*2 if !t.selectorWrap { bw++ } bh = 3 } columnSelected := t.columnsSelectable && !t.rowsSelectable && column == t.selectedColumn cellSelected := !cell.NotSelectable && (columnSelected || rowSelected || t.rowsSelectable && t.columnsSelectable && column == t.selectedColumn && row == t.selectedRow) entries, ok := cellsByBackgroundColor[cell.BackgroundColor] cellsByBackgroundColor[cell.BackgroundColor] = append(entries, &cellInfo{ x: bx, y: by, w: bw, h: bh, cell: cell, selected: cellSelected, }) if !ok { backgroundColors = append(backgroundColors, cell.BackgroundColor) } columnX += columnWidth + 1 } } sort.Slice(backgroundColors, func(i int, j int) bool { // Draw brightest colors last (i.e. on top). r, g, b := backgroundColors[i].RGB() c := colorful.Color{R: float64(r) / 255, G: float64(g) / 255, B: float64(b) / 255} _, _, li := c.Hcl() r, g, b = backgroundColors[j].RGB() c = colorful.Color{R: float64(r) / 255, G: float64(g) / 255, B: float64(b) / 255} _, _, lj := c.Hcl() return li < lj }) selFg, selBg, selAttr := t.selectedStyle.Decompose() for _, bgColor := range backgroundColors { entries := cellsByBackgroundColor[bgColor] for _, info := range entries { if info.selected { if info.cell.selectedStyle != (tcell.Style{}) { infoBg, infoFg, infoAttr := info.cell.selectedStyle.Decompose() defer colorBackground(info.x, info.y, info.w, info.h, infoBg, infoFg, false, false, infoAttr, false) } else if t.selectedStyle != (tcell.Style{}) { defer colorBackground(info.x, info.y, info.w, info.h, selBg, selFg, false, false, selAttr, false) } else { defer colorBackground(info.x, info.y, info.w, info.h, bgColor, info.cell.Color, false, false, 0, true) } } else { colorBackground(info.x, info.y, info.w, info.h, bgColor, info.cell.Color, info.cell.Transparent, true, 0, false) } } } // Remember column infos. t.visibleColumnIndices, t.visibleColumnWidths = columns, widths } // InputHandler returns the handler for this primitive. func (t *Table) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) { return t.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) { key := event.Key() if (!t.rowsSelectable && !t.columnsSelectable && key == tcell.KeyEnter) || key == tcell.KeyEscape || key == tcell.KeyTab || key == tcell.KeyBacktab { if t.done != nil { t.done(key) } return } // Movement functions. previouslySelectedRow, previouslySelectedColumn := t.selectedRow, t.selectedColumn lastColumn := t.content.GetColumnCount() - 1 rowCount := t.content.GetRowCount() if rowCount == 0 { return // No movement on empty tables. } var ( // Move the selection forward, don't go beyond final cell, return // true if a selection was found. forward = func(finalRow, finalColumn int) bool { row, column := t.selectedRow, t.selectedColumn for { // Stop if the current selection is fine. cell := t.content.GetCell(row, column) if cell != nil && !cell.NotSelectable { t.selectedRow, t.selectedColumn = row, column return true } // If we reached the final cell, stop. if row == finalRow && column == finalColumn { return false } // Move forward. column++ if column > lastColumn { column = 0 row++ if row >= rowCount { row = 0 } } } } // Move the selection backwards, don't go beyond final cell, return // true if a selection was found. backwards = func(finalRow, finalColumn int) bool { row, column := t.selectedRow, t.selectedColumn for { // Stop if the current selection is fine. cell := t.content.GetCell(row, column) if cell != nil && !cell.NotSelectable { t.selectedRow, t.selectedColumn = row, column return true } // If we reached the final cell, stop. if row == finalRow && column == finalColumn { return false } // Move backwards. column-- if column < 0 { column = lastColumn row-- if row < 0 { row = rowCount - 1 } } } } home = func() { if t.rowsSelectable { t.selectedRow = 0 t.selectedColumn = 0 forward(rowCount-1, lastColumn) t.clampToSelection = true } else { t.trackEnd = false t.rowOffset = 0 t.columnOffset = 0 } } end = func() { if t.rowsSelectable { t.selectedRow = rowCount - 1 t.selectedColumn = lastColumn backwards(0, 0) t.clampToSelection = true } else { t.trackEnd = true t.columnOffset = 0 } } down = func() { if t.rowsSelectable { t.selectedRow++ if t.selectedRow >= rowCount { if t.wrapVertically { t.selectedRow = 0 } else { t.selectedRow = rowCount - 1 } } row, column := t.selectedRow, t.selectedColumn finalRow, finalColumn := rowCount-1, lastColumn if t.wrapVertically { finalRow = row finalColumn = column } if !forward(finalRow, finalColumn) { backwards(row, column) } t.clampToSelection = true } else { t.rowOffset++ } } up = func() { if t.rowsSelectable { t.selectedRow-- if t.selectedRow < 0 { if t.wrapVertically { t.selectedRow = rowCount - 1 } else { t.selectedRow = 0 } } row, column := t.selectedRow, t.selectedColumn finalRow, finalColumn := 0, 0 if t.wrapVertically { finalRow = row finalColumn = column } if !backwards(finalRow, finalColumn) { forward(row, column) } t.clampToSelection = true } else { t.trackEnd = false t.rowOffset-- } } left = func() { if t.columnsSelectable { row, column := t.selectedRow, t.selectedColumn t.selectedColumn-- if t.selectedColumn < 0 { if t.wrapHorizontally { t.selectedColumn = lastColumn t.selectedRow-- if t.selectedRow < 0 { if t.wrapVertically { t.selectedRow = rowCount - 1 } else { t.selectedColumn = 0 t.selectedRow = 0 } } } else { t.selectedColumn = 0 } } finalRow, finalColumn := row, column if !t.wrapHorizontally { finalColumn = 0 } else if !t.wrapVertically { finalRow = 0 finalColumn = 0 } if !backwards(finalRow, finalColumn) { forward(row, column) } t.clampToSelection = true } else { t.columnOffset-- } } right = func() { if t.columnsSelectable { row, column := t.selectedRow, t.selectedColumn t.selectedColumn++ if t.selectedColumn > lastColumn { if t.wrapHorizontally { t.selectedColumn = 0 t.selectedRow++ if t.selectedRow >= rowCount { if t.wrapVertically { t.selectedRow = 0 } else { t.selectedColumn = lastColumn t.selectedRow = rowCount - 1 } } } else { t.selectedColumn = lastColumn } } finalRow, finalColumn := row, column if !t.wrapHorizontally { finalColumn = lastColumn } else if !t.wrapVertically { finalRow = rowCount - 1 finalColumn = lastColumn } if !forward(finalRow, finalColumn) { backwards(row, column) } t.clampToSelection = true } else { t.columnOffset++ } } pageDown = func() { offsetAmount := t.visibleRows - t.fixedRows if offsetAmount < 0 { offsetAmount = 0 } if t.rowsSelectable { row, column := t.selectedRow, t.selectedColumn t.selectedRow += offsetAmount if t.selectedRow >= rowCount { t.selectedRow = rowCount - 1 } finalRow, finalColumn := rowCount-1, lastColumn if !forward(finalRow, finalColumn) { backwards(row, column) } t.clampToSelection = true } else { t.rowOffset += offsetAmount } } pageUp = func() { offsetAmount := t.visibleRows - t.fixedRows if offsetAmount < 0 { offsetAmount = 0 } if t.rowsSelectable { row, column := t.selectedRow, t.selectedColumn t.selectedRow -= offsetAmount if t.selectedRow < 0 { t.selectedRow = 0 } finalRow, finalColumn := 0, 0 if !backwards(finalRow, finalColumn) { forward(row, column) } t.clampToSelection = true } else { t.trackEnd = false t.rowOffset -= offsetAmount } } ) switch key { case tcell.KeyRune: switch event.Rune() { case 'g': home() case 'G': end() case 'j': down() case 'k': up() case 'h': left() case 'l': right() } case tcell.KeyHome: home() case tcell.KeyEnd: end() case tcell.KeyUp: up() case tcell.KeyDown: down() case tcell.KeyLeft: left() case tcell.KeyRight: right() case tcell.KeyPgDn, tcell.KeyCtrlF: pageDown() case tcell.KeyPgUp, tcell.KeyCtrlB: pageUp() case tcell.KeyEnter: if (t.rowsSelectable || t.columnsSelectable) && t.selected != nil { t.selected(t.selectedRow, t.selectedColumn) } } // If the selection has changed, notify the handler. if t.selectionChanged != nil && (t.rowsSelectable && previouslySelectedRow != t.selectedRow || t.columnsSelectable && previouslySelectedColumn != t.selectedColumn) { t.selectionChanged(t.selectedRow, t.selectedColumn) } }) } // MouseHandler returns the mouse handler for this primitive. func (t *Table) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return t.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { x, y := event.Position() if !t.InRect(x, y) { return false, nil } switch action { case MouseLeftDown: setFocus(t) consumed = true case MouseLeftClick: selectEvent := true row, column := t.cellAt(x, y) cell := t.content.GetCell(row, column) if cell != nil { if cell.Clicked != nil { if noSelect := cell.Clicked(); noSelect { selectEvent = false } } if cell.OnClicked != nil { cell.OnClicked(t, row, column) } } if selectEvent && (t.rowsSelectable || t.columnsSelectable) { t.Select(row, column) } consumed = true case MouseScrollUp: t.trackEnd = false t.rowOffset-- row, _ := t.GetSelection() if row-1 >= 0 && row-1 < t.GetRowCount() { t.Select(row-1, 0) } consumed = true case MouseScrollDown: t.rowOffset++ row, _ := t.GetSelection() if row+1 >= 0 && row+1 < t.GetRowCount() { t.Select(row+1, 0) } consumed = true } return }) } golang-github-darkhz-tview-0.0~git20240308.6078a88/textarea.go000066400000000000000000002335161457770046000233560ustar00rootroot00000000000000package tview import ( "strings" "unicode" "unicode/utf8" "github.com/gdamore/tcell/v2" "github.com/rivo/uniseg" ) const ( // The minimum capacity of the text area's piece chain slice. pieceChainMinCap = 10 // The minimum capacity of the text area's edit buffer. editBufferMinCap = 200 // The maximum number of bytes making up a grapheme cluster. In theory, this // could be longer but it would be highly unusual. maxGraphemeClusterSize = 40 // The default value for the [TextArea.minCursorPrefix] variable. minCursorPrefixDefault = 5 // The default value for the [TextArea.minCursorSuffix] variable. minCursorSuffixDefault = 3 ) // Types of user actions on a text area. type taAction int const ( taActionOther taAction = iota taActionTypeSpace // Typing a space character. taActionTypeNonSpace // Typing a non-space character. taActionBackspace // Deleting the previous character. taActionDelete // Deleting the next character. ) // NewLine is the string sequence to be inserted when hitting the Enter key in a // TextArea. The default is "\n" but you may change it to "\r\n" if required. var NewLine = "\n" // textAreaSpan represents a range of text in a text area. The text area widget // roughly follows the concept of Piece Chains outlined in // http://www.catch22.net/tuts/neatpad/piece-chains with some modifications. // This type represents a "span" (or "piece") and thus refers to a subset of the // text in the editor as part of a doubly-linked list. // // In most places where we reference a position in the text, we use a // three-element int array. The first element is the index of the referenced // span in the piece chain. The second element is the offset into the span's // referenced text (relative to the span's start), its value is always >= 0 and // < span.length. The third element is the state of the text parser at that // position. // // A range of text is represented by a span range which is a starting position // (3-int array) and an ending position (3-int array). The starting position // references the first character of the range, the ending position references // the position after the last character of the range. The end of the text is // therefore always [3]int{1, 0, 0}, position 0 of the ending sentinel. // // Sentinel spans are dummy spans not referring to any text. There are always // two sentinel spans: the starting span at index 0 of the [TextArea.spans] // slice and the ending span at index 1. type textAreaSpan struct { // Links to the previous and next textAreaSpan objects as indices into the // [TextArea.spans] slice. The sentinel spans (index 0 and 1) have -1 as // their previous or next links, respectively. previous, next int // The start index and the length of the text segment this span represents. // If "length" is negative, the span represents a substring of // [TextArea.initialText] and the actual length is its absolute value. If it // is positive, the span represents a substring of [TextArea.editText]. For // the sentinel spans (index 0 and 1), both values will be 0. Others will // never have a zero length. offset, length int } // textAreaUndoItem represents an undoable edit to the text area. It describes // the two spans wrapping a text change. type textAreaUndoItem struct { before, after int // The index of the copied "before" and "after" spans into the "spans" slice. originalBefore, originalAfter int // The original indices of the "before" and "after" spans. pos [3]int // The cursor position to be assumed after applying an undo. length int // The total text length at the time the undo item was created. continuation bool // If true, this item is a continuation of the previous undo item. It is handled together with all other undo items in the same continuation sequence. } // TextArea implements a simple text editor for multi-line text. Multi-color // text is not supported. Word-wrapping is enabled by default but can be turned // off or be changed to character-wrapping. // // At this point, a text area cannot be added to a [Form]. This will be added in // the future. // // # Navigation and Editing // // A text area is always in editing mode and no other mode exists. The following // keys can be used to move the cursor (subject to what the user's terminal // supports and how it is configured): // // - Left arrow: Move left. // - Right arrow: Move right. // - Down arrow: Move down. // - Up arrow: Move up. // - Ctrl-A, Home: Move to the beginning of the current line. // - Ctrl-E, End: Move to the end of the current line. // - Ctrl-F, page down: Move down by one page. // - Ctrl-B, page up: Move up by one page. // - Alt-Up arrow: Scroll the page up, leaving the cursor in its position. // - Alt-Down arrow: Scroll the page down, leaving the cursor in its position. // - Alt-Left arrow: Scroll the page to the left, leaving the cursor in its // position. Ignored if wrapping is enabled. // - Alt-Right arrow: Scroll the page to the right, leaving the cursor in its // position. Ignored if wrapping is enabled. // - Alt-B, Ctrl-Left arrow: Jump to the beginning of the current or previous // word. // - Alt-F, Ctrl-Right arrow: Jump to the end of the current or next word. // // Words are defined according to [Unicode Standard Annex #29]. We skip any // words that contain only spaces or punctuation. // // Entering a character will insert it at the current cursor location. // Subsequent characters are shifted accordingly. If the cursor is outside the // visible area, any changes to the text will move it into the visible area. The // following keys can also be used to modify the text: // // - Enter: Insert a newline character (see [NewLine]). // - Tab: Insert a tab character (\t). It will be rendered like [TabSize] // spaces. (This may eventually be changed to behave like regular tabs.) // - Ctrl-H, Backspace: Delete one character to the left of the cursor. // - Ctrl-D, Delete: Delete the character under the cursor (or the first // character on the next line if the cursor is at the end of a line). // - Alt-Backspace: Delete the word to the left of the cursor. // - Ctrl-K: Delete everything under and to the right of the cursor until the // next newline character. // - Ctrl-W: Delete from the start of the current word to the left of the // cursor. // - Ctrl-U: Delete the current line, i.e. everything after the last newline // character before the cursor up until the next newline character. This may // span multiple visible rows if wrapping is enabled. // // Text can be selected by moving the cursor while holding the Shift key, to the // extent that this is supported by the user's terminal. The Ctrl-L key can be // used to select the entire text. (Ctrl-A already binds to the "Home" key.) // // When text is selected: // // - Entering a character will replace the selected text with the new // character. // - Backspace, delete, Ctrl-H, Ctrl-D: Delete the selected text. // - Ctrl-Q: Copy the selected text into the clipboard, unselect the text. // - Ctrl-X: Copy the selected text into the clipboard and delete it. // - Ctrl-V: Replace the selected text with the clipboard text. If no text is // selected, the clipboard text will be inserted at the cursor location. // // The Ctrl-Q key was chosen for the "copy" function because the Ctrl-C key is // the default key to stop the application. If your application frees up the // global Ctrl-C key and you want to bind it to the "copy to clipboard" // function, you may use [Box.SetInputCapture] to override the Ctrl-Q key to // implement copying to the clipboard. Note that using your terminal's / // operating system's key bindings for copy+paste functionality may not have the // expected effect as tview will not be able to handle these keys. Pasting text // using your operating system's or terminal's own methods may be very slow as // each character will be pasted individually. However, some terminals support // pasting text blocks which is supported by the text area, see // [Application.EnablePaste] for details. // // The default clipboard is an internal text buffer local to this text area // instance, i.e. the operating system's clipboard is not used. If you want to // implement your own clipboard (or make use of your operating system's // clipboard), you can use [TextArea.SetClipboard] which provides all the // functionality needed to implement your own clipboard. // // The text area also supports Undo: // // - Ctrl-Z: Undo the last change. // - Ctrl-Y: Redo the last Undo change. // // Undo does not affect the clipboard. // // If the mouse is enabled, the following actions are available: // // - Left click: Move the cursor to the clicked position or to the end of the // line if past the last character. // - Left double-click: Select the word under the cursor. // - Left click while holding the Shift key: Select text. // - Scroll wheel: Scroll the text. // // [Unicode Standard Annex #29]: https://unicode.org/reports/tr29/ type TextArea struct { *Box // Whether or not this text area is disabled/read-only. disabled bool // The size of the text area. If set to 0, the text area will use the entire // available space. width, height int // The text to be shown in the text area when it is empty. placeholder string // The label text shown, usually when part of a form. label string // The width of the text area's label. labelWidth int // Styles: // The label style. labelStyle tcell.Style // The style of the text. Background colors different from the Box's // background color may lead to unwanted artefacts. textStyle tcell.Style // The style of the selected text. selectedStyle tcell.Style // The style of the placeholder text. placeholderStyle tcell.Style // Text manipulation related fields: // The text area's text prior to any editing. It is referenced by spans with // a negative length. initialText string // Any text that's been added by the user at some point. We only ever append // to this buffer. It is referenced by spans with a positive length. editText strings.Builder // The total length of all text in the text area. length int // The maximum number of bytes allowed in the text area. If 0, there is no // limit. maxLength int // The piece chain. The first two spans are sentinel spans which don't // reference anything and always remain in the same place. Spans are never // deleted from this slice. spans []textAreaSpan // An optional function which transforms grapheme clusters. This can be used // to hide characters from the screen while preserving the original text. transform func(cluster, rest string, boundaries int) (newCluster string, newBoundaries int) // Display, navigation, and cursor related fields: // If set to true, lines that are longer than the available width are // wrapped onto the next line. If set to false, any characters beyond the // available width are discarded. wrap bool // If set to true and if wrap is also true, lines are split at spaces or // after punctuation characters. wordWrap bool // The index of the first line shown in the text area. rowOffset int // The number of cells to be skipped on each line (not used in wrap mode). columnOffset int // The inner height and width of the text area the last time it was drawn. lastHeight, lastWidth int // The width of the currently known widest line, as determined by // [TextArea.extendLines]. widestLine int // Text positions and states of the start of lines. Each element is a span // position (see [textAreaSpan]). Not all lines of the text may be contained // at any time, extend as needed with the [TextArea.extendLines] function. lineStarts [][3]int // The cursor always points to the next position where a new character would // be placed. The selection start is the same as the cursor as long as there // is no selection. When there is one, the selection is between // selectionStart and cursor. cursor, selectionStart struct { // The row and column in screen space but relative to the start of the // text which may be outside the text area's box. The column value may // be larger than where the cursor actually is if the line the cursor // is on is shorter. The actualColumn is the position as it is seen on // screen. These three values may not be determined yet, in which case // the row is negative. row, column, actualColumn int // The textAreaSpan position with state for the actual next character. pos [3]int } // The minimum width of text (if available) to be shown left of the cursor. minCursorPrefix int // The minimum width of text (if available) to be shown right of the cursor. minCursorSuffix int // Set to true when the mouse is dragging to select text. dragging bool // Clipboard related fields: // The internal clipboard. clipboard string // The function to call when the user copies/cuts a text selection to the // clipboard. copyToClipboard func(string) // The function to call when the user pastes text from the clipboard. pasteFromClipboard func() string // Undo/redo related fields: // The last action performed by the user. lastAction taAction // The undo stack's items. Each item is a copy of the span before the // modified span range and a copy of the span after the modified span range. // To undo an action, the two referenced spans are put back into their // original place. Undos and redos decrease or increase the nextUndo value. // Thus, the next undo action is not always the last item. undoStack []textAreaUndoItem // The current undo/redo position on the undo stack. If no undo or redo has // been performed yet, this is the same as len(undoStack). nextUndo int // Event handlers: // An optional function which is called when the input has changed. changed func() // An optional function which is called when the position of the cursor or // the selection has changed. moved func() // A callback function set by the Form class and called when the user leaves // this form item. finished func(tcell.Key) } // NewTextArea returns a new text area. Use [TextArea.SetText] to set the // initial text. func NewTextArea() *TextArea { t := &TextArea{ Box: NewBox(), wrap: true, wordWrap: true, placeholderStyle: tcell.StyleDefault.Background(Styles.PrimitiveBackgroundColor).Foreground(Styles.TertiaryTextColor), labelStyle: tcell.StyleDefault.Foreground(Styles.SecondaryTextColor), textStyle: tcell.StyleDefault.Background(Styles.PrimitiveBackgroundColor).Foreground(Styles.PrimaryTextColor), selectedStyle: tcell.StyleDefault.Background(Styles.PrimaryTextColor).Foreground(Styles.PrimitiveBackgroundColor), spans: make([]textAreaSpan, 2, pieceChainMinCap), // We reserve some space to avoid reallocations right when editing starts. lastAction: taActionOther, minCursorPrefix: minCursorPrefixDefault, minCursorSuffix: minCursorSuffixDefault, } t.editText.Grow(editBufferMinCap) t.spans[0] = textAreaSpan{previous: -1, next: 1} t.spans[1] = textAreaSpan{previous: 0, next: -1} t.cursor.pos = [3]int{1, 0, -1} t.selectionStart = t.cursor t.SetClipboard(nil, nil) return t } // SetText sets the text of the text area. All existing text is deleted and // replaced with the new text. Any edits are discarded, no undos are available. // This function is typically only used to initialize the text area with a text // after it has been created. To clear the text area's text (again, no undos), // provide an empty string. // // If cursorAtTheEnd is false, the cursor is placed at the start of the text. If // it is true, it is placed at the end of the text. For very long texts, placing // the cursor at the end can be an expensive operation because the entire text // needs to be parsed and laid out. // // If you want to set text and preserve undo functionality, use // [TextArea.Replace] instead. func (t *TextArea) SetText(text string, cursorAtTheEnd bool) *TextArea { t.spans = t.spans[:2] t.initialText = text t.editText.Reset() t.lineStarts = nil t.length = len(text) t.rowOffset = 0 t.columnOffset = 0 t.reset() t.cursor.row, t.cursor.actualColumn, t.cursor.column = 0, 0, 0 t.cursor.pos = [3]int{1, 0, -1} t.undoStack = t.undoStack[:0] t.nextUndo = 0 if len(text) > 0 { t.spans = append(t.spans, textAreaSpan{ previous: 0, next: 1, offset: 0, length: -len(text), }) t.spans[0].next = 2 t.spans[1].previous = 2 if cursorAtTheEnd { t.cursor.row = -1 if t.lastWidth > 0 { t.findCursor(true, 0) } } else { t.cursor.pos = [3]int{2, 0, -1} } } else { t.spans[0].next = 1 t.spans[1].previous = 0 } t.selectionStart = t.cursor if t.changed != nil { t.changed() } if t.lastWidth > 0 && t.moved != nil { t.moved() } return t } // GetText returns the entire text of the text area. Note that this will newly // allocate the entire text. func (t *TextArea) GetText() string { if t.length == 0 { return "" } var text strings.Builder text.Grow(t.length) spanIndex := t.spans[0].next for spanIndex != 1 { span := &t.spans[spanIndex] if span.length < 0 { text.WriteString(t.initialText[span.offset : span.offset-span.length]) } else { text.WriteString(t.editText.String()[span.offset : span.offset+span.length]) } spanIndex = t.spans[spanIndex].next } return text.String() } // getTextBeforeCursor returns the text of the text area up until the cursor. // Note that this will result in a new allocation for the returned text. func (t *TextArea) getTextBeforeCursor() string { if t.length == 0 || t.cursor.pos[0] == t.spans[0].next && t.cursor.pos[1] == 0 { return "" } var text strings.Builder spanIndex := t.spans[0].next for spanIndex != 1 { span := &t.spans[spanIndex] length := span.length if length < 0 { if t.cursor.pos[0] == spanIndex { length = -t.cursor.pos[1] } text.WriteString(t.initialText[span.offset : span.offset-length]) } else { if t.cursor.pos[0] == spanIndex { length = t.cursor.pos[1] } text.WriteString(t.editText.String()[span.offset : span.offset+length]) } if t.cursor.pos[0] == spanIndex { break } spanIndex = t.spans[spanIndex].next } return text.String() } // getTextAfterCursor returns the text of the text area after the cursor. Note // that this will result in a new allocation for the returned text. func (t *TextArea) getTextAfterCursor() string { if t.length == 0 || t.cursor.pos[0] == 1 { return "" } var text strings.Builder spanIndex := t.cursor.pos[0] cursorOffset := t.cursor.pos[1] for spanIndex != 1 { span := &t.spans[spanIndex] length := span.length if length < 0 { text.WriteString(t.initialText[span.offset+cursorOffset : span.offset-length]) } else { text.WriteString(t.editText.String()[span.offset+cursorOffset : span.offset+length]) } spanIndex = t.spans[spanIndex].next cursorOffset = 0 } return text.String() } // HasSelection returns whether the selected text is non-empty. func (t *TextArea) HasSelection() bool { return t.selectionStart != t.cursor } // GetSelection returns the currently selected text and its start and end // positions within the entire text as a half-open interval. If the returned // text is an empty string, the start and end positions are the same and can be // interpreted as the cursor position. // // Calling this function will result in string allocations as well as a search // for text positions. This is expensive if the text has been edited extensively // already. Use [TextArea.HasSelection] first if you are only interested in // selected text. func (t *TextArea) GetSelection() (text string, start int, end int) { from, to := t.selectionStart.pos, t.cursor.pos if t.cursor.row < t.selectionStart.row || (t.cursor.row == t.selectionStart.row && t.cursor.actualColumn < t.selectionStart.actualColumn) { from, to = to, from } if from[0] == 1 { start = t.length } if to[0] == 1 { end = t.length } var ( index int selection strings.Builder inside bool ) for span := t.spans[0].next; span != 1; span = t.spans[span].next { var spanText string length := t.spans[span].length if length < 0 { length = -length spanText = t.initialText } else { spanText = t.editText.String() } spanText = spanText[t.spans[span].offset : t.spans[span].offset+length] if from[0] == span && to[0] == span { if from != to { selection.WriteString(spanText[from[1]:to[1]]) } start = index + from[1] end = index + to[1] break } else if from[0] == span { if from != to { selection.WriteString(spanText[from[1]:]) } start = index + from[1] inside = true } else if to[0] == span { if from != to { selection.WriteString(spanText[:to[1]]) } end = index + to[1] break } else if inside && from != to { selection.WriteString(spanText) } index += length } if selection.Len() != 0 { text = selection.String() } return } // GetCursor returns the current cursor position where the first character of // the entire text is in row 0, column 0. If the user has selected text, the // "from" values will refer to the beginning of the selection and the "to" // values to the end of the selection (exclusive). They are the same if there // is no selection. func (t *TextArea) GetCursor() (fromRow, fromColumn, toRow, toColumn int) { fromRow, fromColumn = t.selectionStart.row, t.selectionStart.actualColumn toRow, toColumn = t.cursor.row, t.cursor.actualColumn if toRow < fromRow || (toRow == fromRow && toColumn < fromColumn) { fromRow, fromColumn, toRow, toColumn = toRow, toColumn, fromRow, fromColumn } if t.length > 0 && t.wrap && fromColumn >= t.lastWidth { // This happens when a row has text all the way until the end, pushing the cursor outside the viewport. fromRow++ fromColumn = 0 } if t.length > 0 && t.wrap && toColumn >= t.lastWidth { toRow++ toColumn = 0 } return } // GetTextLength returns the string length of the text in the text area. func (t *TextArea) GetTextLength() int { return t.length } // Replace replaces a section of the text with new text. The start and end // positions refer to index positions within the entire text string (as a // half-open interval). They may be the same, in which case text is inserted at // the given position. If the text is an empty string, text between start and // end is deleted. Index positions will be shifted to line up with character // boundaries. A "changed" event will be triggered. // // Previous selections are cleared. The cursor will be located at the end of the // replaced text. Scroll offsets will not be changed. A "moved" event will be // triggered. // // The effects of this function can be undone (and redone) by the user. func (t *TextArea) Replace(start, end int, text string) *TextArea { t.Select(start, end) row := t.selectionStart.row t.cursor.pos = t.replace(t.selectionStart.pos, t.cursor.pos, text, false) t.cursor.row = -1 t.truncateLines(row - 1) t.findCursor(false, row) t.selectionStart = t.cursor if t.moved != nil { t.moved() } // The "changed" event will have been triggered by the "replace" function. return t } // Select selects a section of the text. The start and end positions refer to // index positions within the entire text string (as a half-open interval). They // may be the same, in which case the cursor is placed at the given position. // Any previous selection is removed. Scroll offsets will be preserved. // // Index positions will be shifted to line up with character boundaries. func (t *TextArea) Select(start, end int) *TextArea { oldFrom, oldTo := t.selectionStart, t.cursor defer func() { if (oldFrom != t.selectionStart || oldTo != t.cursor) && t.moved != nil { t.moved() } }() // Clamp input values. if start < 0 { start = 0 } if start > t.length { start = t.length } if end < 0 { end = 0 } if end > t.length { end = t.length } if end < start { start, end = end, start } // Find the cursor positions. var row, index int t.cursor.row, t.cursor.pos = -1, [3]int{1, 0, -1} t.selectionStart = t.cursor RowLoop: for { if row >= len(t.lineStarts) { t.extendLines(t.lastWidth, row) if row >= len(t.lineStarts) { break } } // Check the spans of this row. pos := t.lineStarts[row] var ( next [3]int lineIndex int ) if row+1 < len(t.lineStarts) { next = t.lineStarts[row+1] } else { next = [3]int{1, 0, -1} } for { if pos[0] == next[0] { if start >= index+lineIndex && start < index+lineIndex+next[1]-pos[1] || end >= index+lineIndex && end < index+lineIndex+next[1]-pos[1] { break } index += lineIndex + next[1] - pos[1] row++ continue RowLoop // Move on to the next row. } else { length := t.spans[pos[0]].length if length < 0 { length = -length } if start >= index+lineIndex && start < index+lineIndex+length-pos[1] || end >= index+lineIndex && end < index+lineIndex+length-pos[1] { break } lineIndex += length - pos[1] pos[0], pos[1] = t.spans[pos[0]].next, 0 } } // One of the indices is in this row. Step through it. pos = t.lineStarts[row] endPos := pos var ( cluster, text string column, width int ) for pos != next { if t.selectionStart.row < 0 && start <= index { t.selectionStart.row, t.selectionStart.column, t.selectionStart.actualColumn = row, column, column t.selectionStart.pos = pos } if t.cursor.row < 0 && end <= index { t.cursor.row, t.cursor.column, t.cursor.actualColumn = row, column, column t.cursor.pos = pos break RowLoop } cluster, text, _, width, pos, endPos = t.step(text, pos, endPos) index += len(cluster) column += width } } if t.cursor.row < 0 { t.findCursor(false, 0) // This only happens if we couldn't find the locations above. t.selectionStart = t.cursor } return t } // SetWrap sets the flag that, if true, leads to lines that are longer than the // available width being wrapped onto the next line. If false, any characters // beyond the available width are not displayed. func (t *TextArea) SetWrap(wrap bool) *TextArea { if t.wrap != wrap { t.wrap = wrap t.reset() } return t } // SetWordWrap sets the flag that causes lines that are longer than the // available width to be wrapped onto the next line at spaces or after // punctuation marks (according to [Unicode Standard Annex #14]). This flag is // ignored if the flag set with [TextArea.SetWrap] is false. The text area's // default is word-wrapping. // // [Unicode Standard Annex #14]: https://www.unicode.org/reports/tr14/ func (t *TextArea) SetWordWrap(wrapOnWords bool) *TextArea { if t.wordWrap != wrapOnWords { t.wordWrap = wrapOnWords t.reset() } return t } // SetPlaceholder sets the text to be displayed when the text area is empty. func (t *TextArea) SetPlaceholder(placeholder string) *TextArea { t.placeholder = placeholder return t } // SetLabel sets the text to be displayed before the text area. func (t *TextArea) SetLabel(label string) *TextArea { t.label = label return t } // GetLabel returns the text to be displayed before the text area. func (t *TextArea) GetLabel() string { return t.label } // SetLabelWidth sets the screen width of the label. A value of 0 will cause the // primitive to use the width of the label string. func (t *TextArea) SetLabelWidth(width int) *TextArea { t.labelWidth = width return t } // GetLabelWidth returns the screen width of the label. func (t *TextArea) GetLabelWidth() int { return t.labelWidth } // SetSize sets the screen size of the input element of the text area. The input // element is always located next to the label which is always located in the // top left corner. If any of the values are 0 or larger than the available // space, the available space will be used. func (t *TextArea) SetSize(rows, columns int) *TextArea { t.width = columns t.height = rows return t } // GetFieldWidth returns this primitive's field width. func (t *TextArea) GetFieldWidth() int { return t.width } // GetFieldHeight returns this primitive's field height. func (t *TextArea) GetFieldHeight() int { return t.height } // SetDisabled sets whether or not the item is disabled / read-only. func (t *TextArea) SetDisabled(disabled bool) FormItem { t.disabled = disabled if t.finished != nil { t.finished(-1) } return t } // GetDisabled returns whether or not the item is disabled / read-only. func (t *TextArea) GetDisabled() bool { return t.disabled } // SetMaxLength sets the maximum number of bytes allowed in the text area. A // value of 0 means there is no limit. If the text area currently contains more // bytes than this, it may violate this constraint. func (t *TextArea) SetMaxLength(maxLength int) *TextArea { t.maxLength = maxLength return t } // setMinCursorPadding sets a minimum width to be reserved left and right of the // cursor. This is ignored if wrapping is enabled. func (t *TextArea) setMinCursorPadding(prefix, suffix int) *TextArea { t.minCursorPrefix = prefix t.minCursorSuffix = suffix return t } // SetLabelStyle sets the style of the label. func (t *TextArea) SetLabelStyle(style tcell.Style) *TextArea { t.labelStyle = style return t } // GetLabelStyle returns the style of the label. func (t *TextArea) GetLabelStyle() tcell.Style { return t.labelStyle } // SetTextStyle sets the style of the text. func (t *TextArea) SetTextStyle(style tcell.Style) *TextArea { t.textStyle = style return t } // GetTextStyle returns the style of the text. func (t *TextArea) GetTextStyle() tcell.Style { return t.textStyle } // SetSelectedStyle sets the style of the selected text. func (t *TextArea) SetSelectedStyle(style tcell.Style) *TextArea { t.selectedStyle = style return t } // SetPlaceholderStyle sets the style of the placeholder text. func (t *TextArea) SetPlaceholderStyle(style tcell.Style) *TextArea { t.placeholderStyle = style return t } // GetPlaceholderStyle returns the style of the placeholder text. func (t *TextArea) GetPlaceholderStyle() tcell.Style { return t.placeholderStyle } // GetOffset returns the text's offset, that is, the number of rows and columns // skipped during drawing at the top or on the left, respectively. Note that the // column offset is ignored if wrapping is enabled. func (t *TextArea) GetOffset() (row, column int) { return t.rowOffset, t.columnOffset } // SetOffset sets the text's offset, that is, the number of rows and columns // skipped during drawing at the top or on the left, respectively. If wrapping // is enabled, the column offset is ignored. These values may get adjusted // automatically to ensure that some text is always visible. func (t *TextArea) SetOffset(row, column int) *TextArea { t.rowOffset, t.columnOffset = row, column return t } // SetClipboard allows you to implement your own clipboard by providing a // function that is called when the user wishes to store text in the clipboard // (copyToClipboard) and a function that is called when the user wishes to // retrieve text from the clipboard (pasteFromClipboard). // // Providing nil values will cause the default clipboard implementation to be // used. Note that the default clipboard is local to this text area instance. // Copying text to other widgets will not work. func (t *TextArea) SetClipboard(copyToClipboard func(string), pasteFromClipboard func() string) *TextArea { t.copyToClipboard = copyToClipboard if t.copyToClipboard == nil { t.copyToClipboard = func(text string) { t.clipboard = text } } t.pasteFromClipboard = pasteFromClipboard if t.pasteFromClipboard == nil { t.pasteFromClipboard = func() string { return t.clipboard } } return t } // GetClipboardText returns the current text of the clipboard by calling the // pasteFromClipboard function set with [TextArea.SetClipboard]. func (t *TextArea) GetClipboardText() string { return t.pasteFromClipboard() } // SetChangedFunc sets a handler which is called whenever the text of the text // area has changed. func (t *TextArea) SetChangedFunc(handler func()) *TextArea { t.changed = handler return t } // SetMovedFunc sets a handler which is called whenever the cursor position or // the text selection has changed. func (t *TextArea) SetMovedFunc(handler func()) *TextArea { t.moved = handler return t } // SetFinishedFunc sets a callback invoked when the user leaves this form item. func (t *TextArea) SetFinishedFunc(handler func(key tcell.Key)) FormItem { t.finished = handler return t } // Focus is called when this primitive receives focus. func (t *TextArea) Focus(delegate func(p Primitive)) { // If we're part of a form and this item is disabled, there's nothing the // user can do here so we're finished. if t.finished != nil && t.disabled { t.finished(-1) return } t.Box.Focus(delegate) } // SetFormAttributes sets attributes shared by all form items. func (t *TextArea) SetFormAttributes(labelWidth int, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem { t.labelWidth = labelWidth t.backgroundColor = bgColor t.labelStyle = t.labelStyle.Foreground(labelColor) t.textStyle = tcell.StyleDefault.Foreground(fieldTextColor).Background(fieldBgColor) return t } // replace deletes a range of text and inserts the given text at that position. // If the resulting text would exceed the maximum length, the function does not // do anything. The function returns the end position of the deleted/inserted // range. // // The function can hang if "deleteStart" is located after "deleteEnd". // // Undo events are always generated unless continuation is true and text is // either appended to the end of a span or a span is shortened at the beginning // or the end (and nothing else). // // This function only modifies [TextArea.lineStarts] to update span references // but does not change it to reflect the new layout. // // A "changed" event will be triggered. func (t *TextArea) replace(deleteStart, deleteEnd [3]int, insert string, continuation bool) [3]int { // Maybe nothing needs to be done? if deleteStart == deleteEnd && insert == "" || t.maxLength > 0 && len(insert) > 0 && t.length+len(insert) >= t.maxLength { return deleteEnd } // Notify at the end. if t.changed != nil { defer t.changed() } // Handle a few cases where we don't put anything onto the undo stack for // increased efficiency. if continuation { // Same action as the one before. An undo item was already generated for // this block of (same) actions. We're also only changing one character. switch { case insert == "" && deleteStart[1] != 0 && deleteEnd[1] == 0: // Simple backspace. Just shorten this span. length := t.spans[deleteStart[0]].length if length < 0 { t.length -= -length - deleteStart[1] length = -deleteStart[1] } else { t.length -= length - deleteStart[1] length = deleteStart[1] } t.spans[deleteStart[0]].length = length return deleteEnd case insert == "" && deleteStart[1] == 0 && deleteEnd[1] != 0: // Simple delete. Just clip the beginning of this span. t.spans[deleteEnd[0]].offset += deleteEnd[1] if t.spans[deleteEnd[0]].length < 0 { t.spans[deleteEnd[0]].length += deleteEnd[1] } else { t.spans[deleteEnd[0]].length -= deleteEnd[1] } t.length -= deleteEnd[1] deleteEnd[1] = 0 return deleteEnd case insert != "" && deleteStart == deleteEnd && deleteEnd[1] == 0: previous := t.spans[deleteStart[0]].previous bufferSpan := t.spans[previous] if bufferSpan.length > 0 && bufferSpan.offset+bufferSpan.length == t.editText.Len() { // Typing individual characters. Simply extend the edit buffer. length, _ := t.editText.WriteString(insert) t.spans[previous].length += length t.length += length return deleteEnd } } } // All other cases generate an undo item. before := t.spans[deleteStart[0]].previous after := deleteEnd[0] if deleteEnd[1] > 0 { after = t.spans[deleteEnd[0]].next } t.undoStack = t.undoStack[:t.nextUndo] t.undoStack = append(t.undoStack, textAreaUndoItem{ before: len(t.spans), after: len(t.spans) + 1, originalBefore: before, originalAfter: after, length: t.length, pos: t.cursor.pos, continuation: continuation, }) t.spans = append(t.spans, t.spans[before]) t.spans = append(t.spans, t.spans[after]) t.nextUndo++ // Adjust total text length by subtracting everything between "before" and // "after". Inserted spans will be added back. for index := deleteStart[0]; index != after; index = t.spans[index].next { if t.spans[index].length < 0 { t.length += t.spans[index].length } else { t.length -= t.spans[index].length } } t.spans[before].next = after t.spans[after].previous = before // We go from left to right, connecting new spans as needed. We update // "before" as the span to connect new spans to. // If we start deleting in the middle of a span, connect a partial span. if deleteStart[1] != 0 { span := textAreaSpan{ previous: before, next: after, offset: t.spans[deleteStart[0]].offset, length: deleteStart[1], } if t.spans[deleteStart[0]].length < 0 { span.length = -span.length } t.length += deleteStart[1] // This was previously subtracted. t.spans[before].next = len(t.spans) t.spans[after].previous = len(t.spans) before = len(t.spans) for row, lineStart := range t.lineStarts { // Also redirect line starts until the end of this new span. if lineStart[0] == deleteStart[0] { if lineStart[1] >= deleteStart[1] { t.lineStarts = t.lineStarts[:row] // Everything else is unknown at this point. break } t.lineStarts[row][0] = len(t.spans) } } t.spans = append(t.spans, span) } // If we insert text, connect a new span. if insert != "" { span := textAreaSpan{ previous: before, next: after, offset: t.editText.Len(), } span.length, _ = t.editText.WriteString(insert) t.length += span.length t.spans[before].next = len(t.spans) t.spans[after].previous = len(t.spans) before = len(t.spans) t.spans = append(t.spans, span) } // If we stop deleting in the middle of a span, connect a partial span. if deleteEnd[1] != 0 { span := textAreaSpan{ previous: before, next: after, offset: t.spans[deleteEnd[0]].offset + deleteEnd[1], } length := t.spans[deleteEnd[0]].length if length < 0 { span.length = length + deleteEnd[1] t.length -= span.length // This was previously subtracted. } else { span.length = length - deleteEnd[1] t.length += span.length // This was previously subtracted. } t.spans[before].next = len(t.spans) t.spans[after].previous = len(t.spans) deleteEnd[0], deleteEnd[1] = len(t.spans), 0 t.spans = append(t.spans, span) } return deleteEnd } // Draw draws this primitive onto the screen. func (t *TextArea) Draw(screen tcell.Screen) { t.Box.DrawForSubclass(screen, t) // Prepare x, y, width, height := t.GetInnerRect() if width <= 0 || height <= 0 { return // We have no space for anything. } columnOffset := t.columnOffset if t.wrap { columnOffset = 0 } // Draw label. _, labelBg, _ := t.labelStyle.Decompose() if t.labelWidth > 0 { labelWidth := t.labelWidth if labelWidth > width { labelWidth = width } printWithStyle(screen, t.label, x, y, 0, labelWidth, AlignLeft, t.labelStyle, labelBg == tcell.ColorDefault) x += labelWidth width -= labelWidth } else { _, _, drawnWidth := printWithStyle(screen, t.label, x, y, 0, width, AlignLeft, t.labelStyle, labelBg == tcell.ColorDefault) x += drawnWidth width -= drawnWidth } // What's the space for the input element? if t.width > 0 && t.width < width { width = t.width } if t.height > 0 && t.height < height { height = t.height } if width <= 0 { return // No space left for the text area. } // Draw the input element if necessary. _, bg, _ := t.textStyle.Decompose() if t.disabled { bg = t.backgroundColor } if bg != t.backgroundColor { for row := 0; row < height; row++ { for column := 0; column < width; column++ { screen.SetContent(x+column, y+row, ' ', nil, t.textStyle) } } } // Show/hide the cursor at the end. defer func() { if t.HasFocus() { row, column := t.cursor.row, t.cursor.actualColumn if t.length > 0 && t.wrap && column >= t.lastWidth { // This happens when a row has text all the way until the end, pushing the cursor outside the viewport. row++ column = 0 } if row >= 0 && row-t.rowOffset >= 0 && row-t.rowOffset < height && column-columnOffset >= 0 && column-columnOffset < width { screen.ShowCursor(x+column-columnOffset, y+row-t.rowOffset) } else { screen.HideCursor() } } }() // No text, show placeholder. if t.length == 0 { t.lastHeight, t.lastWidth = height, width t.cursor.row, t.cursor.column, t.cursor.actualColumn, t.cursor.pos = 0, 0, 0, [3]int{1, 0, -1} t.rowOffset, t.columnOffset = 0, 0 if len(t.placeholder) > 0 { t.drawPlaceholder(screen, x, y, width, height) } return // We're done already. } // Make sure the visible lines are broken over. firstDrawing := t.lastWidth == 0 if t.lastWidth != width && t.lineStarts != nil { t.reset() } t.lastHeight, t.lastWidth = height, width t.extendLines(width, t.rowOffset+height) if len(t.lineStarts) <= t.rowOffset { return // It's scrolled out of view. } // If the cursor position is unknown, find it. This usually only happens // before the screen is drawn for the first time. if t.cursor.row < 0 { t.findCursor(true, 0) if t.selectionStart.row < 0 { t.selectionStart = t.cursor } if firstDrawing && t.moved != nil { t.moved() } } // Print the text. var cluster, text string line := t.rowOffset pos := t.lineStarts[line] endPos := pos posX, posY := 0, 0 for pos[0] != 1 { var clusterWidth int cluster, text, _, clusterWidth, pos, endPos = t.step(text, pos, endPos) // Prepare drawing. runes := []rune(cluster) style := t.selectedStyle fromRow, fromColumn := t.cursor.row, t.cursor.actualColumn toRow, toColumn := t.selectionStart.row, t.selectionStart.actualColumn if fromRow > toRow || fromRow == toRow && fromColumn > toColumn { fromRow, fromColumn, toRow, toColumn = toRow, toColumn, fromRow, fromColumn } if toRow < line || toRow == line && toColumn <= posX || fromRow > line || fromRow == line && fromColumn > posX { style = t.textStyle if t.disabled { style = style.Background(t.backgroundColor) } } // Selected tabs are a bit special. if cluster == "\t" && style == t.selectedStyle { for colX := 0; colX < clusterWidth && posX+colX-columnOffset < width; colX++ { screen.SetContent(x+posX+colX-columnOffset, y+posY, ' ', nil, style) } } // Draw character. if posX+clusterWidth-columnOffset <= width && posX-columnOffset >= 0 && clusterWidth > 0 { screen.SetContent(x+posX-columnOffset, y+posY, runes[0], runes[1:], style) } // Advance. posX += clusterWidth if line+1 < len(t.lineStarts) && t.lineStarts[line+1] == pos { // We must break over. posY++ if posY >= height { break // Done. } posX = 0 line++ } } } // drawPlaceholder draws the placeholder text into the given rectangle. It does // not do anything if the text area already contains text or if there is no // placeholder text. func (t *TextArea) drawPlaceholder(screen tcell.Screen, x, y, width, height int) { // We use a TextView to draw the placeholder. It will take care of word // wrapping etc. textView := NewTextView(). SetText(t.placeholder). SetTextStyle(t.placeholderStyle) textView.SetRect(x, y, width, height) textView.Draw(screen) } // reset resets many of the local variables of the text area because they cannot // be used anymore and must be recalculated, typically after the text area's // size has changed. func (t *TextArea) reset() { t.truncateLines(0) if t.wrap { t.cursor.row = -1 t.selectionStart.row = -1 } t.widestLine = 0 } // extendLines traverses the current text and extends [TextArea.lineStarts] such // that it describes at least maxLines+1 lines (or less if the text is shorter). // Text is laid out for the given width while respecting the wrapping settings. // It is assumed that if [TextArea.lineStarts] already has entries, they obey // the same rules. // // If width is 0, nothing happens. func (t *TextArea) extendLines(width, maxLines int) { if width <= 0 { return } // Start with the first span. if len(t.lineStarts) == 0 { if len(t.spans) > 2 { t.lineStarts = append(t.lineStarts, [3]int{t.spans[0].next, 0, -1}) } else { return // No text. } } // Determine starting positions and starting spans. pos := t.lineStarts[len(t.lineStarts)-1] // The starting position is the last known line. endPos := pos var ( cluster, text string lineWidth, clusterWidth, boundaries int lastGraphemeBreak, lastLineBreak [3]int widthSinceLineBreak int ) for pos[0] != 1 { // Get the next grapheme cluster. cluster, text, boundaries, clusterWidth, pos, endPos = t.step(text, pos, endPos) lineWidth += clusterWidth widthSinceLineBreak += clusterWidth // Any line breaks? if !t.wrap || lineWidth <= width { if boundaries&uniseg.MaskLine == uniseg.LineMustBreak && (len(text) > 0 || uniseg.HasTrailingLineBreakInString(cluster)) { // We must break over. t.lineStarts = append(t.lineStarts, pos) if lineWidth > t.widestLine { t.widestLine = lineWidth } lineWidth = 0 lastGraphemeBreak = [3]int{} lastLineBreak = [3]int{} widthSinceLineBreak = 0 if len(t.lineStarts) > maxLines { break // We have enough lines, we can stop. } continue } } else { // t.wrap && lineWidth > width if !t.wordWrap || lastLineBreak == [3]int{} { if lastGraphemeBreak != [3]int{} { // We have at least one character on each line. // Break after last grapheme. t.lineStarts = append(t.lineStarts, lastGraphemeBreak) if lineWidth > t.widestLine { t.widestLine = lineWidth } lineWidth = clusterWidth lastLineBreak = [3]int{} } } else { // t.wordWrap && lastLineBreak != [3]int{} // Break after last line break opportunity. t.lineStarts = append(t.lineStarts, lastLineBreak) if lineWidth > t.widestLine { t.widestLine = lineWidth } lineWidth = widthSinceLineBreak lastLineBreak = [3]int{} } } // Analyze break opportunities. if boundaries&uniseg.MaskLine == uniseg.LineCanBreak { lastLineBreak = pos widthSinceLineBreak = 0 } lastGraphemeBreak = pos // Can we stop? if len(t.lineStarts) > maxLines { break } } if lineWidth > t.widestLine { t.widestLine = lineWidth } } // truncateLines truncates the trailing lines of the [TextArea.lineStarts] // slice such that len(lineStarts) <= fromLine. If fromLine is negative, a value // of 0 is assumed. If it is greater than the length of lineStarts, nothing // happens. func (t *TextArea) truncateLines(fromLine int) { if fromLine < 0 { fromLine = 0 } if fromLine < len(t.lineStarts) { t.lineStarts = t.lineStarts[:fromLine] } } // findCursor determines the cursor position if its "row" value is < 0 // (=unknown) but only its span position ("pos" value) is known. If the cursor // position is already known (row >= 0), it can also be used to modify row and // column offsets such that the cursor is visible during the next call to // [TextArea.Draw], by setting "clamp" to true. // // To determine the cursor position, "startRow" helps reduce processing time by // indicating the lowest row in which searching should start. Set this to 0 if // you don't have any information where the cursor might be (but know that this // is expensive for long texts). // // The cursor's desired column will be set to its actual column. func (t *TextArea) findCursor(clamp bool, startRow int) { defer func() { t.cursor.column = t.cursor.actualColumn }() if !clamp && t.cursor.row >= 0 || t.lastWidth <= 0 { return // Nothing to do. } // Clamp to viewport. if clamp && t.cursor.row >= 0 { cursorRow := t.cursor.row if t.wrap && t.cursor.actualColumn >= t.lastWidth { cursorRow++ // A row can push the cursor just outside the viewport. It will wrap onto the next line. } if cursorRow < t.rowOffset { // We're above the viewport. t.rowOffset = cursorRow } else if cursorRow >= t.rowOffset+t.lastHeight { // We're below the viewport. t.rowOffset = cursorRow - t.lastHeight + 1 if t.rowOffset >= len(t.lineStarts) { t.extendLines(t.lastWidth, t.rowOffset) if t.rowOffset >= len(t.lineStarts) { t.rowOffset = len(t.lineStarts) - 1 if t.rowOffset < 0 { t.rowOffset = 0 } } } } if !t.wrap { if t.cursor.actualColumn < t.columnOffset+t.minCursorPrefix { // We're left of the viewport. t.columnOffset = t.cursor.actualColumn - t.minCursorPrefix if t.columnOffset < 0 { t.columnOffset = 0 } } else if t.cursor.actualColumn >= t.columnOffset+t.lastWidth-t.minCursorSuffix { // We're right of the viewport. t.columnOffset = t.cursor.actualColumn - t.lastWidth + t.minCursorSuffix if t.columnOffset >= t.widestLine { t.columnOffset = t.widestLine - 1 if t.columnOffset < 0 { t.columnOffset = 0 } } } } return } // The screen position of the cursor is unknown. Find it. This can be // expensive. First, find the row. row := startRow if row < 0 { row = 0 } RowLoop: for { // Examine the current row. if row+1 >= len(t.lineStarts) { t.extendLines(t.lastWidth, row+1) } if row >= len(t.lineStarts) { t.cursor.row, t.cursor.actualColumn, t.cursor.pos = row, 0, [3]int{1, 0, -1} break // It's the end of the text. } // Check this row's spans to see if the cursor is in this row. pos := t.lineStarts[row] for pos[0] != 1 { if row+1 >= len(t.lineStarts) { break // It's the last row so the cursor must be in this row. } if t.cursor.pos[0] == pos[0] { // The cursor is in this span. if t.lineStarts[row+1][0] == pos[0] { // The next row starts with the same span. if t.cursor.pos[1] >= t.lineStarts[row+1][1] { // The cursor is not in this row. row++ continue RowLoop } else { // The cursor is in this row. break } } else { // The next row starts with a different span. The cursor // must be in this row. break } } else { // The cursor is in a different span. if t.lineStarts[row+1][0] == pos[0] { // The next row starts with the same span. This row is // irrelevant. row++ continue RowLoop } else { // The next row starts with a different span. Move towards it. pos = [3]int{t.spans[pos[0]].next, 0, -1} } } } // Try to find the screen position in this row. pos = t.lineStarts[row] endPos := pos column := 0 var text string for { if pos[0] == 1 || t.cursor.pos[0] == pos[0] && t.cursor.pos[1] == pos[1] { // We found the position. We're done. t.cursor.row, t.cursor.actualColumn, t.cursor.pos = row, column, pos break RowLoop } var clusterWidth int _, text, _, clusterWidth, pos, endPos = t.step(text, pos, endPos) if row+1 < len(t.lineStarts) && t.lineStarts[row+1] == pos { // We reached the end of the line. Go to the next one. row++ continue RowLoop } column += clusterWidth } } if clamp && t.cursor.row >= 0 { // We know the position now. Adapt offsets. t.findCursor(true, startRow) } } // setTransform sets the transform function to be used when drawing the text. // This function is called for each grapheme cluster and can be used to modify // the cluster, the cluster's screen width, and the cluster's boundaries. The // function is called with the original cluster, the rest of the text, the // original cluster's width, and the original cluster's boundaries. The function // must return the new cluster, the new width, and the new boundaries. This only // affects the drawing of the text, not the text content itself. The boundaries // values correspond to the values returned by // [github.com/rivo/uniseg.StepString]. func (t *TextArea) setTransform(transform func(cluster, rest string, boundaries int) (newCluster string, newBoundaries int)) { t.transform = transform } // step is similar to [github.com/rivo/uniseg.StepString] but it iterates over // the piece chain, starting with "pos", a span position plus state (which may // be -1 for the start of the text). The returned "boundaries" value is the same // value returned by [github.com/rivo/uniseg.StepString], "width" is the screen // width of the grapheme. The "pos" and "endPos" positions refer to the start // and the end of the "text" string, respectively. For the first call, text may // be empty and pos/endPos may be the same. For consecutive calls, provide // "rest" as the text and "newPos" and "newEndPos" as the new positions/states. // An empty "rest" string indicates the end of the text. The "endPos" state is // irrelevant. func (t *TextArea) step(text string, pos, endPos [3]int) (cluster, rest string, boundaries, width int, newPos, newEndPos [3]int) { if pos[0] == 1 { return // We're already past the end. } // We want to make sure we have a text at least the size of a grapheme // cluster. span := t.spans[pos[0]] if len(text) < maxGraphemeClusterSize && (span.length < 0 && -span.length-pos[1] >= maxGraphemeClusterSize || span.length > 0 && t.spans[pos[0]].length-pos[1] >= maxGraphemeClusterSize) { // We can use a substring of one span. if span.length < 0 { text = t.initialText[span.offset+pos[1] : span.offset-span.length] } else { text = t.editText.String()[span.offset+pos[1] : span.offset+span.length] } endPos = [3]int{span.next, 0, -1} } else { // We have to compose the text from multiple spans. for len(text) < maxGraphemeClusterSize && endPos[0] != 1 { endSpan := t.spans[endPos[0]] var moreText string if endSpan.length < 0 { moreText = t.initialText[endSpan.offset+endPos[1] : endSpan.offset-endSpan.length] } else { moreText = t.editText.String()[endSpan.offset+endPos[1] : endSpan.offset+endSpan.length] } if len(moreText) > maxGraphemeClusterSize { moreText = moreText[:maxGraphemeClusterSize] } text += moreText endPos[1] += len(moreText) if endPos[1] >= endSpan.length { endPos[0], endPos[1] = endSpan.next, 0 } } } // Run the grapheme cluster iterator. cluster, text, boundaries, pos[2] = uniseg.StepString(text, pos[2]) pos[1] += len(cluster) for pos[0] != 1 && (span.length < 0 && pos[1] >= -span.length || span.length >= 0 && pos[1] >= span.length) { pos[0] = span.next if span.length < 0 { pos[1] += span.length } else { pos[1] -= span.length } span = t.spans[pos[0]] } if t.transform != nil { cluster, boundaries = t.transform(cluster, text, boundaries) } if cluster == "\t" { width = TabSize } else { width = boundaries >> uniseg.ShiftWidth } return cluster, text, boundaries, width, pos, endPos } // moveCursor sets the cursor's screen position and span position for the given // row and column which are screen space coordinates relative to the top-left // corner of the text area's full text (visible or not). The column value may be // negative, in which case, the cursor will be placed at the end of the line. // The cursor's actual position will be aligned with a grapheme cluster // boundary. The next call to [TextArea.Draw] will attempt to keep the cursor in // the viewport. func (t *TextArea) moveCursor(row, column int) { // Are we within the range of rows? if len(t.lineStarts) <= row { // No. Extent the line buffer. t.extendLines(t.lastWidth, row) } if len(t.lineStarts) == 0 { return // No lines. Nothing to do. } if row < 0 { // We're at the start of the text. row = 0 column = 0 } else if row >= len(t.lineStarts) { // We're already past the end. row = len(t.lineStarts) - 1 column = -1 } // Iterate through this row until we find the position. t.cursor.row, t.cursor.actualColumn = row, 0 if t.wrap { t.cursor.actualColumn = 0 } pos := t.lineStarts[row] endPos := pos var text string for pos[0] != 1 { var clusterWidth int oldPos := pos // We may have to revert to this position. _, text, _, clusterWidth, pos, endPos = t.step(text, pos, endPos) if len(t.lineStarts) > row+1 && pos == t.lineStarts[row+1] || // We've reached the end of the line. column >= 0 && t.cursor.actualColumn+clusterWidth > column { // We're past the requested column. pos = oldPos break } t.cursor.actualColumn += clusterWidth } if column < 0 { t.cursor.column = t.cursor.actualColumn } else { t.cursor.column = column } t.cursor.pos = pos t.findCursor(true, row) } // moveWordRight moves the cursor to the end of the current or next word. If // after is set to true, the cursor will be placed after the word. If false, the // cursor will be placed on the last character of the word. If clamp is set to // true, the cursor will be visible during the next call to [TextArea.Draw]. func (t *TextArea) moveWordRight(after, clamp bool) { // Because we rely on clampToCursor to calculate the new screen position, // this is an expensive operation for large texts. pos := t.cursor.pos endPos := pos var ( cluster, text string inWord bool ) for pos[0] != 0 { var boundaries int oldPos := pos cluster, text, boundaries, _, pos, endPos = t.step(text, pos, endPos) if oldPos == t.cursor.pos { continue // Skip the first character. } firstRune, _ := utf8.DecodeRuneInString(cluster) if !unicode.IsSpace(firstRune) && !unicode.IsPunct(firstRune) { inWord = true } if inWord && boundaries&uniseg.MaskWord != 0 { if !after { pos = oldPos } break } } startRow := t.cursor.row t.cursor.row, t.cursor.column, t.cursor.actualColumn = -1, 0, 0 t.cursor.pos = pos t.findCursor(clamp, startRow) } // moveWordLeft moves the cursor to the beginning of the current or previous // word. If clamp is true, the cursor will be visible during the next call to // [TextArea.Draw]. func (t *TextArea) moveWordLeft(clamp bool) { // We go back row by row, trying to find the last word boundary before the // cursor. row := t.cursor.row if row+1 < len(t.lineStarts) { t.extendLines(t.lastWidth, row+1) } if row >= len(t.lineStarts) { row = len(t.lineStarts) - 1 } for row >= 0 { pos := t.lineStarts[row] endPos := pos var lastWordBoundary [3]int var ( cluster, text string inWord bool boundaries int ) for pos[0] != 1 && pos != t.cursor.pos { oldBoundaries := boundaries oldPos := pos cluster, text, boundaries, _, pos, endPos = t.step(text, pos, endPos) firstRune, _ := utf8.DecodeRuneInString(cluster) wordRune := !unicode.IsSpace(firstRune) && !unicode.IsPunct(firstRune) if oldBoundaries&uniseg.MaskWord != 0 { if pos != t.cursor.pos && !inWord && wordRune { // A boundary transitioning from a space/punctuation word to // a letter word. lastWordBoundary = oldPos } inWord = false } if wordRune { inWord = true } } if lastWordBoundary[0] != 0 { // We found something. t.cursor.pos = lastWordBoundary break } row-- } if row < 0 { // We didn't find anything. We're at the start of the text. t.cursor.pos = [3]int{t.spans[0].next, 0, -1} row = 0 } t.cursor.row, t.cursor.column, t.cursor.actualColumn = -1, 0, 0 t.findCursor(clamp, row) } // deleteLine deletes all characters between the last newline before the cursor // and the next newline after the cursor (inclusive). func (t *TextArea) deleteLine() { // We go back row by row, trying to find the last mandatory line break // before the cursor. startRow := t.cursor.row if t.cursor.actualColumn == 0 && t.cursor.pos[0] == 1 { startRow-- // If we're at the very end, delete the row before. } if startRow+1 < len(t.lineStarts) { t.extendLines(t.lastWidth, startRow+1) } if len(t.lineStarts) == 0 { return // Nothing to delete. } if startRow >= len(t.lineStarts) { startRow = len(t.lineStarts) - 1 } for startRow >= 0 { // What's the last rune before the start of the line? pos := t.lineStarts[startRow] span := t.spans[pos[0]] var text string if pos[1] > 0 { // Extract text from this span. if span.length < 0 { text = t.initialText } else { text = t.editText.String() } text = text[:span.offset+pos[1]] } else { // Extract text from the previous span. if span.previous != 0 { span = t.spans[span.previous] if span.length < 0 { text = t.initialText[:span.offset-span.length] } else { text = t.editText.String()[:span.offset+span.length] } } } if uniseg.HasTrailingLineBreakInString(text) { // The row before this one ends with a mandatory line break. This is // the first line we will delete. break } startRow-- } if startRow < 0 { // We didn't find anything. It'll be the first line. startRow = 0 } // Find the next line break after the cursor. pos := t.cursor.pos endPos := pos var cluster, text string for pos[0] != 1 { cluster, text, _, _, pos, endPos = t.step(text, pos, endPos) if uniseg.HasTrailingLineBreakInString(cluster) { break } } // Delete the text. t.cursor.pos = t.replace(t.lineStarts[startRow], pos, "", false) t.cursor.row = -1 t.truncateLines(startRow) t.findCursor(true, startRow) } // getSelection returns the current selection as span locations where the first // returned location is always before or the same as the second returned // location. This assumes that the cursor and selection positions are known. The // third return value is the starting row of the selection. func (t *TextArea) getSelection() ([3]int, [3]int, int) { from := t.selectionStart.pos to := t.cursor.pos row := t.selectionStart.row if t.cursor.row < t.selectionStart.row || (t.cursor.row == t.selectionStart.row && t.cursor.actualColumn < t.selectionStart.actualColumn) { from, to = to, from row = t.cursor.row } return from, to, row } // getSelectedText returns the text of the current selection. func (t *TextArea) getSelectedText() string { var text strings.Builder from, to, _ := t.getSelection() for from[0] != to[0] { span := t.spans[from[0]] if span.length < 0 { text.WriteString(t.initialText[span.offset+from[1] : span.offset-span.length]) } else { text.WriteString(t.editText.String()[span.offset+from[1] : span.offset+span.length]) } from[0], from[1] = span.next, 0 } if from[0] != 1 && from[1] < to[1] { span := t.spans[from[0]] if span.length < 0 { text.WriteString(t.initialText[span.offset+from[1] : span.offset+to[1]]) } else { text.WriteString(t.editText.String()[span.offset+from[1] : span.offset+to[1]]) } } return text.String() } // InputHandler returns the handler for this primitive. func (t *TextArea) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) { return t.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) { if t.disabled { return } // All actions except a few specific ones are "other" actions. newLastAction := taActionOther defer func() { t.lastAction = newLastAction }() // Trigger a "moved" event if requested. if t.moved != nil { selectionStart, cursor := t.selectionStart, t.cursor defer func() { if selectionStart != t.selectionStart || cursor != t.cursor { t.moved() } }() } // Process the different key events. switch key := event.Key(); key { case tcell.KeyLeft: // Move one grapheme cluster to the left. if event.Modifiers()&tcell.ModAlt == 0 { // Regular movement. if event.Modifiers()&tcell.ModShift == 0 && t.selectionStart.pos != t.cursor.pos { // Move to the start of the selection. if t.selectionStart.row < t.cursor.row || (t.selectionStart.row == t.cursor.row && t.selectionStart.actualColumn < t.cursor.actualColumn) { t.cursor = t.selectionStart } t.findCursor(true, t.cursor.row) } else if event.Modifiers()&tcell.ModMeta != 0 || event.Modifiers()&tcell.ModCtrl != 0 { // This captures Ctrl-Left on some systems. t.moveWordLeft(event.Modifiers()&tcell.ModShift != 0) } else if t.cursor.actualColumn == 0 { // Move to the end of the previous row. if t.cursor.row > 0 { t.moveCursor(t.cursor.row-1, -1) } } else { // Move one grapheme cluster to the left. t.moveCursor(t.cursor.row, t.cursor.actualColumn-1) } if event.Modifiers()&tcell.ModShift == 0 { t.selectionStart = t.cursor } } else if !t.wrap { // This doesn't work on all terminals. // Just scroll. t.columnOffset-- if t.columnOffset < 0 { t.columnOffset = 0 } } case tcell.KeyRight: // Move one grapheme cluster to the right. if event.Modifiers()&tcell.ModAlt == 0 { // Regular movement. if event.Modifiers()&tcell.ModShift == 0 && t.selectionStart.pos != t.cursor.pos { // Move to the end of the selection. if t.selectionStart.row > t.cursor.row || (t.selectionStart.row == t.cursor.row && t.selectionStart.actualColumn > t.cursor.actualColumn) { t.cursor = t.selectionStart } t.findCursor(true, t.cursor.row) } else if t.cursor.pos[0] != 1 { if event.Modifiers()&tcell.ModMeta != 0 || event.Modifiers()&tcell.ModCtrl != 0 { // This captures Ctrl-Right on some systems. t.moveWordRight(event.Modifiers()&tcell.ModShift != 0, true) } else { // Move one grapheme cluster to the right. var clusterWidth int _, _, _, clusterWidth, t.cursor.pos, _ = t.step("", t.cursor.pos, t.cursor.pos) if len(t.lineStarts) <= t.cursor.row+1 { t.extendLines(t.lastWidth, t.cursor.row+1) } if t.cursor.row+1 < len(t.lineStarts) && t.lineStarts[t.cursor.row+1] == t.cursor.pos { // We've reached the end of the line. t.cursor.row++ t.cursor.actualColumn = 0 t.cursor.column = 0 t.findCursor(true, t.cursor.row) } else { // Move one character to the right. t.moveCursor(t.cursor.row, t.cursor.actualColumn+clusterWidth) } } } if event.Modifiers()&tcell.ModShift == 0 { t.selectionStart = t.cursor } } else if !t.wrap { // This doesn't work on all terminals. // Just scroll. t.columnOffset++ if t.columnOffset >= t.widestLine { t.columnOffset = t.widestLine - 1 if t.columnOffset < 0 { t.columnOffset = 0 } } } case tcell.KeyDown: // Move one row down. if event.Modifiers()&tcell.ModAlt == 0 { // Regular movement. column := t.cursor.column t.moveCursor(t.cursor.row+1, t.cursor.column) t.cursor.column = column if event.Modifiers()&tcell.ModShift == 0 { t.selectionStart = t.cursor } } else { // Just scroll. t.rowOffset++ if t.rowOffset >= len(t.lineStarts) { t.extendLines(t.lastWidth, t.rowOffset) if t.rowOffset >= len(t.lineStarts) { t.rowOffset = len(t.lineStarts) - 1 if t.rowOffset < 0 { t.rowOffset = 0 } } } } case tcell.KeyUp: // Move one row up. if event.Modifiers()&tcell.ModAlt == 0 { // Regular movement. column := t.cursor.column t.moveCursor(t.cursor.row-1, t.cursor.column) t.cursor.column = column if event.Modifiers()&tcell.ModShift == 0 { t.selectionStart = t.cursor } } else { // Just scroll. t.rowOffset-- if t.rowOffset < 0 { t.rowOffset = 0 } } case tcell.KeyHome, tcell.KeyCtrlA: // Move to the start of the line. t.moveCursor(t.cursor.row, 0) if event.Modifiers()&tcell.ModShift == 0 { t.selectionStart = t.cursor } case tcell.KeyEnd, tcell.KeyCtrlE: // Move to the end of the line. t.moveCursor(t.cursor.row, -1) if event.Modifiers()&tcell.ModShift == 0 { t.selectionStart = t.cursor } case tcell.KeyPgDn, tcell.KeyCtrlF: // Move one page down. column := t.cursor.column t.moveCursor(t.cursor.row+t.lastHeight, t.cursor.column) t.cursor.column = column if event.Modifiers()&tcell.ModShift == 0 { t.selectionStart = t.cursor } case tcell.KeyPgUp, tcell.KeyCtrlB: // Move one page up. column := t.cursor.column t.moveCursor(t.cursor.row-t.lastHeight, t.cursor.column) t.cursor.column = column if event.Modifiers()&tcell.ModShift == 0 { t.selectionStart = t.cursor } case tcell.KeyEnter: // Insert a newline. from, to, row := t.getSelection() t.cursor.pos = t.replace(from, to, NewLine, t.lastAction == taActionTypeSpace) t.cursor.row = -1 t.truncateLines(row - 1) t.findCursor(true, row) t.selectionStart = t.cursor newLastAction = taActionTypeSpace case tcell.KeyTab: // Insert a tab character. It will be rendered as TabSize spaces. // But forwarding takes precedence. if t.finished != nil { t.finished(key) return } from, to, row := t.getSelection() t.cursor.pos = t.replace(from, to, "\t", t.lastAction == taActionTypeSpace) t.cursor.row = -1 t.truncateLines(row - 1) t.findCursor(true, row) t.selectionStart = t.cursor newLastAction = taActionTypeSpace case tcell.KeyBacktab, tcell.KeyEscape: // Only used in forms. if t.finished != nil { t.finished(key) return } case tcell.KeyRune: if event.Modifiers()&tcell.ModAlt > 0 { // We accept some Alt- key combinations. switch event.Rune() { case 'f': if event.Modifiers()&tcell.ModShift == 0 { t.moveWordRight(false, true) t.selectionStart = t.cursor } else { t.moveWordRight(true, true) } case 'b': t.moveWordLeft(true) if event.Modifiers()&tcell.ModShift == 0 { t.selectionStart = t.cursor } } } else { // Other keys are simply accepted as regular characters. r := event.Rune() from, to, row := t.getSelection() newLastAction = taActionTypeNonSpace if unicode.IsSpace(r) { newLastAction = taActionTypeSpace } t.cursor.pos = t.replace(from, to, string(r), newLastAction == t.lastAction || t.lastAction == taActionTypeNonSpace && newLastAction == taActionTypeSpace) t.cursor.row = -1 t.truncateLines(row - 1) t.findCursor(true, row) t.selectionStart = t.cursor } case tcell.KeyBackspace, tcell.KeyBackspace2: // Delete backwards. tcell.KeyBackspace is the same as tcell.CtrlH. from, to, row := t.getSelection() if from != to { // Simply delete the current selection. t.cursor.pos = t.replace(from, to, "", false) t.cursor.row = -1 t.truncateLines(row - 1) t.findCursor(true, row) t.selectionStart = t.cursor break } beforeCursor := t.cursor if event.Modifiers()&tcell.ModAlt == 0 { // Move the cursor back by one grapheme cluster. if t.cursor.actualColumn == 0 { // Move to the end of the previous row. if t.cursor.row > 0 { t.moveCursor(t.cursor.row-1, -1) } } else { // Move one grapheme cluster to the left. t.moveCursor(t.cursor.row, t.cursor.actualColumn-1) } newLastAction = taActionBackspace } else { // Move the cursor back by one word. t.moveWordLeft(false) } // Remove that last grapheme cluster. if t.cursor.pos != beforeCursor.pos { t.cursor, beforeCursor = beforeCursor, t.cursor // So we put the right position on the stack. t.cursor.pos = t.replace(beforeCursor.pos, t.cursor.pos, "", t.lastAction == taActionBackspace) // Delete the character. t.cursor.row = -1 t.truncateLines(beforeCursor.row - 1) t.findCursor(true, beforeCursor.row-1) } t.selectionStart = t.cursor case tcell.KeyDelete, tcell.KeyCtrlD: // Delete forward. from, to, row := t.getSelection() if from != to { // Simply delete the current selection. t.cursor.pos = t.replace(from, to, "", false) t.cursor.row = -1 t.truncateLines(row - 1) t.findCursor(true, row) t.selectionStart = t.cursor break } if t.cursor.pos[0] != 1 { _, _, _, _, endPos, _ := t.step("", t.cursor.pos, t.cursor.pos) t.cursor.pos = t.replace(t.cursor.pos, endPos, "", t.lastAction == taActionDelete) // Delete the character. t.cursor.pos[2] = endPos[2] t.truncateLines(t.cursor.row - 1) t.findCursor(true, t.cursor.row) newLastAction = taActionDelete } t.selectionStart = t.cursor case tcell.KeyCtrlK: // Delete everything under and to the right of the cursor until before the next newline character. pos := t.cursor.pos endPos := pos var cluster, text string for pos[0] != 1 { var boundaries int oldPos := pos cluster, text, boundaries, _, pos, endPos = t.step(text, pos, endPos) if boundaries&uniseg.MaskLine == uniseg.LineMustBreak { if uniseg.HasTrailingLineBreakInString(cluster) { pos = oldPos } break } } t.cursor.pos = t.replace(t.cursor.pos, pos, "", false) row := t.cursor.row t.cursor.row = -1 t.truncateLines(row - 1) t.findCursor(true, row) t.selectionStart = t.cursor case tcell.KeyCtrlW: // Delete from the start of the current word to the left of the cursor. pos := t.cursor.pos t.moveWordLeft(true) t.cursor.pos = t.replace(t.cursor.pos, pos, "", false) row := t.cursor.row - 1 t.cursor.row = -1 t.truncateLines(row) t.findCursor(true, row) t.selectionStart = t.cursor case tcell.KeyCtrlU: // Delete the current line. t.deleteLine() t.selectionStart = t.cursor case tcell.KeyCtrlL: // Select everything. t.selectionStart.row, t.selectionStart.column, t.selectionStart.actualColumn = 0, 0, 0 t.selectionStart.pos = [3]int{t.spans[0].next, 0, -1} row := t.cursor.row t.cursor.row = -1 t.cursor.pos = [3]int{1, 0, -1} t.findCursor(false, row) case tcell.KeyCtrlQ: // Copy to clipboard. if t.cursor != t.selectionStart { t.copyToClipboard(t.getSelectedText()) t.selectionStart = t.cursor } case tcell.KeyCtrlX: // Cut to clipboard. if t.cursor != t.selectionStart { t.copyToClipboard(t.getSelectedText()) from, to, row := t.getSelection() t.cursor.pos = t.replace(from, to, "", false) t.cursor.row = -1 t.truncateLines(row - 1) t.findCursor(true, row) t.selectionStart = t.cursor } case tcell.KeyCtrlV: // Paste from clipboard. from, to, row := t.getSelection() t.cursor.pos = t.replace(from, to, t.pasteFromClipboard(), false) t.cursor.row = -1 t.truncateLines(row - 1) t.findCursor(true, row) t.selectionStart = t.cursor case tcell.KeyCtrlZ: // Undo. if t.nextUndo <= 0 { break } for t.nextUndo > 0 { t.nextUndo-- undo := t.undoStack[t.nextUndo] t.spans[undo.originalBefore], t.spans[undo.before] = t.spans[undo.before], t.spans[undo.originalBefore] t.spans[undo.originalAfter], t.spans[undo.after] = t.spans[undo.after], t.spans[undo.originalAfter] t.cursor.pos, t.undoStack[t.nextUndo].pos = undo.pos, t.cursor.pos t.length, t.undoStack[t.nextUndo].length = undo.length, t.length if !undo.continuation { break } } t.cursor.row = -1 t.truncateLines(0) // This is why Undo is expensive for large texts. (t.lineStarts can get largely unusable after an undo.) t.findCursor(true, 0) t.selectionStart = t.cursor if t.changed != nil { defer t.changed() } case tcell.KeyCtrlY: // Redo. if t.nextUndo >= len(t.undoStack) { break } for t.nextUndo < len(t.undoStack) { undo := t.undoStack[t.nextUndo] t.spans[undo.originalBefore], t.spans[undo.before] = t.spans[undo.before], t.spans[undo.originalBefore] t.spans[undo.originalAfter], t.spans[undo.after] = t.spans[undo.after], t.spans[undo.originalAfter] t.cursor.pos, t.undoStack[t.nextUndo].pos = undo.pos, t.cursor.pos t.length, t.undoStack[t.nextUndo].length = undo.length, t.length t.nextUndo++ if t.nextUndo < len(t.undoStack) && !t.undoStack[t.nextUndo].continuation { break } } t.cursor.row = -1 t.truncateLines(0) // This is why Redo is expensive for large texts. (t.lineStarts can get largely unusable after an undo.) t.findCursor(true, 0) t.selectionStart = t.cursor if t.changed != nil { defer t.changed() } } }) } // MouseHandler returns the mouse handler for this primitive. func (t *TextArea) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return t.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { if t.disabled { return false, nil } x, y := event.Position() rectX, rectY, _, _ := t.GetInnerRect() if !t.InRect(x, y) { return false, nil } // Trigger a "moved" event at the end if requested. if t.moved != nil { selectionStart, cursor := t.selectionStart, t.cursor defer func() { if selectionStart != t.selectionStart || cursor != t.cursor { t.moved() } }() } // Turn mouse coordinates into text coordinates. labelWidth := t.labelWidth if labelWidth == 0 && t.label != "" { labelWidth = TaggedStringWidth(t.label) } column := x - rectX - labelWidth row := y - rectY if !t.wrap { column += t.columnOffset } row += t.rowOffset // Process mouse actions. switch action { case MouseLeftDown: t.moveCursor(row, column) if event.Modifiers()&tcell.ModShift == 0 { t.selectionStart = t.cursor } setFocus(t) consumed = true capture = t t.dragging = true case MouseMove: if !t.dragging { break } t.moveCursor(row, column) consumed = true case MouseLeftUp: t.moveCursor(row, column) consumed = true capture = nil t.dragging = false case MouseLeftDoubleClick: // Select word. // Left down/up was already triggered so we are at the correct // position. t.moveWordLeft(false) t.selectionStart = t.cursor t.moveWordRight(true, false) consumed = true case MouseScrollUp: if t.rowOffset > 0 { t.rowOffset-- } consumed = true case MouseScrollDown: t.rowOffset++ if t.rowOffset >= len(t.lineStarts) { t.rowOffset = len(t.lineStarts) - 1 if t.rowOffset < 0 { t.rowOffset = 0 } } consumed = true case MouseScrollLeft: if t.columnOffset > 0 { t.columnOffset-- } consumed = true case MouseScrollRight: t.columnOffset++ if t.columnOffset >= t.widestLine { t.columnOffset = t.widestLine - 1 if t.columnOffset < 0 { t.columnOffset = 0 } } consumed = true } return }) } // PasteHandler returns the handler for this primitive. func (t *TextArea) PasteHandler() func(pastedText string, setFocus func(p Primitive)) { return t.WrapPasteHandler(func(pastedText string, setFocus func(p Primitive)) { from, to, row := t.getSelection() t.cursor.pos = t.replace(from, to, pastedText, false) t.cursor.row = -1 t.truncateLines(row - 1) t.findCursor(true, row) t.selectionStart = t.cursor }) } golang-github-darkhz-tview-0.0~git20240308.6078a88/textview.go000066400000000000000000001223321457770046000234110ustar00rootroot00000000000000package tview import ( "math" "strings" "sync" "github.com/gdamore/tcell/v2" colorful "github.com/lucasb-eyer/go-colorful" ) // TabSize is the number of spaces with which a tab character will be replaced. var TabSize = 4 // textViewLine contains information about a line displayed in the text view. type textViewLine struct { offset int // The string position in the buffer where this line starts. width int // The screen width of this line. length int // The string length (in bytes) of this line. state *stepState // The parser state at the beginning of the line, before parsing the first character. regions map[string][2]int // The start and end columns of all regions in this line. Only valid for visible lines. May be nil. } // TextViewWriter is a writer that can be used to write to and clear a TextView // in batches, i.e. multiple writes with the lock only being acquired once. Don't // instantiated this class directly but use the TextView's BatchWriter method // instead. type TextViewWriter struct { t *TextView } // Close implements io.Closer for the writer by unlocking the original TextView. func (w TextViewWriter) Close() error { w.t.Unlock() return nil } // Clear removes all text from the buffer. func (w TextViewWriter) Clear() { w.t.clear() } // Write implements the io.Writer interface. It behaves like the TextView's // Write() method except that it does not acquire the lock. func (w TextViewWriter) Write(p []byte) (n int, err error) { return w.t.write(p) } // HasFocus returns whether the underlying TextView has focus. func (w TextViewWriter) HasFocus() bool { return w.t.hasFocus } // TextView is a component to display read-only text. While the text to be // displayed can be changed or appended to, there is no functionality that // allows the user to edit it. For that, [TextArea] should be used. // // TextView implements the io.Writer interface so you can stream text to it, // appending to the existing text. This does not trigger a redraw automatically // but if a handler is installed via [TextView.SetChangedFunc], you can cause it // to be redrawn. (See [TextView.SetChangedFunc] for more details.) // // Tab characters advance the text to the next tab stop at every [TabSize] // screen columns, but only if the text is left-aligned. If the text is centered // or right-aligned, tab characters are simply replaced with [TabSize] spaces. // // Word wrapping is enabled by default. Use [TextView.SetWrap] and // [TextView.SetWordWrap] to change this. // // # Navigation // // If the text view is set to be scrollable (which is the default), text is kept // in a buffer which may be larger than the screen and can be navigated // with Vim-like key binds: // // - h, left arrow: Move left. // - l, right arrow: Move right. // - j, down arrow: Move down. // - k, up arrow: Move up. // - g, home: Move to the top. // - G, end: Move to the bottom. // - Ctrl-F, page down: Move down by one page. // - Ctrl-B, page up: Move up by one page. // // If the text is not scrollable, any text above the top visible line is // discarded. This can be useful when you want to continuously stream text to // the text view and only keep the latest lines. // // Use [Box.SetInputCapture] to override or modify keyboard input. // // # Styles / Colors // // If dynamic colors are enabled via [TextView.SetDynamicColors], text style can // be changed dynamically by embedding color strings in square brackets. This // works the same way as anywhere else. See the package documentation for more // information. // // # Regions and Highlights // // If regions are enabled via [TextView.SetRegions], you can define text regions // within the text and assign region IDs to them. Text regions start with region // tags. Region tags are square brackets that contain a region ID in double // quotes, for example: // // We define a ["rg"]region[""] here. // // A text region ends with the next region tag. Tags with no region ID ([""]) // don't start new regions. They can therefore be used to mark the end of a // region. Region IDs must satisfy the following regular expression: // // [a-zA-Z0-9_,;: \-\.]+ // // Regions can be highlighted by calling the [TextView.Highlight] function with // one or more region IDs. This can be used to display search results, for // example. // // The [TextView.ScrollToHighlight] function can be used to jump to the // currently highlighted region once when the text view is drawn the next time. // // # Large Texts // // The text view can handle reasonably large texts. It will parse the text as // needed. For optimal performance, it is best to access or display parts of the // text very far down only if really needed. For example, call // [TextView.ScrollToBeginning] before adding the text to the text view, to // avoid scrolling the text all the way to the bottom, forcing a full-text // parse. // // For even larger texts or "infinite" streams of text such as log files, you // should consider using [TextView.SetMaxLines] to limit the number of lines in // the text view buffer. Or disable the text view's scrollability altogether // (using [TextView.SetScrollable]). This will cause the text view to discard // lines moving out of the visible area at the top. // // See https://github.com/rivo/tview/wiki/TextView for an example. type TextView struct { sync.Mutex *Box // The size of the text area. If set to 0, the text view will use the entire // available space. width, height int // The text buffer. text strings.Builder // The line index. It is valid at any time but may not contain trailing // lines which are not visible. lineIndex []*textViewLine // The screen width of the longest line in the index. longestLine int // Regions mapped by their ID to the line where they start. Regions which // cannot be found in [TextView.lineIndex] are not contained. regions map[string]int // The label text shown, usually when part of a form. label string // The width of the text area's label. labelWidth int // The label style. labelStyle tcell.Style // The text alignment, one of AlignLeft, AlignCenter, or AlignRight. align int // Currently highlighted regions. highlights map[string]struct{} // The last width for which the current text view was drawn. lastWidth int // The height of the content the last time the text view was drawn. pageSize int // The index of the first line shown in the text view. lineOffset int // If set to true, the text view will always remain at the end of the // content when text is added. trackEnd bool // The width of the characters to be skipped on each line (not used in wrap // mode). columnOffset int // The maximum number of lines kept in the line index, effectively the // latest word-wrapped lines. Ignored if 0. maxLines int // If set to true, the text view will keep a buffer of text which can be // navigated when the text is longer than what fits into the box. scrollable bool // If set to true, lines that are longer than the available width are // wrapped onto the next line. If set to false, any characters beyond the // available width are discarded. wrap bool // If set to true and if wrap is also true, Unicode line breaking is // applied. wordWrap bool // The (starting) style of the text. This also defines the background color // of the main text element. textStyle tcell.Style // Whether or not style tags are used. styleTags bool // Whether or not region tags are used. regionTags bool // A temporary flag which, when true, will automatically bring the current // highlight(s) into the visible screen the next time the text view is // drawn. scrollToHighlights bool // If true, setting new highlights will be a XOR instead of an overwrite // operation. toggleHighlights bool // An optional function which is called when the content of the text view // has changed. changed func() // An optional function which is called when the user presses one of the // following keys: Escape, Enter, Tab, Backtab. done func(tcell.Key) // An optional function which is called when one or more regions were // highlighted. highlighted func(added, removed, remaining []string) // A callback function set by the Form class and called when the user leaves // this form item. finished func(tcell.Key) } // NewTextView returns a new text view. func NewTextView() *TextView { return &TextView{ Box: NewBox(), labelStyle: tcell.StyleDefault.Foreground(Styles.SecondaryTextColor), highlights: make(map[string]struct{}), lineOffset: -1, scrollable: true, align: AlignLeft, wrap: true, wordWrap: true, textStyle: tcell.StyleDefault.Background(Styles.PrimitiveBackgroundColor).Foreground(Styles.PrimaryTextColor), regionTags: false, styleTags: false, } } // SetLabel sets the text to be displayed before the text view. func (t *TextView) SetLabel(label string) *TextView { t.label = label return t } // GetLabel returns the text to be displayed before the text view. func (t *TextView) GetLabel() string { return t.label } // SetLabelWidth sets the screen width of the label. A value of 0 will cause the // primitive to use the width of the label string. func (t *TextView) SetLabelWidth(width int) *TextView { t.labelWidth = width return t } // SetSize sets the screen size of the main text element of the text view. This // element is always located next to the label which is always located in the // top left corner. If any of the values are 0 or larger than the available // space, the available space will be used. func (t *TextView) SetSize(rows, columns int) *TextView { t.width = columns t.height = rows return t } // GetFieldWidth returns this primitive's field width. func (t *TextView) GetFieldWidth() int { return t.width } // GetFieldHeight returns this primitive's field height. func (t *TextView) GetFieldHeight() int { return t.height } // SetDisabled sets whether or not the item is disabled / read-only. func (t *TextView) SetDisabled(disabled bool) FormItem { return t // Text views are always read-only. } // SetScrollable sets the flag that decides whether or not the text view is // scrollable. If false, text that moves above the text view's top row will be // permanently deleted. func (t *TextView) SetScrollable(scrollable bool) *TextView { t.scrollable = scrollable if !scrollable { t.trackEnd = true } return t } // SetWrap sets the flag that, if true, leads to lines that are longer than the // available width being wrapped onto the next line. If false, any characters // beyond the available width are not displayed. func (t *TextView) SetWrap(wrap bool) *TextView { if t.wrap != wrap { t.resetIndex() // This invalidates the entire index. } t.wrap = wrap return t } // SetWordWrap sets the flag that, if true and if the "wrap" flag is also true // (see [TextView.SetWrap]), wraps according to [Unicode Standard Annex #14]. // // This flag is ignored if the "wrap" flag is false. func (t *TextView) SetWordWrap(wrapOnWords bool) *TextView { if t.wrap && t.wordWrap != wrapOnWords { t.resetIndex() // This invalidates the entire index. } t.wordWrap = wrapOnWords return t } // SetMaxLines sets the maximum number of lines for this text view. Lines at the // beginning of the text will be discarded when the text view is drawn, so as to // remain below this value. Only lines above the first visible line are removed. // // Broken-over lines via word/character wrapping are counted individually. // // Note that [TextView.GetText] will return the shortened text. // // A value of 0 (the default) will keep all lines in place. func (t *TextView) SetMaxLines(maxLines int) *TextView { t.maxLines = maxLines return t } // SetTextAlign sets the text alignment within the text view. This must be // either AlignLeft, AlignCenter, or AlignRight. func (t *TextView) SetTextAlign(align int) *TextView { t.align = align return t } // SetTextColor sets the initial color of the text. func (t *TextView) SetTextColor(color tcell.Color) *TextView { t.textStyle = t.textStyle.Foreground(color) t.resetIndex() return t } // SetBackgroundColor overrides its implementation in Box to set the background // color of this primitive. For backwards compatibility reasons, it also sets // the background color of the main text element. func (t *TextView) SetBackgroundColor(color tcell.Color) *Box { t.Box.SetBackgroundColor(color) t.textStyle = t.textStyle.Background(color) t.resetIndex() return t.Box } // SetTextStyle sets the initial style of the text. This style's background // color also determines the background color of the main text element. func (t *TextView) SetTextStyle(style tcell.Style) *TextView { t.textStyle = style t.resetIndex() return t } // SetText sets the text of this text view to the provided string. Previously // contained text will be removed. As with writing to the text view io.Writer // interface directly, this does not trigger an automatic redraw but it will // trigger the "changed" callback if one is set. func (t *TextView) SetText(text string) *TextView { t.Lock() defer t.Unlock() t.text.Reset() t.text.WriteString(text) t.resetIndex() if t.changed != nil { go t.changed() } return t } // GetText returns the current text of this text view. If "stripAllTags" is set // to true, any region/style tags are stripped from the text. func (t *TextView) GetText(stripAllTags bool) string { if !stripAllTags || (!t.styleTags && !t.regionTags) { return t.text.String() } var ( str strings.Builder state *stepState text = t.text.String() opts stepOptions ch string ) if t.styleTags { opts = stepOptionsStyle } if t.regionTags { opts |= stepOptionsRegion } for len(text) > 0 { ch, text, state = step(text, state, opts) str.WriteString(ch) } return str.String() } // GetOriginalLineCount returns the number of lines in the original text buffer, // without applying any wrapping. This is an expensive call as it needs to // iterate over the entire text. func (t *TextView) GetOriginalLineCount() int { if t.text.Len() == 0 { return 0 } var ( state *stepState str = t.text.String() lines int = 1 ) for len(str) > 0 { _, str, state = step(str, state, stepOptionsNone) if lineBreak, optional := state.LineBreak(); lineBreak && !optional { lines++ } } return lines } // SetDynamicColors sets the flag that allows the text color to be changed // dynamically with style tags. See class description for details. func (t *TextView) SetDynamicColors(dynamic bool) *TextView { if t.styleTags != dynamic { t.resetIndex() // This invalidates the entire index. } t.styleTags = dynamic return t } // SetRegions sets the flag that allows to define regions in the text. See class // description for details. func (t *TextView) SetRegions(regions bool) *TextView { if t.regionTags != regions { t.resetIndex() // This invalidates the entire index. } t.regionTags = regions return t } // SetChangedFunc sets a handler function which is called when the text of the // text view has changed. This is useful when text is written to this // [io.Writer] in a separate goroutine. Doing so does not automatically cause // the screen to be refreshed so you may want to use the "changed" handler to // redraw the screen. // // Note that to avoid race conditions or deadlocks, there are a few rules you // should follow: // // - You can call [Application.Draw] from this handler. // - You can call [TextView.HasFocus] from this handler. // - During the execution of this handler, access to any other variables from // this primitive or any other primitive must be queued using // [Application.QueueUpdate]. // // See package description for details on dealing with concurrency. func (t *TextView) SetChangedFunc(handler func()) *TextView { t.changed = handler return t } // SetDoneFunc sets a handler which is called when the user presses on the // following keys: Escape, Enter, Tab, Backtab. The key is passed to the // handler. func (t *TextView) SetDoneFunc(handler func(key tcell.Key)) *TextView { t.done = handler return t } // SetHighlightedFunc sets a handler which is called when the list of currently // highlighted regions change. It receives a list of region IDs which were newly // highlighted, those that are not highlighted anymore, and those that remain // highlighted. // // Note that because regions are only determined when drawing the text view, // this function can only fire for regions that have existed when the text view // was last drawn. func (t *TextView) SetHighlightedFunc(handler func(added, removed, remaining []string)) *TextView { t.highlighted = handler return t } // SetFinishedFunc sets a callback invoked when the user leaves this form item. func (t *TextView) SetFinishedFunc(handler func(key tcell.Key)) FormItem { t.finished = handler return t } // SetFormAttributes sets attributes shared by all form items. func (t *TextView) SetFormAttributes(labelWidth int, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem { t.labelWidth = labelWidth t.backgroundColor = bgColor t.labelStyle = t.labelStyle.Foreground(labelColor) // We ignore the field background color because this is a read-only element. t.textStyle = tcell.StyleDefault.Foreground(fieldTextColor).Background(bgColor) return t } // ScrollTo scrolls to the specified row and column (both starting with 0). func (t *TextView) ScrollTo(row, column int) *TextView { if !t.scrollable { return t } t.lineOffset = row t.columnOffset = column t.trackEnd = false return t } // ScrollToBeginning scrolls to the top left corner of the text if the text view // is scrollable. func (t *TextView) ScrollToBeginning() *TextView { if !t.scrollable { return t } t.trackEnd = false t.lineOffset = 0 t.columnOffset = 0 return t } // ScrollToEnd scrolls to the bottom left corner of the text if the text view // is scrollable. Adding new rows to the end of the text view will cause it to // scroll with the new data. func (t *TextView) ScrollToEnd() *TextView { if !t.scrollable { return t } t.trackEnd = true t.columnOffset = 0 return t } // GetScrollOffset returns the number of rows and columns that are skipped at // the top left corner when the text view has been scrolled. func (t *TextView) GetScrollOffset() (row, column int) { return t.lineOffset, t.columnOffset } // Clear removes all text from the buffer. This triggers the "changed" callback. func (t *TextView) Clear() *TextView { t.Lock() defer t.Unlock() t.clear() if t.changed != nil { go t.changed() } return t } // clear is the internal implementation of clear. It is used by TextViewWriter // and anywhere that we need to perform a write without locking the buffer. func (t *TextView) clear() { t.text.Reset() t.resetIndex() } // Highlight specifies which regions should be highlighted. If highlight // toggling is set to true (see [TextView.SetToggleHighlights]), the highlight // of the provided regions is toggled (i.e. highlighted regions are // un-highlighted and vice versa). If toggling is set to false, the provided // regions are highlighted and all other regions will not be highlighted (you // may also provide nil to turn off all highlights). // // For more information on regions, see class description. Empty region strings // or regions not contained in the text are ignored. // // Text in highlighted regions will be drawn inverted, i.e. with their // background and foreground colors swapped. // // If toggling is set to false, clicking outside of any region will remove all // highlights. // // This function is expensive if a specified region is in a part of the text // that has not yet been parsed. func (t *TextView) Highlight(regionIDs ...string) *TextView { // Make sure we know these regions. t.parseAhead(t.lastWidth, func(lineNumber int, line *textViewLine) bool { for _, regionID := range regionIDs { if _, ok := t.regions[regionID]; !ok { return false } } return true }) // Remove unknown regions. newRegions := make([]string, 0, len(regionIDs)) for _, regionID := range regionIDs { if _, ok := t.regions[regionID]; ok { newRegions = append(newRegions, regionID) } } regionIDs = newRegions // Toggle highlights. if t.toggleHighlights { var newIDs []string HighlightLoop: for regionID := range t.highlights { for _, id := range regionIDs { if regionID == id { continue HighlightLoop } } newIDs = append(newIDs, regionID) } for _, regionID := range regionIDs { if _, ok := t.highlights[regionID]; !ok { newIDs = append(newIDs, regionID) } } regionIDs = newIDs } // Now we have a list of region IDs that end up being highlighted. // Determine added and removed regions. var added, removed, remaining []string if t.highlighted != nil { for _, regionID := range regionIDs { if _, ok := t.highlights[regionID]; ok { remaining = append(remaining, regionID) delete(t.highlights, regionID) } else { added = append(added, regionID) } } for regionID := range t.highlights { removed = append(removed, regionID) } } // Make new selection. t.highlights = make(map[string]struct{}) for _, id := range regionIDs { if id == "" { continue } t.highlights[id] = struct{}{} } // Notify. if t.highlighted != nil && (len(added) > 0 || len(removed) > 0) { t.highlighted(added, removed, remaining) } return t } // GetHighlights returns the IDs of all currently highlighted regions. func (t *TextView) GetHighlights() (regionIDs []string) { for id := range t.highlights { regionIDs = append(regionIDs, id) } return } // SetToggleHighlights sets a flag to determine how regions are highlighted. // When set to true, the [TextView.Highlight] function (or a mouse click) will // toggle the provided/selected regions. When set to false, [TextView.Highlight] // (or a mouse click) will simply highlight the provided regions. func (t *TextView) SetToggleHighlights(toggle bool) *TextView { t.toggleHighlights = toggle return t } // ScrollToHighlight will cause the visible area to be scrolled so that the // highlighted regions appear in the visible area of the text view. This // repositioning happens the next time the text view is drawn. It happens only // once so you will need to call this function repeatedly to always keep // highlighted regions in view. // // Nothing happens if there are no highlighted regions or if the text view is // not scrollable. func (t *TextView) ScrollToHighlight() *TextView { if len(t.highlights) == 0 || !t.scrollable || !t.regionTags { return t } t.scrollToHighlights = true t.trackEnd = false return t } // GetRegionText returns the text of the first region with the given ID. If // dynamic colors are enabled, style tags are stripped from the text. // // If the region does not exist or if regions are turned off, an empty string // is returned. // // This function can be expensive if the specified region is way beyond the // visible area of the text view as the text needs to be parsed until the region // can be found, or if the region does not contain any text. func (t *TextView) GetRegionText(regionID string) string { if !t.regionTags || regionID == "" { return "" } // Parse until we find the region. lineNumber, ok := t.regions[regionID] if !ok { lineNumber = -1 t.parseAhead(t.lastWidth, func(number int, line *textViewLine) bool { lineNumber, ok = t.regions[regionID] return ok }) if lineNumber < 0 { return "" // We couldn't find this region. } } // Extract text from region. var ( line = t.lineIndex[lineNumber] text = t.text.String()[line.offset:] st = *line.state state = &st options = stepOptionsRegion regionText strings.Builder ) if t.styleTags { options |= stepOptionsStyle } for len(text) > 0 { var ch string ch, text, state = step(text, state, options) if state.region == regionID { regionText.WriteString(ch) } else if regionText.Len() > 0 { break } } return regionText.String() } // GetRegionIDs returns the region IDs within the textview. func (t *TextView) GetRegionIDs() []string { var ( state *stepState regionIDs []string ) text := t.GetText(false) for len(text) > 0 { _, text, state = step(text, state, stepOptionsRegion) if state.region != "" { regionIDs = append(regionIDs, state.region) state.region = "" } } return regionIDs } // GetRegionStart returns the start position of the region. func (t *TextView) GetRegionStart(region string) int { lineNumber, ok := t.regions[region] if !ok { return 0 } line := t.lineIndex[lineNumber] regions, ok := line.regions[region] if !ok { return 0 } return regions[0] } // Focus is called when this primitive receives focus. func (t *TextView) Focus(delegate func(p Primitive)) { // Implemented here with locking because this is used by layout primitives. t.Lock() defer t.Unlock() // But if we're part of a form and not scrollable, there's nothing the user // can do here so we're finished. if t.finished != nil && !t.scrollable { t.finished(-1) return } t.Box.Focus(delegate) } // HasFocus returns whether or not this primitive has focus. func (t *TextView) HasFocus() bool { // Implemented here with locking because this may be used in the "changed" // callback. t.Lock() defer t.Unlock() return t.Box.HasFocus() } // Write lets us implement the io.Writer interface. func (t *TextView) Write(p []byte) (n int, err error) { t.Lock() defer t.Unlock() return t.write(p) } // write is the internal implementation of Write. It is used by [TextViewWriter] // and anywhere that we need to perform a write without locking the buffer. func (t *TextView) write(p []byte) (n int, err error) { // Notify at the end. changed := t.changed if changed != nil { defer func() { // We always call the "changed" function in a separate goroutine to avoid // deadlocks. go changed() }() } return t.text.Write(p) } // BatchWriter returns a new writer that can be used to write into the buffer // but without Locking/Unlocking the buffer on every write, as [TextView.Write] // and [TextView.Clear] do. The lock will be acquired once when BatchWriter is // called, and will be released when the returned writer is closed. Example: // // tv := tview.NewTextView() // w := tv.BatchWriter() // defer w.Close() // w.Clear() // fmt.Fprintln(w, "To sit in solemn silence") // fmt.Fprintln(w, "on a dull, dark, dock") // fmt.Println(tv.GetText(false)) // // Note that using the batch writer requires you to manage any issues that may // arise from concurrency yourself. See package description for details on // dealing with concurrency. func (t *TextView) BatchWriter() TextViewWriter { t.Lock() return TextViewWriter{ t: t, } } // resetIndex resets all indexed data, including the line index. func (t *TextView) resetIndex() { t.lineIndex = nil t.regions = make(map[string]int) t.longestLine = 0 } // parseAhead parses the text buffer starting at the last line in // [TextView.lineIndex] until either the end of the buffer or until stop returns // true for the last complete line that was parsed. If wrapping is enabled, // width will be used as the available screen width. If width is 0, it is // assumed that there is no wrapping. This can happen when this function is // called before the first time [TextView.Draw] is called. // // There is no guarantee that stop will ever be called. // // The function adds entries to the [TextView.lineIndex] slice and the // [TextView.regions] map and adjusts [TextView.longestLine]. func (t *TextView) parseAhead(width int, stop func(lineNumber int, line *textViewLine) bool) { if t.text.Len() == 0 { return // No text. Nothing to parse. } // If width is 0, make it infinite. if width == 0 { width = math.MaxInt } // What kind of tags do we scan for? var options stepOptions if t.styleTags { options |= stepOptionsStyle } if t.regionTags { options |= stepOptionsRegion } // Start parsing at the last line in the index. var lastLine *textViewLine str := t.text.String() if len(t.lineIndex) == 0 { // Insert the first line. lastLine = &textViewLine{ state: &stepState{ unisegState: -1, style: t.textStyle, }, } t.lineIndex = append(t.lineIndex, lastLine) } else { // Reset the last line. lastLine = t.lineIndex[len(t.lineIndex)-1] lastLine.width = 0 lastLine.length = 0 str = str[lastLine.offset:] } // Parse. var ( lastOption int // Text index of the last optional split point. lastOptionWidth int // Line width at last optional split point. lastOptionState *stepState // State at last optional split point. leftPos int // The current position in the line (only for left-alignment). offset = lastLine.offset // Text index of the current position. st = *lastLine.state // Current state. state = &st // Pointer to current state. ) for len(str) > 0 { var c string region := state.region c, str, state = step(str, state, options) w := state.Width() if c == "\t" { if t.align == AlignLeft { w = TabSize - leftPos%TabSize } else { w = TabSize } } length := state.GrossLength() // Would it exceed the line width? if t.wrap && lastLine.width+w > width { if lastOptionWidth == 0 { // No split point so far. Just split at the current position. if stop(len(t.lineIndex)-1, lastLine) { return } st := *state lastLine = &textViewLine{ offset: offset, state: &st, } lastOption, lastOptionWidth, leftPos = 0, 0, 0 } else { // Split at the last split point. newLine := &textViewLine{ offset: lastLine.offset + lastOption, width: lastLine.width - lastOptionWidth, length: lastLine.length - lastOption, state: lastOptionState, } lastLine.width = lastOptionWidth lastLine.length = lastOption if stop(len(t.lineIndex)-1, lastLine) { return } lastLine = newLine lastOption, lastOptionWidth = 0, 0 leftPos -= lastOptionWidth } t.lineIndex = append(t.lineIndex, lastLine) } // Move ahead. lastLine.width += w lastLine.length += length offset += length leftPos += w // Do we have a new longest line? if lastLine.width > t.longestLine { t.longestLine = lastLine.width } // Check for split points. if lineBreak, optional := state.LineBreak(); lineBreak { if optional { if t.wrap && t.wordWrap { // Remember this split point. lastOption = offset - lastLine.offset lastOptionWidth = lastLine.width st := *state lastOptionState = &st } } else { // We must split here. if stop(len(t.lineIndex)-1, lastLine) { return } st := *state lastLine = &textViewLine{ offset: offset, state: &st, } t.lineIndex = append(t.lineIndex, lastLine) lastOption, lastOptionWidth, leftPos = 0, 0, 0 } } // Add new regions if any. if t.regionTags && state.region != "" && state.region != region { if _, ok := t.regions[state.region]; !ok { t.regions[state.region] = len(t.lineIndex) - 1 } } } } // Draw draws this primitive onto the screen. func (t *TextView) Draw(screen tcell.Screen) { t.Box.DrawForSubclass(screen, t) t.Lock() defer t.Unlock() // Get the available size. x, y, width, height := t.GetInnerRect() t.pageSize = height // Draw label. _, labelBg, _ := t.labelStyle.Decompose() if t.labelWidth > 0 { labelWidth := t.labelWidth if labelWidth > width { labelWidth = width } printWithStyle(screen, t.label, x, y, 0, labelWidth, AlignLeft, t.labelStyle, labelBg == tcell.ColorDefault) x += labelWidth width -= labelWidth } else { _, _, drawnWidth := printWithStyle(screen, t.label, x, y, 0, width, AlignLeft, t.labelStyle, labelBg == tcell.ColorDefault) x += drawnWidth width -= drawnWidth } // What's the space for the text element? if t.width > 0 && t.width < width { width = t.width } if t.height > 0 && t.height < height { height = t.height } if width <= 0 { return // No space left for the text area. } // Draw the text element if necessary. _, bg, _ := t.textStyle.Decompose() if bg != t.backgroundColor { for row := 0; row < height; row++ { for column := 0; column < width; column++ { screen.SetContent(x+column, y+row, ' ', nil, t.textStyle) } } } // If the width has changed, we need to reindex. if width != t.lastWidth && t.wrap { t.resetIndex() } t.lastWidth = width // What are our parse options? var options stepOptions if t.styleTags { options |= stepOptionsStyle } if t.regionTags { options |= stepOptionsRegion } // Scroll to highlighted regions. if t.regionTags && t.scrollToHighlights { // Make sure we know all highlighted regions. t.parseAhead(width, func(lineNumber int, line *textViewLine) bool { for regionID := range t.highlights { if _, ok := t.regions[regionID]; !ok { return false } t.highlights[regionID] = struct{}{} } return true }) // What is the line range for all highlighted regions? var ( firstRegion string fromHighlight, toHighlight int ) for regionID := range t.highlights { // We can safely assume that the region is known. line := t.regions[regionID] if firstRegion == "" || line > toHighlight { toHighlight = line } if firstRegion == "" || line < fromHighlight { fromHighlight = line firstRegion = regionID } } if firstRegion != "" { // Do we fit the entire height? if toHighlight-fromHighlight+1 < height { // Yes, let's center the highlights. t.lineOffset = (fromHighlight + toHighlight - height) / 2 } else { // No, let's move to the start of the highlights. t.lineOffset = fromHighlight } // If the highlight is too far to the right, move it to the middle. if t.wrap { // Find the first highlight's column in screen space. line := t.lineIndex[fromHighlight] st := *line.state state := &st str := t.text.String()[line.offset:] var posHighlight int for len(str) > 0 && posHighlight < line.width && state.region != firstRegion { _, str, state = step(str, state, options) posHighlight += state.Width() } if posHighlight-t.columnOffset > 3*width/4 { t.columnOffset = posHighlight - width/2 } // If the highlight is off-screen on the left, move it on-screen. if posHighlight-t.columnOffset < 0 { t.columnOffset = posHighlight - width/4 } } } } t.scrollToHighlights = false // Make sure our index has enough lines. t.parseAhead(width, func(lineNumber int, line *textViewLine) bool { return lineNumber >= t.lineOffset+height }) // Adjust line offset. if t.trackEnd { t.parseAhead(width, func(lineNumber int, line *textViewLine) bool { return false }) t.lineOffset = len(t.lineIndex) - height } if t.lineOffset > len(t.lineIndex)-height { t.lineOffset = len(t.lineIndex) - height } if t.lineOffset < 0 { t.lineOffset = 0 } // Adjust column offset. if t.align == AlignLeft || t.align == AlignRight { if t.columnOffset+width > t.longestLine { t.columnOffset = t.longestLine - width } if t.columnOffset < 0 { t.columnOffset = 0 } } else { // AlignCenter. half := (t.longestLine - width) / 2 if half > 0 { if t.columnOffset > half { t.columnOffset = half } if t.columnOffset < -half { t.columnOffset = -half } } else { t.columnOffset = 0 } } // Draw visible lines. for line := t.lineOffset; line < len(t.lineIndex); line++ { // Are we done? if line-t.lineOffset >= height { break } info := t.lineIndex[line] info.regions = nil // Determine starting point of the text and the screen. var skipWidth, xPos int switch t.align { case AlignLeft: skipWidth = t.columnOffset case AlignCenter: skipWidth = t.columnOffset + (info.width-width)/2 if skipWidth < 0 { skipWidth = 0 xPos = (width-info.width)/2 - t.columnOffset } case AlignRight: maxWidth := width if t.longestLine > width { maxWidth = t.longestLine } skipWidth = t.columnOffset - (maxWidth - info.width) if skipWidth < 0 { skipWidth = 0 xPos = maxWidth - info.width - t.columnOffset } } // Draw the line text. str := t.text.String()[info.offset:] st := *info.state state := &st var processed int for len(str) > 0 && xPos < width && processed < info.length { var ch string ch, str, state = step(str, state, options) w := state.Width() if ch == "\t" { if t.align == AlignLeft { w = TabSize - xPos%TabSize } else { w = TabSize } } processed += state.GrossLength() // Don't draw anything while we skip characters. if skipWidth > 0 { skipWidth -= w continue } // Draw this character. if w > 0 { style := state.Style() // Do we highlight this character? var highlighted bool if state.region != "" { if _, ok := t.highlights[state.region]; ok { highlighted = true } } if highlighted { fg, bg, _ := style.Decompose() if bg == t.backgroundColor { r, g, b := fg.RGB() c := colorful.Color{R: float64(r) / 255, G: float64(g) / 255, B: float64(b) / 255} _, _, li := c.Hcl() if li < .5 { bg = tcell.ColorWhite } else { bg = tcell.ColorBlack } } style = style.Background(fg).Foreground(bg) } // Paint on screen. for offset := w - 1; offset >= 0; offset-- { runes := []rune(ch) if offset == 0 { screen.SetContent(x+xPos+offset, y+line-t.lineOffset, runes[0], runes[1:], style) } else { screen.SetContent(x+xPos+offset, y+line-t.lineOffset, ' ', nil, style) } } // Register this region. if state.region != "" { if info.regions == nil { info.regions = make(map[string][2]int) } fromTo, ok := info.regions[state.region] if !ok { fromTo = [2]int{xPos, xPos + w} } else { if xPos < fromTo[0] { fromTo[0] = xPos } if xPos+w > fromTo[1] { fromTo[1] = xPos + w } } info.regions[state.region] = fromTo } } xPos += w } } // If this view is not scrollable, we'll purge the buffer of lines that have // scrolled out of view. var purgeStart int if !t.scrollable && t.lineOffset > 0 { purgeStart = t.lineOffset } // If we reached the maximum number of lines, we'll purge the buffer of the // oldest lines. if t.maxLines > 0 && len(t.lineIndex) > t.maxLines { purgeStart = len(t.lineIndex) - t.maxLines } // Purge. if purgeStart > 0 && purgeStart < len(t.lineIndex) { newText := t.text.String()[t.lineIndex[purgeStart].offset:] t.text.Reset() t.text.WriteString(newText) t.resetIndex() t.lineOffset = 0 } } // InputHandler returns the handler for this primitive. func (t *TextView) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) { return t.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) { key := event.Key() if key == tcell.KeyEscape || key == tcell.KeyEnter || key == tcell.KeyTab || key == tcell.KeyBacktab { if t.done != nil { t.done(key) } if t.finished != nil { t.finished(key) } return } if !t.scrollable { return } switch key { case tcell.KeyRune: switch event.Rune() { case 'g': // Home. t.trackEnd = false t.lineOffset = 0 t.columnOffset = 0 case 'G': // End. t.trackEnd = true t.columnOffset = 0 case 'j': // Down. t.lineOffset++ case 'k': // Up. t.trackEnd = false t.lineOffset-- case 'h': // Left. t.columnOffset-- case 'l': // Right. t.columnOffset++ } case tcell.KeyHome: t.trackEnd = false t.lineOffset = 0 t.columnOffset = 0 case tcell.KeyEnd: t.trackEnd = true t.columnOffset = 0 case tcell.KeyUp: t.trackEnd = false t.lineOffset-- case tcell.KeyDown: t.lineOffset++ case tcell.KeyLeft: t.columnOffset-- case tcell.KeyRight: t.columnOffset++ case tcell.KeyPgDn, tcell.KeyCtrlF: t.lineOffset += t.pageSize case tcell.KeyPgUp, tcell.KeyCtrlB: t.trackEnd = false t.lineOffset -= t.pageSize } }) } // MouseHandler returns the mouse handler for this primitive. func (t *TextView) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return t.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { x, y := event.Position() if !t.InRect(x, y) { return false, nil } rectX, rectY, width, height := t.GetInnerRect() switch action { case MouseLeftDown: setFocus(t) consumed = true case MouseLeftClick: if t.regionTags { // Find a region to highlight. x -= rectX y -= rectY var highlightedID string if y+t.lineOffset < len(t.lineIndex) { line := t.lineIndex[y+t.lineOffset] for regionID, fromTo := range line.regions { if x >= fromTo[0] && x < fromTo[1] { highlightedID = regionID break } } } if highlightedID != "" { t.Highlight(highlightedID) } else if !t.toggleHighlights { t.Highlight() } } consumed = true case MouseScrollUp: if !t.scrollable { break } t.trackEnd = false t.lineOffset-- consumed = true case MouseScrollDown: if !t.scrollable { break } t.lineOffset++ if len(t.lineIndex)-t.lineOffset < height { // If we scroll to the end, turn on tracking. t.parseAhead(width, func(lineNumber int, line *textViewLine) bool { return len(t.lineIndex)-t.lineOffset < height }) if len(t.lineIndex)-t.lineOffset < height { t.trackEnd = true } } consumed = true } return }) } golang-github-darkhz-tview-0.0~git20240308.6078a88/treeview.go000066400000000000000000000610621457770046000233660ustar00rootroot00000000000000package tview import ( "github.com/gdamore/tcell/v2" ) // Tree navigation events. const ( treeNone int = iota treeHome treeEnd treeMove treeParent treeChild treeScroll // Move without changing the selection, even when off screen. ) // TreeNode represents one node in a tree view. type TreeNode struct { // The reference object. reference interface{} // This node's child nodes. children []*TreeNode // The item's text. text string // The text color. color tcell.Color // Whether or not this node can be selected. selectable bool // Whether or not this node's children should be displayed. expanded bool // The additional horizontal indent of this node's text. indent int // An optional function which is called when the user selects this node. selected func() // The hierarchy level (0 for the root, 1 for its children, and so on). This // is only up to date immediately after a call to process() (e.g. via // Draw()). level int // Temporary member variables. parent *TreeNode // The parent node (nil for the root). graphicsX int // The x-coordinate of the left-most graphics rune. textX int // The x-coordinate of the first rune of the text. } // NewTreeNode returns a new tree node. func NewTreeNode(text string) *TreeNode { return &TreeNode{ text: text, color: Styles.PrimaryTextColor, indent: 2, expanded: true, selectable: true, } } // Walk traverses this node's subtree in depth-first, pre-order (NLR) order and // calls the provided callback function on each traversed node (which includes // this node) with the traversed node and its parent node (nil for this node). // The callback returns whether traversal should continue with the traversed // node's child nodes (true) or not recurse any deeper (false). func (n *TreeNode) Walk(callback func(node, parent *TreeNode) bool) *TreeNode { n.parent = nil nodes := []*TreeNode{n} for len(nodes) > 0 { // Pop the top node and process it. node := nodes[len(nodes)-1] nodes = nodes[:len(nodes)-1] if !callback(node, node.parent) { // Don't add any children. continue } // Add children in reverse order. for index := len(node.children) - 1; index >= 0; index-- { node.children[index].parent = node nodes = append(nodes, node.children[index]) } } return n } // SetReference allows you to store a reference of any type in this node. This // will allow you to establish a mapping between the TreeView hierarchy and your // internal tree structure. func (n *TreeNode) SetReference(reference interface{}) *TreeNode { n.reference = reference return n } // GetReference returns this node's reference object. func (n *TreeNode) GetReference() interface{} { return n.reference } // SetChildren sets this node's child nodes. func (n *TreeNode) SetChildren(childNodes []*TreeNode) *TreeNode { n.children = childNodes return n } // GetParent returns this node's parent node. func (t *TreeNode) GetParent() *TreeNode { return t.parent } // GetText returns this node's text. func (n *TreeNode) GetText() string { return n.text } // GetChildren returns this node's children. func (n *TreeNode) GetChildren() []*TreeNode { return n.children } // ClearChildren removes all child nodes from this node. func (n *TreeNode) ClearChildren() *TreeNode { n.children = nil return n } // AddChild adds a new child node to this node. func (n *TreeNode) AddChild(node *TreeNode) *TreeNode { n.children = append(n.children, node) return n } // RemoveChild removes a child node from this node. If the child node cannot be // found, nothing happens. func (n *TreeNode) RemoveChild(node *TreeNode) *TreeNode { for index, child := range n.children { if child == node { n.children = append(n.children[:index], n.children[index+1:]...) break } } return n } // SetSelectable sets a flag indicating whether this node can be selected by // the user. func (n *TreeNode) SetSelectable(selectable bool) *TreeNode { n.selectable = selectable return n } // SetSelectedFunc sets a function which is called when the user selects this // node by hitting Enter when it is selected. func (n *TreeNode) SetSelectedFunc(handler func()) *TreeNode { n.selected = handler return n } // SetExpanded sets whether or not this node's child nodes should be displayed. func (n *TreeNode) SetExpanded(expanded bool) *TreeNode { n.expanded = expanded return n } // Expand makes the child nodes of this node appear. func (n *TreeNode) Expand() *TreeNode { n.expanded = true return n } // Collapse makes the child nodes of this node disappear. func (n *TreeNode) Collapse() *TreeNode { n.expanded = false return n } // ExpandAll expands this node and all descendent nodes. func (n *TreeNode) ExpandAll() *TreeNode { n.Walk(func(node, parent *TreeNode) bool { node.expanded = true return true }) return n } // CollapseAll collapses this node and all descendent nodes. func (n *TreeNode) CollapseAll() *TreeNode { n.Walk(func(node, parent *TreeNode) bool { n.expanded = false return true }) return n } // IsExpanded returns whether the child nodes of this node are visible. func (n *TreeNode) IsExpanded() bool { return n.expanded } // SetText sets the node's text which is displayed. func (n *TreeNode) SetText(text string) *TreeNode { n.text = text return n } // GetColor returns the node's color. func (n *TreeNode) GetColor() tcell.Color { return n.color } // SetColor sets the node's text color. func (n *TreeNode) SetColor(color tcell.Color) *TreeNode { n.color = color return n } // SetIndent sets an additional indentation for this node's text. A value of 0 // keeps the text as far left as possible with a minimum of line graphics. Any // value greater than that moves the text to the right. func (n *TreeNode) SetIndent(indent int) *TreeNode { n.indent = indent return n } // GetLevel returns the node's level within the hierarchy, where 0 corresponds // to the root node, 1 corresponds to its children, and so on. This is only // guaranteed to be up to date immediately after the tree that contains this // node is drawn. func (n *TreeNode) GetLevel() int { return n.level } // TreeView displays tree structures. A tree consists of nodes (TreeNode // objects) where each node has zero or more child nodes and exactly one parent // node (except for the root node which has no parent node). // // The SetRoot() function is used to specify the root of the tree. Other nodes // are added locally to the root node or any of its descendents. See the // TreeNode documentation for details on node attributes. (You can use // SetReference() to store a reference to nodes of your own tree structure.) // // Nodes can be selected by calling SetCurrentNode(). The user can navigate the // selection or the tree by using the following keys: // // - j, down arrow, right arrow: Move (the selection) down by one node. // - k, up arrow, left arrow: Move (the selection) up by one node. // - g, home: Move (the selection) to the top. // - G, end: Move (the selection) to the bottom. // - J: Move (the selection) up one level (if that node is selectable). // - K: Move (the selection) to the last node one level down (if any). // - Ctrl-F, page down: Move (the selection) down by one page. // - Ctrl-B, page up: Move (the selection) up by one page. // // Selected nodes can trigger the "selected" callback when the user hits Enter. // // The root node corresponds to level 0, its children correspond to level 1, // their children to level 2, and so on. Per default, the first level that is // displayed is 0, i.e. the root node. You can call SetTopLevel() to hide // levels. // // If graphics are turned on (see SetGraphics()), lines indicate the tree's // hierarchy. Alternative (or additionally), you can set different prefixes // using SetPrefixes() for different levels, for example to display hierarchical // bullet point lists. // // See https://github.com/rivo/tview/wiki/TreeView for an example. type TreeView struct { *Box // The root node. root *TreeNode // The currently selected node or nil if no node is selected. currentNode *TreeNode // The last note that was selected or nil of there is no such node. lastNode *TreeNode // The movement to be performed during the call to Draw(), one of the // constants defined above. movement int // The number of nodes to move down or up, when movement is treeMove, // excluding non-selectable nodes for selection movement, including them for // scrolling. step int // The top hierarchical level shown. (0 corresponds to the root level.) topLevel int // Strings drawn before the nodes, based on their level. prefixes []string // Vertical scroll offset. offsetY int // If set to true, all node texts will be aligned horizontally. align bool // If set to true, the tree structure is drawn using lines. graphics bool // The color of the lines. graphicsColor tcell.Color // Style for the currently selected node. selectedStyle tcell.Style // An optional function which is called when the user has navigated to a new // tree node. changed func(node *TreeNode) // An optional function which is called when a tree item was selected. selected func(node *TreeNode) // An optional function which is called when the user moves away from this // primitive. done func(key tcell.Key) // The visible nodes, top-down, as set by process(). nodes []*TreeNode // Temporarily set to true while we know that the tree has not changed and // therefore does not need to be reprocessed. stableNodes bool } // NewTreeView returns a new tree view. func NewTreeView() *TreeView { return &TreeView{ Box: NewBox(), graphics: true, graphicsColor: Styles.GraphicsColor, } } // SetRoot sets the root node of the tree. func (t *TreeView) SetRoot(root *TreeNode) *TreeView { t.root = root return t } // GetRoot returns the root node of the tree. If no such node was previously // set, nil is returned. func (t *TreeView) GetRoot() *TreeNode { return t.root } // SetCurrentNode sets the currently selected node. Provide nil to clear all // selections. Selected nodes must be visible and selectable, or else the // selection will be changed to the top-most selectable and visible node. // // This function does NOT trigger the "changed" callback because the actual node // that will be selected is not known until the tree is drawn. Triggering the // "changed" callback is thus deferred until the next call to [TreeView.Draw]. func (t *TreeView) SetCurrentNode(node *TreeNode) *TreeView { t.currentNode = node return t } // GetCurrentNode returns the currently selected node or nil of no node is // currently selected. func (t *TreeView) GetCurrentNode() *TreeNode { return t.currentNode } // GetPath returns all nodes located on the path from the root to the given // node, including the root and the node itself. If there is no root node, nil // is returned. If there are multiple paths to the node, a random one is chosen // and returned. func (t *TreeView) GetPath(node *TreeNode) []*TreeNode { if t.root == nil { return nil } var f func(current *TreeNode, path []*TreeNode) []*TreeNode f = func(current *TreeNode, path []*TreeNode) []*TreeNode { if current == node { return path } for _, child := range current.children { newPath := make([]*TreeNode, len(path), len(path)+1) copy(newPath, path) if p := f(child, append(newPath, child)); p != nil { return p } } return nil } return f(t.root, []*TreeNode{t.root}) } // SetTopLevel sets the first tree level that is visible with 0 referring to the // root, 1 to the root's child nodes, and so on. Nodes above the top level are // not displayed. func (t *TreeView) SetTopLevel(topLevel int) *TreeView { t.topLevel = topLevel return t } // SetPrefixes defines the strings drawn before the nodes' texts. This is a // slice of strings where each element corresponds to a node's hierarchy level, // i.e. 0 for the root, 1 for the root's children, and so on (levels will // cycle). // // For example, to display a hierarchical list with bullet points: // // treeView.SetGraphics(false). // SetPrefixes([]string{"* ", "- ", "x "}) // // Deeper levels will cycle through the prefixes. func (t *TreeView) SetPrefixes(prefixes []string) *TreeView { t.prefixes = prefixes return t } // SetAlign controls the horizontal alignment of the node texts. If set to true, // all texts except that of top-level nodes will be placed in the same column. // If set to false, they will indent with the hierarchy. func (t *TreeView) SetAlign(align bool) *TreeView { t.align = align return t } // SetGraphics sets a flag which determines whether or not line graphics are // drawn to illustrate the tree's hierarchy. func (t *TreeView) SetGraphics(showGraphics bool) *TreeView { t.graphics = showGraphics return t } // SetGraphicsColor sets the colors of the lines used to draw the tree structure. func (t *TreeView) SetGraphicsColor(color tcell.Color) *TreeView { t.graphicsColor = color return t } // SetSelectedStyle sets the style for the currently selected node. func (t *TreeView) SetSelectedStyle(style tcell.Style) *TreeView { t.selectedStyle = style return t } // SetChangedFunc sets the function which is called when the currently selected // node changes, for example when the user navigates to a new tree node. func (t *TreeView) SetChangedFunc(handler func(node *TreeNode)) *TreeView { t.changed = handler return t } // SetSelectedFunc sets the function which is called when the user selects a // node by pressing Enter on the current selection. func (t *TreeView) SetSelectedFunc(handler func(node *TreeNode)) *TreeView { t.selected = handler return t } // SetDoneFunc sets a handler which is called whenever the user presses the // Escape, Tab, or Backtab key. func (t *TreeView) SetDoneFunc(handler func(key tcell.Key)) *TreeView { t.done = handler return t } // GetScrollOffset returns the number of node rows that were skipped at the top // of the tree view. Note that when the user navigates the tree view, this value // is only updated after the tree view has been redrawn. func (t *TreeView) GetScrollOffset() int { return t.offsetY } // GetRowCount returns the number of "visible" nodes. This includes nodes which // fall outside the tree view's box but notably does not include the children // of collapsed nodes. Note that this value is only up to date after the tree // view has been drawn. func (t *TreeView) GetRowCount() int { return len(t.nodes) } // Move moves the selection (if a node is currently selected) or scrolls the // tree view (if there is no selection), by the given offset (positive values to // move/scroll down, negative values to move/scroll up). For selection changes, // the offset refers to the number selectable, visible nodes. For scrolling, the // offset refers to the number of visible nodes. // // If the offset is 0, nothing happens. func (t *TreeView) Move(offset int) *TreeView { if offset == 0 { return t } t.movement = treeMove t.step = offset t.process(false) return t } // process builds the visible tree, populates the "nodes" slice, and processes // pending movement actions. Set "drawingAfter" to true if you know that // [TreeView.Draw] will be called immediately after this function (to avoid // having [TreeView.Draw] call it again). func (t *TreeView) process(drawingAfter bool) { t.stableNodes = drawingAfter _, _, _, height := t.GetInnerRect() // Determine visible nodes and their placement. t.nodes = nil if t.root == nil { return } parentSelectedIndex, selectedIndex, topLevelGraphicsX := -1, -1, -1 var graphicsOffset, maxTextX int if t.graphics { graphicsOffset = 1 } t.root.Walk(func(node, parent *TreeNode) bool { // Set node attributes. node.parent = parent if parent == nil { node.level = 0 node.graphicsX = 0 node.textX = 0 } else { node.level = parent.level + 1 node.graphicsX = parent.textX node.textX = node.graphicsX + graphicsOffset + node.indent } if !t.graphics && t.align { // Without graphics, we align nodes on the first column. node.textX = 0 } if node.level == t.topLevel { // No graphics for top level nodes. node.graphicsX = 0 node.textX = 0 } // Add the node to the list. if node.level >= t.topLevel { // This node will be visible. if node.textX > maxTextX { maxTextX = node.textX } if node == t.currentNode && node.selectable { selectedIndex = len(t.nodes) // Also find parent node. for index := len(t.nodes) - 1; index >= 0; index-- { if t.nodes[index] == parent && t.nodes[index].selectable { parentSelectedIndex = index break } } } // Maybe we want to skip this level. if t.topLevel == node.level && (topLevelGraphicsX < 0 || node.graphicsX < topLevelGraphicsX) { topLevelGraphicsX = node.graphicsX } t.nodes = append(t.nodes, node) } // Recurse if desired. return node.expanded }) // Post-process positions. for _, node := range t.nodes { // If text must align, we correct the positions. if t.align && node.level > t.topLevel { node.textX = maxTextX } // If we skipped levels, shift to the left. if topLevelGraphicsX > 0 { node.graphicsX -= topLevelGraphicsX node.textX -= topLevelGraphicsX } } // Process selection. (Also trigger events if necessary.) if selectedIndex >= 0 { // Move the selection. switch t.movement { case treeMove: for t.step < 0 { // Going up. index := selectedIndex for index > 0 { index-- if t.nodes[index].selectable { selectedIndex = index break } } t.step++ } for t.step > 0 { // Going down. index := selectedIndex for index < len(t.nodes)-1 { index++ if t.nodes[index].selectable { selectedIndex = index break } } t.step-- } case treeParent: if parentSelectedIndex >= 0 { selectedIndex = parentSelectedIndex } case treeChild: index := selectedIndex for index < len(t.nodes)-1 { index++ if t.nodes[index].selectable && t.nodes[index].parent == t.nodes[selectedIndex] { selectedIndex = index } } } t.currentNode = t.nodes[selectedIndex] // Move selection into viewport. if t.movement != treeScroll { if selectedIndex-t.offsetY >= height { t.offsetY = selectedIndex - height + 1 } if selectedIndex < t.offsetY { t.offsetY = selectedIndex } if t.movement != treeHome && t.movement != treeEnd { // treeScroll, treeHome, and treeEnd are handled by Draw(). t.movement = treeNone t.step = 0 } } } else { // If selection is not visible or selectable, select the first candidate. if t.currentNode != nil { for index, node := range t.nodes { if node.selectable { selectedIndex = index t.currentNode = node break } } } if selectedIndex < 0 { t.currentNode = nil } } // Trigger "changed" callback. if t.changed != nil && t.currentNode != nil && t.currentNode != t.lastNode { t.changed(t.currentNode) } t.lastNode = t.currentNode } // Draw draws this primitive onto the screen. func (t *TreeView) Draw(screen tcell.Screen) { t.Box.DrawForSubclass(screen, t) if t.root == nil { return } _, totalHeight := screen.Size() if !t.stableNodes { t.process(false) } else { t.stableNodes = false } // Scroll the tree, t.movement is treeNone after process() when there is a // selection, except for treeScroll, treeHome, and treeEnd. x, y, width, height := t.GetInnerRect() switch t.movement { case treeMove, treeScroll: t.offsetY += t.step case treeHome: t.offsetY = 0 case treeEnd: t.offsetY = len(t.nodes) } t.movement = treeNone // Fix invalid offsets. if t.offsetY >= len(t.nodes)-height { t.offsetY = len(t.nodes) - height } if t.offsetY < 0 { t.offsetY = 0 } // Draw the tree. posY := y lineStyle := tcell.StyleDefault.Background(t.backgroundColor).Foreground(t.graphicsColor) for index, node := range t.nodes { // Skip invisible parts. if posY >= y+height+1 || posY >= totalHeight { break } if index < t.offsetY { continue } // Draw the graphics. if t.graphics { // Draw ancestor branches. ancestor := node.parent for ancestor != nil && ancestor.parent != nil && ancestor.parent.level >= t.topLevel { if ancestor.graphicsX >= width { continue } // Draw a branch if this ancestor is not a last child. if ancestor.parent.children[len(ancestor.parent.children)-1] != ancestor { if posY-1 >= y && ancestor.textX > ancestor.graphicsX { PrintJoinedSemigraphics(screen, x+ancestor.graphicsX, posY-1, Borders.Vertical, lineStyle) } if posY < y+height { screen.SetContent(x+ancestor.graphicsX, posY, Borders.Vertical, nil, lineStyle) } } ancestor = ancestor.parent } if node.textX > node.graphicsX && node.graphicsX < width { // Connect to the node above. if posY-1 >= y && t.nodes[index-1].graphicsX <= node.graphicsX && t.nodes[index-1].textX > node.graphicsX { PrintJoinedSemigraphics(screen, x+node.graphicsX, posY-1, Borders.TopLeft, lineStyle) } // Join this node. if posY < y+height { screen.SetContent(x+node.graphicsX, posY, Borders.BottomLeft, nil, lineStyle) for pos := node.graphicsX + 1; pos < node.textX && pos < width; pos++ { screen.SetContent(x+pos, posY, Borders.Horizontal, nil, lineStyle) } } } } // Draw the prefix and the text. if node.textX < width && posY < y+height { // Prefix. var prefixWidth int if len(t.prefixes) > 0 { _, prefixWidth = Print(screen, t.prefixes[(node.level-t.topLevel)%len(t.prefixes)], x+node.textX, posY, width-node.textX, AlignLeft, node.color) } // Text. if node.textX+prefixWidth < width { style := tcell.StyleDefault.Background(t.backgroundColor).Foreground(node.color) if node == t.currentNode { if t.selectedStyle != (tcell.Style{}) { style = t.selectedStyle } else { style = tcell.StyleDefault.Background(node.color).Foreground(t.backgroundColor) } } printWithStyle(screen, node.text, x+node.textX+prefixWidth, posY, 0, width-node.textX-prefixWidth, AlignLeft, style, false) } } // Advance. posY++ } } // InputHandler returns the handler for this primitive. func (t *TreeView) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) { return t.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p Primitive)) { selectNode := func() { node := t.currentNode if node != nil { if t.selected != nil { t.selected(node) } if node.selected != nil { node.selected() } } } // Because the tree is flattened into a list only at drawing time, we also // postpone the (selection) movement to drawing time. switch key := event.Key(); key { case tcell.KeyTab, tcell.KeyBacktab, tcell.KeyEscape: if t.done != nil { t.done(key) } case tcell.KeyDown, tcell.KeyRight: t.movement = treeMove t.step = 1 case tcell.KeyUp, tcell.KeyLeft: t.movement = treeMove t.step = -1 case tcell.KeyHome: t.movement = treeHome case tcell.KeyEnd: t.movement = treeEnd case tcell.KeyPgDn, tcell.KeyCtrlF: _, _, _, height := t.GetInnerRect() t.movement = treeMove t.step = height case tcell.KeyPgUp, tcell.KeyCtrlB: _, _, _, height := t.GetInnerRect() t.movement = treeMove t.step = -height case tcell.KeyRune: switch event.Rune() { case 'g': t.movement = treeHome case 'G': t.movement = treeEnd case 'j': t.movement = treeMove t.step = 1 case 'J': t.movement = treeChild case 'k': t.movement = treeMove t.step = -1 case 'K': t.movement = treeParent case ' ': selectNode() } case tcell.KeyEnter: selectNode() } t.process(true) }) } // MouseHandler returns the mouse handler for this primitive. func (t *TreeView) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return t.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { x, y := event.Position() if !t.InRect(x, y) { return false, nil } switch action { case MouseLeftDown: setFocus(t) consumed = true case MouseLeftClick: _, rectY, _, _ := t.GetInnerRect() y += t.offsetY - rectY if y >= 0 && y < len(t.nodes) { node := t.nodes[y] if node.selectable { previousNode := t.currentNode t.currentNode = node if previousNode != node && t.changed != nil { t.changed(node) } if t.selected != nil { t.selected(node) } if node.selected != nil { node.selected() } } } consumed = true case MouseScrollUp: t.movement = treeScroll t.step = -1 consumed = true case MouseScrollDown: t.movement = treeScroll t.step = 1 consumed = true } return }) } golang-github-darkhz-tview-0.0~git20240308.6078a88/tview.gif000066400000000000000000035551101457770046000230370ustar00rootroot00000000000000GIF89aM1pn |VX  $# "   1 lj;YS 0/ 1!!D -'=?()jG N  M  ! !A $j HF!! "%*"/."TR#CP$&$$v%&&()((*H)$)%")+)****,%*1+++1,-.'-.-.//1/08'172C33)3B"443525>674787978 99:<;;$#;;8;<;;=<<<<><<>?>?<)?@X@A&AGBC$BCBEMFF%#FGFFHDFHEFHEGG GH0GHFGIGGLJHK'IJHJL*K/(KMJKNLLM+LMKM# MNOMPMNO,NS-OOMOPOOPOPQAPQPQ2QRPQYRRQRS?RTRRTRST/STRSTRSV0SWUT$"TTSTUTTVTTW,T^UU674787978 99:<;;$#;;8;<;;=<<<<><<>?>?<)?@X@A&AGBC$BCBEMFF%#FGFFHDFHEGG GH0GHFGIGGLJHK'IJHJL*K/(KMJKNLLM+LMKM# MNOMPMNO,NS-OOMOPOPQAPQPQ2QRPQYRRQRS?RTRST/STRSV0SWUT$"TTSTUTTVTTW,T^UUP 6`Hao<-9S؍@(C+Ha _!4լ.bQ)t}-ɰ[Ǔg  A NfA W9@@oKϲŠHsYP*n B 7.{n{D  bK1Rxlm/ϪA3ːB  l&Ċ3`F`4S6CtN-xӯ@СdzAxL3LR4 CEd`r AvDb M]AdF džXQ9:sXXR 2.,Ou`\ꁍ_(P#ƺFŬ+ "[E8qc`Czp|AAЛY<1`g 2 @=%РJ4 *M.D$E aCQ9< u;%Ez4@7"Hq!k>` d *IAP»޽ZpL}AP ]pEEkb 3T( Z/ Nr[9>F;bhVs7BT@s;"R@Bq|9ыBf6hs > TÀ: R$`1QMV >rn0xv/' ~-4ՋAT0a:{.t]Xvy*+}6ˡɒ4!/@(Ib _0#g: @@qEThjn#n$@ O0`&aT0Qv6v {7sXjX,`H_0r[B&GF#b*ls_"$'c &vj4/vߌtM1q3}Hc[";ȇ{Rxm2βpż5_Ѳ0t_$N= PԨL`ACjZ A_"F F-rv{lg-빎1A F`{G@$ R{up ;~-Wp [U52zkLALTP1Ou| j p`W2VjXv]v][H g7p,}WK6 lpWr}1`qPX]ەxصxxz|QVI#u8V%!Mc HPŵ{Oqu Fak|nx kPX`wL }L7{7ؗw֧<V e^`bwQ5yzlWTM2dVq"؆mvR#-6gw1 g'ȋw"W @1}VHW~у^~ =%g142S=qvu au}F-@-}~wywf f 3h}H H skӘ][؈T݈Џc @%oSԔMbh$sE%Џ 0!00Ney<E) uy>QDiVNj~~:.]^>ֿ^opd^@; 1"GrE76:ȰnOJ_L_-ֻ<. "ˀ^ ^K(/9o;O% DOH j(<)3T4_X,@1ʲ qbIg.jL]%*laݶ6u% #B:PR" Q( 0C 7:#L;` ʳD[MRG5֔ >d/9p-b0"N)˸?DLΠaNń# , EF cL332 2 j,BS+Nbl׈G-TplhI4 P T`9fapE{GH5iD!8ygA@j`" LA  oM AZІ9BDrTi#~M' [b5kZqxC`l "@ ~c  `^:¨!pF ]8dd$M3y@;͐F50DORw'Լ/syrao}#4141!QE1F"$)# Ɣ!" :cJ&cǤd&05 abB 6 uzG<x'>Q mTנ5A dhF*i-F5:_@f0QvD'~f0_D|g7!Sy*:9ә0kThy,9@)*Lb?}2`"0 \%l%*" t?Bse(- 2> - XWT`Q-XA jFH0Hl97xdX _00,"q!ET m(Q6 MI!, ,L3Za"x;^Y};tjmd#H*y׀J "AH4z!UFjgH HX ,F1q`u @z, @7\  !'4Ѝ,CNJDXF <mFQ XP#F @]uW]z9́㻎NȻs;fY_DV@/OZ 'Fk d]i@݀ чC7bV"ОAd\8- i/blp;0G+Vx{rqa@T@;Mj0ixw/c.nX%ZRCܹ C*1 j>uQT`|o8O ' 92*O"*)+- .eb}V|,HA Q˒FPe7DA@P/1l7{x[_0`ۛ @CUUi %}Ep a;Xmkn(/(a 2\Ĵix ((5KP`/Xxxe)2(UW0O:8Lb0QbIuTUUvj'=yLZթjJ@Ja`cKQT>X`"ؾC+p! DwcAHnO/pZhOx?Kx-th-LGrGVB)hXTWU\x?ݨEԂP̈giQuL֒U5[Ldy@҈V٥$QHpx/>!QJ%%ђ4Kc<ي0ꆪK j#iYJbYHAH VPn(u]\W WH/PP/ 8 ljp+0:`5@pWWP¥Hzs0XдxړC >\s =UU@'mUu"YH@kf'A)K]"GwUYChsp;6Xb0l>jȀ(]8K( J}Waa_/ p#D= 8gc[p(.TUȅ\PݒH=/W$Dni fh `,l@ ,4-Qݖwzzmզȳ Ddp402-X p- Mh>`Vax"؁6x786t6:]Q*# P` ~K\\莎E9lа) ,h(2]`. Q:I9WS c0WpWL_cd†TV(LC6S] ƠٞujDvŠft"[lUX% *x_cfPvc )_(XCN ZL ]x:R8$т>@w!8(: 1,L$L4'xHKT" |z߽&. i'*0q^b`^E/vgv<5YObs]v,dh#D-\>vj^@fՎeMnv⻦'sHURf .ixizx)N?ȂT8 d@guK σ Д蝎ՑGΈ(架QU>'x&nV]ks jyJF'p(q3zlUe8#*.]!Y4€@@h7;R U6 F'HC3`N[T%X:% P=5K(@HeiiKpWpi5}.†h % ea؂t(7 ]M'pgiqmY>7; ;3 9n[&Urmc#@ox,@w7h,ڄ(0.[᪆M@HpNEi栃X!cx8VxY@r#\JaUH~Bd"u Zx&He8׳&OԳ>DS%lTo`†Վ(԰9ILk맨ܕV|0'o@U߰nkI'Oփ!enx |+VZ3 h(H "QVxiꆵ]6@߂iȅ`9=X' \#M90\ KapYX5 Lj-|&wLc`asigC ҜU` „ 2l!&68QZ3NwB,oūWIsQS9t:uҤFN„ZU-XfɌ-KRc΄@p@!i+ذbǒ[+s~AmG k \!bbQ8':BD @5v3eĒhCL/Y z?b> O c+(d%ٯ&C%h}%שSSDٰdZڒa^2L2Z3(`E@AcCL> k9QE9Q5'OH̤R:0uO~3 80MP#"5\0Q@eOE5UU]eo#/f0 ,pwT;M\HC``&YM+A\2*@t#/af@Ҥ 7xsAB5 XFJ.@M.N@b^Bq %Rk !L^G)BKd#L.50M. Z/V%]9d9)yu 6#9Ҩ -=z-}ۣXT@fTM3 zĠ:!3)!5B0PSa Mx"5A *J)TS2#U(M/1ߪ@@W YDB;d pE/!Gt`PLdFD |GtE3VAܕ5PA `NtAc6A %_@w}@،A%w ,7tYilж X+X XB#(-tn-Xta-$v<{t_KFjHFN`HO"(,\C 8?}Jkb4(0F"U3?tՍ߾>c!>c!P/#kqP ӿ! @<  R.0 Uo,jb\Ujx`ɂABjzRq dHDˆh8ldC׀ A| אe$"v!DkZ Ѽ1[`Yw2#lcULxaD@X>Rp`()aLc#:$Ih$҈wHE*x LlbOySiE}p$bĀ5 @ih@ g(7][Ыt @c~<lkfU uApi + Jڽq RhG<ΰ/ yf(C=8Gl,dt&χNZќ!(D q̃ /)#2("Fш@ JI(cTi*1O`)=p3!.X_l""$| xNZB,bǀ ;  h "~1[(hWaR% |q"sAB*9 rAU <<!@]h/!Lj!7' >=+ iXAbPX! x%@>xa@Ta[ǃl::D`O$T (%Zb°\(.,d\e@D@;cő^6h!&p%! @1/c*C,Ac;dַ\{J'A9}%@K B&AF. )B(5&ƍ5dC9bU _#1(wZwE[520dӱP2e9 r9q_(I3|2z˜F^OmDH" arb;q2ʬTqB,0 .~xᇼ% 0A5_D@e=:d%: BT`ኸ9 U |bqi"ӥTyWїȅyiLsJ~OWkgwo5dHf7юR*H,<|[Ź dM bp; %Ioc_', LZ xZ2A<ܢ@7"HN, N@tJ 6 fPZ]h+2z[_PEYW`NX8%K,Ov Li !0%LCm(6q`z.LX7XX&G7 `,q^~Y-Cؑ3]e[i =e PReË2B$AB116֏B0@BB\2J$, 1 , E7D6&@ @V&@`9LC^ \J Ԕ@Ux)؀vxÁ9 m]X5ؐJA$/PB8HC D9DU`)7LxC7HÄ4XXU·5Y[;P+ !:8ᝠ0 C۶ Q N/O`Ccc!cppc^< >cB(<dL^c @AΏBZٰ t@,H" Ff@jDA3X((čAHA=O^EPhBMN>XNB#:ҚtXuX=!e-42A’E7U|4Q vdC2LCPMQ7 y@ A$hB:6L'zgUYS,CB11'4P0=O8& 0'r+`ޛ1@'v`vbC6L/0^A BV= `A,D4CNkAj4U|+@.UW/xT*3Q\ dLA@Ad T@1@daM6x*2EA-2$2Ҷ} }ö})%ъi, 6/[;*`l] /B I5^ tZTBC"8,A, /t1`( +h j%T0l׼\4@$AxA3  r. 1 @@`@ @r,B)㑚Өlfn9,m5Մ&B D6 4 '@m#6-``.t/` 304I B%\FU,-Tf_@2 +`nݗ*|щ@DX!嶊>XZ,R $ @ Hʎ/fxlRRC6@)m^G-o A0jqrq1(.D'BOF, 1@,d< @\dU `YJ^\0@ɝsZH D3 @ xC)V5H) Cl_1 ,D9lv)2@0@ pn\,d@31D'ζ7@/Pi68"+tr/.gB tlgT&<,t-kp@܁9@@Ld@+ "< AW6 e 0@ T^HbB 9u@bxǮ H0  J1 ( X 8f ٨☒rz1 q J`.1CR4O&Hrq_F1x7+VYŏxpwkW(x ctb d^^aBCс- &uB@Fb0 5Px"^:m%i&0 2`O"6^\H1"'*6$B6+ -t%vQ^h@K`@_e.Ɯ dꅱr_XS1T1_C%qq5 l 'Ђfф60&$+0*B()Mo;w8E%?j8;TP_X<oq=:蠴kǶ>oRWHk8x#nCA!D%w?T,1] `L~)Dz-9ψ;V;'{oCzCl6C}};q",U"}*q[@ @ lgR^x$sw|d 88bzK"Ӧ/L%:o̗7Vzlx794~S>0@㹘9g@!8w*zـtW<`PuWF +,ONס0Pp:{7(wu5kp '9p>% CJ:)C;~m+dʙxn| RMWPvC7tN (;4úG46,loO_8n7Osez[>/rhGy p!@2U6@@@A&TaC!F8bE1Z!͙3*(#Z!fXKdÐA 2aÄAMMX`z4h*X6jtNOa)5j,J 5QXbd "`d[ouHA'rPl1" \Ç'VƎ0C @"g5FW%ʥl *,@)ѭT%^b%Q:TMYj.aBWH5O]u79ac0>~%O]q啃"tʨͯ"pW9'd_!`S]J#/1t+[WlK<ڙj3>h=?[U@'@ prVPR_4 0OlY3%h `Âta׫̰\b% 񈢛Vto2åF'HO! %X3ý-@, c^(l) c81UaH6qġ!`5?Ƒ0DWc#8Acg)٦0ii !XAwȆ`_; emYc-ȞrM4@? pBꅦ P=#0BB yꌼA5B'c`׍_ 1 \ \!cc,}y4 Pԥ nq6э oϢ.@5^;n%k20 ~`8fP 3 F+ aըG'g8 @A 3< yM @xZ@s<Dt6z]HٜoYqdu xCZeH,8Nv/fXtYXK,d1XT,4Z `@B b07gǂ;0GXNȵɑmw|Ayч7}Qozu{~∂ GHV/A93e:Vu 3L, cQ pĈ"!<*C7Gލ;" =Bsr?0ӍX^Ot +0 kHlא4I炂aHvv^n.M1@T` J! .ztj2 ej2ElQ/Hk<|9X3ږ! X  lAQ a ϖ!PْAXX'bî3 !~]  d.]@hV]óL̡@LLaC s)@{$,rFa&l@2k @yRlt AپWG@ ax`A V *}V"RH8x `: twb`ƴpdZa5toJ@N7 C! wg$n| P _@`,K8@^\A}qbb`ϜaZmá՜a\! LWW  A6vOXgw+-Y{-Lv`j^ : 0A^ `8 ^n CH5!JJ<dW׊ l2 8lb̢<DL`H .} n  ҀʥFSfMG @ RNꜯg/E`DyIMQ9UyYrTrƮ09> m0Q,g-u1BpČ0+LZ@h/"b:QPҴ9Yy͹љG\`:ž/'B΄C"#Dr9"\O ϖ40Td:"d SeD빆 :9င̂܎)` Úg::zΌ+V!-r0Vzx4%d RsL02RfW^L!w8t$84BCav 8ԀҮ㊍8T@X@dy6@x  Re: X"С{n"R;8zZԖ`"0n @`FxM b垸0rx! ,[m@@jb  IRAt&T`/`@ bj\!U8h@VhqSॳb8A@@ @ Xueۓ.́B*@ ր |#«;}JK 3,Fn][a Ijcg\b/jCa%"P+pƍ yVA)!D8Ō * U-S$Kh͜;{  tbpڎ)k׷^ k b& Y/b_x=`[+3Z-cJ ְ/"sA0W LNyyd #`L<%0\4E>)fK@ DK29MGCYK-Hc.8Z.ST`  B tqoq WFffSr*T+0.ӌs 螬sj9&Tk,HR7M}N0!!T!b61H]R0aDGR! ! B͈/xUPŪ3;QM5qirG/! y,*j:U bȎEX09|% f0&Bsx0PWBS8)2B6[sZ™Ðy*(L=T9 WWCP A]df%ƸՅ8Lqg2ϛt1' @sXL,0G#{܁@qs"M0 2X%qbPB </`4/)PP8EGf ac%$|(\ԷLIeߓbkxay PcĜʢVDux@lZ1<;D7poL^!JQo6P+r]68@S8C)5Iۂn$rx@ԖTr F4R @21`c>\`H4uPp; p*@č?r ByuvpQ0 [,x5t3(@@0ڀP> ذET 8!X&X׽‰b8lJnf 3 %@xu%Qh/z-8^}]8`c P: 2fPِ N9rƣW'"K(ԢP$%, eybn boRXсXeǃ`4C7P/$LI!7sT-W/hrGG /LkzӜ0-ŇF\ܑCŷ2RPgEXNJf+DM) ߮7d_/ uS]jpS)|Z*]kSI޶gmpJnLdiPA(fBo-Ÿ+r1zX '{Cy[XܡQX5 0c۰F-"d2.Pl9'4.ƨZ0uP* tHxc,acmp-7t"RVQ;G*F F`E+B;D =S"$ 7S®VG Msge >b9VdMB&@3CJŴK SxgQ \Lx(L!y_|`"ԫ~EE>d=e&F/*`A5^V4:5o` 4^ Aܜ=fLo)K`%=H =,wQAlE l. B1lG$2, P ,vU H<*+q p&,-TA m |3{0Pq0 g  D8 @qP ?(%Z8%Sz/T$R,CAUsWGw 0e pO pujWP @ P5QN cf %!`! 6 I@ v4E0G& V6 f /!P8@hb99j@ H9U!M 9 900+ȋ#@ h ,7nG5d40pW@ u {gxpG(x `qpG`! #)! sdH3Q+GWa! p)w D T \ |<"A _ UPKCj/P *@ДA bX L,0+@vZ.@hv0080. M@V9@Hh ;(pYqr W@=,`40V&: qq P q  9R YPzz-7c.֚*ᆿ |;@S`:b İ hҀW$B!*)t <^2>QA`\ 0 QP)]` Vvg9a9g-1I 9( 5CQD,BA0PAv9b&>bEQx7#-AՐݐ|Qw7g0uRḭ̌D gP PxJ I P a*Gy(.>J($O0 ZEUm8ځ` O ! V1   g$AbC ^ urp MFa" w4XUe ƠXM#j3EMhv9l0@M8ʒf + : Q*$3pW$Qpm:f@`#~a T1cݴHɯh=jqVgtU YPV`:Gq8) Q  ?1!p@˄ r K``v@   6/ "F?] ;8218.E:8>vD}P w"}BP*Ө$ C`9VBB\Hq x0I$b0 p@H!`U 0BZ T 0PP9b %pY2,`(DˋY:9۔A& ֺy0낼&bSk$,r2e|4o|ב p4T1!kֶ҉6e&f`)A 5 ,#7a#C%c[Sq})8( 5^ D%$9H. {,c˱R,{Zd- Z_CGVpd E#{&)EUe1Wƶ (dlq0ֳc`S;sSV=a_*C^7d< c|L@_/g 0G3V袖)T @C%NX" IE!E$Ya։Rڦ^dHLFZUc=$ `́H46QNZUoHsf( 0ө _c N*5B q\(ۑH5^,u$] WY5WmW͡EI4$ 0c)`IF Twx ؃OAMf%+@U6q bO0 1^$׊AYf&J{4,zm@ 4@rɢXAiebj0;8 bb9lvΏ>LZ#H#PH&E,(5h8Öq_L"dᥕ@36yJ &$ ȗVvfD!U^.E]l[IRK5Ai@_^Hxhe'3v~01!FY"h.RDψvܨi(:t P o0If4fB ][aFEO3kCMba` F?n~a bz `";Z1sy0!0ɵfERA >^hBi<68nX*U3 FLFer )2ڨٖۡ)!l @l.shy,d bu(1,n h5QYXKtTnv º: CչWT bc#qX^`1C"ⅅX| 0-.dBLm[p8 7$b 4H - `A Fo8&`(d `X \E/ G n @A@N<<Ұd`[hvWԏ3WBG"VP \`A$͏#ݮgHF Gd v@=Ic41>PrdH ]JqxPZ/P}K=$DA1aJXI@V2m,[#8j67~\t .MrFzO;Lx!r4&Ot&g?!RȁH xK&ty_$?e73/KN d 8ĨY<,cmq2F? hD]<4L""8@anFR (6ꑄ4 H @dQ Hx0!dMJ.AlH"V}qVq(ԣ>?c ԫl P8j0l`6 `C0@ r(*3tż ULlڶTrǖXn6A2 D\2^{ $( PD^l!qS1 5m 8*1sFzP7*i/2 `uТWȀL"EhYO/iᩬFCq> iتʆ( =1Na `#˷XV[8+ a1垐! FZu&U;iHA p-Jb0P] |qwBP@ bB83Hت@1f)dD[$ sЌw Bo 1BodA+R+V ФY ;` u!V@an, V _H#MLm@3"%) :Z }L[r_w-o|;~P* ݛa4 yϏЄH^8FO:H([ y:@UKb\b#'yM~r"JhfH I@n|mN8ɋ`aIR$]Kgzӝh# Z]ʄ"8|Y E3~ )d$cz* fԣ< 8„ pRg|xGz)_ʌ/^u@P32xo@OH]V|E,4J:1E_ VXE\ G;Ë6\"G<}g_h2'a6N/‰d Ub' X y3暑1_A.80 <@ȳ[ ۿk q `[X9bA.0:- WـhٜJV0X gh$in(۟B \p }8iDN-3x jC@(8XhW7@n0>[_0J">@Ń:P EQ?C2St?Y(0K[؅dм@EX4/.x! !OsP.) UyT;`$@Foʰ 4lŜ$x`$Fbƴ43G{3-7 HH,H77ȁTG#:j$Hظy${HHHĪ{2ZH,I4i|5EdpAJI̧D4@I)𸟤rp1#ɡ\аIT 0É:JRH OO@ʛZpLl_b` h{.#a7! T8PKB+OMP}C8PO|NЁ[43A_(utHb[Pm@THP h1rhQ;0! 4P]R&<{t+6Q*4_t(;(0aU =&m;vR;194OOkX`Ȃ_(VNUR7T=;BM{! YQJ=U ?РͺTXu&LԶ/3RS/DU^TVX-VBMUkVf}VgVhViɛaScVR:/U^efQV/nVv'd͙5eXٞY Zڟ-Z]`]خ|ՙmZTK.9 ZZZZZZ U҆uZތZ7Gx[[[[[[uMM[JP+.:H(%`\m\}\ɍ\ʝ\˭\̽\\-mȺݛ٥/M%]ܮ8̢\]-˵Kkcؽݐط)]Dݨ-ު0ݡ|]]^|ݽlH^Ä^ޒX^ ___́8D-__=_菱-Kߑ `|M\`F9 RH_ # 0S٤VSx\PR94&v Y,SnأY N-`!  ۆmfRDP0a+fPV%fN*F:P(c N*vZ4NH b<&#Y&~SxgZxg D&fSU>`l=Ga7[m %N[@/ƅADIG-f`n8\dk[ކ[`&n7F+b&I>Ugv[f8[hf&^Zef}c:nW^cyE:Nkvmh%aEa>IfJ8?Q[GZ(chVbkx@NpLr=6bl \fhmgen$͋sc`ewVndS#'f+ddv{騮V_&g0wfbs?s@tAtB/tC?tDOtE_tFotGtHxnDnH@tNtOt :J KgQS߼T7sxuXuYW׀HWP:PBHʞ U@ 4` P+Xho?_#鮈`V({ hZX~bH wW?Pp($`RpˁbOp: P[HX"x_uL`sy(MW P|9H'rT8Xy9j@, y(x[8,hHmH0VcW&wx{4jZ>u)G@x"I{Ï2(09}w~Bu(}$y~@p*"  c|G&Ql R!84621# Ё84cBn|a @A tHQ hqFRb \ƍ"PH@c .#̍y+Ȫb 5  (а$GL96duXI ]Ѓ̌TpC| DI@59/ nա@뢀eu-!@@8 EP7J.2׫!! "kA =>՘Ld!L a/>8Ⱦ^@4łB44A46Пh| M#DC@\"_Q2]T[(&TbGpIPbC=d\A J|g:4'UR`iG`o1tC]` k1DG/x 8]AbMTT(UA-B cF 4CD-P_wBs~ Y6O5z%Us(@RIΕsƙ%[A@`PőA\x5a F)(}:X>6 AO>7| a {]`؍ l{aP]2bZ Nj&C8r Č_gŖăP3YZ%[ލ8cQ T с01(cbZC)( R ԅ W$E$\-WQRt(exPQbًF IsF0U?@2}F1lX$9X.Я@? T (4"} !+`Eqp@CIJ8!(E)1H- "-9r_C'iAPO}4^W`J[:$Er C` 8 x"c{dEq/)[elHC\( HU~\dbd`iEE9,j0aH(:.~$ " Cp:h# .n .l9$1'%:( W>B^9p;eSFhLlTPg)) b1FH:udZB*ɊD| ~cƢQcL>a+11|~;ĺV;aE5!T "Й""8ܕL0tEu}CĘD@)ƹ|A>R6«Xlr[&|=!iL(`PB-ObRE%hݠ_8H!H\DRn=#-V1ާæ#9Գc?s_L(@(ѓ\6JEX Hp, .pXed% @PDD3RPT+.\ˎ5GX-Xͣ :(6+ɷ@80*ƕq.@S̨q $Slר#?➍6 1Eg7r J>5(m 4J@).?@ *ws 6ax`qA<0 B.P[# PQ ei>-)t?{W8X)*`ޛZxmϪPLJ. WSxQ(-R͸=S2!i>x-TD< _8Q^p[175󺂿Nx8;@O<"9%Nxd[p| yF( -AB:ч.z FpћntRԛ3z/`c=\:/YّWj P 1,=go~=Էy|2{򢯺^{`HR?>=ko>={{.>‡=ow _>ҟ>oc?>} ! , A H*\ȰÇz ?+Dlh Iɓ( _˔ bLI͛8sɳh>l!ѣHᔴӧPJ$P* t.Mz@ծidU5T]˷߿SZCbDRXCCP`V jĩ4N `C 3*_bJkjI #Y Hki_ki4(_́tي"ׅdǃW8`ؼ04l6P(`NBP@70 <蠂7xg0d@@]B?l/]?]@-!dXOvBYۀEu@"4DL2 P#D(bA-p `)Zl#&MZs gU6\]B29X'w@xT(A*ǘ9@ 0 [0  @I&DBt4PsO8-ĔjPcK  AX8@TeAl.tAV"4DF\/OU)ЯMo@ -M Q AoTDlGe 7G,l}1w ,rގl(, 41c~ڬ<@$jm0 -B2JdH\X0ģiCCA.Tvl Z$!%u0Q0@GA A Gy4HYI8`3 I Ёc?_6^QEATe>dÂLtL] WSFAe)ߏzZ2K,Fsen} eF] ynռh 4WBs_IbE3a?jYPY̠ (HZ72-$#/"9D`PA,B0`R28_XF@#ALF`xRaL/n\>1y0נ@d.9}}~3N?<7L7] =bG ȩ C^x<>hh|S~Pgᙬ/9s>Ay P'磌D!s Ptq~'vX{DW@|`~~g~h&wdgJ  a23r@j x~ z.F%l7F1i!6va}'I eAQRG>cs y>rzSv1--j'҅c @Q@ h'OE d#f .x.0 0UP-'g$ `LfmF񄋖&vKUN @0cԳ+/\qHmC :byH|o~~#n?8-^fRx,s xf E:'@1 7`]։&~|ޠst7YI\F`*s  Q_;QYa3 txdaېhև|7uۀeD]QI@Y D"}P7DS@ uq&hpgp5G&x$PDpB1@+Bܨ@#/0q7# !Aqd<ug1" Sт+B050:> ֐0 @ k67Gpwf T8iy"a Pq@%1b ELW6PlrX.C4ߦB ad k К qf)0 Z \ 8L8uFgfF i@ 6|0ј igTfiV\EC2P49A5P]/p {L a a  I= p [)| hpk0 !haapb5 <-Ahr_ <;; x$ )gV@ i0 kp YngaV@isp6'3s0jָ%qH1D2Ĩж`Q:@cor8ta[ٛ)p63&!r*$D3ABkyڥ A *kiPfU "z Tci ?! 9;Ȁ{+F|2PJtHҰȚꛈ dJZ`*I  67D?] F?xuшV"-سA9f6QnrlaѰ` ٪p 7:ӝ;-?'ˍ`b QqLt0 9k GW\d Đ ݐv縪EqfՀ E&vF9 ZQXa ')3{! jvQWnt[o2C)Dֶ;Lw+Ku^`y{  , ;ٰ"APUj0 s  )+(9+ H@ X{E4a*%TXe+ `p Ð {PZ! Kq 5\Lp a @ lI&h]|G 5Ȑ  p8 Rb-@*5A'![u/KO^QJ{?;g3'cka LaK a  4Y XI ٝPWK9*xAy[SAmHTw[<{i7d{fa~{r AoP|r\)gIgq iʻ1ea Q%  g|@e|6FX˛*3xDȓ-_~YfΗ}H\:u1a{=1ݿjV+XيElo҄tF\yL0nzVf9QI;z^xѼjnFr螖Q3>* <)>Z갶zX."DB`O2e(mΣB*2jpP"YXi-'90|3ρ*yw TEN#ҫĔaDnjF@f2% K\ˁZc2ƋM>T 5j]'j]gR|LMN.˛䊫]-k$Ѯ5ZyŷH+[?k42*be \gNh3'І `_)'BJ.ېHo3JK f^1fa4XiE"*mqGb71b` "fl_BϚ,Ʈ))g7Jぜ8֔0>/cbHYdA!Έ/Ov rM,& :6("D(aV׷s92k9`܎($ڛ7] 1R 2(Yz1F&ZMJ6Kp:N.lEewּ9~ZwLF01"kGZ"␋n_àF0`@R"lg Qzd `ZHHQfҬQVJVrZEV RHܗ')3PgYƊ#0A.bD@>ES h DTjS DBR cq׌tя1I 1vpD'\bf lq"죉#BDQh#.Y6B j0[ fĈIZ&'%-g2\Gjn"i@`Ôʈ"YG ɤ1g$W\"2Dn)yrӞX{Q lF"G2߁ !4D$(FXo\ab iGK)wIB'Bx>@CJdR\?(c6M)Pl  E2J$MxW&a /nM4"`; 0qo߾8'PG5Q]& Χɸ&\UIaR,I,";%I`jRR:}TY@ J$bK?Bdˀ4#2\8EPLs -8r+acA#SZj!l,<ҋ  9d : Apol6׸kFzZ3}A@XyC4P;JU@0k)Ed@0V3XB]QȢ~HN GVBLB" @"Azcq#Ө%ԴY_ |Df068 n3dYX cĊq6(J ))E _R&A|@6T@k%͝eu81Ll\zڑyN4)0+$LIÁ@ Qش)eƼ*,(]z'T=mTs S#jq jp.ZET~D` Tlڜ9]HL.U^QvD"c91cQmgb@EL ;2w9>r$c!-E퉨cF4]X,ShFra#wF&s7)eDz޹[!Gi8JeꈲSJ@@v엄jHpxPqFꃟ@ #M&# 2 [&%_*SgÕi{O]uM h"P]]<y;VN#uUtUvg+?aY"uL1ʙ;Ȝ& ߾W*r<}V+@ d]uK^Z:Gl#;MBVe @n9*>趖:0DZ @R;9Q(B=@!(+A1A9ل& 2 i$-d8h8Z8hh2sA*G [0C9:(&RB1@F6ÔH$~z&GD(H(4:l=(@=GDͰ3#;h;3Á=/?S;.2 <B\ b&'R@f>938TgL>2]L$D)kFÓB?̈{) )4X  /pyG`OR:8H-:CDKGkL p18b(b^䉑ȒLaKRÈ.0Gxp"$(/9Y@c\؄ɧ_H37TDCtsH̍!L>ǫ4˸ʗjIc,ɆD()x: ("R틈^:sD$ 1`#?ʈmFhDP؁(Z `b Vo%zDy}讋(*dl,郿>*υ ҭ2^v;A(xo$W(Y"*Z!z@!"D(""KD-&`248 V9nFz 3ځlj7luǏLF|ndk\単i|"R.S|Kt r_ۄkulLB ^H2 _)sP}|w#=8ks^ ,>hp@[}Ï6p`K ``8KM ;Hp`D"GSIH[Eߍz}Lſu|'РB-j(ҤJ2m)ԨRb , l<Ǣ҃sr-\"N.N%hгPغ.l0Ċ fX?Oa@6ԌBd¢٠'QDgYK O12VeC0e? KOK(Ar*Ď :qAF{ 8HrNYbrאr\ h^TaO4U$*{4%h@M5s*:C%tD"R$vI$v !ZKJMDmt! % d͆ @v $x4aNS?=*R;d0!p%z*T4RAb1ϕ;.f&T()v rБQpQl+H 58@YAŦ W{c,bv 7"6c҈"A̡fsOx]?/bP *79N"Z ZB[Js s%"$kH?0MæŌ" 1KfF0"QJ֗d# @#ͨ?x0 Kv$I@pKFNX@rW YI4HLæA *㊑0>CH!!anS\צIp^!y^C8tzOp.f(gCVWD&FJґXdR@ 8U6~>~6ah3A#ͨD"c E^IT\lJ!@C꾉7*%s3c(E;!͋LV@&CC of?dE/NZVWP@ <*yeͷUmCꓮe TI9ؽ .pu|+ $)2xtp0 wC%}`p;8.&J,% O!@Ys1ɉPv eiH(Wf q,a1> `uCܤcA΍  K p04 $ 1sX |? ߺk͙ui|O0  | $EݽcD*|nP A@_5DNwt8A75$I_.`jR5UȗBA7`7iO"^ b60/0U3x㴥=<\`VULA!%Xi \h+zT!%"#92(?XL( A| b`ұq9?*@(u@-4h]d.bCǠI?.G"J! QIB|DH -G}$9A.Kƥl>Τ1dQ! Pe !N ƍ:%%~Xd%*HeS'S(?RWCG_SaYeSd ‡NpDyHSD\ue}a7Davd(藪d[2\`^GL]AC'Dn?hPDd"0@ @p|hΝXDdĦ@`{ХDBd<+$b&EHr!C|Tk J "#TsLB( 3{5/l%w A0(a!N(>V(fv~ջ|(x((q֨ \2 (YI($):geJ.0)*8`pL* @if`ّD`)RBڀ)E]T镚.Cp^Cwi]HPp( F ̩2Y 0)QI*L*V^*fn*vd*jTx!}G n!0$X ˵PڈD*E(G,C% ]T*x6V^h"ʡL@d 2fQR巆++6 UjSk?kҫ+ !>ϻ,jP&l ),.6,"D pN^vN"zlĊ,ȎlǞ֫n,*J "ʿ,ڬެ,ϾHm&->F-NV-^f-՚D4+҆-FƊΕٮ-۶-ˆL0-펪mb(1*͋.&.Ʌ-a)T瞀$*O* ÀJH켪§Sn.ʍ厊 ѫ@0ͬ6vJPZ.k"54^ e,oP( =YnF