#define OUT (*params.out)  \

/*5:*/
#line 323 "pp3.w"

#include <iostream> 
#include <string> 
#include <fstream> 
#include <sstream> 
#include <vector> 
#include <map> 
#include <list> 
#include <iomanip> 
#include <cstdlib> 
#include <cmath> 
#include <cfloat> 

using namespace std;

/*39:*/
#line 1521 "pp3.w"

inline double fmin(const double&x,const double&y){
return x<y?x:y;
}

inline double fmax(const double&x,const double&y){
return x> y?x:y;
}

inline double fdim(const double&x,const double&y){
return x> y?x-y:0.0;
}


/*:39*/
#line 338 "pp3.w"


/*:5*//*6:*/
#line 357 "pp3.w"

#ifndef DATADIR
#define DATADIR ""
#endif

/*66:*/
#line 2229 "pp3.w"

struct color{
double red,green,blue;
string name;
color(string name,double red,double green,double blue)
:red(red),green(green),blue(blue),name(name){}
color(double red,double green,double blue)
:red(red),green(green),blue(blue),name(){}
void set(ostream&out)const;
};

/*:66*/
#line 362 "pp3.w"


struct parameters{
double center_rectascension,center_declination;
double view_frame_width,view_frame_height;
double grad_per_cm;
double label_skip,minimal_nebula_radius,faintest_cluster_magnitude,
faintest_diffuse_nebula_magnitude,faintest_star_magnitude,
star_scaling,minimal_star_radius,faintest_star_disk_magnitude,
faintest_star_with_label_magnitude,shortest_constellation_line;
string constellation;
int font_size;
double penalties_label,penalties_star,penalties_nebula,
penalties_boundary,penalties_boundary_rim,penalties_cline,
penalties_cline_rim,penalties_threshold,penalties_rim;
string filename_stars,filename_nebulae,filename_dimensions,
filename_lines,filename_boundaries,filename_milkyway,
filename_preamble,filename_include;
string filename_output;
ostream*out;
istream*in;
bool input_file;
color bgcolor,gridcolor,eclipticcolor,boundarycolor,hlboundarycolor,
starcolor,nebulacolor,labelcolor,textlabelcolor,clinecolor,
milkywaycolor;
double linewidth_grid,linewidth_ecliptic,linewidth_boundary,
linewidth_hlboundary,linewidth_cline,linewidth_nebula;
string linestyle_grid,linestyle_ecliptic,linestyle_boundary,
linestyle_hlboundary,linestyle_cline,linestyle_nebula;
bool milkyway_visible,colored_stars,show_grid,show_ecliptic,
show_boundaries,show_lines,show_labels;
bool create_eps,create_pdf;
parameters():/*7:*/
#line 403 "pp3.w"

center_rectascension(5.8),center_declination(0.0),
view_frame_width(15.0),view_frame_height(15.0),
grad_per_cm(4.0),
constellation("ORI"),font_size(10),
label_skip(0.06),minimal_nebula_radius(0.1),
faintest_cluster_magnitude(4.0),
faintest_diffuse_nebula_magnitude(8.0),
faintest_star_magnitude(7.0),star_scaling(1.0),
minimal_star_radius(0.015),
faintest_star_disk_magnitude(4.5),
faintest_star_with_label_magnitude(3.7),
shortest_constellation_line(0.1),
penalties_label(1.0),penalties_star(1.0),
penalties_nebula(1.0),penalties_boundary(1.0),
penalties_boundary_rim(1.0),penalties_cline(1.0),
penalties_cline_rim(1.0),penalties_threshold(1.0),
penalties_rim(1.0),
filename_stars(DATADIR"stars.dat"),
filename_nebulae(DATADIR"nebulae.dat"),
filename_dimensions("labeldimens.dat"),
filename_lines(DATADIR"lines.dat"),
filename_boundaries(DATADIR"boundaries.dat"),
filename_milkyway(DATADIR"milkyway.dat"),
filename_preamble(),filename_include(),
filename_output(),out(&cout),in(0),input_file(false),
bgcolor("bgcolor",0,0,0.4),
gridcolor("gridcolor",0,0.298,0.447),
eclipticcolor("eclipticcolor",1,0,0),
boundarycolor("boundarycolor",0.5,0.5,0),
hlboundarycolor("hlboundarycolor",1,1,0),
starcolor("starcolor",1,1,1),
nebulacolor("nebulacolor",1,1,1),
labelcolor("labelcolor",0,1,1),
textlabelcolor(1,1,0),
clinecolor("clinecolor",0,1,0),
milkywaycolor(0,0,1),
linewidth_grid(0.025),linewidth_ecliptic(0.018),
linewidth_boundary(0.035),linewidth_hlboundary(0.035),
linewidth_cline(0.035),linewidth_nebula(0.018),
linestyle_grid("solid"),linestyle_ecliptic("dashed"),
linestyle_boundary("dashed"),
linestyle_hlboundary("dashed"),linestyle_cline("solid"),
linestyle_nebula("solid"),
milkyway_visible(true),
colored_stars(true),
show_grid(true),show_ecliptic(true),show_boundaries(true),
show_lines(true),show_labels(true),
create_eps(false),
create_pdf(false)


/*:7*/
#line 394 "pp3.w"
{}
int view_frame_width_in_bp(){
return int(ceil(view_frame_width/2.54*72));
}
int view_frame_height_in_bp(){
return int(ceil(view_frame_height/2.54*72));
}
}params;

/*:6*//*35:*/
#line 1428 "pp3.w"

typedef enum{hidden,visible,undecided}visibility;

struct view_data{
visibility in_view;
double x,y;
double radius,skip;
visibility with_label;
bool label_arranged;
string label;
double label_width,label_height;
color label_color;
int label_angle;
view_data():in_view(undecided),x(DBL_MAX),y(DBL_MAX),radius(0.0),
skip(params.label_skip),
with_label(undecided),label_arranged(false),label(),
label_width(0.24),label_height(0.36),
label_color(params.labelcolor),label_angle(0){}
void get_label_boundaries(double&left,double&right,double&top,
double&bottom)const;
double scope()const{return radius+skip+
fmax(label_width,label_height)+2.0*skip;}
bool has_valid_coordinates()const{return x!=DBL_MAX&&y!=DBL_MAX;}
virtual double penalties_with(const double left,const double right,
const double top,const double bottom,
bool core= true)const;
};

/*:35*//*36:*/
#line 1460 "pp3.w"

typedef vector<view_data*> objects_list;

/*:36*//*37:*/
#line 1472 "pp3.w"

void view_data::get_label_boundaries(double&left,double&right,double&top,
double&bottom)const{
const double origin_x= 
x+(radius+skip)*cos(M_PI_4*double(label_angle));
const double origin_y= 
y+(radius+skip)*sin(M_PI_4*double(label_angle));
switch(label_angle){
case 0:case 1:case 7:left= origin_x;break;
case 2:case 6:left= origin_x-label_width/2.0;break;
case 3:case 4:case 5:left= origin_x-label_width;break;
}
right= left+label_width;
switch(label_angle){
case 0:case 4:bottom= origin_y-label_height/2.0;break;
case 1:case 2:case 3:bottom= origin_y;break;
case 5:case 6:case 7:bottom= origin_y-label_height;break;
}
top= bottom+label_height;
}

/*:37*//*38:*/
#line 1498 "pp3.w"

double view_data::penalties_with(const double left,const double right,
const double top,const double bottom,
bool core)const{
if(with_label==visible&&label_arranged){
double left2,right2,top2,bottom2;
get_label_boundaries(left2,right2,top2,bottom2);
const double overlap_left= fmax(left,left2);
const double overlap_right= fmin(right,right2);
const double overlap_top= fmin(top,top2);
const double overlap_bottom= fmax(bottom,bottom2);
const double overlap_x= fdim(overlap_right,overlap_left);
const double overlap_y= fdim(overlap_top,overlap_bottom);
return overlap_x*overlap_y*params.penalties_label;
}else return 0.0;
}


/*:38*//*40:*/
#line 1551 "pp3.w"

struct star:public view_data{
int hd,bs;
double rectascension,declination;
double magnitude;
double b_v;
int flamsteed;
string name;
string constellation;
string spectral_class;
star():hd(0),bs(0),rectascension(0.0),declination(0.0),
magnitude(0.0),b_v(0.0),flamsteed(0),name(""),
spectral_class(""),view_data(){}
virtual double penalties_with(const double left,const double right,
const double top,const double bottom,
bool core= true)const;
};

/*:40*//*41:*/
#line 1575 "pp3.w"

double star::penalties_with(const double left,const double right,
const double top,const double bottom,
bool core)const{
double penalties= view_data::penalties_with(left,right,top,bottom,
core);
const double left2= x-radius,right2= x+radius,top2= y+radius,
bottom2= y-radius;
const double overlap_left= fmax(left,left2);
const double overlap_right= fmin(right,right2);
const double overlap_top= fmin(top,top2);
const double overlap_bottom= fmax(bottom,bottom2);
const double overlap_x= fdim(overlap_right,overlap_left);
const double overlap_y= fdim(overlap_top,overlap_bottom);
penalties+= overlap_x*overlap_y*params.penalties_star;
return penalties;
}


typedef vector<star> stars_list;

/*:41*//*42:*/
#line 1618 "pp3.w"

istream&operator>>(istream&in,star&s){
in>>s.hd>>s.bs>>s.rectascension
>>s.declination>>s.magnitude>>s.b_v
>>s.flamsteed;
char ch;
do in.get(ch);while(in&&ch!='\n');
getline(in,s.name);
getline(in,s.constellation);
getline(in,s.spectral_class);
return in;
}

/*:42*//*43:*/
#line 1634 "pp3.w"

void read_stars(stars_list&stars){
ifstream stars_file(params.filename_stars.c_str());
if(!stars_file)throw string("No stars file found");
star current_star;
stars_file>>current_star;
while(stars_file){
current_star.label= string("\\Starname{")+current_star.name+'}';
stars.push_back(current_star);
stars_file>>current_star;
}
}


