// @(#)root/gui:$Id$
// Author: Katerina Opocenska   11/09/2008

/*************************************************************************
* Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
* All rights reserved.                                                  *
*                                                                       *
* For the licensing terms see $ROOTSYS/LICENSE.                         *
* For the list of contributors see $ROOTSYS/README/CREDITS.             *
*************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  ROOT EVENT RECORDING SYSTEM                                         //
// ==================================================================   //
//                                                                      //
//  TRecorder class provides interface for recording and replaying      //
//  events in ROOT.                                                     //
//  Recorded events are:                                                //
//  - Commands typed by user in commandline ('new TCanvas')             //
//  - GUI events (mouse movement, button clicks, ...)                   //
//                                                                      //
//  All the recorded events from one session are stored in one TFile    //
//  and can be replayed again anytime.                                  //
//                                                                      //
//  Recording                                                           //
//  ==================================================================  //
//                                                                      //
//  1] To start recording                                               //
//                                                                      //
//    TRecorder r(const char *filename, "NEW")                          //
//    TRecorder r(const char *filename, "RECREATE")                     //
//                                                                      //
//    or:                                                               //
//                                                                      //
//    TRecorder *recorder = new TRecorder;                              //
//    recorder->Start(const char *filename, ...)                        //
//                                                                      //
//    -filename      Name of ROOT file in which to save                 //
//                   recorded events.                                   //
//                                                                      //
//  2] To stop recording                                                //
//                                                                      //
//    recorder->Stop()                                                  //
//                                                                      //
//                                                                      //
//  IMPORTANT:                                                          //
//  State capturing is part of recording. It means that if you want to  //
//  record events for some object (window), creation of this object     //
//  must be also recorded.                                              //
//                                                                      //
//    Example:                                                          //
//    --------                                                          //
//    t = new TRecorder();          // Create a new recorder            //
//    t->Start("logfile.root");     // ! Start recording first          //
//                                                                      //
//    c = new TCanvas();            // ! Then, create an object         //
//    c->Dump();                    // Work with that object            //
//                                                                      //
//    t->Stop();                    // Stop recording                   //
//                                                                      //
//  It is strongly recommended to start recording with empty ROOT       //
//  environment, at least with no previously created ROOT GUI.          //
//  This ensures that only events for well known windows are stored.    //
//  Events for windows, which were not created during recording,        //
//  cannot be replayed.                                                 //
//                                                                      //
//  Replaying                                                           //
//  =================================================================== //
//                                                                      //
//  1] To start replaying                                               //
//                                                                      //
//    TRecorder r(const char *filename)                                 //
//    TRecorder r(const char *filename, "READ")                         //
//                                                                      //
//    or:                                                               //
//                                                                      //
//    TRecorder *recorder = new TRecorder;                              //
//    recorder->Replay(const char *filename,                            //
//                      Bool_t showMouseCursor = kTRUE);                //
//                                                                      //
//    -filename         A name of file with recorded events             //
//                      previously created with TRecorder::Start        //
//                                                                      //
//    -showMouseCursor  If kTRUE, mouse cursor is replayed as well.     //
//                      In that case it is not recommended to use mouse //
//                      during replaying.                               //
//                                                                      //
//  In general, it is not recommended to use mouse to change positions  //
//  and states of ROOT windows during replaying.                        //
//                                                                      //
//  IMPORTANT:                                                          //
//  The state of ROOT environment before replaying of some events       //
//  must be exactly the same as before recording them.                  //
//  Therefore it is strongly recommended to start both recording        //
//  and replaying with empty ROOT environment.                          //
//                                                                      //
//  2] To pause replaying                                               //
//                                                                      //
//    recorder->Pause()                                                 //
//                                                                      //
//    Replaying is stopped until recorder->Resume() is called.          //
//                                                                      //
//                                                                      //
//  3] To resume paused replaying                                       //
//                                                                      //
//    recorder->Resume()                                                //
//                                                                      //
//    Resumes previously stopped replaying.                             //
//                                                                      //
//                                                                      //
//  4] To stop replaying before its end                                 //
//                                                                      //
//    recorder->Stop()                                                  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TRecorder.h"

#include "TROOT.h"
#include "TFile.h"
#include "TTimer.h"
#include "TTree.h"
#include "TMutex.h"
#include "TGButton.h"
#include "TGFileDialog.h"
#include "TGLabel.h"
#include "TGWindow.h"
#include "Buttons.h"
#include "TKey.h"
#include "TPaveLabel.h"
#include "TLatex.h"
#include "TVirtualDragManager.h"
#include "TGPicture.h"
#include "KeySymbols.h"

// Names of ROOT GUI events. Used for listing event logs.
const char *kRecEventNames[] = {
   "KeyPress",
   "KeyRelease",
   "ButtonPress",
   "ButtonRelease",
   "MotionNotify",
   "EnterNotify",
   "LeaveNotify",
   "FocusIn",
   "FocusOut",
   "Expose",
   "ConfigureNotify",
   "MapNotify",
   "UnmapNotify",
   "DestroyNotify",
   "ClientMessage",
   "SelectionClear",
   "SelectionRequest",
   "SelectionNotify",
   "ColormapNotify",
   "ButtonDoubleClick",
   "OtherEvent"
};

// Names of TTrees in the TFile with recorded events
const char *kCmdEventTree   = "CmdEvents";   // Name of TTree with commandline events
const char *kGuiEventTree   = "GuiEvents";   // Name of TTree with GUI events
const char *kWindowsTree    = "WindowsTree"; // Name of TTree with window IDs
const char *kExtraEventTree = "ExtraEvents"; // Name of TTree with extra events (PaveLabels and Texts)
const char *kBranchName     = "MainBranch";  // Name of the main branch in all TTress

ClassImp(TRecorder)


//_____________________________________________________________________________
//
// TGCursorWindow
//
// Window used as fake mouse cursor wile replaying events.
//_____________________________________________________________________________

class TGCursorWindow : public TGFrame {

protected:
   Pixmap_t fPic, fMask;            // Pixmaps used as Window shape

public:
   TGCursorWindow();
   virtual ~TGCursorWindow();
};

static TGCursorWindow *gCursorWin = 0;
static Int_t gDecorWidth  = 0;
static Int_t gDecorHeight = 0;

//______________________________________________________________________________
TGCursorWindow::TGCursorWindow() :
      TGFrame(gClient->GetDefaultRoot(), 32, 32, kTempFrame)
{
   // TGCursorWindow constructor.

   SetWindowAttributes_t wattr;
   const TGPicture *pbg = fClient->GetPicture("recursor.png");
   fPic  = pbg->GetPicture();
   fMask = pbg->GetMask();

   gVirtualX->ShapeCombineMask(fId, 0, 0, fMask);
   SetBackgroundPixmap(fPic);

   wattr.fMask = kWAOverrideRedirect | kWASaveUnder;
   wattr.fSaveUnder = kTRUE;
   wattr.fOverrideRedirect = kTRUE;

   gVirtualX->ChangeWindowAttributes(fId, &wattr);
}

//______________________________________________________________________________
TGCursorWindow::~TGCursorWindow()
{
   // Destructor.

}

//______________________________________________________________________________
TRecorder::TRecorder()
{
   // Creates initial INACTIVE state for the recorder

   fFilename = "";
   fRecorderState = new TRecorderInactive();
}

//______________________________________________________________________________
TRecorder::TRecorder(const char *filename, Option_t *option)
{
   // Creates a recorder with filename to replay or to record,
   // depending on option (NEW or RECREATE will start recording,
   // READ will start replaying)

   TString opt(option);
   fFilename = "";
   fRecorderState = new TRecorderInactive();
   if ((opt == "NEW") || (opt == "RECREATE"))
      Start(filename, option);
   else
      Replay(filename);
}

//______________________________________________________________________________
TRecorder::~TRecorder()
{
   // Destructor.

   delete fRecorderState;
}

//______________________________________________________________________________
void TRecorder::Browse(TBrowser *)
{
   // Browse the recorder from a ROOT file. This allows to replay a
   // session from the browser.

   Replay(fFilename);
}

//______________________________________________________________________________
void TRecorder::Start(const char *filename, Option_t *option, Window_t *w,
                      Int_t winCount)
{
   // Starts recording events

   fRecorderState->Start(this, filename, option, w, winCount);
}

//______________________________________________________________________________
void TRecorder::Stop(Bool_t guiCommand)
{
   // Stopps recording events

   fRecorderState->Stop(this, guiCommand);
}

//______________________________________________________________________________
Bool_t TRecorder::Replay(const char *filename, Bool_t showMouseCursor,
                         TRecorder::EReplayModes mode)
{
   // Replays events from 'filename'

   return fRecorderState->Replay(this, filename, showMouseCursor, mode);
}

//______________________________________________________________________________
void TRecorder::Pause()
{
   // Pauses replaying

   fRecorderState->Pause(this);
}

//______________________________________________________________________________
void TRecorder::Resume()
{
   // Resumes replaying

   fRecorderState->Resume(this);
}

//______________________________________________________________________________
void TRecorder::ReplayStop()
{
   // Cancells replaying

   fRecorderState->ReplayStop(this);
}

//______________________________________________________________________________
void TRecorder::ListCmd(const char *filename)
{
   // Prints out recorded commandline events

   fRecorderState->ListCmd(filename);
}

//______________________________________________________________________________
void TRecorder::ListGui(const char *filename)
{
   // Prints out recorded GUI events

   fRecorderState->ListGui(filename);
}

//______________________________________________________________________________
void TRecorder::ChangeState(TRecorderState *newstate, Bool_t delPreviousState)
{
   // Changes state from the current to the passed one (newstate)
   // Deletes the old state if delPreviousState = KTRUE

   if (delPreviousState)
      delete fRecorderState;

   fRecorderState = newstate;
}

//______________________________________________________________________________
TRecorder::ERecorderState TRecorder::GetState() const
{
   // Get current state of recorder.

   return fRecorderState->GetState();
}


//______________________________________________________________________________
void TRecorder::PrevCanvases(const char *filename, Option_t *option)
{
   // Save previous canvases in a .root file

   fRecorderState->PrevCanvases(filename,option);
}

//______________________________________________________________________________
// Represents state of TRecorder when replaying

ClassImp(TRecorderReplaying)

//______________________________________________________________________________
TRecorderReplaying::TRecorderReplaying(const char *filename)
{
   // Allocates all necessary data structures used for replaying
   // What is allocated here is deleted in destructor

   fCanv = 0;
   fCmdTree = 0;
   fCmdTreeCounter = 0;
   fEventReplayed = kTRUE;
   fExtraTree = 0;
   fExtraTreeCounter = 0;
   fFilterStatusBar = kFALSE;
   fGuiTree = 0;
   fGuiTreeCounter = 0;
   fNextEvent = 0;
   fRecorder = 0;
   fRegWinCounter = 0;
   fShowMouseCursor = kTRUE;
   fWaitingForWindow = kFALSE;
   fWin = 0;
   fWinTree = 0;
   fWinTreeEntries = 0;
   fFile       = TFile::Open(filename);
   fCmdEvent   = new TRecCmdEvent();
   fGuiEvent   = new TRecGuiEvent();
   fExtraEvent = new TRecExtraEvent();
   fWindowList = new TList();
   fTimer      = new TTimer();
   fMutex      = new TMutex(kFALSE);
   if (!gCursorWin)
      gCursorWin  = new TGCursorWindow();
}

//______________________________________________________________________________
TRecorderReplaying::~TRecorderReplaying()
{
   // Closes all signal-slot connections
   // Frees all memory allocated in contructor.

   fTimer->Disconnect(fTimer, "Timeout()", this, "ReplayRealtime()");
   fTimer->TurnOff();
   // delete fTimer;

   gClient->Disconnect(gClient, "RegisteredWindow(Window_t)", this,
                       "RegisterWindow(Window_t)");

   if (fFile) {
      fFile->Close();
      delete fFile;
   }

   delete fWindowList;
   delete fCmdEvent;
   delete fGuiEvent;
   delete fExtraEvent;
   delete fMutex;
   if (gCursorWin)
      gCursorWin->DeleteWindow();
   gCursorWin = 0;
}

//______________________________________________________________________________
Bool_t TRecorderReplaying::Initialize(TRecorder *r, Bool_t showMouseCursor,
                                      TRecorder::EReplayModes)
{
   // Initialization of data structures for replaying.
   // Start of replaying.
   //
   // Return value:
   //  - kTRUE  = everything is OK and replaying has begun
   //  - kFALSE = non existing or invalid log file, replaying has not started

   fWin              = 0;
   fGuiTreeCounter   = 0;
   fCmdTreeCounter   = 0;
   fExtraTreeCounter = 0;
   fRegWinCounter    = 0;
   fRecorder         = 0;

   fFilterStatusBar  = kFALSE;

   fWaitingForWindow = kFALSE;

   fEventReplayed    = 1;

   fRecorder = r;
   fShowMouseCursor = showMouseCursor;

   if (!fFile || fFile->IsZombie() || !fFile->IsOpen())
      return kFALSE;

   fCmdTree   = (TTree*) fFile->Get(kCmdEventTree);
   fWinTree   = (TTree*) fFile->Get(kWindowsTree);
   fGuiTree   = (TTree*) fFile->Get(kGuiEventTree);
   fExtraTree = (TTree*) fFile->Get(kExtraEventTree);

   if (!fCmdTree || !fWinTree || ! fGuiTree || ! fExtraTree) {
      Error("TRecorderReplaying::Initialize",
            "The ROOT file is not valid event logfile.");
      return kFALSE;
   }

   try {
      fCmdTree->SetBranchAddress(kBranchName, &fCmdEvent);
      fWinTree->SetBranchAddress(kBranchName, &fWin);
      fGuiTree->SetBranchAddress(kBranchName, &fGuiEvent);
      fExtraTree->SetBranchAddress(kBranchName, &fExtraEvent);
   }
   catch(...) {
      Error("TRecorderReplaying::Initialize",
            "The ROOT file is not valid event logfile");
      return kFALSE;
   }

   // No event to replay in given ROOT file
   if (!PrepareNextEvent()) {
      Info("TRecorderReplaying::Initialize",
           "Log file empty. No event to replay.");
      return kFALSE;
   }

   // Number of registered windows during recording
   fWinTreeEntries = fWinTree->GetEntries();

   // When a window is registered during replaying,
   // TRecorderReplaying::RegisterWindow(Window_t) is called
   gClient->Connect("RegisteredWindow(Window_t)", "TRecorderReplaying",
                    this, "RegisterWindow(Window_t)");

   Info("TRecorderReplaying::Initialize", "Replaying of file %s started",
        fFile->GetName());

   TFile *f = TFile::Open(fFile->GetName());
   if (f && !f->IsZombie()) {
      TIter nextkey(f->GetListOfKeys());
      TKey *key;
      TObject *obj;
      while ((key = (TKey*)nextkey())) {
         fFilterStatusBar = kTRUE;
         obj = key->ReadObj();
         if (!obj->InheritsFrom("TCanvas"))
            continue;
         fCanv = (TCanvas*) obj;
         fCanv->Draw();
      }
      TCanvas *canvas;
      TIter nextc(gROOT->GetListOfCanvases());
      while ((canvas = (TCanvas*)nextc())) {
         canvas->SetWindowSize(canvas->GetWindowWidth(),
                               canvas->GetWindowHeight());
      }
      fFilterStatusBar = kFALSE;
      f->Close();
   }

   gPad = 0;
   // Starts replaying
   fTimer->Connect("Timeout()","TRecorderReplaying",this,"ReplayRealtime()");
   fTimer->Start(0);

   return kTRUE;
}

//______________________________________________________________________________
void TRecorderReplaying::RegisterWindow(Window_t w)
{
   // Creates mapping for the newly registered window w and adds this
   // mapping to fWindowList
   //
   // Called by signal whenever a new window is registered during replaying.
   //
   // The new window ID is mapped to the old one with the same number in the
   // list of registered windows.
   // It means that 1st new window is mapped to the 1st original,
   // 2nd to the 2nd, Nth new to the Nth original.

   if (fFilterStatusBar) {
      TGWindow *win = gClient->GetWindowById(w);
      if (win) {
         if (win->GetParent()->InheritsFrom("TGStatusBar")) {
            fFilterStatusBar = kFALSE;
            return;
         }
      }
   }

   // Get original window ID that was registered as 'fRegWinCounter'th
   if (fWinTreeEntries > fRegWinCounter) {
      fWinTree->GetEntry(fRegWinCounter);
   }
   else {
      // More windows registered when replaying then when recording.
      // Cannot continue
      Error("TRecorderReplaying::RegisterWindow",
            "More windows registered than expected");
      //ReplayStop(fRecorder);
      return;
   }

   if ((gDebug > 0) && (fWaitingForWindow)) {
      std::ios::fmtflags f = std::cout.flags(); // store flags
      std::cout << " Window registered: new ID: " << std::hex << w <<
              "  previous ID: " << fWin << std::dec << std::endl;
      std::cout.flags( f ); // restore flags (reset std::hex)
   }

   // Lock mutex for guarding access to fWindowList
   fMutex->Lock();

   // Increases counter of registered windows
   fRegWinCounter++;

   // Creates new mapping of original window (fWin) and a new one (w)
   TRecWinPair *ids = new TRecWinPair(fWin, w);
   // Saves the newly created mapping
   fWindowList->Add(ids);

   // If we are waiting for this window to be registered
   // (Replaying was stopped because of that)
   if (fWaitingForWindow && fGuiEvent->fWindow == fWin) {

      if (gDebug > 0) {
         std::ios::fmtflags f = std::cout.flags(); // store flags
         std::cout << " Window " << std::hex << fGuiEvent->fWindow <<
                 " registered." << std::dec << std::endl;
         std::cout.flags( f ); // restore flags (reset std::hex)
      }

      fNextEvent = fGuiEvent;
      // Sets that we do not wait for this window anymore
      fWaitingForWindow = kFALSE;

      // Start replaying of events again
      fTimer->Start(25);
   }
   fMutex->UnLock();
}

//______________________________________________________________________________
Bool_t TRecorderReplaying::RemapWindowReferences()
{
   // All references to the old windows (IDs) in fNextEvent are replaced by
   // new ones according to the mappings in fWindowList

   // Lock mutex for guarding access to fWindowList
   fMutex->Lock();

   TRecWinPair *ids;
   TListIter it(fWindowList);

   Bool_t found = kFALSE;

   // Iterates through the whole list of mappings
   while ((ids = (TRecWinPair*)it.Next())) {
      // Window that the event belongs to
      if (!found && fGuiEvent->fWindow == 0) {
         fGuiEvent->fWindow = gVirtualX->GetDefaultRootWindow();
         found = kTRUE;
      }
      else if (!found && ids->fKey == fGuiEvent->fWindow) {
         fGuiEvent->fWindow = ids->fValue;
         found = kTRUE;
      }
      for (Int_t i = 0; i < 5; ++i) {
         if ((Long_t) ids->fKey == fGuiEvent->fUser[i])
            fGuiEvent->fUser[i] = ids->fValue;
      }
      if (fGuiEvent->fMasked && ids->fKey == fGuiEvent->fMasked) {
         fGuiEvent->fMasked = ids->fValue;
      }
   }

   if (!found && fGuiEvent->fWindow == 0) {
      fGuiEvent->fWindow = gVirtualX->GetDefaultRootWindow();
      found = kTRUE;
   }
   // Mapping for the event found
   if (found) {
      fMutex->UnLock();
      return kTRUE;
   }

   if (gDebug > 0) {
      // save actual formatting flags
      std::ios_base::fmtflags org_flags = std::cout.flags();
      std::cout << "fGuiTreeCounter = " << std::dec << fGuiTreeCounter <<
              " No mapping found for ID " << std::hex << fGuiEvent->fWindow << std::endl;
      TRecorderInactive::DumpRootEvent(fGuiEvent,0);
      // restore original formatting flags
      std::cout.flags(org_flags);
   }

   // Stopps timer and waits for the appropriate window to be registered
   fTimer->Stop();
   fWaitingForWindow = kTRUE;

   fMutex->UnLock();
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TRecorderReplaying::FilterEvent(TRecGuiEvent *e)
{

   // Not all the recorded events are replayed.
   // Some of them are generated automatically in ROOT
   // as a consequence of other events.
   //
   // RETURN VALUE:
   //    -  kTRUE  = passed TRecGuiEvent *e should be filtered
   //                (should not be replayed)
   //    -  kFALSE = passed TRecGuiEvent *e should not be filtered
   //                (should be replayed)

   // We do not replay any client messages except closing of windows
   if (e->fType == kClientMessage) {
      if ((e->fFormat == 32) && (e->fHandle != TRecGuiEvent::kROOT_MESSAGE)
          && ((Atom_t)e->fUser[0] == TRecGuiEvent::kWM_DELETE_WINDOW))
         return kFALSE;
      else
         return kTRUE;
   }

   // See TRecorderRecording::SetTypeOfConfigureNotify to get know
   // which kConfigureNotify events are filtered
   if (e->fType == kConfigureNotify && e->fUser[4] == TRecGuiEvent::kCNFilter) {
      return kTRUE;
   }

   if (e->fType == kOtherEvent) {
      if (e->fFormat >= kGKeyPress && e->fFormat < kOtherEvent)
         return kFALSE;
      return kTRUE;
   }

   return kFALSE;
}

//______________________________________________________________________________
Bool_t TRecorderReplaying::PrepareNextEvent()
{
   // Finds the next event in log file to replay and sets it to fNextEvent
   //
   // Reads both from CmdTree and GuiTree and chooses that event that becomes
   // earlier
   // - fCmdTreeCounter determines actual position in fCmdTree
   // - fGuiTreeCounter determines actual position in fCmdTree
   //
   // If GUI event should be replayed, we must first make sure that there is
   // appropriate mapping for this event
   //
   //  RETURN VALUE:
   //  kFALSE = there is no event to be replayed
   //  kTRUE  = there is still at least one event to be replayed. Cases:
   //             - fNextEvent  = 0 => We are waiting for the appropriate
   //                                  window to be registered
   //             - fNextEvent != 0 => fNextEvent can be replayed (windows are
   //                                  ready)

   fCmdEvent   =  0;
   fGuiEvent   =  0;
   fExtraEvent =  0;
   fNextEvent  =  0;

   // Reads the next unreplayed commandline event to fCmdEvent
   if (fCmdTree->GetEntries() > fCmdTreeCounter)
      fCmdTree->GetEntry(fCmdTreeCounter);

   // Reads the next unreplayed extra event to fExtraEvent
   if (fExtraTree->GetEntries() > fExtraTreeCounter)
      fExtraTree->GetEntry(fExtraTreeCounter);

   // Reads the next unreplayed GUI event to fGuiEvent
   // Skips GUI events that should not be replayed (FilterEvent call)
   while (fGuiTree->GetEntries() > fGuiTreeCounter) {
      fGuiTree->GetEntry(fGuiTreeCounter);
      if (!fGuiEvent || !FilterEvent(fGuiEvent))
         break;
      fGuiTreeCounter++;
   }

   // Chooses which one will be fNextEvent (the next event to be replayed)
   if (fCmdEvent && fGuiEvent && fExtraEvent) {
      // If there are all uf them, compares their times and chooses the
      // earlier one
      if ((fCmdEvent->GetTime() <= fGuiEvent->GetTime()) &&
          (fCmdEvent->GetTime() <= fExtraEvent->GetTime()))
         fNextEvent = fCmdEvent;
      else {
         if (fGuiEvent->GetTime() <= fExtraEvent->GetTime())
            fNextEvent = fGuiEvent;
         else
            fNextEvent = fExtraEvent;
      }
   }
   else if (fCmdEvent && fGuiEvent) {
      // If there are both of them, compares their times and chooses the
      // earlier one
      if (fCmdEvent->GetTime() <= fGuiEvent->GetTime())
         fNextEvent = fCmdEvent;
      else
         fNextEvent = fGuiEvent;
   }
   else if (fCmdEvent && fExtraEvent ) {
      // If there are both of them, compares their times and chooses the
      // earlier one
      if (fCmdEvent->GetTime() <= fExtraEvent->GetTime())
         fNextEvent = fCmdEvent;
      else
         fNextEvent = fExtraEvent;
   }
   else if (fGuiEvent && fExtraEvent) {
      // If there are both of them, compares their times and chooses the
      // earlier one
      if (fExtraEvent->GetTime() <= fGuiEvent->GetTime())
         fNextEvent = fExtraEvent;
      else
         fNextEvent = fGuiEvent;
   }

   // Nor commandline neither event to replay
   else if (!fCmdEvent && !fGuiEvent && !fExtraEvent)
      fNextEvent = 0;
   // Only GUI event to replay
   else if (fGuiEvent)
      fNextEvent = fGuiEvent;
   // Only commandline event to replay
   else if (fCmdEvent)
      fNextEvent = fCmdEvent;
   else
      fNextEvent = fExtraEvent;

   // Nothing to replay
   if (fNextEvent == 0)
      return kFALSE;

   // Commandline event to replay
   if (fNextEvent == fCmdEvent)
      fCmdTreeCounter++;

   // Extra event to replay
   if (fNextEvent == fExtraEvent)
      fExtraTreeCounter++;

   // GUI event to replay
   if (fNextEvent == fGuiEvent) {
      // We have the new window to send this event to
      if (RemapWindowReferences())
         fGuiTreeCounter++;
      // We do not have it yet (waiting for registraion)
      else
         fNextEvent = 0;
   }
   return kTRUE;
}

//______________________________________________________________________________
Bool_t TRecorderReplaying::CanOverlap()
{
   // ButtonPress and ButtonRelease must be sometimes replayed more times
   // Example: pressing of a button opens small window and user chooses
   // something from that window (color)
   // Window must be opened while user is choosing

   if (!fGuiEvent) {
      Error("TRecorderReplaying::CanOverlap()", "fGuiEvent = 0");
      return kFALSE;
   }

   // only GUI events overlapping is allowed
   if (fNextEvent->GetType() != TRecEvent::kGuiEvent)
      return kFALSE;


   if (gDebug > 0) {
      std::cout << "Event overlapping " <<
              kRecEventNames[((TRecGuiEvent*)fNextEvent)->fType] << std::endl;
      TRecorderInactive::DumpRootEvent(((TRecGuiEvent*)fNextEvent), 0);
   }

   // GUI event
   TRecGuiEvent *e  = (TRecGuiEvent*) fNextEvent;

   // Overlapping allowed for ButtonPress, ButtonRelease and MotionNotify
   if (e->fType == kButtonPress || e->fType == kButtonRelease ||
       e->fType == kMotionNotify)
      return kTRUE;

   return kFALSE;
}

//______________________________________________________________________________
void TRecorderReplaying::ReplayRealtime()
{
   // Replays the next event.
   //
   // It is called when fTimer times out.
   // Every time fTimer is set again to time equal to time difference between
   // current two events being replayed.
   //
   // It can happen that execution of an event lasts different time during the
   // recording and during the replaying.
   // If fTimer times out too early and the previous event has not been yet
   // replayed, it is usually postponed in order
   // to keep events execution in the right order.
   // The excpetions are determined by TRecorderReplaying::CanOverlap()
   //

   UInt_t keysym;
   char str[2];

   if ((gROOT->GetEditorMode() == kText) ||
       (gROOT->GetEditorMode() == kPaveLabel)){
      gROOT->SetEditorMode();
   }

   // If there are automatically generated ROOT events in the queue, they
   // are let to be handled first
   if (gVirtualX->EventsPending()) {
      gSystem->ProcessEvents();
      return;
   }

   // Previous event has not been replayed yet and it is not allowed for
   // this event to be replayed more times
   if (!fEventReplayed && !CanOverlap())
      return;

   // Event to replay prepared
   if (fNextEvent) {
      // Sets that fNextEvent has not been replayed yet
      fEventReplayed = 0;

      // Remembers its execution time to compute time difference with
      // the next event
      fPreviousEventTime = fNextEvent->GetTime();

      // Special execution of events causing potential deadlocks
      if (fNextEvent->GetType() == TRecEvent::kGuiEvent) {
         TRecGuiEvent *ev = (TRecGuiEvent *)fNextEvent;
         if (ev->fType == kGKeyPress && ev->fState & kKeyControlMask) {
            Event_t *e = ev->CreateEvent(ev);
            gVirtualX->LookupString(e, str, sizeof(str), keysym);
            // catch the ctrl-s event
            if ((keysym & ~0x20) == kKey_S) {
               fEventReplayed = 1;
               PrepareNextEvent();
               ev->ReplayEvent(fShowMouseCursor);
               return;
            }
         }
      }

      // REPLAYS CURRENT EVENT
      fNextEvent->ReplayEvent(fShowMouseCursor);

      // Sets that fNextEvent has been replayed
      fEventReplayed = 1;
   }

   // Prepares new event for replaying
   if (!PrepareNextEvent()) {
      // No more events to be replayed (replaying has finished).

      // Switches recorder back to INACTIVE state
      Info("TRecorderReplaying::ReplayRealtime", "Replaying finished");
      fRecorder->ChangeState(new TRecorderInactive());
      return;
   }
   else {
      // We have event to replay here.

      // It will be replayed with the same time difference to the previous
      // one as when recording.
      // After given time, timer will call this method again
      if (fNextEvent)
         fTimer->Start(Long_t(fNextEvent->GetTime() - fPreviousEventTime));
   }
}

//______________________________________________________________________________
void TRecorderReplaying::Pause(TRecorder *r)
{
   // Pauses replaying

   fTimer->Stop();
   r->ChangeState(new TRecorderPaused(this), kFALSE);
   Info("TRecorderReplaying::Pause", "Replaying paused.");
}

//______________________________________________________________________________
void TRecorderReplaying::ReplayStop(TRecorder *r)
{
   // Cancels replaying

   Info("TRecorderReplaying::ReplayStop", "Replaying cancelled");
   r->ChangeState(new TRecorderInactive());
}

//______________________________________________________________________________
void TRecorderReplaying::Continue()
{
   // Continues previously paused replaying

   if (fNextEvent)
      fTimer->Start(Long_t(fNextEvent->GetTime() - fPreviousEventTime));
}

//______________________________________________________________________________
// Represents state of TRecorder after its creation

ClassImp(TRecorderInactive)

//______________________________________________________________________________
void TRecorderInactive::Start(TRecorder *r, const char *filename,
                              Option_t *option, Window_t *w, Int_t winCount)
{
   // Switches from INACTIVE state to RECORDING and starts recording

   // const char *filename = name of ROOT file where to store recorded events
   // Option_t *option     = option for creation of ROOT file
   // Window_t *w          = list of IDs of recorder windows (if GUI for
   //                        recorder is used) [0 by default]
   // Int_t winCount       = number of IDs it this list [0 by default]

   TRecorderRecording *rec = new TRecorderRecording(r, filename, option, w, winCount);
   if (rec->StartRecording()) {
      r->ChangeState(rec);
      r->fFilename = gSystem->BaseName(filename);
   }
   else
      delete rec;
}

//______________________________________________________________________________
Bool_t TRecorderInactive::Replay(TRecorder *r, const char *filename,
                                 Bool_t showMouseCursor,
                                 TRecorder::EReplayModes mode)
{
   // Switches from INACTIVE state of recorder to REPLAYING
   // Return kTRUE if replaying has started or kFALSE if it is not possible
   // (bad file etc.)

   // const char *filename = name of ROOT file from where to replay recorded
   // events
   // TRecorder::EReplayModes mode     = mode of replaying

   TRecorderReplaying *replay = new TRecorderReplaying(filename);

   if (replay->Initialize(r, showMouseCursor, mode)) {
      r->ChangeState(replay);
      r->fFilename = gSystem->BaseName(filename);
      return kTRUE;
   }
   else {
      delete replay;
      return kFALSE;
   }
}

//______________________________________________________________________________
void TRecorderInactive::ListCmd(const char *filename)
{
   // Prints out commandline events recorded in given file

   /*
   if (!TClassTable::GetDict(" TRecCmdEvent")) {
      Error("TRecorderInactive::List", " TRecCmdEvent not in dictionary.");
      return;
   }*/

   TFile *file = TFile::Open(filename);
   if (!file) return;
   if (file->IsZombie() || !file->IsOpen()) {
      delete file;
      return;
   }
   TTree *t1 = (TTree*)file->Get(kCmdEventTree);

   if (!t1) {
      Error("TRecorderInactive::List",
            "The ROOT file is not valid event logfile.");
      delete file;
      return;
   }

   TRecCmdEvent *fCmdEvent = new  TRecCmdEvent();
   t1->SetBranchAddress(kBranchName, &fCmdEvent);

   Int_t entries = t1->GetEntries();
   for (Int_t i = 0; i < entries; ++i) {
      t1->GetEntry(i);
      std::cout << "[" << i << "] " << "fTime=" <<
             (ULong64_t) fCmdEvent->GetTime() << " fText=" <<
             fCmdEvent->GetText() << std::endl;
   }
   std::cout << std::endl;

   delete fCmdEvent;
   delete file;
}

