/******************************************************************************
 *
 * 
 *
 * Copyright (C) 1997-2014 by Dimitri van Heesch.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation under the terms of the GNU General Public License is hereby 
 * granted. No representations are made about the suitability of this software 
 * for any purpose. It is provided "as is" without express or implied warranty.
 * See the GNU General Public License for more details.
 *
 * Documents produced by Doxygen are derivative works derived from the
 * input used in their production; they are not affected by this license.
 *
 */

#include <stdlib.h>

#include <qdir.h>
#include <qregexp.h>
#include "message.h"
#include "htmlgen.h"
#include "config.h"
#include "util.h"
#include "doxygen.h"
#include "logos.h"
#include "diagram.h"
#include "version.h"
#include "dot.h"
#include "language.h"
#include "htmlhelp.h"
#include "docparser.h"
#include "htmldocvisitor.h"
#include "searchindex.h"
#include "pagedef.h"
#include "debug.h"
#include "dirdef.h"
#include "vhdldocgen.h"
#include "layout.h"
#include "image.h"
#include "ftvhelp.h"
#include "bufstr.h"


//#define DBG_HTML(x) x;
#define DBG_HTML(x) 

static const char defaultHtmlHeader[] =
#include "header.html.h"
;

static const char defaultHtmlFooter[] =
#include "footer.html.h"
;

static const char defaultStyleSheet[] = 
#include "doxygen.css.h"
;

static const char search_functions_script[]=
#include "search_functions.php.h"
;

static const char search_opensearch_script[]=
#include "search_opensearch.php.h"
;

static const char search_styleSheet[] =
#include "search.css.h"
;

static const char search_jquery_script1[]=
#include "jquery_p1.js.h"
;

static const char search_jquery_script2[]=
#include "jquery_p2.js.h"
;

static const char search_jquery_script3[]=
#include "jquery_p3.js.h"
;

static const char search_jquery_script4[]=
#include "jquery_ui.js.h"
;

static const char search_jquery_script5[]=
#include "jquery_fx.js.h"
;

static const char search_jquery_script6[]=
#include "jquery_pt.js.h"
;

static const char svgpan_script[]=
#include "svgpan.js.h"
;

static const char dynsections_script[]=
#include "dynsections.js.h"
;

static const char extsearch_script[]=
#include "extsearch.js.h"
;

static QCString g_header;
static QCString g_footer;
static QCString g_mathjax_code;

//------------------------- Pictures for the Tabs ------------------------

// active tab background luma
static unsigned char tab_a_png[36] =
{
   31,  42,  59,  69,  73,  74,  75,  77,  77,
   77,  79,  80,  80,  82,  81,  83,  84,  86,
   87,  88,  89,  90,  91,  91,  93,  94,  94,
   96,  96,  97,  98,  98,  99,  99,  99, 100
};

// normal tab background luma
static unsigned char tab_b_png[36] =
{
    218, 228, 235, 233, 230, 227, 225, 222, 221,
    218, 217, 215, 214, 213, 212, 211, 210, 209,
    209, 197, 198, 199, 200, 201, 202, 203, 204,
    205, 207, 209, 211, 213, 217, 219, 206, 188 
};

// hovering tab background luma
static unsigned char tab_h_png[36] =
{
    181, 191, 198, 196, 193, 190, 188, 185, 184,
    181, 180, 178, 177, 176, 175, 174, 173, 172,
    172, 154, 155, 156, 157, 158, 159, 160, 161,
    162, 164, 166, 168, 170, 174, 176, 163, 145
};

// shadowed header
static unsigned char header_png[12] = 
{
  255, 240, 241, 242, 243, 244, 
  245, 246, 247, 248, 249, 250
};

// function header
static unsigned char func_header_png[56] =
{
  248, 247, 246, 245, 244, 243, 242, 241,
  240, 239, 238, 237, 236, 235, 234, 233,
  232, 231, 230, 229, 228, 223, 223, 223,
  223, 223, 223, 223, 223, 223, 223, 223,
  224, 224, 224, 224, 225, 225, 225, 225,
  225, 226, 226, 226, 227, 227, 227, 227,
  228, 228, 228, 229, 229, 229, 229, 229
};

// tab separator
static unsigned char tab_s_png[36] =
{
  187, 186, 185, 183, 182, 181, 180, 178, 176,
  174, 173, 171, 169, 167, 164, 163, 161, 158,
  156, 154, 152, 150, 148, 145, 143, 141, 140,
  138, 136, 134, 131, 131, 128, 126, 125, 124
};

// breadcrumbs luma
static unsigned char bc_s_png[240] =
{
  150,187,187,148,148,148,148,148,
  147,175,186,147,147,147,147,147,
  146,153,185,185,146,146,146,146,
  144,144,177,183,144,144,144,144,
  144,144,159,182,144,144,144,144,
  143,143,144,179,181,143,143,143,
  142,142,142,165,180,142,142,142,
  141,141,141,144,178,178,141,141,
  139,139,139,139,167,176,139,139,
  137,137,137,137,146,174,137,137,
  137,137,137,137,137,169,173,137,
  135,135,135,135,135,150,171,135,
  133,133,133,133,133,135,167,169,
  132,132,132,132,132,132,154,167,
  129,129,129,129,129,129,140,164,
  129,129,129,129,129,129,154,163,
  127,127,127,127,127,128,161,161,
  125,125,125,125,125,141,158,125,
  123,123,123,123,123,152,156,123,
  121,121,121,121,129,154,121,121,
  120,120,120,120,143,152,120,120,
  118,118,118,120,150,150,118,118,
  117,117,117,132,148,117,117,117,
  114,114,114,142,145,114,114,114,
  113,113,120,143,113,113,113,113,
  111,111,133,141,111,111,111,111,
  110,112,140,140,110,110,110,110,
  109,124,138,109,109,109,109,109,
  107,133,136,107,107,107,107,107,
  111,134,106,106,106,106,106,106
};

// breadcrumbs alpha map
static unsigned char bc_s_a_png[240] =
{
  241,241, 21,  0,  0,  0,  0,  0,
  162,205,117,  0,  0,  0,  0,  0,
   54,231,225,  3,  0,  0,  0,  0,
    0,198,215, 78,  0,  0,  0,  0,
    0, 93,211,186,  0,  0,  0,  0,
    0,  6,232,235, 42,  0,  0,  0,
    0,  0,132,203,147,  0,  0,  0,
    0,  0, 27,242,241, 15,  0,  0,
    0,  0,  0,168,205,108,  0,  0,
    0,  0,  0, 63,228,219,  0,  0,
    0,  0,  0,  0,207,221, 72,  0,
    0,  0,  0,  0,102,208,177,  0,
    0,  0,  0,  0,  9,238,240, 36,
    0,  0,  0,  0,  0,138,201,138,
    0,  0,  0,  0,  0, 77,187,158,
    0,  0,  0,  0,  0,159,204,120,
    0,  0,  0,  0, 15,241,241, 21,
    0,  0,  0,  0,111,208,171,  0,
    0,  0,  0,  0,210,222, 66,  0,
    0,  0,  0, 60,227,219,  0,  0,
    0,  0,  0,162,204,114,  0,  0,
    0,  0, 18,238,238, 21,  0,  0,
    0,  0,114,205,165,  0,  0,  0,
    0,  0,216,225, 60,  0,  0,  0,
    0, 66,226,216,  0,  0,  0,  0,
    0,165,204,111,  0,  0,  0,  0,
   21,241,241, 18,  0,  0,  0,  0,
  117,203,159,  0,  0,  0,  0,  0,
  219,227, 57,  0,  0,  0,  0,  0,
  211,201,  0,  0,  0,  0,  0,  0
};

// doxygen logo luma
static unsigned char doxygen_png[3224] =
{
  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,255,255,255,255,255,255,255,255,
   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 91, 91, 91, 91, 32, 32,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
   32, 32, 32, 32, 32, 32, 32, 32, 32, 32,255,255,255,255, 32, 32,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
   32, 32, 32, 32, 32, 32, 32, 32, 32, 32,253,253,253,253, 32, 32,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,255,255,255,255,255,255,255,255,
   32, 32, 32, 32, 32, 32, 32, 32, 32, 32,251,251,251,251, 32, 32,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,255,255,255,255,255,255,255,255,
   32, 32, 32, 32, 32, 32, 32, 32, 32, 32,249,249,249,249, 32, 32,249,249,249,249, 32, 32, 32, 32, 32, 32,249,249,249,249, 32, 32, 32, 32, 32, 32,249,249,249,249, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,249,249,249, 32, 32, 32, 32, 32,249,249,249,249, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,249,249,249,249,249,249, 32, 32, 32, 32, 32, 32, 32,249,249,249,249,249, 32, 32, 32, 32, 32,249, 32, 32, 32, 32, 32,255,255,255,
   32, 32, 32, 32, 46,132,190,190,147, 61,247,247,247,247, 32, 32,247,247, 32, 32,118,161,190,190,161,118, 32, 32,247, 32, 46, 89, 89, 89, 89, 46, 32,247,247, 32, 89, 89, 89, 89, 61, 89, 89, 89, 89, 46, 32,247, 32, 46, 89, 89, 89, 89, 32,247, 32, 32,118,175,190,161, 89, 61, 89, 89, 89, 61, 32,247,247,247, 32, 32,104,147,190,190,190,132, 89, 32, 32,247,247, 32, 46, 89, 89, 89, 75, 32, 89,161,190,161, 75, 32,255,255,
   32, 32, 32, 74,230,244,244,244,244,244,244,244,244,244, 32, 32,244, 32, 74,216,244,244,244,244,244,244,216, 74, 32,244, 32,187,244,244,244,159, 32,244, 32,117,244,244,244,230, 46,173,244,244,244,131, 32,244, 32,131,244,244,244,173, 32, 32, 46,173,244,244,244,244,244,230,244,244,244,131, 32,244,244, 32, 74,202,244,244,244,244,244,244,244,173, 46, 32,244, 32, 89,244,244,244,187,145,244,244,244,244,244, 89, 32,255,
   32, 32, 46,213,241,241,241,241,241,241,241,241,241,241, 32, 32, 32, 60,227,241,241,241,241,241,241,241,241,227, 60, 32, 32, 46,227,241,241,241,102, 32, 60,227,241,241,241, 88, 32,116,241,241,241,199, 32,241, 32,185,241,241,241,116, 32, 32,143,241,241,241,241,241,241,241,241,241,241,130, 32,241, 32, 74,227,241,241,241,199,185,241,241,241,241,171, 32,241, 32, 88,241,241,241,241,241,241,241,241,241,241,199, 32,255,
   32, 32,128,237,237,237,223,128, 87,128,237,237,237,237, 32, 32, 32,182,237,237,237,196,100,100,196,237,237,237,182, 32,237, 32,100,237,237,237,223, 59,196,237,237,237,141, 32, 32, 46,237,237,237,237, 59, 32, 46,237,237,237,237, 46, 32, 59,237,237,237,237,169, 87, 87,182,237,237,237,128, 32,237, 32,196,237,237,237, 87, 32, 32, 73,223,237,237,237, 73, 32, 32, 87,237,237,237,237,223,182,223,237,237,237,237, 46, 32,
   32, 32,207,234,234,234,113, 32, 32, 32,234,234,234,234, 32, 32, 59,234,234,234,221, 45, 32, 32, 45,221,234,234,234, 59, 32,234, 32,140,234,234,234,221,234,234,234,194, 32, 32,234, 32,167,234,234,234,126, 32, 99,234,234,234,167, 32, 32,126,234,234,234,180, 32, 32, 32,126,234,234,234,126, 32, 32, 99,234,234,234,167, 32, 32, 32, 32,153,234,234,234,126, 32, 32, 86,234,234,234,207, 45, 32, 45,234,234,234,234, 86, 32,
   32, 45,231,231,231,218, 32, 32, 32, 32,231,231,231,231, 32, 32, 98,231,231,231,165, 32,231,231, 32,165,231,231,231, 98, 32,231, 32, 45,191,231,231,231,231,231,218, 72, 32,231,231, 32, 98,231,231,231,165, 32,151,231,231,231,112, 32, 32,165,231,231,231,112, 32,231, 32,125,231,231,231,125, 32, 32,138,231,231,231,178,125,125,125,125,178,231,231,231,178, 32, 32, 85,231,231,231,178, 32,255, 32,191,231,231,231, 85, 32,
   32, 84,227,227,227,175, 32, 32, 32, 32,227,227,227,227, 32, 32,123,227,227,227,123, 32,227,227, 32,123,227,227,227,123, 32,227,227, 32, 71,227,227,227,227,227,123, 32,227,227,227,227, 32,214,227,227,227, 45,201,227,227,227, 45, 32, 32,175,227,227,227, 84, 32,227, 32,123,227,227,227,123, 32, 32,175,227,227,227,227,227,227,227,227,227,227,227,227,175, 32, 32, 84,227,227,227,175, 32,255, 32,175,227,227,227, 84, 32,
   32, 83,223,223,223,172, 32, 32, 32, 32,223,223,223,223, 32, 32,121,223,223,223,121, 32,223,223, 32,121,223,223,223,121, 32,223,223,223, 32,172,223,223,223,210, 45, 32,223,223,223,223, 32,147,223,223,223,134,223,223,223,147, 32,223, 32,172,223,223,223, 83, 32,223, 32,121,223,223,223,121, 32, 32,172,223,223,223,223,223,223,223,223,223,223,223,223,172, 32, 32, 83,223,223,223,172, 32,255, 32,172,223,223,223, 83, 32,
   32, 82,220,220,220,170, 32, 32, 32, 32,220,220,220,220, 32, 32,120,220,220,220,120, 32,220,220, 32,120,220,220,220,120, 32,220,220, 32, 95,220,220,220,220,220,132, 32,220,220,220,220, 32, 95,220,220,220,207,220,220,220, 95, 32,220, 32,170,220,220,220,107, 32,220, 32,120,220,220,220,120, 32, 32,170,220,220,220,132, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 82,220,220,220,170, 32,255, 32,170,220,220,220, 82, 32,
   32, 57,216,216,216,216, 32, 32, 32, 32,216,216,216,216, 32, 32, 81,216,216,216,167, 32,216,216, 32,155,216,216,216, 81, 32,216, 32, 57,204,216,216,216,216,216,216, 93, 32,216,216,216,216, 32,204,216,216,216,216,216,204, 32,216,216, 32,118,216,216,216,167, 32, 32, 32,130,216,216,216,118, 32, 32,118,216,216,216,191, 32, 32,216,216,216, 32, 32, 44, 57, 32, 32, 81,216,216,216,167, 32,255, 32,167,216,216,216, 81, 32,
   32, 32,189,213,213,213,116, 32, 32, 80,213,213,213,213, 32, 32, 44,201,213,213,213, 68, 32, 32, 68,213,213,213,213, 44, 32, 32, 32,165,213,213,213,165,213,213,213,201, 44, 32,213,213,213, 32,129,213,213,213,213,213,141, 32,213,213, 32, 80,213,213,213,213,165,116,153,213,213,213,213,116, 32, 32, 56,213,213,213,213,153, 56, 32, 32, 32, 44,104,189,116, 32, 32, 80,213,213,213,165, 32,255, 32,165,213,213,213, 80, 32,
   32, 32,139,210,210,210,210,174,174,210,210,210,210,210, 32, 32, 32,127,210,210,210,198,127,127,198,210,210,210,127, 32,210, 32,115,210,210,210,174, 44,139,210,210,210,163, 32, 32,210,210, 32, 68,210,210,210,210,210, 91, 32,210,210,210, 32,174,210,210,210,210,210,210,210,210,210,210,115, 32,210, 32,127,210,210,210,210,210,174,163,163,210,210,210,115, 32, 32, 79,210,210,210,163, 32,255, 32,163,210,210,210, 79, 32,
   32, 32, 55,194,206,206,206,206,206,194,206,206,206,206, 32, 32, 32, 44,171,206,206,206,206,206,206,206,206,171, 44, 32, 32, 67,206,206,206,206, 67, 32, 44,183,206,206,206,113, 32,206,206,206, 32,183,206,206,206,194, 32,206,206,206,206, 32, 67,194,206,206,206,206,206,171,206,206,206,113, 32,206, 32, 32,136,206,206,206,206,206,206,206,206,206,206,113, 32, 32, 78,206,206,206,160, 32,255, 32,160,206,206,206, 78, 32,
   32, 32, 32,100,192,203,203,203,157, 55,203,203,203,203, 32, 32,203, 32, 43,135,203,203,203,203,203,203,135, 43, 32, 32, 43,180,203,203,203,112, 32,203, 32, 66,203,203,203,203, 66, 32,203,203, 32,157,203,203,203,135, 32,203,203,203,203,203, 32, 43,112,157,157,123, 55,112,203,203,203,112, 32,203,203, 32, 32, 78,146,203,203,203,203,203,203,169,123, 55, 32, 32, 78,203,203,203,157, 32,255, 32,157,203,203,203, 78, 32,
   32, 32, 32, 32, 54,110,110, 88, 32, 32, 32, 32, 32, 32, 32, 32,200,200, 32, 32, 54, 99,110,110, 99, 54, 32, 32,200,200, 32, 32, 32, 32, 32, 32, 32,200,200, 32, 32, 32, 32, 32, 32,200,200, 32, 54,200,200,200,200, 77, 32,200,200,200,200,200, 32, 32, 32, 32, 32, 32, 32,166,200,200,200, 88, 32,200,200,200,200, 32, 32, 32, 66, 77, 77, 77, 32, 32, 32, 32,200,200, 32, 32, 32, 32, 32, 32,255, 32, 32, 32, 32, 32, 32,255,
   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,198,198,198,198, 32, 32, 32, 32, 32, 32,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, 32,109,198,198,198,176, 32,198,198,198,198,198, 32, 98,121, 76, 32, 32, 54,109,198,198,198,198, 43, 32,198,198,198,198,198,198,198, 32, 32, 32, 32,198,198,198,198,198,198,198,198,198,198,198,198,255,255,255,255,255,255,255,255,
   32, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 33,159,191,191,191,117, 36, 41, 41, 41, 41, 41, 34,108,191,191,191,191,191,191,191,191,191,117, 36, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,255,
   32, 41, 97,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 78, 38, 64,190,192,192,192, 66, 66, 41, 41, 85,128, 65, 34,107,190,192,192,192,192,192,192,192,139, 48, 39, 41, 41,105,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 97, 41,255,
   32, 41, 97,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 96, 36, 95,147,148,148,139, 55, 41, 41, 85,121,128, 91, 38, 75,137,158,190,190,190,170,139, 97, 49, 37, 41, 41,105,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 97, 41,255,
   32, 41, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 41, 36, 45, 45, 45, 48, 38, 41, 41, 76, 76, 76, 76, 76, 37, 34, 42, 33, 33, 33, 39, 48, 59, 41, 41, 41, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 41,255,
   32, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,255,
  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
};