/*:43*//*44:*/
#line 1652 "pp3.w"

typedef enum{unknown,galaxy,emission,reflection,open_cluster,
globular_cluster}nebula_kind;

/*:44*//*45:*/
#line 1670 "pp3.w"

struct nebula:public view_data{
int ngc,ic,messier;
string constellation;
double rectascension,declination;
double magnitude;
double diameter_x,diameter_y;
double horizontal_angle;
nebula_kind kind;
nebula():ngc(0),ic(0),messier(0),constellation(),rectascension(0.0),
declination(0.0),magnitude(0.0),diameter_x(0.0),
diameter_y(0.0),horizontal_angle(0.0),kind(unknown){}
virtual double penalties_with(const double left,const double right,
const double top,const double bottom,
bool core= true)const;
};

typedef vector<nebula> nebulae_list;

/*:45*//*46:*/
#line 1695 "pp3.w"

double nebula::penalties_with(const double left,const double right,
const double top,const double bottom,
bool core)const{
double penalties= view_data::penalties_with(left,right,top,bottom,core);
const double left2= x-radius,right2= x+radius,top2= y+radius,
bottom2= y-radius;
const double overlap_left= fmax(left,left2);
const double overlap_right= fmin(right,right2);
const double overlap_top= fmin(top,top2);
const double overlap_bottom= fmax(bottom,bottom2);
const double overlap_x= fdim(overlap_right,overlap_left);
const double overlap_y= fdim(overlap_top,overlap_bottom);
penalties+= overlap_x*overlap_y*params.penalties_nebula;
return penalties;
}

/*:46*//*47:*/
#line 1723 "pp3.w"

istream&operator>>(istream&in,nebula&n){
int kind;
in>>n.ngc>>n.ic>>n.messier>>n.constellation>>n.rectascension
>>n.declination>>n.magnitude>>n.diameter_x>>n.diameter_y
>>n.horizontal_angle>>kind;
n.kind= nebula_kind(kind);
return in;
}

/*:47*//*48:*/
#line 1736 "pp3.w"

void read_nebulae(nebulae_list&nebulae){
ifstream nebulae_file(params.filename_nebulae.c_str());
nebula current_nebula;
nebulae_file>>current_nebula;
while(nebulae_file){
/*49:*/
#line 1755 "pp3.w"

string catalogue;
stringstream number;
if(current_nebula.messier> 0){
catalogue= "\\Messier{";
number<<current_nebula.messier;
}else if(current_nebula.ngc> 0){
catalogue= "\\NGC{";
number<<current_nebula.ngc;
}else if(current_nebula.ic> 0){
catalogue= "\\IC{";
number<<current_nebula.ic;
}else throw string("Invalid catalogue: \"")+catalogue+'"';
current_nebula.label= catalogue+number.str()+'}';


/*:49*/
#line 1742 "pp3.w"

nebulae.push_back(current_nebula);
nebulae_file>>current_nebula;
}
}

/*:48*//*50:*/
#line 1780 "pp3.w"

struct point{
double x,y;
point(const double x,const double y):x(x),y(y){}
point():x(0.0),y(0.0){}
};

/*:50*//*51:*/
#line 1802 "pp3.w"

struct boundary{
vector<point> points;
vector<string> constellations;
bool belongs_to_constellation(const string constellation)const;
};

typedef vector<boundary> boundaries_list;

/*:51*//*52:*/
#line 1817 "pp3.w"

bool boundary::belongs_to_constellation(const string constellation)const{
for(int i= 0;i<constellations.size();i++)
if(constellations[i].substr(0,3)==constellation.substr(0,3))
return true;
return false;
}

/*:52*//*53:*/
#line 1845 "pp3.w"

istream&operator>>(istream&in,boundary&p){
int size;
in>>size;
p.points.resize(size);
for(int i= 0;i<size;i++)
in>>p.points[i].x>>p.points[i].y;
in>>size;
p.constellations.resize(size);
for(int i= 0;i<size;i++)
in>>p.constellations[i];
return in;
}

/*:53*//*54:*/
#line 1862 "pp3.w"

void read_constellation_boundaries(boundaries_list&boundaries){
ifstream boundaryfile(params.filename_boundaries.c_str());
boundary current_boundary;
boundaryfile>>current_boundary;
while(boundaryfile){
boundaries.push_back(current_boundary);
boundaryfile>>current_boundary;
}
}

/*:54*//*55:*/
#line 1884 "pp3.w"

struct boundary_atom:public view_data{
point start,end;
boundary_atom(point start,point end);
virtual double penalties_with(const double left,const double right,
const double top,const double bottom,
bool core= true)const;
};

/*:55*//*56:*/
#line 1900 "pp3.w"

boundary_atom::boundary_atom(point start,point end):start(start),end(end){
x= (start.x+end.x)/2.0;
y= (start.y+end.y)/2.0;
radius= hypot(end.x-start.x,end.y-start.y)/2.0;
radius*= M_PI_2;
in_view= visible;
with_label= hidden;
skip= 0.0;
}

/*:56*//*57:*/
#line 1921 "pp3.w"

/*59:*/
#line 2033 "pp3.w"

bool line_intersection(double numerator,double denominator,
double zero_point,double slope,
double min,double max,
double&intersection){
if(denominator==0)return false;
const double lambda= numerator/denominator;
intersection= zero_point+lambda*slope;
return lambda> 0.0&&lambda<1.0&&
intersection> min&&intersection<max;
}

/*:59*/
#line 1922 "pp3.w"


double boundary_atom::penalties_with(const double left,const double right,
const double top,const double bottom,
bool core)
const{
double intersection;
point r(end.x-start.x,end.y-start.y);
vector<point> intersection_points;
if(line_intersection(left-start.x,r.x,start.y,r.y,
bottom,top,intersection))
intersection_points.push_back(point(left,intersection));
if(line_intersection(right-start.x,r.x,start.y,r.y,
bottom,top,intersection))
intersection_points.push_back(point(right,intersection));
if(line_intersection(top-start.y,r.y,start.x,r.x,
left,right,intersection))
intersection_points.push_back(point(intersection,top));
if(line_intersection(bottom-start.y,r.y,start.x,r.x,
left,right,intersection))
intersection_points.push_back(point(intersection,bottom));
if(start.x> left&&start.x<right&&start.y> bottom&&start.y<top)
intersection_points.push_back(start);
if(end.x> left&&end.x<right&&end.y> bottom&&end.y<top)
intersection_points.push_back(end);
if(intersection_points.empty())return 0.0;
if(intersection_points.size()!=2){
cerr<<"pp3: Funny "<<intersection_points.size()
<<"-fold constellation boundary intersecrtion."<<endl;
return 0.0;
}
const double length= hypot(intersection_points[1].x-
intersection_points[0].x,
intersection_points[1].y-
intersection_points[0].y);
return(core?8.0*params.penalties_boundary:
0.5*params.penalties_boundary_rim)/72.27*2.54*length;
}

/*:57*//*58:*/
#line 1979 "pp3.w"

struct connection:public view_data{
point start,end;
int from,to;
connection(const int from,const int to)
:from(from),to(to),start(),end(){in_view= visible;
with_label= hidden;skip= 0.0;}
virtual double penalties_with(const double left,const double right,
const double top,const double bottom,
bool core= true)const;
};

typedef vector<connection> connections_list;

/*:58*//*60:*/
#line 2052 "pp3.w"

double connection::penalties_with(const double left,const double right,
const double top,const double bottom,
bool core)const
{
double intersection;
point r(end.x-start.x,end.y-start.y);
vector<point> intersection_points;
if(line_intersection(left-start.x,r.x,start.y,r.y,
bottom,top,intersection))
intersection_points.push_back(point(left,intersection));
if(line_intersection(right-start.x,r.x,start.y,r.y,
bottom,top,intersection))
intersection_points.push_back(point(right,intersection));
if(line_intersection(top-start.y,r.y,start.x,r.x,
left,right,intersection))
intersection_points.push_back(point(intersection,top));
if(line_intersection(bottom-start.y,r.y,start.x,r.x,
left,right,intersection))
intersection_points.push_back(point(intersection,bottom));
if(start.x> left&&start.x<right&&start.y> bottom&&start.y<top)
intersection_points.push_back(start);
if(end.x> left&&end.x<right&&end.y> bottom&&end.y<top)
intersection_points.push_back(end);
if(intersection_points.empty())return 0.0;
if(intersection_points.size()!=2){
cerr<<"pp3: Funny "<<intersection_points.size()
<<"-fold constellation line intersecrtion."<<endl;
return 0.0;
}
const double length= hypot(intersection_points[1].x-
intersection_points[0].x,
intersection_points[1].y-
intersection_points[0].y);
return(core?8.0*params.penalties_cline:
0.5*params.penalties_cline_rim)/72.27*2.54*length;
}

/*:60*//*61:*/
#line 2101 "pp3.w"

