REBOL [
    Title: "Mapserver client: Demo map"
    Version: 0.2.3
    Author: "Janeks Kamerovskis"
    Purpose: { Simple Mapserver (http://mapserver.gis.umn.edu) client.}
    File: %cl4mapserv.r
    Date: 13-Mar-2006
    library: [
        level: 'intermediate
        platform: [ all plugin ]
        type: [ demo ]
        domain: [ vid ]
        plugin: [size: 240x100]
        tested-under: [ View 1.2.1.3.1 "WinXP" ]
        support: none
        license: none
        see-also: none
    ]
]

mapserver-exe-base: "http://terrasip.gis.umn.edu/cgi-bin/mapserv40"
mapserver-cgivars: [
	"map=/data/projects/tutorial/example2-2.map"
	"mode=map"
]
mapserver-layers: [
    "states"
    "hydro"
    "roads"
]

if not value? 'mapsize [
	mapsize: 400x300
]
if not value? 'imgType [
	imgType: "GIF"
]
mapFileName: to-file rejoin [ "mapImg." imgType ]

base-mapext: [ 201621.496941 -355683.111522 1425518.020722 559449.337703 ]

mouse-map-xy: [ 0 0 ]
rubber-box: [
	pen red
	box none none
]

mapext: base-mapext
extents-history: []
repend extents-history [ mapext ]
extents-history: tail extents-history

rejoin: func [
	"Reduces and joins a block of values."
	block [block!] "Values to reduce and join"
	/with string [ string! ]
][
	if empty? block: reduce block [return block]
	if with [ block: next block forskip block 2 [ insert block string ] ]
	block: head block
	append either series? first block [copy first block] [
		form first block] next block
]

mapserver-cgivar-mapsize: rejoin [ "mapsize=" first mapsize "+" second mapsize ]
mapserver-cgivar-mapext: rejoin [ "mapext=" rejoin/with mapext "+" ]