// doxygen logo alpha map
static unsigned char doxygen_a_png[3224] =
{
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 66, 66, 66, 66,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,145,247,247,247,247,145,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,247,247,247,247,247,247,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,247,247,247,247,247,247,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,247,247,247,247,247,247,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0, 16,115,181,181,132,247,247,247,247,247,247,  0,  0,  0,  0,  0, 99,148,181,181,148, 99,  0,  0,  0,  0, 16, 66, 66, 66, 66, 16,  0,  0,  0,  0, 66, 66, 66, 66, 33, 66, 66, 66, 66, 16,  0,  0,  0, 16, 66, 66, 66, 66,  0,  0,  0,  0, 99,165,181,148, 66, 33, 66, 66, 66, 33,  0,  0,  0,  0,  0,  0, 82,132,181,181,181,115, 66,  0,  0,  0,  0,  0, 16, 66, 66, 66, 49,  0, 66,148,181,148, 49,  0,  0,  0,
    0,  0,  0,129,247,247,247,247,247,247,247,247,247,247,247,  0,  0,  0,112,214,247,247,247,247,247,247,214,112,  0, 16,247,247,247,247,247,247, 46,  0,  0,145,247,247,247,247,247,247,247,247,247,247, 16,  0, 16,247,247,247,247,247, 66,  0, 63,165,247,247,247,247,247,247,247,247,247,247, 33,  0,  0,  0, 96,198,247,247,247,247,247,247,247,165, 63,  0,  0, 16,247,247,247,247,247,145,247,247,247,247,247,145,  0,  0,
    0,  0,112,247,247,247,247,247,247,247,247,247,247,247,247,  0,  0,129,247,247,247,247,247,247,247,247,247,247,129,  0,181,247,247,247,247,247,148,  0,129,247,247,247,247,247,247,247,247,247,247,247,115,  0,115,247,247,247,247,247,165, 30,247,247,247,247,247,247,247,247,247,247,247,247,115,  0,  0,129,247,247,247,247,247,247,247,247,247,247,247, 63,  0, 66,247,247,247,247,247,247,247,247,247,247,247,247, 96,  0,
    0, 16,247,247,247,247,247,247,247,247,247,247,247,247,247,  0, 79,247,247,247,247,247,247,247,247,247,247,247,247, 79, 79,247,247,247,247,247,247,129,247,247,247,247,247,247,129,247,247,247,247,247,198,  0,181,247,247,247,247,247, 99,145,247,247,247,247,247,247,247,247,247,247,247,247,115,  0, 96,247,247,247,247,247,247,247,247,247,247,247,247,165,  0, 66,247,247,247,247,247,247,247,247,247,247,247,247,198,  0,
    0,115,247,247,247,247,247,247,247,247,247,247,247,247,247,  0,181,247,247,247,247,247,247,247,247,247,247,247,247,181,  0,129,247,247,247,247,247,247,247,247,247,247,247,145, 16,247,247,247,247,247,247, 33,247,247,247,247,247,247, 33,247,247,247,247,247,247,247,247,247,247,247,247,247,115,  0,198,247,247,247,247,247,198,181,247,247,247,247,247,247, 49, 66,247,247,247,247,247,247,247,247,247,247,247,247,247, 16,
    0,214,247,247,247,247,247,129, 66,247,247,247,247,247,247, 33,247,247,247,247,247,247, 96, 96,247,247,247,247,247,247, 33,  0,145,247,247,247,247,247,247,247,247,247,198, 30,  0,165,247,247,247,247,247,115,247,247,247,247,247,165,115,247,247,247,247,247,181, 66,115,247,247,247,247,247,115, 82,247,247,247,247,247,165,115,115,148,247,247,247,247,247,115, 66,247,247,247,247,247,247,181,247,247,247,247,247,247, 66,
   16,247,247,247,247,247,231,  0,  0,247,247,247,247,247,247, 82,247,247,247,247,247,165,  0,  0,165,247,247,247,247,247, 82,  0, 30,247,247,247,247,247,247,247,247,247, 96,  0,  0, 82,247,247,247,247,247,165,247,247,247,247,247, 99,165,247,247,247,247,247, 99,  0,115,247,247,247,247,247,115,132,247,247,247,247,247,247,247,247,247,247,247,247,247,247,181, 66,247,247,247,247,247,181,  0,198,247,247,247,247,247, 66,
   66,247,247,247,247,247,181,  0,  0,247,247,247,247,247,247,115,247,247,247,247,247,115,  0,  0,115,247,247,247,247,247,115,  0,  0, 96,247,247,247,247,247,247,247,129,  0,  0,  0,  0,231,247,247,247,247,247,247,247,247,247,247, 16,181,247,247,247,247,247, 66,  0,115,247,247,247,247,247,115,181,247,247,247,247,247,247,247,247,247,247,247,247,247,247,181, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
   66,247,247,247,247,247,181,  0,  0,247,247,247,247,247,247,115,247,247,247,247,247,115,  0,  0,115,247,247,247,247,247,115,  0,  0,  0,181,247,247,247,247,247,247, 30,  0,  0,  0,  0,148,247,247,247,247,247,247,247,247,247,148,  0,181,247,247,247,247,247, 66,  0,115,247,247,247,247,247,115,181,247,247,247,247,247,247,247,247,247,247,247,247,247,247,181, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
   66,247,247,247,247,247,181,  0,  0,247,247,247,247,247,247,115,247,247,247,247,247,115,  0,  0,115,247,247,247,247,247,115,  0,  0,129,247,247,247,247,247,247,247,145,  0,  0,  0,  0, 82,247,247,247,247,247,247,247,247,247, 82,  0,181,247,247,247,247,247, 99,  0,115,247,247,247,247,247,115,181,247,247,247,247,247,247,247,247,247,247,247,247,247,181, 79, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
   33,247,247,247,247,247,247, 14,  0,247,247,247,247,247,247, 66,247,247,247,247,247,181,  0,  0,165,247,247,247,247,247, 66,  0, 79,247,247,247,247,247,247,247,247,247,129,  0,  0,  0,  0,231,247,247,247,247,247,247,247,231,  0,  0,115,247,247,247,247,247,181,115,165,247,247,247,247,247,115,115,247,247,247,247,247,214, 63,  0,  0,  0, 16,112,247,247, 33, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
    0,214,247,247,247,247,247,198,198,247,247,247,247,247,247, 16,247,247,247,247,247,247,132,132,247,247,247,247,247,247, 16, 14,181,247,247,247,247,247,247,247,247,247,247, 79,  0,  0,  0,132,247,247,247,247,247,247,247,148,  0,  0, 66,247,247,247,247,247,247,247,247,247,247,247,247,247,115, 33,247,247,247,247,247,247,247,198,181,181,247,247,247,247,115, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
    0,148,247,247,247,247,247,247,247,247,247,247,247,247,247,  0,132,247,247,247,247,247,247,247,247,247,247,247,247,145,  0,145,247,247,247,247,247,247,247,247,247,247,247,181, 14,  0,  0, 49,247,247,247,247,247,247,247, 82,  0,  0,  0,198,247,247,247,247,247,247,247,247,247,247,247,247,115,  0,145,247,247,247,247,247,247,247,247,247,247,247,247,247,115, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
    0, 46,247,247,247,247,247,247,247,247,247,247,247,247,247,  0, 30,247,247,247,247,247,247,247,247,247,247,247,247, 30,112,247,247,247,247,247,247, 96,247,247,247,247,247,247,145,  0,  0,  0,214,247,247,247,247,247,231,  0,  0,  0,  0, 96,247,247,247,247,247,247,247,247,247,247,247,247,115,  0, 30,148,247,247,247,247,247,247,247,247,247,247,247,247,115, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
    0,  0,129,247,247,247,247,247,247,247,247,247,247,247,247,  0,  0, 96,247,247,247,247,247,247,247,247,247,247, 96, 16,247,247,247,247,247,247,145,  0,112,247,247,247,247,247,247, 49,  0,  0,181,247,247,247,247,247,148,  0,  0,  0,  0,  0,129,247,247,247,247,247,247,247,247,247,247,247,115,  0,  0, 46,148,247,247,247,247,247,247,247,247,247,247,247, 33, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
    0,  0,  0,129,247,247,247,247,181,145,247,247,247,247,145,  0,  0,  0, 46,148,247,247,247,247,247,247,148, 46,  0,  0,112,214,247,247,247,145, 14,  0,  0,145,247,247,247,247,145,  0,  0, 33,247,247,247,247,247,247, 66,  0,  0,  0,  0,  0, 99,132,115,181,181,132,198,247,247,247,247,247, 82,  0,  0,  0,  0, 66,165,247,247,247,247,247,247,198,132, 33,  0,  0,145,247,247,247,181, 79,  0, 79,181,247,247,247,145,  0,
    0,  0,  0,  0, 33,115,115, 82,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 33, 99,115,115, 99, 33,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,115,247,247,247,247,247,214,  0,  0,  0,  0,  0, 99,247,247,247,247,247,247,247,247,247,247,247,247, 16,  0,  0,  0,  0,  0,  0,  0, 49, 66, 66, 66,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,165,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,108,224,255,255,255,255,255,255,101,164,255,255,255,143,250,255,255,255,255,255,255,255,255,255,255,255, 98,170,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,165,  0,
    0,165,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,136,251,255,255,255,255,255,255,101,130,255,255,255,153,250,255,255,255,255,255,255,255,255,255,255,121, 98,189,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,165,  0,
    0,165,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,198,252,255,255,255,255,255,164,164,255,255,255,255,176,249,251,255,255,255,255,255,255,255,255,150, 86,192,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,165,  0,
    0,165,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,164,198,255,255,255,255,201,133,164,255,255,255,255,255,145,203,255,255,255,255,255,255,255,117, 79,194,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,165,  0,
    0, 66,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, 73, 73,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, 47, 70,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, 66,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
};