void read_constellation_lines(connections_list&connections,
const stars_list&stars){
ifstream file(params.filename_lines.c_str());
string from_catalogue_name,to_catalogue_name;
int from_catalogue_index= 0,to_catalogue_index= 0;
file>>to_catalogue_name;
while(file){
if(to_catalogue_name[0]=='#'){
string dummy;
getline(file,dummy);
}else if(to_catalogue_name==";")
from_catalogue_index= 0;
else{
file>>to_catalogue_index;
if(from_catalogue_index> 0&&to_catalogue_index> 0){
/*62:*/
#line 2129 "pp3.w"

int from_index= -1,to_index= -1;
for(int i= 0;i<stars.size();i++){
/*63:*/
#line 2154 "pp3.w"


if(from_index==-1)
if(from_catalogue_name=="HD"){
if(stars[i].hd==from_catalogue_index)from_index= i;
}else{
if(from_catalogue_name==stars[i].constellation)
if(stars[i].flamsteed==from_catalogue_index)
from_index= i;
}else if(to_index!=-1)break;

/*:63*/
#line 2132 "pp3.w"

/*64:*/
#line 2169 "pp3.w"


if(to_index==-1)
if(to_catalogue_name=="HD"){
if(stars[i].hd==to_catalogue_index)to_index= i;
}else{
if(to_catalogue_name==stars[i].constellation)
if(stars[i].flamsteed==to_catalogue_index)
to_index= i;
}else if(from_index!=-1)break;


/*:64*/
#line 2133 "pp3.w"

}
if(from_index==-1||to_index==-1){
stringstream error_message;
error_message<<"Unrecognised star in constellation lines: ";
if(from_index==0)
error_message<<from_catalogue_name<<' '
<<from_catalogue_index;
else
error_message<<to_catalogue_name<<' '
<<to_catalogue_index;
throw error_message.str();
}
connections.push_back(connection(from_index,to_index));

/*:62*/
#line 2117 "pp3.w"

}
from_catalogue_name= to_catalogue_name;
from_catalogue_index= to_catalogue_index;
}
file>>to_catalogue_name;
}
}

/*:61*//*67:*/
#line 2246 "pp3.w"

void color::set(ostream&out)const{
out<<"\\newrgbcolor{dummycolor}{"<<red<<' '<<green<<' '<<blue
<<"}\\dummycolor\n  \\psset{linecolor=dummycolor}%\n";
}

/*:67*//*68:*/
#line 2258 "pp3.w"

istream&operator>>(istream&in,color&c){
in>>c.red>>c.green>>c.blue;
if(!in
||c.red<0.0||c.red> 1.0
||c.green<0.0||c.green> 1.0
||c.blue<0.0||c.blue> 1.0)
throw string("Invalid RGB values in input script");
return in;
}

/*:68*//*69:*/
#line 2273 "pp3.w"

ostream&operator<<(ostream&out,const color&c){
if(c.name.empty())throw string("Cannot write unnamed color to stream");
out<<"\\newrgbcolor{"<<c.name<<"}{"<<c.red<<' '<<c.green
<<' '<<c.blue<<"}%\n";
return out;
}

/*:69*//*70:*/
#line 2288 "pp3.w"

color interpolate_colors(const double x,const color c1,const color c2,
const string new_name= ""){
if(x<0.0||x> 1.0)throw string("Invalid x for color interpolation");
const double y= 1.0-x;
return color(new_name,
y*c1.red+x*c2.red,
y*c1.green+x*c2.green,
y*c1.blue+x*c2.blue);
}


/*:70*//*72:*/
#line 2327 "pp3.w"

class transformation{
double width,height,rad_per_cm;
double a[3][3],a_unscaled[3][3];
inline double stretch_factor(double z)const;
public:
transformation(const double rectascension,
const double declination,
const double width,const double height,
const double grad_per_cm);
bool polar_projection(const double rectascension,const double declination,
double&x,double&y)const;
double get_rad_per_cm()const{return rad_per_cm;}
};

/*:72*//*73:*/
#line 2400 "pp3.w"

inline double transformation::stretch_factor(const double z)const{
const double zt= 1.0-z;
return 1.0+zt*
(1.0/3.0+zt*
(2.0/15.0+zt*
(2.0/35.0+zt*
(8.0/315.0+zt*
(8.0/693.0)))));
}

/*:73*//*74:*/
#line 2425 "pp3.w"

transformation::transformation(const double rectascension,
const double declination,
const double width,const double height,
const double grad_per_cm){
const double phi= -(rectascension+12)*15.0*M_PI/180.0;
const double delta= declination*M_PI/180.0;
const double alpha= -delta+M_PI_2;
rad_per_cm= grad_per_cm*M_PI/180.0;
a_unscaled[0][0]= sin(phi);
a_unscaled[0][1]= cos(phi);
a_unscaled[0][2]= 0.0;
a_unscaled[1][0]= cos(phi)*cos(alpha);
a_unscaled[1][1]= -sin(phi)*cos(alpha);
a_unscaled[1][2]= sin(alpha);
a_unscaled[2][0]= -cos(phi)*sin(alpha);
a_unscaled[2][1]= sin(phi)*sin(alpha);
a_unscaled[2][2]= cos(alpha);
for(int i= 0;i<3;i++)
for(int j= 0;j<3;j++)
a[i][j]= a_unscaled[i][j]/rad_per_cm;
transformation::width= width;
transformation::height= height;
}

/*:74*//*75:*/
#line 2459 "pp3.w"

bool transformation::polar_projection(const double rectascension,
const double declination,
double&x,double&y)const{
const double phi= rectascension*15.0*M_PI/180.0;
const double delta= declination*M_PI/180.0;
const double cos_delta= cos(delta);

const double x0= cos_delta*cos(phi);
const double y0= cos_delta*sin(phi);
const double z0= sin(delta);

const double z1= 
a_unscaled[2][0]*x0+a_unscaled[2][1]*y0+a_unscaled[2][2]*z0;
if(z1<-DBL_EPSILON)return false;
const double stretch= stretch_factor(z1);
const double x1= a[0][0]*x0+a[0][1]*y0;
const double y1= a[1][0]*x0+a[1][1]*y0+a[1][2]*z0;
x= x1*stretch+width/2.0;
y= y1*stretch+height/2.0;
if(x<0.0||x> width||y<0.0||y> height)return false;
return true;
}


/*:75*//*77:*/
#line 2507 "pp3.w"

double calculate_overlap(double left1,double right1,double top1,
double bottom1,double left2,double right2,
double top2,double bottom2){
const double overlap_left= fmax(left1,left2);
const double overlap_right= fmin(right1,right2);
const double overlap_top= fmin(top1,top2);
const double overlap_bottom= fmax(bottom1,bottom2);
const double overlap_x= fdim(overlap_right,overlap_left);
const double overlap_y= fdim(overlap_top,overlap_bottom);
return overlap_x*overlap_y;
}

/*:77*//*78:*/
#line 2527 "pp3.w"

struct dimension{
double width,height;
dimension():height(0.0),width(0.0){}
dimension(const dimension&d):width(d.width),height(d.height){}
};

typedef map<string,dimension> dimensions_list;

/*:78*//*79:*/
#line 2544 "pp3.w"

/*117:*/
#line 3797 "pp3.w"

void create_preamble(ostream&out){
out<<"\\documentclass["<<params.font_size<<"pt]{article}\n\n"
<<"\\nofiles"
<<"\\usepackage[dvips]{color}\n"
<<"\\usepackage{pstricks,pst-text}\n"
<<"\\newcommand*{\\Label}[1]{#1}\n"
<<"\\newcommand*{\\TextLabel}[1]{#1}\n"
<<"\\newcommand*{\\FlexLabel}[1]{#1}\n"
<<"\\newcommand*{\\Starname}[1]{#1}\n"
<<"\\newcommand*{\\Messier}[1]{M\\,#1}\n"
<<"\\newcommand*{\\NGC}[1]{NGC\\,#1}\n"
<<"\\newcommand*{\\IC}[1]{IC\\,#1}\n\n";

if(params.filename_preamble.empty())
out<<"\\usepackage{mathptmx}\n"
<<"\\usepackage{helvet}\n"
<<"\\AtBeginDocument{\\sffamily}\n";
else out<<"\\input "<<params.filename_preamble<<'\n';
}

/*:117*/
#line 2545 "pp3.w"

/*85:*/
#line 2752 "pp3.w"

void recalculate_dimensions(dimensions_list&dimensions,
const objects_list&objects)
{
list<string> required_names;
for(int i= 0;i<objects.size();i++){
const string current_name= objects[i]->label;
if(!current_name.empty())required_names.push_back(current_name);
}
required_names.unique();

ofstream temp_file("pp3temp.tex");
create_preamble(temp_file);
temp_file<<"\n\\begin{document}\n"
<<"\\newwrite\\labelsfile\n"
<<"\\catcode`\\_=11  % for underscores in the filename\n"
<<"\\immediate\\openout\\labelsfile=pp3temp.dat\n"
<<"\\catcode`\\_=8\n";
list<string> ::const_iterator p= required_names.begin();
while(p!=required_names.end())
temp_file<<"\\setbox0 = \\vbox{\\hbox{"
<<*(p++)
<<"}\\hrule height 0pt}\n"
<<"  \\immediate\\write\\labelsfile{"
"\\the\\wd0s \\the\\ht0s}\n";
temp_file<<"\\immediate\\closeout\\labelsfile\n\\end{document}\n";
temp_file.close();
string commandline("latex pp3temp");
if(params.filename_output.empty())
commandline+= " > pp3dump.log";
if(system(commandline.c_str())!=0)
throw string("Label dimensions calculations: LaTeX call failed: ")
+commandline;

ifstream raw_labels_file("pp3temp.dat");
ofstream cooked_labels_file("labeldimens.dat");
cooked_labels_file.setf(ios::fixed);
cooked_labels_file.precision(5);
p= required_names.begin();
while(p!=required_names.end()){
string current_width,current_height;
string current_name;
current_name= *(p++);
raw_labels_file>>current_width>>current_height;
current_width.substr(0,current_width.length()-3);
current_height.substr(0,current_height.length()-3);
dimensions[current_name].width= strtod(current_width.c_str(),0)
/72.27*2.54;
dimensions[current_name].height= strtod(current_height.c_str(),0)
/72.27*2.54;
cooked_labels_file<<current_name<<'\n'
<<dimensions[current_name].width
<<' '
<<dimensions[current_name].height
<<'\n';
}
}

/*:85*/
#line 2546 "pp3.w"


