Contract con_poker_1_card_games_v1


Contract Code


  
1 # con_poker_1_card_games_v1
2 import con_rsa_encryption as rsa
3 import con_phi_lst001 as phi
4
5 phi_balances = ForeignHash(foreign_contract='con_phi_lst001', foreign_name='balances')
6 player_metadata = ForeignHash(foreign_contract='con_gamma_phi_profile_v2', foreign_name='metadata')
7
8 games = Hash(default_value=None)
9 hands = Hash(default_value=None)
10 players_games = Hash(default_value=[])
11 players_invites = Hash(default_value=[])
12 messages_hash = Hash(default_value=[])
13 owner = Variable()
14
15 MAX_PLAYERS = 50
16 MAX_RANDOM_NUMBER = 99999999
17 ONE_CARD_POKER = 0
18 BLIND_POKER = 1
19
20 DECK = [
21 '2c', '2d', '2h', '2s',
22 '3c', '3d', '3h', '3s',
23 '4c', '4d', '4h', '4s',
24 '5c', '5d', '5h', '5s',
25 '6c', '6d', '6h', '6s',
26 '7c', '7d', '7h', '7s',
27 '8c', '8d', '8h', '8s',
28 '9c', '9d', '9h', '9s',
29 'Tc', 'Td', 'Th', 'Ts',
30 'Jc', 'Jd', 'Jh', 'Js',
31 'Qc', 'Qd', 'Qh', 'Qs',
32 'Kc', 'Kd', 'Kh', 'Ks',
33 'Ac', 'Ad', 'Ah', 'As',
34 ]
35
36 RANKS = {
37 '2c': 13, '2d': 13, '2h': 13, '2s': 13,
38 '3c': 12, '3d': 12, '3h': 12, '3s': 12,
39 '4c': 11, '4d': 11, '4h': 11, '4s': 11,
40 '5c': 10, '5d': 10, '5h': 10, '5s': 10,
41 '6c': 9, '6d': 9, '6h': 9, '6s': 9,
42 '7c': 8, '7d': 8, '7h': 8, '7s': 8,
43 '8c': 7, '8d': 7, '8h': 7, '8s': 7,
44 '9c': 6, '9d': 6, '9h': 6, '9s': 6,
45 'Tc': 5, 'Td': 5, 'Th': 5, 'Ts': 5,
46 'Jc': 4, 'Jd': 4, 'Jh': 4, 'Js': 4,
47 'Qc': 3, 'Qd': 3, 'Qh': 3, 'Qs': 3,
48 'Kc': 2, 'Kd': 2, 'Kh': 2, 'Ks': 2,
49 'Ac': 1, 'Ad': 1, 'Ah': 1, 'As': 1,
50 }
51
52
53 random.seed()
54
55
56 @construct
57 def seed():
58 owner.set(ctx.caller)
59
60
61 def get_players_and_assert_exists(game_id: str) -> dict:
62 players = games[game_id, 'players']
63 assert players is not None, f'Game {game_id} does not exist.'
64 return players
65
66
67 def create_game_id(creator: str) -> str:
68 return hashlib.sha3(":".join([creator, str(now)]))
69
70
71 def create_hand_id(game_id: str) -> str:
72 return hashlib.sha3(":".join([game_id, str(now)]))
73
74
75 @export
76 def game_message(game_id: str, message: str):
77 player = ctx.caller
78 players = get_players_and_assert_exists(game_id)
79 assert player in players, 'You do not belong to this game.'
80 messages = messages_hash[game_id, player] or []
81 messages.append(message)
82 messages_hash[game_id, player] = messages
83
84
85 @export
86 def hand_message(hand_id: str, message: str):
87 player = ctx.caller
88 active_players = hands[hand_id, 'active_players']
89 assert player in active_players, 'You do not belong to this hand.'
90 messages = messages_hash[hand_id, player] or []
91 messages.append(message)
92 messages_hash[hand_id, player] = messages
93
94
95 @export
96 def add_chips_to_game(game_id: str, amount: float):
97 player = ctx.caller
98 assert amount > 0, 'Amount must be a positive number'
99
100 players = get_players_and_assert_exists(game_id)
101 assert player in players, 'You do not belong to this game.'
102
103 games[game_id, player] = (games[game_id, player] or 0.0) + amount
104 assert phi_balances[player, ctx.this] >= amount, 'You have not approved enough for this amount of chips'
105 phi.transfer_from(amount, ctx.this, player)
106
107
108 @export
109 def withdraw_chips_from_game(game_id: str, amount: float):
110 player = ctx.caller
111 assert amount > 0, 'Amount must be a positive number'
112
113 players = get_players_and_assert_exists(game_id)
114 assert player in players, 'You do not belong to this game.'
115
116 current_chip_count = games[game_id, player]
117
118 assert current_chip_count >= amount, 'You cannot withdraw more than you have.'
119
120 games[game_id, player] = current_chip_count - amount
121 phi.transfer(
122 amount=amount,
123 to=player
124 )
125
126
127 @export
128 def respond_to_invite(game_id: str, accept: bool):
129 player = ctx.caller
130 player_invites = players_invites[player] or []
131 players = get_players_and_assert_exists(game_id)
132 assert player not in players, 'You are already a part of this game.'
133 assert len(players) < MAX_PLAYERS, f'Only {MAX_PLAYERS} are allowed to play at the same time.'
134 declined = players_invites[player, 'declined'] or []
135 assert game_id in player_invites or game_id in declined or games[game_id, 'public'], 'You have not been invited to this game.'
136 if game_id in player_invites:
137 player_invites.remove(game_id)
138 players_invites[player] = player_invites
139 players_invites[player, game_id] = accept
140 if accept:
141 if game_id in declined:
142 declined.remove(game_id)
143 players_invites[player, 'declined'] = declined
144 players.append(player)
145 games[game_id, 'players'] = players
146 players_games[player] = (players_games[player] or []) + [game_id]
147 else:
148 if game_id not in declined:
149 declined.append(game_id)
150 players_invites[player, 'declined'] = declined
151
152
153 @export
154 def decline_all_invites():
155 # Nuclear option
156 player = ctx.caller
157 invites = players_invites[player] or []
158 for invite in invites:
159 players_invites[player, invite] = False
160 players_invites[player] = []
161
162
163 def send_invite_requests(game_id: str, others: list):
164 for other in others:
165 player_invites = players_invites[other] or []
166 player_invites.append(game_id)
167 players_invites[other] = player_invites
168
169
170 @export
171 def start_game(other_players: list, ante: float, public: bool = False) -> str:
172 creator = ctx.caller
173
174 assert ante >= 0, 'Ante must be non-negative.'
175 assert creator not in other_players, f'Caller can\'t be in other_players input.'
176 #assert other_players is not None and (len(other_players) > 0), 'You cannot play by yourself!'
177 assert len(other_players) < MAX_PLAYERS, f'Only {MAX_PLAYERS} are allowed to play at the same time.'
178
179 game_id = create_game_id(creator=creator)
180
181 assert games[game_id, 'creator'] is None, f'Game {game_id} has already been created.'
182
183 games[game_id, 'players'] = [creator]
184 games[game_id, 'ante'] = ante
185 games[game_id, 'creator'] = creator
186 games[game_id, 'invitees'] = other_players
187 games[game_id, 'public'] = public
188
189 players_games[creator] = (players_games[creator] or []) + [game_id]
190 send_invite_requests(game_id, other_players)
191
192 return game_id
193
194
195 @export
196 def add_player_to_game(game_id: str, player_to_add: str):
197 player = ctx.caller
198 assert player != player_to_add, 'You cannot add yourself to a game.'
199 creator = games[game_id, 'creator']
200 assert player == creator, 'Only the game creator can add players.'
201 players = get_players_and_assert_exists(game_id)
202 assert player_to_add not in players, 'Player is already in the game.'
203 invitees = games[game_id, 'invitees']
204 assert player_to_add not in invitees, 'Player has already been invited.'
205 invitees.append(player_to_add)
206 assert len(players) < MAX_PLAYERS, f'Only {MAX_PLAYERS} are allowed to play at the same time.'
207 games[game_id, 'invitees'] = invitees
208 send_invite_requests(game_id, [player_to_add])
209
210
211 @export
212 def leave_game(game_id: str):
213 player = ctx.caller
214 players = get_players_and_assert_exists(game_id)
215 assert player in players, 'You are not in this game.'
216
217 chips = games[game_id, player]
218 assert chips is None or chips == 0, 'You still have chips in this game. Please withdraw them before leaving.'
219
220 player_games = players_games[player]
221 player_games.remove(game_id)
222 players_games[player] = player_games
223 players.remove(player)
224 games[game_id, 'players'] = players
225
226 hand_id = games[game_id, 'current_hand']
227
228 if hand_id is not None:
229 # Check some stuff
230 active_players = hands[hand_id, 'active_players'] or []
231 if player in active_players:
232 folded = hands[hand_id, 'folded']
233 all_in = hands[hand_id, 'all_in']
234 next_better = hands[hand_id, 'next_better']
235 if next_better == player:
236 # Check for next better before removing player from hand state
237 next_better = get_next_better(active_players, folded, all_in, player)
238 hands[hand_id, 'next_better'] = next_better
239 active_players.remove(player)
240 hands[hand_id, 'active_players'] = active_players
241 if player in folded:
242 folded.remove(player)
243 hands[hand_id, 'folded'] = folded
244 if player in all_in:
245 all_in.remove(player)
246 hands[hand_id, 'all_in'] = all_in
247
248
249 @export
250 def start_hand(game_id: str, game_type: int) -> str:
251 dealer = ctx.caller
252 assert game_type == ONE_CARD_POKER or game_type == BLIND_POKER, 'Invalid game type.'
253
254 players = get_players_and_assert_exists(game_id)
255 assert dealer in players, 'You are not a part of this game.'
256 assert len(players) > 1, 'You cannot start a hand by yourself.'
257
258 previous_hand_id = games[game_id, 'current_hand']
259 if previous_hand_id is not None:
260 assert hands[previous_hand_id, 'payed_out'], 'The previous hand has not been payed out yet.'
261
262 hand_id = create_game_id(game_id)
263 # Update game state
264 games[game_id, 'current_hand'] = hand_id
265 # Update hand state
266 hands[hand_id, 'game_id'] = game_id
267 hands[hand_id, 'game_type'] = game_type
268 hands[hand_id, 'dealer'] = dealer
269 hands[hand_id, 'folded'] = []
270 hands[hand_id, 'completed'] = False
271 hands[hand_id, 'payed_out'] = False
272 hands[hand_id, 'reached_dealer'] = False
273 hands[hand_id, 'active_players'] = []
274 hands[hand_id, 'current_bet'] = 0
275 hands[hand_id, 'all_in'] = []
276 return hand_id
277
278
279 def active_player_sort(players: list) -> int:
280 def sort(player):
281 return players.index(player)
282 return sort
283
284
285 @export
286 def ante_up(hand_id: str):
287 player = ctx.caller
288 game_id = hands[hand_id, 'game_id']
289 assert game_id is not None, 'This game does not exist.'
290 players = get_players_and_assert_exists(game_id)
291 assert player in players, 'You are not a part of this game.'
292 ante = games[game_id, 'ante']
293 chips = games[game_id, player]
294 assert chips is not None and chips >= ante, 'You do not have enough chips.'
295 active_players = hands[hand_id, 'active_players'] or []
296 assert player not in active_players, 'You have already paid the ante.'
297 # Pay ante
298 hands[hand_id, player, 'bet'] = ante
299 hands[hand_id, player, 'max_bet'] = chips
300 games[game_id, player] -= ante
301 # Update hand state
302 active_players.append(player)
303 active_players.sort(key=active_player_sort(players))
304 hands[hand_id, 'active_players'] = active_players
305 hands[hand_id, 'current_bet'] = ante
306 if chips == ante:
307 # All in
308 all_in = hands[hand_id, 'all_in']
309 all_in.append(player)
310 hands[hand_id, 'all_in'] = all_in
311
312
313 @export
314 def deal_cards(hand_id: str):
315 dealer = ctx.caller
316
317 active_players = hands[hand_id, 'active_players']
318
319 assert dealer == hands[hand_id, 'dealer'], 'You are not the dealer.'
320 assert len(active_players) > 1, f'Not enough active players: {len(active_players)} <= 1'
321 assert dealer in active_players, 'You are not actively part of this hand.'
322
323 game_type = hands[hand_id, 'game_type']
324
325 cards = DECK
326 random.shuffle(cards)
327
328 for i in range(len(active_players)):
329 player = active_players[i]
330 player_key = player_metadata[player, 'public_rsa_key']
331 assert player_key is not None, f'Player {player} has not setup their encryption keys.'
332
333 if game_type == ONE_CARD_POKER:
334 player_hand = cards[i: i+1]
335 else:
336 # Player's hand is actually everyone elses hand
337 player_hand = cards[0:i] + cards[i+1:len(active_players)]
338 assert len(player_hand) == len(active_players)-1, f'Something went wrong. {len(player_hand)} != {len(active_players)-1}'
339
340 player_hand_str = ",".join(player_hand)
341 salt = str(random.randint(0, MAX_RANDOM_NUMBER))
342
343 player_hand_str_with_salt = f'{player_hand_str}:{salt}'
344
345 # Encrypt players hand with their personal keys
346 player_encrypted_hand = rsa.encrypt(
347 message_str=player_hand_str_with_salt,
348 n=player_key[0],
349 e=player_key[1]
350 )
351
352 # For verification purposes
353 house_encrypted_hand = hashlib.sha3(player_hand_str_with_salt)
354
355 hands[hand_id, player, 'player_encrypted_hand'] = player_encrypted_hand
356 hands[hand_id, player, 'house_encrypted_hand'] = house_encrypted_hand
357
358 # Update hand state
359 all_in = hands[hand_id, 'all_in']
360 hands[hand_id, 'next_better'] = get_next_better(active_players, [], all_in, dealer)
361 ante = games[hands[hand_id, 'game_id'], 'ante']
362 hands[hand_id, 'pot'] = ante * len(active_players)
363
364
365 def get_next_better(players: list, folded: list, all_in: list, current_better: str) -> str:
366 if len(folded) >= len(players) - 1:
367 return None # No one needs to bet, only one player left in the hand
368 if len(players) == len(all_in):
369 return None # No one needs to bet, everyone is all in
370 non_folded_players = [p for p in players if p not in folded and p not in all_in]
371 current_index = non_folded_players.index(current_better)
372 assert current_index >= 0, 'Current better has folded, which does not make sense.'
373 return non_folded_players[(current_index + 1) % len(non_folded_players)]
374
375
376 @export
377 def bet_check_or_fold(hand_id: str, bet: float):
378 player = ctx.caller
379
380 assert hands[hand_id, player, 'player_encrypted_hand'] is not None, 'Hand does not exist'
381 assert not hands[hand_id, 'completed'], 'This hand has already completed.'
382 assert hands[hand_id, 'next_better'] == player, 'It is not your turn to bet.'
383
384 active_players = hands[hand_id, 'active_players']
385 folded = hands[hand_id, 'folded']
386
387 call_bet = hands[hand_id, 'current_bet'] or 0.0
388 player_previous_bet = hands[hand_id, player, 'bet'] or 0.0
389 dealer = hands[hand_id, 'dealer']
390
391 if dealer == player:
392 # Been around the circle once
393 hands[hand_id, 'reached_dealer'] = True
394 reached_dealer = True
395 else:
396 reached_dealer = hands[hand_id, 'reached_dealer']
397
398 all_in = hands[hand_id, 'all_in']
399 next_better = get_next_better(active_players, folded, all_in, player)
400
401 if next_better is None:
402 # No need to bet, this is the end of the hand
403 hands[hand_id, 'completed'] = True
404
405 else:
406 if bet < 0:
407 # Folding
408 folded.append(player)
409 hands[hand_id, 'folded'] = folded
410 if player in all_in:
411 all_in.remove(player)
412 hands[hand_id, 'all_in'] = all_in
413 if len(folded) == len(active_players) - 1:
414 hands[hand_id, 'completed'] = True
415 elif bet == 0:
416 # Checking
417 max_bet = hands[hand_id, player, 'max_bet']
418 if max_bet == player_previous_bet and player not in all_in:
419 all_in.append(player)
420 hands[hand_id, 'all_in'] = all_in
421 assert max_bet == player_previous_bet or player_previous_bet >= call_bet, 'Cannot check in this scenario. Current bet is above your bet and you are not all in.'
422 next_players_bet = hands[hand_id, next_better, 'bet']
423 if next_players_bet is not None and next_players_bet == call_bet and reached_dealer:
424 # Betting is over (TODO allow reraise)
425 hands[hand_id, 'completed'] = True
426 else:
427 # Betting
428 game_id = hands[hand_id, 'game_id']
429 assert games[game_id, player] >= bet, 'You do not have enough chips to make this bet'
430 current_bet = player_previous_bet + bet
431 max_bet = hands[hand_id, player, 'max_bet']
432 if max_bet == current_bet and player not in all_in:
433 all_in.append(player)
434 hands[hand_id, 'all_in'] = all_in
435 assert max_bet == current_bet or current_bet >= call_bet, 'Current bet is above your bet and you did not go all in.'
436 hands[hand_id, player, 'bet'] = current_bet
437 hands[hand_id, 'current_bet'] = current_bet
438 hands[hand_id, 'pot'] += bet
439 games[game_id, player] -= bet
440
441 hands[hand_id, 'next_better'] = next_better
442
443
444 @export
445 def verify_hand(hand_id: str, player_hand_str: str) -> str:
446 # TODO allow user to not verify onchain to hide bluffs
447
448 player = ctx.caller
449 assert hands[hand_id, 'completed'], 'This hand has not completed yet.'
450 folded = hands[hand_id, 'folded']
451 assert player not in folded, 'No need to verify your hand because you folded.'
452 active_players = hands[hand_id, 'active_players']
453 assert player in active_players, 'You are not an active player in this hand.'
454
455 # Check if player has bet enough
456 bet_should_equal = hands[hand_id, 'current_bet']
457 assert bet_should_equal is not None, 'There is no current bet.'
458
459 player_bet = hands[hand_id, player, 'bet']
460 assert player_bet is not None, 'You have not bet yet.'
461
462 assert bet_should_equal == player_bet, 'Bets have not stabilized.'
463
464 # For verification purposes
465 house_encrypted_hand = hashlib.sha3(player_hand_str)
466
467 previous_house_encrypted_hand = hands[hand_id, player, 'house_encrypted_hand']
468
469 verified = previous_house_encrypted_hand is not None and \
470 previous_house_encrypted_hand == house_encrypted_hand
471
472 if not verified:
473 # BAD ACTOR NEEDS TO BE PUNISHED
474 folded.append(player)
475 hands[hand_id, 'folded'] = folded
476
477 return 'Verification failed. Your hand has been forfeited.'
478
479 else:
480 cards = player_hand_str.split(':')[0].split(',')
481
482 game_type = hands[hand_id, 'game_type']
483
484 if game_type == ONE_CARD_POKER:
485 rank = RANKS[cards[0]]
486 hands[hand_id, player, 'rank'] = rank
487 hands[hand_id, player, 'hand'] = cards
488 else:
489 j = 0
490 for p in active_players:
491 if p != player:
492 if p not in folded:
493 card = cards[j]
494 rank = RANKS[card]
495 hands[hand_id, p, 'rank'] = rank
496 hands[hand_id, p, 'hand'] = card
497 j += 1
498
499 return 'Verification succeeded.'
500
501
502 def find_winners(ranks: dict, players: list) -> list:
503 sorted_rank_values = sorted(ranks.keys())
504 player_set = set(players)
505 for rank in sorted_rank_values:
506 players_with_rank = ranks[rank]
507 intersection = player_set.intersection(set(players_with_rank))
508 if len(intersection) > 0:
509 # Found players
510 winners = list(intersection)
511 break
512 return winners
513
514
515 def calculate_ranks(hand_id: str, players: list) -> dict:
516 ranks = {}
517 for p in players:
518 rank = hands[hand_id, p, 'rank']
519 assert rank is not None, f'Player {p} has not verified their hand yet.'
520 if rank not in ranks:
521 ranks[rank] = []
522 ranks[rank].append(p)
523 return ranks
524
525
526 @export
527 def payout_hand(hand_id: str):
528 pot = hands[hand_id, 'pot']
529 assert pot > 0, 'There is no pot to claim!'
530 assert not hands[hand_id, 'payed_out'], 'This hand has already been payed out.'
531
532 folded = hands[hand_id, 'folded']
533 all_in = hands[hand_id, 'all_in']
534 active_players = hands[hand_id, 'active_players']
535
536 remaining = [p for p in active_players if p not in folded]
537 assert len(remaining) > 0, 'There are no remaining players.'
538
539 payouts = {}
540
541 if len(remaining) == 1:
542 # Just pay out, everyone else folded
543 payouts[remaining[0]] = pot
544 else:
545 ranks = calculate_ranks(hand_id, remaining)
546 if len(all_in) > 0:
547 # Need to calculate split pots
548 all_in_map = {}
549 for player in all_in:
550 # Check all in amount
551 amount = hands[hand_id, player, 'max_bet']
552 all_in_map[player] = amount
553 pots = sorted(set(all_in_map.values()))
554 total_payed_out = 0
555 for bet in pots:
556 players_in_pot = []
557 for player in remaining:
558 if player not in all_in_map or all_in_map[player] >= bet:
559 players_in_pot.append(player)
560 pot_winners = find_winners(ranks, players_in_pot)
561 pot_payout = bet * len(players_in_pot)
562 total_payed_out += pot_payout
563 payout = pot_payout / len(pot_winners)
564 for winner in pot_winners:
565 if winner not in payouts:
566 payouts[winner] = 0
567 payouts[winner] += payout
568 remaining_to_payout = pot - total_payed_out
569 not_all_in = set(remaining).difference(set(all_in))
570 assert remaining_to_payout == 0 or len(not_all_in) > 0, 'Invalid state when calculating side pots.'
571 if remaining_to_payout > 0:
572 if len(not_all_in) == 1:
573 winners = not_all_in
574 else:
575 winners = find_winners(ranks, not_all_in)
576 payout = remaining_to_payout / len(winners)
577 for winner in winners:
578 if winner not in payouts:
579 payouts[winner] = 0
580 payouts[winner] += payout
581 else:
582 winners = find_winners(ranks, remaining)
583 payout = pot / len(winners)
584 for winner in winners:
585 payouts[winner] = payout
586
587 game_id = hands[hand_id, 'game_id']
588 for player, payout in payouts.items():
589 games[game_id, player] += payout
590
591 hands[hand_id, 'winners'] = list(payouts.keys())
592 hands[hand_id, 'payed_out'] = True
593
594
595 @export
596 def emergency_withdraw(amount: float):
597 assert ctx.caller == owner.get(), 'Only the owner can call emergency_withdraw()'
598 phi.transfer(
599 amount=amount,
600 to=ctx.caller
601 )
602
603
604 @export
605 def emergency_game_update(keys: list, value: Any):
606 assert ctx.caller == owner.get(), 'Only the owner can call emergency_withdraw()'
607 if len(keys) == 1:
608 games[keys[0]] = value
609 elif len(keys) == 2:
610 games[keys[0], keys[1]] = value
611 elif len(keys) == 3:
612 games[keys[0], keys[1], keys[2]] = value
613 elif len(keys) == 4:
614 games[keys[0], keys[1], keys[2], keys[3]] = value
615
616
617 @export
618 def emergency_hand_update(keys: list, value: Any):
619 assert ctx.caller == owner.get(), 'Only the owner can call emergency_withdraw()'
620 if len(keys) == 1:
621 hands[keys[0]] = value
622 elif len(keys) == 2:
623 hands[keys[0], keys[1]] = value
624 elif len(keys) == 3:
625 hands[keys[0], keys[1], keys[2]] = value
626 elif len(keys) == 4:
627 hands[keys[0], keys[1], keys[2], keys[3]] = value
628
629
630 @export
631 def change_ownership(new_owner: str):
632 assert ctx.caller == owner.get(), 'Only the owner can change ownership!'
633
634 owner.set(new_owner)