//______________________________________________________________________________
void TRecorderInactive::ListGui(const char *filename)
{
   // Prints out GUI events recorded in given file

   /*
   if (!TClassTable::GetDict("TRecGuiEvent")) {
      Error("TRecorderInactive::ListGui",
            "TRecGuiEvent not in the dictionary.");
      return;
   }*/

   TFile *file = TFile::Open(filename);
   if (!file) return;
   if (file->IsZombie() || !file->IsOpen()) {
      delete file;
      return;
   }
   TTree *t1 = (TTree*)file->Get(kGuiEventTree);

   if (!t1) {
      Error("TRecorderInactive::ListGui",
            "The ROOT file is not valid event logfile.");
      delete file;
      return;
   }

   TRecGuiEvent *guiEvent = new TRecGuiEvent();
   t1->SetBranchAddress(kBranchName, &guiEvent);

   Int_t entries = t1->GetEntries();

   for (Int_t i = 0; i < entries ; ++i) {
      t1->GetEntry(i);
      DumpRootEvent(guiEvent, i);
   }

   delete file;
   delete guiEvent;
}

//______________________________________________________________________________
void TRecorderInactive::DumpRootEvent(TRecGuiEvent *e, Int_t n)
{
   // Prints out attributes of one GUI event TRecGuiEvent *e
   // Int_n n is number of event if called in cycle

   std::ios::fmtflags f = std::cout.flags(); // store flags
   std::cout << "[" << n << "] " << std::dec <<  std::setw(10)
      << e->GetTime().AsString() << std::setw(15) << kRecEventNames[e->fType]
      << " fW:"   << std::hex << e->fWindow
      << " t:"    << std::dec << e->fTime
      << " x:"    << DisplayValid(e->fX)
      << " y:"    << DisplayValid(e->fY)
      << " fXR:"  << DisplayValid(e->fXRoot)
      << " fYR:"  << DisplayValid(e->fYRoot)
      << " c:"    << DisplayValid(e->fCode)
      << " s:"    << DisplayValid(e->fState)
      << " w:"    << DisplayValid(e->fWidth)
      << " h:"    << DisplayValid(e->fHeight)
      << " cnt:"  << DisplayValid(e->fCount)
      << " se:"   << e->fSendEvent
      << " h:"    << e->fHandle
      << " fF:"   << DisplayValid(e->fFormat)
      << " | ";

   for (Int_t i=0; i<5; ++i)
      if (DisplayValid(e->fUser[i]) != -1)
         std::cout << "[" << i << "]=" << DisplayValid(e->fUser[i]);

   if (e->fMasked)
      std::cout << " | fM:" << std::hex << e->fMasked;

   std::cout << std::endl;
   std::cout.flags( f ); // restore flags (reset std::hex)
}

//______________________________________________________________________________
void TRecorderInactive::PrevCanvases(const char *filename, Option_t *option)
{
   // Save previous canvases in a .root file

   fCollect = gROOT->GetListOfCanvases();
   TFile *f = TFile::Open(filename, option);
   if (f && !f->IsZombie()) {
      fCollect->Write();
      f->Close();
      delete f;
   }
}

//______________________________________________________________________________
// Represents state of TRecorder when paused

   ClassImp(TRecorderPaused)

//______________________________________________________________________________
TRecorderPaused::TRecorderPaused(TRecorderReplaying *state)
{
   // Rememeber the recorder state that is paused

   fReplayingState = state;
}

//______________________________________________________________________________
void TRecorderPaused::Resume(TRecorder *r)
{
   // Continues replaying

   fReplayingState->Continue();
   Info("TRecorderPaused::Resume", "Replaying resumed");

   // Switches back to the previous replaying state
   r->ChangeState(fReplayingState);
}

//______________________________________________________________________________
void TRecorderPaused::ReplayStop(TRecorder *r)
{
   // Replaying is cancelled

   delete fReplayingState;

   Info("TRecorderReplaying::ReplayStop", "Reaplying cancelled");
   r->ChangeState(new TRecorderInactive());
}