void arrange_labels(objects_list&objects,dimensions_list&dimensions){
objects_list vicinity;
/*84:*/
#line 2707 "pp3.w"

bool dimensions_recalculated= false;
for(int i= 0;i<objects.size();i++){
view_data*current_object= objects[i];
if(current_object->with_label==visible){
if(!dimensions_recalculated&&
dimensions.find(current_object->label)==dimensions.end()){
recalculate_dimensions(dimensions,objects);
dimensions_recalculated= true;
if(dimensions.find(current_object->label)==dimensions.end())
throw string("Update of label dimensions file failed: \"")+
current_object->label+"\" not found";
}
current_object->label_width= dimensions[current_object->label].width;
current_object->label_height= 
dimensions[current_object->label].height;
}
}


/*:84*/
#line 2550 "pp3.w"

for(int i= 0;i<objects.size();i++){
vicinity.clear();
if(objects[i]->in_view==visible&&objects[i]->with_label==visible
&&!objects[i]->label_arranged){
/*80:*/
#line 2626 "pp3.w"

const double on_object_scope= objects[i]->scope();
for(int j= 0;j<objects.size();j++){
if(i!=j&&objects[j]->in_view==visible){
const double distance= 
hypot(objects[i]->x-objects[j]->x,
objects[i]->y-objects[j]->y);
if(distance<on_object_scope+objects[j]->scope()&&
/*81:*/
#line 2639 "pp3.w"

(distance> objects[j]->skip||
(objects[j]->with_label==visible&&!objects[j]->label.empty()))

/*:81*/
#line 2634 "pp3.w"
)
vicinity.push_back(objects[j]);
}
}

/*:80*/
#line 2555 "pp3.w"

double best_penalty= DBL_MAX;
int best_angle= 0;
for(int k= 0;k<8;k++){
objects[i]->label_angle= k;
double on_object_left,on_object_right,on_object_top,
on_object_bottom;
objects[i]->
get_label_boundaries(on_object_left,on_object_right,
on_object_top,on_object_bottom);
double penalty= 0.0;
double rim_width= 2.0*objects[i]->skip;
for(int j= 0;j<vicinity.size();j++){
penalty+= vicinity[j]->
penalties_with(on_object_left,on_object_right,
on_object_top,on_object_bottom)+
vicinity[j]->
penalties_with(on_object_left-rim_width,
on_object_right+rim_width,
on_object_top+rim_width,
on_object_bottom-rim_width,
false)*params.penalties_rim;
}
if(on_object_left<0.0||on_object_bottom<0.0||
on_object_right> params.view_frame_width||
on_object_top> params.view_frame_height)
penalty+= 10000.0;
if(penalty<best_penalty){
best_penalty= penalty;
best_angle= k;
}
}
if(!objects[i]->label.empty())
if(best_penalty<0.4*params.penalties_threshold*
objects[i]->label_height*objects[i]->label_width){
objects[i]->label_angle= best_angle;
objects[i]->label_arranged= true;
#ifdef DEBUG
stringstream penalty;
penalty.precision(2);
penalty<<" "<<best_penalty<<" ("
<<best_penalty/
(objects[i]->label_height*objects[i]->label_width)
*100<<"%)";

cerr<<"pp3DEBUG: Object "<<objects[i]->label<<' ';
const star*s= dynamic_cast<star*> (objects[i]);
if(s)cerr<<s->constellation;
cerr<<" has penalty of"<<penalty.str()<<endl;
#endif
}else{
objects[i]->with_label= hidden;
objects[i]->label_arranged= true;
}
}
}
}

/*:79*//*82:*/
#line 2649 "pp3.w"

void print_labels(const objects_list&objects){
for(int i= 0;i<objects.size();i++)
if(objects[i]->in_view==visible&&objects[i]->with_label==visible
&&objects[i]->label_arranged){
double left,right,top,bottom;
objects[i]->get_label_boundaries(left,right,top,bottom);
if(left<0.0||bottom<0.0||right> params.view_frame_width
||top> params.view_frame_height)continue;

objects[i]->label_color.set(OUT);
OUT<<"\\hbox to 0pt{";
OUT<<"\\hskip"<<left<<"cm";
OUT<<"\\vbox to 0pt{\\vss\n  \\hbox{\\Label{";
OUT<<objects[i]->label;
OUT<<"}}\\vskip"<<bottom<<"cm";
OUT<<"\\hrule height 0pt}\\hss}%\n";
#ifdef DEBUG
OUT<<"\\psframe[linewidth=0.3pt]("<<left<<','<<bottom
<<")("<<right<<','<<top<<")%\n";
#endif
}
}

/*:82*//*83:*/
#line 2682 "pp3.w"

void read_label_dimensions(dimensions_list&dimensions){
ifstream file(params.filename_dimensions.c_str());
string name,dummy;
getline(file,name);
while(file){
file>>dimensions[name].width>>dimensions[name].height;
getline(file,dummy);
getline(file,name);
}
}

/*:83*//*86:*/
#line 2817 "pp3.w"

struct text:public view_data{
string contents;
double rectascension,declination;
text(string t,double r,double d,color c,int angle);
};

typedef list<text> texts_list;

/*:86*//*87:*/
#line 2832 "pp3.w"

text::text(string t,double r,double d,color c,int angle)
:contents(t),rectascension(r),declination(d){
label= string("\\TextLabel{")+t+'}';
with_label= visible;
label_angle= angle;
label_arranged= true;
label_color= c;
radius= skip= 0.0;
}

/*:87*//*88:*/
#line 2848 "pp3.w"

void draw_text_labels(transformation&mytransform,texts_list&texts,
objects_list&objects){
texts_list::iterator p= texts.begin();
while(p!=texts.end()){
double x,y;
if(mytransform.polar_projection(p->rectascension,
p->declination,
x,y)){
p->in_view= visible;
p->x= x;
p->y= y;
objects.push_back(&(*p));
}
p++;
}
}

/*:88*//*89:*/
#line 2886 "pp3.w"

struct flex_label:public view_data{
double rectascension,declination;
flex_label(string s,double r,double d,color c,int a);
virtual bool draw(const transformation&mytransform,
dimensions_list&dimensions,objects_list&objects)
const= 0;
};

/*:89*//*90:*/
#line 2900 "pp3.w"

flex_label::flex_label(string s,double r,double d,color c,int a)
:rectascension(r),declination(d){
label_color= c;
label= string("\\FlexLabel{")+s+'}';
label_angle= a;
in_view= visible;
with_label= hidden;
label_arranged= true;
}

typedef list<flex_label*> flexes_list;

/*:90*//*91:*/
#line 2916 "pp3.w"

struct declination_flex:public flex_label{
declination_flex(string s,double r,double d,color c,int a)
:flex_label(s,r,d,c,a){}
virtual bool draw(const transformation&mytransform,
dimensions_list&dimensions,objects_list&objects)
const;
virtual double penalties_with(const double left,const double right,
const double top,const double bottom,
bool core= true)const;
};

/*:91*//*92:*/
#line 2944 "pp3.w"

bool declination_flex::draw(const transformation&mytransform,
dimensions_list&dimensions,
objects_list&objects)const{
if(dimensions.find(label)==dimensions.end())
recalculate_dimensions(dimensions,objects);
if(dimensions.find(label)==dimensions.end())
throw string("Update of label dimensions file failed: \"")+
label+"\" not found";
const double label_width= dimensions[label].width;
const double label_height= dimensions[label].height;
const double rectascension_halfwidth= label_width
*mytransform.get_rad_per_cm()*180.0/M_PI/15.0
/cos(declination*M_PI/180.0)/2.0;
char justification;
double path_point_rectascension[3];
path_point_rectascension[0]= rectascension;
path_point_rectascension[1]= rectascension-rectascension_halfwidth;
path_point_rectascension[2]= rectascension-
2.0*rectascension_halfwidth;
switch(label_angle){
case 0:case 1:case 7:
justification= 'l';
break;
case 2:case 6:
justification= 'c';
for(int i= 0;i<3;i++)
path_point_rectascension[i]+= rectascension_halfwidth;
break;
case 3:case 4:case 5:
justification= 'r';
for(int i= 0;i<3;i++)
path_point_rectascension[i]+= 2.0*rectascension_halfwidth;
break;
}
double lower;
switch(label_angle){
case 0:case 4:lower= -0.4;break;
case 1:case 2:case 3:lower= 0.0;break;
case 5:case 6:case 7:lower= -0.8;break;
}
double x[3],y[3];
for(int i= 0;i<3;i++)
if(!mytransform.polar_projection(path_point_rectascension[i],
declination,x[i],y[i]))
return false;

label_color.set(OUT);
OUT<<"\\FlexLabel{\\pstextpath["<<justification
<<"](0,"<<lower<<"em){\\pscurve[linestyle=none]%\n  ";
for(int i= 0;i<3;i++)
OUT<<'('<<x[i]<<"cm,"<<y[i]<<"cm)";
OUT<<"}{\\dummycolor"<<label<<"}}%\n";

return true;
}

/*:92*//*93:*/
#line 3004 "pp3.w"

double declination_flex::penalties_with(const double left,const double right,
const double top,const double bottom,
bool core)const{
return 0.0;
}

/*:93*//*94:*/
#line 3019 "pp3.w"

void draw_flex_labels(const transformation&mytransform,
const flexes_list&flexes,objects_list&objects,
dimensions_list&dimensions){
flexes_list::const_iterator p= flexes.begin();
while(p!=flexes.end())objects.push_back(*p++);
p= flexes.begin();
while(p!=flexes.end())(*p++)->draw(mytransform,dimensions,objects);
}

/*:94*//*95:*/
#line 3044 "pp3.w"

/*96:*/
#line 3095 "pp3.w"