Round: func [
	"Rounds a Number At any given Place."
	[catch]
	Number [number!]    "Number to round."
	/At Place [integer!]    "Optional Places."
][
	throw-on-error [
		Place: either none? Place [1] [10 ** Place]
		Number: Place * Number
		Number: Number + either positive?
		Number [0.5][-0.5]
		Number: Number - (Number // 1)
		Number / Place
	]
]

pad-decimal: func [value [number!] len [integer!] /local s] [
	s: form value
	either value = to-integer value [
   	head insert tail s #"."
   	head insert/dup tail s #"0" len
	][
		head insert/dup tail s #"0" len - ((length? s) - index? find s #".")
	]
]

imgxy-to-mapxy: func [ imgxy ][
	return reduce [
		mapext/1 + ((((mapext/3) - (mapext/1)) / mapsize/1) * imgxy/1)
		mapext/2 + ((((mapext/4) - (mapext/2)) / mapsize/2) * ( mapsize/2 - imgxy/2 ))
	]
]

rbox-to-mapext: func [
    startxy
    endxy
    /local startp endp
][
    startp: 0x0
    endp: 0x0
    startp/x: min startxy/x endxy/x
    startp/y: min startxy/y endxy/y
    endp/x: max startxy/x endxy/x
    endp/y: max startxy/y endxy/y
    startxy: startp
    endxy: endp
	either ((endxy/x - startxy/x) / (endxy/y - startxy/y)) > (mapsize/x / mapsize/y) [
		rubber-box/4/x: startxy/x
		rubber-box/4/y: startxy/y - ( 0.5 * ( ((endxy/x - startxy/x) / (mapsize/x / mapsize/y)) - (endxy/y - startxy/y) ) )
		rubber-box/5/x: endxy/x
		rubber-box/5/y: endxy/y + ( 0.5 * ( ((endxy/x - startxy/x) / (mapsize/x / mapsize/y)) - (endxy/y - startxy/y) ) )
	][
		rubber-box/4/x: startxy/x - ( 0.5 * ( ((endxy/y - startxy/y) * (mapsize/x / mapsize/y)) - (endxy/x - startxy/x) ) )
		rubber-box/4/y: startxy/y
		rubber-box/5/x: endxy/x + ( 0.5 * ( ((endxy/y - startxy/y) * (mapsize/x / mapsize/y)) - (endxy/x - startxy/x) ) )
		rubber-box/5/y: endxy/y
	]
	return reduce [
		first imgxy-to-mapxy reduce [ rubber-box/4/x rubber-box/5/y ]
		second imgxy-to-mapxy reduce [ rubber-box/4/x rubber-box/5/y ]
		first imgxy-to-mapxy reduce [ rubber-box/5/x rubber-box/4/y ]
		second imgxy-to-mapxy reduce [ rubber-box/5/x rubber-box/4/y ]
	]
]

zoomout-ext: func [ cur-ext zoom-ext ][
	return reduce [
		2 * cur-ext/1 - zoom-ext/1
		2 * cur-ext/2 - zoom-ext/2
		2 * cur-ext/3 - zoom-ext/3
		2 * cur-ext/4 - zoom-ext/4
	]
]

create-mapserver-url: func [ mapext ][
    myUrl: to-url rejoin [
        mapserver-exe-base "?"
        rejoin/with [
            rejoin/with mapserver-cgivars "&"
            rejoin [ "layers=" rejoin/with mapserver-layers "+" ]
            rejoin [ "mapext=" rejoin/with mapext "+" ]
            rejoin [ "map_size=" mapsize/x "+" mapsize/y ]
			rejoin [ "map_imagetype=" imgType ]
        ]
        "&"
    ]
]
create-mapserver-url mapext

tools-switch: func [ on-tool ][
	if all [ tgBtn-zoomin/state on-tool <> 1 ] [ tgBtn-zoomin/state: false]
	if on-tool = 1 [ tgBtn-zoomin/state: true ]
	if all [ tgBtn-zoomout/state on-tool <> 2 ] [ tgBtn-zoomout/state: false ]
	if on-tool = 2 [ tgBtn-zoomout/state: true ]
	if all [ tgBtn-pan/state on-tool <> 3 ] [ tgBtn-pan/state: false ]
	if on-tool = 3 [ tgBtn-pan/state: true ]
;	if all [ tgBtn-info/state on-tool <> 4 ] [ tgBtn-info/state: false ]
;	if on-tool = 4 [ tgBtn-info/state: true ]
	show tgBtn-zoomin
	show tgBtn-zoomout
	show tgBtn-pan
;	show tgBtn-info
]

backb-img: make image! [25x25 #{
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
A1B6B6A1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCA1B6B6000000626E6FA1B6B6B4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F
000000626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCA1B6B6626E6F000000000000626E6FA1B6B6B4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000000000
000000626E6FA1B6B6A1B6B6A1B6B6A1B6B6A1B6B6A1B6B6A1B6B6A1B6B6
A1B6B6A1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
A1B6B6626E6F000000000000B4CCCC000000626E6F626E6F626E6F626E6F
626E6F626E6F626E6F626E6F626E6F626E6F626E6FA1B6B6B4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000000000B4CCCCB4CCCC
000000000000000000000000000000000000000000000000000000000000
000000000000626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F
000000000000B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCC000000000000626E6FA1B6B6B4CCCCB4CCCC
B4CCCCB4CCCCA1B6B6626E6F000000000000B4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC000000000000
626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000000000
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCC000000000000626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCC
A1B6B6626E6F000000000000000000B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC000000000000626E6FA1B6B6
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000000000
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCC000000000000626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCA1B6B6626E6F000000000000B4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC000000000000
626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F
000000000000B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCC000000000000626E6FA1B6B6B4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000000000B4CCCCB4CCCC
000000000000000000000000000000000000000000000000000000000000
000000000000626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
A1B6B6626E6F000000000000B4CCCC000000626E6F626E6F626E6F626E6F
626E6F626E6F626E6F626E6F626E6F626E6F626E6FA1B6B6B4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000000000
000000626E6FA1B6B6A1B6B6A1B6B6A1B6B6A1B6B6A1B6B6A1B6B6A1B6B6
A1B6B6A1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCA1B6B6626E6F000000000000626E6FA1B6B6B4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F
000000626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCA1B6B6000000626E6FA1B6B6B4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
A1B6B6A1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
}]