// magnifying glass icon (raw png)
unsigned char mag_sel_png[] = {
  0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
  0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13,
  0x08, 0x06, 0x00, 0x00, 0x00, 0x90, 0x8c, 0x2d, 0xb5, 0x00, 0x00, 0x00,
  0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
  0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48,
  0x52, 0x4d, 0x00, 0x00, 0x6d, 0x98, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x00,
  0xe0, 0x38, 0x00, 0x00, 0x82, 0xd5, 0x00, 0x00, 0x7a, 0x07, 0x00, 0x00,
  0xca, 0xb4, 0x00, 0x00, 0x33, 0x44, 0x00, 0x00, 0x1c, 0x76, 0x84, 0x36,
  0x2a, 0xbd, 0x00, 0x00, 0x01, 0xb9, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
  0xe4, 0x94, 0xbb, 0x8a, 0x22, 0x41, 0x14, 0x86, 0xbf, 0xda, 0x16, 0x3a,
  0x10, 0xba, 0x03, 0x2f, 0x78, 0x03, 0x51, 0x11, 0x4c, 0xd4, 0x40, 0xd4,
  0x37, 0x30, 0x31, 0x30, 0xe9, 0x07, 0xf0, 0x15, 0x14, 0x7c, 0x1e, 0x31,
  0x37, 0x33, 0x11, 0x73, 0xe9, 0x56, 0x44, 0x84, 0x36, 0xe9, 0x40, 0x50,
  0x54, 0x14, 0xc4, 0xc0, 0xa8, 0x6d, 0x50, 0x6a, 0x92, 0x1d, 0xd9, 0x9d,
  0x99, 0x75, 0x0d, 0x26, 0x58, 0xd8, 0x3f, 0xaa, 0xe2, 0xfc, 0xf5, 0xd5,
  0x39, 0x9c, 0x53, 0x25, 0xa4, 0x94, 0x7c, 0xa7, 0x7e, 0xf0, 0xcd, 0xfa,
  0xf7, 0x81, 0xbe, 0xf7, 0xc5, 0xf9, 0x7c, 0x96, 0x93, 0xc9, 0x84, 0xe5,
  0x72, 0xc9, 0x66, 0xb3, 0x21, 0x99, 0x4c, 0x92, 0xcf, 0xe7, 0xa9, 0x54,
  0x2a, 0x04, 0x02, 0x01, 0xf1, 0x2a, 0x50, 0x48, 0x29, 0x39, 0x9d, 0x4e,
  0x72, 0x30, 0x18, 0x60, 0x59, 0xd6, 0x27, 0x43, 0xb5, 0x5a, 0xa5, 0xd1,
  0x68, 0x10, 0x0c, 0x06, 0xc5, 0xcb, 0x19, 0x4e, 0xa7, 0x53, 0x2c, 0xcb,
  0x22, 0x95, 0x4a, 0x51, 0x2a, 0x95, 0xc8, 0x64, 0x32, 0xac, 0x56, 0x2b,
  0x66, 0xb3, 0x19, 0x93, 0xc9, 0x84, 0x48, 0x24, 0x42, 0xbd, 0x5e, 0x7f,
  0xbd, 0x64, 0xdb, 0xb6, 0x01, 0x28, 0x97, 0xcb, 0x54, 0x2a, 0x15, 0x34,
  0x4d, 0x13, 0xa1, 0x50, 0x48, 0x2a, 0x8a, 0xc2, 0x7a, 0xbd, 0xc6, 0xb6,
  0x6d, 0xea, 0xf5, 0x3a, 0xa3, 0xd1, 0x48, 0xf6, 0xfb, 0xfd, 0xc7, 0x61,
  0xc3, 0x30, 0xa8, 0xd5, 0x6a, 0xe2, 0x53, 0x53, 0xb6, 0xdb, 0x2d, 0x00,
  0xc5, 0x62, 0x11, 0x4d, 0xd3, 0x04, 0x80, 0xa6, 0x69, 0xa2, 0x50, 0x28,
  0xf0, 0x6b, 0x1c, 0x10, 0x86, 0x61, 0x3c, 0x60, 0x80, 0xf8, 0xb2, 0xcb,
  0x89, 0x44, 0x02, 0x00, 0xc7, 0x71, 0x00, 0xde, 0x27, 0x5d, 0xfe, 0xdc,
  0x3f, 0xe2, 0x1f, 0xa0, 0xe2, 0x8f, 0x63, 0x93, 0xcb, 0xe5, 0x00, 0x18,
  0x8f, 0xc7, 0x98, 0xa6, 0x89, 0xeb, 0xba, 0xd2, 0x34, 0x4d, 0xc6, 0xe3,
  0x31, 0x00, 0xe9, 0x74, 0x1a, 0x80, 0x5a, 0xad, 0xf6, 0x80, 0x3e, 0xed,
  0xf2, 0x7a, 0xbd, 0x96, 0xc3, 0xe1, 0x90, 0xf9, 0x7c, 0xfe, 0xa5, 0x29,
  0x1c, 0x0e, 0xd3, 0xe9, 0x74, 0xd0, 0x75, 0x5d, 0x00, 0x8c, 0x46, 0xa3,
  0x8f, 0x17, 0xfc, 0x0e, 0xf4, 0x3c, 0x4f, 0xee, 0x76, 0x3b, 0x16, 0x8b,
  0x05, 0x8e, 0xe3, 0xb0, 0xdf, 0xef, 0x89, 0xc7, 0xe3, 0xa4, 0xd3, 0x69,
  0x6c, 0xdb, 0xe6, 0x74, 0x3a, 0x11, 0x8d, 0x46, 0x69, 0xb7, 0xdb, 0x0f,
  0xe8, 0xd3, 0x0c, 0x01, 0x3c, 0xcf, 0x93, 0xae, 0xeb, 0xe2, 0x79, 0x1e,
  0xb7, 0xdb, 0x0d, 0x9f, 0xcf, 0x87, 0xa2, 0x28, 0x5c, 0x2e, 0x17, 0x7a,
  0xbd, 0x1e, 0xc7, 0xe3, 0x91, 0x58, 0x2c, 0x46, 0xab, 0xd5, 0x7a, 0x0a,
  0x7d, 0xbc, 0x14, 0x55, 0x55, 0x85, 0xaa, 0xaa, 0x9f, 0x0c, 0x7e, 0xbf,
  0x5f, 0x36, 0x9b, 0x4d, 0xba, 0xdd, 0x2e, 0xd7, 0xeb, 0x95, 0xeb, 0xf5,
  0x8a, 0xae, 0xeb, 0x7f, 0xcf, 0xf0, 0x99, 0x5c, 0xd7, 0x95, 0x87, 0xc3,
  0x81, 0xfb, 0xfd, 0x4e, 0x36, 0x9b, 0x7d, 0xad, 0xe4, 0xff, 0xe7, 0xfb,
  0x7a, 0x1b, 0x00, 0x59, 0xa8, 0xba, 0x68, 0xca, 0x4f, 0xc5, 0xa7, 0x00,
  0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
unsigned int mag_sel_png_len = 563;

unsigned char mag_png[] = {
  0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
  0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13,
  0x08, 0x06, 0x00, 0x00, 0x00, 0x90, 0x8c, 0x2d, 0xb5, 0x00, 0x00, 0x00,
  0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
  0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48,
  0x52, 0x4d, 0x00, 0x00, 0x6d, 0x98, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x00,
  0xe0, 0x38, 0x00, 0x00, 0x82, 0xd5, 0x00, 0x00, 0x7a, 0x07, 0x00, 0x00,
  0xca, 0xb4, 0x00, 0x00, 0x33, 0x44, 0x00, 0x00, 0x1c, 0x76, 0x84, 0x36,
  0x2a, 0xbd, 0x00, 0x00, 0x01, 0x92, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
  0xe4, 0x94, 0xbb, 0xaa, 0xea, 0x50, 0x10, 0x86, 0xbf, 0xec, 0x08, 0x29,
  0x36, 0x24, 0x85, 0x17, 0xbc, 0x81, 0x18, 0x11, 0x6c, 0xd4, 0x42, 0x8c,
  0x0f, 0x61, 0xe1, 0x2b, 0xf8, 0x0a, 0x0a, 0x3e, 0x8f, 0xf8, 0x0c, 0x36,
  0x62, 0x1f, 0x92, 0x88, 0x88, 0x10, 0x9b, 0x14, 0x42, 0x44, 0x45, 0x41,
  0x2c, 0xac, 0x92, 0x80, 0xb2, 0x4e, 0x73, 0x94, 0x03, 0xfb, 0xb0, 0x4d,
  0xb1, 0x8b, 0x03, 0xe7, 0xaf, 0xd6, 0x62, 0xfe, 0xf5, 0x31, 0xc3, 0xcc,
  0x1a, 0x49, 0x08, 0xc1, 0x4f, 0xea, 0x83, 0x1f, 0xd6, 0xbf, 0x0f, 0x4c,
  0x3c, 0x0f, 0xd7, 0xeb, 0x55, 0x38, 0x8e, 0xc3, 0x66, 0xb3, 0x61, 0xb7,
  0xdb, 0x51, 0x2a, 0x95, 0xa8, 0xd7, 0xeb, 0x18, 0x86, 0x41, 0x32, 0x99,
  0x94, 0xe2, 0x02, 0x25, 0x21, 0x04, 0x97, 0xcb, 0x45, 0x4c, 0xa7, 0x53,
  0x6c, 0xdb, 0xfe, 0x62, 0xe8, 0x74, 0x3a, 0xf4, 0x7a, 0x3d, 0x52, 0xa9,
  0x94, 0x14, 0x3b, 0xc3, 0xc5, 0x62, 0x81, 0x6d, 0xdb, 0x94, 0xcb, 0x65,
  0x5a, 0xad, 0x16, 0x95, 0x4a, 0x85, 0xed, 0x76, 0xcb, 0x72, 0xb9, 0xc4,
  0x71, 0x1c, 0xb2, 0xd9, 0x2c, 0xdd, 0x6e, 0x37, 0x7e, 0xc9, 0xae, 0xeb,
  0x02, 0xd0, 0x6e, 0xb7, 0x31, 0x0c, 0x03, 0x55, 0x55, 0xa5, 0x74, 0x3a,
  0x2d, 0x64, 0x59, 0xc6, 0xf7, 0x7d, 0x5c, 0xd7, 0x8d, 0x0d, 0xfc, 0x00,
  0xd8, 0xef, 0xf7, 0x00, 0x34, 0x9b, 0x4d, 0x54, 0x55, 0x95, 0x00, 0x54,
  0x55, 0x95, 0x1a, 0x8d, 0x06, 0x7f, 0xc6, 0x63, 0x03, 0x8b, 0xc5, 0x22,
  0x00, 0x9e, 0xe7, 0x01, 0x3c, 0x27, 0x5d, 0xfc, 0xbe, 0xbf, 0xe2, 0xb1,
  0x81, 0xb5, 0x5a, 0x0d, 0x00, 0xd3, 0x34, 0xb1, 0x2c, 0x8b, 0x20, 0x08,
  0x84, 0x65, 0x59, 0x98, 0xa6, 0x09, 0x80, 0xae, 0xeb, 0xaf, 0x07, 0xf3,
  0xf9, 0xfc, 0x7d, 0x97, 0x7d, 0xdf, 0x17, 0xb3, 0xd9, 0x8c, 0xd5, 0x6a,
  0xf5, 0x57, 0x53, 0x26, 0x93, 0x61, 0x34, 0x1a, 0xa1, 0x69, 0x9a, 0x14,
  0x6b, 0x6c, 0xa2, 0x28, 0x12, 0x87, 0xc3, 0x81, 0xf5, 0x7a, 0x8d, 0xe7,
  0x79, 0x1c, 0x8f, 0x47, 0x0a, 0x85, 0x02, 0xba, 0xae, 0xe3, 0xba, 0x2e,
  0x97, 0xcb, 0x85, 0x5c, 0x2e, 0xc7, 0x70, 0x38, 0x7c, 0x0b, 0x95, 0x9e,
  0xcb, 0x21, 0x8a, 0x22, 0x11, 0x04, 0x01, 0x51, 0x14, 0x71, 0xbf, 0xdf,
  0x49, 0x24, 0x12, 0xc8, 0xb2, 0xcc, 0xed, 0x76, 0x63, 0x32, 0x99, 0x70,
  0x3e, 0x9f, 0xc9, 0xe7, 0xf3, 0x0c, 0x06, 0x83, 0x6f, 0xa1, 0xaf, 0x9f,
  0xa2, 0x28, 0x8a, 0xa4, 0x28, 0xca, 0x17, 0xc3, 0xe7, 0xe7, 0xa7, 0xe8,
  0xf7, 0xfb, 0x8c, 0xc7, 0x63, 0xc2, 0x30, 0x24, 0x0c, 0x43, 0x34, 0x4d,
  0x7b, 0x9f, 0xe1, 0x77, 0x0a, 0x82, 0x40, 0x9c, 0x4e, 0x27, 0x1e, 0x8f,
  0x07, 0xd5, 0x6a, 0x35, 0x5e, 0xc9, 0xff, 0xcf, 0xfa, 0xfa, 0x35, 0x00,
  0x70, 0xf3, 0xae, 0xcb, 0x89, 0xcd, 0xd2, 0x46, 0x00, 0x00, 0x00, 0x00,
  0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
unsigned int mag_png_len = 524;

unsigned char search_l_png[] = {
  0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
  0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13,
  0x08, 0x06, 0x00, 0x00, 0x00, 0x90, 0x8c, 0x2d, 0xb5, 0x00, 0x00, 0x00,
  0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
  0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48,
  0x52, 0x4d, 0x00, 0x00, 0x6d, 0x98, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x00,
  0xe0, 0x38, 0x00, 0x00, 0x82, 0xd5, 0x00, 0x00, 0x7a, 0x07, 0x00, 0x00,
  0xca, 0xb4, 0x00, 0x00, 0x33, 0x44, 0x00, 0x00, 0x1c, 0x76, 0x84, 0x36,
  0x2a, 0xbd, 0x00, 0x00, 0x01, 0xe2, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
  0xac, 0x54, 0x3d, 0xab, 0xda, 0x50, 0x18, 0x7e, 0xce, 0xc9, 0x39, 0x31,
  0x4d, 0xfc, 0x40, 0x30, 0x46, 0x14, 0xec, 0x50, 0x44, 0x17, 0x2f, 0x9d,
  0xba, 0x15, 0xda, 0xd1, 0xa1, 0x2e, 0xdd, 0x3b, 0x14, 0x4a, 0xa1, 0x7f,
  0xa6, 0x74, 0xbd, 0x43, 0xff, 0x84, 0xfd, 0x05, 0x82, 0xda, 0xa5, 0x83,
  0x1d, 0xdc, 0x8a, 0x88, 0xa0, 0x44, 0x83, 0xc6, 0x28, 0xad, 0x1f, 0x49,
  0xde, 0x2e, 0x8d, 0x78, 0x6f, 0xaf, 0x34, 0x68, 0x9f, 0xed, 0xbc, 0x70,
  0x1e, 0x9e, 0x8f, 0xf7, 0x1c, 0x46, 0x44, 0x38, 0x45, 0xaf, 0xd7, 0x63,
  0xb6, 0x6d, 0xe7, 0x6d, 0xdb, 0x6e, 0xba, 0xae, 0xfb, 0x6e, 0xb3, 0xd9,
  0xdc, 0x6c, 0xb7, 0xdb, 0x04, 0xe7, 0x1c, 0x8c, 0x31, 0xfc, 0x0b, 0x2c,
  0x22, 0xec, 0x76, 0xbb, 0xcc, 0xf3, 0xbc, 0xcc, 0x68, 0x34, 0x7a, 0xed,
  0xba, 0xee, 0x87, 0x6c, 0x36, 0x7b, 0x93, 0xcb, 0xe5, 0x44, 0x3a, 0x9d,
  0x86, 0xa6, 0x69, 0x50, 0x14, 0x25, 0x3e, 0x61, 0xa7, 0xd3, 0x61, 0xf3,
  0xf9, 0xfc, 0xc9, 0x78, 0x3c, 0xbe, 0xd5, 0x75, 0xfd, 0x79, 0xa5, 0x52,
  0x11, 0xa6, 0x69, 0x22, 0x95, 0x4a, 0x41, 0xd3, 0x34, 0x08, 0x21, 0xc0,
  0x18, 0x8b, 0x45, 0x28, 0x00, 0x60, 0xb5, 0x5a, 0xa5, 0x27, 0x93, 0xc9,
  0xa7, 0x62, 0xb1, 0xf8, 0xb2, 0x5a, 0xad, 0x22, 0x9f, 0xcf, 0xc3, 0x30,
  0x0c, 0x48, 0x29, 0xc1, 0x39, 0x47, 0x5c, 0xbb, 0x00, 0x20, 0xda, 0xed,
  0x36, 0x9f, 0x4e, 0xa7, 0xaf, 0x4c, 0xd3, 0x7c, 0x51, 0xaf, 0xd7, 0x61,
  0x59, 0x16, 0x74, 0x5d, 0x87, 0x94, 0x12, 0x97, 0x40, 0x2c, 0x16, 0x0b,
  0x93, 0x88, 0xde, 0xd6, 0x6a, 0x35, 0xdd, 0xb2, 0x2c, 0x18, 0x86, 0x01,
  0x21, 0x04, 0x2e, 0x05, 0xf7, 0x3c, 0xaf, 0x59, 0x2e, 0x97, 0x9f, 0x45,
  0xca, 0x38, 0xe7, 0xb8, 0x06, 0x3c, 0x08, 0x82, 0x46, 0xa1, 0x50, 0x78,
  0x74, 0xad, 0xb2, 0x23, 0xa1, 0x94, 0xf2, 0x69, 0x26, 0x93, 0xe1, 0x51,
  0x66, 0xf7, 0xf7, 0xd2, 0xf7, 0xfd, 0x07, 0x2f, 0x9e, 0x9b, 0x73, 0x55,
  0x55, 0xb3, 0x91, 0x55, 0xc6, 0x18, 0xc2, 0x30, 0xbc, 0x1b, 0xf2, 0x19,
  0xd5, 0xe7, 0xe6, 0x5c, 0x4a, 0x39, 0x06, 0x70, 0x5c, 0x8b, 0xb8, 0xeb,
  0x71, 0xd6, 0x32, 0x11, 0x75, 0xf6, 0xfb, 0xfd, 0xd1, 0xea, 0xd5, 0xa5,
  0x10, 0xd1, 0xb7, 0xf5, 0x7a, 0x1d, 0x84, 0x61, 0x08, 0x22, 0xba, 0x9e,
  0x50, 0x51, 0x94, 0xaf, 0x8e, 0xe3, 0xfc, 0xdc, 0xed, 0x76, 0xf8, 0x1f,
  0xe0, 0x89, 0x44, 0xe2, 0xc7, 0x72, 0xb9, 0xfc, 0xee, 0x38, 0x0e, 0x7c,
  0xdf, 0x3f, 0x5a, 0xbf, 0xdf, 0x76, 0x6c, 0xc2, 0x46, 0xa3, 0xf1, 0x2b,
  0x08, 0x82, 0xdb, 0xe1, 0x70, 0xe8, 0x2c, 0x16, 0x0b, 0x04, 0x41, 0x00,
  0x22, 0xba, 0xb8, 0x1c, 0xfe, 0x67, 0x05, 0xbe, 0x78, 0x9e, 0xf7, 0x79,
  0x30, 0x18, 0x8c, 0x67, 0xb3, 0x19, 0x45, 0x25, 0x9d, 0x53, 0x49, 0x44,
  0x38, 0x1c, 0x0e, 0x38, 0x2d, 0xf3, 0xce, 0x6f, 0x03, 0x60, 0x29, 0x84,
  0xf8, 0xe8, 0x79, 0x9e, 0xdb, 0xef, 0xf7, 0xdf, 0x97, 0x4a, 0xa5, 0xc7,
  0xd1, 0x53, 0x54, 0x55, 0x15, 0x52, 0xca, 0xbf, 0x14, 0x0b, 0x21, 0x1e,
  0x8c, 0x87, 0x9d, 0x1e, 0x5a, 0xad, 0x96, 0x00, 0x50, 0x27, 0xa2, 0x37,
  0xaa, 0xaa, 0x36, 0x0d, 0xc3, 0x28, 0x26, 0x93, 0x49, 0xa1, 0x69, 0x9a,
  0xc2, 0x39, 0x8f, 0x95, 0xc1, 0xef, 0x01, 0x00, 0x35, 0xe5, 0xd5, 0x5e,
  0xd0, 0xed, 0x0c, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44,
  0xae, 0x42, 0x60, 0x82
};
unsigned int search_l_png_len = 604;

unsigned char search_m_png[] = {
  0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
  0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13,
  0x08, 0x02, 0x00, 0x00, 0x00, 0x35, 0x5e, 0x4b, 0x4d, 0x00, 0x00, 0x00,
  0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xd6, 0xd8, 0xd4, 0x4f, 0x58,
  0x32, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66,
  0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20,
  0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x61, 0x64, 0x79, 0x71, 0xc9,
  0x65, 0x3c, 0x00, 0x00, 0x00, 0x30, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
  0x62, 0x2c, 0x2f, 0x2f, 0x67, 0x60, 0x60, 0x60, 0x3c, 0x7e, 0xfc, 0x38,
  0x88, 0xfa, 0xf8, 0xf1, 0x23, 0x88, 0xfa, 0xff, 0xff, 0x3f, 0x90, 0x62,
  0x62, 0x00, 0x03, 0x5a, 0x50, 0x2c, 0x10, 0x1b, 0x58, 0x6e, 0xdd, 0xba,
  0x05, 0xa4, 0x00, 0x02, 0x0c, 0x00, 0xa5, 0x07, 0x0f, 0x3c, 0x7e, 0xe1,
  0x45, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42,
  0x60, 0x82
};
unsigned int search_m_png_len = 158;

unsigned char search_r_png[] = {
  0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
  0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13,
  0x08, 0x06, 0x00, 0x00, 0x00, 0x9d, 0x92, 0x5d, 0xf2, 0x00, 0x00, 0x00,
  0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
  0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48,
  0x52, 0x4d, 0x00, 0x00, 0x6d, 0x98, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x00,
  0xe0, 0x38, 0x00, 0x00, 0x82, 0xd5, 0x00, 0x00, 0x7a, 0x07, 0x00, 0x00,
  0xca, 0xb4, 0x00, 0x00, 0x33, 0x44, 0x00, 0x00, 0x1c, 0x76, 0x84, 0x36,
  0x2a, 0xbd, 0x00, 0x00, 0x01, 0xea, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
  0xa4, 0xd4, 0xbf, 0xaa, 0x1a, 0x41, 0x14, 0x06, 0xf0, 0x6f, 0xf6, 0x9f,
  0xb2, 0x0a, 0x6b, 0xa5, 0x56, 0x8b, 0xa4, 0x92, 0xd4, 0x69, 0x7c, 0x03,
  0xb1, 0x59, 0x49, 0x11, 0x52, 0xdf, 0xbc, 0x43, 0xcc, 0x2b, 0xa4, 0x4c,
  0x97, 0x67, 0x08, 0xa4, 0x11, 0x2c, 0x52, 0x5c, 0x42, 0x24, 0x60, 0x8a,
  0x34, 0x29, 0x42, 0x50, 0x41, 0x21, 0xa0, 0x97, 0xd5, 0x55, 0xb3, 0xbb,
  0xee, 0xb2, 0xce, 0xee, 0xcc, 0x49, 0x91, 0x28, 0xc2, 0x0d, 0xe6, 0xaa,
  0xa7, 0x9d, 0xc3, 0x8f, 0x73, 0x98, 0xf9, 0x86, 0x75, 0x3a, 0x1d, 0xc2,
  0x89, 0x12, 0x42, 0x24, 0xf9, 0x7c, 0x7e, 0x5a, 0x2c, 0x16, 0x3f, 0x96,
  0x4a, 0xa5, 0x5e, 0xb5, 0x5a, 0xfd, 0x52, 0x2e, 0x97, 0xfd, 0x46, 0xa3,
  0x21, 0x8e, 0xfb, 0xd8, 0x60, 0x30, 0x38, 0x09, 0x65, 0x59, 0x86, 0x24,
  0x49, 0x10, 0x04, 0x81, 0xf0, 0x3c, 0x6f, 0xb3, 0xd9, 0x6c, 0x7e, 0x58,
  0x96, 0x75, 0x5b, 0xab, 0xd5, 0xde, 0x34, 0x9b, 0xcd, 0x5f, 0x07, 0xc8,
  0xf7, 0xfd, 0x93, 0x90, 0x94, 0xf2, 0x80, 0x85, 0x61, 0x88, 0xe5, 0x72,
  0x49, 0xe3, 0xf1, 0x58, 0xc6, 0x71, 0xfc, 0xc1, 0xb6, 0xed, 0xe7, 0x8e,
  0xe3, 0x84, 0x00, 0xc0, 0xa4, 0x94, 0x27, 0x21, 0x22, 0x82, 0x94, 0x12,
  0x52, 0x4a, 0xa4, 0x69, 0x8a, 0x28, 0x8a, 0xb0, 0x58, 0x2c, 0x30, 0x1c,
  0x0e, 0x85, 0xeb, 0xba, 0xef, 0x6b, 0xb5, 0xda, 0x4d, 0xab, 0xd5, 0x8a,
  0x34, 0xc6, 0xd8, 0x29, 0x07, 0x8c, 0x31, 0x28, 0x8a, 0x02, 0x22, 0x82,
  0xae, 0xeb, 0x30, 0x0c, 0x03, 0xb9, 0x5c, 0x0e, 0x86, 0x61, 0xa8, 0x52,
  0xca, 0xa7, 0xf3, 0xf9, 0xfc, 0x67, 0xbf, 0xdf, 0x7f, 0xa5, 0xe0, 0x81,
  0xc5, 0x18, 0x03, 0x63, 0x0c, 0x9a, 0xa6, 0xa1, 0x50, 0x28, 0xa0, 0x52,
  0xa9, 0xa0, 0x5e, 0xaf, 0x6b, 0x00, 0x5e, 0xac, 0xd7, 0xeb, 0x47, 0x0f,
  0x86, 0x8e, 0x41, 0x55, 0x55, 0x61, 0x9a, 0x26, 0x2a, 0x95, 0x0a, 0x6c,
  0xdb, 0xb6, 0x82, 0x20, 0x78, 0x76, 0x36, 0xb4, 0xc7, 0xf6, 0x93, 0x55,
  0xab, 0x55, 0x26, 0x84, 0x78, 0xac, 0x1c, 0x5f, 0xf3, 0xb9, 0xa5, 0xeb,
  0x3a, 0x2c, 0xcb, 0x82, 0xae, 0xeb, 0xbb, 0x03, 0xa4, 0x69, 0xda, 0xd9,
  0x53, 0x29, 0x8a, 0x02, 0xd3, 0x34, 0x99, 0x61, 0x18, 0xcb, 0x8b, 0x56,
  0x3b, 0xc6, 0xfe, 0x4e, 0x76, 0x77, 0x15, 0x44, 0x44, 0xe0, 0x9c, 0x0b,
  0x22, 0xfa, 0xaa, 0x5c, 0x83, 0x48, 0x29, 0x11, 0x86, 0xe1, 0x86, 0x88,
  0xbe, 0x5f, 0x35, 0xd1, 0x6e, 0xb7, 0x83, 0xe7, 0x79, 0x3d, 0x55, 0x55,
  0x7d, 0xd0, 0x05, 0x25, 0xa5, 0x24, 0xce, 0x39, 0x4d, 0x26, 0x93, 0x45,
  0xb7, 0xdb, 0x7d, 0x42, 0x44, 0x50, 0x2e, 0x59, 0x49, 0x08, 0x81, 0xf5,
  0x7a, 0x9d, 0x4c, 0xa7, 0xd3, 0x77, 0x42, 0x88, 0x6f, 0x00, 0xa0, 0xed,
  0x0f, 0xb3, 0x2c, 0x3b, 0xe4, 0xe9, 0x5f, 0xf9, 0x23, 0xfa, 0x93, 0x6d,
  0xce, 0x39, 0x56, 0xab, 0x95, 0x18, 0x0e, 0x87, 0x9f, 0x82, 0x20, 0x78,
  0xdd, 0x6e, 0xb7, 0xd3, 0x7b, 0xe9, 0x27, 0xa2, 0x7b, 0x08, 0x11, 0x21,
  0x4d, 0x53, 0x70, 0xce, 0x11, 0xc7, 0xb1, 0x74, 0x5d, 0xd7, 0x9f, 0xcd,
  0x66, 0x3d, 0xce, 0xf9, 0x4b, 0xc7, 0x71, 0xee, 0x0e, 0xef, 0x70, 0x34,
  0x1a, 0xe1, 0x7f, 0xff, 0x51, 0x92, 0x24, 0xd8, 0x6e, 0xb7, 0x61, 0x14,
  0x45, 0x9f, 0x39, 0xe7, 0x6f, 0x19, 0x63, 0xb7, 0x8e, 0xe3, 0x44, 0xc7,
  0x7d, 0xbf, 0x07, 0x00, 0x5f, 0x77, 0x46, 0x8c, 0x30, 0x2c, 0xd8, 0x9d,
  0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
unsigned int search_r_png_len = 612;

static unsigned char close_png[] = {
  0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
  0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b,
  0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0xac, 0x77, 0x26, 0x00, 0x00, 0x00,
  0xd8, 0x49, 0x44, 0x41, 0x54, 0x18, 0x19, 0x75, 0x51, 0xbd, 0x12, 0x46,
  0x40, 0x0c, 0xdc, 0x18, 0x15, 0x0a, 0x14, 0x14, 0x1a, 0x43, 0xeb, 0x35,
  0xbc, 0x7f, 0xa7, 0x43, 0x67, 0x06, 0x33, 0x28, 0xd0, 0xde, 0x77, 0x7b,
  0x23, 0x2a, 0xdf, 0x16, 0x97, 0x9f, 0xdb, 0xcb, 0x26, 0x39, 0xc1, 0x83,
  0x7d, 0xdf, 0xcd, 0xb2, 0x2c, 0xd8, 0xb6, 0x0d, 0xe7, 0x79, 0x22, 0x8a,
  0x22, 0xc4, 0x71, 0x8c, 0x3c, 0xcf, 0x91, 0xa6, 0xa9, 0x90, 0xe6, 0x8e,
  0x69, 0x9a, 0xcc, 0x38, 0x8e, 0xb8, 0xae, 0x4b, 0xdf, 0xbe, 0x36, 0x0c,
  0x43, 0x94, 0x65, 0x89, 0xa2, 0x28, 0xc4, 0x3b, 0x8e, 0xe3, 0x2f, 0x91,
  0x2f, 0xa8, 0xc2, 0x42, 0x56, 0xd1, 0x78, 0xf3, 0x3c, 0xbb, 0x04, 0x2f,
  0xda, 0xb6, 0x45, 0x55, 0x55, 0x74, 0x9d, 0x65, 0x2c, 0x22, 0xb8, 0xef,
  0x1b, 0xeb, 0xba, 0xc2, 0x67, 0x8f, 0x4c, 0x10, 0x7d, 0xdf, 0xa3, 0xae,
  0x6b, 0xe7, 0xd3, 0x32, 0x56, 0x90, 0xe7, 0x53, 0x46, 0x31, 0x0c, 0x83,
  0x73, 0x95, 0xa8, 0x31, 0x93, 0x9c, 0xc7, 0xe3, 0xd4, 0x0a, 0xb6, 0xa0,
  0x44, 0x5a, 0xc6, 0xc6, 0x18, 0x77, 0xcd, 0x41, 0xbd, 0x24, 0x49, 0x94,
  0xfb, 0x12, 0x59, 0x51, 0x5b, 0xd2, 0x16, 0xed, 0xfa, 0x20, 0xdc, 0x6f,
  0xd7, 0x75, 0x9f, 0x6b, 0xd3, 0x2a, 0x41, 0x10, 0xa0, 0x69, 0x1a, 0x57,
  0x59, 0x28, 0x47, 0x99, 0x2f, 0x30, 0xcf, 0x7b, 0xfb, 0x41, 0xcf, 0x1a,
  0x2c, 0xeb, 0xeb, 0x07, 0x29, 0x9d, 0x65, 0x19, 0x6c, 0xab, 0x6e, 0x5d,
  0x3f, 0x07, 0x0a, 0x79, 0x90, 0x0e, 0x11, 0x45, 0xc2, 0x00, 0x00, 0x00,
  0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static unsigned int close_png_len = 273;


static unsigned char closed_png[81] =
{
  0,  0,  0,  0,142,  0,  0,  0,  0,
  0,  0,  0,  0,142,142,  0,  0,  0,
  0,  0,  0,  0,142,142,142,  0,  0,
  0,  0,  0,  0,142,142,142,142,  0,
  0,  0,  0,  0,142,142,142,142,142,
  0,  0,  0,  0,142,142,142,142,  0,
  0,  0,  0,  0,142,142,142,  0,  0,
  0,  0,  0,  0,142,142,  0,  0,  0,
  0,  0,  0,  0,142,  0,  0,  0,  0
};

static unsigned char closed_a_png[81] =
{
  0,  0,  0,  0,255,  0,  0,  0,  0,
  0,  0,  0,  0,255,255,  0,  0,  0,
  0,  0,  0,  0,255,255,255,  0,  0,
  0,  0,  0,  0,255,255,255,255,  0,
  0,  0,  0,  0,255,255,255,255,255,
  0,  0,  0,  0,255,255,255,255,  0,
  0,  0,  0,  0,255,255,255,  0,  0,
  0,  0,  0,  0,255,255,  0,  0,  0,
  0,  0,  0,  0,255,  0,  0,  0,  0
};

static unsigned char open_png[81] =
{
    0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,
  142,142,142,142,142,142,142,142,142,
    0,142,142,142,142,142,142,142,  0,
    0,  0,142,142,142,142,142,  0,  0,
    0,  0,  0,142,142,142,  0,  0,  0,
    0,  0,  0,  0,142,  0,  0,  0,  0
};

static unsigned char open_a_png[81] =
{
    0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,
  255,255,255,255,255,255,255,255,255,
    0,255,255,255,255,255,255,255,  0,
    0,  0,255,255,255,255,255,  0,  0,
    0,  0,  0,255,255,255,  0,  0,  0,
    0,  0,  0,  0,255,  0,  0,  0,  0
};

static unsigned char bdwn_png[7*8] =
{
    0,  0,  0,142,  0,  0,  0,
    0,  0,  0,142,  0,  0,  0,
    0,  0,  0,142,  0,  0,  0,
  142,  0,  0,142,  0,  0,142,
  142,142,  0,142,  0,142,142,
  142,142,142,142,142,142,142,
    0,142,142,142,142,142,  0,
    0,  0,142,142,142,  0,  0,
};

static unsigned char bdwn_a_png[7*8] =
{
    0,  0,  0,255,  0,  0,  0,
    0,  0,  0,255,  0,  0,  0,
    0,  0,  0,255,  0,  0,  0,
  128,  0,  0,255,  0,  0,128,
  255,128,  0,255,  0,128,255,
  128,255,128,255,128,255,128,
    0,128,255,255,255,128,  0,
    0,  0,128,255,128,  0,  0,
};

static unsigned char sync_on_png[576] =
{
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,138,128,128,128,128,133,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,129,205,186,128,128,128,128,160,210,134,128,128,128,128,128,128,128,
  128,128,128,128,128,128,139,217,255,181,128,128,128,128,152,255,229,147,128,128,128,128,128,128,
  128,128,128,128,128,156,236,255,255,181,128,128,128,128,152,255,255,243,164,128,128,128,128,128,
  128,128,128,128,175,249,255,255,255,223,196,198,198,197,211,255,255,255,253,186,128,128,128,128,
  128,128,133,202,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,214,137,128,128,
  128,128,135,217,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,225,140,128,128,
  128,128,128,128,189,255,255,255,255,238,224,225,225,224,232,255,255,255,255,201,131,128,128,128,
  128,128,128,128,128,167,245,255,255,183,128,128,128,128,155,255,255,250,179,128,128,128,128,128,
  128,128,128,128,128,128,150,231,255,188,128,128,128,128,161,255,238,158,128,128,128,128,128,128,
  128,128,128,128,128,128,128,136,216,188,128,128,128,128,161,223,142,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,130,141,128,128,128,128,135,132,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128
};

static unsigned char sync_off_png[576] =
{
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,138,128,128,128,128,128,128,133,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,129,205,186,128,128,128,128,128,128,160,210,134,128,128,128,128,128,128,
  128,128,128,128,128,139,217,255,181,128,128,128,128,128,128,152,255,229,147,128,128,128,128,128,
  128,128,128,128,156,236,255,255,181,128,128,128,128,128,128,152,255,255,243,164,128,128,128,128,
  128,128,128,175,249,255,255,255,223,196,198,198,128,128,197,211,255,255,255,253,186,128,128,128,
  128,128,202,255,255,255,255,255,255,255,255,225,128,128,255,255,255,255,255,255,255,214,128,128,
  128,128,217,255,255,255,255,255,255,255,255,128,128,198,255,255,255,255,255,255,255,225,128,128,
  128,128,128,189,255,255,255,255,238,224,225,128,128,225,224,232,255,255,255,255,201,128,128,128,
  128,128,128,128,167,245,255,255,183,128,128,128,128,128,128,155,255,255,250,179,128,128,128,128,
  128,128,128,128,128,150,231,255,188,128,128,128,128,128,128,161,255,238,158,128,128,128,128,128,
  128,128,128,128,128,128,136,216,188,128,128,128,128,128,128,161,223,142,128,128,128,128,128,128,
  128,128,128,128,128,128,128,130,141,128,128,128,128,128,128,135,132,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128
};

static unsigned char sync_a_png[576] =
{
    0,  0,  0,  0,  0,  0,  0, 29, 98,157,207,231,234,211,164,104, 38,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0, 21,143,234,255,255,255,255,255,255,255,255,244,155, 33,  0,  0,  0,  0,  0,
    0,  0,  0,  0, 70,221,255,255,255,255,255,255,255,255,255,255,255,255,235, 93,  0,  0,  0,  0,
    0,  0,  0, 92,251,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,116,  0,  0,  0,
    0,  0, 68,251,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 96,  0,  0,
    0, 20,225,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,243, 41,  0,
    0,143,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,172,  1,
   28,238,255,255,255,255,255,253,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 42,
   99,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,133,
  160,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,204,
  212,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,224,
  234,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,237,255,236,
  235,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,230,255,236,
  216,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,226,
  168,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,208,
  107,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,147,
   39,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 53,
    0,159,255,255,255,255,255,255,251,255,255,255,255,255,255,255,255,255,255,255,255,255,190,  3,
    0, 31,239,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,249, 54,  0,
    0,  0, 91,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,119,  0,  0,
    0,  0,  0,116,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,145,  0,  0,  0,
    0,  0,  0,  0, 98,240,255,255,255,255,255,255,255,255,255,255,255,255,248,119,  0,  0,  0,  0,
    0,  0,  0,  0,  0, 45,168,252,255,255,255,255,255,255,255,255,255,184, 58,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0, 45,131,201,222,234,236,224,204,142, 54,  0,  0,  0,  0,  0,  0,  0
};


//------------------------------------------------------------------------

static const char tabs_css[] = 
".tabs, .tabs2, .tabs3 {\n"
"    background-image: url('tab_b.png');\n"
"    width: 100%;\n"
"    z-index: 101;\n"
"    font-size: 13px;\n"
"    font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;\n"
"}\n"
"\n"
".tabs2 {\n"
"    font-size: 10px;\n"
"}\n"
".tabs3 {\n"
"    font-size: 9px;\n"
"}\n"
"\n"
".tablist {\n"
"    margin: 0;\n"
"    padding: 0;\n"
"    display: table;\n"
"}\n"
"\n"
".tablist li {\n"
"    float: left;\n"
"    display: table-cell;\n"
"    background-image: url('tab_b.png');\n"
"    line-height: 36px;\n"
"    list-style: none;\n"
"}\n"
"\n"
".tablist a {\n"
"    display: block;\n"
"    padding: 0 20px;\n"
"    font-weight: bold;\n"
"    background-image:url('tab_s.png');\n"
"    background-repeat:no-repeat;\n"
"    background-position:right;\n"
"    color: ##30;\n"
"    text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);\n"
"    text-decoration: none;\n"
"    outline: none;\n"
"}\n"
"\n"
".tabs3 .tablist a {\n"
"    padding: 0 10px;\n"
"}\n"
"\n"
".tablist a:hover {\n"
"    background-image: url('tab_h.png');\n"
"    background-repeat:repeat-x;\n"
"    color: #fff;\n"
"    text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);\n"
"    text-decoration: none;\n"
"}\n"
"\n"
".tablist li.current a {\n"
"    background-image: url('tab_a.png');\n"
"    background-repeat:repeat-x;\n"
"    color: #fff;\n"
"    text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);\n"
"}\n"
;

struct img_data_item
{
  const char *name;
  unsigned char *content;
  unsigned int len;
};


static void writeImgData(const char *dir,img_data_item *data)
{
  while (data->name)
  {
    QCString fileName;
    fileName=(QCString)dir+"/"+data->name;
    QFile f(fileName);
    if (f.open(IO_WriteOnly))
    {
      f.writeBlock((char*)data->content,
                    data->len>0 ? data->len : qstrlen((char*)data->content));
    }
    else
    {
      fprintf(stderr,"Warning: Cannot open file %s for writing\n",data->name);
    }
    Doxygen::indexList->addImageFile(QCString("/search/")+data->name);
    data++;
  }
}

static ColoredImgDataItem colored_tab_data[] =
{
  // file_name      W   H  luma_data        alpha_data
  { "tab_a.png",    1, 36, tab_a_png,       0 },
  { "tab_b.png",    1, 36, tab_b_png,       0 },
  { "tab_h.png",    1, 36, tab_h_png,       0 },
  { "tab_s.png",    1, 36, tab_s_png,       0 },
  { "nav_h.png",    1, 12, header_png,      0 },
  { "nav_f.png",    1, 56, func_header_png, 0 },
  { "bc_s.png",     8, 30, bc_s_png,        bc_s_a_png },
  { "doxygen.png", 104,31, doxygen_png,     doxygen_a_png },
  { "closed.png",   9,  9, closed_png,      closed_a_png },
  { "open.png",     9,  9, open_png,        open_a_png },
  { "bdwn.png",     7,  8, bdwn_png,        bdwn_a_png },
  { "sync_on.png", 24, 24, sync_on_png,     sync_a_png },
  { "sync_off.png",24, 24, sync_off_png,    sync_a_png },
  { 0, 0, 0, 0, 0 }
};

static img_data_item search_client_data[] =
{
  // file_name          raw_data          num bytes
  { "mag_sel.png",      mag_sel_png,      mag_sel_png_len  },
  { "search_l.png",     search_l_png,     search_l_png_len },
  { "search_m.png",     search_m_png,     search_m_png_len },
  { "search_r.png",     search_r_png,     search_r_png_len },
  { "close.png",        close_png,        close_png_len    },
  { 0, 0, 0 }
};

static img_data_item search_server_data[] =
{
  // file_name          raw_data          num bytes
  { "mag.png",          mag_png,          mag_png_len      },
  { "search_l.png",     search_l_png,     search_l_png_len },
  { "search_m.png",     search_m_png,     search_m_png_len },
  { "search_r.png",     search_r_png,     search_r_png_len },
  { 0, 0, 0 }
};

//------------------------------------------------------------------------

static void writeClientSearchBox(FTextStream &t,const char *relPath)
{
  t << "        <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n";
  t << "        <span class=\"left\">\n";
  t << "          <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag_sel.png\"\n";
  t << "               onmouseover=\"return searchBox.OnSearchSelectShow()\"\n";
  t << "               onmouseout=\"return searchBox.OnSearchSelectHide()\"\n";
  t << "               alt=\"\"/>\n";
  t << "          <input type=\"text\" id=\"MSearchField\" value=\"" 
    << theTranslator->trSearch() << "\" accesskey=\"S\"\n";
  t << "               onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n";
  t << "               onblur=\"searchBox.OnSearchFieldFocus(false)\" \n";
  t << "               onkeyup=\"searchBox.OnSearchFieldChange(event)\"/>\n";
  t << "          </span><span class=\"right\">\n";
  t << "            <a id=\"MSearchClose\" href=\"javascript:searchBox.CloseResultsWindow()\">"
    << "<img id=\"MSearchCloseImg\" border=\"0\" src=\"" << relPath << "search/close.png\" alt=\"\"/></a>\n";
  t << "          </span>\n";
  t << "        </div>\n";
}

static void writeServerSearchBox(FTextStream &t,const char *relPath,bool highlightSearch)
{
  static bool externalSearch = Config_getBool("EXTERNAL_SEARCH");
  t << "        <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n";
  t << "          <div class=\"left\">\n";
  t << "            <form id=\"FSearchBox\" action=\"" << relPath;
  if (externalSearch)
  {
    t << "search" << Doxygen::htmlFileExtension;
  }
  else
  {
    t << "search.php";
  }
  t << "\" method=\"get\">\n";
  t << "              <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag.png\" alt=\"\"/>\n";
  if (!highlightSearch)
  {
    t << "              <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\""
      << theTranslator->trSearch() << "\" size=\"20\" accesskey=\"S\" \n";
    t << "                     onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n";
    t << "                     onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n";
    t << "            </form>\n";
    t << "          </div><div class=\"right\"></div>\n";
    t << "        </div>\n";
  }
}

//------------------------------------------------------------------------

/// substitute all occurrences of \a src in \a s by \a dst
QCString substitute(const char *s,const char *src,const char *dst)
{
  if (s==0 || src==0) return s;
  const char *p, *q;
  int srcLen = qstrlen(src);
  int dstLen = dst ? qstrlen(dst) : 0;
  int resLen;
  if (srcLen!=dstLen)
  {
    int count;
    for (count=0, p=s; (q=strstr(p,src))!=0; p=q+srcLen) count++;
    resLen = (int)(p-s)+qstrlen(p)+count*(dstLen-srcLen);
  }
  else // result has same size as s
  {
    resLen = qstrlen(s);
  }
  QCString result(resLen+1);
  char *r;
  for (r=result.data(), p=s; (q=strstr(p,src))!=0; p=q+srcLen)
  {
    int l = (int)(q-p);
    memcpy(r,p,l);
    r+=l;
    if (dst) memcpy(r,dst,dstLen);
    r+=dstLen;
  }
  qstrcpy(r,p);
  //printf("substitute(%s,%s,%s)->%s\n",s,src,dst,result.data());
  return result;
}
//----------------------------------------------------------------------

/// Clear a text block \a s from \a begin to \a end markers
QCString clearBlock(const char *s,const char *begin,const char *end)
{
  if (s==0 || begin==0 || end==0) return s;
  const char *p, *q;
  int beginLen = qstrlen(begin);
  int endLen = qstrlen(end);
  int resLen = 0;
  for (p=s; (q=strstr(p,begin))!=0; p=q+endLen)
  {
    resLen+=(int)(q-p);
    p=q+beginLen;
    if ((q=strstr(p,end))==0)
    {
      resLen+=beginLen;
      break;
    }
  }
  resLen+=qstrlen(p);
  // resLen is the length of the string without the marked block

  QCString result(resLen+1);
  char *r;
  for (r=result.data(), p=s; (q=strstr(p,begin))!=0; p=q+endLen)
  {
    int l = (int)(q-p);
    memcpy(r,p,l);
    r+=l;
    p=q+beginLen;
    if ((q=strstr(p,end))==0)
    {
      memcpy(r,begin,beginLen);
      r+=beginLen;
      break;
    }
  }
  qstrcpy(r,p);
  return result;
}
//----------------------------------------------------------------------

QCString selectBlock(const QCString& s,const QCString &name,bool enable)
{
  const QCString begin = "<!--BEGIN " + name + "-->";
  const QCString end = "<!--END " + name + "-->";
  const QCString nobegin = "<!--BEGIN !" + name + "-->";
  const QCString noend = "<!--END !" + name + "-->";

  QCString result = s;
  if (enable)
  {
    result = substitute(result, begin, "");
    result = substitute(result, end, "");
    result = clearBlock(result, nobegin, noend);
  }
  else
  {
    result = substitute(result, nobegin, "");
    result = substitute(result, noend, "");
    result = clearBlock(result, begin, end);
  }

  return result;
}

static QCString getSearchBox(bool serverSide, QCString relPath, bool highlightSearch)
{
  QGString result;
  FTextStream t(&result);
  if (serverSide) {
    writeServerSearchBox(t, relPath, highlightSearch);
  }
  else {
     writeClientSearchBox(t, relPath);
  }
  return QCString(result);
}

static QCString removeEmptyLines(const QCString &s)
{
  BufStr out(s.length()+1);
  char *p=s.data();
  if (p)
  {
    char c;
    while ((c=*p++))
    {
      if (c=='\n')
      {
        char *e = p;
        while (*e==' ' || *e=='\t') e++;
        if (*e=='\n') 
        {
          p=e;
        }
        else out.addChar(c);
      }
      else
      {
        out.addChar(c);
      }
    }
  }
  out.addChar('\0');
  //printf("removeEmptyLines(%s)=%s\n",s.data(),out.data());
  return out.data();
}

static QCString substituteHtmlKeywords(const QCString &s,
                                       const QCString &title,
                                       const QCString &relPath,
                                       const QCString &navPath=QCString())
{
  // Build CSS/Javascript tags depending on treeview, search engine settings
  QCString cssFile;
  QStrList extraCssFile;
  QCString generatedBy;
  QCString treeViewCssJs;
  QCString searchCssJs;
  QCString searchBox;
  QCString mathJaxJs;
  QCString extraCssText;

  static QCString projectName = Config_getString("PROJECT_NAME");
  static bool timeStamp = Config_getBool("HTML_TIMESTAMP");
  static bool treeView = Config_getBool("GENERATE_TREEVIEW");
  static bool searchEngine = Config_getBool("SEARCHENGINE");
  static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
  static bool mathJax = Config_getBool("USE_MATHJAX");
  static QCString mathJaxFormat = Config_getEnum("MATHJAX_FORMAT");
  static bool disableIndex = Config_getBool("DISABLE_INDEX");
  static bool hasProjectName = !projectName.isEmpty();
  static bool hasProjectNumber = !Config_getString("PROJECT_NUMBER").isEmpty();
  static bool hasProjectBrief = !Config_getString("PROJECT_BRIEF").isEmpty();
  static bool hasProjectLogo = !Config_getString("PROJECT_LOGO").isEmpty();
  static bool titleArea = (hasProjectName || hasProjectBrief || hasProjectLogo || (disableIndex && searchEngine));

  cssFile = Config_getString("HTML_STYLESHEET");
  if (cssFile.isEmpty())
  {
    cssFile = "doxygen.css";
  }
  else
  {
    QFileInfo cssfi(cssFile);
    if (cssfi.exists())
    {
      cssFile = cssfi.fileName().utf8();
    }
    else
    {
      cssFile = "doxygen.css";
    }
  }

  extraCssText = "";
  extraCssFile = Config_getList("HTML_EXTRA_STYLESHEET");
  for (uint i=0; i<extraCssFile.count(); ++i)
  {
    QCString fileName(extraCssFile.at(i));
    if (!fileName.isEmpty())
    {
      QFileInfo fi(fileName);
      if (fi.exists())
      {
        extraCssText += "<link href=\"$relpath^"+stripPath(fileName)+"\" rel=\"stylesheet\" type=\"text/css\"/>\n";
      }
    }
  }

  if (timeStamp) 
  {
    generatedBy = theTranslator->trGeneratedAt(dateToString(TRUE), convertToHtml(Config_getString("PROJECT_NAME")));
  }
  else 
  {
    generatedBy = theTranslator->trGeneratedBy();
  }

  if (treeView)
  {
    treeViewCssJs = "<link href=\"$relpath^navtree.css\" rel=\"stylesheet\" type=\"text/css\"/>\n"
                    "<script type=\"text/javascript\" src=\"$relpath^resize.js\"></script>\n"
                    "<script type=\"text/javascript\" src=\"$relpath^navtree.js\"></script>\n"
                    "<script type=\"text/javascript\">\n"
                    "  $(document).ready(initResizable);\n"
                    "  $(window).load(resizeHeight);\n"
                    "</script>";
  }

  if (searchEngine)
  {
    searchCssJs = "<link href=\"$relpath^search/search.css\" rel=\"stylesheet\" type=\"text/css\"/>\n";
    searchCssJs += "<script type=\"text/javascript\" src=\"$relpath^search/search.js\"></script>\n";

    if (!serverBasedSearch) 
    {
      searchCssJs += "<script type=\"text/javascript\">\n"
                     "  $(document).ready(function() { searchBox.OnSelectItem(0); });\n"
                     "</script>";
    }
    else 
    {
      searchCssJs += "<script type=\"text/javascript\">\n"
                     "  $(document).ready(function() {\n"
                     "    if ($('.searchresults').length > 0) { searchBox.DOMSearchField().focus(); }\n"
                     "  });\n"
                     "</script>\n";

      // OPENSEARCH_PROVIDER {
      searchCssJs += "<link rel=\"search\" href=\"" + relPath +
                     "search-opensearch.php?v=opensearch.xml\" "
                     "type=\"application/opensearchdescription+xml\" title=\"" +
                     (hasProjectName ? projectName : QCString("Doxygen")) + 
                     "\"/>";
      // OPENSEARCH_PROVIDER }
    }
    searchBox = getSearchBox(serverBasedSearch, relPath, FALSE);
  }

  if (mathJax)
  {
    QCString path = Config_getString("MATHJAX_RELPATH");  
    if (!path.isEmpty() && path.at(path.length()-1)!='/')  
    {   
      path+="/";   
    }   
    if (path.isEmpty() || path.left(2)=="..") // relative path  
    {  
      path.prepend(relPath);   
    }  
    mathJaxJs = "<script type=\"text/x-mathjax-config\">\n"
                "  MathJax.Hub.Config({\n"
                "    extensions: [\"tex2jax.js\"";
    QStrList &mathJaxExtensions = Config_getList("MATHJAX_EXTENSIONS");
    const char *s = mathJaxExtensions.first();
    while (s)
    {
      mathJaxJs+= ", \""+QCString(s)+".js\"";
      s = mathJaxExtensions.next();
    }
    if (mathJaxFormat.isEmpty())
    {
      mathJaxFormat = "HTML-CSS";
    }
    mathJaxJs += "],\n"
                 "    jax: [\"input/TeX\",\"output/"+mathJaxFormat+"\"],\n"
                 "});\n";
    if (!g_mathjax_code.isEmpty())
    {
      mathJaxJs += g_mathjax_code;
      mathJaxJs += "\n";
    }
    mathJaxJs += "</script>";
    mathJaxJs += "<script src=\"" + path + "MathJax.js\"></script>\n";
  }

  // first substitute generic keywords
  QCString result = substituteKeywords(s,title,
        convertToHtml(Config_getString("PROJECT_NAME")),
        convertToHtml(Config_getString("PROJECT_NUMBER")),
        convertToHtml(Config_getString("PROJECT_BRIEF")));

  // additional HTML only keywords
  result = substitute(result,"$navpath",navPath);
  result = substitute(result,"$stylesheet",cssFile);
  result = substitute(result,"$treeview",treeViewCssJs);
  result = substitute(result,"$searchbox",searchBox);
  result = substitute(result,"$search",searchCssJs);
  result = substitute(result,"$mathjax",mathJaxJs);
  result = substitute(result,"$generatedby",generatedBy);
  result = substitute(result,"$extrastylesheet",extraCssText);
  result = substitute(result,"$relpath$",relPath); //<-- obsolete: for backwards compatibility only
  result = substitute(result,"$relpath^",relPath); //<-- must be last
  
  // additional HTML only conditional blocks
  result = selectBlock(result,"DISABLE_INDEX",disableIndex);
  result = selectBlock(result,"GENERATE_TREEVIEW",treeView);
  result = selectBlock(result,"SEARCHENGINE",searchEngine);
  result = selectBlock(result,"TITLEAREA",titleArea);
  result = selectBlock(result,"PROJECT_NAME",hasProjectName);
  result = selectBlock(result,"PROJECT_NUMBER",hasProjectNumber);
  result = selectBlock(result,"PROJECT_BRIEF",hasProjectBrief);
  result = selectBlock(result,"PROJECT_LOGO",hasProjectLogo);

  result = removeEmptyLines(result);

  return result;
}

//--------------------------------------------------------------------------

HtmlCodeGenerator::HtmlCodeGenerator()
   : m_streamSet(FALSE), m_col(0)
{
}

HtmlCodeGenerator::HtmlCodeGenerator(FTextStream &t,const QCString &relPath) 
   : m_col(0), m_relPath(relPath)
{
  setTextStream(t);
}

void HtmlCodeGenerator::setTextStream(FTextStream &t)
{
  m_streamSet = t.device()!=0;
  m_t.setDevice(t.device());
}

void HtmlCodeGenerator::setRelativePath(const QCString &path)
{
  m_relPath = path;
}

void HtmlCodeGenerator::codify(const char *str)
{
  static int tabSize = Config_getInt("TAB_SIZE");
  if (str && m_streamSet)
  { 
    const char *p=str;
    char c;
    int spacesToNextTabStop;
    while (*p)
    {
      c=*p++;
      switch(c)
      {
        case '\t': spacesToNextTabStop = 
                         tabSize - (m_col%tabSize); 
                   m_t << Doxygen::spaces.left(spacesToNextTabStop); 
                   m_col+=spacesToNextTabStop; 
                   break; 
        case '\n': m_t << "\n"; m_col=0; 
                   break;
        case '\r': break;
        case '<':  m_t << "&lt;"; m_col++; 
                   break;
        case '>':  m_t << "&gt;"; m_col++; 
                   break;
        case '&':  m_t << "&amp;"; m_col++; 
                   break;
        case '\'': m_t << "&#39;"; m_col++; // &apos; is not valid XHTML
                   break;
        case '"':  m_t << "&quot;"; m_col++;
                   break;
        case '\\':
                   if (*p=='<')
                     { m_t << "&lt;"; p++; }
                   else if (*p=='>')
                     { m_t << "&gt;"; p++; }
                   else
                     m_t << "\\";
                   m_col++;
                   break;
        default:   p=writeUtf8Char(m_t,p-1);    
                   m_col++;                    
                   break;
      }
    }
  }
}

void HtmlCodeGenerator::docify(const char *str)
{
  if (str && m_streamSet)
  {
    const char *p=str;
    char c;
    while (*p)
    {
      c=*p++;
      switch(c)
      {
        case '<':  m_t << "&lt;"; break;
        case '>':  m_t << "&gt;"; break;
        case '&':  m_t << "&amp;"; break;
        case '"':  m_t << "&quot;"; break;
        case '\\':
                   if (*p=='<')
                     { m_t << "&lt;"; p++; }
                   else if (*p=='>')
                     { m_t << "&gt;"; p++; }
                   else
                     m_t << "\\";
                   break;
        default:   m_t << c; 
      }
    }
  }
}

void HtmlCodeGenerator::writeLineNumber(const char *ref,const char *filename,
                                    const char *anchor,int l)
{
  if (!m_streamSet) return;
  QCString lineNumber,lineAnchor;
  lineNumber.sprintf("%5d",l);
  lineAnchor.sprintf("l%05d",l);

  m_t << "<div class=\"line\">";
  m_t << "<a name=\"" << lineAnchor << "\"></a><span class=\"lineno\">"; 
  if (filename)
  {
    _writeCodeLink("line",ref,filename,anchor,lineNumber,0);
  }
  else
  {
    codify(lineNumber);
  }
  m_t << "</span>"; 
  m_t << "&#160;";
}

void HtmlCodeGenerator::writeCodeLink(const char *ref,const char *f,
                                      const char *anchor, const char *name,
                                      const char *tooltip)
{
  if (!m_streamSet) return;
  //printf("writeCodeLink(ref=%s,f=%s,anchor=%s,name=%s,tooltip=%s)\n",ref,f,anchor,name,tooltip);
  _writeCodeLink("code",ref,f,anchor,name,tooltip);
}

void HtmlCodeGenerator::_writeCodeLink(const char *className,
                                      const char *ref,const char *f,
                                      const char *anchor, const char *name,
                                      const char *tooltip)
{
  if (ref) 
  {
    m_t << "<a class=\"" << className << "Ref\" ";
    m_t << externalLinkTarget() << externalRef(m_relPath,ref,FALSE);
  }
  else
  {
    m_t << "<a class=\"" << className << "\" ";
  }
  m_t << "href=\"";
  m_t << externalRef(m_relPath,ref,TRUE);
  if (f) m_t << f << Doxygen::htmlFileExtension;
  if (anchor) m_t << "#" << anchor;
  m_t << "\"";
  if (tooltip) m_t << " title=\"" << tooltip << "\"";
  m_t << ">";
  docify(name);
  m_t << "</a>";
  m_col+=qstrlen(name);
}

void HtmlCodeGenerator::writeTooltip(const char *id, const DocLinkInfo &docInfo,
                                     const char *decl, const char *desc,
                                     const SourceLinkInfo &defInfo,
                                     const SourceLinkInfo &declInfo)
{
  m_t << "<div class=\"ttc\" id=\"" << id << "\">";
  m_t << "<div class=\"ttname\">";
  if (!docInfo.url.isEmpty())
  {
    m_t << "<a href=\"";
    m_t << externalRef(m_relPath,docInfo.ref,TRUE);
    m_t << docInfo.url << Doxygen::htmlFileExtension;
    if (!docInfo.anchor.isEmpty())
    {
      m_t << "#" << docInfo.anchor;
    }
    m_t << "\">";
  }
  docify(docInfo.name);
  if (!docInfo.url.isEmpty())
  {
    m_t << "</a>";
  }
  m_t << "</div>";
  if (decl)
  {
    m_t << "<div class=\"ttdeci\">";
    docify(decl);
    m_t << "</div>";
  }
  if (desc)
  {
    m_t << "<div class=\"ttdoc\">";
    m_t << desc; // desc is already HTML escaped
    m_t << "</div>";
  }
  if (!defInfo.file.isEmpty())
  {
    m_t << "<div class=\"ttdef\"><b>Definition:</b> ";
    if (!defInfo.url.isEmpty())
    {
      m_t << "<a href=\"";
      m_t << externalRef(m_relPath,defInfo.ref,TRUE);
      m_t << defInfo.url << Doxygen::htmlFileExtension;
      if (!defInfo.anchor.isEmpty())
      {
        m_t << "#" << defInfo.anchor;
      }
      m_t << "\">";
    }
    m_t << defInfo.file << ":" << defInfo.line;
    if (!defInfo.url.isEmpty())
    {
      m_t << "</a>";
    }
    m_t << "</div>";
  }
  if (!declInfo.file.isEmpty())
  {
    m_t << "<div class=\"ttdecl\"><b>Declaration:</b> ";
    if (!declInfo.url.isEmpty())
    {
      m_t << "<a href=\"";
      m_t << externalRef(m_relPath,declInfo.ref,TRUE);
      m_t << declInfo.url << Doxygen::htmlFileExtension;
      if (!declInfo.anchor.isEmpty())
      {
        m_t << "#" << declInfo.anchor;
      }
      m_t << "\">";
    }
    m_t << declInfo.file << ":" << declInfo.line;
    if (!declInfo.url.isEmpty())
    {
      m_t << "</a>";
    }
    m_t << "</div>";
  }
  m_t << "</div>" << endl;
}


void HtmlCodeGenerator::startCodeLine(bool hasLineNumbers) 
{ 
  if (m_streamSet)
  {
    if (!hasLineNumbers) m_t << "<div class=\"line\">";
    m_col=0; 
  }
}

void HtmlCodeGenerator::endCodeLine() 
{ 
  if (m_streamSet) m_t << "</div>\n";
}

void HtmlCodeGenerator::startFontClass(const char *s) 
{ 
  if (m_streamSet) m_t << "<span class=\"" << s << "\">"; 
}

void HtmlCodeGenerator::endFontClass() 
{ 
  if (m_streamSet) m_t << "</span>"; 
}

void HtmlCodeGenerator::writeCodeAnchor(const char *anchor) 
{ 
  if (m_streamSet) m_t << "<a name=\"" << anchor << "\"></a>"; 
}

//--------------------------------------------------------------------------

HtmlGenerator::HtmlGenerator() : OutputGenerator()
{
  dir=Config_getString("HTML_OUTPUT");
  m_emptySection=FALSE;
}

HtmlGenerator::~HtmlGenerator()
{
  //printf("HtmlGenerator::~HtmlGenerator()\n");
}

void HtmlGenerator::init()
{
  QCString dname=Config_getString("HTML_OUTPUT");
  QDir d(dname);
  if (!d.exists() && !d.mkdir(dname))
  {
    err("Could not create output directory %s\n",dname.data());
    exit(1);
  }
  //writeLogo(dname);
  if (!Config_getString("HTML_HEADER").isEmpty()) 
  {
    g_header=fileToString(Config_getString("HTML_HEADER"));
    //printf("g_header='%s'\n",g_header.data());
  }
  else 
  {
    g_header = defaultHtmlHeader;
  }

  if (!Config_getString("HTML_FOOTER").isEmpty()) 
  {
    g_footer=fileToString(Config_getString("HTML_FOOTER"));
    //printf("g_footer='%s'\n",g_footer.data());
  }
  else 
  {
    g_footer = defaultHtmlFooter;
  }

  if (Config_getBool("USE_MATHJAX"))
  {
    if (!Config_getString("MATHJAX_CODEFILE").isEmpty()) 
    {
      g_mathjax_code=fileToString(Config_getString("MATHJAX_CODEFILE"));
      //printf("g_mathjax_code='%s'\n",g_mathjax_code.data());
    }
  }
  createSubDirs(d);

  QCString fileName=dname+"/tabs.css";
  QFile f(fileName);
  if (f.open(IO_WriteOnly))
  {
    FTextStream t(&f);
    t << replaceColorMarkers(tabs_css);
  }
  else
  {
    fprintf(stderr,"Warning: Cannot open file %s for writing\n",fileName.data());
  }

  {
    QFile f(dname+"/jquery.js");
    if (f.open(IO_WriteOnly))
    {
      FTextStream t(&f);
      t << search_jquery_script1 << search_jquery_script2 << search_jquery_script3;
      if (Config_getBool("GENERATE_TREEVIEW"))
      {
        t << search_jquery_script4 << search_jquery_script5;
      }
      if (Config_getBool("SOURCE_BROWSER"))
      {
        t << search_jquery_script6;
      }
    }
  }

  if (Config_getBool("INTERACTIVE_SVG"))
  {
    QFile f(dname+"/svgpan.js");
    if (f.open(IO_WriteOnly))
    {
      FTextStream t(&f);
      t << svgpan_script;
    }
  }

  {
    QFile f(dname+"/dynsections.js");
    if (f.open(IO_WriteOnly))
    {
      FTextStream t(&f);
      t << dynsections_script;
      if (Config_getBool("SOURCE_BROWSER") && Config_getBool("SOURCE_TOOLTIPS"))
      {
        t << endl << 
          "$(document).ready(function() {\n"
          "  $('.code,.codeRef').each(function() {\n"
          "    $(this).data('powertip',$('#'+$(this).attr('href').replace(/.*\\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html());\n"
          "    $(this).powerTip({ placement: 's', smartPlacement: true, mouseOnToPopup: true });\n"
          "  });\n"
          "});\n";
      }
    }
  }
}

/// Additional initialization after indices have been created
void HtmlGenerator::writeTabData()
{
  Doxygen::indexList->addStyleSheetFile("tabs.css");
  QCString dname=Config_getString("HTML_OUTPUT");
  writeColoredImgData(dname,colored_tab_data);

  {
    unsigned char shadow[6] = { 5, 5, 5, 5, 5, 5 };
    unsigned char shadow_alpha[6]  = { 80, 60, 40, 20, 10, 0 };
    ColoredImage img(1,6,shadow,shadow_alpha,0,0,100);
    img.save(dname+"/nav_g.png");
  }
}

void HtmlGenerator::writeSearchData(const char *dir)
{
  static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
  writeImgData(dir,serverBasedSearch ? search_server_data : search_client_data);
  QCString searchDirName = Config_getString("HTML_OUTPUT")+"/search";
  QFile f(searchDirName+"/search.css");
  if (f.open(IO_WriteOnly))
  {
    FTextStream t(&f);
    QCString searchCss = replaceColorMarkers(search_styleSheet);
    searchCss = substitute(searchCss,"$doxygenversion",versionString);
    if (Config_getBool("DISABLE_INDEX"))
    {
      // move up the search box if there are no tabs
      searchCss = substitute(searchCss,"margin-top: 8px;","margin-top: 0px;");
    }
    t << searchCss;
  }
  Doxygen::indexList->addStyleSheetFile("search/search.css");
}

void HtmlGenerator::writeStyleSheetFile(QFile &file)
{
  FTextStream t(&file);
  t << replaceColorMarkers(substitute(defaultStyleSheet,"$doxygenversion",versionString));
}

void HtmlGenerator::writeHeaderFile(QFile &file, const char * /*cssname*/)
{
  FTextStream t(&file);
  t << "<!-- HTML header for doxygen " << versionString << "-->" << endl;
  QCString contents(defaultHtmlHeader);
  t << contents;
}

void HtmlGenerator::writeFooterFile(QFile &file)
{
  FTextStream t(&file);
  t << "<!-- HTML footer for doxygen " << versionString << "-->" <<  endl;
  QCString contents(defaultHtmlFooter);
  t << contents;
}

void HtmlGenerator::startFile(const char *name,const char *,
                              const char *title)
{
  //printf("HtmlGenerator::startFile(%s)\n",name);
  QCString fileName=name;
  lastTitle=title;
  relPath = relativePathToRoot(fileName);

  if (fileName.right(Doxygen::htmlFileExtension.length())!=Doxygen::htmlFileExtension) 
  {
    fileName+=Doxygen::htmlFileExtension;
  }
  startPlainFile(fileName);
  m_codeGen.setTextStream(t);
  m_codeGen.setRelativePath(relPath);
  Doxygen::indexList->addIndexFile(fileName);
  
  lastFile = fileName;
  t << substituteHtmlKeywords(g_header,convertToHtml(filterTitle(title)),relPath);

  t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " 
    << versionString << " -->" << endl;
  //static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
  static bool searchEngine = Config_getBool("SEARCHENGINE");
  if (searchEngine /*&& !generateTreeView*/)
  {
    t << "<script type=\"text/javascript\">\n";
    t << "var searchBox = new SearchBox(\"searchBox\", \""
      << relPath<< "search\",false,'" << theTranslator->trSearch() << "');\n";
    t << "</script>\n";
  }
  //generateDynamicSections(t,relPath);
  m_sectionCount=0;
}

void HtmlGenerator::writeSearchInfo(FTextStream &t,const QCString &relPath)
{
  static bool searchEngine      = Config_getBool("SEARCHENGINE");
  static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
  if (searchEngine && !serverBasedSearch)
  {
    (void)relPath;
    t << "<!-- window showing the filter options -->\n";
    t << "<div id=\"MSearchSelectWindow\"\n";
    t << "     onmouseover=\"return searchBox.OnSearchSelectShow()\"\n";
    t << "     onmouseout=\"return searchBox.OnSearchSelectHide()\"\n";
    t << "     onkeydown=\"return searchBox.OnSearchSelectKey(event)\">\n";
    writeSearchCategories(t);
    t << "</div>\n";
    t << "\n";
    t << "<!-- iframe showing the search results (closed by default) -->\n";
    t << "<div id=\"MSearchResultsWindow\">\n";
    t << "<iframe src=\"javascript:void(0)\" frameborder=\"0\" \n";
    t << "        name=\"MSearchResults\" id=\"MSearchResults\">\n";
    t << "</iframe>\n";
    t << "</div>\n";
    t << "\n";
  }
}

void HtmlGenerator::writeSearchInfo()
{
  writeSearchInfo(t,relPath);
}


QCString HtmlGenerator::writeLogoAsString(const char *path)
{
  static bool timeStamp = Config_getBool("HTML_TIMESTAMP");
  QCString result;
  if (timeStamp)
  {
    result += theTranslator->trGeneratedAt(
               dateToString(TRUE),
               Config_getString("PROJECT_NAME")
              );
  }
  else
  {
    result += theTranslator->trGeneratedBy();
  }
  result += "&#160;\n<a href=\"http://www.doxygen.org/index.html\">\n"
            "<img class=\"footer\" src=\"";
  result += path;
  result += "doxygen.png\" alt=\"doxygen\"/></a> ";
  result += versionString;
  result += " ";
  return result;
}

void HtmlGenerator::writeLogo()
{
  t << writeLogoAsString(relPath);
}

void HtmlGenerator::writePageFooter(FTextStream &t,const QCString &lastTitle,
                              const QCString &relPath,const QCString &navPath)
{
  t << substituteHtmlKeywords(g_footer,convertToHtml(lastTitle),relPath,navPath);
}

void HtmlGenerator::writeFooter(const char *navPath)
{
  writePageFooter(t,lastTitle,relPath,navPath);
}

void HtmlGenerator::endFile()
{
  endPlainFile();
}

void HtmlGenerator::startProjectNumber()
{
  t << "<h3 class=\"version\">";
}

void HtmlGenerator::endProjectNumber()
{
  t << "</h3>";
}

void HtmlGenerator::writeStyleInfo(int part)
{
  //printf("writeStyleInfo(%d)\n",part);
  if (part==0)
  {
    if (Config_getString("HTML_STYLESHEET").isEmpty()) // write default style sheet
    {
      //printf("write doxygen.css\n");
      startPlainFile("doxygen.css"); 
      
      // alternative, cooler looking titles
      //t << "H1 { text-align: center; border-width: thin none thin none;" << endl;
      //t << "     border-style : double; border-color : blue; padding-left : 1em; padding-right : 1em }" << endl;

      t << replaceColorMarkers(substitute(defaultStyleSheet,"$doxygenversion",versionString));
      endPlainFile();
      Doxygen::indexList->addStyleSheetFile("doxygen.css");
    }
    else // write user defined style sheet
    {
      QCString cssname=Config_getString("HTML_STYLESHEET");
      QFileInfo cssfi(cssname);
      if (!cssfi.exists() || !cssfi.isFile() || !cssfi.isReadable())
      {
        err("style sheet %s does not exist or is not readable!", Config_getString("HTML_STYLESHEET").data());
      }
      else
      {
        // convert style sheet to string
        QCString fileStr = fileToString(cssname);
        // write the string into the output dir
        startPlainFile(cssfi.fileName().utf8());
        t << fileStr;
        endPlainFile();
      }
      Doxygen::indexList->addStyleSheetFile(cssfi.fileName().utf8());
    }
    static QStrList extraCssFile = Config_getList("HTML_EXTRA_STYLESHEET");
    for (uint i=0; i<extraCssFile.count(); ++i)
    {
      QCString fileName(extraCssFile.at(i));
      if (!fileName.isEmpty())
      {
        QFileInfo fi(fileName);
        if (fi.exists())
        {
          Doxygen::indexList->addStyleSheetFile(fi.fileName().utf8());
        }
      }
    }
  }
}

void HtmlGenerator::startDoxyAnchor(const char *,const char *,
                                    const char *anchor, const char *,
                                    const char *)
{
  t << "<a class=\"anchor\" id=\"" << anchor << "\"></a>";
}

void HtmlGenerator::endDoxyAnchor(const char *,const char *)
{
}

//void HtmlGenerator::newParagraph()
//{
//  t << endl << "<p>" << endl;
//}

void HtmlGenerator::startParagraph()
{
  t << endl << "<p>";
}

void HtmlGenerator::endParagraph()
{
  t << "</p>" << endl;
}

void HtmlGenerator::writeString(const char *text)
{
  t << text;
}

void HtmlGenerator::startIndexListItem()
{
  t << "<li>";
}

void HtmlGenerator::endIndexListItem()
{
  t << "</li>" << endl;
}

void HtmlGenerator::startIndexItem(const char *ref,const char *f)
{
  //printf("HtmlGenerator::startIndexItem(%s,%s)\n",ref,f);
  if (ref || f)
  {
    if (ref) 
    {
      t << "<a class=\"elRef\" ";
      t << externalLinkTarget() << externalRef(relPath,ref,FALSE);
    }
    else
    {
      t << "<a class=\"el\" ";
    }
    t << "href=\"";
    t << externalRef(relPath,ref,TRUE);
    if (f) t << f << Doxygen::htmlFileExtension << "\">";
  }
  else
  {
    t << "<b>";
  }
}

void HtmlGenerator::endIndexItem(const char *ref,const char *f)
{
  //printf("HtmlGenerator::endIndexItem(%s,%s,%s)\n",ref,f,name);
  if (ref || f)
  {
    t << "</a>";
  }
  else
  {
    t << "</b>";
  }
}

void HtmlGenerator::writeStartAnnoItem(const char *,const char *f,
                                       const char *path,const char *name)
{
  t << "<li>";
  if (path) docify(path);
  t << "<a class=\"el\" href=\"" << f << Doxygen::htmlFileExtension << "\">";
  docify(name);
  t << "</a> ";
}

void HtmlGenerator::writeObjectLink(const char *ref,const char *f,
                                    const char *anchor, const char *name)
{
  if (ref) 
  {
    t << "<a class=\"elRef\" ";
    t << externalLinkTarget() << externalRef(relPath,ref,FALSE);
  }
  else
  {
    t << "<a class=\"el\" ";
  }
  t << "href=\"";
  t << externalRef(relPath,ref,TRUE);
  if (f) t << f << Doxygen::htmlFileExtension;
  if (anchor) t << "#" << anchor;
  t << "\">";
  docify(name);
  t << "</a>";
}

void HtmlGenerator::startTextLink(const char *f,const char *anchor)
{
  t << "<a href=\"";
  if (f)   t << relPath << f << Doxygen::htmlFileExtension;
  if (anchor) t << "#" << anchor;
  t << "\">"; 
}

void HtmlGenerator::endTextLink()
{
  t << "</a>";
}

void HtmlGenerator::startHtmlLink(const char *url)
{
  static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
  t << "<a ";
  if (generateTreeView) t << "target=\"top\" ";
  t << "href=\"";
  if (url) t << url;
  t << "\">"; 
}

void HtmlGenerator::endHtmlLink()
{
  t << "</a>";
}

void HtmlGenerator::startGroupHeader(int extraIndentLevel)
{
  if (extraIndentLevel==2)
  {
    t << "<h4 class=\"groupheader\">";
  }
  else if (extraIndentLevel==1)
  {
    t << "<h3 class=\"groupheader\">";
  }
  else // extraIndentLevel==0
  {
    t << "<h2 class=\"groupheader\">";
  }
}

void HtmlGenerator::endGroupHeader(int extraIndentLevel)
{
  if (extraIndentLevel==2)
  {
    t << "</h4>" << endl;
  }
  else if (extraIndentLevel==1)
  {
    t << "</h3>" << endl;
  }
  else
  {
    t << "</h2>" << endl;
  }
}

void HtmlGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type)
{
  switch(type)
  {
    case SectionInfo::Page:          t << "\n\n<h1>"; break;
    case SectionInfo::Section:       t << "\n\n<h2>"; break;
    case SectionInfo::Subsection:    t << "\n\n<h3>"; break;
    case SectionInfo::Subsubsection: t << "\n\n<h4>"; break;
    case SectionInfo::Paragraph:     t << "\n\n<h5>"; break;
    default: ASSERT(0); break;
  }
  t << "<a class=\"anchor\" id=\"" << lab << "\"></a>";
}

void HtmlGenerator::endSection(const char *,SectionInfo::SectionType type)
{
  switch(type)
  {
    case SectionInfo::Page:          t << "</h1>"; break;
    case SectionInfo::Section:       t << "</h2>"; break;
    case SectionInfo::Subsection:    t << "</h3>"; break;
    case SectionInfo::Subsubsection: t << "</h4>"; break;
    case SectionInfo::Paragraph:     t << "</h5>"; break;
    default: ASSERT(0); break;
  }
}

void HtmlGenerator::docify(const char *str)
{
  docify(str,FALSE);
}

void HtmlGenerator::docify(const char *str,bool inHtmlComment)
{
  if (str)
  {
    const char *p=str;
    char c;
    while (*p)
    {
      c=*p++;
      switch(c)
      {
        case '<':  t << "&lt;"; break;
        case '>':  t << "&gt;"; break;
        case '&':  t << "&amp;"; break;
        case '"':  t << "&quot;"; break;
        case '-':  if (inHtmlComment) t << "&#45;"; else t << "-"; break;
        case '\\':
                   if (*p=='<')
                     { t << "&lt;"; p++; }
                   else if (*p=='>')
                     { t << "&gt;"; p++; }
                   else
                     t << "\\";
                   break;
        default:   t << c; 
      }
    }
  }
}

void HtmlGenerator::writeChar(char c)
{
  char cs[2];
  cs[0]=c;
  cs[1]=0;
  docify(cs);
}

//--- helper function for dynamic sections -------------------------

static void startSectionHeader(FTextStream &t,
                               const QCString &relPath,int sectionCount)
{
  //t << "<!-- startSectionHeader -->";
  static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS");
  if (dynamicSections)
  {
    t << "<div id=\"dynsection-" << sectionCount << "\" "
         "onclick=\"return toggleVisibility(this)\" "
         "class=\"dynheader closed\" "
         "style=\"cursor:pointer;\">" << endl;
    t << "  <img id=\"dynsection-" << sectionCount << "-trigger\" src=\"" 
      << relPath << "closed.png\" alt=\"+\"/> ";
  }
  else
  {
    t << "<div class=\"dynheader\">" << endl;
  }
}

static void endSectionHeader(FTextStream &t)
{
  //t << "<!-- endSectionHeader -->";
  t << "</div>" << endl;
}

static void startSectionSummary(FTextStream &t,int sectionCount)
{
  //t << "<!-- startSectionSummary -->";
  static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS");
  if (dynamicSections)
  {
    t << "<div id=\"dynsection-" << sectionCount << "-summary\" "
         "class=\"dynsummary\" "
         "style=\"display:block;\">" << endl;
  }
}

static void endSectionSummary(FTextStream &t)
{
  //t << "<!-- endSectionSummary -->";
  static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS");
  if (dynamicSections)
  {
    t << "</div>" << endl;
  }
}

static void startSectionContent(FTextStream &t,int sectionCount)
{
  //t << "<!-- startSectionContent -->";
  static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS");
  if (dynamicSections)
  {
    t << "<div id=\"dynsection-" << sectionCount << "-content\" "
         "class=\"dyncontent\" "
         "style=\"display:none;\">" << endl;
  }
  else
  {
    t << "<div class=\"dyncontent\">" << endl;
  }
}

static void endSectionContent(FTextStream &t)
{
  //t << "<!-- endSectionContent -->";
  t << "</div>" << endl;
}

//----------------------------

void HtmlGenerator::startClassDiagram()
{
  startSectionHeader(t,relPath,m_sectionCount);
}

void HtmlGenerator::endClassDiagram(const ClassDiagram &d,
                                const char *fileName,const char *name)
{
  endSectionHeader(t);
  startSectionSummary(t,m_sectionCount);
  endSectionSummary(t);
  startSectionContent(t,m_sectionCount);
  t << " <div class=\"center\">" << endl;
  t << "  <img src=\"";
  t << relPath << fileName << ".png\" usemap=\"#";
  docify(name);
  t << "_map\" alt=\"\"/>" << endl;
  t << "  <map id=\"";
  docify(name);
  t << "_map\" name=\"";
  docify(name);
  t << "_map\">" << endl;

  d.writeImage(t,dir,relPath,fileName);
  t << " </div>";
  endSectionContent(t);
  m_sectionCount++;
}


void HtmlGenerator::startMemberList()  
{ 
  DBG_HTML(t << "<!-- startMemberList -->" << endl)
}

void HtmlGenerator::endMemberList()    
{ 
  DBG_HTML(t << "<!-- endMemberList -->" << endl)
}

// anonymous type:
//  0 = single column right aligned
//  1 = double column left aligned
//  2 = single column left aligned
void HtmlGenerator::startMemberItem(const char *anchor,int annoType,const char *inheritId) 
{ 
  DBG_HTML(t << "<!-- startMemberItem() -->" << endl)
  if (m_emptySection)
  {
    t << "<table class=\"memberdecls\">" << endl;
    m_emptySection=FALSE;
  }
  t << "<tr class=\"memitem:" << anchor;
  if (inheritId)
  {
    t << " inherit " << inheritId;
  }
  t << "\">";
  switch(annoType)
  {
    case 0:  t << "<td class=\"memItemLeft\" align=\"right\" valign=\"top\">"; break;
    case 1:  t << "<td class=\"memItemLeft\" >"; break;
    case 2:  t << "<td class=\"memItemLeft\" valign=\"top\">"; break;
    default: t << "<td class=\"memTemplParams\" colspan=\"2\">"; break;
  }
}

void HtmlGenerator::endMemberItem() 
{ 
  t << "</td></tr>"; 
  t << endl; 
}

void HtmlGenerator::startMemberTemplateParams()
{
}

void HtmlGenerator::endMemberTemplateParams(const char *anchor,const char *inheritId)
{
  t << "</td></tr>" << endl;
  t << "<tr class=\"memitem:" << anchor;
  if (inheritId)
  {
    t << " inherit " << inheritId;
  }
  t << "\"><td class=\"memTemplItemLeft\" align=\"right\" valign=\"top\">";
}


void HtmlGenerator::insertMemberAlign(bool templ) 
{ 
  DBG_HTML(t << "<!-- insertMemberAlign -->" << endl)
  QCString className = templ ? "memTemplItemRight" : "memItemRight";
  t << "&#160;</td><td class=\"" << className << "\" valign=\"bottom\">"; 
}

void HtmlGenerator::startMemberDescription(const char *anchor,const char *inheritId) 
{ 
  DBG_HTML(t << "<!-- startMemberDescription -->" << endl)
    if (m_emptySection)
    {
      t << "<table class=\"memberdecls\">" << endl;
      m_emptySection=FALSE;
    }
  t << "<tr class=\"memdesc:" << anchor;
  if (inheritId)
  {
    t << " inherit " << inheritId;
  }
  t << "\"><td class=\"mdescLeft\">&#160;</td><td class=\"mdescRight\">"; 
}

void HtmlGenerator::endMemberDescription()   
{ 
  DBG_HTML(t << "<!-- endMemberDescription -->" << endl)
  t << "<br /></td></tr>" << endl; 
}

void HtmlGenerator::startMemberSections()
{
  DBG_HTML(t << "<!-- startMemberSections -->" << endl)
  m_emptySection=TRUE; // we postpone writing <table> until we actually
                       // write a row to prevent empty tables, which 
                       // are not valid XHTML!
}

void HtmlGenerator::endMemberSections()
{
  DBG_HTML(t << "<!-- endMemberSections -->" << endl)
  if (!m_emptySection)
  {
    t << "</table>" << endl;
  }
}

void HtmlGenerator::startMemberHeader(const char *anchor)
{
  DBG_HTML(t << "<!-- startMemberHeader -->" << endl)
  if (!m_emptySection)
  {
    t << "</table>";
    m_emptySection=TRUE;
  }
  if (m_emptySection)
  {
    t << "<table class=\"memberdecls\">" << endl;
    m_emptySection=FALSE;
  }
  t << "<tr class=\"heading\"><td colspan=\"2\"><h2 class=\"groupheader\">";
  if (anchor)
  {
    t << "<a name=\"" << anchor << "\"></a>" << endl;
  }
}

void HtmlGenerator::endMemberHeader()
{
  DBG_HTML(t << "<!-- endMemberHeader -->" << endl)
  t << "</h2></td></tr>" << endl;
}

void HtmlGenerator::startMemberSubtitle()
{
  DBG_HTML(t << "<!-- startMemberSubtitle -->" << endl)
  t << "<tr><td class=\"ititle\" colspan=\"2\">";
}

void HtmlGenerator::endMemberSubtitle()
{
  DBG_HTML(t << "<!-- endMemberSubtitle -->" << endl)
  t << "</td></tr>" << endl;
}

void HtmlGenerator::startIndexList() 
{ 
  t << "<table>"  << endl; 
}

void HtmlGenerator::endIndexList()
{
  t << "</table>" << endl;
}

void HtmlGenerator::startIndexKey() 
{ 
  // inserted 'class = ...', 02 jan 2002, jh
  t << "  <tr><td class=\"indexkey\">"; 
}

void HtmlGenerator::endIndexKey()
{
  t << "</td>";
}

void HtmlGenerator::startIndexValue(bool) 
{ 
  // inserted 'class = ...', 02 jan 2002, jh
  t << "<td class=\"indexvalue\">"; 
}

void HtmlGenerator::endIndexValue(const char *,bool)
{
  t << "</td></tr>" << endl;
}

void HtmlGenerator::startMemberDocList()
{
  DBG_HTML(t << "<!-- startMemberDocList -->" << endl;)
}

void HtmlGenerator::endMemberDocList()
{
  DBG_HTML(t << "<!-- endMemberDocList -->" << endl;)
}

void HtmlGenerator::startMemberDoc(const char *,const char *,const char *,const char *,bool) 
{ 
  DBG_HTML(t << "<!-- startMemberDoc -->" << endl;)
 
  t << "\n<div class=\"memitem\">" << endl;
  t << "<div class=\"memproto\">" << endl;
}

void HtmlGenerator::startMemberDocPrefixItem()
{
  DBG_HTML(t << "<!-- startMemberDocPrefixItem -->" << endl;)
  t << "<div class=\"memtemplate\">" << endl;
}

void HtmlGenerator::endMemberDocPrefixItem()
{
  DBG_HTML(t << "<!-- endMemberDocPrefixItem -->" << endl;)
  t << "</div>" << endl;
}

void HtmlGenerator::startMemberDocName(bool /*align*/)
{
  DBG_HTML(t << "<!-- startMemberDocName -->" << endl;)

  t << "      <table class=\"memname\">" << endl;
    
  t << "        <tr>" << endl;
  t << "          <td class=\"memname\">";
}

void HtmlGenerator::endMemberDocName()
{
  DBG_HTML(t << "<!-- endMemberDocName -->" << endl;)
  t << "</td>" << endl;
}

void HtmlGenerator::startParameterList(bool openBracket)
{
  DBG_HTML(t << "<!-- startParameterList -->" << endl;)
  t << "          <td>";
  if (openBracket) t << "(";
  t << "</td>" << endl;
}

void HtmlGenerator::startParameterType(bool first,const char *key)
{
  if (first)
  {
    DBG_HTML(t << "<!-- startFirstParameterType -->" << endl;)
    t << "          <td class=\"paramtype\">";
  }
  else
  {
    DBG_HTML(t << "<!-- startParameterType -->" << endl;)
    t << "        <tr>" << endl;
    t << "          <td class=\"paramkey\">";
    if (key) t << key;
    t << "</td>" << endl;
    t << "          <td></td>" << endl;
    t << "          <td class=\"paramtype\">";
  }
}

void HtmlGenerator::endParameterType()
{
  DBG_HTML(t << "<!-- endParameterType -->" << endl;)
  t << "&#160;</td>" << endl;
}

void HtmlGenerator::startParameterName(bool /*oneArgOnly*/)
{
  DBG_HTML(t << "<!-- startParameterName -->" << endl;)
  t << "          <td class=\"paramname\">";
}

void HtmlGenerator::endParameterName(bool last,bool emptyList,bool closeBracket)
{
  DBG_HTML(t << "<!-- endParameterName -->" << endl;)
  if (last)
  {
    if (emptyList)
    {
      if (closeBracket) t << "</td><td>)";
      t << "</td>" << endl;
      t << "          <td>";
    }
    else
    {
      t << "&#160;</td>" << endl;
      t << "        </tr>" << endl;
      t << "        <tr>" << endl;
      t << "          <td></td>" << endl;
      t << "          <td>";
      if (closeBracket) t << ")";
      t << "</td>" << endl;
      t << "          <td></td><td>";
    }
  }
  else
  {
    t << "</td>" << endl;
    t << "        </tr>" << endl;
  }
}

void HtmlGenerator::endParameterList()
{
  DBG_HTML(t << "<!-- endParameterList -->" << endl;)
  t << "</td>" << endl;
  t << "        </tr>" << endl;
}

void HtmlGenerator::exceptionEntry(const char* prefix,bool closeBracket)
{
  DBG_HTML(t << "<!-- exceptionEntry -->" << endl;)
  t << "</td>" << endl;
  t << "        </tr>" << endl;
  t << "        <tr>" << endl;
  t << "          <td align=\"right\">";
  // colspan 2 so it gets both parameter type and parameter name columns
  if (prefix)
    t << prefix << "</td><td>(</td><td colspan=\"2\">";
  else if (closeBracket)
    t << "</td><td>)</td><td></td><td>";
  else
    t << "</td><td></td><td colspan=\"2\">";
}

void HtmlGenerator::endMemberDoc(bool hasArgs)     
{ 
  DBG_HTML(t << "<!-- endMemberDoc -->" << endl;)
  if (!hasArgs)
  {
    t << "        </tr>" << endl;
  }
  t << "      </table>" << endl;
 // t << "</div>" << endl;
}

void HtmlGenerator::startDotGraph()
{
  startSectionHeader(t,relPath,m_sectionCount);
}

void HtmlGenerator::endDotGraph(const DotClassGraph &g)
{
  bool generateLegend = Config_getBool("GENERATE_LEGEND");
  bool umlLook = Config_getBool("UML_LOOK");
  endSectionHeader(t);
  startSectionSummary(t,m_sectionCount);
  endSectionSummary(t);
  startSectionContent(t,m_sectionCount);

  g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,TRUE,m_sectionCount);
  if (generateLegend && !umlLook)
  {
    t << "<center><span class=\"legend\">[";
    startHtmlLink(relPath+"graph_legend"+Doxygen::htmlFileExtension);
    t << theTranslator->trLegend();
    endHtmlLink();
    t << "]</span></center>";
  }

  endSectionContent(t);
  m_sectionCount++;
}

void HtmlGenerator::startInclDepGraph()
{
  startSectionHeader(t,relPath,m_sectionCount);
}

void HtmlGenerator::endInclDepGraph(const DotInclDepGraph &g)
{
  endSectionHeader(t);
  startSectionSummary(t,m_sectionCount);
  endSectionSummary(t);
  startSectionContent(t,m_sectionCount);

  g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);

  endSectionContent(t);
  m_sectionCount++;
}

void HtmlGenerator::startGroupCollaboration()
{
  startSectionHeader(t,relPath,m_sectionCount);
}

void HtmlGenerator::endGroupCollaboration(const DotGroupCollaboration &g)
{
  endSectionHeader(t);
  startSectionSummary(t,m_sectionCount);
  endSectionSummary(t);
  startSectionContent(t,m_sectionCount);

  g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);

  endSectionContent(t);
  m_sectionCount++;
}

