Contract con_harvest_002


Contract Code


  
1 import currency # For buy function
2
3 #NFTs are always part of a collection.
4
5 collection_name = Variable() # The name of the collection for display
6 collection_owner = Variable() # Only the owner can mint new NFTs for this collection
7 collection_nfts = Hash(default_value=0) # All NFTs of the collection
8 collection_balances = Hash(default_value=0) # All user balances of the NFTs
9 collection_balances_approvals = Hash(default_value=0) # Approval amounts of certain NFTs
10 plants = Hash(default_value=0) #store various data related to plants and growing seasons
11 metadata = Hash()
12 nicknames = Hash()
13 emergency = Hash()
14
15 random.seed()
16
17 @construct
18 def seed():
19 collection_name.set("Harvest Blueberry Plants") # Sets the name
20 collection_owner.set(ctx.caller) # Sets the owner
21 metadata['operator'] = ctx.caller
22
23 metadata['growing_season_length'] = 14
24 metadata['plant price'] = 500
25 metadata['ipfs_contract'] = 'con_harvest_gen1_ipfs'
26
27 plants['growing_season'] = False
28 plants['growing_season_start_time'] = now
29 plants['count'] = 0
30 plants['active_generation'] = 1
31 emergency['addresses'] = {
32 'ae7d14d6d9b8443f881ba6244727b69b681010e782d4fe482dbfb0b6aca02d5d' : 0,
33 '49aceeabdccdcb39f8c2c112e110ead1a5fef22c644825c1917b2df3204c433f' : 0,
34 'e8dc708028e049397b5baf9579924dde58ce5bebee5655da0b53066117572e73' : 0
35 }
36
37 nicknames = {}
38
39
40 @export
41 def change_metadata(key: str, new_value: str, convert_to_decimal: bool=False):
42 assert ctx.caller == metadata['operator'], "only operator can set metadata"
43 if convert_to_decimal:
44 new_value = decimal(new_value)
45 metadata[key] = new_value
46
47 # function to mint a new NFT
48 def mint_nft(name: str, description: str, ipfs_image_url: str, nft_metadata: dict, amount: int):
49 assert name != "", "Name cannot be empty"
50 assert collection_nfts[name] == 0, "Name already exists"
51 assert amount > 0, "You cannot transfer negative amounts"
52
53 collection_nfts[name] = {"description": description, "ipfs_image_url": ipfs_image_url, "nft_metadata": f"See collection_nfts[{name},'nft_metadata']", "amount": amount} # Adds NFT to collection with all details
54 collection_nfts[name,"nft_metadata"] = nft_metadata
55 collection_balances[ctx.caller, name] = amount # Mints the NFT
56
57 # standard transfer function
58 @export
59 def transfer(name: str, amount:int, to: str):
60 assert amount > 0, "You cannot transfer negative amounts"
61 assert name != "", "Please specify the name of the NFT you want to transfer"
62 assert collection_balances[ctx.caller, name] >= amount, "You don't have enough NFTs to send"
63
64 collection_balances[ctx.caller, name] -= amount # Removes amount from sender
65 collection_balances[to, name] += amount # Adds amount to receiver
66
67 # allows other account to spend on your behalf
68 @export
69 def approve(amount: int, name: str, to: str):
70 assert amount > 0, "Cannot approve negative amounts"
71
72 collection_balances_approvals[ctx.caller, to, name] += amount # Approves certain amount for spending by another account
73
74 # transfers on your behalf
75 @export
76 def transfer_from(name:str, amount:int, to: str, main_account: str):
77 assert amount > 0, 'Cannot send negative balances!'
78
79 assert collection_balances_approvals[main_account, to, name] >= amount, "Not enough NFTs approved to send! You have {} and are trying to spend {}"\
80 .format(collection_balances_approvals[main_account, to, name], amount)
81 assert collection_balances[main_account, name] >= amount, "Not enough NFTs to send!"
82
83 collection_balances_approvals[main_account, to, name] -= amount # Removes Approval Amount
84 collection_balances[main_account, name] -= amount # Removes amount from sender
85
86 collection_balances[to, name] += amount # Adds amount to receiver
87
88 @export
89 def start_growing_season():
90 assert collection_owner.get() == ctx.caller, "Only the owner can start a growing season."
91 grow_season = plants['growing_season']
92 assert grow_season == False, "It is already growing season."
93 growing_season_length = metadata['growing_season_length']
94 active_gen = plants['active_generation']
95 active_gen += 1
96 plants['growing_season'] = True
97 plants['growing_season_start_time'] = now
98 plants['growing_season_end_time'] = now + datetime.timedelta(days = growing_season_length + 3)
99 plants[active_gen, 'finalize_time'] = now + datetime.timedelta(days = growing_season_length + 6)
100 plants['active_generation'] = active_gen
101 plants[active_gen, 'total_berries'] = 0
102 plants[active_gen, 'sellable_berries'] = 0
103 plants[active_gen, 'total_tau'] = 0
104 plants[active_gen, 'claimable_tau'] = 0
105 plants[active_gen,'stale_claim_time'] = now + datetime.timedelta(days = growing_season_length + 30)
106
107
108 @export
109 def buy_plant(nick : str, referrer : str = False):
110 assert plants['growing_season'] == True, 'The growing season has not started, so you cannot buy a plant.'
111 assert plants['growing_season_end_time'] >= now + datetime.timedelta(days = 11), "It's too far into the growing season and you cannot buy a plant now."
112 assert not nick.isdigit(), "The plant nickname can't be an integer."
113 assert bool(collection_nfts[nick]) == False, "This nickname already exists."
114 assert nick.isalnum() == True, "Only alphanumeric characters allowed."
115 assert nick != "", "Name cannot be empty"
116 assert len(nick) >= 3, "The minimum length is 3 characters."
117 plant_generation = plants['active_generation']
118 growing_season_length = metadata['growing_season_length']
119
120 plant_data = {
121 "current_water": (random.randint(70, 90)),
122 "current_bugs" : (random.randint(5, 25)),
123 "current_photosynthesis" : 0,
124 "current_nutrients" : (random.randint(70, 90)),
125 "current_weeds" : (random.randint(5, 25)),
126 "current_toxicity" : 0,
127 "current_weather" : 1,
128 "last_interaction" : now,
129 "last_daily" : now,
130 "last_calc" : now,
131 "alive" : True,
132 "last_squash_weed" : (now + datetime.timedelta(days = -1)),
133 "last_grow_light" : (now + datetime.timedelta(days = -1)),
134 "burn_amount" : 0,
135 "plant_end_time" : (now + datetime.timedelta(days = growing_season_length))
136 }
137
138 plant_calc_data = {
139 "previous_water": plant_data["current_water"],
140 "previous_bugs" : plant_data["current_bugs"],
141 "previous_nutrients" : plant_data["current_nutrients"],
142 "previous_weeds" : plant_data["current_weeds"],
143 "total_water": 0,
144 "total_bugs" : 0,
145 "total_nutrients" : 0,
146 "total_weeds": 0
147 }
148
149 p_count = plants['count'] + 1
150 name = f"Gen_{plant_generation}_{p_count}"
151 collection_nfts[nick] = [plant_generation , p_count]
152 payment(plant_generation, metadata['plant price'])
153
154 #assigns random, one time use IPFS image
155 ipfs_c = importlib.import_module(metadata['ipfs_contract'])
156 ipfs_image_url = ipfs_c.pick_random()
157
158 mint_nft(name,'This is a blueberry plant. Keep it alive and healthy by tending to it during growing season.' , ipfs_image_url , plant_data,1)
159 collection_nfts[name,'plant_calc_data'] = plant_calc_data
160
161 if bool(referrer) == True:
162 referrer_info = collection_nfts[referrer]
163 assert referrer_info[0] == plant_generation, "You have entered a referrer that isn't part of the current generation. Please try again."
164 collection_nfts[nick,'bonus_berries'] = 3
165 collection_nfts[referrer,'bonus_berries'] += 3
166 else:
167 collection_nfts[nick,'bonus_berries'] = 0
168
169 plants['count'] = p_count
170 return [plant_data["current_water"],plant_data["current_photosynthesis"],plant_data["current_bugs"],plant_data["current_nutrients"],plant_data["current_weeds"],plant_data['current_toxicity'],plant_data["burn_amount"],plant_data["current_weather"],ipfs_image_url]
171
172 def action_setup(plant_generation : int, plant_number : int):
173 name = f'Gen_{plant_generation}_{plant_number}'
174 assert collection_balances[ctx.caller, name] == 1, "You do not own this plant."
175 plant_data = collection_nfts[name,"nft_metadata"]
176 assert plant_data["alive"] == True, 'Your plant is dead due to neglect and you must buy a new plant to try again. Try not to kill it too.'
177 assert now <= plant_data['plant_end_time'], "Your plant's growing season has ended."
178
179
180 #interaction idle check. If idle too long, plant gets penalized.
181 if now > plant_data['last_interaction'] + datetime.timedelta(hours = 12):
182 plant_data["current_water"] -= (random.randint(5, 15))
183 plant_data["current_bugs"] += (random.randint(5, 15))
184 plant_data["current_nutrients"] -= (random.randint(5, 15))
185 plant_data["current_weeds"] += (random.randint(5, 15))
186
187 plant_data = daily_conditions(plant_data, plant_generation) #checks if weather and other daily conditions need updating
188 plant_data = totalizer_calc(plant_data,name) #checks if enough time has passed to add info to the plant totalizer calculations
189
190
191 plant_data = dead_check(plant_data)
192 plant_data['last_interaction'] = now #resets the interaction time
193
194 plant_all = {
195 'plant_data' : plant_data,
196 'name' : name
197 }
198
199 return plant_all
200
201 def daily_conditions(plant_data, plant_generation):
202 while now - plant_data["last_daily"] > datetime.timedelta(hours = 12) and now < (plant_data['plant_end_time']): #Loops through to calculate changes to plant if it's been more than a day since the last day's changes. Does multiple days worth too if needed
203 current_weather = random.randint(1, 3) # 1=sunny 2=cloudy 3=rainy
204 if current_weather == 1:
205 plant_data["current_water"] -= (random.randint(10, 15)) #how much water is lost each sunny day
206 plant_data["current_photosynthesis"] += (random.randint(4, 7)) #How much photosynthesis increases each sunny day
207 if current_weather == 2:
208 plant_data["current_water"] -= (random.randint(5, 9)) #how much water is lost each cloudy day
209 plant_data["current_photosynthesis"] += (random.randint(2, 4)) #How much photosynthesis increases each cloudy day
210 if current_weather == 3:
211 plant_data["current_water"] += (random.randint(3, 10)) #how much water is gained each rainy day
212 plant_data["current_photosynthesis"] += (random.randint(1, 2)) #How much photosynthesis increases each rainy day
213
214 plant_data["current_bugs"] += (random.randint(3, 10)) #how many bugs are added each day
215 plant_data["current_nutrients"] -= (random.randint(3, 6)) #how many nutrients are consumed each day
216 plant_data["current_weeds"] += (random.randint(2, 10)) #how many weeds grow each day
217 plant_data["last_daily"] += datetime.timedelta(hours = 12)
218 plant_data["current_weather"] = current_weather
219 plant_data['current_toxicity'] -= (random.randint(0, 2))
220 plant_data['burn_amount'] -= (random.randint(0, 1))
221
222 if plant_data['current_toxicity'] < 0:
223 plant_data['current_toxicity'] = 0
224
225 if plant_data['burn_amount'] < 0:
226 plant_data['burn_amount'] = 0
227
228 if plant_data['current_water'] > 100 : #water can't be above 100%
229 plant_data['current_water'] = 100
230
231 if plant_data["current_photosynthesis"] > 100 :
232 plant_data["burn_amount"] += (plant_data["current_photosynthesis"]-100)
233 plant_data["current_photosynthesis"] = 100
234
235 return plant_data
236
237 def totalizer_calc(plant_data,name):
238 if now > plant_data['last_calc'] + datetime.timedelta(hours = 3):
239 if now > plant_data['plant_end_time'] :
240 delta = plant_data['plant_end_time'] - plant_data['last_calc']
241 else:
242 delta = now - plant_data['last_calc']
243 delta_d = (delta.seconds / 86400)
244 plant_calc_data = collection_nfts[name,'plant_calc_data']
245 #This sections performs an integral on the various properties for use in determining total berries produced.
246 plant_calc_data["total_water"] += (delta_d**2*((plant_data["current_water"]/100-plant_calc_data["previous_water"]/100)/(delta_d))/2)+plant_calc_data["previous_water"]/100*delta_d
247 plant_calc_data["total_bugs"] += (delta_d**2*(((1-plant_data["current_bugs"]/100)-(1-plant_calc_data["previous_bugs"]/100))/(delta_d))/2)+(1-plant_calc_data["previous_bugs"]/100)*delta_d
248 plant_calc_data["total_nutrients"] += (delta_d**2*((plant_data["current_nutrients"]/100-plant_calc_data["previous_nutrients"]/100)/(delta_d))/2)+plant_calc_data["previous_nutrients"]/100*delta_d
249 plant_calc_data["total_weeds"] += (delta_d**2*(((1-plant_data["current_weeds"]/100)-(1-plant_calc_data["previous_weeds"]/100))/(delta_d))/2)+(1-plant_calc_data["previous_weeds"]/100)*delta_d
250 plant_data['last_calc'] = now
251 #Updates previous values for next calculation period.
252 plant_calc_data["previous_water"] = plant_data["current_water"]
253 plant_calc_data["previous_bugs"] = plant_data["current_bugs"]
254 plant_calc_data["previous_nutrients"] = plant_data["current_nutrients"]
255 plant_calc_data["previous_weeds"] = plant_data["current_weeds"]
256
257 collection_nfts[name,'plant_calc_data'] = plant_calc_data
258
259 return plant_data
260
261 def dead_check(plant_data): #checks to see if your plant has died.
262 if plant_data["current_toxicity"] >= 100 or plant_data["current_bugs"] >= 100 or plant_data["current_weeds"] >= 100 or plant_data["burn_amount"] >= 100 or plant_data["current_water"] <= 0 or plant_data["current_nutrients"] <= 0:
263 plant_data["alive"] = False
264 return plant_data
265
266 @export
267 def water(plant_generation : int, plant_number : int, num_times : int = 1): #Water your plant to increase its current_water.
268 plant_all = action_setup(plant_generation,plant_number) #Runs the main method that performs all of the various checks required for the plant.
269 plant_data = plant_all['plant_data']
270 name = plant_all['name']
271
272 for x in range(0, num_times):
273 plant_data['current_water'] += (random.randint(5, 15))
274 if plant_data['current_water'] > 100 : #water can't be above 1
275 plant_data['current_water'] = 100
276
277 collection_nfts[name,"nft_metadata"] = plant_data
278 return [plant_data["current_water"],plant_data["current_photosynthesis"],plant_data["current_bugs"],plant_data["current_nutrients"],plant_data["current_weeds"],plant_data['current_toxicity'],plant_data["burn_amount"],plant_data["current_weather"]]
279
280 @export
281 def squash(plant_generation : int, plant_number : int): #Squash bugs to reduce current_bugs and takes 5 minutes. Share's a timer with pullweeds.
282 plant_all = action_setup(plant_generation,plant_number) #Runs the main method that performs all of the various checks required for the plant.
283 plant_data = plant_all['plant_data']
284 name = plant_all['name']
285
286 t_delta = plant_data["last_squash_weed"] + datetime.timedelta(minutes = 5)
287 assert now > t_delta, f"You are still squashing bugs or pulling weeds. Try again at {t_delta}."
288
289 plant_data['current_bugs'] -= (random.randint(2, 5))
290 if plant_data['current_bugs'] < 0 :
291 plant_data['current_bugs'] = 0
292
293 plant_data["last_squash_weed"] = now
294 collection_nfts[name,"nft_metadata"] = plant_data
295 return [plant_data["current_water"],plant_data["current_photosynthesis"],plant_data["current_bugs"],plant_data["current_nutrients"],plant_data["current_weeds"],plant_data['current_toxicity'],plant_data["burn_amount"],plant_data["current_weather"]]
296
297 @export
298 def spraybugs(plant_generation : int, plant_number : int): #Spray bugs to instantly reduce current_bugs but costs tau and adds small amount of toxicity
299 plant_all = action_setup(plant_generation,plant_number) #Runs the main method that performs all of the various checks required for the plant.
300 plant_data = plant_all['plant_data']
301 name = plant_all['name']
302
303 plant_data['current_toxicity'] += (random.randint(1, 3))
304
305 plant_data['current_bugs'] -= (random.randint(10, 20))
306 if plant_data['current_bugs'] < 0 :
307 plant_data['current_bugs'] = 0
308
309 payment(plant_generation, 5)
310 collection_nfts[name,"nft_metadata"] = plant_data
311 return [plant_data["current_water"],plant_data["current_photosynthesis"],plant_data["current_bugs"],plant_data["current_nutrients"],plant_data["current_weeds"],plant_data['current_toxicity'],plant_data["burn_amount"],plant_data["current_weather"]]
312
313 @export
314 def growlights(plant_generation : int, plant_number : int): #add photosynthesis to help plant catchup after several rainy days. Adds amount to current_photosynthesis but if it goes over 100%, burns your plant.
315 plant_all = action_setup(plant_generation,plant_number) #Runs the main method that performs all of the various checks required for the plant.
316 plant_data = plant_all['plant_data']
317 name = plant_all['name']
318
319 t_delta = plant_data["last_grow_light"] + datetime.timedelta(hours = 12)
320 assert now > t_delta, f"You have used a grow light or shade too recently. Try again at {t_delta}."
321
322 payment(plant_generation, 5)
323 plant_data['current_photosynthesis'] += (random.randint(3, 5))
324 plant_data["last_grow_light"] = now
325
326 if plant_data["current_photosynthesis"] > 100 :
327 plant_data["burn_amount"] += (plant_data["current_photosynthesis"]-100)
328 plant_data["current_photosynthesis"] = 100
329
330 collection_nfts[name,"nft_metadata"] = plant_data
331 return [plant_data["current_water"],plant_data["current_photosynthesis"],plant_data["current_bugs"],plant_data["current_nutrients"],plant_data["current_weeds"],plant_data['current_toxicity'],plant_data["burn_amount"],plant_data["current_weather"]]
332
333 @export
334 def shade(plant_generation : int, plant_number : int): #shades your plant to reduce photosynthesis by a small amount
335 plant_all = action_setup(plant_generation,plant_number) #Runs the main method that performs all of the various checks required for the plant.
336 plant_data = plant_all['plant_data']
337 name = plant_all['name']
338
339 t_delta = plant_data["last_grow_light"] + datetime.timedelta(hours = 12)
340 assert now > t_delta, f"You have used a grow light or shade too recently. Try again at {t_delta}."
341
342 plant_data['current_photosynthesis'] -= (random.randint(3, 5))
343 plant_data["last_grow_light"] = now
344
345 if plant_data["current_photosynthesis"] < 0 :
346 plant_data["current_photosynthesis"] = 0
347
348 collection_nfts[name,"nft_metadata"] = plant_data
349 return [plant_data["current_water"],plant_data["current_photosynthesis"],plant_data["current_bugs"],plant_data["current_nutrients"],plant_data["current_weeds"],plant_data['current_toxicity'],plant_data["burn_amount"],plant_data["current_weather"]]
350
351 @export
352 def fertilize(plant_generation : int, plant_number : int, num_times : int = 1): #increases current nutrients of the plant but if nutrients go over 100%, it burns your plant.
353 plant_all = action_setup(plant_generation,plant_number) #Runs the main method that performs all of the various checks required for the plant.
354 plant_data = plant_all['plant_data']
355 name = plant_all['name']
356
357 for x in range(0, num_times):
358 plant_data['current_nutrients'] += (random.randint(4, 6))
359
360 if plant_data['current_nutrients'] > 100 :
361 plant_data["burn_amount"] += (plant_data['current_nutrients']-100)
362 plant_data['current_nutrients'] = 100
363
364 collection_nfts[name,"nft_metadata"] = plant_data
365 return [plant_data["current_water"],plant_data["current_photosynthesis"],plant_data["current_bugs"],plant_data["current_nutrients"],plant_data["current_weeds"],plant_data['current_toxicity'],plant_data["burn_amount"],plant_data["current_weather"]]
366
367 @export
368 def pullweeds(plant_generation : int, plant_number : int): #reduces current weeds in plant and takes 5 minutes to do. Share's a timer with squash bugs.
369
370 plant_all = action_setup(plant_generation,plant_number) #Runs the main method that performs all of the various checks required for the plant.
371 plant_data = plant_all['plant_data']
372 name = plant_all['name']
373
374 t_delta = plant_data["last_squash_weed"] + datetime.timedelta(minutes = 5)
375 assert now > t_delta, f"You are still squashing bugs or pulling weeds. Try again at {t_delta}."
376
377 plant_data['current_weeds'] -= (random.randint(2, 5))
378 if plant_data['current_weeds'] < 0 :
379 plant_data['current_weeds'] = 0
380
381 plant_data["last_squash_weed"] = now
382 collection_nfts[name,"nft_metadata"] = plant_data
383 return [plant_data["current_water"],plant_data["current_photosynthesis"],plant_data["current_bugs"],plant_data["current_nutrients"],plant_data["current_weeds"],plant_data['current_toxicity'],plant_data["burn_amount"],plant_data["current_weather"]]
384
385 @export
386 def sprayweeds(plant_generation : int, plant_number : int): #Spray weeds to instantly reduce current_weeds but costs tau and adds small amount of toxicity
387 plant_all = action_setup(plant_generation,plant_number) #Runs the main method that performs all of the various checks required for the plant.
388 plant_data = plant_all['plant_data']
389 name = plant_all['name']
390
391 plant_data['current_toxicity'] += (random.randint(1, 3))
392
393 plant_data['current_weeds'] -= (random.randint(10, 20))
394 if plant_data['current_weeds'] < 0 :
395 plant_data['current_weeds'] = 0
396
397 payment(plant_generation, 5)
398
399 collection_nfts[name,"nft_metadata"] = plant_data
400 return [plant_data["current_water"],plant_data["current_photosynthesis"],plant_data["current_bugs"],plant_data["current_nutrients"],plant_data["current_weeds"],plant_data['current_toxicity'],plant_data["burn_amount"],plant_data["current_weather"]]
401
402 @export
403 def finalize(plant_generation : int, plant_number : int): #Finalizes your plant at the end of growing season to deterimine your berry yield.
404 name = f'Gen_{plant_generation}_{plant_number}'
405 assert collection_balances[ctx.caller, name] == 1, "You do not own this plant."
406 assert collection_nfts[name,'finalized'] == False, 'This plant has already been finalized.'
407 plant_data = collection_nfts[name,"nft_metadata"]
408 end_time = plant_data['plant_end_time']
409 finalize_time = plants[plant_generation, 'finalize_time']
410 assert now <= finalize_time and now >= end_time, f'It is not time to finalize your plant. Try between {end_time} and {finalize_time}'
411 plant_data = daily_conditions(plant_data, plant_generation) #checks if weather and other daily conditions need updating
412 plant_data = dead_check(plant_data)
413 if plant_data["alive"] == False:
414 plant_data['last_calc'] = now
415 collection_nfts[name,"nft_metadata"] = plant_data
416 return 'Your plant is dead due to neglect and you cannot grow any berries. Try again next season.'
417
418 if plants['growing_season'] == True : #first person to run this also turns growing_season to false and resets plant counter for next growing season
419 plants['growing_season'] = False
420 plants['count'] = 0
421
422 plant_data = totalizer_calc(plant_data,name)
423 collection_nfts[name,"nft_metadata"] = plant_data
424 plant_calc_data = collection_nfts[name,'plant_calc_data']
425
426 length = metadata['growing_season_length']
427 berries = int(collection_nfts[name,'bonus_berries'] + (1000 * ((plant_calc_data["total_water"]*plant_calc_data["total_bugs"]*plant_calc_data["total_nutrients"]*plant_calc_data["total_weeds"])/(length**4))*(1-plant_data['current_toxicity']/100)*(plant_data["current_photosynthesis"]/100)*(1-plant_data["burn_amount"]/100)))
428 collection_nfts[name,'berries'] = berries
429 collection_nfts[name,'final_score'] = berries
430 plants[plant_generation,'total_berries'] += berries
431
432 if plants[plant_generation, 'claimable_tau'] == 0: #sets the total amount of tau that can be claimed by players.
433 plants[plant_generation, 'claimable_tau'] = plants[plant_generation, 'total_tau']
434
435 collection_nfts[name,'finalized'] == True
436 berries = str(berries)
437 return berries
438
439 @export
440 def sellberries(plant_generation : int, plant_number : int): #redeem berries for TAU. Must be done after plant finalize time is over.
441 name = f'Gen_{plant_generation}_{plant_number}'
442 assert collection_balances[ctx.caller, name] == 1, "You do not own this plant."
443 berries = collection_nfts[name,'berries']
444 assert berries > 0, "You don't have any berries to sell."
445 assert now >= plants[plant_generation, 'finalize_time'], f"You can't sell yet. Try again after {plants[plant_generation, 'finalize_time']} but do not wait too long."
446 sell_price = plants[plant_generation, 'total_tau'] / plants[plant_generation,'total_berries']
447 proceeds = sell_price * berries
448 currency.transfer(amount=proceeds, to=ctx.caller)
449 collection_nfts[name,'berries'] = 0
450 plants[plant_generation, 'claimable_tau'] -= proceeds
451 proceeds = str(proceeds)
452 return proceeds
453
454 def payment(plant_generation, amount): #used to process payments
455 dev_reward = 0.05
456 currency.transfer_from(amount=amount*(1-dev_reward), to=ctx.this, main_account=ctx.caller)
457 currency.transfer_from(amount=amount*dev_reward, to=metadata['operator'], main_account=ctx.caller)
458 plants[plant_generation, 'total_tau'] += amount*(1-dev_reward)
459
460 @export
461 def manual_reward_add(plant_generation : int, amount : int): #used to manually add more tau to the prize pool
462 currency.transfer_from(amount=amount, to=ctx.this, main_account=ctx.caller)
463 plants[plant_generation, 'total_tau'] += amount
464
465 @export
466 def stale_claims(plant_generation : int): #used by the operator to claim tau from a plant generation that ended at least 30 days prior. This allows players ample time to sell their berries
467 assert metadata['operator'] == ctx.caller, "Only the operator can claim stale tau."
468 stale_claim_time = plants[plant_generation,'stale_claim_time']
469 assert now >= stale_claim_time, f"The tau is not stale yet and cannot be claimed. Try again after {stale_claim_time}"
470 stale_tau = plants[plant_generation, 'claimable_tau']
471 assert stale_tau > 0, "There is no stale tau to claim."
472 currency.transfer(amount=stale_tau, to=ctx.caller)
473
474 @export
475 def manual_season_end(): #only needed if for some reason there were no finalized plants in the current grow season
476 assert metadata['operator'] == ctx.caller, "Only the operator can do this."
477 assert now > plants['growing_season_end_time'], "You can't end the season before the end_time."
478 plants['growing_season'] = False
479 plants['count'] = 0
480
481 @export
482 def new_nickname(plant_generation : int, plant_number : int, nick : str):
483 name = f'Gen_{plant_generation}_{plant_number}'
484 assert collection_balances[ctx.caller, name] == 1, "You do not own this plant."
485 assert not nick.isdigit(), "The plant nickname can't be an integer."
486 assert bool(collection_nfts[nick]) == False, "This nickname already exists."
487 assert nick.isalnum() == True, "Only alphanumeric characters allowed."
488 assert nick != "", "Name cannot be empty"
489 assert len(nick) >= 3, "The minimum length is 3 characters."
490 payment(plant_generation, 25)
491 collection_nfts[nick] = [plant_generation , plant_number]
492
493 @export
494 def nickname_interaction(nickname : str, function_name :str): #allows players to interact with a plant based on its nickname
495 nick = collection_nfts[nickname]
496
497 function_names = {
498 'water' : water,
499 'squash' : squash,
500 'spraybugs' : spraybugs,
501 'growlights' : growlights,
502 'shade' : shade,
503 'fertilize' : fertilize,
504 'pullweeds' : pullweeds,
505 'sprayweeds' : sprayweeds,
506 'finalize' : finalize,
507 'sellberries' : sellberries
508 }
509
510 return function_names[function_name](nick[0],nick[1])
511
512 @export
513 def e_wdraw_enable(enable:bool):
514 emergency_addresses = emergency['addresses']
515 call_address = ctx.caller
516 assert call_address in emergency_addresses.keys(), "You are not approved to do this."
517 emergency_addresses[call_address] = int(enable)
518 emergency['addresses'] = emergency_addresses
519
520 @export
521 def multisig_emergency_withdraw(amount:float): #can only be run if at least 2 of 3 multisig accounts approve of the emergency_withdraw
522 emergency_addresses = emergency['addresses']
523 call_address = ctx.caller
524 approval_check = sum(emergency_addresses.values())
525 assert approval_check >= 2, "An emergency withdrawal is not approved."
526 assert metadata['operator'] == call_address, "Only the operator can claim tau."
527 currency.transfer(amount=amount, to=call_address)