forwb-img: make image! [25x25 #{
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCA1B6B6A1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000
A1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCA1B6B6626E6F000000626E6FA1B6B6B4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000
000000626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCA1B6B6A1B6B6A1B6B6A1B6B6A1B6B6A1B6B6A1B6B6
A1B6B6A1B6B6A1B6B6626E6F000000000000000000626E6FA1B6B6B4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F626E6F
626E6F626E6F626E6F626E6F626E6F626E6F626E6F626E6F626E6F000000
B4CCCC000000000000626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCA1B6B6626E6F000000000000000000000000000000000000000000
000000000000000000000000000000B4CCCCB4CCCC000000000000626E6F
A1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000
000000B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCC000000000000626E6FA1B6B6B4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCA1B6B6626E6F000000000000B4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC000000
000000626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6
626E6F000000000000B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC000000000000626E6FA1B6B6B4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000000000B4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
000000000000000000626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCA1B6B6
626E6F000000000000B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC000000000000626E6FA1B6B6B4CCCC
B4CCCCB4CCCCB4CCCCA1B6B6626E6F000000000000B4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC000000
000000626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000
000000B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCC000000000000626E6FA1B6B6B4CCCCB4CCCCB4CCCC
B4CCCCA1B6B6626E6F000000000000000000000000000000000000000000
000000000000000000000000000000B4CCCCB4CCCC000000000000626E6F
A1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F626E6F
626E6F626E6F626E6F626E6F626E6F626E6F626E6F626E6F626E6F000000
B4CCCC000000000000626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCA1B6B6A1B6B6A1B6B6A1B6B6A1B6B6A1B6B6A1B6B6
A1B6B6A1B6B6A1B6B6626E6F000000000000000000626E6FA1B6B6B4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000
000000626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCA1B6B6626E6F000000626E6FA1B6B6B4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000
A1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCA1B6B6A1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
}]

infobt-img: make image! [25x25 #{
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6A1B6B6A1B6B6A1B6B6A1B6B6
A1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6
A1B6B6000000000000000000000000A1B6B6A1B6B6B4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCA1B6B6000000000000000000000000000000
000000A1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6
000000000000000000000000000000000000A1B6B6B4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCA1B6B6000000000000000000000000000000
000000A1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6
A1B6B6000000000000000000000000A1B6B6A1B6B6B4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6A1B6B6A1B6B6A1B6B6A1B6B6
A1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F
626E6F626E6F626E6F626E6F626E6F626E6F626E6FA1B6B6B4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCA1B6B6626E6F000000000000000000000000000000000000
000000000000626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000
000000000000000000000000000000000000000000626E6FA1B6B6B4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCA1B6B6626E6F626E6F000000000000000000000000
626E6F626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6
626E6F000000000000000000000000626E6FA1B6B6B4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000000000000000000000
626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6
626E6F000000000000000000000000626E6FA1B6B6B4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000000000000000000000
626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6
626E6F000000000000000000000000626E6FA1B6B6B4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000000000000000000000
626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6
626E6F000000000000000000000000626E6FA1B6B6B4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000000000000000000000
626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F
626E6F000000000000000000000000626E6F626E6FA1B6B6B4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCA1B6B6626E6F000000000000000000000000000000000000
000000000000626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6626E6F000000
000000000000000000000000000000000000000000626E6FA1B6B6B4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCA1B6B6626E6F626E6F626E6F626E6F626E6F626E6F
626E6F626E6FA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA1B6B6
A1B6B6A1B6B6A1B6B6A1B6B6A1B6B6A1B6B6A1B6B6B4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
}]