void HtmlGenerator::startCallGraph()
{
  startSectionHeader(t,relPath,m_sectionCount);
}

void HtmlGenerator::endCallGraph(const DotCallGraph &g)
{
  endSectionHeader(t);
  startSectionSummary(t,m_sectionCount);
  endSectionSummary(t);
  startSectionContent(t,m_sectionCount);

  g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);

  endSectionContent(t);
  m_sectionCount++;
}

void HtmlGenerator::startDirDepGraph()
{
  startSectionHeader(t,relPath,m_sectionCount);
}

void HtmlGenerator::endDirDepGraph(const DotDirDeps &g)
{
  endSectionHeader(t);
  startSectionSummary(t,m_sectionCount);
  endSectionSummary(t);
  startSectionContent(t,m_sectionCount);

  g.writeGraph(t,GOF_BITMAP,EOF_Html,dir,fileName,relPath,TRUE,m_sectionCount);

  endSectionContent(t);
  m_sectionCount++;
}

void HtmlGenerator::writeGraphicalHierarchy(const DotGfxHierarchyTable &g)
{
  g.writeGraph(t,dir,fileName);
}

void HtmlGenerator::startMemberGroupHeader(bool)
{
  t << "<tr><td colspan=\"2\"><div class=\"groupHeader\">";
}