Byte Code

e3000000000000000000000000350000004000000073c8030000640064016c005a01640064016c025a036504640264036404640564068d045a056504640764086404640964068d045a06650764016404640a640b8d035a08650764016404640c640b8d035a09650767006404640d640b8d035a0a650767006404640e640b8d035a0b650767006404640f640b8d035a0c650d6404641064118d025a0e64125a0f64135a1064005a1164145a1264156416641764186419641a641b641c641d641e641f6420642164226423642464256426642764286429642a642b642c642d642e642f6430643164326433643464356436643764386439643a643b643c643d643e643f64406441644264436444644564466447644867345a136449644964496449644a644a644a644a644b644b644b644b644c644c644c644c644d644d644d644d644e644e644e644e644f644f644f644f64506450645064506451645164516451645264526452645264536453645364536454645464546454641464146414641464559c345a1465156a16830001006456645784005a176518651964589c026459645a84045a1a65186518645b9c02645c645d84045a1b6518651864589c02645e645f84045a1c651d640483016518651864609c0264616462840483015a1e651d640483016518651864639c0264646465840483015a1f651d640483016518652064669c0264676468840483015a21651d640483016518652064669c026469646a840483015a22651d6404830165186523646b9c02646c646d840483015a24651d64048301646e646f840083015a256518652664709c026471647284045a27651d6404830164a4652665206523651864749c0464756476840583015a28651d640483016518651864779c0264786479840483015a29651d640483016518647a9c01647b647c840483015a2a651d640483016518652b6518647d9c03647e647f840483015a2c6526652b64809c026481648284045a2d651d64048301651864839c0164846485840483015a2e651d64048301651864839c0164866487840483015a2f6526652665266518651864889c056489648a84045a30651d6404830165186520648b9c02648c648d840483015a31651d64048301651865186518648e9c03648f6490840483015a3265196526652664919c036492649384045a3365186526651964949c036495649684045a34651d64048301651864839c0164976498840483015a35651d64048301652064999c01649a649b840483015a36651d6404830165266537649c9c02649d649e840483015a38651d6404830165266537649c9c02649f64a0840483015a39651d64048301651864a19c0164a264a3840483015a3a6401530029a5e9000000004eda0e636f6e5f7068695f6c7374303031da0862616c616e636573da19636f6e5f706f6b65725f315f636172645f67616d65735f7631da0c7068695f62616c616e6365732904da10666f726569676e5f636f6e7472616374da0c666f726569676e5f6e616d65da08636f6e7472616374da046e616d65da18636f6e5f67616d6d615f7068695f70726f66696c655f7632da086d65746164617461da0f706c617965725f6d65746164617461da0567616d65732903da0d64656661756c745f76616c756572080000007209000000da0568616e6473da0d706c61796572735f67616d6573da0f706c61796572735f696e7669746573da0d6d657373616765735f68617368da056f776e6572290272080000007209000000e93200000069ffe0f505e901000000da023263da023264da023268da023273da023363da023364da023368da023373da023463da023464da023468da023473da023563da023564da023568da023573da023663da023664da023668da023673da023763da023764da023768da023773da023863da023864da023868da023873da023963da023964da023968da023973da025463da025464da025468da025473da024a63da024a64da024a68da024a73da025163da025164da025168da025173da024b63da024b64da024b68da024b73da024163da024164da024168da024173e90d000000e90c000000e90b000000e90a000000e909000000e908000000e907000000e906000000e905000000e904000000e903000000e90200000029347216000000721700000072180000007219000000721a000000721b000000721c000000721d000000721e000000721f0000007220000000722100000072220000007223000000722400000072250000007226000000722700000072280000007229000000722a000000722b000000722c000000722d000000722e000000722f0000007230000000723100000072320000007233000000723400000072350000007236000000723700000072380000007239000000723a000000723b000000723c000000723d000000723e000000723f0000007240000000724100000072420000007243000000724400000072450000007246000000724700000072480000007249000000630000000000000000000000000200000043000000731000000074006a0174026a03830101006400530029014e2904da075f5f6f776e6572da03736574da03637478da0663616c6c6572a900725a000000725a000000da00da045f5f5f5f2700000073020000000001725c0000002902da0767616d655f6964da0672657475726e630100000000000000020000000400000043000000732800000074007c006401660219007d017c0164006b097324740164027c009b0064039d03830182017c01530029044eda07706c61796572737a0547616d65207a1020646f6573206e6f742065786973742e2902da075f5f67616d6573da0e417373657274696f6e4572726f722902725d000000725f000000725a000000725a000000725b000000da1f5f5f6765745f706c61796572735f616e645f6173736572745f6578697374732b000000730600000000010c01180172620000002902da0763726561746f72725e000000630100000000000000010000000500000043000000731800000074006a0164016a027c00740374048301670283018301530029024efa013a2905da07686173686c6962da0473686133da046a6f696eda03737472da036e6f7729017263000000725a000000725a000000725b000000da105f5f6372656174655f67616d655f69643100000073020000000001726a000000630100000000000000010000000500000043000000731800000074006a0164016a027c00740374048301670283018301530029024e72640000002905726500000072660000007267000000726800000072690000002901725d000000725a000000725a000000725b000000da105f5f6372656174655f68616e645f69643500000073020000000001726b0000002902725d000000da076d657373616765630200000000000000050000000400000043000000734800000074006a017d0274027c0083017d037c027c036b06731e740364018301820174047c007c0266021900702c67007d047c046a057c01830101007c0474047c007c0266023c006400530029024e7a1f596f7520646f206e6f742062656c6f6e6720746f20746869732067616d652e29067258000000725900000072620000007261000000da0f5f5f6d657373616765735f68617368da06617070656e642905725d000000726c000000da06706c61796572725f000000da086d65737361676573725a000000725a000000725b000000da0c67616d655f6d65737361676539000000730c000000000206010801100110010a0172710000002902da0768616e645f6964726c000000630200000000000000050000000400000043000000734c00000074006a017d0274027c006401660219007d037c027c036b067322740364028301820174047c007c0266021900703067007d047c046a057c01830101007c0474047c007c0266023c006400530029034eda0e6163746976655f706c61796572737a1f596f7520646f206e6f742062656c6f6e6720746f20746869732068616e642e290672580000007259000000da075f5f68616e64737261000000726d000000726e00000029057272000000726c000000726f00000072730000007270000000725a000000725a000000725b000000da0c68616e645f6d65737361676543000000730c000000000206010c01100110010a0172750000002902725d000000da06616d6f756e74630200000000000000040000000400000043000000737c00000074006a017d027c0164016b047316740264028301820174037c0083017d037c027c036b06732e740264038301820174047c007c026602190070407405640483017c01170074047c007c0266023c0074067c0274006a07660219007c016b057368740264058301820174086a097c0174006a077c02830301006400530029064e72010000007a20416d6f756e74206d757374206265206120706f736974697665206e756d6265727a1f596f7520646f206e6f742062656c6f6e6720746f20746869732067616d652e7a03302e307a35596f752068617665206e6f7420617070726f76656420656e6f75676820666f72207468697320616d6f756e74206f66206368697073290a72580000007259000000726100000072620000007260000000da07646563696d616cda0e5f5f7068695f62616c616e636573da0474686973da03706869da0d7472616e736665725f66726f6d2904725d0000007276000000726f000000725f000000725a000000725a000000725b000000da116164645f63686970735f746f5f67616d654d00000073120000000002060110010801100112010e010c010e01727c000000630200000000000000050000000400000043000000736c00000074006a017d027c0164016b047316740264028301820174037c0083017d037c027c036b06732e740264038301820174047c007c02660219007d047c047c016b05734a74026404830182017c047c01180074047c007c0266023c0074056a067c017c0264058d0201006400530029064e72010000007a20416d6f756e74206d757374206265206120706f736974697665206e756d6265727a1f596f7520646f206e6f742062656c6f6e6720746f20746869732067616d652e7a27596f752063616e6e6f74207769746864726177206d6f7265207468616e20796f7520686176652e29027276000000da02746f290772580000007259000000726100000072620000007260000000727a000000da087472616e736665722905725d0000007276000000726f000000725f000000da1263757272656e745f636869705f636f756e74725a000000725a000000725b000000da1877697468647261775f63686970735f66726f6d5f67616d655a0000007310000000000206011001080110010c011001100172800000002902725d000000da06616363657074630200000000000000060000000400000043000000731401000074006a017d0274027c021900701067007d0374037c0083017d047c027c046b07732a740464018301820174057c04830174066b0073467404640274069b0064039d038301820174027c02640466021900705467007d057c007c036b06737a7c007c056b06737a74077c00640566021900737a74046406830182017c007c036b0672947c036a087c00830101007c0374027c023c007c0174027c027c0066023c007c0172f07c007c056b0672c27c056a087c00830101007c0574027c02640466023c007c046a097c02830101007c0474077c00640766023c00740a7c02190070e267007c0067011700740a7c023c006e207c007c056b07900172107c056a097c00830101007c0574027c02640466023c006400530029084e7a24596f752061726520616c726561647920612070617274206f6620746869732067616d652e7a054f6e6c79207a262061726520616c6c6f77656420746f20706c6179206174207468652073616d652074696d652eda086465636c696e6564da067075626c69637a27596f752068617665206e6f74206265656e20696e766974656420746f20746869732067616d652e725f000000290b72580000007259000000da115f5f706c61796572735f696e766974657372620000007261000000da036c656eda0b4d41585f504c41594552537260000000da0672656d6f7665726e000000da0f5f5f706c61796572735f67616d65732906725d0000007281000000726f000000da0e706c617965725f696e7669746573725f0000007282000000725a000000725a000000725b000000da11726573706f6e645f746f5f696e7669746566000000732e000000000206010c01080110010601160110011201120108010a0108010c01040108010a010c010a010c0118010a010a01728a000000630000000000000000030000000500000043000000733800000074006a017d0074027c001900701067007d0178187c0144005d107d02640174027c007c0266023c0071185700670074027c003c006400530029024e4629037258000000725900000072840000002903726f000000da07696e7669746573da06696e76697465725a000000725a000000725b000000da136465636c696e655f616c6c5f696e766974657381000000730a000000000206010c010a011001728d0000002902725d000000da066f74686572736302000000000000000400000004000000430000007330000000782a7c0144005d227d0274007c021900701467007d037c036a017c00830101007c0374007c023c00710657006400530029014e29027284000000726e0000002904725d000000728e000000da056f746865727289000000725a000000725a000000725b000000da165f5f73656e645f696e766974655f72657175657374738a000000730800000000010a010c010a017290000000462904da0d6f746865725f706c6179657273da04616e74657283000000725e00000063030000000000000005000000040000004300000073ce00000074006a017d037c0164016b05731674026402830182017c037c006b077326740264038301820174037c00830174046b0073427402640474049b0064059d038301820174057c0364068d017d0474067c0464076602190064006b08736c740264087c049b0064099d03830182017c03670174067c04640a66023c007c0174067c04640b66023c007c0374067c04640766023c007c0074067c04640c66023c007c0274067c04640d66023c0074077c03190070b467007c046701170074077c033c0074087c047c00830201007c045300290e4e72010000007a1a416e7465206d757374206265206e6f6e2d6e656761746976652e7a2743616c6c65722063616e277420626520696e206f746865725f706c617965727320696e7075742e7a054f6e6c79207a262061726520616c6c6f77656420746f20706c6179206174207468652073616d652074696d652e2901726300000072630000007a0547616d65207a1a2068617320616c7265616479206265656e20637265617465642e725f0000007292000000da08696e7669746565737283000000290972580000007259000000726100000072850000007286000000726a00000072600000007288000000729000000029057291000000729200000072830000007263000000725d000000725a000000725a000000725b000000da0a73746172745f67616d659100000073200000000002060110011001060116010a010a0116010e010c010c010c010c0116010a0172940000002902725d000000da0d706c617965725f746f5f61646463020000000000000006000000040000004300000073a800000074006a017d027c027c016b037316740264018301820174037c006402660219007d037c027c036b027332740264038301820174047c0083017d047c017c046b07734a740264048301820174037c006405660219007d057c017c056b07736674026406830182017c056a057c018301010074067c04830174076b00738c7402640774079b0064089d03830182017c0574037c00640566023c0074087c007c016701830201006400530029094e7a22596f752063616e6e6f742061646420796f757273656c6620746f20612067616d652e72630000007a264f6e6c79207468652067616d652063726561746f722063616e2061646420706c61796572732e7a1e506c6179657220697320616c726561647920696e207468652067616d652e72930000007a20506c617965722068617320616c7265616479206265656e20696e76697465642e7a054f6e6c79207a262061726520616c6c6f77656420746f20706c6179206174207468652073616d652074696d652e290972580000007259000000726100000072600000007262000000726e0000007285000000728600000072900000002906725d0000007295000000726f0000007263000000725f0000007293000000725a000000725a000000725b000000da126164645f706c617965725f746f5f67616d65a5000000731a0000000002060110010c011001080110010c0110010a01060116010c0172960000002901725d0000006301000000000000000a0000000500000043000000734201000074006a017d0174027c0083017d027c017c026b06731e740364018301820174047c007c01660219007d037c0364006b0873427c0364026b027342740364038301820174057c0119007d047c046a067c00830101007c0474057c013c007c026a067c01830101007c0274047c00640466023c0074047c006405660219007d057c0564006b099001723e74077c05640666021900709667007d067c017c066b069001723e74077c056407660219007d0774077c056408660219007d0874077c056409660219007d097c097c016b0272e874087c067c077c087c0183047d097c0974077c05640966023c007c066a067c01830101007c0674077c05640666023c007c017c076b069001721e7c076a067c01830101007c0774077c05640766023c007c017c086b069001723e7c086a067c01830101007c0874077c05640866023c0064005300290a4e7a19596f7520617265206e6f7420696e20746869732067616d652e72010000007a47596f75207374696c6c206861766520636869707320696e20746869732067616d652e20506c65617365207769746864726177207468656d206265666f7265206c656176696e672e725f000000da0c63757272656e745f68616e647273000000da06666f6c646564da06616c6c5f696eda0b6e6578745f626574746572290972580000007259000000726200000072610000007260000000728800000072870000007274000000da115f5f6765745f6e6578745f626574746572290a725d000000726f000000725f000000da056368697073da0c706c617965725f67616d65737272000000727300000072980000007299000000729a000000725a000000725a000000725b000000da0a6c656176655f67616d65b6000000733a00000000020601080110010c01180108010a0108010a010c010c010a0110010a010c010c010c010801060108010c010a010c010a010a010c010a010a01729e0000002903725d000000da0967616d655f74797065725e000000630200000000000000060000000400000043000000730201000074006a017d027c0174026b02731e7c0174036b02731e740464018301820174057c0083017d037c027c036b067336740464028301820174067c03830164036b04734a740464048301820174077c006405660219007d047c0464006b09727274087c046406660219007372740464078301820174097c0083017d057c0574077c00640566023c007c0074087c05640866023c007c0174087c05640966023c007c0274087c05640a66023c00670074087c05640b66023c00640c74087c05640d66023c00640c74087c05640666023c00640c74087c05640e66023c00670074087c05640f66023c00641074087c05641166023c00670074087c05641266023c007c05530029134e7a12496e76616c69642067616d6520747970652e7a20596f7520617265206e6f7420612070617274206f6620746869732067616d652e72150000007a24596f752063616e6e6f7420737461727420612068616e6420627920796f757273656c662e7297000000da0970617965645f6f75747a2d5468652070726576696f75732068616e6420686173206e6f74206265656e207061796564206f7574207965742e725d000000729f000000da066465616c6572729800000046da09636f6d706c65746564da0e726561636865645f6465616c657272730000007201000000da0b63757272656e745f6265747299000000290a72580000007259000000da0e4f4e455f434152445f504f4b4552da0b424c494e445f504f4b455272610000007262000000728500000072600000007274000000726a0000002906725d000000729f00000072a1000000725f000000da1070726576696f75735f68616e645f69647272000000725a000000725a000000725b000000da0a73746172745f68616e64d7000000732c0000000002060118010801100114010c0108010e01060108010c010c010c010c010c010c010c010c010c010c010c0172a80000002902725f000000725e0000006301000000000000000200000003000000030000007310000000870066016401640284087d017c01530029034e630100000000000000010000000200000013000000730a00000088006a007c008301530029014e2901da05696e6465782901726f0000002901725f000000725a000000725b000000da065f5f736f7274f3000000730200000000017a245f5f6163746976655f706c617965725f736f72742e3c6c6f63616c733e2e5f5f736f7274725a0000002902725f00000072aa000000725a0000002901725f000000725b000000da145f5f6163746976655f706c617965725f736f7274f1000000730400000000020c0272ab00000029017272000000630100000000000000080000000500000043000000731c01000074006a017d0174027c006401660219007d027c0264006b097322740364028301820174047c0283017d037c017c036b06733a740364038301820174057c026404660219007d0474057c027c01660219007d057c0564006b0972627c057c046b05736a740364058301820174027c00640666021900707867007d067c017c066b07738a74036407830182017c0474027c007c01640866033c007c0574027c007c01640966033c0074057c027c016602050019007c04380003003c007c066a067c01830101007c066a0774087c038301640a8d0101007c0674027c00640666023c007c0474027c00640b66023c007c057c046b029001721874027c00640c660219007d077c076a067c01830101007c0774027c00640c66023c0064005300290d4e725d0000007a19546869732067616d6520646f6573206e6f742065786973742e7a20596f7520617265206e6f7420612070617274206f6620746869732067616d652e72920000007a1d596f7520646f206e6f74206861766520656e6f7567682063686970732e72730000007a1f596f75206861766520616c726561647920706169642074686520616e74652eda03626574da076d61785f6265742901da036b657972a400000072990000002909725800000072590000007274000000726100000072620000007260000000726e000000da04736f727472ab00000029087272000000726f000000725d000000725f0000007292000000729c00000072730000007299000000725a000000725a000000725b000000da07616e74655f7570f8000000732a000000000206010c011001080110010c010c011801100110010e010e0114010a0110010c010c010a010c010a0172b000000063010000000000000010000000070000004300000073de01000074006a017d0174027c006401660219007d027c0174027c006402660219006b02732a740364038301820174047c02830164046b04734a7403640574047c0283019b0064069d03830182017c017c026b06735a740364078301820174027c006408660219007d0374057d0474066a077c048301010090017818740874047c0283018301440090015d067d057c027c0519007d0674097c066409660219007d077c0764006b0973b67403640a7c069b00640b9d03830182017c03740a6b0272d07c047c057c0564041700850219007d086e567c04640c7c05850219007c047c056404170074047c0283018502190017007d0874047c08830174047c028301640418006b02900173267403640d74047c0883019b00640e74047c028301640418009b009d0483018201640f6a0b7c0883017d09740c74066a0d640c740e830283017d0a7c099b0064107c0a9b009d037d0b740f6a107c0b7c07640c19007c076404190064118d037d0c74116a127c0b83017d0d7c0c74027c007c06641266033c007c0d74027c007c06641366033c007184570074027c006414660219007d0e74137c0267007c0e7c01830474027c00641566023c00741474027c006416660219006417660219007d0f7c0f74047c028301140074027c00641866023c006400530029194e727300000072a10000007a17596f7520617265206e6f7420746865206465616c65722e72150000007a1b4e6f7420656e6f7567682061637469766520706c61796572733a207a05203c3d20317a27596f7520617265206e6f74206163746976656c792070617274206f6620746869732068616e642e729f000000da0e7075626c69635f7273615f6b65797a07506c61796572207a2520686173206e6f7420736574757020746865697220656e6372797074696f6e206b6579732e72010000007a16536f6d657468696e672077656e742077726f6e672e207a0420213d20fa012c72640000002903da0b6d6573736167655f737472da016eda0165da15706c617965725f656e637279707465645f68616e64da14686f7573655f656e637279707465645f68616e647299000000729a000000725d0000007292000000da03706f74291572580000007259000000727400000072610000007285000000da044445434bda0672616e646f6dda0773687566666c65da0572616e6765da115f5f706c617965725f6d6574616461746172a500000072670000007268000000da0772616e64696e74da114d41585f52414e444f4d5f4e554d424552da03727361da07656e637279707472650000007266000000729b00000072600000002910727200000072a10000007273000000729f000000da056361726473da0169726f000000da0a706c617965725f6b6579da0b706c617965725f68616e64da0f706c617965725f68616e645f737472da0473616c74da19706c617965725f68616e645f7374725f776974685f73616c7472b600000072b700000072990000007292000000725a000000725a000000725b000000da0a6465616c5f636172647311010000733e000000000206010c01180106011a0110010c0104010a01160108010c0118010801120220010c012a010a0110010e01040114010a020e0112010c0106011001140172c90000002905725f00000072980000007299000000da0e63757272656e745f626574746572725e000000630400000000000000060000000400000003000000736e00000074008801830174007c008301640118006b0572186400530074007c0083017400880083016b02722c640053008700870166026402640384087c00440083017d047c046a017c0383017d057c0564046b05735a74026405830182017c047c056401170074007c04830116001900530029064e7215000000630100000000000000020000000400000013000000732000000067007c005d187d017c0188016b0772047c0188006b0772047c01910271045300725a000000725a0000002902da022e30da0170290272990000007298000000725a000000725b000000fa0a3c6c697374636f6d703e3c010000730400000006000c017a255f5f6765745f6e6578745f6265747465722e3c6c6f63616c733e2e3c6c697374636f6d703e72010000007a3543757272656e74206265747465722068617320666f6c6465642c20776869636820646f6573206e6f74206d616b652073656e73652e2903728500000072a900000072610000002906725f0000007298000000729900000072ca000000da126e6f6e5f666f6c6465645f706c6179657273da0d63757272656e745f696e646578725a000000290272990000007298000000725b000000729b0000003601000073100000000002140104011001040114020a011001729b0000002902727200000072ac0000006302000000000000000f000000050000004300000073c202000074006a017d0274027c007c0264016603190064006b097320740364028301820174027c006403660219000c007336740364048301820174027c006405660219007c026b02734e740364068301820174027c006407660219007d0374027c006408660219007d0474027c0064096602190070787404640a83017d0574027c007c02640b66031900708e7404640a83017d0674027c00640c660219007d077c077c026b0272b6640d74027c00640e66023c00640d7d086e0c74027c00640e660219007d0874027c00640f660219007d0974057c037c047c097c0283047d0a7c0a64006b0872f4640d74027c00640366023c0090016ebe7c0164106b009001725a7c046a067c02830101007c0474027c00640866023c007c027c096b06900172347c096a077c02830101007c0974027c00640f66023c0074087c04830174087c038301641118006b02900272b2640d74027c00640366023c0090016e587c0164106b02900172ee74027c007c026412660319007d0b7c0b7c066b029001729c7c027c096b079001729c7c096a067c02830101007c0974027c00640f66023c007c0b7c066b02900173b87c067c056b05900173b8740364138301820174027c007c0a640b660319007d0c7c0c64006b09900272b27c0c7c056b02900272b27c08900272b2640d74027c00640366023c006ec474027c006414660219007d0d74097c0d7c02660219007c016b059002731474036415830182017c067c0117007d0e74027c007c026412660319007d0b7c0b7c0e6b02900272547c027c096b07900272547c096a067c02830101007c0974027c00640f66023c007c0b7c0e6b02900273707c0e7c056b059002737074036416830182017c0e74027c007c02640b66033c007c0e74027c00640966023c0074027c0064176602050019007c01370003003c0074097c0d7c026602050019007c01380003003c007c0a74027c00640566023c006400530029184e72b60000007a1348616e6420646f6573206e6f7420657869737472a20000007a20546869732068616e642068617320616c726561647920636f6d706c657465642e729a0000007a1b4974206973206e6f7420796f7572207475726e20746f206265742e7273000000729800000072a40000007a03302e3072ac00000072a10000005472a300000072990000007201000000721500000072ad0000007a5443616e6e6f7420636865636b20696e2074686973207363656e6172696f2e2043757272656e74206265742069732061626f766520796f75722062657420616e6420796f7520617265206e6f7420616c6c20696e2e725d0000007a2d596f7520646f206e6f74206861766520656e6f75676820636869707320746f206d616b652074686973206265747a3843757272656e74206265742069732061626f766520796f75722062657420616e6420796f7520646964206e6f7420676f20616c6c20696e2e72b8000000290a72580000007259000000727400000072610000007277000000729b000000726e000000728700000072850000007260000000290f727200000072ac000000726f00000072730000007298000000da0863616c6c5f626574da13706c617965725f70726576696f75735f62657472a100000072a30000007299000000729a00000072ad000000da106e6578745f706c61796572735f626574725d00000072a4000000725a000000725a000000725b000000da116265745f636865636b5f6f725f666f6c64430100007368000000000206010c010e01100106010a010e010c010c01140116010c0108010c0106020c010c010e01080110010a010a010c010a010a010c01160110010a010e0114010a010c011c010e01140106010e020c010a01100108010e0114010a010c011c010e010c011401140172d30000002903727200000072c6000000725e000000630200000000000000100000000600000043000000739a01000074006a017d0274027c00640166021900731a740364028301820174027c006403660219007d037c027c036b077336740364048301820174027c006405660219007d047c027c046b067352740364068301820174027c006407660219007d057c0564006b09736e740364088301820174027c007c026409660319007d067c0664006b09738c7403640a830182017c057c066b02739c7403640b8301820174046a057c0183017d0774027c007c02640c660319007d087c0864006b096fc27c087c076b027d097c0973e27c036a067c02830101007c0374027c00640366023c00640d53007c016a07640e8301640f19006a07641083017d0a74027c006411660219007d0b7c0b74086b029001723674097c0a640f190019007d0c7c0c74027c007c02641266033c007c0a74027c007c02641366033c006e5c640f7d0d78567c0444005d4e7d0e7c0e7c026b03900172407c0e7c036b07900172847c0a7c0d19007d0f74097c0f19007d0c7c0c74027c007c0e641266033c007c0f74027c007c0e641366033c007c0d641437007d0d900171405700641553006400530029164e72a20000007a20546869732068616e6420686173206e6f7420636f6d706c65746564207965742e72980000007a2f4e6f206e65656420746f2076657269667920796f75722068616e64206265636175736520796f7520666f6c6465642e72730000007a2a596f7520617265206e6f7420616e2061637469766520706c6179657220696e20746869732068616e642e72a40000007a185468657265206973206e6f2063757272656e74206265742e72ac0000007a15596f752068617665206e6f7420626574207965742e7a19426574732068617665206e6f742073746162696c697a65642e72b70000007a32566572696669636174696f6e206661696c65642e20596f75722068616e6420686173206265656e20666f726665697465642e7264000000720100000072b2000000729f000000da0472616e6bda0468616e6472150000007a17566572696669636174696f6e207375636365656465642e290a725800000072590000007274000000726100000072650000007266000000726e000000da0573706c697472a5000000da0552414e4b532910727200000072c6000000726f00000072980000007273000000da106265745f73686f756c645f657175616cda0a706c617965725f62657472b7000000da1d70726576696f75735f686f7573655f656e637279707465645f68616e64da08766572696669656472c2000000729f00000072d4000000da016a72cc000000da0463617264725a000000725a000000725b000000da0b7665726966795f68616e647d01000073480000000002060114010c0110010c0110010c0110010e01100110010a01060108010801080104010a010c01040214010c010a010c010e01100204010a010a010a01080108010e010e010e0172de0000002903da0572616e6b73725f000000725e000000630200000000000000080000000400000043000000735200000074007c006a01830083017d0274027c0183017d0378387c0244005d307d047c007c0419007d057c036a0374027c05830183017d0674047c06830164016b04721a74057c0683017d075000711a57007c07530029024e72010000002906da06736f72746564da046b6579737257000000da0c696e74657273656374696f6e7285000000da046c697374290872df000000725f000000da12736f727465645f72616e6b5f76616c756573da0a706c617965725f73657472d4000000da11706c61796572735f776974685f72616e6b72e2000000da0777696e6e657273725a000000725a000000725b000000da0e5f5f66696e645f77696e6e657273a7010000731200000000010c0108010a0108010e010c010801060172e800000029037272000000725f000000725e000000630200000000000000050000000500000043000000735a00000069007d0278507c0144005d487d0374007c007c036401660319007d047c0464006b097334740164027c039b0064039d03830182017c047c026b07724467007c027c043c007c027c0419006a027c0383010100710a57007c02530029044e72d40000007a07506c61796572207a2120686173206e6f742076657269666965642074686569722068616e64207965742e290372740000007261000000726e00000029057272000000725f00000072df00000072cc00000072d4000000725a000000725a000000725b000000da115f5f63616c63756c6174655f72616e6b73b30100007310000000000104010a010e01180108010801120172e900000063010000000000000016000000070000000300000073bc02000074007c006401660219007d017c0164026b04731c740164038301820174007c006404660219000c007332740164058301820174007c00640666021900890074007c006407660219007d0274007c006408660219007d03870066016409640a84087c03440083017d0474027c04830164026b04737c7401640b8301820169007d0574027c048301640c6b02729c7c017c057c04640219003c0090016ec474037c007c0483027d0674027c02830164026b049002723269007d0778227c0244005d1a7d0874007c007c08640d660319007d097c097c077c083c0071be5700740474057c076a068300830183017d0a64027d0b789e7c0a44005d967d0c67007d0d788c7c0444005d847d087c087c076b07900173207c077c0819007c0c6b05900172047c0d6a077c088301010074087c067c0d83027d0e7c0c74027c0d830114007d0f7c0b7c0f37007d0b7c0f74027c0e83011b007d1078307c0e44005d287d117c117c056b079001727064027c057c113c007c057c11050019007c10370003003c009001715a570090017104570071f657007c017c0b18007d1274057c0483016a0974057c02830183017d137c1264026b02900173ca74027c13830164026b04900173ca7401640e830182017c1264026b049002726074027c138301640c6b02900172e87c137d146e0a74087c067c1383027d147c1274027c1483011b007d1078607c1444005d287d117c117c056b079002721a64027c057c113c007c057c11050019007c10370003003c009002710457006e2e74087c067c0483027d147c0174027c1483011b007d1078167c1444005d0e7d117c107c057c113c009002714e570074007c00640f660219007d15782a7c056a0a830044005d1e5c027d087d10740b7c157c086602050019007c10370003003c00900271765700740c7c056a0d8300830174007c00641066023c00641174007c00640466023c006400530029124e72b800000072010000007a195468657265206973206e6f20706f7420746f20636c61696d2172a00000007a25546869732068616e642068617320616c7265616479206265656e207061796564206f75742e729800000072990000007273000000630100000000000000020000000400000013000000731800000067007c005d107d017c0188006b0772047c01910271045300725a000000725a000000290272cb00000072cc00000029017298000000725a000000725b00000072cd000000c7010000730200000006007a1f7061796f75745f68616e642e3c6c6f63616c733e2e3c6c697374636f6d703e7a1f546865726520617265206e6f2072656d61696e696e6720706c61796572732e721500000072ad0000007a29496e76616c6964207374617465207768656e2063616c63756c6174696e67207369646520706f74732e725d00000072e700000054290e72740000007261000000728500000072e900000072e00000007257000000da0676616c756573726e00000072e8000000da0a646966666572656e6365da056974656d73726000000072e300000072e10000002916727200000072b800000072990000007273000000da0972656d61696e696e67da077061796f75747372df000000da0a616c6c5f696e5f6d6170726f0000007276000000da04706f7473da0f746f74616c5f70617965645f6f757472ac000000da0e706c61796572735f696e5f706f74da0b706f745f77696e6e657273da0a706f745f7061796f7574da067061796f7574da0677696e6e6572da1372656d61696e696e675f746f5f7061796f7574da0a6e6f745f616c6c5f696e72e7000000725d000000725a00000029017298000000725b000000da0b7061796f75745f68616e64be010000736e00000000020c011001100106010c010c010c011201140104010c0110020a010e0104010a010e010c01100104010a0104010a0118010a010a010c0108010c010a010a010801200108011201100110010a010e0106020a010c010a010a01080118020a010c010a010e010c0112011a01140172f900000029017276000000630100000000000000010000000400000043000000732a00000074006a0174026a0383006b027316740464018301820174056a067c0074006a0164028d0201006400530029034e7a2c4f6e6c7920746865206f776e65722063616e2063616c6c20656d657267656e63795f7769746864726177282929027276000000727d0000002907725800000072590000007256000000da036765747261000000727a000000727e00000029017276000000725a000000725a000000725b000000da12656d657267656e63795f7769746864726177fc010000730600000000021001060172fb000000290272e1000000da0576616c756563020000000000000002000000070000004300000073aa00000074006a0174026a0383006b027316740464018301820174057c00830164026b0272307c0174067c00640319003c006e7674057c00830164046b0272527c0174067c00640319007c006402190066023c006e5474057c00830164056b02727a7c0174067c00640319007c00640219007c006404190066033c006e2c74057c00830164066b0272a67c0174067c00640319007c00640219007c00640419007c006405190066043c006400530029074e7a2c4f6e6c7920746865206f776e65722063616e2063616c6c20656d657267656e63795f7769746864726177282972150000007201000000725500000072540000007253000000290772580000007259000000725600000072fa000000726100000072850000007260000000290272e100000072fc000000725a000000725a000000725b000000da15656d657267656e63795f67616d655f7570646174650302000073140000000002100106010c010e010c0116010c011c010c0172fd00000063020000000000000002000000070000004300000073aa00000074006a0174026a0383006b027316740464018301820174057c00830164026b0272307c0174067c00640319003c006e7674057c00830164046b0272527c0174067c00640319007c006402190066023c006e5474057c00830164056b02727a7c0174067c00640319007c00640219007c006404190066033c006e2c74057c00830164066b0272a67c0174067c00640319007c00640219007c00640419007c006405190066043c006400530029074e7a2c4f6e6c7920746865206f776e65722063616e2063616c6c20656d657267656e63795f7769746864726177282972150000007201000000725500000072540000007253000000290772580000007259000000725600000072fa000000726100000072850000007274000000290272e100000072fc000000725a000000725a000000725b000000da15656d657267656e63795f68616e645f7570646174651102000073140000000002100106010c010e010c0116010c011c010c0172fe0000002901da096e65775f6f776e6572630100000000000000010000000200000043000000732400000074006a0174026a0383006b027316740464018301820174026a057c00830101006400530029024e7a244f6e6c7920746865206f776e65722063616e206368616e6765206f776e65727368697021290672580000007259000000725600000072fa00000072610000007257000000290172ff000000725a000000725a000000725b000000da106368616e67655f6f776e6572736869701f0200007304000000000216017200010000290146293bda12636f6e5f7273615f656e6372797074696f6e72c00000007202000000727a000000da0b466f726569676e48617368727800000072bd000000da04486173687260000000727400000072880000007284000000726d000000da085661726961626c657256000000728600000072bf00000072a500000072a600000072b900000072d700000072ba000000da0473656564725c0000007268000000da04646963747262000000726a000000726b000000da085f5f6578706f727472710000007275000000da05666c6f6174727c0000007280000000da04626f6f6c728a000000728d00000072e3000000729000000072940000007296000000729e000000da03696e7472a800000072ab00000072b000000072c9000000729b00000072d300000072de00000072e800000072e900000072f900000072fb000000da03416e7972fd00000072fe0000007200010000725a000000725a000000725a000000725b000000da083c6d6f64756c653e0100000073a400000008010801040104010801040104010801060108010601080104010a0104010a0104010a010c01040104010401040116011801180118010e010c010e01100110011001100114010803080410061004100406011209060112090601120c0601120b0601121a1009100706011813060112100601102006011419100706011018060110240601100c0601123906011429120c120b0601103d060110060601120d0601120d0601