zoominbt-img: make image! [25x25 #{
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCACC2C382939569777A
6573757585879CB1B2B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
AAC1C15965681C1F24171A1F171A1F171A1F171A1F171A1F373F438B9E9F
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCC9CB1B22C3236171A1F272B306671747E8D8F
859596738183434B4F171A1F191C216C7A7CB3CBCBB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA7BEBE2A2F34
171A1F576164C5DBDCD6EEEE535D60171A1FC2D8D8D6EEEE8C9C9D21252A
171A1F6F7F81B2CACAB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB2CACA515C5F171A1F596366D6EEEED6EEEED6EEEE535D60
171A1FC2D8D8D6EEEED6EEEEA4B7B8171A1F1F24289AAFB1B4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC9DB2B31B1E23272B30
C6DCDDD6EEEED6EEEED6EEEE535D60171A1FC2D8D8D6EEEED6EEEED6EEEE
667174171A1F556063AEC5C5B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCC6A797B171A1F667174D6EEEED6EEEED6EEEED6EEEE535D60
171A1FC2D8D8D6EEEED6EEEED6EEEEB4C8C9171A1F2F363AA1B7B7B4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC4F5A5C171A1F7F8E90
525C5F525C5F525C5F525C5F292E33171A1F4C5558525C5F525C5F525C5F
8B9A9C1E222621262A92A6A7B2CACAB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCC485255171A1F869697171A1F171A1F171A1F171A1F171A1F
171A1F171A1F171A1F171A1F171A1F6C797B282D321E23278A9C9DB0C8C8
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC525D60171A1F738082
C3D9D9C3D9D9C3D9D9C3D9D94D5659171A1FB1C5C6C3D9D9C3D9D9C3D9D9
BACFCF171A1F262B308A9D9EB0C8C8B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCC707F81171A1F434B4FD4ECECD6EEEED6EEEED6EEEE535D60
171A1FC2D8D8D6EEEED6EEEED6EEEE92A2A4171A1F3C434793A6A8B2CACA
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC90A4A52B3035171A1F
8C9C9DD6EEEED6EEEED6EEEE535D60171A1FC2D8D8D6EEEED6EEEEC5DBDC
22272C171A1F606C6FA1B7B7B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCA6BCBD637073181C2122262BA5B8B9D6EEEED6EEEE535D60
171A1FC2D8D8D6EEEEC5DBDC2A2F34171A1F171A1F5D696BADC4C4B4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB2C9CA98ACAD4B5559
171A1F181B20667275B2C7C78B9B9D6D7A7CB9CECE91A1A322272C171A1F
32383C1E2227181B206F7E81B2CACAB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB1C9C990A3A4545F621E2227171A1F171A1F1C2025
282C31171A1F171A1F171A1F181B201E22277583851D2126181B206F7E7F
B3CBCBB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCAFC7C7
9AAFB07585874751542D333721252A1E2227262B303B43475E6A6D546063
181C211E22277582841D2126181B206E7D7FB1C9C9B4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCABC2C29AAFB08A9D9E7E8F91
7B8C8E8192948DA0A1A0B5B6A5BBBC5E6A6D181C211E22277582841D2126
191C216B797BB2C9CAB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB1C9C9AEC5C5ADC4C4AFC6C6B2C9CAB4CCCCB4CCCC
A8BEBF5F6C6E181C211E22277582841D2126191C21809192B1C9C9B4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCADC4C4626F71181C211D2126
272C31171A1F5E6B6DA2B8B9B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCAAC1C1616E71181C21171A1F40484C768688A4BABBB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCAFC6C6758587
5C696C78888A9DB2B2B2CACAB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCAEC5C5A1B7B7A5BBBBB3CBCBB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
}]

zoomoutbt-img: make image! [25x25 #{
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCACC2C382939569777A
6573757585879CB1B2B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
AAC1C15965681C1F24171A1F171A1F171A1F171A1F171A1F373F438B9E9F
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCC9CB1B22C3236171A1F272B306671748A9A9C
98AAAB758385434B4F171A1F191C216C7A7CB3CBCBB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCA7BEBE2A2F34
171A1F576164C5DBDCD6EEEED6EEEED6EEEED6EEEED6EEEE8C9C9D21252A
171A1F718082B2C9CAB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB2CACA515C5F171A1F596366D6EEEED6EEEED6EEEED6EEEE
D6EEEED6EEEED6EEEED6EEEEADC1C21C20251F23289CB0B1B4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC9DB2B31B1E23272B30
C6DCDDD6EEEED6EEEED6EEEED6EEEED6EEEED6EEEED6EEEED6EEEED6EEEE
727F81171A1F566164ADC5C5B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCC6A797B171A1F667174D6EEEED6EEEED6EEEED6EEEED6EEEE
D6EEEED6EEEED6EEEED6EEEED6EEEEBBD1D1171A1F363D41A1B7B7B4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC4F5A5C171A1F7F8E90
525C5F525C5F525C5F525C5F525C5F525C5F525C5F525C5F525C5F525C5F
8C9C9E1F2328262B2F92A6A7B2CACAB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCC485255171A1F869697171A1F171A1F171A1F171A1F171A1F
171A1F171A1F171A1F171A1F171A1F6C797B292E331F23288A9D9EB0C8C8
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC525D60171A1F738082
C3D9D9C3D9D9C3D9D9C3D9D9C3D9D9C3D9D9C3D9D9C3D9D9C3D9D9C3D9D9
BACFD0171A1F272C308A9D9EB0C8C8B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCC707F81171A1F434B4FD4ECECD6EEEED6EEEED6EEEED6EEEE
D6EEEED6EEEED6EEEED6EEEED6EEEE92A2A4171A1F3C434793A6A8B2CACA
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC90A4A52B3035171A1F
8C9C9DD6EEEED6EEEED6EEEED6EEEED6EEEED6EEEED6EEEED6EEEEC5DBDC
22272C171A1F606D6FA1B7B7B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCA6BCBD637073181C2122262BA5B8B9D6EEEED6EEEED6EEEE
D6EEEED6EEEED6EEEECBE1E12B3035171A1F171A1F5C686BADC4C4B4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB2C9CA98ACAD4B5559
171A1F181B20677376B4C8C9D2E9E9D6EEEECAE0E197A8AA2C3136171A1F
32383C1E2227181B206F7E81B2CACAB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB1C9C98FA2A3545F621E2227171A1F171A1F1D2126
2A2F33171A1F171A1F171A1F181B201E22277583851D2126181B206F7E7F
B3CBCBB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCAFC7C7
9AAFB07484864751542D333721252A2025292E34383C44485F6B6F546063
181C211E22277582841D2126181B206E7D7FB1C9C9B4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCAAC1C19AAEAF8A9C9D7E8F91
7B8C8E8192948D9FA19FB4B5A5BBBC5E6A6D181C211E22277582841D2126
191C216B797BB2C9CAB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB0C8C8AEC5C5ADC4C4AFC6C6B2C9CAB4CCCCB4CCCC
A8BEBF5F6C6E181C211E22277582841D2126191C21809192B1C9C9B4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCADC4C4626F71181C211D2126
272C31171A1F5E6B6DA2B8B9B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCAAC1C1616E71181C21171A1F40484C768688A4BABBB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCAFC6C6758587
5C696C78888A9DB2B2B2CACAB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCAEC5C5A1B7B7A5BBBBB3CBCBB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
}]