Byte Code

e300000000000000000000000006000000400000007300030000640064016c005a0065016402640364048d025a0265016402640564048d025a03650464006402640664078d035a05650464006402640864078d035a06650464006402640964078d035a07650464006402640a64078d035a0865046402640b64048d025a0965046402640c64048d025a0a65046402640d64048d025a0b650c6a0d83000100640e640f84005a0e650f64028301645a65106510651164119c0364126413840583015a126510651065106513651464149c056415641684045a15650f6402830165106514651064179c0364186419840483015a16650f64028301651465106510641a9c03641b641c840483015a17650f640283016510651465106510641d9c04641e641f840483015a18650f6402830164206421840083015a19650f64028301645b6510651064229c0264236424840583015a1a6514651464259c026426642784045a1b6428642984005a1c642a642b84005a1d642c642d84005a1e650f64028301645c651465146514642f9c0364306431840583015a1f650f640283016514651464259c0264326433840483015a20650f640283016514651464259c0264346435840483015a21650f640283016514651464259c0264366437840483015a22650f640283016514651464259c0264386439840483015a23650f64028301645d651465146514642f9c03643a643b840583015a24650f640283016514651464259c02643c643d840483015a25650f640283016514651464259c02643e643f840483015a26650f640283016514651464259c0264406441840483015a27650f640283016514651464259c0264426443840483015a286444644584005a29650f640283016514651464469c0264476448840483015a2a650f64028301651464499c01644a644b840483015a2b650f64028301644c644d840083015a2c650f64028301651465146510644e9c03644f6450840483015a2d650f640283016510651064519c0264526453840483015a2e650f64028301651164549c0164556456840483015a2f650f64028301653064579c0164586459840483015a3164015300295ee9000000004eda0f636f6e5f686172766573745f303032da0f636f6c6c656374696f6e5f6e616d652902da08636f6e7472616374da046e616d65da10636f6c6c656374696f6e5f6f776e6572da0f636f6c6c656374696f6e5f6e6674732903da0d64656661756c745f76616c756572040000007205000000da13636f6c6c656374696f6e5f62616c616e636573da1d636f6c6c656374696f6e5f62616c616e6365735f617070726f76616c73da06706c616e7473da086d65746164617461da096e69636b6e616d6573da09656d657267656e6379630000000000000000010000000400000043000000737000000074006a0164018301010074026a0174036a048301010074036a04740564023c006403740564043c006405740564063c006407740564083c0064097406640a3c0074077406640b3c00640c7406640d3c00640e7406640f3c00640c640c640c64109c03740864113c0069007d006400530029124e7a184861727665737420426c7565626572727920506c616e7473da086f70657261746f72e90e000000da1567726f77696e675f736561736f6e5f6c656e67746869f40100007a0b706c616e74207072696365da15636f6e5f686172766573745f67656e315f69706673da0d697066735f636f6e747261637446da0e67726f77696e675f736561736f6eda1967726f77696e675f736561736f6e5f73746172745f74696d657201000000da05636f756e74e901000000da116163746976655f67656e65726174696f6e2903da4061653764313464366439623834343366383831626136323434373237623639623638313031306537383264346665343832646266623062366163613032643564da4034396163656561626463636463623339663863326331313265313130656164316135666566323263363434383235633139313762326466333230346334333366da4065386463373038303238653034393339376235626166393537393932346464653538636535626562656535363535646130623533303636313137353732653733da096164647265737365732909da115f5f636f6c6c656374696f6e5f6e616d65da03736574da125f5f636f6c6c656374696f6e5f6f776e6572da03637478da0663616c6c6572da0a5f5f6d65746164617461da085f5f706c616e7473da036e6f77da0b5f5f656d657267656e63792901da0b5f5f6e69636b6e616d6573a9007227000000da00da045f5f5f5f13000000731c00000000010a010c010a010801080108010801080108010803020202010c017229000000462903da036b6579da096e65775f76616c7565da12636f6e766572745f746f5f646563696d616c630300000000000000030000000300000043000000732e00000074006a017402640119006b02731674036402830182017c02722274047c0183017d017c0174027c003c006400530029034e720f0000007a1e6f6e6c79206f70657261746f722063616e20736574206d657461646174612905722000000072210000007222000000da0e417373657274696f6e4572726f72da07646563696d616c2903722a000000722b000000722c000000722700000072270000007228000000da0f6368616e67655f6d6574616461746127000000730a00000000021001060104010801722f00000029057205000000da0b6465736372697074696f6eda0e697066735f696d6167655f75726cda0c6e66745f6d65746164617461da06616d6f756e74630500000000000000050000000500000043000000736c0000007c0064016b037310740064028301820174017c00190064036b02732474006404830182017c0464036b04733474006405830182017c017c0264067c009b0064079d037c0464089c0474017c003c007c0374017c00640966023c007c04740274036a047c0066023c0064005300290a4e72280000007a144e616d652063616e6e6f7420626520656d70747972010000007a134e616d6520616c7265616479206578697374737a24596f752063616e6e6f74207472616e73666572206e6567617469766520616d6f756e74737a1453656520636f6c6c656374696f6e5f6e6674735b7a102c276e66745f6d65746164617461275d2904723000000072310000007232000000723300000072320000002905722d000000da115f5f636f6c6c656374696f6e5f6e667473da155f5f636f6c6c656374696f6e5f62616c616e63657372200000007221000000290572050000007230000000723100000072320000007233000000722700000072270000007228000000da0a5f5f6d696e745f6e667430000000731000000000021001140110010201020116010c017236000000290372050000007233000000da02746f63030000000000000003000000040000004300000073680000007c0164016b04731074006402830182017c0064036b0373207400640483018201740174026a037c00660219007c016b05733a7400640583018201740174026a037c006602050019007c01380003003c0074017c027c006602050019007c01370003003c006400530029064e72010000007a24596f752063616e6e6f74207472616e73666572206e6567617469766520616d6f756e747372280000007a37506c65617365207370656369667920746865206e616d65206f6620746865204e465420796f752077616e7420746f207472616e736665727a22596f7520646f6e2774206861766520656e6f756768204e46547320746f2073656e642904722d0000007235000000722000000072210000002903720500000072330000007237000000722700000072270000007228000000da087472616e736665723c000000730c0000000002100110010c010e01160172380000002903723300000072050000007237000000630300000000000000030000000400000043000000732c0000007c0064016b0473107400640283018201740174026a037c027c016603050019007c00370003003c006400530029034e72010000007a1f43616e6e6f7420617070726f7665206e6567617469766520616d6f756e74732904722d000000da1f5f5f636f6c6c656374696f6e5f62616c616e6365735f617070726f76616c73722000000072210000002903723300000072050000007237000000722700000072270000007228000000da07617070726f766546000000730400000000021001723a0000002904720500000072330000007237000000da0c6d61696e5f6163636f756e7463040000000000000004000000060000004300000073960000007c0164016b047310740064028301820174017c037c027c00660319007c016b05733c740064036a0274017c037c027c00660319007c0183028301820174037c037c00660219007c016b057354740064048301820174017c037c027c006603050019007c01380003003c0074037c037c006602050019007c01380003003c0074037c027c006602050019007c01370003003c006400530029054e72010000007a1e43616e6e6f742073656e64206e656761746976652062616c616e636573217a484e6f7420656e6f756768204e46547320617070726f76656420746f2073656e642120596f752068617665207b7d20616e642061726520747279696e6720746f207370656e64207b7d7a184e6f7420656e6f756768204e46547320746f2073656e64212904722d0000007239000000da06666f726d617472350000002904720500000072330000007237000000723b000000722700000072270000007228000000da0d7472616e736665725f66726f6d4c0000007312000000000210010c010c0114010a010e0116011401723d00000063000000000000000003000000040000004300000073e200000074006a01830074026a036b02731674046401830182017405640219007d007c0064036b02732e74046404830182017406640519007d017405640619007d027c02640737007d026408740564023c007407740564093c00740774086a097c01640a1700640b8d0117007405640c3c00740774086a097c01640d1700640b8d01170074057c02640e66023c007c02740564063c00640f74057c02641066023c00640f74057c02641166023c00640f74057c02641266023c00640f74057c02641366023c00740774086a097c0164141700640b8d01170074057c02641566023c006400530029164e7a2a4f6e6c7920746865206f776e65722063616e20737461727420612067726f77696e6720736561736f6e2e7214000000467a1d497420697320616c72656164792067726f77696e6720736561736f6e2e721100000072180000007217000000547215000000e9030000002901da0464617973da1767726f77696e675f736561736f6e5f656e645f74696d65e906000000da0d66696e616c697a655f74696d657201000000da0d746f74616c5f62657272696573da1073656c6c61626c655f62657272696573da09746f74616c5f746175da0d636c61696d61626c655f746175e91e000000da107374616c655f636c61696d5f74696d65290a721f000000da0367657472200000007221000000722d000000722300000072220000007224000000da086461746574696d65da0974696d6564656c74612903da0b67726f775f736561736f6e7211000000da0a6163746976655f67656e722700000072270000007228000000da1473746172745f67726f77696e675f736561736f6e5900000073280000000002060110010801100108010801080108010801060112010601160108010c010c010c010c010601724e0000002902da046e69636bda0872656665727265726302000000000000000b0000001200000043000000733402000074006401190064026b0273147401640383018201740064041900740274036a04640564068d0117006b05733474016407830182017c006a0583000c0073467401640883018201740674077c001900830164096b02735e7401640a830182017c006a08830064026b0273727401640b830182017c00640c6b0373827401640d8301820174097c008301640e6b0573967401640f830182017400641019007d02740a641119007d03740b6a0c641264138302740b6a0c6414641583026416740b6a0c641264138302740b6a0c641464158302641664177402740274026402740274036a04642b64068d011700740274036a04642c64068d0117006416740274036a047c0364068d01170064189c0f7d047c04641919007c04641a19007c04641b19007c04641c19006416641664166416641d9c087d057400641e1900641717007d06641f7c029b0064207c069b009d047d077c027c06670274077c003c00740d7c02740a6421190083020100740e6a0f740a6422190083017d087c086a1083007d0974117c0764237c097c046417830501007c0574077c07642466023c0074067c01830164026b02900172ea74077c0119007d0a7c0a641619007c026b02900173c87401642583018201640e74077c00642666023c0074077c016426660205001900640e370003003c006e0c641674077c00642666023c007c067400641e3c007c04641919007c04642719007c04641a19007c04641b19007c04641c19007c04642819007c04642919007c04642a19007c0967095300292d4e7214000000547a3e5468652067726f77696e6720736561736f6e20686173206e6f7420737461727465642c20736f20796f752063616e6e6f7420627579206120706c616e742e7240000000e90b0000002901723f0000007a444974277320746f6f2066617220696e746f207468652067726f77696e6720736561736f6e20616e6420796f752063616e6e6f7420627579206120706c616e74206e6f772e7a2754686520706c616e74206e69636b6e616d652063616e277420626520616e20696e74656765722e467a1d54686973206e69636b6e616d6520616c7265616479206578697374732e7a254f6e6c7920616c7068616e756d65726963206368617261637465727320616c6c6f7765642e72280000007a144e616d652063616e6e6f7420626520656d707479723e0000007a23546865206d696e696d756d206c656e677468206973203320636861726163746572732e72180000007211000000e946000000e95a000000e905000000e91900000072010000007217000000290fda0d63757272656e745f7761746572da0c63757272656e745f62756773da1663757272656e745f70686f746f73796e746865736973da1163757272656e745f6e75747269656e7473da0d63757272656e745f7765656473da1063757272656e745f746f786963697479da0f63757272656e745f77656174686572da106c6173745f696e746572616374696f6eda0a6c6173745f6461696c79da096c6173745f63616c63da05616c697665da106c6173745f7371756173685f77656564da0f6c6173745f67726f775f6c69676874da0b6275726e5f616d6f756e74da0e706c616e745f656e645f74696d65725600000072570000007259000000725a0000002908da0e70726576696f75735f7761746572da0d70726576696f75735f62756773da1270726576696f75735f6e75747269656e7473da0e70726576696f75735f7765656473da0b746f74616c5f7761746572da0a746f74616c5f62756773da0f746f74616c5f6e75747269656e7473da0b746f74616c5f77656564737216000000da0447656e5fda015f7a0b706c616e7420707269636572130000007a5c54686973206973206120626c7565626572727920706c616e742e204b65657020697420616c69766520616e64206865616c7468792062792074656e64696e6720746f20697420647572696e672067726f77696e6720736561736f6e2eda0f706c616e745f63616c635f646174617a58596f75206861766520656e7465726564206120726566657272657220746861742069736e27742070617274206f66207468652063757272656e742067656e65726174696f6e2e20506c656173652074727920616761696e2eda0d626f6e75735f626572726965737258000000725b0000007263000000725c000000e9ffffffff727100000029127223000000722d0000007224000000724a000000724b000000da0769736469676974da04626f6f6c7234000000da076973616c6e756dda036c656e7222000000da0672616e646f6dda0772616e64696e74da095f5f7061796d656e74da09696d706f72746c6962da0d696d706f72745f6d6f64756c65da0b7069636b5f72616e646f6d7236000000290b724f0000007250000000da10706c616e745f67656e65726174696f6e7211000000da0a706c616e745f64617461726f000000da07705f636f756e747205000000da06697066735f637231000000da0d72656665727265725f696e666f722700000072270000007228000000da096275795f706c616e74710000007364000000000206010e010c010e01060112010a010e01140110011401080108010a010c010a010e01060110010e0108010e0106010601080108010a010c0110010c010e010e010801040102010a010c010e010801060110010c0116020c01080108010c010c010c0172810000002902727c000000da0c706c616e745f6e756d626572630200000000000000050000000600000043000000730801000064017c009b0064027c019b009d047d02740074016a027c026602190064036b02732a740364048301820174047c026405660219007d037c036406190064076b02734a740364088301820174057c03640919006b01735e7403640a8301820174057c03640b190074066a07640c640d8d0117006b0472d67c03640e0500190074086a09640f64108302380003003c007c0364110500190074086a09640f64108302370003003c007c0364120500190074086a09640f64108302380003003c007c0364130500190074086a09640f64108302370003003c00740a7c037c0083027d03740b7c037c0283027d03740c7c0383017d0374057c03640b3c007c037c0264149c027d047c04530029154e726d000000726e00000072170000007a1a596f7520646f206e6f74206f776e207468697320706c616e742e72320000007260000000547a64596f757220706c616e7420697320646561642064756520746f206e65676c65637420616e6420796f75206d757374206275792061206e657720706c616e7420746f2074727920616761696e2e20547279206e6f7420746f206b696c6c20697420746f6f2e72640000007a26596f757220706c616e7427732067726f77696e6720736561736f6e2068617320656e6465642e725d000000e90c0000002901da05686f75727372560000007254000000e90f00000072570000007259000000725a0000002902727d0000007205000000290d723500000072200000007221000000722d00000072340000007224000000724a000000724b00000072760000007277000000da125f5f6461696c795f636f6e646974696f6e73da105f5f746f74616c697a65725f63616c63da0c5f5f646561645f636865636b2905727c00000072820000007205000000727d000000da09706c616e745f616c6c722700000072270000007228000000da0e5f5f616374696f6e5f7365747570a80000007326000000000110010c010e010c0106010e010e010601180118011801180118010a010a01080108010a01728a00000063020000000000000003000000060000004300000073ec010000900178e474007c0064011900180074016a02640264038d016b046f2674007c00640419006b00900172e674036a046405640683027d027c0264056b02726e7c0064070500190074036a04640864098302380003003c007c00640a0500190074036a04640b640c8302370003003c007c02640d6b0272a67c0064070500190074036a04640e640f8302380003003c007c00640a0500190074036a04640d640b8302370003003c007c0264066b0272de7c0064070500190074036a04640664088302370003003c007c00640a0500190074036a046405640d8302370003003c007c0064100500190074036a04640664088302370003003c007c0064110500190074036a04640664128302380003003c007c0064130500190074036a04640d64088302370003003c007c0064010500190074016a02640264038d01370003003c007c027c0064143c007c0064150500190074036a046416640d8302380003003c007c0064170500190074036a04641664058302380003003c007c006415190064166b009001728c64167c0064153c007c006417190064166b00900172a264167c0064173c007c006407190064186b04900172b864187c0064073c007c00640a190064186b0472047c006417050019007c00640a190064181800370003003c0064187c00640a3c00710457007c00530029194e725e00000072830000002901728400000072640000007217000000723e0000007256000000e90a00000072850000007258000000e904000000e907000000e9020000007254000000e909000000725700000072590000007241000000725a000000725c000000725b00000072010000007263000000e96400000029057224000000724a000000724b000000727600000072770000002903727d000000727c000000725c0000007227000000722700000072280000007286000000be000000733c00000000011c010e010c0108011801180108011801180108011801180118011801180118010801180118010e0108010e0108010e0108010c010e010a010c01728600000063020000000000000005000000080000004300000073ca01000074007c006401190074016a02640264038d0117006b04900172c674007c00640419006b0472387c00640419007c006401190018007d026e0c74007c006401190018007d027c026a0364051b007d0374047c016406660219007d047c046407050019007c03640813007c0064091900640a1b007c04640b1900640a1b0018007c031b00140064081b007c04640b1900640a1b007c0314001700370003003c007c04640c050019007c0364081300640d7c00640e1900640a1b001800640d7c04640f1900640a1b00180018007c031b00140064081b00640d7c04640f1900640a1b0018007c0314001700370003003c007c046410050019007c03640813007c0064111900640a1b007c0464121900640a1b0018007c031b00140064081b007c0464121900640a1b007c0314001700370003003c007c046413050019007c0364081300640d7c0064141900640a1b001800640d7c0464151900640a1b00180018007c031b00140064081b00640d7c0464151900640a1b0018007c0314001700370003003c0074007c0064013c007c00640919007c04640b3c007c00640e19007c04640f3c007c00641119007c0464123c007c00641419007c0464153c007c0474047c01640666023c007c00530029164e725f000000723e0000002901728400000072640000006980510100726f0000007269000000728e000000725600000072900000007265000000726a000000721700000072570000007266000000726b00000072590000007267000000726c000000725a000000726800000029057224000000724a000000724b000000da077365636f6e647372340000002905727d0000007205000000da0564656c7461da0764656c74615f64726f0000007227000000722700000072280000007287000000df000000733200000000011a010c0112020c010a010c0108022601160108023c010c0108022601160108023c010c0108010c010c010c010c010c01728700000063010000000000000001000000030000004300000073540000007c006401190064026b0573487c006403190064026b0573487c006404190064026b0573487c006405190064026b0573487c006406190064076b0173487c006408190064076b01725064097c00640a3c007c005300290b4e725b00000072900000007257000000725a000000726300000072560000007201000000725900000046726000000072270000002901727d000000722700000072270000007228000000728800000000010000730c000000000112011401100112010801728800000072170000002903727c0000007282000000da096e756d5f74696d6573630300000000000000070000000900000043000000739a00000074007c007c0183027d037c03640119007d047c03640219007d05782a740164037c02830244005d1c7d067c0464040500190074026a03640564068302370003003c00712657007c046404190064076b04725a64077c0464043c007c0474047c05640866023c007c04640419007c04640919007c04640a19007c04640b19007c04640c19007c04640d19007c04640e19007c04640f19006708530029104e727d0000007205000000720100000072560000007254000000728500000072900000007232000000725800000072570000007259000000725a000000725b0000007263000000725c0000002905728a000000da0572616e67657276000000727700000072340000002907727c000000728200000072940000007289000000727d0000007205000000da0178722700000072270000007228000000da05776174657209010000731a00000000020a010801080110011c010c0108010c0108010c010c010c01729700000063020000000000000006000000090000004300000073ba00000074007c007c0183027d027c02640119007d037c02640219007d047c036403190074016a02640464058d0117007d0574037c056b047346740464067c059b0064079d03830182017c0364080500190074056a06640964048302380003003c007c0364081900640a6b007272640a7c0364083c0074037c0364033c007c0374077c04640b66023c007c03640c19007c03640d19007c03640819007c03640e19007c03640f19007c03641019007c03641119007c03641219006708530029134e727d0000007205000000726100000072540000002901da076d696e757465737a3c596f7520617265207374696c6c20737175617368696e672062756773206f722070756c6c696e672077656564732e2054727920616761696e20617420da012e7257000000728e00000072010000007232000000725600000072580000007259000000725a000000725b0000007263000000725c0000002908728a000000724a000000724b0000007224000000722d0000007276000000727700000072340000002906727c00000072820000007289000000727d0000007205000000da07745f64656c7461722700000072270000007228000000da067371756173681a010000731e00000000020a01080108011401180118010c01080108010c0108010c010c010c01729b00000063020000000000000005000000090000004300000073a800000074007c007c0183027d027c02640119007d037c02640219007d047c0364030500190074016a02640464058302370003003c007c0364060500190074016a02640764088302380003003c007c036406190064096b00725e64097c0364063c0074037c00640a830201007c0374047c04640b66023c007c03640c19007c03640d19007c03640619007c03640e19007c03640f19007c03640319007c03641019007c03641119006708530029124e727d0000007205000000725b0000007217000000723e0000007257000000728b000000e914000000720100000072540000007232000000725600000072580000007259000000725a0000007263000000725c0000002905728a00000072760000007277000000727800000072340000002905727c00000072820000007289000000727d0000007205000000722700000072270000007228000000da097370726179627567732d010000731c00000000020a0108010801180118010c0108010a010c0108010c010c010c01729d00000063020000000000000006000000090000004300000073dc00000074007c007c0183027d027c02640119007d037c02640219007d047c036403190074016a02640464058d0117007d0574037c056b047346740464067c059b0064079d038301820174057c006408830201007c0364090500190074066a07640a64088302370003003c0074037c0364033c007c0364091900640b6b04729c7c03640c050019007c0364091900640b1800370003003c00640b7c0364093c007c0374087c04640d66023c007c03640e19007c03640919007c03640f19007c03641019007c03641119007c03641219007c03640c19007c03641319006708530029144e727d000000720500000072620000007283000000290172840000007a3f596f752068617665207573656420612067726f77206c69676874206f7220736861646520746f6f20726563656e746c792e2054727920616761696e20617420729900000072540000007258000000723e000000729000000072630000007232000000725600000072570000007259000000725a000000725b000000725c0000002909728a000000724a000000724b0000007224000000722d00000072780000007276000000727700000072340000002906727c00000072820000007289000000727d0000007205000000729a000000722700000072270000007228000000da0a67726f776c69676874733f010000732200000000020a0108010801140118010a01180108010c01180108010c0108010c010c010c01729e00000063020000000000000006000000090000004300000073ba00000074007c007c0183027d027c02640119007d037c02640219007d047c036403190074016a02640464058d0117007d0574037c056b047346740464067c059b0064079d03830182017c0364080500190074056a066409640a8302380003003c0074037c0364033c007c0364081900640b6b00727a640b7c0364083c007c0374077c04640c66023c007c03640d19007c03640819007c03640e19007c03640f19007c03641019007c03641119007c03641219007c03641319006708530029144e727d000000720500000072620000007283000000290172840000007a3f596f752068617665207573656420612067726f77206c69676874206f7220736861646520746f6f20726563656e746c792e2054727920616761696e2061742072990000007258000000723e000000725400000072010000007232000000725600000072570000007259000000725a000000725b0000007263000000725c0000002908728a000000724a000000724b0000007224000000722d0000007276000000727700000072340000002906727c00000072820000007289000000727d0000007205000000729a000000722700000072270000007228000000da05736861646554010000731e00000000020a010801080114011801180108010c0108010c0108010c010c010c01729f00000063030000000000000007000000090000004300000073b200000074007c007c0183027d037c03640119007d047c03640219007d05782a740164037c02830244005d1c7d067c0464040500190074026a03640564068302370003003c00712657007c046404190064076b0472727c046408050019007c046404190064071800370003003c0064077c0464043c007c0474047c05640966023c007c04640a19007c04640b19007c04640c19007c04640419007c04640d19007c04640e19007c04640819007c04640f19006708530029104e727d000000720500000072010000007259000000728c0000007241000000729000000072630000007232000000725600000072580000007257000000725a000000725b000000725c0000002905728a00000072950000007276000000727700000072340000002907727c000000728200000072940000007289000000727d00000072050000007296000000722700000072270000007228000000da0966657274696c697a6567010000731c00000000020a010801080110011c010c01180108010c0108010c010c010c0172a000000063020000000000000006000000090000004300000073ba00000074007c007c0183027d027c02640119007d037c02640219007d047c036403190074016a02640464058d0117007d0574037c056b047346740464067c059b0064079d03830182017c0364080500190074056a06640964048302380003003c007c0364081900640a6b007272640a7c0364083c0074037c0364033c007c0374077c04640b66023c007c03640c19007c03640d19007c03640e19007c03640f19007c03640819007c03641019007c03641119007c03641219006708530029134e727d000000720500000072610000007254000000290172980000007a3c596f7520617265207374696c6c20737175617368696e672062756773206f722070756c6c696e672077656564732e2054727920616761696e206174207299000000725a000000728e000000720100000072320000007256000000725800000072570000007259000000725b0000007263000000725c0000002908728a000000724a000000724b0000007224000000722d0000007276000000727700000072340000002906727c00000072820000007289000000727d0000007205000000729a000000722700000072270000007228000000da0970756c6c776565647379010000731e00000000020a01080108011401180118010c01080108010c0108010c010c010c0172a100000063020000000000000005000000090000004300000073a800000074007c007c0183027d027c02640119007d037c02640219007d047c0364030500190074016a02640464058302370003003c007c0364060500190074016a02640764088302380003003c007c036406190064096b00725e64097c0364063c0074037c00640a830201007c0374047c04640b66023c007c03640c19007c03640d19007c03640e19007c03640f19007c03640619007c03640319007c03641019007c03641119006708530029124e727d0000007205000000725b0000007217000000723e000000725a000000728b000000729c00000072010000007254000000723200000072560000007258000000725700000072590000007263000000725c0000002905728a00000072760000007277000000727800000072340000002905727c00000072820000007289000000727d0000007205000000722700000072270000007228000000da0a737072617977656564738c010000731c00000000020a0108010801180118010c0108010a010c0108010c010c010c0172a200000063020000000000000009000000060000004300000073d801000064017c009b0064027c019b009d047d02740074016a027c026602190064036b02732a740364048301820174047c0264056602190064066b027342740364078301820174047c026408660219007d037c03640919007d0474057c00640a660219007d0574067c056b01727274067c046b0573867403640b7c049b00640c7c059b009d048301820174077c037c0083027d0374087c0383017d037c03640d190064066b0272bc74067c03640e3c007c0374047c02640866023c00640f530074056410190064116b0272d86406740564103c006412740564133c0074097c037c0283027d037c0374047c02640866023c0074047c026414660219007d06740a641519007d07740b74047c0264166602190064177c06641819007c066419190014007c06641a190014007c06641b190014007c07641c13001b00140064037c03641d1900641e1b00180014007c03641f1900641e1b00140064037c0364201900641e1b0018001400170083017d087c0874047c02642166023c007c0874047c02642266023c0074057c0064236602050019007c08370003003c0074057c0064246602190064126b02900172bc74057c0064256602190074057c00642466023c0074047c0264056602190064116b020100740c7c0883017d087c08530029264e726d000000726e00000072170000007a1a596f7520646f206e6f74206f776e207468697320706c616e742eda0966696e616c697a6564467a265468697320706c616e742068617320616c7265616479206265656e2066696e616c697a65642e7232000000726400000072420000007a334974206973206e6f742074696d6520746f2066696e616c697a6520796f757220706c616e742e20547279206265747765656e207a0520616e64207260000000725f0000007a59596f757220706c616e7420697320646561642064756520746f206e65676c65637420616e6420796f752063616e6e6f742067726f7720616e7920626572726965732e2054727920616761696e206e65787420736561736f6e2e72140000005472010000007216000000726f0000007211000000727000000069e80300007269000000726a000000726b000000726c000000728c000000725b000000729000000072580000007263000000da0762657272696573da0b66696e616c5f73636f7265724300000072460000007245000000290d723500000072200000007221000000722d0000007234000000722300000072240000007286000000728800000072870000007222000000da03696e74da037374722909727c00000072820000007205000000727d000000da08656e645f74696d657242000000726f000000da066c656e67746872a4000000722700000072270000007228000000da0866696e616c697a659e0100007344000000000210010c010e010a010e010c0108010c0124010a0108010c0108010c0204020c01080108010a010c010c0108010c044a0112010c010c0114011201020112011001080172aa00000063020000000000000006000000050000004300000073ca00000064017c009b0064027c019b009d047d02740074016a027c026602190064036b02732a740364048301820174047c026405660219007d037c0364066b0473467403640783018201740574067c006408660219006b05736e7403640974067c006408660219009b00640a9d038301820174067c00640b6602190074067c00640c660219001b007d047c047c0314007d0574076a087c0574016a02640d8d020100640674047c02640566023c0074067c00640e6602050019007c05380003003c0074097c0583017d057c055300290f4e726d000000726e00000072170000007a1a596f7520646f206e6f74206f776e207468697320706c616e742e72a400000072010000007a23596f7520646f6e2774206861766520616e79206265727269657320746f2073656c6c2e72420000007a24596f752063616e27742073656c6c207965742e2054727920616761696e206166746572207a1a2062757420646f206e6f74207761697420746f6f206c6f6e672e724500000072430000002902723300000072370000007246000000290a723500000072200000007221000000722d000000723400000072240000007223000000da0863757272656e6379723800000072a70000002906727c0000007282000000720500000072a4000000da0a73656c6c5f7072696365da0870726f6365656473722700000072270000007228000000da0b73656c6c62657272696573c9010000731e000000000210010c010e010c011001120116010c010c01080110010c011401080172ae000000630200000000000000030000000600000043000000735e0000007400640183017d0274016a027c0164027c021800140074036a0474036a0564038d03010074016a027c017c02140074066404190074036a0564038d03010074077c0064056602050019007c0164027c0218001400370003003c006400530029064e7a04302e30357217000000290372330000007237000000723b000000720f00000072450000002908722e00000072ab000000723d0000007220000000da04746869737221000000722200000072230000002903727c0000007233000000da0a6465765f7265776172647227000000722700000072280000007278000000dc010000730c0000000001080112010a010c010e0172780000002902727c0000007233000000630200000000000000020000000500000043000000732c00000074006a017c0174026a0374026a0464018d03010074057c0064026602050019007c01370003003c006400530029034e290372330000007237000000723b0000007245000000290672ab000000723d000000722000000072af000000722100000072230000002902727c0000007233000000722700000072270000007228000000da116d616e75616c5f7265776172645f616464e501000073040000000002140172b10000002901727c000000630100000000000000030000000400000043000000736800000074006401190074016a026b027316740364028301820174047c006403660219007d0174057c016b057338740364047c019b009d028301820174047c006405660219007d027c0264066b047354740364078301820174066a077c0274016a0264088d0201006400530029094e720f0000007a264f6e6c7920746865206f70657261746f722063616e20636c61696d207374616c65207461752e72480000007a4054686520746175206973206e6f74207374616c652079657420616e642063616e6e6f7420626520636c61696d65642e2054727920616761696e20616674657220724600000072010000007a1f5468657265206973206e6f207374616c652074617520746f20636c61696d2e2902723300000072370000002908722200000072200000007221000000722d0000007223000000722400000072ab00000072380000002903727c0000007248000000da097374616c655f746175722700000072270000007228000000da0c7374616c655f636c61696d73eb010000730e0000000002060110010c0116010c01100172b3000000630000000000000000000000000300000043000000733e00000074006401190074016a026b027316740364028301820174047405640319006b04732a74036404830182016405740564063c006407740564083c006400530029094e720f0000007a1e4f6e6c7920746865206f70657261746f722063616e20646f20746869732e72400000007a2d596f752063616e277420656e642074686520736561736f6e206265666f72652074686520656e645f74696d652e467214000000720100000072160000002906722200000072200000007221000000722d000000722400000072230000007227000000722700000072270000007228000000da116d616e75616c5f736561736f6e5f656e64f6010000730c0000000002060110010e010601080172b40000002903727c0000007282000000724f00000063030000000000000004000000040000004300000073a600000064017c009b0064027c019b009d047d03740074016a027c036602190064036b02732a74036404830182017c026a0483000c00733c7403640583018201740574067c021900830164066b02735474036407830182017c026a07830064086b02736874036409830182017c02640a6b0373787403640b8301820174087c028301640c6b05738c7403640d8301820174097c00640e830201007c007c01670274067c023c0064005300290f4e726d000000726e00000072170000007a1a596f7520646f206e6f74206f776e207468697320706c616e742e7a2754686520706c616e74206e69636b6e616d652063616e277420626520616e20696e74656765722e467a1d54686973206e69636b6e616d6520616c7265616479206578697374732e547a254f6e6c7920616c7068616e756d65726963206368617261637465727320616c6c6f7765642e72280000007a144e616d652063616e6e6f7420626520656d707479723e0000007a23546865206d696e696d756d206c656e677468206973203320636861726163746572732e7255000000290a723500000072200000007221000000722d0000007272000000727300000072340000007274000000727500000072780000002904727c0000007282000000724f0000007205000000722700000072270000007228000000da0c6e65775f6e69636b6e616d65000200007316000000000210010c010e0112010a010e011401100114010a0172b50000002902da086e69636b6e616d65da0d66756e6374696f6e5f6e616d65630200000000000000040000000b00000043000000733800000074007c0019007d02740174027403740474057406740774087409740a64019c0a7d037c037c0119007c02640219007c02640319008302530029044e290a7297000000729b000000729d000000729e000000729f00000072a000000072a100000072a200000072aa00000072ae00000072010000007217000000290b72340000007297000000729b000000729d000000729e000000729f00000072a000000072a100000072a200000072aa00000072ae000000290472b600000072b7000000724f000000da0e66756e6374696f6e5f6e616d6573722700000072270000007228000000da146e69636b6e616d655f696e746572616374696f6e0f020000730c000000000208010401060106010a0172b90000002901da06656e61626c65630100000000000000030000000300000043000000733a0000007400640119007d0174016a027d027c027c016a0383006b067322740464028301820174057c0083017c017c023c007c01740064013c006400530029034e721c0000007a20596f7520617265206e6f7420617070726f76656420746f20646f20746869732e2906722500000072200000007221000000da046b657973722d00000072a6000000290372ba000000da13656d657267656e63795f616464726573736573da0c63616c6c5f61646472657373722700000072270000007228000000da0e655f77647261775f656e61626c6519020000730c0000000002080106010e0106010c0172be0000002901723300000063010000000000000004000000040000004300000073500000007400640119007d0174016a027d0274037c016a04830083017d037c0364026b05732a74056403830182017406640419007c026b02733e740564058301820174076a087c007c0264068d0201006400530029074e721c000000728e0000007a28416e20656d657267656e6379207769746864726177616c206973206e6f7420617070726f7665642e720f0000007a204f6e6c7920746865206f70657261746f722063616e20636c61696d207461752e2902723300000072370000002909722500000072200000007221000000da0373756dda0676616c756573722d000000722200000072ab00000072380000002904723300000072bc00000072bd000000da0e617070726f76616c5f636865636b722700000072270000007228000000da1b6d756c74697369675f656d657267656e63795f776974686472617723020000730e0000000002080106010c01100106010e0172c20000002901462901462901721700000029017217000000293272ab000000da085661726961626c65721d000000721f000000da044861736872340000007235000000723900000072230000007222000000722600000072250000007276000000da04736565647229000000da085f5f6578706f727472a70000007273000000722f000000da046469637472a600000072360000007238000000723a000000723d000000724e0000007281000000728a0000007286000000728700000072880000007297000000729b000000729d000000729e000000729f00000072a000000072a100000072a200000072aa00000072ae000000727800000072b100000072b300000072b400000072b500000072b900000072be000000da05666c6f617472c20000007227000000722700000072270000007228000000da083c6d6f64756c653e01000000738400000008010c0204010801060108010601080104010a010e010c010c010c0108030814060116080601100b06011409060114050601160c101806011436101608210821080906011610060112120601121106011214060112120601161106011212060112110601122a060112120809060112050601100a100a0601140e06011209060110090601