wmglobe: Add version 0.5 to repository.

From
http://web.cs.mun.ca/~gstarkes/wmaker/dockapps/files/wmglobe-0.5.tar.gz
This commit is contained in:
Doug Torrance 2016-12-27 14:22:04 -05:00 committed by Carlos R. Mafra
parent b1491b9d02
commit 3b8506cfaa
27 changed files with 7464 additions and 0 deletions

45
wmglobe/CHANGES Normal file
View file

@ -0,0 +1,45 @@
VMGlobe
0.5 released 6/02/99
- floating point exception bug solved
- many minor bugs solved (earth displaying, mouse, time management)
- compile time options in header
- night map option available in parameter screen
- option -time only available in command line
- new default map
0.5.pre1 released 20/01/99
- option selection through parameters screens (right button)
- approximation of date & time of view point
- new default map (bigger, better)
- display of time uses setlocale()
- option -dawn value : enhance dawn borderline
- option -time : change date displayed
- option -nonimap
- reorganize sources, little CPU gain, better earth displaying
- rename -austral to -oz
- modify comportment of -rand option when zooming
- change left button comportment : only change longitude
- shift+left button : change longitude & latitude
- man page
0.3.1 released 5/02/99
- option -austral
- solved bug about colors 24 and 32 bit per pixel
0.3 released 3/02/99
- right button : screen of digital modification of latitude/long.
0.2.1 released 3/02/99
- change & enhance mouse operations (longitude/latitude/zoom)
- minor bugs, CPU optimization
0.2 released 1/01/99
- bug about ipc & shared memory solved.
- new functionnality :
left click = change longitude
middle click = zoom in / zoom out
right click = change latitude
- a few hints for compile on *BSD
0.1 released 31/12/98

339
wmglobe/COPYING Normal file
View file

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

22
wmglobe/Makefile Normal file
View file

@ -0,0 +1,22 @@
INC = -I/usr/X11R6/include
LIBS = -lXext -lX11 -lm -L/usr/X11R6/lib \
-ltiff -lXpm -lpng -lz -ljpeg -lungif -lwraster
OBJS = src/wmglobe.o src/rend.o src/wmgutil.o \
src/sunpos.o src/myconvert.o src/mycontext.o
.c.o :
gcc -c -O2 -Wall $(INC) $< -o $*.o
all: wmglobe
clean:
rm -f src/*.o wmglobe
wmglobe : $(OBJS)
gcc -O2 -Wall $(OBJS) -o wmglobe $(LIBS)
strip wmglobe
install :
install wmglobe /usr/local/bin
install wmglobe.1 /usr/local/man/man1

349
wmglobe/README Normal file
View file

@ -0,0 +1,349 @@
WMGlobe 0.5 - The Whole Earth spinning on you desktop... as a dockable app
Copyright (C) 1998,99 Jerome Dumonteil <jerome.dumonteil@capway.com>
This program is licensed under the terms of the GNU GPL, see below.
Description
----------------------------------------
WMGlobe is a WindowMaker dock.app that displays the earth on an icon. It's
an adaptation of XGlobe to WMaker environnement. WMGlobe uses a map which is
rendered on a sphere by raytracing. Yes, for a 64x64 pixel result :-)
It's still a beta version...
Installation
----------------------------------------
You need WindowMaker to build WMGlobe. WMGlobe needs libwraster to compile,
this lib is built by WindowMaker. No more need at run time if statically
linked, but then, you need WindowMaker to get the full magic :-)
tar -xvzf wmglobe-0.5.tar.gz
cd wmglobe-0.5
make
then move wmglobe in /usr/local/bin and man page somewhere or do
(as root) :
make install
If it doesn't work, look for the graphic libraries.
The Makefile is quite crude...
WMGlobe is developped on Linux (WMaker 0.51.0 and linux 2.0.36/ix86).
If you are successful on other platforms, please tell me so.
platforms with successfull built reported :
NetBSD 1.3.2 / SPARC (wmaker 0.20.3) , with Makefile adaptations for libs
Linux 2.0.36 / RedHat 5.1
Linux 2.0.36 / SuSE 5.3 (wmaker 0.20.3) , -lungif -> -lgif
Linux 2.2.0-pre4 / Debian :-)
FreeBSD-3.0 with -ltiff -> -ltiff34 and -lungif -> -lgif
Solaris 2.6 / Sun Sparc (wmaker 0.20.3) , with Makefile adaptations for libs
AIX 4.2.1 / IBM RS/6000-250 (wmaker 0.50.2)
RPM & DEBIAN linux packages coming soon. Or you can directly use the binary.
compile time problems :
Xlib.h, Xpm.h ... :
If you compile wmglobe on a computer installed with packages (.rpm), you may
lack of these header files. Just install the "xxx-dev.rpm" packages for XFree86
and graphics libs, or install a rpm version of wmglobe.
libwraster :
WindowMaker 0.20.3 uses a libwraster.a , so if you use it, you can execute
the binary on a computer without WindowMaker on it, and displaying on a
remote computer (this one using WindowMaker). WM 0.51.0 creates a dynamic
libwraster.so, so it's necessary to have it on the computer running wmglobe
if you buit WMGlobe with this one. Both versions of WMGlobe run on WM 0.20.3
and 0.51.0
graphic libs :
you can use libgif or libungif. If your version of WindowMaker is built
without support for some graphic type, you don't need it (just remove it
from the makefile).
This problem may happen with RedHat 5.2, if you get this kind of message,
just add a libtiff to your system :
/usr/local/lib/libwraster.so: undefined reference to `TIFFReadDirectory'
...
make: *** [wmglobe] Error 1
compile time options :
You can modify the file wmgoption.h where many options are set up in defines :
To disable the builtin default map, just comment out the line in wmgoptions.h :
#define DEFMAPOK
to supprim the shift+left/left method of rotate earth, uncomment the lines
#define MOUSE_LAT_FULL
you can also suppress some options screen in wmgoption.h
Maps
----------------------------------------
Like XGlobe, WMGlobe needs a longitude/latitude map to work. By default,
it uses a low quality built-in map of earth. But you will probably want
to use better ones.
You can get maps usable with WMGlobe on the net. See the LINKS chapter.
using custom maps :
- For the image to be mapped correctly, position 0°North 0°West must be in
the center of the image and the latitude must be linear from 90°N to 90°S.
- When using a night map, make sure that day and night map have the same
dimensions.
By the way, you can use maps of Mars, Luna ... and text.
Configuration options
----------------------------------------
Configuration is done through command line options.
-v version
-h short help
-zoom zoom_value Value > 1 to magnify the view, value < 1 to lower.
Default : 1.0
-pos latitude long. Initial viewing fixed at this position, don't follow
the sun rotation. Accepted values in the form
45°12'36 or 45.21 or 45:12:36
Default : the initial position is "under" the sun, and
the point of view follows the sun
-rand New random position at every refresh of screen
-map map_file Map used for the rendering. Can be JPEG, GIG, XPM
PNM, TIFF but none BMP
Default : use internal map of earth.
-nimap night_file Map used for the dark side of the earth. Must be of
the same width x height as the day side map.
Default : if the default internal day map is used, use
a default internal night file (see -nonimap option).
If a custom day map is provided, and no night map, the
dark side is computed via the -light option.
-nonimap Don't use the default night map.
-delay seconds Time in seconds between each calculation of a new
position. Limited to 0.04 at compile time (25 frames
per second should be enough). The sun position move
only once per minute, so if you use wmglobe without
-dlong or -accel option, the CPU cost of WMGlobe is
*very* low. The use of very low value for -delay plus
-dlong and -accel can be CPU costly (but very nice...)
Default : 1.0 sec.
-dlat delta_latitude Move the point of view by delta_lat degrees per second,
with a value of 6 the earth make a full rotation in
one minute. The value can be formated as -pos option.
Default : 0°0'0
-dlong delta_long Move the point of view by delta_long degrees per
second. With a value of -0°0'15" the earth make a full
rotation in 24 hours toward the west. By default,
-dlong and -dlat are null. If they are used, the view
follow their values. Going back to "follow sun" mode
in parameters screen put -dlat and -dlong to zero.
-light light_value Level of light of the dark side when there is no
night map, from 0 to 1.
Default : 0.25
-dawn dawn_value Level of continuity for dawn limit, from 0 to 1. With
a value of 1, the border line between night and day is
at maximum contrast.
Default : 0.2
-bord border_num 0 1 or 2. There are 3 different borders for the icon.
Default : 0
-accel time_multi Time warp factor. With -accel 24, the sun make a full
rotation in one hour (or the earth, I'm not sure).
Default : 1.0
-time seconds Time to display in seconds since 01-01-1970 (see the
date command). Necessary if you need to be sure that
WMGlobe is Y2K compliant without changing system time.
Negative values for dates before 1970 accepted.
Default : not set, use current time.
-fun dx dy Move the earth image by dx dy pixels in the icon. See
puzzle.sh to understand why.
-oz Start in "austral" mode (for "down under" people)
-d display Select another display
-w -shape Useless, since it is set by default (WMaker dockable
application)
mouse :
left button Change longitude while pressed, change longitude &
latitude if shift+left button.
middle button Zoom in, shift + middle button : zoom out
right button Displays 7 screens of parameters. On every screen, just
clic with left or right button on the figures to change
their value. The TIME screen shows an approximation
of date and time of the earth zone currently displayed,
using GMT time + longitude offset, it's close to the
real local time by one or two hours. Others options
don't need more help. Intuitive they said...
Links : Some sites dealing with WindowMaker
-------------------------------------------
Official Window Maker Website :
http://www.windowmaker.org/
The Dock App Warehouse :
http://www.bensinclair.com/dockapp/
Links : Where to find maps and similar softs
--------------------------------------------
where to find the sources of wmglobe :
http://www.capway.com/dumonte1/wm/wmglobe-0.5.tar.gz
the web page of WMGlobe (made by Sylvestre Taburet) :
http://www.capway.com/dumonte1/wm/wmg.html
where to find maps and similar softs :
Earth image by a cgi :
http://www.fourmilab.ch/cgi-bin/uncgi/Earth
two softs running under X :
XGlobe Homepage: http://www.uni-karlsruhe.de/~uddn/xglobe
(the recent 0.2 version brings a very nice map of earth)
Xearth Homepage: http://www.cs.colorado.edu/~tuna/xearth/
For the maps XGlobe doc says :
« WHERE TO GET MAPS:
1. LivingEarth Inc.
http://livingearth.com/LE/LivEarthImg.html
http://livingearth.com/LE/BrillEarthImg.html
Livingearth Inc. has some nice (day and night) images on their web pages.
With these you can test the -nightmap option of XEarth. Unfortunately
they are pretty low-res (400x200).
You can find a higher-resolution (but heavily compressed) version of this
day map at the "Earth View" page:
http://www.fourmilab.ch/cgi-bin/uncgi/Earth
Check "No night" and set display to "map", then save the image.
2. NOAA NGDC Marine Geology & Geophysics
http://www.ngdc.noaa.gov:80/mgg/image/mggd.gif
This image is definitely not "photo-realistic" but nonetheless pretty
interesting. It also has a rather high resolution. »
Todo
----------------------------------------
- test on different platforms, better makefile
- changing map "on the fly", map generator, clouds generator...
- must work on every current WindowMaker platform
- see how to minimize CPU load
- feature : load a local detailed map of some part of the globe when zooming
(country maps, city maps)
- maybe port to other window manager
Bugs
----------------------------------------
- The Makefile
- if you use the --enable-single-icon compile time option of WindowMaker,
you can not display more than one WMGlobe.
- WMGlobe hopes that an overflow of a long integer dont generate an error
and that LONG_MAX +1 = LONG_MIN . This happens with high values of -accel
when the date go over year 2038. The expected result is wmglobe
continuing smoothly from 1901.
License
----------------------------------------
WMGlobe is Copyright (C) 1998,99 by Jerome Dumonteil and licensed through
the GNU General Public License.
Read the COPYING file for the complete GNU license.
Credits
----------------------------------------
Original idea, tests, logos : Sylvestre Taburet <staburet@consort.fr>
The code in 'sunpos.cpp' is taken from Xearth by Kirk Lauritz Johnson.
/*
* sunpos.c
* kirk johnson
* july 1993
*
* code for calculating the position on the earth's surface for which
* the sun is directly overhead (adapted from _practical astronomy
* with your calculator, third edition_, peter duffett-smith,
* cambridge university press, 1988.)
*
*
* Copyright (C) 1989, 1990, 1993, 1994, 1995 Kirk Lauritz Johnson
*
* Parts of the source code (as marked) are:
* Copyright (C) 1989, 1990, 1991 by Jim Frost
* Copyright (C) 1992 by Jamie Zawinski <jwz@lucid.com>
*
* Permission to use, copy, modify and freely distribute xearth for
* non-commercial and not-for-profit purposes is hereby granted
* without fee, provided that both the above copyright notice and this
* permission notice appear in all copies and in supporting
* documentation.
*/
The rendering engine is taken from XGlobe by Thorsten Scheuermann
XGlobe Homepage: http://www.uni-karlsruhe.de/~uddn/xglobe
Raster graphics library by Alfredo K. Kojima, & stuff of Window Maker
<http://windowmaker.org> by A. K. Kojima, Dan Pascu, Matthew Hawkins & team
Feedback
----------------------------------------
For your questions, bugs, remarks, please contact our representative on
planet Earth : jerome dumonteil <jerome.dumonteil@capway.com>

17
wmglobe/puzzle.sh Executable file
View file

@ -0,0 +1,17 @@
#!/bin/sh
#just for the fun, solve the puzzle and put it on the clip :)
if [ -x ./wmglobe ]
then
WMG="nice ./wmglobe"
else
WMG="nice wmglobe"
fi
HOP=" -delay 0.1 -pos -25 10 -dlat 0.5 -dlong -5 -zoom 1.8 -accel 240"
$WMG $HOP -fun 32 32 &
$WMG $HOP -fun -32 32 &
$WMG $HOP -fun 32 -32 &
$WMG $HOP -fun -32 -32 &
$WMG -map ./wmgmap.gif -delay 0.05 -dlong 25 -pos 0 0 -accel 10000&

38
wmglobe/src/cadre0.xbm Normal file
View file

@ -0,0 +1,38 @@
#define rond_width 64
#define rond_height 64
static char cadre0_bits[] = {
0x00,0xe0,0xff,0xff,0xff,0xff,0x07,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0x0f,
0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0xfc,0xff,0xff,0xff,0xff,
0x3f,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,
0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,
0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,
0xff,0xff,0xff,0xff,0x0f,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0xfc,0xff,
0xff,0xff,0xff,0xff,0xff,0x3f,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xfc,0xff,0xff,0xff,
0xff,0xff,0xff,0x3f,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0xf0,0xff,0xff,
0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,
0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,
0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,
0x00,0xf8,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0x1f,
0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,
0x07,0x00};

38
wmglobe/src/cadre1.xbm Normal file
View file

@ -0,0 +1,38 @@
#define rond_width 64
#define rond_height 64
static char cadre1_bits[] = {
0x00,0x00,0xc0,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0xf8,0xff,0xff,0x1f,0x00,
0x00,0x00,0x00,0xfe,0xff,0xff,0x7f,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0xff,
0x01,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0xf0,0xff,0xff,0xff,
0xff,0x0f,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0xfc,0xff,0xff,
0xff,0xff,0x3f,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0xff,0xff,
0xff,0xff,0xff,0xff,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0xc0,0xff,
0xff,0xff,0xff,0xff,0xff,0x03,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0xe0,
0xff,0xff,0xff,0xff,0xff,0xff,0x07,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,
0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,
0x1f,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xfc,0xff,0xff,0xff,0xff,0xff,
0xff,0x3f,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xfe,0xff,0xff,0xff,0xff,
0xff,0xff,0x7f,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xfe,
0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,
0x3f,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0xf8,0xff,0xff,0xff,0xff,0xff,
0xff,0x1f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xe0,0xff,0xff,0xff,0xff,
0xff,0xff,0x07,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0xc0,0xff,0xff,0xff,
0xff,0xff,0xff,0x03,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x00,0xff,0xff,
0xff,0xff,0xff,0xff,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0xfc,
0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,
0xf0,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0x03,0x00,
0x00,0x80,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0xfe,0xff,0xff,0x7f,0x00,
0x00,0x00,0x00,0xf8,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0x03,
0x00,0x00};

38
wmglobe/src/cadre2.xbm Normal file
View file

@ -0,0 +1,38 @@
#define cadre2_width 64
#define cadre2_height 64
static char cadre2_bits[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,
0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,
0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,
0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,
0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,
0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,
0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,
0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,
0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,
0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,
0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,
0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,
0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,
0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,
0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,
0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,
0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,
0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,
0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,
0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,
0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,
0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,
0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,
0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,
0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,
0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,
0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,
0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,
0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,
0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00};

247
wmglobe/src/defmap.xpm Normal file
View file