void HtmlGenerator::endMemberGroupHeader()
{
  t << "</div></td></tr>" << endl;
}

void HtmlGenerator::startMemberGroupDocs()
{
  t << "<tr><td colspan=\"2\"><div class=\"groupText\">";
}

void HtmlGenerator::endMemberGroupDocs()
{
  t << "</div></td></tr>" << endl;
}

void HtmlGenerator::startMemberGroup()
{
}

void HtmlGenerator::endMemberGroup(bool)
{
}

void HtmlGenerator::startIndent()        
{ 
  DBG_HTML(t << "<!-- startIndent -->" << endl;)

  t << "<div class=\"memdoc\">\n";
}

void HtmlGenerator::endIndent()          
{ 
  DBG_HTML(t << "<!-- endIndent -->" << endl;)
  t << endl << "</div>" << endl << "</div>" << endl; 
}

void HtmlGenerator::addIndexItem(const char *,const char *)
{
}

void HtmlGenerator::writeNonBreakableSpace(int n)
{
  int i;
  for (i=0;i<n;i++)
  {
    t << "&#160;";
  }
}

void HtmlGenerator::startSimpleSect(SectionTypes,
                                const char *filename,const char *anchor,
                                const char *title)
{
  t << "<dl><dt><b>";
  if (filename)
  {
    writeObjectLink(0,filename,anchor,title);
  }
  else
  {
    docify(title);
  }
  t << "</b></dt>";
}

