Contract con_rocketswap_official_v1_1


Contract Code

1 import currency
2 I = importlib
3 token_interface = [I.Func('transfer', args=('amount', 'to')), I.Func(
4 'approve', args=('amount', 'to')), I.Func('transfer_from', args=(
5 'amount', 'to', 'main_account'))]
6 pairs = Hash(contract='con_rocketswap_official_v1_1', name='pairs')
7 prices = Hash(default_value=0, contract='con_rocketswap_official_v1_1',
8 name='prices')
9 lp_points = Hash(default_value=0, contract='con_rocketswap_official_v1_1',
10 name='lp_points')
11 reserves = Hash(default_value=[0, 0], contract=
12 'con_rocketswap_official_v1_1', name='reserves')
13 staked_amount = Hash(default_value=0, contract=
14 'con_rocketswap_official_v1_1', name='staked_amount')
15 discount = Hash(default_value=1, contract='con_rocketswap_official_v1_1',
16 name='discount')
17 state = Hash(contract='con_rocketswap_official_v1_1', name='state')
18
19
20 def ():
21 state['FEE_PERCENTAGE'] = decimal('0.5') / 100
22 state['TOKEN_CONTRACT'] = 'con_rswp_lst001'
23 state['TOKEN_DISCOUNT'] = decimal('0.75')
24 state['BURN_PERCENTAGE'] = decimal('0.8')
25 state['BURN_ADDRESS'] = 'burn'
26 state['LOG_ACCURACY'] = decimal('1000000000.0')
27 state['MULTIPLIER'] = decimal('0.07')
28 state['DISCOUNT_FLOOR'] = decimal('0.505')
29 state['OWNER'] = ctx.caller
30
31
32 @export('con_rocketswap_official_v1_1')
33 def create_market(contract: str, currency_amount: float=0, token_amount:
34 float=0):
35 assert pairs[contract] is None, 'Market already exists!'
36 assert currency_amount > 0 and token_amount > 0, 'Must provide currency amount and token amount!'
37 token = I.import_module(contract)
38 assert I.enforce_interface(token, token_interface
39 ), 'Invalid token interface!'
40 currency.transfer_from(amount=currency_amount, to=ctx.this,
41 main_account=ctx.caller)
42 token.transfer_from(amount=token_amount, to=ctx.this, main_account=ctx.
43 caller)
44 prices[contract] = currency_amount / token_amount
45 pairs[contract] = True
46 lp_points[contract, ctx.caller] = 100
47 lp_points[contract] = 100
48 reserves[contract] = [currency_amount, token_amount]
49 return True
50
51
52 @export('con_rocketswap_official_v1_1')
53 def liquidity_balance_of(contract: str, account: str):
54 return lp_points[contract, account]
55
56
57 @export('con_rocketswap_official_v1_1')
58 def add_liquidity(contract: str, currency_amount: float=0):
59 assert pairs[contract] is True, 'Market does not exist!'
60 assert currency_amount > 0
61 token = I.import_module(contract)
62 assert I.enforce_interface(token, token_interface
63 ), 'Invalid token interface!'
64 token_amount = currency_amount / prices[contract]
65 currency.transfer_from(amount=currency_amount, to=ctx.this,
66 main_account=ctx.caller)
67 token.transfer_from(amount=token_amount, to=ctx.this, main_account=ctx.
68 caller)
69 total_lp_points = lp_points[contract]
70 currency_reserve, token_reserve = reserves[contract]
71 points_per_currency = total_lp_points / currency_reserve
72 lp_to_mint = points_per_currency * currency_amount
73 lp_points[contract, ctx.caller] += lp_to_mint
74 lp_points[contract] += lp_to_mint
75 reserves[contract] = [currency_reserve + currency_amount,
76 token_reserve + token_amount]
77 return lp_to_mint
78
79
80 @export('con_rocketswap_official_v1_1')
81 def remove_liquidity(contract: str, amount: float=0):
82 assert pairs[contract] is True, 'Market does not exist!'
83 assert amount > 0, 'Must be a positive LP point amount!'
84 assert lp_points[contract, ctx.caller
85 ] >= amount, 'Not enough LP points to remove!'
86 token = I.import_module(contract)
87 assert I.enforce_interface(token, token_interface
88 ), 'Invalid token interface!'
89 lp_percentage = amount / lp_points[contract]
90 currency_reserve, token_reserve = reserves[contract]
91 currency_amount = currency_reserve * lp_percentage
92 token_amount = token_reserve * lp_percentage
93 currency.transfer(to=ctx.caller, amount=currency_amount)
94 token.transfer(to=ctx.caller, amount=token_amount)
95 lp_points[contract, ctx.caller] -= amount
96 lp_points[contract] -= amount
97 assert lp_points[contract] > 1, 'Not enough remaining liquidity!'
98 new_currency_reserve = currency_reserve - currency_amount
99 new_token_reserve = token_reserve - token_amount
100 assert new_currency_reserve > 0 and new_token_reserve > 0, 'Not enough remaining liquidity!'
101 reserves[contract] = [new_currency_reserve, new_token_reserve]
102 return currency_amount, token_amount
103
104
105 @export('con_rocketswap_official_v1_1')
106 def transfer_liquidity(contract: str, to: str, amount: float):
107 assert amount > 0, 'Must be a positive LP point amount!'
108 assert lp_points[contract, ctx.caller
109 ] >= amount, 'Not enough LP points to transfer!'
110 lp_points[contract, ctx.caller] -= amount
111 lp_points[contract, to] += amount
112
113
114 @export('con_rocketswap_official_v1_1')
115 def approve_liquidity(contract: str, to: str, amount: float):
116 assert amount > 0, 'Cannot send negative balances!'
117 lp_points[contract, ctx.caller, to] += amount
118
119
120 @export('con_rocketswap_official_v1_1')
121 def transfer_liquidity_from(contract: str, to: str, main_account: str,
122 amount: float):
123 assert amount > 0, 'Cannot send negative balances!'
124 assert lp_points[contract, main_account, ctx.caller
125 ] >= amount, 'Not enough coins approved to send! You have {} and are trying to spend {}'.format(
126 lp_points[main_account, ctx.caller], amount)
127 assert lp_points[contract, main_account
128 ] >= amount, 'Not enough coins to send!'
129 lp_points[contract, main_account, ctx.caller] -= amount
130 lp_points[contract, main_account] -= amount
131 lp_points[contract, to] += amount
132
133
134 @export('con_rocketswap_official_v1_1')
135 def buy(contract: str, currency_amount: float, minimum_received: float=0,
136 token_fees: bool=False):
137 assert pairs[contract] is True, 'Market does not exist!'
138 assert currency_amount > 0, 'Must provide currency amount!'
139 token = I.import_module(contract)
140 amm_token = I.import_module(state['TOKEN_CONTRACT'])
141 assert I.enforce_interface(token, token_interface
142 ), 'Invalid token interface!'
143 if contract == state['TOKEN_CONTRACT']:
144 currency.transfer_from(amount=currency_amount, to=ctx.this,
145 main_account=ctx.caller)
146 tokens_purchased = internal_buy(contract=state['TOKEN_CONTRACT'
147 ], currency_amount=currency_amount)
148 token.transfer(amount=tokens_purchased, to=ctx.caller)
149 return tokens_purchased
150 currency_reserve, token_reserve = reserves[contract]
151 k = currency_reserve * token_reserve
152 new_currency_reserve = currency_reserve + currency_amount
153 new_token_reserve = k / new_currency_reserve
154 tokens_purchased = token_reserve - new_token_reserve
155 fee_percent = state['FEE_PERCENTAGE'] * discount[ctx.caller]
156 fee = tokens_purchased * fee_percent
157 if token_fees is True:
158 fee = fee * state['TOKEN_DISCOUNT']
159 rswp_k = currency_reserve * token_reserve
160 rswp_new_token_reserve = token_reserve + fee
161 rswp_new_currency_reserve = rswp_k / rswp_new_token_reserve
162 rswp_currency_purchased = currency_reserve - rswp_new_currency_reserve
163 rswp_currency_purchased += rswp_currency_purchased * fee_percent
164 rswp_currency_reserve_2, rswp_token_reserve_2 = reserves[state[
165 'TOKEN_CONTRACT']]
166 rswp_k_2 = rswp_currency_reserve_2 * rswp_token_reserve_2
167 rswp_new_currency_reserve_2 = (rswp_currency_reserve_2 +
168 rswp_currency_purchased)
169 rswp_new_currency_reserve_2 += rswp_currency_purchased * fee_percent
170 rswp_new_token_reserve_2 = rswp_k_2 / rswp_new_currency_reserve_2
171 sell_amount = rswp_token_reserve_2 - rswp_new_token_reserve_2
172 sell_amount_with_fee = sell_amount * state['BURN_PERCENTAGE']
173 amm_token.transfer_from(amount=sell_amount, to=ctx.this,
174 main_account=ctx.caller)
175 currency_received = internal_sell(contract=state[
176 'TOKEN_CONTRACT'], token_amount=sell_amount_with_fee)
177 amm_token.transfer(amount=sell_amount - sell_amount_with_fee, to=
178 state['BURN_ADDRESS'])
179 token_received = internal_buy(contract=contract, currency_amount=
180 currency_received)
181 new_currency_reserve += reserves[contract][0] - currency_reserve
182 new_token_reserve += reserves[contract][1] - token_reserve
183 new_token_reserve = new_token_reserve + token_received
184 else:
185 tokens_purchased = tokens_purchased - fee
186 burn_amount = internal_buy(contract=state['TOKEN_CONTRACT'],
187 currency_amount=internal_sell(contract=contract, token_amount
188 =fee - fee * state['BURN_PERCENTAGE']))
189 new_currency_reserve += reserves[contract][0] - currency_reserve
190 new_token_reserve += reserves[contract][1] - token_reserve
191 new_token_reserve = new_token_reserve + fee * state['BURN_PERCENTAGE'
192 ]
193 amm_token.transfer(amount=burn_amount, to=state['BURN_ADDRESS'])
194 if minimum_received != None:
195 assert tokens_purchased >= minimum_received, 'Only {} tokens can be purchased, which is less than your minimum, which is {} tokens.'.format(
196 tokens_purchased, minimum_received)
197 assert tokens_purchased > 0, 'Token reserve error!'
198 currency.transfer_from(amount=currency_amount, to=ctx.this,
199 main_account=ctx.caller)
200 token.transfer(amount=tokens_purchased, to=ctx.caller)
201 reserves[contract] = [new_currency_reserve, new_token_reserve]
202 prices[contract] = new_currency_reserve / new_token_reserve
203 return tokens_purchased
204
205
206 @export('con_rocketswap_official_v1_1')
207 def sell(contract: str, token_amount: float, minimum_received: float=0,
208 token_fees: bool=False):
209 assert pairs[contract] is True, 'Market does not exist!'
210 assert token_amount > 0, 'Must provide currency amount and token amount!'
211 token = I.import_module(contract)
212 amm_token = I.import_module(state['TOKEN_CONTRACT'])
213 assert I.enforce_interface(token, token_interface
214 ), 'Invalid token interface!'
215 if contract == state['TOKEN_CONTRACT']:
216 token.transfer_from(amount=token_amount, to=ctx.this, main_account=
217 ctx.caller)
218 currency_purchased = internal_sell(contract=state[
219 'TOKEN_CONTRACT'], token_amount=token_amount)
220 currency.transfer(amount=currency_purchased, to=ctx.caller)
221 return currency_purchased
222 currency_reserve, token_reserve = reserves[contract]
223 k = currency_reserve * token_reserve
224 new_token_reserve = token_reserve + token_amount
225 new_currency_reserve = k / new_token_reserve
226 currency_purchased = currency_reserve - new_currency_reserve
227 fee_percent = state['FEE_PERCENTAGE'] * discount[ctx.caller]
228 fee = currency_purchased * fee_percent
229 if token_fees is True:
230 fee = fee * state['TOKEN_DISCOUNT']
231 rswp_currency_reserve, rswp_token_reserve = reserves[state[
232 'TOKEN_CONTRACT']]
233 rswp_k = rswp_currency_reserve * rswp_token_reserve
234 rswp_new_currency_reserve = rswp_currency_reserve + fee
235 rswp_new_currency_reserve += fee * fee_percent
236 rswp_new_token_reserve = rswp_k / rswp_new_currency_reserve
237 sell_amount = rswp_token_reserve - rswp_new_token_reserve
238 sell_amount_with_fee = sell_amount * state['BURN_PERCENTAGE']
239 amm_token.transfer_from(amount=sell_amount, to=ctx.this,
240 main_account=ctx.caller)
241 currency_received = internal_sell(contract=state[
242 'TOKEN_CONTRACT'], token_amount=sell_amount_with_fee)
243 amm_token.transfer(amount=sell_amount - sell_amount_with_fee, to=
244 state['BURN_ADDRESS'])
245 new_currency_reserve = new_currency_reserve + currency_received
246 else:
247 currency_purchased = currency_purchased - fee
248 burn_amount = fee - fee * state['BURN_PERCENTAGE']
249 new_currency_reserve = new_currency_reserve + fee * state[
250 'BURN_PERCENTAGE']
251 token_received = internal_buy(contract=state['TOKEN_CONTRACT'],
252 currency_amount=burn_amount)
253 amm_token.transfer(amount=token_received, to=state['BURN_ADDRESS'])
254 if minimum_received != None:
255 assert currency_purchased >= minimum_received, 'Only {} TAU can be purchased, which is less than your minimum, which is {} TAU.'.format(
256 currency_purchased, minimum_received)
257 assert currency_purchased > 0, 'Token reserve error!'
258 token.transfer_from(amount=token_amount, to=ctx.this, main_account=ctx.
259 caller)
260 currency.transfer(amount=currency_purchased, to=ctx.caller)
261 reserves[contract] = [new_currency_reserve, new_token_reserve]
262 prices[contract] = new_currency_reserve / new_token_reserve
263 return currency_purchased
264
265
266 @export('con_rocketswap_official_v1_1')
267 def stake(amount: float, token_contract: str=None):
268 assert amount >= 0, 'Must be a positive stake amount!'
269 if token_contract == None:
270 token_contract = state['TOKEN_CONTRACT']
271 amm_token = I.import_module(token_contract)
272 current_balance = staked_amount[ctx.caller, token_contract]
273 if amount < current_balance:
274 amm_token.transfer(current_balance - amount, ctx.caller)
275 staked_amount[ctx.caller, token_contract] = amount
276 discount_amount = state['LOG_ACCURACY'] * (staked_amount[ctx.
277 caller, state['TOKEN_CONTRACT']] ** (1 / state[
278 'LOG_ACCURACY']) - 1) * state['MULTIPLIER'] - state[
279 'DISCOUNT_FLOOR']
280 if discount_amount > decimal('0.99'):
281 discount_amount = decimal('0.99')
282 if discount_amount < 0:
283 discount_amount = 0
284 discount[ctx.caller] = 1 - discount_amount
285 return discount_amount
286 elif amount > current_balance:
287 amm_token.transfer_from(amount - current_balance, ctx.this, ctx.caller)
288 staked_amount[ctx.caller, token_contract] = amount
289 discount_amount = state['LOG_ACCURACY'] * (staked_amount[ctx.
290 caller, state['TOKEN_CONTRACT']] ** (1 / state[
291 'LOG_ACCURACY']) - 1) * state['MULTIPLIER'] - state[
292 'DISCOUNT_FLOOR']
293 if discount_amount > decimal('0.99'):
294 discount_amount = decimal('0.99')
295 if discount_amount < 0:
296 discount_amount = 0
297 discount[ctx.caller] = 1 - discount_amount
298 return discount_amount
299
300
301 @export('con_rocketswap_official_v1_1')
302 def change_state(key: str, new_value: str, convert_to_decimal: bool=False):
303 assert state['OWNER'] == ctx.caller, 'Not the owner!'
304 if convert_to_decimal:
305 new_value = decimal(new_value)
306 state[key] = new_value
307 return new_value
308
309
310 @export('con_rocketswap_official_v1_1')
311 def change_state_float(key: str, new_value: float, convert_to_int: bool=False):
312 assert state['OWNER'] == ctx.caller, 'Not the owner!'
313 if convert_to_int:
314 new_value = int(new_value)
315 state[key] = new_value
316 return new_value
317
318
319 @export('con_rocketswap_official_v1_1')
320 def sync_reserves(contract: str):
321 assert state['SYNC_ENABLED'] is True, 'Sync is not enabled!'
322 token = I.import_module(contract)
323 new_balance = token.balance_of(ctx.this)
324 assert new_balance > 0, 'Cannot be a negative balance!'
325 reserves[contract][1] = new_balance
326 return new_balance
327
328
329 def internal_buy(contract: str, currency_amount: float):
330 assert pairs[contract] is True, 'RSWP Market does not exist!'
331 if currency_amount <= 0:
332 return 0
333 token = I.import_module(contract)
334 assert I.enforce_interface(token, token_interface
335 ), 'Invalid token interface!'
336 currency_reserve, token_reserve = reserves[contract]
337 k = currency_reserve * token_reserve
338 new_currency_reserve = currency_reserve + currency_amount
339 new_token_reserve = k / new_currency_reserve
340 tokens_purchased = token_reserve - new_token_reserve
341 fee = tokens_purchased * state['FEE_PERCENTAGE']
342 tokens_purchased -= fee
343 new_token_reserve += fee
344 assert tokens_purchased > 0, 'Token reserve error!'
345 reserves[contract] = [new_currency_reserve, new_token_reserve]
346 prices[contract] = new_currency_reserve / new_token_reserve
347 return tokens_purchased
348
349
350 def internal_sell(contract: str, token_amount: float):
351 assert pairs[contract] is True, 'RSWP Market does not exist!'
352 if token_amount <= 0:
353 return 0
354 token = I.import_module(contract)
355 assert I.enforce_interface(token, token_interface
356 ), 'Invalid token interface!'
357 currency_reserve, token_reserve = reserves[contract]
358 k = currency_reserve * token_reserve
359 new_token_reserve = token_reserve + token_amount
360 new_currency_reserve = k / new_token_reserve
361 currency_purchased = currency_reserve - new_currency_reserve
362 fee = currency_purchased * state['FEE_PERCENTAGE']
363 currency_purchased -= fee
364 new_currency_reserve += fee
365 assert currency_purchased > 0, 'Token reserve error!'
366 reserves[contract] = [new_currency_reserve, new_token_reserve]
367 prices[contract] = new_currency_reserve / new_token_reserve
368 return currency_purchased
369