void create_hs_colour(double b_v,string spectral_class){
double hue,saturation;
const double bv0= -0.1,bv1= 0.001,bv2= 0.62,bv3= 1.7;
const double hue0= 0.6,hue1= 0.47,hue2= 0.17,hue3= 0.0;
const double min_saturation= 0.0,max_saturation= 0.2;
/*97:*/
#line 3130 "pp3.w"

if(b_v> 90.0){
switch(spectral_class[0]){
case'O':b_v= 0.0;break;
case'B':b_v= -0.07;break;
case'A':b_v= 0.11;break;
case'F':b_v= 0.43;break;
case'G':b_v= 0.89;break;
case'K':b_v= 1.24;break;
case'M':b_v= 1.62;break;
case'N':b_v= 2.88;break;
case'S':b_v= 1.84;break;
case'C':b_v= 3.02;break;
default:b_v= 0.0;break;
}
}


/*:97*/
#line 3101 "pp3.w"

if(b_v<bv0)b_v= bv0;
if(b_v> bv3)b_v= bv3;
if(b_v<bv1){
hue= (b_v-bv0)/(bv1-bv0)
*(hue1-hue0)+hue0;
saturation= (b_v-bv0)/(bv1-bv0)
*(min_saturation-max_saturation)+max_saturation;
}
else if(b_v<bv2){
hue= 0.3;
saturation= 0;
}
else{
hue= (b_v-bv2)/(bv3-bv2)
*(hue3-hue2)+hue2;
saturation= (b_v-bv2)/(bv3-bv2)
*(max_saturation-min_saturation)+min_saturation;
}
OUT<<hue<<' '<<saturation;
}

/*:96*/
#line 3045 "pp3.w"


void draw_stars(const transformation&mytransform,stars_list&stars,
objects_list&objects){
for(int i= 0;i<stars.size();i++)
if(stars[i].in_view!=hidden&&
stars[i].magnitude<params.faintest_star_magnitude){

if(mytransform.polar_projection(stars[i].rectascension,
stars[i].declination,
stars[i].x,stars[i].y)){
stars[i].in_view= visible;
const double m_dot= params.faintest_star_disk_magnitude;
const double r_min= params.minimal_star_radius/
params.star_scaling;
stars[i].radius= params.star_scaling*
(stars[i].magnitude<m_dot?
sqrt((m_dot-stars[i].magnitude)/300.0+r_min*r_min)
:r_min);
if(stars[i].with_label==undecided)
stars[i].with_label= 
(stars[i].magnitude<
params.faintest_star_with_label_magnitude&&
!stars[i].name.empty())?visible:hidden;
if(params.colored_stars){
OUT<<"\\newhsbcolor{starcolor}{";
create_hs_colour(stars[i].b_v,stars[i].spectral_class);
OUT<<" 1}%\n";
}else OUT<<params.starcolor;
OUT<<"\\pscircle*[linecolor=starcolor]("
<<stars[i].x<<","
<<stars[i].y<<"){"
<<stars[i].radius/2.54*72.27<<"pt}%\n";
objects.push_back(&stars[i]);
}else stars[i].in_view= hidden;
}else stars[i].in_view= stars[i].with_label= hidden;
}

/*:95*//*98:*/
#line 3172 "pp3.w"

void draw_nebulae(const transformation&mytransform,nebulae_list&nebulae,
objects_list&objects){
OUT<<"\\psset{linecolor=nebulacolor,linewidth="
<<params.linewidth_nebula<<"cm,linestyle="
<<params.linestyle_nebula<<",curvature=1 .5 -1}%\n";
for(int i= 0;i<nebulae.size();i++)
if(nebulae[i].in_view==visible||
(nebulae[i].in_view==undecided&&
(((nebulae[i].kind==open_cluster||
nebulae[i].kind==globular_cluster)
&&nebulae[i].magnitude<params.faintest_cluster_magnitude)
||
((nebulae[i].kind==galaxy||nebulae[i].kind==reflection||
nebulae[i].kind==emission)&&
nebulae[i].magnitude<params.faintest_diffuse_nebula_magnitude)
||
nebulae[i].messier> 0))){
if(mytransform.polar_projection(nebulae[i].rectascension,
nebulae[i].declination,
nebulae[i].x,nebulae[i].y)){
nebulae[i].in_view= visible;
if(nebulae[i].horizontal_angle> 360.0)
nebulae[i].diameter_x= nebulae[i].diameter_y= 
sqrt(nebulae[i].diameter_x*nebulae[i].diameter_y);
nebulae[i].radius= nebulae[i].diameter_x/2.0/
mytransform.get_rad_per_cm()*M_PI/180.0;
if(nebulae[i].with_label!=hidden)
nebulae[i].with_label= visible;
if(nebulae[i].radius> params.minimal_nebula_radius){
/*99:*/
#line 3229 "pp3.w"

if(nebulae[i].diameter_x==nebulae[i].diameter_y)
OUT<<"\\pscircle("<<nebulae[i].x<<','<<nebulae[i].y
<<"){"<<nebulae[i].radius<<"}%\n";
else{
double rectascension[4],declination[4];
const double r_scale= 1.0/cos(nebulae[i].declination*M_PI/180.0);
const double cos_angle
= cos(nebulae[i].horizontal_angle*M_PI/180.0);
const double sin_angle
= sin(nebulae[i].horizontal_angle*M_PI/180.0);
const double half_x= nebulae[i].diameter_x/2.0;
const double half_y= nebulae[i].diameter_y/2.0;
rectascension[0]= nebulae[i].rectascension-
half_x*cos_angle/15.0*r_scale;
declination[0]= nebulae[i].declination-
half_x*sin_angle;
rectascension[1]= nebulae[i].rectascension+
half_y*sin_angle/15.0*r_scale;
declination[1]= nebulae[i].declination-
half_y*cos_angle;
rectascension[2]= nebulae[i].rectascension+
half_x*cos_angle/15.0*r_scale;
declination[2]= nebulae[i].declination+
half_x*sin_angle;
rectascension[3]= nebulae[i].rectascension-
half_y*sin_angle/15.0*r_scale;
declination[3]= nebulae[i].declination+
half_y*cos_angle;
OUT<<"\\psccurve";
for(int j= 0;j<4;j++){
double x,y;
mytransform.polar_projection(rectascension[j],
declination[j],x,y);
OUT<<'('<<x<<','<<y<<')';
}
}
OUT<<"\\relax\n";


/*:99*/
#line 3202 "pp3.w"

}else{
nebulae[i].radius= params.minimal_nebula_radius;
OUT<<"\\pscircle("
<<nebulae[i].x<<","
<<nebulae[i].y<<"){"
<<nebulae[i].radius/2.54*72.27<<"pt}%\n";
}
objects.push_back(&nebulae[i]);
}else nebulae[i].in_view= hidden;
}else nebulae[i].in_view= nebulae[i].with_label= hidden;
}

/*:98*//*101:*/
#line 3299 "pp3.w"

inline void add_curve_point(const double rectascension,
const double declination,
const transformation&transform,
const int i,bool&within_curve,
const int steps){
static double last_x,last_y;
double x,y;
if(transform.polar_projection(rectascension,declination,x,y)){
if(!within_curve){
OUT<<"\\pscurve"<<"("<<x<<','<<y<<")";
within_curve= true;
}else if(i%steps==0)OUT<<"("<<x<<','<<y<<")";
if(i%(steps*4)==0||steps==1)OUT<<"%\n";

}else
if(within_curve){
OUT<<"("<<last_x<<','<<last_y<<")"<<"\\relax\n";
within_curve= false;
}
last_x= x;last_y= y;
}

/*:101*//*102:*/
#line 3344 "pp3.w"

void create_grid(const transformation transform,
const double scans_per_cm= 10,
const double point_distance= 5.0){
if(!params.show_grid&&!params.show_ecliptic)return;
const double scans_per_fullcircle= 
scans_per_cm/transform.get_rad_per_cm()*2.0*M_PI;
const int steps= int((point_distance*M_PI/180.0)*
(scans_per_fullcircle/(2.0*M_PI)))+2;
bool within_curve;
if(params.show_grid){
OUT<<"\\psset{linestyle="<<params.linestyle_grid
<<",linecolor=gridcolor,linewidth="
<<params.linewidth_grid<<"cm}%\n";
/*103:*/
#line 3374 "pp3.w"

for(int declination= -80;declination<=80;declination+= 10){
if(declination==0)
OUT<<"\\psset{linewidth="<<2.0*params.linewidth_grid
<<"cm}%\n";
within_curve= false;
const int number_of_points= 
int(cos(declination*M_PI/180.0)*scans_per_fullcircle);
for(int i= 0;i<=number_of_points;i++)
add_curve_point(double(i)/double(number_of_points)*24.0,
declination,transform,i,within_curve,
i==number_of_points?1:steps);
if(declination==0)
OUT<<"\\psset{linewidth="<<params.linewidth_grid<<"cm}%\n";
}

/*:103*/
#line 3358 "pp3.w"

/*104:*/
#line 3394 "pp3.w"

const int number_of_points= int(scans_per_fullcircle/2.0);
for(int rectascension= 0;rectascension<=23;rectascension++){
within_curve= false;
for(int i= 0;i<=number_of_points;i++)
add_curve_point(double(rectascension),
double(i)/double(number_of_points)*160.0-80.0,
transform,i,within_curve,
i==number_of_points?1:steps);
}

/*:104*/
#line 3359 "pp3.w"

}
if(params.show_ecliptic){
/*105:*/
#line 3422 "pp3.w"

OUT<<"\\psset{linestyle="<<params.linestyle_ecliptic
<<",linecolor=eclipticcolor,"
<<"linewidth="<<params.linewidth_ecliptic<<"cm}%\n";
{
const double epsilon= 23.44*M_PI/180.0;
const int number_of_points= int(scans_per_fullcircle);
within_curve= false;
for(int i= 0;i<=number_of_points;i++){
const double phi0= double(i)/double(number_of_points)*2.0*M_PI;
const double m_sin_phi0= -sin(phi0);
const double phi= atan2(m_sin_phi0*cos(epsilon),cos(phi0));
const double delta= asin(m_sin_phi0*sin(epsilon));
add_curve_point(phi*12.0/M_PI,delta*180.0/M_PI,
transform,i,within_curve,
i==number_of_points?1:steps);
}
}

/*:105*/
#line 3362 "pp3.w"

}
}