void HtmlGenerator::endSimpleSect()
{
  t << "</dl>"; 
}

void HtmlGenerator::startParamList(ParamListTypes,
                                const char *title)
{
  t << "<dl><dt><b>";
  docify(title);
  t << "</b></dt>";
}

void HtmlGenerator::endParamList()
{
  t << "</dl>"; 
}

void HtmlGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *)
{
  HtmlDocVisitor *visitor = new HtmlDocVisitor(t,m_codeGen,ctx);
  n->accept(visitor);
  delete visitor; 
}

//---------------- helpers for index generation -----------------------------

static void startQuickIndexList(FTextStream &t,bool compact,bool topLevel=TRUE)
{
  if (compact) 
  {
    if (topLevel)
    {
      t << "  <div id=\"navrow1\" class=\"tabs\">\n";
    }
    else
    {
      t << "  <div id=\"navrow2\" class=\"tabs2\">\n";
    }
    t << "    <ul class=\"tablist\">\n"; 
  }
  else 
  {
    t << "<ul>";
  }
}

static void endQuickIndexList(FTextStream &t,bool compact)
{
  if (compact) 
  {
    t << "    </ul>\n";
    t << "  </div>\n";
  }
  else 
  {
    t << "</ul>\n";
  }
}

static void startQuickIndexItem(FTextStream &t,const char *l,
                                bool hl,bool /*compact*/,
                                const QCString &relPath)
{
  t << "      <li"; 
  if (hl) 
  {
    t << " class=\"current\"";
  }
  t << ">";
  if (l) t << "<a href=\"" << correctURL(l,relPath) << "\">";
  t << "<span>";
}