//______________________________________________________________________________
// Represents state of TRecorder when recording events

ClassImp(TRecorderRecording)

//______________________________________________________________________________
TRecorderRecording::TRecorderRecording(TRecorder *r, const char *filename,
                                       Option_t *option, Window_t *w,
                                       Int_t winCount)
{
   // Initializes TRecorderRecording for recording
   // What is allocated here is deleted in destructor

   fRecorder = r;

   // Remember window IDs of GUI recorder (appropriate events are
   // filtered = not recorded)
   fFilteredIdsCount = winCount;
   fFilteredIds = new Window_t[fFilteredIdsCount];
   for(Int_t i=0; i < fFilteredIdsCount; ++i)
      fFilteredIds[i] = w[i];

   // No unhandled commandline event in the beginning
   fCmdEventPending = kFALSE;

   // Filer pave events (mouse button move)
   fFilterEventPave = kFALSE;

   // No registered windows in the beginning
   fRegWinCounter = 0;

   // New timer for recording
   fTimer      = new TTimer(25, kTRUE);

   fMouseTimer = new TTimer(50, kTRUE);
   fMouseTimer->Connect("Timeout()", "TRecorderRecording", this,
                        "RecordMousePosition()");

   // File where store recorded events
   fFile       = TFile::Open(filename, option);

   // TTrees with windows, commandline events and GUi events
   fWinTree   = new TTree(kWindowsTree,    "Windows");
   fCmdTree   = new TTree(kCmdEventTree,   "Commandline events");
   fGuiTree   = new TTree(kGuiEventTree,   "GUI events");
   fExtraTree = new TTree(kExtraEventTree, "Extra events");

   fWin        = 0;
   fCmdEvent   = new TRecCmdEvent();
   fGuiEvent   = new TRecGuiEvent();
   fExtraEvent = new TRecExtraEvent();
}

//______________________________________________________________________________
TRecorderRecording::~TRecorderRecording()
{
   // Freeing of allocated memory

   delete[] fFilteredIds;

   if (fFile)
      delete fFile;
   delete fMouseTimer;
   delete fTimer;
   delete fCmdEvent;
   delete fGuiEvent;
   delete fExtraEvent;
}

//______________________________________________________________________________
Bool_t TRecorderRecording::StartRecording()
{
   // Connects appropriate signals and slots in order to gain all registered
   // windows and processed events in ROOT and then starts recording

   if (!fFile || fFile->IsZombie() || !fFile->IsOpen())
      return kFALSE;

   // When user types something in the commandline,
   // TRecorderRecording::RecordCmdEvent(const char *line) is called
   gApplication->Connect("LineProcessed(const char*)", "TRecorderRecording",
                         this, "RecordCmdEvent(const char*)");

   // When a new window in ROOT is registered,
   // TRecorderRecording::RegisterWindow(Window_t) is called
   gClient->Connect("RegisteredWindow(Window_t)", "TRecorderRecording", this,
                    "RegisterWindow(Window_t)");

   // When a GUI event (different from kConfigureNotify) is processed in
   // TGClient::HandleEvent or in TGClient::HandleMaskEvent,
   // TRecorderRecording::RecordGuiEvent(Event_t*, Window_t) is called
   gClient->Connect("ProcessedEvent(Event_t*, Window_t)", "TRecorderRecording",
                    this, "RecordGuiEvent(Event_t*, Window_t)");

   // When a kConfigureNotify event is processed in TGFrame::HandleEvent,
   // TRecorderRecording::RecordGuiCNEvent(Event_t*) is called
   TQObject::Connect("TGFrame", "ProcessedConfigure(Event_t*)",
                     "TRecorderRecording", this, "RecordGuiCNEvent(Event_t*)");

   // When a PaveLabel is created, TRecorderRecording::RecordPave(TObject*)
   // is called
   TQObject::Connect("TPad", "RecordPave(const TObject*)", "TRecorderRecording",
                     this, "RecordPave(const TObject*)");

   // When a Text is created, TRecorderRecording::RecordText() is called
   TQObject::Connect("TPad", "RecordLatex(const TObject*)",
                     "TRecorderRecording", this, "RecordText(const TObject*)");

   // When a PaveLabel is created, TRecorderRecording::FilterEventPave()
   // is called to filter mouse clicks events.
   TQObject::Connect("TPad", "EventPave()", "TRecorderRecording", this,
                     "FilterEventPave()");

   // When starting editing a TLatex or a TPaveLabel, StartEditing()
   // is called to memorize edition starting time.
   TQObject::Connect("TPad", "StartEditing()", "TRecorderRecording", this,
                     "StartEditing()");

   // Gui Builder specific events.
   TQObject::Connect("TGuiBldDragManager", "TimerEvent(Event_t*)",
                     "TRecorderRecording", this, "RecordGuiBldEvent(Event_t*)");

   // Creates in TTrees appropriate branches to store registered windows,
   // commandline events and GUI events
   fWinTree->Branch(kBranchName, &fWin, "fWin/l");
   fCmdTree->Branch(kBranchName, " TRecCmdEvent", &fCmdEvent);
   fGuiTree->Branch(kBranchName, "TRecGuiEvent", &fGuiEvent);
   fExtraTree->Branch(kBranchName, "TRecExtraEvent", &fExtraEvent);

   Int_t numCanvases = gROOT->GetListOfCanvases()->LastIndex();

   if (numCanvases >= 0){

      TIter nextwindow (gClient->GetListOfWindows());
      TGWindow *twin;
      Window_t  twin2;
      Int_t cnt = 0;
      while ((twin = (TGWindow*) nextwindow())) {
         twin2 = (Window_t) twin->GetId();
         if (IsFiltered(twin2)) {
            if (gDebug > 0) {
               std::cout << "WindowID "<< twin2 << " filtered" << std::endl;
            }
         }
         else if (twin != gClient->GetRoot()) {
            RegisterWindow(twin2);
         }
         cnt++;
      }
      //Info("TRecorderRecording::StartRecording", "Previous Canvases");
   }

   // Starts the timer for recording
   fTimer->TurnOn();

   // start mouse events recording timer
   fMouseTimer->Start(50);

   Info("TRecorderRecording::StartRecording", "Recording started. Log file: %s",
        fFile->GetName());

   return kTRUE;
}

//______________________________________________________________________________
void TRecorderRecording::Stop(TRecorder *, Bool_t guiCommand)
{
   // Disconnects all slots and stopps recording.

   TQObject::Disconnect("TGuiBldDragManager", "TimerEvent(Event_t*)", this,
                        "RecordGuiBldEvent(Event_t*)");
   TQObject::Disconnect("TGFrame", "ProcessedConfigure(Event_t*)", this,
                        "RecordGuiCNEvent(Event_t*)");
   TQObject::Disconnect("TPad", "RecordPave(const TObject*)", this,
                        "RecordPave(const TObject*)");
   TQObject::Disconnect("TPad", "RecordLatex(const TObject*)", this,
                        "RecordText(const TObject*)");
   TQObject::Disconnect("TPad", "EventPave()", this, "FilterEventPave()");
   TQObject::Disconnect("TPad", "StartEditing()", this, "StartEditing()");
   gClient->Disconnect(gClient, "ProcessedEvent(Event_t*, Window_t)", this,
                       "RecordGuiEvent(Event_t*, Window_t)");
   gClient->Disconnect(gClient, "RegisteredWindow(Window_t)", this,
                       "RegisterWindow(Window_t)");
   gApplication->Disconnect(gApplication, "LineProcessed(const char*)", this,
                            "RecordCmdEvent(const char*)");

   // Decides if to store the last event. It is stored if GUI recorder is used,
   // otherwise it is 'TEventRecorded::Stop' and should not be stored
   if (fCmdEventPending && guiCommand)
      fCmdTree->Fill();

   fRecorder->Write("recorder");
   fFile->Write();
   fFile->Close();
   fTimer->TurnOff();

   fMouseTimer->TurnOff();

   Info("TRecorderRecording::Stop", "Recording finished.");

   fRecorder->ChangeState(new TRecorderInactive());
}

//______________________________________________________________________________
void TRecorderRecording::RegisterWindow(Window_t w)
{
   // This method is called when RegisteredWindow(Window_t) is emitted from
   // TGClient.

   // Stores ID of the registered window in appropriate TTree
   fWin = (ULong64_t) w;
   fWinTree->Fill();
}

//______________________________________________________________________________
void TRecorderRecording::RecordCmdEvent(const char *line)
{
   // Records commandline event (text and time) ans saves the previous
   // commandline event
   // This 1 event delay in saving ensures that the last commandline events
   // 'TRecorder::Stop' will be not stored

   // If there is some previously recorded event, saves it in TTree now
   if (fCmdEventPending)
      fCmdTree->Fill();

   // Fill information about this new commandline event: command text and
   // time of event execution
   fCmdEvent->SetTime(fTimer->GetAbsTime());
   fCmdEvent->SetText((char*)line);

   // This event will be stored next time (if it is not the last one
   // 'TRecorder::Stop')
   fCmdEventPending = kTRUE;
   return;
}

//______________________________________________________________________________
void TRecorderRecording::RecordGuiEvent(Event_t *e, Window_t wid)
{
   // Records GUI Event_t *e different from kConfigureNotify (they are
   // recorded in TRecorderRecording::RecordGuiCNEvent)
   //
   // It is called via signal-slot when an event is processed in
   // TGClient::HandleEvent(Event_t *event)
   // or in TGClient::HandleMaskEvent(Event_t *event, Window_t wid)
   //
   // If signal is emitted from TGClient::HandleEvent(Event_t *event),
   // then wid = 0

   // If this event is caused by a recorder itself (GUI recorder),
   // it is not recorded
   if (fFilteredIdsCount && IsFiltered(e->fWindow))
      return;

   // Doesn't record the mouse clicks when a pavelabel is recorded
   if  (fFilterEventPave && (e->fCode == 1)) {
      fFilterEventPave = kFALSE;
      return;
   }
   fFilterEventPave = kFALSE;

   // don't record any copy/paste event, as event->fUser[x] parameters
   // will be invalid when replaying on a different OS
   if (e->fType == kSelectionClear || e->fType == kSelectionRequest ||
       e->fType == kSelectionNotify)
      return;

   // Copies all items of e to fGuiEvent
   CopyEvent(e, wid);

   // Saves time of recording
   fGuiEvent->SetTime(fTimer->GetAbsTime());

   // Saves recorded event itself in TTree
   fGuiTree->Fill();
}

//______________________________________________________________________________
void TRecorderRecording::RecordGuiBldEvent(Event_t *e)
{
   // Special case for the gui builder, having a timer handling some of the
   // events.

   e->fFormat = e->fType;
   e->fType = kOtherEvent;

   // Copies all items of e to fGuiEvent
   CopyEvent(e, 0);

   // Saves time of recording
   fGuiEvent->SetTime(fTimer->GetAbsTime());

   // Saves recorded event itself in TTree
   fGuiTree->Fill();
}

//______________________________________________________________________________
void TRecorderRecording::RecordMousePosition()
{
   // Try to record all mouse moves...

   Window_t dum;
   Event_t ev;
   ev.fCode = 0;
   ev.fType = kMotionNotify;
   ev.fState = 0;
   ev.fWindow = 0;
   ev.fUser[0] = ev.fUser[1] = ev.fUser[2] = ev.fUser[3] = ev.fUser[4] = 0;
   ev.fCount = 0;
   ev.fFormat = 0;
   ev.fHandle = 0;
   ev.fHeight = 0;
   ev.fSendEvent = 0;
   ev.fTime = 0;
   ev.fWidth = 0;

   gVirtualX->QueryPointer(gVirtualX->GetDefaultRootWindow(), dum, dum,
                           ev.fXRoot, ev.fYRoot, ev.fX, ev.fY, ev.fState);
   ev.fXRoot -= gDecorWidth;
   ev.fYRoot -= gDecorHeight;

   RecordGuiEvent(&ev, 0);
   fMouseTimer->Reset();
}

//______________________________________________________________________________
void TRecorderRecording::RecordGuiCNEvent(Event_t *e)
{
   // Records GUI Event_t *e of type kConfigureNotify.
   // It is called via signal-slot when an kConfigureNotify event is processed
   // in TGFrame::HandleEvent

   // If this event is caused by a recorder itself, it is not recorded
   if (fFilteredIdsCount && IsFiltered(e->fWindow))
      return;

   // Sets fUser[4] value to one of EConfigureNotifyType
   // According to this value, event is or is not replayed in the future
   SetTypeOfConfigureNotify(e);

   // Copies all items of e to fGuiEvent
   CopyEvent(e, 0);

   // Saves time of recording
   fGuiEvent->SetTime(fTimer->GetAbsTime());

   // Saves recorded event itself in TTree
   fGuiTree->Fill();
}

//______________________________________________________________________________
void TRecorderRecording::RecordPave(const TObject *obj)
{
   // Records TPaveLabel object created in TCreatePrimitives::Pave()

   Long64_t extratime = fBeginPave;
   Long64_t interval = (Long64_t)fTimer->GetAbsTime() - fBeginPave;
   TPaveLabel *pavel = (TPaveLabel *) obj;
   const char *label;
   label = pavel->GetLabel();
   TString aux = "";
   TString cad = "";
   cad = "TPaveLabel *p = new TPaveLabel(";
   cad += pavel->GetX1();
   cad += ",";
   cad += pavel->GetY1();
   cad += ",";
   cad += pavel->GetX2();
   cad += ",";
   cad += pavel->GetY2();
   cad += ",\"\"); p->Draw(); gPad->Modified(); gPad->Update();";
   Int_t i, len = (Int_t)strlen(label);
   interval /= (len + 2);
   RecordExtraEvent(cad, extratime);
   for (i=0; i < len; ++i) {
      cad = "p->SetLabel(\"";
      cad += (aux += label[i]);
      cad += "\"); ";
#ifndef R__WIN32
      cad += " p->SetTextFont(83); p->SetTextSizePixels(14); ";
#endif
      cad += " gPad->Modified(); gPad->Update();";
      extratime += interval;
      RecordExtraEvent(cad, extratime);
   }
   cad  = "p->SetTextFont(";
   cad += pavel->GetTextFont();
   cad += "); p->SetTextSize(";
   cad += pavel->GetTextSize();
   cad += "); gPad->Modified(); gPad->Update();";
   extratime += interval;
   RecordExtraEvent(cad, extratime);
}

//______________________________________________________________________________
void TRecorderRecording::RecordText(const TObject *obj)
{
   // Records TLatex object created in TCreatePrimitives::Text()

   Long64_t extratime = fBeginPave;
   Long64_t interval = (Long64_t)fTimer->GetAbsTime() - fBeginPave;
   TLatex *texto = (TLatex *) obj;
   const char *label;
   label = texto->GetTitle();
   TString aux = "";
   TString cad = "";
   cad = "TLatex *l = new TLatex(";
   cad += texto->GetX();
   cad += ",";
   cad += texto->GetY();
   cad += ",\"\"); l->Draw(); gPad->Modified(); gPad->Update();";
   Int_t i, len = (Int_t)strlen(label);
   interval /= (len + 2);
   RecordExtraEvent(cad, extratime);
   for (i=0; i < len; ++i) {
      cad = "l->SetTitle(\"";
      cad += (aux += label[i]);
      cad += "\"); ";
#ifndef R__WIN32
      cad += " l->SetTextFont(83); l->SetTextSizePixels(14); ";
#endif
      cad += " gPad->Modified(); gPad->Update();";
      extratime += interval;
      RecordExtraEvent(cad, extratime);
   }
   cad  = "l->SetTextFont(";
   cad += texto->GetTextFont();
   cad += "); l->SetTextSize(";
   cad += texto->GetTextSize();
   cad += "); gPad->Modified(); gPad->Update();";
   cad += " TVirtualPad *spad = gPad->GetCanvas()->GetSelectedPad();";
   cad += " gPad->GetCanvas()->Selected(spad, l, kButton1Down);";
   extratime += interval;
   RecordExtraEvent(cad, extratime);
}

//______________________________________________________________________________
void TRecorderRecording::FilterEventPave()
{
   // Change the state of the flag to kTRUE when you are recording a pavelabel.

   fFilterEventPave = kTRUE;
}

//______________________________________________________________________________
void TRecorderRecording::StartEditing()
{
   // Memorize the starting time of editinga TLatex or a TPaveLabel

   fBeginPave = fTimer->GetAbsTime();
}

//______________________________________________________________________________
void TRecorderRecording::RecordExtraEvent(TString line, TTime extTime)
{
   // Records TLatex or TPaveLabel object created in TCreatePrimitives,
   // ExtTime is needed for the correct replay of these events.

   fExtraEvent->SetTime(extTime);
   fExtraEvent->SetText(line);
   fExtraTree->Fill();
}

//______________________________________________________________________________
void TRecorderRecording::CopyEvent(Event_t *e, Window_t wid)
{
   // Copies all items of given event to fGuiEvent

   fGuiEvent->fType     = e->fType;
   fGuiEvent->fWindow   = e->fWindow;
   fGuiEvent->fTime     = e->fTime;

   fGuiEvent->fX        = e->fX;
   fGuiEvent->fY        = e->fY;
   fGuiEvent->fXRoot    = e->fXRoot;
   fGuiEvent->fYRoot    = e->fYRoot;

   fGuiEvent->fCode     = e->fCode;
   fGuiEvent->fState    = e->fState;

   fGuiEvent->fWidth    = e->fWidth;
   fGuiEvent->fHeight   = e->fHeight;

   fGuiEvent->fCount       = e->fCount;
   fGuiEvent->fSendEvent   = e->fSendEvent;
   fGuiEvent->fHandle      = e->fHandle;
   fGuiEvent->fFormat      = e->fFormat;

   if (fGuiEvent->fHandle == gROOT_MESSAGE)
      fGuiEvent->fHandle = TRecGuiEvent::kROOT_MESSAGE;

   for(Int_t i=0; i<5; ++i)
      fGuiEvent->fUser[i] = e->fUser[i];

   if (fGuiEvent->fUser[0] == (Int_t)gWM_DELETE_WINDOW)
      fGuiEvent->fUser[0] = TRecGuiEvent::kWM_DELETE_WINDOW;

   if (e->fType == kGKeyPress || e->fType == kKeyRelease) {
      char tmp[10] = {0};
      UInt_t keysym = 0;
      gVirtualX->LookupString(e, tmp, sizeof(tmp), keysym);
      fGuiEvent->fCode = keysym;
   }

   fGuiEvent->fMasked  = wid;
}