Byte Code

e30000000000000000000000000700000040000000731e020000640064016c005a0065015a0265026a036402644264058d0265026a036406644364058d0265026a036407644464058d0267035a0465056409640a640b8d025a06650564006409640c640d8d035a07650564006409640e640d8d035a0865056400640067026409640f640d8d035a096505640064096410640d8d035a0a6505641164096412640d8d035a0b650564096413640b8d025a0c6414641584005a0d650e640983016445650f6510651064169c0364176418840583015a11650e64098301650f650f64199c02641a641b840483015a12650e640983016446650f6510641c9c02641d641e840583015a13650e640983016447650f6510641f9c0264206421840583015a14650e64098301650f650f651064229c0364236424840483015a15650e64098301650f650f651064229c0364256426840483015a16650e64098301650f650f650f651064279c0464286429840483015a17650e640983016448650f651065106518642b9c04642c642d840583015a19650e640983016449650f651065106518642e9c04642f6430840583015a1a650e64098301644a6510650f64319c0264326433840583015a1b650e64098301644b650f650f651864349c0364356436840583015a1c650e64098301644c650f6510651864379c0364386439840583015a1d650e64098301650f643a9c01643b643c840483015a1e650f6510641c9c02643d643e84045a1f650f6510643f9c026440644184045a2064015300294de9000000004eda087472616e73666572da06616d6f756e74da02746f2901da0461726773da07617070726f7665da0d7472616e736665725f66726f6dda0c6d61696e5f6163636f756e74da1c636f6e5f726f636b6574737761705f6f6666696369616c5f76315f31da0570616972732902da08636f6e7472616374da046e616d65da067072696365732903da0d64656661756c745f76616c7565720b000000720c000000da096c705f706f696e7473da087265736572766573da0d7374616b65645f616d6f756e74e901000000da08646973636f756e74da057374617465630000000000000000000000000300000043000000736a00000074006401830164021b00740164033c006404740164053c00740064068301740164073c00740064088301740164093c00640a7401640b3c007400640c83017401640d3c007400640e83017401640f3c00740064108301740164113c0074026a03740164123c006400530029134e7a03302e35e964000000da0e4645455f50455243454e54414745da0f636f6e5f727377705f6c7374303031da0e544f4b454e5f434f4e54524143547a04302e3735da0e544f4b454e5f444953434f554e547a03302e38da0f4255524e5f50455243454e54414745da046275726eda0c4255524e5f414444524553537a0c313030303030303030302e30da0c4c4f475f41434355524143597a04302e3037da0a4d554c5449504c4945527a05302e353035da0e444953434f554e545f464c4f4f52da054f574e45522904da07646563696d616cda075f5f7374617465da03637478da0663616c6c6572a90072250000007225000000da00da045f5f5f5f1400000073120000000001100108010c010c0108010c010c010c0172270000002903720b000000da0f63757272656e63795f616d6f756e74da0c746f6b656e5f616d6f756e7463030000000000000004000000050000004300000073ac00000074007c00190064006b08731474016401830182017c0164026b0472247c0264026b04732c740164038301820174026a037c0083017d0374026a047c0374058302734a740164048301820174066a077c0174086a0974086a0a64058d0301007c036a077c0274086a0974086a0a64058d0301007c017c021b00740b7c003c00640674007c003c006407740c7c0074086a0a66023c006407740c7c003c007c017c026702740d7c003c006406530029084e7a164d61726b657420616c7265616479206578697374732172010000007a2e4d7573742070726f766964652063757272656e637920616d6f756e7420616e6420746f6b656e20616d6f756e74217a18496e76616c696420746f6b656e20696e74657266616365212903720300000072040000007208000000547215000000290eda075f5f7061697273da0e417373657274696f6e4572726f72da0149da0d696d706f72745f6d6f64756c65da11656e666f7263655f696e74657266616365da0f746f6b656e5f696e74657266616365da0863757272656e637972070000007223000000da04746869737224000000da085f5f707269636573da0b5f5f6c705f706f696e7473da0a5f5f72657365727665732904720b00000072280000007229000000da05746f6b656e722500000072250000007226000000da0d6372656174655f6d61726b657420000000731c0000000003140118010a010e0106010a010a0114020c0108010e0108010c0172360000002902720b000000da076163636f756e74630200000000000000020000000300000043000000730c00000074007c007c0166021900530029014e290172330000002902720b0000007237000000722500000072250000007226000000da146c69717569646974795f62616c616e63655f6f66340000007302000000000272380000002902720b000000722800000063020000000000000009000000050000004300000073d400000074007c00190064016b08731474016402830182017c0164036b0473207401820174026a037c0083017d0274026a047c0274058302733e74016404830182017c0174067c0019001b007d0374076a087c0174096a0a74096a0b64058d0301007c026a087c0374096a0a74096a0b64058d030100740c7c0019007d04740d7c0019005c027d057d067c047c051b007d077c077c0114007d08740c7c0074096a0b6602050019007c08370003003c00740c7c00050019007c08370003003c007c057c0117007c067c0317006702740d7c003c007c08530029064e547a164d61726b657420646f6573206e6f742065786973742172010000007a18496e76616c696420746f6b656e20696e74657266616365212903720300000072040000007208000000290e722a000000722b000000722c000000722d000000722e000000722f000000723200000072300000007207000000722300000072310000007224000000723300000072340000002909720b000000722800000072350000007229000000da0f746f74616c5f6c705f706f696e7473da1063757272656e63795f72657365727665da0d746f6b656e5f72657365727665da13706f696e74735f7065725f63757272656e6379da0a6c705f746f5f6d696e74722500000072250000007226000000da0d6164645f6c6971756964697479390000007324000000000214010c010a010e0106010c010a010a01140208010c01080108011601100106010e01723e0000002902720b00000072030000006302000000000000000a0000000400000043000000731c01000074007c00190064016b08731474016402830182017c0164036b047324740164048301820174027c0074036a04660219007c016b05733e740164058301820174056a067c0083017d0274056a077c0274088302735c74016406830182017c0174027c0019001b007d0374097c0019005c027d047d057c047c0314007d067c057c0314007d07740a6a0b74036a047c0664078d0201007c026a0b74036a047c0764078d02010074027c0074036a046602050019007c01380003003c0074027c00050019007c01380003003c0074027c00190064086b0473de74016409830182017c047c0618007d087c057c0718007d097c0864036b046ffc7c0964036b049001730874016409830182017c087c09670274097c003c007c067c0766025300290a4e547a164d61726b657420646f6573206e6f742065786973742172010000007a234d757374206265206120706f736974697665204c5020706f696e7420616d6f756e74217a1f4e6f7420656e6f756768204c5020706f696e747320746f2072656d6f7665217a18496e76616c696420746f6b656e20696e746572666163652129027204000000720300000072120000007a1f4e6f7420656e6f7567682072656d61696e696e67206c697175696469747921290c722a000000722b000000723300000072230000007224000000722c000000722d000000722e000000722f000000723400000072300000007202000000290a720b00000072030000007235000000da0d6c705f70657263656e74616765723a000000723b00000072280000007229000000da146e65775f63757272656e63795f72657365727665da116e65775f746f6b656e5f72657365727665722500000072250000007226000000da1072656d6f76655f6c697175696469747950000000732a0000000002140110010c010e010a010e0106010c010c010801080110011001160110011401080108011a010c0172420000002903720b0000007204000000720300000063030000000000000003000000040000004300000073580000007c0264016b047310740064028301820174017c0074026a03660219007c026b05732a740064038301820174017c0074026a036602050019007c02380003003c0074017c007c016602050019007c02370003003c006400530029044e72010000007a234d757374206265206120706f736974697665204c5020706f696e7420616d6f756e74217a214e6f7420656e6f756768204c5020706f696e747320746f207472616e73666572212904722b0000007233000000722300000072240000002903720b00000072040000007203000000722500000072250000007226000000da127472616e736665725f6c697175696469747969000000730a000000000210010c010e0116017243000000630300000000000000030000000400000043000000732c0000007c0264016b047310740064028301820174017c0074026a037c016603050019007c02370003003c006400530029034e72010000007a1e43616e6e6f742073656e64206e656761746976652062616c616e636573212904722b0000007233000000722300000072240000002903720b00000072040000007203000000722500000072250000007226000000da11617070726f76655f6c69717569646974797200000073040000000002100172440000002904720b000000720400000072080000007203000000630400000000000000040000000500000043000000739a0000007c0364016b047310740064028301820174017c007c0274026a03660319007c036b05733e740064036a0474017c0274026a03660219007c0383028301820174017c007c02660219007c036b057356740064048301820174017c007c0274026a036603050019007c03380003003c0074017c007c026602050019007c03380003003c0074017c007c016602050019007c03370003003c006400530029054e72010000007a1e43616e6e6f742073656e64206e656761746976652062616c616e636573217a494e6f7420656e6f75676820636f696e7320617070726f76656420746f2073656e642120596f752068617665207b7d20616e642061726520747279696e6720746f207370656e64207b7d7a194e6f7420656e6f75676820636f696e7320746f2073656e64212905722b000000723300000072230000007224000000da06666f726d61742904720b000000720400000072080000007203000000722500000072250000007226000000da177472616e736665725f6c69717569646974795f66726f6d780000007312000000000310010e010c0114010a010e01180114017246000000462904720b0000007228000000da106d696e696d756d5f7265636569766564da0a746f6b656e5f666565736304000000000000001c000000080000004300000073c802000074007c00190064016b08731474016402830182017c0164036b047324740164048301820174026a037c0083017d0474026a0374046405190083017d0574026a057c0474068302735074016406830182017c007404640519006b02729474076a087c0174096a0a74096a0b64078d030100740c7404640519007c0164088d027d067c046a0d7c0674096a0b64098d0201007c065300740e7c0019005c027d077d087c077c0814007d097c077c0117007d0a7c097c0a1b007d0b7c087c0b18007d067404640a1900740f74096a0b190014007d0c7c067c0c14007d0d7c0364016b08900172dc7c0d7404640b190014007d0d7c077c0814007d0e7c087c0d17007d0f7c0e7c0f1b007d107c077c1018007d117c117c117c0c140037007d11740e74046405190019005c027d127d137c127c1314007d147c127c1117007d157c157c117c0c140037007d157c147c151b007d167c137c1618007d177c177404640c190014007d187c056a087c1774096a0a74096a0b64078d03010074107404640519007c18640d8d027d197c056a0d7c177c1818007404640e190064098d020100740c7c007c1964088d027d1a7c0a740e7c001900640319007c07180037007d0a7c0b740e7c001900640f19007c08180037007d0b7c0b7c1a17007d0b6e767c067c0d18007d06740c74046405190074107c007c0d7c0d7404640c190014001800640d8d0264088d027d1b7c0a740e7c001900640319007c07180037007d0a7c0b740e7c001900640f19007c08180037007d0b7c0b7c0d7404640c1900140017007d0b7c056a0d7c1b7404640e190064098d0201007c0264006b03900272767c067c026b0590027376740164106a117c067c028302830182017c0664036b0490027388740164118301820174076a087c0174096a0a74096a0b64078d0301007c046a0d7c0674096a0b64098d0201007c0a7c0b6702740e7c003c007c0a7c0b1b0074127c003c007c06530029124e547a164d61726b657420646f6573206e6f742065786973742172010000007a1d4d7573742070726f766964652063757272656e637920616d6f756e742172180000007a18496e76616c696420746f6b656e20696e746572666163652129037203000000720400000072080000002902720b000000722800000029027203000000720400000072160000007219000000721a0000002902720b0000007229000000721c00000072120000007a554f6e6c79207b7d20746f6b656e732063616e206265207075726368617365642c207768696368206973206c657373207468616e20796f7572206d696e696d756d2c207768696368206973207b7d20746f6b656e732e7a14546f6b656e2072657365727665206572726f72212913722a000000722b000000722c000000722d0000007222000000722e000000722f00000072300000007207000000722300000072310000007224000000da0e5f5f696e7465726e616c5f62757972020000007234000000da0a5f5f646973636f756e74da0f5f5f696e7465726e616c5f73656c6c72450000007232000000291c720b0000007228000000724700000072480000007235000000da09616d6d5f746f6b656eda10746f6b656e735f707572636861736564723a000000723b000000da016b72400000007241000000da0b6665655f70657263656e74da03666565da06727377705f6bda16727377705f6e65775f746f6b656e5f72657365727665da19727377705f6e65775f63757272656e63795f72657365727665da17727377705f63757272656e63795f707572636861736564da17727377705f63757272656e63795f726573657276655f32da14727377705f746f6b656e5f726573657276655f32da08727377705f6b5f32da1b727377705f6e65775f63757272656e63795f726573657276655f32da18727377705f6e65775f746f6b656e5f726573657276655f32da0b73656c6c5f616d6f756e74da1473656c6c5f616d6f756e745f776974685f666565da1163757272656e63795f7265636569766564da0e746f6b656e5f7265636569766564da0b6275726e5f616d6f756e74722500000072250000007226000000da036275798600000073820000000003140110010a010e010e0106010c010a010a0108010801100104010c010801080108010801120108010a010c0108010801080108010c0104010c010801020106010c01080108010c010a010a0104010c010a010c0104010801140114010a02080108010401180114011401100212010a0110010a0112010a010a0110010c010c01725f0000002904720b000000722900000072470000007248000000630400000000000000180000000500000043000000733c02000074007c00190064016b08731474016402830182017c0164036b047324740164048301820174026a037c0083017d0474026a0374046405190083017d0574026a057c0474068302735074016406830182017c007404640519006b0272947c046a077c0174086a0974086a0a64078d030100740b7404640519007c0164088d027d06740c6a0d7c0674086a0a64098d0201007c065300740e7c0019005c027d077d087c077c0814007d097c087c0117007d0a7c097c0a1b007d0b7c077c0b18007d067404640a1900740f74086a0a190014007d0c7c067c0c14007d0d7c0364016b089001727c7c0d7404640b190014007d0d740e74046405190019005c027d0e7d0f7c0e7c0f14007d107c0e7c0d17007d117c117c0d7c0c140037007d117c107c111b007d127c0f7c1218007d137c137404640c190014007d147c056a077c1374086a0974086a0a64078d030100740b7404640519007c1464088d027d157c056a0d7c137c1418007404640d190064098d0201007c0b7c1517007d0b6e4a7c067c0d18007d067c0d7c0d7404640c1900140018007d167c0b7c0d7404640c1900140017007d0b74107404640519007c16640e8d027d177c056a0d7c177404640d190064098d0201007c0264006b03900172ea7c067c026b05900173ea7401640f6a117c067c028302830182017c0664036b04900173fc74016410830182017c046a077c0174086a0974086a0a64078d030100740c6a0d7c0674086a0a64098d0201007c0b7c0a6702740e7c003c007c0b7c0a1b0074127c003c007c06530029114e547a164d61726b657420646f6573206e6f742065786973742172010000007a2e4d7573742070726f766964652063757272656e637920616d6f756e7420616e6420746f6b656e20616d6f756e742172180000007a18496e76616c696420746f6b656e20696e746572666163652129037203000000720400000072080000002902720b000000722900000029027203000000720400000072160000007219000000721a000000721c0000002902720b00000072280000007a4f4f6e6c79207b7d205441552063616e206265207075726368617365642c207768696368206973206c657373207468616e20796f7572206d696e696d756d2c207768696368206973207b7d205441552e7a14546f6b656e2072657365727665206572726f72212913722a000000722b000000722c000000722d0000007222000000722e000000722f0000007207000000722300000072310000007224000000724b000000723000000072020000007234000000724a0000007249000000724500000072320000002918720b0000007229000000724700000072480000007235000000724c000000da1263757272656e63795f707572636861736564723a000000723b000000724e00000072410000007240000000724f0000007250000000da15727377705f63757272656e63795f72657365727665da12727377705f746f6b656e5f72657365727665725100000072530000007252000000725a000000725b000000725c000000725e000000725d000000722500000072250000007226000000da0473656c6cce000000736a0000000003140110010a010e010e0106010c010a010a0104010c01100104010c010801080108010801120108010a010c0104010c01080108010c01080108010c010a010a0104010c010a010c010a020801100106010a010801080112010a0110010a011201140210010c010c01726300000029027203000000da0e746f6b656e5f636f6e7472616374630200000000000000050000000500000043000000736e0100007c0064016b05731074006402830182017c0164006b0272207401640319007d0174026a037c0183017d02740474056a067c01660219007d037c007c036b0072cc7c026a077c037c00180074056a06830201007c00740474056a067c0166023c00740164041900740474056a067401640319006602190064057401640419001b001300640518001400740164061900140074016407190018007d047c047408640883016b0472ae7408640883017d047c0464016b0072ba64017d0464057c041800740974056a063c007c0453007c007c036b049001726a7c026a0a7c007c03180074056a0b74056a06830301007c00740474056a067c0166023c00740164041900740474056a067401640319006602190064057401640419001b001300640518001400740164061900140074016407190018007d047c047408640883016b049001724a7408640883017d047c0464016b009001725864017d0464057c041800740974056a063c007c0453006400530029094e72010000007a204d757374206265206120706f736974697665207374616b6520616d6f756e74217218000000721d0000007212000000721e000000721f0000007a04302e3939290c722b0000007222000000722c000000722d000000da0f5f5f7374616b65645f616d6f756e747223000000722400000072020000007221000000724a00000072070000007231000000290572030000007264000000724c000000da0f63757272656e745f62616c616e6365da0f646973636f756e745f616d6f756e74722500000072250000007226000000da057374616b650a010000733600000000021001080108010a010e01080112010e03320108010c010801080104010e0104010a0116010e03320108010e0108010a0104010e0172680000002903da036b6579da096e65775f76616c7565da12636f6e766572745f746f5f646563696d616c630300000000000000030000000300000043000000732e00000074006401190074016a026b02731674036402830182017c02722274047c0183017d017c0174007c003c007c01530029034e72200000007a0e4e6f7420746865206f776e6572212905722200000072230000007224000000722b000000722100000029037269000000726a000000726b000000722500000072250000007226000000da0c6368616e67655f73746174652d010000730a00000000021601040108010801726c00000029037269000000726a000000da0e636f6e766572745f746f5f696e74630300000000000000030000000300000043000000732e00000074006401190074016a026b02731674036402830182017c02722274047c0183017d017c0174007c003c007c01530029034e72200000007a0e4e6f7420746865206f776e6572212905722200000072230000007224000000722b000000da03696e7429037269000000726a000000726d000000722500000072250000007226000000da126368616e67655f73746174655f666c6f617436010000730a00000000021601040108010801726f0000002901720b000000630100000000000000030000000300000043000000734a00000074006401190064026b087314740164038301820174026a037c0083017d017c016a0474056a0683017d027c0264046b04733a74016405830182017c0274077c00190064063c007c02530029074eda0c53594e435f454e41424c4544547a1453796e63206973206e6f7420656e61626c65642172010000007a1d43616e6e6f742062652061206e656761746976652062616c616e636521721200000029087222000000722b000000722c000000722d000000da0a62616c616e63655f6f667223000000723100000072340000002903720b0000007235000000da0b6e65775f62616c616e6365722500000072250000007226000000da0d73796e635f72657365727665733f010000730c000000000214010a010c0110010c0172730000006302000000000000000a000000030000004300000073b200000074007c00190064016b08731474016402830182017c0164036b0172206403530074026a037c0083017d0274026a047c0274058302733e740164048301820174067c0019005c027d037d047c037c0414007d057c037c0117007d067c057c061b007d077c047c0718007d087c0874076405190014007d097c087c0938007d087c077c0937007d077c0864036b04739674016406830182017c067c07670274067c003c007c067c071b0074087c003c007c08530029074e547a1b52535750204d61726b657420646f6573206e6f742065786973742172010000007a18496e76616c696420746f6b656e20696e746572666163652172160000007a14546f6b656e2072657365727665206572726f72212909722a000000722b000000722c000000722d000000722e000000722f000000723400000072220000007232000000290a720b00000072280000007235000000723a000000723b000000724e00000072400000007241000000724d0000007250000000722500000072250000007226000000724900000049010000732400000000011401080104010a010e0106010c0108010801080108010c010801080110010c010c0172490000002902720b00000072290000006302000000000000000a000000030000004300000073b200000074007c00190064016b08731474016402830182017c0164036b0172206403530074026a037c0083017d0274026a047c0274058302733e740164048301820174067c0019005c027d037d047c037c0414007d057c047c0117007d067c057c061b007d077c037c0718007d087c0874076405190014007d097c087c0938007d087c077c0937007d077c0864036b04739674016406830182017c077c06670274067c003c007c077c061b0074087c003c007c08530029074e547a1b52535750204d61726b657420646f6573206e6f742065786973742172010000007a18496e76616c696420746f6b656e20696e746572666163652172160000007a14546f6b656e2072657365727665206572726f72212909722a000000722b000000722c000000722d000000722e000000722f000000723400000072220000007232000000290a720b00000072290000007235000000723a000000723b000000724e0000007241000000724000000072600000007250000000722500000072250000007226000000724b0000005e010000732400000000011401080104010a010e0106010c0108010801080108010c010801080110010c010c01724b000000290272030000007204000000290272030000007204000000290372030000007204000000720800000029027201000000720100000029017201000000290172010000002902720100000046290272010000004629014e29014629014629217230000000da09696d706f72746c6962722c000000da0446756e63722f000000da0448617368722a0000007232000000723300000072340000007265000000724a00000072220000007227000000da085f5f6578706f7274da03737472da05666c6f617472360000007238000000723e0000007242000000724300000072440000007246000000da04626f6f6c725f00000072630000007268000000726c000000726f00000072730000007249000000724b0000007225000000722500000072250000007226000000da083c6d6f64756c653e0100000073620000000801040110010e010a010c01060108010601080108010a0104010a01060108010c03080c060100011612060112040601141606011418060114080601140506010601100c06010001184606010001183a060114220601160806011608060110091015