-
Notifications
You must be signed in to change notification settings - Fork 0
/
mandel3.p8
841 lines (751 loc) · 33.8 KB
/
mandel3.p8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
pico-8 cartridge // http://www.pico-8.com
version 29
__lua__
function _init()
colors={1,2,5,4,3,13,9,8,14,6,15,12,11,10,7}
orig_field_of_view=1/6
orig_turn_amount=.003
orig_speed = .1
--debug stuff, disable for release
force_draw_width=false
debug=false
--
largest_width=0
max_screenx_offset=0
skipped_columns=0
field_of_view=orig_field_of_view -- 45*
turn_amount=orig_turn_amount
speed = orig_speed
height_zoom_ratio = 1.05
screen_width = -sin(field_of_view/2) * 2
base_player_height = 0.09
player_height = base_player_height
player_foot_height = false
pixel_columns_i = 1
grid_division_factor = 5
max_additional_iterations=20
cached_grid=two_dim()
worked_grid=two_dim()
player = {
coords=makevec2d(-.749,1.1),
bearing=makeangle(.5)
}
prog_man={
current_max_iterations=false,
current_max_iterations_raw=5,
iteration_speed=0.1
}
pixel_columns={}
for i=0,127,16 do
add(pixel_columns,{
calc_screenx=i,
screenx=i,
prog_man=prog_man,
draw_width=16
})
end
for i=8,127,16 do
add(pixel_columns,{
calc_screenx=i,
screenx=i,
prog_man=prog_man,
draw_width=8
})
end
for i=4,127,8 do
add(pixel_columns,{
calc_screenx=i,
screenx=i,
prog_man=prog_man,
draw_width=4
})
end
for i=2,127,4 do
add(pixel_columns,{
calc_screenx=i,
screenx=i,
prog_man=prog_man,
draw_width=2
})
end
for i=1,127,2 do
add(pixel_columns,{
calc_screenx=i,
screenx=i,
prog_man=prog_man,
draw_width=1
})
end
draw_stars()
end
function _update60()
local offset = makevec2d(0,0)
local facing = player.bearing:tovector()
changed_position=false
changed_height=false
if btn(0) then
changed_position=true
player.bearing-=turn_amount
end
if btn(1) then
changed_position=true
player.bearing+=turn_amount
end
if btn(2) then
changed_position=true
offset+=facing
end
if btn(3) then
changed_position=true
offset-=facing
end
player.coords+= offset*speed*base_player_height
if prog_man.iteration_speed<5 then
prog_man.iteration_speed+=0.0001
end
prog_man.current_max_iterations_raw+=prog_man.iteration_speed
prog_man.current_max_iterations=flr(prog_man.current_max_iterations_raw)
if btn(5) then
changed_height=true
base_player_height/= height_zoom_ratio
end
if btn(4) then
changed_height=true
base_player_height*= height_zoom_ratio
end
if changed_height or not grid_size then
if 1/(2^(grid_division_factor+1)) > base_player_height/6 then
grid_division_factor+=1
elseif 1/(2^(grid_division_factor-1)) < base_player_height/6 then
grid_division_factor-=1
end
grid_size=1/(2^grid_division_factor)
draw_distance=base_player_height*10
end
if stat(0)/2048 > 0.9 then
reset_grid_cache=60
cached_grid=two_dim()
elseif reset_grid_cache then
reset_grid_cache-=1
if reset_grid_cache<=0 then
reset_grid_cache=false
end
end
update_player_height()
--printh(player.coords.x..","..player.coords.y)
end
function update_player_height()
if not first_iterations then
return
end
if player_foot_height then
player_foot_height+=mid(base_player_height*.1,base_player_height*-.1,height_transform(first_iterations)-player_foot_height)
else
player_foot_height=height_transform(first_iterations)
end
player_height=base_player_height+player_foot_height
first_iterations=false
end
progressive_coroutine=false
first_draw=true
function _draw()
if first_draw then
cls()
end
if is_drawing then
is_resuming=true
assert(coresume(progressive_coroutine,prog_man))
end
is_resuming=false
if first_draw or changed_position or changed_height then
progressive_coroutine=cocreate(raycast_walls_progressively)
end
is_drawing=true
assert(coresume(progressive_coroutine,prog_man))
if reset_grid_cache then
rectfill(25,59,102,67,1)
rectfill(26,60,101,66,0)
print("reclaiming cache...",27,61,7)
end
if debug then
debug_info()
end
first_draw=false
end
function debug_info()
--printh("DEBUG")
printh(player.bearing.val)
printh(tostr(player.coords.x)..","..tostr(player.coords.y))
if stat(7) < 60 then
printh(stat(7))
printh(stat(1))
end
end
stars={}
function draw_stars()
stars={}
local x,y,angle
color(7)
angle=player.bearing-field_of_view/2
local init=flr(angle.val*100)
local final=flr((angle.val+field_of_view)*100)
local x
for i=init,final do
x=flr((i-init)/100/field_of_view*128)
if not stars[x] then
stars[x]={}
end
add(stars[x],flr(64-((i*19)%64)*orig_field_of_view/field_of_view))
end
end
function raycast_walls_progressively(prog_man)
local should_recache=true
if pixel_columns_i > 64 then
--worked_grid=two_dim()
pixel_columns_i = 1
end
pixel_columns_i_done=pixel_columns_i
local max_draw_width=min(8,pixel_columns[pixel_columns_i].draw_width)
local drawn_all=false
local resetting=false
while true do
raycast_pixel_column(pixel_columns[pixel_columns_i], max_draw_width, should_recache)
pixel_columns_i+=1
if pixel_columns_i > 64 and not drawn_all then
pixel_columns_i=1
resetting=true
end
if pixel_columns_i > #pixel_columns then
pixel_columns_i=1
resetting=true
end
if pixel_columns_i == pixel_columns_i_done then
drawn_all=true
end
if resetting then
resetting=false
worked_grid=two_dim()
if drawn_all then
should_recache=false
--kjfgkdfjgd()
max_draw_width=1
end
end
end
end
function raycast_pixel_column(pixel_column, max_draw_width, should_recache) -- TODO: pass in a copy of the player
local pa,pv,currx,curry,intx,inty,xstep,ystep,distance
local height,distance_to_pixel_col,screeny,max_y,lowest_y,current_draw_distance,blocker_ratio
local calc_screenx,screenx,draw_width
local prog_man=pixel_column.prog_man
if should_recache or not pixel_column.cache then
pixel_column.cache={}
end
local cache=pixel_column.cache
calc_screenx=pixel_column.calc_screenx
if not cache.pa then
cache.pa=screenx_to_angle(calc_screenx) -- TODO: make this take in a copy of the player
end
pa=cache.pa
if not cache.pv then
cache.pv=pa:tovector()
end
pv=cache.pv
screenx=pixel_column.screenx
draw_width=min(max_draw_width, pixel_column.draw_width)
xstep=towinf(pv.x)*grid_size
ystep=towinf(pv.y)*grid_size
currx=round((player.coords.x+xstep/2)/grid_size)*grid_size-xstep/2
curry=round((player.coords.y+ystep/2)/grid_size)*grid_size-ystep/2
local initx=currx
local inity=curry
-- TODO: make this stuff work with the variable grid size
-- take the largest coord difference from player coord (eg, if most of the difference is across x, then take x difference)
-- for some number Z indicating how big the grid is, make the grid ceil(x_difference/Z)
-- that way it won't switch grids in the middle of a larger grid
-- for this to work, the result needs to be only powers of 2... or rather, each new grid size needs to be double the last
-- haven't figured out whether the raw value should be rounded up to the next power of two or down to the last
if abs(pv.x) > abs(pv.y) then
intx= currx - xstep/2
distance = (intx - player.coords.x) / pv.x
inty= player.coords.y + distance * pv.y
else
inty= curry - ystep/2
distance = (inty - player.coords.y) / pv.y
intx= player.coords.x + distance * pv.x
end
distance_to_pixel_col = 1/cos(pa.val-player.bearing.val)
max_y = 127
lowest_y = 128
current_draw_distance=draw_distance
blocker_ratio=false
did_draw=false
local first_loop=true
local max_wall_height=height_transform(prog_man.current_max_iterations)
local front_distance,temp_max_y
local maxed_out
while distance < current_draw_distance and not maxed_out do
front_distance=distance
maxed_out=false
iterations = mandelbrot(currx, curry, prog_man.current_max_iterations) --flr(10*(currx+curry))
if iterations <= 0 then
maxed_out=true
if iterations == 0 then
iterations=prog_man.current_max_iterations
else
iterations=abs(iterations)
end
end
if first_loop and not first_iterations then
first_iterations=iterations
end
first_loop=false
height = height_transform(iterations)
relative_height = height - player_height
if relative_height < 0 then
-- hack to make the distance calculated to the far wall rather than close wall for if we can see the top so it doesn't look empty
-- distance gets overwritten each iteration so this is (for now) fine to do
-- there's probably a more efficient way to do this, but screw it
if (currx + xstep/2 - intx) / pv.x < (curry + ystep/2 - inty) / pv.y then
distance = (currx + xstep/2 - player.coords.x) / pv.x
else
distance = (curry + ystep/2 - player.coords.y) / pv.y
end
end
screen_distance_from_center = relative_height * distance_to_pixel_col / distance
pixels_from_center = 128 * (screen_distance_from_center/screen_width)
screeny = flr(63.5 - pixels_from_center)
if screeny <= max_y then
-- this draws black from bottom of the screen up to the lowest thing we draw if the lowest thing isn't at the bottom
-- hypothetically this might not be necessary, but leaving it commented for now
-- if not did_draw then
-- temp_max_y=min(max_y,ceil(63.5 - 128 * ((-player_height * distance_to_pixel_col / front_distance)/screen_width))) --y of bottom front of stretched cube
-- if temp_max_y < max_y then
-- rectfill(screenx, temp_max_y+1, screenx+draw_width-1, max_y, 0)
-- end
-- max_y=min(temp_max_y,max_y)
-- end
if relative_height > 0 then
current_draw_distance=min(current_draw_distance,distance * (max_wall_height-player_height)/relative_height)
end
did_draw=true
if front_distance < distance then
--draw the front first
screen_distance_from_center_front = relative_height * distance_to_pixel_col / front_distance
pixels_from_center_front = 128 * (screen_distance_from_center_front/screen_width)
screeny_front = flr(63.5 - pixels_from_center_front)
if screeny_front <= max_y then
rectfill(screenx, max_y, screenx+draw_width-1, screeny_front, color_transform(iterations))
max_y=screeny_front-1
end
--then draw the top
if screeny <= max_y then
rectfill(screenx, max_y, screenx+draw_width-1, screeny, color_transform(iterations,true))
end
else
rectfill(screenx, max_y, screenx+draw_width-1, screeny, color_transform(iterations))
end
fillp(0)
lowest_y = min(screeny,lowest_y)
max_y = screeny-1
--printh(draw_width)
end
if is_resuming or stat(1) > 0.9 then
is_drawing=false
yield()
end
if (currx + xstep/2 - intx) / pv.x < (curry + ystep/2 - inty) / pv.y then
intx= currx + xstep/2
distance = (intx - player.coords.x) / pv.x
inty= player.coords.y + distance * pv.y
currx+= xstep
else
inty= curry + ystep/2
distance = (inty - player.coords.y) / pv.y
intx= player.coords.x + distance * pv.x
curry+= ystep
end
end
if lowest_y > 0 then
if maxed_out then
fillp(0b0101101001011010)
rectfill(screenx, lowest_y-1, screenx+draw_width-1, 0, 0x01)
fillp(0)
else
-- draw the sky/stars if the lowest y (highest on the screen) isn't 0
rectfill(screenx, lowest_y-1, screenx+draw_width-1, 0, 0)
for starx=screenx,screenx+draw_width-1 do
if stars[starx] then
for i=1,#stars[starx] do
if stars[starx][i] < lowest_y then
pset(starx, stars[starx][i], 7)
end
end
end
end
end
end
end
shift_map={1, 9, 13, 2, 4, 12, 14, 6, 11, 8, 3, 7, 5, 0, 10, 15}
iteration_cache={}
function color_transform(iterations,is_top)
if iterations < 100 then
iterations*=4
else
iterations+=400
end
if is_top then
iterations+=8
end
if iteration_cache[iterations] then
fillp(iteration_cache[iterations][2])
return iteration_cache[iterations][1]
end
local scaled=(iterations/16) % 14
local diff=ceil(scaled)-scaled
local flp=0
for i=1,flr(diff*16) do
flp|=shl(1,shift_map[i+1])
end
fillp(flp)
iteration_cache[iterations] = {colors[1+ceil(scaled)]+colors[1+flr(scaled)]*16,flp}
return iteration_cache[iterations][1]
end
function height_transform(iterations)
return iterations^min(.5,base_player_height)/4
end
log10_table = {
0, 0.3, 0.475,
0.6, 0.7, 0.775,
0.8375, 0.9, 0.95, 1
}
function logx(x,n)
return log10(n)/log10(x)
end
function log10(n)
if (n < 1) return nil
local e = 0
while n > 10 do
n /= 10
e += 1
end
return log10_table[flr(n)] + e
end
function mandelbrot(x, y, current_max_iterations)
local y=abs(y)
x=towinf(x/grid_size)*grid_size
y=towinf(y/grid_size)*grid_size
if not cached_grid[x][y] then
cached_grid[x][y]={
0,
0,
0
}
end
local cache=cached_grid[x][y]
if worked_grid[x][y] then
if cache[3] < 0 and abs(cache[3]) >= flr(current_max_iterations) then
return 0
else
return cache[3]
end
end
worked_grid[x][y]=true
if abs(cache[3]) >= flr(current_max_iterations) then
cache[3]= -flr(current_max_iterations)
return 0
end
local zx=cache[1]
local zy=cache[2]
local xswap
local i=abs(cache[3])
local max_iterations=min(flr(current_max_iterations),i+max_additional_iterations)
while i < max_iterations and abs(zx) < 2 and abs(zy) < 2 do
i+= 1
xswap = zx*zx - zy*zy + x
zy = (zy + zy)*zx + y
zx = xswap
end
cache[1]=zx
cache[2]=zy
if i < flr(max_iterations) then
cache[3]=i
return i
else
cache[3]=-i
if i < flr(current_max_iterations) then
return -i
else
return 0
end
end
end
function screenx_to_angle(screenx)
local offset_from_center_of_screen = (screenx - 127/2) * (screen_width/128)
return makeangle(player.bearing.val+atan2(offset_from_center_of_screen, 1)+1/4)
end
--NB - not currently used
function angle_to_screenx(angle)
local offset_from_center_of_screen = -sin(angle.val-player.bearing.val)
return round(offset_from_center_of_screen/screen_width * 128 + 127/2)
end
makeangle = (function()
local mt = {
__add=function(a,b)
if type(a) == "table" then
a=a.val
end
if type(b) == "table" then
b=b.val
end
local val=a+b
if val < 0 then
val = abs(flr(val))+val
elseif val >= 1 then
val = val%1
end
return makeangle(val)
end,
__sub=function(a,b)
if type(b) == "number" then
return a+makeangle(-b)
else
return a+makeangle(-b.val)
end
end
}
local function angle_tovector(a)
return makevec2d(cos(a.val-.25),sin(a.val-.25))
end
return function(angle)
local t={
val=angle,
tovector=angle_tovector
}
setmetatable(t,mt)
return t
end
end)()
makevec2d = (function()
mt = {
__add = function(a, b)
return makevec2d(
a.x + b.x,
a.y + b.y
)
end,
__sub = function(a,b)
return a+makevec2d(-b.x,-b.y)
end,
__mul = function(a, b)
if type(a) == "number" then
return makevec2d(b.x * a, b.y * a)
elseif type(b) == "number" then
return makevec2d(a.x * b, a.y * b)
else
return a.x * b.x + a.y * b.y
end
end,
__div = function(a,b)
return a*(1/b)
end,
__eq = function(a, b)
return a.x == b.x and a.y == b.y
end
}
local function vec2d_tostring(t)
return "(" .. t.x .. ", " .. t.y .. ")"
end
local function magnitude(t)
return sqrt(t.x*t.x+t.y*t.y)
end
local function bearing(t)
return makeangle(atan2(t.x,t.y))+.25
end
local function diamond_distance(t)
return abs(t.x)+abs(t.y)
end
local function normalize(t)
return t/t:tomagnitude()
end
local function project_onto(t,direction)
local dir_mag=direction:tomagnitude()
return ((direction*t)/(dir_mag*dir_mag))*direction
end
local function cross_with(t,vector)
-- signed magnitude of 3d cross product
return t.x*vector.y-t.y*vector.x
end
return function(x, y)
local t = {
x=x,
y=y,
tostring=vec2d_tostring,
tobearing=bearing,
tomagnitude=magnitude,
diamond_distance=diamond_distance,
project_onto=project_onto,
cross_with=cross_with,
normalize=normalize
}
setmetatable(t, mt)
return t
end
end)()
function round(n)
return flr(n+0.5)
end
function towinf(n) -- rounds to the larger number regardless of sign (eg, -0.4 to -1)
if n > 0 then
return -flr(-n)
else
return flr(n)
end
end
two_dim_parent_mt={
__index=function(obj,key)
obj[key]={}
return obj[key]
end
}
function two_dim()
local obj={}
setmetatable(obj,two_dim_parent_mt)
return obj
end
__gfx__
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__label__
52222222255505555500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
52222222255505555500000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000000000000000000000
52222222255555555500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
44222222255555555555555555000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000700000
44222222255555555555555555550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
44222222255555555555555555550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
44222222255555555555555555555000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
44222222255555555555555555555500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
44222222255555555555555555555522202222200000000000000000000000000000070000000000000000000000000000000000000000000000000000000000
44222222255555555555555555555522202222220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
44222222255555555555555555555522222222220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
44222222255555555555555555555522222222222222222222222222220000000000000000000000000000000000000000000000000000000000000000000000
44222222255555555555555555555542222222222222222222222222222000000000000000000000000000000000000000000000000000000000000000000000
44222222255555555555555555555542222222222222222222222222222000000000000000000000000000000000000000000000000000000000000000000000
44222222255555555555555555555542222222222222222222222222222555555000000000000000000000000000000000000000000000000000000000000000
44222222255555555555555555555542222222222444222222222222222555555000000000000000000000000000700000000000000000000000000000000000
44d22222255555555555555555555542222222222444222222222222222555555555550000000000000000000000000000000000000000000000000000000000
44d22222255555555555555555555542222222224444222222222222222555555555550000000000000000000000000000000000000000000000000000000000
44d22222255555555555555555555542222222224444422222222222222555555555555500000000000000000000000000000000000000000000000000000000
44d22222255555555555555555555542222222224444422222222222222555555555555500000000000000000000000000000000000000000000000000000000
44d22222255555555555555555555542222222224444422222222222222555555555555550000000000000000000000000000000000000000000000000000000
44d22222255555555555555555555542222222224444422222222222222555555555555550000000000000000000000000000000000000000000000000000000
44d22222255555555555555555555542223222224444422222222222222555555555555550000000000000000000000000000000000000000007000000000000
44d22222255555555555555555555542223222224444432222222222222555555555555550000000000000000000000000000000000000000000000000000000
44d22222255555555555555555555543223222224444432222222222222555555555555554000000000000000000000000000000000000000000000000000000
44d22222255555555555555555555543223322224444433222222222222555555555555554000000000000000000000000000000000000000000000000000000
44d22222255555555555555555555543223322224444433222222222222555555555555554000000000000000000000000000000000000000000000000000000
44d22222255555555555555555555543223322224444433222222222222555555555555554220000000000000000000000000000000000000000000000000000
44d22222255555555555555555555543223322224444433222222222222555555555555554220000000000000000000000000000000000000000000000000000
44d22222255555555555555555555543223322224444433222222222222555555555555554225550000000000000000000000000000000000000000000000000
44d22222255955555555555555555543223322224444433222222222222555555555555554225555000000000000000000000000000000000000000000000000
44d22222255955555555555555555543223322224444433222222222222555555555555554225555520000000000000000000000000000000000000000000000
44d22222255955555555555555555543223322224444433222222222222555555555555554244555522222222200000020000000000000000000000000000000
44d22222255995555555555555555543223322224444433d22222222222555555555555554244555552222222222222220000000000000000000000000000000
44d22222255995555555555555555543223322224444433d22222222222555555555555554344355552222222222222225500000000000000000000000000000
44d22222255995555555555555555543223322224444433d22222222222555555555555554344355552222222222222225550000000000000000000000000000
44d22222255995555555555555555543223322224444433d22222222222555555555555554344355552222222222222225555000000000000000000000000000
44d22222255995555555555555555543293322224444433d22222222222555555555555554344355552222222222222225555550000000000000000000000000
44d22222255995555555555555555543293322224444433d22222222222555555555555554344355552322222222222225555554000000000000000000000000
44d22222255995555555555555555543293322224444433d22222222222555555555555554344355552322222222222225555554000000000000000000044440
44d22222255995555555555555555543293322224444433d22222222222555555555555554344355552332222222222225555554000000000000000000044440
44d22222255995555555555555555543293322224444433d22222222222555555555555554344355552332222222222225555554400700000000000000044440
44d22222255995555555555555555543293322224444433d222222222225555555555555543443d5552332222222222225555554400000000000000000044440
44d22222255995555555555555555543293322224444433d222222222225555555555555543443d5552332222222222225555554400000000000000000044443
44d22222255995555555555555555543293322224444433d222222222225555555555555543443d555d332222222222225555554400000000000000000044443
44d22222255995555555555555555543293322284444433d222222222225555555555555543443d555d332222222222225555554400000000000000000044443
44d22222255995555555555555555543293322284444433d222222222225555555555555543443d555d332222222222225555554400000000000000000d44443
44d22222255995555555555555555543293322284444433d222222222225555555555555543443d555d3322222222222255555544d0000000000000000d44443
44d22222255995555555555555555543293322284444433d222222222225555555555555543443d555d3322222222222255555544d0000000000000000d44443
44d2ee22255995555555555555555543293322284444433d222222222225555555555555543443d555d3322222222222255555544d0000000000000000d44443
44d2ee22255995555555555555555543293382284444433d222222222225555555555555543443d555d3392222222222255555544d0000000000000000d44443
44d2ee22255995555555555555555543293382284444433d222222222225555555555555543443d555d3392222222222255555544d0000000000000000d44443
44d2ee22255995555555555555555543293382284444433d222222222225555555555555543443d555d3392222222222255555544d0000000000000000d44443
44d2ee22255995555555555555555543293382284444433d222222222225555555555555543443d555d3392222222222255555544d0000000000000000d44443
44d2ee22255995555555555555555543293382284444433d222222222225555555555555543443d555d3392222222222255555544d8000000000000000d44443
44d2ee22255995555555555555555543293382284444433d222222222225555555555555543443d555d3392222222222255555544d8000000000000000d44443
44d2ee22255995555555555555555543293382284444433d222222222225555555555555543443d555d3392222222222255555544d8000000000000000d44443
44d2ee22255995555555555555555543293382284444433d222222222225555555555555543443d555d3392222222222255555544d8000000000000000d44443
44d2ee22255995555555555555555543293382284444433d222222222225555555555555543443d555d3392222222222255555544d8000000000000000d44443
44d2ee22255995555555555555555543293382284444433d222222222225555555555555543443d555d3392222222222255555544d8000000000000000d44443
44d2ee22255995555555555555555543293382284444433d22222e222225555555555555543443d555d3392222222222255555544d8000000000000000d44443
44d2ee22255995555555555555555543293382284444433d22222e222225555555555555543443d555d339222222222e255555544d8000000000000000d44443
44d2ee22256996555555555555555543293386684444433d22222e222225555555555555543443d555d339222222222e255555544d8000000000000000d44443
44d2ee22256996555555555555555543293386684444433d22222e222225555555555555543443d555d339222222222e255555544d8000000000000600d44443
44d2ee22256996555555555555555543293386684444433d22222e222225555555555555543443d555d339222222222e255555544d8000000000000600d44443
44d2ee22256996555555555555555543293386684444433d22222e222225555555555555543443d555d339222222222e255555544d8000000000000600d44443
44d2ee22256996555555555555555543293386684444433d22222e222225555555555555543443d555d339222222222e255555544d8000000000000600d44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d339222222222e255555544d8000000000000600d44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d339222222222e255555544d800000000000f600d44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d339222222222e255555544d8f0000000000f600d44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d339222222222e255555544d8f0000000000f600d44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d339222222222e255555544d8f0000000000f600d44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d339222222222e255555544d8f0000000000f600d44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d339222222222e255555544d8f0000000000f600d44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d339222222222ec55555544d8f0000000000f600d44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d339222222222ec55555544d8f0000000000f600d44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d339222222222ec55555544d8f0000000000f600d44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d339222222222ec55555544d8f0000000000f60bd44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d339222222222ec55555544d8f0000000000f60bd44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d339222222222ec55555544d8f0000000000f60bd44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d3392b2222222ec55555544d8f0000000000f60bd44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d3392b2222222ec55555544d8f0000000000f60bd44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d3392b2222222ec55555544d8f0000000000f60bd44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d3392b2222222ec55555544d8f0000000000f60bd44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d3392b2222222ec55555544d8f0000000000f60bd44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d3392b2222222ec55555544d8f0000000000f60bd44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d3392b2222222ec55555544d8f0000000000f60bd44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d3392b2222222ec55555544d8f0000000000f60bd44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d3392b2222222ec55555544d8f0000000000f60bd44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d3392b2222222ec55555544d8f0000000000f60bd44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d3390b0000000ec00000544d8f0000000000f60bd44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d3390b0000000ec000000000000000000000f60bd44443
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d3390b0000000ec0000000000000000000000000000000
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d3390b0000000ec0000000000000000000000000000000
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d555d3390b0000000ec0000000000000000000000000000000
44d2ee22256996555555555555555543293386684444433d22222e226225555555555555543443d0000000000000000ec0000000000000000000000000000000
44d2ee22256996555555555555555543293386684444433d222a2e226225555555555555543443d0000000000000000000000000000000000000000000000000
44d2ee22256996555555555555555543a93386684444433d222a2e226225555555555555543443d0000000000000000000000000000000000000000000000000
44d2ee22256996555555555555555543a93386684444433d222a2e226225555555555555543443d0000000000000000000000000000000000000000000000000
44d2ee22256996555555555555555543a93386684444433d222a2e226225555555555555543443d0000000000000000000000000000000000000000000000000
44d2ee22256996555555555555555543a93386684444433d222a2e226225555555555555543443d0000000000000000000000000000000000000000000000000
44d2ee22256996555555555555555543a93386684444433d222a2e22622555555555555554000000000000000000000000000000000000000000000000000000
44d2ee22256996555555555555555543a93386684444433d222a2e22622555555555555554000000000000000000000000000000000000000000000000000000
44d2ee22256996555555555555555543a93386684444433d222a2e22622555555555555554000000000000000000000000000000000000000000000000000000
44d2ee22256996555555555555555543a93386684444433d222a2e22622555555555555554000000000000000000000000000000000000000000000000000000
44d2ee22256996555555555555555543a93386684444433d222a2e22622555555555555554000000000000000000000000000000000000000000000000000000
44d2ee22256996555555555555555543a93386684444433d222a2e22622555555555555554000000000000000000000000000000000000000000000000000000
44d2ee22256996555555555555555543a93386684444433d222a2e22622555555555555554000000000000000000000000000000000000000000000000000000
44d2ee2225699655a555555555555543a93386684444433d222a0e00600000000000000000000000000000000000000000000000000000000000000000000000
44d2ee2225699655a555555555555543a93386684444433d000a0e00600000000000000000000000000000000000000000000000000000000000000000000000
44d2ee2225699655a555555555555543a93386684444433d000a0e00600000000000000000000000000000000000000000000000000000000000000000000000
44d2ee2225699655a555555555555543a93386684444433d000a0e00600000000000000000000000000000000000000000000000000000000000000000000000
44d2ee2225699655a555555555555543a93386684444433d000a0e00600000000000000000000000000000000000000000000000000000000000000000000000
44d7ee2225699655a555555555555543a93386684444433d000a0e00600000000000000000000000000000000000000000000000000000000000000000000000
44d7ee2225699655a555555555555543a93386684444433d000a0e00600000000000000000000000000000000000000000000000000000000000000000000000
44d7ee2225699655a555555555555543a93386684444433d000a0e00600000000000000000000000000000000000000000000000000000000000000000000000
44d7ee2225699655a555555555555543a93386684444433d000a0e00600000000000000000000000000000000000000000000000000000000000000000000000
44d7ee2225699655a555555555555543a93386684444433d00000000000000000000000000000000000000000000000000000000000000000000000000000000
44d7ee2225699655a555555555555543a93300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
44d7ee2225699655a555555555000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
44d7ee2225699655a500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
44d7ee2225699600a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
44d7ee0000699600a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
44d7ee0000699600a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
44d7ee0000699600a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
44d7ee0000699600a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
44d7ee0000699600a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
44d7ee0000699600a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000