static void endQuickIndexItem(FTextStream &t,const char *l)
{
  t << "</span>";
  if (l) t << "</a>";
  t << "</li>\n";
}

static QCString fixSpaces(const QCString &s)
{
  return substitute(s," ","&#160;");
}

static bool quickLinkVisible(LayoutNavEntry::Kind kind)
{
  static bool showFiles = Config_getBool("SHOW_FILES");
  static bool showNamespaces = Config_getBool("SHOW_NAMESPACES");
  switch (kind)
  {
    case LayoutNavEntry::MainPage:         return TRUE; 
    case LayoutNavEntry::User:             return TRUE;                                           
    case LayoutNavEntry::UserGroup:        return TRUE;                                           
    case LayoutNavEntry::Pages:            return indexedPages>0;
    case LayoutNavEntry::Modules:          return documentedGroups>0;
    case LayoutNavEntry::Namespaces:       return documentedNamespaces>0 && showNamespaces;
    case LayoutNavEntry::NamespaceList:    return documentedNamespaces>0 && showNamespaces;
    case LayoutNavEntry::NamespaceMembers: return documentedNamespaceMembers[NMHL_All]>0;
    case LayoutNavEntry::Classes:          return annotatedClasses>0;
    case LayoutNavEntry::ClassList:        return annotatedClasses>0; 
    case LayoutNavEntry::ClassIndex:       return annotatedClasses>0; 
    case LayoutNavEntry::ClassHierarchy:   return hierarchyClasses>0;
    case LayoutNavEntry::ClassMembers:     return documentedClassMembers[CMHL_All]>0;
    case LayoutNavEntry::Files:            return documentedHtmlFiles>0 && showFiles;
    case LayoutNavEntry::FileList:         return documentedHtmlFiles>0 && showFiles;
    case LayoutNavEntry::FileGlobals:      return documentedFileMembers[FMHL_All]>0;
    //case LayoutNavEntry::Dirs:             return documentedDirs>0;
    case LayoutNavEntry::Examples:         return Doxygen::exampleSDict->count()>0;
  }
  return FALSE;
}

static void renderQuickLinksAsTree(FTextStream &t,const QCString &relPath,LayoutNavEntry *root)

{
  QListIterator<LayoutNavEntry> li(root->children());
  LayoutNavEntry *entry;
  int count=0;
  for (li.toFirst();(entry=li.current());++li)
  {
    if (entry->visible() && quickLinkVisible(entry->kind())) count++;
  }
  if (count>0) // at least one item is visible
  {
    startQuickIndexList(t,FALSE);
    for (li.toFirst();(entry=li.current());++li)
    {
      if (entry->visible() && quickLinkVisible(entry->kind()))
      {
        QCString url = entry->url();
        t << "<li><a href=\"" << relPath << url << "\"><span>";
        t << fixSpaces(entry->title());
        t << "</span></a>\n";
        // recursive into child list
        renderQuickLinksAsTree(t,relPath,entry);
        t << "</li>";
      }
    }
    endQuickIndexList(t,FALSE);
  }
}


static void renderQuickLinksAsTabs(FTextStream &t,const QCString &relPath,
                             LayoutNavEntry *hlEntry,LayoutNavEntry::Kind kind,
                             bool highlightParent,bool highlightSearch)
{
  if (hlEntry->parent()) // first draw the tabs for the parent of hlEntry
  {
    renderQuickLinksAsTabs(t,relPath,hlEntry->parent(),kind,highlightParent,highlightSearch);
  }
  if (hlEntry->parent() && hlEntry->parent()->children().count()>0) // draw tabs for row containing hlEntry
  {
    bool topLevel = hlEntry->parent()->parent()==0;
    QListIterator<LayoutNavEntry> li(hlEntry->parent()->children());
    LayoutNavEntry *entry;

    int count=0;
    for (li.toFirst();(entry=li.current());++li)
    {
      if (entry->visible() && quickLinkVisible(entry->kind())) count++;
    }
    if (count>0) // at least one item is visible
    {
      startQuickIndexList(t,TRUE,topLevel);
      for (li.toFirst();(entry=li.current());++li)
      {
        if (entry->visible() && quickLinkVisible(entry->kind()))
        {
          QCString url = entry->url();
          startQuickIndexItem(t,url,
              entry==hlEntry  && 
              (entry->children().count()>0 || 
               (entry->kind()==kind && !highlightParent)
              ),
              TRUE,relPath);
          t << fixSpaces(entry->title());
          endQuickIndexItem(t,url);
        }
      }
      if (hlEntry->parent()==LayoutDocManager::instance().rootNavEntry()) // first row is special as it contains the search box
      {
        static bool searchEngine      = Config_getBool("SEARCHENGINE");
        static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
        if (searchEngine)
        {
          t << "      <li>\n";
          if (!serverBasedSearch) // pure client side search
          {
            writeClientSearchBox(t,relPath);
            t << "      </li>\n";
          }
          else // server based search
          {
            writeServerSearchBox(t,relPath,highlightSearch);
            if (!highlightSearch)
            {
              t << "      </li>\n";
            }
          }
        }
        if (!highlightSearch) // on the search page the index will be ended by the
          // page itself
        {
          endQuickIndexList(t,TRUE);
        }
      }
      else // normal case for other rows than first one
      {
        endQuickIndexList(t,TRUE);
      }
    }
  }
}

