pax_global_header00006660000000000000000000000064140766103660014523gustar00rootroot0000000000000052 comment=d45b96278a61b34b3df3e48bb2712de877bdefca harmonica-0.1.0/000077500000000000000000000000001407661036600134625ustar00rootroot00000000000000harmonica-0.1.0/.github/000077500000000000000000000000001407661036600150225ustar00rootroot00000000000000harmonica-0.1.0/.github/workflows/000077500000000000000000000000001407661036600170575ustar00rootroot00000000000000harmonica-0.1.0/.github/workflows/build.yml000066400000000000000000000014541407661036600207050ustar00rootroot00000000000000name: build on: [push, pull_request] jobs: build: strategy: matrix: go-version: [~1.16, ^1] os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} env: GO111MODULE: "on" steps: - name: Install Go uses: actions/setup-go@v2 with: go-version: ${{ matrix.go-version }} - name: Checkout Code uses: actions/checkout@v2 - name: Download Go Modules run: go mod download - name: Build run: go build -v ./... - name: Build Examples (on Ubuntu) if: matrix.os == 'ubuntu-latest' run: | sudo apt-get install libgl1-mesa-dev xorg-dev go build -v ./... working-directory: ./examples - name: Test run: go test ./... harmonica-0.1.0/.github/workflows/lint.yml000066400000000000000000000010571407661036600205530ustar00rootroot00000000000000name: lint on: [push, pull_request] jobs: golangci: name: lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: golangci-lint uses: golangci/golangci-lint-action@v2 with: # Optional: golangci-lint command line arguments. args: --issues-exit-code=0 # Optional: working directory, useful for monorepos # working-directory: somedir # Optional: show only new issues if it's a pull request. The default value is `false`. only-new-issues: true harmonica-0.1.0/LICENSE000066400000000000000000000020641407661036600144710ustar00rootroot00000000000000MIT License Copyright (c) 2021 Charmbracelet, Inc. 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. harmonica-0.1.0/README.md000066400000000000000000000077711407661036600147550ustar00rootroot00000000000000Harmonica =========

Harmonica Image
Latest Release GoDoc Build Status

