vacation/vacation.p8

2055 lines
70 KiB
Lua
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

pico-8 cartridge // http://www.pico-8.com
version 41
__lua__
-- vacation (18+)
-- kistaro windrider
--------------------------------
-- copyright (C) 2024 kistaro windrider
--
-- this program is free software; you can redistribute it and/or modify
-- it under the terms of the gnu general public license as published by
-- the free software foundation; either version 2 of the license, or
-- (at your option) any later version.
--
-- this program is distributed in the hope that it will be useful,
-- but without any warranty; without even the implied warranty of
-- merchantability or fitness for a particular purpose. see the
-- gnu general public license for more details.
--------------------------------
-- monogram font by vincius menezio
-- https://datagoblin.itch.io/monogram
-- tab 0: library
-- tab 1: p8 entry points
-- tabs 2...F: actual code
function usplit(str)
return unpack(split(str))
end
function csv(s)
local ret = split(s, "\n")
for i, v in ipairs(ret) do
ret[i] = type(v) == "string" and split(v) or { v }
end
return ret
end
function hz(n)
return t()*2*n&1~=0
end
-- generate standard "overlay"
-- constructor for type tt.
-- if more is defined, generated
-- new calls more(ret) after
-- ret is definitely not nil
-- before calling setmetatable.
-- use to initialize mutables.
--
-- if there was a previous new,
-- it is invoked on the new
-- object *after* more, because
-- this works better with the
-- `more` impls i use.
function mknew(tt, more)
local mt, oldnew={__index=tt},tt.new
tt.new=function(ret)
if (not ret) ret = {}
if (more) more(ret)
if (oldnew) oldnew(ret)
setmetatable(ret, mt)
return ret
end
end
event_list = {is_event_list=true}
mknew(event_list, function(x)
x.next=nil
x.tail=x
end)
function event_list:push_back(x)
self.tail.next = x
self.tail = x
end
function event_list:strip(f)
local p, n = self, self.next
while n do
if f(n) then
p.next = n.next
else
p = n
end
n = n.next
end
self.tail = p
return p
end
function event_list:update()
local p, n = self, self.next
while n do
if n:update() then
p.next = n.next
else
p = n
end
n = n.next
end
self.tail = p
return p
end
function event_list:draw()
local n = self.next
while n do
n:draw()
n = n.next
end
end
-- if t[mname] is a thing,
-- invoke it as a method. else,
-- try each object in t
function outer_or_each_opt(t, mname)
local fun = t[mname]
if fun then
fun(t)
return
end
foreach(t, function(o)
local f = o[mname]
if(f) f(o)
end)
end
function nop() end
blank = {}
function blank:update() end
function blank:draw() end
-- puke emits a verbose string
-- describing item, indented to
-- the specified depth (0 by
-- default). used for table
-- debugging. table-type keys
-- are not legible here
function puke(item, indent, seen, hidekey)
if (type(item) ~= "table") return tostr(item)
seen = seen or {}
if (seen[item]) return "<<...>>"
seen[item] = true
indent = indent or 0
local pfx = "\n"
for _=1,indent do
pfx ..= " "
end
local xpfx = pfx.." "
if item.is_event_list then
local ret,n = "event_list <",0
item:strip(function(x)
n += 1
ret ..= xpfx..tostr(n)..": "..puke(x, indent+2, seen, "next")
end)
return ret..pfx..">"
end
local ret = "{"
for k, v in pairs(item) do
if (k ~= hidekey) ret ..= xpfx..tostr(k)..": "..puke(v, indent+2, seen)
end
return ret..pfx.."}"
end
-- convenience for debugging
function puketh(item, ...)
printh(puke(item), ...)
end
function pukeboard(item)
puketh(item, "@clip")
end
-------------------------------
-- view
-------------------------------
-- composits drawable items.
-- add items to .views to
-- composit them. x and y are
-- relative reverse camera
-- offsets. drawable items will
-- observe appropriate incoming
-- camera and clip state.
-- clipping respects existing
-- clipping so stacked views
-- intersect.
-------------------------------
view = {
x=0,
y=0,
w=255,
h=128,
}
mknew(view, function(x)
if (not x.views) x.views = {}
end)
function view.of(subviews)
return view.new{views=subviews}
end
function view:update()
outer_or_each_opt(self.views, "update")
end
function view:draw()
local oldcam, oldclip = $0x5f28, $0x5f20
poke2(0x5f28, %0x5f28-self.x)
poke2(0x5f2a, %0x5f2a-self.y)
clip(-%0x5f28, -%0x5f2a, self.w, self.h, true)
outer_or_each_opt(self.views, "draw")
poke4(0x5f20, oldclip)
poke4(0x5f28, oldcam)
end
-- draws opaque rectangles.
-- default bg is equivalent to
-- clip-aware cls.
-- restores prior fill pattern.
bg = {
x=0,y=0,w=128,h=128,fp=0,c=0
}
mknew(bg)
function bg:draw()
local oldfp=fillp(self.fp)
rectfill(self.x,self.y,self.x+self.w,self.y+self.h,self.c)
fillp(oldfp)
end
-->8
-- setup and p8 entry points
function _init()
-- disable btnp repeat
-- TODO: set back to 30 frames
-- outside of game mode
poke(0x5f5c, 255)
-- complex fill API mode
poke(0x5f34, 1)
awakener_hold_frames = 0
-- debug mode: skip splahes
-- mainview = ao_splash.new()
arm_awakener()
mainview=newtitle()
end
function arm_awakener()
awakener_hold_frames=0
awakener_armed=true
end
function _update60()
if awakener_armed then
if btn() & 0x30 > 0 then
awakener_hold_frames += 1
else
awakener_hold_frames = 0
end
if awakener_hold_frames == 90 then
exit_dither = ditherer.new{di=1}
awakener_armed = false
end
end
if exit_dither and exit_dither:update() then
exit_dither = nil
awakener_hold_frames=0
mainview = fast_awakener.new()
end
mainview:update()
end
function _draw()
mainview:draw()
if awakener_hold_frames >= 30 then
local gpx=(awakener_hold_frames-30) * 2 + 7
rectfill(0,0,gpx,9,4)
rectfill(gpx+1,0,128,9,5)
font_default()
print("keep holding for awakener", 1, 1, 7)
font_special()
end
if exit_dither then
exit_dither:draw()
end
end
function font_monogram()
memcpy(0x5600, 0x2000, 0x800)
poke(0x5f58, 0x81)
end
function font_compact()
memcpy(0x5600, 0x2800, 0x800)
poke(0x5f58, 0x81)
end
function font_default()
poke(0x5f58, 0x80)
end
function font_special()
poke(0x5f58, 0x81)
end
-->8
-- text rendering
-- text colors for zonk mode:
txtbox = {
x=0,
y=0,
f=0,
interval=4,
mode=0x81,
}
mknew(txtbox, function(self)
if (not self.cols) self.cols = {14,10,9,8}
self.c = deli(self.cols)
end)
function txtbox:update()
if #self.cols > 0 then
self.f += 1
if self.f >= self.interval then
self.f = 0
self.col = deli(self.cols)
end
end
end
function txtbox:draw()
poke(0x5f58, self.mode)
print(self.text, self.x, self.y, self.col)
end
function txtbox:xmax()
return print(self.text, self.x, -9999)
end
spring = {
from = 128,
to = 0,
frames=120,
f = 0,
}
mknew(spring)
function easeoutovershoot(t)
t-=1
return 1+2.7*t*t*t+1.7*t*t
end
function spring:update()
local v = self.v
self.v:update()
if self.f >= self.frames then
v.y=self.to
return true
end
local t, range = self.f/self.frames, self.to - self.from
v.y = self.from + easeoutovershoot(t)*range
self.f += 1
end
function spring:draw()
self.v:draw()
end
scoot = {
from=0,
to=-128,
frames=60,
f=0,
}
mknew(scoot)
function scoot:update()
local v = self.v
self.v:update()
if self.f >= self.frames then
v.y=self.to
return true
end
self.f += 1
if self.f <= 0 then
v.y=self.from
return
end
local t, range = self.f/self.frames, self.to - self.from
v.y = self.from + range * t * t * t
end
function scoot:draw()
self.v:draw()
end
scootbox = {}
mknew(scootbox, function(x)
x.v = view.new{
x=x.x,
y=x.from or scoot.from,
}
x.s = scoot.new{
from=x.from or scoot.from,
to=x.to or scoot.to,
frames=x.frames or scoot.frames,
v=x.v
}
end)
function scootbox:update()
if self.go then
self.s:update()
else
self.v:update()
end
end
function scootbox:push(drawable)
add(self.v.views, drawable)
end
function scootbox:done()
return self.s.f >= self.s.frames
end
function scootbox:draw()
return self.v:draw()
end
nrm_txt_pal = split"14,10,9,8"
sfd_txt_pal = split"15,10,9,8"
hlt_txt_pal = split"13,11,9,8"
shd_txt_pal = split"12,12,1,0"
function cparr(t)
local ret = {}
for i,x in ipairs(t) do
ret[i]=x
end
return ret
end
function zonk_txt(s, x, y, p, md, amt, frms)
md = md or 0x80
frms = frms or 0
amt = amt or 0
local itv = (frms>>2)&0x7ff
local t1 = txtbox.new{
x=x+1,
y=y+1,
interval=itv,
cols=cparr(shd_txt_pal),
mode=md,
text=s,
}
local v = view.of{
t1,
txtbox.new{
x=x,
y=y,
interval=itv,
cols=cparr(p),
mode=md,
text=s,
},
}
itv=spring.new{
from=amt,
frames=frms,
v=v,
}
itv.eff_w=t1:xmax()-1
return itv
end
-->8
-- zonk renderer
fadetable = split"0,1.5,1025.5,1029.5,1285.5,1413.5,9605.5,9637.5,-23130.5,-23066.5,-18970.5,-18954.5,-2570.5,-2568.5,-520.5,-8.5,-0.5"
ditherer = {
i = 0,
di = 0.25,
c=0,
pattern=fadetable,
}
mknew(ditherer, function(x)
if (x.di and x.di < 0 and not x.i) x.i = (x.pattern and #x.pattern or #fadetable) + 0.99
end)
function ditherer:update()
if (self.i > 0 and self.di < 0) self.i += self.di
if (self.i < #self.pattern + 1 and self.di > 0) self.i += self.di
return self.i < 0 or self.i >= #self.pattern + 1
end
function ditherer:draw()
local idx = min(flr(self.i), #self.pattern)
if (idx < 1) idx = 1
fillp(self.pattern[#self.pattern+1-idx])
rectfill(0,0,128,128,self.c)
end
fuzzy = {
p = 0xffff,
n = 0,
interval = 3,
tries = 4,
}
mknew(fuzzy, function(x)
local p = (x.p or fuzzy.p) & 0xffff
x.mass = 0
while p ~= 0 do
x.mass += p & 1
p = (p >>> 1) & 0xffff
end
end)
function fuzzy:update()
self.n += 1
if (self.n < self.interval) return
self.n = 0
for i=1,self.tries do
local b = 1 << rnd(16)
if b & self.p == 0 then
if i == self.tries or not self.weight or self.mass <= self.weight then
self.mass += 1
self.p |= b
return
end
else
if i == self.tries or not self.weight or self.mass >= self.weight then
self.mass -= 1
self.p &= ~b
return
end
end
end
end
function fuzzy:set_fillp()
fillp(self.p + 0x0.8)
end
fuzzy_stripey = {
y = 0,
dy = -0.25,
thicc = 3,
weight = 12,
spacing = 7,
gap = 32,
colors = split"3,5,2,1",
}
mknew(fuzzy_stripey, function(f)
f.fuzz = fuzzy.new{
weight = f.weight or fuzzy_stripey.weight,
interval = f.interval,
tries = f.tries,
}
end)
function fuzzy_stripey:update()
local fz = self.fuzz
fz.weight = self.weight
fz.interval = self.interval
fz.tries = self.tries
self.y += self.dy
if (self.y <= -self.gap) self.y += self.gap
if (self.y >= 0) self.y -= self.gap
fz:update()
end
function fuzzy_stripey:draw()
self.fuzz:set_fillp()
for y=self.y,128,self.gap do
for i,c in ipairs(self.colors) do
local y0 = y + (i-1) * self.spacing
rectfill(0, y0, 128, y0 + self.thicc, c)
end
end
end
--@musurca & @felice
function cminskycirc(r,c)
local j,k,rat=r,0,1/r
poke(0x5f25,c) --set color
for i=1,r*0.785 do
k-=rat*j
j+=rat*k
pset(63.5+j,63.5+k)
pset(63.5+j,63.5-k)
pset(63.5-j,63.5+k)
pset(63.5-j,63.5-k)
pset(63.5+k,63.5+j)
pset(63.5+k,63.5-j)
pset(63.5-k,63.5+j)
pset(63.5-k,63.5-j)
end
pset(63.5,63.5-r)
pset(63.5,63.5+r)
pset(63.5-r,63.5)
pset(63.5+r,63.5)
end
obvious_breather=split"2,3,4,3,2"
bg_breather=split"1,2,3,2,1"
breather = {
colors = obvious_breather,
sep = 8,
speed=240,
f=0,
}
mknew(breather)
function breather:update()
if (self.freeze) return
local f = self.f + 1
if (not self.on) f = 0
if (f >= self.speed) f = -self.speed
if f == 0 or f == -self.speed then
if self.nextspeed then
self.speed = self.nextspeed
self.nextspeed = nil
end
if self.off_soon then
self.on = false
f=0
end
if self.nextcolors then
self.colors=self.nextcolors
end
end
self.f = f
end
function easeinout(t)
if(t<.5) then
return t*t*t*4
else
t-=1
return 1-t*t*t*-4
end
end
function breather:draw()
fillp(0)
local cols, f, spd, sep = self.colors, self.f, self.speed, self.sep
local stall = sep * (#cols - 1)
local cap = spd-stall
if (f >= 0) f += stall
for i,c in ipairs(cols) do
local ef = f - (i-1)*sep
ef = abs(ef) - stall
if ef <= cap and ef > 0 then
cminskycirc(easeinout(ef/cap)<<6,c)
end
end
end
function breather:matches(x, alwaysmatched)
if (not self.on) return true
if (x==1) return not alwaysmatched and self:starting_reverse()
if (x==2) return not alwaysmatched and self:starting_forward()
if (x==3) return not alwaysmatched and self:starting_reverse() or self:starting_forward()
return true
end
function breather:starting_reverse()
return self.f + self.speed < self.sep * #self.colors
end
function breather:starting_forward()
return self.f > 0 and self.f < self.sep * #self.colors
end
def_z_pal = {
[0]=0,129,1,2,4,5,6,7,1,5,6,140,2,12,7,7
}
def_14_fade = split"0,0,0,0,0,128,129,133,141,13,6,15,7"
def_15_fade = split"0,0,128,129,133,141,13,13,6,6,15,15,7"
def_13_fade = split"0,0,0,0,0,128,129,133,141,140,140,13,12"
def_shd_fade = split"0,0,0,128,130,141,2"
-- frames per character to wait
-- during zonk text display.
fchr=2
zonk_mode = {
files={},
lnh = 9,
--space width
spc_full=6,
--text mode
txmd=0x81,
--text spring-in distance
txd=10,
--text spring-in frames
txf=20,
--exit frames
exf=60,
--exit magnitude
exmg=16,
--character wait multiplier
cmul=1,
p=def_z_pal,
fd13 = def_13_fade,
fd14 = def_14_fade,
fd15 = def_15_fade,
fd12 = def_shd_fade,
twt=60,
expect_cfg_line=true,
txt_frame=blank,
playing_text=true,
cx=0,
cy=0,
}
mknew(zonk_mode, function(self)
self.stripes=fuzzy_stripey.new{
colors=self.bg_stripe_cols,
dy=self.bg_dy,
weight=self.bg_wgt,
}
self.brth=breather.new{
colors=self.br_cols,
sep=self.br_sep,
speed=self.br_spd,
}
self.alwaysmatched=true
end)
function zonk_mode:set(_, field,value)
pukeboard{field=field, value=value}
self[field]=value
end
function zonk_mode:g(_, fn, ...)
return _ENV[fn](...)
end
function zonk_mode:at(_, x, y)
self.txt_frame=scootbox.new{
x=x,
from=y-5,
to=y-5-self.exmg,
frames=self.exf,
}
end
function zonk_mode:center(_, rows, cols)
local w,h = cols*self.spc_full, rows*self.lnh-1
self:at(_, 64-ceil(w/2), 64-ceil(h/2))
end
function zonk_mode:bon()
self.brth.on=true
self.brth.off_soon=false
end
function zonk_mode:boff()
self.brth.off_soon=true
end
function zonk_mode:bspd(_, spd)
self.brth.nextspeed=spd
end
function zonk_mode:bpal(_, p)
self.brth.nextcolors= p == 1 and obvious_breather or bg_breather
end
function zonk_mode:bgdy(_, dy)
self.stripes.dy = dy
end
function zonk_mode:bgwt(_, w)
self.stripes.weight = w
end
function zonk_mode:activate()
clear_alt_pal_bits()
pal()
font_monogram()
if (type(self.file) == "string") self.file = split(self.file, "\n")
if (not self.file) self:next_file()
assert(self.file)
end
function zonk_mode:next_file()
if #self.files > 0 then
self.file=split(deli(self.files,1), "\n")
self.expect_cfg_line=true
self.cy=5
self.cx=0
end
end
-- return char count, item
-- or 0, nil: end of page
-- or nil (, nil): end of file
function zonk_mode:next_item()
if not self.line then
if (not self.file or #self.file == 0) return
if self.expect_cfg_line then
self.expect_cfg_line = false
local cfg_line = deli(self.file, 1)
for i,cmd in ipairs(split(cfg_line, " ")) do
if #cmd > 0 then
local frags = split(cmd,":")
assert(type(self[frags[1]])=="function", tostr(i).." - "..cfg_line)
self[frags[1]](self, unpack(frags))
end
end
return self:next_item()
end
local line = deli(self.file, 1)
if line == "-----" then
self.line = nil
self.expect_cfg_line = true
self.cx = 0
self.cy = 5
return 0, nil
end
self.line = split(line, " ")
end
if #self.line==0 then
self.line = nil
self.cx = 0
self.cy += self.lnh
return self:next_item()
end
-- parse token
local token = tostr(deli(self.line, 1))
while #token == 0 and #self.line > 0 do
-- emit extra spaces
self.cx += self.spc_full
token = tostr(deli(self.line, 1))
end
local pp,cmult=nrm_txt_pal,1
if (token[1]==">") token,self.cx=sub(token,2),self.cx+self.spc_full\2
if (token[1]=="$") token,cmult=sub(token,2),2
if (token[1]=="^") token,cmult=sub(token,2),0.5
if (token[1]=="!") token,pp=sub(token,2),sfd_txt_pal
if (token[1]=="#") token,pp=sub(token,2),hlt_txt_pal
local ret = zonk_txt(token,self.cx,self.cy,pp,self.txmd,self.txf,self.txd*cmult)
self.cx = ret.eff_w+self.spc_full
return #token,ret
end
function zonk_mode:empty()
if (self.file and #self.file > 0) return false
return #self.files == 0
end
function fadetbl(col, tbl, frac)
pal(col,tbl[1+(frac*#tbl)&0x7fff],1)
end
function zonk_mode:update()
if (not self.brth:matches(self.bwt)) self.alwaysmatched=false
if self.playing_text then
self.twt -= 1
if self.twt <= 0 then
local cn,item = self:next_item()
if not cn then
self:next_file()
self.playing_text=false
elseif cn < 0 then
self.twt = -cn
else
self.twt = cn*fchr*self.cmul
end
if item then
self.txt_frame:push(item)
else
self.playing_text=false
end
end
else
--waiting to advance or exit
if self.wtmr then
self.twt += self.wait_more
self.wtmr = nil
end
if self.twt <= 0 then
if (btnp(1)) self.confirmed=true
if not self.nextpage and self.confirmed and self.brth:matches(self.bwt, self.alwaysmatched) then
self.nextpage = true
self.txt_frame.go = true
self.fpfrm = self.exf
self.alwaysmatched=true
end
else
self.twt -= 1
end
end
if self.nextpage and not self.d then
if self.fpfrm > 0 then
self.fpfrm -= 1
elseif self:empty() then
self.txt_frame=blank
self.d = ditherer.new{di=0.5}
else
self.nextpage = false
self.confirmed=false
self.txt_frame=blank
self.playing_text=true
self.fpfrm=nil
end
end
self.stripes:update()
self.brth:update()
self.txt_frame:update()
if (self.d and self.d:update()) seq:next()
end
function zonk_mode:draw()
cls(0)
pal(self.p, 1)
if (not self.hide_stripes) self.stripes:draw()
if (not self.hide_breath) self.brth:draw()
if self.fpfrm then
local ffrac = self.fpfrm/self.exf
fadetbl(12, self.fd12, ffrac)
fadetbl(13, self.fd13, ffrac)
fadetbl(14, self.fd14, ffrac)
fadetbl(15, self.fd15, ffrac)
end
self.txt_frame:draw()
-- TODO: draw throbber
if not self.playing_text and not self.confirmed and self.twt <= 0 then
font_default()
print("➡️",121,121,12)
print("➡️",120,120,self:throbber_color())
end
if(self.d) self.d:draw()
end
function zonk_mode:throbber_color()
if (not self.bwt or self.bwt==0) return ((t()<<1)&0x1 < 1) and 7 or 6
return self.brth:matches(self.bwt) and 7 or 6
end
-->8
-- awakener
fast_awakener = {}
mknew(fast_awakener)
function fast_awakener:update()
--todo: implement
end
function fast_awakener:draw()
cls()
pal()
clear_alt_pal_bits()
font_default()
print("placeholder", 45, 61, 8)
end
count_up=[[bgdy:-0.1 bspd:240 center:3:18
>wITH EVERY COUNT
FROM 1 !UP TO 5,
YOU !WAKE FURTHER.
-----
bgdy:0 center:5:19
>aS YOU !WAKE !UP,
THE WORLD RETURNS.
YOUR MIND IS !NOW
RETURNING TO ITS
USUAL FLOW.
-----
bpal:1 set:bwt:2 center:3:19
!aWAKEN, BECOMING
FULLY ALERT AT THE
>COUNT OF #5...
-----
set:exf:10 set:txf:30 set:txd:45 set:confirmed:1 bgdy:0.1 bspd:225 center:1:1
1
-----
set:confirmed:1 bspd:210 bgdy:0.15 bgwt:10 center:1:1
2
-----
set:confirmed:1 bspd:180 bgdy:0.2 bgwt:12 center:1:1
3
-----
set:confirmed:1 bgdy:0.25 bpal:2 bgwt:14 center:1:1
4
-----
set:confirmed:1 bgdy:0.4 bgwt:16 center:1:1
5
-----
set:hide_breath:1 set:hide_stripes:1 boff set:txf:1 set:txd:0 set:exd:0 set:exf:1 set:bwt:0 center:1:12
wide awake!
]]
function normal_awakener()
return zonk_mode.new{
br_spd=300,
br_cols=bg_breather,
file=[[center:2:15 bon
yOU'VE LEARNED
SO WELL!
-----
center:2:14
yOU'RE SUCH A
!GOOD !TOY!
-----
center:4:19
tAKE A MOMENT TO
JUST !ENJOY HOW
>IT FEELS, TO BE
#VINYL FULL OF #AIR.
-----
center:6:20 bgdy:-0.2
bECAUSE, NEXT, IT'S
>TIME TO #WAKE #UP.
yOU GET TO TAKE YOUR
!HAPPY MOOD AND !VIVID
!MEMORIES OF THIS
EXPERIENCE WITH YOU,
-----
center:4:20 bgdy:-0.15 bspd:270
BUT !ALL THE HYPNOTIC
!SUGGESTIONS FROM
>THIS GAME WILL !FADE
>AS YOU #WAKE #UP.
]],
files={count_up},
}
end
-->8
-- consent screens
ao_splash = {
fwait = 180,
}
mknew(ao_splash, function(self)
self.c = breather.new{
colors={7,15,14,8,2},
sep=3,
f=15,
on=true,
}
font_monogram()
end)
function ao_splash:update()
if self.c.f < self.c.speed/2.5 then
self.c:update()
return
end
self.fwait -= 1
if (self.fwait < ao_splash.fwait-30 and (btnp() & 0xf > 0) and self.fwait > 0) self.fwait = 0
if self.fwait == 0 then
self.d = ditherer.new{di=1}
end
if (self.d) self.d:update()
if self.fwait <= -32 then
-- TODO: consent screen
mainview=consent_splash.new()
mainview:update()
end
end
function ao_splash:draw()
cls()
self.c:draw()
if self.fwait < ao_splash.fwait then
print("18+", 55, 60, 7)
print("aDULTS ONLY", 30, 90, 15)
end
if (self.d) self.d:draw()
end
consent_splash = {
f = 0,
}
mknew(consent_splash, function(self)
self.d = ditherer.new{
di=-1
}
awakener_armed = true
awakener_hold_frames = 0
end)
function consent_splash:update()
if (self.f < 0x7fff) self.f += 1
if (btnp(1) and self.f > 150) self.d.di = 1
if self.d:update() and self.d.di > 0 then
mainview=newtitle()
mainview:update()
end
end
function consent_splash:draw()
cls()
font_special()
print("\^w\^twarning", 20, 2, 10)
font_default()
cursor(1, 25)
color(6)
print("this game will \fchypnotize\f6 you.")
if (self.f < 45) return
print("")
print("hypnotic suggstions include:")
print("relaxation, trance, obedience,")
print("loss of volition, euphoria, joy,")
print("amnesia, identity loss, and the")
print("experience of \fetranformation")
print("into a pooltoy orca.\f6")
if (self.f < 90) return
print("")
print("an awakener that removes all")
print("suggestions is available at")
print("\faany time:\f6 hold ❎ or 🅾️.")
print("gameplay uses only arrows.")
if(self.f < 300) return
print("")
print("")
print(" consent and begin: \f7➡")
self.d:draw()
end
-->8
-- title screen
-- currently just loading
-- whatever view I want to debug
function newtitle()
local ret = title_screen.new()
ret:activate()
return ret
end
title_screen = {}
mknew(title_screen, function(t)
t.a = arcade_level.new{
noscore=true,
max_score=9999,
wordwait=9999,
extra_layer={
draw=function()
t:draw_menu()
end,
update=nop,
},
phin_x = 62,
}
end)
function title_screen:activate()
self.a:activate()
font_monogram()
end
function title_screen:draw()
self.a:draw()
end
function title_screen:draw_menu()
font_special()
print("\^w\^tvACATION", 18, 24, 0)
print("\^w\^tvACATION", 17, 23, 3)
print("\^w\^tvACATION", 16, 22, 15)
if hz(8) or self.a.wordremain ~= 0 then
print("pRESS", 43, 96, 3)
print("pRESS", 42, 95, 15)
font_default()
print("➡️", 79, 98, 3)
print("➡️", 78, 97, 15)
end
end
function title_screen:update()
self.a.wordwait=999
if btnp(1) and self.a.wordremain ~= 0 then
self.a.wordremain=0
create_game()
end
self.a:update()
end
-->8
-- dolphin sprite renderer
phinstate_nrm = {
--s={4, 36, 4, 9},
s={4},
ws=3,
hs=2,
idle=true,
xo=-12,
yo=-8,
}
phinstate_jump_full = {
s={64},
ws=2,
hs=3,
xo=-4,
yo=-8,
}
phinstate_jump_wane = {
s={69},
ws=3,
hs=3,
xo=-12,
yo=-8,
}
phinstate_crest = {
s={72},
ws=3,
hs=2,
xo=-12,
yo=-8,
}
phinstate_fall_wax = {
s={128},
ws=3,
hs=3,
xo=-12,
yo=-16,
}
phinstate_fall_full = {
s={77},
ws=2,
hs=3,
xo=-4,
yo=-16,
}
phinstate_dive_full = phinstate_fall_full
phinstate_dive_wane = {
s={128},
ws=3,
hs=3,
xo=-12,
yo=-16,
}
phinstate_return = {
s={104},
ws=3,
hs=2,
xo=-12,
yo=-8,
}
phinstate_rise_wax = phinstate_jump_wane
phinstate_rise_full = phinstate_jump_full
phinstate_error = {
s={0},
ws=1,
hs=2,
}
-- coordinates are the notional
-- center point of the dolphin.
-- many states are off-center.
toyphin = {
x=-12,
xtarget=16,
y=64,
dy=0,
state=phinstate_nrm
}
mknew(toyphin)
function toyphin:update()
local x, y, dy, splash = self.x, self.y, self.dy, self.splasher
-- entry mode?
if not self.entered then
x += 1
self.entered = x >= self.xtarget
elseif self.exiting then
if x + self.state.xo > 128 then
self.exited = true
else
x += 1
end
end
-- button handling
if self.entered and not self.exiting then
if y >= 61 and y <= 67 then
if (btn(2)) and dy < 1 then
splash:jump_splash(x)
dy=-3.8
elseif (btn(3)) and dy > -1 then
splash:dive_splash(x)
dy=3.8
end
else
dy += (btn(3) and 0.125 or 0) - (btn(2) and 0.125 or 0)
end
end
if (y > 64) dy -= 0.3
if (y < 64) dy += 0.3
local new_y = y + dy
if new_y <= 64 and y > 64 then
-- surfacing
splash:surfacing_splash(x, -dy, btn(2) and (dy > -3.8))
if btn(2) then
-- maybe boost
if dy > -3.8 then
new_y = 64 + ((dy + y - 64)/dy * -3.8)
dy = -3.8
else
dy = (dy - 7.6) / 3
end
else
-- brake
if dy > -0.75 then
--stabilize
new_y = 64
dy = 0
else
dy /= 2
end
end
elseif new_y >= 64 and y < 64 then
-- landing
splash:landing_splash(x, dy, btn(3) and (dy < 3.8))
if btn(3) then
-- maybe boost
if dy < 3.8 then
new_y = 64 - ((dy - y + 64)/dy * 3.8)
dy = 3.8
else
dy = (7.6 + dy) / 3
end
else
--brake
if dy < 0.75 then
--stabilize
new_y = 64
dy = 0
else
dy /= 2
end
end
end
y=new_y
local wet, st = y > 64, phinstate_error
if dy < -2.15 then
st = wet and phinstate_rise_full or phinstate_jump_full
elseif dy <= -1 and (y < 60 or y > 68) then
st = wet and phinstate_rise_wax or phinstate_jump_wane
elseif dy <= -1 then
st = phinstate_nrm
elseif dy < 1 then
-- handle idle special case later
st = wet and phinstate_return or phinstate_crest
elseif dy <= 2.15 and (y < 60 or y < 68) then
st = wet and phinstate_dive_wane or phinstate_fall_wax
elseif dy <= 2.15 then
st = phinstate_nrm
else
st = wet and phinstate_dive_full or phinstate_fall_full
end
if (y == 64 and dy == 0) st = phinstate_nrm
-- test mode
--if (btn(5)) self.exiting = true
self.x, self.y, self.dy, self.state = x, y, dy, st
end
-- hitbox for current state
function toyphin:box()
local st = self.state
return {self.x + st.xo, self.y + st.yo, st.ws * 8, st.hs * 8}
end
function toyphin:draw()
local st, y = self.state, self.y
if (st.idle) y += wave()
spr(st.s[1+(((t()<<1)&0x0.FFFF*#st.s)&0x7FFF)], self.x + st.xo, y + st.yo, self.state.ws, self.state.hs)
end
-->8
-- arcade mode
wordtarget = {
x = 129,
y = 60,
on_hit = nop,
}
mknew(wordtarget, function(x)
poke(0x5f58, 0x81)
x.w = print(x.str, 0, -9999)-1
end)
function collides(b1, b2)
if (b1[1] > b2[1] + b2[3]) return false
if (b1[1] + b1[3] < b2[1]) return false
if (b1[2] > b2[2] + b2[4]) return false
return not (b1[2] + b1[4] < b2[2])
end
function wordtarget:update()
if collides({self.x, self.y, self.w, 6}, self.phin:box()) then
self:on_hit()
return true
end
self.x -= 1
return self.x < -self.w
end
function wordtarget:draw()
poke(0x5f58, 0x81)
-- debug: show hitbox
--rect(self.x-1, self.y-1, self.x+self.w+1, self.y + 8, 0x10F1.5a5a)
print(self.str, self.x+1, self.y+1, 0x100b)
print(self.str, self.x, self.y, 0x100a)
end
-- palette use:
-- 0: shallow sea blue (1)
-- 1: black (for sprites)
-- 2: dolphin shading
-- 3: azure water, maybe score display? (140)
-- 4, 5: keep default in sky layer (for emergency awakener)
-- 6: dolphin specular highlights
-- 7: dolphin white paint
-- 8, 9: unassigned, layer specific
-- 10: word primary (yellow 10?)
-- 11: word shadow (wood 132?)
-- 12: dolphin eye
-- 13: common sky color
-- 14: dolphin primary color
-- 15: highlight white (all layers)
--
-- dolphin colors are different
-- between zones; correlated.
-- wave, text, and black colors
-- are the same between zones.
-- other colors are for
-- elements that only ever
-- appear in one zone.
--
-- TODO: consider changing sky
-- colors in different stages;
-- document what colors those
-- are (nrm_pal) if so.
game_nrm_pal = {
[0] = 1, 0, 2, 140, 4, 5, 7, 7, 8, 9, 10, 132, 12, 12, 14, 7
}
-- undersea palette local decisions:
-- 4: deeper sea blue (129)
game_uw_pal = {
[0]=1, 0, 130, 140, 129, 5, 141, 13, 8, 9, 10, 132, 131, 12, 141, 7
}
function setup_arcade_pal()
-- per-line color mode
poke(0x5f5f, 0x10)
-- rows 72 and lower: sea
memset(0x5f79,0xff,7)
pal()
pal(game_nrm_pal, 1)
pal(game_uw_pal, 2)
end
-- global wave amplitude clock
-- wave per 2 seconds
-- optional toff: offset. at
-- toff==0 draw directly under
-- the dolphin
function wave(toff)
toff = toff or 0
return 2.5 * sin((t()+toff)>>1)
end
function clear_alt_pal_bits()
memset(0x5f70,0x0,16)
end
sea = {}
mknew(sea)
function sea:draw()
local w = wave()
rectfill(0, 66+w, 128, 77+w, 0x1000)
poke2(0x5f78, 0xffe0.00ff <<> w)
rectfill(0, 78+w, 128, 89+w, 0x1040.a842)
rectfill(0, 90+w, 128, 97+(w>>1), 0x1004.e169)
rectfill(0, 98+(w>>1), 128, 104+(w>>2), 0x1004.a842)
rectfill(0, 104+(w>>2), 128, 110+(w>>2), 0x1004)
rectfill(0, 111+(w>>2), 128, 118+(w>>3), 0x1041.e169)
rectfill(0, 119+(w>>3), 128, 124+(w>>3), 0x1041.a842)
rectfill(0, 125+(w>>3), 128, 128, 0x1001)
end
spark = {
x=0,
y=0,
dx=0,
dy=0,
f=-1,
}
mknew(spark)
function spark:update()
self.f += 1
if (self.f >= 12) return true
self.x += self.dx
self.y += self.dy
end
function spark:draw()
spr(48+self.f\2, self.x, self.y)
end
arcade_level = {
score=0,
wordwait = 90,
}
mknew(arcade_level, function(x)
x.phin = toyphin.new{
splasher=x,
xtarget=x.phin_x,
}
x.sky = bg.new{c=13}
x.sea = sea.new()
x.bg = event_list.new()
x.fg = event_list.new()
x.words = event_list.new()
x.t0 = t()
x.wordremain = x.max_score or arcade_level.max_score
x.wordtimer = x.wordwait or arcade_level.wordwait
if (type(x.wordsets) == "string") x.wordsets = csv(x.wordsets)
x.v = view.of{
x.sky,
x.sea,
x.waves,
x.noscore and blank or {
draw=function()
poke(0x5f58, 0)
local s = tostr(x.score)
print(s,1,2,3)
print(s,2,1,3)
print(s,0,1,3)
print(s,1,0,3)
print(s,1,1,15)
end
},
x.bg,
x.phin,
x.fg,
x.words,
x.extra_layer or blank,
}
x.d = ditherer.new{
c=1,
di = 0.34,
}
end)
function arcade_level:activate()
-- TODO: fade in level music
font_compact()
end
function arcade_level:update()
if self.phin.entered then
if self.wordtimer <= 0 and self.wordremain > 0 then
self:spawn_word()
self.wordtimer = self.wordwait
self.wordremain -= 1
end
self.wordtimer -= 1
end
if self.wordremain <= 0 and self.words.next == nil then
self.phin.exiting = true
end
if self.phin.x > 90 then
if (self.d:update()) seq:next()
end
self.v:update()
end
function arcade_level:spawn_word()
-- pick row from pattern
if not self.pattern then
self.pattern=gen_pattern()
self.pattern_idx = 0
self.next_break = 9 + flr(rnd(9))
end
local i, pbk = (self.pattern_idx&3)+1,0
if self.next_break == 0 then
-- do pattern break
local np = gen_pattern()
i = np[1]==self.pattern[i] and 2 or 1
self.next_break = 9 + flr(rnd(9))
pbk=3
end
self.pattern_idx = i
self.next_break -= 1
local row = self.pattern[i]
self.words:push_back(wordtarget.new{
y=32*row+flr(rnd(13))-6,
phin=self.phin,
on_hit = function(word)
self:word_hit(word)
end,
str=rnd(self.wordsets[row + pbk]),
})
end
function irnd(n)
return rnd(n) & 0x7fff
end
function gen_pattern()
local x0 = irnd(3)
local x1 = irnd(2)
if (x1 == x0) x1 = 2
local x2 = irnd(2)
if (x2 == x1) x2 = 2
local x3 = irnd(2)
if (x3 == x2) x3 = 2
while x3 == x2 or x3 == x0 do
x3 = (x3 + 1)%3
end
return {x0 + 1, x1 + 1, x2 + 1, x3 + 1}
end
function arcade_level:next_row()
if not self.pattern then
self.pattern=gen_pattern()
self.pattern_idx = 0
self.next_break = 9 + flr(rnd(9))
end
local i, pbk = (self.pattern_idx&3)+1,0
if self.next_break == 0 then
-- do pattern break
local np = gen_pattern()
i = np[1]==self.pattern[i] and 2 or 1
self.next_break = 9 + flr(rnd(9))
pbk=3
end
self.pattern_idx = i
self.next_break -= 1
return self.pattern[i], pbk
end
function arcade_level:word_hit(word)
self.score += 1
-- TODO: sfx
self.bg:push_back(spark.new{x=word.x-1, y=word.y-1, dx=-2})
self.bg:push_back(spark.new{x=word.x+word.w, y=word.y-1, dx=1})
end
function arcade_level:draw()
setup_arcade_pal()
self.v:draw()
self.d:draw()
end
function arcade_level:draw_splash(x, force)
if (force < 0.5) return
local n = (force + rnd(force)) & 0x7FF
for i=0,n do
local d = droplet.new{x=x, force=force, y=72+wave(), f=i/n-0.5}
if rnd() < 0.5 then
self.bg:push_back(d)
else
self.fg:push_back(d)
end
end
end
function arcade_level:dive_splash(x)
-- TODO: sfx, vfx for dive input
self:draw_splash(x, 3.8)
end
function arcade_level:jump_splash(x)
-- TODO: sfx, vfx for jump input
self:draw_splash(x, 3.8)
end
function arcade_level:surfacing_splash(x, force, harder)
-- TODO: sfx, vfx for surfacing from a dive
self:draw_splash(x, force)
end
function arcade_level:landing_splash(x, force, harder)
-- TODO: sfx, vfx for landing from a jump
self:draw_splash(x, force)
end
splashcols = {0x1003, 0x103d.a5a5}
droplet = {}
mknew(droplet, function(d)
d.dx = (d.f * d.force >> 2) - 0.75
d.x += 16 * d.f
d.dy = -rnd(d.force*0.66)
d.r = 1 + rnd(0.75 + (d.force >> 4))
d.c = rnd(splashcols)
end)
function droplet:update()
self.x += self.dx
self.y += self.dy
self.dy += 0.3
return self.y >72 + wave()
end
function droplet:draw()
circfill(self.x, self.y, self.r, self.c)
local r2 = self.r >> 1
pset(self.x+r2, self.y-r2, 0x100F)
end
-->8
-- game sequencer
sequencer = {
idx = 0,
score = 0,
max_score = 0,
}
mknew(sequencer)
function sequencer:next()
if (mainview.score) self.score += mainview.score
if (mainview.max_score) self.max_score += mainview.max_score
self.idx += 1
local rec = self[self.idx]
if rec == nil then
mainview = newtitle()
return
end
if rec.params then
mainview = rec.f(unpack(rec.params))
else
mainview = rec.f()
end
mainview:activate()
mainview:update()
end
function create_game()
seq = sequencer.new{
{
f=zonk_mode.new,
params={{
file=[[center:4:19
wELCOME! iN A LATER
VERSION, THERE WILL
BE A TUTORIAL HERE.]],
txd=0,
txf=1,
cmul=0.25,
hide_stripes=true,
}},
},
{
f = arcade_level.new,
params = {{
max_score=25,
wordsets=[[JUMP,PLAY,AIR,SUN
DRIFT,SURF,FLOAT,WAVES
DIVE,WATER,OCEAN,SEA
DRIFT,SOAR,IMAGINE,BE
RELAX,CHILL,TOY,POOLTOY
SINK,DEEP,TRANCE,FOLLOW]]
}},
},
{
f = zonk_mode.new,
params={{
file=[[center:5:14
ZONK TEXT TEST
#ZONK TEXT #TEST
$ZONK $TEXT $TEST
!ZONK !TEXT !TEST
^ZONK ^TEXT ^TEST
-----
center:1:13 bon bpal:1 set:confirmed:true set:bwt:1 set:txf:2 set:txd:0 set:exd:0 set:exf:10
bREATHE IN...
-----
center:1:14 set:confirmed:true set:bwt:2 bpal:2
bREATHE OUT...
-----
set:bwt:0 set:txd:16 set:txf:20 set:exf:60 center:3:19
>gREAT! iT'S LIKE
YOU'VE BEEN DOING
THIS ALL YOUR LIFE.]],
}},
},
{f=normal_awakener},
}
end
__gfx__
00888800777777777777777777777777000000000000000000000000777777777777777700000000000000000000000000000000000000000000000000000000
0888e780700000000000000000000007000000000000000000000000700000000000000700000000000000000000000000000000000000000000000000000000
88888878700000000000000000000007000000000000000000000000700002222220000700000000000000000000000000000000000000000000000000000000
88a8a8e8700000000000000000000007000000000000000000000000700002eeee2000070000000000ee00000000000000000000000000000000000000000000
888a888870000000000000000000000700000000022260000000000070000222e22000070000000000e7e00000000000000000000eee70000000000000000000
88a8a888700000000000000000000007000000000022260000000000700002eeee20000700000000002e7e00000000000000000000eee7000000000000000000
08888880700000000000000000000007000000000002222600000000700002222220000700000000000ee7ee0000000000000000000eeee70000000000000000
008888007000000000000000000000070220000000266222662000007000022e2200000700000000e7eee7e77ee000000ee0000000ee7eee77e0000000000000
00000000700000000000000000000007226200002662222222222000700002e2e22000070e00000eee7eeeeeeeeee000ee7e0000e77eeeeeeeeee00000000000
00000000702222022222222222222207022626622222222227772620700002eeee200007e77e0e7eeeee77eee777e7e00e77eeeeeeeeeeeee777e7e000000000
00000000702ee222e22e22ee22e2e2070e2622222222222227c122627000022222200007eee7eee7e222eeeee7c1ee7e02e7ee77eeeeeeeee7c1ee7e00000000
00000000702e2e2e2e2e22e2e2e2e207222222eee222222222eee262700002222e20000702eeeee2222222eeee222e7eeeeeee222eeeeeeeee222e7e00000000
00000000702e2e2e2e2e22ee22eee207222eeeeeeeeee2222eeeeee0700002eeee2000072e7ee20000022eeee2222220eee2222222222eeee222222000000000
00000000702eee22e22ee2e222e2e2072eee0000eeee22262eeee0007000022222200007eeee20000000ee7e22222000e22200002222ee7e2222200000000000
00000000702222222222222202222207ee00000000022262000000007000022ee2200007ee220000000eeee70000000022000000000eeee70000000000000000
00000000700000000000000000000007000000000022220000000000700002e22e200007020000000eee220000000000000000000eee22000000000000000000
000000007000000000000000000000070000000000000000000000007000022ee220000700000000000000000000000000000000000000000000000000000000
00000000700000000000000000000007000000000000000000000000700000222220000700000000000000000000000000000000000000000000000000000000
000000007000000000000000000000070000000000000000000000007000022eee20000700000000000000000000000000000000000000000000000000000000
00000000700000000000000000000007000000000000000000000000700002e22e20000700000000000000000000000000000000000000000000000000000000
00000000700000000000000000000007000000000000000000000000700002eeee200007000000000222e0000000000000000000022270000000000000000000
0000000070000000000000000000000700000000000000000000000070000222222000070000000000222e000000000000000000002227000000000000000000
000000007000000000000000000000070000000000000000000000007000000000000007000000000002222e0000000000000000000222270000000000000000
000000007777777777777777777777770000000000000000000000007777777777777777022000000022e222ee20000002200000002272227720000000000000
000000000000000000000000a00aa00a000aa00000a00a0000000000000000000000000022e200002ee222222222200022720000277222222222200000000000
00000000000aa0000f0aa0f0000ff00000a00a000000000000000000000000000000000002ee22222222222227772e2002772222222222222777272000000000
000aa0000000000000affa0000a00a000a0000a0a000000a000000000000000000000000022e22ee2222222227c122e20e2722772222222227c1227200000000
00aaaa000a0ff0a00afaafa0af0000faa000000a000000000000000000000000000000002222227772222222227772e2222222eee222222222eee27200000000
00aaaa000a0ff0a00afaafa0af0000faa000000a00000000000000000000000000000000222777777777722227777770222eeeeeeeeee2222eeeeee000000000
000aa0000000000000affa0000a00a000a0000a0a000000a00000000000000000000000027770000777722e2777770002eee0000eeee2272eeeee00000000000
00000000000aa0000f0aa0f0000ff00000a00a0000000000000000000000000000000000770000000002222e00000000ee000000000222270000000000000000
000000000000000000000000a00aa00a000aa00000a00a00000000000000000000000000000000000222770000000000000000000222ee000000000000000000
00000000000066000000000000000000000002200000000000000000000002200000000000000000000000000000000000000000000000000000000000000000
0000000000022260000000000000000000222662000000000000000000222662000000000000000000000000000070220000000000220e220000000000000000
00000000002222e000000000000000006227222e00000000000000002227222e0000000000000000000000000222026200000000022262220000000000000000
0000000002712ee00000000000060026227c1eee0000000000006622227c1eee0000000000220000000000000e22e262000000000e2226220000000000000000
00000000627ceee00000000000222222227ceee000000000006622266272eee000000000002620000000000000ee26220000000000ee22260000000000000000
000000022277eee000000000022226222222eee000000000022222622222eee0000000000022620000000000000ee22600000000000ee2220000000000000000
000000222222ee0000000000000062222222ee0000000000000022222222ee000000000000022622000000000000e226000000000000e2220000000000000000
000066226622ee000000000000006222222220000000000000002222222220000000000026222626622000000000eee2200002000000ee222000000000000000
0006222622226e0000000000000622222226000000000000000222222226000002000002622222222222200000000ee22200020000000ee26200000000000000
00022222222226000000000000022222e22600000000000000022222e226000026620222222222222777262000000ee22266022000000ee22620002000000000
0022002222222200000000000062222ee000000000000000002222eee22e0000222622222eee222227c1226200000ee22226226000000ee22222022000000000
0000002226ee2600000000000662eeee000000000000000002222eee022e00000e22222eeeeeee2222eee26200000ee22222226000020ee22226262000000000
0000002226ee2260000000222222eee000000000000000662222ee0002e00000e2622e00000ee2222eeeeee2000022ee22222200000266ee2222622000000000
000000222ee0022000000226622ee0000000000000000222622ee000000000002222e00000002262eeeeee000000222222222600000222226222260000000000
00000022eee0022000000222222e00000000000000000222222e00000000000022ee000000022226000000000000222222222600000022222622220000000000
0000022eee0000200000000e22e00000000000000000000e22e00000000000000e00000002222200000000000000006622222260000000222222220000000000
0000022ee00000000000000222e00000000000000000000226e000000000000000000000000000000000000000000002222772200000000ee227720000000000
0000022e00000000000000002ee0000000000000000000002ee000000000000000000000000000000000000000000000eeec720000000000eeec720000000000
0006622e00000000000000000ee0000000000000000000000ee000000000000000000000000000000000000000000000eeee1200000000000ee1720000000000
0022226e00000000000000000000000000000000000000000000000000000000000000000022000000000000000000000eee2600000000000ee2220000000000
02222226000000000000000000000000000000000000000000000000000000000000000000262000000000000000000000ee26000000000000ee220000000000
022e022e0000000000000000000000000000000000000000000000000000000000200000002262000000000000000000000e620000000000000e200000000000
0200022e000000000000000000000000000000000000000000000000000000000222000000022622000000000000000000002200000000000000000000000000
00000020000000000000000000000000000000000000000000000000000000000262000000222626622000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000e26220002226222222220000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000002222262222666222277726200000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000222ee2662222222227c122620000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000ee00eeeee222222222eee2620000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000eeeeeee2222eeeeee00000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000eeee2262eeeee0000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000022226000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000222ee00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000ee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000e7e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000026000000000000000e00000002e7e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000002260000000000000eee0000000ee7ee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000002e2260000000000000e7e0000002ee7e77ee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000022222200000000000002e7ee0002ee7eeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000ee66222200000200000eeeee7eeee777eeee777e7e000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000eeee222260000260000eee22e77eeeeeeeee7c1ee7e00000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000ee6226200260000220022222eeeeeeeee222e7e00000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000ee2222222260000000002222222eeee222222000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000ee22222222000000000002222ee7e2222200000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000ee222266200000000000000eeee70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000ee2226222000000000000eee22000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000ee22222660000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000222662222220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000e22222227722000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000eee22222c72000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000002eee122000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000eeee26200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000eee22600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000ee2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__label__
cssscccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
s777sccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
s7s7sccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
s7s7sccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
s7s7sccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
s777sccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cssscccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
2ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
222ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
77272ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c0227211111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
eee27211111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
eeeee111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
ttt11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1
h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111
1h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h11
11h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h1
h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1
h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111
1h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h11
11h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h1
h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1
h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111
1h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h11
11h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h1
111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h
hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1
h11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11h
1hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh1
111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h
hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1
h11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11h
1hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh11hh1
111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h111h
1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh
h1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hh
hh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1h
1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h1h
1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh
h1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hhh1hh
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
0hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh0
h00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00h
hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0
000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h
0hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh0
h00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00hh00h
hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0hhh0
000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h
0h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h00
00h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h0
h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0h0
h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000
0h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h00
00h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h000h0
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__map__
0606090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1f1f1f1f1f1f1f0000001f1f1f00000000001f1b1f00000000001b041b00000000001b001b00000000001b1b1b00000000080c0e0c0800000002060e060200000f010101010000000000101010101e00110a041f041f04000000000e000000000000000000060c0000000000000c0c0000000a0a0000000000040a0400000000
000000000000000004040404040004000a0a000000000000000a1f0a0a1f0a00083e0b3e683e08000033180c063300000609091e090916000804000000000000080404040404080002040404040402000004150e150400000004041f0404000000000000000404020000001f0000000000000000000404001010080402010100
0e11191513110e000406040404041f000e11100804021f000e11100c10110e001212111f101010001f01010f10100f000e01010f11110e001f101008040404000e11110e11110e000e11111e10100e0000040400000404000004040000040402001806010618000000001f001f00000000030c100c0300000e11100804000400
0e19151519010e0000001e1111111e0001010f1111110f0000000e1101110e0010101e1111111e0000000e111f010e000c12020f0202020000001e11111e100e01010f11111111000400060404041f00100018101010110e01011109070911000302020202021c0000000f151515150000000f111111110000000e1111110e00
00000f11110f010100001e11111e101000000d130101010000001e010e100f0002020f0202021c000000111111111e0000001111110a04000000111115150a000000110a040a110000001111111e100e00001f0804021f000c04040404040c0001010204081010000c08080808080c00040a1100000000000000000000001f00
02040000000000000e1111111f1111000f11110f11110f000e11010101110e000f11111111110f001f01010f01011f001f01010f010101000e11011d11110e001111111f111111001f04040404041f001010101011110e0011090503050911000101010101011f00111b15111111110011111315191111000e11111111110e00
0f11110f010101000e111111150916000f11110f111111000e11010e10110e001f040404040404001111111111110e0011111111110a040011111111151b110011110a040a11110011110a04040404001f10080402011f000804040204040800040404000404040004080810080804000000120d000000000000000000000000
1f1f1f1f1f1f1f00150a150a150a150000111f15150e00000e1f111b0e110e00110411041104110002061e0e0f0c0800000e13131f170e00001b1f1f0e04000004110e1b1b0e1104000e0e001f0e0a0000040e1f151d00000e1b191b0e110e00000e1f151f110e00040c1414040703000e1115110e110e0000040e1b0e040000
00000015000000000e1b131b0e110e000000041f0e1b00001f110a040a111f000e1b111f0e110e00000502001408000008150200081502000e151b150e110e001f001f001f001f001515151515151500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1e083c1106000000100c020c10000000227a2222120000001e2000023c000000083c10020c000000020202221c000000083e080c08000000123f12021c0000003c107e043800000002073202320000000f020e101c0000003e404020180000003e10080810000000083804023c00000032071278180000007a42020a72000000
093e4b6d660000001a272273320000003c4a494946000000123a123a1a000000236222221c0000000c00082a4d000000000c1221400000007d79113d5d0000003e3c081e2e00000006247e2610000000244e04463c0000000a3c5a46300000001e041e4438000000143e2408080000003a56523008000000041c041e06000000
08023e201c00000022222620180000003e1824723000000004362c26640000003e182442300000001a272223120000000e641c28780000000402062b1900000000000e1008000000000a1f120400000000040f150d00000000040c060e0000003e2014040200000030080e0808000000083e2220180000003e0808083e000000
107e181412000000043e242232000000083e083e080000003c24221008000000047c1210080000003e2020203e000000247e242010000000062026100c0000003e20101826000000043e240438000000222420100c0000003e222d300c0000001c083e08040000002a2a20100c0000001c003e080400000004041c2404000000
083e080804000000001c00003e0000003e2028102c000000083e305e08000000202020100e0000001024244442000000021e02021c0000003e2020100c0000000c12214000000000083e082a2a0000003e201408100000003c003e001e000000080424427e00000040281068060000001e041e043c000000043e240404000000
1c1010103e0000001e101e101e0000003e003e201800000024242420100000001414145432000000020222120e0000003e2222223e0000003e2220100c0000003e203c2018000000062020100e000000001510080600000000041e140400000000000c081e000000001c18101c00000008046310080000000810630408000000
04050700000100000000000000607700672000617700060600000000006677070100000060072700000010200070700000000110600020111000102100000671333313111333121333103333117766007600f1758f17677f7788767086182273ff8fff01ffffedff81ff8f7f8188f800ff8fff01ffffeeff88888808818888f0
0007070707070000000007070700000000000705070000000000050205000000000005000500000000000505050000000004060706040000000103070301000000070101010000000000040404070000000507020702000000000001000000000000000001020000000000000303000000050500000000000002050200000000
000000000000000000010101000100000005050000000000000a1f0a1f0a0000000207030607020000050402010500000002050e050e0000000101000000000000020101010200000001020202010000000502070205000000000207020000000000000000010100000000070000000000000000000100000004040201010000
0002050505020000000203020207000000030402010700000003040204030000000505070404000000070103040300000006010305020000000704040202000000020502050200000002050604030000000001000100000000000001000101000000020102000000000003000300000000000102010000000003040200020000
0006090d0106000000000306050700000001030505030000000006010106000000040605050600000000020503060000000402070202000000000605060403000001010305050000000100010101000000020002020201000001050305050000000101010102000000000f151515000000000305050500000000020505020000
000003050503010000000605050604000000030501010000000006030603000000020702020600000000090909060000000005050503000000001111150a000000000502050500000000050505060300000007060307000000030101010300000001020202040000000302020203000000020500000000000000000000070000
0002040000000000000205070505000000030503050300000006010101060000000709090907000000070103010700000007010301010000000e010d090600000005050705050000000101010101000000040404040502000005050305050000000101010107000000111b151111000000090b0f0d0900000006090909060000
0003050301010000000609090d06080000030503050500000006010204030000000702020202000000090909090600000009090905030000001111151b1100000005050205050000000505020202000000070402010700000006020102060000000101000101000000030204020300000000000a050000000003030000000000
007f7f7f7f7f7f0000752a752a752a0000617f5d5d3e0000003e6363773e0000001164116411640000021e0e0f080000000e171f1f0e0000001b1f1f0e040000001c3677361c0000000e0e1f0e0a0000001c3e7f2a3a0000003e6763673e0000003f2d3f213f0000001c040407070000003e636b633e000000040e1f0e040000
0000007500000000003e7363733e000000081c7f3e220000001f0e040e1f0000003e7763633e000000000572200000000000112a64000000003e6b776b3e0000001f001f001f00000015151515150000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000100010101000000040e050e0400000c0207020f000000110e0a0e11000000050502070200000001010001010000000603050603000000050000000000000006090d09060000000306050700000000001209120000000000000704000000000000000000000000030503050000000007000000000000
000205020000000000020702000700000003020103000000000103020100000000020100000000000000000505030100000f0b0b0a0a000000000001000000000000000000020300000203020200000000020502000000000000091209000000001109052a3920000011091d120918000021130a757240000000020002010600
000204030605070000020103060507000002050306050700000a0503060507000005000306050700000200030605070000000b160d1f00000000000e010e040000020402050306000002010205030600000205020503060000050002050306000001020000020200000201000001010000020500000202000005000000020200
000e1217120e0000000a050007090900000102000205020000040200020502000002050002050200000a0500060906000005000002050200000005020500000000100e15120d0000000204000909060000040200090906000006090009090600000900000909060000040200050506030001050b0b0501000006090509050000
000204020507050000020102050705000002050205070500000a0506090f090000050002050705000002000205070500001e050f051d0000000e0101010e040000020407030107000002010703010700000205070301070000050007030107000001020002020200000201000101010000020500020202000005000002020200
0002050e09090600000a05090b0d0900000204060909060000040206090906000002050609090600000a0506090906000009000609090600000200070002000000160915120d00000002040909090600000402090909060000020508090906000009000909090600000402050502020000010709090701000005000505020200