navfullbt-img: make image! [25x25 #{
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCACC3C37C8C8C7C8B8B
7C8B8B7C8B8B7C8B8BA1B6B6B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCA1B6B67C8B8B7C8B8B7C8B8B7C8B8B7C8C8CACC3C3B4CCCCB4CCCC
B4CCCCB4CCCC353B3A0C0B0A0C0B0A0C0B0A0C0B0A0C0B0A444C4CB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC4A53520C0B0A0C0B0A0C0B0A
0C0B0A0C0B0A323737ACC3C3B4CCCCB4CCCCB4CCCC1C1E1E121211798685
555D5C0C0B0A0C0B0A464E4FB0C8C8B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B3CBCB4F59590C0B0A0C0B0A555D5C7986851212111B1D1C9FB4B5B4CCCC
B4CCCCB4CCCC1C1E1D191918A5B7B7181817181817464F4FA0B5B6B4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCABC2C2181817181817181817
A5B7B71919181B1C1C9DB2B3B4CCCCB4CCCCB4CCCC1C1E1D0F0F0E131312
181817181817181817626E6FB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCC626E6F1818171818170D0D0C1313120F0F0E1B1C1C9DB2B3B4CCCC
B4CCCCB4CCCC1C1E1D0C0B0A0F0F0E586364181817181817181817626E6F
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC626E6F181817181817626E6F626E6F
0F0F0E0C0B0A1B1C1C9DB2B3B4CCCCB4CCCCB4CCCC4952521A1C1B647172
A9C0C0B4CCCC626E6F181817181817626E6FB4CCCCB4CCCCB4CCCC626E6F
181817181817626E6FB4CCCCB0C7C86E7C7C1B1C1C454D4DA1B7B7B4CCCC
B4CCCCB4CCCCA1B7B790A4A5A9C0C0B4CCCCB4CCCCB4CCCC626E6F181817
181817626E6FB4CCCC626E6F181817181817626E6FB4CCCCB4CCCCB4CCCC
AFC6C695A9AA9BB0B0B0C7C8B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCC626E6F181817181817181817181817181817
626E6FB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
626E6F181817181817181817626E6FB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCC626E6F181817181817181817181817181817
626E6FB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC626E6F181817
181817626E6FB4CCCC626E6F181817181817626E6FB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC65717123252488999A
B4CCCCB4CCCC626E6F181817181817626E6FB4CCCCB4CCCCB4CCCC626E6F
181817181817626E6FB4CCCCB4CCCC8A9B9B232625646F6FB4CCCCB4CCCC
B4CCCCB4CCCC1E201F0C0B0A10100F181817181817181817181817626E6F
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC626E6F1818171818171818177E8E8E
1111100C0B0A1D1E1EA4BABBB4CCCCB4CCCCB4CCCC1C1E1D0F0F0E131312
181817181817181817626E6FB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCC626E6F1818171818170E0D0C1313120F0F0E1B1C1C9DB2B3B4CCCC
B4CCCCB4CCCC1C1E1D191918A5B7B71818170C0B0A636E6EB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC6672720C0B0A181817
A5B7B71919181B1C1C9DB2B3B4CCCCB4CCCCB4CCCC1C1E1D121211798685
555D5C0C0B0A0C0B0A5A6565B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCC5E69690C0B0A0C0B0A555D5C7986851212111B1C1C9DB2B3B4CCCC
B4CCCCB4CCCC2D31310C0B0A0C0B0A0C0B0A0C0B0A0C0B0A3F4746B0C8C8
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB3CBCB464E4E0C0B0A0C0B0A0C0B0A
0C0B0A0C0B0A2A2E2E9EB3B4B4CCCCB4CCCCB4CCCC8294954F58594E5859
4E58594E58594E58597D8D8EB3CBCBB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCC8C9E9F505B5C4E58594E58594E58594F585979898AA8BEBFB4CCCC
B4CCCCB4CCCCACC3C3A0B5B69EB3B49EB3B49EB3B49EB3B4AAC0C1B4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCAFC7C7A0B5B69EB3B49EB3B4
9EB3B49FB4B4A8BEBFB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
B4CCCCB4CCCCB4CCCCB4CCCCB4CCCC
}]