//______________________________________________________________________________
Bool_t TRecorderRecording::IsFiltered(Window_t id)
{
   // Returns kTRUE if passed id belongs to window IDs of recorder GUI itself

   for(Int_t i=0; i < fFilteredIdsCount; ++i)
      if (id == fFilteredIds[i])
         return kTRUE;

   return kFALSE;
}

//______________________________________________________________________________
void TRecorderRecording::SetTypeOfConfigureNotify(Event_t *e)
{
   // Sets type of kConfigureNotify event to one of EConfigureNotify
   //
   // On Linux paremeters of GUI event kConfigureNotify are different
   // than parameters of the same event executed on Windows.
   // Therefore we need to distinguish [on Linux], if the event is movement
   // or resize event.
   // On Windows, we do not need to distinguish them.

   // On both platforms, we mark the events matching the criteria
   // (automatically generated in ROOT) as events that should be filtered
   // when replaying (TRecGuiEvent::kCNFilter)
   if ((e->fX == 0 && e->fX == 0)) { // || e->fFormat == 32 ) {
      e->fUser[4] = TRecGuiEvent::kCNFilter;
      return;
   }

#ifdef WIN32

   // No need to distinguish between move and resize on Windows
   e->fUser[4] = TRecGuiEvent::kCNMoveResize;

#else

   TGWindow *w = gClient->GetWindowById(e->fWindow);
   if (w) {
      TGFrame *t = (TGFrame *)w;

      // If this event does not cause any change in position or size ->
      // automatically generated event
      if (t->GetWidth() == e->fWidth && t->GetHeight() == e->fHeight &&
          e->fX == t->GetX() && e->fY == t->GetY()) {
         e->fUser[4] = TRecGuiEvent::kCNFilter;
      }
      else {
         // Size of the window did not change -> move
         if (t->GetWidth() == e->fWidth && t->GetHeight() == e->fHeight) {
            e->fUser[4] = TRecGuiEvent::kCNMove;
         }
         // Size of the window changed -> resize
         else {
            e->fUser[4] = TRecGuiEvent::kCNResize;
         }
      }
   }

#endif
}



//______________________________________________________________________________
// The GUI for the recorder

ClassImp(TGRecorder)

//______________________________________________________________________________
TGRecorder::TGRecorder(const TGWindow *p, UInt_t w, UInt_t h) :
   TGMainFrame(p ? p : gClient->GetRoot(), w, h)
{
   // The GUI for the recorder

   TGHorizontalFrame *hframe;
   TGVerticalFrame *vframe;
   SetCleanup(kDeepCleanup);
   fRecorder = new TRecorder();
   fFilteredIds[0] = GetId();

   // Create a horizontal frame widget with buttons
   hframe = new TGHorizontalFrame(this, 200, 75, kChildFrame | kFixedHeight,
                                  (Pixel_t)0x000000);
   fFilteredIds[1] = hframe->GetId();

   // LABEL WITH TIME

   vframe = new TGVerticalFrame(hframe, 200, 75, kChildFrame | kFixedHeight,
                                (Pixel_t)0x000000);
   fFilteredIds[2] = vframe->GetId();

   TGLabel *fStatusLabel = new TGLabel(vframe, "Status:");
   fStatusLabel->SetTextColor(0x7cffff);
   fStatusLabel->SetBackgroundColor((Pixel_t)0x000000);
   vframe->AddFrame(fStatusLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,
                                                    2, 2, 2, 2));
   fFilteredIds[3] = fStatusLabel->GetId();

   TGLabel *fTimeLabel = new TGLabel(vframe, "Time: ");
   fTimeLabel->SetTextColor(0x7cffff);
   fTimeLabel->SetBackgroundColor((Pixel_t)0x000000);
   vframe->AddFrame(fTimeLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,
                                                  2, 2, 13, 2));
   fFilteredIds[4] = fTimeLabel->GetId();

   hframe->AddFrame(vframe, new TGLayoutHints(kLHintsLeft | kLHintsExpandY));

   vframe = new TGVerticalFrame(hframe, 200, 75, kChildFrame | kFixedHeight,
                                (Pixel_t)0x000000);
   fFilteredIds[5] = vframe->GetId();

   fStatus = new TGLabel(vframe, "Inactive");
   fStatus->SetTextColor(0x7cffff);
   fStatus->SetBackgroundColor((Pixel_t)0x000000);
   vframe->AddFrame(fStatus, new TGLayoutHints(kLHintsLeft | kLHintsTop,
                                               2, 2, 2, 2));
   fFilteredIds[6] = fStatus->GetId();

   fTimeDisplay = new TGLabel(vframe, "00:00:00");
   fTimeDisplay->SetTextColor(0x7cffff);
   fTimeDisplay->SetTextFont("Helvetica -34", kFALSE);
   fTimeDisplay->SetBackgroundColor((Pixel_t)0x000000);
   vframe->AddFrame(fTimeDisplay, new TGLayoutHints(kLHintsLeft | kLHintsTop,
                                                    2, 2, 2, 2));
   fFilteredIds[7] = fTimeDisplay->GetId();

   hframe->AddFrame(vframe, new TGLayoutHints(kLHintsLeft | kLHintsExpandY,
                                              10, 0, 0, 0));
   AddFrame(hframe, new TGLayoutHints(kLHintsExpandX, 2, 2, 2, 2));

   // Create a horizontal frame widget with buttons
   hframe = new TGHorizontalFrame(this, 200, 200);
   fFilteredIds[8] = hframe->GetId();

   // START-STOP button
   fStartStop = new TGPictureButton(hframe,gClient->GetPicture("record.png"));
   fStartStop->SetStyle(gClient->GetStyle());
   fStartStop->Connect("Clicked()","TGRecorder",this,"StartStop()");
   hframe->AddFrame(fStartStop, new TGLayoutHints(kLHintsLeft | kLHintsTop,
                                                  2, 2, 2, 2));
   fStartStop->Resize(40,40);
   fFilteredIds[9] = fStartStop->GetId();

   // REPLAY button
   fReplay = new TGPictureButton(hframe,gClient->GetPicture("replay.png"));
   fReplay->SetStyle(gClient->GetStyle());
   fReplay->Connect("Clicked()","TGRecorder",this,"Replay()");
   hframe->AddFrame(fReplay, new TGLayoutHints(kLHintsLeft | kLHintsTop,
                                               2, 2, 2, 2));
   fReplay->Resize(40,40);
   fFilteredIds[10] = fReplay->GetId();

   // MOUSE CURSOR CHECKBOX
   fCursorCheckBox = new TGCheckButton(this,"Show mouse cursor");
   AddFrame(fCursorCheckBox, new TGLayoutHints(kLHintsCenterX, 2, 2, 2, 2));
   fFilteredIds[11] = fCursorCheckBox->GetId();

   // Timer
   fTimer = new TTimer(25);
   fTimer->Connect("Timeout()", "TGRecorder", this, "Update()");

   AddFrame(hframe, new TGLayoutHints(kLHintsCenterX, 2, 2, 2, 2));

   SetEditDisabled(kEditDisable | kEditDisableGrab);
   SetWindowName("ROOT Event Recorder");
   MapSubwindows();
   Layout();
   MapWindow();

   SetDefault();
}

//______________________________________________________________________________
void TGRecorder::SetDefault()
{
   // Sets GUI to the default inactive state

   fTimeDisplay->SetText("00:00:00");

   fReplay->SetPicture(gClient->GetPicture("replay.png"));
   fReplay->SetEnabled(kTRUE);

   fCursorCheckBox->SetEnabled(kTRUE);
   fCursorCheckBox->SetOn(kTRUE);

   fStartStop->SetPicture(gClient->GetPicture("record.png"));
   fStartStop->SetEnabled(kTRUE);
}

//______________________________________________________________________________
void TGRecorder::Update()
{
   // Called when fTimer timeouts (every 0.025 second)
   // Updates GUI of recorder

   struct tm *running;
   static int cnt = 0;
   TString stime;
   time( &fElapsed );
   time_t elapsed_time = (time_t)difftime( fElapsed, fStart );
   running = gmtime( &elapsed_time );

   switch(fRecorder->GetState()) {

      // When recording or replaying, updates timer
      // and displays new value of seconds counter
      case TRecorder::kRecording:
      case TRecorder::kReplaying:

         // Every whole second: updates timer and displays new value
         if (cnt >= 10) {
            if (fRecorder->GetState() == TRecorder::kReplaying)
               fStatus->SetText("Replaying");
            else
               fStatus->SetText("Recording");
            stime.Form("%02d:%02d:%02d", running->tm_hour,
                        running->tm_min, running->tm_sec);
            fTimeDisplay->SetText(stime.Data());

            cnt = 0;
            if (gVirtualX->EventsPending()) {
               fStatus->SetText("Waiting...");
               fStatus->SetTextColor((Pixel_t)0xff0000);
            }
            else {
               fStatus->SetTextColor((Pixel_t)0x7cffff);
            }
            fStatus->Resize();
            fTimeDisplay->Resize();
         }
         else
            ++cnt;

         // Changes background color according to the queue of pending events
         fTimer->Reset();
         break;

      // End of replaying or recording. Sets recorder GUI to default state
      case TRecorder::kInactive:
         fStatus->SetText("Inactive");
         fStatus->SetTextColor((Pixel_t)0x7cffff);
         fStatus->Resize();
         fTimer->TurnOff();
         SetDefault();
         break;

      default:
         break;
   }
}

//______________________________________________________________________________
void TGRecorder::StartStop()
{
   // Handles push of the fStartStop button
   // according to the current recorder state

   static const char *gFiletypes[] = {
      "All files", "*", "Text files", "*.txt", "ROOT files", "*.root", 0, 0
   };
   TGFileInfo fi;

   switch(fRecorder->GetState()) {

      // Starts recording
      case TRecorder::kInactive:

         fi.fFileTypes = gFiletypes;
         fi.fOverwrite = kFALSE;

         new TGFileDialog(gClient->GetDefaultRoot(),
                          gClient->GetDefaultRoot(),
                          kFDSave,&fi);

         if (fi.fFilename && strlen(fi.fFilename)) {

            if (!gROOT->GetListOfCanvases()->IsEmpty()) {
               fRecorder->PrevCanvases(fi.fFilename, "RECREATE");
               fRecorder->Start(fi.fFilename, "UPDATE", fFilteredIds,
                                fgWidgetsCount);
            }
            else {
               fRecorder->Start(fi.fFilename, "RECREATE", fFilteredIds,
                                fgWidgetsCount);
            }
            fCursorCheckBox->SetDisabledAndSelected(kTRUE);
            fStartStop->SetPicture(gClient->GetPicture("stop.png"));
            fReplay->SetEnabled(kFALSE);
            fTimer->TurnOn();
            time( &fStart );
         }
         break;

      // Stops recording
      case TRecorder::kRecording:
         fRecorder->Stop(kTRUE);
         break;

      // Pauses replaying
      case TRecorder::kReplaying:
         fRecorder->Pause();
         fStartStop->SetPicture(gClient->GetPicture("replay.png"));
         break;

      // Resumes replaying
      case TRecorder::kPaused:
         fRecorder->Resume();
         fStartStop->SetPicture(gClient->GetPicture("pause.png"));
         break;

      default:
         break;
   } // switch
}

//______________________________________________________________________________
void TGRecorder::Replay()
{
   // Handles push of fReplay button
   // according to the current recorder state

   TGFileInfo fi;

   switch(fRecorder->GetState()) {

      // Starts replaying
      case TRecorder::kInactive:

         new TGFileDialog(gClient->GetDefaultRoot(),
                          gClient->GetDefaultRoot(),
                          kFDOpen, &fi);

         if (fi.fFilename && strlen(fi.fFilename)) {
            if (fRecorder->Replay(fi.fFilename, fCursorCheckBox->IsOn())) {

               fTimer->TurnOn();
               time( &fStart );

               fReplay->SetPicture(gClient->GetPicture("stop.png"));
               fStartStop->SetPicture(gClient->GetPicture("pause.png"));

               if (fCursorCheckBox->IsOn())
                  fStartStop->SetEnabled(kFALSE);

               fCursorCheckBox->SetEnabled(kFALSE);
            }
         }
         break;

      // Stops replaying
      case TRecorder::kReplaying:
      case TRecorder::kPaused:
         fRecorder->ReplayStop();
         break;

      default:
         break;

   } // switch
}

//______________________________________________________________________________
TGRecorder::~TGRecorder()
{
   // Destructor. Cleanup the GUI.

   fTimer->TurnOff();
   delete fTimer;
   Cleanup();
}

//______________________________________________________________________________
// Helper class

ClassImp(TRecCmdEvent)
ClassImp(TRecGuiEvent)

//______________________________________________________________________________
void TRecGuiEvent::ReplayEvent(Bool_t showMouseCursor)
{
   // Replays stored GUI event

   Int_t    px, py, dx, dy;
   Window_t wtarget;
   Event_t *e = CreateEvent(this);

   // don't try to replay any copy/paste event, as event->fUser[x]
   // parameters are invalid on different OSes
   if (e->fType == kSelectionClear || e->fType == kSelectionRequest ||
       e->fType == kSelectionNotify) {
      delete e;
      return;
   }

   // Replays movement/resize event
   if (e->fType == kConfigureNotify) {
      TGWindow *w = gClient->GetWindowById(e->fWindow);

      // Theoretically, w should always exist (we found the right mapping,
      // otherwise we would not get here).
      // Anyway, it can happen that it was destroyed by some earlier ROOT event
      // We give higher priority to automatically generated
      // ROOT events in TRecorderReplaying::ReplayRealtime.

      if (w) {
         WindowAttributes_t attr;
         if (e->fUser[4] == TRecGuiEvent::kCNMove) {
            // Linux: movement of the window
            // first get window attribute to compensate the border size
            gVirtualX->GetWindowAttributes(e->fWindow, attr);
            if ((e->fX - attr.fX > 0) && (e->fY - attr.fY > 0))
               w->Move(e->fX - attr.fX, e->fY - attr.fY);
         }
         else {
            if (e->fUser[4] == TRecGuiEvent::kCNResize) {
               // Linux: resize of the window
               w->Resize(e->fWidth, e->fHeight);
            }
            else {
               if (e->fUser[4] == TRecGuiEvent::kCNMoveResize) {
                  // Windows: movement or resize of the window
                  w->MoveResize(e->fX, e->fY, e->fWidth, e->fHeight);
               }
               else {
                  if (gDebug > 0)
                     Error("TRecGuiEvent::ReplayEvent",
                           "kConfigureNotify: Unknown value: fUser[4] = %ld ",
                           e->fUser[4]);
               }
            }
         }
      }
      else {
         // w = 0
         if (gDebug > 0)
            Error("TRecGuiEvent::ReplayEvent",
                  "kConfigureNotify: Window does not exist anymore ");
      }
      delete e;
      return;

   } // kConfigureNotify

   if (showMouseCursor && e->fType == kButtonPress) {
      gVirtualX->TranslateCoordinates(e->fWindow, gVirtualX->GetDefaultRootWindow(),
                                      e->fX, e->fY, px, py, wtarget);
      dx = px - gCursorWin->GetX();
      dy = py - gCursorWin->GetY();
      if (TMath::Abs(dx) > 5) gDecorWidth += dx;
      if (TMath::Abs(dy) > 5) gDecorHeight += dy;
   }
   // Displays fake mouse cursor for MotionNotify event
   if (showMouseCursor && e->fType == kMotionNotify) {
      if (gCursorWin && e->fWindow == gVirtualX->GetDefaultRootWindow()) {
         if (!gCursorWin->IsMapped()) {
            gCursorWin->MapRaised();
         }
         if (gVirtualX->GetDrawMode() == TVirtualX::kCopy) {
//#ifdef R__MACOSX
            // this may have side effects (e.g. stealing focus)
            gCursorWin->RaiseWindow();
//#endif
            gCursorWin->Move(e->fXRoot + gDecorWidth, e->fYRoot + gDecorHeight);
         }
      }
   }

   // Lets all the other events to be handled the same way as when recording
   // first, special case for the gui builder, having a timer handling
   // some of the events
   if (e->fType == kOtherEvent && e->fFormat >= kGKeyPress &&
       e->fFormat < kOtherEvent) {
      e->fType = (EGEventType)e->fFormat;
      if (gDragManager)
         gDragManager->HandleTimerEvent(e, 0);
      delete e;
      return;
   }
   else { // then the normal cases
      if (!fMasked)
         gClient->HandleEvent(e);
      else
         gClient->HandleMaskEvent(e, fMasked);
   }
   delete e;
}

//______________________________________________________________________________
Event_t *TRecGuiEvent::CreateEvent(TRecGuiEvent *ge)
{
   // Converts TRecGuiEvent type to Event_t type

   Event_t *e = new Event_t();

   // Copies all data items

   e->fType   = ge->fType;
   e->fWindow = ge->fWindow;
   e->fTime   = ge->fTime;

   e->fX = ge->fX;
   e->fY = ge->fY;
   e->fXRoot = ge->fXRoot;
   e->fYRoot = ge->fYRoot;

   e->fCode   = ge->fCode;
   e->fState  = ge->fState;

   e->fWidth  = ge->fWidth;
   e->fHeight = ge->fHeight;

   e->fCount  = ge->fCount;
   e->fSendEvent = ge->fSendEvent;

   e->fHandle = ge->fHandle;
   e->fFormat = ge->fFormat;

   if (e->fHandle == TRecGuiEvent::kROOT_MESSAGE)
      e->fHandle = gROOT_MESSAGE;

   for(Int_t i=0; i<5; ++i)
      e->fUser[i] = ge->fUser[i];

   if (e->fUser[0] == TRecGuiEvent::kWM_DELETE_WINDOW)
      e->fUser[0] = gWM_DELETE_WINDOW;

   if (ge->fType == kGKeyPress || ge->fType == kKeyRelease) {
      e->fCode    = gVirtualX->KeysymToKeycode(ge->fCode);
#ifdef R__WIN32
      e->fUser[1] = 1;
      e->fUser[2] = e->fCode;
#endif
   }

   return e;
}