/*:102*//*107:*/
#line 3461 "pp3.w"

void draw_boundary_line(const boundary&b,const transformation&transform,
objects_list&objects,bool highlighted= false){
vector<point> current_line;
for(int j= 0;j<b.points.size();j++){
const double rectascension= b.points[j].x;
const double declination= b.points[j].y;
double x,y;
if(!transform.polar_projection(rectascension,declination,x,y))
continue;
current_line.push_back(point(x,y));
}
if(current_line.size()>=2){
if(current_line.size()==2)OUT<<"\\psline";
else OUT<<"\\pscurve";
OUT<<"[liftpen=2]{c-c}";
for(int j= 0;j<current_line.size();j++){
OUT<<'('<<current_line[j].x<<','
<<current_line[j].y<<')';
if(j%4==3)OUT<<"%\n";
if(highlighted)
/*108:*/
#line 3493 "pp3.w"

if(j> 0)objects.push_back(new boundary_atom(current_line[j],
current_line[j-1]));

/*:108*/
#line 3482 "pp3.w"

}
OUT<<"\\relax\n";
}
}

/*:107*//*109:*/
#line 3509 "pp3.w"

void draw_boundaries(const transformation&mytransform,
boundaries_list&boundaries,
objects_list&objects,
string constellation= string("")){
OUT<<"\\psset{linecolor=boundarycolor,linewidth="
<<params.linewidth_boundary<<"cm,"
<<"linestyle="<<params.linestyle_boundary<<"}%\n";
if(!constellation.empty()){
for(int i= 0;i<boundaries.size();i++)
if(!boundaries[i].belongs_to_constellation(constellation))
draw_boundary_line(boundaries[i],mytransform,objects);
OUT<<"\\psset{linecolor=hlboundarycolor,linewidth="
<<params.linewidth_boundary<<"cm,"<<"linestyle="
<<params.linestyle_hlboundary<<"}%\n";
OUT<<"\\pscustom{";
for(int i= 0;i<boundaries.size();i++)
if(boundaries[i].belongs_to_constellation(constellation))
draw_boundary_line(boundaries[i],mytransform,objects,true);
OUT<<"}%\n";
}else
for(int i= 0;i<boundaries.size();i++)
draw_boundary_line(boundaries[i],mytransform,objects);
}

/*:109*//*110:*/
#line 3551 "pp3.w"

void draw_constellation_lines(connections_list&connections,
const stars_list&stars,
objects_list&objects){
OUT<<"\\psset{linecolor=clinecolor,linestyle="<<params.linestyle_cline
<<",linewidth="<<params.linewidth_cline<<"cm}%\n";
for(int i= 0;i<connections.size();i++)
if((stars[connections[i].from].in_view==visible||
stars[connections[i].to].in_view==visible)
&&stars[connections[i].from].has_valid_coordinates()
&&stars[connections[i].to].has_valid_coordinates()){
double x1= stars[connections[i].from].x;
double y1= stars[connections[i].from].y;
double x2= stars[connections[i].to].x;
double y2= stars[connections[i].to].y;
const double phi= atan2(y2-y1,x2-x1);
double r= hypot(x2-x1,y2-y1);
double skip;
skip= stars[connections[i].from].radius+
stars[connections[i].from].skip;
r-= skip;
x1+= skip*cos(phi);
y1+= skip*sin(phi);
skip= stars[connections[i].to].radius+
stars[connections[i].to].skip;
r-= skip;
x2-= skip*cos(phi);
y2-= skip*sin(phi);
connections[i].radius= r/2.0;
connections[i].x= (x1+x2)/2.0;
connections[i].y= (y1+y2)/2.0;
if(r> params.shortest_constellation_line&&r> 0.0){
OUT<<"\\psline{cc-cc}("<<x1<<','<<y1
<<")("<<x2<<','<<y2<<")%\n";
connections[i].start= point(x1,y1);
connections[i].end= point(x2,y2);
objects.push_back(&connections[i]);
}
}

}


/*:110*//*111:*/
#line 3602 "pp3.w"

void draw_milky_way(const transformation&mytransform){
vector<vector<point> > pixels(256);
/*65:*/
#line 2202 "pp3.w"

ifstream file(params.filename_milkyway.c_str());
double radius;
file>>radius;
double rectascension,declination,x,y;
int pixel;
const double cm_per_grad= 1.0/
(mytransform.get_rad_per_cm()*180.0/M_PI);
radius*= cm_per_grad/2.54*72.27;
file>>rectascension>>declination>>pixel;
while(file){
if(mytransform.polar_projection(rectascension,declination,x,y))
pixels[pixel].push_back(point(x,y));
file>>rectascension>>declination>>pixel;
}


/*:65*/
#line 3605 "pp3.w"

for(int i= 1;i<pixels.size();i++){
if(pixels[i].size()==0)continue;
interpolate_colors(double(i)/255.0,params.bgcolor,
params.milkywaycolor).set(OUT);
for(int j= 0;j<pixels[i].size();j++)
OUT<<"\\qdisk("<<pixels[i][j].x<<","<<pixels[i][j].y
<<"){"<<radius<<"pt}%\n";
}
}


/*:111*//*112:*/
#line 3632 "pp3.w"

/*9:*/
#line 472 "pp3.w"

bool read_boolean(istream&script){
string boolean;
script>>boolean;
if(boolean=="on")return true;
else if(boolean=="off")return false;
else throw string("Expected \"on\" or \"off\" in \"switch\" construct "
"in input script");
}

/*:9*//*10:*/
#line 494 "pp3.w"

string read_string(istream&script){
const string UnexpectedEOS("Unexpected end of input script while reading a"
" string parameter");
char c;
string contents;
while(script.get(c))if(!isspace(c))break;
if(!script)throw UnexpectedEOS;
if(c!='"'){
script>>contents;
if(script)contents.insert(contents.begin(),c);else contents= c;
}else{
while(script.get(c)){
if(c=='"')break;
if(c=='\\'){
if(!script.get(c))
throw UnexpectedEOS;
switch(c){
case'\\':case'"':contents+= c;break;
default:throw string("Unknown escape sequence in string");
}
}else contents+= c;
}
if(!script)
throw UnexpectedEOS;
}
return contents;
}

/*:10*//*11:*/
#line 535 "pp3.w"