pan-img: make image! [25x25 #{
AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAAB6B6AAB6B6AADBDBAADBDB
AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB
AAB6B6556D6D556D6DAAB6B6AADBDBAAB6B6AAB6B6AADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB
AAB6B6AAB6B6AAB6B6AAB6B6AAB6B6556D6D000000000000000000AAB6B6
556D6D556D6DAAB6B6AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAADBDBAADBDBAAB6B6556D6D000000556D6DAAB6B6
000000556D6D556D6D000000556D6D000000000000556D6DAAB6B6AADBDB
AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAAB6B6
000000000000000000000000556D6D000000556D6DAADBDB000000000000
002424002424000000556D6DAAB6B6AADBDBAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAAB6B6556D6D000000AADBDBAADBDB000000000000
000000AADBDBAADBDB000000004949FFDBDBAADBDB000000556D6D556D6D
556D6DAAB6B6AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAAB6B6556D6D
000000556D6DAADBDBFFDBDB000000000000AADBDBAADBDB000000554949
AADBDBAADBDB000000556D6D000000000000556D6DAADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAAB6B6AAB6B6556D6D000000AADBDBAADBDB000000
000000AADBDBAADBDB000000554949AADBDBAADBDB000000000000000000
556D6D000000AAB6B6AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAAB6B6
556D6D000000556D6DAADBDB556D6D000000AADBDBAADBDB000000002424
AADBDBAADBDB000000000000000000AADBDB000000556D6DAADBDBAADBDB
AADBDBAADBDBAADBDBAADBDBAAB6B6AAB6B6556D6D000000AADBDBAADBDB
000000AADBDBAADBDB000000000000AADBDBAADBDB000000000000556D6D
AADBDB000000556D6DAAB6B6AADBDBAADBDBAADBDBAAB6B6556D6D000000
556D6DAAB6B6000000556D6DFFDBDBAADBDBAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDB000000556D6DAADBDBAADBDB000000556D6DAAB6B6AADBDB
AADBDBAAB6B6556D6D000000000000000000556D6D556D6D000000AADBDB
AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB000000AADBDBAADBDB
556D6D000000AAB6B6AAB6B6AADBDBAADBDBAAB6B6000000000000AADBDB
AADBDB000000002424000000AADBDBAADBDBAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAADBDBAADBDB000000000000AAB6B6AAB6B6AADBDB
AADBDBAAB6B6556D6D000000556D6DAADBDBAADBDB000000000000AADBDB
AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB
000000556D6DAAB6B6AAB6B6AADBDBAADBDBAAB6B6AAB6B6000000000000
556D6DAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAADBDB556D6D000000556D6DAAB6B6AAB6B6AADBDB
AADBDBAADBDBAAB6B6556D6D000000556D6DAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB556D6D
000000556D6DAAB6B6AADBDBAADBDBAADBDBAADBDBAADBDBAAB6B6000000
000000556D6DAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDBAADBDB556D6D000000000000AAB6B6AADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAAB6B6556D6D000000000000556D6DAADBDBAADBDB
AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB556D6D000000000000
000000AAB6B6AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAAB6B6
556D6D000000000000556D6DAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDB556D6D000000000000556D6DAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAADBDBAADBDBAAB6B6556D6D000000000000556D6D
AADBDBAADBDBAADBDBAADBDBAADBDBAADBDB556D6D000000000000556D6D
AAB6B6AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB
AADBDBAAB6B6556D6D000000000000556D6DAADBDBAADBDBAADBDBAADBDB
AADBDB556D6D000000556D6DAAB6B6AADBDBAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAAB6B6556D6D000000
556D6DAADBDBAADBDBAADBDBAADBDBAADBDB556D6D000000556D6DAAB6B6
AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAAB6B6000000556D6DAADBDBAADBDBAADBDBAADBDB
AADBDB556D6D000000556D6DAAB6B6AADBDBAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDBAADBDB
AADBDBAADBDBAADBDBAADBDBAADBDB
}]