ClassImp(TRecWinPair)
 TRecorder.cxx:1
 TRecorder.cxx:2
 TRecorder.cxx:3
 TRecorder.cxx:4
 TRecorder.cxx:5
 TRecorder.cxx:6
 TRecorder.cxx:7
 TRecorder.cxx:8
 TRecorder.cxx:9
 TRecorder.cxx:10
 TRecorder.cxx:11
 TRecorder.cxx:12
 TRecorder.cxx:13
 TRecorder.cxx:14
 TRecorder.cxx:15
 TRecorder.cxx:16
 TRecorder.cxx:17
 TRecorder.cxx:18
 TRecorder.cxx:19
 TRecorder.cxx:20
 TRecorder.cxx:21
 TRecorder.cxx:22
 TRecorder.cxx:23
 TRecorder.cxx:24
 TRecorder.cxx:25
 TRecorder.cxx:26
 TRecorder.cxx:27
 TRecorder.cxx:28
 TRecorder.cxx:29
 TRecorder.cxx:30
 TRecorder.cxx:31
 TRecorder.cxx:32
 TRecorder.cxx:33
 TRecorder.cxx:34
 TRecorder.cxx:35
 TRecorder.cxx:36
 TRecorder.cxx:37
 TRecorder.cxx:38
 TRecorder.cxx:39
 TRecorder.cxx:40
 TRecorder.cxx:41
 TRecorder.cxx:42
 TRecorder.cxx:43
 TRecorder.cxx:44
 TRecorder.cxx:45
 TRecorder.cxx:46
 TRecorder.cxx:47
 TRecorder.cxx:48
 TRecorder.cxx:49
 TRecorder.cxx:50
 TRecorder.cxx:51
 TRecorder.cxx:52
 TRecorder.cxx:53
 TRecorder.cxx:54
 TRecorder.cxx:55
 TRecorder.cxx:56
 TRecorder.cxx:57
 TRecorder.cxx:58
 TRecorder.cxx:59
 TRecorder.cxx:60
 TRecorder.cxx:61
 TRecorder.cxx:62
 TRecorder.cxx:63
 TRecorder.cxx:64
 TRecorder.cxx:65
 TRecorder.cxx:66
 TRecorder.cxx:67
 TRecorder.cxx:68
 TRecorder.cxx:69
 TRecorder.cxx:70
 TRecorder.cxx:71
 TRecorder.cxx:72
 TRecorder.cxx:73
 TRecorder.cxx:74
 TRecorder.cxx:75
 TRecorder.cxx:76
 TRecorder.cxx:77
 TRecorder.cxx:78
 TRecorder.cxx:79
 TRecorder.cxx:80
 TRecorder.cxx:81
 TRecorder.cxx:82
 TRecorder.cxx:83
 TRecorder.cxx:84
 TRecorder.cxx:85
 TRecorder.cxx:86
 TRecorder.cxx:87
 TRecorder.cxx:88
 TRecorder.cxx:89
 TRecorder.cxx:90
 TRecorder.cxx:91
 TRecorder.cxx:92
 TRecorder.cxx:93
 TRecorder.cxx:94
 TRecorder.cxx:95
 TRecorder.cxx:96
 TRecorder.cxx:97
 TRecorder.cxx:98
 TRecorder.cxx:99
 TRecorder.cxx:100
 TRecorder.cxx:101
 TRecorder.cxx:102
 TRecorder.cxx:103
 TRecorder.cxx:104
 TRecorder.cxx:105
 TRecorder.cxx:106
 TRecorder.cxx:107
 TRecorder.cxx:108
 TRecorder.cxx:109
 TRecorder.cxx:110
 TRecorder.cxx:111
 TRecorder.cxx:112
 TRecorder.cxx:113
 TRecorder.cxx:114
 TRecorder.cxx:115
 TRecorder.cxx:116
 TRecorder.cxx:117
 TRecorder.cxx:118
 TRecorder.cxx:119
 TRecorder.cxx:120
 TRecorder.cxx:121
 TRecorder.cxx:122
 TRecorder.cxx:123
 TRecorder.cxx:124
 TRecorder.cxx:125
 TRecorder.cxx:126
 TRecorder.cxx:127
 TRecorder.cxx:128
 TRecorder.cxx:129
 TRecorder.cxx:130
 TRecorder.cxx:131
 TRecorder.cxx:132
 TRecorder.cxx:133
 TRecorder.cxx:134
 TRecorder.cxx:135
 TRecorder.cxx:136
 TRecorder.cxx:137
 TRecorder.cxx:138
 TRecorder.cxx:139
 TRecorder.cxx:140
 TRecorder.cxx:141
 TRecorder.cxx:142
 TRecorder.cxx:143
 TRecorder.cxx:144
 TRecorder.cxx:145
 TRecorder.cxx:146
 TRecorder.cxx:147
 TRecorder.cxx:148
 TRecorder.cxx:149
 TRecorder.cxx:150
 TRecorder.cxx:151
 TRecorder.cxx:152
 TRecorder.cxx:153
 TRecorder.cxx:154
 TRecorder.cxx:155
 TRecorder.cxx:156
 TRecorder.cxx:157
 TRecorder.cxx:158
 TRecorder.cxx:159
 TRecorder.cxx:160
 TRecorder.cxx:161
 TRecorder.cxx:162
 TRecorder.cxx:163
 TRecorder.cxx:164
 TRecorder.cxx:165
 TRecorder.cxx:166
 TRecorder.cxx:167
 TRecorder.cxx:168
 TRecorder.cxx:169
 TRecorder.cxx:170
 TRecorder.cxx:171
 TRecorder.cxx:172
 TRecorder.cxx:173
 TRecorder.cxx:174
 TRecorder.cxx:175
 TRecorder.cxx:176
 TRecorder.cxx:177
 TRecorder.cxx:178
 TRecorder.cxx:179
 TRecorder.cxx:180
 TRecorder.cxx:181
 TRecorder.cxx:182
 TRecorder.cxx:183
 TRecorder.cxx:184
 TRecorder.cxx:185
 TRecorder.cxx:186
 TRecorder.cxx:187
 TRecorder.cxx:188
 TRecorder.cxx:189
 TRecorder.cxx:190
 TRecorder.cxx:191
 TRecorder.cxx:192
 TRecorder.cxx:193
 TRecorder.cxx:194
 TRecorder.cxx:195
 TRecorder.cxx:196
 TRecorder.cxx:197
 TRecorder.cxx:198
 TRecorder.cxx:199
 TRecorder.cxx:200
 TRecorder.cxx:201
 TRecorder.cxx:202
 TRecorder.cxx:203
 TRecorder.cxx:204
 TRecorder.cxx:205
 TRecorder.cxx:206
 TRecorder.cxx:207
 TRecorder.cxx:208
 TRecorder.cxx:209
 TRecorder.cxx:210
 TRecorder.cxx:211
 TRecorder.cxx:212
 TRecorder.cxx:213
 TRecorder.cxx:214
 TRecorder.cxx:215
 TRecorder.cxx:216
 TRecorder.cxx:217
 TRecorder.cxx:218
 TRecorder.cxx:219
 TRecorder.cxx:220
 TRecorder.cxx:221
 TRecorder.cxx:222
 TRecorder.cxx:223
 TRecorder.cxx:224
 TRecorder.cxx:225
 TRecorder.cxx:226
 TRecorder.cxx:227
 TRecorder.cxx:228
 TRecorder.cxx:229
 TRecorder.cxx:230
 TRecorder.cxx:231
 TRecorder.cxx:232
 TRecorder.cxx:233
 TRecorder.cxx:234
 TRecorder.cxx:235
 TRecorder.cxx:236
 TRecorder.cxx:237
 TRecorder.cxx:238
 TRecorder.cxx:239
 TRecorder.cxx:240
 TRecorder.cxx:241
 TRecorder.cxx:242
 TRecorder.cxx:243
 TRecorder.cxx:244
 TRecorder.cxx:245
 TRecorder.cxx:246
 TRecorder.cxx:247
 TRecorder.cxx:248
 TRecorder.cxx:249
 TRecorder.cxx:250
 TRecorder.cxx:251
 TRecorder.cxx:252
 TRecorder.cxx:253
 TRecorder.cxx:254
 TRecorder.cxx:255
 TRecorder.cxx:256
 TRecorder.cxx:257
 TRecorder.cxx:258
 TRecorder.cxx:259
 TRecorder.cxx:260
 TRecorder.cxx:261
 TRecorder.cxx:262
 TRecorder.cxx:263
 TRecorder.cxx:264
 TRecorder.cxx:265
 TRecorder.cxx:266
 TRecorder.cxx:267
 TRecorder.cxx:268
 TRecorder.cxx:269
 TRecorder.cxx:270
 TRecorder.cxx:271
 TRecorder.cxx:272
 TRecorder.cxx:273
 TRecorder.cxx:274
 TRecorder.cxx:275
 TRecorder.cxx:276
 TRecorder.cxx:277
 TRecorder.cxx:278
 TRecorder.cxx:279
 TRecorder.cxx:280
 TRecorder.cxx:281
 TRecorder.cxx:282
 TRecorder.cxx:283
 TRecorder.cxx:284
 TRecorder.cxx:285
 TRecorder.cxx:286
 TRecorder.cxx:287
 TRecorder.cxx:288
 TRecorder.cxx:289
 TRecorder.cxx:290
 TRecorder.cxx:291
 TRecorder.cxx:292
 TRecorder.cxx:293
 TRecorder.cxx:294
 TRecorder.cxx:295
 TRecorder.cxx:296
 TRecorder.cxx:297
 TRecorder.cxx:298
 TRecorder.cxx:299
 TRecorder.cxx:300
 TRecorder.cxx:301
 TRecorder.cxx:302
 TRecorder.cxx:303
 TRecorder.cxx:304
 TRecorder.cxx:305
 TRecorder.cxx:306
 TRecorder.cxx:307
 TRecorder.cxx:308
 TRecorder.cxx:309
 TRecorder.cxx:310
 TRecorder.cxx:311
 TRecorder.cxx:312
 TRecorder.cxx:313
 TRecorder.cxx:314
 TRecorder.cxx:315
 TRecorder.cxx:316
 TRecorder.cxx:317
 TRecorder.cxx:318
 TRecorder.cxx:319
 TRecorder.cxx:320
 TRecorder.cxx:321
 TRecorder.cxx:322
 TRecorder.cxx:323
 TRecorder.cxx:324
 TRecorder.cxx:325
 TRecorder.cxx:326
 TRecorder.cxx:327
 TRecorder.cxx:328
 TRecorder.cxx:329
 TRecorder.cxx:330
 TRecorder.cxx:331
 TRecorder.cxx:332
 TRecorder.cxx:333
 TRecorder.cxx:334
 TRecorder.cxx:335
 TRecorder.cxx:336
 TRecorder.cxx:337
 TRecorder.cxx:338
 TRecorder.cxx:339
 TRecorder.cxx:340
 TRecorder.cxx:341
 TRecorder.cxx:342
 TRecorder.cxx:343
 TRecorder.cxx:344
 TRecorder.cxx:345
 TRecorder.cxx:346
 TRecorder.cxx:347
 TRecorder.cxx:348
 TRecorder.cxx:349
 TRecorder.cxx:350
 TRecorder.cxx:351
 TRecorder.cxx:352
 TRecorder.cxx:353
 TRecorder.cxx:354
 TRecorder.cxx:355
 TRecorder.cxx:356
 TRecorder.cxx:357
 TRecorder.cxx:358
 TRecorder.cxx:359
 TRecorder.cxx:360
 TRecorder.cxx:361
 TRecorder.cxx:362
 TRecorder.cxx:363
 TRecorder.cxx:364
 TRecorder.cxx:365
 TRecorder.cxx:366
 TRecorder.cxx:367
 TRecorder.cxx:368
 TRecorder.cxx:369
 TRecorder.cxx:370
 TRecorder.cxx:371
 TRecorder.cxx:372
 TRecorder.cxx:373
 TRecorder.cxx:374
 TRecorder.cxx:375
 TRecorder.cxx:376
 TRecorder.cxx:377
 TRecorder.cxx:378
 TRecorder.cxx:379
 TRecorder.cxx:380
 TRecorder.cxx:381
 TRecorder.cxx:382
 TRecorder.cxx:383
 TRecorder.cxx:384
 TRecorder.cxx:385
 TRecorder.cxx:386
 TRecorder.cxx:387
 TRecorder.cxx:388
 TRecorder.cxx:389
 TRecorder.cxx:390
 TRecorder.cxx:391
 TRecorder.cxx:392
 TRecorder.cxx:393
 TRecorder.cxx:394
 TRecorder.cxx:395
 TRecorder.cxx:396
 TRecorder.cxx:397
 TRecorder.cxx:398
 TRecorder.cxx:399
 TRecorder.cxx:400
 TRecorder.cxx:401
 TRecorder.cxx:402
 TRecorder.cxx:403
 TRecorder.cxx:404
 TRecorder.cxx:405
 TRecorder.cxx:406
 TRecorder.cxx:407
 TRecorder.cxx:408
 TRecorder.cxx:409
 TRecorder.cxx:410
 TRecorder.cxx:411
 TRecorder.cxx:412
 TRecorder.cxx:413
 TRecorder.cxx:414
 TRecorder.cxx:415
 TRecorder.cxx:416
 TRecorder.cxx:417
 TRecorder.cxx:418
 TRecorder.cxx:419
 TRecorder.cxx:420
 TRecorder.cxx:421
 TRecorder.cxx:422
 TRecorder.cxx:423
 TRecorder.cxx:424
 TRecorder.cxx:425
 TRecorder.cxx:426
 TRecorder.cxx:427
 TRecorder.cxx:428
 TRecorder.cxx:429
 TRecorder.cxx:430
 TRecorder.cxx:431
 TRecorder.cxx:432
 TRecorder.cxx:433
 TRecorder.cxx:434
 TRecorder.cxx:435
 TRecorder.cxx:436
 TRecorder.cxx:437
 TRecorder.cxx:438
 TRecorder.cxx:439
 TRecorder.cxx:440
 TRecorder.cxx:441
 TRecorder.cxx:442
 TRecorder.cxx:443
 TRecorder.cxx:444
 TRecorder.cxx:445
 TRecorder.cxx:446
 TRecorder.cxx:447
 TRecorder.cxx:448
 TRecorder.cxx:449
 TRecorder.cxx:450
 TRecorder.cxx:451
 TRecorder.cxx:452
 TRecorder.cxx:453
 TRecorder.cxx:454
 TRecorder.cxx:455
 TRecorder.cxx:456
 TRecorder.cxx:457
 TRecorder.cxx:458
 TRecorder.cxx:459
 TRecorder.cxx:460
 TRecorder.cxx:461
 TRecorder.cxx:462
 TRecorder.cxx:463
 TRecorder.cxx:464
 TRecorder.cxx:465
 TRecorder.cxx:466
 TRecorder.cxx:467
 TRecorder.cxx:468
 TRecorder.cxx:469
 TRecorder.cxx:470
 TRecorder.cxx:471
 TRecorder.cxx:472
 TRecorder.cxx:473
 TRecorder.cxx:474
 TRecorder.cxx:475
 TRecorder.cxx:476
 TRecorder.cxx:477
 TRecorder.cxx:478
 TRecorder.cxx:479
 TRecorder.cxx:480
 TRecorder.cxx:481
 TRecorder.cxx:482
 TRecorder.cxx:483
 TRecorder.cxx:484
 TRecorder.cxx:485
 TRecorder.cxx:486
 TRecorder.cxx:487
 TRecorder.cxx:488
 TRecorder.cxx:489
 TRecorder.cxx:490
 TRecorder.cxx:491
 TRecorder.cxx:492
 TRecorder.cxx:493
 TRecorder.cxx:494
 TRecorder.cxx:495
 TRecorder.cxx:496
 TRecorder.cxx:497
 TRecorder.cxx:498
 TRecorder.cxx:499
 TRecorder.cxx:500
 TRecorder.cxx:501
 TRecorder.cxx:502
 TRecorder.cxx:503
 TRecorder.cxx:504
 TRecorder.cxx:505
 TRecorder.cxx:506
 TRecorder.cxx:507
 TRecorder.cxx:508
 TRecorder.cxx:509
 TRecorder.cxx:510
 TRecorder.cxx:511
 TRecorder.cxx:512
 TRecorder.cxx:513
 TRecorder.cxx:514
 TRecorder.cxx:515
 TRecorder.cxx:516
 TRecorder.cxx:517
 TRecorder.cxx:518
 TRecorder.cxx:519
 TRecorder.cxx:520
 TRecorder.cxx:521
 TRecorder.cxx:522
 TRecorder.cxx:523
 TRecorder.cxx:524
 TRecorder.cxx:525
 TRecorder.cxx:526
 TRecorder.cxx:527
 TRecorder.cxx:528
 TRecorder.cxx:529
 TRecorder.cxx:530
 TRecorder.cxx:531
 TRecorder.cxx:532
 TRecorder.cxx:533
 TRecorder.cxx:534
 TRecorder.cxx:535
 TRecorder.cxx:536
 TRecorder.cxx:537
 TRecorder.cxx:538
 TRecorder.cxx:539
 TRecorder.cxx:540
 TRecorder.cxx:541
 TRecorder.cxx:542
 TRecorder.cxx:543
 TRecorder.cxx:544
 TRecorder.cxx:545
 TRecorder.cxx:546
 TRecorder.cxx:547
 TRecorder.cxx:548
 TRecorder.cxx:549
 TRecorder.cxx:550
 TRecorder.cxx:551
 TRecorder.cxx:552
 TRecorder.cxx:553
 TRecorder.cxx:554
 TRecorder.cxx:555
 TRecorder.cxx:556
 TRecorder.cxx:557
 TRecorder.cxx:558
 TRecorder.cxx:559
 TRecorder.cxx:560
 TRecorder.cxx:561
 TRecorder.cxx:562
 TRecorder.cxx:563
 TRecorder.cxx:564
 TRecorder.cxx:565
 TRecorder.cxx:566
 TRecorder.cxx:567
 TRecorder.cxx:568
 TRecorder.cxx:569
 TRecorder.cxx:570
 TRecorder.cxx:571
 TRecorder.cxx:572
 TRecorder.cxx:573
 TRecorder.cxx:574
 TRecorder.cxx:575
 TRecorder.cxx:576
 TRecorder.cxx:577
 TRecorder.cxx:578
 TRecorder.cxx:579
 TRecorder.cxx:580
 TRecorder.cxx:581
 TRecorder.cxx:582
 TRecorder.cxx:583
 TRecorder.cxx:584
 TRecorder.cxx:585
 TRecorder.cxx:586
 TRecorder.cxx:587
 TRecorder.cxx:588
 TRecorder.cxx:589
 TRecorder.cxx:590
 TRecorder.cxx:591
 TRecorder.cxx:592
 TRecorder.cxx:593
 TRecorder.cxx:594
 TRecorder.cxx:595
 TRecorder.cxx:596
 TRecorder.cxx:597
 TRecorder.cxx:598
 TRecorder.cxx:599
 TRecorder.cxx:600
 TRecorder.cxx:601
 TRecorder.cxx:602
 TRecorder.cxx:603
 TRecorder.cxx:604
 TRecorder.cxx:605
 TRecorder.cxx:606
 TRecorder.cxx:607
 TRecorder.cxx:608
 TRecorder.cxx:609
 TRecorder.cxx:610
 TRecorder.cxx:611
 TRecorder.cxx:612
 TRecorder.cxx:613
 TRecorder.cxx:614
 TRecorder.cxx:615
 TRecorder.cxx:616
 TRecorder.cxx:617
 TRecorder.cxx:618
 TRecorder.cxx:619
 TRecorder.cxx:620
 TRecorder.cxx:621
 TRecorder.cxx:622
 TRecorder.cxx:623
 TRecorder.cxx:624
 TRecorder.cxx:625
 TRecorder.cxx:626
 TRecorder.cxx:627
 TRecorder.cxx:628
 TRecorder.cxx:629
 TRecorder.cxx:630
 TRecorder.cxx:631
 TRecorder.cxx:632
 TRecorder.cxx:633
 TRecorder.cxx:634
 TRecorder.cxx:635
 TRecorder.cxx:636
 TRecorder.cxx:637
 TRecorder.cxx:638
 TRecorder.cxx:639
 TRecorder.cxx:640
 TRecorder.cxx:641
 TRecorder.cxx:642
 TRecorder.cxx:643
 TRecorder.cxx:644
 TRecorder.cxx:645
 TRecorder.cxx:646
 TRecorder.cxx:647
 TRecorder.cxx:648
 TRecorder.cxx:649
 TRecorder.cxx:650
 TRecorder.cxx:651
 TRecorder.cxx:652
 TRecorder.cxx:653
 TRecorder.cxx:654
 TRecorder.cxx:655
 TRecorder.cxx:656
 TRecorder.cxx:657
 TRecorder.cxx:658
 TRecorder.cxx:659
 TRecorder.cxx:660
 TRecorder.cxx:661
 TRecorder.cxx:662
 TRecorder.cxx:663
 TRecorder.cxx:664
 TRecorder.cxx:665
 TRecorder.cxx:666
 TRecorder.cxx:667
 TRecorder.cxx:668
 TRecorder.cxx:669
 TRecorder.cxx:670
 TRecorder.cxx:671
 TRecorder.cxx:672
 TRecorder.cxx:673
 TRecorder.cxx:674
 TRecorder.cxx:675
 TRecorder.cxx:676
 TRecorder.cxx:677
 TRecorder.cxx:678
 TRecorder.cxx:679
 TRecorder.cxx:680
 TRecorder.cxx:681
 TRecorder.cxx:682
 TRecorder.cxx:683
 TRecorder.cxx:684
 TRecorder.cxx:685
 TRecorder.cxx:686
 TRecorder.cxx:687
 TRecorder.cxx:688
 TRecorder.cxx:689
 TRecorder.cxx:690
 TRecorder.cxx:691
 TRecorder.cxx:692
 TRecorder.cxx:693
 TRecorder.cxx:694
 TRecorder.cxx:695
 TRecorder.cxx:696
 TRecorder.cxx:697
 TRecorder.cxx:698
 TRecorder.cxx:699
 TRecorder.cxx:700
 TRecorder.cxx:701
 TRecorder.cxx:702
 TRecorder.cxx:703
 TRecorder.cxx:704
 TRecorder.cxx:705
 TRecorder.cxx:706
 TRecorder.cxx:707
 TRecorder.cxx:708
 TRecorder.cxx:709
 TRecorder.cxx:710
 TRecorder.cxx:711
 TRecorder.cxx:712
 TRecorder.cxx:713
 TRecorder.cxx:714
 TRecorder.cxx:715
 TRecorder.cxx:716
 TRecorder.cxx:717
 TRecorder.cxx:718
 TRecorder.cxx:719
 TRecorder.cxx:720
 TRecorder.cxx:721
 TRecorder.cxx:722
 TRecorder.cxx:723
 TRecorder.cxx:724
 TRecorder.cxx:725
 TRecorder.cxx:726
 TRecorder.cxx:727
 TRecorder.cxx:728
 TRecorder.cxx:729
 TRecorder.cxx:730
 TRecorder.cxx:731
 TRecorder.cxx:732
 TRecorder.cxx:733
 TRecorder.cxx:734
 TRecorder.cxx:735
 TRecorder.cxx:736
 TRecorder.cxx:737
 TRecorder.cxx:738
 TRecorder.cxx:739
 TRecorder.cxx:740
 TRecorder.cxx:741
 TRecorder.cxx:742
 TRecorder.cxx:743
 TRecorder.cxx:744
 TRecorder.cxx:745
 TRecorder.cxx:746
 TRecorder.cxx:747
 TRecorder.cxx:748
 TRecorder.cxx:749
 TRecorder.cxx:750
 TRecorder.cxx:751
 TRecorder.cxx:752
 TRecorder.cxx:753
 TRecorder.cxx:754
 TRecorder.cxx:755
 TRecorder.cxx:756
 TRecorder.cxx:757
 TRecorder.cxx:758
 TRecorder.cxx:759
 TRecorder.cxx:760
 TRecorder.cxx:761
 TRecorder.cxx:762
 TRecorder.cxx:763
 TRecorder.cxx:764
 TRecorder.cxx:765
 TRecorder.cxx:766
 TRecorder.cxx:767
 TRecorder.cxx:768
 TRecorder.cxx:769
 TRecorder.cxx:770
 TRecorder.cxx:771
 TRecorder.cxx:772
 TRecorder.cxx:773
 TRecorder.cxx:774
 TRecorder.cxx:775
 TRecorder.cxx:776
 TRecorder.cxx:777
 TRecorder.cxx:778
 TRecorder.cxx:779
 TRecorder.cxx:780
 TRecorder.cxx:781
 TRecorder.cxx:782
 TRecorder.cxx:783
 TRecorder.cxx:784
 TRecorder.cxx:785
 TRecorder.cxx:786
 TRecorder.cxx:787
 TRecorder.cxx:788
 TRecorder.cxx:789
 TRecorder.cxx:790
 TRecorder.cxx:791
 TRecorder.cxx:792
 TRecorder.cxx:793
 TRecorder.cxx:794
 TRecorder.cxx:795
 TRecorder.cxx:796
 TRecorder.cxx:797
 TRecorder.cxx:798
 TRecorder.cxx:799
 TRecorder.cxx:800
 TRecorder.cxx:801
 TRecorder.cxx:802
 TRecorder.cxx:803
 TRecorder.cxx:804
 TRecorder.cxx:805
 TRecorder.cxx:806
 TRecorder.cxx:807
 TRecorder.cxx:808
 TRecorder.cxx:809
 TRecorder.cxx:810
 TRecorder.cxx:811
 TRecorder.cxx:812
 TRecorder.cxx:813
 TRecorder.cxx:814
 TRecorder.cxx:815
 TRecorder.cxx:816
 TRecorder.cxx:817
 TRecorder.cxx:818
 TRecorder.cxx:819
 TRecorder.cxx:820
 TRecorder.cxx:821
 TRecorder.cxx:822
 TRecorder.cxx:823
 TRecorder.cxx:824
 TRecorder.cxx:825
 TRecorder.cxx:826
 TRecorder.cxx:827
 TRecorder.cxx:828
 TRecorder.cxx:829
 TRecorder.cxx:830
 TRecorder.cxx:831
 TRecorder.cxx:832
 TRecorder.cxx:833
 TRecorder.cxx:834
 TRecorder.cxx:835
 TRecorder.cxx:836
 TRecorder.cxx:837
 TRecorder.cxx:838
 TRecorder.cxx:839
 TRecorder.cxx:840
 TRecorder.cxx:841
 TRecorder.cxx:842
 TRecorder.cxx:843
 TRecorder.cxx:844
 TRecorder.cxx:845
 TRecorder.cxx:846
 TRecorder.cxx:847
 TRecorder.cxx:848
 TRecorder.cxx:849
 TRecorder.cxx:850
 TRecorder.cxx:851
 TRecorder.cxx:852
 TRecorder.cxx:853
 TRecorder.cxx:854
 TRecorder.cxx:855
 TRecorder.cxx:856
 TRecorder.cxx:857
 TRecorder.cxx:858
 TRecorder.cxx:859
 TRecorder.cxx:860
 TRecorder.cxx:861
 TRecorder.cxx:862
 TRecorder.cxx:863
 TRecorder.cxx:864
 TRecorder.cxx:865
 TRecorder.cxx:866
 TRecorder.cxx:867
 TRecorder.cxx:868
 TRecorder.cxx:869
 TRecorder.cxx:870
 TRecorder.cxx:871
 TRecorder.cxx:872
 TRecorder.cxx:873
 TRecorder.cxx:874
 TRecorder.cxx:875
 TRecorder.cxx:876
 TRecorder.cxx:877
 TRecorder.cxx:878
 TRecorder.cxx:879
 TRecorder.cxx:880
 TRecorder.cxx:881
 TRecorder.cxx:882
 TRecorder.cxx:883
 TRecorder.cxx:884
 TRecorder.cxx:885
 TRecorder.cxx:886
 TRecorder.cxx:887
 TRecorder.cxx:888
 TRecorder.cxx:889
 TRecorder.cxx:890
 TRecorder.cxx:891
 TRecorder.cxx:892
 TRecorder.cxx:893
 TRecorder.cxx:894
 TRecorder.cxx:895
 TRecorder.cxx:896
 TRecorder.cxx:897
 TRecorder.cxx:898
 TRecorder.cxx:899
 TRecorder.cxx:900
 TRecorder.cxx:901
 TRecorder.cxx:902
 TRecorder.cxx:903
 TRecorder.cxx:904
 TRecorder.cxx:905
 TRecorder.cxx:906
 TRecorder.cxx:907
 TRecorder.cxx:908
 TRecorder.cxx:909
 TRecorder.cxx:910
 TRecorder.cxx:911
 TRecorder.cxx:912
 TRecorder.cxx:913
 TRecorder.cxx:914
 TRecorder.cxx:915
 TRecorder.cxx:916
 TRecorder.cxx:917
 TRecorder.cxx:918
 TRecorder.cxx:919
 TRecorder.cxx:920
 TRecorder.cxx:921
 TRecorder.cxx:922
 TRecorder.cxx:923
 TRecorder.cxx:924
 TRecorder.cxx:925
 TRecorder.cxx:926
 TRecorder.cxx:927
 TRecorder.cxx:928
 TRecorder.cxx:929
 TRecorder.cxx:930
 TRecorder.cxx:931
 TRecorder.cxx:932
 TRecorder.cxx:933
 TRecorder.cxx:934
 TRecorder.cxx:935
 TRecorder.cxx:936
 TRecorder.cxx:937
 TRecorder.cxx:938
 TRecorder.cxx:939
 TRecorder.cxx:940
 TRecorder.cxx:941
 TRecorder.cxx:942
 TRecorder.cxx:943
 TRecorder.cxx:944
 TRecorder.cxx:945
 TRecorder.cxx:946
 TRecorder.cxx:947
 TRecorder.cxx:948
 TRecorder.cxx:949
 TRecorder.cxx:950
 TRecorder.cxx:951
 TRecorder.cxx:952
 TRecorder.cxx:953
 TRecorder.cxx:954
 TRecorder.cxx:955
 TRecorder.cxx:956
 TRecorder.cxx:957
 TRecorder.cxx:958
 TRecorder.cxx:959
 TRecorder.cxx:960
 TRecorder.cxx:961
 TRecorder.cxx:962
 TRecorder.cxx:963
 TRecorder.cxx:964
 TRecorder.cxx:965
 TRecorder.cxx:966
 TRecorder.cxx:967
 TRecorder.cxx:968
 TRecorder.cxx:969
 TRecorder.cxx:970
 TRecorder.cxx:971
 TRecorder.cxx:972
 TRecorder.cxx:973
 TRecorder.cxx:974
 TRecorder.cxx:975
 TRecorder.cxx:976
 TRecorder.cxx:977
 TRecorder.cxx:978
 TRecorder.cxx:979
 TRecorder.cxx:980
 TRecorder.cxx:981
 TRecorder.cxx:982
 TRecorder.cxx:983
 TRecorder.cxx:984
 TRecorder.cxx:985
 TRecorder.cxx:986
 TRecorder.cxx:987
 TRecorder.cxx:988
 TRecorder.cxx:989
 TRecorder.cxx:990
 TRecorder.cxx:991
 TRecorder.cxx:992
 TRecorder.cxx:993
 TRecorder.cxx:994
 TRecorder.cxx:995
 TRecorder.cxx:996
 TRecorder.cxx:997
 TRecorder.cxx:998
 TRecorder.cxx:999
 TRecorder.cxx:1000
 TRecorder.cxx:1001
 TRecorder.cxx:1002
 TRecorder.cxx:1003
 TRecorder.cxx:1004
 TRecorder.cxx:1005
 TRecorder.cxx:1006
 TRecorder.cxx:1007
 TRecorder.cxx:1008
 TRecorder.cxx:1009
 TRecorder.cxx:1010
 TRecorder.cxx:1011
 TRecorder.cxx:1012
 TRecorder.cxx:1013
 TRecorder.cxx:1014
 TRecorder.cxx:1015
 TRecorder.cxx:1016
 TRecorder.cxx:1017
 TRecorder.cxx:1018
 TRecorder.cxx:1019
 TRecorder.cxx:1020
 TRecorder.cxx:1021
 TRecorder.cxx:1022
 TRecorder.cxx:1023
 TRecorder.cxx:1024
 TRecorder.cxx:1025
 TRecorder.cxx:1026
 TRecorder.cxx:1027
 TRecorder.cxx:1028
 TRecorder.cxx:1029
 TRecorder.cxx:1030
 TRecorder.cxx:1031
 TRecorder.cxx:1032
 TRecorder.cxx:1033
 TRecorder.cxx:1034
 TRecorder.cxx:1035
 TRecorder.cxx:1036
 TRecorder.cxx:1037
 TRecorder.cxx:1038
 TRecorder.cxx:1039
 TRecorder.cxx:1040
 TRecorder.cxx:1041
 TRecorder.cxx:1042
 TRecorder.cxx:1043
 TRecorder.cxx:1044
 TRecorder.cxx:1045
 TRecorder.cxx:1046
 TRecorder.cxx:1047
 TRecorder.cxx:1048
 TRecorder.cxx:1049
 TRecorder.cxx:1050
 TRecorder.cxx:1051
 TRecorder.cxx:1052
 TRecorder.cxx:1053
 TRecorder.cxx:1054
 TRecorder.cxx:1055
 TRecorder.cxx:1056
 TRecorder.cxx:1057
 TRecorder.cxx:1058
 TRecorder.cxx:1059
 TRecorder.cxx:1060
 TRecorder.cxx:1061
 TRecorder.cxx:1062
 TRecorder.cxx:1063
 TRecorder.cxx:1064
 TRecorder.cxx:1065
 TRecorder.cxx:1066
 TRecorder.cxx:1067
 TRecorder.cxx:1068
 TRecorder.cxx:1069
 TRecorder.cxx:1070
 TRecorder.cxx:1071
 TRecorder.cxx:1072
 TRecorder.cxx:1073
 TRecorder.cxx:1074
 TRecorder.cxx:1075
 TRecorder.cxx:1076
 TRecorder.cxx:1077
 TRecorder.cxx:1078
 TRecorder.cxx:1079
 TRecorder.cxx:1080
 TRecorder.cxx:1081
 TRecorder.cxx:1082
 TRecorder.cxx:1083
 TRecorder.cxx:1084
 TRecorder.cxx:1085
 TRecorder.cxx:1086
 TRecorder.cxx:1087
 TRecorder.cxx:1088
 TRecorder.cxx:1089
 TRecorder.cxx:1090
 TRecorder.cxx:1091
 TRecorder.cxx:1092
 TRecorder.cxx:1093
 TRecorder.cxx:1094
 TRecorder.cxx:1095
 TRecorder.cxx:1096
 TRecorder.cxx:1097
 TRecorder.cxx:1098
 TRecorder.cxx:1099
 TRecorder.cxx:1100
 TRecorder.cxx:1101
 TRecorder.cxx:1102
 TRecorder.cxx:1103
 TRecorder.cxx:1104
 TRecorder.cxx:1105
 TRecorder.cxx:1106
 TRecorder.cxx:1107
 TRecorder.cxx:1108
 TRecorder.cxx:1109
 TRecorder.cxx:1110
 TRecorder.cxx:1111
 TRecorder.cxx:1112
 TRecorder.cxx:1113
 TRecorder.cxx:1114
 TRecorder.cxx:1115
 TRecorder.cxx:1116
 TRecorder.cxx:1117
 TRecorder.cxx:1118
 TRecorder.cxx:1119
 TRecorder.cxx:1120
 TRecorder.cxx:1121
 TRecorder.cxx:1122
 TRecorder.cxx:1123
 TRecorder.cxx:1124
 TRecorder.cxx:1125
 TRecorder.cxx:1126
 TRecorder.cxx:1127
 TRecorder.cxx:1128
 TRecorder.cxx:1129
 TRecorder.cxx:1130
 TRecorder.cxx:1131
 TRecorder.cxx:1132
 TRecorder.cxx:1133
 TRecorder.cxx:1134
 TRecorder.cxx:1135
 TRecorder.cxx:1136
 TRecorder.cxx:1137
 TRecorder.cxx:1138
 TRecorder.cxx:1139
 TRecorder.cxx:1140
 TRecorder.cxx:1141
 TRecorder.cxx:1142
 TRecorder.cxx:1143
 TRecorder.cxx:1144
 TRecorder.cxx:1145
 TRecorder.cxx:1146
 TRecorder.cxx:1147
 TRecorder.cxx:1148
 TRecorder.cxx:1149
 TRecorder.cxx:1150
 TRecorder.cxx:1151
 TRecorder.cxx:1152
 TRecorder.cxx:1153
 TRecorder.cxx:1154
 TRecorder.cxx:1155
 TRecorder.cxx:1156
 TRecorder.cxx:1157
 TRecorder.cxx:1158
 TRecorder.cxx:1159
 TRecorder.cxx:1160
 TRecorder.cxx:1161
 TRecorder.cxx:1162
 TRecorder.cxx:1163
 TRecorder.cxx:1164
 TRecorder.cxx:1165
 TRecorder.cxx:1166
 TRecorder.cxx:1167
 TRecorder.cxx:1168
 TRecorder.cxx:1169
 TRecorder.cxx:1170
 TRecorder.cxx:1171
 TRecorder.cxx:1172
 TRecorder.cxx:1173
 TRecorder.cxx:1174
 TRecorder.cxx:1175
 TRecorder.cxx:1176
 TRecorder.cxx:1177
 TRecorder.cxx:1178
 TRecorder.cxx:1179
 TRecorder.cxx:1180
 TRecorder.cxx:1181
 TRecorder.cxx:1182
 TRecorder.cxx:1183
 TRecorder.cxx:1184
 TRecorder.cxx:1185
 TRecorder.cxx:1186
 TRecorder.cxx:1187
 TRecorder.cxx:1188
 TRecorder.cxx:1189
 TRecorder.cxx:1190
 TRecorder.cxx:1191
 TRecorder.cxx:1192
 TRecorder.cxx:1193
 TRecorder.cxx:1194
 TRecorder.cxx:1195
 TRecorder.cxx:1196
 TRecorder.cxx:1197
 TRecorder.cxx:1198
 TRecorder.cxx:1199
 TRecorder.cxx:1200
 TRecorder.cxx:1201
 TRecorder.cxx:1202
 TRecorder.cxx:1203
 TRecorder.cxx:1204
 TRecorder.cxx:1205
 TRecorder.cxx:1206
 TRecorder.cxx:1207
 TRecorder.cxx:1208
 TRecorder.cxx:1209
 TRecorder.cxx:1210
 TRecorder.cxx:1211
 TRecorder.cxx:1212
 TRecorder.cxx:1213
 TRecorder.cxx:1214
 TRecorder.cxx:1215
 TRecorder.cxx:1216
 TRecorder.cxx:1217
 TRecorder.cxx:1218
 TRecorder.cxx:1219
 TRecorder.cxx:1220
 TRecorder.cxx:1221
 TRecorder.cxx:1222
 TRecorder.cxx:1223
 TRecorder.cxx:1224
 TRecorder.cxx:1225
 TRecorder.cxx:1226
 TRecorder.cxx:1227
 TRecorder.cxx:1228
 TRecorder.cxx:1229
 TRecorder.cxx:1230
 TRecorder.cxx:1231
 TRecorder.cxx:1232
 TRecorder.cxx:1233
 TRecorder.cxx:1234
 TRecorder.cxx:1235
 TRecorder.cxx:1236
 TRecorder.cxx:1237
 TRecorder.cxx:1238
 TRecorder.cxx:1239
 TRecorder.cxx:1240
 TRecorder.cxx:1241
 TRecorder.cxx:1242
 TRecorder.cxx:1243
 TRecorder.cxx:1244
 TRecorder.cxx:1245
 TRecorder.cxx:1246
 TRecorder.cxx:1247
 TRecorder.cxx:1248
 TRecorder.cxx:1249
 TRecorder.cxx:1250
 TRecorder.cxx:1251
 TRecorder.cxx:1252
 TRecorder.cxx:1253
 TRecorder.cxx:1254
 TRecorder.cxx:1255
 TRecorder.cxx:1256
 TRecorder.cxx:1257
 TRecorder.cxx:1258
 TRecorder.cxx:1259
 TRecorder.cxx:1260
 TRecorder.cxx:1261
 TRecorder.cxx:1262
 TRecorder.cxx:1263
 TRecorder.cxx:1264
 TRecorder.cxx:1265
 TRecorder.cxx:1266
 TRecorder.cxx:1267
 TRecorder.cxx:1268
 TRecorder.cxx:1269
 TRecorder.cxx:1270
 TRecorder.cxx:1271
 TRecorder.cxx:1272
 TRecorder.cxx:1273
 TRecorder.cxx:1274
 TRecorder.cxx:1275
 TRecorder.cxx:1276
 TRecorder.cxx:1277
 TRecorder.cxx:1278
 TRecorder.cxx:1279
 TRecorder.cxx:1280
 TRecorder.cxx:1281
 TRecorder.cxx:1282
 TRecorder.cxx:1283
 TRecorder.cxx:1284
 TRecorder.cxx:1285
 TRecorder.cxx:1286
 TRecorder.cxx:1287
 TRecorder.cxx:1288
 TRecorder.cxx:1289
 TRecorder.cxx:1290
 TRecorder.cxx:1291
 TRecorder.cxx:1292
 TRecorder.cxx:1293
 TRecorder.cxx:1294
 TRecorder.cxx:1295
 TRecorder.cxx:1296
 TRecorder.cxx:1297
 TRecorder.cxx:1298
 TRecorder.cxx:1299
 TRecorder.cxx:1300
 TRecorder.cxx:1301
 TRecorder.cxx:1302
 TRecorder.cxx:1303
 TRecorder.cxx:1304
 TRecorder.cxx:1305
 TRecorder.cxx:1306
 TRecorder.cxx:1307
 TRecorder.cxx:1308
 TRecorder.cxx:1309
 TRecorder.cxx:1310
 TRecorder.cxx:1311
 TRecorder.cxx:1312
 TRecorder.cxx:1313
 TRecorder.cxx:1314
 TRecorder.cxx:1315
 TRecorder.cxx:1316
 TRecorder.cxx:1317
 TRecorder.cxx:1318
 TRecorder.cxx:1319
 TRecorder.cxx:1320
 TRecorder.cxx:1321
 TRecorder.cxx:1322
 TRecorder.cxx:1323
 TRecorder.cxx:1324
 TRecorder.cxx:1325
 TRecorder.cxx:1326
 TRecorder.cxx:1327
 TRecorder.cxx:1328
 TRecorder.cxx:1329
 TRecorder.cxx:1330
 TRecorder.cxx:1331
 TRecorder.cxx:1332
 TRecorder.cxx:1333
 TRecorder.cxx:1334
 TRecorder.cxx:1335
 TRecorder.cxx:1336
 TRecorder.cxx:1337
 TRecorder.cxx:1338
 TRecorder.cxx:1339
 TRecorder.cxx:1340
 TRecorder.cxx:1341
 TRecorder.cxx:1342
 TRecorder.cxx:1343
 TRecorder.cxx:1344
 TRecorder.cxx:1345
 TRecorder.cxx:1346
 TRecorder.cxx:1347
 TRecorder.cxx:1348
 TRecorder.cxx:1349
 TRecorder.cxx:1350
 TRecorder.cxx:1351
 TRecorder.cxx:1352
 TRecorder.cxx:1353
 TRecorder.cxx:1354
 TRecorder.cxx:1355
 TRecorder.cxx:1356
 TRecorder.cxx:1357
 TRecorder.cxx:1358
 TRecorder.cxx:1359
 TRecorder.cxx:1360
 TRecorder.cxx:1361
 TRecorder.cxx:1362
 TRecorder.cxx:1363
 TRecorder.cxx:1364
 TRecorder.cxx:1365
 TRecorder.cxx:1366
 TRecorder.cxx:1367
 TRecorder.cxx:1368
 TRecorder.cxx:1369
 TRecorder.cxx:1370
 TRecorder.cxx:1371
 TRecorder.cxx:1372
 TRecorder.cxx:1373
 TRecorder.cxx:1374
 TRecorder.cxx:1375
 TRecorder.cxx:1376
 TRecorder.cxx:1377
 TRecorder.cxx:1378
 TRecorder.cxx:1379
 TRecorder.cxx:1380
 TRecorder.cxx:1381
 TRecorder.cxx:1382
 TRecorder.cxx:1383
 TRecorder.cxx:1384
 TRecorder.cxx:1385
 TRecorder.cxx:1386
 TRecorder.cxx:1387
 TRecorder.cxx:1388
 TRecorder.cxx:1389
 TRecorder.cxx:1390
 TRecorder.cxx:1391
 TRecorder.cxx:1392
 TRecorder.cxx:1393
 TRecorder.cxx:1394
 TRecorder.cxx:1395
 TRecorder.cxx:1396
 TRecorder.cxx:1397
 TRecorder.cxx:1398
 TRecorder.cxx:1399
 TRecorder.cxx:1400
 TRecorder.cxx:1401
 TRecorder.cxx:1402
 TRecorder.cxx:1403
 TRecorder.cxx:1404
 TRecorder.cxx:1405
 TRecorder.cxx:1406
 TRecorder.cxx:1407
 TRecorder.cxx:1408
 TRecorder.cxx:1409
 TRecorder.cxx:1410
 TRecorder.cxx:1411
 TRecorder.cxx:1412
 TRecorder.cxx:1413
 TRecorder.cxx:1414
 TRecorder.cxx:1415
 TRecorder.cxx:1416
 TRecorder.cxx:1417
 TRecorder.cxx:1418
 TRecorder.cxx:1419
 TRecorder.cxx:1420
 TRecorder.cxx:1421
 TRecorder.cxx:1422
 TRecorder.cxx:1423
 TRecorder.cxx:1424
 TRecorder.cxx:1425
 TRecorder.cxx:1426
 TRecorder.cxx:1427
 TRecorder.cxx:1428
 TRecorder.cxx:1429
 TRecorder.cxx:1430
 TRecorder.cxx:1431
 TRecorder.cxx:1432
 TRecorder.cxx:1433
 TRecorder.cxx:1434
 TRecorder.cxx:1435
 TRecorder.cxx:1436
 TRecorder.cxx:1437
 TRecorder.cxx:1438
 TRecorder.cxx:1439
 TRecorder.cxx:1440
 TRecorder.cxx:1441
 TRecorder.cxx:1442
 TRecorder.cxx:1443
 TRecorder.cxx:1444
 TRecorder.cxx:1445
 TRecorder.cxx:1446
 TRecorder.cxx:1447
 TRecorder.cxx:1448
 TRecorder.cxx:1449
 TRecorder.cxx:1450
 TRecorder.cxx:1451
 TRecorder.cxx:1452
 TRecorder.cxx:1453
 TRecorder.cxx:1454
 TRecorder.cxx:1455
 TRecorder.cxx:1456
 TRecorder.cxx:1457
 TRecorder.cxx:1458
 TRecorder.cxx:1459
 TRecorder.cxx:1460
 TRecorder.cxx:1461
 TRecorder.cxx:1462
 TRecorder.cxx:1463
 TRecorder.cxx:1464
 TRecorder.cxx:1465
 TRecorder.cxx:1466
 TRecorder.cxx:1467
 TRecorder.cxx:1468
 TRecorder.cxx:1469
 TRecorder.cxx:1470
 TRecorder.cxx:1471
 TRecorder.cxx:1472
 TRecorder.cxx:1473
 TRecorder.cxx:1474
 TRecorder.cxx:1475
 TRecorder.cxx:1476
 TRecorder.cxx:1477
 TRecorder.cxx:1478
 TRecorder.cxx:1479
 TRecorder.cxx:1480
 TRecorder.cxx:1481
 TRecorder.cxx:1482
 TRecorder.cxx:1483
 TRecorder.cxx:1484
 TRecorder.cxx:1485
 TRecorder.cxx:1486
 TRecorder.cxx:1487
 TRecorder.cxx:1488
 TRecorder.cxx:1489
 TRecorder.cxx:1490
 TRecorder.cxx:1491
 TRecorder.cxx:1492
 TRecorder.cxx:1493
 TRecorder.cxx:1494
 TRecorder.cxx:1495
 TRecorder.cxx:1496
 TRecorder.cxx:1497
 TRecorder.cxx:1498
 TRecorder.cxx:1499
 TRecorder.cxx:1500
 TRecorder.cxx:1501
 TRecorder.cxx:1502
 TRecorder.cxx:1503
 TRecorder.cxx:1504
 TRecorder.cxx:1505
 TRecorder.cxx:1506
 TRecorder.cxx:1507
 TRecorder.cxx:1508
 TRecorder.cxx:1509
 TRecorder.cxx:1510
 TRecorder.cxx:1511
 TRecorder.cxx:1512
 TRecorder.cxx:1513
 TRecorder.cxx:1514
 TRecorder.cxx:1515
 TRecorder.cxx:1516
 TRecorder.cxx:1517
 TRecorder.cxx:1518
 TRecorder.cxx:1519
 TRecorder.cxx:1520
 TRecorder.cxx:1521
 TRecorder.cxx:1522
 TRecorder.cxx:1523
 TRecorder.cxx:1524
 TRecorder.cxx:1525
 TRecorder.cxx:1526
 TRecorder.cxx:1527
 TRecorder.cxx:1528
 TRecorder.cxx:1529
 TRecorder.cxx:1530
 TRecorder.cxx:1531
 TRecorder.cxx:1532
 TRecorder.cxx:1533
 TRecorder.cxx:1534
 TRecorder.cxx:1535
 TRecorder.cxx:1536
 TRecorder.cxx:1537
 TRecorder.cxx:1538
 TRecorder.cxx:1539
 TRecorder.cxx:1540
 TRecorder.cxx:1541
 TRecorder.cxx:1542
 TRecorder.cxx:1543
 TRecorder.cxx:1544
 TRecorder.cxx:1545
 TRecorder.cxx:1546
 TRecorder.cxx:1547
 TRecorder.cxx:1548
 TRecorder.cxx:1549
 TRecorder.cxx:1550
 TRecorder.cxx:1551
 TRecorder.cxx:1552
 TRecorder.cxx:1553
 TRecorder.cxx:1554
 TRecorder.cxx:1555
 TRecorder.cxx:1556
 TRecorder.cxx:1557
 TRecorder.cxx:1558
 TRecorder.cxx:1559
 TRecorder.cxx:1560
 TRecorder.cxx:1561
 TRecorder.cxx:1562
 TRecorder.cxx:1563
 TRecorder.cxx:1564
 TRecorder.cxx:1565
 TRecorder.cxx:1566
 TRecorder.cxx:1567
 TRecorder.cxx:1568
 TRecorder.cxx:1569
 TRecorder.cxx:1570
 TRecorder.cxx:1571
 TRecorder.cxx:1572
 TRecorder.cxx:1573
 TRecorder.cxx:1574
 TRecorder.cxx:1575
 TRecorder.cxx:1576
 TRecorder.cxx:1577
 TRecorder.cxx:1578
 TRecorder.cxx:1579
 TRecorder.cxx:1580
 TRecorder.cxx:1581
 TRecorder.cxx:1582
 TRecorder.cxx:1583
 TRecorder.cxx:1584
 TRecorder.cxx:1585
 TRecorder.cxx:1586
 TRecorder.cxx:1587
 TRecorder.cxx:1588
 TRecorder.cxx:1589
 TRecorder.cxx:1590
 TRecorder.cxx:1591
 TRecorder.cxx:1592
 TRecorder.cxx:1593
 TRecorder.cxx:1594
 TRecorder.cxx:1595
 TRecorder.cxx:1596
 TRecorder.cxx:1597
 TRecorder.cxx:1598
 TRecorder.cxx:1599
 TRecorder.cxx:1600
 TRecorder.cxx:1601
 TRecorder.cxx:1602
 TRecorder.cxx:1603
 TRecorder.cxx:1604
 TRecorder.cxx:1605
 TRecorder.cxx:1606
 TRecorder.cxx:1607
 TRecorder.cxx:1608
 TRecorder.cxx:1609
 TRecorder.cxx:1610
 TRecorder.cxx:1611
 TRecorder.cxx:1612
 TRecorder.cxx:1613
 TRecorder.cxx:1614
 TRecorder.cxx:1615
 TRecorder.cxx:1616
 TRecorder.cxx:1617
 TRecorder.cxx:1618
 TRecorder.cxx:1619
 TRecorder.cxx:1620
 TRecorder.cxx:1621
 TRecorder.cxx:1622
 TRecorder.cxx:1623
 TRecorder.cxx:1624
 TRecorder.cxx:1625
 TRecorder.cxx:1626
 TRecorder.cxx:1627
 TRecorder.cxx:1628
 TRecorder.cxx:1629
 TRecorder.cxx:1630
 TRecorder.cxx:1631
 TRecorder.cxx:1632
 TRecorder.cxx:1633
 TRecorder.cxx:1634
 TRecorder.cxx:1635
 TRecorder.cxx:1636
 TRecorder.cxx:1637
 TRecorder.cxx:1638
 TRecorder.cxx:1639
 TRecorder.cxx:1640
 TRecorder.cxx:1641
 TRecorder.cxx:1642
 TRecorder.cxx:1643
 TRecorder.cxx:1644
 TRecorder.cxx:1645
 TRecorder.cxx:1646
 TRecorder.cxx:1647
 TRecorder.cxx:1648
 TRecorder.cxx:1649
 TRecorder.cxx:1650
 TRecorder.cxx:1651
 TRecorder.cxx:1652
 TRecorder.cxx:1653
 TRecorder.cxx:1654
 TRecorder.cxx:1655
 TRecorder.cxx:1656
 TRecorder.cxx:1657
 TRecorder.cxx:1658
 TRecorder.cxx:1659
 TRecorder.cxx:1660
 TRecorder.cxx:1661
 TRecorder.cxx:1662
 TRecorder.cxx:1663
 TRecorder.cxx:1664
 TRecorder.cxx:1665
 TRecorder.cxx:1666
 TRecorder.cxx:1667
 TRecorder.cxx:1668
 TRecorder.cxx:1669
 TRecorder.cxx:1670
 TRecorder.cxx:1671
 TRecorder.cxx:1672
 TRecorder.cxx:1673
 TRecorder.cxx:1674
 TRecorder.cxx:1675
 TRecorder.cxx:1676
 TRecorder.cxx:1677
 TRecorder.cxx:1678
 TRecorder.cxx:1679
 TRecorder.cxx:1680
 TRecorder.cxx:1681
 TRecorder.cxx:1682
 TRecorder.cxx:1683
 TRecorder.cxx:1684
 TRecorder.cxx:1685
 TRecorder.cxx:1686
 TRecorder.cxx:1687
 TRecorder.cxx:1688
 TRecorder.cxx:1689
 TRecorder.cxx:1690
 TRecorder.cxx:1691
 TRecorder.cxx:1692
 TRecorder.cxx:1693
 TRecorder.cxx:1694
 TRecorder.cxx:1695
 TRecorder.cxx:1696
 TRecorder.cxx:1697
 TRecorder.cxx:1698
 TRecorder.cxx:1699
 TRecorder.cxx:1700
 TRecorder.cxx:1701
 TRecorder.cxx:1702
 TRecorder.cxx:1703
 TRecorder.cxx:1704
 TRecorder.cxx:1705
 TRecorder.cxx:1706
 TRecorder.cxx:1707
 TRecorder.cxx:1708
 TRecorder.cxx:1709
 TRecorder.cxx:1710
 TRecorder.cxx:1711
 TRecorder.cxx:1712
 TRecorder.cxx:1713
 TRecorder.cxx:1714
 TRecorder.cxx:1715
 TRecorder.cxx:1716
 TRecorder.cxx:1717
 TRecorder.cxx:1718
 TRecorder.cxx:1719
 TRecorder.cxx:1720
 TRecorder.cxx:1721
 TRecorder.cxx:1722
 TRecorder.cxx:1723
 TRecorder.cxx:1724
 TRecorder.cxx:1725
 TRecorder.cxx:1726
 TRecorder.cxx:1727
 TRecorder.cxx:1728
 TRecorder.cxx:1729
 TRecorder.cxx:1730
 TRecorder.cxx:1731
 TRecorder.cxx:1732
 TRecorder.cxx:1733
 TRecorder.cxx:1734
 TRecorder.cxx:1735
 TRecorder.cxx:1736
 TRecorder.cxx:1737
 TRecorder.cxx:1738
 TRecorder.cxx:1739
 TRecorder.cxx:1740
 TRecorder.cxx:1741
 TRecorder.cxx:1742
 TRecorder.cxx:1743
 TRecorder.cxx:1744
 TRecorder.cxx:1745
 TRecorder.cxx:1746
 TRecorder.cxx:1747
 TRecorder.cxx:1748
 TRecorder.cxx:1749
 TRecorder.cxx:1750
 TRecorder.cxx:1751
 TRecorder.cxx:1752
 TRecorder.cxx:1753
 TRecorder.cxx:1754
 TRecorder.cxx:1755
 TRecorder.cxx:1756
 TRecorder.cxx:1757
 TRecorder.cxx:1758
 TRecorder.cxx:1759
 TRecorder.cxx:1760
 TRecorder.cxx:1761
 TRecorder.cxx:1762
 TRecorder.cxx:1763
 TRecorder.cxx:1764
 TRecorder.cxx:1765
 TRecorder.cxx:1766
 TRecorder.cxx:1767
 TRecorder.cxx:1768
 TRecorder.cxx:1769
 TRecorder.cxx:1770
 TRecorder.cxx:1771
 TRecorder.cxx:1772
 TRecorder.cxx:1773
 TRecorder.cxx:1774
 TRecorder.cxx:1775
 TRecorder.cxx:1776
 TRecorder.cxx:1777
 TRecorder.cxx:1778
 TRecorder.cxx:1779
 TRecorder.cxx:1780
 TRecorder.cxx:1781
 TRecorder.cxx:1782
 TRecorder.cxx:1783
 TRecorder.cxx:1784
 TRecorder.cxx:1785
 TRecorder.cxx:1786
 TRecorder.cxx:1787
 TRecorder.cxx:1788
 TRecorder.cxx:1789
 TRecorder.cxx:1790
 TRecorder.cxx:1791
 TRecorder.cxx:1792
 TRecorder.cxx:1793
 TRecorder.cxx:1794
 TRecorder.cxx:1795
 TRecorder.cxx:1796
 TRecorder.cxx:1797
 TRecorder.cxx:1798
 TRecorder.cxx:1799
 TRecorder.cxx:1800
 TRecorder.cxx:1801
 TRecorder.cxx:1802
 TRecorder.cxx:1803
 TRecorder.cxx:1804
 TRecorder.cxx:1805
 TRecorder.cxx:1806
 TRecorder.cxx:1807
 TRecorder.cxx:1808
 TRecorder.cxx:1809
 TRecorder.cxx:1810
 TRecorder.cxx:1811
 TRecorder.cxx:1812
 TRecorder.cxx:1813
 TRecorder.cxx:1814
 TRecorder.cxx:1815
 TRecorder.cxx:1816
 TRecorder.cxx:1817
 TRecorder.cxx:1818
 TRecorder.cxx:1819
 TRecorder.cxx:1820
 TRecorder.cxx:1821
 TRecorder.cxx:1822
 TRecorder.cxx:1823
 TRecorder.cxx:1824
 TRecorder.cxx:1825
 TRecorder.cxx:1826
 TRecorder.cxx:1827
 TRecorder.cxx:1828
 TRecorder.cxx:1829
 TRecorder.cxx:1830
 TRecorder.cxx:1831
 TRecorder.cxx:1832
 TRecorder.cxx:1833
 TRecorder.cxx:1834
 TRecorder.cxx:1835
 TRecorder.cxx:1836
 TRecorder.cxx:1837
 TRecorder.cxx:1838
 TRecorder.cxx:1839
 TRecorder.cxx:1840
 TRecorder.cxx:1841
 TRecorder.cxx:1842
 TRecorder.cxx:1843
 TRecorder.cxx:1844
 TRecorder.cxx:1845
 TRecorder.cxx:1846
 TRecorder.cxx:1847
 TRecorder.cxx:1848
 TRecorder.cxx:1849
 TRecorder.cxx:1850
 TRecorder.cxx:1851
 TRecorder.cxx:1852
 TRecorder.cxx:1853
 TRecorder.cxx:1854
 TRecorder.cxx:1855
 TRecorder.cxx:1856
 TRecorder.cxx:1857
 TRecorder.cxx:1858
 TRecorder.cxx:1859
 TRecorder.cxx:1860
 TRecorder.cxx:1861
 TRecorder.cxx:1862
 TRecorder.cxx:1863
 TRecorder.cxx:1864
 TRecorder.cxx:1865
 TRecorder.cxx:1866
 TRecorder.cxx:1867
 TRecorder.cxx:1868
 TRecorder.cxx:1869
 TRecorder.cxx:1870
 TRecorder.cxx:1871
 TRecorder.cxx:1872
 TRecorder.cxx:1873
 TRecorder.cxx:1874
 TRecorder.cxx:1875
 TRecorder.cxx:1876
 TRecorder.cxx:1877
 TRecorder.cxx:1878
 TRecorder.cxx:1879
 TRecorder.cxx:1880
 TRecorder.cxx:1881
 TRecorder.cxx:1882
 TRecorder.cxx:1883
 TRecorder.cxx:1884
 TRecorder.cxx:1885
 TRecorder.cxx:1886
 TRecorder.cxx:1887
 TRecorder.cxx:1888
 TRecorder.cxx:1889
 TRecorder.cxx:1890
 TRecorder.cxx:1891
 TRecorder.cxx:1892
 TRecorder.cxx:1893
 TRecorder.cxx:1894
 TRecorder.cxx:1895
 TRecorder.cxx:1896
 TRecorder.cxx:1897
 TRecorder.cxx:1898
 TRecorder.cxx:1899
 TRecorder.cxx:1900
 TRecorder.cxx:1901
 TRecorder.cxx:1902
 TRecorder.cxx:1903
 TRecorder.cxx:1904
 TRecorder.cxx:1905
 TRecorder.cxx:1906
 TRecorder.cxx:1907
 TRecorder.cxx:1908
 TRecorder.cxx:1909
 TRecorder.cxx:1910
 TRecorder.cxx:1911
 TRecorder.cxx:1912
 TRecorder.cxx:1913
 TRecorder.cxx:1914
 TRecorder.cxx:1915
 TRecorder.cxx:1916
 TRecorder.cxx:1917
 TRecorder.cxx:1918
 TRecorder.cxx:1919
 TRecorder.cxx:1920
 TRecorder.cxx:1921
 TRecorder.cxx:1922
 TRecorder.cxx:1923
 TRecorder.cxx:1924
 TRecorder.cxx:1925
 TRecorder.cxx:1926
 TRecorder.cxx:1927
 TRecorder.cxx:1928
 TRecorder.cxx:1929
 TRecorder.cxx:1930
 TRecorder.cxx:1931
 TRecorder.cxx:1932
 TRecorder.cxx:1933
 TRecorder.cxx:1934
 TRecorder.cxx:1935
 TRecorder.cxx:1936
 TRecorder.cxx:1937
 TRecorder.cxx:1938
 TRecorder.cxx:1939
 TRecorder.cxx:1940
 TRecorder.cxx:1941
 TRecorder.cxx:1942
 TRecorder.cxx:1943
 TRecorder.cxx:1944
 TRecorder.cxx:1945
 TRecorder.cxx:1946
 TRecorder.cxx:1947
 TRecorder.cxx:1948
 TRecorder.cxx:1949
 TRecorder.cxx:1950
 TRecorder.cxx:1951
 TRecorder.cxx:1952
 TRecorder.cxx:1953
 TRecorder.cxx:1954
 TRecorder.cxx:1955
 TRecorder.cxx:1956
 TRecorder.cxx:1957
 TRecorder.cxx:1958
 TRecorder.cxx:1959
 TRecorder.cxx:1960
 TRecorder.cxx:1961
 TRecorder.cxx:1962
 TRecorder.cxx:1963
 TRecorder.cxx:1964
 TRecorder.cxx:1965
 TRecorder.cxx:1966
 TRecorder.cxx:1967
 TRecorder.cxx:1968
 TRecorder.cxx:1969
 TRecorder.cxx:1970
 TRecorder.cxx:1971
 TRecorder.cxx:1972
 TRecorder.cxx:1973
 TRecorder.cxx:1974
 TRecorder.cxx:1975
 TRecorder.cxx:1976
 TRecorder.cxx:1977
 TRecorder.cxx:1978
 TRecorder.cxx:1979
 TRecorder.cxx:1980
 TRecorder.cxx:1981
 TRecorder.cxx:1982
 TRecorder.cxx:1983
 TRecorder.cxx:1984
 TRecorder.cxx:1985
 TRecorder.cxx:1986
 TRecorder.cxx:1987
 TRecorder.cxx:1988
 TRecorder.cxx:1989
 TRecorder.cxx:1990
 TRecorder.cxx:1991
 TRecorder.cxx:1992
 TRecorder.cxx:1993
 TRecorder.cxx:1994
 TRecorder.cxx:1995
 TRecorder.cxx:1996
 TRecorder.cxx:1997
 TRecorder.cxx:1998
 TRecorder.cxx:1999
 TRecorder.cxx:2000
 TRecorder.cxx:2001
 TRecorder.cxx:2002
 TRecorder.cxx:2003
 TRecorder.cxx:2004
 TRecorder.cxx:2005
 TRecorder.cxx:2006
 TRecorder.cxx:2007
 TRecorder.cxx:2008
 TRecorder.cxx:2009
 TRecorder.cxx:2010
 TRecorder.cxx:2011
 TRecorder.cxx:2012
 TRecorder.cxx:2013
 TRecorder.cxx:2014
 TRecorder.cxx:2015
 TRecorder.cxx:2016
 TRecorder.cxx:2017
 TRecorder.cxx:2018
 TRecorder.cxx:2019
 TRecorder.cxx:2020
 TRecorder.cxx:2021
 TRecorder.cxx:2022
 TRecorder.cxx:2023
 TRecorder.cxx:2024
 TRecorder.cxx:2025
 TRecorder.cxx:2026
 TRecorder.cxx:2027
 TRecorder.cxx:2028
 TRecorder.cxx:2029
 TRecorder.cxx:2030
 TRecorder.cxx:2031
 TRecorder.cxx:2032
 TRecorder.cxx:2033
 TRecorder.cxx:2034
 TRecorder.cxx:2035
 TRecorder.cxx:2036
 TRecorder.cxx:2037
 TRecorder.cxx:2038
 TRecorder.cxx:2039
 TRecorder.cxx:2040
 TRecorder.cxx:2041
 TRecorder.cxx:2042
 TRecorder.cxx:2043
 TRecorder.cxx:2044
 TRecorder.cxx:2045
 TRecorder.cxx:2046
 TRecorder.cxx:2047
 TRecorder.cxx:2048
 TRecorder.cxx:2049
 TRecorder.cxx:2050
 TRecorder.cxx:2051
 TRecorder.cxx:2052
 TRecorder.cxx:2053
 TRecorder.cxx:2054
 TRecorder.cxx:2055
 TRecorder.cxx:2056
 TRecorder.cxx:2057
 TRecorder.cxx:2058
 TRecorder.cxx:2059
 TRecorder.cxx:2060
 TRecorder.cxx:2061
 TRecorder.cxx:2062
 TRecorder.cxx:2063
 TRecorder.cxx:2064
 TRecorder.cxx:2065
 TRecorder.cxx:2066
 TRecorder.cxx:2067
 TRecorder.cxx:2068
 TRecorder.cxx:2069
 TRecorder.cxx:2070
 TRecorder.cxx:2071
 TRecorder.cxx:2072
 TRecorder.cxx:2073
 TRecorder.cxx:2074
 TRecorder.cxx:2075
 TRecorder.cxx:2076
 TRecorder.cxx:2077
 TRecorder.cxx:2078
 TRecorder.cxx:2079
 TRecorder.cxx:2080
 TRecorder.cxx:2081
 TRecorder.cxx:2082
 TRecorder.cxx:2083
 TRecorder.cxx:2084
 TRecorder.cxx:2085
 TRecorder.cxx:2086
 TRecorder.cxx:2087
 TRecorder.cxx:2088
 TRecorder.cxx:2089
 TRecorder.cxx:2090
 TRecorder.cxx:2091
 TRecorder.cxx:2092
 TRecorder.cxx:2093
 TRecorder.cxx:2094
 TRecorder.cxx:2095
 TRecorder.cxx:2096
 TRecorder.cxx:2097
 TRecorder.cxx:2098
 TRecorder.cxx:2099
 TRecorder.cxx:2100
 TRecorder.cxx:2101
 TRecorder.cxx:2102
 TRecorder.cxx:2103
 TRecorder.cxx:2104
 TRecorder.cxx:2105
 TRecorder.cxx:2106
 TRecorder.cxx:2107
 TRecorder.cxx:2108
 TRecorder.cxx:2109
 TRecorder.cxx:2110
 TRecorder.cxx:2111
 TRecorder.cxx:2112
 TRecorder.cxx:2113
 TRecorder.cxx:2114
 TRecorder.cxx:2115
 TRecorder.cxx:2116
 TRecorder.cxx:2117
 TRecorder.cxx:2118
 TRecorder.cxx:2119
 TRecorder.cxx:2120
 TRecorder.cxx:2121
 TRecorder.cxx:2122
 TRecorder.cxx:2123
 TRecorder.cxx:2124
 TRecorder.cxx:2125
 TRecorder.cxx:2126
 TRecorder.cxx:2127
 TRecorder.cxx:2128
 TRecorder.cxx:2129
 TRecorder.cxx:2130
 TRecorder.cxx:2131
 TRecorder.cxx:2132
 TRecorder.cxx:2133
 TRecorder.cxx:2134
 TRecorder.cxx:2135
 TRecorder.cxx:2136
 TRecorder.cxx:2137
 TRecorder.cxx:2138
 TRecorder.cxx:2139
 TRecorder.cxx:2140
 TRecorder.cxx:2141
 TRecorder.cxx:2142
 TRecorder.cxx:2143
 TRecorder.cxx:2144
 TRecorder.cxx:2145
 TRecorder.cxx:2146
 TRecorder.cxx:2147
 TRecorder.cxx:2148
 TRecorder.cxx:2149
 TRecorder.cxx:2150
 TRecorder.cxx:2151
 TRecorder.cxx:2152
 TRecorder.cxx:2153
 TRecorder.cxx:2154
 TRecorder.cxx:2155
 TRecorder.cxx:2156
 TRecorder.cxx:2157
 TRecorder.cxx:2158
 TRecorder.cxx:2159
 TRecorder.cxx:2160
 TRecorder.cxx:2161
 TRecorder.cxx:2162
 TRecorder.cxx:2163
 TRecorder.cxx:2164
 TRecorder.cxx:2165
 TRecorder.cxx:2166
 TRecorder.cxx:2167
 TRecorder.cxx:2168
 TRecorder.cxx:2169
 TRecorder.cxx:2170
 TRecorder.cxx:2171
 TRecorder.cxx:2172
 TRecorder.cxx:2173
 TRecorder.cxx:2174
 TRecorder.cxx:2175
 TRecorder.cxx:2176
 TRecorder.cxx:2177
 TRecorder.cxx:2178
 TRecorder.cxx:2179
 TRecorder.cxx:2180
 TRecorder.cxx:2181
 TRecorder.cxx:2182
 TRecorder.cxx:2183
 TRecorder.cxx:2184
 TRecorder.cxx:2185
 TRecorder.cxx:2186
 TRecorder.cxx:2187
 TRecorder.cxx:2188
 TRecorder.cxx:2189
 TRecorder.cxx:2190
 TRecorder.cxx:2191
 TRecorder.cxx:2192
 TRecorder.cxx:2193
 TRecorder.cxx:2194
 TRecorder.cxx:2195
 TRecorder.cxx:2196
 TRecorder.cxx:2197
 TRecorder.cxx:2198
 TRecorder.cxx:2199
 TRecorder.cxx:2200
 TRecorder.cxx:2201
 TRecorder.cxx:2202
 TRecorder.cxx:2203
 TRecorder.cxx:2204
 TRecorder.cxx:2205
 TRecorder.cxx:2206
 TRecorder.cxx:2207
 TRecorder.cxx:2208
 TRecorder.cxx:2209
 TRecorder.cxx:2210
 TRecorder.cxx:2211
 TRecorder.cxx:2212
 TRecorder.cxx:2213
 TRecorder.cxx:2214
 TRecorder.cxx:2215
 TRecorder.cxx:2216
 TRecorder.cxx:2217
 TRecorder.cxx:2218
 TRecorder.cxx:2219
 TRecorder.cxx:2220
 TRecorder.cxx:2221
 TRecorder.cxx:2222
 TRecorder.cxx:2223
 TRecorder.cxx:2224
 TRecorder.cxx:2225
 TRecorder.cxx:2226
 TRecorder.cxx:2227
 TRecorder.cxx:2228
 TRecorder.cxx:2229
 TRecorder.cxx:2230
 TRecorder.cxx:2231
 TRecorder.cxx:2232
 TRecorder.cxx:2233
 TRecorder.cxx:2234
 TRecorder.cxx:2235
 TRecorder.cxx:2236
 TRecorder.cxx:2237
 TRecorder.cxx:2238
 TRecorder.cxx:2239
 TRecorder.cxx:2240
 TRecorder.cxx:2241