From 76d7802a4df9078f84d7ff82eb781d9b09c44795 Mon Sep 17 00:00:00 2001 From: <> Date: Mon, 2 Dec 2024 02:41:41 +0000 Subject: [PATCH] Deployed a5c90f1 with MkDocs version: 1.6.1 --- .nojekyll | 0 404.html | 844 +++ animal_shogi/index.html | 1260 ++++ api/index.html | 3223 ++++++++ api_usage/index.html | 1054 +++ assets/2048_dark.gif | Bin 0 -> 235325 bytes assets/2048_light.gif | Bin 0 -> 242900 bytes assets/_mkdocstrings.css | 143 + assets/animal_shogi_dark.gif | Bin 0 -> 387554 bytes assets/animal_shogi_light.gif | Bin 0 -> 391067 bytes assets/backgammon_dark.gif | Bin 0 -> 1137523 bytes assets/backgammon_light.gif | Bin 0 -> 1124361 bytes assets/bridge_bidding_dark.gif | Bin 0 -> 953275 bytes assets/bridge_bidding_light.gif | Bin 0 -> 946320 bytes assets/chess_dark.gif | Bin 0 -> 1138646 bytes assets/chess_light.gif | Bin 0 -> 1132789 bytes assets/connect_four_dark.gif | Bin 0 -> 245317 bytes assets/connect_four_light.gif | Bin 0 -> 237193 bytes assets/favicon.svg | 113 + assets/gardner_chess_dark.gif | Bin 0 -> 444700 bytes assets/gardner_chess_light.gif | Bin 0 -> 407989 bytes assets/generate_gif.py | 25 + assets/generate_gif.sh | 22 + assets/go-19x19_dark.gif | Bin 0 -> 647620 bytes assets/go-19x19_light.gif | Bin 0 -> 631377 bytes assets/go_dark.gif | Bin 0 -> 879337 bytes assets/go_light.gif | Bin 0 -> 681098 bytes assets/hex_dark.gif | Bin 0 -> 1068244 bytes assets/hex_light.gif | Bin 0 -> 1084250 bytes assets/icon.svg | 113 + assets/images/favicon.png | Bin 0 -> 1870 bytes assets/javascripts/bundle.83f73b43.min.js | 16 + assets/javascripts/bundle.83f73b43.min.js.map | 7 + assets/javascripts/lunr/min/lunr.ar.min.js | 1 + assets/javascripts/lunr/min/lunr.da.min.js | 18 + assets/javascripts/lunr/min/lunr.de.min.js | 18 + assets/javascripts/lunr/min/lunr.du.min.js | 18 + assets/javascripts/lunr/min/lunr.el.min.js | 1 + assets/javascripts/lunr/min/lunr.es.min.js | 18 + assets/javascripts/lunr/min/lunr.fi.min.js | 18 + assets/javascripts/lunr/min/lunr.fr.min.js | 18 + assets/javascripts/lunr/min/lunr.he.min.js | 1 + assets/javascripts/lunr/min/lunr.hi.min.js | 1 + assets/javascripts/lunr/min/lunr.hu.min.js | 18 + assets/javascripts/lunr/min/lunr.hy.min.js | 1 + assets/javascripts/lunr/min/lunr.it.min.js | 18 + assets/javascripts/lunr/min/lunr.ja.min.js | 1 + assets/javascripts/lunr/min/lunr.jp.min.js | 1 + assets/javascripts/lunr/min/lunr.kn.min.js | 1 + assets/javascripts/lunr/min/lunr.ko.min.js | 1 + assets/javascripts/lunr/min/lunr.multi.min.js | 1 + assets/javascripts/lunr/min/lunr.nl.min.js | 18 + assets/javascripts/lunr/min/lunr.no.min.js | 18 + assets/javascripts/lunr/min/lunr.pt.min.js | 18 + assets/javascripts/lunr/min/lunr.ro.min.js | 18 + assets/javascripts/lunr/min/lunr.ru.min.js | 18 + assets/javascripts/lunr/min/lunr.sa.min.js | 1 + .../lunr/min/lunr.stemmer.support.min.js | 1 + assets/javascripts/lunr/min/lunr.sv.min.js | 18 + assets/javascripts/lunr/min/lunr.ta.min.js | 1 + assets/javascripts/lunr/min/lunr.te.min.js | 1 + assets/javascripts/lunr/min/lunr.th.min.js | 1 + assets/javascripts/lunr/min/lunr.tr.min.js | 18 + assets/javascripts/lunr/min/lunr.vi.min.js | 1 + assets/javascripts/lunr/min/lunr.zh.min.js | 1 + assets/javascripts/lunr/tinyseg.js | 206 + assets/javascripts/lunr/wordcut.js | 6708 +++++++++++++++++ .../workers/search.6ce7567c.min.js | 42 + .../workers/search.6ce7567c.min.js.map | 7 + assets/kuhn_poker_dark.gif | Bin 0 -> 190846 bytes assets/kuhn_poker_light.gif | Bin 0 -> 191414 bytes assets/leduc_holdem_dark.gif | Bin 0 -> 200265 bytes assets/leduc_holdem_light.gif | Bin 0 -> 203373 bytes assets/leduc_holdem_tree.png | Bin 0 -> 95861 bytes assets/logo.svg | 65 + assets/minatar-asterix.gif | Bin 0 -> 90988 bytes assets/minatar-breakout.gif | Bin 0 -> 112302 bytes assets/minatar-freeway.gif | Bin 0 -> 150017 bytes assets/minatar-seaquest.gif | Bin 0 -> 112621 bytes assets/minatar-space_invaders.gif | Bin 0 -> 118495 bytes assets/othello_dark.gif | Bin 0 -> 412847 bytes assets/othello_light.gif | Bin 0 -> 384063 bytes assets/shogi_dark.gif | Bin 0 -> 1521319 bytes assets/shogi_light.gif | Bin 0 -> 1639674 bytes assets/sparrow_mahjong_dark.svg | 2 + assets/sparrow_mahjong_light.svg | 2 + assets/stylesheets/main.6f8fc17f.min.css | 1 + assets/stylesheets/main.6f8fc17f.min.css.map | 1 + assets/stylesheets/palette.06af60db.min.css | 1 + .../stylesheets/palette.06af60db.min.css.map | 1 + assets/tic_tac_toe_dark.gif | Bin 0 -> 80083 bytes assets/tic_tac_toe_light.gif | Bin 0 -> 91001 bytes backgammon/index.html | 1208 +++ bridge_bidding/index.html | 1256 +++ chess/index.html | 1259 ++++ connect_four/index.html | 1189 +++ gardner_chess/index.html | 1280 ++++ go/index.html | 1339 ++++ hex/index.html | 1251 +++ index.html | 1248 +++ kuhn_poker/index.html | 1199 +++ leduc_holdem/index.html | 1235 +++ minatar_asterix/index.html | 1213 +++ minatar_breakout/index.html | 1214 +++ minatar_freeway/index.html | 1225 +++ minatar_seaquest/index.html | 1246 +++ minatar_space_invaders/index.html | 1225 +++ objects.inv | Bin 0 -> 538 bytes othello/index.html | 1220 +++ play2048/index.html | 1191 +++ requirements.in | 3 + requirements.txt | 71 + search/search_index.json | 1 + shogi/index.html | 1470 ++++ sitemap.xml | 95 + sitemap.xml.gz | Bin 0 -> 368 bytes sparrow_mahjong/index.html | 1251 +++ tic_tac_toe/index.html | 1187 +++ 118 files changed, 39219 insertions(+) create mode 100644 .nojekyll create mode 100644 404.html create mode 100644 animal_shogi/index.html create mode 100644 api/index.html create mode 100644 api_usage/index.html create mode 100644 assets/2048_dark.gif create mode 100644 assets/2048_light.gif create mode 100644 assets/_mkdocstrings.css create mode 100644 assets/animal_shogi_dark.gif create mode 100644 assets/animal_shogi_light.gif create mode 100644 assets/backgammon_dark.gif create mode 100644 assets/backgammon_light.gif create mode 100644 assets/bridge_bidding_dark.gif create mode 100644 assets/bridge_bidding_light.gif create mode 100644 assets/chess_dark.gif create mode 100644 assets/chess_light.gif create mode 100644 assets/connect_four_dark.gif create mode 100644 assets/connect_four_light.gif create mode 100644 assets/favicon.svg create mode 100644 assets/gardner_chess_dark.gif create mode 100644 assets/gardner_chess_light.gif create mode 100644 assets/generate_gif.py create mode 100644 assets/generate_gif.sh create mode 100644 assets/go-19x19_dark.gif create mode 100644 assets/go-19x19_light.gif create mode 100644 assets/go_dark.gif create mode 100644 assets/go_light.gif create mode 100644 assets/hex_dark.gif create mode 100644 assets/hex_light.gif create mode 100644 assets/icon.svg create mode 100644 assets/images/favicon.png create mode 100644 assets/javascripts/bundle.83f73b43.min.js create mode 100644 assets/javascripts/bundle.83f73b43.min.js.map create mode 100644 assets/javascripts/lunr/min/lunr.ar.min.js create mode 100644 assets/javascripts/lunr/min/lunr.da.min.js create mode 100644 assets/javascripts/lunr/min/lunr.de.min.js create mode 100644 assets/javascripts/lunr/min/lunr.du.min.js create mode 100644 assets/javascripts/lunr/min/lunr.el.min.js create mode 100644 assets/javascripts/lunr/min/lunr.es.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.he.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hu.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hy.min.js create mode 100644 assets/javascripts/lunr/min/lunr.it.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ja.min.js create mode 100644 assets/javascripts/lunr/min/lunr.jp.min.js create mode 100644 assets/javascripts/lunr/min/lunr.kn.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 assets/javascripts/lunr/min/lunr.multi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.nl.min.js create mode 100644 assets/javascripts/lunr/min/lunr.no.min.js create mode 100644 assets/javascripts/lunr/min/lunr.pt.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ro.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ru.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sa.min.js create mode 100644 assets/javascripts/lunr/min/lunr.stemmer.support.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sv.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 assets/javascripts/lunr/min/lunr.te.min.js create mode 100644 assets/javascripts/lunr/min/lunr.th.min.js create mode 100644 assets/javascripts/lunr/min/lunr.tr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.vi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.zh.min.js create mode 100644 assets/javascripts/lunr/tinyseg.js create mode 100644 assets/javascripts/lunr/wordcut.js create mode 100644 assets/javascripts/workers/search.6ce7567c.min.js create mode 100644 assets/javascripts/workers/search.6ce7567c.min.js.map create mode 100644 assets/kuhn_poker_dark.gif create mode 100644 assets/kuhn_poker_light.gif create mode 100644 assets/leduc_holdem_dark.gif create mode 100644 assets/leduc_holdem_light.gif create mode 100644 assets/leduc_holdem_tree.png create mode 100644 assets/logo.svg create mode 100644 assets/minatar-asterix.gif create mode 100644 assets/minatar-breakout.gif create mode 100644 assets/minatar-freeway.gif create mode 100644 assets/minatar-seaquest.gif create mode 100644 assets/minatar-space_invaders.gif create mode 100644 assets/othello_dark.gif create mode 100644 assets/othello_light.gif create mode 100644 assets/shogi_dark.gif create mode 100644 assets/shogi_light.gif create mode 100644 assets/sparrow_mahjong_dark.svg create mode 100644 assets/sparrow_mahjong_light.svg create mode 100644 assets/stylesheets/main.6f8fc17f.min.css create mode 100644 assets/stylesheets/main.6f8fc17f.min.css.map create mode 100644 assets/stylesheets/palette.06af60db.min.css create mode 100644 assets/stylesheets/palette.06af60db.min.css.map create mode 100644 assets/tic_tac_toe_dark.gif create mode 100644 assets/tic_tac_toe_light.gif create mode 100644 backgammon/index.html create mode 100644 bridge_bidding/index.html create mode 100644 chess/index.html create mode 100644 connect_four/index.html create mode 100644 gardner_chess/index.html create mode 100644 go/index.html create mode 100644 hex/index.html create mode 100644 index.html create mode 100644 kuhn_poker/index.html create mode 100644 leduc_holdem/index.html create mode 100644 minatar_asterix/index.html create mode 100644 minatar_breakout/index.html create mode 100644 minatar_freeway/index.html create mode 100644 minatar_seaquest/index.html create mode 100644 minatar_space_invaders/index.html create mode 100644 objects.inv create mode 100644 othello/index.html create mode 100644 play2048/index.html create mode 100644 requirements.in create mode 100644 requirements.txt create mode 100644 search/search_index.json create mode 100644 shogi/index.html create mode 100644 sitemap.xml create mode 100644 sitemap.xml.gz create mode 100644 sparrow_mahjong/index.html create mode 100644 tic_tac_toe/index.html diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/404.html b/404.html new file mode 100644 index 000000000..b32cf0ad8 --- /dev/null +++ b/404.html @@ -0,0 +1,844 @@ + + + +
+ + + + + + + + + + + + + + + + + + ++ +
++ +
+or you can directly load AnimalShogi
class
Animal Shogi (Dōbutsu shōgi) is a variant of shogi primarily developed for children. It consists of a 3x4 board and four types of pieces (five including promoted pieces). One of the rule differences from regular shogi is the Try Rule, where entering the opponent's territory with the king leads to victory.
+See also Wikipedia
+Name | +Value | +
---|---|
Version | +v2 |
+
Number of players | +2 |
+
Number of actions | +132 |
+
Observation shape | +(4, 3, 194) |
+
Observation type | +float |
+
Rewards | +{-1, 0, 1} |
+
Index | +Description | +
---|---|
[:, :, 0:5] |
+my pieces on board | +
[:, :, 5:10] |
+opponent's pieces on board | +
[:, :, 10:16] |
+my hands | +
[:, :, 16:22] |
+opponent's hands | +
[:, :, 22:24] |
+repetitions | +
... | +... | +
[:, :, 193] |
+player_id 's turn' |
+
[:, :, 194] |
+Elapsed timesteps (normalized to 1 ) |
+
Uses AlphaZero like action label:
+132
labels8 x 12
(direction) x (source square)3 x 12
(drop piece type) x (destination square)Non-zero rewards are given only at the terminal states. +The reward at terminal state is described in this table:
++ | Reward | +
---|---|
Win | ++1 |
+
Lose | +-1 |
+
Draw | +0 |
+
Termination happens when
+In cases 3 and 4, the game is declared a draw.
+v2
: Fixed a bug in Pawn drop #1218 by @KazukiOhta (v2.3.0)v1
: Fixed visualization #1208 and bug in Gold's move #1209 by @KazukiOhta (v2.2.0)v0
: Initial release (v1.0.0)Pgx offers a baseline model for Animal Shogi. Users can use it for an anchor opponent in evaluation. +See our paper for more details. See this colab for how to use it.
+++[!WARNING] +Curren latest model (
+animal_shogi_v0
) is trained withv0
environment. It may perform significantly worse inv1
environment.
Model ID | +Description | +
---|---|
animal_shogi_v0 |
+See our paper for the training details. | +
This is the list of all public APIs of Pgx.
+Two important components in Pgx are State
and Env
.
pgx.State
+
+
+
+ Bases: ABC
Base state class of all Pgx game environments. Basically an immutable (frozen) dataclass.
+A basic usage is generating via Env.init
:
state = env.init(jax.random.PRNGKey(0))
+
and Env.step
receives and returns this state class:
state = env.step(state, action)
+
Serialization via flax.struct.serialization
is supported.
+There are 6 common attributes over all games:
Attributes:
+Name | +Type | +Description | +
---|---|---|
current_player |
+
+ Array
+ |
+
+
+
+ id of agent to play. +Note that this does NOT represent the turn (e.g., black/white in Go). +This ID is consistent over the parallel vmapped states. + |
+
observation |
+
+ Array
+ |
+
+
+
+ observation for the current state.
+ |
+
rewards |
+
+ Array
+ |
+
+
+
+ the |
+
terminated |
+
+ Array
+ |
+
+
+
+ denotes that the state is terminal state. Note that
+some environments (e.g., Go) have an |
+
truncated |
+
+ Array
+ |
+
+
+
+ indicates that the episode ends with the reason other than termination.
+Note that current Pgx environments do not invoke truncation but users can use |
+
legal_action_mask |
+
+ Array
+ |
+
+
+
+ Boolean array of legal actions. If illegal action is taken, +the game will terminate immediately with the penalty to the palyer. + |
+
pgx/core.py
66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 |
|
env_id: EnvId
+
+
+ abstractmethod
+ property
+
+
+Environment id (e.g. "go_19x19")
+save_svg(filename, *, color_theme=None, scale=None)
+
+Save the entire state (not observation) to a file.
+The filename must end with .svg
Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
+ color_theme
+ |
+
+ Optional[Literal['light', 'dark']]
+ |
+
+
+
+ xxx see also global config. + |
+
+ None
+ |
+
+ scale
+ |
+
+ Optional[float]
+ |
+
+
+
+ change image size. Default(None) is 1.0 + |
+
+ None
+ |
+
Returns:
+Type | +Description | +
---|---|
+ None
+ |
+
+
+
+ None + |
+
pgx/core.py
to_svg(*, color_theme=None, scale=None)
+
+Return SVG string. Useful for visualization in notebook.
+ + +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
+ color_theme
+ |
+
+ Optional[Literal['light', 'dark']]
+ |
+
+
+
+ xxx see also global config. + |
+
+ None
+ |
+
+ scale
+ |
+
+ Optional[float]
+ |
+
+
+
+ change image size. Default(None) is 1.0 + |
+
+ None
+ |
+
Returns:
+Name | Type | +Description | +
---|---|---|
str |
+ str
+ |
+
+
+
+ SVG string + |
+
pgx/core.py
pgx.Env
+
+
+
+ Bases: ABC
Environment class API.
+Example usage
+ +pgx/core.py
159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 |
|
id: EnvId
+
+
+ abstractmethod
+ property
+
+
+Environment id.
+num_actions: int
+
+
+ property
+
+
+Return the size of action space (e.g., 9 in Tic-tac-toe)
+num_players: int
+
+
+ abstractmethod
+ property
+
+
+Number of players (e.g., 2 in Tic-tac-toe)
+observation_shape: Tuple[int, ...]
+
+
+ property
+
+
+Return the matrix shape of observation
+version: str
+
+
+ abstractmethod
+ property
+
+
+Environment version. Updated when behavior, parameter, or API is changed. +Refactoring or speeding up without any expected behavior changes will NOT update the version number.
+init(key)
+
+Return the initial state. Note that no internal state of +environment changes.
+ + +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
+ key
+ |
+
+ PRNGKey
+ |
+
+
+
+ pseudo-random generator key in JAX. Consumed in this function. + |
+ + required + | +
Returns:
+Name | Type | +Description | +
---|---|---|
State |
+ State
+ |
+
+
+
+ initial state of environment + |
+
pgx/core.py
observe(state, player_id)
+
+step(state, action, key=None)
+
+Step function.
+ +pgx/core.py
pgx.EnvId = Literal['2048', 'animal_shogi', 'backgammon', 'bridge_bidding', 'chess', 'connect_four', 'gardner_chess', 'go_9x9', 'go_19x19', 'hex', 'kuhn_poker', 'leduc_holdem', 'minatar-asterix', 'minatar-breakout', 'minatar-freeway', 'minatar-seaquest', 'minatar-space_invaders', 'othello', 'shogi', 'sparrow_mahjong', 'tic_tac_toe']
+
+
+ module-attribute
+
+
+Naming convention of EnvId
Hyphen -
is used to represent that there is a different original game source (e.g., MinAtar
), and underscore -
is used for the other cases.
pgx.make(env_id)
+
+Load the specified environment.
+ +BridgeBidding
environment
BridgeBidding
environment requires the domain knowledge of bridge game.
+So we forbid users to load the bridge environment by make("bridge_bidding")
.
+Use BridgeBidding
class directly by from pgx.bridge_bidding import BridgeBidding
.
pgx/core.py
317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 |
|
pgx.available_envs()
+
+List up all environment id available in pgx.make
function.
Example usage
+pgx.available_envs()
+('2048', 'animal_shogi', 'backgammon', 'chess', 'connect_four', 'go_9x9', 'go_19x19', 'hex', 'kuhn_poker', 'leduc_holdem', 'minatar-asterix', 'minatar-breakout', 'minatar-freeway', 'minatar-seaquest', 'minatar-space_invaders', 'othello', 'shogi', 'sparrow_mahjong', 'tic_tac_toe')
+
BridgeBidding
environment
BridgeBidding
environment requires the domain knowledge of bridge game.
+So we forbid users to load the bridge environment by make("bridge_bidding")
.
+Use BridgeBidding
class directly by from pgx.bridge_bidding import BridgeBidding
.
pgx/core.py
pgx.set_visualization_config(*, color_theme='light', scale=1.0, frame_duration_seconds=0.2)
+
+pgx/_src/visualizer.py
pgx.save_svg(state, filename, *, color_theme=None, scale=None)
+
+pgx/_src/visualizer.py
pgx.save_svg_animation(states, filename, *, color_theme=None, scale=None, frame_duration_seconds=None)
+
+pgx/_src/visualizer.py
pgx.BaselineModelId = Literal['animal_shogi_v0', 'gardner_chess_v0', 'go_9x9_v0', 'hex_v0', 'othello_v0', 'minatar-asterix_v0', 'minatar-breakout_v0', 'minatar-freeway_v0', 'minatar-seaquest_v0', 'minatar-space_invaders_v0']
+
+
+ module-attribute
+
+
+pgx.make_baseline_model(model_id, download_dir='baselines')
+
+pgx/_src/baseline.py
import jax
+import jax.numpy as jnp
+import pgx
+
+seed = 42
+batch_size = 10
+key = jax.random.PRNGKey(seed)
+
+
+def act_randomly(rng_key, obs, mask):
+ """Ignore observation and choose randomly from legal actions"""
+ del obs
+ probs = mask / mask.sum()
+ logits = jnp.maximum(jnp.log(probs), jnp.finfo(probs.dtype).min)
+ return jax.random.categorical(rng_key, logits=logits, axis=-1)
+
+
+# Load the environment
+env = pgx.make("go_9x9")
+init_fn = jax.jit(jax.vmap(env.init))
+step_fn = jax.jit(jax.vmap(env.step))
+
+# Initialize the states
+key, subkey = jax.random.split(key)
+keys = jax.random.split(subkey, batch_size)
+state = init_fn(keys)
+
+# Run random simulation
+while not (state.terminated | state.truncated).all():
+ key, subkey = jax.random.split(key)
+ action = act_randomly(subkey, state.observation, state.legal_action_mask)
+ state = step_fn(state, action) # state.reward (2,)
+
This illustrative example helps to understand
+state.current_player
is definedEnv.step
behaves against already terminated statesimport jax
+import jax.numpy as jnp
+import pgx
+from pgx.experimental.utils import act_randomly
+
+seed = 42
+batch_size = 10
+key = jax.random.PRNGKey(seed)
+
+# Prepare agent A and B
+# Agent A: random player
+# Agent B: baseline player provided by Pgx
+A = 0
+B = 1
+
+# Load the environment
+env = pgx.make("go_9x9")
+init_fn = jax.jit(jax.vmap(env.init))
+step_fn = jax.jit(jax.vmap(env.step))
+
+# Prepare baseline model
+# Note that it additionaly requires Haiku library ($ pip install dm-haiku)
+model_id = "go_9x9_v0"
+model = pgx.make_baseline_model(model_id)
+
+# Initialize the states
+key, subkey = jax.random.split(key)
+keys = jax.random.split(subkey, batch_size)
+state = init_fn(keys)
+print(f"Game index: {jnp.arange(batch_size)}") # [0 1 2 3 4 5 6 7 8 9]
+print(f"Black player: {state.current_player}") # [1 1 0 1 0 0 1 1 1 1]
+# In other words
+print(f"A is black: {state.current_player == A}") # [False False True False True True False False False False]
+print(f"B is black: {state.current_player == B}") # [ True True False True False False True True True True]
+
+# Run simulation
+R = state.rewards
+while not (state.terminated | state.truncated).all():
+ # Action of random player A
+ key, subkey = jax.random.split(key)
+ action_A = jax.jit(act_randomly)(subkey, state)
+ # Greedy action of baseline model B
+ logits, value = model(state.observation)
+ action_B = logits.argmax(axis=-1)
+
+ action = jnp.where(state.current_player == A, action_A, action_B)
+ state = step_fn(state, action)
+ R += state.rewards
+
+print(f"Return of agent A = {R[:, A]}") # [-1. -1. -1. -1. -1. -1. -1. -1. -1. -1.]
+print(f"Return of agent B = {R[:, B]}") # [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
+
Note that we can avoid to explicitly deal with the first batch dimension like [:, A]
by using vmap
later.
vFS> zdaQrnX5=-SPmD*w7!;=k3t$D*et0J?QppkX zZ~%258Y|&?m+HMglFtP*TmtVN {l-?JO_K$d;=fqgC&Y{%FM)LotXhlM?;K%9cj6LYz?<%RLP z#^P64ft(gv7(a&*%~iwGK*0JV91H^Q=DFYd_Dy)X2XOa$A}9e|4_f@33t1&)`j~I4 zJ7~+;IJj?DDHAUn1|)8e&d+^)q7@xZoRFC2Z#N}i9;7qWFuR`TMQ!@zBPF@#kt)7# z*#~xqxnDg}lREA?DPK-`;yu|9KHepzdtW4j{kAp=A3neypEZ1a9i+;B>~wpx%!!^` zm&1DOYva4KsPbO5&(57bcTwr%_nA%h vC7P2~lBhzM(L zL(pt-3lIE61;8C72F+`h!g?Iv`;SmUe(8ktp#=LiCo6OWX|)!5vfx_KfZV^@YthAc zlPw~WgXCr!w8w6>`$POFsci1lJaHyr^?$!1{Q`MPbhp@a_gr)pa0A;|0)vxbG~{74 z2ZMT(6~HPG4~2RHoFd7F!GUH_hJMgO)xq40!6di(AF#bYJeU(v1vcP7D$2v6SBGdV zhD^XKlI|NgrHHzyd$KXYeYt>$7z~asQD7D|iXT) gOW|@RB%7KwWgWOFH z%%~20z%>3w5#YQ??TQP)WHd9fhvho-scuHBHJ4M}H ?1fMjS%0Who)1T2qy U(<6z6UdSFs=4 z0U!7KEb!AP{`Mx$k}Zsx3&5AkD Kx^FrJhUUKqczkRV&?fg6g5@2(=W zBx=zee-EFyNRc?)n2;xycmtnwN||&dnzR=jM;V%g2}t~sl9*hbC_9&Eh8gc1n)ose zNb0kP!>|vp6Z17@WSC6$gNH`Nh(UH1b8szo0EjUKV>*QQy8Q$sf{Fp(HytUGU2?db zv~gUCk|h|GICMB1QRH217t$)1((D)9D>t2*VVvcQS$M_LtBli|@K`h4ojdU|y16oX zH8T3$GX_&LhFda5momm5GbZser@1m`H8SVjGZ#}cms>JdmonEMGdJ F2fBdhI(xgFWUYwG>wo~-}-?5qZW-Jw~c(Zo9M{Ozes zp;ET(E7wE8@&wD;=~}zT kJsY$R qhmgh>#Rg0nsl7X031_+GGq|jtza*N_#P$Xa} ^OnEQgS-kMg(#*=?EqfG`WaR{ctrp62?i)wM*pAdUrv+nC~!i{IHD{ zV~W$f@x^wMgx*@TbM(k#AXMRunfg(~ua5HbrG%CX3I-LP7Lbe#C#g#;JkkoXqjign ztnsXw`q9iX9Ft_sKWWv<`WRr_jSu$%Tu^)szi z?Ff}#`PJ~8U`1tbgF^fFJ}x6^Co^`>2o@{uV&)r*BGc8{ItCU(mY<)%6?4-|>^iqI zA0}Q{=GHXV*ycH`WLOpuJayO?g~ER@FX5!Gu`g4K(Xmb1-fMGAE#r@|tapxob(wTH zk91xyA)wQoephF6--^_9P`T `QM$_l+*Vn7$ zXd7$nxkDP%n9K%Ll+%;^s(ZkkJtK;&hL+2F&gquw#gS`A;)kf>IUhCKZM(u|WB4Ke zbK?(=Gx-~ibNq3)xzY0j{AnZP{o6xOf}PLZ;mFS0^TqG0+|wT%_j2go zbY_DQpgLDY>^w$4BFVf1b*@oYQ=(Xt$P-buB1ke)Vnzg=UMRIKeV3(CzT7+&5Xb)D z7!z14KY9cg&xKvd$n=NEVed2a$e8MVz*yZva6|ei2^YdKvxN!?&w>w>2JwH+oAKhr zCrSf`hC}8}#w_->p}tc^2_Ush0I<<5_lFi<7+N(yurV!*gi*4P)|TLkFlUWL{DdT< z-W(*LJ)4aB)@y`bqyCNERv}uYAft5_K*#U%A;v~{mv{?~g}W6tGLm%{_Yu%LAaNC8 z>-F(duImsd%@sHXc(X|1WIm+GY@Hy;YC^mgG)!Gq8&~YCjm@JmAP*OnSgXDFMQ^D@ zb=@(!^Cp>rY-mJi8(pw(*O-|$SxWu*D)k5cKDx!@pfvq>tOd2^R!ORimF&Cpq04 aer4iH0sf ~4{ zz7W^MLejv18!zddQ*j&hkq1yIy=Xk}<|s!)l&UQ^tGcBATkhT$Kvz0%G}?$2jcit{ zK)Sd~*&Mk1ScNHNPP4?$59VZ@qyuT*r{1pOm6n!&oCcw`OoiAwGF$sVa={qk;`_>q z9>h$Tn(tvEjn`@US0wSIPNbyj8gmFV-56j$_gzg)WQ8&1^CAueq=)L7<+(7FN|7b@ z=Zv{yGY({4R47QO_u}6z)kc=*Tkjga2SK34JP9tNvjvKxmMI!cLEv=WHFcueS{iH$ z;bAukL@DGtECoVsao@L;iuiM$n@fen&5Di%Rl54puF1*Pw(ccRx;9DaF8uC1baqWS ze}qfyC*A)j`^v!C(xWSvcW>1`MDI01t9Ltn-(h!iu2jGD?e)y9?bXH{P(}M0ni#hg z@ys0jRi~90o`13BgXmG XtoL(lGOAxKKA%Yx7G=$HJ7yOq2 z1?ik#Iv=_)kygcb9GnBVK9@vBUNVqk#r=8Bm!9OEQ15cEyM*5DMnr3GXzt(t_=>B9 zJlM7q8{7=~On(mB3K7iI>o=kx`#JWf#qLvca=XN!(1+28eHyiy@wMJ-58?o$%`^cN zPBf^@+=>IR?9!MO(LrLvM@VXAK`0;}OD=}Y+P5mov2blxXDdcHY+jOSmm<~(x*wS0 z+%hxci4fQoi~)G81}Kv1LNI(07V>c(0u68UWkFK@{*gyWaz3`no})&Qwd!poX#Ta) zU`9A1bN%TiQMt+$+T%~>Pc2;XP+0vCL4*QrW6AWak$o~Ie929+H(}jPSQ+a^z>*08 z-P39V&6Cs)p7pNGCb6Gh$BaAaZ8ME__175ow9n5Q-1HBb<#Z woD=fnUe^Lehn5_=!M-*}jI*X@sx`gn}baX+0Jbz6?JHm^$A zJR2Z;3sLvH$LifRA5uP(aphc`_lw%`8znMihU>4|hEoNHbmbqvR4Z!qI}NF&ey@-i z>$NF_Hs`IHU86MX?h(<)J4`| Tv@wq(I}O+AA+(#nB%h|!`EcCUcny?% z7k^^2-?)n)oV ankT%a{fgE5@!#${#k|Z2`Q4EuJ05Z~MN}%cTNV}e&ZH)I zHmrDFSH=w)s*odez1m#2yQ_mXe7B5dDVTp9@~)dCJ1kQ6e!QX`<2!(Nd pmgk11W*HE0MbG`$eA*>Odwn|9n?}Yi8i*ZXnG8@LLj)v>6P19Ppzw zcVI;DUlI!-FbhC+^OGSBz$FdD5DR3#51_#%S5hSJ&vRbsGnU1+d=CnE_75}=VlZJ2 zx;)U-V29IcwB=i{)587ez)b1lNcn&sT)}2)LSa!q?_vlKoV^RoV4@0gqzb(X-or9; z5)Gj@4Z;15?tp O&}e`w~rGZ1Vus5CE0EY)Zh4KaEiiO|*E>_?&q(oTX`r z0Y5yccnVg7Bdvb3PR71PfqAG#N~i@DK{qp8?{wH?p=HIsWi^FW?L&YjD6IPfoe?A5 zoFiWBqE!c+br- ;d#@d&}@0L;YzVUCEq;(%dsKR7&> zWOMt52kuvKN7PgogvTi8mKa`hP*G9zhoNYgC4T~qSY66UAC_1iu{bwCtXN4*%wP-| zUc3NR>?aE#^H5yqVO-84kj5Rf9Tdx28Vl >qcy5KkED z3Wb*-&Xpi3;UsOrDvL)fPwlISm-PFRn0d{eGlOBd;B9lD y f1MQnYu*2UdQzPGv;F;bQl$3!-AVn~5dYc-$(;XPC-r9^ z{ImW2g*M^5e(!^SHpIX7K^W)%u#<}UdnZ+vvLpcWyOWamH=PtB@t;oWrUyn4gXVW9 zmGj@OlM?AdB>y*^l*(o=uD*}pw}0xS`g(DdU@m)c4XyvFlM D6j;ZF#oob()Oc1 z#})pEPD<4u>l(Ne@PBA0Rr-4sB=eH&{!crp%>bmoby74h|92 3&Q^=ofJwQ zDb7+R6b>%>4qLQe4~xDW5kgmvc(rpCwEW56;;1MZyn4A4A gs3tq4s$1B=x*oG&Tw$ojvLK3ym^A(Hk4o7a)DUxLcIBhVT4 zn}0Ie8paq+zyHN9LckPjEek`284a68-*^}viEM;FP{I)IUK7^pPv-Pe-`A0 eX@?;pjYqWsxMJKIdTP+iOG;UpIJysi+n5MVpi%K}_guD$ZMYk&t>x{Fiea zm?zp=?XxH65R3}CS+cMR1!|*20WY=Wv}EBT-w{?=Vz(V=wIF$yyvT4%F)p8#)DHOA zE73tM>r{r(6(cV76j*E6i@EdpZ$*@4ssgL_R`8HCbz`t%Qg=epFu7EnMP111s3~>4 zVi{9LSjGYCHpA3Wrg^19CTxnzcP|S$zHz0L+Y?hfUyKSSl<;h**8_|hiGD?HE0oDF z6W;J8Icetl$n?J#QP%ABd1dV-#ODZAep4g)HZVtDj#4Ih-bM llMuVFAcw8&SfZp_ly*^R8=0d zRZ7Hkc2w2oRW7{dN)6^L1?Dv74>PdJ sWnT!OzOHHHrB&M=Sd4 zcmV 5%JswDPWiuvkf_bLru?Ivs(;YY85avK#|8zI#3Lb$O>514Pz&t9B7voSz&OM^ zcSVk M8aK&usY;JOk!0`%vxwip8FXBP;dpJbo%2nLt>2X0d+gX`dmTvW znLM2TSZLD&uZHV+!o+-eIX(A1U(o{}yJ4e3bR#QvZvH`=Xi?SRK*AR&66NH!#l%oo zrd4g!8RHfL+aXw^PY@&mn~+qpHDPL_+t_U>eP|Fs2aN-*byBzfy6|&a{7oRv^TU9E zC=&`?J{M{6WRS=m1`=>|mm(h*wgC2v73^?2InU!TUof*7UW r%XAe{G6Zg~<%i zr9s_>PMg?hkE!hu(nRz+b J(pHQs9;4{`knpnL2osg(n#J%l7b6|IeImb7 z*r@eey&zN@2^RbjoI@zwezX8 bgrhnkIg+(&ogf}}*8N5}=oF`hS>169GW)S(vT;)5|7v7r zXTACK#J!?);u_nPsYjaK7XE9!wm$jpgkP_1edxsztk}eT9-zmx;qQ7cJEU_SE|<1Z z=%txTnRS7t# }mESh K$fE#e-JHOP~`}UV#dhV>Bk@r;e z*Yk~_#r?24b%FMNFeQEvoqn+Uez$D?nCkw`0{R~S`Vhf>k3nbzhwt%0{!m5!HGTrq zE T{HA^bO>Lz^-LJ zBLvZDB#>hGE!bGBF^~bqhYOdw4Ayes-s|edQ+h^l#y=>zI0%#6+uAWm2IN&H=B^*a z$;J9nKLubYu4HT;lp2I*#|dx%$Z6w#HU$K`AIf<)lY1`)`hp~yn>=*Hx%2?R_DNoV zfe;r2d^ZI5s6#*~h&}u;BvIWf<}k>15EO)~>8~Cft8S6g97-`08uk#HmJ(dx78-vk zskki_e`qw+X#G*ltCR}#c13Q$OmU|e&R}X| s?@z`xW#UZ za^P4Ah|KTCpZ!~1Hpyvvj%_!02sX~;G#MEPPk@vq`YhW;W%{yj2VoXjGvJ;t9`bWa z_FNb*_0SkT*&g35g3&Fi;PB& {dZ`GBp~PSjVubCg&+N*M7bB7y?*JVypdMwx9>UE6QX7ipM2t-_ zPn-`)bSg?@?^Z)M3H#0&ZK@Wnr4cqI?y0-PCW^;txa4IVs*1{GkxQa!>yoU&nQW(& z9NLp$)snn87%T*nVn8*Q;`S}Y#ylnPFvS--HJmzCCo~e28kq%3HIhgTF-n!{O|eHv zTlt)(yqgNJNV^eEbpMtH7)*nJMUJaeZkXema|>QH(^?rw-xTBi45w{A6R@)oD0Ij@ zpd!R3D)h@hs0vnx3O5s1Q0McO4+9|c%FKWn5CGAfxf+W8!hwuNr4NUz|FGw` PowIgo$U2W-RP42im;v2+%(Lw)K& za_J0#fbH2Kr6dSqI3%h+-`6oyET4&g@j+m6sz9O6a*n%!1_F{B0R>m8v0~|WJeWnE z(?hFXV+r0FP8^vpuYjX&JYHK-hLvjfg8p?&TjCFD0b!(*U*1=54>;k?q+JMB@0Ac! zAmn+qIL(Zv(+UuMZv>h`U dfEl4rdt!h@$ei9xRn={36=KZ#Z5n@EqB;e*Pcq zy#-es>YuHNdlG_MaCi3*EI|SUcY;gd?rudDP&iZ-UTER2!5xx7a0!GE+(ID11H(Bz z_w;{m- FFF^G9L&S+GGZ+v z9Z(m+;aGxt7SR~IqXkCCX65TnBv!trzRy%03S+Hpl{btYH=tPpiDTPH{Mf9-89^L1 z4U9279fl|g0;#rENi2DyG;xyKyNpS)chKVd (V|$@bHgG|F}uI9)Z(+9 z#(uMHmiaYSagxqke_Ku?8NCQ%>%l9`M_H7}xoi)JfPF4N(9kx)2{B!&^Y4b`xEzOJ zA&|Ahp{OvI(xxO6D{#C(ok1W59h1Fah(c6THQP2Xl9LlzD(| c$<@}2NDVg*(jL%N2@9&^)tcDW4N)kZ;Fj92 zMRL`^V8)&14aM9Oy4Xcj5xwolyqMo9PN#3)R_*tX9JBu-TkmU?r_r?QMNiT?>ASIu z->Y2yIKrd*7tP-PjkCjZ5H7MIXWG;iw^YcT^aYEy?!YdBMh{kt+Pya>ud#_pF25}!hy-G@taAInx z2*gBbp*i3D1;u%|wUQxsfvs4UCp#+JLd&8Dx}RtRpt4Og)UPr3!ZpZzr8O~Zfn0n& z>OlXp fPDMnb`B5CjMlD zS BE0v(3auuZh1(VcH{I9Hc&7&EiBah? zxjxOxA=nm30gPE>zISSDf(yWK-|K4&Wqi~%KYicw&X?y59;?eLE(ZJH{gN0yLu1b} zgw#;Y6tZvT-sV`@({P#=%2~>u5Z#(r4-YxZt8ZeH{e7uX@-!`IkH+38^VV<_(=x zT(P-BYQ~BR7wn`vNI#XFj6eQ_pbhC&h!4;-_7yJn$3QA6fu~Yc&x+ag_FfvPzRp4r zm*%9S;ETH}IpYauNNxc{gvP}XRIZ4+L%AGd{@J&zK1lUu
*i{@wX2;;odnOW=sJeW@;T4;>HemU!fI |LI5^=xVGa&h%rSy{+zZsse2yuDIJElB)| z_uR$K_Q{fIfn00ba??Sq%xe|Gxb;pY3iKz!7Ry_wpE}n``2y;lG&a|C+iTzd?}SqD z?nka$$oGl2{=VmJ_0=|rQxeSE3eR2-PWP}!j-MMn{YqzI>h7&F#4KF}MN6N$va6R| znPX!c4p7#V`_44H>H3=Cy6sY?CTD6H+OjxE{&)}k^46+9u}zK*E5=QWbDHpp_rUI< zyA|DgtG-i;Q5~0) )36p6-J-j15R zf)vFkvOG-mx3W9fy#*m@H9t!}8K|la@TDIK;W22zl`9h@i%agt8PRc6^w9ZVp`{Cx zeo#IzE<;Il&1tUo`|#4VH9FEmmkDPT=g`8>eX*tPD{ +>(KNg0v6A@q-~}1Nk$DJNrtUr*mwMn-!L;`<>~NfM`k<_6TNG?crL15`x0P zUN#Zl_>Ujo$z6T+{w%%nuDZltL%7&1cp`J+)t0!J#6g8Yan84;_e)z>Y2L>j`S%jr zDXvtPZ;zJ?sGs$!GfK=zBzVIoX@*6zIwosftr0UCyA1Ha (%Ssk+OI0UkYf$8psY_CEp1NU_mWC)mX2Iu_W}Vb<^kllYp6Y&<@i`{JQ2iW zL~pLnyL0)H< 2W$~4GQQ>=Q3?F@7jlz-t>OvG9R-)Idw6*?P7MejH`Wq5bt_3 zZxF^sKL8yT-wygb5qx7V7B-#TlL7nm-fru=%*Cf3-(NGgH%1&(A0T95*R3I!%&dVc z2p^O ^9pP`{({;AsWCifPI+lPMBv_xa+W=>rD8#eZZlZH<6*=X;vtMVHn|} zADy^A(`6W2n?K7#`5cZtmwyn4VFdo77oWeq(B-|K1Vtc4oR}EY^M#?6&qAaO#X|>F zRIh#XOQq;Y;%KVTV03>!4e=ONXsFt#xNcl@zd;Q1Vua;IG~uuCw-gb^ZDzI<;kxYj zYYLt_-(>QKJ@V!OIb<&i$?$(Rx?j(@C(JrRnt)Gs+?%IlF}>ZQ+2yY7+<%wKJ)DuD zmBrl;$0f3R)}J^Z***FE3Y6gw`XTBHHw3NBJFk<05#r!>dRJJv>&Z4~GnTMo_er?} z_(;^P?&MW64hg!LDw$kdG}JB0FkT_T9Ru6F8%o^kKtfFJ5nS%B)$blM>KL{QOlk6X zKJ7tH&O*84QHbG5Cq_w99woX%X_aMTrF>7jIvQ2R7-L! w~+4@X?<37W?JuUKUC@*?g0!LEJSQfCI^m<3|)&TYx0Ab$C zl9W(m$IW=ro)Np3N#FnrLNbP2(Uk1L3OS;q#Nf=N*+EYsvI}t0Q}__NR3bpz4i_du znbCg*Ev8KEhQ$uRa)tunvkN(`$edxA>8M2RBr@YuKrT;A_EjI;YbnzQH@T4`d_yH? zvppvt7TvOxJBynu7?Af7mN$3xw(&A{CJr!H&g60_ j03y;wYslakHobuV_F1d@~OdK$jBA#6mF*oc| ze2L(vDiV||5;iUp4HPR9hZjk96iF`^$y^u7QWeWf7AqPTzX~i?h8L@L6ss*4Yg`v= zQk7^+mgpLn=m(Y3_B+hwguknw-3Q3z8hoe)P!IUEQ=duV74uy7IWo5M|aS>SV*eY*(95xq-}= z%Pg!gYbdDH!QySR9n8LC*fz`ML%C|Ant;GCiJY`RECux<%+4?rjg!4Fwtvh35%Jh~ z*Gy@nJu?q^(oRC8^H+b4ae}2n5u9@fSylj6b W99pW&9XEl9{L*D3#@oB)1&Z>_ycmKdc^OuYBJy(O?Fe8{??`eA-V? zR9XwXWyM4#cWzKoY_WV~CJa;Rp%K VX4I=aKe{fe{K6z`V#%?W1VG_Q2j}eWVcUMr zNh7)9P4V&5ZFVVAu8lEzCLf-y3GY9;+GZrHvDnc!pdH^zw}nXT@gUY3_Y3M|U jNxQ_A{yJ5$ZUqd^8WHNpSozm!p@yGgd9S4>6I`IbY4IYdJ z-LHRmbbNdIWu&`hM+V=O`OIs;T KD*23-bKC tA8SeHIkDtUc6fmeepQh1X*8v{@+1l=Dc(meX+?53iE~b_uv*Zt2RbfTq{M|uz zGAppIG=g-iZ-_TAh5E^ul_HgV96vaPftaJ{>0~*f;N$)TXXZF+`%ftJ@8~iAAziH` zK9qjzegBac52PDLP>dgNIq*tSkUjn#h=~nXv2a!%MK-(_U36?rBk=S-t$<*QjR6It z#zH#{p;p4Fr=qHpIpoEJ!NC1ZJ|3&hBBSkn37cg>mdXBUR^=v(1>u0q2!T-Ku<0Yb z@G&(lM7a2bbE&Y@)%zcSNqG9oS~WuA13+I#`17HiP>%#0N3bmCZf1L+pF_hUH7)mO zmPKO8_rqPlaacAKMfw|P!tXQxF zQ$G63X^B19hc&gIh`c6tWu2v|AiH!W%nyTdN~+p14YM$|#80m<_djLzlL*m;0916y zb%;wyh`E~g*j{q#I-Ywg2>Fx?#!KpE31*~8<*sVc{hWD?@eBFno_=4aXt@*kiVtBl z!ST9zT(>6mNiJ(OQuyyMsbHaaF009^ 8LO4jalx$X{Cg|wE{Af(4cK%6~ z8*wE&-xMZ)0t41Vuz`>Az;G08w&t?W$@16uduE$LoTS7mD}_CyDPyvl=!^ =A1cOjABhp+^O>>0-p+ZkkjW?R=;Mdp{l?N zN8GWE1}tlfK6D6|v7MDc=jUb@$4<$&rvW?74{-ml!BhYEHT8 SogrI@ySt2W)oxz+$9lv|hsi?Gfg2yMI18q4vPd{eN>a{o8|@>3)iNejr2D?3dK6 z{ty3f^8osGG1%yE Iv!YEE4*GfOs$kYO}v&>l+PxRW)c&BuIiWC zX>?YCUOA^<<@74VE+T$|Q);PH^SC^E=(BBAs8N~G$2V}?rf xG93?8dd&ttH?eM9~2UGjUq}Rf;)zQHG;H?JQYsDm9bp%Jf1HV{DdC2gOe354k zN>7ZZvSpkhA%Q!4TkY9FSb)-(&m89~<|eZ2ewL?D?a_9@r}EFeD~qI@Dl)G_%g*hp zcvcTO=K}@O@)S!x-RC%|(U}OC$aru+7=oN`L|7!nEzNY{E)U0d(51VU9aiOd9sTwU z-LcK~*Bq~(PB(DXdS4J(_Mu2Io~~VLL@)xZz6al|B;C*|sxzyMMSf?FOA&7C_li6* zu@HcG=3ERgtR?Y0w%Q>10vv+14JSASubC6Hk19b3!~>;4fMDy9H^)ioI<{Nfts^v@ zXlKw#X)@kEO9K08qWIn59mXYwKJvHj%6PfEcw&L=B8GI21 FPpqo#$) zHSEK;8&8aUzWbg7zTnuj1}N#1U6!q9KgvuxA-`(2%)K^_9S3gR*=y}SHZGlPMBScH z)B>g(ua)eugKwqZ*w3#}{setrJ1})~SY}#2y-E)`)_w6}MPd0Ob+}8;=U#fP=-FjU zrZm!$F5p8HOHh2zkG*G;S=@THLGw?HqSe1YB==p^ygS|+ZqJrVcBx&j?#R@3xsfaL zIBLVlb8lFNgw`waj}D*2S89`1UY^C{jkp8`Mr!eG_>nV?MrdtEVB$mur|_dThFkPSE*n^}D@SlT zkkjc1FvZ;q5JyF^QiMF!kFtmm5^NOmw YaX$KOEyc7~q-R0GG z5PrUEPdpk;O2KLxCCbarW^O19(1{TmjWOAEdM_3@2$XsK(9Z7Q?1Urp5t}BOoJSqU z 1`9O#(^bi|G>Gyoc*h8RECt;%ur7eD|zFucvrt6U~Fjx^3N5R3y#SPTxK zh*Hi3MJ&eT?8X(agHj9w(neoo_&+OK45+>gK#ax~w}q6%f$NolxzHHsWz_72A3_P( zybDgE0B5tuCy6DL#wD~ECbWsi3y#LmY{a$uhc@9P*1F50r@I&%&^`JoJ4)jErOjLa z)4excy4*J$pDlJ2?Gb+6GKl^N#Lz%q^rsg`u>zV{(oY=Xa|hXkXz%n{ceI6veoAHe zO?QzIPikxw3UV*f 8POivanAh9ia6&+8{^ zGWwN*>PV78R;o->>f`8#vK(T533s6-WqwNhWAWEDKOvXXkb}##?=5Mk`mZhQMaH}- zto_u6n0?iksQYl@$JrCKmI7-XGS;**YW*@yBr>#-8O^O!76Cz#%6@)}{PqDNK@NJ> zS3#zfnQs9Z9_<-MMv0UDSpj-k{(B}al)<)3epZ02e0FGdNmf*Q*7-u#m_0OD<^Cbd zoJfR#YFuVTDZyecGHocKaT4LFNMI%i2oHcFmY}Lb(4= t1#!CA?SyUIxobF3ipV!FoVBS-3gz0XeM!k)KrTra jAi(pL^c+@fMU7eLL#4l zD*r~pmIhu(yIlB$3icEpN?MWGfJBg26f%$Jmb4cz?nfQAhaT@$A%yUXPH_uGz+uEx z*=W}}4B#R~NyPLkw~g5JbsX0J;L>*SSky>E(@nBkCZHr zHZG41ERTbigFDI-mdhd6<;hgYR7qsIF)}j{356r!9mt$zWZpHhfT{u^Sy60UQ5sm0 z|EDAAkCFWUf|2|Oum7KGq5Xr`fAIPbUjM=CKY0BIum9lnAH4p9*Z&oGU6<^2bx9=s zfY)NlFN(dn_fpd^(jGG>3mU1|T;M%Zg#0^RZ$la}JgcXCOxS#fiqkFq)Lz5D5o~eZ ze!xcx83v6&eUU^$!^FvQ-S^6%f5UFerNCC4Ow%jSd>h}#@=P fJ}3g26_11_QU+@;`6Yp%DF7%4 z34`rH13<7eSa7ZiEPD^ut#aCs*tBl~qS1?t%P*=w6y;gYO zB0R cEjIsM06v4o366^mq^I{b1z$S zmtna&S8z40$VpJn$e3*zB^f`?LnU6`79e{}ELX)NYEB_9lOz8InP0P%tLzaigq}|_ zntu-{=mX>%j0$6bWA7+)aKJ#6KvA2;0(Xi+J=`23$NZwALQ2*AW>BF4AkQ5e@tFg0 zWQ~Yg%mZB%5P=c--wK)V3Z7LU&T#LGK9$;h@=xHsE);jn;21CLvo88A0X=Lla%C&x zxGqwqDiW3~R#Pp;UM>>iEM8+OAyh4ST~VUpSkeeA;TtcJkhE3akJkz;wE}0%m1NjC z6r)2+nT?Aa_Ddy=eWg{)*q}K9GnxC8xk`bFE9`Wu?5_F>u8$SVpIeu&;ka)2%k5G8 z4epdk1zhBmyienaJO?s~$J<-%DixD5ndb`m95q=$r9zgZqWL5lhcbl$rdV@bp-EEN zu$=q~l+p&T?C7X`w_MqMUD-=j)h}5!Xk0ZMSTzc-8t WPczk@1o;2W1@iyICGsC%{J&y8<`2040rx-P{s-Lu zfcqbC|6d5)qi tI@^M;7l z7@Dp-cQz(C@n`t)Z8R+(N2zrYdVN+9)~qX0`FPw_vj_`m$%@2xyzM$1uF4dIA)Sv} zvfmuLf?8598qe=XJD&Tw=ku {pO}xdviTmrxd_%Kr1pf^S>t}hjOuA4GLkh;d_Wfp5dlA2V``suI}a?7n&)ppXi z?^q=N^2qzcS+>LG#lk9tO@~+_CPhLl>UmZpBa}-cP)8$>Kh0M3!YN|Hz9V?gPeUnp z!^^T>U(DUV{Z49rMjDxz#*aE6)GHGD@gf{CYw`NbLIy|r!8vD`30Jj^MqpSmCR OoeTR%iYoh03tRJ?TM_${Yv~B<2+=IC0kX+?(AZTKMX_GBMB5FBI50(TzKlL) zi-EF5t``CCvE!&mfx*7vMUAm7SmE90u@!c4eMND@v2mlm!B`o=wwE%gI4&-W{ORS| znaV&Y4#*=5 =RpniG90qYv1k@ zhes0Au@gvG5*8al1_O{IbjTh%#7zmZsFdWajK6I6&{!pF`QN;B)FtoFY`U5Yayl1s zhGMU4(tQZLd>S>~Vw$|97Q7zYD9Dz{OA33dlzAsHD=P1#U@o|~gnI}Wpg#EMtPc*l zffsjHD%Vviy^`nO^D+3WeyKuPX`(xx!hWgOb!of-o?=RFifpNggWg!)>B@Tws(Z2z zBQh_3r1Peva4>r-YWY05az!i1xb*Zf+e U abX)`IY9xi zIhNdjz1#-MY`A##IvW%bklO;wJrHB{w#usl<#i+T{0hTTBcVG+&_!Hma7uWcRsMHS z{vI;lPb*?*BOePb?;A&+7k2K @<)(WvxUO?)2U&K}+X73;@2xk-yEF`$jrK1w{ zeMoyK }X$`(=qPv*q+3@kzhB2qb% z;>c4r>_j%VW$TxP8u60XOJ#8s en&a!56RO%% z$=aXBwdaAgm+;!_j@sMh+Pmvo6zV!OsX7dkI;@~Noa{Qh&N_mXy2m$lgw*x_wcAGW z^74v`imzY4R#Q{^zn(X;wzmFf;mF?J-oe2E001~TI{wF I#wKn%f>cE3@ zv#Oupx$(#zim5FkBI!rdC=I$l_t))ATACPQg-dvS`H;kvy&d22)3LK!Dk|@};ZNJS z+OLSrEy>oE`G+q3MD@-#qm|+){GJXe{qI|EA{6Lk;E~SX78&TnWO4yshMzmRGI-ZG zejF~ga`EN=ys11n9BVWWqz&=-b=H-%-4)t>d#gNW|Hb(db#X29<1cdahdna3_3(UB z2YOqa$b|y`d(=z%=vWnpf}on-9r`F@EW=eFn!xSCSki7kOFzo(R!eYmiXmfMbzEFw zBJoG%Z$@0>i&k-b8stS`Y A&)Vtj7u5-)uq{53F{d`|;xMIgYXeM) z!fxdTLM-r>Skfm{BoNRh%kUA}u=Vh57Z&X{yFAxpoE>MADUX-Aeyk&9X;uCJ8@Op| z?1nwpB?AUYwBy)rI`SEKCsE}iYagYPnk+Im({-5%QOQoVRpKV8y7DA!5T&m?rec}3 zqGFNLG~fIVu!!L`_(|c3=r&>ytAuKwyLGB!g{Q6QX H61%+*g~K8 z#z&fi4<^1NoZ;h)Y45AXBu0XNycbT}I%|=Q;`Sa_B Et39`& zqgfZ^-Tzb?;Hq`l<|Z6;MDQ+p=6mmb4e|HZ9oO6AR*Ym##rHb{C {EXa)r39g$V0cpmYb}8EL)-ziHg_T_c-t*ik_elN6rC- zrTil&g>&w%CNzI)%!)5{CLaHl@&MIxaulDk+Ba{Cfj$p)3^4)(p#*#6JKSUIFUwRb z;o^g=({*u1-%OT1XY%X*R2Q1FL=d-L%CR%1IMeDderXyV5)AwSjt4*&2NyZ Hszr9XfugI;HgQ*Kd}znds6Wz!1N zFc}TUy*|_V%$lmwA5S=sHD04BoT9u0n{F^AT~CN*+QLY{2uw&2raVB5wGDjiOa!+} zvzslyQebmrc=Uul9Buyun?6`4$4ZFRDGq=auvQ{6Phg2g)GLQR_4SFI{| 0^2w|9$8(%I zq!gU*t%>F!V)s6V8ZizL;)=hXs1!KT>0L8ter$;CRomlv1fOWs_ACuk++*;7skV0i zs)$KH;Mk*j-H9Nr85nfp_>MDPnkQ22QnfG51Xk*id0MAGcOZOatUdxEtS`_#e4ZkS zS7OCdocV~s&ZEKzDA-b0NXlbF&b8#B-I9Ym+He%(T67>HD~rwDa%eU-hUAg8)@Qi5 z3@j~+qzWbX9j&{5TQW)Z)F;WaeJq&vdT (hOl{P>Jlky72s Cs## zL?lG!{x?W-WPV{}*vCI6*I=#6IC-j+vLUMa@CW}2@kb4p7K4_fHs2fB##i6lf>@7U z=C3I3`EKwAam<7V467PeWFTIwxQ32oS59#22)%J^-AEo&yQV!bRuFb@c1+7&quC#j zWnz;|Q8nrnz348v`A(lFlzZUJrf}s9m3_3oQNZD6fqZW0B;}F+`_^8T<*oaaqN8?3 zzxafDmxrp~I}q;g0eOJNX Zj&Ii|I3yqul6kBK?yLnV5uxVxLplgmhi|v9!$9_ zEY`|@R2Th{+nV8E|M`XYu))V)3>`n8@K;|9mi(G~VTynB+Rb1ks%<9kPPm+@EU|6W zmiONK>uL)Aq*h-3^&FCDRs0l@)s+tMFC`9&GyCmmNN1iCp;c)CY_-`S_HlV$L+$)~ zyKUaD>%yMeWCeL~wI8(_=+Tq+x!&OB@SE|?R35EsyOPg|?FT2HFL|p@N!;@~xs}rc zKQ6+l?;6r3m)A_lu3u=kpU&{!=C7=+)s@M(_)VTq=#bwCPs=!E-5+U0uUw2MbzRm@ zgnl2OyKT$A&p$A~JsY9Byv}mkBsZGhG2G2!+!qVIH3$#&38zU7|2YyeI1=u=6;6m2 zal;ldll8(W({%r(L~N`?@_+=>;@c*A6cb-_)=k^8Z^BkB^4A&WRYg{{nikl;Hsb#G zvIN6Y-QR3v*rlbO+8XFvK7D0DEE@gH(z1!(O3DtE1q($D$A*(EM)W*dm%{qZu9b0H zjA X_>ZSBo+qQbQvf~1f!>BdUv}X0DGb$DHWG_K z+$Py*ejAicU^LVwViXv?2#ocQR8K~wIEhQ90Hun9(hWgrP*n9^G7bt;vw6~N3X|Np z$nzl(mpJ~TUi3^TxS|c5w2LmN=;VTh@@Oiek2Jm!C%ze-R ^gg#-k-A5EqXFgz;9{Z5hE z1x-N -TV>~69ciYVA&?wB@!bcRj$m7mzF#hDt+P(pjCdNeee^4>#X^QFmNyz2?J z!b#lA6KwaBEEXdLx-yN!O$|4I#_lGJksPi*3uC~BCoQExPtv;lvB-YKX`Ns@6u=|` z6!;BL?l3gL5{m8Z*+Q-GY!!tb4li$H{J1!}-#WH6KUSzawy;IE;+347n0J3bwt{YM zSNqFl4v& 6 Cdb1lyS(LtzRl%mQ<| z-SI89?*WJ6JwO|kN)i1!FcqRr(shl5L3wWOPe|{ z=euQAMH^}`ie?fHMp!R44S(UxlAjEwuDnk!&$tdBo`0#ty&~_mp8%&~GOVC`5i`sk zTbCd6a2E6Tl41h69)ztZ9$Qb ER;(Axoi>N`hBDv*)1ih- z7s0@YDB(;(7^lPFWk_(vm#d0o{|dNqWhY)mDK;{l9$8ya*|c9dNnRO^Rh33xRiavz zIbJ!`QE>{&X;VcuURMoMB~D#ewHjA{l&o06`%tsQ>9-25{K8rJ6 sh|0Ltk6dUL((c_ADRxzs6bq+I=!58R%=` @97Cw5zxeQxPi%vXua-0`~G?#^ZZ{7q?H* zF%VSOMHNW+K3h(>hJ+H$^Phynbf*3cs6c>fIR~WG%Gf$xD)T{ln9AfB$zUTp_*(y9 zIP5ooMNO!1S);Ru=#-sh_p4gwuQ!p|!!VksrsY4BD3x+LZ8|;+j`KDg@4tH0WVcw! zQhjyTQr@@5xHO+oL1Mbn_vCxFOAlV>ko!I7;}NX-VIsdy$02-^Y{nMa%7c=YqisCT z(Tt7P4c+W#55rhaW(lgp)h;<+Bm6pQUdE#Nk!SXj#2 FyKsr%DN`jXu4hd*(5% z>cu9Q$j9W;kS*{=+G|d~^_}Yii ^%r_>A;09Fi@rv|eYqJTLvYKBbARzAE9}i>Y_ePE)h;>W?s~12Z}Rr%!sG{q z6Qx-~hRdDFDaG4^ynB*{9=V?n>q#8z+{xI_zkaYGe54tPuPWPzXM7S#@xB0yXBUk{ zc#`>%cY(44W8WkANi^$W!MR0*)YWGVTrBo*0{g%8hm% 3qPXky{B-&Iwq@r0J^5_13p2CRHNQr}lu3MMwccc>7^@>?kp zu@(Q|r013GF=)3=fve$q?dj6{zLX!f_g++ I`Aif_s_@5QIFah4 zdsLowDdn$TR%kaGei}3rj_1FBkUKIZHB)Mc!A8Fa^pR9kJwDAyrXd8@;R%qPKON~8 zkf`a=Hs2yhQhuCM`RE0|4mbUJwS8ixPT%Oli_2d%DFlub3cdR5G$;juGs{x-ql+)Z z$r?%oSt-<$fii~=$`#>&{TS8Kkoq|&=NGrb%bS_OZISq=Z3<1}x|lU@ed6kKkLVm< zFTdv`izkbVa!s>XF+ekDYh-bC`_VD!8Qa*DA>|@mDcQclC{*n5o0AW@qH^F$-WjRR zB{ji`*EVifw=%n _PJ2~*G*HQw1{rFRQ4uG_^@Z!^aI zdeDZMBhU{YI_`ve9=~+IkIKHWILRaL{UTBq%9XSJhF5%m_$?pMjkEDevY~tT9Um7% zf)1{b!Qe^LNmw(!`CVjxk3~vlv gpRrq1|Ofv+)2xz;ss7AHRU77KRDRXoJ_5w7oa|R1PD`xbEelcJttYr zP;-LM)L(jLzd4otB;ht|Ny~uoT6{;}Ybr{(aP60!`oZBG igZ#JXBZ$@1nx3h2K^8zJ(57sxN+azQv`rf9bw|>z?>XNvJ1d zVOi*0RNq_Ls@o-dnM1)35+ZHpLic!0FwHMXK-%>~m(*aEPCW-PZhKgd`1)|7K)Zq6 z@!kH-ieR2tPh*#RvdHc56LY`8i^L<+mCnzf&!anP6|8Dum&q7OzKbX|RS9XPpGht* zx{ThsL;wZ1K6U%In%$AO6E}TBzZV}+SOcY81b-vU_ka8wG}%h_PFS}gwaWCha-I%w zO) )}XC=B2Ywqw5t?!;5z&ssZqp8*4_2Wx3rErUMg`<&1w9+ zjPI3ZH24PK&3k&^u~N2aD <}1JNF$Fpj*t!;s+mD*%l`_Fy!L++2W6 Z+Oo}a5uT2QZiOL{#{_in4C%+m5ncA(jhaf4o>%md^d+W^ ~ C<;AdbG1vp3TqpRJJFwN*S;F}fBrUC#vg6q{a%SVu2qbUTv>cX3cWlGbCDUF z-3WJ734c`bQ5)`!f$wi}wR>`J)Hr7Ha$HIWKjktH)t!iMV%}Z`qEB#wAN);H;z$^O zBv2`;XD9gg{Jk%IYh=(&q&S6_WO-y}mRmj0lb=2O3K${N7V%Xy!dExKf+-4W5%pmt z`o%(om|rwKG@7w3`l*Al29A X; zhW0aF#7*a*MJAF~LI=1VYBUx~@g*Q=8<61(MlOOu^9~K-@lF2tN&4U%-}roAK(0Rc zIyt@y2T*{8kI)BEYdNB gB&hGjxQl6yAa9;CFQ5nJc% O(Is*ZmuM|-O1QmTitIe>!6$pP2xl1c=S#tBNZynN*)?p52$ zBgc{cOeI~)H%tJTQreuZ#*v}{2;*Ex%Q#6Jl*`aFN;W{c^Mj(bDb3zqWuQ}L?lq^e zA~GJnR;Wj&17(uqRV33`n&4Qhutb(RAcdVGnsP5Wh$$<058`9w=C_m?u$LBObPs(R z0L2u|G%?IXe+B*VZ>mRKYVw|<8qg>lMxoUjHzyCnvx6P)qMEN`+iqZ+t)tQ|!Q_j5 z!g_tamr SNxx6Y0@eBSsB6*r)WT^{*p8#;$ z?d-#U)imhyB>)O=zwDA90fnA n@3=hL$&iq}+|m*K@`arC`oKEI z!si?Lcfi7ZWz4W%ECqfHmlJILf&yak`=GF`f_MSc&S|b5BJP3d{09Z(84@+{1Y5EI zBB_~8by9eyqLATZG-yvXEM_vwR;&UO PiBp z;FwvCmst^Lg^;AL!NaYCS7Jz1${JQOBM~$dmF6l{ |bM@8yY_0+z|GH3eJiOS24I&^AW z`BETa2K~tjM5Ydiy96Y-lC0N^oA;2~6>r!VPx?incma*OQii`6Na|Gp4Uaxe#i5u` zPJGZG (o z*xBN|(&Bp4;!fS_Db?z2(&`)3>Yv>j*x4Gq(i(cx8cy97Db*Hj(iR)k7MI-yK0yDk zJ(~EVTKxY>wV3-$k@#o6O%(bt-}YCI;-C38wuA(lSy@m#(LbsMZ~A)@-P6s9B4zVo z8qU{$Wh4-)xvI?-bCr5b{J8YW;ZM=f|4B{YQhdde4JSg!yx$nlecf8K+UfI%-SU8x zd$}hZwbGWWQtnYz95ELp(Ao~2ID+XlYkYq_{yV6U6Xd2}U~{Yh-JtYk;n2oRc~MIN zeOzSBRNW_Ii$~#+aUa^eMo8sWd=9_Z*r$o+c8G7xRhy%m^S(QGS)CF%)9B8Ta4{-L zbZP~^YdPJo&t8FOtQ~uQUk?)-(FpDg!dVR|1M=JjT-{)PoXCF?7*ciky`B7v->r&1 zUFhYWl0`(s6*hi2s-qZvRNAvRivT=rhjpL(W^zjpV#h@bw{tTbvsgy7?R74~P^fVn z$M`D*XtR*wAuG`_jfgMn^S3r4n=a2ze1SFcHH!AM4SJvS5=>g0-1cBzd3snh^v&K&vGLJzIZShTe>7d2wxGDr=`$aMYKwr%G^cD2pvktZrgKr3rY zlN-29X@<#NjDi|#rvcb>KW6zcLMN=eSYD(-1<%H`Qo9Dy%FOz6l%gLZRrA6Bmc6jx z@F~u$;Bd9LO&KP(x&5ky{b}o}2#G9!FOqqietLL2hsL+;jEjFfti#Rzz$Wa1fH~^Q zapLFjLUB-s>Z6Pgb{pU<$+D(cQ$Lgl=lWGSTgn`qGBE6`1o~QQVh@g+8|ASFiYc42 z4?8XQ#Y?UJ7D_G|JL!4=Yh@A7!W0?y@4LT|IdApFsq_DfW)io7*fR~FQ;x?(BY#5h zgZorlFQQC*f`Q#J`fmBV9fKyp5Nd)|m0-~DLvUmI@8HJuc#g;56f9YZPKv}moWdv{ z>Y1DDsDwf8c&j!1RO^NGukntT?${sG^cm`wmHgVwYVzPI=P--LE&z@DeahhHU~;OK z9HUT|wl99FWo?r{CWzjoSn7(nS+{ zWjM7QA``eBhc9}%sSiq(Y9#eq hZ&_k;ow0cd-LWZ>7&hu(RK7PUtM&ZcUod zg|y5ty?q|FAeQ(1{&HnxrR(V3x8sguXqnr)?>%A1GCvO*-(24=576E3zq)vy_xtGJ z%SLj`i}kNb!N1VgFY$yswPzt}U#u;Ty<27Pgp*003~FQWh|6s}(~NAg2!Dj9oI%YU z&dwG$hob2&kHWt$h>|mbZ#)`KG7OGsav%SQS5Dd;9HSexH*R7TSJUOa1%%>R;qaWM zuu9g07%Ww_Qssv@->zdQB_oL5o}}>x*2nW1Mv|yo4GD6x#JA$e$}{#42lI#XM`>D9 z@AxN)QOQHRbBdnfM~p}}cqE _NV%Lu<6WOFT zmXE&78y(Ylm2%H)BV5F8$w;h8Wt(1P3g*xPsp@T?a4;vRK1tdoSK_GWlQqTX@xoOy zq+rd|1|-na7WIEZ35SaPR1<(jGFwz^N70bbZx-vf+DUpvojrZ?wN$0G`zaxGQ7uVS zPh7(`BguCsie9*}UBjb=Sel&XB~}KBhJSaX >(fbWFx0_5QTEP%OsK?+=d(SQA$ehTR1e6QVEN(haAFmjTyjJ zQwVAKJq7e-sTAH>_`1zrtV4xNwr_gj@|8{j&8um+r*45#HBv=~i9_{iMvi1+!mCP- z(xY;)-qpQ4<(n@%I>ltoWv`z po$!KD}=o1lR2d&8W0g zC+IqytLu^zslLkQdb<(`kLIbW_59!1d&{V({)g?CZUqrx01*UfB$OCRx279d z7+`|#8M?c>1yM>tQc4Nw5RfjJ2Y+|2^V~0 zZvaoQ*5Ef_NLKz;GV^&&>?dany6E08$}QWlsd*bT$K01B$_4{XnyD d_OVx3ZQnNdhsd+du)U`8np!6e}={f_qOQ_mWX4Ogk z?t1F|^FJ@o_K9C$NjSFlJUP6Z>(s(1o$h;`dWZ%+5Tm^HeBAl_N! b(x6 z1N2@^ 3x;f=uAxRQm(>2>#5wD^(w9M_8p7w@n;Q+VGcufWv;m2Db_6osKG2- zfx-#Opr&=^0K)r9%69tD7^WA8U*g4xKa2%_gXR({ZA;UNP^XeK(b6dmi*qi}#~dIE z>0L-wTWls%TD-X&J(GF-ucxFe5iEVGyK#Y@WZKS+87lByjfxCJO;)7winMI^(Z=wL zm{;7%1{ MexlZ^C*1ecZ{#3T~u*q^!i<^1gtF|()aEkx!r`(6{Tog+6T1RGTHaCA&4$M?ZhVab#JoT{^CN`QZNSno} z$*#}o-f^gPTRP-C)gTiW+LTW3m=m}_FKFCU!{lxj8eP1~_Ois#*D}3Cxu@Mrdk5m4 z{%f5}=igPUtn`H9EUBZem>r&NvDqb#{GM!(=;AspPjnuV*K0^-4?YnY2x<|nMdkgm zw3mB*YlnS-Ke6=ej7K5(i}o|R`y0o}gehP$%{IJ5Ty3voM!cK;J#{PYTi29}^SKdU z!F{UPfeL6GE(U&UUnJTUNPF;Gsq#;FK+vYQTl=wFTrgd=S)iDZWq`f~Hprsu!u3ku z>qg(|%+LKhs|(?rS2UIDgG;ZAR +Xv*2 Wl+pk8LizNa@u>rBTh8)@oSB|u+%{IJJVnj9 zqhh^nb(C!iNdC(U;!t@9N?!YHq=PplA|4Nc)I;?8+TU9fRUl&cCOqvNfueLs--L(D zM>iNCn*PJq=mo@l0LFYYh#6puxwkb6Y#+ntV#FUgM({euZ^II|rIV3x?nh2)6MqrK z(q-%lAnqp+9k JLiwznOedf>g-%BDFq0MsF^#x$Q2ga~>>CSe*KNQMp6W=H z>Zm-8U_v||IAO^io36=|x(#B#9mcPnKp>oWUY0-@5%~Zd!px-rYJfjD8s|d*}`?(0_3SvDTGtm6q95fk_0aaDKJuv!0{%+NxIY! z{q`Vr!!)J#gt^x#ukh07cG9#6(=oPFy@r!nwv&BP@pe~9SCkAlwqe0aiJW!VqIp>K z)M#W|7#o5-P?Zo< n!P#r! ?pOC<9OUzv&hjIY2|IL?N&YWBUE;e!6~k ziC^{sDxP{gJBJbX2QV=XPMd4Tw`FKRB;$`&0f;0_#6`sacirN0_!T$y>qixU1_i@r z1rw*_{PVJZn8Zq~$PqhDFFLP4iK+)buntO-hbuJDn&adU!fg~s+l#;VGgk5lKd=`Q z=$MII4K!>NFrCWvcX(2v8&qWz{1Sm8nE!XnVsa9fX+h8pTWH0u*a1wl=4Wi8tScg& zc5&}lgchm(^(#t39s>^sOH`>%LKs4%IidokOD};~uNbhI#*xAq$#?CRIJ?CmhKcb+ z%pzB*ec%W=qw?jsJc79r8sQ>|Ax7A4IU%@QI;lKhI7bbZU8WqDw;P$Pgna8zQEwF2 zIFeA%kz8{fk&US6q)FH3D9`MOazRxxlvnV7sK6F1AFilc1y+IQD>JSuS$F(OIjX)m zGLAV`&C#r<PwvhbM|y4UQz%8P${%6*q|>4?Xh5mC6tNYiy7;yEyk_RyDZ` z)l|pTyEHXEJGESdbp(ucHyt& aG=K`sHQawxvA?61?o8!XIPt0^)WQo%Y(G zA~>o?K$x5sEOIq^u&sfsv*F&RF#0Gr25bb@!(L3lrU-0jkdAX@a0hP$!WPl8Eni5` z6vomdW2|t`DF4r`iT{~e?EMQ%{431yf7s>l|18X5J(A9QFH<=1m8hjMIuY_pTZDei zm4pz{DeJIdGGXHU+Ba+}*Dh5^#xl5Ws+h^uOg-)zdBUM(^gz{{&X@xCbDi}Ro&YC7 z^+KyN8nZ1ZQ?TYfv9VpzEGb21*6nb0JxUC!vcL!-_7e|GulrdEeJs&JGyi+NG?hpD zKvbn+vjim}`ru^;+s>p6_26-g$o9@RN%Q`5_J9^ggDN}HvIm)dPRnI(??+rRU;kbj zc)7Qf9SC+Fi_J#km}PX>@8w2zirjU!dv8MCLlmk^TF>>qLjuy{OucSCZy6TX_AFi9 z3}4U>nhT))|7={bQ(9Qwluw%bqEYD<9;-q67998;tqh(I8iXwUnq&! 7l1K z2G1bta3KZ@*4;A(4w|3%1tHI{E*ZlaGk}E=d>lw7_=GTMElO0&pdem=T(~Gw$_liO zhRQLv7sV*~UKYh=$Ff;RU;o**N_np5z?9DWR*5kUOS&~9RXIs1FU>GqsW4r>0?wFe z(*bA7dOK3inC-Mc_##IY0cOt7+EtoGlmf2x5YS`c(p+OKqT)OU@`d7p02Dm4*wTsy zSr{O_P*SAhuS{7O9ll_n9G2mTtSCnqv6jE{ye_GX?#p1WO#V6Yq@q)c!zLcQ;9pvs zuyf5`TTFAq+K@TCz*-FnX5TL!lUH`GoR1@N(e33{aVh>59F1xybrdmaZOjm*>8Mq{ z*=~z$5UuXa>&xW4cMuq!{dEuy-(zC)9{FJq@AG`X{Vbj8WvJHt 4Smdwfytl$$wUCR`a^Xh=CV${UhF%=zDlCG zyr0Wb#hy$Y^Zz=X`Yu-FeIJQnJewv_vpyR&;M6%|(DzdtpKSz=%aRHgRi7_7xBfa` zbh;S-`1#pq=PA{fpPYqMLCIamOFU=4+#ge0SX{2cSZgkS#&G6HJ=SulG9GyB_7uF4 z?DbRyTa5qUYAcWSpx@Byx$5=%(#)Lv2l=fB9jk)dH ?HYu3Y*P5#eK80z zcfDMU=b _bQ%v1KF0b`jC8E3W8V7||rOFVJB; z;%U}H^!l2_ICzCP`10OY9>*npS{L=T)3PhYkCm$BfG7ln{RoBul`vU_DSxMWoU8kR zS%lBq^|GIgL_b2J7c<&8M(3de l>xczdgr1p|)G=q%_`(O_NkJIlY z2P;s%m_Aa!ys&4TWuM-(BnCd4HpM$&`zWE9@7|$pS#1C);|Y&L6NOmxlSPe3Nf=lr zW>GxHynoYuu)Rtu!khK*E)V~K^>N~1|HfSduv4+a6+7@!hKvM1LgFY4yLH{>*W~s~ z`TIyr&E5z41IbAC=~Yrw$&Ei+O3doP4{;0#O86Qvuw01TGl{K>f6FsqQ^$lxjqv9( ztr1F@7bN&~>@&Px-1uVSf06^6vTh!qm-fMG^1x!Ik`i?ohj4S}pZ#Qsr`gq5-_VAh zrmVavJyVBDQy7y!(NZA2o>+<0QDVZizc1LDwA5@WfEw@AU$d)ce0!Y18@nSnkDMTJ z^#<{bmaDeUO>!5X=E&$4stJgwXKkJah;FQD1uaY$7VwsjqPZNA)_tMR!~{Ivu+8-q zCG$dF##C8}S9* Z(xxo)l%cgOm1iU&*?=W+|- z+*f+IC-e!A+onY^V{TxeQA*Lb;g3azO?#AKu)Q8x`md@tZ-|>GGtQfa2{P?{N(AaW ze4Fp=tF_FCjRO)~IGU<|xd@fwP^GN2_CBa_hpK%4i8qU@3^K$ E8E%vAU?k07#=O z=mSHrTjb*LDp{sMH`753!P_rCv0%NxmveP7c7e;30J~2w1%F5X3152(0S$7Td%(g} z!vIs4Lx2{(_{iHe+SlL@l07Q%xm^~FwA8}}-)fT{y|&??LJpapzX~ku%HWNj@75b@ z$oSo9LxjBgvXA>Z>;0`fb~kuzN9`nI=KH4Tn&B8Im Khr_0`)m1w`r z)eUH$sTt#~vU};II+Y>OQu3({dBO~-89U30bydei~%IAD6nj6V-m?M#4sGu$71 z9vqv!Z;#)xz}3;>&)FMJAt^aHHg=3-wSsxWh*~6OX>FhAUMKr}^IfK jv3xY&E__<)<&7Z?iq4p(m+cq*x?jr_uz&|;sA>NM<#h&uvl=9&n)j=gz z7*@&Lcn1W=JS0F*M~FfWM}(Gs$E#3(G*axxCdvzS!dhLE8#|`l#`u){UUc(d^lB{N z4w~C9wn3sN@-@iy ~Oom0F8t2JvF20A$+xrcI;qCFxbk8KD z
TkSZ^|U`G6 >| zxE>bm!RR~;njxh7NhbS@2tQ9~DBdJYS;YL|L6q+SmGi9xgZWifuKQW7x__nm91eK9 z{~?h(24BqbQPo#oLe<_ou3Jn(THy65F-h?6 SrL2W0Hp#qJgKt5Ms+}iER)X;vO31=knMfl=3o!+S7%S44(ptLjbdWs;^{=5jH<) zK@SMOnzi6G2xVmRD^_sXDRJqb1XV?$A+30!v4hSfg6@K4mPh9 QWZ;?euk%N>`R&6e} zWf5+3R`x(5$2k}0xu`3-sANhgmmsu213GCN37U&IQHY2vi= `fa?iVY#EhzPJp@PnXfWeE8pMBFx_ z9xpl{2Jb0_Wg(+-2;g}zXv1Yh6A(eCZB=}ZWo2_80WlY1&>L!V7-8d`fH_P7iLrPs ziq9>yHO)r}Ffr0Bz6_va=gTZI2V&_8ad>#m_J>S)>TtaKO=bk*Pl55XazeXvao36_ zhp_m)ws?#y<39$k+i{JHo)|UTVB#AlR5m9N3LB+H8j%YpQj`-{q$afbBz7 N~m=j6#NPiAmJlA1INsJp (5N5Knx6Z~ zFuMjvr9oDuWnJ>qklA8-pt$n8QH8K^)*{`=j96^d53;HQ5vpd&c_exvx6qIkrFVO? z!G}~K_KrCT)>*MkYSY$gb4^9WX<=inVF=+Y>XJ~B?a ip^D=*##O1_P9wBXqe zV->thX*Ma{P7aIPu7f}@{8LtQ^3WJ3#sNJ(N)S>-Qb*11hQT^rqMt0nq8|F zQR!Kcd3wJ*aa}5REz#}(?HqyCjO41PR)w)4tBtDKBXVp|m6}6kUzDpmy({zK)h1 StKm*RuOi z4zb9Np87_zHf9P^K2FvFF7LqSQ!Jd>ug{8V3}rTWkr>a}9*;dwe$19E>l8nyn=IIF zkf2LUP;UH)5JSx=L7lewfp9YkyHSyD;{O=t_@A-F|0q)s6NO=5Jio%h`1^T|CRTE> zw6jsOv~zgp^w7@I#l=#bmz!VU?}fqj_bb=;*Z++@#(yak|G!cw{^}9`sZemI{7(wS zUtuB>Xg-j|US>OXUp%p2#ViRA!%|G mCmmOQmjCDkCH5fadvU(Mchx*PBW|nH?+d@CG3$Ern~R9? zSUD#~2M1S*f{S-atoMTr21@w#d5mGBeSZ x@X?Q7qm|5j0KkC)OfkLikD9XAf S ?Hz z3Zv_kfNP!#jQWLW4xyjAn8fUoN11Wrl;!#HxLEDE31CBp0eXwwRhd8oPlFPuT~66X zn8{Dv0eS~9sR8<6?{S(`2_wS79MQ?ib?yIh9Q;a91qJ-C5bGHXEns~tLIxWQx)7X1 zwp?8z*42ot&2l4e-cVFuNe<0USyCl=t2IZ+Qt@AvLCUtw@TX%*jr}z{yBR$Ifs55z z;?G>`$k 3tNrA6A@93)3A>!gvTR`rl&9Xi*_z?Fg176#mDXnqybVh(tOR00G z4vt?a`ystgh>1Dx!NA?(bHLAH8sxz*NCW(=jLVg}Sq(P4opi zr~M$>y^osb3vVI~?U&y*&;3kR2mLHnJwH%4sx}O=VYB|WCCe2(u}`SEbo#<^VRSsg zbVK6xMdd7O|LdDhuG3-J&sENa>Jl^pm0tu$Qzkw$1~pA8kh(N`3-RckbXb1YJDXLq ze9-*O&?~!nR zs1}sE?<*)+0}&rKFnAN%BQoFB2yZn|_)u(U*4xZLJQJHm?pLC5I}Mt7^F9*OZ`1@F z@No5MZ?WJqcfD1(J(xNg>emrd>SH~;CH%ZdE-C#;H xnWXy_I2KBLl}7SiXX`DgCA_FtAww|ab{4slJx;} zBo130R12j(4fYtMIz#=>uH7Tv0Ae;H2t*j)4Dof<_mQR#eSEag>k(r4{bODk?GT?5 zT vcmBx!#vVnekl1qC%EW#eqn>JKYxu?(io_Z9n85pc>(dPaAwzvb<=Qm+54 zW!!UXLu3rE)i-;UR+m*wsb2@7D`QCNFH#qrfGEpXB*C9uhST@1L%Bf~DL=%R`Ez%^ z=tRAW*1znhg-PN7Z&!)7O-e- 2KQP{6KD=5l6?x+L#ar++TTM)+ zS{@K7k@q|wvTrOu-=-- Kpx zicF9(B^qbeS|xP`d>~sm!sjgVPP#L(SJ<1=rgxMi4H@qv@HxU4x9=?xMVp$urA?U` z3_5|*uE> jvI3e3*p}qGqPO>RTdjQeIReiAFX!Hwl|(0_}12^`^z0n+%$znb$>Gc z(kpq>*jH~hdm{UnH|Eawy}QQx{vR$LxyB 3zn*CgA z>AL8)3HD+)-iZ_Hal)-Lx4cI()3Xt8R <^e z>L>Zi9U%O|0$V}#=c9{W!beR?_z sH%>cs zkH5gQezxT{B)jBsllEnug|$CKv1jSewck41&ASnu@`lu3k0cxH!Jkdz t58_&FV)n+s $uWsfl-O-%gzY@0rGFk4&5wn^L*K z`pn@d`x-MCPPijZ?@Qh*3%Re);Z`G^LJ|m?M`&-Vd1Pp3?>{*+euqICaEbk}>g{Q5 zztUUp2JLpoF|Anrm^CHB={zDIwg#C1VsF^i0@QUM{cSs2BT9Pudm{0Vq_s$`v=1pI zl -?2-0g|EXr>g#u6W@GUQ~sk#`#=3BD` zzQ*4jpUvDB1NTVB7liHg)OU$+NK`$^{6D>yK%JD*?_iBNUnNggyG1&g1hYE7u)xAW z;)aCc&`N>^2WkG`bN`g)Zu4_D{y=kd9DG*bKmMN#BQJC%isA`?mkJQ(4b|qhqe34C zV?)Be3bGzs;W5DcaO=V`r@~o=(4fm^?}x3ye148i=|I*pZ84C?n@b4878p+`!bCTM z(=S31>3Mn)p)_dzR?$lX5cx_d(!e0{+&2=8?PWxODK+G*3NpN5Wqd3Y6{i=4=@&(z zP4v7h%Bn2V)xd>(h=oxfstJPb;X!>_q5PodPD4>k1Cf>lFm?bi5Ec kU(Z7k|M=2#y-MUXsmDKLhV5w*6IEOP7`qAH|} zB};IGOU0N^IsR%k^x}sV&B6J$5bE>h3pUZVz~~bDR5v!0&&8=AMYt?`Y9# ileVC`Yfb^lyIkGjH{|c^V6Rzjw3Q zAAEfsSOajVG7s5(J<}mua7-*Y4S S@H0T0?AhWk zG&LnPDQ9wW_1W{&*@wYS$Wm|?YYr_9_*n<&549GPt`=)?{(H*+dLyUm3;$0F1w4*u zj>jS>BMR*kX>IP2fTn`LV?(Dtp+JG%pfMEHus+wHD{UzO9l5i@lt;lI$qP&5gT6t7 z76yY9jk1!ZidB{KIZkyn1$1?Nbk&+N&n~zo7=v0i|H27VqdZ)T5SNU?8z~e!h2FbJ zOdB6P91+-q%Mdcy^B_Z~d%%c~4E5qDTlyJ_0V}YokoJ_*_dUZ0Jt?CA@Vu}uZY~LX zx*aCSLCpl@VYV-;g-eGC7zAn mH&})geu_>{3qpjguJI5r`uEaltcdCD2LKNl;dx`CXcOP+3)7s<@W|| z+tmTBbyHp9gtTT^6n`lPK!uwjJe+~(C5F>dOmn0SMgr^Wnn2-(zmy~MO^}d)?O5F( zf9}zay1kj^<&v}~B0?s!sCUF$BDDOj%l2+evwu(*zc=27k>=(!gWR_5Qr~@D68m=c zORZQt*Y%I^WzoXd*FS#!=<@%)7MZS3e|O?{tvKJ`5l i zNG7g9URaYjLB1pT+e;b<#zHy+2#2U_ne%p{l_4rb*uVn%hmPQ9)MBinl{t%lnPnt> z2l>x{bKDC?3%(M-Dny{gvoKuvpv*9yag5Cpolr#r*ZUjs=(FN>{2Ti)c|x1yD#gy6 zs!X}Lky2J}&lIip7kW6~Ll0E?4#1e)d6K~#>0Um(N$>i>!Nk(P<*LNRmI%(G{a=ZX zhymfJc%c2?_z(T=2=oi01+VRkLY6+U7sg3180D)y>qw!zH!(x8d~Pvu%BTifaOw0- zG91c$>vuV-8YU|$w0e4I_Nq!Je->#Iz6edh^uB$BQ|;;cPjN>6UK*%pX1{UbZ6;T( zdyp|k(`5K=mNjo33bVQXpB@eSX!h0&%5MkshjE=;MmOh9RLPaMHz|0&w~r!on_bWQ z>G>or4r}m4BkRx~NJu|Ve sZn$L59A^IMA5YSLc zf6#b}QBstpTemggX+Lk#>h|YWVO%DeIDJavrv1S5KMBn2UB)dHAxld3-x7|{+G$st zZl76mVq@f@Nx*~i-ZIK656nm3J@_+qdpZB3n4`+nLn{dVM`7je;K${1!dmtI66MEL z5PA6Ex9uETwz&4q5U*!frYN_u69hk{gEd^0Rk(4Vf_vwBk9Qz$ZNGE&;rg$(fKSYc zU5^iM;Jx_jSqB3=2ef?^z+B_h5gA@F=$CgP;5}LW_kq6`8r5#lGw=NlyY*&Uk=@se zi>`N9+12rMh_#UYH}+Nmxp%k6GWbCpla&w7Qd%X@XKuo1895BY*S#xG$inbt-(soP z_fGMX`H`kr;N+&aZvRpX9fp|W2@||Ir&E_de7uTR+A2-fQX6;)S=N&u`apghPf4Po z8fI39A;sH^_iB3Nfj>d$Q#}~;&2)Zf0x-ITLXq3LUYYDU8D$G#LrTNDAT$q1jK{W$ zD@C}bU{;5dLoxA!N2!oz3h?-~|DzbIm_qrX?E#*V-*L=&YcH`95@45n^dtb{=a-j* z(o0MUQ4B@TiQz-iY@Uh1&P8G@O2f*YYtIv66lDm)hE-o#qZzaI3t68u3`==?rr@w| za6KK5c(%ThS{GByWvBGnXrKXKjki$!2r!sGjuY!dQo_5aNPq`e#i3Fxd6ho=#a845 z^;s +q OYo@Ax~z_MbnGzetnXQF kbwGp}p zpUCpn&nh(fcIoQl&I)Y0m(_Ja)ToNo66YWB#>+J0Z6Dlgc&qnJXGL_04pM8;r<}(v zM%_&h^@_m7Y*xAz1{66yh`1mwSth5#{ >55TxO#NJ^vh@xEOrwb24*T4lI^ zi=yV@i 3Oa8JtHR#)ry5yfFDnI-uTP*rFY-^SzaTt47N%aZbRMKB@ zsG~+a3pYrLxqNs~VNu<`vbO>Xsg_+jR!L=sY|)SIF!2AJpK^V|qHMs}H+lb^Lmzij z)#35eueiB7#daD7f`v!;{06|#`(!~Iuxqi$gwuHO6)!HCsud^$S;3LrM|aB`#do>- zkRRlsmrPza<|1!)nla}euy3}Pgw@GDiV=PB0@pdor%-X#VA$%U4yI%{C{}VD|DaNf z<2LMp3_zOp&H|Tt>x-@EYaTm|l2>W%B)0Y?uQaR0h`7vku>CI~4;#v{-#Dy%zA+`5 zi4fc@5I!JPB5umtXy05B1ZL8%K$;o||G`rUJxAKxc&(j(N(zIYXU>n82&%a)3`S5! z=JPB>-h(kBZI~|AzH|C8UA1SeZIw9z+79?p?dn@wPr0&GD6VFv2r&bLZ;qlL|I`Es znEOt9+xfw-x8@g9i%-Kyta-!N!%^jRn=a1z;uv1$)IXAST`xuUdzU5`mm&v*tj=7d zgWruWZ;bh{`35bf_5{3A6PSd}RJm*LcCF?GwOKRv6v8h6D;< }jx$adY8{Z lJw_+8k(ML0!D82lk`!>cz-U#2DT*TBO6OKp2u%8f4*R) z{7NlX+~<~U?ZDdoyZmcV%Vb)ay7+FuN`%OV#B|H)H3k5Ns^!8R^T(_|eEGvSODA_Y z3P^jdXYdi7v}YI}d4eTg2*cJnL+HOyMV#c44y_pejCie+rPY+{#VWfiV5qjbAT+s?VOGw}55wykQz!I*m z?`vWgu7c<0r7z=(@ADGo$1{W`WWDr!y)7-U9WDd_(QO;?5rj((g-gI7JWU1_dhVQx z;Y>&i<}!#JEL^-ySBWh`6c4Q3MkqRGqB{gJghd$7c?oadQ;R5D-6&(f2#vOgw6jQ( zlL#%qeGPPE1_RWSN#7d;^;I+lAqo9KB7sAZA=}1bFha CPMa4qA~FluijLViE@AI3qhw%| z)V^GGmz13Vu4enFgl%XNl9G>-yL+2*5XpV78MFf6?U$5l@~~*W*b@6_=S$ypZGcr; zjQd3F=%w$xJsL6rqZIIZy|hiag|wSxi}|V;vvEn0ToM(@7azABw?+{0dyb;YR%i!A z`3E4hsu*`w7ID)?G0?&~H1PB_G9eTKpSy=IpeQg