get-pan-ext: func [
	offs
][
	xd: (first imgxy-to-mapxy offs) - mapext/1
	yd: (second imgxy-to-mapxy offs) - mapext/4
	reduce [
		mapext/1 - xd
		mapext/2 - yd
		mapext/3 - xd
		mapext/4 - yd
	]
]

errMsgLayout: layout [
	backcolor maroon
	errMsgText: text yellow "This is error text"
]

tag-parser: make object! [
    tags: make block! 100
    text: make string! 8000
    html-code: [
        copy tag ["<" thru ">"] (append tags tag) |
        copy txt to "<" (append text txt)
    ]
    parse-tags: func [ site [ url! file! ] ] [
        clear tags clear text
        parse read site [to "<" some html-code]
        foreach tag tags [
		;	print tag
		]
        return text
    ]
]

loadMapImg: func [
	mapUrl
	/local rezImg tmpWl
][
	mapFileSize: 60302
	if exists? mapFileName [
		mapFileSize: size? mapFileName
		delete mapFileName
	]
	mapDwnlProgr/data: 0
	mapDwnlProgr/color: red
	progrInfoTxt/text: "    Loading map: 0%"
	show [ mapDwnlProgr progrInfoTxt ]
	either attempt [
		tmpWl: copy system/ports/wait-list
		clear system/ports/wait-list
		rezImg: read-thru/to/progress mapUrl mapFileName :mapLoadProgress
	][
		system/ports/wait-list: tmpWl
		mapDwnlProgr/data: 1
		progrInfoTxt/text: "    Map loaded: 100%"
		show [ mapDwnlProgr progrInfoTxt ]
		either "" = copy/part read mapFileName 6 [
			errMsgText: tag-parser/parse-tags mapFileName
			view/options/title/new/offset layout [
				backcolor maroon
				errMsgText: text yellow errMsgText
			] [ all-over ] "Error:" 100x100
			return none
		][
			return load mapFileName
		]
	][
		return none
	]
]

mapLoadProgress: func [
	totb
	curb
	/local progPerc
][
	either curb / mapFileSize > 1 [
		progPerc: 1
	][
		progPerc: curb / mapFileSize
	]
	mapDwnlProgr/data: progPerc
	mapDwnlProgr/color: red
    progrInfoTxt/text: rejoin [ "    Loading map: " to-integer 100 * progPerc "%" ]
	show [ mapDwnlProgr progrInfoTxt ]
	true
]