static void writeDefaultQuickLinks(FTextStream &t,bool compact,
                                   HighlightedItem hli,
                                   const char *file,
                                   const QCString &relPath)
{
  LayoutNavEntry *root = LayoutDocManager::instance().rootNavEntry();
  LayoutNavEntry::Kind kind = (LayoutNavEntry::Kind)-1;
  LayoutNavEntry::Kind altKind = (LayoutNavEntry::Kind)-1; // fall back for the old layout file
  bool highlightParent=FALSE;
  switch (hli) // map HLI enums to LayoutNavEntry::Kind enums
  {
    case HLI_Main:             kind = LayoutNavEntry::MainPage;         break;
    case HLI_Modules:          kind = LayoutNavEntry::Modules;          break;
    //case HLI_Directories:      kind = LayoutNavEntry::Dirs;             break;
    case HLI_Namespaces:       kind = LayoutNavEntry::NamespaceList;    altKind = LayoutNavEntry::Namespaces;  break;
    case HLI_Hierarchy:        kind = LayoutNavEntry::ClassHierarchy;   break;
    case HLI_Classes:          kind = LayoutNavEntry::ClassIndex;       altKind = LayoutNavEntry::Classes;     break;
    case HLI_Annotated:        kind = LayoutNavEntry::ClassList;        altKind = LayoutNavEntry::Classes;     break;
    case HLI_Files:            kind = LayoutNavEntry::FileList;         altKind = LayoutNavEntry::Files;       break;
    case HLI_NamespaceMembers: kind = LayoutNavEntry::NamespaceMembers; break;
    case HLI_Functions:        kind = LayoutNavEntry::ClassMembers;     break;
    case HLI_Globals:          kind = LayoutNavEntry::FileGlobals;      break;
    case HLI_Pages:            kind = LayoutNavEntry::Pages;            break;
    case HLI_Examples:         kind = LayoutNavEntry::Examples;         break;
    case HLI_UserGroup:        kind = LayoutNavEntry::UserGroup;        break;
    case HLI_ClassVisible:     kind = LayoutNavEntry::ClassList;        altKind = LayoutNavEntry::Classes;          
                               highlightParent = TRUE; break;
    case HLI_NamespaceVisible: kind = LayoutNavEntry::NamespaceList;    altKind = LayoutNavEntry::Namespaces;       
                               highlightParent = TRUE; break;
    case HLI_FileVisible:      kind = LayoutNavEntry::FileList;         altKind = LayoutNavEntry::Files;            
                               highlightParent = TRUE; break;
    case HLI_None:   break;
    case HLI_Search: break;
  }
  
  if (compact)
  {
    // find highlighted index item
    LayoutNavEntry *hlEntry = root->find(kind,kind==LayoutNavEntry::UserGroup ? file : 0);
    if (!hlEntry && altKind!=(LayoutNavEntry::Kind)-1) { hlEntry=root->find(altKind); kind=altKind; }
    if (!hlEntry) // highlighted item not found in the index! -> just show the level 1 index...
    {
      highlightParent=TRUE;
      hlEntry = root->children().getFirst();
      if (hlEntry==0) 
      {
        return; // argl, empty index!
      }
    }
    if (kind==LayoutNavEntry::UserGroup)
    {
      LayoutNavEntry *e = hlEntry->children().getFirst();
      if (e)
      {
        hlEntry = e; 
      }
    }
    renderQuickLinksAsTabs(t,relPath,hlEntry,kind,highlightParent,hli==HLI_Search);
  }
  else
  {
    renderQuickLinksAsTree(t,relPath,root);
  }
}

void HtmlGenerator::endQuickIndices()
{
  t << "</div><!-- top -->" << endl;
}

QCString HtmlGenerator::writeSplitBarAsString(const char *name,const char *relpath)
{
  static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
  QCString result;
  // write split bar
  if (generateTreeView)
  {
    result = QCString(
    "<div id=\"side-nav\" class=\"ui-resizable side-nav-resizable\">\n"
    "  <div id=\"nav-tree\">\n"
    "    <div id=\"nav-tree-contents\">\n"
    "      <div id=\"nav-sync\" class=\"sync\"></div>\n"
    "    </div>\n"
    "  </div>\n"
    "  <div id=\"splitbar\" style=\"-moz-user-select:none;\" \n"
    "       class=\"ui-resizable-handle\">\n"
    "  </div>\n"
    "</div>\n"
    "<script type=\"text/javascript\">\n"
    "$(document).ready(function(){initNavTree('") + 
    QCString(name) + Doxygen::htmlFileExtension + 
    QCString("','") + relpath +
    QCString("');});\n"
    "</script>\n"
    "<div id=\"doc-content\">\n");
  }
  return result;
}

void HtmlGenerator::writeSplitBar(const char *name)
{
  t << writeSplitBarAsString(name,relPath);
}

void HtmlGenerator::writeNavigationPath(const char *s)
{
  t << substitute(s,"$relpath^",relPath);
}

void HtmlGenerator::startContents()
{
  t << "<div class=\"contents\">" << endl;
}

void HtmlGenerator::endContents()
{
  t << "</div><!-- contents -->" << endl;
}

void HtmlGenerator::writeQuickLinks(bool compact,HighlightedItem hli,const char *file)
{
  writeDefaultQuickLinks(t,compact,hli,file,relPath);
}

// PHP based search script
void HtmlGenerator::writeSearchPage()
{
  static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
  static bool disableIndex = Config_getBool("DISABLE_INDEX");
  static QCString projectName = Config_getString("PROJECT_NAME");

  // OPENSEARCH_PROVIDER {
  QCString configFileName = Config_getString("HTML_OUTPUT")+"/search-config.php";
  QFile cf(configFileName);
  if (cf.open(IO_WriteOnly))
  {
    FTextStream t(&cf);
    t << "<script language=\"php\">\n\n";
    t << "$config = array(\n";
    t << "  'PROJECT_NAME' => \"" << convertToHtml(projectName) << "\",\n";
    t << "  'GENERATE_TREEVIEW' => " << (generateTreeView?"true":"false") << ",\n";
    t << "  'DISABLE_INDEX' => " << (disableIndex?"true":"false") << ",\n";
    t << ");\n\n";
    t << "$translator = array(\n";
    t << "  'search_results_title' => \"" << theTranslator->trSearchResultsTitle() << "\",\n";
    t << "  'search_results' => array(\n";  
    t << "    0 => \"" << theTranslator->trSearchResults(0) << "\",\n";     
    t << "    1 => \"" << theTranslator->trSearchResults(1) << "\",\n";     
    t << "    2 => \"" << substitute(theTranslator->trSearchResults(2), "$", "\\$") << "\",\n";     
    t << "  ),\n";
    t << "  'search_matches' => \"" << theTranslator->trSearchMatches() << "\",\n";
    t << "  'search' => \"" << theTranslator->trSearch() << "\",\n";
    t << "  'split_bar' => \"" << substitute(substitute(writeSplitBarAsString("search",""), "\"","\\\""), "\n","\\n") << "\",\n";
    t << "  'logo' => \"" << substitute(substitute(writeLogoAsString(""), "\"","\\\""), "\n","\\n") << "\",\n";
    t << ");\n\n";
    t << "</script>\n";
  }

  QCString functionsFileName = Config_getString("HTML_OUTPUT")+"/search-functions.php";
  QFile ff(functionsFileName);
  if (ff.open(IO_WriteOnly))
  {
    FTextStream t(&ff);
    // Write stuff from search_functions.php source file...
    t << search_functions_script;
  }

  QCString opensearchFileName = Config_getString("HTML_OUTPUT")+"/search-opensearch.php";
  QFile of(opensearchFileName);
  if (of.open(IO_WriteOnly))
  {
    FTextStream t(&of);
    // Write stuff from search_opensearch.php source file...
    t << search_opensearch_script;
  }
  // OPENSEARCH_PROVIDER }

  QCString fileName = Config_getString("HTML_OUTPUT")+"/search.php";
  QFile f(fileName);
  if (f.open(IO_WriteOnly))
  {
    FTextStream t(&f);
    t << substituteHtmlKeywords(g_header,"Search","");

    t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " 
      << versionString << " -->" << endl;
    t << "<script type=\"text/javascript\">\n";
    t << "var searchBox = new SearchBox(\"searchBox\", \""
      << "search\",false,'" << theTranslator->trSearch() << "');\n";
    t << "</script>\n";
    if (!Config_getBool("DISABLE_INDEX"))
    {
      writeDefaultQuickLinks(t,TRUE,HLI_Search,0,"");
    }
    else
    {
      t << "</div>" << endl;
    }

    t << "<script language=\"php\">\n";
    t << "require_once \"search-functions.php\";\n";
    t << "main();\n";
    t << "</script>\n";

    // Write empty navigation path, to make footer connect properly
    if (generateTreeView)
    {
      t << "</div><!-- doc-contents -->\n";
      //t << "<div id=\"nav-path\" class=\"navpath\">\n";
      //t << "  <ul>\n";
    }

    writePageFooter(t,"Search","","");
  }
  QCString scriptName = Config_getString("HTML_OUTPUT")+"/search/search.js";
  QFile sf(scriptName);
  if (sf.open(IO_WriteOnly))
  {
    FTextStream t(&sf);
    t << extsearch_script;
  }
  else
  {
     err("Failed to open file '%s' for writing...\n",scriptName.data());
  }
}

void HtmlGenerator::writeExternalSearchPage()
{
  static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
  QCString fileName = Config_getString("HTML_OUTPUT")+"/search"+Doxygen::htmlFileExtension;
  QFile f(fileName);
  if (f.open(IO_WriteOnly))
  {
    FTextStream t(&f);
    t << substituteHtmlKeywords(g_header,"Search","");

    t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " 
      << versionString << " -->" << endl;
    t << "<script type=\"text/javascript\">\n";
    t << "var searchBox = new SearchBox(\"searchBox\", \""
      << "search\",false,'" << theTranslator->trSearch() << "');\n";
    t << "</script>\n";
    if (!Config_getBool("DISABLE_INDEX"))
    {
      writeDefaultQuickLinks(t,TRUE,HLI_Search,0,"");
      t << "            <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\"\" size=\"20\" accesskey=\"S\" onfocus=\"searchBox.OnSearchFieldFocus(true)\" onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n";
      t << "            </form>\n";
      t << "          </div><div class=\"right\"></div>\n";
      t << "        </div>\n";
      t << "      </li>\n";
      t << "    </ul>\n";
      t << "  </div>\n";
      t << "</div>\n";
    }
    else
    {
      t << "</div>" << endl;
    }
    t << writeSplitBarAsString("search","");
    t << "<div class=\"header\">" << endl;
    t << "  <div class=\"headertitle\">" << endl;
    t << "    <div class=\"title\">" << theTranslator->trSearchResultsTitle() << "</div>" << endl;
    t << "  </div>" << endl;
    t << "</div>" << endl;
    t << "<div class=\"contents\">" << endl;

    t << "<div id=\"searchresults\"></div>" << endl;
    t << "</div>" << endl;

    if (generateTreeView)
    {
      t << "</div><!-- doc-contents -->" << endl;
    }

    writePageFooter(t,"Search","","");
  }
  QCString scriptName = Config_getString("HTML_OUTPUT")+"/search/search.js";
  QFile sf(scriptName);
  if (sf.open(IO_WriteOnly))
  {
    FTextStream t(&sf);
    t << "var searchResultsText=["
      << "\"" << theTranslator->trSearchResults(0) << "\","
      << "\"" << theTranslator->trSearchResults(1) << "\","
      << "\"" << theTranslator->trSearchResults(2) << "\"];" << endl;
    t << "var serverUrl=\"" << Config_getString("SEARCHENGINE_URL") << "\";" << endl;
    t << "var tagMap = {" << endl;
    bool first=TRUE;
    // add search mappings
    QStrList &extraSearchMappings = Config_getList("EXTRA_SEARCH_MAPPINGS");
    char *ml=extraSearchMappings.first();
    while (ml)
    {
      QCString mapLine = ml;
      int eqPos = mapLine.find('=');
      if (eqPos!=-1) // tag command contains a destination
      {
        QCString tagName = mapLine.left(eqPos).stripWhiteSpace();
        QCString destName = mapLine.right(mapLine.length()-eqPos-1).stripWhiteSpace();
        if (!tagName.isEmpty())
        {
          if (!first) t << "," << endl;
          t << "  \"" << tagName << "\": \"" << destName << "\"";
          first=FALSE;
        }
      }
      ml=extraSearchMappings.next();
    }
    if (!first) t << endl;
    t << "};" << endl << endl;
    t << extsearch_script;
    t << endl;
    t << "$(document).ready(function() {" << endl;
    t << "  var query = trim(getURLParameter('query'));" << endl;
    t << "  if (query) {" << endl;
    t << "    searchFor(query,0,20);" << endl;
    t << "  } else {" << endl;
    t << "    var results = $('#results');" << endl;
    t << "    results.html('<p>" << theTranslator->trSearchResults(0) << "</p>');" << endl;
    t << "  }" << endl;
    t << "});" << endl;
  }
  else
  {
     err("Failed to open file '%s' for writing...\n",scriptName.data());
  }
}

void HtmlGenerator::startConstraintList(const char *header)
{
  t << "<div class=\"typeconstraint\">" << endl;
  t << "<dl><dt><b>" << header << "</b></dt><dd>" << endl;
  t << "<table border=\"0\" cellspacing=\"2\" cellpadding=\"0\">" << endl;
}

void HtmlGenerator::startConstraintParam()
{
  t << "<tr><td valign=\"top\"><em>";
}

void HtmlGenerator::endConstraintParam()
{
  t << "</em></td>";
}

void HtmlGenerator::startConstraintType()
{
  t << "<td>&#160;:</td><td valign=\"top\"><em>";
}

void HtmlGenerator::endConstraintType()
{
  t << "</em></td>";
}

void HtmlGenerator::startConstraintDocs()
{
  t << "<td>&#160;";
}

void HtmlGenerator::endConstraintDocs()
{
  t << "</td></tr>" << endl;
}

void HtmlGenerator::endConstraintList()
{
  t << "</table>" << endl;
  t << "</dl>" << endl;
  t << "</div>" << endl;
}

void HtmlGenerator::lineBreak(const char *style)
{
  if (style)
  {
    t << "<br class=\"" << style << "\" />" << endl;
  }
  else
  {
    t << "<br />" << endl;
  }
}

void HtmlGenerator::startHeaderSection()
{
  t << "<div class=\"header\">" << endl;
}

void HtmlGenerator::startTitleHead(const char *) 
{ 
  t << "  <div class=\"headertitle\">" << endl;
  startTitle(); 
}

void HtmlGenerator::endTitleHead(const char *,const char *) 
{ 
  endTitle(); 
  t << "  </div>" << endl;
}

void HtmlGenerator::endHeaderSection()
{
  t << "</div><!--header-->" << endl;
}

void HtmlGenerator::startInlineHeader()
{
  if (m_emptySection)
  {
    t << "<table class=\"memberdecls\">" << endl;
    m_emptySection=FALSE;
  }
  t << "<tr><td colspan=\"2\"><h3>";
}

void HtmlGenerator::endInlineHeader()
{
  t << "</h3></td></tr>" << endl;
}

void HtmlGenerator::startMemberDocSimple()
{
  DBG_HTML(t << "<!-- startMemberDocSimple -->" << endl;)
  t << "<table class=\"fieldtable\">" << endl;
  t << "<tr><th colspan=\"3\">" << theTranslator->trCompoundMembers() << "</th></tr>" << endl;
}

void HtmlGenerator::endMemberDocSimple()
{
  DBG_HTML(t << "<!-- endMemberDocSimple -->" << endl;)
  t << "</table>" << endl;
}

void HtmlGenerator::startInlineMemberType()
{
  DBG_HTML(t << "<!-- startInlineMemberType -->" << endl;)
  t << "<tr><td class=\"fieldtype\">" << endl;
}

void HtmlGenerator::endInlineMemberType()
{
  DBG_HTML(t << "<!-- endInlineMemberType -->" << endl;)
  t << "</td>" << endl;
}

void HtmlGenerator::startInlineMemberName()
{
  DBG_HTML(t << "<!-- startInlineMemberName -->" << endl;)
  t << "<td class=\"fieldname\">" << endl;
}

void HtmlGenerator::endInlineMemberName()
{
  DBG_HTML(t << "<!-- endInlineMemberName -->" << endl;)
  t << "</td>" << endl;
}

void HtmlGenerator::startInlineMemberDoc()
{
  DBG_HTML(t << "<!-- startInlineMemberDoc -->" << endl;)
  t << "<td class=\"fielddoc\">" << endl;
}

void HtmlGenerator::endInlineMemberDoc()
{
  DBG_HTML(t << "<!-- endInlineMemberDoc -->" << endl;)
  t << "</td></tr>" << endl;
}

void HtmlGenerator::startLabels()
{
  DBG_HTML(t << "<!-- startLabels -->" << endl;)
  t << "<span class=\"mlabels\">";
}

void HtmlGenerator::writeLabel(const char *l,bool /*isLast*/)
{
  DBG_HTML(t << "<!-- writeLabel(" << l << ") -->" << endl;)
  //t << "<tt>[" << l << "]</tt>";
  //if (!isLast) t << ", ";
  t << "<span class=\"mlabel\">" << l << "</span>";
}

void HtmlGenerator::endLabels()
{
  DBG_HTML(t << "<!-- endLabels -->" << endl;)
  t << "</span>";
}

void HtmlGenerator::writeInheritedSectionTitle(
                  const char *id,    const char *ref, 
                  const char *file,  const char *anchor,
                  const char *title, const char *name)
{
  DBG_HTML(t << "<!-- writeInheritedSectionTitle -->" << endl;)
  QCString a = anchor;
  if (!a.isEmpty()) a.prepend("#");
  QCString classLink = QCString("<a class=\"el\" href=\"");
  if (ref)
  {
    classLink+= externalLinkTarget() + externalRef(relPath,ref,TRUE);
  }
  else
  {
    classLink+=relPath;
  }
  classLink+=file+Doxygen::htmlFileExtension+a;
  classLink+=QCString("\">")+convertToHtml(name,FALSE)+"</a>";
  t << "<tr class=\"inherit_header " << id << "\">"
    << "<td colspan=\"2\" onclick=\"javascript:toggleInherit('" << id << "')\">"
    << "<img src=\"" << relPath << "closed.png\" alt=\"-\"/>&#160;" 
    << theTranslator->trInheritedFrom(convertToHtml(title,FALSE),classLink)
    << "</td></tr>" << endl;
}

void HtmlGenerator::writeSummaryLink(const char *file,const char *anchor,const char *title,bool first)
{
  if (first)
  {
    t << "  <div class=\"summary\">\n";
  }
  else
  {
    t << " &#124;\n";
  }
  t << "<a href=\"";
  if (file)
  {
    t << relPath << file;
    t << Doxygen::htmlFileExtension;
  }
  else
  {
    t << "#";
    t << anchor;
  }
  t << "\">";
  t << title;
  t << "</a>";
}

void HtmlGenerator::endMemberDeclaration(const char *anchor,const char *inheritId)
{
  t << "<tr class=\"separator:" << anchor;
  if (inheritId)
  {
    t << " inherit " << inheritId;
  }
  t << "\"><td class=\"memSeparator\" colspan=\"2\">&#160;</td></tr>\n";
}

void HtmlGenerator::setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile)
{
  if (Doxygen::searchIndex)
  {
    Doxygen::searchIndex->setCurrentDoc(context,anchor,isSourceFile);
  }
}

void HtmlGenerator::addWord(const char *word,bool hiPriority)
{
  if (Doxygen::searchIndex)
  {
    Doxygen::searchIndex->addWord(word,hiPriority);
  }
}