A simple, efficient spring animation library for smooth, natural motion. Harmonica OpenGL Demo It even works well on the command line. Harmonica TUI Demo [examples]: https://github.com/charmbracelet/harmonica/tree/master/examples [docs]: https://pkg.go.dev/github.com/charmbracelet/harmonica?tab=doc ## Usage Harmonica is framework-agnostic and works well in 2D and 3D contexts. Simply call [`NewSpring`][newspring] with your settings to initialize and [`Update`][update] on each frame to animate. ```go import "github.com/charmbracelet/harmonica" // A thing we want to animate. sprite := struct{ x, xVelocity float64 y, yVelocity float64 }{} // Where we want to animate it. const targetX = 50.0 const targetY = 100.0 // Initialize a spring with framerate, angular frequency, and damping values. spring := harmonica.NewSpring(harmonica.FPS(60), 6.0, 0.5) // Animate! for { sprite.x, sprite.xVelocity = spring.Update(&sprite.x, &sprite.xVelocity, targetX) sprite.y, sprite.yVelocity = spring.Update(&sprite.y, &sprite.yVelocity, targetY) time.Sleep(time.Second/60) } ``` For details, see the [examples][examples] and the [docs][docs]. [newspring]: https://pkg.go.dev/github.com/charmbracelet/harmonica#NewSpring [update]: https://pkg.go.dev/github.com/charmbracelet/harmonica#Update ## Settings [`NewSpring`][newspring] takes three values: * **Time Delta:** the time step to operate on. Game engines typically provide a way to determine the time delta, however if that's not available you can simply set the framerate with the included `FPS(int)` utility function. Make the framerate you set here matches your actual framerate. * **Angular Velocity:** this translates roughly to the speed. Higher values are faster. * **Damping Ratio:** the springiness of the animation, generally between `0` and `1`, though it can go higher. Lower values are springier. For details, see below. ## Damping Ratios The damping ratio affects the motion in one of three different ways depending on how it's set. ### Under-Damping A spring is under-damped when its damping ratio is less than `1`. An under-damped spring reaches equilibrium the fastest, but overshoots and will continue to oscillate as its amplitude decays over time. ### Critical Damping A spring is critically-damped the damping ratio is exactly `1`. A critically damped spring will reach equilibrium as fast as possible without oscillating. ### Over-Damping A spring is over-damped the damping ratio is greater than `1`. An over-damped spring will never oscillate, but reaches equilibrium at a slower rate than a critically damped spring. ## Acknowledgements This library is a fairly straightforward port of [Ryan Juckett][juckett]’s excellent damped simple harmonic oscillator originally writen in C++ in 2008 and published in 2012. [Ryan’s writeup][writeup] on the subject is fantastic. [juckett]: https://www.ryanjuckett.com/ [writeup]: https://www.ryanjuckett.com/damped-springs/ ## License [MIT](https://github.com/charmbracelet/harmonica/raw/master/LICENSE) *** Part of [Charm](https://charm.sh). The Charm logo Charm热爱开源 • Charm loves open source harmonica-0.1.0/examples/000077500000000000000000000000001407661036600153005ustar00rootroot00000000000000harmonica-0.1.0/examples/go.mod000066400000000000000000000005561407661036600164140ustar00rootroot00000000000000module examples go 1.16 replace github.com/charmbracelet/harmonica => ../ require ( github.com/charmbracelet/bubbletea v0.14.1 github.com/charmbracelet/harmonica v0.0.0-20210709144143-16876a63b30d github.com/charmbracelet/lipgloss v0.3.0 github.com/faiface/pixel v0.10.0 github.com/fogleman/gg v1.3.0 golang.org/x/image v0.0.0-20190523035834-f03afa92d3ff ) harmonica-0.1.0/examples/go.sum000066400000000000000000000125751407661036600164450ustar00rootroot00000000000000github.com/charmbracelet/bubbletea v0.14.1 h1:pD/bM5LBEH/nDo7nKcgNUgi4uRHQhpWTIHZbG5vuSlc= github.com/charmbracelet/bubbletea v0.14.1/go.mod h1:b5lOf5mLjMg1tRn1HVla54guZB+jvsyV0yYAQja95zE= github.com/charmbracelet/lipgloss v0.3.0 h1:5MysOD6sHr4RP4jkZNWGVIul5GKoOsP12NgbgXPvAlA= github.com/charmbracelet/lipgloss v0.3.0/go.mod h1:VkhdBS2eNAmRkTwRKLJCFhCOVkjntMusBDxv7TXahuk= github.com/containerd/console v1.0.1 h1:u7SFAJyRqWcG6ogaMAx3KjSTy1e3hT9QxqX7Jco7dRc= github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/faiface/glhf v0.0.0-20181018222622-82a6317ac380 h1:FvZ0mIGh6b3kOITxUnxS3tLZMh7yEoHo75v3/AgUqg0= github.com/faiface/glhf v0.0.0-20181018222622-82a6317ac380/go.mod h1:zqnPFFIuYFFxl7uH2gYByJwIVKG7fRqlqQCbzAnHs9g= github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 h1:baVdMKlASEHrj19iqjARrPbaRisD7EuZEVJj6ZMLl1Q= github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3/go.mod h1:VEPNJUlxl5KdWjDvz6Q1l+rJlxF2i6xqDeGuGAxa87M= github.com/faiface/pixel v0.10.0 h1:EHm3ZdQw2Ck4y51cZqFfqQpwLqNHOoXwbNEc9Dijql0= github.com/faiface/pixel v0.10.0/go.mod h1:lU0YYcW77vL0F1CG8oX51GXurymL45MXd57otHNLK7A= github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 h1:SCYMcCJ89LjRGwEa0tRluNRiMjZHalQZrVrvTbPh+qw= github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72 h1:b+9H1GAsx5RsjvDFLoS5zkNBzIQMuVKUYQDmxU3N5XE= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/mathgl v0.0.0-20190416160123-c4601bc793c7 h1:THttjeRn1iiz69E875U6gAik8KTWk/JYAHoSVpUxBBI= github.com/go-gl/mathgl v0.0.0-20190416160123-c4601bc793c7/go.mod h1:yhpkQzEiH9yPyxDUGzkmgScbaBVlhC06qodikEM0ZwQ= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= 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-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 h1:y1p/ycavWjGT9FnmSjdbWUlLGvcxrY0Rw3ATltrxOhk= github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ= github.com/muesli/termenv v0.8.1 h1:9q230czSP3DHVpkaPDXGp0TOfAwyjyYwXlUCQxQSaBk= github.com/muesli/termenv v0.8.1/go.mod h1:kzt/D/4a88RoheZmwfqorY3A+tnsSMA9HJC/fQSFKo0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190523035834-f03afa92d3ff h1:+2zgJKVDVAz/BWSsuniCmU1kLCjL88Z8/kv39xCI9NQ= golang.org/x/image v0.0.0-20190523035834-f03afa92d3ff/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20210422114643-f5beecf764ed h1:Ei4bQjjpYUsS4efOUz+5Nz++IVkHk87n2zBA0NxBWc0= golang.org/x/term v0.0.0-20210422114643-f5beecf764ed/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= harmonica-0.1.0/examples/opengl/000077500000000000000000000000001407661036600165645ustar00rootroot00000000000000harmonica-0.1.0/examples/opengl/JetBrainsMono-Regular.ttf000066400000000000000000005175441407661036600234340ustar00rootroot00000000000000 DSIG\GDEFbEb1fGPOSK+3 GSUB3GW|OS/2`cmap$: cvt '^h.fpgmb/ gasp1glyf{B8X<XX<XZX2X]XnX2XdXUX]XXXiX\X2XLXZXPXXX^X\X7X7X#X6X(X6X2X XXXXXXXiX#X\XZX\X<XZXPXDX\XXX7XaX2X]X7XFXUXX^XUXUX<XZX7X(X6X7X7X7X7XZXZXZXUX7XZXPX\X^XXZXiX[XPXZXHXFXPXUX@XFXBX@XXXXXXXXXXXXXXXXXXXXXXXZXXXXXXXX<XXXXnXXX#X#XXXKXKXXxXXsXUXUXXXnXXiXXXXPXXX<XXUXKXUXXXXXXXXX4XXX\XXXXXXCXXX>XXXpXX\XXXDXX,XRXXXXXXXXXaXWXXXXXXXXXXXX9XXXsXXXXXX>XXX"XX}XsXXXXXX]XUX+XHXZXXXXKX-X#XXX(XXZX#XxXPXPXXFXX+XAX#X#X#XXAXXiXdXUXUXUXUXUXUXAXAXAXFXPX#X<X<X+X+XX(X7XXZX]XXXXXX-X-XXXX7XX#XXXXAXX#X#XXX2XXXXXXX X X(X X X-X(X-XX XX XXXXXXXXXXXXXXXXXXXXXX,X XX,XXXXXX,XXX<XXXXXXXXXXXX<XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXKXXXXXXXXXXXX%XXXXXXXXXXXXXXXXXXXXXXXXXXFXXXXXXXXXXXX%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX^XXX%XBXX'X-X7XAXMX-X-XXXXUXXXPXFXPXX<X<XQX XXXXXXX<X\XXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXX XXaXXXX*XXXmXXXXXXXCXXXXwX~XXXXCXXXXXXCXXX4XGXXXXXXXX*XXXXXWXX9XXXX7XX%J;e4\44zz\fuaX}XXXXXwXwXXXXXXf%J;4\44z4z%fua44X}XXXXXwXwXXXXXXX}4***4 //// XZXiX2XXXXX "" /9~137Y #(8u~ #:CO\_     " $ & 0 3 : ? D p y z !!!!"!$!.!!"" " """""#"%"+"7"<"I"a"e"""""""""###%#t##%%%%%%%%%%%%&''''6'q'''**+X 0:427Y#%6t~$;DQ^     $ & 0 2 9 > D p t z !!!!"!$!.!!""" """""#"%"'"6"<"H"`"d"""""""""###%#t##%%%%%%%%%%%%&''''6'n'''**+X&  VTLED7/`?>AbsQL'2x )9kfU4iݓݠݘundV]H>ܭvأ$$ <xz|~  68:<>F6\LCmJnSTI?]>M@AE!%78?BNPRXY_y{|WNXbr 1348@EXY^_hUVDpli^z23sG{1mj<;=F 2&)/ICEF"^j`bwhuz>"/ -KFHI`2b #$4'05(<:>=A@MKDLGOQS U T V WZ\[]s+ar*x0}57~69<;:CBAWTGVSU[aikj?l$M ;t,9v.=DfWUwqx|ytZ[^bc`YXda\_   vr|nopqtuwxyz{s]Z\  136*,-.+JHi!k#cefgdm%o'p(q)n&JLNPQROdcegghcefdHLO     tnrl~oumsqk}pvz{`dyj_xi^cbgfwh]ae|&%$#"! '345IMUYJNVZQSKOW[LPX\RT=>;6Z\Y[, UXEY KQKSZX4(Y`f UX%acc#b!!YC#DC`B-, `f-,#!#!-, dBCC ``BCB%CCTx #CCadPxC`B!e!CCB C#BC`B#PXeYC`B-,+CX#!#!CC#PXeY d P&Z( CEcEEX!%YR[X!#!X PPX!@Y 8PX!8YY  CEcEad(PX! CEcE 0PX!0Y PX f a PX` PX! ` 6PX!6``YYY% CcRXK PX! CKPX!Kac CcbYYdaY+YY#PXeYY dC#BY-, E %ad CPX#B#B!!Y`-,#!#!+ dbB #BEX CEc C`Ec*! C +0%&QX`PaRYX#Y!Y @SX+!@Y#PXeY-, C+C`B-, #B# #Babfc`*- , E Ccb PX@`Yfc`D`- , CEB*!C`B- ,C#DC`B- , E +#C%` E#a d PX!0PX @YY#PXeY%#aDD`- , E +#C%` E#a d$PX@Y#PXeY%#aDD`-, #B EPX!#!Y*!-,EdaD-,` CJPX #BYCJRX #BY-, bfc c#aC` ` #B#-,KTXdDY$ e#x-,KQXKSXdDY!Y$e#x-,CUXCaB+YC%B%B%B# %PXC`%B #a*!#a #a*!C`%B%a*!YCGCG`b PX@`Yfc Ccb PX@`Yfc`#DC>C`B-,ETX#B E#B #`B `BBB` #Ba++"Y-,+-,+-,+-,+-,+-,+-,+-,+-,+-, +-+,# bfc`KTX# .]!!Y-,,# bfc`KTX# .q!!Y--,# bfc&`KTX# .r!!Y- ,+ETX#B E#B #`B `aBB`++"Y-!, +-", +-#, +-$, +-%, +-&, +-', +-(, +-), +-*, +-., <`-/, `` C#`C%a`.*!-0,/+/*-1, G Ccb PX@`Yfc`#a8# UX G Ccb PX@`Yfc`#a8!Y-2,ETXEB1*EX0Y"Y-3,+ETXEB1*EX0Y"Y-4, 5`-5,EBEcb PX@`Yfc+Ccb PX@`Yfc+D>#84*!-6, < G Ccb PX@`Yfc`Ca8-7,.<-8, < G Ccb PX@`Yfc`CaCc8-9,% . G#B%IG#G#a Xb!Y#B8*-:,#B%%G#G#a B C+e.# <8-;,#B%% .G#G#a #B B C+ `PX @QX  &YBB# C #G#G#a#F`Cb PX@`Yfc` + a C`d#CadPXCaC`Y%b PX@`Yfca# &#Fa8# CF% CG#G#a` Cb PX@`Yfc`# +#C`+%a%b PX@`Yfc&a %`d#%`dPX!#!Y# &#Fa8Y-<,#B & .G#G#a#<8-=,#B #B F#G+#a8->,#B%%G#G#aTX. <#!%%G#G#a %%G#G#a%%I%acc# Xb!Ycb PX@`Yfc`#.# <8#!Y-?,#B C .G#G#a ` `fb PX@`Yfc# <8-@,# .F%FCXPRYX +.0+-~,>+@+-,>+A+-,>+B+-,>+@+-,>+A+-,>+B+-,?+.0+-,?+@+-,?+A+-,?+B+-,?+@+-,?+A+-,?+B+-, EPXEX#!!YYB+e$PxEX0Y-KRXYcpBA1!*B@ NF6& *B@ RJ>. * B @ *B@@@@@ *D$QX@XdD(QXXDY'QX@cTXDYYYYY@ PH8(*DdDDZZPP&L0LZZPP&L.LZZPP&L 0LFF??;EFF??>H2jv&2>JV nXdpDr~*&2>JV&2>JVb <Hfr~  D P \ h    & 6 B N Z f r ~    & 2  & 2  R bnz&2~".^jv&R :FR^jvdp| ,8DP&P<HT&p|(:,4FRx| >JVbt R ^ p | !.!:!F!R!^!n!z!!!!!!"0"<"H"T"`"l"x""#X#d#p#$Z$%,%v%%%%&&&&&''>'v'(((((((() ))")p)|))))))****6*b*****++L+X+d+p+|++++++++,z,,-- -*-6-l---..j..../////:/B/J/R////0$0P0z001 1^12 2P2X223333V344T4\4455X5x555666L66677*7n77788 8868>8J8889 949f99::T:;;";t;;;;<0<<=0=8========>:>B>J>r>z>>>>>? ???"?*?h?????@ @@"@.@:@@ADAtAB6BxBCC>CFCtCCD.D6DDEE^EEEEF&F|FFFFFFFFGVGbGnGHHVHHIZIIJJDJJK.KKL:LJLZLjLzLLLLLLMMFMMNNRNNOBOOP PQ0QTQzQRRXRRS4SSSTRTTTUUUHUUUUUVFVVVWW(W4W@W\WdWWWWWXX(XPX`XpXXXYYHYhYYYZ*Z^ZZ[[[\\&\\\\\\] ]]6]B^L^^^^^_8____`$`:``aXbNbcdleRefghi iiijjHj~jjjkk,kPktkkkkkkklRlm6mn.nlnooVooppBpZpbpppq*qrqr$rJsst$txtu uu.uuuvvVnԆ"Rv8nڔBhJvʕ>`0R~lHzН4`<\Ȟ2NjΠ2dڡ"D^ޢ>jȢ"V֤,XzȤJlF>f(Zک*Lb~Pث" NhԮX"ΰ"ܲ6ltгj@d6rҷT4ȹVҺxL4HԾPbt@ȊȚ\˞"̆`Ά~0:XИ,Flђd҄ FpӲ >^~ԞԨԲԼ  (dՊդվ ,Z֚Lnך׸Lfج4>HR\fpzلَ٘٢BpڮV Bܢ\ݜnޠ8ߖ0Z 1@. LgW_O+3!%!!Z,,&m;;2&,@) Lh8M9N  +33#'#3'&&'2y[00B8&@V V?2&&b2&&X2&'X2+&'X&hX2&&X2&&X2&&X2&&X2&&X2g&X2+&'X&hX2&&X2&&X2&&X2&&~X2+&&X2&&N2&&X2&&X25Ie@ LKPX@h8M9M_=N@hc8M9NY@!% +33#33#"&5467'#3'&&'2y!55>C:Ma?N  +"&54632#4&#"326530dttdbtZA;;CC;;AZt pbJbpqa>CB>>CC>aqX&gX&]X5.@ 'LKPX@6~ra>Ma?M_ =N@4~ ca>Ma?NY@.-%"'! +532654&&54632#4&#"32653#1#F72KUtdbtZA;;CC;;AZtb 8&B67 @jTJbpqa>CB>>CC>aq$"1X&]X&]\ '@$_8M_9N ! +332#'32654&##\Gg99gGccBKKBc6bCCc6PJB#AJ 7@4g_8M_9N! +3#5332#'32654&##3#\RRGg99gGccBKKBcllOK@6bCCc6PJB#AJK\&!X 7@4g_8M_9N! +3#5332#'32654&##3#\RRGg99gGccBKKBcllOK@6bCCc6PJB#AJKd /@,g_8M_9N  +3!!!!!d(KRQRd&%vd&%ld&%ld&%ld{&%ld+&%'lld0&%ld:&%ld&%ld&%~ld&%ld+&%ld&%bd&%ld&%ld5 nKPX@)g_8M_ 9M_=N@&gc_8M_ 9NY@!% +3!!!!!#33#"&5467d(K/!@;ga>Ma?N  +"&54632#4&#"32655#530dttdbtZA;;CC;;At pbJbpqa>CB>>DD>ZRaqX&8bX&8XX&8XX&8XX&8\X&8X] '@$g8M9N  +3333##]ZZZ8&P N;@8  g  g8M 9N +3#53533533###35#]SSZZSSZ KKPk]&?Xi )@&_8M_9N  +353#5!#3iR6RRRi&Bbi&BXi&BXi&B~Xi&BXi+&BXi&BNi&BXi&BXi5bKPX@#_8M_ 9M_=N@ c_8M_ 9NY@!% +353#5!#3#33#"&5467i! 5+ ,@) L8M`9N  +35737!s__ZJ&@P@d}P}RL .@+L8M9N +3366773#4>7#LvN  JvX wVx  ??!& ,puk(m'gsr1Z$@! L8M9N +33.53#ZxWxIQ$&qIQ%fZ&YbZ&YXZ&YjXZL/@,L8M9Ma=N! +53265#3.53#A5>WxWp]R=4bIQ%fIR$M5XkZ&YXX -@*a>Ma?N   +"&54632'2654&#",brrbbrrb;??;:@@ pbJbpobbpQC>J>CC>>CX&_bX&_XX&_XXg&_XX+&_'XXX&_XX&&_XX&_XX&_~XX+&_XX&_NX&_XX*#>@; La>Ma?N##  +"&546326553'2654&#",brrbP6K/rb;??;:@@ pbJbp&KP91DbpQC>J>CC>>CX&lXX+*&lhXX&lDX&lNX&lNX&_XX&_XX5+dKPX@!a>Ma?M_=N@ca>Ma?NY@&$++  +"&547#"&54632332654&#"{7C8 brrbbr+'!<;??;:@@5(.6pbJbpob;Z-<C>J>CC>>C#5#u@ "! LKPX@a>Ma?N@!a>Ma?NY@##&& +7&5463273#"'&#"265#Lrb\8!TFrbU7);G:@z;? (-=Jbp1;})5bp+I:1CC>)~(#5&ubX&_X(?+KPX@ L@  LYKPX@#g a>M a ?NKPX@8g a>Ma>Ma ?M a ?N@3g a>M_8M_9M a ?NYY@&$++  +"&5463235!#3#3!5#'2654&#"HSSH#. . *00**00 fXrXf)PRRRP*P;3r3;;33;\& +@(g_8M9N $! +332##32654&##\fyyf;GG;ubbu}I=>HZ& /@,gg8M9N %! +3332##32654&##ZZBa6vc:BC9ږ2Z<[mA78@PL!8@5La>Ma?M=N!!%# +'"#"&54632'2654&#"g ewweew:5u;GG;;GGub@buubCdJ=@>II>=J\!3@0 Lg_8M9N! +332##32654&##\Ab6MBju8DD85^?Jj6G:;F\!&|b\!&|X\!&|jXH);@8~a>Ma?N)) +"&'332654&''&&546632#4&#"0k{ZKC?G/,cKQ5`A`tZA;:A0-dIP8e k]7@>7,B lI;W1kY6=82-B nJMa?M_ =N@4~ ca>Ma?NY@=<","! +532654&&'332654&''&&546632#4&#"#"##F72PZZKC?G/,cKQ5`A`tZA;:A0-dIP8eC 8&B67 @eO7@>7,B lI;W1kY6=82-B nJ]3Xp[@a6RH=Ma?N  +"&55!54&#"#4632'2655#,aqJ=;:>Zpbdnpb>:; s_ȃ>CD>aqpb_sKFAAF7!!@_8M9N +3#5!#RRx7!/@,g_8M9N +3#53#5!#3#ȑ'KRRK7!&X75!o@ LKKPX@$_8M9M_=N@!c_8M9NY@!( +3#5!###532654 8&B6UF72RRx#$"17 E7!&jXZ$@!8Ma?N  +"&5332653,flZ;=<:;=ZP!<5(.6pb>CC>y6-<Z&XZ&X2& !@L8M9N  +336673]|  {[4YY4&?&@#L8M9N +3366736673#&&'mTV7D]>9RVq>C!GG!!GG!&&"AA"?&b?&X?&~X?&N(0&@# L8M9N +3366773#'&&'(hq  scg}  ~rh' '' &#5#@ L8M9N +336673]  ]##,7#5&b#5&X#5&~X#+5&X#5&N#5&X#5&X#5&XU ,@)L_8M_9N  +35!5!!UISZ.RZRU&bU&XU&XA0&LKPX@(gaAM a?N@,gaAM9M a?NY@" &&  +"&5463354&#"#6632#5#'2655#"WddU=81@Z tW_nX[2@R-4? YLMX728)#GTbTi5>G@2N2+.5A&[gA&`]Az&]A+&'h]`]Az&]A&]A&]A&_]A&^]Av&]A+&'h]^]A&&]A+&]A&]A &X]A+0&h]A&ZSA9&d]A&c]A510*5KPX@ ' L@ ' LKYKPX@2  gaAM a ?M_=NKPX@/  gcaAM a ?N@3  gcaAM9M a ?NYY@,+1/+5,5&%  ** +"&5463354&#"#663233#"&5467#5#'2655#"WddU=81@Z tW_n"G@2N2+.5AD&a]A &b]#503<H@ /LKPX@3rr  g aAM b ?N@5  g aAM b ?NY@'>=CA=H>H:854,*('%#  33 +"&55463354#"#46323>32#32653#"&&'#354&#"2655#">ISFJC#UI<'41%DM% &UPA%27%!$ (H"# L@<>IJT"?M%%VJi%."?M%%OK&--&.%i#<"#5&[b\"k LKPX@8MaAMa?N@!8MaAM9Ma?NY@""  +"&'##336632'26554&#"L>PZZP>Sddq9BB97AA =6iڠ}5>n_^nND@@DF>>FU0;@8~aAMa?N  +"&554632#&&#"326730dwwd_tZA8;FF;8AZt pbbpfX59C>>D:4XfU&[fU&_\U50.@ 'LKPX@6~raAMa?M_ =N@4~ caAMa?NY@.-%"'! +532654&&554632#&&#"32673###F72KWwd_tZA8;FF;8AZt_ 8&B67 @kSbpfX59C>>D:4Xf$"1U&^\U &Y\U"k LKPX@8MaAMa?N@!8MaAM9Ma?NY@""  +"&5546323'53#5#'26554&#" RedS>PZZP 8@@89BB n^_n>5}&i6=NF>>FD@@DF ,L@ILJj8Ma?N"!(&!,",    +"&&5466323&&''57'37'2654&#"+Dh95_?,;  AxHh,jN,5:gF@MM@>MM 8fCCc7& 5%[LP8c@EP1q@@Fi:PPAAPPAAP?X&LKPX@$_8MaAM a ?N@(_8MaAM9M a ?NY@!&&  +53"&5546323'53#5#'26554&#"Z LYYL9GZZG2772188&l[\l>5}&i5>NC<NZ^^ZN 8>>89== n^e_n>5}Z>FD@Z@DU0">@;gaAMa?N   +"&&5546632!32673354&#",Aa55aAAa5B=4@Z uA>=B 4_?@^44^@a5AE%%EQKAFFAU&[bU&`XU&_XU&^XUq&XU+&'hX^XU!&XU&&XU&XU &XXU &YXU+0&hXU&ZNU9&dXU&cXX50%.KPX@0gaAMa?M` =N@-g daAMa?NY@,*'&$" %% +"&547#"&554632!327333354&#"u7C; assabr?=iZ2'"<>>=?5(/5s__ss_a5AEJ+@ -< AFFAU &bXZ0C@@gaAMa?N  +"&55!54&#"#6632'2655#,aqL<>gZ pWbppb><= s_a5AEJEQs__sKFAAF<-@*g_8M9N!# +3#5354633#"3#ܠRH@R_AKR:_RcXL0)oLKPX@ iaAM_=N@$i;MaAM_=NY@$"))%&! +532557##"&554632353#26554&#"QO>UbbU>OY[Q%8@@89??RNFd5>o^t^n>5iJV%F>i>FD@i@DXL&[_XL&`UXL&_UXL&^UXLp&fUXL &YU\-@*L8MaAM9N#$ +3336632#4&#"\ZL?SbZ?68A7EYxeSC=RarFL6&^_- 1@.Lg8M;M9N  +33373#'#_Zjgiki_-&jXa#&& (@%_8M_9N    +!"&5#5!33|IW& UFR"'R&& 0&& ]X&& jl v& > 5+&,@) L_8M_9N!' +757#5!733#"&55dx& IWPQRlPl"'RUFB0#V LKPX@a;M9N@;MaAM9NY@####$$ +333663236632#4&#"#4&#"BO/$G1$49SH&B#)L#)N@^"&%"\#%%"\\0LLKPX@a;M9N@;MaAM9NY@ #$ +3336632#4&#"\ZL?SbZ?68A&i7=68?ZZK?S`p]R=4Y;AF@&i7[-<B@@BB@@B#5N'J@G &% LaAMa?N ' '&& +7&55463273#"'7&#"26554'#QrbL4.[TrbP6)0 0E=#5&-[bU &bX#50(6?Y@V  $L  g aAM a ?N*)=;871/)6*6!(( +"&5546323>32#32673#"&&'#'26554&#"354&#"CNNC(33(CN$%U L8(33$$ &&& $ WIJV%%VJd&- >I%%M-&&--&&-M&--&\L0"hLKPX@a;Ma?M=N@!;MaAMa?M=NY@""%$ +336632#"&'#726554&#"\ZQ>SccS>Py9AA97BBi6=m__n>5}D@@DF>>FWV"lLK1PX@!8MaAMa?M=N@!8MaAMa?NY@""%% +336632#"&'#726554&#"WZP>SddS>Px9BB97AA}5>n_^n=6D@@DF>>FXL0"hLKPX@aAMa?M=N@!;MaAMa?M=NY@""%% +57##"&554632353'26554&#"P>SabR>PZ8@@89??}5>n__m=6i&F>>FD@@Do0ZLKPX@a;M9N@;MaAM9NY@ #" +33632#54&#"oXvWgZ?:9A&blm]!AEF@o&4[vo&4_l0&4jZ.*;@8~aAMaBN *) +"&'3332654''&&546332#&&##"#UdZ5,*54]JQO^^&O` Z0)&3/(+JYQabMB"+$D IFJQJ?&&"  LHLWZ&8[bZ&8_XZ5.<@ 5LKPX@6~raAMaBM_ =N@4~ caAMaBNY@<;+2:2! +532654&&'3332654''&&546332#&&##"###F72GTZ5,*54]JQO^^&O` Z0)&3/(+JYQab 8&B67 >K<"+$D IFJQJ?&&"  LHLW$"1Z&8^XZ.&8jX\(7@4 Lia>Ma9N(($!$!+$ +346632##532654&##532654&#"\4_@`u=6]3`Z@; g_;M ` 9 N" +7535#53533#3#33#"&55U}ZܯEE>^aqZ&E[bZ&E`XZ&E^XZ &EXXZ+&&EhXZ&EZNZ9&EdXZXNK PX@pa;Ma?N@a;Ma?NY@ ### +73326532553##"&ZZ@78AF#K+/t__r^>EE>^#KP+4aqqZX&M[bZ+X&MhWZX&MZNZX9&MdXZX &MbXZ&E\XZ&EcXZ5&VKPX@;Ma?M`=N@d;Ma?NY@  +"&5467#"&53325333t7C" bpZxxZW"<5(/pb^^4-<ZD&EaXZ &EbX7!& !@L;M9N  +336673_z  w\&!==!r#5&'@$L;M9N +3366736673#&&'{XP7 =V=  9L\c; >&z33z33|88#5&Y[b#5&Y^X#5 &YXX#5&YZN2&&&@# L;M9N +3366773#'&&'2÷jm  nijv w    7L!& "@L;M=N  +736673Qd  xa//T&7L!&_[b7L!&_^X7L! &_XX7+!&&_h7L!&_ZN7L!9&_dX7L!&_cX7L! &_bXZ& ,@)L_;M_9N  +35!5!!Z4EZzRZRZ&h[bZ&h_XZ &hYX%LK.PX@,ig Y aQ@3ig Y aQY@" %%  +"&5463354&#"#6632#5#'2655#"-681Z#$2=15>/ 3',Z7"/''.&*0*7 &$- 1@.iYaQ   +"&554632'26554&#",4??44??4$$$$:/P/::/P/:($P$$P$2&^ 1@.g_M_N !+3!!32#'32654&##^yhyyhyy>FF>yRtbauRG=>F]n@_MN+3!!nRxn&qbn9GK PX@p_MN@_MNY@ +3!53!nTU_xt?3@0S_M_N +53667!3#5!73#-$vFPz; yFsٌ=Mvd%d&%~l L6@3 LgM N +333333#### z^h*L+g^x]p-L-qxbDDVV2,N@K&LgaMa N  ,, +"&&'332654&##532654&#"#>32Fk;ZPAEOOEY[;DD;;IZ:eBBb6C9BN=m 3[<8BG=>HRB78AC:>\30W;?T `H@a6Z$@!LMN+333#4667ZWxWf$QIq&%QIZ&yX\0P\0&PbMK.PX@_MaN@_MMa"NY@ !+53267!###,'xZQVTO`&v}L X]?X_^!@_MN+3!##^Z&x\&yX7!2& "@LMN +3736673Jb  sb"=="e&2&&X6"%C@@W i i_ O%$ +5"&&55463532#'"326554&#=\3o]T]o3[>T8@@8@@8F4]?atFFta?]4FI@=GG=@I(0K/@,LiMN##+!#"&55332673 G3^oZG;0> Zr`;Gq&^t5 )@&TM`N +5!3333yZZKvv@ %@"M`N +333333BTuHtSjj&@t?-@*TM`N +5!333333QQtFtQ/rrr^ MK PX@qM`N@M`NY@ +5#333#ZZ}}x&}^& +@(gM`N !+3332#'32654&##^ZBc77cB;II;6`A@a6RI<DC>zR>DD>aqTH@EgaMa N  +"&5332655#5354&#"#4632(brZ@:;AA;:@Zrbdrr qa>DD>Rz>CD>aqpbbpiBi&B~X-N4@1Li_MN"#+3#5!#7632#4#"nn@xLWGUZW8:,OORaR({>/<0#sKPX@!gaM a N@)gMaMM a NY@##  +"&55##3354632'2654&#"MZOSSOYNP[[P+--++-- fXŇYefXXfN:6r6::66:88@5Lg_MN'+3&&546633##3#"8BL6bAZty7ED@jJ?^5&6G;:HL>@; Li_MMaN#$! +532654#"##5!#7632#F5>W8:,Zn@xLWGUp]R=4{>/OORaRXk#5Z 9@6gaMa N  +"&54632354&#"2655#,bppbbpp>;;>y;>? qbIbppbart@CC@3D@@DA0Z&?@<Li_Ma N!&& +"&554633#"36632'26554&#",aq{QTK>Wapb:>>::>> sdZ_ZA27pbPdsPFAPAFEBPAF\ &!<@9g_M_N!!+332#32654&##32654&##\S`@7>KfW*00*/55/&K@3?J=GT@($#(x,(', &@_MN+3!!&R, &[ GK PX@p_MN@_MNY@ +3!53!6U&i,t5&3@0S_M_N +53667!3#5!73#-%gFP< dM'ٌObU0U &XXF&6@3 LgM N +33353373#'##5#xpW`5L3cVpxZd6L6e A-,R@Oga!Ma "N%$  ,+ +"&'3332654&##532654##"#66332# Um _:.41753og.0].+8_ kS.Yc;:G@l[I@0%(0N*$K!BLOG1=D>IX^&$@!LMN+333#467^VsV&+b,,b)^&`Xa#& -@*LgMN +33373#'#aZ^gi_&a#&[b&MK!PX@_MaN@_MMa"NY@ !+53267!###.%uZNXTH]4rL &.@+LMN+3366773#54>7#LzH  DzWb_c& ??!U-jla%7-BU^& '@$gMN +33353#5#^ZZZ&U.^&!@_MN+3!##^Z&,\L01S07!&!@_MN+3#5!#OO)7L!&_7L!&_`X6L"#B@?M aM aM N#" +5"&55463532#'"326554&#`no_P`nn`N:BB;AA;l^]kk]^lD==FF==D2&&^N&/@,LiMN##+!5#&55332673A$fqZE=*; Ze[3;^t5& )@&TM`N +5!3333yZZK&**@& %@"M`N +333333BTuHtS&@t?&-@*TM`N +5!333333QQtFtQ/&&&&^& MK PX@qM`N@M`NY@ +5#333#ZZ}}&,}b&& +@(gM`N !+3332#'32654&##bZ]kl\4774&]QP^R/--/&& 1@.g_M_N !+3#5332#'32654&##x]kl\xx4774xP]QP^R/--/A& 6@3iM`N    ! +3332#!3%32654&##AT-YggYT~-5;;5-&]QQ]&H6006I&!K'PX@ i_MaNK.PX@+i_MaMaN@(i_M_Ma"NYY@!%!! +53267!32####%326554&##4dUE*EU[lO,$*$,@B&3@0iM` N%! +3335332###7326554&##@SI=HXXH=$))$=&UF(FUK,$($,Z.8Z0H@Ega!Ma N  +"&554632#&&#"3#326730drrd_rZ?8;AA;8?Zr pbbpfX59C>P(>D:4XfT0H@Ega!Ma N  +"&'332655#5354&#"#6632(_rZ@7;AA;7@Zr_drr fX4:D>(P>C95XfpbbpU+ &YgU+ &XgFL &Y9@6 L giMN#$ +53533#36632#4&#"#\ZL?SbZ?68AZ:KUUK7&0#sKPX@!gaM a N@)gMa!MM a NY@##  +"&55##3354632'26554&#"ETXSSXSFJZZJ&++&%** ^LS&KM]]ML^F5//55//5<& 8@5Lg_MN &+37&&54633#5#35#"E=68?Z^^ZK?S`xeSC= ;AF@:KUUK7@;ga.Ma/N  +"&54632'2654&#"53,brrbbrrb;??;:@@% pbJbpobbpQC>J>CC>>C RRiB\0P2& @(M)N +33#&&102y[{z&G^]GL XZYP =@:g_(M_)N   +5!5!5!Pf|fRRRRRRX_^\&y7/@, L_(M_)N#!+355!!'7!7<GC6P$PPWP7!#56"(06"+@(i(M)N +!5"&&53332653#=\3T@8T8@T3[>4]?`=GG=`?]42''_K*PX@ ra.M`)N@!a.M`)NY@''%'( +3535.546323#52654&#"326%weew%5(2G;;G2(P#E5buub5D#PnI9>II>9In &&)&%'?'B'_5''&i'~XB#5'~X\LDB@?Lg(M )Ma-N!# +33333##53265##\Zlb8_\-8%i9GX\O7.RZ0!g LKPX@a1Ma/N@!+Ma1M)Ma/NY@!! +"&554632353#5#'26554&#" S_`R>NZZN 8>>89== n__m=6ii5>NF>>FD@@D\L)?@< Lia.M_)M-N'%!,$+46632##32654&##532654&#"\5a@?_4>7=F6`A{]3.R8>W_H=^5G::BNF77AB:? sdSYmKK(^8VdsPG@VCIICV@GP--R@Oga1Mb 2N+*(%! -- +#"&54675&&546332#&&##"33#"332673F/\kH?;DgX2Rf _4*2,43+qo0880//<_ pVI;J?5AOLB!)##*N/((. ?JDL1@.L_(M_)M-N72+54##"&54677!5!3320`ih[KW;5J@0]KJXRZL8+3:F\L0TLKPX@a+M)M-N@+Ma1M)M-NY@ #$+3336632#4&#"\ZL?SbZ?68A&i7>0>FF>^i5>>5}7!&XFN,D@A Lga.M_)M-N,,4!$"*2 +54##"&5467&&54632#&&#"33#"3320Yv}KC;B{eCc7ZH<:C@88BRH><>C=U.+&YK.PX@_+Ma2N@_+M)Ma2NY@ +"&5###5!#33L[WTc)#`O,*PP),T^L08@5La1Ma/M-N%#+4632#"&'#726554&#"^paan_S>Nv9==99=?_mm__n>5}D@@DD@>FUL04@1a1M_)M-N5"%2+54##"&554632#&&#"3320bdwwd_tZA8;FF;bBH0fbbpfX59C>>:C=U:&!0@-_+Ma/N!! +"&&554663!#'26554&#")@_55_@075_@9AA99AA 5^??_4RD4?^5PF<NZZN 8>>89==qn__m=6ii5>NF>>FD@@DP&\L&#^L&&9@6L+M)Ma-N!#+3333##53265#467^Vs,_\-8,&+b!GX\O7.,,b)I&,I@FL_+M a /N)&#!,,  +"&55467#5!##"&''2655332554##":D'$s:s$'C;1>>!J!=== VK.BRRB.KV9229L,((,TTTTZ5@2 LgW_O+33&&53#%3#Z1BBM&0MR'iL&.G@D+*#"LiYaQ%#+'#"&54632'27&#"'!4&'665j  YkjZ@;ia>Ma?N$"(( +"&54632'2654&#"7"&54632,ewweew6cCM_9N"' +3576654&#"#6632!\94C:@IZ{ectBKKY=_,=FH?ctqa>zNRFE@BLg_8Ma?N  +"&&53326554&##57!5!!Bc6ZE=>DD>O\l7d 5^?=EH:2>DNRTp\2?^5P 0@-Lh8M_9N  +!5!53353 cZA)\U!M@JL~i_8Ma?N !! +"&'3326554&#"#!!36636*Yr Z@7???>': Z G6Ycr \N+/D>G>D)"R#(ocGaq@!8@5 Lj8Ma?N!!  +"&&546736632'2654&#"-Gk;#bD+<[2;iHAQQAAQQ ;iE0e7/ 8cCGk;PUFFUUFFUFRLK PX@r_8M9N@_8M9NY@  +3!#5!ZvTzB)76@31La>Ma?N+**7+7%#  +"&&5467&&54663276654&#"2654&'',Fj:OBA@9b??c8@ABO:id/:H::H8JBP61+.04P 1W9>k Y37T00T72Y!k>9W1 C(1=>0)BE8,GG+8E@!6@3Lia>M9N!!&$ +3'#"&&5466322654&#"B+Ma?N   +"&5463274&#"2655,brrbbrrA::A{;@A pbJbpobbp>BCC>>BE0 5+;1 5+E2 5+<3 5+<4 5+;5 5+;6 5+;7 5+~;8 5+E9 5+H -@*aRMaSN   +"&554632'26554&#",HSSHHSSH(--((--OFEOOEFO?.((--((.> )@&LPM`QN  +535733za_h@*WOG@H4@1LaRM_QN"' +576654&#"#66323*##*FP@DN*%Wy-&++&BNMA#H_@?C@@L~_PMaSN  +"&5332654&##57#53DPE*%#)(#]Y6>PL@#**##)CY@OUF7@L? 0@-LhPM_QN  +5#573353fԪNF\]h>M@JL~i_PMaSN  +"&'332654&#"#5!#632=PF*$*+%,A=9CQA7+%%+@,H>BM>8@5 LjPMaSN  +"&5467733632'2654&#"-FVkL}97ASH'--'&..NAG"H=AN>,%&++&%,>RLKPX@r_PMQN@_PMQNY@  +##5!ӧE"i?PH%26@3-LaRMaSN'&&2'2!  +"&5467&&5463276654&#"2654&'',EQ2*'-MABM,&)0Q\("!&-%+""-+?5">929928>#5? " !"$ /"H6@3LiaRMQN$# +7##"&54632'2654&#"~97ATFGUj&..&'--"H=ANNAF,%&++&%,Z@8M9N +33Ze?&:-jdD@_ ' ( L  hi  W _  O--,*! +D3!53557333357654&#"#66326633Zv >FUi?xF$$<E68E-)] *m2 6F=&@E(+##4>>2<4 2jdD@_  L  h  Wh _  O +D3!53557333!5#573353Zv >FUa?G~Es<2 6F="&FPY*ձdD@ %" LK PX@Cr~ g  i  W  h _  O@D~ g  i  W  h _  OY@)**)('&$#!   +D"&5332654&##57#533!5#573353:F<%%%QU-8Fye?G~Es<:/9?27B8*/:p&FPY @a?N   +"&54632,&--&&-- ,%'..'%,`w.KPX@ =N@ vY@  +3P70 -@*aAMa?N      +"&54632"&54632,%..%&--&%..%&--)""))"")\)""))"")`0 TKPX@aAM=N@aANY@   +"&546332#3"!*+  +*!P*! ++ !*7< )0@-a?N$"))  +"&554632!"&5546323"&554632m FFFFFFw,@)_8MaBN  +%53"&546332# j/"""xxu""!#Lw, -@*aAM_=N   +"&546332#53"$$$$?@" "}y}"pK PX@&ri_8MaBN@'i_8MaBNY@"!!$! +7532654&##532"&546332#2@KKA}}Fg90U8="""ʹG;;GU5`B9[6i""!#nV+ !K PX@&rja;M_=NK1PX@'ja;M_=N@$jca;NYY@ !!  +"&546332#"&5466753#"33O$$$$j|/U9Z2@KKA}" "qa9X4iB;:CU> 5+ @YaQ   +%"&54632,4DD45CCD45CC54D#^5b1-@* L-)(IWaQ#" +7'7667'&&''77&&5536677'&&'#H6:NXX DXEYYL97H7  ^2N7 S +R"__"R+ S 7N2NJJ#5zKPX@(   g8M_;M  9 N@&h   g8M  9 NY@ +37#537#53733733#3##7#37#S%Ua$bn%F%%F%Ua$bn%F%%1$AAAA >b>&dD@W_O +D5! lPPK >@v +3Kc_nTK >@v +3_cnTLl$@!_=N  +"&533!2653#M]Z2()1Z]M]M(22(M]F 0@-iYaQ      +"&54632"&54632,%..%&--&%..%&--)""))"")\)""))"") >@ 5+x > 5+H2+&&554667厞I\@^43_@x#ΕbnUU~OM~SsH 2+5>554&&'5sA^34^@]IxYS~MO~UUnbU>$=@:LigYaQ#! $$ +"&776&##5326''&633#"33Xe &AnnA& eX--/2 5216 2/-nWO5/P/5OWP++9J J9++PU>$8@5 LigYaQ$#!%!,! +5326''&67&&776&##53233#"#U-/2 6125 2/--Ye &Ann@' eYnP++9J J9++PWO5/P/5OW>(@%gW_O +3#3nPP>(@%gW_O +53#53nP PTn@Lv+33ko@Lv+!3koiGYX@GZX@"r@W_O +5!@"PP"r]P"r@W_O +5!P"PP"Xr@W_O +5!X"PP"r]<&dD@W_O +D5!<dKK`w?U` 32#54&#"db'6 ''#)9*FUU& '$)8FP"$+,PA<< &+,CE>$(H@ELggW_ O%%%(%('&#! $$ +"&776&##5326''&633#"3333 3@0gW_O   +!!!33'ZnPPT>'W֜5+>5>#'KPX@7g   gc8M _ ;M 9 N@5g   h   gc8M 9 NY@&'&%$#"!  +37!#53#53!733733#3##7#!!337#S%%F%%F%Ua$bn%F%%QF$P PAA/'>>'>'>>pES'B'>>M'>E\'H ݰ5+/0'@@0'@'@@`D-g'@k7'@/7~75+75+&E@,!/=K;K.PX@ ! L@ ! LYK PX@@ ri_8M aAMa ?M a ?NK.PX@A i_8M aAMa ?M a ?N@= i_8M aAM a BMa ?NYY@%?>10#"FC>K?J850=1<*'"/#.!$! +%532654&##5325%667&&'%5%"&546332#"&546332#%"&546332#2@KKA}}Fg90U86! "!*+  +*!!*+  +*!"""ʹG;;GU5`B9[6iW  Zd*! ++ !*\*! ++ !*""!#Rd0 {KPX@$W W e aAN@& g g eaANY@#      +"&5463275!"&5463275!$,,$$,,&$,,$$,,&+%$,,$%+ PP,%$++$%,FPP-g&՜@775+-wg'@7t75+`10'AA;'CC5@2h g  9 N +!7!5!7!5!73!!!!ngAqZquWgnPPPPI@F  g   g_;N +7!5!7!5!7!5!73!!!!!!XO !OXQX{YOOpdX2F}F}FF}F}F.'E>M'E@a'EEW,`@]L gi   g_8M a B N '$, +!$! +%532654&##532%5!567!"&546332#2@KKA}}Fg90U8' ("""ʹG;;GU5`B9[6iPP$P""!#^ 'Ix'II5+@1>4@1=<; L>732-)( IWaQ#" +%'7667'&&''77&&5536677'&&'#5%667&&'%5bHJ;Nww DXEwwL9KHK  6! "@2l7 *S* +R"}}"R* *S*  6l2lJIkW  Zd >'IM 5+H'.2@ J'IKPX@' g 8M _ ;M9N@%  h g 8M9NY@210/.-)( +&&'!#7##7#537#5373373!667!5545!37#}%F%%F%Ua$co%F%%F%8w@^43_@sa$xzAAtUU~OM~S(>3?C%&LK PX@Fr  igge  8M_ ;M9NKPX@G  igge  8M_ ;M9N@E  i hgge  8M9NYY@5CBA@?><:975420)(#!  33 +"&77!#7##7#537#5373373!'&633#"33!&&##53267!37#Xe &%F%%F%Ua$co%F%%F%fX--/3 <;<: 2/-U,3KK3,V$nWOAAȆOWP++7OR7++Pw P >#'KPX@7  ggc 8M_ ;M9N@5  g hgc 8M9NY@&'&%$#"!  +!#7##7#537#5373373!3#3!5!37#%F%%F%Ua$co%F%%F%Eu$n6AA,PPw|'+7KPX@:i  g i8M_;M  9 N@8hi  g i8M  9 NY@.-,31,7-7+*)(#!'' +!7#537#53733733#3##7#"&5463237#"&54632%Ua$bn%F%%F%Ua$bn%F%%$,,$$,,"$$,,$$,,AAAA+%$,,$%+,%$++$%,!%33KPX@2  g8M _ ;M _ 9 NKPX@9  g8M _ ;M _ 9 NK.PX@7  h  g8M _ 9 N@;  h  g8M 9MaBNYYY@6'&.+&3'2%$#"!!   +7737#537#53733733#3##7#37#"&766332#8jb%Ua$bn%F%%F%Ua$bn%F%%1$"))xxuAAAA *""!#26DKPX@>  i g _8M _;M_9NK.PX@@  h  i g8M a>M_9N@K    h  ig8M a>M9MaBNYY@087?<7D8C65432210/.-,+*)(%#" +!7#537#537337336632#532654&#"!3##7#37#"&546332#%Ua$co%F%%F%lIl;gVZ2AHOEFP$q}%F%%1$}$$$$AA`r6cC[vdJBAKH? '%#!h&$" g 8M(9NY@NONMLKJIHGFEDCBA@?>=<;;:9876543210/.-,+*)('&%$#"! ) +!7#537#5373373!73373!733733#3##7##7!#7##7!#7#37#!7!37#!7!37#%Ua$bn%F%%F%%F%%F%%F%%F%Ua$bn%F%%F%%F%%F%%F%%1$$0$$0$AAAA 9KOSW[_cg KPX@L20.,*(&$" g 8M31/-+)'_ ;M4%#!9N@J 31/-+)'h20.,*(&$" g 8M4%#!9NY@fgfedcba`_^]\[ZYXWVUTSRQPONMLKKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$#"! 5 +!7#537#5373373!73373!73373!733733#3##7##7!#7##7!#7##7!#7#37#!7!37#!7!37#!7!37#i%Ua$bn%F%%F%%F%%F%%F%%F%%F%%F%Ua$bn%F%%F%%F%%F%%F%%F%%F%%1$$:$$:$$:$AAAA #'KPX@.   g8M_;M  9 NKPX@?W   g8M_;M_;M  9 N@6XhW   g8M  9 NYY@.$$$'$'&%#"!  +!7#537#53733733#3##7#5!37#5!%Ua$bn%F%%F%Ua$bn%F%%j$AAAAPPPP!KPX@.  g  c8M _ ;M9N@,  h  g  c8M9NY@ !  +##7#537#53733733#3#!37#8%F%Ua$bn%F%%F%Ua$bn*V$d,AAAAKmsC/3@ . K%$JKPX@.  g  c8M _ ;M9N@,  h  g  c8M9NY@ 3210// +##7#537#53733733#3#!&&55466737#v8%F%Ua$bn%F%%F%Ua$bn*sBLI\@^42]?C$d,AAAA*cbnUU~OL|TKm5>'MI5+5>'MP'II5+5+> 4@1hW_O  +3!!!!c_J<jnPP> 4@1hW_O  +3!!!!c_<cjnPP>#@  Lv +35%667&&'%c_A?R6! !ndZ  K>>&MM> ?@< hW_O    +3!!!!!3c_ <2jc_nPPT>'M'MM"AKPX@c8N@W_OY@  +5!3!"ZdKK@W_O +5!8dKK}/@Lv+53yfsz-1s/@Lv+3sfsmzk > 5+`0A]tg%.U@R    L   g _8M _9N.,(&%# +5#353353#5#32654&##32654&##VV55>C:/U>S!"V?X0;?0T=SU8JJ8%<##T1?@1V?XT=S2=9U@L99L#<&&<#Htf#*2:@7(2' +"Lv## +5&&'3'&&546753#4&'56654&''^kZ;6KQcTlIPhhR/; nJRl -B6<0,B ZX*.  LKPX@.g  i Y  c _8N@/g  i   i  c_8NY@'+++.+.-,%#**  +%"&5546323'5#53533##5#'26554&#"5! R`_S>NttZ^^ZN 8>>89==2n^)_n>5}>FD@@DPP+`@]    g   ga8M a?N)(&$!  ++ +"&55#535#5354632#&&#"3#3#32673@ewQQQQwe]u ZE7QI@p]R=4*RBIP=]3UPD99DK*B@?Lga>M_ 9N**"& +35>54'#53.54632#4&#"3#!K2#hKtbcs_B7:@"#3rd59P19&UdeY2<95#30P+I5P-+6@3L_8M9N +!5575575#5!#77Ӱ0K0d0K0OO0K0d0K0#5>@; Lh  g8M 9 N +7535#53366733#3##5<à]  ]ZxKKK##,KKKxx>5+0oK PX@&rpiYbR@(~iYbRY@ +"&54632#54&#"3265531DRRDDRZ!!!!ZR RDDRRD(2!!!!2(DR(L0 ,@)W_O +533333(AZZAR<i??i>1'@%C%@'1F9c>>c9P'@%P%@'Px@v+3!xhPn& @@=ggW_O   +5!5!5!PHHFFFFFFP 2@/ggW_O +35!!5!5!5!PJ'RRR&N:@7igYaQ$"+5!6632#"&'2654&#"~3#)66)#3]5*!)6)(7)!"FC@@    gYaQ33 +3332653##"&55#53533#F2QJ2JQ2hc6chxx(xxJQQJaggasy&yy&y2b+B@?iiYaQ! '% +!+  +%"&&546632'26654&&#"7"&54632,XQQXYQQYJvDDvJJvDDvJ  2QXYQQYXQ2DvJJvDDvJJvD   +-&@#W_O+33!3+ZNZx&A ?@&' :7 LK PX@Orr  r  r ij  i Y b  R@S    ij  i Y b  RY@??=;9842/.&###$#+7546327&&#"#54632332553#"&'32553#"&&'#&#"AH:&&/UH:-8e?w  /UG;## /UG;#2$V?f /nF;G k.7FF;G% 7FF:H d)7FF:H$!7F#: "*@  LK PX@1qg  g W _ O@0g  g W _ OY@'%$#"!(!! +7537#537#!5!273###74&'3#32665#<<1/?4>P?h?o.?.:,#7c9h(EP'@%#: %+@ )LK PX@0p  h  gW_O@/  h  gW_OY@+*" !1( +7&&5546633733#3#23!!"'37#"7#x4j.?.<<1/:c9PPP̪'@%'C#: C@@LiW_O!( +7&&5546633733#!!"'#"xCFR:gEX@?@o& @:Zm;CI<nN,Bb6RRk6HB5 D@A LgY_O(! +753!5!273###74'3265o1 @?CFR:gEX@?@#Zm;CIxR32#"'#'2>7'&#"!26554&#";HL=f$3$;HK>f$2$ ,'' && % J=K=Jc- J=K=Jc. < T4)"K"))"K") T4<2& @Lv +73#&&'> @ +-G@ ڰ5++- @YaQ33+3332653##"&5+ZHD6DHZuo:ouDHHDkqqkL(@%gW_O!%!+532654633#"#i5>QI@p]R=4@BIP}RtvRPgPI.@+gW_O+!#533&673 oc  TP{"3 4!9&Z)?@< LiYaQ$"))+"&554632354.'30'26554&#",bpaW>K1NZ*+@@+pb:>=;:>> sdPbp726bR>6Ng?dsPFAPBEFAPAF]L&"@v+!3!3cZZ&&Y@v+3Z(+ @ Iv+.53+]IZqaxnau+H @Jv +4667I]aqbnXuY-YGX@-YHGX@J )3K.PX@,  i  ia8Ma  9N@4  i  i8Ma8M 9Ma BNY@++*0.*3+3$"))   +"&55463232554#""&554632'2554#"?LL??LLJCAAAc?LL??LL?AAAH?A?HH?A?Hp&CACCAC'H?A?HH?A?HEBACCABX 5?I3& LK.PX@1i   ja8M  a 9N@9i   j8Ma8M9M  a BNY@7A@76FD@IAI<:6?7?1/*($"55   +"&55463232554#""&5546326632#"&''2554#"32554#"x7AA78@@5A5>>5A5>H&8A88A8;3Z3;++;3Z3;++4:Z::Z::Z::Z:1I &@#c_QN  +5#53533#ddPdd1iFiiFi7  #/G@D iYa  Q%$ +)$/%/##    +"&54632!"&54632"&54632!"&54632$..$$..$..$$..$$..$$..!$..$$..\-$$--$$--$$--$$--$$--$$--$$--$$-0@#:<@9ggW_O +%"&&554663!!"3!5! Eg::gE1CIIC16cA,Bb6RHB(BHRRR59@6ggW_O!%!+75!26554&#!5!2#5!1CIIC1Eg::gERHB(BHR6bB,Ac6RRXX*@'W_O+13!!ZXP 1@.iYaQ     +%"&54632'2654&#",4DD45CC5#--##--D45CC54D(-##--##-A @J Iv+77'373'M[[MIc6]]6cC#x:X+@(gW_O +%"&&554663!!"3! Eg::gE1CIIC1x6cA,Bb6RHB(BHR#F:2@/ggW_O!$!+75!26655!5!54&&#!5!2##1(?%C%?(1?h??h?FP'@%P%@'P9c>>c9x5X(@%gW_O!%!+75!26554&#!5!2#1CIIC1Eg::gExRHB(BHR6bB,Ac6XX&@#W_O+3#5!#XPP2&3@0 LW_O+33373'6677#[22\`  6&4ZY4XXGX@ X5+bQP@M?>90+*MIH%!LiiYaQCB54 +%"&&546632'26654&&#"''7667'&&''77&&5536677'&&'#,XQQXYQQYJvDDvJJvDDvH#:N== DXE>>L9$H$  QXYQQYXQ2DvJJvDDvJJvD)237 S +R"<<"R+ S 7424JIb#B@?igYaQ  # #"!  +%"&&546632'26654&&#"'5!,XQQXYQQYJvDDvJJvDDvV@QXYQQYXQ2DvJJvDDvJJvDPPb+A@>+*)('&%$#"! LiYaQ +%"&&546632'26654&&#"''7'77',XQQXYQQYJvDDvJJvDDvF3334QXYQQYXQ2DvJJvDDvJJvDB4344bl+B@?iiYaQ! '% +!+  +!"&&546632'26654&&#"7"&54632,XQQXYQQYJvDDvJJvDDvJ  QXYQQYXQ2DvJJvDDvJJvD   b+\@Y   i g Y a Q  + +*)('&%$#"!  +%"&&546632'26654&&#"75#53533#,XQQXYQQYJvDDvJJvDDvXQXYQQYXQ2DvJJvDDvJJvDPP N&@# L Jv+3467#5%'&&'# -#! - 'ii - L+l(@%LIW_O(+7'667'##5!#5467'E;a  ,PL>dNa0  "(#:q:@7LW_O!'+776675#!5!25&&''3  (J(  i#  P  K+l0@-L JW_O1+75327&&'77&&553,  =cPKN d?!  /a N@Lv+%53&&533677+ߺ Z - i -- 'i-KNj0@-L JW_O+736676633-Pc<   ,K0 !f= N(#:q:@7LW_O!6+%3663!!"&'j  )J)  #''  P -KNl,@)LIW_O!+%&&'#!#"&'P,   aKf"  /N#q)C@@$%LW_O))7F+73663!25&&''3#76675#!"&'j  )h(  ij  ()  #''       VN'&@#'&LJv+%53&&5467#5%'&&'#3677,޺  -""  -i -v- 'ii -- 'iI& ;@8KgW_O +3#5733#333}b}ZW HH NV2+%5%+' iiN{",@)LW_O9$(2+46332'&547632#"'&54677##"&)m"! k)J) "!  )KI:@7LW_O!6+7'73663!!"&'g  ) )  K  P KI:@7LW_O!'+%76675#!5!25&&''3K  ( (  iK  P KI)C@@$%LW_O))7F+7'73663!25&&''3#76675#!"&'g  )h(  ig  ()  K      Xy@W_O+5!XԥX@v+!XJX@v+!XXh@v+!XlX @v+!X9X@v+!X"XW@v+!X}X@v+!X(hX@v+!XhlWX@W_O+5!XWK@v+3K(@v+3(@v+3(,@v+!,(w@v+!w(@v+!( @v+! (,X@v+!,,( X@v+3 K(,h@v+!,l,Xh@v+!,,lh,@v+!,hlX@v+!!,,(llX*@'v+!!,,hlllX@v+!!X(llX@v+!!,b,hX@v+!,,hlX*@'v+!!,,,hlllX@v+!!,,7<X #'+/37;?CGKOSW[_cgkosw{53!5335335335353!5335335335353!5335335335353!5335335335353!5335335335353!5335335335353!5335335335353!5335335335353!5335335335353!5335335335353!53353353353<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<oi*@'v+33cap@v+3p4pl&@#W_O+#5!#pbp$@!W_O+#5!ppl$@!W_O+!#pfbl@W_O+5!^@W_O+5!rl(@%Wg_O+5!!!r2d2? B@?W_   O       +53!53353353dd2d2d= Q@Ng g gW_ O       +53535353l@W_O+5!r%3 6@3W_O   +53!53353~~J~% =@:v   +333dFReoF@`@v+3@ l`'@$W_O+5333v`$@!W_O+533p`@v+#3#22p 0l`$@!W_O+33Rvp`@v+3ppl` /@,W_O +#5333#pvbp`*@'W_O+#533ppl`*@'W_O+33#pvbpl` 7@4Wg_O +#5!333#d2pv2d0pl .@+Wg_O +!5!!!rp2d0l` .@+Wg_O +5!3!!dDd2pl` 4@1Wg_O +!5!3!!dpDd0pl .@+Wg_O +#535!#pd2bl` .@+Wg_O +5#53332dvpl` 4@1Wg_O +#5333#pdvbpl` 6@3Wg_O +!5333##2pDd2bp^ $@!YaQ !$+4&&##532:iH##fSpIl;dTg pl $@!YaQ !$+46633#"Se##Gj:pgTd;lI @^` $@!YaQ !+5326653##Hi:dSf@d;lI4gT@l` &@#YaQ   +"&&5333IeSd:jG#@Tg4Il;d`lp(@% Lv+5533# PP P((W( (W`lp@Lv+53P0((`lp@Lv+530PР((F@*@'W_O+53!53r4@dddd[^}*@'v+33ddd;9p^@v+3dp4pl&@#W_O+!5!!pdd0p^$@!W_O+!5!rpdpl$@!W_O+!!rp4d0@l@W_O+5!@dd@^@W_O+5!r@ddl(@%Wg_O+5!5!5!r2d2@? B@?W_   O       +53!53353353dd2d2d@dddddddd=^ Q@Ng g gW_ O       +53535353ddddddd@l@W_O+5!r@dd%@3 6@3W_O   +53!53353~~J~@dddddd%^ =@:v   +333dddddXRiNdQ@^`@v+3d@ p`@v+3332d2p4D@l`'@$W_O+5!3!d@dDd@^`$@!W_O+5!3d@d@l`$@!W_O+3!d@ Ddp^`@v+3dppl` /@,W_O +!5!3!!dpdDd0p^`*@'W_O+!5!3dpdpl`*@'W_O+3!!dpDd0pl` 7@4Wg_O +#53533!#2dpd2vbpl .@+Wg_O +!5!5!!rpd2bl` .@+Wg_O +5!5!3!d2dvpl` 4@1Wg_O +!5!3!!dpdvbpl .@+Wg_O +#5!3#p2d0l` .@+Wg_O +5333#Dd2pl` 4@1Wg_O +#5333#pDd0pl` 6@3Wg_O +#5#5333!2p2dvb@l` ,@)W_O +533333ddd@dDDd@` )@&W_O +53333ddd@dD@l` )@&W_O +3333ddd@ DDdpl` /@,W_O +!5333!pdDd0@l`'@$W_O+5333@dDdp` ,@)W_O +!533#2pd0@`$@!W_O+533@dpl` ,@)W_O +#33!2p Dd0@l`$@!W_O+33@ Ddpl` /@,W_O +#5!3!#dpvbl`'@$W_O+5!3!dvp` -@*W_O +#5!33d2pv^`$@!W_O+5!3dpl` -@*W_O +33!#2dpfvbl`$@!W_O+3!dRvl` 7@4gW_O  +5!3!5!ddXddd^` .@+gW_O +'5!5!5!3ddddX|l` .@+gW_O +73!!!ddddpl`8@5 W_O +#533333###dddddpdDDd00p` 5@2W_O  +#53333dddpdpl` 5@2W_O  +33#!3^ddpDd0pl` /@,W_O +#5333#pdDd0p`*@'W_O+#533pdpl`*@'W_O+33#pDd0pl` /@,W_O +!5!3!!dpvbp^`*@'W_O+!5!3dppl`*@'W_O+3!!dpvbpl`=@:  gW_O +!5!5!5!3!!!!dpldddXdddp^` 4@1gW_O +!5!5!5!3dpldddXpl` 4@1gW_O +3!!!!dpddd^L0<@9LiYaQ%#+4632#"&'#726554&#"^paan_S>Nv9==99=?_mm__n>5}D@@DD@>Fbb M@J LJgiW_O      +#%!'53"54332# 66 2 !!!!b2k99kl""""DH@IW_O+!!ִ"Hp%s4n2+7%?EHBr05Bd8  2+7'7'77'{8:8:e8:8:[9u  2+7'7'77'Y9:9:\9:9:'<0  2+77'77'''-,ת--ҖIHI-L0+6LKPX@0  i g   ia>Ma =N@7    i g   ia>Ma =NY@!-,31,6-6*(#! ++ +"&&54632#5##"&5546323'54&#"332554&#"EU~E~rG 7)AEEA)7 UPZdk]FP')PGXTrR7#OLxLO#FUZthdsK*fo/,\x\76#-@ '"LKPX@,a>Ma?Ma?N@)a>M_9Ma?NY@%$$-%-!  ## +"&55467'&&54632#4&#"73#''267'R]73cQWfZ5.)1G^quc?J_"?>/ XM}5I *H$HW\O,1-&:ǡWaP-( C}(-AL *@'_8M=N   % +"&55463333UiiUPZP^LPM]rrMf ;KG@DL~~ea>N32'$"! ;: +"&&'3332654''&&54675"&&546332#&&##"##6654&''&6Y9_ >*93 gh 2> 9dD@.iYaQ      +D"&54632'2654&#",CSSCDRRE)22)(11PAAPPAAP34*+44+*4w@v +3P7U "@v +3!3;PP77Y>@v +3ZnTY>/@,gW_O +33ZZZ||P> /@,W_O  +#53533#ZnvPPF(8@5 LiYaQ'% +!"&55'74632326776554#"QMZFdXHIWOFQ)$"2 D -Bx5WF!%WIJQ%FUTGUCll%)**/!I!ZUI&P>=@:  gW_O +5#53#53533#3#ZnP"PPPN '5y@ "LKPX@ i_8M 9N@" i8Ma>M 9NY@)(0.(5)5''  +"&5546323.53#.'26554&#"(77()66_uF_r ,://:://:;DJLK&DIKKHc<#L@ILigYaQ"  +"&&5546632!32673!5&&#",Gm<:8750_1_.,(& $$$!+32654&#"35#'354&#"#32654&5#"326"&546335#"&54632354632##32#"&55#+Ào,p+,,1==1,,1==12==12==2++2==21==,C,+++[=22<=22<<2,,2<<22=<22==2++2=l 72@/YaQ$"77  +%"&54632".546766326654&'&&76,!! CtX12*34]<<]42+11Xt#|###0WrBAr+0K,=_66_=,K0*sABrW0ll#1I@F~iYaQ%$,*$1%1##  +".54>32'26654&&#"7"&554632,CtX11XtCCtX11XtC32'26654&&#",CtX11XtCCtX11XtCN@4    i g   i ca>NY@!/.53.8/8,*%# -- +"&&54632#5##"&5546323'54&&#"3!2554&#"U~E~Ln;G 7)AEEA)7 &I6Zdk]/P')PdGX'ZLR7#OLxLO#F9:thdsKfo/,\x\#CMW@+QGB" LKPX@7 a>Ma  ?M  a  ?N@1 a>M_ 9M  a ?NY@-ONED%$NWOWDMEMA@:86531$C%C!  ## +"&55467'&&54632#4&#"73#'!"&55467'&&54632#4&#"#''267'!267'R]73cQWfZ5.)1G^quc?JR]73cQWfZ5.)1Uc?J_"?>/G"?>/ XM}5I *H$HW\O,1-&:ǡWaXM}5I *H$HW\O,1-&:*WaP-( C}(--( C}(-#Ccmw@K+{qgbB"LKPX@B  a >Ma ?Ma ?N@9  a >M_ 9Ma ?NY@AyxonedED%$xynwowdmema`ZXVUSQDcEcA@:86531$C%C!  ## +"&55467'&&54632#4&#"73#'!"&55467'&&54632#4&#"#'!"&55467'&&54632#4&#"#'%267'!267'!267'R]73cQWfZ5.)1G^quc?JdR]73cQWfZ5.)1Uc?JR]73cQWfZ5.)1Uc?J"?>/G"?>/G"?>/ XM}5I *H$HW\O,1-&:ǡWaXM}5I *H$HW\O,1-&:*WaXM}5I *H$HW\O,1-&:*WaP-( C}(--( C}(--( C}(-%04@  ,$ LKPX@0g   ga>Ma ?N@4g   ga>M 9Ma?NY@11141432*(%%"," +#'#"&55467'&&54632#4&#"!!%32671'5!S?KcR]73cQWfZ5.)1u[/+"?>WaXM}5I *H$HW\O,1-&:P(--( CnPPGKPX@g_8N@Wg_OY@  +3!!Z]UCP# q3@0 LWh_O# +%3!&&''3#7667!Z[ji#N >$(C@@ LggW_ O%%%(%('&$#!%!,! +5326''&67&&776&##53233#"#!37s/2 6125 2/ssYe &Ann@' eYZnP++9J J9++PWO5/P/5OWTE> 3@0gW_O   +5!!5!!3<'vZnP PTT>&r VKPX@g_8N@Wg_OY@   +3!!!3RZ:ZUCPC> -@*v   +3!3!3ZZZnTTT _@  LKPX@_8N@W_OY@   +3!3!35667&&'wZZZS' 'CUCCCdh r hKPX@gg _8N@%Wgg_ OY@    +3!!!!!3RZ::ZUCPPC1 P@  LKPX@_8N@W_OY@   +3!35667&&'ZTZS' 'CUCCdh  YKPX@gg_8N@!Wgg_OY@  +3!!!!Z]]UCPP# q @@=LWhg_O  +%3!'3#7!5!7667&&''!Zkjik;#NهhA@  LKPX@ _8N@W_OY@  +35667&&'ZS' 'CUCdh tf-4<6@3<21%$ 5,Lv-- +5&&'3'&&5467535%667&&'&&'56654&''^kZ;6KQcTlIPh(dZ   nJRl -B6<0,B  _5ZK!PX@g _;N@ Wg_ OY@ +%5#5353!533##5!߿XXXn_PP_5kK!PX@  g  _; N@% W  g _   OY@ +%5#5353!53!533##5!#5!XXXXnXn_PP-g >@; LWg_O  +%5#53533#%5%667&&'%5XA6! "-PPW  Zdd0 #'KPX@*W   W e  aAN@, g    ge aANY@3$$  $'$'&% # #"!      +"&5463275!!5!"&54632%5!!5!$,,$$,,!!$,,$$,,!&!+%$,,$%+ PPPP,$%++%$,FPPPP #d@a g  g _8M a B N #"    +%5375!!5!5!!5!"&546332#j!!!&!"""xxuPPPPPPPP""!#/@,gW_O +5!5!PPPPO1 hK.PX@gc_;N@#ggW_OY@   +5!5!5!hhhFFFFFF# qlLK PX@%pqhW_O@#hW_OY@ +77!5!7667&&''!5!'3k~?kj#PP# qlLK PX@%pqhW_O@#hW_OY@ +77!5!7667&&''!5!'3kj*kj#PP# qG@DLWhg_ O +'7!5!7667&&''!5!'337667&&''3pkkVkjþj#PP#qG@D LWgg_ O +7'!5!'7!5!7333rj%??dji.2i.2#PPPP7=''7=5@2h g  9 N +!7!5!7!5!73!!!!nbgmqZq+g' X5+-g'4@775+1  2+%5%6675&&'%55%bbZXd?ZZ# q B@?LWhg_O  +%3!'3#7!7!7667&&''!jjkjik_j_?#&(هP*@S& 5+#q<@9 LWg_O    +%3!!!3jkj#&(P&(#q G@DLWgg_ O  +%3!!!!!3jjP??jkj#&(PPPP&(mAS'' #q0@-LW`P# +%3!!i{#''P #q0@-LW_O#+%3!!i #''K #q 3@0 LWh_O  +53#5!#3|ZZjir''# q 5@2LW`P  +%3!'3#7!ifji#''#q 4@1LWh_O  +%3!73#'!iij`#''-g'4@775+C$b@_L    h _8M a BN$#  +%533!!%5!"&546332#\jij"""xxu''P PP""!#@D1>4@1654 L>:32-)( IWaQ#" +7'7667'&&''77&&5536677'&&'#%5%HJ;Nww DXEwwL9KHK  R! "6@2l7 *S* +R"}}"R* *S*  6l2lJIkdW  @1>K;@8JIH654 LKD@?>:32-)( IWaQ#" +%'7667'&&''77&&5536677'&&'#%5%5%667&&'%5IHJ;Nww DXEwwL9KHK  R! "66! "@2l7 *S* +R"}}"R* *S*  6l2lJIkdW  ZW  ZdEA@ LKPX@ _8N@W_OY@  +53'SZZC' 'Umdrhp w P@  LKPX@_8N@W_OY@   +3!53'xZSZZC' 'UCmdrhp ~ _@  LKPX@_8N@W_OY@   +3!3!53'-ZZSZZC' 'UCCmdrhp  *@' Lv +375667&&'55Zn' 'CSwSC& &nzk  gdodrk  tf-4<I@F2$<1% ,L5KaBN-- +5&'%5%'&&546753#4&'56654&''yi! !,]7JRcTFH@EF<;/.($"! #6L?KaBN77 +5&'%5%'&&5467535%667&&'&'56654&''yi! !,]7JRcT<#P%[R6! "?4(IPiX0-,1160+ /dW  lJPgdW    mKRl -B6<0,AC$(,͵LKPX@D  h  g8M_;M  9 N@B  hh  g8M  9 NY@2))),),+*('&%$$#"!  +!7#537#53733733#3##7#%3!!%37#5!%Ua$bn%F%%F%Ua$bn%F%%Aii$3AAAA#''PȯPP-&g >@; LWg_O  +75#53533#%%5%XgR! "6-PPdW  -g %E@B$#"% LWg_O  +%5#53533#%%5%5%667&&'%5XbR! "66! "-PPdW  ZW  Zd1 2+%%5%2%51bbdZX#q @@=LWhg_O  +%3!53#5!'!5!ikZZk:=#''נO#q lLK PX@%pqhW_O@#hW_OY@  +%3!!!!ik>=>~k#''POQPC# q w@ LK PX@'pqhW_O@%hW_OY@  +%3!'3#7!'!7'!*ikkjikk}AB=#''هOQO# q w@ LK PX@'pqhW_O@%hW_OY@  +%3!'3#7!'!7'!ikkjikZk%AB>#''هOQO#q B@?LWhg_O  +%3!73#'!'!'7!ikjijjak??_=#''؇PPO4(l2+5%5%%667&&'%48N% %(dd  GAS'#q<@9 LWh_O    +%3!!!3iFji#''K''#q G@DLWhg_ O  +%3!!!!!3ik.?@mkji#''POQP''AS''ֺ#qLR@ QNK LK PX@4 rW   j j_O@5  W   j j_OY@$MMMRMRPOLLJHDB><8620#$$$$$! +%33232>3232>3232553#".#"#".#"#".##!3i&1""2%%4$$3%%2"/UG;%2!$3&%3$"1&&1"Zji#''''''''''''7((:H''''''''''''#q=@ <LKK PX@7r    jYb R@8    jYb RY@==8620$#$$$$! +%332>3232>3232553#".#"#".#"i "2%%4$$3%%2"/UG;%2!$3&%3$" )#''''''''8((:I''''''!AS M@LJ IK PX@,rr iYb R@. iYb RY@IGCA>=;953/-)'$#!MM +%%5%5%667&&'%5".#"#5463232>3232553#".#"bR! "66! "%2"/UH:%1"!2%%2"/UG;%2!!1AdW  ZW  Zd3''7((;G''''''7((:H''''#qf@   LK PX@7   r  i Y b R@8     i Y b RY@)b`\ZVTPNJHDB?><:640.*($" ff +%".'#332>3232>3232>3232553#".#"#".#"#".#"$0" ji#"2%&1""2%%4$$3%%2"/UG;%2!$3&%3$"1&&1""1$& '' ''''''''''''''7((:H''''''''''''*>#@ Lv +75%3(+_nqdZ  T>*@' Lv +75%35%667&&'%+_=;R6! " nqdZ  dW  BnKPX@"iYgaQ@)iYgaQY@  +'".#"#5463232655!!d)8)$''UUF*9)#' &/F+,& <NK.PX@=   ii i  g  e a >N@D   ii i  g  e a >NYY@'=<CA32#5#'2554&#"vAEEA)7 UP2I70/9J3/K>5/UH:/K>6%5,,3D_ArG 7P')P7OLxLO#FUZ-JXYJ-'4'7FF;G'4',JWWJ,rR7#?fo/,\x\# q=@ L< KK PX@7  r      jYbR@8        jYbRY@==;:97$$$"$$$% +77.#"#".#"#"&55332>3232>32333) "$2&%4$!1&:HU/"2%%3$$4%&1"j#"''''''H:((7'''''''W3K PX@,rr iYb R@. iYb RY@/-)'$#! 33 +'".#"#5463232>3232553#".#"_%2"/UH:%1"!2%%2"/UG;%2!!1''7((;G''''''7((:H''''# qa@ ] ` LK PX@8  r   i   Y  b RKPX@9     i   Y  b R@@        i   Y  b RYY@"aa_^YWSQMKGEA?;953$$$$$$$ +7'#".#"#".#"#".#"#"&55332>3232>3232>3232>7'3"2%%2""1&%2"$2&%4$!1&:HU/"2%&2$$4%&1""2%&1"$j#&$#''''''''''''H:((7''''''''''''%% 9=@: LgW_O +3!!'&&'5!9Tw  |$^PPPw@(N+3P7`w?wdD@v +D3P77*dD@v +D3!3JPP77cXwdD@v +D3P7% 3dD@(YaQ      +D"&54632#"&54632########"##""##" 'dD@YaQ   +D"&54632!&&!!&&"##"JdD@v +D'3sdn[dD@v +D73jao;2dD@'W_O +D73!73n\sn\se&@_8N +73 U&'dD@Lv +D73#'ScRPNN'dD@Lv +D'373cRPeNN4t 1dD@&YaQ    +D"&5332653HXG0()1GXPA'00'AP\`LD 9dD@.iYaQ      +D"&54632'2654&#"6BB66BB6!!!!`?33??33?5!""!4t mdDK.PX@iYbR@)iYbRY@  +D".#"#5463232553&A2(&A1#-2#-24t&dD@W_O +D5!4@KKz89NdDK PX@qW_O@W_OY@ !$ +D7654##5322 Pi&/(? A'# 4m%dD@W_O +D#'3#'3Ws\!Ws\zGpdD@v +D#7P}p NdDK PX@pYbR@YbRY@ ! +D532553##K:/A#KP+4+ 'dD@YaQ   +D"&54632!&&!!&&"##"\L 9dD@.iYaQ      +D"&54632'2654&#"6BB66BB7! !!7--77--73f.dD@v +D73f_iiu5B6dD@+ LiY_O! +D532654I#uF72#98&B67 _=$"1a5) .dD@#Y`P  +D"&54673337C&/K "<5(:! -<"h&dD@W_O +D5!"FFNdD@v +D3[HldD@v +D3=?n} XXs YXtZX[X\Xw^Xw_X`X`DaX bXcX5kX5 lXf.j%1 +@(YaQ      +"&54632#"&54632########1"##""##"0 @YaQ   +"&54632!&&!!&&0####J*@v +'3sdn**[@v +73jao*;**@'W_O +73!73n\sn\s**@Lv +73#'ScRP*NN*@Lv +'373cRPe*NN4%t )@&YaQ    +"&5332653HXG0()1GX%PA'00'AP\L 1@.iYaQ      +"&54632'2654&#"6BB66BB6!!!!?33??33?5!""!4/teK.PX@iYbR@)iYbRY@  +".#"#5463232553&A2(&A1/#-2#-24Ht@W_O +5!4@HKKz 3FK PX@qW_O@W_OY@ !$ +7654##532- KP/:# ? A)"4*m@W_O +#'3#'3Ws\!Ws\*4%t &@#YaQ ""+4632#4&#"4XHHXG1)(0%APPA'00'z*8@W_O +#7A}sH ?@gABCDEFGHIJKL345MNO6PQRST7UVWX8YhZ[\]^_`abcdef9:ghij;<klmnop=qrDistuvwxykz{|}~ljnmEFoGHprsqIJKLtvwuMNOPQxRy{|z}STUVWX~YZ[\]      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~" ? ^`>@B      !aA  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ #   _   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~CAbreveuni1EAEuni1EB6uni1EB0uni1EB2uni1EB4uni01CDuni1EA4uni1EACuni1EA6uni1EA8uni1EAAuni1EA0uni1EA2AmacronAogonekAEacute Ccircumflex CdotaccentDcaronDcroatEbreveEcaronuni1EBEuni1EC6uni1EC0uni1EC2uni1EC4 Edotaccentuni1EB8uni1EBAEmacronEogonekuni1EBCuni01F4Gcaron Gcircumflexuni0122 GdotaccentHbar HcircumflexIbreveuni1ECAuni1EC8ImacronIogonekItilde Jcircumflexuni0136LacuteLcaronuni013BLdotNacuteNcaronuni0145EngObreveuni1ED0uni1ED8uni1ED2uni1ED4uni1ED6uni1ECCuni1ECEOhornuni1EDAuni1EE2uni1EDCuni1EDEuni1EE0 OhungarumlautOmacronuni01EA OslashacuteRacuteRcaronuni0156Sacute Scircumflexuni0218uni1E9Euni018FTbarTcaronuni0162uni021AUbreveuni1EE4uni1EE6Uhornuni1EE8uni1EF0uni1EEAuni1EECuni1EEE UhungarumlautUmacronUogonekUringUtildeWacute Wcircumflex WdieresisWgrave Ycircumflexuni1EF4Ygraveuni1EF6uni0232uni1EF8Zacute Zdotaccentabreveuni1EAFuni1EB7uni1EB1uni1EB3uni1EB5uni01CEuni1EA5uni1EADuni1EA7uni1EA9uni1EABuni1EA1uni1EA3amacronaogonekaeacute ccircumflex cdotaccentdcaronebreveecaronuni1EBFuni1EC7uni1EC1uni1EC3uni1EC5 edotaccentuni1EB9uni1EBBemacroneogonekuni1EBDuni0259uni01F5gcaron gcircumflexuni0123 gdotaccenthbar hcircumflexibreve i.loclTRKuni1ECBuni1EC9imacroniogonekitildeuni0237 jcircumflexuni0137 kgreenlandiclacutelcaronuni013Cldotnacute napostrophencaronuni0146engobreveuni1ED1uni1ED9uni1ED3uni1ED5uni1ED7uni1ECDuni1ECFohornuni1EDBuni1EE3uni1EDDuni1EDFuni1EE1 ohungarumlautomacronuni01EB oslashacuteracutercaronuni0157sacute scircumflexuni0219longstbartcaronuni0163uni021Bubreveuni1EE5uni1EE7uhornuni1EE9uni1EF1uni1EEBuni1EEDuni1EEF uhungarumlautumacronuogonekuringutildewacute wcircumflex wdieresiswgrave ycircumflexuni1EF5ygraveuni1EF7uni0233uni1EF9zacute zdotaccentuni0410uni0411uni0412uni0413uni0403uni0490uni0414uni0415uni0401uni0416uni0417uni0418uni0419uni041Auni040Cuni041Buni041Cuni041Duni041Euni041Funi0420uni0421uni0422uni0423uni040Euni0424uni0425uni0427uni0426uni0428uni0429uni040Funi042Cuni042Auni042Buni0409uni040Auni0405uni0404uni042Duni0406uni0407uni0408uni040Buni042Euni042Funi0402uni04AEuni04E8uni0430uni0431uni0432uni0433uni0453uni0491uni0434uni0435uni0451uni0436uni0437uni0438uni0439uni043Auni045Cuni043Buni043Cuni043Duni043Euni043Funi0440uni0441uni0442uni0443uni045Euni0444uni0445uni0447uni0446uni0448uni0449uni045Funi044Cuni044Auni044Buni0459uni045Auni0455uni0454uni044Duni0456uni0457uni0458uni045Buni044Euni044Funi0452uni04AFuni04E9AlphaBetaGammauni0394EpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsiuni03A9 Alphatonos EpsilontonosEtatonos Iotatonos Omicrontonos Upsilontonos Omegatonos IotadieresisUpsilondieresisuni03CFalphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronrhouni03C2sigmatauupsilonphichipsiomega iotatonos iotadieresisiotadieresistonos upsilontonosupsilondieresisupsilondieresistonos omicrontonos omegatonos alphatonos epsilontonosetatonosuni03D7uni03D6uni2115uni211Auni2124 zero.zerouni2080uni2081uni2082uni2083uni2084uni2085uni2086uni2087uni2088uni2089uni2070uni00B9uni00B2uni00B3uni2074uni2075uni2076uni2077uni2078uni2079onedotenleaderuni203Euni203F colon.caseperiodcentered.loclCAT.caseperiodcentered.loclCATuni2770uni276Euni2771uni276Funi00ADuni2010hyphen_hyphen.ligahyphen_hyphen_hyphen.ligahyphen_hyphen_greater.ligahyphen_bar.ligahyphen_greater.ligahyphen_greater_greater.ligahyphen_less.ligahyphen_less_less.ligahyphen_asciitilde.ligabraceleft_bar.ligabracketleft_bar.ligabracketleft_less.ligabracketright_numbersign.ligaperiod_period.ligaperiod_period_period.ligaperiod_period_less.ligaperiod_question.ligaperiod_equal.ligacolon_colon.ligacolon_colon_colon.ligacolon_colon_equal.ligacolon_question.ligacolon_question_greater.ligacolon_equal.ligacolon_greater.ligacolon_less.ligasemicolon_semicolon.ligaexclam_exclam.ligaexclam_equal.ligaexclam_equal_equal.ligaquestion_period.ligaquestion_colon.ligaquestion_question.ligaquestion_equal.ligaasterisk_asterisk_asterisk.ligaasterisk_greater.ligaasterisk_slash.liganumbersign_parenleft.liganumbersign_braceleft.liganumbersign_bracketleft.liganumbersign_colon.liganumbersign_exclam.liganumbersign_question.liganumbersign_numbersign.liga%numbersign_numbersign_numbersign.liga0numbersign_numbersign_numbersign_numbersign.liganumbersign_equal.liganumbersign_underscore.liga$numbersign_underscore_parenleft.ligaslash_asterisk.ligaslash_asterisk_asterisk.ligaslash_equal.ligaslash_equal_equal.ligaslash_greater.ligaslash_slash.ligaslash_slash_equal.ligaslash_slash_slash.ligaunderscore_bar_underscore.ligaunderscore_underscore.ligauni27E8uni27E9 anoteleiauni037Euni00A0CRuniFEFFuni20BFdongEurouni20BDuni20AEuni2219uni2201uni2210uni2223uni2215elementuni220E equivalence existentialuni22B8uni228Euni2A00uni2A06uni2249uni220C notelement notsubsetuni2285 logicaland logicalor intersectionunionuni00B5uni2225uni239Cuni239Duni239Buni239Funi23A0uni239Euni207Auni2237uni2236 reflexsubsetreflexsupersetuni22A2uni2218similaruni22C6 propersubsetsuchthatpropersupersetuni22A4 universaluni22A5uni229Buni2296circlemultiplyuni2299 circleplusarrowupuni2197 arrowrightuni2198 arrowdownuni2199 arrowleftuni2196 arrowboth arrowupdnuni21E7uni2304uni279Cuni27F5uni27F6uni27F7uni2581uni2582uni2583dnblockuni2585uni2586uni2587blockupblockuni2594uni258Funi258Euni258Dlfblockuni258Buni258Auni2589rtblockuni2595uni2596uni2597uni2598uni2599uni259Auni259Buni259Cuni259Duni259Euni259Fltshadeshadedkshadeuni25CFuni25EFuni25D4uni25D5uni25CCuni25CE openbulletuni25C6uni25C7 filledboxuni25A1uni25AAuni25ABuni25E7uni25E8uni25E9uni25EAuni25EBtriagupuni25B6triagdnuni25C0uni25B3uni25B7uni25BDuni25C1triagrttriaglfuni25BBuni25C5uni25B4uni25B8uni25BEuni25C2uni25B5uni25B9uni25BFuni25C3uni2566uni2557uni2554uni2550uni2569uni255Duni255Auni2551uni256Cuni2563uni2560uni2565uni2556uni2553uni2530uni2512uni2527uni250Euni251Funi2541uni252Funi2511uni2529uni250Duni2521uni2547uni2564uni2555uni2552uni254Duni254Funi257Buni2533uni2513uni250Funi2501uni2578uni257Euni2509uni250Buni257Auni2505uni2507uni2579uni253Buni251Buni257Funi2517uni2503uni254Buni252Buni2523uni2545uni252Duni2535uni253Duni2532uni253Auni254Auni2543uni256Euni256Duni256Funi2570uni2573uni2572uni2571uni254Cuni254Euni2577uni252Cuni2510uni250Cuni2500uni2574uni257Cuni2508uni250Auni2576uni2504uni2506uni2575uni257Duni2534uni2518uni2514uni2502uni253Cuni2524uni251Cuni2546uni252Euni2536uni253Euni2531uni2539uni2549uni2544uni2568uni255Cuni2559uni2540uni2538uni2526uni251Auni251Euni2516uni2548uni2537uni252Auni2519uni2522uni2515uni2567uni255Buni2558uni256Buni2562uni255Funi2542uni2528uni2520uni253Funi2525uni251Duni256Auni2561uni255Euni2374uni26A0uni26A1uni2713uni2715uni2717uni2736minuteseconduni2113uni2116 estimateduni2303houseuni2325uni2318uni23FBuni23FCuni2B58uni23FDuni23FEuni2305uni02F3uni02F7at_underscore.ligaampersand_ampersand.liga"ampersand_ampersand_ampersand.ligaampersand_equal.ligabar_hyphen.ligabar_hyphen_greater.ligabar_braceright.ligabar_bracketright.liga bar_bar.ligabar_bar_hyphen.ligabar_bar_bar.ligabar_bar_bar_greater.ligabar_bar_equal.ligabar_bar_greater.ligabar_equal.ligabar_equal_greater.ligabar_greater.ligadollar_greater.ligaplus_plus.ligaplus_plus_plus.ligaplus_greater.ligaequal_colon_equal.ligaequal_exclam_equal.ligaequal_equal.ligaequal_equal_equal.ligaequal_equal_greater.ligaequal_greater.ligaequal_greater_greater.ligaequal_less_less.ligaequal_slash_equal.ligagreater_hyphen.ligagreater_hyphen_greater.ligagreater_bracketright.ligagreater_colon.ligagreater_equal.ligagreater_equal_greater.ligagreater_greater.ligagreater_greater_hyphen.ligagreater_greater_equal.ligagreater_greater_greater.ligaless_hyphen.ligaless_hyphen_hyphen.ligaless_hyphen_bar.ligaless_hyphen_greater.ligaless_hyphen_less.ligaless_colon.ligaless_exclam_hyphen_hyphen.ligaless_asterisk.ligaless_asterisk_greater.liga less_bar.ligaless_bar_bar.ligaless_bar_bar_bar.ligaless_bar_greater.ligaless_dollar.ligaless_dollar_greater.liga"less_numbersign_hyphen_hyphen.ligaless_plus.ligaless_plus_greater.ligaless_equal.ligaless_equal_bar.ligaless_equal_equal.ligaless_equal_equal_greater.ligaless_equal_greater.ligaless_equal_less.ligaless_greater.ligaless_less.ligaless_less_hyphen.ligaless_less_equal.ligaless_less_less.ligaless_less_asciitilde.ligaless_asciitilde.ligaless_asciitilde_greater.ligaless_asciitilde_asciitilde.ligaless_slash.ligaless_slash_greater.ligaasciitilde_hyphen.ligaasciitilde_at.ligaasciitilde_greater.ligaasciitilde_asciitilde.liga"asciitilde_asciitilde_greater.ligaasciicircum_equal.ligauni0374uni0375uni02BCuni02BAuni02C9uni02B9uni0308uni0307 gravecomb acutecombuni030B uni030C.altuni0302uni030Cuni0306uni030A tildecombuni0304 hookabovecombuni030Funi0312uni031B dotbelowcombuni0325uni0326uni0327uni0328uni0336uni0337uni0338 uni0326.alt uni0308.case uni0307.casegravecomb.caseacutecomb.case uni030B.case uni0302.case uni030C.case uni0306.case uni030A.casetildecomb.case uni0304.casehookabovecomb.case uni030F.case uni0311.case uni0312.case uni031B.casedotbelowcomb.case uni0324.case uni0326.case uni0327.case uni0328.case uni032E.case uni0331.case dieresis.casedotaccent.case grave.case acute.casehungarumlaut.casecircumflex.case caron.case breve.case ring.case tilde.case macron.casetonos tonos.case dieresistonos brevecombcy uni03060301 uni03060300 uni03060309 uni03060303 uni03020301 uni03020300 uni03020309 uni03020303uni03060301.caseuni03060300.caseuni03060309.caseuni03060303.caseuni03020301.caseuni03020300.caseuni03020309.caseuni03020303.caseuniE0A0uniE0A1uniE0A2uniE0B0uniE0B1uniE0B2uniE0B3NULLSPC 9\^wyy{/224=@WY]_knnpruvy|~ Xo} XfDFLTlatn84AZE 4CAT 4CRT 4KAZ 4MOL 4ROM 4TAT 4TRK 4mark (pXlno~.6\^w\yyv{w/224= @W*Y]B_kGnnTprUuvXy|Z~^afghklmoquvwyz} ?444 444444444.....::"(::::::::::::.......444444444::::::::&&&&<<<<<<<<<<<<<<<<<<<<<<<TTTTBZHBZHBZHBZHBZHBZHBZHBZHBZHBZHBZHBZHBZHBZHBZHBZHBZHBZHZZZZZZZZZZZZZZZZZZNlTNlTNlTNlTNlTNlTNlTNlTNlTNlTNlTNlTNlTNlTNlTNlTNlTNlTNlTNlTNlTNBBNlTllllllllllllllllllx x x x x x x x x x x x x x x x x x x x x x x ~~~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l~l~~l$*0$*0$*0$*0$*0$*0$*0$*0$*0$*0$*0$*0$*0666~ZZZZZxxxxxx~flr~flr~flr~flr~flr~flr~flr~flr~flr~flr~flr~flr~flrflrflrflrflrflrflr~flr~flr~f~f~f~flr~~~~~~~`l~`l~`l~`l~`l~`l~`l~`l~~~~~~~`l~`l~`~`l~`l~~~~~~~~~~~~~~~~~~<ZHBZHNlTZZx ~l~l~~~~~flr~~~$*0$*06<BZHNlTZNlT<BZHZNlTZ~x~~~flr~`l~~~~~`l~`l~`l~flr~x~")&"&''@&h+61h1J&.&.;&;J&@@,m@&L&^,1&,&0&0,, DFLTlatn4AZE CAT NCRT KAZ MOL jROM TAT TRK      aaltVcalt^casevccmp|ccmpfracloclloclloclordnsinfsubssupszero !#&)+.047;=@DGJMORTVY]`bdhkmoruwz~ "$&(*-/2468:<>@BDFHJLNPRTVXZ\^`bdyfilfilluonmvxsrtz{$v`nt ( B  Z t p V p p d ^ p ~ 9 FxXjxxdVddr:PHPP6P^1D&?bt1D$v? ???"6V00h0RlR<\d1D.<\<<\<\0BRl  v? !"9!4!!"25"L""#h#v#$"9$4$9$%%&89&F&99''9''((b(|(()L+)Z)))*>++*L**+2+P+++,z00,-0-"-t-.0..0..//x/000$01D0161D1D1R1112$2>233h33434F4`44445J5d5556X96r6?67z?78498R999$9<\9:,<\:>:<\:;8<\;J;;h>z>?????@"@@@@ATArABBCBCCCCCCDDnDDEEXErEFFRFlFFGNGlGGH0HJHHI*IDIIJ&JDJJKK.KKKLLdL~LLMTMnMMN8NRNNO@O^OOPzPzQQdQdQRRRSSS(S(S6SjSSTT2Tl3lmlm=DQ~3_;CRVXYZ[\^_`abcdefghjklpqrstuvwxyz"JRX^djpv|(.:n%&0'1(2)3*4+5,6-7.8/9|}P".QR0{J! op &)/8CL69 #';=DQ"qst  $%(,157:>?AHKNP uvz~-@BEwFGIOM rxy +234<" !"#$>@ACEGIJMSUWX]b.@>>I>HHILH>|H b.@IIIIIIHHHHHP"4H\HHHHHHHHHzHzHHfHH HpHpHp HTQ&:Pf|H<H<HBhA @ BX@=$BH@A^B8@DE@B@ zW.@AjAj7AZ77Eh7A87 xU 0@R@@@@t@t@t@d@dDD@T@B@B@(X"4H\@@@@@@@@DD?Dp????? ?Z 0@R??C0C ?C ?tCCCC"?RB"*$6H\p???BB? ? B>>BBC|C|B$Ch>Bn$>>BZ%*>o"4H\>z>zBB>hBBBBBA'BAA(>.AA')t$4DTdv==<<0<$<<" 0@R$^$^$^$N$N$N$>$>9>$.>$$?$>"4H\########>">"#A>##B###C#?"4H\#n#n#n8#\#\88==8E=#68E#"#"8tF ~>"~(>Rh~8$8$;N11:J<8;:117;$111<<<1H<<11I<:11H7:1v1vH /C]"4H\7`7`7`127N7N1 1 ,2274742c7 +2c2+2|c ,]&:Pf|11) ) ) 1((((666(e66((f6t(((g1V(((e4$6J^11(h(h1 (V(V166(Di5(0(0j0((i3 2BT00'0'''0x'05p'l0V'l 2 0@R))'f0 )'V)'F'F4'6n)'$n4r"4H\)v)v00)d0 0 0 44/p4t//q)*//p t$6J^(((/((//44/ts3(/`s((/Lt vq&6FVfv/(j/(Z(Z/.(J.%(:.(*..+(.3@.v'.vs&6FVfv.d.d.d.T.T.T.D.D1.4.4'1.$.$...2.x--y-P"4H\--------2.2.-{2--|-v-v-v}-ZS"2BRd-B-B0-200-"0-"-0,10,0#.@,,/,//1./,/ " (8HXhx,P,P0)\,@0*,00', 0, ,0/,0+000p0+0v !X$4FVfx+/$"b++/-0/*/*..*.*/.*.;"4FZ*~*~..*l*l*l.z/b.h/P*H.V*4*4.BD&:L^r))..,".)--)---)--*:..-.--)--r="4H\)R)R ))@ )).6.6)." f)) R)~ 5"4H\-b-b -b-P-P-P--->--*-- b$6JZj|+`+`,D*`,+P,4(*N,+>,",+*,+++,+*+"4HXj***),,**'v),*****,Z*|*j*j*PG*By&:Pbv*(*(+ + )&+***&)+|***)***++*+**)**$8J^r*^*^)z*^(x**L)h*L*8)T*8*8+ + *&+ ).*))) C *:JZn')& ))&&)&)%%h'* )v%'))b%)P%)P)@%%**%)% $8JZj|((($')l((&)X(((((((% )((~(~(dE(<N`r(H(H(H(H&b((6(6(6$("("("(((('''$h(('(''''''F$8J^r''''%('~' '~'j&'j'j(R(R'X(>&'D'0&'0B 0@R&&&&x&x&&h&&'&&F&.@&&"&""'`"%" @.@%%" %!!&!%v! @ 0@R%:%:%:%*%*%*%%%&v% $$$A.@```PPP&@..H{A"4H\$T$T$T$T$B$B$B$B%%$0%$$$$$#B 0@R##"t#"d"d#"T %"D#"2~"4H\#`#`! <#N! * *$$ $! #! @E"4H\"""#D""#2#2$$# $"# """ @"P|&:Pf|#|#|#|#f#f#P~~~ $6H\pDDDp22^  LL"":"&n.@"N $6J^DDD000!!! | $6J^  n!V!V \!B Hrr 4  0@R<<,H  ] 0@Rp`` JP|> "2BRd>>>....$:JZl22xN      &8J^r0LnZZFFF*_.@ppp```P>>$Jw 0@RbRRB2  @E (8L`tzzNj>>Z..F62Vt H E.@ Zz >E.@\\\LLL<** 0@R|p "4H\||||jjjj  XDD000.@DD4~r> >.@ vGhZ$8J^r$Dnt`` M"4H\    -$8J^r"~~jxjj``XLRD0>0@(>Rf|nZDD0x >(:Pdv<<*** D.lXXF2$8J^rnn\H00xx"4H\BBB000 $"4H\VDD,,2  tt   '"4H\666 $$ ~ ~ l  X  D &"2BRd  `"4H\,,,tN:  ] 0@R` PP @t0 G"2BRd  l|t"4H\ " "f  T  v. b  N H"2BRddd  T  D r4 b bZ R @u"4H\       v]$8J^r  | n nh Z Z ZPP H < 4 4!.    "4H\    #n# Z# +]$8J^r D DR l 2@~ ,jjX%D%  0% <"4H\    'r x ' d ' "4H\`` N z z  h)  T) @) ]$6H\p~~lZ P P+ <xx, dd+ I 0@R&: .r.pw"4H\ P P0 <x0dd1|P6.@""VFF 63$3 N.@D44 Z$55] L].@DDJ4:: *77 M.@DD 4  p v9 d9 Q"4H\<*zz h; T;@; 7.@x p=V~= 6.@DD4 t?b? "4H\< *AxA\A :.@ C~C 9.@DD(4EE "4H\<<<**  G |GhG 1I.@I~~I 0I.@DD4,KKI I"4H\BH066$M MM KM.@DD4,OO JM.@DDJ4::*QQM M.@Dp44B$SNSU JU.@D44$UUW JW.@  ^WjW JS.@00D 44$YYE EJ 0@R4$$n[z[ Jb.@@@D044$]]C CJ.@D44$__@ @J.@\\DL44$a*a J"4H\`fNTTBc(.ccbS JSb.FJJP:@@0eeXJ {JX ^p&@g.hghiklmoX\^fgthnX)~X\^hjlpz ! $jk~ T'~X\^hjlpz0Rt [Zdb [Zdb  ^`=D;C $Pp 6qR  G  0123456789$ , <M;M=M $,ww$_lmlm_>YX)PQ~@@RRX\^hjlpz ! harmonica-0.1.0/examples/opengl/main.go000066400000000000000000000142731407661036600200460ustar00rootroot00000000000000package main import ( "fmt" "image" "math" "math/rand" "time" "github.com/charmbracelet/harmonica" "github.com/faiface/pixel" "github.com/faiface/pixel/pixelgl" "github.com/fogleman/gg" "golang.org/x/image/font" ) const ( width = 1024 height = 768 bgColor = "#575BD8" textColor = "#827EFF" spriteColor = "#FFFDF5" fontFile = "JetBrainsMono-Regular.ttf" idleTimeout = time.Second * 4 ) func main() { rand.Seed(time.Now().UnixNano()) pixelgl.Run(Game{}.Run) } type Game struct { deltaTime float64 frequency float64 damping float64 win *pixelgl.Window shift bool font font.Face sprite *Sprite lastClick time.Time dirty bool showHelp bool } func (g Game) Size() (width, height float64) { return g.win.Bounds().W(), g.win.Bounds().H() } func (g Game) MousePosition() (x, y float64) { return g.win.MousePosition().X, g.win.MousePosition().Y } func (g Game) Run() { g.frequency = 10.0 g.damping = 0.2 g.showHelp = true var err error if g.font, err = gg.LoadFontFace(fontFile, 24); err != nil { panic(err) } cfg := pixelgl.WindowConfig{ Title: "Harmonica Example", Bounds: pixel.R(0, 0, width, height), VSync: true, Resizable: false, } if g.win, err = pixelgl.NewWindow(cfg); err != nil { panic(err) } last := time.Now() for !g.win.Closed() { w, h := g.Size() // Get delta time g.deltaTime = time.Since(last).Seconds() last = time.Now() g.Update() // Use fogleman/gg to render everything ctx := gg.NewContext(int(w), int(h)) g.Draw(ctx) canvas := g.win.Canvas() canvas.SetPixels(ctx.Image().(*image.RGBA).Pix) // Render g.win.Update() } } func (g *Game) Update() { pressed := g.win.JustPressed released := g.win.JustReleased // Handle shift key switch { case pressed(pixelgl.KeyLeftShift), pressed(pixelgl.KeyRightShift): g.shift = true case released(pixelgl.KeyLeftShift), released(pixelgl.KeyRightShift): g.shift = false } adjustFreq, adjustDamp := 0.0, 0.0 // Handle arrow keys to adjust frequency and damping switch { case released(pixelgl.KeyLeft): adjustFreq = -0.1 case released(pixelgl.KeyRight): adjustFreq = 0.1 case released(pixelgl.KeyUp): adjustDamp = 0.01 case released(pixelgl.KeyDown): adjustDamp = -0.01 case released(pixelgl.KeySpace): g.showHelp = !g.showHelp } if g.shift { adjustDamp *= 10 adjustFreq *= 10 } if adjustFreq != 0 || adjustDamp != 0 { g.frequency = math.Max(0, g.frequency+adjustFreq) g.damping = math.Max(0, g.damping+adjustDamp) g.dirty = true } if time.Now().After(g.lastClick.Add(idleTimeout)) { if g.sprite != nil { g.sprite.Hide() } } if released(pixelgl.MouseButtonLeft) { if g.sprite == nil { g.sprite = NewSprite(g) } else { s := g.sprite s.TargetX, s.TargetY = g.MousePosition() switch s.State() { case hiding, gone: s.Show() } } g.lastClick = time.Now() } // Sprite if g.sprite != nil { g.sprite.Update() } g.dirty = false } func (g Game) Draw(ctx *gg.Context) { w, h := g.Size() // BG ctx.SetHexColor(bgColor) ctx.DrawRectangle(0, 0, w, h) ctx.Fill() // Help text if g.showHelp { // For some reason our text renders upside down and backwards. Apply a // matrix to fix it. ctx.ScaleAbout(-1, 1, w/2, h/2) ctx.RotateAbout(math.Pi, w/2, h/2) // Instructional text ctx.Push() ctx.SetHexColor(textColor) ctx.SetFontFace(g.font) ctx.DrawStringAnchored("Click!", w/2, h/2, 0.5, 0.5) ctx.Fill() ctx.Pop() // Status str := fmt.Sprintf( "Frequency: %.1f (←/→: adjust) • Damping: %.2f (↑/↓: adjust)", g.frequency, g.damping, ) ctx.Push() ctx.SetHexColor(textColor) ctx.SetFontFace(g.font) ctx.DrawStringAnchored(str, w/2, h-34, 0.5, 0) ctx.Fill() ctx.Pop() // Reset matrix ctx.Identity() } // Draw sprites if g.sprite != nil { g.sprite.Draw(ctx) } } type SpriteState int const ( moving SpriteState = iota stopped hiding gone ) type Sprite struct { TargetX, TargetY, TargetRadius float64 X, xVel float64 Y, yVel float64 radius, radiusVel float64 color string spring harmonica.Spring game *Game } func NewSprite(g *Game) *Sprite { mouseX, mouseY := g.MousePosition() s := &Sprite{ X: mouseX, Y: mouseY, TargetX: mouseX, TargetY: mouseY, radius: 0.1, color: spriteColor, game: g, } s.computeSpring() s.randomRadius() return s } func (s *Sprite) Update() { if s.State() == gone { return } if s.game.dirty { // Recompute spring coefficients since our frequency or damping has // changed. s.computeSpring() } // Calculate positions based on our spring s.X, s.xVel = s.spring.Update(s.X, s.xVel, s.TargetX) s.Y, s.yVel = s.spring.Update(s.Y, s.yVel, s.TargetY) s.radius, s.radiusVel = s.spring.Update(s.radius, s.radiusVel, s.TargetRadius) } func (s Sprite) Draw(ctx *gg.Context) { if s.State() == gone { return } ctx.Push() ctx.DrawCircle(s.X, s.Y, s.radius) ctx.SetHexColor(s.color) ctx.Fill() ctx.Pop() } func (s Sprite) State() SpriteState { const precision = 2 x := roundFloat(s.X, precision) tX := roundFloat(s.TargetX, precision) y := roundFloat(s.Y, precision) tY := roundFloat(s.TargetY, precision) r := roundFloat(s.radius, precision) tR := roundFloat(s.TargetRadius, precision) if r == 0.0 { return gone } if s.TargetRadius == 0 { return hiding } if x == tX && y == tY && r == tR { return stopped } return moving } func (s *Sprite) computeSpring() { // Calculate spring coefficients s.spring = harmonica.NewSpring(s.game.deltaTime, s.game.frequency, s.game.damping) } func (s *Sprite) randomRadius() { s.TargetRadius = rand.Float64()*100.0 + 100.0 } func (s *Sprite) Show() { if s.State() == gone { s.X, s.Y = s.game.MousePosition() } if s.radius < 0.1 { s.radius = 0.1 } s.computeSpring() s.randomRadius() } func (s *Sprite) Hide() { // Fixed frequency and damping when hiding s.spring = harmonica.NewSpring(s.game.deltaTime, 32.0, 1.0) s.TargetRadius = 0 } func roundFloat(input float64, decimalPlaces int) float64 { pow := math.Pow(10, float64(decimalPlaces)) return math.Round(pow*input) / pow } harmonica-0.1.0/examples/tui/000077500000000000000000000000001407661036600161015ustar00rootroot00000000000000harmonica-0.1.0/examples/tui/main.go000066400000000000000000000041121407661036600173520ustar00rootroot00000000000000package main import ( "fmt" "math" "os" "strings" "time" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/harmonica" "github.com/charmbracelet/lipgloss" ) const ( fps = 60 spriteWidth = 12 spriteHeight = 5 frequency = 7.0 damping = 0.15 ) var ( helpStyle = lipgloss.NewStyle(). Foreground(lipgloss.AdaptiveColor{Light: "246", Dark: "241"}). MarginTop(1). MarginLeft(2) spriteStyle = lipgloss.NewStyle(). Foreground(lipgloss.Color("#FFFDF5")). Background(lipgloss.Color("#575BD8")) ) type frameMsg time.Time func animate() tea.Cmd { return tea.Tick(time.Second/fps, func(t time.Time) tea.Msg { return frameMsg(t) }) } func waitASec(ms int) tea.Cmd { return func() tea.Msg { time.Sleep(time.Millisecond * time.Duration(ms)) return nil } } type model struct { x float64 xVel float64 spring harmonica.Spring } func (_ model) Init() tea.Cmd { return tea.Sequentially(waitASec(500), animate()) } func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg.(type) { case tea.KeyMsg: return m, tea.Quit // Step foreward one frame case frameMsg: const targetX = 60 // Update x position (and velocity) with our spring. m.x, m.xVel = m.spring.Update(m.x, m.xVel, targetX) // Quit when we're basically at the target position. if math.Abs(m.x-targetX) < 0.01 { return m, tea.Sequentially(waitASec(750), tea.Quit) } // Request next frame return m, animate() default: return m, nil } } func (m model) View() string { var out strings.Builder fmt.Fprint(&out, "\n") x := int(math.Round(m.x)) if x < 0 { return "" } spriteRow := spriteStyle.Render(strings.Repeat("/", spriteWidth)) row := strings.Repeat(" ", x) + spriteRow + "\n" fmt.Fprint(&out, strings.Repeat(row, spriteHeight)) fmt.Fprint(&out, helpStyle.Render("Press any key to quit")) return out.String() } func main() { m := model{ spring: harmonica.NewSpring(harmonica.FPS(fps), frequency, damping), } if err := tea.NewProgram(m).Start(); err != nil { fmt.Println("Error running program:", err) os.Exit(1) } } harmonica-0.1.0/go.mod000066400000000000000000000000631407661036600145670ustar00rootroot00000000000000module github.com/charmbracelet/harmonica go 1.16 harmonica-0.1.0/go.sum000066400000000000000000000000001407661036600146030ustar00rootroot00000000000000harmonica-0.1.0/harmonica.go000066400000000000000000000160141407661036600157540ustar00rootroot00000000000000// Package harmonica implements a simplified damped harmonic oscillator. This // is ported from Ryan Juckett’s simple damped harmonic motion, originally // written in C++. // // Example usage: // // // Run once to initialize. // spring := NewSpring(FPS(60), 6.0, 0.2) // // // Update on every frame. // pos := 0.0 // velocity := 0.0 // targetPos := 100.0 // someUpdateLoop(func() { // pos, velocity = spring.Update(pos, velocity, targetPos) // }) // // For background on the algorithm see: // https://www.ryanjuckett.com/damped-springs/ package harmonica /****************************************************************************** Copyright (c) 2008-2012 Ryan Juckett http://www.ryanjuckett.com/ This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. ******************************************************************************* Ported to Go by Charmbracelet, Inc. in 2021. ******************************************************************************/ import ( "math" "time" ) // FPS returns a time delta for a given number of frames per second. This // value can be used as the time delta when initializing a Spring. Note that // game engines often provide the time delta as well, which you should use // instead of this function, if possible. // // Example: // // spring := NewSpring(FPS(60), 5.0, 0.2) // func FPS(n int) float64 { return (time.Second / time.Duration(n)).Seconds() } // In calculus ε is, in vague terms, an arbitrarily small positive number. In // the original C++ source ε is represented as such: // // const float epsilon = 0.0001 // // Some Go programmers use: // // const epsilon float64 = 0.00000001 // // We can, however, calculate the machine’s epsilon value, with the drawback // that it must be a variable versus a constant. var epsilon = math.Nextafter(1, 2) - 1 // Spring contains a cached set of motion parameters that can be used to // efficiently update multiple springs using the same time step, angular // frequency and damping ratio. // // To use a Spring call New with the time delta (that's animation frame // length), frequency, and damping parameters, cache the result, then call // Update to update position and velocity values for each spring that neeeds // updating. // // Example: // // // First precompute spring coefficients based on your settings: // var x, xVel, y, yVel float64 // deltaTime := FPS(60) // s := NewSpring(deltaTime, 5.0, 0.2) // // // Then, in your update loop: // x, xVel = s.Update(x, xVel, 10) // update the X position // y, yVel = s.Update(y, yVel, 20) // update the Y position // type Spring struct { posPosCoef, posVelCoef float64 velPosCoef, velVelCoef float64 } // NewSpring initializes a new Spring, computing the parameters needed to // simulate a damped spring over a given period of time. // // The delta time is the time step to advance; essentially the framerate. // // The angular frequency is the angular frequency of motion, which affects the // speed. // // The damping ratio is the damping ratio of motion, which determines the // oscillation, or lack thereof. There are three categories of damping ratios: // // Damping ratio > 1: over-damped. // Damping ratio = 1: critlcally-damped. // Damping ratio < 1: under-damped. // // An over-damped spring will never oscillate, but reaches equilibrium at // a slower rate than a critically damped spring. // // A critically damped spring will reach equilibrium as fast as possible // without oscillating. // // An under-damped spring will reach equilibrium the fastest, but also // overshoots it and continues to oscillate as its amplitude decays over time. func NewSpring(deltaTime, angularFrequency, dampingRatio float64) (s Spring) { // Keep values in a legal range. angularFrequency = math.Max(0.0, angularFrequency) dampingRatio = math.Max(0.0, dampingRatio) // If there is no angular frequency, the spring will not move and we can // return identity. if angularFrequency < epsilon { s.posPosCoef = 1.0 s.posVelCoef = 0.0 s.velPosCoef = 0.0 s.velVelCoef = 1.0 return s } if dampingRatio > 1.0+epsilon { // Over-damped. var ( za = -angularFrequency * dampingRatio zb = angularFrequency * math.Sqrt(dampingRatio*dampingRatio-1.0) z1 = za - zb z2 = za + zb e1 = math.Exp(z1 * deltaTime) e2 = math.Exp(z2 * deltaTime) invTwoZb = 1.0 / (2.0 * zb) // = 1 / (z2 - z1) e1_Over_TwoZb = e1 * invTwoZb e2_Over_TwoZb = e2 * invTwoZb z1e1_Over_TwoZb = z1 * e1_Over_TwoZb z2e2_Over_TwoZb = z2 * e2_Over_TwoZb ) s.posPosCoef = e1_Over_TwoZb*z2 - z2e2_Over_TwoZb + e2 s.posVelCoef = -e1_Over_TwoZb + e2_Over_TwoZb s.velPosCoef = (z1e1_Over_TwoZb - z2e2_Over_TwoZb + e2) * z2 s.velVelCoef = -z1e1_Over_TwoZb + z2e2_Over_TwoZb } else if dampingRatio < 1.0-epsilon { // Under-damped. var ( omegaZeta = angularFrequency * dampingRatio alpha = angularFrequency * math.Sqrt(1.0-dampingRatio*dampingRatio) expTerm = math.Exp(-omegaZeta * deltaTime) cosTerm = math.Cos(alpha * deltaTime) sinTerm = math.Sin(alpha * deltaTime) invAlpha = 1.0 / alpha expSin = expTerm * sinTerm expCos = expTerm * cosTerm expOmegaZetaSin_Over_Alpha = expTerm * omegaZeta * sinTerm * invAlpha ) s.posPosCoef = expCos + expOmegaZetaSin_Over_Alpha s.posVelCoef = expSin * invAlpha s.velPosCoef = -expSin*alpha - omegaZeta*expOmegaZetaSin_Over_Alpha s.velVelCoef = expCos - expOmegaZetaSin_Over_Alpha } else { // Critically damped. var ( expTerm = math.Exp(-angularFrequency * deltaTime) timeExp = deltaTime * expTerm timeExpFreq = timeExp * angularFrequency ) s.posPosCoef = timeExpFreq + expTerm s.posVelCoef = timeExp s.velPosCoef = -angularFrequency * timeExpFreq s.velVelCoef = -timeExpFreq + expTerm } return s } // Update updates position and velocity values against a given target value. // Call this after calling NewSpring to update values. func (s Spring) Update(pos, vel float64, equilibriumPos float64) (newPos, newVel float64) { oldPos := pos - equilibriumPos // update in equilibrium relative space oldVel := vel newPos = oldPos*s.posPosCoef + oldVel*s.posVelCoef + equilibriumPos newVel = oldPos*s.velPosCoef + oldVel*s.velVelCoef return newPos, newVel }