void read_parameters_from_script(istream&script){
string opcode;
script>>opcode;
while(opcode!="objects_and_labels"&&script){
if(opcode[0]=='#'){
string rest_of_line;
getline(script,rest_of_line);
}else
/*12:*/
#line 585 "pp3.w"

if(opcode=="color"){
string color_name;
script>>color_name;
if(color_name=="background")script>>params.bgcolor;
else if(color_name=="grid")script>>params.gridcolor;
else if(color_name=="ecliptic")script>>params.eclipticcolor;
else if(color_name=="boundaries")
script>>params.boundarycolor;
else if(color_name=="highlighted_boundaries")
script>>params.hlboundarycolor;
else if(color_name=="stars")script>>params.starcolor;
else if(color_name=="nebulae")script>>params.nebulacolor;
else if(color_name=="labels")script>>params.labelcolor;
else if(color_name=="text_labels")
script>>params.textlabelcolor;
else if(color_name=="constellation_lines")
script>>params.clinecolor;
else if(color_name=="milky_way")script>>params.milkywaycolor;
else throw string("Undefined \"color\" construct"
" in input script: \"")+color_name+'"';
}

/*:12*/
#line 544 "pp3.w"

else
/*13:*/
#line 621 "pp3.w"

if(opcode=="line_width"){
string line_name;
script>>line_name;
if(line_name=="grid")script>>params.linewidth_grid;
else if(line_name=="ecliptic")
script>>params.linewidth_ecliptic;
else if(line_name=="boundaries")
script>>params.linewidth_boundary;
else if(line_name=="highlighted_boundaries")
script>>params.linewidth_hlboundary;
else if(line_name=="nebulae")
script>>params.linewidth_nebula;
else if(line_name=="constellation_lines")
script>>params.linewidth_cline;
else throw string("Undefined \"line_width\" construct"
" in input script: \"")+line_name+'"';
}

/*:13*/
#line 546 "pp3.w"

else
/*14:*/
#line 657 "pp3.w"

if(opcode=="line_style"){
string line_name;
script>>line_name;
if(line_name=="grid")script>>params.linestyle_grid;
else if(line_name=="ecliptic")
script>>params.linestyle_ecliptic;
else if(line_name=="boundaries")
script>>params.linestyle_boundary;
else if(line_name=="highlighted_boundaries")
script>>params.linestyle_hlboundary;
else if(line_name=="nebulae")
script>>params.linestyle_nebula;
else if(line_name=="constellation_lines")
script>>params.linestyle_cline;
else throw string("Undefined \"line_width\" construct"
" in input script: \"")+line_name+'"';
}


/*:14*/
#line 548 "pp3.w"

else
/*15:*/
#line 695 "pp3.w"

if(opcode=="switch"){
string switch_name;
script>>switch_name;
if(switch_name=="milky_way")
params.milkyway_visible= read_boolean(script);
else if(switch_name=="colored_stars")
params.colored_stars= read_boolean(script);
else if(switch_name=="grid")
params.show_grid= read_boolean(script);
else if(switch_name=="ecliptic")
params.show_ecliptic= read_boolean(script);
else if(switch_name=="boundaries")
params.show_boundaries= read_boolean(script);
else if(switch_name=="constellation_lines")
params.show_lines= read_boolean(script);
else if(switch_name=="labels")
params.show_labels= read_boolean(script);
else if(switch_name=="eps_output")
params.create_eps= read_boolean(script);
else if(switch_name=="pdf_output")
params.create_pdf= read_boolean(script);
else throw string("Undefined \"switch\" construct"
" in input script: \"")+switch_name+'"';
}

/*:15*/
#line 550 "pp3.w"

else
/*16:*/
#line 761 "pp3.w"

if(opcode=="penalties"){
string penalty_name;
double value;
script>>penalty_name>>value;
value/= 1000.0;
if(penalty_name=="stars")
params.penalties_star= value;
else if(penalty_name=="labels")
params.penalties_label= value;
else if(penalty_name=="nebulae")
params.penalties_nebula= value;
else if(penalty_name=="boundaries")
params.penalties_boundary= value;
else if(penalty_name=="boundaries_rim")
params.penalties_boundary_rim= value;
else if(penalty_name=="constellation_lines")
params.penalties_cline= value;
else if(penalty_name=="constellation_lines_rim")
params.penalties_cline_rim= value;
else if(penalty_name=="threshold")
params.penalties_threshold= value;
else if(penalty_name=="rim")
params.penalties_rim= value;
else throw string("Undefined \"penalties\" construct"
" in input script: \"")+penalty_name+'"';
}

/*:16*/
#line 552 "pp3.w"

else
/*17:*/
#line 825 "pp3.w"

if(opcode=="filename"){
string object_name;
script>>object_name;
if(object_name=="output")
params.filename_output= read_string(script);
else if(object_name=="stars")
params.filename_stars= read_string(script);
else if(object_name=="nebulae")
params.filename_nebulae= read_string(script);
else if(object_name=="label_dimensions")
params.filename_dimensions= read_string(script);
else if(object_name=="constellation_lines")
params.filename_lines= read_string(script);
else if(object_name=="boundaries")
params.filename_boundaries= read_string(script);
else if(object_name=="milky_way")
params.filename_milkyway= read_string(script);
else if(object_name=="latex_preamble")
params.filename_preamble= read_string(script);
else if(object_name=="include"){
if(!params.filename_include.empty())
throw string("Nesting depth of include files greater"
" than one");
params.filename_include= read_string(script);
ifstream included_script(params.filename_include.c_str());
read_parameters_from_script(included_script);
}
else throw string("Undefined \"filename\" construct"
" in input script: \"")+object_name+'"';
}


/*:17*/
#line 554 "pp3.w"

else
/*18:*/
#line 915 "pp3.w"

if(opcode=="set"){
string param_name;
script>>param_name;
if(param_name=="center_rectascension")
script>>params.center_rectascension;
else if(param_name=="center_declination")
script>>params.center_declination;
else if(param_name=="box_width")
script>>params.view_frame_width;
else if(param_name=="box_height")
script>>params.view_frame_height;
else if(param_name=="grad_per_cm")
script>>params.grad_per_cm;
else if(param_name=="constellation")
params.constellation= read_string(script);
else if(param_name=="shortest_constellation_line")
script>>params.shortest_constellation_line;
else if(param_name=="label_skip")
script>>params.label_skip;
else if(param_name=="minimal_nebula_radius")
script>>params.minimal_nebula_radius;
else if(param_name=="faintest_cluster_magnitude")
script>>params.faintest_cluster_magnitude;
else if(param_name=="faintest_diffuse_nebula_magnitude")
script>>params.faintest_diffuse_nebula_magnitude;
else if(param_name=="faintest_star_magnitude")
script>>params.faintest_star_magnitude;
else if(param_name=="minimal_star_radius")
script>>params.minimal_star_radius;
else if(param_name=="faintest_star_disk_magnitude")
script>>params.faintest_star_disk_magnitude;
else if(param_name=="faintest_star_with_label_magnitude")
script>>params.faintest_star_with_label_magnitude;
else if(param_name=="star_scaling")
script>>params.star_scaling;
else if(param_name=="fontsize")
script>>params.font_size;
else
throw string("Undefined \"set\" construct in input script: \"")
+param_name+'"';
}

/*:18*/
#line 556 "pp3.w"

else throw string("Undefined opcode in input script: \"")
+opcode+'"';
script>>opcode;
}
}

/*:11*//*19:*/
#line 966 "pp3.w"

typedef map<int,int> index_list;

/*:19*//*21:*/
#line 1009 "pp3.w"

bool assure_valid_catalogue_index(const int index,const index_list&catalogue,
const string catalogue_name){
if(catalogue.find(index)==catalogue.end()){
cerr<<"pp3: Warning: Invalid "<<catalogue_name<<" index: "
<<index<<".\n";
return false;
}else return true;
}

bool assure_valid_catalogue_index(const int index,
const string constellation,
map<string,index_list> &flamsteed){
bool found= true;
if(flamsteed.find(constellation)==flamsteed.end())found= false;
else if(flamsteed[constellation].find(index)==
flamsteed[constellation].end())found= false;
if(!found)cerr<<"pp3: Warning: Invalid Flamsteed number: "
<<index<<".\n";
return found;
}

bool assure_valid_catalogue_index(const int index,
const index_list&henry_draper){
if(henry_draper.find(index)==henry_draper.end()){
cerr<<"pp3: Warning: Invalid HD number: "
<<index<<".\n";
return false;
}else return true;
}

/*:21*//*22:*/
#line 1047 "pp3.w"

void search_objects(istream&script,
index_list&ngc,index_list&ic,
index_list&messier,index_list&henry_draper,
map<string,index_list> &flamsteed,
vector<int> &found_stars,vector<int> &found_nebulae){
found_stars.clear();
found_nebulae.clear();
string catalogue_name;
int catalogue_index;
script>>catalogue_name;
while(script&&catalogue_name!=";"){
script>>catalogue_index;
if(catalogue_index<=0){
stringstream error_message;
error_message<<"Invalid index: "<<catalogue_index;
throw error_message.str();
}
if(!script)throw string("Unexpected end of input script");
if(catalogue_name=="NGC"){
if(assure_valid_catalogue_index(catalogue_index,ngc,"NGC"))
found_nebulae.push_back(ngc[catalogue_index]);
}else if(catalogue_name=="IC"){
if(assure_valid_catalogue_index(catalogue_index,ic,"IC"))
found_nebulae.push_back(ic[catalogue_index]);
}else if(catalogue_name=="M"){
if(assure_valid_catalogue_index(catalogue_index,messier,"M"))
found_nebulae.push_back(messier[catalogue_index]);
}else if(catalogue_name=="HD"){
if(assure_valid_catalogue_index(catalogue_index,henry_draper))
found_stars.push_back(henry_draper[catalogue_index]);
}else{
if(assure_valid_catalogue_index(catalogue_index,
catalogue_name,flamsteed))
found_stars.
push_back(flamsteed[catalogue_name][catalogue_index]);
}
script>>catalogue_name;
}
}

/*:22*//*23:*/
#line 1094 "pp3.w"

view_data*identify_object(istream&script,index_list&ngc,
index_list&ic,index_list&messier,
index_list&henry_draper,
map<string,index_list> &flamsteed,
stars_list&stars,nebulae_list&nebulae){
string catalogue_name;
int catalogue_index;
script>>catalogue_name>>catalogue_index;
if(!script)throw string("Unexpected end of input script");
if(catalogue_name=="NGC"){
if(assure_valid_catalogue_index(catalogue_index,ngc,"NGC"))
return&nebulae[ngc[catalogue_index]];
}else if(catalogue_name=="IC"){
if(assure_valid_catalogue_index(catalogue_index,ic,"IC"))
return&nebulae[ic[catalogue_index]];
}else if(catalogue_name=="M"){
if(assure_valid_catalogue_index(catalogue_index,messier,"M"))
return&nebulae[messier[catalogue_index]];
}else if(catalogue_name=="HD"){
if(assure_valid_catalogue_index(catalogue_index,henry_draper))
return&stars[henry_draper[catalogue_index]];
}else{
if(assure_valid_catalogue_index(catalogue_index,
catalogue_name,flamsteed))
return&stars[flamsteed[catalogue_name][catalogue_index]];
}
return 0;
}

/*:23*//*24:*/
#line 1137 "pp3.w"