@ -0,0 +1,247 @@
/* XPM */
static char * defmap_xpm[] = {
"360 180 64 1",
" c None",
". c #B5FCF9",
"+ c #F5FDF8",
"@ c #7BF8F9",
"# c #84D8CD",
"$ c #82A7C9",
"% c #68BECA",
"& c #48BEDC",
"* c #48A4D2",
"= c #67A4C6",
"- c #6BD7DB",
"; c #4BF6FA",
"> c #438BC6",
", c #4CDCE6",
"' c #BBDAD0",
") c #82C0C6",
"! c #3053D6",
"~ c #3A3AFF",
"{ c #306FC2",
"] c #A1D8CC",
"^ c #648DC4",
"/ c #4570C8",
"( c #425CCD",
"_ c #A4C1CB",
": c #D7E0BC",
"< c #5A76C2",
"[ c #99ACC7",
"} c #81BF40",
"| c #8895D0",
"1 c #69A742",
"2 c #6D8F55",
"3 c #3A8E3D",
"4 c #BCD65E",
"5 c #5B7670",
"6 c #9FC04F",
"7 c #B9C155",
"8 c #9ED55E",
"9 c #DFC33E",
"0 c #9DA947",
"a c #82A745",
"b c #D7D955",
"c c #69BF3C",
"d c #69D947",
"e c #84D650",
"f c #B7AB41",
"g c #8E9243",
"h c #74ED42",
"i c #4EEC36",
"j c #445C91",
"k c #AAEE5E",
"l c #4EDC3C",
"m c #37D833",
"n c #3EC039",
"o c #46A63E",
"p c #34A439",
"q c #DCED65",
"r c #31734A",
"s c #45736A",
"t c #315594",
"u c #FAF755",
"v c #737A6D",
"w c #D58E2E",
"x c #F0DD45",
"y c #E2A935",
".+.+.+.++.++.+.+.+.+.+.+.+.+.+......+..+..+...+.........+.+.+.+....+..+...+.....................+..+..+..+...+...+...+..+..+..+...+...+...+.+..+.+.+.+.+.+.+.+..+.+.+.+.+..+.+.+..+..+..+...+..+..+..+..+..+..+..+..+..+..+..+..+.+..+..+.+..+..+..+.+.+..+.+.+..+..+..+..+..+.+..+..+..+..+..+..............+....+...........+......+...+...+..+...+.............+....+",
".+.++++++++++++++++++++.+.+.++++++++++.++.+++.+.+.+.+...+++++.++.+..+..++..+.+.+.+.+.+.+.++.+.+.+..+.+.+..+.+.++..++..+..+..+.+.+.+.+..+.+..++.+.+.+.+.+.+.+.+.+.+.+.++.+++.++.+.+.+.+.+.++.+.+.+.+.+.+.+.+.+.++.++.++.++.+.+.+.+.+.+.+.+.+.+.+..+.+.+.+.+.+.+.+.+.+.+.++.++.+.++.+.+.+.+.+....+.................................+......................................",
".+.+++++++++++.++++++++++++++++++++++++++++.++.+.++.++....+.+++++..+.+.+.+.+.......+...+...+..+.+.+.+.+.++.+.+..+...+.+.+.+.+.+.+..+.+.+.+.+.+.+.++.++.++++.++.+++++++++.++++++++.++.+.+.+.+.+.+.+.+.+.+.++.+.+.+.++.++.++.++.++.+.++.+.++.++.+++.+.+.++.+++.++.++.++.++.+.+.++.+.+.+.+.+..+.+..............................+...............+.......................@...",
".+.+.+...+.+++.+.+++++++++++++++++++++++++.+.++.+.+.+++.+..+..++++..+.+...+.+.+.+..+++.+++.++.+.+++.++.+..+.+.+.+.+.+...+..+..+.+.+..+...+.+.+.+..+.+.+..+.+.++.+.+.+.++.+.+.+.+++.+.+++.+.+.+.+.+.+.+.+.+.++.+.++.+.++.++.++.+.++.++.++.++.+.+.+.+++.++.+.++.++.+.++.++++.++.+++.++.++.++.+................................+.+...+................@.@..@.@.@.@.@.@.....",
"..+.....+..++++++++++++++++++++++++++++++++++++++++++.+.+.+.+.+.+.+...+.+...++.+.++.+++++++.++.+.+.+.+.+....@.@.@.@.............@.@..@..@...@@.@....@.@.@.@@......+.+.+++++++++.+.++.+.++.++.+.+.+.+.+.+.+.+.+.+.++++.++.++.++.++.++.++.++.+++.+++.+.++.+++.++.+++.+.++.+++.++..+..+.......................@.@.@...@................................@.@.@...............",
".+.+++.+.+.++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.+..++..+.+..+++++.++++++++.++.+..#$%&*&&*&**&=&--.@@@@@;;;;;;;;;;;&&*%*>>>**=********&,,,#-@@..@......+.+++.+++.+.++.+++.+.+++.+.+.+..+..+.+..++.++.++.++.++.+.+.+.++.+.+.+.+++.++.+.+.++.+.+++.++.+.+.++.......................@.@.@@@;;;;@.@@.@...........................@..............+......",
"..+.+.++.+++++++++++++++++++++++++++++++++++++++++++++++++++.+++.++.++++.++++++++++++++++++.+...')$%%>!~~!!~~~~~~~~~~~!!{>*>>**&&>*>*>{!!~~~!~~!!{{!!!{!!~~!>{{{!>&%&%-@@@@@@...++.++++.+.+..+.+......+....+......++..+..+..+.....+.+..+...+.+..+.+..+.+.++.+.+.+.+..+.+.++.+.+.+.@@@@..+.+...++.+..@@....@@@;@;@@@@.@..@....++.+.+.+................@....@.............",
"....+.+.+.+.+.+++++++++++++++++++++++++++++++++++++++++++++++.+++++++.+++.++.+.+.....+.+.]$^/(/(!{^$_]_].+.+...])$&=*!~~~~!~!!!!~~~!!>&*^>)$=$:.]..@@;;;,,{!~~~~~~~~~~!>****,;@@.+.+..+.']#_)%)=^^^^<=$%$^=>=-]..].'':.+.+...+..'.].':..:''.+:.:..+.+..+...+.............+.++.+......+............@@@.@....@@;@@.@@........+...+.+.+.+.+................................",
".+...+.+.+.++.+.+++++++++++++++++++++++++++++++++++++++++.+.+.+.+...+.+.+..+.']._)[)^>({(/)'''.+.:+..+++++++++:+.]%/!~~^$)'.+:#.]=]+:+..++++++++++++++..,,,&&&{~!!{~~~~~~~~~!{{>>%)%)$^!~~~~~~~~~~~~~~~~~~~~~~~!~~~~~!!~!!(</!!~~!~~~!~!~~~({{>!!((><<^/-@,,-&&*%=>>>>>^$)]])$-)=>%#%=^&-&&%)#@..@@@.......@......+.+.+++++.+++...+.++++++.........+++.+.+..+......+.+..",
".++..+.+.+.+.++++.+++++++++++++++++++++++++++++.+.+++++.++++++.+.+.....])^/{~~~~~~~~<%''=>*)_=_'_]+']]'+.+:++.]^!!)''.++++++++++++++++++++++++++++++++++++..@;;;;@=>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!!!~!!~~~~~~~~~~~~~~~~~~~~{>**=(~~!{%%&/=%~>^!~~!*&&{~~~~~~~~~~~~~~~~~~!/#..#{~~~~~~>#..+..++++++++++++++++++++..++++++++........+.+.+.......+++.+.+.+++++.+.+.+",
"++.++.++.++.+.+.++++++++++++++++++++..........+..+...+.+..+..'_]]-%$<(!~~~~!~~~~!~~~^)].:.:'%<*#$})'.+++++'$^!~~~!(:++++++++++++++++++++++++++++++++++++++++.@@,,>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=^=|>][))_)]]])<~~~~~~~~~~~~~~~~~~~~!~~~~~~~~!!!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!>>#.]##>~~~~~~/).++++++++++++++++++.+........+.+++++++++.+.+.+.+.++++.+++++++++.++++++++",
"+++++++++++++++++++++++++++++.++++++++..+.++.+++.+.]#$=^//!!~~!~~~~~~!~~~~~/>>>(~~{!!~<)'.'$1232#:.++++''>~!^|_':+++++++++++++++++++++++++++++++++++++++++++.@@!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!>)'__4::_=/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!(/>((>~~~~~~(]+++++++++++.+....@@@@;,,,,,@@.....+.++++.+.+.+++++++++++++++++++++++++",
"+++++++++++++++++++++++++++.+.+.++++.++..+..+....@@%>!~~~~~~~!!!~~~//{~~~~~~~~~~~~~!!~!~!>~!>=%#].:++'=<!~~!|['.+++++++++++++++++++++++++++++++++++++++++++..->!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!~!<(!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{>>~!~~~!>_+.+.+.+.......@@@,-,,;,&&&&&-@@.....+...++.++++++++++++++++++++++++",
"+++++++++++++++++++++++++++++++++++++.++.+.+.......+.]>~~~{==>=>{(!~~~/!~~~!/~!!//~!^*<<^==^))'_]'#+.$!~~~~~~/=:.+++::++++++++++++++++++++++++++++++++++++++.-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!!{>%#>~~~~~~~~~~~~~~~~~~~~~~~~~!!(!!!(=]]-%*>><^/!(-...@@@@----]@..@...+..++++++++.+++.+.......++++++++++++++++++++++",
"+++++++.++++.++++++++++++++++++++++++++.+..+.+...+..]!~~~!!!!!~>-%%*//>%*=!~{({*)-!~/*!/_})5>/>$___$<~~~~~~~~~~!!~~~!~~(<[++++++++++++++++++++++++++++++++++..*!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!*))#)=^/(~~~~~~~~~~~~~~~~~~~~!!(<^|$6_6_62]474].]#]]4__/**{!~~!~~!~~~{!{,;;@@;,#8]'].':++:+++++++++++.++++++++++++++++++++",
"+++++++++.+++++++++++++++++++++++++++++.+...+.+..])>!~~~!!!!~~~~!!^*>>!!!~~~~~~~!!~!/={~^^[^$[______(~~~~~~~~~~~~~~~~~~~~~/'+++++++++++++++++++++++++++++++++.%{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!%]#^(~~~~~~~~~~~~~~~~~~~~~~~~~^__474747794702a00a676776a$!~~~~~~~~~~~~~~~~>,;;;;;,,--]...+.:''++++++++++++++++++++++++++++++",
"++++.++.+++.++.+++++++++++++++.++.::+'.+....)^/(!~~~~~~(-###%-)>!~~~~~~~~{>!~~!(>>{~/)%=*!~{>={!(=^^$$^!~~~~~~~~~~~~~~~~~~~!]++++++++++++++++++++++++++++++]_=!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*-->!~~~~~~~~~~~/!~~~~~~~~!<<^^$17497b777777777[76777$a2[aa<<<^<(~~~~/>/{!~~{&,;;;;;,&&--%==|<^$[''_____':+:++++++++++++++++++",
"[___.+....+.@@)><>^_'++.)//{!!!!!!~~!~!!!(!~~~~~~~~~~~!%##]#)>%-#)*={{>!)%%~~!>>%%=!{)^/!~/%c>/%)_]>=$:'<~~~~~~~~~~~~~~~~~~~{#+++++++++++++++++++++++++++:#$)>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!%-=!~~~~~~~~~~~!=_)^~!<~/(!(]4947977477979777777770a0a06607774bb476)$^)6)*=*!~~~!!{>*{>22a=/{!!!~~~~~~~~~~~>(><$''___[|[__|^|[|",
"!!~~/{{/{//<{!~~~~~~~!^<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!<)#)>!>#########-cd#{~~~!>$>!>c{~~~=c)1=}6e6%}%]+.]/<!~~~~~~~~~~~~~~~>&*'+++++++++++++++++++++++++']']/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!%--=!~~~~~~~~~~([47:2^)=a$]_6a[699797f774777979fffa0ga0aa6007f7f77b7b:40776a%(~!>{{{{(>=48_6))_'_=!!~~~~~~~~~~~~~~~~~~~~~~~~~~~!",
"/!~~~~~~~~~~~~~~~~!!/>=*^>>/!!(~~~~~~~~~~~~~~~~~~~~~~~~~~!~~~!>%c)c#hhhhihh%{(~~~~~>hii>~~!>*c))e)e-)c)7:+:']$^~~~~~~~~~~~~~~!*&#+++++++++++++++++++++++++$>)=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!/<=^^$$$<~~~~~~~~~~~~~~~~~~~~~~!^>>~~!~~~~~~!_4b44)j_7776774$a777777776}}}00a00aa222121a0a00f7ff6g0g0:+0g6:_g|7b[0_67777647766_4_[||$___>/~~~~~~~~~~~~~~~~~~~!",
"~~~~~~~~~~~~~~~~!%)##eekk]8#88]c-#%%=*!(!~~~!!!{{**=->!>!>>(~~!%--lllhlmlnllm*(~~{>>opmn3!~~~!{c%1/{/!/))]]8)4'#>~~~~~~~~~~~~).%{.++++++++++++++++++++++++._<!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!(2[1}4_8]]]8_)$$!!~~~~~~~~~~~~~!(~~~~~~~~!{=$$^(!!$7777[<8667779b7777f7aaa}a}aaa0ag0gagg221211a}a07f77:::q0ga7+++bf:+f0066f0f7777767677666676[%>(<^<//<>~/==^^^^/!!",
"(!~~~~~~~~~~~!^=)8ddddde8e8k4kk8kkkkk8##-%==%n%dkhkh#h#hhhhhld*=c>>&*>*>npp>>!!~!>d&!{nmmp&*!~^)}%{~~~~/*})]876]{!~~~~~~~~~~~~!~!_+++++++++++++++++++++'[|/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(=^66a}}88648)8b'4:]']_|(~~~~~/(~~/>!/^=!^^^$^[49977[2a4947/$66a777777f7000a}a000}aa0aaa112ga1111aag00f0b497707:+q+:f:970ff007f00006000000677746a6))___])))==))6)a))[)",
"6)=<!~~~~~~~~~!^#8dddldehkkk]e:ke]deeeeddddkhdhhhhkhhhhhhhhihhhihp>r*p>rmiin&p>*oclcplmmimic{>#}))/~~~~)%((=8'8:+')>~~~~~~~~~~!>=+++++++++++++++++:|(!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sf6}ccc164666}6444_8'''':_$~~!]=(!^[]'77'4'b'4bbb7977777b7_ja7967f7779f707600}000aaa1aggag211a1}1a06440}6a00g2::+:+q::9ffgff00f70ag0g0000ff77777067667774_8_7744777447",
"6668){^=>~~~~~!/tr33pcdddddddldhhlihlhhhhhhhhehhhihihiiiild>&dihiiilhiinnhilmmlihldhliimimilc%*==>!~~~~~!~<)628]_':.#*!~~~~~~~(=)'+++++++++++++++_!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!|68acc}6446686}86688)}_]]'])!(()_$_'b9b4b7949b749776f77ff022[7977676f6776}aaa}0aa6aa}}aa2g2ag111111}aaa1111111120+++::f7u90gfffff00f0g0gg000ff7ff704:7776_74:77706067f0",
"^v)[8)8))^~~(%#8)-ccmnclnnlhhdlddlllihhhhhkkhhhhiiiiiiii,>{{pnliiilmmmiiiiiimmllllllmlmiimmd%>>{!~~~~~!~~{##}668=!/)_>~~~~~~~~!*''++++++++++:_=/~~~~~~~~~~~~/%^{^=))#^~~~~~~~~~~~~~~~~~~~~~~~~~~g7acc1}7b7|^2866666688$!~(!/$#']44:4bb4774477477770f67777767649766a}66a60606}}a}}a}a}ac}a111111111c1aa21a1121o111g:b+++7::gf00ffffw0fggff0g0f7ff60007:47:+b9777600770[6_",
"!~~~!^)^~~~~~/^=1=3dcnlllndnmcdkkchidihhhhhkkkhiiiiiiiiimnmlililiiiimmmnmmnmmmmmnlmlmmmmimi%>()#%>!~~~=-^*$]%}]8]=<~!~~~~~~~~~~~{)+++++++++]~~~~~~~~~~~~~~~~~/e]6.++.=!~~~~~~~~~~~~~~~~~~~~~~~t|71cc164942~!=666676776}//)$2)4b4b447468666477666600606f7666766666}}c}}66}06a}}}1}1}ccc11a11112111o11a0a1111112o11aa7::++++:b+4776000ff0gf0f000gag0_:v:++::::970776706a5j",
"~~~~~~!~~!~~~~~~~!rnnnldedo]k+.:+.keddhdlhehkhhiiihiiiiiiiiiiimiiiiimmlmmmmnmmpnnnmlmlmmm*!!~{=%({>!~~!~~~~{$]]})6)/~~~~~~~~~~~~(#+++++++++<~~~~~~~~~~~~~~~~~!/*=]^<~~~~~~~~~~~~~~~~~~~~~~~~jv[0acdc}9b[v!56746676774868864q4747b948}cd}c}e}}}8}}aa}6af7}}676}6}}}}}c1}}}}ac}}cc11}1cc}1111121211112a0aag112o11o1212a0777:+:+++++b7fggggfggwggg70:::::9:f77ffff677777[a~",
"~~~~~~~~~~!~~~!p%ddcncdeddo1+:e6}4':+qeccdeddkhihiiiiiiiiiiiimiilllmmnlmmmmnnn{pmmnmmli*{!~~~~~~((~~!~//!!(~~/=)%>/!~~~~~~~~~~~~~*:++++++]!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!v06}}1ccc677j!~_76}11aa6646688bbb744b748ee}dcc}}ccc}111a}}}6676}}666}}}c}c}}}}a}}1}}}}}1}1ac11a22221212112222a12111111o1o132522v2fb:+++++:47000000070++++7fgg5v20ggg7+++:_'_]<",
"~~~~~~~~~~~~~~*cnncpnnncdhe+eoddk'}]::+:88k}kdhdiiiimiiiiiiiiiii&t{nmmmmmmmnnnnmmmmmml{~~~~~~~~~~~~~/~#8_4])!~~~!!~~~~~~~~~~~~~~~~<:+++++)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~0fa1ccc1}a74v~~~a701c1}a7f686}14bb486466e}dcccdcdcdcdc11a6}}}66}}}}}c}ccc}}}}c}a}}ac1c111c1aaaaaaag1221222522g11aa211111o111o231226:x::+++++++::7+++:++_vj5g_2s0:++:++:05<!~~~~",
"~~~~~~~~~~~~~!t>1nnldnlnce]%odd-><]8].'++'_:8dldhiimimmiiiiiiiimp&lmimmmmmmnmnnmnmmnm*~~~~~~~~~~~~~~~~=664648)/~~~~~~~~~~~~~~~~~~~~!||_+:!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!071oc1cc}}67[(~![886_}$64as288}4848}eee}ddceccdcccccc}11a}c}}67}1cccccccc1c1}c}}a}}}}cccc1}c}aaagga2g222222a11111a2121o1111112121a4q:ff+:b::+++++++++:v!~~!5t^'+_72g_[5t~~~~~~~",
"~~~~~~~~~~~~~(~!({clcponnc*t*)<!~~~!!jj^16:'q#dplilmmliiiiiiiiimiiimmmmmmmmmmmmnnmmmi{~~~~~~~~~~~~~~~~a4486744<~~~!=~~~~~~~~~~~~~~~~~~!^(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~271cc1a}g667f[~~!/2a252a04676e6e}6}e}c}edc}dcdcdccccc11}6}}e}66}}cccccc1c1ca}1}}0}aa}}1}1c1caa0ag22a2g222212a4a21a04a1212o1112216407f0++4a2[022gv|07[5~~~~~/_:vjt!~~~!~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~>s>s3nd#{!~~~~~~~~~~~~~t$)}8kcdlclmmmiiiiiiiiiiiimmmimimmmnmmmmmnmmn*~~~~~~~~~~~~~~()4844448c<!<)]=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/(~~~~~~~~(6}1j!10af675t~~~=$676}}8}}}}}eee68}dcce}d}eecece}dcc11a0}ccc}6}c1ccc}1}1c}}}}0}a}}}a}c1a}}ca0aaaagg2g1g121107f067:+7a212221a264+72g7:+7/!~~~~~~~~!t!~~~~!5::vt!~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~!$)>5&/~~~~~~~~~~~~~~~s#11.8]8]dcnhmiiiiiilhiiimiimimmmmnnmmnnmmii>!~~~~~~~~~~~~~!6886484ee#8848=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{1c3/~~~~~~~~!!!!/(7676$!|!~/as6471}e}}}}ee}888}ec}cecdcddcc}cccc11}66d}c}}}}c}cccc1}1}a}}}}}aa}11cc}1a1aaag0g121212a1aa0660:7++:+7440::q4+::+a6++$!~~~~~~~~~~~~~~~~52:+72~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~^%^!~!!~~~~~~~~~~~~~~~~~{=odnce''#1cdliiiiikhhimiimniiimmnmmnnnnpmmnhd&>~~~~~~~~~~~^}e86}48166k6k8!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!=cc3~~~~~~~~~~=c=!26}8|~!~!_776766}}cccceecd}ec}}e}e}dd}}}d}dcdcc}6688e}}66}6}a6}ac1cc}a0}}}aa11111a1aaaaga222a2111}1a07:7++q++4q:+q:7'::+:70++_/~~~~~~~~~~~~~~~~!22:::2v!~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~(/^/~~~~~~~~~~~~~~~~~~~~~~~~~2noldk}'kdnomiimiililliiimnmmmmnmnmmnpnmnnlldd%*(!!~~~~~/84}}}a676}86a88=(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!scc1!~~~~~~~~~^c12a_^!~~~~t677666}c}cd}ccdeced}d}}eedce}e}6}e}cc}}}664777777977f606a}}766f}6aag1gaaaaa0gaga222g2aa6a6ga094:b:+b7:++:+++++:x::b|t~~~~~~~~~~~~~~~~~/2::072!~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~!t!onlnooddcdndiilllmmmimmmmmnnnmmmnpnnnpnmlnddn%c-=~~!=88a}ccnn188cdek88})>!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{1c>/2}a!~~~~~~~~/1132s!t>2^/60660}}}c}}ceec}eeed}ee}}8}e}8444488}}}66679xxx9xxx9497976779b99977aa1a}66b07g622g221g2a'2670074f++::++x:4f77fb:4002s/!~~~~~~~~~~~~~~~~(0:7gv<~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=~{ndlnocdoc8keddlnniiimimmmmmpn3p{3mmmmmmnncoceeed~~!eenoonnmnnndlnnldeco}$/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^}4)~~{}86!~~~~!jsocc1a81611a}6}6666}a}6e6e}ece}dc}ce}}88446bxxb7478fb9bb9xxxuxuux9b9bb9bb94999x90aa0a467+qu0g002221083070004b:++:x:b4:+:0aa0a00aa121a5(^!~~~~~~~~~~~!_:62!~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!~tcdmllnnncek+kddldhiiimmmmmmnpp>!mmmmnmmn3oodeed3!~cnnmnnnnnmmlmlmlllce66)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>161!(c}}61(~~!3ccccc}a6}1}}}ac}}e}8}}66686e}}}eeee}e}88}44xqxxb994769xxxxuuxuuuuuuxxx9bbbbbqxuq977f704:+b74q:bf00a112_4404:+q::::9++::9qf0060a0}1a0a2128(~~~~~~~~~~~~$4<~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~tdekddlllnd]q.dlllilimmmmmmnnpnnpmmmmmnppppnopll{{nnnnppnnnnmmmllndde}6$=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!>>t~~>1cee}!~jocc1ccc11}1}}666}c}cc}cc}}8}6}888}e846848484bxxbxxxb97b9xxxuuuuuuuuuuuuuxxuxxuuuuuxbx9774:7:b4:b'b47aa6407:+:+:xb9fff7+ub77fffyff7610a66a50/~~~~~~~~~~~~/5!~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!od1dklmlmnnck'hdlmlimmmmmmmmmnmmmmnnnnppnmmmpnpmnnppnppnnnnmlndee)e)^!/%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/*/5/j{1c}c}ccc}c1111}aa}}c}c}}11}66}664bb4e}844bbb74xqxquxxxb9xxxuuuuuuuuxuuuuuuuuuuuuuuuuuxbbx:7b+::77f0:::470f79q+:x:9yfyf79+:9yfwyy9yf:4600:_v!62~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!1ennlmmmmnoc:enllilmmmmmmmnmmmmmpnnmnn3nmnmmnnnnnpnnpnnpnmncr!!{!!~~~[a!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{j*1ccccccc}ccc111}1111}}1c11}}66}}664446}8464bbbxqxuuxxxxx9xuuuuuuxuuuuuuuuxxxuuuuuuuuxxuq+:xf4xb9::b777ff077:+++x9x9xfff:++x9f9fyfyf0ff0a6:as~a=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{}pomlllmno%kdnmlilmimmnmnnnmmmnnnmmn{{pmmnnpnnmnnnpnnpmmpon}/~~~~~^6}[=!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(^>a6}ccccccc1}ac}111}}1}111}}}0}6646}6}64bb4bx49bxuuxuxuuuuuuuuuuuxuuuxuuuuuuuuuuuuuuuxxbbx:x+q+bf7:+9+:bb77gb:q++xx9x999y9x::9yyy9yy9f0aaaa0q:2!!a!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~2dcdldmicdooppocllliimmnnmnmnmnmmm3!!~~{mmnnnnnnpppnpnnmmm}c!~~~~!<^^1=<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~t>168cccccc1ncc}1caaa}}6}}ca1c}a}679bb97b77b99bxbqxuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuqxxxb:u+ubb9bbf:qbbf7bb99xuxxxx99xxx9q9yy9999fgf2aag047g(~!^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~thhhhdlmnncccoponniiiiimmmmmnmmnmnp*p>{{pnnnnnpppppnpponmlee{~~~!~~~~~~/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!a4}ccccc1c}:8a}c1aa}}}6}e}}}}67b7g77b6vr7qxxxxuuuxx4|s5buuuuuuuuuuuuuuuuuuuuquuuuuuxuubxuxbx9xu++47fb:x:x9xxxxxuxxxxxx9xxb9y99999wgga2gg007as~~t=!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!8keedncd#.:]'eopnnnmiiimmnmmmmmmmmmnn>>&!{{3nnnpnppppoolndco*>{!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~j}ecccncc8:+}a2a6}}0}6}76}846860t~s645s5bxxxxxxuub5!~<0uuuuuuk#quuuuuuuuuuuubuuuuuuquxuuuuuuuuxxxu+:bbx9x9xxxxxxxxxx9xx99:9999799fgggg1ggg0^~~~!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~tkhkhhln}k'+48]:ok3pnmmnmmnmmmmmmmmmm>!di&~{3nnmmnmppooon>t>c*/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~s}cnccncc1:1165t566006a676}4b70j~~~^ajt^4bxxxuxuqg~~^q+uuuuuk,dquuuxuuuuuuuuuuuuuqxxxuuuuuuuxuuuxxxuu999x9xxxuxuuxxxxx9x:ff979fyyf22g21g0gs~~~~s$j~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{hdhkhhickkk'8:ee'}onnpnmmmmmmmmmmmmm{{lll>olmp33nnnpnot~~~>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/=</({!3}dcn11}1stt1}62t5666}a74667bba~~~~~~~~~t2499xxxq7~~t'uuuuuuukquuuuxxuxuxxxxxuuxxxuqqqxxxxxuuuxuuuuuuuuuxuxuxuxuxxx9x997ff0f707fgggag12aa/~~~~!267)/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sdihkhhhdhk8e]:'#k]enmmmmmmmmmmmnmnmn{!llmn*>pppppp3ppt~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!64611111::cct~~!~!<j}6fs~t5f80697777bj~~~!~!~~~~~t7bxxuuqv~~t_uuuuuquuuuuuuuuxxxxbuxxx9qu+uxxux9x99xuuuuuuuuuxuuuuuxuxuuxxxx997gagaa1g0gga02jjj!~~~~!=2[2j~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~tiddhkkhkkqu}'8]8+:.onliiiiimmmmmnmnnpppnnprpnppp3rpp*!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~a7f66ff6a:1r!~~~~j5~!=77fj~tg7794999x2jj504705t!ttgxxxxuq:|~~^2quuuuuxuuuuuxuxxxxbxqu:q:xxxqxxxxx9uxuuuuxuuuuuuuxxuuxxuxxxxxy04aaa01agagga2!~~~~~~~~~>!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(llhhkkqh8qu7:+]o'q+oolilihiiiimmmnnnnnnpnpnnp3333p3t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~a7f9799775!~~~~~~|0~~~t|b7|t[b9972vff0bbxxxxqxb979xxxuxuxx:!~!'buuuuuuuuuuuuuxbxxq:+++xuxuuuuuuuxuuxxxuuuuuuxuuuuuxxxxxxxx9x7f0ga1s11aggga/~~~~~~~~~!2^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~tcilehkkkquu4:86]8.:onnhdhhhhiimmnmmmmmnpnnnnp33rp3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(bb979qxx7~~!!~~~~0g~~~~~v7t!j7b75~jf9xxuuxuuxxxxxx9xuuquqq7~~~_uuuuuuuuuuxuxxuqu+++uquuuuuuuuuuuuuuxuxxuuuuuuuuuuuxxx9999x9900a1s!52s5aagt~~~~~~~~~~(6[!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>diekkkqkqq4:1o1]q'1oldiiihhkilmmmmnmmpnnnnnpr33pt~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(bxbbxxuu7~~~~~~~~!!~~~!!jf~~~5790/!g9xxuuuxxxxx9xuuuuuxuxqv~~~tuuxuuuuuuxuuxuux:u:+:uuuuuuuuuuuuuxxxuuxuxuxxxxxuuuuxuxxxyffffa2j~~!~~!a66(~~~~~~~~~~sa<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!3hd'kkqqqqqkoc.+:.enldihddhhhhlnmmnnmnnnn333rp3!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~7bbxuuu_(~~~~~~~~~j~~<':5!~~~!|bg(!5y9xxxxuxx9xxxuuuuuqquu7<~~tuuxuuxuuxuuuuxbx::++u:uuuuuuuuxxbxqxxxuxuxx99999xuxxuxxxyffw00aa}j>s!~~/2g_!~~~~~~~!sa1!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!ohcqquuqu4kcn}e.:8nlhhhiidhhkmmnnnmmnmnp3rrrpp!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!g70v5!~tvg0g07f9x7!~!<!~~~~~!|j~~~vg9fgfbfg9uuuuuuuuuuuuqu_$_qxqxxxxuxuuuuuxquxq:++xquuuuuuq99q:xubxxxxxx99yyxxxux999ff0f00a}}a}/!~~~2a2/~~~~~~/1112~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{dkquuuquukkcdc'.}3nlhhddhdhdllmmmmnnnn3rr3pnp~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!v5jjvf9xuuuuuuuu:j~~~~~~~~~~~(^<!(~!~~jvj5xuuuuuuuuuuuuuuuuuuuuxxxxxxuxuxu:q::++:+++++qqq++u+ux:ub9q9f9997f9f9999fff00000a}ec=!~~~~~511/~~!/s>11}=/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>c8quuxuxq8k]38]ppcehkhlhllmmmmmmnnnnprrronp{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~vuxuuuuuuuuuuuuuu9j~~~~~~~~~~~~!(~~~~~~!=!jquuuuuuuuuqxuuuuuuuuuuxxxxxxuquqx9b09+++:u:uxxxx+x+qxxb+q:xbff9f0ff00gfggf0a0}}}}cc2!~~~~~^5(~!<}12o={!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~tj6uuuuux8]eoc8cndqqbkddhllnllnmnlncp3r33{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~tgxxxuuuuuuuuuuuuuu45~~~~~~~~~~~~~~~~~~~~~~!auuuuuuuuuuuxuuuuuxuuxuxxxuxxquxqqq7bbb:++++xqxxxxu+xxx:x::++b7fff6fffgffff000}cce}}a^~~~~~!~~(2o1^s/!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~jb4uuuuqcer311ocbkqqeldddllmlmmnonnp33!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!9xu9uuuuuuuuuuuuuuuuu97gj~~~~^:_5!~~~~~~~~~(kxuuuuuuuuuuuuxuuuuquuxx9xxuxxxxbb9qqxb7:++++:x9bxxx:xxx++:+++:b000f0wg0f0f00}ac}c}e}_!~~~~~~~($2(!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~a46buuu8co33on}bqqkkddeehdilnnnnmnno!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~0uxxuuuuuuuuuuuuuuuuuuuuu7j!~juuuu:[|/!!/(!jauuuuuuuuuuuuuuuxuuuuquxxxbxuuuxb999bu4747q++++:+b9xxb9:++:++:++:b77gfgfggff}}6c}}}cc}6$~~~~~~~~=/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!65tuuuq8eonnd84bxk4eekqhlinn33nnmm3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~fbxxxuuuuuuuuuuuuuuuuuuuuuu:|vuuuuuuuu::48quuuuuuuuuuuuuuuuquxuuuxqxxxxuuuuuuxxqxb46797y7:+:+:::b::u+u:q+++++++:fggg0ag0a}}}a8}}ce6=!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<$tguqu4}8}oc87xb8ekk}21o*t~~!t{rno~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~jbxuxuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu0jaquxuuuuqxxxxuxuuuuuxbbbxb9bbf7b+++:u++:bf_:+++++:+bgggfgg0a1a1c66}8}c})!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~s%j0uuq8qb}o148behc{~~~~~~~~~~~~3n!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/~(<!v:quuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuqquuuuuuuuuuuuu0~~'xquuuxuqqxxquxxuxxquuuux9bbxb7f9+++:+++++++++++b72gggggga111}}}}}ecdc*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^]/tgub}}4kcc18}e}!~~~~~~~~~~~~~rn>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!/!5:uxuuuuuuuuuuuuuuuuuuuuuuuuuuubuuuuuuuuuuuuuuuq^0qxuuuuuuuuuuu5~j6qxquququxxxuxbqxquuuuux79bbxbb70f7+++:++f77g4bag2ggg0g0a111}}}}6e})=!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<%/~aq06b44}ecndo~~~~~~~~~~~~~~tpn~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(:uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu9uuuuuuuuuuuuuuuq{!4buuuuuuuuuuuu5~~<[a54bbqbquqxxxxuuuuxxx7677bqbb777f7fgf0ggfg00ggaggggggaa1aae}e}cc&~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/]~j6807bqec3od>~~~~~~~~~~~~~~~{{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~7uuuuuuuuuuuuuuuuuuuuuqxuuuuuuuuuuuuuuuuuuuuuuuuq$~<447xuuuuuuuuu4_~~t$2<)74q44477xxxuxxxx977779bbxb9bb766aggggg0000gggggggaaa1a}cccdc/~!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!_>~t}4b64edppk{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~juuuuuuuuuuuuuuuuuuuuuuuquuuuuuuuuuuuuuuuuuuuuuuuuq/!_77xuuuuuuuuuu7jj[+a~!~~t!!~!t4buuxx97f9997xxqbbxbb460a0ggga000ggggagaagggaaa}ccc>~{^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^/~!6661o1npc{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~juuuuuuuuuuuuuuuuuuuuuuxuuuuuuuuuuuuuuuuuuuuuuuuuuuu0~t674xuuuuuuuuuuuuuuk_^!~~~~~~~j6quxx9979997xxxbxbb4466}00gaga00gggg2g0aaa2g1ccc%(~!2^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~tck}p33nn!~~~~~~~~~~~~~!t{{!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuxuuuuuuuuuuuuuuuq^~j74uuuuuuuuuuuuuuuuqb|~~~~~~~~!0997b79b97fbbxbxxb468#caa000ag00aa1gg0a}aa}12^/!~~~|t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~s}cc333nr~~~~~~~~t!~~~~~!!ttt~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~juuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuxxxuuuuuuuuuuuuuuuxb!t:buquuuuuuuuuuuuuuuu2~~~~~~~~~577g7799979xxbbbbba^>!(}a0a0aa0ga1122a25115/~~~~~~~!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sonpppppp~~~~~~!rpp~~~~~~~~~{rt~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!7uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu99uuuuuuuuuuuuuuuquq5~[bbuuuuuuuuuuuuuuuu_!~~~~~~~~~~5js79477x9bxbxbb'!~~~~2a0}a01aa}}1a25!~jr!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!ndnp33ppt~~~~~t33{~~~~~~~~~~!!~~!t!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuxuuuuuuuuuuuuuuuuub2~!2quuuuuuuuuuuuuuu4~~~~~~~~~~~~~~s79967x99xbbb$(~~~~~!566ggga0}}cc1!~!1^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~3nn33p3r!~~~tr33!~~~~~~~~~~~~~~{p3!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~vuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu4t~!7quuuuuuuuuuuuu:v~~~~~~~~~~~~~~t797f99x9bbbg~~~~~~~~t006ag00}1}11~~(a{~~~~~~~~~!(!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!r3pcp3r33rrr33~~~~~~~~~~{~~~~~t~~~~!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~5uuuuuuuuuuuuuuuuuuuuuuuxxuuuuuuuuuuuuuuuuuuuuuuuuuuuux:~~j:uuuuuuuuuuuu0(~~~~~~~~~~~~~~~!f9977bbxx4v~~~~~~~~~~v076aaa0a}11s!~~~~~~~~~~~~^1(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{s3pp3rr3rpp~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu5~!$uuuuuuuuu:0<!~~~~~~~~~~~~~~~~~09yyx99b7<~~~~~~~~~~~26aga0}}a}c}32~~~~~~~~~~~~2a/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~t{~ttpp3p3r33{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~tuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuux6(~5uuuuuuuu:/~~~~~~~~~~~~~~~~~~~~5b999xbg!~~~~~~~~~~~~!jtsg0a6a}1a115~~~~~~~~~~(a2~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~rppr33nnp3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~juuuuuuxxuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuxxxq4j(quuuuu_<!~~~~~~~~~~~~~~~~~~~~~~f9999bj~~~~~~~~~~~~~~~~t0006a}6a111!~~~~~~~~~~22j~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!ttrrpp3{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!9uuux999xxuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuxxxxu8s'u:'[j~~~~~~~~~~~~~~~~~~~~~~~~~v9x9xb5~~~~~~~~~~~~~~~~~26a760}}a12t~~~~~~~~~~52>^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!3pp{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[9xx99yyy9xxxxuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuxxxx9xxb4a$j~~~~~~~~~~~~~~~~~~~~~~~~~~~~j9xx99<~~~~~~~~~~~!!~~~~5}jv600}a}at~~~~~~~~~~(5t5(!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!ppt~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~j06000fgfy999x9xxuuuuuuuuuuuuuuuuxxxx9xxxuuuuuxxuxxx9xb9xbb4v~~!tj|_(~~~~~~~~~~~~~~~~~~~~~~~gbxx9~~~~~~~~~~~~~~~~~~sa!~j6666aa!~~~~~~~~~!~t2ts/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{n{~~~~~~~~~t>3tj~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!acc}0aa6f999999xuxxuuuuuuuuuuuxx99bb9xxxxxx999xxx9xx9bbxbqqg07uu++<~~~~~~~~~~~~~~~~~~~~~~~t4xx7~~~~~~~~~~~~~~~~~~5^~~~2a0}2!~~~~~~~~~~{~!23sj~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~r3!~~~~~~!3ppop33s{~~s!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!o}}}}}}}}}}}a7bb46xxb76bxxxxux9977799yyyy99999xxxxb9xxxxuuuuuuuu:~~~~~~~~~~~~~~~~~~~~~~~~~fxbs^~~~~~~~~~~~~~~~~!22~~~!s)=~~~~~~~~~~~/~~~<>ss~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!3pr!tt~{ppp33r3oooopn*!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{c8}}}ccccoc}}06}a67a1a667b4977}}6}a7f99yyy9999x9x9bxxxxxxuuuuuu|~~~~~~~~~~~~~~~~~~~~~~~~~54js45~~~~~~~~~~~~~~~~a4j~~~(s~~~~~~~~~~~!!~~~tss1j~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{{~tpr33rr3r3nooooonn=!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!)88}cccncc}}}1a}a}}}cc1}}6}aca11cc166f6f99999xbb9x9xxxxuxxxxuu:!~~~~~~~~~~~~~~~~~~~~~~~~~~!~57[~~~~~~~~~~~~~~~~t6g!~~~~~~~~~~~~~~~~~~~!s>a25~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~t3rrrrr3ooon313ooabj~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!>686ee}e}446}}}a0}c1cc1}ccccc1ccccc}}}66f7999xxbxxxxxxuuxxuuuv~~~~~~~~~~~~~~~~~~~~~~~~~~~~~t4a~~~~~~~~~~~!~!~~~j6gt~~~~~~~~~~~~~s5~~~~!!15!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~t3rrsr33oono3o3o31a)(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~t}846888846>t~!t1}}cce}cdnclcnccclc}c}67999b9xxxxxxxxxuuxuu:~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!~~~~~~~~~~~~~~5jt~!a70!~~~~~~~~~~~s}6$!~~~~t!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~t3rrr3333po333ooo3o1)a|0|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!^)^(!!(j!~~~~~<$12ccccccccnccncndcc6694x9x9xxqxxxxuxuxuuuj~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~546j!57bg~~~~~~~~~!2a67g~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!rr3333o3333o333o3331264q7/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!sc}ccnccncncccc}67799b9x99xuxxuxxx99xuv~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!540sj67g~~~~!~~~!s1aa2!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~t2r333333pooo3333o3poo1}a}a~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~tac}cccc1nccc}}8679bbb9x9xxqxxuq9x9xqv~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~t568s247!~~~~~~^a11a6a~~~~~~~~~~(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(31r3oppp33popp3o3o3pooooooo!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~tc}}1ccoccc}67677799b99b9bxxxqqxx99f(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~j387620/~~~!0a}111}07<~~!~~(!~^s~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>3r333o333333opp33oo3opoopno{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/}}}}}}acc67b77677994b9xbbbbxxqqb9[~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!t66b61j~~~(bb4a11a60j!5>22^~~^v~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%srrro3p3333333333p33p3opooooo!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~2}}c686}}6877777y99949b5sbbbxxxx9a~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!j}4b}s~~~!9bb6aaa70~sttsj~~~^t!/j|j~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~t1rr33333333333oo33p33o3o333pnno{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~2686646}666449979999b94j^xbxx9xb0!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(j26442s~~~vxx6a077t~0f7a5(t~/~!/076/((t!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$1rr3333p3333333333o3333pp3onnnonost~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~j476666676979999999999464b9bxbx0!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!r76b67^!~t7qf6f9v~t797t~jj!~tjjt215~311>j!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^13r3p33333r333p33r3333o3oooo3nooopoo/!~!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~587476674999x9xx9x9b99bb9b9999t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!569b4j!!~jvgg7bj~!6v72~~~$j$22!<6}2ooco112(~~~~~~~!~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~to33333333p333r3o333o3oo3o33oooopo3cd647x9<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~5646776f9b9999x9x999xxxbbxxx0~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~v446t~~~~~~~jj~~~2220t~~t~~~!~~t!=1coooooo^(~~~~~((~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!'13p333333pp33333o3p3p33p33pooonooon1}4f9x9j~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~a74477799999x9x9b6b9xxx9bxbj~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~j66t~~~~~~~~~~~~//t^t~~~~~~~~~!!~!{cooo3oo1!!({!<!~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~:13333r333r33333333333p3opnpopononoco}607xx71>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<64477b999999999xf49xxbb9bb<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ts60vtjj!!~~~~~~!~~~~~~~~~~~~!^~~~>ooo3ooo}<~!!~~~~!~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$}33333r3333p333333333p3p3ooopopoooccc007qxb66!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!6444799999999x9xb7b9xxbbbq2~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~5[777462t~~~~~!~~!~!(~~~!/~~~~~~>11ooo>3}s~~~~~~~~!~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>1r13333333pppoop3333pp3popooopooc}e60f747744/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~g4444b9x999xx9bbb7bb9bb9bqv~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!jgg$2<^^^j^^/ss52!~~~!~~~~~!{sa6a/~t51(~~~~~~~~!~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=31333333pop3p3p3333oop3popopooo160006}cce77j~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~644b49x9999xb946444q9bb9bx0~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!~!!t2st~sa2t~~~~~~~~~~~~~!//!~~!>1/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{or33333333p33op3333op33poonoooc146a6}ccdc40!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<b4q4bx9xxx9xb4bqq4q44b9bqb<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!/~!5j~~~~~~~~~~~~~~~~~~~~~~!t<(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)1333333333333o33o3ppo3pponooo167a}}c1ccc1!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~j44kqqxx99xxxq444kbbk6bxbbbg~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!~~~~~~(s{!~~~~~~~~>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/[333333p3r333333p3oo33ooocooca7}}cc}0}})~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$qb4qbqqxx9xxxq44q4qkebbbbq|~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~s2a6a%^~~~~(c!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)a3r3333333p333p33ooo3onnoco167a0}0}}66/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<q4qquqbuxxxxxxbqbk4b48kbbbb|~~~~~~~|4~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!~!297761s~~~~/c3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~()133p33333o3o331o31o3o1ocoe0797446}}4s~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~_b4qquuuuuxxxxbbbkbkk48k4q4qa~~~~~~<k:5~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~j21tsf79701>~~~~^7a^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]c28r2rr33o}11211111oponc169999b7}e88!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!qubqqqquxuuuxb7bbqbk4kk4kkk'^~~~~!<84:^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<a0f009f97f05!~~~g7}6s~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!))86}3a321}664b76}ao3o1o}bbb97q7868}!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<uqqququuuuuuxqbqbqkk4k4k#@@=~~~~<88:q'!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!s6f9fffyyfy9ff0j~!67}}>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^'':181o}}4bxuuq4}1oooc84qq8686668}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<uuxuquxuquuuuuubbqbqbkkk#)/~~~~~)44qq[~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$7ffwfyfyyyyyywwwv5707}o!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=]}18c}6bxquuub8o1o}}ek48cc868}}c~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!:uxxquuxuuxquuqquqqbkbkk%~~~~~~~644:q<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~tfyyyyyyyyyyyyyywwfg206g2(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<]}8k}quxuuuuukc1}e44qqq868e}e}=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<uuxxuuuuuuuxuuxqxqqbk4=!~~~~~~~$44::!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~jw999yyyyyyy9999yywwf6fa}a2j~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(q4'#4bxuuuuux488444kbq4}6e}eee{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!7uququuuuxuu4xuuuqxqq6~~~~~~~~!64qq_~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~jvgy9y9999wyyy9y99y9yy9y9ff6600a^~~~~~~~~~~~~~~~!~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!::qu67xxuuuuuqbqq88}ec}e}}}e}e~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<uxxuuuuuuuqxquxqxxbb4t~~~~~~~<44bqv~~~~~~!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~t[ffwwwwyy9yyyy9y9y9yyy9x9y9gfff0a0j~~~~~~~~~~~~~~!(~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~q77b64xuuuuuqb4q4ecccoo}8c}68s~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~7uuuuuuuuuuuxuuquqqbq/~~~~~~~[b6b:!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<:uuywwwwyyywyyyyy9yyy9y999yy00fff6a1/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!u4b4667xuuuub4bbkdcddoo1c}e}$~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$uuuuuuuuuuuuxquqxqbq^~~~~~~~^4647~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<uuuq9ywwyyywyyyyyyyy9yyyxx99ffyff00aa!~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<q6u4}bxxuuxqkebq4ccdnncn12/!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|uuuuuuuuuuxuqxuuqqbq<~~~~~~~/:4q^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[xuxx9yyyyyywyyyyy999999xxxx9yffyf0a002!~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^:7q40bxxub66}e488ooconn{!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~juuuuuuuuuuxuxuquuq[(~~~~~~~~~^[<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<xxyy9xyyy9ywwyyyyyy999uuuxx9xyfff0000a2~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^qbq74buuuf7q}}6kkconoo!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~juuuuuuuuuuququuqu:!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<yyy9yyyyyy9ywwwyyy999xuuuu9999f00fff06at~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[:uq67xuuuub6}}646doon3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~_uuuuuuuuuuuxxuux:~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!9yyyyyyfyyyyyywyyyyy9xxuuxux9yyf0ffyf00j~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!bb:b0abquqxb}c164qecno>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~j:uuuuuuuuuuuuuuu|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~gyywwwyyyy9ywyywy99y99xuuuuxx99yffgfw005~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!:9q46}}buxx4}48kqxecnc{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~5uuuuuuuuuuuuuu[~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~t9yywywy9yyywywyyy9y99xuuuuuuu9yywff067<~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<q06086kqquq7xb6684ecn/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~4uuuuuuuuuuuu_!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~f9yyywww9yy99yyy9y999xuuxxuuuxxx99ff66!~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<7abbxqxuqu41q4}ec}oo!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/uuuuuuuuuuu:j~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~v999yyyyyyyy999yy999xxx99yxuuuuuxxbfa_~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<7_6xxxxubbc}4}conco{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!buuuuuuuuu:!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~57y9yyyyfygv<!~!~jgyxxxyyyy9uuuuux9y4v~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<0:a9xuxux611}ocnon*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~:uuuuuuuu[!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~27997779fj~~~~~~~~~vxxf9yyyy9uuuuxb9g~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^a4fxuuxuu4cocnpce3!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<::_v^^(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^776<t~!!~~~~~~~~~~~[v09yyyyxuuuuxx7!~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[66xxuxuxuq6oo3*c_(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(j~~~~~~~~~~~~~~~~~~~^|7yyxuxxux9xv~~~~~~~~~~~~~~~~~~~~~~!~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~jb'7uxxuuuuuxb6>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(~5f99xxx9994!~~~~~~~~~~~~~~~~~~~~~~~/~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~g6abxxxuxuxxuuuq<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~![7y9y99770~~~~~~~~~~~~~~~~~~~~~~~~jvt~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~jf84quxuxxuxuxuuq<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!/2[5a_5!~~~~~~~~~~~~~~~~~~~~~~~~~j2v2!~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~50:4uuuuuuuxuuxbv~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!v3vt~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~j94qxuxuuxubv(!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!~!(~~~~~~~~~~~~~~~~~~~~~~~~~t5j~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~v:0xuuuuuxu:~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!a=}(~~~~~~~~~~~~~~~~~~~~~~!53(s~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~f:4uquxxu5v<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=}1!~~~~~~~~~~~~~~~~~~~~~~[a^~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~2[9xuuuuu2<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!=(~~~~~~~~~~~~~~~~~~~~~([15~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~t56bxuqxq_/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~![g1j!~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!^6buuuu4$~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!a5a=~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~j54bxqx:^!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/2/!~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~![_4bxuq6~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~5q84xxu4*!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~t):8bbuq4>!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(6:_xbxu|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!$:8xxq[!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~2:49q:j~~~~~~~~!!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~t[:xq9<~~~~~~~~(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~5:6fb:!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<$0bx7^!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(|[|(!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/^((~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(/<'_[)!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!]:${~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/~(~~~~~~~~~!//!~~~~~~~~~~~~~~~~~~|_~~~~~~~!(!(!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~![:']&/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|_+++:|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!~|<~~~((<|(!<:::'_[|<(([::.'#=!~(/!<<||[(~(|[[['+[[<<<!~~~~~~~!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$[::$**&{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!(|<':+++++++:_||^<<<(!!~~~~~~~~~~~~!([_''+++++:++++++++++++++++++++++++++++++++++++:++++++++++++++:_|</~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!<++^**&>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(!~~~~~!|:+++++++++++++++++++++++++++!~~~!~~~[:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++:_|<(<~~~~~~~~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(_'(<_+++.,*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~([++[<^~|+++++++++++++++++++++++++++++:!!~~(<[:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++:'''[<!~~~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<!~!'+:_++++++%!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!~~~~~~~!~~~!~!((<[[|(!|[[__'_[|<<(<|[_:++++++++++++++++++++++++++++++++++++++++]&&$++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++:_[[[|/~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!/$$)'++:_++++++=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~':+|(|+_|['<(_+:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#-.++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++:|<~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<$':::[~~~~~~~~~~~~~~~~~!~~([_#++:[$++++++#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!<_+:+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++|~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<|(!~!!~~~~~~~~~~!|(~~~~~~$::++++:'_':::::_||((~~|__/<')'$__]'+++++++]!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~![++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++::$~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!~!(/[_''+++:+++:'_:_'___:++:':::':+++++++++++++++++++++++++++++++++++++++++'!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(||[+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++:|(~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!(/<|[_'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++:|/!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(<'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++:/!~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~(||[+:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++:']|^/!~~~~~~~~~~~~~~~~~~~~~~<||+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'~~~~~~~~~~~~~~~~~",
"~~~~~~~~~~~~~~~~~~(||[[|<^_]:_++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++..'$(!~~~~~~~~~~~~~(|['++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++|~~<^<~~~~~~~~~~~",
"~~~~~!(|['_____::++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++::__'_':+++::++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++:::$^<((!~~~~~~~",
"(<|_:+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++:_|(!!",
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"};

215
wmglobe/src/defnimap.xpm Normal file
View file

@ -0,0 +1,215 @@
/* XPM */
static char * defnimap_xpm[] = {
"360 180 32 1",
" c None",
". c #020204",
"+ c #3A4347",
"@ c #461F11",
"# c #0D2939",
"$ c #5C5C59",
"% c #653E21",
"& c #2F251C",
"* c #422F11",
"= c #151414",
"- c #662F14",
"; c #474F54",
"> c #26393C",
", c #29120C",
"' c #464543",
") c #6E6E70",
"! c #1A353C",
"~ c #574A49",
"{ c #765A34",
"] c #764A24",
"^ c #562E1C",
"/ c #0C0E14",
"( c #6E3917",
"_ c #302E28",
": c #291C17",
"< c #423A1B",
"[ c #373836",
"} c #161D14",
"| c #1A2427",
"1 c #5A3A24",
"2 c #65625C",
"3 c #5A524C",
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",
"!!!!>>>>>>>>>>>>>>!>>>>!!!!!!!>!!!!>!>!!!!!!!!!!!!!!!!!!!>>>>>!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!>!!!!!!!!>!>!>!>!>!>!>!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#!!",
"!!!>>>>>>>>>>!!!>>>>>>>>>>>>>>[+>>>+>>>>>>!!>>!!!!!!!!!!!!!!!>>!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!>!>!!>!>!!!!>!>!!!!!!!!!>!!!!!>!!!>!!>!!!>!!!!!!!!!!!!!!!!!!!!!!!!!!>!>!>!>!>!!>!!>!!!!>!!>!>!!!!!!>!!!>!!>!>!>!>!!!!>!!>!>!>!>!>!!>!!!!!!!!!!!!!!!!#!#!#!##!##!#!##!##!###!##!!#!#!!#!!#!!#!!!!!#!!#!###!########!##!#!##!",
"!!!!!!!!!!!!>!>!!>>+>+[[>+[>+>>[>+>[>+>[+>!!!!!!!!!!>!!!!!!!!!!>>!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!>!>!!!!!!>!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!>!!!!!!>>!>>!>!>!>!>!>!>!>!!!!!!!!!!!!!!!!!!>!!>!>!!!>!!>!!!!!!!!!!!>!!!!!>!>!!>!!!!>!>>!!!!!>!!!!!!>!!!>!>!!!!>!!>!!!!>!!!!!>!!>!!!!!!!#!!#!!!!#!!!!!!!!!!!#!#!!!!!!!!!!!#!!!#!#!!##!#!!#!#!!#!#!!!!!!#!#!#!#!!!!",
"#!!!!!#!!!!!>!>!>[>[[>+>+>[[[+++[[>>>>>>!>>>>+>>+>>>!!!!!!!!!>!!!!!!!!!!!!!!!!!!!!!!>!>!>!>!!!!>!!>!!>!!!!!#!!#!###!#!#!!!!!!!!!!!!!!#!#!!!!#!##!!!!!#!!#!!#!!!!!!!!!!!>!!!>!!!>!>!!>!>!>!!>!!!>!!!!!!!!!!>!!!!!>!>!>!>!>!>!>!>!!!!>!!!>>!!!!!!>!>!!>!>!>!>!>!!!>!!>!!>!!!>!!>!!!!!!!!!!!!!!#!!#!!#!#!!#!##!#####!##!####!##!!!!!#!!#!!#!!!!!#!!#!#!!!####!#!!!!!!!!#!!!",
"!!!!!!>!!!!>[[>>[>++++++[>>>>+'[+>+>>>>>>!>>>+>+>++++++>>!>>!>>>>>!!!!!!!!!!!!!!!!!>!>>!>>>>!>!!!!!!!!####}}}/}}}}}}}###################}}/}}////}/=///==/=/#}#}####!#!!!!!!>!!!!!>!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!>!!!!!>!!>!!!!>!>!>!!!!!>!>!!!!!!!>!>!!!!>!!!!>!!!!!!!!!#!#!!!!!#!!#!!#!!#!##!#!#######!!!#!!!!#!!##!#!!#>!!!!!#!#!!#!!#!!#!!!!!#!!#!#!#!!!#!!",
"!!!!!!!!!>!!>>>[>++++[';++>+>++++>+'';+[[>>>![>[>+[+>>+>+>!>!!>!!>!>!!!!!!>!!!>>!!>>>>!>!>>!>!!!|#}#==..../...../........//=//=}//}/=//............././/........./=}}}}######!!!!!!!>!!!#!_!#!!!!!!!#!#|!#!!!#!#!!!!!!!!!!!!!!!#!!!#!!!!#!!!!!!!!!!!!!>!!!!!!!!!!!!!!>!!!!!!!!!#!!######!!!!#!!!!!!!#!!!!!#!########!###!##!!!!!!!!!#!#!!!!#!!#!!!!#!##!!#!#!#!#!#!#!##!",
"#|#>#!!!!!!!!!!!>>>+[++>+[>>>>>[>>[[++>+>'++'>+>>>+>+[!>!>>!!>!>!!>!>>>>!!!>>!!!!!!!!!>!!!}=/.//.///}#=}|#|!#|##/}///................/}=}/|}#}_!#||###/}}}//............//==}=}#|#_!#>#_#}}}}}=//////}}/}/./=##||#||||#|!#!##|#!##||##|!#|#!#!|!#!!!!!!!!!!!!!#!!!!!#!!!!!!!!>!|#|#!!!#!####!!!!!!!#!!##!!######!##!#!!!#>!!!!>#!!!!!!!!!#!!!!!#!!!#!!#!#!!!!!!!!!#!!!!!",
">!!!!!!!!!!!!!>!!!!>!>>>>+>>>>>>>>>>>>>+>>>>[>>>>>>>>>>>>!!!!!!>>!!!!!!!!!>!!!#!##}}=/../=|}|||_||_||>##>>__>_|||}=//..=}|#!>>|#|}|>>|!|!!>[[>>+>+!!!>##}#/}}//.../........./..//}}}==/....................................//...............///..../////}}#|}===///=///=/}||==}}=}/=}}/}}}/}####!###!!!!!#!##!##!!!!!!!>!!!!!!!!!!!!!>!!!!!!#!#!#!!!!!!!!!!!!!!!!!!!!!!!",
"!!!!!#!_#!!!!!!!!>!>>>>[>![>>>>>>>>>_>!!!>!>!>!!!!!!!>>!>>>>!>!!!!!!!!###}/........./|>>|//=}}}|}|#|=:|&_|>#>||=./:|!|>>[>>>>[>+>>>[>>[+[+[>+[+[+[[[>[+>>!!#######//..............................................................//==|..../}|#/||./=/../////.................../}!#|......./##!!!!>>>>>>>>>>!+!+>>>>>!!>>>>>!!>##!!!!!!!!!!!!!!!#!!!>>!!!!!!!!!!!!!#!#!",
"!!#!>>!>!>!!!>!>!>>>>>>+>>>>+>>>>>>!!!!#!!!!!!!!!!!!!!!!!!>!|##|#}}}................=|_[>++_}==}/}=}|_>!>_|==...../_[+>+>'[++[>+[+>++>[+[>++>>>+>+++[>+++++!#}#/=/.............................=}=}/_::|__|>!&/...................../...........................................//}|}==/.......##!!+>++>+>+>+>+>>>!>!!#!#!!!>>!>!>>!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!>!>>>>_",
">[>>!!>>>>_>>!>>>!!>>>>>>>!>!>>!>>!>!!!>!!!!!>!>!!!##}}///.........../.....}=///..//../:>>>|}=/==}|!!_||}=.//=:|!>!>>+>+++>+>+++++++>++[>+[+'[+++[+++++++[+>!##.............................../=|_&|||_:=/...........................................................................//.//.......#!>>>>>>!+>!!!!!!#######=#=###!##!!!>>>>!!!!!!!>>>>>+>>>>+>+>+>+>>+>+>>",
">>>>[>!>>!>!!>!>>>>>>>>>>>_!!!!!!>!!>!!!!!!!!!!!!##=/........../...///............../.../=.//}/=}=|>_#=/....}||__>[+[[[>[+>'>[>>[>+>+[+++[+[++[[++[++[+[+>>#!}/.....................................=//....................................................................................//.....//}!!!!!!!!#!#!!!###}|}|#/}}}==#}##!!!!!!!!!!!!>+>>+++>[>>>[+![>>[>>>>",
">>>!!!>!>>>>>>>!>!>!>!>>>>!!>>>>>>>>>!>!!!!!!#!!!!!!!!..../=}=}=//..../...../..///../}=/===/==|}:|||_=.......//|>&>!__!>>[+[+++++++++++[++++[+++[++[+++'+[_!##....................................................................................../=|_/..........................//.../=||||}=//=/./##!!##|#}}##|!####!#!!!!!!>[>+>>!!!!!!!!!!!!>>>>>>+>++[>>>+>>>>>>>",
">>>>>>>!>>>!>>>>_>>!>[!!>>>>[>>>>>>>>!>!!!!!!!!#!!!!|...../../.}}=#=//=|/=..///=|:/./=./|:}=///}#+>!=.........../......./=>+[[++[+[+[+++[+['+[+'+'++1+[++['+_#}...............................................................................}##>_==//......................//==::::||=&|:&|_||||:|:=/=..............}#####=}:|_#|_>+;'+!>!>!>>>+>>>>>!>!!>>>[>>>>>>>>>",
">>>>>>>>!!>>>>>>>>>+>>+[+>>>>+!>>>>>>>!!!!!!!!!>###/.....//....../=/=//./.......//./=}=.==:=|:![!>+!/...................../|++[+++'[++[++++[+['['[[++''[''[+>#=/............................................................................}>_}/.........................=:|::::|::::::==:==:&::::=:/................//######/}=||!_>>|_&>;$$$2$)2+;;$);+;++>+>+>[[>+>>",
"++>>!!>>!>!!>!>>>>>>[>>!>_!>>!_>>>!>>!!!!!!!}/./../..../||||||}/.........//....////./:|=}/./==/.====_#=.....................|>+[+[+'++'['1+'['+[''+<['++[>_::}............................................................................=||=............/..........///===:::::::::::::::::::::}=:=://////..../////...//}/##/}=/}=}/==/=}||_#![>[++;+!$$))))$;;;;;;;;3+",
"}|||!!!!!!>!###====|#>>>#/=./../.......................}||||:/}|#:==///.|}|...//}:///}///./}==/}::_/}|++/.................../}!++'+[<'['++'''[''+<'+'+<+[||}|/........................................................................../}|}.............=::=..=.//=/&:&::::|@:::::::::,::::,:==::=:::|@&:::::/::}===/......///===}=//..............////#_>_|||}}!_}==|}",
"..../././///./........=................................/:|:/.=|||#||||||=|}/..../#/.=}/...}}|==}}:|}|}_+>>/=................=}/|_'++''[+[['['+['[+'[+[+[&|||}/..........................................................................|:#:.........../:||:/=:=:}:|::=:@&:@:::::::::::::,=}=,:==:::,::,&:&&:[_::|:}=/..=//////}::|:}:||:=/.............................",
"//................../=/==///./................................=}}|:|||}}}=|}//...../|}}/.../}:||:|:}||:|';[_!|}............../}=}_['[+'<+'++<'+'''['''[>>_}/|=............................................/====}}}=.......................///..........:&:@|:/:::::::::::,:::,::::}&,:=,,=:===}====,},:::::=:=,[':=:*|==:&}:}:|:|::::&=::|::===:}://.................../",
".................}||}:}::|:|}|&}}}====/.........//=}|/.}///....|||}=}}}=}==}/}/../=//}=//...../=}=////==:_!:}_>&/............#+|/|[+'[''['[+['['[''[+'+[[[#|/......................................../=:}:|:&|&:&::}=.........................//}:=////=|&:::=|::|::::|:::,:}=&}====:=:::=,=,==,}==,},:,,:&*[**:,:|''3*:'~:=:::,::|:|::::::::::::::=/////////./=====///.",
"/.............==|&==}}=}:}::&|::____|:|||}=}}}}}|#||||||}|||}}==}//}/=}///////.../#=./}/}/}=..=|}}/..../=|:&:::|=................|+'[++['+'''+'+'+[[+___|}/......................................./==::}}}:|:::|:||&&|&|:}/.....//..=/.//=/===:}}::::::=,:::|/=::=,}@::::::::}==::::=::==,}===}=,}}=:==:::&:&::,&[~['_@[@:,,,:,},:,=::=,:==::|::|:=|:::|:::|:==|}:::::::",
":}}/..........//:}:=}}=}}|_|&}_|||=}}}:=}}}:}}}||}|}}}|}}}}|}}:}}=//=///}}}/}//===}}/}}/}}=|/=|:}|/....#}//|:||[;;#=........../=|_['''+''['''+'['+_=./............................................==:}}}:=::::}}:&&|&|&&|:&|}...|}/.=:|:_:|:||::&&&@}:::::&::/=:&:::::,:,::,::::=,=:======,=,=,=====::_|,}:=:,==[^['([[[@::=:,:,::,,,==:,=::,:|::::|::::|:}::::::|::|:|:",
":::|:/=}/......//=/=/=}}}}=}}}|}}=}=}}}|:}}|}}}}}:|}}|}#}}/==}}}}}}}}}}}/|#}}}}}}}:}=}}}=}}=}=====......../|:=:&|[;+|}.........||_''[+''+'[+[+['[|...............................................=:&=}}},&||:}::&::&|::&|&|&}.//|:=|&&:&:::&@::&&:::::::,::==:::::::::::::==:=}=:=:==}}:=,,==,=}},}=}==:==:===},=:'~[1[:&[::=,:,,:},:::,::,,,:,,:,::|&|:::|:|_|::::=::::",
"==:}:::||=../}|}:|==}===}}}}}}}}}}}}=}|}}}:}:}:}|=||}}}}#=///=}}}}}}}}}}}}}}}/}}}=}}}/}}}}}}|///........./||:::|}./||}.........}!_+'+<+<+'''__=/............/}=/==}||=..........................=:=}=,,&|:===::}::::||=.////=:|&|&&&&&::&::&:::::::,:}:::::::|::,|=,}:::},:=:=:}}=}::=:}}=}=====}=}=::==:=}=}====:[^33'@[',=:,:::,,,:,=,=,==,::::,=:&*&&['*&:&::==:::=::",
"..../=|=...../==/=/}====}======>_=}}}:}}}|,}}|}}}|}}|}==}}/=#}}/#}}}}/}/}/}/}}/}/}/}/}}/}/}=//|||=....:|//||}}||::=............./=[+'+'+''+!.................=|||+;;>}......................../=:=:}}}::&=..=|,,}::::::./:=,|&&:&:::::&|::&:::::::,:,:::::}::::::}}}}}}}:}:}}}},=}}=}}===,=}}},=}===,,===},=====,=::~[32~~'<'__|:::==:,,:,:::=,,=:_*/'3~~***&,:::::,:=//",
".................//==}=}|}=|[3'+~+[}=}}:}}|::|}|}}}=}|}|}##}#/}}}}}}}}}}}/}/}}///}}}}}}}}/.../}}////.......=|&&|}:#/............/_>''[''[[>=................./==|!|=......................../=::}}}=:&&:,/=:&:|:&=,:&:}|::|&|:&:&&&&}}}}}},}:}:}=}=:}:::}::::}:},:}}=},=}=}=:}}}=,}}=:}}====,=}=}===}:}=====,}==/====:&_&1['~2)3'_:,=,},},=,:==&}*['['*@::&:,,:::::::::.",
"........./.....==}====}|}==|'+=|}*!+3+|}}}=}}}|=|}}}#/#}}}=|}#}}}}/}}/}/}}/}}///}}/}/}}//.......//....//../../=|===..............=>[''+++>/...............................................=}::===}}:&:=..&:::}}}=::|::::&&&@::@::::}}}}=}}}|}}}===:},}:,}}}:},}}}}:}}}}:=:}=}::}}},=}}},}=,====}=:====,==,==}=}|===,==,/=/,:&*2)$33;_&:=:=::=&:~22~@&,:/==,::=|3$[_|[||=",
"..............===}}=}===}|:$|,}}_|&|>[''&__:&=}}}}}}}}}}}}}}}|}}////}}}}}}}//}/}}}}}}}/............./.:|:::}/...//................=>+'<++|...............................................:,==}}}:}},&=...=:}===}}::|&||}:&&|:&:|&}|}:}}:}|=}}}}}==:}}:|,:}}=|}}}}}}=::}}},|=}=}==}}=,====}==,=,======,=}}}=====}=}==}/=,=,=:*_^3))322$~'~_~3''$3[====:=/&'~'_'~':,//....",
"............../}=//}=}}=}}>}/}||==[_&'!';|_[!}}/}}}}}/}}}}}}}}}}//}}}}//}}/}}}}///}/}/................:====:::/..................../=:|[>/...............................................::=}}}=}}:::=/./|&::&:}:&}/}:::&:|&|}}}}|}|}|}}}}}}:}:=}}}}=}::=}}}}:}}}}}==}}:}=,}}}:}},=}}}:=::=}=======,===,==:=====}=}=======}&*[,:$'@[3~~~~32$2$[=....//=[~&:,,@://.......",
"............./..=/==}//==}/.}|=/...//.==:}'[[_}/}}}/}}}}}#}#}/#}}#}}/}}}}}}//}}}}}}}}/................=::===::/....}...................=/................................................=:}=:}},=::::=.../===//=::,:}|}}:},||}:}|:}}:}}:}}}}}==::}}:}:&}}}=}}=,==:}}=}=:::=,},}}}=:==,:,=,===,=====,|&}===|_}===========&_,:::~$_}}_&==:=::&:,.....=[[,=//.//..........",
"..................////=}=_=/............./||}|>}}}}}}/}}/}/}}}}}}}}}}}}/}}/}}}/}}///}}/............../::=:::=:}///|:=..........................................................//........=::}./=}=:,:=/...=}::,}:}||,},||}&|:=}}}}}}|}||}}}}}=}=,=:}}}}:}:=}:}}}}}=}=::}}:}}}==}=}:}}}}==,:=,===,,===:&:::&<'&:===,=|,=&[~&==,;3:=........././..../=~<=/................",
"......................}#//}/.............../:=}_|_!|}}}!}}#}}}}}}}}}/}#}/}}}}//}}/}}/#}/............../:=:=:=:=::::|:=......................................................./}}./........./..=/@}::}.=../}/:&:}}:}}}|:}||&}|}:|}|:}|}}}:}}:}=}=::|}|}=}}}}}}=:}=:=:,}}:}==::},},===,:=:==,=,=,===}==,:::[&'1['&&&:[[*&'_'':_3~:.................=='3_=.................",
"....................=|=/../.................=}=}}=}_>#}}}}}/#}}|}}}}}#/}##}}//}}/}}///}}}}=/...........===:===:/=}:=}:......................................................./=}}=..........}}=.=:}&=./..&:::::,}}}:}}|:}}|:}}},}|}|:|:}|}}|}}}|,}::}:}:,:,}}:}=}}}}}=,}}:}=,===}:}=:========}===},}::_&'^[~[*'[~[+_[[3'<::;;[=.................==;~_==.................",
".................//|=/........................=/=}}_}_|}=/}}}}}=}}}/}}}/}/}}}}}}}/}/#//}}}=}=/......../:=====:=:=:==::=......................................................./}}=..........=}===:///....:::,:}:=:}}}}|}}}|}}:|}}|}}}}}}}}}}|}=}:|&:,,:,==,,,:,::=:}:::,},=}=}===:==::,=:,==,=},&}:=::&&_*_'&*[)~1[~33~~&^[<,..................=='':&=/.................",
".............../...............................///=====}}}}}}}}}}}}}}}/#/}/}}//}}////}//====}=}}}=...==:=},}====}=}}}}}:}=.................................................=}}=/=}|........./}=}=//.===/:},}:}}}}}}:}}:|:}|:}|}|::}|||&,:,&:}}}::,:/=,=,:,,=,/:,,:=:,/=,,::==,}::,[:==&==,====,}_}&_=,:&:''**~~&[@&&&:@[[::=//................./,':,/=..................",
"...............................................=./=}=}/}==}}!}}}}/}}#}}}}}/}}//////#/}}}}/}=}=:=}=../:=,====}/===}===}===:=/............................................../}::../}:}....../==}}=}:}:=,}}::||:&}}::}&:}}}:|}|}:}}}|&,::=:=:::,::==,,,=,:,::::,/=/=:==,,=/,,,:}:=}}::&*'&=,,=},=:|=}&:::&&*'~*_**&'<*::}=:=,==}====//............/_[:}....................",
".............................................../../}==/}}===}!+>}}/}}}}}}}}}}}}//=.}}}/}/}///=,}}}=..}=}==/}/}}}}=}}}=}}==}:..............................................=}|}./}}}&}/...=}}}=:}=:}}}:=}}}}},}:,}|:,|}}}|}:}|:}:&}:|,::,,,/,=&},,=,:@,:::@::,@:,,/,,=,,,::/:,,:::&_::&[&:}=,==}}::_==:[*'[_::'~'*:*:=:,,:=:}=:}===&/............:_=.....................",
".................................................../}!_=}/}=}}:[_}}/}}}}}//}}/}//}//}}}}}}/=//}//}=//}}/}//}///}}}=}}}=}=:==..............................................==./.==}}:}..==}==}}}}=}=}}:,:}}:}}}}}}:|::,|:&}|&&:|,|:}:=,==,=,,,==,:,=::@::@:&:&:,@,::,::::@:,:,/,:_,:&&:[<&&&&}}=&:,:_|_^|,,:,,:[*,=,:,,,/,:&,=::&}/:/............///.....................",
"..................................................../}}}!}}}/==}>[|}}/}}}}}/}}/#//}/}}/}//}/}//=/}==}///}///}/}}/=}}}:}:=/=|...................................................===/=//}=}}}}}}}=:=,=:}}}}}}}}:==}:}|}:,:=&,}}}:::}::,=::},,=,=,,,:@@:::&:,:@@:&,@:,:::@&@&:,,::*&_&'*_:=,[&*[::,,=_^*&:,=,//:&'&,/,,///,,[&::='|=.:}....................................",
"...................................................../}=}=}}}}=/}!|=}}}}}}}}}}/}}}}}///}}}//}}}}////}/}///#///}}}.////....:}......................................................//=}}}}:}}}:}}}}==}=,}}=}}}}}:}::}}:}:=&:}::}:,,,=:,::::},,,::@:::@,@:&&::&::::&@:@:&::::_,|:::},:&[^|:,=:,,,}:|'3:,,,,,,,*''&:,/,,,==,,::=:[,=.==....................................",
"....................................................../}/=}/}/}==}>}/}}/}}/}/}}/}//}#/}//}/////}}#/#/}}}}//#/}}//}=/.....==:}:/................................................/===:}}:}}}:}=}}}}==,}}}=,}:=:==:,:,::}:}:==:}=:===::,::,:,@::::::@::&:@:&@:@:@:,:&@&&@:,:/,::*&&:,=&*:_*=:=,,|&&~~::=,,,/,,=@*,,//,//,,,=}==,[*=/.:.....................................",
"......................................................./}=}}}}}}}/==//}=}}#}}/}/#}}/}/#}}///.////}/}/////////=}}===......},==}/................................................/==:}}=}}=}===:==:}}=::,}:=}=}}}}}:==:,,,=:,,/,,,,:::::::@::@@&@@::@@:::@:&&:@&&@&&&@}::::::=:_&&:,=:::|::::==,,,,::,,,=,,,,,|:/,,,/,,,===:::*&=/./=.....................................",
"......................................................./}}}}==/=}}}}/}///}}}}}}}//}}/}/}////////}/}/}}}}/}}#//=/}}}/.../....../................................................../}&}:=}}}}}}:&}}}=}=}}}:},}},}::=,======/},,,:}:&@:,:=//&*&&&&*&&::&@&&&&@&&&|&::&:@:&:/,::=,/:&&&::,,::=,,:,,,,,,,,,,,,,,:,,/,/,/,,=:=,=,:&,=...}.....................................",
"......................................................./}:|}}=}}|>+!!||/}/}/#}}}}/}}}//}}}/}//}/}//////}////}/}======///........................................................../,|}}}=}=&=}}==::,}::},&:,|:,|:=.//::///=:,/,,::::/..=:_<*&*&#}&:@,&@:@:&&@&:&*&&&@:&,:::@:&,:,:,|_::=,,,,,,,:,,@,,,,,,/,:=,,,,/,/,/,===,=:/..../.....................................",
"......................................................./:|||}}}|![[_|_!/!///}/}/}}/}}}}}}}}}/.}}/.///}}/}}}/}/=////=}/............................................................/|}}}}=}}}=},:/.=}:,}:}:&|:&_:,/.../=/.,==,:,,:,:/..}&<_<*[~&##::&@,:,@:@&&&*&:@:},,::&@:&&@::@:,:,|,,,,,,,::,:,,@,,,,,:&,,,,,,/,,,==,=,=,/....=}/....................................",
".......................................................=}=}||}}=|__:|[&|>|}/}//}}}}/}}/}/}/}//}}}/}}}////}///}/...//......................................................./=/=/./=}}=}}=}}/./}}:=.=::,}},:&,:&&=..........===/,,:,}/..&_<&<'<&||@@&:,@:::,,:=:@::,:=:},::,,:,:::::,@:::,:,::,@,,@,,,,,,,,,=,,,,,,,,=:=}=,}/.....=::}/..................................",
"......................................................./}}}}||}}:}:&|+_:>_!/}}}}}/}}}}}/}}/=../}=////}//}//}/..............................................................:::=}}===}}}/..../,/}}:=///::=:&}:::&/..../....../=,=,:<&/../}&*&~<::&&:@@:,:,,:,,,,},,,&&,::,,=,=,,:@:@:@:@::@:,,@:,@,:,,,,/:&,=,/==/,=,=,=/=/...../==:,/...................................",
"......................................................./}}}}}|}}|&|=_|||'>[=/}}/#/}}/}}/}}}}/=/}}/////}////}/..............................................................:,::,::,}}=/...../=..=:::/./:::&:&:@&=/.==}==/....=,=,:,&:/..}=&&*_:::@&:&@:,,,,=,}:&=:&:}:},=,,,,:,:@:@|:@,:::@::,:::,:,,,,,:|:=}:},=,=:==..........=/......................................",
"........................................................}}:}&&}:}&%:[;>=*'>}/}}}}#}#}}}}/////#////}/}//}////...............................................................}:=@:::::=.......,:.../}::}/}:@:&,,:,/:,,,,,,::,,,,:,::*,:&...||&::@:@&:@}@::=,=}_*[*&:::::&&@&:,::,::::,&:&:@::@,@,,,,,,,,,=,:,==/=}==,,}=........./==......................................",
"........................................................}|=|}||:&&*&*&||_++}=}}}}}}}|/}}}}}}}}}/}/}}/}//}/................................................................/&@::@*^@:/../....:,.../.=://.&::///=,,,:::::,=,:,,,::@}&}::...&&*&,&&:@:@=:,::,:&'~<&:::@*&*_&@_&,}:,:,:@&::&,::::,,,,,,,,,,,=}}/./====:=/........../}:......................................",
"......................................................../}||[|:}::&:[==/__!//=}}=}}}|}}/}}}}/}/}/}////////................................................................/&*&&&^11&........//.../.=:.../@:,//,,,:@@::,:,/=,:@:&&&_&,=.../&:,}@:::::@,::::::[*=&&,**_**&&::::::,::::,:,::,:@:@:@,,,,,,:,:=/..,../=,:/..........==/......................................",
"........................................................./|}*_::&:&__=}+;[>|/}}}}}}}|}#}}//}/}}/}}/}//}/...................................................................&&@^1~%_/........./..=&_//.../:&,///,,,,:,:,,,,,:@@:@@:&~_}/../_::,::::::@::,=:::&'[@|&&*&*_@:,,,:,,::,::,,,,,,,::,,,,,/,=,=:==:/=//..==::........./}=/......................................",
"..........................................................=}}&:_&:::|}=}:+__=}}}|=}}}}}}/}}/}}=}//}////}..................................................................../,@:,=.../,//=,/,::...=....../=/.../,=,/,,,/,:@**<*@*:&*&:_&=},},:,,::,@:&:::=&}:_'<:=:&&:&:},=},,_:,,,,=,=/,=,,,,@,,,,,::,:=,==}=....====....../:}==.......................................",
"........................................................../=}&*_@:&&,}=}}|+}//}}}}}=}}}}}/}}/}/}}///////...................................................................../////=,,::@@::_@_&/...........===./....////}&&*&**_*&,&@&:_*&:,:,,,,,,}:@::=:,:_[*<3<*<::,<<:<&::&=,&,,,,,,,,,,,,/,,:,},}=}}|}}......=}=/..////==},/.......................................",
"...........................................................=}:&**&&:&:|_/|_/=}}}}}}}=}/}}}#//=}=///}/}}/...................................................................../@,:@&&:@&&*&****:/............///......}/.:**<**<_*&:::@:&::&&_:},},=,,:=::,},:~32&*&,::::&&&},::&:&:/,,/:,::::,,}:=,,::}:}:}=......==/../}=====/.........................................",
"............................................................./:&@@@::}|&/}|}/=&:,}}}}}=/}}}}}//}//////...................................................................../=,,:&****@***<*<_<:/....................../=&***<<<&@*},&&,&:,::,:,,,::,}:}::}=:=:[3$~|:::,:,&::,:,&&*~3&,,=:},,=,:,::}==}}}:}}:=...../../===,=/............................................",
"............................................................../&&&_@*:}|//====::&:}==}}=}/}/}}}/}//=......................................................................./@:,:@&**@*@**<<<'**_,:=.....=|&=........../}::_*****:&@:::<*&::::,:/,,}:,::=,::=,}:_~3~[*=,=,,:},:&<+';$3_:,,,::,,:=:,=:,,}}}}:}:......../:=/...............................................",
"...............................................................=&:@[@@=}======}:,:}}==}}}}}=///}}}/.......................................................................=::,::*@&******<<<<<**&&*:/../+<<*_|}/./././=:&&&**<*<&&&&@::<_&&},},,=,:::,,,/,:::,},*'33[*:&,,:,/:+3*'~';2<<&_,:,},,,::}:}},}}}}:=........==................................................",
".............................................................../:=/@@@&}|===}}:::&:}}:|}}}}/}/}}/}/....................................................................../=,,,,&@**<<<<<<<<'<<****@&_*}=<<<<<*<[*__}_*&@&@*&<<<<<<*&&&,:<3:::=,:,:@::&=:,,,:}::=,,@~3[<|_&,&_<'<|*'3$~;$'<},,,=,:,=}}}:&}}}|:}..........................................................",
"................................................................=:/:|:&:}=}/=}::,}:}:===///...////}....................................................................../=::,:***@*<<<<<<<<<**@@**@*[*[<<*<<<<<<<*&:*:&&@**<<<<<<<*=/=::,&&*<,,==::,@::&,=,=,:=,=,=&*~'~&:<@_}:=[;3))'+3&==,},====}=}}:::}}}}/.........................................................",
"................................................................./}/:@&::::===,::=}==............==...............................................................././=./::,&&&&**<<<<<<<<<<****_@&&&*<<<*<<<<<<<<*_&:&,&:_**<<*<<<<}..}=:::,}:}:,,::::::}:::&:==,=,,,=&33'['232$'$~~23*:====,,,},=,},}}}:|}}=..........................................................",
"................................................................./_//=@:=::=,}=}=}:............../}/............................................................././///_:::@**@*@&<<<<<<<*<<*****_@*&=&<***<<'<<<<*<&}=},:*<<**<<<<<*/./=},::}:,:==:=:/,,::&:@:,:,====,,::&3~2'33@_&:&_=,=,=,==:=}==}:},}:}|}...........................................................",
"................................................................../}/.=:=,:::====}=..............//=..................................................................&_@:::&&&::@*<<<***:@&*&*******:,<**<<<1'<'<<*&:=.}:&*@&**<*<<<*=../}=/}}}=:,}:,,:=:@&:,:,=::,:=,,=:,:,:,:,=,},,:=,,=,==,,=}:=}}}||}|=............................................................",
".................................................................../|./}},}::},==}/...............//.................................................................&<_:@&@&&@&:&@<*<*,&_&=::&&*<<*@&*<<<<*<<'<'<<<*:}./:=,::@**&**<<,&../}/,=:}}=}}==:,:&,:,,,,==:,}=,==/,:,:=:,=,==:=:,=,,,==,:==:,}}}}}/............................................................",
"....................................................................&=..=:::,}}//}..................................................................................=**::&&@&&::&&<<<<_**_*&&:&_<<<&@**<*<<*<<<'<'<<_&:=.}::,:&&&*&*<<[&//=*=..../..../==:::=,,=,=,,/::=,,:}:}:===,=,:=:,=,===:}==:==}:}=}=./=..........................................................",
"...................................................................../=./}=:=/}==}................................................................................./[<&@@&&&@&****<<<<<<*:::@*:*<<****&@&****<<''<'<*&&}./=:}::@**&&***__<_*}&}......../=::,,=,=/,/,,=,==,,}:}::}=:=,=:=:,===,,=:=,====}}/..==..........................................................",
"........................................................................./}:===/}=/.............../................................................................|<*::*@&&&*****<<<<<*,@&&&*****@*<*&,*&*<<<'<<'<**&@:}./},:&&&&*******<**_&&=.........=,==,,,,,:,=,=,===,|:|}=,=:},=:,}:=,=:=:==::==/....=/..........................................................",
"........................................................................../}===////................./............................................................./+*_**&&**<<****<<<****&@<@***:**@:,,,****<<<'<'<_<&:,}./}&,:@&****<<<<*@&&,_=........./,,=},,==,/,==:=,,===/.},:=:=,},=}}=====}==/...................................................................",
"........................................................................../=}////=/.......///........///........................................................../&'<<_*<<<<<<<*<<<<*****_@***@***&&,,:**&<<<<'<<*<<*&&:/.:}::&@&*&<<<<<****_&..........././=,/,:,,=,,,,=}/....=:=,=}==}:}==,=..//.....................................................................",
"......................../..................................................}}=}////.......==/.............../......................................................}<***<<<<<<<<<<<<<*****@:&*<*****<&::***<<'<'<'*<<**&},..=}::&***<<<<<*<<*&/............./=,==,/,,=====/......=::,:,=}}}:=}/..}=.....................................................................",
"............................................................................/}}}}/=/.....//=...............//=/....................................................=<'<<<1<<<<''1<<<<<<^***@:_*<<<<<***&*_<<1'<'<<<<__*@::...}:,&***<<<<*<<_:/............../,/,:=,/,,:==......../}:===,,:=}}}../:/........../..........................................................",
".............................................................................././}////=/////........../............................................................=<<<**<<'<<<<<<<<<*<**&,,:<<<<<<<****<&*<<'<'<<<**<*&&:&/./}:&**<<****@_=/.............../,,/,,,=//,=........../::,}==:==:=/.............=}..........................................................",
"................................................................................/}/}//////=/.......................................................................=**********<<***<****@*@:**<<<<<<<_&<<*<'<'<<'<<<<&&&&,:/./=}@&<<&_&,:}=................../,/,,,=,==...........=::=:=::}}}}==............/:=.........................................................",
"...................................................................................//.//////.//=...................................................................&***@@@@@@******<^**&@@***<***<<*<<<**<*<<<<<<<<*&*&:&:=,/.,}&@[**&&}/..................../,/,,,,=.............////:=:,:=}},=/........../==..........................................................",
".......................................................................................//}/==////................................................................./***:&,::&:@@*@*@****<***<<***<<*<***<***<*<<*****:@:@,,::}//:&&&&&://....................../,/,/==.................::=:=},==}}...........==/.........................................................",
"..........................................................................................///}///..................................................................:@:@,,,,,,::@:@@&**@<*<*<<**<<&_***@**@*@&***&@**@::@,,,,::/}}&}:/.........................,,,,,,/.................=:=::}:}===.........../==/........................................................",
"............................................................................................//=/...................................................................=,,,,/,,,,,,,,,@@@&****^<<<<***|@:::::::@:@*@@@:@:@::,,/,==:}}............................../,,/,/................./=/=::}::=}/..........///=/.......................................................",
"..............................................................................................//....................................................................=:},,,/,,,,,,,},&@::@&@******:@:@,,,:,,@@@*&,,,@:,,,::,,==://.../=_/.......................=,,,,..................==../:,::=}............/////......................................................",
"............................................................................................../}/..........//......................................................./}=}}=,}=,:=,,,,,:,:::::::*&@:&,,,/,,,,,,:,,,,,,,,,,,/,,,,::=,}__*</........................=,,=............/.....,=...=}}:=.........../../=//......................................................",
"................................................................................................/........////=////../................................................/=},|}}}}},}=}:,=::,::,,,,,=,:,,,,}:==,,,,,,/,,,,,,,=,},,:,&&*<*<*.........................=},.=.................==....=}}.........../.../=./......................................................",
".................................................................................................///....////=//////=/==...............................................=||,:}}}}}=}:}}:}==,=}}}:=:,,,=}},=:,=/,/,/,,,/,==,/,,,,,:@:@<<*}.........................==//&/................=&=..../.........../....//==/.....................................................",
"..................................................................................................//.////=/////=/}/}//}=...............................................}|&}},}}}}}}=}=:}::}=}=}}:}=}:==}}=:,,,,,,/,,,,,=,,,,,,@,,,,@_&/.........................././::................/:=................/..../===/.....................................................",
"......................................................................................................////////}/}////=/=:=..............................................=|,::}}|::&:}}}:=}}}}}=}}}}=}}}}}=}}}}:,,,.,==,,=,:,@,:@:,:*_=............................./&}................./:=..............//...../}//.....................................................",
".......................................................................................................//////////}//}/=/==/............................................../|}&}}&}:&:=/../=}}}:}}:}}}}}}}}}}}}}}},,//,,=,=,,,,,,@:@:*&.............................../..............=/...}@:/.........../,:=...../.......................................................",
".......................................................................................................////////}//}//}/===}====............................................}:=/////....../:===}}}}}|=}=}=}}:}}::=,,,,,/::=:,,:,,@,&@/..............................................=&:///,:=..........==::}.............................................................",
".......................................................................................................////////}//////////===:::.............................................................=}:}==}}}}}}}}}}},,,==/,,/:,::,,=,=,,:=................................................=&://&&,........//}=}=/.............................................................",
".......................................................................................................///////////}////=/=/==,}=}.............................................................=}}}}}}}=}}}}},::=,=,,/,,,:,=:=,,,,:=................................................../:|/=:&.......====:==........../...................................................",
"...................................................................................................../=}//}}/}//}//}//}//=//=/=//............................................................/},}}}}=}}}}:::::}=/,=,,,/,=:,:}=,/,.....................................................=|::=|/....:=}},=}::/........==...................................................",
".....................................................................................................////////////}/////}//}//=/===.........................................................../}|}}}}}}}},,}}:,,,/,,==},,,/:=,,==.....................................................//}:&:=..../&&&==}},:=.==/}=..==...................................................",
"....................................................................................................}/////}////////}///////}//}///...........................................................}:}},:,:},:},},,,/,,=/,=/}==,,=:/=.......................................................//}:&|/....&@&:=,=::././//...=/.//}/..............................................",
"....................................................................................................=///////}///////////}//////}/}//.........................................................=:,:&|:}:|:::,=/,/,,,,=/=,,=,=,,,........................................................//::&&=/...=@_:::::/.:::=//..//./::}////..........................................",
"...................................................................................................}////}///}////}/}//////}/}///}}/=//......................................................./&|:,|:,},}/,,,/,/,/,,=}},,==,,=.........................................................../&,&,&=./.&*::,&=..:::/.//..//./=,/./===/.......................................",
"...................................................................................................}}//////////}//}//////}////}////=/////.....................................................=:&:,:|::,,//,,,,,,=/,,,=,,,,=/............................................................/:&&&/...//==:&=./:,:=...:/==:./}&/==}==}//......./............................",
".................................................................................................../////////}///////}/}///}////}/}/}/==},:,::=................................................./:|:,::,,,,,//,,/,,/,=,===,,/..............................................................=&:&........//...===:/...././../.=}}=}/===//.....//...........................",
"...................................................................................................!/}//}/}/////}//}////}//}/}//}/////}/=:=:@:/.................................................}|&:=:=/,/,,,,,,,:/,,,,,=,=/.............................................................../:}/............=/.=..........//../}/}=/===.././/............................",
"..................................................................................................._}/}/////}////////////////}//}/}/}/}===,,,::=/.............................................../:::=:,/,,,,.,,/,:=,=,===,}=.................................................................=:}=/////.................../=.../=}}/}}=}/./..............................",
"...................................................................................................}}////////////////}///}/}//}//}///=/=/,=:::,,}.............................................../},&:=,,/.,,,,/,/,:/=,,,,===..................................................................=,:::::=......./..../....=....../}/}//=}}/................................",
"..................................................................................................../}/}/////}/}/}/}//}/////}//}//}/}=}=},=:,=:,:/...............................................}=:&}/,,=,.,,,,=,:,===/,,,/.................................................................../..==,}====}===//=/=/.../......//}}|/.//}/...............................",
".....................................................................................................}/}}/////////////////}//////}///==,,=,=}==}:................................................},},,,,,,,,,=,}::}:=,,,/,==............................................................................//.,/../:=/..............=/....==/..............................",
".....................................................................................................////}///}//}/////}/////}/}//}/}=}},=======::................................................}:}:},,/,,/,:,}},}:=}=,=,=:/............................................................................../=.///......................////.............................",
"......................................................................................................#}//////////}}////}/}/////}///==:======}==..................................................}&|,},/=,,,,=,:}:},:}=,,===.........................................................................................//./......../.....................................",
"....................................................................................................../}/}///////////////////}//}/}/=,===,===}=..................................................}:}::}:,,,=,},}:|,||&}:==:==......../................................................................................/==:=}/..../}.....................................",
".......................................................................................................|/////}/}////////}/}/}//}/====},=}=}=,}/................................................./&,|},:=:=,,,,:,}:|:,&|:==,==.......}&.............................................................................../=::::}/..../}=....................................",
"......................................................................................................./|//}/////}//}/}/////}//}//},,:,:=,=},/..................................................&}:::}::::,:,==,=:}|&_:&|::},....../__/........................................................................../==//:@:::=/....=&==...................................",
"........................................................................................................!}/}///////}///}/}}//}/==}=,:,,::=}=}..................................................._&,}}:,:,::},,,}=:}&|}&|&__|=.....=|&_=........................................................................./:=,::,,:,::=....::::/..................................",
".........................................................................................................||||}/}/}/}==:}:==}//}/==:,::},::=:=................................................../<::,}:}::,:::::,}:}|_}__|!_=..../|&|*|......................................................................../==,,,:,:,:,,:::/..:&}}/..................................",
"..........................................................................................................=[_>}|=/==::::&,}}/}/==:}:,:===,:=}..................................................=~&=}::,}::::,}:=:}:}&|_|#|/.....:&_&_&........................................................................=,:@::,:,@@@@,,,,=/::,:}..................................",
"............................................................................................................=&}=}}==::&@&@:}/}/===:}}=,}==,=}................................................../<|:::}:,&},::,:::=}}:}__}.......|&&__=......................................................................./:@,@,,@@@@,@@@@,,,:=::==/.................................",
".............................................................................................................=|}:&=&,@&&@&:}=/}=}:|&@}},}====...................................................=&,::,:&:::::},,,::,}&|}........=&|@[/......................................................................,,@@@@@@@,@@@@@@@@,,:,:=}==/................................",
"............................................................................................................./[&!}|:::@@@*::=:::,}:,},==:}==/...................................................._=,:::&:&:,::=::==:=}}.........::__:....................................................................=,,@@@@@@@@@@@@@@@@@@@@@,:::,:==...............................",
"..............................................................................................................[_'_&::&&*&@@:::,=}====}}=,,}}...................................................../&}:&@&*@&::::=::,,:,:........}&|@_=................................................................./:::,,,,@@@@,@@@@@@@@@@@@@@,,:,:,:==..............//..............",
"..............................................................................................................*:,:=:@&:@&@&::::==,}===}=}=:/......................................................|:,_***&&:,}::,}:,==}/.......:&:&_.................................................................=[%1:,,,,@,,@@,@@@@@@@@@@@@@,:,}:::==/.............................",
"............................................................................................................./__|:,=,@@&@_::::}|/}=//=,}}==.......................................................*&:***@*@&&::,:},}:},=.......=|:&_.................................................................=%(%-@@,,@@,,@@@@@@@@@@@@@@@:,,,,,::}}.............................",
".............................................................................................................=*:&:=:}:@&::}=:::==}}/}=////........................................................}<&&@_***&:,:==:::==&=......./_&&}.................................................................&^1@1@,@@,,,,,@,@@@@@@@@@-@@@:,::,:=::=............................",
".............................................................................................................}[:::=,:*&:::=}::}=/}/=//............................................................}<&&<@***@:},:::,::}/.........=:=..................................................................=*@@@@@,,@@@,,,@,,@@@@@--%-@@@@,,},,:===...........................",
".............................................................................................................}_&&:=:@@&==:===:}=/=/}............................................................../_*:****&&::}:::},&/...............................................................................=,@@,@@,,,,@,,,,,@@,@@@-1%^@&&::,:,:,:}:...........................",
".............................................................................................................|^_:,::&_@:::===:}}}/=/...............................................................}*&:_&:*:@:=:,|::&................................................................................/,,@@,,@,@,,@,@,,,@@@@@-~111@@,:,=:,,,,:/..........................",
".............................................................................................................__*:==::&&@:==,=::}=///.............................................................../_*&<*&*&&@:&@::*:.................................................................................:,,,@,@,@,@,,,@,@,@,@@^~~]]^-@@@,::::,:/..........................",
"............................................................................................................/*&&:,==:::::,}}::==}=}................................................................./<*<<****&*@&&@}...................................................................................@,,,@,,,@@,,@,,,@,@@@@%1<{%(^@@,,,,}::/..........................",
"............................................................................................................=_::==::::&::::=:::=}/}.................................................................._**<**@*@&@&@}.................................................................................../,@,@,,@,@,,@@,@@@@,@@@1*@^1]--^-@:,:::...........................",
"............................................................................................................/:}_:::@&:::=::====}/..................................................................../_***&@@&@@_*=....................................................................................,,,@,@,,,,@@@,,,@@@@*@*&@&-(](((-(@,}|...........................",
"............................................................................................................,:::::@@@@:/=:===//=/.....................................................................&****@&:@&*/.....................................................................................=:@,,@,@,,,.,/./.,,@@@@,:@,^](-((^@,&/...........................",
"............................................................................................................/:<=:@@:&,:===//=/==......................................................................,:&@__@&&:/......................................................................................=:@@,:,@,,.........,^@@@,@@,@](((@@@=............................",
"............................................................................................................==&,::@&@:,====/}}//......................................................................=:::/==/........................................................................................./::://./............&/:@:,,@@-((]-@:/............................",
"............................................................................................................:&::@@@@@@&,//}/}|/.........................................................................................................................................................................//...................=:@,@-----@@&=.............................",
".........................................................................................................../|_,:::@&@&&:&}/................................................................................................................................................................................................../.=,@@@@@@:@|........................=.....",
"...........................................................................................................,,=&@,:@@@@@@@&&/....................................................................................................................................................................................................}:,@::::::......................../=....",
"........................................................................................................../::::@@&::@&@&@@_/..................................................................................................................................................................................................../=}=,}:=........................../===..",
"........................................................................................................../:_:&&@@@@,@&@@&=......................................................................................................................................................................................................../..............................=,=/..",
"........................................................................................................../:_&:@&@&&&:,/............................................................................................................................................................................................................./../..........................=....",
"..........................................................................................................,[,:&&@@@@&_............................................................................................................................................................................................................../}=}/......................./=//....",
"..........................................................................................................:[:@&::&&/,/...............................................................................................................................................................................................................}:}....................../_==......",
"..........................................................................................................=:::&*@&&=/.................................................................................................................................................................................................................=/...................../}==.......",
".........................................................................................................//:&@:&:@:/......................................................................................................................................................................................................................................./:==/........",
"........................................................................................................./=:::@:&:=........................................................................................................................................................................................................................................===}.........",
".........................................................................................................//|:@&:&=........................................................................................................................................................................................................................................./=,..........",
"......................................................................................................../:|::::::........................................................................................................................................................................................................................................../............",
".........................................................................................................=[}::@::}......................................................................................................................................................................................................................................................",
"......................................................................................................../:[::,&&:}......................................................................................................................................................................................................................................................",
"......................................................................................................../=+:::::=.......................................................................................................................................................................................................................................................",
".........................................................................................................=[::@&=/.......................................................................................................................................................................................................................................................",
".........................................................................................................:|::::/........./..............................................................................................................................................................................................................................................",
"........................................................................................................./:::::/......../...............................................................................................................................................................................................................................................",
"..........................................................................................................=&:,::/.......................................................................................................................................................................................................................................................",
".........................................................................................................../==:::=......................................................................................................................................................................................................................................................",
"............................................................................................................./===/......................................................................................................................................................................................................................................................",
"........................................................................................................................................................................................................................................................................................................................................................................",
"........................................................................................................................................................................................................................................................................................................................................................................",
"........................................................................................................................................................................................................................................................................................................................................................................",
"........................................................................................................................................................................................................................................................................................................................................................................",
"........................................................................................................................................................................................................................................................................................................................................................................",
"........................................................................................................................................................................................................................................................................................................................................................................",
".........................................................................................................................////...........................................................................................................................................................................................................................................",
"....................................................................................................................///|}}=.............................................................................................................................................................................................................................................",
"....................................................................................................................|_=/...............................................................................................................................................................././..........//...................=|............................................",
"..................................................................................................................|_||=/..............................................................................................................}&[[[!=...............................=/....////.=_!__|}}=//}_[!_#=..././/==|/..}}}|_[|:///.......................................",
"..............................................................................................................._}[>}==}/........................................................................................................./=/|_['''''+[|=/=////.............../||__[[++[>[++++[++'''''''[+['''''+[[[[+++'+''+[[+'''''+''+++[>_}//................................",
"................................................................................................................/[_/=}//.............................................................................................//......:!+[+'+'''+''''''';'+'+[++[[>........}[[+''''''''[''''''''''''''''''''''+''';+'''''''''''''''''''''''+''+++!_}/./..........................",
"............................................................................................................||/.|>++##}............................................................................................/}+[|/=.}>''<'''''''''''''''''''''''''_/.../=}_+'''''''''''''''''''''''''''''''''''''''';'''''';'''''''''''''''''''''''++++[_|_}/....................",
"........................................................................................................=...#>>|+'+++|}.................................................................///}|}/.}:}|&_||}=//=}|&_[[++'+'+[[''''''''''''''''''+'''+''''''[|#}}[[+'''''''''''';''''''''''''';''''+''''''''''''''''''''''''+;'''''+''''''''''''''''+''+[>&}}}}/............",
"......................................................................................................../|}|&[+_:'++++>}...............................................|[[}.}!}}||//|[['[+'''<+++''''''''+''''+'''<''''''''''''''+'';+'''''''''''''''''+!||_+''''''''''+'''''''''''''''''+''''''+''''';'''''''''''''''';'''''''''+'''''''''''''''''''''';'++_}/.........",
".............................................................................=}||||=................./../}|}|>_}:++''+!|...........................................=|!*++''+*''<'''+''''''''''''''''''''''''''''''''''''''''''''''''''''''+''''''''''''[>|[++'''''''''''''''''''''''+''+''''''''''';''''''''';''''''''''';''''''''''''''''''''';''''''''''+<++=.........",
"..................................................==/../............}/......}||_['[>_|___&!_|}=/...=|_//|}|||:#_[<'[+'_}........................................}[+++'+'''''''''''''''''''''''''''+';'''<'''''''''''''''''''';'''''+'''''''''''''';';''''+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';''''''';'''''''''''''';''';'<+[[[:..........",
".............................................//}|_|[+[_[>[[_|_|_||__>+!_![>_[['+''''++'++'['+'+++[[++[+[[[++++++'+'+[+&..................................../}}}[++<'+''''''''''+'''+''''''''''''''''''''''''+''+;'''''''''+''+''''+''''+;'''''+''''+'''''''''''''+'''''''+''+''+''+''''''''''''''''''';'''''''''''';+''''''''''''+''';''''''''''''''''[+[:/.............",
"..................................///=||>+++>[[+;+'+'+''''+++'++'++''[''''''+'+'''+'''+''+''''+'''+'+'[++'''''+'+'+++>_}/................................./|_[[+++;'''+''+''''''''''''''''+''''''''+'''''+''''''''''''+'''''''''''''''''''+'''''+''';''''''''''''''+''+'''''''''''''''''''+''''+';''''''';'''''';+'';'';''''''''''';''''';''''';'''';+_/................",
"............................/=}_>[++++'''''''+'''+'+'++++'+'''''''++;++'''';'''+''+'+''+''+++'++''+'+'''[;++[+[[+[>_!!>!!|!}=//......................./=|>''+[+'<''''''''''''''''''''''+'''''''''''''+''''''''''''''''''''''''''''''''''''''''''''<'''';'';'''+'''''''''''''''''';''''''';''''''''''''''''';';''''''''''''''''''''''''''''';''''''''''_.................",
"...................}=|}=//||_||[''''''+'+'+'+'+++;+;+'';'+''+++++''''+'+'++''+''+''+''+'+''''+'''+''+''+'+'[>[>!>!>>_>_>_>_!>#!##}/............../=|_[+'''[+''''''+''+'''+'''''''''+'''''''''+'''''''';'''+''''+''+'''''''''''+'''+'''''''+''''''''''''''''+''''''''''''''''''''''''''''''+'''''''';''''''''''''''''''+;''';''''''+''';'''''''''''''''+}..///...........",
"....../=|__|_#&_![[+''+++'++;+'+'+'+'''''''''+''+'+'+'++'++''+''++++'+''''+'''+''+''+'+''+'+'+++'++'+''+'''+>[>[_>_>>!#_!_>_>_>>[!!__|_||_![[[[_[+''''''''''''''''''''''''''+''+'''''';''''+'''+''''''''''''''''''''''''+'''''''''''''''''''+''''+'''+'''''''''''''''''''+''+''+'''+''+'''''''''+'''';''''''''';''''''''''''''''''''''''''''''';'''''''+!_|=//./........",
"/==&!++''+++''+'''+'+''+''+'+'''+'+''+'+'+'+'''''''+'+''+''+''++''''''+'+''++'''';+''''+'+''''''+''''++''++[+[+[[[>![[>>_!>!_>_[+'++++'+'''+''+'+'''+''''''+''+''''<''+''+'''''''''+'''''''''''''+'''''''''''''''''''+'''+'''''''''+''''''''''+'''''''+'''''''+'''+'''+'''''''''''''''''''+''+''''''''''''''''''''';'''';''''''''''''';'';'';'''';'''''''';+'+'++[_:=/..",
"+++'1''+'+'''''++''''+''+''+'''''''''+'+;''+'''''''+'+''+''''''++'+'+'''''';+''++''+'''+''++'++''+'''''+''+[_[![[[[[[['+>[>[>[>+<''+'+'''''''+''''''''+'''''''''''''+'''''''''+''''''+'''+''''''''''+''+''''+''''''+'''''''''''+''''''+''''''''''''+''''''''''''''''+'''''''''''''''''''''''''';''''''';''';''''''''''''''';';'''''''''''''''''''''''''''''''''''''+'+++",
"''+'''''''+'''+''+'+''+''+''';''''';'''''+''+''+''''+;'+;+''+'+''<''''''+'+''+;'''''''+'''''''''''+'''['''+++++[[[[[[+[['['''''''+''''''''''''';[';+'''+'''''''''+'''['''+'+'''+''''''''''''''''''''''';+''+;'''+'''''''''+'''''''''''''''''''''''''''+'''''''''''+';''''''''''+''''''''';''';'''''''''''''''''''''''';'''''''''';'';';'''''''''''''''';'''''''''+;'''''",
"'''+'+'+';''+''''''''''''''''';''''+''''''''''''+'''''++''''''''''''''+'''+''''';''''''''+''''''''';''''[;''''+'+'''''+'''''+'+'''''''+''+''';''''''''''''''+''+'''''''+''''''''''''''''''''''''''''''''''''';'''''''''''';'+';''''''''''''''''''''''''''+'''''+''''''''''+''+'''+''''+''''''''''';''''''''''';';''''''''''''';'''''''''''';'''';';'''''''''''''''''''''",
"''';';''''';'';''';';'''';'+''';''''''';'''+''''''''''''+'';'''';+'+''''';''';''+';+'''''''''+''''''';'''''''''''''+'''''''''''''''+''''''''''''';';';'+'''''''''''';''''''''''''''''+'';'''+'''+'''''''''''''''''''+'''''''''''+'''''''+'''+''+''''''''''''+''''''''''+'''''';'''''''''''''+'+''''''''''''''''''';'''''''''''''''''''''''''';''''''''''+'''''''''''''''",
"''+'''';'''''''';'''''+''''''+'';''''+'+'''''+';''+''''''''''+'''''''''''''''''''''';'+';''+''';';[''''+'''+'''''+''''''+''''';;''''';'''';'''''''''''''''';''''''+''';''''''''';''';''+'';'''''''+;<''''+''<''''''''''''''''''''''+'''''''''''''''''''''';''''''''''''''''''''''''+''''''+'''''+''';'''''';''''''''''''''''''''''''''';''''''''''''''';'';';'''';;'''''",
";';'+''''''';''''''+;';''';'';''''';;''';';+'''+;';'''';''+''';''''+'';'+'''+';''''+'';''''''''''';'''';+'''+'''';'+'+'';'+;''+'''''''+''''+'''''''''';';''''';'''''''''''+'''''++''''''+''''''''''''''''''+''+''''''';'''''+'''''''+'';'''''''''''''+'''''''';'+''+'''''''''''''''''''+''''';''''''''';''''''''''''''';''''''''''''''''';''''''''''''''''''''''''''''''",
"''''''+'''''''''+'''''''+''''''+'''+'''''''''+''''''''''+;'''+'''''''+''''+''''''+;''';''';'''''+'+''''''''''''''''''''''''''''';'''';''+''''+''+''+''''+';''';'';''+'''''''+'''''''''''''''''''''+'''+'''';'''''+'''+'''+''''''''''''''';''''''+''''''+''''''''''''''''+'''''''+'''''''''''''''''''''''''''''''''';''''''''''''''''''''''''';'';';''''''''''';'''''''''",
"''';';'+''''+''''''''''';'''''''''''''''''''''+''';''+''''+';''''';''''';';''''''''''''''''''''''''''''''';'';+''''';'''';''''+''+'''''';''''''''''''''''''+'''''+''''''';''''''+'''''''+''+'''''''''''''''''''''';'''''''''''+'''''''+'''''''''''''''''''''+'''''''+'''''''+'''''''''''''''''''''''''';''''''''''''''';'';'';'';'';''''''''''''''''''''''''';''''''''''",
"''''''''''';''''';'''''''''''''';''''''''';'''''+'''''';''''''''+''+;'''''''+'+''''''+'+''''''''';''''''''''''''+''''''''''+'''''''+''''''''''''+;''''+''''''+'''''''''''''''''''''+'''''''''+'''''''''''''''''+'+'''''+''''''''+''''''+'+''+'''''''';'''+''''''''''''''''+'''+'''''''''''+''''''';'''''''''''''''''''''''''''''''''''''''''''''''';';'''''''''''';'';''",
"'''''';';'''';''''''';''''''';''''';'''''''''''''+';'''''''''''''''''''''''''''''''''''''''+''''''''''+''''''''''''''''''''''''';'''+;'''+'''''''''+;''''''''''''''''+''+'''''''+'''''''''''''''''+''''''''+''''''''+'''''''''''''''''''''''''''+'''''''''''''+'''''''''''''''''''+'''+''''+''''''''''''';'';'';''''''''''''''''''';''''''';'';'''''''''';''''''''''''''"};

556
wmglobe/src/mycontext.c Normal file
View file

@ -0,0 +1,556 @@
/* WMGlobe 0.5 - All the Earth on a WMaker Icon
* mycontext.c - an adaptation of wrlib for use in wmglobe
* initial source taken in WindowMaker-0.20.3/wrlib :
*/
/* context.c - X context management
* Raster graphics library
*
* Copyright (c) 1997 Alfredo K. Kojima
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* #include <config.h>
*/
#include "wmglobe.h"
/*
* #include <X11/Xlib.h>
* #include <X11/Xutil.h>
* #include <X11/Xatom.h>
*
* #include <stdio.h>
* #include <stdlib.h>
* #include <string.h>
* #include <assert.h>
*
* #include <math.h>
*
* #include "wraster.h"
*/
static Bool bestContext(Display * dpy, int screen_number, RContext * context);
static RContextAttributes DEFAULT_CONTEXT_ATTRIBS =
{
RC_DefaultVisual, /* flags */
0, /* render_mode */
0, /* colors_per_channel */
0,
0,
0,
0,
0 /* NO use_shared_memory */
};
static XColor *
allocatePseudoColor(RContext * ctx)
{
XColor *colors;
XColor avcolors[256];
int avncolors;
int i, ncolors, r, g, b;
int retries;
int cpc = ctx->attribs->colors_per_channel;
ncolors = cpc * cpc * cpc;
if (ncolors > (1 << ctx->depth)) {
/* reduce colormap size */
cpc = ctx->attribs->colors_per_channel = 1 << ((int) ctx->depth / 3);
ncolors = cpc * cpc * cpc;
}
assert(cpc >= 2 && ncolors <= (1 << ctx->depth));
colors = malloc(sizeof(XColor) * ncolors);
if (!colors) {
RErrorCode = RERR_NOMEMORY;
return NULL;
}
i = 0;
if ((ctx->attribs->flags & RC_GammaCorrection) && ctx->attribs->rgamma > 0
&& ctx->attribs->ggamma > 0 && ctx->attribs->bgamma > 0) {
double rg, gg, bg;
double tmp;
/* do gamma correction */
rg = 1.0 / ctx->attribs->rgamma;
gg = 1.0 / ctx->attribs->ggamma;
bg = 1.0 / ctx->attribs->bgamma;
for (r = 0; r < cpc; r++) {
for (g = 0; g < cpc; g++) {
for (b = 0; b < cpc; b++) {
colors[i].red = (r * 0xffff) / (cpc - 1);
colors[i].green = (g * 0xffff) / (cpc - 1);
colors[i].blue = (b * 0xffff) / (cpc - 1);
colors[i].flags = DoRed | DoGreen | DoBlue;
tmp = (double) colors[i].red / 65536.0;
colors[i].red = (unsigned short) (65536.0 * pow(tmp, rg));
tmp = (double) colors[i].green / 65536.0;
colors[i].green = (unsigned short) (65536.0 * pow(tmp, gg));
tmp = (double) colors[i].blue / 65536.0;
colors[i].blue = (unsigned short) (65536.0 * pow(tmp, bg));
i++;
}
}
}
} else {
for (r = 0; r < cpc; r++) {
for (g = 0; g < cpc; g++) {
for (b = 0; b < cpc; b++) {
colors[i].red = (r * 0xffff) / (cpc - 1);
colors[i].green = (g * 0xffff) / (cpc - 1);
colors[i].blue = (b * 0xffff) / (cpc - 1);
colors[i].flags = DoRed | DoGreen | DoBlue;
i++;
}
}
}
}
/* try to allocate the colors */
for (i = 0; i < ncolors; i++) {
if (!XAllocColor(ctx->dpy, ctx->cmap, &(colors[i]))) {
colors[i].flags = 0; /* failed */
} else {
colors[i].flags = DoRed | DoGreen | DoBlue;
}
}
/* try to allocate close values for the colors that couldn't
* be allocated before */
avncolors = (1 << ctx->depth > 256 ? 256 : 1 << ctx->depth);
for (i = 0; i < avncolors; i++)
avcolors[i].pixel = i;
XQueryColors(ctx->dpy, ctx->cmap, avcolors, avncolors);
for (i = 0; i < ncolors; i++) {
if (colors[i].flags == 0) {
int j;
unsigned long cdiff = 0xffffffff, diff;
unsigned long closest = 0;
retries = 2;
while (retries--) {
/* find closest color */
for (j = 0; j < avncolors; j++) {
r = (colors[i].red - avcolors[i].red) >> 8;
g = (colors[i].green - avcolors[i].green) >> 8;
b = (colors[i].blue - avcolors[i].blue) >> 8;
diff = r * r + g * g + b * b;
if (diff < cdiff) {
cdiff = diff;
closest = j;
}
}
/* allocate closest color found */
colors[i].red = avcolors[closest].red;
colors[i].green = avcolors[closest].green;
colors[i].blue = avcolors[closest].blue;
if (XAllocColor(ctx->dpy, ctx->cmap, &colors[i])) {
colors[i].flags = DoRed | DoGreen | DoBlue;
break; /* succeeded, don't need to retry */
}
#ifdef DEBUG
printf("close color allocation failed. Retrying...\n");
#endif
}
}
}
return colors;
}
static XColor *
allocateGrayScale(RContext * ctx)
{
XColor *colors;
XColor avcolors[256];
int avncolors;
int i, ncolors, r, g, b;
int retries;
int cpc = ctx->attribs->colors_per_channel;
ncolors = cpc * cpc * cpc;
if (ctx->vclass == StaticGray) {
/* we might as well use all grays */
ncolors = 1 << ctx->depth;
} else {
if (ncolors > (1 << ctx->depth)) {
/* reduce colormap size */
cpc = ctx->attribs->colors_per_channel = 1 << ((int) ctx->depth / 3);
ncolors = cpc * cpc * cpc;
}
assert(cpc >= 2 && ncolors <= (1 << ctx->depth));
}
if (ncolors >= 256 && ctx->vclass == StaticGray) {
/* don't need dithering for 256 levels of gray in StaticGray visual */
ctx->attribs->render_mode = RM_MATCH;
}
colors = malloc(sizeof(XColor) * ncolors);
if (!colors) {
RErrorCode = RERR_NOMEMORY;
return False;
}
for (i = 0; i < ncolors; i++) {
colors[i].red = (i * 0xffff) / (ncolors - 1);
colors[i].green = (i * 0xffff) / (ncolors - 1);
colors[i].blue = (i * 0xffff) / (ncolors - 1);
colors[i].flags = DoRed | DoGreen | DoBlue;
}
/* try to allocate the colors */
for (i = 0; i < ncolors; i++) {
#ifdef DEBUG
printf("trying:%x,%x,%x\n", colors[i].red, colors[i].green, colors[i].blue);
#endif
if (!XAllocColor(ctx->dpy, ctx->cmap, &(colors[i]))) {
colors[i].flags = 0; /* failed */
#ifdef DEBUG
printf("failed:%x,%x,%x\n", colors[i].red, colors[i].green, colors[i].blue);
#endif
} else {
colors[i].flags = DoRed | DoGreen | DoBlue;
#ifdef DEBUG
printf("success:%x,%x,%x\n", colors[i].red, colors[i].green, colors[i].blue);
#endif
}
}
/* try to allocate close values for the colors that couldn't
* be allocated before */
avncolors = (1 << ctx->depth > 256 ? 256 : 1 << ctx->depth);
for (i = 0; i < avncolors; i++)
avcolors[i].pixel = i;
XQueryColors(ctx->dpy, ctx->cmap, avcolors, avncolors);
for (i = 0; i < ncolors; i++) {
if (colors[i].flags == 0) {
int j;
unsigned long cdiff = 0xffffffff, diff;
unsigned long closest = 0;
retries = 2;
while (retries--) {
/* find closest color */
for (j = 0; j < avncolors; j++) {
r = (colors[i].red - avcolors[i].red) >> 8;
g = (colors[i].green - avcolors[i].green) >> 8;
b = (colors[i].blue - avcolors[i].blue) >> 8;
diff = r * r + g * g + b * b;
if (diff < cdiff) {
cdiff = diff;
closest = j;
}
}
/* allocate closest color found */
#ifdef DEBUG
printf("best match:%x,%x,%x => %x,%x,%x\n", colors[i].red, colors[i].green, colors[i].blue, avcolors[closest].red, avcolors[closest].green, avcolors[closest].blue);
#endif
colors[i].red = avcolors[closest].red;
colors[i].green = avcolors[closest].green;
colors[i].blue = avcolors[closest].blue;
if (XAllocColor(ctx->dpy, ctx->cmap, &colors[i])) {
colors[i].flags = DoRed | DoGreen | DoBlue;
break; /* succeeded, don't need to retry */
}
#ifdef DEBUG
printf("close color allocation failed. Retrying...\n");
#endif
}
}
}
return colors;
}
static char *
mygetenv(char *var, int scr)
{
char *p;
char varname[64];
sprintf(varname, "%s%i", var, scr);
p = getenv(varname);
if (!p) {
p = getenv(var);
}
return p;
}
static void gatherconfig(RContext * context, int screen_n)
{
char *ptr;
ptr = mygetenv("WRASTER_GAMMA", screen_n);
if (ptr) {
float g1, g2, g3;
if (sscanf(ptr, "%f/%f/%f", &g1, &g2, &g3) != 3
|| g1 <= 0.0 || g2 <= 0.0 || g3 <= 0.0) {
printf("wrlib: invalid value(s) for gamma correction \"%s\"\n",
ptr);
} else {
context->attribs->flags |= RC_GammaCorrection;
context->attribs->rgamma = g1;
context->attribs->ggamma = g2;
context->attribs->bgamma = g3;
}
}
ptr = mygetenv("WRASTER_COLOR_RESOLUTION", screen_n);
if (ptr) {
int i;
if (sscanf(ptr, "%d", &i) != 1 || i < 2 || i > 6) {
printf("wrlib: invalid value for color resolution \"%s\"\n", ptr);
} else {
context->attribs->flags |= RC_ColorsPerChannel;
context->attribs->colors_per_channel = i;
}
}
}
static void getColormap(RContext * context, int screen_number)
{
Colormap cmap = None;
XStandardColormap *cmaps;
int ncmaps, i;
if (XGetRGBColormaps(context->dpy,
RootWindow(context->dpy, screen_number),
&cmaps, &ncmaps, XA_RGB_DEFAULT_MAP)) {
for (i = 0; i < ncmaps; ++i) {
if (cmaps[i].visualid == context->visual->visualid) {
puts("ACHOU");
cmap = cmaps[i].colormap;
break;
}
}
XFree(cmaps);
}
if (cmap == None) {
XColor color;
cmap = XCreateColormap(context->dpy,
RootWindow(context->dpy, screen_number),
context->visual, AllocNone);
color.red = color.green = color.blue = 0;
XAllocColor(context->dpy, cmap, &color);
context->black = color.pixel;
color.red = color.green = color.blue = 0xffff;
XAllocColor(context->dpy, cmap, &color);
context->white = color.pixel;
}
context->cmap = cmap;
}
static int count_offset(unsigned long mask)
{
int i;
i = 0;
while ((mask & 1) == 0) {
i++;
mask = mask >> 1;
}
return i;
}
RContext *
myRCreateContext(Display * dpy, int screen_number, RContextAttributes * attribs)
{
RContext *context;
XGCValues gcv;
context = malloc(sizeof(RContext));
if (!context) {
RErrorCode = RERR_NOMEMORY;
return NULL;
}
memset(context, 0, sizeof(RContext));
context->dpy = dpy;
context->screen_number = screen_number;
context->attribs = malloc(sizeof(RContextAttributes));
if (!context->attribs) {
free(context);
RErrorCode = RERR_NOMEMORY;
return NULL;
}
if (!attribs)
*context->attribs = DEFAULT_CONTEXT_ATTRIBS;
else
*context->attribs = *attribs;
/* get configuration from environment variables */
gatherconfig(context, screen_number);
if ((context->attribs->flags & RC_VisualID)) {
XVisualInfo *vinfo, templ;
int nret;
templ.screen = screen_number;
templ.visualid = context->attribs->visualid;
vinfo = XGetVisualInfo(context->dpy, VisualIDMask | VisualScreenMask,
&templ, &nret);
if (!vinfo || nret == 0) {
free(context);
RErrorCode = RERR_BADVISUALID;
return NULL;
}
if (vinfo[0].visual == DefaultVisual(dpy, screen_number)) {
context->attribs->flags |= RC_DefaultVisual;
} else {
XSetWindowAttributes attr;
unsigned long mask;
context->visual = vinfo[0].visual;
context->depth = vinfo[0].depth;
context->vclass = vinfo[0].class;
getColormap(context, screen_number);
attr.colormap = context->cmap;
attr.override_redirect = True;
attr.border_pixel = 0;
attr.background_pixel = 0;
mask = CWBorderPixel | CWColormap | CWOverrideRedirect | CWBackPixel;
context->drawable =
XCreateWindow(dpy, RootWindow(dpy, screen_number), 1, 1,
1, 1, 0, context->depth, CopyFromParent,
context->visual, mask, &attr);
/* XSetWindowColormap(dpy, context->drawable, attr.colormap); */
}
XFree(vinfo);
}
/* use default */
if (!context->visual) {
if ((context->attribs->flags & RC_DefaultVisual)
|| !bestContext(dpy, screen_number, context)) {
context->visual = DefaultVisual(dpy, screen_number);
context->depth = DefaultDepth(dpy, screen_number);
context->cmap = DefaultColormap(dpy, screen_number);
context->drawable = RootWindow(dpy, screen_number);
context->black = BlackPixel(dpy, screen_number);
context->white = WhitePixel(dpy, screen_number);
context->vclass = context->visual->class;
}
}
gcv.function = GXcopy;
gcv.graphics_exposures = False;
context->copy_gc = XCreateGC(dpy, context->drawable, GCFunction
| GCGraphicsExposures, &gcv);
if (context->vclass == PseudoColor || context->vclass == StaticColor) {
context->colors = allocatePseudoColor(context);
if (!context->colors) {
return NULL;
}
} else if (context->vclass == GrayScale || context->vclass == StaticGray) {
context->colors = allocateGrayScale(context);
if (!context->colors) {
return NULL;
}
} else if (context->vclass == TrueColor) {
/* calc offsets to create a TrueColor pixel */
context->red_offset = count_offset(context->visual->red_mask);
context->green_offset = count_offset(context->visual->green_mask);
context->blue_offset = count_offset(context->visual->blue_mask);
/* disable dithering on 24 bits visuals */
if (context->depth >= 24)
context->attribs->render_mode = RM_MATCH;
}
/* check avaiability of MIT-SHM */
return context;
}
static Bool
bestContext(Display * dpy, int screen_number, RContext * context)
{
XVisualInfo *vinfo = NULL, rvinfo;
int best = -1, numvis, i;
long flags;
XSetWindowAttributes attr;
rvinfo.class = TrueColor;
rvinfo.screen = screen_number;
flags = VisualClassMask | VisualScreenMask;
vinfo = XGetVisualInfo(dpy, flags, &rvinfo, &numvis);
if (vinfo) { /* look for a TrueColor, 24-bit or more (pref 24) */
for (i = numvis - 1, best = -1; i >= 0; i--) {
if (vinfo[i].depth == 24)
best = i;
else if (vinfo[i].depth > 24 && best < 0)
best = i;
}
}
#if 0
if (best == -1) { /* look for a DirectColor, 24-bit or more (pref 24) */
rvinfo.class = DirectColor;
if (vinfo)
XFree((char *) vinfo);
vinfo = XGetVisualInfo(dpy, flags, &rvinfo, &numvis);
if (vinfo) {
for (i = 0, best = -1; i < numvis; i++) {
if (vinfo[i].depth == 24)
best = i;
else if (vinfo[i].depth > 24 && best < 0)
best = i;
}
}
}
#endif
if (best > -1) {
context->visual = vinfo[best].visual;
context->depth = vinfo[best].depth;
context->vclass = vinfo[best].class;
getColormap(context, screen_number);
attr.colormap = context->cmap;
attr.override_redirect = True;
attr.border_pixel = 0;
context->drawable =
XCreateWindow(dpy, RootWindow(dpy, screen_number),
1, 1, 1, 1, 0, context->depth,
CopyFromParent, context->visual,
CWBorderPixel | CWColormap | CWOverrideRedirect, &attr);
/* XSetWindowColormap(dpy, context->drawable, context->cmap); */
}
if (vinfo)
XFree((char *) vinfo);
if (best < 0)
return False;
else
return True;
}

578
wmglobe/src/myconvert.c Normal file
View file

@ -0,0 +1,578 @@
/* WMGlobe 0.5 - All the Earth on a WMaker Icon
* myconvert.c - an adaptation of wrlib for use in wmglobe
* initial source taken in WindowMaker-0.20.3/wrlib :
*/
/* convert.c - convert RImage to Pixmap
* Raster graphics library
*
* Copyright (c) 1997 Alfredo K. Kojima
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* #include <config.h>
*/
#include "wmglobe.h"
typedef struct RConversionTable {
unsigned short table[256];
unsigned short index;
struct RConversionTable *next;
} RConversionTable;
static RConversionTable *conversionTable = NULL;
static RConversionTable *pif[3];
static short *re, *ge, *be;
static short *nre, *nge, *nbe;
static RXImage *ximgok;
void initmyconvert()
{
pif[0] = (RConversionTable *) malloc(sizeof(RConversionTable));
pif[1] = (RConversionTable *) malloc(sizeof(RConversionTable));
pif[2] = (RConversionTable *) malloc(sizeof(RConversionTable));
re = (short *) malloc((DIAMETRE + 2) * sizeof(short));
ge = (short *) malloc((DIAMETRE + 2) * sizeof(short));
be = (short *) malloc((DIAMETRE + 2) * sizeof(short));
nre = (short *) malloc((DIAMETRE + 2) * sizeof(short));
nge = (short *) malloc((DIAMETRE + 2) * sizeof(short));
nbe = (short *) malloc((DIAMETRE + 2) * sizeof(short));
ximgok = NULL;
return;
}
static unsigned short *
computeTable(unsigned short mask, int hop)
{
RConversionTable *tmp = conversionTable;
int i;
tmp = pif[hop];
for (i = 0; i < 256; i++)
tmp->table[i] = (i * mask + 0x7f) / 0xff;
tmp->index = mask;
return tmp->table;
}
static RXImage *
image2TrueColor(RContext * ctx, RImage * image)
{
RXImage *ximg;
register int x, y, r, g, b;
unsigned char *red, *grn, *blu;
unsigned long pixel;
unsigned short rmask, gmask, bmask;
unsigned short roffs, goffs, boffs;
unsigned short *rtable, *gtable, *btable;
int ofs;
if (ximgok == NULL)
ximgok = RCreateXImage(ctx, ctx->depth, image->width, image->height);
ximg = ximgok;
if (!ximg) {
puts("err ");
return NULL;
}
red = image->data[0];
grn = image->data[1];
blu = image->data[2];
roffs = ctx->red_offset;
goffs = ctx->green_offset;
boffs = ctx->blue_offset;
rmask = ctx->visual->red_mask >> roffs;
gmask = ctx->visual->green_mask >> goffs;
bmask = ctx->visual->blue_mask >> boffs;
rtable = computeTable(rmask, 0);
gtable = computeTable(gmask, 1);
btable = computeTable(bmask, 2);
if (rtable == NULL || gtable == NULL || btable == NULL) {
RErrorCode = RERR_NOMEMORY;
RDestroyXImage(ctx, ximg);
return NULL;
}
if (ctx->attribs->render_mode == RM_MATCH) {
/* fake match */
#ifdef DEBUG
puts("true color match");
#endif
for (y = 0, ofs = 0; y < image->height; y++) {
for (x = 0; x < image->width; x++, ofs++) {
/* reduce pixel */
r = rtable[red[ofs]];
g = gtable[grn[ofs]];
b = btable[blu[ofs]];
pixel = (r << roffs) | (g << goffs) | (b << boffs);
XPutPixel(ximg->image, x, y, pixel);
}
}
} else {
/* dither */
short *rerr, *gerr, *berr;
short *nrerr, *ngerr, *nberr;
short *terr;
int rer, ger, ber;
const int dr = 0xff / rmask;
const int dg = 0xff / gmask;
const int db = 0xff / bmask;
#ifdef DEBUG
puts("true color dither");
#endif
rerr = re;
gerr = ge;
berr = be;
nrerr = nre;
ngerr = nge;
nberr = nbe;
if (!rerr || !gerr || !berr || !nrerr || !ngerr || !nberr) {
RErrorCode = RERR_NOMEMORY;
RDestroyXImage(ctx, ximg);
return NULL;
}
for (x = 0; x < image->width; x++) {
rerr[x] = red[x];
gerr[x] = grn[x];
berr[x] = blu[x];
}
rerr[x] = gerr[x] = berr[x] = 0;
/* convert and dither the image to XImage */
for (y = 0, ofs = 0; y < image->height; y++) {
if (y < image->height - 1) {
int x1;
for (x = 0, x1 = ofs + image->width; x < image->width; x++, x1++) {
nrerr[x] = red[x1];
ngerr[x] = grn[x1];
nberr[x] = blu[x1];
}
/* last column */
x1--;
nrerr[x] = red[x1];
ngerr[x] = grn[x1];
nberr[x] = blu[x1];
}
for (x = 0; x < image->width; x++) {
/* reduce pixel */
if (rerr[x] > 0xff)
rerr[x] = 0xff;
else if (rerr[x] < 0)
rerr[x] = 0;
if (gerr[x] > 0xff)
gerr[x] = 0xff;
else if (gerr[x] < 0)
gerr[x] = 0;
if (berr[x] > 0xff)
berr[x] = 0xff;
else if (berr[x] < 0)
berr[x] = 0;
r = rtable[rerr[x]];
g = gtable[gerr[x]];
b = btable[berr[x]];
pixel = (r << roffs) | (g << goffs) | (b << boffs);
XPutPixel(ximg->image, x, y, pixel);
/* calc error */
rer = rerr[x] - r * dr;
ger = gerr[x] - g * dg;
ber = berr[x] - b * db;
/* distribute error */
r = (rer * 3) / 8;
g = (ger * 3) / 8;
b = (ber * 3) / 8;
/* x+1, y */
rerr[x + 1] += r;
gerr[x + 1] += g;
berr[x + 1] += b;
/* x, y+1 */
nrerr[x] += r;
ngerr[x] += g;
nberr[x] += b;
/* x+1, y+1 */
nrerr[x + 1] += rer - 2 * r;
ngerr[x + 1] += ger - 2 * g;
nberr[x + 1] += ber - 2 * b;
}
ofs += image->width;
/* skip to next line */
terr = rerr;
rerr = nrerr;
nrerr = terr;
terr = gerr;
gerr = ngerr;
ngerr = terr;
terr = berr;
berr = nberr;
nberr = terr;
}
}
return ximg;
}
static RXImage *
image2PseudoColor(RContext * ctx, RImage * image)
{
RXImage *ximg;
register int x, y, r, g, b;
unsigned char *red, *grn, *blu;
unsigned long pixel;
const int cpc = ctx->attribs->colors_per_channel;
const unsigned short rmask = cpc - 1; /* different sizes could be used */
const unsigned short gmask = rmask; /* for r,g,b */
const unsigned short bmask = rmask;
unsigned short *rtable, *gtable, *btable;
const int cpccpc = cpc * cpc;
unsigned char *data;
int ofs;
/*register unsigned char maxrgb = 0xff; */
if (ximgok == NULL)
ximgok = RCreateXImage(ctx, ctx->depth, image->width, image->height);
ximg = ximgok;
if (!ximg) {
puts("err psc");
return NULL;
}
red = image->data[0];
grn = image->data[1];
blu = image->data[2];
data = ximg->image->data;
/* Tables are same at the moment because rmask==gmask==bmask. */
rtable = computeTable(rmask, 0);
gtable = computeTable(gmask, 1);
btable = computeTable(bmask, 2);
if (rtable == NULL || gtable == NULL || btable == NULL) {
RErrorCode = RERR_NOMEMORY;
RDestroyXImage(ctx, ximg);
return NULL;
}
if (ctx->attribs->render_mode == RM_MATCH) {
/* fake match */
#ifdef DEBUG
printf("pseudo color match with %d colors per channel\n", cpc);
#endif
for (y = 0, ofs = 0; y < image->height; y++) {
for (x = 0; x < image->width; x++, ofs++) {
/* reduce pixel */
r = rtable[red[ofs]];
g = gtable[grn[ofs]];
b = btable[blu[ofs]];
pixel = r * cpccpc + g * cpc + b;
/*data[ofs] = ctx->colors[pixel].pixel; */
XPutPixel(ximg->image, x, y, ctx->colors[pixel].pixel);
}
}
} else {
/* dither */
short *rerr, *gerr, *berr;
short *nrerr, *ngerr, *nberr;
short *terr;
int rer, ger, ber;
const int dr = 0xff / rmask;
const int dg = 0xff / gmask;
const int db = 0xff / bmask;
#ifdef DEBUG
printf("pseudo color dithering with %d colors per channel\n", cpc);
#endif
rerr = re;
gerr = ge;
berr = be;
nrerr = nre;
ngerr = nge;
nberr = nbe;
if (!rerr || !gerr || !berr || !nrerr || !ngerr || !nberr) {
RErrorCode = RERR_NOMEMORY;
RDestroyXImage(ctx, ximg);
return NULL;
}
for (x = 0; x < image->width; x++) {
rerr[x] = red[x];
gerr[x] = grn[x];
berr[x] = blu[x];
}
rerr[x] = gerr[x] = berr[x] = 0;
/* convert and dither the image to XImage */
for (y = 0, ofs = 0; y < image->height; y++) {
if (y < image->height - 1) {
int x1;
for (x = 0, x1 = ofs + image->width; x < image->width; x++, x1++) {
nrerr[x] = red[x1];
ngerr[x] = grn[x1];
nberr[x] = blu[x1];
}
/* last column */
x1--;
nrerr[x] = red[x1];
ngerr[x] = grn[x1];
nberr[x] = blu[x1];
}
for (x = 0; x < image->width; x++, ofs++) {
/* reduce pixel */
if (rerr[x] > 0xff)
rerr[x] = 0xff;
else if (rerr[x] < 0)
rerr[x] = 0;
if (gerr[x] > 0xff)
gerr[x] = 0xff;
else if (gerr[x] < 0)
gerr[x] = 0;
if (berr[x] > 0xff)
berr[x] = 0xff;
else if (berr[x] < 0)
berr[x] = 0;
r = rtable[rerr[x]];
g = gtable[gerr[x]];
b = btable[berr[x]];
pixel = r * cpccpc + g * cpc + b;
/*data[ofs] = ctx->colors[pixel].pixel; */
XPutPixel(ximg->image, x, y, ctx->colors[pixel].pixel);
/* calc error */
rer = rerr[x] - r * dr;
ger = gerr[x] - g * dg;
ber = berr[x] - b * db;
/* distribute error */
rerr[x + 1] += (rer * 7) / 16;
gerr[x + 1] += (ger * 7) / 16;
berr[x + 1] += (ber * 7) / 16;
nrerr[x] += (rer * 5) / 16;
ngerr[x] += (ger * 5) / 16;
nberr[x] += (ber * 5) / 16;
if (x > 0) {
nrerr[x - 1] += (rer * 3) / 16;
ngerr[x - 1] += (ger * 3) / 16;
nberr[x - 1] += (ber * 3) / 16;
}
nrerr[x + 1] += rer / 16;
ngerr[x + 1] += ger / 16;
nberr[x + 1] += ber / 16;
}
/* skip to next line */
terr = rerr;
rerr = nrerr;
nrerr = terr;
terr = gerr;
gerr = ngerr;
ngerr = terr;
terr = berr;
berr = nberr;
nberr = terr;
}
}
ximg->image->data = (char *) data;
return ximg;
}
static RXImage *
image2GrayScale(RContext * ctx, RImage * image)
{
RXImage *ximg;
register int x, y, g;
unsigned char *red, *grn, *blu;
const int cpc = ctx->attribs->colors_per_channel;
unsigned short gmask;
unsigned short *table;
unsigned char *data;
int ofs;
/*register unsigned char maxrgb = 0xff; */
if (ximgok == NULL)
ximgok = RCreateXImage(ctx, ctx->depth, image->width, image->height);
ximg = ximgok;
if (!ximg) {
puts("error!");
return NULL;
}
red = image->data[0];
grn = image->data[1];
blu = image->data[2];
data = ximg->image->data;
if (ctx->vclass == StaticGray)
gmask = (1 << ctx->depth) - 1; /* use all grays */
else
gmask = cpc * cpc * cpc - 1;
table = computeTable(gmask, 0);
if (table == NULL) {
RErrorCode = RERR_NOMEMORY;
RDestroyXImage(ctx, ximg);
return NULL;
}
if (ctx->attribs->render_mode == RM_MATCH) {
/* fake match */
#ifdef DEBUG
printf("grayscale match with %d colors per channel\n", cpc);
#endif
for (y = 0, ofs = 0; y < image->height; y++) {
for (x = 0; x < image->width; x++, ofs++) {
/* reduce pixel */
g = table[(red[ofs] * 30 + grn[ofs] * 59 + blu[ofs] * 11) / 100];
/*data[ofs] = ctx->colors[g].pixel; */
XPutPixel(ximg->image, x, y, ctx->colors[g].pixel);
}
}
} else {
/* dither */
short *gerr;
short *ngerr;
short *terr;
int ger;
const int dg = 0xff / gmask;
#ifdef DEBUG
printf("grayscale dither with %d colors per channel\n", cpc);
#endif
gerr = ge;
ngerr = nge;
if (!gerr || !ngerr) {
RErrorCode = RERR_NOMEMORY;
RDestroyXImage(ctx, ximg);
return NULL;
}
for (x = 0; x < image->width; x++) {
gerr[x] = (red[x] * 30 + grn[x] * 59 + blu[x] * 11) / 100;
}
gerr[x] = 0;
/* convert and dither the image to XImage */
for (y = 0, ofs = 0; y < image->height; y++) {
if (y < image->height - 1) {
int x1;
for (x = 0, x1 = ofs + image->width; x < image->width; x++, x1++) {
ngerr[x] = (red[x1] * 30 + grn[x1] * 59 + blu[x1] * 11) / 100;
}
/* last column */
x1--;
ngerr[x] = (red[x1] * 30 + grn[x1] * 59 + blu[x1] * 11) / 100;
}
for (x = 0; x < image->width; x++, ofs++) {
/* reduce pixel */
if (gerr[x] > 0xff)
gerr[x] = 0xff;
else if (gerr[x] < 0)
gerr[x] = 0;
g = table[gerr[x]];
/*data[ofs] = ctx->colors[g].pixel; */
XPutPixel(ximg->image, x, y, ctx->colors[g].pixel);
/* calc error */
ger = gerr[x] - g * dg;
/* distribute error */
g = (ger * 3) / 8;
/* x+1, y */
gerr[x + 1] += g;
/* x, y+1 */
ngerr[x] += g;
/* x+1, y+1 */
ngerr[x + 1] += ger - 2 * g;
}
/* skip to next line */
terr = gerr;
gerr = ngerr;
ngerr = terr;
}
}
ximg->image->data = (char *) data;
return ximg;
}
int myRConvertImage(RContext * context, RImage * image, Pixmap * pixmap)
{
RXImage *ximg = NULL;
assert(context != NULL);
assert(image != NULL);
assert(pixmap != NULL);
/* clear error message */
if (context->vclass == TrueColor)
ximg = image2TrueColor(context, image);
else if (context->vclass == PseudoColor || context->vclass == StaticColor)
ximg = image2PseudoColor(context, image);
else if (context->vclass == GrayScale || context->vclass == StaticGray)
ximg = image2GrayScale(context, image);
if (!ximg) {
#ifdef C_ALLOCA
alloca(0);
#endif
return False;
}
/*
* *pixmap = XCreatePixmap(context->dpy, context->drawable, image->width,
* image->height, context->depth);
*/
RPutXImage(context, *pixmap, context->copy_gc, ximg, 0, 0, 0, 0,
image->width, image->height);
/*
* RDestroyXImage(context, ximg);
*/
#ifdef C_ALLOCA
alloca(0);
#endif
return True;
}

703
wmglobe/src/rend.c Normal file
View file

@ -0,0 +1,703 @@
/* WMGlobe 0.5 - All the Earth on a WMaker Icon
* copyright (C) 1998,99 Jerome Dumonteil <jerome.dumonteil@capway.com>
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***************************************************************************/
/* this code is based on XGlobe :
renderer.cpp
*
*
* This file is part of XGlobe. See README for details.
*
* Copyright (C) 1998 Thorsten Scheuermann
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public Licenses as published by
* the Free Software Foundation.
*************************************************************************** */
#include "wmglobe.h"
static RColor mygetMapColorLinear
(double longitude, double latitude, double angle);
/*
* static RColor getMapColor(double longitude, double latitude, double angle);
*/
static void randomPosition();
void setViewPos(double lat, double lon);
static void myRPutPixel(int x, int y, RColor * color);
static void getquarter(RImage * image, int x, int y, MPO * m[4], int dx, int dy);
static void updateTime(int force);
static struct timeval timeaccel(struct timeval t);
/* ------------------------------------------------------------------------ */
struct timeval timeaccel(struct timeval t)
{
struct timeval at;
double rr;
t = diftimev(t, tini);
rr = floor((double) t.tv_sec * time_multi + (double) t.tv_usec * time_multi / 1000000.);
/*** something bad may appen if time_multi=max after 41 minutes (overflow) ***/
while (rr > (double) LONG_MAX)
rr -= (2.0 * (double) LONG_MAX + 1.0);
at.tv_sec = (int) rr;
at.tv_usec = (int) (t.tv_usec * time_multi) % 1000000;
return addtimev(at, tbase);
}
/* ------------------------------------------------------------------------ */
static void myRPutPixel(int x, int y, RColor * color)
{
int ofs;
unsigned char *sr, *sg, *sb;
ofs = y * DIAMETRE + x;
sr = small->data[0] + ofs;
sg = small->data[1] + ofs;
sb = small->data[2] + ofs;
*sr = color->red;
*sg = color->green;
*sb = color->blue;
return;
}
/* ------------------------------------------------------------------------ */
static void getquarter(RImage * image, int x, int y, MPO * m[4], int dx, int dy)
{
int xx;
register int ofs;
/*** hope this is faster than calculation with floats .... ****/
x %= image->width;
xx = x;
y %= image->height;
ofs = y * image->width + x;
m[0]->r = image->data[0][ofs];
m[0]->g = image->data[1][ofs];
m[0]->b = image->data[2][ofs];
xx++;
xx %= image->width;
ofs = y * image->width + xx;
m[1]->r = image->data[0][ofs];
m[1]->g = image->data[1][ofs];
m[1]->b = image->data[2][ofs];
y++;
y %= image->height;
ofs = y * image->width + x;
m[2]->r = image->data[0][ofs];
m[2]->g = image->data[1][ofs];
m[2]->b = image->data[2][ofs];
ofs = y * image->width + xx;
m[3]->r = image->data[0][ofs];
m[3]->g = image->data[1][ofs];
m[3]->b = image->data[2][ofs];
/*
* m[0]->r=((m[0]->r*(256-dx)*(256-dy))+
* (m[1]->r*dx*(256-dy))+
* (m[2]->r*(256-dx)*dy)+
* (m[3]->r*dx*dy))>>16;
* m[0]->g=((m[0]->g*(256-dx)*(256-dy))+
* (m[1]->g*dx*(256-dy))+
* (m[2]->g*(256-dx)*dy)+
* (m[3]->g*dx*dy))>>16;
* m[0]->b=((m[0]->b*(256-dx)*(256-dy))+
* (m[1]->b*dx*(256-dy))+
* (m[2]->b*(256-dx)*dy)+
* (m[3]->b*dx*dy))>>16;
*/
if ((ofs = m[1]->r - m[0]->r) != 0)
m[0]->r += (ofs * dx) >> 8;
if ((ofs = m[1]->g - m[0]->g) != 0)
m[0]->g += (ofs * dx) >> 8;
if ((ofs = m[1]->b - m[0]->b) != 0)
m[0]->b += (ofs * dx) >> 8;
if ((ofs = m[3]->r - m[2]->r) != 0)
m[2]->r += (ofs * dx) >> 8;
if ((ofs = m[3]->g - m[2]->g) != 0)
m[2]->g += (ofs * dx) >> 8;
if ((ofs = m[3]->b - m[2]->b) != 0)
m[2]->b += (ofs * dx) >> 8;
if ((ofs = m[2]->r - m[0]->r) != 0)
m[0]->r += (ofs * dy) >> 8;
if ((ofs = m[2]->g - m[0]->g) != 0)
m[0]->g += (ofs * dy) >> 8;
if ((ofs = m[2]->b - m[0]->b) != 0)
m[0]->b += (ofs * dy) >> 8;
return;
}
/* ------------------------------------------------------------------------ */
void calcDistance()
{
double tan_a;
tan_a = (zoom * DIAMETRE / 2.0) / proj_dist;
/*
* distance of camera to center of earth ( = coordinate origin)
*/
center_dist = radius / sin(atan(tan_a));
c_coef = center_dist * center_dist - radius * radius;
solution = FALSE;
return;
}
/* ------------------------------------------------------------------------ */
void renderFrame()
{
int py, px;
RColor teinte;
double dir_x, dir_y, dir_z; /* direction of cast ray */
double hit_x, hit_y, hit_z; /* hit position on earth surface */
double hit2_x, hit2_y, hit2_z; /* mirrored hit position on earth surface */
double sp_x, sp_y, sp_z; /* intersection point of globe and ray */
double a; /* coeff. of quardatic equation */
double radikand;
double wurzel;
double r; /* r' */
double s1, s2, s; /*distance between intersections and
camera position */
double longitude, latitude; /* coordinates of hit position */
double light_angle; /* cosine of angle between sunlight and
surface normal */
int startx, endx; /* the region to be painted */
int starty, endy;
double m11;
double m12;
double m13;
double m21;
double m22;
double m23;
double m31;
double m32;
double m33;
a = dir_x = dir_y = 0;
dir_z = -proj_dist;
#ifdef DEBUG
fprintf(stdout, "solution : %d\n", solution);
#endif
/*
* clear image
*/
if (solution == FALSE)
RClearImage(small, &noir);
/*
* rotation matrix
*/
m11 = cos(v_long);
m22 = cos(v_lat);
m23 = sin(v_lat);
m31 = -sin(v_long);
m12 = m23 * m31;
m13 = -m22 * m31;
m21 = 0.;
m32 = -m23 * m11;
m33 = m22 * m11;
/*
* calc. radius of projected sphere
*/
if (solution == FALSE) {
b_coef = 2 * center_dist * dir_z;
radius_proj = (int) sqrt(b_coef * b_coef / (4 * c_coef) - dir_z * dir_z) + 1;
}
/*-----------------------------------------------------------------------------------------*/
if (fun) {
starty = DIAMETRE / 2 - radius_proj - 3;
endy = DIAMETRE - starty - 1;
if ((double) starty < (double) (-funy))
starty = -funy;
if ((double) starty > (double) (DIAMETRE - 1 - funy))
starty = DIAMETRE - 1 - funy;
if ((double) endy < (double) (-funy))
endy = -funy;
if ((double) endy > (double) (DIAMETRE - 1 - funy))
endy = DIAMETRE - 1 - funy;
for (py = starty; py <= endy; py++) {
startx = DIAMETRE / 2 - 6 -
(int) sqrt(radius_proj * radius_proj -
(py - DIAMETRE / 2) *
(py - DIAMETRE / 2));
endx = DIAMETRE - startx - 1;
if ((double) startx < (double) (-funx))
startx = -funx;
if ((double) startx > (double) (DIAMETRE - 1 - funx))
startx = DIAMETRE - 1 - funx;
if ((double) endx < (double) (-funx))
endx = -funx;
if ((double) endx > (double) (DIAMETRE - 1 - funx))
endx = DIAMETRE - 1 - funx;
/*
* calculate offset into image data
*/
for (px = startx; px <= endx; px++) {
dir_x = (double) px - DIAMETRE / 2 + 0.5;
dir_y = -(double) py + DIAMETRE / 2 - 0.5;
a = dir_x * dir_x + dir_y * dir_y + dir_z * dir_z;
/*
* c constant, see above
*/
radikand = b_coef * b_coef - 4 * a * c_coef; /*what's under the sq.root when solving the
quadratic equation */
if (radikand >= 0.0) { /* solution exists <=> intersection */
wurzel = sqrt(radikand);
s1 = (-b_coef + wurzel) / (2. * a);
s2 = (-b_coef - wurzel) / (2. * a);
s = (s1 < s2) ? s1 : s2; /* smaller solution belongs to nearer
* intersection */
sp_x = s * dir_x; /* sp = camera pos + s*dir */
sp_y = s * dir_y;
sp_z = center_dist + s * dir_z;
hit_x = m11 * sp_x + m12 * sp_y + m13 * sp_z;
hit_y = m22 * sp_y + m23 * sp_z;
hit_z = m31 * sp_x + m32 * sp_y + m33 * sp_z;
hit2_x = -m11 * sp_x + m12 * sp_y + m13 * sp_z;
hit2_y = m22 * sp_y + m23 * sp_z;
hit2_z = -m31 * sp_x + m32 * sp_y + m33 * sp_z;
/*** hope hit_z wont get too close to zero *******/
if (ABS(hit_z) < 0.001) {
if (hit_x * hit_z > 0.)
longitude = PI / 2.;
else
longitude = -PI / 2.;
if (hit_z > 0.)
hit_z = 0.001;
else
hit_z = -0.001;
} else {
longitude = atan(hit_x / hit_z);
}
if (hit_z < 0.)
longitude += PI;
r = (double) sqrt(hit_x * hit_x + hit_z * hit_z);
latitude = atan(-hit_y / r);
light_angle =
(light_x * hit_x + light_y * hit_y + light_z * hit_z) / radius;
/*
* Set pixel in image
*/
teinte = mygetMapColorLinear(longitude, latitude, light_angle);
RPutPixel(small, px + funx, py + funy, &teinte);
}
} /*px */
} /*py */
}
/*-----------------------------------------------------------------------------------------*/
/*** not fun : ***/
else {
starty = DIAMETRE / 2 - radius_proj - 3;
starty = (starty < 0) ? 0 : starty;
endy = DIAMETRE - starty - 1;
/*
* py 0 to 63 max
*/
for (py = starty; py <= endy; py++) {
startx = DIAMETRE / 2 - 6 -
(int) sqrt(radius_proj * radius_proj -
(py - DIAMETRE / 2) *
(py - DIAMETRE / 2));
startx = (startx < 0) ? 0 : startx;
/*
* 0<= startx <=31
*/
for (px = startx; px < DIAMETRE / 2; px++) {
if (solution == FALSE) {
dir_x = (double) px - DIAMETRE / 2 + 0.5;
dir_y = -(double) py + DIAMETRE / 2 - 0.5;
a = dir_x * dir_x + dir_y * dir_y + dir_z * dir_z;
soluce[px][py][0] = b_coef * b_coef - 4 * a * c_coef;
/*what's under the sq.root when solving the
quadratic equation */
}
if (soluce[px][py][0] >= 0.0) { /* solution exists <=> intersection */
if (solution == FALSE) {
wurzel = sqrt(soluce[px][py][0]);
s1 = (-b_coef + wurzel) / (2. * a);
s2 = (-b_coef - wurzel) / (2. * a);
s = (s1 < s2) ? s1 : s2; /* smaller solution belongs to nearer
* intersection */
soluce[px][py][1] = s * dir_x; /* sp = camera pos + s*dir */
soluce[px][py][2] = s * dir_y;
soluce[px][py][3] = center_dist + s * dir_z;
}
sp_x = soluce[px][py][1];
sp_y = soluce[px][py][2];
sp_z = soluce[px][py][3];
hit_x = m11 * sp_x + m12 * sp_y + m13 * sp_z;
hit_y = m22 * sp_y + m23 * sp_z;
hit_z = m31 * sp_x + m32 * sp_y + m33 * sp_z;
hit2_x = -m11 * sp_x + m12 * sp_y + m13 * sp_z;
hit2_y = m22 * sp_y + m23 * sp_z;
hit2_z = -m31 * sp_x + m32 * sp_y + m33 * sp_z;
/*** hope hit_z wont get too close to zero *******/
#ifdef DEBUG
if (ABS(hit_z) < ABS(minhz)) {
minhz = hit_z;
fprintf(stdout, "should >>0 : hit_z %f\n", hit_z);
fprintf(stdout, " hit_x %f\n", hit_x);
fprintf(stdout, " ratio %f\n", hit_x / hit_z);
fprintf(stdout, " long %f\n", atan(hit_x / hit_z));
sleep(5);
}
#endif
if (ABS(hit_z) < 0.001) {
if (hit_x * hit_z > 0.)
longitude = PI / 2.;
else
longitude = -PI / 2.;
if (hit_z > 0.)
hit_z = 0.001;
else
hit_z = -0.001;
} else {
longitude = atan(hit_x / hit_z);
}
if (hit_z < 0.)
longitude += PI;
r = (double) sqrt(hit_x * hit_x + hit_z * hit_z);
latitude = atan(-hit_y / r);
light_angle =
(light_x * hit_x + light_y * hit_y + light_z * hit_z) / radius;
if (sens == 1) {
/*
* Set pixel in image
*/
teinte = mygetMapColorLinear(longitude, latitude, light_angle);
myRPutPixel(px, py, &teinte);
/*
* mirror the left half-circle of the globe: we need a new position
* and have to recalc. the light intensity
*/
light_angle =
(light_x * hit2_x + light_y * hit2_y + light_z * hit2_z) / radius;
teinte = mygetMapColorLinear(2 * v_long - longitude, latitude, light_angle);
myRPutPixel(DIAMETRE - px - 1, py, &teinte);
} else {
/* sens==-1 */
/*
* Set pixel in image
*/
teinte = mygetMapColorLinear(longitude, latitude, light_angle);
myRPutPixel(DIAMETRE - px - 1, DIAMETRE - py - 1, &teinte);
/*
* mirror the left half-circle of the globe: we need a new position
* and have to recalc. the light intensity
*/
light_angle =
(light_x * hit2_x + light_y * hit2_y + light_z * hit2_z) / radius;
teinte = mygetMapColorLinear(2 * v_long - longitude, latitude, light_angle);
myRPutPixel(px, DIAMETRE - py - 1, &teinte);
}
}
} /*px */
} /*py */
} /*else fun */
solution = TRUE;
return;
}
/*------------------------------------------------------------------------ */
static RColor
mygetMapColorLinear(double longitude, double latitude, double angle)
{
RColor point;
int x, y, xl, yl, dx, dy, ang;
if (longitude < 0.)
longitude += 2 * PI;
latitude += PI / 2;
longitude += PI;
if (longitude >= 2 * PI)
longitude -= 2 * PI;
if (angle > 0)
ang = (int) floor((1 - ((1 - angle) * dawn)) * 256);
else
ang = angle * 256;
xl = (int) (longitude * mratiox);
yl = (int) (latitude * mratioy);
x = xl >> 8;
y = yl >> 8;
dx = xl - (x << 8);
dy = yl - (y << 8);
if (use_nightmap) {
if (ang > 0) {
getquarter(map, x, y, md, dx, dy);
getquarter(mapnight, x, y, mn, dx, dy);
md[0]->r = ((mn[0]->r * (256 - ang) + md[0]->r * ang)) >> 8;
md[0]->g = ((mn[0]->g * (256 - ang) + md[0]->g * ang)) >> 8;
md[0]->b = ((mn[0]->b * (256 - ang) + md[0]->b * ang)) >> 8;
} else {
getquarter(mapnight, x, y, md, dx, dy);
}
} else {
getquarter(map, x, y, md, dx, dy);
if (ang > 0) {
md[0]->r = ((md[0]->r * aml + md[0]->r * ang / 256 * (256 - aml))) >> 8;
md[0]->g = ((md[0]->g * aml + md[0]->g * ang / 256 * (256 - aml))) >> 8;
md[0]->b = ((md[0]->b * aml + md[0]->b * ang / 256 * (256 - aml))) >> 8;
} else {
md[0]->r = (md[0]->r * aml) >> 8;
md[0]->g = (md[0]->g * aml) >> 8;
md[0]->b = (md[0]->b * aml) >> 8;
}
}
point.red = (unsigned char) md[0]->r;
point.green = (unsigned char) md[0]->g;
point.blue = (unsigned char) md[0]->b;
point.alpha = 255;
return point;
}
/* ------------------------------------------------------------------------ */
static void randomPosition()
{
addlat = ((rand() % 30001) / 30000.) * 180. - 90.;
addlong = ((rand() % 30001) / 30000.) * 360. - 180.;
return;
}
/* ------------------------------------------------------------------------ */
static void updateTime(int force)
{
/* calcul of sun position every minute */
if ((trend.tv_sec - tsunpos) >= 60 || force) {
tsunpos = trend.tv_sec;
GetSunPos(tsunpos, &sun_lat, &sun_long);
light_x = cos(sun_lat) * sin(sun_long);
light_y = sin(sun_lat);
light_z = cos(sun_lat) * cos(sun_long);
do_something = TRUE;
}
return;
}
/* ------------------------------------------------------------------------ */
void setViewPos(double lat, double lon)
{
double dif;
while (lat >= 360.)
lat -= 360.;
while (lat <= -360.)
lat += 360.;
while (addlat >= 360.)
addlat -= 360.;
while (addlat <= -360.)
addlat += 360.;
if (lat >= 90.) {
dif = lat;
lat = 180. - lat;
addlat += (lat - dif);
dlat *= -1;
if (!fun) {
lon += 180.;
addlong += 180.;
}
sens *= -1;
}
if (lat <= -90.) {
dif = lat;
lat = -180. - lat;
addlat += (lat - dif);
dlat *= -1;
if (!fun) {
lon += 180.;
addlong += 180.;
}
sens *= -1;
}
if (lat >= 90.) {
dif = lat;
lat = 180. - lat;
addlat += (lat - dif);
dlat *= -1;
if (!fun) {
lon += 180.;
addlong += 180.;
}
sens *= -1;
}
if (lat <= -90.) {
dif = lat;
lat = -180. - lat;
addlat += (lat - dif);
dlat *= -1;
if (!fun) {
lon += 180.;
addlong += 180.;
}
sens *= -1;
}
while (lon >= 180.) {
lon -= 360.;
addlong -= 360.;
}
while (lon <= -180.) {
lon += 360.;
addlong += 360.;
}
v_lat = lat * PI / 180.;
v_long = lon * PI / 180.;
dv_lat = lat;
dv_long = lon;
return;
}
/* ------------------------------------------------------------------------ */
void recalc(int calme)
{
double coeff, va, vo;
struct timeval tv, tnow;
tnow = getimev();
trend = timeaccel(tnow);
tv = diftimev(tnow, tlast);
if (firstTime) {
firstTime = FALSE;
updateTime(TRUE);
} else {
coeff = (double) tv.tv_sec + tv.tv_usec / 1000000.;
if (!calme) {
/** while !clic button rotate earth **/
addlat += dlat * coeff;
addlong += dlong * coeff;
}
}
if (addlong != old_dvlong || addlat != old_dvlat || p_type == PTRANDOM) {
old_dvlong = addlong;
old_dvlat = addlat;
do_something = TRUE;
}
if (calme && p_type == PTSUNREL) {
va = sun_lat * 180. / PI;
vo = sun_long * 180. / PI;
updateTime(TRUE);
addlat -= sun_lat * 180. / PI - va;
addlong -= sun_long * 180. / PI - vo;
} else {
updateTime(FALSE);
}
if (do_something) {
switch (p_type) {
case PTSUNREL:
setViewPos(sun_lat * 180. / PI + addlat,
sun_long * 180. / PI + addlong);
break;
case PTFIXED:
setViewPos(addlat, addlong);
break;
case PTRANDOM:
if (stoprand == FALSE)
randomPosition();
else
stoprand--;
setViewPos(addlat, addlong);
break;
default:
break;
}
#ifdef DEBUG
fprintf(stdout, "%s render\n", ctime(&trend.tv_sec));
#endif
renderFrame();
}
tlast = tnow;
tnext = addtimev(tnow, tdelay);
return;
}
/* ------------------------------------------------------------------------ */

73
wmglobe/src/scrdiv.xpm Normal file
View file

@ -0,0 +1,73 @@
/* XPM */
static char * scrdiv_xpm[] = {
"64 64 6 1",
" c None",
". c #000000",
"+ c #CCCC6E",
"@ c #FFFFFF",
"# c #CCCCCC",
"$ c #F7F3FF",
" ",
"............................................................ ",
"....................................++...................... ",
"...................................+..+..................... ",
"...................................+..+..................... ",
"....................................++...................... ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
"............................................................ ",
" ",
"@@@@@@@@@@@@@@@@@@@#@@@@@@@$@@@$@@@@@@@#@@@@@@@@@@@@@@@@@@@# ",
"@#######.####.#####.@#####.####.#######.@##################. ",
"@######..###..#####.@#####..###..######.@##################. ",
"@#####...##...#####.@#####...##...#####.@#####.......######. ",
"@####....#....#####.@#####....#....####.@#####.......######. ",
"@#####...##...#####.@#####...##...#####.@#####.......######. ",
"@######..###..#####.@#####..###..######.@##################. ",
"@#######.####.#####.@#####.####.#######.@##################. ",
"#...................#...................#................... ",
" ",
"...................#...................#...................# ",
".#######.####.#####@.#####.####.#######@.##################@ ",
".######..###..#####@.#####..###..######@.##################@ ",
".#####...##...#####@.#####...##...#####@.#####.......######@ ",
".####....#....#####@.#####....#....####@.#####.......######@ ",
".#####...##...#####@.#####...##...#####@.#####.......######@ ",
".######..###..#####@.#####..###..######@.##################@ ",
".#######.####.#####@.#####.####.#######@.##################@ ",
"#@@@@@@@@@@@@@@@@@@@#@@@@@@@@@@@@@@@@@@@#@@@@@@@@@@@@@@@@@@@ ",
" ",
".............................................................# ",
".@@@@@@@@@@@@@@@@@@@#@@@@@@@$@@@$@@@@@@@#@@@@@@@@@@@@@@@@@@@## ",
".@#######.####.#####.@#####.####.#######.@##################.# ",
".@######..###..#####.@#####..###..######.@##################.# ",
".@#####...##...#####.@#####...##...#####.@#####.......######.# ",
".@####....#....#####.@#####....#....####.@#####.......######.# ",
".@#####...##...#####.@#####...##...#####.@#####.......######.# ",
".@######..###..#####.@#####..###..######.@##################.# ",
".@#######.####.#####.@#####.####.#######.@##################.# ",
".#...................#...................#...................# ",
"############################################################## ",
" ",
" ",
" ",
" ",
" "};

73
wmglobe/src/scrpos.xpm Normal file
View file

@ -0,0 +1,73 @@
/* XPM */
static char * scrpos_xpm[] = {
"64 64 6 1",
" c None",
". c #000000",
"+ c #CCCC6E",
"@ c #FFFFFF",
"# c #CCCCCC",
"$ c #F7F3FF",
" ",
" ",
" ",
" .. ... ...... ",
" .. ... ...... ",
" .. .. .. .. ",
" .. .. .. .. ",
" .. .. .. .. ",
" .. ....... .. ",
" ..... .. .. .. ",
" ..... .. .. .. ",
" ",
" ............................................................ ",
" ....................................++...................... ",
" ...................................+..+..................... ",
" ...................................+..+..................... ",
" ....................................++...................... ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ",
" ",
" .. ... .. .. .... ",
" .. .. .. ... .. .. .. ",
" .. .. .. ... .. .. . ",
" .. .. .. .. . .. .. ",
" .. .. .. .. . .. .. ... ",
" .. .. .. .. ... .. .. ",
" ..... .. .. .. ... .. .. ",
" ..... ... .. .. ... . ",
" ",
" ............................................................ ",
" ....................................++...................... ",
" ...................................+..+..................... ",
" ...................................+..+..................... ",
" ....................................++...................... ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ",
" ",
" ",
" @@@@@@@@@@@@@@@@@@@#@@@@@@@$@@@$@@@@@@@#@@@@@@@@@@@@@@@@@@@# ",
" @#######.####.#####.@#####.####.#######.@##################. ",
" @######..###..#####.@#####..###..######.@##################. ",
" @#####...##...#####.@#####...##...#####.@#####.......######. ",
" @####....#....#####.@#####....#....####.@#####.......######. ",
" @#####...##...#####.@#####...##...#####.@#####.......######. ",
" @######..###..#####.@#####..###..######.@##################. ",
" @#######.####.#####.@#####.####.#######.@##################. ",
" #...................#...................#................... ",
" ",
" ",
" "};

72
wmglobe/src/scrtime.xpm Normal file
View file

@ -0,0 +1,72 @@
/* XPM */
static char * scrtime_xpm[] = {
"64 64 5 1",
" c None",
". c #000000",
"+ c #FFFFFF",
"@ c #CCCCCC",
"# c #F7F3FF",
" ",
" ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ",
" ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ",
" ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ",
" ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ............................................................ ",
" ",
" ",
" ",
" ",
" +++++++++++++++++++@+++++++#+++#+++++++@+++++++++++++++++++@ ",
" +@@@@@@@.@@@@.@@@@@.+@@@@@.@@@@.@@@@@@@.+@@@@@@@@@@@@@@@@@@. ",
" +@@@@@@..@@@..@@@@@.+@@@@@..@@@..@@@@@@.+@@@@@@@@@@@@@@@@@@. ",
" +@@@@@...@@...@@@@@.+@@@@@...@@...@@@@@.+@@@@@.......@@@@@@. ",
" +@@@@....@....@@@@@.+@@@@@....@....@@@@.+@@@@@.......@@@@@@. ",
" +@@@@@...@@...@@@@@.+@@@@@...@@...@@@@@.+@@@@@.......@@@@@@. ",
" +@@@@@@..@@@..@@@@@.+@@@@@..@@@..@@@@@@.+@@@@@@@@@@@@@@@@@@. ",
" +@@@@@@@.@@@@.@@@@@.+@@@@@.@@@@.@@@@@@@.+@@@@@@@@@@@@@@@@@@. ",
" @...................@...................@................... ",
" ",
" ",
" "};

278
wmglobe/src/sunpos.c Normal file
View file

@ -0,0 +1,278 @@
/* WMGlobe 0.5 - All the Earth on a WMaker Icon
* copyright (C) 1998,99 Jerome Dumonteil <jerome.dumonteil@capway.com>
* sunpos.c is taken from Xearth :
*/
/*
* sunpos.c
* kirk johnson
* july 1993
*
* code for calculating the position on the earth's surface for which
* the sun is directly overhead (adapted from _practical astronomy
* with your calculator, third edition_, peter duffett-smith,
* cambridge university press, 1988.)
*
*
* Copyright (C) 1989, 1990, 1993, 1994, 1995 Kirk Lauritz Johnson
*
* Parts of the source code (as marked) are:
* Copyright (C) 1989, 1990, 1991 by Jim Frost
* Copyright (C) 1992 by Jamie Zawinski <jwz@lucid.com>
*
* Permission to use, copy, modify and freely distribute xearth for
* non-commercial and not-for-profit purposes is hereby granted
* without fee, provided that both the above copyright notice and this
* permission notice appear in all copies and in supporting
* documentation.
*
* Unisys Corporation holds worldwide patent rights on the Lempel Zev
* Welch (LZW) compression technique employed in the CompuServe GIF
* image file format as well as in other formats. Unisys has made it
* clear, however, that it does not require licensing or fees to be
* paid for freely distributed, non-commercial applications (such as
* xearth) that employ LZW/GIF technology. Those wishing further
* information about licensing the LZW patent should contact Unisys
* directly at (lzw_info@unisys.com) or by writing to
*
* Unisys Corporation
* Welch Licensing Department
* M/S-C1SW19
* P.O. Box 500
* Blue Bell, PA 19424
*
* The author makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT
* OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*************************************************************************/
#include <math.h>
#include <time.h>
#ifndef PI
#define PI 3.141592653
#endif
#define TWOPI (2*PI)
/*
* the epoch upon which these astronomical calculations are based is
* 1990 january 0.0, 631065600 seconds since the beginning of the
* "unix epoch" (00:00:00 GMT, Jan. 1, 1970)
*
* given a number of seconds since the start of the unix epoch,
* DaysSinceEpoch() computes the number of days since the start of the
* astronomical epoch (1990 january 0.0)
*/
#define EpochStart (631065600)
#define DaysSinceEpoch(secs) (((secs)-EpochStart)*(1.0/(24*3600)))
/*
* assuming the apparent orbit of the sun about the earth is circular,
* the rate at which the orbit progresses is given by RadsPerDay --
* TWOPI radians per orbit divided by 365.242191 days per year:
*/
#define RadsPerDay (TWOPI/365.242191)
/*
* details of sun's apparent orbit at epoch 1990.0 (after
* duffett-smith, table 6, section 46)
*
* Epsilon_g (ecliptic longitude at epoch 1990.0) 279.403303 degrees
* OmegaBar_g (ecliptic longitude of perigee) 282.768422 degrees
* Eccentricity (eccentricity of orbit) 0.016713
*/
#define Epsilon_g (279.403303*(TWOPI/360))
#define OmegaBar_g (282.768422*(TWOPI/360))
#define Eccentricity (0.016713)
/*
* MeanObliquity gives the mean obliquity of the earth's axis at epoch
* 1990.0 (computed as 23.440592 degrees according to the method given
* in duffett-smith, section 27)
*/
#define MeanObliquity (23.440592*(TWOPI/360))
/*
* solve Kepler's equation via Newton's method
* (after duffett-smith, section 47)
*/
static double solve_keplers_equation(double M)
{
double E;
double delta;
E = M;
while (1) {
delta = E - Eccentricity * sin(E) - M;
if (fabs(delta) <= 1e-10)
break;
E -= delta / (1 - Eccentricity * cos(E));
}
return E;
}
/*
* compute ecliptic longitude of sun (in radians)
* (after duffett-smith, section 47)
*/
static double sun_ecliptic_longitude(time_t ssue)
/* seconds since unix epoch */
{
double D, N;
double M_sun, E;
double v;
D = DaysSinceEpoch(ssue);
N = RadsPerDay * D;
N = fmod(N, TWOPI);
if (N < 0)
N += TWOPI;
M_sun = N + Epsilon_g - OmegaBar_g;
if (M_sun < 0)
M_sun += TWOPI;
E = solve_keplers_equation(M_sun);
v = 2 * atan(sqrt((1 + Eccentricity) / (1 - Eccentricity)) * tan(E / 2));
return (v + OmegaBar_g);
}
/*
* convert from ecliptic to equatorial coordinates
* (after duffett-smith, section 27)
*/
static void ecliptic_to_equatorial(double lambda, double beta, double *alpha, double *delta)
/*
* double lambda; ecliptic longitude
* double beta; ecliptic latitude
* double *alpha; (return) right ascension
* double *delta; (return) declination
*/
{
double sin_e, cos_e;
sin_e = sin(MeanObliquity);
cos_e = cos(MeanObliquity);
*alpha = atan2(sin(lambda) * cos_e - tan(beta) * sin_e, cos(lambda));
*delta = asin(sin(beta) * cos_e + cos(beta) * sin_e * sin(lambda));
}
/*
* computing julian dates (assuming gregorian calendar, thus this is
* only valid for dates of 1582 oct 15 or later)
* (after duffett-smith, section 4)
*/
static double julian_date(int y, int m, int d)
/*
* int y; year (e.g. 19xx)
* int m; month (jan=1, feb=2, ...)
* int d; day of month
*/
{
int A, B, C, D;
double JD;
/* lazy test to ensure gregorian calendar */
/*
* ASSERT(y >= 1583);
*/
if ((m == 1) || (m == 2)) {
y -= 1;
m += 12;
}
A = y / 100;
B = 2 - A + (A / 4);
C = (int) (365.25 * y);
D = (int) (30.6001 * (m + 1));
JD = B + C + D + d + 1720994.5;
return JD;
}
/*
* compute greenwich mean sidereal time (GST) corresponding to a given
* number of seconds since the unix epoch
* (after duffett-smith, section 12)
*/
static double GST(time_t ssue)
/*time_t ssue; seconds since unix epoch */
{
double JD;
double T, T0;
double UT;
struct tm *tm;
tm = gmtime(&ssue);
JD = julian_date(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
T = (JD - 2451545) / 36525;
T0 = ((T + 2.5862e-5) * T + 2400.051336) * T + 6.697374558;
T0 = fmod(T0, 24.0);
if (T0 < 0)
T0 += 24;
UT = tm->tm_hour + (tm->tm_min + tm->tm_sec / 60.0) / 60.0;
T0 += UT * 1.002737909;
T0 = fmod(T0, 24.0);
if (T0 < 0)
T0 += 24;
return T0;
}
/*
* given a particular time (expressed in seconds since the unix
* epoch), compute position on the earth (lat, lon) such that sun is
* directly overhead.
*/
void GetSunPos(time_t ssue, double *lat, double *lon)
/* time_t ssue; seconds since unix epoch */
/* double *lat; (return) latitude */
/* double *lon; (return) longitude */
{
double lambda;
double alpha, delta;
double tmp;
lambda = sun_ecliptic_longitude(ssue);
ecliptic_to_equatorial(lambda, 0.0, &alpha, &delta);
tmp = alpha - (TWOPI / 24) * GST(ssue);
if (tmp < -PI) {
do
tmp += TWOPI;
while (tmp < -PI);
} else if (tmp > PI) {
do
tmp -= TWOPI;
while (tmp < -PI);
}
*lon = tmp;
*lat = delta;
}

387
wmglobe/src/wmglobe.c Normal file
View file

@ -0,0 +1,387 @@
/* WMGlobe 0.5 - All the Earth on a WMaker Icon
* copyright (C) 1998,99 Jerome Dumonteil <jerome.dumonteil@capway.com>
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***************************************************************************/
/*
* I used many functions of wmgeneral.c ("openXwindow")
* for the main function of wmglobe.c
* wmgeneral.c was taken from wmaker applet wmtune-1.0 :
* Author: Martijn Pieterse (pieterse@xs4all.nl)
*
* wmglobe.c uses functions of : Xglobe, Xearth, wmgeneral, wmaker/wrlib
***************************************************************************/
#include "wmglobe.h"
#include "cadre0.xbm"
#include "cadre1.xbm"
#include "cadre2.xbm"
#ifdef DEFMAPOK
#include "defmap.xpm"
#include "defnimap.xpm"
#endif
/***************************************************************************/
int main(int argc, char *argv[])
{
unsigned int borderwidth = 1;
XClassHint classHint;
char *wname = argv[0];
XTextProperty name;
XGCValues gcv;
unsigned long gcm;
XWindowAttributes attributes;
XColor color;
RContext *ctx;
XSizeHints mysizehints;
XWMHints mywmhints;
Pixel back_pix, fore_pix;
char Geometry[256];
char *rond_bits;
int dummy = 0;
int ok, redoaction, wait_release, move_lat_flag;
int xx, yy;
/** initialisation *********************/
xx = 0;
yy = 0;
ok = FALSE;
move_lat_flag = FALSE;
redoaction = 0;
wait_release = 0;
setlocale(LC_TIME, "");
#ifdef DEBUG
fprintf(stdout, "%s\n", setlocale(LC_TIME, ""));
#endif
set_defaults();
cmdline(argc, argv);
switch (typecadre) {
case 1:
rond_bits = cadre1_bits;
break;
case 2:
rond_bits = cadre2_bits;
break;
default:
rond_bits = cadre0_bits;
}
if (p_type == PTRANDOM) {
dlat = 0;
dlong = 0;
}
initmyconvert();
tdelay.tv_sec = (int) floor(delay);
tdelay.tv_usec = (int) ((delay - tdelay.tv_sec) * 1000000);
aml = (int) floor(ambient_light * 256);
/****************************************************************************/
if (!(dpy = XOpenDisplay(dpy_name))) {
fprintf(stderr, "%s: can't open display \"%s\"\n",
wname, XDisplayName(dpy_name));
exit(1);
}
ctx = myRCreateContext(dpy, DefaultScreen(dpy), NULL);
if (ctx->attribs->use_shared_memory) {
#ifdef DEBUG
fprintf(stdout, "enleve les flags use_shared_memory\n");
#endif
ctx->attribs->flags ^= RC_UseSharedMemory;
ctx->attribs->use_shared_memory = FALSE;
ctx->flags.use_shared_pixmap = 0;
}
#ifdef DEBUG
fprintf(stdout, "depth %d\n", ctx->depth);
fflush(stdout);
#endif
/*
* loading maps .............
*
*/
if (dayfile != NULL) {
map = RLoadImage(ctx, dayfile, 0);
if (!map) {
fprintf(stdout, "pb map ! file not found ?\n");
exit(1);
}
} else {
#ifdef DEFMAPOK
map = RGetImageFromXPMData(ctx, defmap_xpm);
if (!map) {
fprintf(stdout, "pb def map ! file not found ?\n");
exit(1);
}
nightfile = NULL;
use_nightmap = TRUE;
}
#else
fprintf(stdout, "need a map !\n");
exit(1);
}
#endif
if (use_nightmap) {
if (nightfile != NULL) {
mapnight = RLoadImage(ctx, nightfile, 0);
if (!mapnight) {
fprintf(stdout, "pb map night! file not found ?\n");
exit(1);
}
} else {
#ifdef DEFMAPOK
mapnight = RGetImageFromXPMData(ctx, defnimap_xpm);
if (!mapnight) {
fprintf(stdout, "pb def map night ! file not found ?\n");
exit(1);
}
}
#else
/* not very useful... */
use_nightmap = FALSE;
}
#endif
}
use_nmap_ini = use_nightmap;
if (!oknimap)
use_nightmap = FALSE;
/* some other init ..................................... */
ratiox = (double) map->width / (2 * PI);
ratioy = (double) map->height / PI;
mratiox = (int) floor(ratiox * 256);
mratioy = (int) floor(ratioy * 256);
loadxpm(ctx->drawable);
small = RCreateImage(DIAMETRE, DIAMETRE, 1);
calcDistance();
/*...................................................... */
/*
* first rendering of the earth
*/
recalc(0);
do_something = FALSE;
/*************************************************************************
* well, here the problems begin : this code is a merge from wmgeneral and
* some stuff of wmaker, should be rewritten ...
************************************************************************/
/* wmg */
XGetWindowAttributes(dpy, ctx->drawable, &attributes);
if (!RConvertImage(ctx, small, &pix)) {
fprintf(stdout, "error small->&pix\n");
puts(RMessageForError(RErrorCode));
exit(1);
}
wmg.pixmap = pix;
wmg.mask = pix;
mysizehints.flags = USSize | USPosition;
mysizehints.x = 0;
mysizehints.y = 0;
color.pixel = 0;
if (!XParseColor(dpy, attributes.colormap, "white", &color)) {
fprintf(stdout, "wmglobe: can't parse white\n");
} else if (!XAllocColor(dpy, attributes.colormap, &color)) {
fprintf(stdout, "wmglobe: can't allocate white\n");
}
back_pix = color.pixel;
XGetWindowAttributes(dpy, ctx->drawable, &attributes);
color.pixel = 0;
if (!XParseColor(dpy, attributes.colormap, "black", &color)) {
fprintf(stdout, "wmglobe: can't parse black\n");
} else if (!XAllocColor(dpy, attributes.colormap, &color)) {
fprintf(stdout, "wmglobe: can't allocate black\n");
}
fore_pix = color.pixel;
XWMGeometry(dpy, ctx->screen_number, Geometry, NULL, borderwidth, &mysizehints,
&mysizehints.x, &mysizehints.y, &mysizehints.width, &mysizehints.height, &dummy);
mysizehints.width = DIAMETRE;
mysizehints.height = DIAMETRE;
win = XCreateSimpleWindow(dpy, ctx->drawable, mysizehints.x, mysizehints.y,
mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
iconwin = XCreateSimpleWindow(dpy, win, mysizehints.x, mysizehints.y,
mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
/* Activate hints */
XSetWMNormalHints(dpy, win, &mysizehints);
classHint.res_name = wname;
classHint.res_class = wname;
XSetClassHint(dpy, win, &classHint);
XSelectInput(dpy, win, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
XSelectInput(dpy, iconwin, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
if (XStringListToTextProperty(&wname, 1, &name) == 0) {
fprintf(stdout, "%s: can't allocate window name\n", wname);
exit(1);
}
XSetWMName(dpy, win, &name);
/* Create GC for drawing */
gcm = GCForeground | GCBackground | GCGraphicsExposures;
gcv.foreground = fore_pix;
gcv.background = back_pix;
gcv.graphics_exposures = 0;
NormalGC = XCreateGC(dpy, ctx->drawable, gcm, &gcv);
/* ONLYSHAPE ON */
if (onlyshape) {
pixmask = XCreateBitmapFromData(dpy, win, rond_bits, DIAMETRE, DIAMETRE);
XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
XShapeCombineMask(dpy, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
}
/* ONLYSHAPE OFF */
mywmhints.initial_state = option_iw;
mywmhints.icon_window = iconwin;
mywmhints.icon_x = mysizehints.x;
mywmhints.icon_y = mysizehints.y;
mywmhints.window_group = win;
mywmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
XSetWMHints(dpy, win, &mywmhints);
XSetCommand(dpy, win, argv, argc);
XMapWindow(dpy, win);
/****************************************************************************/
XCopyArea(dpy, wmg.pixmap, win, NormalGC, 0, 0, DIAMETRE, DIAMETRE, 0, 0);
RedrawWindowXYWH(0, 0, DIAMETRE, DIAMETRE);
/*
* ================= MAIN LOOP ==================
*/
while (1) {
while (XPending(dpy)) {
XNextEvent(dpy, &Event);
switch (Event.type) {
case Expose:
RedrawWindowXYWH(0, 0, DIAMETRE, DIAMETRE);
break;
case DestroyNotify:
XCloseDisplay(dpy);
exit(0);
break;
case ButtonPress:
/*
* earth rotate when clic left (1) , zooming when middle (2)
* change screen to longitude / latitude when (3)
*/
switch (Event.xbutton.button) {
case 1:
#ifdef MOUSE_LAT_NO_SHIFT
move_lat_flag = TRUE;
#else
if (Event.xbutton.state & ShiftMask)
move_lat_flag = TRUE;
else
move_lat_flag = FALSE;
#endif
redoaction = 1;
wait_release = 1;
break;
case 2:
if (Event.xbutton.state & ShiftMask)
redoaction = 2;
else
redoaction = 3;
wait_release = 1;
break;
case 3:
wait_release = 0;
redoaction = 0;
screen_back();
ok = TRUE;
break;
default:
break;
}
break;
case ButtonRelease:
wait_release = 0;
redoaction = 0;
break;
default:
break;
}
}
if (wait_release) {
usleep(2 * VAL_USLEEP_SHORT);
if (redoaction == 1)
rotation_terre(Event.xbutton.x, Event.xbutton.y, move_lat_flag);
else
zooming(Event.xbutton.state & ShiftMask);
ok = TRUE;
}
if (diftimev(tnext, getimev()).tv_sec < 0 || ok) {
ok = FALSE;
recalc(redoaction == 1);
if (do_something) {
if (!myRConvertImage(ctx, small, &pix)) {
fprintf(stdout, "plante !?\n");
fprintf(stdout, RMessageForError(RErrorCode));
exit(1);
}
wmg.pixmap = pix;
wmg.mask = pix;
RedrawWindowXYWH(0, 0, DIAMETRE, DIAMETRE);
#ifdef DEBUG
fprintf(stdout, "draw\n");
#endif
do_something = FALSE;
}
}
usleep(VAL_USLEEP);
}
/*
* Still wonder about freeing some memory for X
*/
return 0;
}

197
wmglobe/src/wmglobe.h Normal file
View file

@ -0,0 +1,197 @@
/* WMGlobe 0.5 - All the Earth on a WMaker Icon
* copyright (C) 1998,99 Jerome Dumonteil <jerome.dumonteil@capway.com>
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***************************************************************************/
/* it uses some functions of : Xglobe, Xearth, wmgeneral, wmaker/wrlib
***************************************************************************/
#ifndef WMG_HEADER_H
#define WMG_HEADER_H
/* customization : see wmgoption.h */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <math.h>
#include <limits.h>
#include <ctype.h> /*toupper */
#include <stdarg.h>
#include <time.h>
#include <sys/timeb.h>
#include <sys/time.h>
#include <sys/types.h>
#include <X11/Xlib.h>
#include <X11/xpm.h>
#include <X11/Xutil.h>
#include <X11/extensions/shape.h>
#include <assert.h>
#include <X11/Xatom.h>
#include <locale.h>
#include "wraster.h"
#include "wmgoption.h"
#define FALSE 0
#define TRUE 1
#define MAX(x, y) ((x) < (y) ? (y) : (x))
#define MIN(x, y) ((x) > (y) ? (y) : (x))
#define ABS(a) ((a) < 0 ? -(a) : (a))
#define PTFIXED 1
#define PTSUNREL 2
#define PTRANDOM 3
#ifndef PI
#define PI 3.141592653
#endif
/*
* wmglobe
* variables globales
*/
/************/
/* Typedefs */
/************/
#define MAX_MOUSE_REGION (8)
typedef struct {
int enable;
int top;
int bottom;
int left;
int right;
} MOUSE_REGION;
MOUSE_REGION mouse_region[MAX_MOUSE_REGION];
typedef struct MPO {
int r, g, b;
} MPO;
MPO *md[4], *mn[4];
double soluce[DIAMETRE / 2][DIAMETRE][4];
int solution;
/************/
typedef struct {
Pixmap pixmap;
Pixmap mask;
XpmAttributes attributes;
} XpmIcon;
/************/
Display *dpy;
char *dayfile, *nightfile, *dpy_name;
Pixmap pix, pixmask;
XEvent Event;
RImage *map, *small, *mapnight;
XpmIcon screenpos, scrdate, scrdiv, numpix, txtpix, wmg;
Window iconwin, win;
int onlyshape, option_iw;
GC NormalGC;
/********* rendering********/
double delay, time_multi;
/*
* struct timeval delta_tim, last_tim, next_tim, render_tim, base_tim,
* vec_tim;
*
* time_t beg_time, ini_time,t1901;
*/
struct timeval tlast, tnext, trend, tdelay, tini, tbase;
time_t tsunpos;
int sens, fun, funx, funy, oknimap, mratiox, mratioy, gotoscr;
int typecadre, p_type, use_nightmap, use_nmap_ini, firstTime, stoprand,
do_something, iop;
double v_lat, v_long, old_dvlat, old_dvlong, dv_lat, dv_long;
double dlat, dlong, addlat, addlong, ratiox, ratioy, dawn;
double sun_lat;
double sun_long;
double fov;
double radius;
double proj_dist; /* distance to projection plane */
double center_dist; /* distance to center of earth */
double ambient_light; /* how dark is the dark side? */
double light_x, light_y, light_z; /* vector of sunlight with lengt 1 */
double c_coef, b_coef;
double zoom;
int radius_proj, aml; /* radius of sphere on screen */
RColor noir;
#ifdef DEBUG
double minhz;
#endif
/****************************************************************/
/* Function Prototypes */
/****************************************************************/
int main(int argc, char *argv[]);
/****************************************************************/
void AddMouseRegion(int index, int left, int top, int right, int bottom);
int CheckMouseRegion(int x, int y);
void RedrawWindowXYWH(int x, int y, int w, int h);
void set_defaults();
void loadxpm(Window drawable);
void cmdline(int argc, char *argv[]);
void screen_back();
void rotation_terre(int x, int y, int lat_flag);
void zooming(int facto);
struct timeval diftimev(struct timeval t1, struct timeval t2);
struct timeval addtimev(struct timeval t1, struct timeval t2);
struct timeval getimev();
/***************************************************************/
void setZoom(double z);
void calcDistance();
void renderFrame();
void initmyconvert();
int myRConvertImage(RContext * context, RImage * image, Pixmap * pixmap);
RContext *myRCreateContext
(Display * dpy, int screen_number, RContextAttributes * attribs);
void setTime(struct timeval t);
void recalc(int calme);
void GetSunPos(time_t ssue, double *lat, double *lon);
void setViewPos(double lat, double lon);
/***************************************************************/
#endif

87
wmglobe/src/wmgoption.h Normal file
View file

@ -0,0 +1,87 @@
/* WMGlobe 0.5 - All the Earth on a WMaker Icon
* copyright (C) 1998,99 Jerome Dumonteil <jerome.dumonteil@capway.com>
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***************************************************************************/
/*
* #define DEBUG
*/
#define WMGVERSION "WMGlobe v.0.5 6 fev 1999 <jerome.dumonteil@capway.com>"
/*
* comment DEFMAPOK to not install the built-in default maps,
* (smaller binary) usefull if you never use the default map
*/
#define DEFMAPOK
/*
* uncomment MOUSE_LAT_FULL to supprim the shift+left method of rotate earth
*/
/*
* #define MOUSE_LAT_NO_SHIFT
*/
/*
* number of parameter screen : min 1, max 7 (all, the recommanded default)
* - this doesnt modify the binary size -
* 1 : postion latitude & longitude
* 2 : time of viewpoint (+ screen 1)
* 3 : delay & zoom (+ screen 1 & 2)
* 4 : light & dawn (+ screen 1..3)
* 5 : accel & night map (+ screen 1..4)
* 6 : dlat & dlong (+ screen 1..5)
* 7 : type of view (+ screen 1..6)
*/
#define NUM_SCREEN 7
/*** 0.04 sec main loop sleep (maximum refresh rate when delay=0) ***/
#define VAL_USLEEP 40000
#define VAL_USLEEP_SHORT 500
/* waiting time before get back from param screen to earth (seconds) */
#define SCREEN_WAIT 5
#define ZOOM_FACTOR 1.06
#define ZOOM_MIN 0.08
#define ZOOM_MAX 100000.0
#define STOP_RANDOM_FACTOR 1
#define RATIO_ROTATE 0.5
#define DEFAULT_DELAY 1.0
#define DEFAULT_V_LAT 0.0
#define DEFAULT_V_LONG 0.0
#define DEFAULT_SENS 1
#define DEFAULT_ZOOM 1.0
#define DEFAULT_LIGHT 0.25
#define DEFAULT_BORDER 0
#define DEFAULT_NIGHTMAP 1 /* 1 or 0 */
#define MAX_DELAY_SEC 86400.0
#define MAX_MULTI_COEF 864000.0
#define MAX_DELTA_LONG 1800.0
/*** (1 - dawn/2) *****/
#define DEFAULT_DAWN 0.9
/* change this if not 64x64 icons (not deep tested) you will need to change
the cadrex.xbm too and a few other things for the parameters menus
--- DIAMETRE must be a multiple of 2 --- */
#define DIAMETRE 64

2357
wmglobe/src/wmgutil.c Normal file

File diff suppressed because it is too large Load diff

398
wmglobe/src/wraster.h Normal file
View file

@ -0,0 +1,398 @@
/*
* Raster graphics library
*
* Copyright (c) 1997, 1998 Alfredo K. Kojima
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* Environment variables:
*
* WRASTER_GAMMA <rgamma>/<ggamma>/<bgamma>
* gamma correction value. Must be greater than 0
* Only for PseudoColor visuals.
*
* Default:
* WRASTER_GAMMA 1/1/1
*
*
* If you want a specific value for a screen, append the screen number
* preceded by a hash to the variable name as in
* WRASTER_GAMMA#1
* for screen number 1
*/
#ifndef RLRASTER_H_
#define RLRASTER_H_
/* version of the header for the library: 0.11 */
#define WRASTER_HEADER_VERSION 11
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#ifdef XSHM
#include <X11/extensions/XShm.h>
#endif
/* RM_MATCH or RM_DITHER */
#define RC_RenderMode (1<<0)
/* number of colors per channel for colormap in PseudoColor mode */
#define RC_ColorsPerChannel (1<<1)
/* do gamma correction */
#define RC_GammaCorrection (1<<2)
/* visual id to use */
#define RC_VisualID (1<<3)
/* shared memory usage */
#define RC_UseSharedMemory (1<<4)
/* use default instead of best visual */
#define RC_DefaultVisual (1<<5)
typedef struct RContextAttributes {
int flags;
int render_mode;
int colors_per_channel; /* for PseudoColor */
float rgamma; /* gamma correction for red, */
float ggamma; /* green, */
float bgamma; /* and blue */
VisualID visualid; /* visual ID to use */
int use_shared_memory; /* True of False */
} RContextAttributes;
/*
* describes a screen in terms of depth, visual, number of colors
* we can use, if we should do dithering, and what colors to use for
* dithering.
*/
typedef struct RContext {
Display *dpy;
int screen_number;
Colormap cmap;
RContextAttributes *attribs;
GC copy_gc;
Visual *visual;
int depth;
Window drawable; /* window to pass for XCreatePixmap(). */
/* generally = root */
int vclass;
unsigned long black;
unsigned long white;
int red_offset; /* only used in 24bpp */
int green_offset;
int blue_offset;
/* only used for pseudocolor and grayscale */
XStandardColormap *std_rgb_map; /* standard RGB colormap */
XStandardColormap *std_gray_map; /* standard grayscale colormap */
int ncolors; /* total number of colors we can use */
XColor *colors; /* internal colormap */
struct {
unsigned int use_shared_pixmap:1;
} flags;
} RContext;
typedef struct RColor {
unsigned char red;
unsigned char green;
unsigned char blue;
unsigned char alpha;
} RColor;
typedef struct RHSVColor {
unsigned short hue; /* 0-359 */
unsigned char saturation; /* 0-255 */
unsigned char value; /* 0-255 */
} RHSVColor;
typedef struct RPoint {
int x, y;
} RPoint;
typedef struct RSegment {
int x1, y1, x2, y2;
} RSegment;
/*
* internal 24bit+alpha image representation
*/
typedef struct RImage {
unsigned width, height; /* size of the image */
RColor background; /* background color */
unsigned char *data[4]; /* image data (R,G,B,A) */
} RImage;
/*
* internal wrapper for XImage. Used for shm abstraction
*/
typedef struct RXImage {
XImage *image;
/* Private data. Do not access */
#ifdef XSHM
XShmSegmentInfo info;
char is_shared;
#endif
} RXImage;
/* note that not all operations are supported in all functions */
enum {
RClearOperation, /* clear with 0 */
RCopyOperation,
RNormalOperation, /* same as combine */
RAddOperation,
RSubtractOperation
};
/* image display modes */
enum {
RDitheredRendering = 0,
RBestMatchRendering = 1
};
/* bw compat */
#define RM_DITHER RDitheredRendering
#define RM_MATCH RBestMatchRendering
enum {
RAbsoluteCoordinates = 0,
RRelativeCoordinates = 1
};
enum {
RSunkenBevel = -1,
RRaisedBevel = 1
};
/* bw compat */
#define RBEV_SUNKEN RSunkenBevel
/* 1 pixel wide */
#define RBEV_RAISED RRaisedBevel
/* 1 pixel wide on top/left 2 on bottom/right */
#define RBEV_RAISED2 2
/* 2 pixel width */
#define RBEV_RAISED3 3
enum {
RHorizontalGradient = 2,
RVerticalGradient = 3,
RDiagonalGradient = 4
};
/* for backwards compatibility */
#define RGRD_HORIZONTAL RHorizontalGradient
#define RGRD_VERTICAL RVerticalGradient
#define RGRD_DIAGONAL RDiagonalGradient
/* error codes */
#define RERR_NONE 0
#define RERR_OPEN 1 /* cant open file */
#define RERR_READ 2 /* error reading from file */
#define RERR_WRITE 3 /* error writing to file */
#define RERR_NOMEMORY 4 /* out of memory */
#define RERR_NOCOLOR 5 /* out of color cells */
#define RERR_BADIMAGEFILE 6 /* image file is corrupted or invalid */
#define RERR_BADFORMAT 7 /* image file format is unknown */
#define RERR_BADINDEX 8 /* no such image index in file */
#define RERR_BADVISUALID 16 /* invalid visual ID requested for context */
#define RERR_XERROR 127 /* internal X error */
#define RERR_INTERNAL 128 /* should not happen */
/*
* Returns a NULL terminated array of strings containing the
* supported formats, such as: TIFF, XPM, PNG, JPEG, PPM, GIF
*/
char **RSupportedFileFormats(void);
void RFreeStringList(char **list);
/*
* Xlib contexts
*/
RContext *RCreateContext(Display * dpy, int screen_number,
RContextAttributes * attribs);
void RDestroyContext(RContext * context);
Bool RGetClosestXColor(RContext * context, RColor * color, XColor * retColor);
/*
* RImage creation
*/
RImage *RCreateImage(unsigned width, unsigned height, int alpha);
RImage *RCreateImageFromXImage(RContext * context, XImage * image, XImage * mask);
RImage *RCreateImageFromDrawable(RContext * context, Drawable drawable,
Pixmap mask);
RImage *RLoadImage(RContext * context, char *file, int index);
void RDestroyImage(RImage * image);
RImage *RGetImageFromXPMData(RContext * context, char **data);
/*
* RImage storing
*/
Bool RSaveImage(RImage * image, char *filename, char *format);
/*
* Area manipulation
*/
RImage *RCloneImage(RImage * image);
RImage *RGetSubImage(RImage * image, int x, int y, unsigned width,
unsigned height);
void RCombineImageWithColor(RImage * image, RColor * color);
void RCombineImages(RImage * image, RImage * src);
void RCombineArea(RImage * image, RImage * src, int sx, int sy, unsigned width,
unsigned height, int dx, int dy);
void RCombineImagesWithOpaqueness(RImage * image, RImage * src, int opaqueness);
void RCombineAreaWithOpaqueness(RImage * image, RImage * src, int sx, int sy,
unsigned width, unsigned height, int dx, int dy,
int opaqueness);
RImage *RScaleImage(RImage * image, unsigned new_width, unsigned new_height);
RImage *RMakeTiledImage(RImage * tile, unsigned width, unsigned height);
RImage *RMakeCenteredImage(RImage * image, unsigned width, unsigned height,
RColor * color);
/*
* Drawing
*/
Bool RGetPixel(RImage * image, int x, int y, RColor * color);
void RPutPixel(RImage * image, int x, int y, RColor * color);
void ROperatePixel(RImage * image, int operation, int x, int y, RColor * color);
void RPutPixels(RImage * image, RPoint * points, int npoints, int mode,
RColor * color);
void ROperatePixels(RImage * image, int operation, RPoint * points,
int npoints, int mode, RColor * color);
int RDrawLine(RImage * image, int x0, int y0, int x1, int y1, RColor * color);
int ROperateLine(RImage * image, int operation, int x0, int y0, int x1, int y1,
RColor * color);
void RDrawLines(RImage * image, RPoint * points, int npoints, int mode,
RColor * color);
void ROperateLines(RImage * image, int operation, RPoint * points, int npoints,
int mode, RColor * color);
void RDrawSegments(RImage * image, RSegment * segs, int nsegs, RColor * color);
void ROperateSegments(RImage * image, int operation, RSegment * segs, int nsegs,
RColor * color);
/*
* Color convertion
*/
void RRGBtoHSV(RColor * color, RHSVColor * hsv);
void RHSVtoRGB(RHSVColor * hsv, RColor * rgb);
/*
* Painting
*/
void RClearImage(RImage * image, RColor * color);
void RBevelImage(RImage * image, int bevel_type);
RImage *RRenderGradient(unsigned width, unsigned height, RColor * from,
RColor * to, int style);
RImage *RRenderMultiGradient(unsigned width, unsigned height, RColor ** colors,
int style);
/*
* Convertion into X Pixmaps
*/
int RConvertImage(RContext * context, RImage * image, Pixmap * pixmap);
int RConvertImageMask(RContext * context, RImage * image, Pixmap * pixmap,
Pixmap * mask, int threshold);
/*
* misc. utilities
*/
RXImage *RCreateXImage(RContext * context, int depth,
unsigned width, unsigned height);
void RDestroyXImage(RContext * context, RXImage * ximage);
void RPutXImage(RContext * context, Drawable d, GC gc, RXImage * ximage,
int src_x, int src_y, int dest_x, int dest_y,
unsigned width, unsigned height);
/* do not free the returned string! */
const char *RMessageForError(int errorCode);
int RBlurImage(RImage * image);
/****** Global Variables *******/
extern int RErrorCode;
#endif

80
wmglobe/src/zapnum.h Normal file
View file

@ -0,0 +1,80 @@
/* WMGlobe 0.5.pre1 - All the Earth on a WMaker Icon
* copyright (C) 1998,99 Jerome Dumonteil <jerome.dumonteil@capway.com>
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***************************************************************************/
int zapnum[14][4] =
{
{90, 0, 10, 13},
{0, 0, 10, 13},
{10, 0, 10, 13},
{20, 0, 10, 13},
{30, 0, 10, 13},
{40, 0, 10, 13},
{50, 0, 10, 13},
{60, 0, 10, 13},
{70, 0, 10, 13},
{80, 0, 10, 13},
{100, 0, 10, 13},
{110, 0, 10, 13},
{100, 0, 5, 13},
{114, 0, 5, 13}
};
/*
* int zapnum2[14][4] =
* {
* {72, 0, 8, 13},
* {0, 0, 8, 13},
* {8, 0, 8, 13},
* {16, 0, 8, 13},
* {24, 0, 8, 13},
* {32, 0, 8, 13},
* {40, 0, 8, 13},
* {48, 0, 8, 13},
* {56, 0, 8, 13},
* {64, 0, 8, 13},
* {80, 0, 8, 13},
* {88, 0, 8, 13},
* {80, 0, 6, 13},
* {92, 0, 6, 13}
* };
*/
int platd[4][2] =
{
{2, 12},
{6, 12},
{16, 12},
{26, 12}
};
int platm[2][2] =
{
{42, 12},
{52, 12}
};
int plongd[4][2] =
{
{2, 36},
{6, 36},
{16, 36},
{26, 36}
};
int plongm[2][2] =
{
{42, 36},
{52, 36}
};

19
wmglobe/src/zapnum.xpm Normal file
View file

@ -0,0 +1,19 @@
/* XPM */
static char * zapnum_xpm[] = {
"120 13 3 1",
" c None",
". c #000000",
"+ c #CCCC6E",
"........................................................................................................................",
"...++++......++++......+++++.......+++....+++++++......+++...++++++++....+++++.....+++++.....+++++......................",
"..+++++....+++.+++...+++..++++....++++....+++++++....+++.....++++++++...++..+++...+++.+++...+++.+++.....................",
"....+++....+++..+++..+++...+++...+++++....++........+++......+.....+...+++...+++.+++...+++..++...++.....................",
"....+++....+++..+++..+++...+++..++.+++....++........++++++...+....++...+++...+++.+++...+++.+++...+++....................",
"....+++.........+++.......+++..++..+++....++++++...+++..+++.......+.....++++.++..+++...+++.+++...+++..............+++++.",
"....+++........+++.....+++++..++...+++........+++..+++...+++.....++......+++++...+++...+++.+++...+++..............+++++.",
"....+++.......+++.........++++++++++++++.......+++.+++...+++....++......++.++++...+++..+++.+++...+++....................",
"....+++......+++.....++....+++++++++++++..++...+++.+++...+++....++.....+++..++++...++++++..+++...+++....................",
"....+++.....+++...+..+++...+++.....+++...+++...+++.+++...+++...++......+++...+++......+++...++...++.....................",
"....+++....++++++++..+++..+++......+++...++++.+++...+++.+++....++.......+++..++......+++....+++.+++.....................",
"..+++++++..++++++++....+++++.......+++....+++++......+++++....++.........+++++.....+++.......+++++......................",
"..................................................................................++...................................."};

16
wmglobe/src/zaptxt.xpm Normal file
View file

@ -0,0 +1,16 @@
/* XPM */
static char * zaptxt_xpm[] = {
"434 10 3 1",
" c None",
". c #000000",
"+ c #CCCC6E",
"..............................................................................................................................................................................................................................................+..................................................................................++.++................++++++.+.+.+...++.++.....++++.++++..+......++.............+.................................",
".+++....++...+++...+++.....++.+++++...++..+++++..+++...+++....................................................................................................................................................................................+..++..............................................++....+.+....+.................++...++...............+++++++.+.+...++...++....++.....++..+......++...++++..++..+.................................",
"++.++..+++..++.++.++.++...+++.++.....++...++.++.++.++.++.++.........+...++++...+++..++++..+++++.+++++..+++..++.++.++++....+++.++.++.++....+...+.+..++..+++..++++...+++..++++...+++.++++++.++.++.++.++.++.++.++.++.++.++.+++++................+...++............................+.+..............+..+...+.+....+.........++++....++...++....++....+....++++++.+.+.+..++...++....++.....++...+.....++..++..++.++.+..................................",
"++.++...++.....++....++...+++.++....++.......++.++.++.++.++...+....+++..++.++.++.++.++.++.++....++....++.++.++.++..++......++.++.++.++....++.++.++.++.++.++.++.++.++.++.++.++.++.++..++...++.++.++.++.++.++.++.++.++.++....++.........++.....+...++.....+......................+.+.....++++.....+..+...+.+...+.........++..++..++.....++..+..+..+.+.+.+++++++.+.+...++...++....++.....++...+.....++......++....+..................................",
"++.++...++....++....++...++++.++++..++++.....++..+++..++.++...+...++.++.++.++.++....++.++.++....++....++....++.++..++......++.++++..++....+++++.+++++.++.++.++.++.++.++.++.++.++.....++...++.++.++.++.+++++.+++++.++.++...+++.........++....+....++...+.+.+..............+++..+++++..++....++....++....................++.+++..++.....++..+.+......+..++++++.+.+.+..++...++....++.....++....+....++.....++....+....+++............................",
"++.++...++....++.....++..+.++....++.++.++...++..++.++..++++.+++++.++.++.++++..++....++.++.++++..++++..+++++.+++++..++......++.+++...++....+++++.+++++.++.++.++++..++.++.++++...+++...++...++.++.++.++.+++++..+++...+++...+++................+....++....+++...+++...............+.+.++........++........................++.+++..++.....++...+..........+++++++.+.+..++.....++...++.....++....+....++....++.....+...++.++...........................",
"++.++...++...++......++.++.++....++.++.++...++..++.++....++...+...+++++.++.++.++....++.++.++....++....++.++.++.++..++...++.++.++++..++....+++++.+++++.++.++.++....++.++.+++......++..++...++.++.++.++.+++++.+++++..+++..+++................+.....++...+.+.+..............+++..+++++..++....++..........................++.++...++.....++..+.+.+.......++++++.+.+.+..++...++....++.....++.....+...++....++....+....++.++...........................",
"++.++...++...++...++.++.+++++.++.++.++.++..++...++.++...++....+...++.++.++.++.++.++.++.++.++....++....++.++.++.++..++...++.++.++.++.++....++.++.++.++.++.++.++....++.++.++++..++.++..++...++.++..+++..++.++.++.++..+++..++............++...+............+...........++.........+.+.....++++..........................+.++......++.....++..+..+........+++++++.+.+...++...++....++.....++.....+...++..........+....++.++...........................",
".+++....++..+++++..+++.....++..+++...+++...++....+++...++.........++.++.++++...+++..++++..+++++.++.....++++.++.++.++++...+++..++.++.+++++.++.++.++..+..+++..++.....+++..++.++..+++...++....+++....+...+...+.++.++..+++..+++++.........++..+......++.................++.........+.+..................................++..++++....++...++....++.+.......++++++.+.+.+..++...++....++.....++......+..++....++...+..++..+++............................",
".....................................................................................................................................................................++...................................................................+.........................................................................+............+...+................+++++++.+.+....++.++.....++++.++++......+..++.........+..++................................."};

242
wmglobe/wmglobe.1 Normal file
View file

@ -0,0 +1,242 @@
.TH WMGlobe 1 "fevrier 1999"
.SH NAME
WMGlobe - The Whole Earth spinning on you desktop...
as a dockable app for WindowMaker
.SH SYNOPSIS
.B wmglobe
.I "[-options]"
.SH "DESCRIPTION"
WMGlobe is a WindowMaker dock.app that displays the earth on an icon. It's
an adaptation of XGlobe to WMaker environnement. WMGlobe uses a map which is
rendered on a sphere by raytracing. Yes, for a 64x64 pixel result:-)
.SH "OPTIONS"
.TP
.B \-v
version. Currently, this should display :
WMGlobe v.0.5 6 fev 1999 <jerome.dumonteil@capway.com>
.TP
.B \-h
short help
.TP
.B \-zoom \fI zoom_value\fP
Value > 1 to magnify the view, value < 1 to lower. Default: 1.0
.TP
.B \-pos \fI latitude longitude\fP
Initial viewing fixed at this position, don't follow
the sun rotation. Accepted values in the form 45°12'36 or 45.21 or 45:12:36 .
Default: the initial position is "under" the sun, and
the point of view follows the sun.
.TP
.B \-rand
New random position at every refresh of screen.
.TP
.B \-map \fI map_file\fP
Map used for the rendering. Can be JPEG, GIG, XPM
PNM, TIFF but none BMP.
Default: use internal map of earth.
.TP
.B \-nimap \fI night_file\fP
Map used for the dark side of the earth. Must be of
the same width x height as the day side map.
Default: if the default internal day map is used, use
a default internal night file (see -nonimap option).
If a custom day map is provided, and no night map, the
dark side is computed via the -light option.
.TP
.B \-nonimap
Don't use the default night map.
.TP
.B \-delay \fI seconds\fP
Time in seconds between each calculation of a new
position. Limited to 0.04 at compile time (25 frames
per second should be enough). The sun position move
only once per minute, so if you use wmglobe without
-dlong or -accel option, the CPU cost of WMGlobe is
*very* low. The use of very low value for -delay plus
-dlong and -accel can be CPU costly (but very nice...).
Default: 1.0 sec.
.TP
.B \-dlat \fI delta_latitude\fP
Move the point of view by delta_lat degrees per second,
with a value of 6 the earth make a full rotation in
one minute. The value can be formated as -pos option.
Default: 0°0'0
.TP
.B \-dlong \fI delta_long\fP
Move the point of view by delta_long degrees per
second. With a value of -0°0'15" the earth make a full
rotation in 24 hours toward the west. By default,
-dlong and -dlat are null. If they are used, the view
follow their values. Going back to "follow sun" mode
in parameters screen put -dlat and -dlong to zero.
.TP
.B \-light \fI light_value\fP
Level of light of the dark side when there is no
night map, from 0 to 1.
Default: 0.25
.TP
.B \-dawn \fI dawn_value\fP
Level of continuity for dawn limit, from 0 to 1. With
a value of 1, the border line between night and day is
at maximum contrast.
Default: 0.2
.TP
.B \-bord \fI border_num\fP
0 1 or 2. There are 3 different borders for the icon.
Default: 0
.TP
.B \-accel \fI time_multi\fP
Time warp factor. With -accel 24, the sun make a full
rotation in one hour (or the earth, I'm not sure). Default: 1.0
.TP
.B \-time \fI seconds\fP
Time to display in seconds since 01-01-1970 (see the
date command). Necessary if you need to be sure that
WMGlobe is Y2K compliant without changing system time.
Negative values for dates before 1970 accepted.
Default: not set, use current time.
.TP
.B \-fun \fI dx dy\fP
Move the earth image by dx dy pixels in the icon. See
puzzle.sh to understand why.
.TP
.B \-oz
Start in "austral" mode (for "down under" people)
.TP
.B \-d \fI display\fP
Select another display
.TP
.B \-w \-shape
Useless, since it is set by default (WMaker dockable
application)
.SH "MOUSE OPTIONS"
.TP
.B left button
Change longitude while pressed, change longitude &
latitude if shift+left button.
.TP
.B middle button
Zoom in, shift + middle button: zoom out
.TP
.B right button
Displays 7 screens of parameters. On every screen, just
clic with left or right button on the figures to change
their value. The TIME screen shows an approximation
of date and time of the earth zone currently displayed,
using GMT time + longitude offset, it's close to the
real local time by one or two hours. Others options
don't need more help. Intuitive they said...
.SH "FILES"
.TP
.B MAPS
Like XGlobe, WMGlobe needs a longitude/latitude map to work. By default,
it uses a low quality built-in map of earth. But you will probably want
to use better ones.
You can get maps usable with WMGlobe on the net. See the links below.
using custom maps:
For the image to be mapped correctly, position 0°North 0°West must be in
the center of the image and the latitude must be linear from 90°N to 90°S.
When using a night map, make sure that day and night map have the same
dimensions.
.TP
.B Links: Where to find maps and similar softs
where to find the sources of wmglobe:
the web page of WMGlobe (made by Sylvestre Taburet):
<http://www.capway.com/dumonte1/wm/wmg.html>
where to find maps and similar softs:
Earth image by a cgi:
<http://www.fourmilab.ch/cgi-bin/uncgi/Earth>
two softs running under X:
XGlobe Homepage: (many links to map of earth)
<http://www.uni-karlsruhe.de/~uddn/xglobe>
Xearth Homepage:
<http://www.cs.colorado.edu/~tuna/xearth/>
By the way, you can use maps of Mars, Luna ... and text.
.SH "ENVIRONMENT"
.LP
WMGlobe uses the setlocale(3) function, so you LANG environment need to be ok.
You need WindowMaker 0.20.3 or 0.51.0 installed to use WMGlobe.
.SH "SEE ALSO"
.LP
The Window Maker User Guide
The Window Maker FAQ
.SH "AUTHOR"
jerome dumonteil <jerome.dumonteil@capway.com>
Patches, bug reports, and suggestions are welcome.
.SH "CREDITS"
WMGlobe is Copyright (C) 1998,99 by Jerome Dumonteil and licensed through
the GNU General Public License.
Read the COPYING file for the complete GNU license.
Original idea, tests, logos:
Sylvestre Taburet <staburet@consort.fr>
The code in 'sunpos.cpp' is taken from Xearth by Kirk Lauritz Johnson.
/*
sunpos.c
kirk johnson
july 1993
code for calculating the position on the earth's surface for which
the sun is directly overhead (adapted from _practical astronomy
with your calculator, third edition_, peter duffett-smith,
cambridge university press, 1988.)
Copyright (C) 1989, 1990, 1993, 1994, 1995 Kirk Lauritz Johnson
Parts of the source code (as marked) are:
Copyright (C) 1989, 1990, 1991 by Jim Frost
Copyright (C) 1992 by Jamie Zawinski <jwz@lucid.com>
Permission to use, copy, modify and freely distribute xearth for
non-commercial and not-for-profit purposes is hereby granted
without fee, provided that both the above copyright notice and this
permission notice appear in all copies and in supporting
documentation.
*/
The rendering engine is taken from XGlobe by Thorsten Scheuermann
XGlobe Homepage: http://www.uni-karlsruhe.de/~uddn/xglobe
Raster graphics library by Alfredo K. Kojima, & stuff of Window Maker
<http://windowmaker.org> by A. K. Kojima, Dan Pascu, Matthew Hawkins & team
.SH "BUGS"
.LP
If you use the --enable-single-icon compile time option of WindowMaker,
you can not display more than one WMGlobe.
WMGlobe hopes that an overflow of a long integer dont generate an error
and that LONG_MAX +1 = LONG_MIN . This happens with high values of -accel
when the date go over year 2038. The expected result is wmglobe
continuing smoothly from 1901.

BIN
wmglobe/wmgmap.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B