mapPane: reduce [
    make face [
        text: ""
        offset: 0x0
        size: mapsize
        color: gold
        image: none
        edge: none
        effect: reduce [
			'draw rubber-box
		]

        feel: make feel [
            engage: func [face action event] [
				switch action [
					down [
						if any [ tgBtn-zoomin/state tgBtn-zoomout/state ] [
							rBoxStartPoint: event/offset
						]
						if tgBtn-pan/state [
							start-pan-offset: event/offset
							start-pan-geo: imgxy-to-mapxy event/offset

						]
					]
					over [
                        if all [ any [ tgBtn-zoomin/state tgBtn-zoomout/state ] rBoxStartPoint <> event/offset ] [
                            rubber-box/4: rBoxStartPoint
                        ]
						if any [ tgBtn-zoomin/state tgBtn-zoomout/state ] [
							rubber-box/5: event/offset
						]
						if tgBtn-pan/state [
		                    offset: offset + event/offset - start-pan-offset
		                    end-pan-geo: imgxy-to-mapxy offset
;		                    text: debugText offset

						]

						mouse-map-xy: imgxy-to-mapxy event/offset
						xyfld/text: rejoin/with [ pad-decimal round/at mouse-map-xy/1 2 2 pad-decimal round/at mouse-map-xy/2 2 2 ] " "
						show xyfld
					]
					away [
						if tgBtn-pan/state [
		                    offset: offset + event/offset - start-pan-offset
		                    end-pan-geo: imgxy-to-mapxy offset
;		                    text: debugText offset
						]
					]
					up [
						if all [
							any [ tgBtn-zoomin/state tgBtn-zoomout/state not tgBtn-pan/state ]
							rBoxStartPoint <> rubber-box/5
							pair? rubber-box/5
						] [
							rubber-box/5: event/offset
                            extents-history: next extents-history
							clear extents-history
							if tgBtn-zoomin/state [
								mapext: rbox-to-mapext rubber-box/4 rubber-box/5
							]
							if tgBtn-zoomout/state [
								mapext: zoomout-ext mapext rbox-to-mapext rubber-box/4 rubber-box/5
							]
							repend/only extents-history mapext
                            extents-history: tail extents-history
                            create-mapserver-url mapext
							face/image: loadMapImg myUrl
						]
						if tgBtn-pan/state [
							extents-history: next extents-history
							mapext: get-pan-ext offset
                            repend/only extents-history mapext
                            extents-history: tail extents-history

                            create-mapserver-url mapext
							offset: 0x0
							face/image: loadMapImg myUrl
						]
						rubber-box/4: none
						rubber-box/5: none
					]
				]
                show face
            ]
   			over: func [face act pos] [
				mouse-map-xy: imgxy-to-mapxy pos - mapBox/offset
				xyfld/text: rejoin/with [ pad-decimal round/at mouse-map-xy/1 2 2 pad-decimal round/at mouse-map-xy/2 2 2 ] " "
				show xyfld
			]

        ]
    ]
]

layer_switch: func [
	layerName
	status
][
	either status [
		if not find mapserver-layers layerName [
			insert mapserver-layers layerName
		]
	][
		remove find mapserver-layers layerName
	]
	create-mapserver-url mapext
	mapBox/pane/1/image: loadMapImg myUrl
	show mapBox
]


layerPane: layout [
	across
	check true [ layer_switch "roads" value ]
	text "Roads"
    return
	check true [ layer_switch "hydro" value ]
	text "Water features"
	return
    check true [ layer_switch "states" value ]
	text "State boundaries"
	return
]


mapAppWin: layout [
	style btn button 30x30
	style tbtn toggle 30x30
	across
	defSpace: space 0x10
	tgBtn-zoomin: tbtn zoominbt-img true [ tools-switch 1 ]
	tgBtn-zoomout: tbtn zoomoutbt-img [ tools-switch 2 ]
	tgBtn-pan: tbtn pan-img [ tools-switch 3 ]
	btn backb-img [
            if tail? extents-history [
                extents-history: back extents-history
            ]
		if not head? extents-history [
			extents-history: back extents-history
			mapext: first extents-history
            create-mapserver-url mapext
			mapBox/pane/1/image: loadMapImg myUrl
			show mapBox
		]
	]
	btn forwb-img [
		if not tail? next extents-history [
			extents-history: skip extents-history 1
			mapext: first extents-history
            create-mapserver-url mapext
			mapBox/pane/1/image: loadMapImg myUrl
			show mapBox
		]
	]
	btn navfullbt-img [
		mapext: base-mapext
        extents-history: next extents-history
        clear extents-history
        repend/only extents-history mapext
        extents-history: tail extents-history
		create-mapserver-url mapext
		mapBox/pane/1/image: loadMapImg myUrl
		show mapBox
	]
;	tgBtn-info: tbtn infobt-img [ tools-switch 4 ]

	space defSpace
	across
	return
	mapBox: box mapsize ibevel 6x6 none none

	layerBox: box 200x100 ibevel ;10x10 none
	return
	xyfld: field center 138 "" ibevel
	mapDwnlProgr: progress 200x24
	progrInfoTxt: code 138
]

mapBox/pane: mapPane

layerBox/pane: layerPane
layerBox/size: to-pair reduce [ 200 mapSize/y ]
layerPane/offset: 0x0

progrInfoTxt/offset: to-pair reduce [ mapDwnlProgr/offset/x + 5 mapDwnlProgr/offset/y ]
progrInfoTxt/size: 200x20

;mapsize: 400x300
imgType: "GIF"

mainWin: layout [
	button 200x20 "Open map" [
		view/options/title/new mapAppWin [all-over] "Mapserver client"
		mapBox/pane/1/image: loadMapImg myUrl
		show mapBox
	]
]

view mainWin