void read_objects_and_labels(istream&script,
const dimensions_list&dimensions,
objects_list&objects,stars_list&stars,
nebulae_list&nebulae,
texts_list&texts,
flexes_list&flexes,
const transformation&mytransform,
bool included= false){
if(!params.filename_include.empty()&&!included){
ifstream included_file(params.filename_include.c_str());
/*25:*/
#line 1193 "pp3.w"

string token;
included_file>>token;
while(included_file){
if(token[0]=='#')getline(included_file,token);
else if(token=="objects_and_labels")break;
included_file>>token;
}


/*:25*/
#line 1148 "pp3.w"

read_objects_and_labels(included_file,dimensions,objects,stars,
nebulae,texts,flexes,mytransform,true);
}
string opcode;
script>>opcode;
if(!script)return;
/*20:*/
#line 980 "pp3.w"

const int max_ngc= 7840,max_ic= 5386,max_messier= 110;
index_list ngc,ic,messier;
for(int i= 0;i<nebulae.size();i++){
if(nebulae[i].ngc> 0&&nebulae[i].ngc<=max_ngc)
ngc[nebulae[i].ngc]= i;
if(nebulae[i].ic> 0&&nebulae[i].ic<=max_ic)
ic[nebulae[i].ic]= i;
if(nebulae[i].messier> 0&&nebulae[i].messier<=max_messier)
messier[nebulae[i].messier]= i;
}
index_list henry_draper;
map<string,index_list> flamsteed;
for(int i= 0;i<stars.size();i++){
if(stars[i].hd> 0)henry_draper[stars[i].hd]= i;
if(stars[i].flamsteed> 0)
flamsteed[stars[i].constellation][stars[i].flamsteed]= i;
}


/*:20*/
#line 1155 "pp3.w"

while(script){
if(opcode[0]=='#'){
string rest_of_line;
getline(script,rest_of_line);
}else
/*26:*/
#line 1214 "pp3.w"

if(opcode=="reposition"){
string position,semicolon;
view_data*current_object= 
identify_object(script,ngc,ic,messier,henry_draper,
flamsteed,stars,nebulae);
int angle;
script>>position>>semicolon;
if(semicolon!=";")
throw string("Expected \";\" after \"reposition\" command");
/*27:*/
#line 1232 "pp3.w"

if(position=="E")angle= 0;
else if(position=="NE")angle= 1;
else if(position=="N")angle= 2;
else if(position=="NW")angle= 3;
else if(position=="W")angle= 4;
else if(position=="SW")angle= 5;
else if(position=="S")angle= 6;
else if(position=="SE")angle= 7;
else throw string("Undefined position angle: ")+position;

/*:27*/
#line 1224 "pp3.w"

if(current_object){
current_object->label_angle= angle;
current_object->with_label= visible;
current_object->label_arranged= true;
}
}

/*:26*/
#line 1161 "pp3.w"

else
/*28:*/
#line 1247 "pp3.w"

if(opcode=="set_label_text"){
view_data*current_object= 
identify_object(script,ngc,ic,messier,henry_draper,
flamsteed,stars,nebulae);
if(current_object)current_object->label= read_string(script);
}


/*:28*/
#line 1163 "pp3.w"

else
/*33:*/
#line 1346 "pp3.w"

if(opcode=="text"){
string token,contents,position("NE");
double rectascension,declination;
contents= read_string(script);
script>>token;
if(token!="at")throw string("\"at\" in \"text\" command expected");
script>>rectascension>>declination;
script>>token;
int angle= 1;
enum{kind_text_label,kind_flex_declination}label_kind
= kind_text_label;
while(script&&token!=";"){
if(token=="color")script>>params.textlabelcolor;
else if(token=="towards"){
script>>position;
/*27:*/
#line 1232 "pp3.w"

if(position=="E")angle= 0;
else if(position=="NE")angle= 1;
else if(position=="N")angle= 2;
else if(position=="NW")angle= 3;
else if(position=="W")angle= 4;
else if(position=="SW")angle= 5;
else if(position=="S")angle= 6;
else if(position=="SE")angle= 7;
else throw string("Undefined position angle: ")+position;

/*:27*/
#line 1362 "pp3.w"

}
else if(token=="along"){
script>>token;
if(token=="declination"){
label_kind= kind_flex_declination;
}else throw string("Invalid \"along\" option");
}else throw string("Invalid \"text\" option");
script>>token;
}
if(!script)
throw string("Unexpected end of script while scanning \"text\"");
switch(label_kind){
case kind_text_label:
texts.push_back(text(contents,rectascension,declination,
params.textlabelcolor,angle));
break;
case kind_flex_declination:
flexes.push_back(new declination_flex(contents,rectascension,
declination,
params.textlabelcolor,angle));
break;
}
}


/*:33*/
#line 1165 "pp3.w"

else{
vector<int> found_stars,found_nebulae;
/*29:*/
#line 1259 "pp3.w"

if(opcode=="delete_labels"){
search_objects(script,ngc,ic,messier,henry_draper,
flamsteed,found_stars,found_nebulae);
for(int i= 0;i<found_stars.size();i++){
stars[found_stars[i]].with_label= hidden;
stars[found_stars[i]].label_arranged= true;
}
for(int i= 0;i<found_nebulae.size();i++){
nebulae[found_nebulae[i]].with_label= hidden;
nebulae[found_nebulae[i]].label_arranged= false;
}
}

/*:29*/
#line 1168 "pp3.w"

else
/*30:*/
#line 1277 "pp3.w"

if(opcode=="add_labels"){
search_objects(script,ngc,ic,messier,henry_draper,
flamsteed,found_stars,found_nebulae);
for(int i= 0;i<found_stars.size();i++)
stars[found_stars[i]].with_label= visible;
for(int i= 0;i<found_nebulae.size();i++)
nebulae[found_nebulae[i]].with_label= visible;
}

/*:30*/
#line 1170 "pp3.w"

else
/*32:*/
#line 1302 "pp3.w"

if(opcode=="delete"){
search_objects(script,ngc,ic,messier,henry_draper,
flamsteed,found_stars,found_nebulae);
for(int i= 0;i<found_stars.size();i++)
stars[found_stars[i]].in_view= hidden;
for(int i= 0;i<found_nebulae.size();i++)
nebulae[found_nebulae[i]].in_view= hidden;
}

/*:32*/
#line 1172 "pp3.w"

else
/*31:*/
#line 1290 "pp3.w"

if(opcode=="add"){
search_objects(script,ngc,ic,messier,henry_draper,
flamsteed,found_stars,found_nebulae);
for(int i= 0;i<found_stars.size();i++)
stars[found_stars[i]].in_view= visible;
for(int i= 0;i<found_nebulae.size();i++)
nebulae[found_nebulae[i]].in_view= visible;
}

/*:31*/
#line 1174 "pp3.w"

else throw string("Undefined opcode in input script: \"")
+opcode+'"';
}
script>>opcode;
}
}

/*:24*/
#line 3633 "pp3.w"


int main(int argc,char**argv){
try{
/*113:*/
#line 3680 "pp3.w"

if(argc==2){
if(argv[1][0]!='-'){
params.in= new ifstream(argv[1]);
if(!params.in->good())
throw string("Input script file ")+argv[1]
+" not found";
else params.input_file= true;
}else if(!strcmp(argv[1],"-"))params.in= &cin;else
cerr<<"Invalid argument: "<<argv[1]<<endl;
}
if(params.in==0){
cerr<<"Syntax:\n  pp3 {input-file}\n\n"
<<"{input-file} may be \"-\" to denote standard input.\n"
<<"You may give an empty file to get a default plot.\n"
<<"The plot is sent to standard output by default.\n";
exit(0);
}

/*:113*/
#line 3637 "pp3.w"

read_parameters_from_script(*params.in);
if(!params.filename_output.empty())
params.out= new ofstream(params.filename_output.c_str());
transformation mytransform(params.center_rectascension,
params.center_declination,
params.view_frame_width,
params.view_frame_height,
params.grad_per_cm);

/*114:*/
#line 3702 "pp3.w"

boundaries_list boundaries;
dimensions_list dimensions;
objects_list objects;
stars_list stars;
nebulae_list nebulae;
connections_list connections;
texts_list texts;
flexes_list flexes;

if(params.show_boundaries)read_constellation_boundaries(boundaries);
read_label_dimensions(dimensions);
read_stars(stars);
read_nebulae(nebulae);
if(params.show_lines)read_constellation_lines(connections,stars);

/*:114*/
#line 3647 "pp3.w"


read_objects_and_labels(*params.in,dimensions,objects,stars,
nebulae,texts,flexes,mytransform);

OUT.setf(ios::fixed);
OUT.precision(3);
/*116:*/
#line 3747 "pp3.w"

create_preamble(OUT);
OUT<<"\\usepackage[nohead,nofoot,margin=0cm,"
<<"paperwidth="<<params.view_frame_width_in_bp()<<"bp,"
<<"paperheight="<<params.view_frame_height_in_bp()<<"bp"
<<"]{geometry}\n\n"
<<"\n\\begin{document}\\parindent0pt\n"
<<"\\pagestyle{empty}\\thispagestyle{empty}%\n"
<<"\\special{papersize="<<params.view_frame_width_in_bp()-0.1
<<"bp,"<<params.view_frame_height_in_bp()-0.1<<"bp}%\n"
<<"\\vbox to \\vsize{\\vfill\\hbox to \\hsize{%\n"
<<params.bgcolor<<params.gridcolor<<params.eclipticcolor
<<params.boundarycolor<<params.hlboundarycolor<<params.starcolor
<<params.nebulacolor<<params.clinecolor;

/*:116*/
#line 3654 "pp3.w"

OUT<<"\\psclip{\\psframe[linestyle=none](0bp,0bp)("
<<params.view_frame_width_in_bp()
<<"bp,"<<params.view_frame_height_in_bp()<<"bp)}%\n"
<<"\\psframe*[linecolor=bgcolor,linestyle=none](-1bp,-1bp)("
<<params.view_frame_width_in_bp()+1
<<"bp,"<<params.view_frame_height_in_bp()+1<<"bp)%\n";
/*115:*/
#line 3725 "pp3.w"

if(params.milkyway_visible)draw_milky_way(mytransform);
create_grid(mytransform);
if(params.show_boundaries)
draw_boundaries(mytransform,boundaries,objects,
params.constellation);
draw_flex_labels(mytransform,flexes,objects,dimensions);
draw_text_labels(mytransform,texts,objects);
draw_nebulae(mytransform,nebulae,objects);
draw_stars(mytransform,stars,objects);
if(params.show_lines)
draw_constellation_lines(connections,stars,objects);
if(params.show_labels){
arrange_labels(objects,dimensions);
print_labels(objects);
}

/*:115*/
#line 3661 "pp3.w"

OUT<<"\\endpsclip\n";
/*118:*/
#line 3821 "pp3.w"

OUT<<"\\hfill}}\\end{document}\n";

/*:118*/
#line 3663 "pp3.w"

if(params.input_file)delete params.in;
/*119:*/
#line 3827 "pp3.w"

if(!params.filename_output.empty()&&(params.create_eps
||params.create_pdf)){
OUT.flush();
string commandline= string("latex ")+params.filename_output;
if(system(commandline.c_str())==0){
string base_filename(params.filename_output);
if(base_filename.find('.')!=string::npos)
base_filename.erase(base_filename.find('.'));
commandline= string("dvips -o ")+base_filename+".eps "
+base_filename;
if(system(commandline.c_str())==0){
if(params.create_pdf){
commandline= string("ps2pdf ")+
base_filename+".eps";
if(system(commandline.c_str())!=0)
throw string("ps2pdf call failed: ")+commandline;
}
}else throw string("dvips call failed: ")+commandline;
}else throw string("LaTeX call failed: ")+commandline;
}


/*:119*/
#line 3665 "pp3.w"

}
catch(string s){
cerr<<"pp3: "<<s<<'.'<<endl;
exit(1);
}
return 0;
}

/*:112*/
