From 7bab7445a9d7875e5f6cba0e9d7d9c0091ea9ae3 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 14 Feb 2008 05:07:55 +0100 Subject: [PATCH 01/36] corr. IRC protocol --- .gitignore | 1 + wiki/index.html | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index ef277c1a1..5dc912d9e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ .[^.]* *.os *.gch +,valgrind.log* Buildhelper.pyc optcache Makefile.in diff --git a/wiki/index.html b/wiki/index.html index 43202dd25..34493fc01 100755 --- a/wiki/index.html +++ b/wiki/index.html @@ -1032,7 +1032,7 @@ cinelerra3/mob is an anonymous account at pipapo.org where everyone can commit c * on the question who decides what to do after a cache miss, we tend to put the decision into the render node (because this seems to be the simpler aproach), but still have to work out the details. -
+
! 1. feb.2008 on #openvideo
 21:00 -23:30 GMT. __Participants__:
 * hermanr
@@ -1047,17 +1047,18 @@ cinelerra3/mob is an anonymous account at pipapo.org where everyone can commit c
 * Velmont
 
 !! Discuss the open points in http://www.pipapo.org/pipawiki/Cinelerra3/DesignProcess — do we need this formalism?
-At start of the project last summer, Cehteh made a [[design process proposal|http://www.pipapo.org/pipawiki/Cinelerra3/DesignProcess]]. We will keeping this up, not for every implementation detail, but for mayor plans, wishes and design decisions. One point in the agenda of future meetings will be to work through proposals in the queue
+At start of the project last summer, Cehteh made a [[design process proposal|http://www.pipapo.org/pipawiki/Cinelerra3/DesignProcess]]. We will keeping this up, not for every implementation detail, but for major plans, wishes and design decisions. One point in the agenda of future meetings will be to work through proposals in the queue
 * proposals in the "idea" state are not complete, can be just brainstorming or need further discussion. Comments please to the proposal page.
 * proposals in the "draft" state are ready for conclusive discussion and will be treated in one of the next meetings
 * "final" proposals are either "accepted" or "dropped". We don't differentiate the latter, but should write a short note why it was dropped.
+* if there is need for more or finer grained categories, we'll extend the page and the template as needed or provide different views
 
 !! The development model
 We employ a distributed model based on GIT. We want this repository to be as complete as possible, including documentation in embedded ~TiddlyWikis and Bug reports. Each dev has its own GIT repo, devs are pulling from each other, they are free to cherry pick and try to make the combined version work. Point is that everyone can clone the git, negotiate with the others what s(he) wants to do, and hack on. Every dev signs off his branch with an standardized signature. For small changes we provide a "Mob GIT", i.e. anonymously pushable git (which is untrusted of course). Cehteh is currently working on a git web frontend which makes the codebase in the mob-repo web-editable like a wiki.
 Will we need a stable version or an official branch?  not yet — as long as the team is small it will work more painless without. At some point, when the project is more mature, we will define an official branch. Later on we will have automated builds and regression test runs. As we do test-driven development anyways, it's just a question of someone setting up all the infrastructure, then we'll do it.
 Ichthyo proposes a new requirement: All devs should ensure the "master" branch of their respective repositories always passes the compiler and the test suite. ~Work-In-Progress should be done on branches. Rationale: it is sufficient to pull from the master branches, and you can be sure the version you pulled worked for the originator.
-A note on dependencies: it will be hard to target minimal dependencies for such a project, but we shall try not bloat it unnecessarily. Sometimes it can be sensible to rather re-invent a feature — esp. when it fits into the core focus of the project — instead of depending on difficult to build and not sufficiently maintained external project. But we should avoid reinventing things like GUI toolkits.
-And, pretty much obvious, we try to stick to modern programming standards. That means, modules have interfaces, interfaces need some (minimal) documentation, and it is not allowed to bypass the interfaces and tangle everything in a wild fashion.
+A note on dependencies: it will be hard to target minimal dependencies for such a project, but we shall try not to bloat it unnecessarily. Sometimes it can be sensible to rather re-invent a feature — esp. when it fits into the core focus of the project — instead of depending on difficult to build and not sufficiently maintained external projects. But we should avoid reinventing things like GUI toolkits.
+And, pretty much obvious, we try to stick to modern programming standards. Read: modules have interfaces, interfaces need some (minimal) documentation, and it is not allowed to bypass the interfaces and tangle everything in a wild fashion.
 Currently, the project can be separated into three layers, which could evolve into sub-projects: Backend, ~Proc-Layer, GUI. For each part, the dev most deeply involved and most knowledgeable will take on the sometimes necessary leadership and have the last word in case of quarrels. Currently, Cehteh cares for the Backend and Ichthyo headed for the ~Proc-Layer. We have postponed any work on the GUI for now and don't participate in GUI toolkit discussions. If there is a dev willing to care for the GUI, collect proposals, care for usability and the users needs and finally code it up, then he will the one to decide what toolkit to use.
 We plan to make the discussion about GPL v3 a point on the agenda of the next meeting.
 
@@ -1067,25 +1068,28 @@ We plan to make the discussion about GPL v3 a point on the agenda of the next me
 * write a short status report for each mayor part //prior// to the meeting (saves us time). Maybe add an TODO list there
 * go through the open issues for the design process drafts
 * publish a protocol of each meeting on the (~Cinelerra-CV, ~LibOpenvideo) Mailinglists, in the TiddlyWiki and on pipapo.org
+* News, Protocols and the agenda of the next meeting can be found at the [[pipawiki-page|http://www.pipapo.org/pipawiki/Cinelerra3/MonthlyMeetings]]
 * next meeting on first Thursday in March (6.3.2008)
 
 !! Who works on what, what are the short term goals, what tasks are open?
 ''Ichthyo'' works on the processing layer. Current goal is to get the core of the builder fleshed out. Next goal is to create a clip object (dummy), add it to the EDL, hand the EDL over to the builder and let the builder make the first (preliminary) render nodes. (note: left many details for later).
-Ichthyo started coding his design draft and things seem to work out as intended. Some Keywords: Have a high-level model and a low level model. The former are the objects in the Session edited by the user, the latter is a network of completely configured render nodes, employing the same pull model as in Cinelerra-2. In between sits the Builder, translating high-level into low-level. This translation is done on demand (not for every frame).
+Ichthyo started coding his design draft and things seem to work out as intended. Some Keywords: Have a high-level model and a low level model. The former is comprised of the objects in the Session edited by the user, the latter is a network of completely configured render nodes, employing the same pull model as in Cinelerra-2. In between sits the Builder, translating high-level into low-level. This translation is done on demand (not for every frame).
 Current state in this part is: basic asset manager is done, asset objects (forming a hierarchy) can be created and will be registered automatically, it is possible to create a clip-"~MediaObject" from a media asset (without caring for any details regarding multichannel clips). Some support lib components are written, Session and data holders start up on demand and shutdown cleanly. The test suite is the only interesting executable, and this will remain so for quite some time. Currently writing the first parts of the Builder.
 Further plans/ideas: Ichthyo is rather determined to embed a Prolog interpreter (YAP Prolog) to handle all sorts of configuration queries in a rule-driven fashion. Things Ichthyo can't do in the near future: caring for session loading/saving serialisation plus storage backends, caring for a DB based implementation of the asset manager and integration with production support software, target the scheduler which will receive any edit operations initiated from the GUI.
 
 ''Cehteh'' is currently working on webgit, which is somewhat related inasmuch it will make small contributions to the mob repository much simpler. Previously he started with some foundation and support facilities. He plans to come back to the Backend implementation in about two weeks. The Backend is intended to handle all media (and even meta-)data as generalized frames. The render nodes network created by the ~Proc-Layer is completely stateless and all data is served from below. While it will be possible to address and access individual data within a frame (e.g. audio samples), frames are the smallest unit for memory and cache management. No plans to use a tiled memory model or to support frames larger than aprox. 20-40% of the available RAM.
-Cehteh's design plan includes a scheduler to organize the access to the raw data, monitor the timings and prefetch data as needed. This scheduler will be configurable via quality preferences ("need realtime", "need perfect quality"). Further, there will be an elaborate caching scheme trying hard to avoid re-rendering any frames already calculated previously. Temporary data will be backed by files and thus swapped out — this swapout and size of temporary data is to be monitored and adjusted on load — and all temporary data is kept as most-recent-used cache discipline. Incoming and outgoing footage shall mostly be handled by using mmaped buffers. The rationale is to avoid unnecessary copy from kernel to user space and wasting memory for an additional in-kernel buffer. Writing via a mmapped buffer is little more tricky; there will be a in-place writing which is used for indices and other precalculated data which needs updates, and the processing layer can query write buffers which are actually a small cache/ring and then comited to the file. Basically, mmapping is a clean solution if you can design for it, and it's portable (posix)
+Cehteh's design plan includes a scheduler to organize the access to the raw data, monitor the timings and prefetch data as needed. This scheduler will be configurable via quality preferences ("need realtime", "need perfect quality"). Further, there will be an elaborate caching scheme trying hard to avoid re-rendering any frames already calculated previously. Temporary data will be backed by files and thus swapped out — this swapout and size of temporary data is to be monitored and adjusted according to the current load — and all temporary data is kept as most-recent-used cache discipline. Incoming and outgoing footage shall mostly be handled by using mmaped buffers. The rationale is to avoid unnecessary copy from kernel to user space and wasting memory for an additional in-kernel buffer. Writing via a mmapped buffer is little more tricky; there will be a in-place writing which is used for indices and other precalculated data which needs updates, and the processing layer can query write buffers which are actually a small cache/ring and then comited to the file. Basically, mmapping is a clean solution if you can design for it, and it's portable (posix)
 Things to do: object serialisation backend is sometime on Cehteh's schedule, but that's ahead and if someone else helps or takes over it would be OK. Even more true for a DB based backend for the asset manager.
 
+''Gmerlin'' plans to implement grayscale support for GAVL, so the upper layers can store arbitrary data in it.
+
 __about multithreading__: since the render nodes are stateless they can be driven in multiple threads (but inter frame dependencies need to be resolved/serialized). Mostly the backend manages threads and does that quite conservatively (compared to Cinelerra-2 which massively creates separate threads for small tasks). Any edit operations initiated from GUI go to a scheduler in the middle layer, which enqueues and effectively serializes operations done to the "media objects" in the high-level model. The editing operations themselves are //not threadsafe // by design, they rely on being scheduled correctly. The builder is triggered from this ~Proc-Layer scheduler and starts in one separate thread, and when done, we swap whole parts of the render nodes network and then the backend can re(start) rendering as needed.
 
 !!The naming discussion
 The discussion looks healthy so far... People can add new proposals on the [[pipawiki|http://www.pipapo.org/pipawiki/Cinelerra3/Names]]. intersting names are still coming in, so we should just let the name-choosing game go on for a while. And, btw, we //can// depart from beeing similar to "Cinelerra" ;-) 
 Let's say, we need a person volonteering to guide/moderate the selection, going over the list and scratching inammprobiate ones. Criteria for good names being:
 * should not be an existing project
-* should be "googeable"
+* should be "googleable"
 * should not be offensive
 * should have one of the free top level domains (.net, .org)
 * should be compatible with educational institutions (sorry, no pr0nedit :)

From 113678ff9324ad45836b354de4e58c473017232d Mon Sep 17 00:00:00 2001
From: Ichthyostega 
Date: Fri, 15 Feb 2008 02:56:25 +0100
Subject: [PATCH 02/36] some refacturing of the (preliminary) struct asset
 impl...

---
 doc/devel/.gitignore                 |  2 +
 src/proc/asset/procpatt.cpp          | 56 ++++++++++------------------
 src/proc/asset/procpatt.hpp          |  6 +--
 src/proc/asset/struct.cpp            | 25 +++++++++++++
 src/proc/asset/struct.hpp            |  3 ++
 src/proc/asset/structfactoryimpl.hpp |  4 +-
 6 files changed, 55 insertions(+), 41 deletions(-)
 create mode 100644 doc/devel/.gitignore

diff --git a/doc/devel/.gitignore b/doc/devel/.gitignore
new file mode 100644
index 000000000..96886436c
--- /dev/null
+++ b/doc/devel/.gitignore
@@ -0,0 +1,2 @@
+,doxylog
+html/*
diff --git a/src/proc/asset/procpatt.cpp b/src/proc/asset/procpatt.cpp
index ec9ecb781..f7ce8895d 100644
--- a/src/proc/asset/procpatt.cpp
+++ b/src/proc/asset/procpatt.cpp
@@ -32,46 +32,26 @@ using util::isnil;
 namespace asset
   {
   
-  namespace // ProcPattern implementation details
-    {
-      /** @internal derive a sensible asset ident tuple when creating 
-       *  a processing pattern asset based on a query
-       *  @todo define the actual naming scheme of struct assets
-       */
-      const Asset::Ident
-      createPatternIdent (const string& properties)
-        {
-          string name ("pattern-" + properties);  // TODO something sensible here; append number, sanitize etc.
-          TODO ("Implement ProcPatt name scheme!!");
-          Category category (STRUCT,"patterns");
-          return Asset::Ident (name, category );
-        }
-    } 
   
-  /** */
-  ProcPatt::ProcPatt (const string& properties)
-    : Struct (createPatternIdent (properties)),
-      propDescriptor_ (properties)
+  /** new processing pattern with empty instruction list.
+   *  @todo preliminary implementation, storing the capabilities
+   *        in the asset name field. We can do better, when
+   *        it's clear what capabilities we need
+   */
+  ProcPatt::ProcPatt (const Asset::Ident& idi)
+    : Struct (idi),
+      instructions_()
+  { }
+  
+  
+  /** @internal used for creating a clone copy */
+  ProcPatt::ProcPatt (const Asset::Ident& idi, const InstructionSequence& instru)
+    : Struct (idi),
+      instructions_(instru)
   {
     TODO ("verify building instructions, maybe preprocess...");
   }
-
-  /** @internal used for creating a clone */
-  ProcPatt::ProcPatt (const string& props, const InstructionSequence& instructs)
-    : Struct (createPatternIdent (props)),
-      propDescriptor_ (props),
-      instructions_ (instructs)
-  { }
-
   
-  /** query the currently defined properties of this
-      processing pattern for a stream-ID predicate */
-  const string& 
-  ProcPatt::queryStreamID()  const
-  {
-    TODO ("really implement querying the properties");
-    return propDescriptor_; /////////////////////////////TODO grober Unfug
-  }
   
   
   /** create a new ProcPatt asset as a literal copy
@@ -84,7 +64,11 @@ namespace asset
   ProcPatt::newCopy (string newID)  const
   {
     TODO ("implement the Pattern-ID within the propDescriptor!");
-    ProcPatt* pP = new ProcPatt (this->propDescriptor_, this->instructions_);
+    TODO ("implement a consitent struct asset naming scheme at one central location!!!!!");
+    const Asset::Ident newIdi ( this->ident.name+".X"
+                              , this->ident.category
+                              );
+    ProcPatt* pP = new ProcPatt (newIdi, this->instructions_);
     return AssetManager::instance().wrap (*pP);
   }
   
diff --git a/src/proc/asset/procpatt.hpp b/src/proc/asset/procpatt.hpp
index 5cd22e1e1..593c57a0f 100644
--- a/src/proc/asset/procpatt.hpp
+++ b/src/proc/asset/procpatt.hpp
@@ -52,17 +52,15 @@ namespace asset
    */
   class ProcPatt : public Struct
     {
-      string propDescriptor_;
       InstructionSequence instructions_;
       
-      ProcPatt (const string& props, const InstructionSequence& instructs);
+      ProcPatt (const Asset::Ident&, const InstructionSequence&);      
       
     protected:
-      explicit ProcPatt (const string& propDescriptor);
+      explicit ProcPatt (const Asset::Ident& idi);
       friend class StructFactoryImpl;
       
     public:
-      const string& queryStreamID()  const;
       shared_ptr newCopy (string newID) const;
       
       ProcPatt& attach (Symbol where, PProc& node);
diff --git a/src/proc/asset/struct.cpp b/src/proc/asset/struct.cpp
index 729da826a..47586202a 100644
--- a/src/proc/asset/struct.cpp
+++ b/src/proc/asset/struct.cpp
@@ -34,6 +34,12 @@
 #include "common/util.hpp"
 #include "nobugcfg.h"
 
+#include 
+
+using boost::regex;
+using boost::smatch;
+using boost::regex_search;
+
 using mobject::Session;
 using cinelerra::query::normalizeID;
 
@@ -47,6 +53,25 @@ namespace asset
   
   /****** NOTE: not really implemented yet. What follows is partially a hack to build simple tests *******/
 
+  namespace // Implementation details
+    {
+    regex streamID_pattern("stream\\(\\s*(\\w+)\\s*\\)");
+  } 
+  
+  
+  
+  /** query the currently defined properties of this
+      structural asset for a stream-ID predicate */
+  const string
+  Struct::queryStreamID()  const
+  {
+    smatch match;
+    
+    if (regex_search (this->ident.name, match, streamID_pattern))
+      return string (match[1]);
+    else
+      return "";
+  }
 
   
   
diff --git a/src/proc/asset/struct.hpp b/src/proc/asset/struct.hpp
index e9cb9de7d..4beb5479e 100644
--- a/src/proc/asset/struct.hpp
+++ b/src/proc/asset/struct.hpp
@@ -84,6 +84,9 @@ namespace asset
           return static_cast& > (Asset::getID()); 
         }
       
+      const string queryStreamID()  const;
+      
+      
     protected:
       Struct (const Asset::Ident& idi) : Asset(idi) {}
       friend class StructFactory;
diff --git a/src/proc/asset/structfactoryimpl.hpp b/src/proc/asset/structfactoryimpl.hpp
index 506baea83..a1086a9fa 100644
--- a/src/proc/asset/structfactoryimpl.hpp
+++ b/src/proc/asset/structfactoryimpl.hpp
@@ -84,7 +84,9 @@ namespace asset
       const Asset::Ident
       createIdent (const Query& query)
         {
-          string name (Traits::namePrefix + query);  // TODO something sensible here; append number, sanitize etc.
+          static int i=0;
+          static format namePattern ("%s%d-%s"); // TODO finally just use the capability string as name??
+          string name = str(namePattern % Traits::namePrefix % (++i) %  query);
           TODO ("struct asset naming scheme??");
           Category cat (STRUCT, Traits::catFolder);
           return Asset::Ident (name, cat );

From 34b14a226ea9f40afea8c9007a23be32d393e9e6 Mon Sep 17 00:00:00 2001
From: Ichthyostega 
Date: Sat, 16 Feb 2008 02:47:01 +0100
Subject: [PATCH 03/36] defer creation of the empty default sesison, avoids
 running complex code in static initialisation

---
 src/proc/mobject/session.hpp                 |  4 ++
 src/proc/mobject/session/sessionimpl.hpp     |  2 +-
 src/proc/mobject/session/sessmanagerimpl.cpp | 49 ++++++++++++++++----
 3 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/src/proc/mobject/session.hpp b/src/proc/mobject/session.hpp
index 149dc6c82..d8b89d16c 100644
--- a/src/proc/mobject/session.hpp
+++ b/src/proc/mobject/session.hpp
@@ -141,6 +141,10 @@ namespace mobject
         virtual ~SessManager() {};
       };
 
+      
+      CINELERRA_ERROR_DECLARE (CREATE_SESSION);  ///< unable to create basic session.
+
+
   } // namespace mobject::session
 
 } // namespace mobject
diff --git a/src/proc/mobject/session/sessionimpl.hpp b/src/proc/mobject/session/sessionimpl.hpp
index d9dc1f078..38448ac41 100644
--- a/src/proc/mobject/session/sessionimpl.hpp
+++ b/src/proc/mobject/session/sessionimpl.hpp
@@ -98,7 +98,7 @@ namespace mobject
         virtual void reset () ;
         virtual void load ()  ;
         virtual void save ()  ;
-        virtual Session* operator-> ()  throw() { return pImpl_.get(); }
+        virtual SessionImpl* operator-> ()  throw() ;
       };
 
       
diff --git a/src/proc/mobject/session/sessmanagerimpl.cpp b/src/proc/mobject/session/sessmanagerimpl.cpp
index ca2797151..ad94c9949 100644
--- a/src/proc/mobject/session/sessmanagerimpl.cpp
+++ b/src/proc/mobject/session/sessmanagerimpl.cpp
@@ -39,6 +39,7 @@
 #include "proc/mobject/session.hpp"
 #include "proc/mobject/session/sessionimpl.hpp"
 #include "proc/mobject/session/defsmanager.hpp"
+#include "common/error.hpp"
 
 using boost::scoped_ptr;
 
@@ -48,17 +49,49 @@ namespace mobject
   {
   namespace session
     {
+    
+    CINELERRA_ERROR_DEFINE (CREATE_SESSION, "unable to create basic session");
+    
+    /** Access to the "current session", which actually is
+     *  an SessionImpl instance. This session object is created 
+     *  either by loading an existing session, or on demand by
+     *  this accessor function here (when no session was loaded
+     *  or created)
+     *  @note any exceptions arising while building the basic
+     *        session object(s) will halt the system.
+     */
+    SessionImpl* 
+    SessManagerImpl::operator-> ()  throw() 
+    { 
+      if (!pImpl_)
+        try
+          { // create empty default configured session
+            this->reset();
+          }
+        catch (...)
+          {
+            ERROR (oper, "Unrecoverable Failure while creating the empty default session.");
+            throw cinelerra::error::Fatal ( "Failure while creating the basic session object. Sysstem halted." 
+                                          , CINELERRA_ERROR_CREATE_SESSION );
+          }
 
-    /** Besides creating the single system-wide Session manger instance,
-     *  creates an empty default Session as well.
-     *  @note any exceptions arising in the course of this will halt
-     *        the system (and this behaviour is desirable).
+          
+      return pImpl_.get();
+    }
+
+    
+    
+    /** Initially (at static init time), only the single system-wide 
+     *  Session manger instance is created. It can be used to load an
+     *  existing session; otherwise an empty default Session an a
+     *  Defaults manager (Config Query system) is created at first
+     *  \link #operator-> access \endlink to the sesion object.
      */
     SessManagerImpl::SessManagerImpl ()  throw()
-      : pDefs_ (new DefsManager),
-        pImpl_ (new SessionImpl (*pDefs_))
-    {
-    }
+      : pDefs_ (0),
+        pImpl_ (0)
+    { }
+    
 
     /** @note no transactional behaviour. 
      *        may succeed partial.

From ea0416881e9c891eff4fe3142fd62cbc64c2bee3 Mon Sep 17 00:00:00 2001
From: Ichthyostega 
Date: Mon, 18 Feb 2008 04:16:53 +0100
Subject: [PATCH 04/36] WIP towards a asset::Struct naming scheme

---
 src/common/query.cpp                          | 37 +++++++++++
 src/common/query.hpp                          |  9 ++-
 src/common/query/mockconfigrules.cpp          | 18 +++++-
 src/proc/asset/pipe.cpp                       | 35 +++++------
 src/proc/asset/pipe.hpp                       |  4 +-
 src/proc/asset/struct.cpp                     | 37 +++++------
 src/proc/asset/struct.hpp                     |  1 +
 src/proc/asset/structfactoryimpl.hpp          | 61 ++++++++++++-------
 tests/components/proc/asset/basicpipetest.cpp | 11 ++--
 9 files changed, 143 insertions(+), 70 deletions(-)

diff --git a/src/common/query.cpp b/src/common/query.cpp
index bb3e6ae86..152086bc3 100644
--- a/src/common/query.cpp
+++ b/src/common/query.cpp
@@ -26,10 +26,18 @@
 #include "nobugcfg.h"
 
 #include 
+#include 
+#include 
 
+using std::map;
+using boost::regex;
+using boost::smatch;
+using boost::regex_search;
 using boost::algorithm::is_upper;
 using boost::algorithm::is_alpha;
 
+using util::contains;
+
 
 namespace cinelerra
   {
@@ -48,6 +56,35 @@ namespace cinelerra
       if (is_upper() (first))
         id[0] = std::tolower (first);
     }
+
+    
+    
+    
+    namespace // Implementation details
+      {
+      map regexTable;
+    }
+    
+    /** (preliminary) helper: instead of really parsing and evaluating the terms,
+     *  just do a regular expression match to extract the literal argument 
+     *  behind the given predicate symbol. e.g calling
+     *  queryID ("stream", "id(abc), stream(mpeg)") 
+     *  yields "mpeg"
+     */
+    const string
+    extractID (Symbol sym, const string& termString)
+    {
+      
+      if (!contains (regexTable, sym))
+        regexTable[sym] = regex (string(sym)+="\\(\\s*([\\w_\\.\\-]+)\\s*\\)"); 
+      
+      smatch match;
+      if (regex_search (termString, match, regexTable[sym]))
+        return string (match[1]);
+      else
+        return "";
+    
+  } 
   
   } // namespace query
     
diff --git a/src/common/query.hpp b/src/common/query.hpp
index b5575f0da..9bdb3a389 100644
--- a/src/common/query.hpp
+++ b/src/common/query.hpp
@@ -28,11 +28,13 @@
 #include 
 #include 
 
+#include 
 
 
 namespace cinelerra
   {
   using std::string;
+  using boost::format;
 
   /* ==== comon definitions for rule based queries ==== */
   
@@ -47,7 +49,9 @@ namespace cinelerra
   class Query : public std::string
     {
     public:
-      Query (const string& predicate="") : string(predicate) {}
+      explicit Query (const string& predicate="") : string(predicate) {}
+      explicit Query (format& pattern)            : string(str(pattern)) {}
+      
       
       const string asKey()  const
         {
@@ -65,6 +69,9 @@ namespace cinelerra
      */
     void normalizeID (string& id);
     
+    const string extractID (Symbol, const string& termString);
+
+    
   
   } // namespace query
     
diff --git a/src/common/query/mockconfigrules.cpp b/src/common/query/mockconfigrules.cpp
index 52f7f93fd..54ba5aaf1 100644
--- a/src/common/query/mockconfigrules.cpp
+++ b/src/common/query/mockconfigrules.cpp
@@ -67,6 +67,14 @@ namespace cinelerra
         Ptr obj = Struct::create (query);
         return AnyPair(query.asKey(), obj);
       }
+      
+      /** shortcut for simply accessing a table entry */ 
+      template
+      any&
+      item (PTAB& table, const string& query)
+      {
+        return (*table)[Query(query).asKey()];
+      }
     
     }
     
@@ -82,8 +90,16 @@ namespace cinelerra
       INFO (config, "creating mock answers for some config queries...");
       isInit_ = true; // allow re-entrance
       
+      typedef const ProcPatt cPP;
+      
       // for baiscpipetest.cpp ---------
-      answer_->insert (entry_Struct ("stream(teststream)"));
+      answer_->insert (entry_Struct ("stream(video)"));
+      answer_->insert (entry_Struct ("stream(teststream)"));
+      item (answer_, "stream(default)")  = item (answer_,"stream(video)"); //TODO killme
+      
+      answer_->insert (entry_Struct ("pipe(master), stream(video)"));
+      item (answer_, "pipe(default)")   = item(answer_,"pipe(master), stream(video)"); //TODO killme
+      TODO ("remove the default entries!!!  DefaultsManager should find them automatically");
     }
 
     
diff --git a/src/proc/asset/pipe.cpp b/src/proc/asset/pipe.cpp
index e15a09254..78899e844 100644
--- a/src/proc/asset/pipe.cpp
+++ b/src/proc/asset/pipe.cpp
@@ -22,35 +22,30 @@
 
 
 #include "proc/asset/pipe.hpp"
+#include "common/util.hpp"
+
+using util::isnil;
 
 namespace asset
   {
   
-  namespace // Pipe Asset implementation details
-    {
-      /** @internal derive a sensible asset ident tuple when creating 
-       *  a pipe asset based on a query
-       *  @todo define the actual naming scheme of struct assets
-       */
-      const Asset::Ident
-      createPipeIdent (PProcPatt& wiring, string& id, wstring& shortD, wstring& longD)
-        {
-          string name ("pipe-" + id);  // TODO something sensible here; append number, sanitize etc.
-          TODO ("Implement pipe name scheme!!");
-          Category category (STRUCT,"pipes");
-          return Asset::Ident (name, category );
-        }
-    } 
   
   /** */
-  Pipe::Pipe (PProcPatt& wiring, string pipeID, wstring shortDesc, wstring longDesc) 
-    : Struct (createPipeIdent (wiring,pipeID,shortDesc,longDesc)),
+  Pipe::Pipe ( const Asset::Ident& idi
+             , PProcPatt& wiring
+             , const string& pipeID
+             , wstring shortName
+             , wstring longName
+             ) 
+    : Struct (idi),
       pipeID_ (pipeID),
       wiringTemplate(wiring),
-      shortDesc (shortDesc),
-      longDesc (longDesc)
+      shortDesc (shortName),
+      longDesc (longName)
   {
-    
+    REQUIRE (!isnil (pipeID));
+    if (isnil (shortDesc))
+      shortDesc = wstring (pipeID.begin(), pipeID.end());
   }
 
   
diff --git a/src/proc/asset/pipe.hpp b/src/proc/asset/pipe.hpp
index 0761efe65..ea354361d 100644
--- a/src/proc/asset/pipe.hpp
+++ b/src/proc/asset/pipe.hpp
@@ -52,7 +52,7 @@ namespace asset
    */
   class Pipe : public Struct
     {
-      string pipeID_;
+      const string pipeID_;
       PProcPatt wiringTemplate;
       
     public:
@@ -66,7 +66,7 @@ namespace asset
 
       
     protected:
-      Pipe (PProcPatt& wiring, string pipeID="", wstring shortDesc =wstring(), wstring longDesc =wstring()) ;
+      Pipe (const Asset::Ident&, PProcPatt& wiring, const string& pipeID, wstring shortName =wstring(), wstring longName =wstring()) ;
       friend class StructFactory;
       friend class StructFactoryImpl;
 
diff --git a/src/proc/asset/struct.cpp b/src/proc/asset/struct.cpp
index 47586202a..bcaff3118 100644
--- a/src/proc/asset/struct.cpp
+++ b/src/proc/asset/struct.cpp
@@ -26,7 +26,6 @@
 #include "proc/asset/procpatt.hpp"
 #include "proc/asset/track.hpp"
 #include "proc/asset/pipe.hpp"
-#include "proc/mobject/session.hpp"
 #include "common/configrules.hpp"
 
 #include "proc/asset/structfactoryimpl.hpp"
@@ -34,18 +33,16 @@
 #include "common/util.hpp"
 #include "nobugcfg.h"
 
-#include 
+#include 
 
-using boost::regex;
-using boost::smatch;
-using boost::regex_search;
+using boost::format;
 
-using mobject::Session;
+using cinelerra::Symbol;
 using cinelerra::query::normalizeID;
-
-using cinelerra::ConfigRules;
 using cinelerra::query::QueryHandler;
+using cinelerra::ConfigRules;
 
+using util::contains;
 
 
 namespace asset
@@ -53,11 +50,6 @@ namespace asset
   
   /****** NOTE: not really implemented yet. What follows is partially a hack to build simple tests *******/
 
-  namespace // Implementation details
-    {
-    regex streamID_pattern("stream\\(\\s*(\\w+)\\s*\\)");
-  } 
-  
   
   
   /** query the currently defined properties of this
@@ -65,12 +57,15 @@ namespace asset
   const string
   Struct::queryStreamID()  const
   {
-    smatch match;
-    
-    if (regex_search (this->ident.name, match, streamID_pattern))
-      return string (match[1]);
-    else
-      return "";
+    return cinelerra::query::extractID ("stream", this->ident.name);
+  }
+  
+  /** query the currently defined properties of this
+      structural asset for a stream-ID predicate */
+  const string
+  Struct::queryPipeID()  const
+  {
+    return cinelerra::query::extractID ("pipe", this->ident.name);
   }
 
   
@@ -126,8 +121,8 @@ namespace asset
   {
     normalizeID (pipeID);
     normalizeID (streamID);
-    PProcPatt processingPattern = Session::current->defaults (Query("stream("+streamID+")"));
-    Pipe* pP = new Pipe (processingPattern, pipeID);
+    static format descriptor("pipe(%s), stream(%s).");
+    Pipe* pP = impl_->fabricate (Query (descriptor % pipeID % streamID));
     return AssetManager::instance().wrap (*pP);
   }
 
diff --git a/src/proc/asset/struct.hpp b/src/proc/asset/struct.hpp
index 4beb5479e..ed6642690 100644
--- a/src/proc/asset/struct.hpp
+++ b/src/proc/asset/struct.hpp
@@ -85,6 +85,7 @@ namespace asset
         }
       
       const string queryStreamID()  const;
+      const string queryPipeID()    const;
       
       
     protected:
diff --git a/src/proc/asset/structfactoryimpl.hpp b/src/proc/asset/structfactoryimpl.hpp
index a1086a9fa..3d78920d3 100644
--- a/src/proc/asset/structfactoryimpl.hpp
+++ b/src/proc/asset/structfactoryimpl.hpp
@@ -34,16 +34,22 @@
 #define ASSET_STRUCTFACTORYIMPL_H
 
 
+#include "proc/mobject/session.hpp"
 #include "common/configrules.hpp"
 #include "common/error.hpp"
+#include "common/util.hpp"
 
 #include 
 
 using boost::format;
 
+using mobject::Session;
+
+using util::isnil;
+using util::contains;
 using asset::Query;
 using cinelerra::query::CINELERRA_ERROR_CAPABILITY_QUERY;
-
+using cinelerra::query::extractID;
 
 namespace asset
   {
@@ -54,16 +60,20 @@ namespace asset
     {
       static Symbol namePrefix;
       static Symbol catFolder;
+      static Symbol idSymbol;
     };
   
-  template<> Symbol Traits::namePrefix = "track-";
+  template<> Symbol Traits::namePrefix = "track";
   template<> Symbol Traits::catFolder  = "tracks";
+  template<> Symbol Traits::idSymbol   = "track";
   
-  template<> Symbol Traits::namePrefix = "pipe-";
+  template<> Symbol Traits::namePrefix = "pipe";
   template<> Symbol Traits::catFolder  = "pipes";
+  template<> Symbol Traits::idSymbol   = "pipe";
   
-  template<> Symbol Traits::namePrefix = "patt-";
+  template<> Symbol Traits::namePrefix = "patt";
   template<> Symbol Traits::catFolder  = "build-templates";
+  template<> Symbol Traits::idSymbol   = "procPatt";
   
   
   
@@ -78,30 +88,32 @@ namespace asset
 
       /** @internal derive a sensible asset ident tuple when creating 
        *  structural asset instances  based on a capability query
-       *  @todo define the actual naming scheme of struct assets
        */
       template
       const Asset::Ident
       createIdent (const Query& query)
         {
-          static int i=0;
-          static format namePattern ("%s%d-%s"); // TODO finally just use the capability string as name??
-          string name = str(namePattern % Traits::namePrefix % (++i) %  query);
-          TODO ("struct asset naming scheme??");
+          string name (query); 
+          string nameID = extractID (Traits::idSymbol, query);
+          if (isnil (nameID))
+            {
+               // no name-ID contained in the query...
+              //  so we'll create a new one
+              static int i=0;
+              static format namePattern ("%s.%d");
+              static format predPattern ("%s(%s), ");
+              nameID = str(namePattern % Traits::namePrefix % (++i) );
+              name.insert(0, 
+                       str(predPattern % Traits::idSymbol % nameID ));
+            }
+          ENSURE (!isnil (name));
+          ENSURE (!isnil (nameID));
+          ENSURE (contains (name, nameID));
+          
           Category cat (STRUCT, Traits::catFolder);
           return Asset::Ident (name, cat );
         }
       
-      typedef std::pair PipeIDs;
-    
-      PipeIDs
-      createPipeIdent (const Query& query)
-        {
-          string name (Traits::namePrefix + query);  // TODO get some more sensible dummy values
-          TODO ("pipe naming scheme??");
-          TODO ("actually extract the pipe stream type from the query...");
-          return PipeIDs (name, "data");                // dummy stream type
-        }
   
     
       
@@ -153,8 +165,15 @@ namespace asset
     Pipe* 
     StructFactoryImpl::fabricate (const Query& caps)
       {
-        PipeIDs ids (createPipeIdent (caps));
-        return recursive_create_ (ids.first, ids.second).get();
+        const Asset::Ident idi (createIdent (caps));
+        string pipeID = extractID ("pipe", idi.name);
+        string streamID = extractID ("stream", caps);
+        if (isnil (streamID)) streamID = "default"; 
+        PProcPatt processingPattern = Session::current->defaults (Query("stream("+streamID+")"));
+        return new Pipe( idi
+                       , processingPattern
+                       , pipeID
+                       );
       }
     
     
diff --git a/tests/components/proc/asset/basicpipetest.cpp b/tests/components/proc/asset/basicpipetest.cpp
index 315ba83a7..62644b95a 100644
--- a/tests/components/proc/asset/basicpipetest.cpp
+++ b/tests/components/proc/asset/basicpipetest.cpp
@@ -65,11 +65,12 @@ namespace asset
       {
         virtual void run(Arg arg) 
           {
-            string pipeID   = isnil(arg)?  "blackHole" : arg[1];
+            string pipeID   = isnil(arg)?  "Black Hole" : arg[1];
             string streamID = 2>arg.size()? "teststream" : arg[2] ;
             
             createExplicit (pipeID,streamID);
             create_or_ref (pipeID);
+            create_using_default ();
             dependProcPatt (pipeID);
           }
         
@@ -80,6 +81,7 @@ namespace asset
           { 
             string pID_sane (pID);
             normalizeID (pID_sane);
+            ASSERT (pID_sane != pID);
             
             PPipe thePipe = asset::Struct::create (pID,sID);
             
@@ -118,6 +120,7 @@ namespace asset
             ASSERT (c1 == c2);
             
             PPipe pipe3 = Pipe::query ("pipe("+pID2+")");
+//////////////////////////////////////////////////////////////TODO: er macht eine Neue, anstatt die Bestehende zu finden            
             ASSERT (pipe3 == pipe2);
           }
         
@@ -130,7 +133,7 @@ namespace asset
             ASSERT (pipe1 == Session::current->defaults (Query()));
             ASSERT (pipe1->ident.category.hasKind(VIDEO));
             ASSERT (pipe1->getProcPatt());
-            PProcPatt popa = Session::current->defaults (Query("pipe()"));
+            PProcPatt popa = Session::current->defaults (Query("pipe(default)"));
             ASSERT (popa == pipe1->getProcPatt());
             
             // several variants to query for "the default pipe"
@@ -138,14 +141,14 @@ namespace asset
             ASSERT (pipe2 == pipe1);
             pipe2 = asset::Struct::create (Query ());
             ASSERT (pipe2 == pipe1);
-            pipe2 = asset::Struct::create (Query ("pipe()"));
+            pipe2 = asset::Struct::create (Query ("pipe(default)"));
             ASSERT (pipe2 == pipe1);
             
             string sID = popa->queryStreamID(); // sort of a "default stream type"
             PPipe pipe3 = Pipe::query ("stream("+sID+")");
             ASSERT (pipe3);
             ASSERT (pipe3->getProcPatt()->queryStreamID() == sID);
-            ASSERT (pipe3->getProcPatt() == Session::current->defaults (Query("stream("+sID+")")));
+            ASSERT (pipe3->getProcPatt() == Session::current->defaults (Query("stream("+sID+")")));
           }
         
         

From 4bbf3aa53f90f0b7795b27e8961183162ca63e66 Mon Sep 17 00:00:00 2001
From: Ichthyostega 
Date: Wed, 20 Feb 2008 04:05:37 +0100
Subject: [PATCH 05/36] test-driven-brainstorming: how to handle
 query-for-default?

---
 tests/51asset.tests                           |   2 +-
 tests/53session.tests                         |   4 +
 .../proc/mobject/session/defsmanagertest.cpp  | 165 ++++++++++++++++++
 wiki/renderengine.html                        |  96 ++++++----
 4 files changed, 232 insertions(+), 35 deletions(-)
 create mode 100644 tests/components/proc/mobject/session/defsmanagertest.cpp

diff --git a/tests/51asset.tests b/tests/51asset.tests
index 6d8195ceb..5e259e95e 100644
--- a/tests/51asset.tests
+++ b/tests/51asset.tests
@@ -34,7 +34,7 @@ return: 0
 END
 
 
-PLANNED "BasicPort_test" BasicPort_test <
+ 
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 2 of the
+  License, or (at your option) any later version.
+ 
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ 
+* *****************************************************/
+
+
+#include "common/test/run.hpp"
+#include "common/util.hpp"
+
+#include "proc/asset.hpp"
+#include "proc/asset/pipe.hpp"
+#include "common/query.hpp"
+#include "proc/assetmanager.hpp"
+#include "proc/mobject/session.hpp"
+
+#include 
+#include 
+
+using boost::format;
+using util::isnil;
+using std::string;
+
+
+namespace asset
+  {
+  namespace test
+    {
+    using mobject::Session;
+    using cinelerra::Query;
+    using cinelerra::query::normalizeID;
+    
+    
+    
+    /***********************************************************************
+     * @test basic behaviour of the defaults manager.
+     *       
  1. retrieving a "default" object repeatedly
  2. + *
  3. retrieving a more constrained "default" object
  4. + *
  5. failure registers a new "default"
  6. + *
+ * Using pipe assets as an example. The defaults manager shouldn't + * interfere with memory management (it holds weak refs). + */ + class DefsManager_test : public Test + { + virtual void run(Arg arg) + { + string pipeID = isnil(arg)? "Black Hole" : arg[1]; + string streamID = 2>arg.size()? "teststream" : arg[2] ; + + normalizeID (pipeID); + normalizeID (streamID); + + retrieveSimpleDefault (pipeID); + retrieveConstrainedDefault (pipeID, streamID); + pipeID = failureCreatesNewDefault(); + verifyRemoval (pipeID); + } + + + + + void retrieveSimpleDefault(string pID) + { + PPipe pipe1 = Pipe::query (""); // "the default pipe" + PPipe pipe2; + + // several variants to query for "the default pipe" + pipe2 = Pipe::query (""); + ASSERT (pipe2 == pipe1); + pipe2 = Pipe::query ("default(X)"); + ASSERT (pipe2 == pipe1); + pipe2 = Session::current->defaults(Query ()); + ASSERT (pipe2 == pipe1); + pipe2 = asset::Struct::create (Query ()); + ASSERT (pipe2 == pipe1); + pipe2 = asset::Struct::create (Query ("default(X)")); + ASSERT (pipe2 == pipe1); + } + + + void retrieveConstrainedDefault(string pID, string sID) + { + PPipe pipe1 = Pipe::query (""); // "the default pipe" + ASSERT (sID != pipe1->getProcPatt()->queryStreamID(), + "stream-ID \"%s\" not suitable for test, because " + "the default-pipe \"%s\" happens to have the same " + "stream-ID. We need it to be different", + sID.c_str(), pID.c_str() + ); + + string query_for_sID ("stream("+sID+")"); + PPipe pipe2 = Pipe::query (query_for_sID); + ASSERT (sID == pipe2->getProcPatt()->queryStreamID()); + ASSERT (pipe2 != pipe1); + ASSERT (pipe2 == Pipe::query (query_for_sID)); // reproducible + } + + + string failureCreatesNewDefault () + { + PPipe pipe1 = Session::current->defaults(Query ()); // "the default pipe" + + string new_pID (str (format ("dummy_%s_%i") + % pipe1->getPipeID() + % std::rand() + )); // make random new pipeID + string query_for_new ("pipe("+new_pID+")"); + PPipe pipe2 = Session::current->defaults(Query (query_for_new)); + + TODO ("a way to do only a query, without creating. Use this to check it is really added as default"); + + ASSERT (pipe1 != pipe2); + ASSERT (pipe2 == Pipe::query (query_for_new)); + return new_pID; + } + + + void verifyRemoval(string pID) + { + string query_for_pID ("pipe("+pID+")"); + size_t hash; + { + PPipe pipe1 = Pipe::query (query_for_pID); + hash = pipe1->getID(); + } + // now AssetManager should have the only ref + ID assetID (hash); + + AssetManager& aMang (AssetManager::instance()); + ASSERT ( aMang.known (assetID)); + aMang.remove (assetID); + ASSERT (!aMang.known (assetID)); + + TODO ("assure the bare default-query now fails..."); + PPipe pipe2 = Session::current->defaults(Query (query_for_pID)); + TODO ("assure the bare default-query now succeeds..."); + } + }; + + + /** Register this test class... */ + LAUNCHER (DefsManager_test, "function session"); + + + + } // namespace test + +} // namespace asset diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 5bc243c00..35ed4e339 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -797,7 +797,7 @@ Error: #f88
&rarr; [[Configuration Rules system|ConfigRules]]
-
+
Many features can be implemented by specifically configuring and wiring some unspecific components. Rather than tie the client code in need of some given feature to these configuration internals, in Cinelerra-3 the client can //query // for some kind of object providing the //needed capabilities. // Right from start (summer 2007), Ichthyo had the intention to implement such a feature using sort of a ''declarative database'', e.g. by embedding a Prolog system. By adding rules to the basic session configuration, users should be able to customize the semi-automatic part of Cinelerra's behaviour to great extent.
 
 [[Configuration Queries|ConfigQuery]] are used at various places, when creating and adding new objects, as well when building or optimizing the render engine node network.
@@ -808,7 +808,7 @@ Error: #f88
!anatomy of a Configuration Query The query is given as a number of logic predicates, which are required to be true. Syntactically, it is a string in prolog syntax, e.g. {{{stream(mpeg)}}}, where "stream" is the //predicate, // meaning here "the stream type is...?" and "mpeg" is a //term // denoting an actual property, object, thing, number etc &mdash; the actual kind of stream in the given example. Multible comma separated predicates are combined with logical "and". Terms may be //variable // at start, which is denoted syntactically by starting them with a uppercase letter. But any variable term need to be //bound // to some known value while computing the solution to the query, otherwise the query fails. A failed query is treated as a local failure, which may cause some operation being aborted or just some other possibility being chosen. -Queries are represented by instantiations of the {{{Query<TYPE>}}} template, because their actual meaning is "retrieve or create an object of TYPE, configured such that...!". At the C++ side, this ensures type safety and fosters programming against interfaces, while being implemented rule-wise by silently prepending the query with the predicate "{{{object(tYPE)}}}" +Queries are represented by instantiations of the {{{Query<TYPE>}}} template, because their actual meaning is "retrieve or create an object of TYPE, configured such that...!". At the C++ side, this ensures type safety and fosters programming against interfaces, while being implemented rule-wise by silently prepending the query with the predicate "{{{object(TYPE)}}}" !executing a Configuration Query Actually posing such an configuration query, for example to the [[Defaults Manager in the Sessison|DefaultsManagement]], may trigger several actions: First it is checked against internal object registries (depending on the target object type), which may cause the delivery of an already existing object (as reference, clone, or smart pointer). Otherwise, the system tries to figure out an viable configuration for a newly created object instance, possibly by issuing recursive queries. In the most general case this may silently impose additional decisions onto the //execution context // of the query &mdash; by default the session. @@ -818,6 +818,9 @@ At start and for debugging/testing, there is an ''dummy'' implementation using a &rarr; [[considerations for a Prolog based implementation|QueryImplProlog]] &rarr; see {{{src/common/query/mockconfigrules.cpp}}} for the table with the hard wired (mock) answers + +{{red{WARN}}} there is an interference with the (planned) Undo function: a totally correct implementation of "Undo" would need to remember and restore the internal state of the query system (similar to backtracking). But, more generally, such an correct implementation is not achievable, because we are never able to capture and control the whole state of a real world system doing such advanced things like video and sound processing. Seemingly we have to accept that after undoing an action, there is no guarantee we can re-do it the same way as it was first time. +
@@ -839,10 +842,36 @@ This is an very important external Interface, because it links together all thre
[[ProcLayer and Engine]]
 
-
-
For several components and properties there is an implicit default value or configuration; it is stored alongside with the session. The intention is that defaults never create an error, instead, they are to be extended silently on demand. Objects configured according to this defaults can be retrieved at the [[Session]] interface by a set of overloaded functions {{{Session::current->default(Query<TYPE> ("query string"))}}}, where the //query string // defines a capability query similar to what is employed for pipes, stream types, codecs etc. The Queries are implemented by [[configuration rules|ConfigRules]]
+
+
As detailed in the [[definition|DefaultsManagement]], {{{default(Obj)}}} is sort of a Joker along the lines "give me a suitable Object and I don't care for further details". Actually, default objects are implemented by the {{{mobject::session::DefsManager}}}, which remembers and keeps track of anything labeled as "default". This defaults manager is a singleton and can be accessed via the [[Session]] interface, meaning that the memory regarding defaults is part of the session state. Accessing an object via the query for an default actually //tagges// this object (stores a weak ref in the ~DefsManager). Alongside with each object successfully queried via "default", the degree of constriction is remembered, i.e. the number of additional conditions contained in the query. This enables us to search for default objects starting with the most unspecific.
+
+!Skeleton
+# ''search'': using the predicate {{{default(X)}}} enumerates existing objects of suitable type
+#* candidates are delivered starting with the least constrained default
+#* the argument is unified
+#** if the rest of the query succeeds we've found our //default object// and are happy.
+#** otherwise, if all enumerated solutions are exhausted without success, we enter
+# ''default creation'': try to get an object fulfilling the conditions and remember this situation
+#* we issue an ConfigQuery with the query terms //minus// the {{{default(X)}}} predicate
+#* it depends on the circumstances how this query is handled. Typically the query resolution first searches existing objects and then creates a new instance to match the required capabilities. Usually, this process succeeds, but there can be configurations leading to failure.
+#** failing the ~ConfigQuery is considered an (non-critical) exception (throws), as defaults queries are supposed to succeed
+#** otherwise, the newly created object is remembered (tagged) as new default, together with the degree of constriction
+
+!!!Implementation details
+Taken precisely, the "degree of constriction" yields only a partial ordering &mdash; but as the "default"-predicate is sort of a existential quantification anyways, its sole purpose is to avoid polluting the session with unnecessary default objects, and we don't need to care for absolute precision. A suitable approximation is to count the number of predicates terms in the query and use a pqueue (separate for each Type) to store weak refs to the the objects tagged as "default"
+{{red{WARN}}} there is an interference with the (planned) Undo function. This is a general problem of the config queries; it seems reasonable we can ignore this issue.
+
+!!!Problems with the (preliminary) mock implementation
+As we don't have a Prolog interpreter on board yet, we utilize a mock store with preconfigured answers. (see {{{MockConfigQuery}}}). As this preliminary solution is lacking the ability to create new objects, we need to resort to some trickery here (please look away). The overall logic is quite broken, because the system isn't capable to do any real resolution &mdash; if we ignore this fact, the rest of the algorithm can be implemented, tested and used right now.
 
+
+
For several components and properties there is an implicit default value or configuration; it is stored alongside with the session. The intention is that defaults never create an error, instead, they are to be extended silently on demand. Objects configured according to this defaults can be retrieved at the [[Session]] interface by a set of overloaded functions {{{Session::current->default(Query<TYPE> ("query string"))}}}, where the //query string // defines a capability query similar to what is employed for pipes, stream types, codecs etc. The Queries are implemented by [[configuration rules|ConfigRules]]
+
+!!!!what is denoted by {{{default}}}?
+{{{default(Obj)}}} is a predicate expressing that the object {{{Obj}}} can be considered the default setup under the given conditions. Using the //default// can be considered as a shortcut for actually finding a exact and unique solution. The latter would require to specify all sorts of detailed properties up to the point where only one single object can satisfy all conditions. On the other hand, leaving some properties unspecified would yield a set of solutions (and the user code issuing the query had to provide means for selecting one soltution from this set). Just falling back on the //default// means that the user code actually doesn't care for any additional properties (as long as the properties he //does// care for are satisfied). Nothing is said specifically on //how//&nbsp; this default gets configured; actually there can be rules //somewhere,// and, additionally, anything encountered once while asking for a default can be re-used as default under similar circumstances.
+&rarr; [[implementing defaults|DefaultsImplementation]]
+
Along the way of working out various [[implementation details|ImplementationDetails]], decisions need to be made on how to understand the different facilities and entities and how to tackle some of the problems. This page is mainly a collection of keywords, summaries and links to further the discussion. And the various decisions should allways be read as proposals to solve some problem at hand...
 
@@ -2226,6 +2255,33 @@ DAMAGE.
 <html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
 ***/
+
+
Pipes play an central role within the Proc Layer, because for everything placed and handled within the EDL, the final goal is to get it transformed into data which can be retrieved at some pipe's exit port. Pipes are special facilities, rather like inventory, separate and not treated like all the other objects.
+We don't distinguish between "input" and "output" ports &mdash; rather, pipes are thought to be ''hooks for making connections to''. By following this line of thought, each pipe has an input side and an output side and is in itself something like a ''Bus'' or ''processing chain''. Other processing entities like effects and transitions can be placed (attached) at the pipe, resulting them to be appended to form this chain. Likewise, we can place [[wiring requests|WiringRequest]] to the pipe, meaning we want it connected so to send it's output to another destination pipe. The [[Builder]] may generate further wiring requests to fulfil the placement of other entities.
+Thus //Pipes are the basic building blocks// of the whole render network. We distinguish ''global available'' Pipes, which are like the sum groups of a mixing console, and the ''lokal pipe'' or [[source port|ClipSourcePort]] of the individual clips, which exist only within the duration of the corresponding clip. The design //limits the possible kinds of pipes // to these two types &mdash; thus we can build local processing chains at clips and global processing chains at the global pipes of the session and that's all we can do. (because of the flexibility which comes with the concept of [[placements|Placement]], this is no real limitation)
+
+The GUI can connect the viewer(s) to some pipe (and moreover can use [[probe points|ProbePoint]] placed like effects and connected to some pipe), and likewise, when starting a ''render'', we get the opportunity to specify the pipes to pull the data from. Pulling data from some pipe is the (only) way to activate the render nodes network reachable from this pipe.
+
+&rarr; [[Handling of Tracks|TrackHandling]]
+&rarr; [[Handling of Pipes|PipeHandling]]
+
+
+
+
+
!Identification
+Pipes are distinct objects and can be identified by their asset ~IDs. Besides, as for all [[structural assets|StructAsset]] there are extended query capabilities, including a symbolic pipe-id and a media (stream) type id. Any pipe can accept and deliver exactly one media stream kind (which may be inherently structured though, e.g. spatial sound systems or stereoscopic video)
+
+!creating pipes
+Pipe assets are created automatically by being used and referred. The [[Session]] holds a collection of global pipes, and further pipes can be created by using an new pipe reference in some placement. Moreover, every clip has an (implicit) [[source port|ClipSourcePort]], which will appear as pipe asset when first used (referred) while [[building|BuildProcess]].
+
+!removal
+Deleting a Pipe is an advanced operation, because it includes finding and "detaching" all references, otherwise the pipe will leap back into existence immediately. Thus, global pipe entries in the Session and pipe references in [[locating pins|LocatingPin]] within any placement have to be removed, while clips using a given source port will be disabled. {{red{todo: implementation deferred}}}
+
+!using Pipes
+there is not much you can do directly with a pipe asset. It is an point of reference, after all. Any connection to some pipe is only temporarily done by a placement in some part of the timeline, so it isn't stored with the pipe. You can edit the (user visible) description an you can globally disable a pipe asset. The pipe's ID and media stream type of course are fixed, because any connection and referral (via the asset ID) is based on them. Later on, we should provide a {{{rewire(oldPipe, newPipe)}}} to search any ref to the {{{oldPipe}}} and try to rewrite it to use the {{{newPipe}}}, possibly with a new media stream type.
+Pipes are integrated with the [[management of defaults|DefaultsManagement]]. For example, any pipe uses implicitly some [[processing pattern|ProcPatt]] &mdash; it may default to the empty pattern. This feature enables to apply some standard wiring to the pipes (e.g a fader for audio, similar to the classic mixing consoles). This //is // a global property of the pipe, but &mdash; contrary to the stream type &mdash; this pattern may be switched
+
+
A Placement represents a //relation:// it is always linked to a //Subject// (this being a [[Media Object|MObject]]) and has the meaning to //place// this Subject in some manner, either relatively to other Media Objects, or by some Constraint or simply absolute at (time,track). The latter case is especially important and represented by a special [[Sub-Interface|ExplicitPlacement]]
 
@@ -2351,34 +2407,6 @@ We need a way of addressing existing [[pipes|Pipe]]. Besides, as the Pipes and T
 //Note, we have yet to specify how exactly the building and rendering will work together with the backend. There are several possibilities how to structure the Playlist//
 
-
-
-Pipes play an central role within the Proc Layer, because for everything placed and handled within the EDL, the final goal is to get it transformed into data which can be retrieved at some pipe's exit port. Pipes are special facilities, rather like inventory, separate and not treated like all the other objects.
-We don't distinguish between "input" and "output" ports &mdash; rather, pipes are thought to be ''hooks for making connections to''. By following this line of thought, each pipe has an input side and an output side and is in itself something like a ''Bus'' or ''processing chain''. Other processing entities like effects and transitions can be placed (attached) at the pipe, resulting them to be appended to form this chain. Likewise, we can place [[wiring requests|WiringRequest]] to the pipe, meaning we want it connected so to send it's output to another destination pipe. The [[Builder]] may generate further wiring requests to fulfil the placement of other entities.
-Thus //Pipes are the basic building blocks// of the whole render network. We distinguish ''global available'' Pipes, which are like the sum groups of a mixing console, and the ''lokal pipe'' or [[source port|ClipSourcePort]] of the individual clips, which exist only within the duration of the corresponding clip. The design //limits the possible kinds of pipes // to these two types &mdash; thus we can build local processing chains at clips and global processing chains at the global pipes of the session and that's all we can do. (because of the flexibility which comes with the concept of [[placements|Placement]], this is no real limitation)
-
-The GUI can connect the viewer(s) to some pipe (and moreover can use [[probe points|ProbePoint]] placed like effects and connected to some pipe), and likewise, when starting a ''render'', we get the opportunity to specify the pipes to pull the data from. Pulling data from some pipe is the (only) way to activate the render nodes network reachable from this pipe.
-
-&rarr; [[Handling of Tracks|TrackHandling]]
-&rarr; [[Handling of Pipes|PipeHandling]]
-
-
-
-
-
!Identification
-Pipes are distinct objects and can be identified by their asset ~IDs. Besides, as for all [[structural assets|StructAsset]] there are extended query capabilities, including a symbolic pipe-id and a media (stream) type id. Any pipe can accept and deliver exactly one media stream kind (which may be inherently structured though, e.g. spatial sound systems or stereoscopic video)
-
-!creating pipes
-Pipe assets are created automatically by being used and referred. The [[Session]] holds a collection of global pipes, and further pipes can be created by using an new pipe reference in some placement. Moreover, every clip has an (implicit) [[source port|ClipSourcePort]], which will appear as pipe asset when first used (referred) while [[building|BuildProcess]].
-
-!removal
-Deleting a Pipe is an advanced operation, because it includes finding and "detaching" all references, otherwise the pipe will leap back into existence immediately. Thus, global pipe entries in the Session and pipe references in [[locating pins|LocatingPin]] within any placement have to be removed, while clips using a given source port will be disabled. {{red{todo: implementation deferred}}}
-
-!using Pipes
-there is not much you can do directly with a pipe asset. It is an point of reference, after all. Any connection to some pipe is only temporarily done by a placement in some part of the timeline, so it isn't stored with the pipe. You can edit the (user visible) description an you can globally disable a pipe asset. The pipe's ID and media stream type of course are fixed, because any connection and referral (via the asset ID) is based on them. Later on, we should provide a {{{rewire(oldPipe, newPipe)}}} to search any ref to the {{{oldPipe}}} and try to rewrite it to use the {{{newPipe}}}, possibly with a new media stream type.
-Pipes are integrated with the [[management of defaults|DefaultsManagement]]. For example, any pipe uses implicitly some [[processing pattern|ProcPatt]] &mdash; it may default to the empty pattern. This feature enables to apply some standard wiring to the pipes (e.g a fader for audio, similar to the classic mixing consoles). This //is // a global property of the pipe, but &mdash; contrary to the stream type &mdash; this pattern may be switched
-
-
Open issues, Things to be worked out, Problems still to be solved... 
 
@@ -2484,9 +2512,9 @@ Like all [[structural assets|StructAsset]], ~ProcPatt employs a special naming s
 
a given Render Engine configuration is a list of Processors. Each Processor in turn contains a Graph of ProcNode.s to do the acutal data processing. In order to cary out any calculations, the Processor needs to be called with a StateProxy containing the state information for this RenderProcess
 
-
+
//obviously, getting this one to work requires quite a lot of technical details to be planned and implemented.// This said...
-The intention is to get much more readable ("declarative") and changeable configuration as by programming it directly within the implementation of some object.
+The intention is to get much more readable ("declarative") and changeable configuration as by programming the decision logic literately within the implementation of some object.
 
 !Draft
 As an example, specifying how a Track can be configured for connecting automatically to some "mpeg" bus (=pipe)

From 919a57ed9a2717348d9c5fe08980d4ab09a9bb03 Mon Sep 17 00:00:00 2001
From: Ichthyostega 
Date: Fri, 22 Feb 2008 04:58:37 +0100
Subject: [PATCH 06/36] doc comment fix

---
 src/common/configrules.hpp                   | 2 +-
 src/common/query/mockconfigrules.hpp         | 2 +-
 src/common/singletonsubclass.hpp             | 2 +-
 src/proc/asset/db.hpp                        | 2 +-
 src/proc/mobject/explicitplacement.hpp       | 2 +-
 tests/components/common/typelistutiltest.cpp | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/common/configrules.hpp b/src/common/configrules.hpp
index a247eb30d..872d34724 100644
--- a/src/common/configrules.hpp
+++ b/src/common/configrules.hpp
@@ -26,7 +26,7 @@
  ** By using the Query template, you can pose a query in prolog syntax and get some
  ** existing or newly created object fulfilling the requested predicates. The actual 
  ** implementation is hidden behind the #instance (Singleton factory). As of 1/2008, 
- ** it is \i planned to use an embedded YAP Prolog system at some point in the future,
+ ** it is \e planned to use an embedded YAP Prolog system at some point in the future,
  ** for now we use a \link MockConfigRules mock implementation \endlink employing a
  ** preconfigured Map.
  **
diff --git a/src/common/query/mockconfigrules.hpp b/src/common/query/mockconfigrules.hpp
index 7b6ce6374..51f4a4cb7 100644
--- a/src/common/query/mockconfigrules.hpp
+++ b/src/common/query/mockconfigrules.hpp
@@ -96,7 +96,7 @@ namespace cinelerra
     
     /** 
      * building block defining how to do 
-     * the mock implementation for \i one type.
+     * the mock implementation for \e one type.
      * We simply access a table holding pre-created objects.
      */
     template
diff --git a/src/common/singletonsubclass.hpp b/src/common/singletonsubclass.hpp
index e779b820e..269351185 100644
--- a/src/common/singletonsubclass.hpp
+++ b/src/common/singletonsubclass.hpp
@@ -81,7 +81,7 @@ namespace cinelerra
               My_scoped_ptr() : scoped_ptr (get()? get() : 0) {}   ///< bypass if already configured
             };
             
-          /** we configure this link \i later, when the singleton factory
+          /** we configure this link \e later, when the singleton factory
            *  is actually created, to point at the desired implementation subclass.
            */
           static My_scoped_ptr link;
diff --git a/src/proc/asset/db.hpp b/src/proc/asset/db.hpp
index 8de442102..ee6ea753d 100644
--- a/src/proc/asset/db.hpp
+++ b/src/proc/asset/db.hpp
@@ -110,7 +110,7 @@ namespace asset
        *  As the destructor of DB needs to call clear(), this
        *  could result in segfaults. This doesn't seem to be
        *  a problem, though, because we register and process
-       *  \i all assets and the net effect is just breaking
+       *  \e all assets and the net effect is just breaking
        *  any cyclic dependencies) 
        */ 
       void
diff --git a/src/proc/mobject/explicitplacement.hpp b/src/proc/mobject/explicitplacement.hpp
index 9cf0917aa..5f70047b9 100644
--- a/src/proc/mobject/explicitplacement.hpp
+++ b/src/proc/mobject/explicitplacement.hpp
@@ -53,7 +53,7 @@ namespace mobject
       typedef std::pair SolutionData;  //TODO (ichthyo consideres better passing of solution by subclass)
 
       /** no need to resolve any further, as this ExplicitPlacement
-       *  already \i is the result of a resolve()-call.
+       *  already \e is the result of a resolve()-call.
        */
       virtual
       ExplicitPlacement resolve ()  const 
diff --git a/tests/components/common/typelistutiltest.cpp b/tests/components/common/typelistutiltest.cpp
index 842a1c5ec..327242e8e 100644
--- a/tests/components/common/typelistutiltest.cpp
+++ b/tests/components/common/typelistutiltest.cpp
@@ -26,7 +26,7 @@
  **
  ** the following test composes both an interface and the corresponding implementation
  ** by instantiating "building block" templates over a collection of types. The resulting
- ** class ends up inheriting a \i virtual function instantiated for each of the types 
+ ** class ends up inheriting a \e virtual function instantiated for each of the types 
  ** in the list. (remember: normally the number and signature of all virtual functions
  ** need to be absolutely fixed in the class definition)
  **

From 4af2d479956d27affc8ff74d63c464273f344fb0 Mon Sep 17 00:00:00 2001
From: Ichthyostega 
Date: Fri, 29 Feb 2008 04:27:24 +0100
Subject: [PATCH 07/36] test-driven-brainstorming: DefsManager interface
 building blocks

---
 src/proc/mobject/session/defsmanager.cpp      |  30 ++++
 src/proc/mobject/session/defsmanager.hpp      |  37 ++++
 .../mobject/session/defsmanagerimpltest.cpp   | 163 ++++++++++++++++++
 .../proc/mobject/session/defsmanagertest.cpp  |  37 ++--
 wiki/renderengine.html                        |   6 +-
 5 files changed, 258 insertions(+), 15 deletions(-)
 create mode 100644 tests/components/proc/mobject/session/defsmanagerimpltest.cpp

diff --git a/src/proc/mobject/session/defsmanager.cpp b/src/proc/mobject/session/defsmanager.cpp
index bfb505efb..52b78437b 100644
--- a/src/proc/mobject/session/defsmanager.cpp
+++ b/src/proc/mobject/session/defsmanager.cpp
@@ -44,6 +44,7 @@ namespace mobject
   {
   namespace session
     {
+    using std::tr1::shared_ptr;
     
     /** initialize the most basic internal defaults. */
     DefsManager::DefsManager ()  throw()
@@ -51,11 +52,40 @@ namespace mobject
       TODO ("setup basic defaults of the session");
     }
 
+    template
+    shared_ptr 
+    DefsManager::search  (const Query& capabilities)
+    {
+      UNIMPLEMENTED ("search for default registered object, dont create");
+    }
+    
+    template
+    shared_ptr 
+    DefsManager::create  (const Query& capabilities)
+    {
+      UNIMPLEMENTED ("retrieve object and register as default");
+    }
+    
+    template
+    bool 
+    DefsManager::define  (shared_ptr& defaultObj, const Query& capabilities)
+    {
+      UNIMPLEMENTED ("just do the defaults registration");
+    }
+
+    template
+    bool 
+    DefsManager::forget  (shared_ptr& defaultObj)
+    {
+      UNIMPLEMENTED ("purge defaults registration");
+    }
+
     
     template
     shared_ptr 
     DefsManager::operator() (const Query& capabilities)
     {
+      TODO ("move this code to create()");
       QueryHandler& typeHandler = ConfigRules::instance();  
       shared_ptr res = typeHandler.resolve (capabilities);
       
diff --git a/src/proc/mobject/session/defsmanager.hpp b/src/proc/mobject/session/defsmanager.hpp
index b48411058..16c6a7bfc 100644
--- a/src/proc/mobject/session/defsmanager.hpp
+++ b/src/proc/mobject/session/defsmanager.hpp
@@ -56,9 +56,46 @@ namespace mobject
         friend class SessManagerImpl;
         
       public:
+        /** common access point: retrieve the default object fulfilling
+         *  some given conditions. May silently trigger object creation.
+         *  @throw error::Config in case no solution is possible, which
+         *         is considered \e misconfiguration. 
+         */
         template
         shared_ptr operator() (const cinelerra::Query&);
         
+        /** search through the registered defaults, never create anything.
+         *  @return object fulfilling the query, \c empty ptr if not found. 
+         */
+        template
+        shared_ptr search  (const cinelerra::Query&);
+        
+        /** retrieve an object fulfilling the query and register it as default.
+         *  The resolution is delegated to the ConfigQuery system (which may cause
+         *  creation of new object instances) 
+         *  @return object fulfilling the query, \c empty ptr if no solution.
+         */ 
+        template
+        shared_ptr create  (const cinelerra::Query&);
+        
+        /** register the given object as default, after ensuring it fulfills the
+         *  query. The latter may cause some properties of the object to be set,
+         *  trigger creation of additional objects, and may fail altogether.
+         *  @return true if query was successfull and object is registered as default
+         *  @note only a weak ref to the object is stored
+         */ 
+        template
+        bool define  (shared_ptr&, const cinelerra::Query&);
+        
+        /** remove the defaults registration of the given object, if there was such
+         *  @return false if nothing has been changed because the object wasn't registered
+         */
+        template
+        bool forget  (shared_ptr&);
+        
+        
+// Q: can we have something along the line of...?
+//
 //        template
 //          < class TAR,                   ///< the target to query for 
 //            template  class SMP  ///<  smart pointer class to wrap the result
diff --git a/tests/components/proc/mobject/session/defsmanagerimpltest.cpp b/tests/components/proc/mobject/session/defsmanagerimpltest.cpp
new file mode 100644
index 000000000..920da9467
--- /dev/null
+++ b/tests/components/proc/mobject/session/defsmanagerimpltest.cpp
@@ -0,0 +1,163 @@
+/*
+  DefsManagerImpl(Test)  -  checking implementation details of the defaults manager
+ 
+  Copyright (C)         CinelerraCV
+    2007,               Hermann Vosseler 
+ 
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 2 of the
+  License, or (at your option) any later version.
+ 
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ 
+* *****************************************************/
+
+
+#include "common/test/run.hpp"
+#include "common/util.hpp"
+
+#include "proc/asset.hpp"
+#include "proc/asset/pipe.hpp"
+#include "common/configrules.hpp"
+#include "proc/assetmanager.hpp"
+#include "proc/mobject/session.hpp"
+
+#include 
+#include 
+
+using boost::format;
+using util::isnil;
+using std::string;
+
+
+namespace asset
+  {
+  namespace test
+    {
+    using mobject::Session;
+    using cinelerra::Symbol;
+    using cinelerra::Query;
+    using cinelerra::query::normalizeID;
+    
+    using cinelerra::ConfigRules;
+    using cinelerra::query::QueryHandler;
+    
+    
+    /** shortcut: query without creating new instances */
+    bool 
+    find (Query& q) 
+    { 
+      return Session::current->defaults.search (q); 
+    }
+    
+    /** shortcut: query for given Pipe-ID */
+    bool 
+    find (const string& pID) 
+    { 
+      return Session::current->defaults.search (Query ("pipe("+pID+")")); 
+    }
+    
+    
+    format pattern ("dummy_%s_%i");
+    
+    /** create a random new ID */
+    string 
+    newID (Symbol prefix)
+    {
+      return str (pattern % prefix % std::rand());
+    }
+    
+    
+    
+    
+    /************************************************************************
+     * @test verify some general assumptions regarding implementation details
+     *       of the the defaults manager.
+     * @see  DefsManager_test for the "big picture"
+     */
+    class DefsManagerImpl_test : public Test
+      {
+        virtual void run(Arg arg) 
+          {
+            define_and_search();
+            string pipeID = create();
+            forget(pipeID);
+          }
+        
+        
+        
+        
+        void define_and_search ()
+          {
+            string sID = newID ("stream");
+            
+             // create Pipes explicitly 
+            //  (without utilizing default queries)
+            PPipe pipe1 = Struct::create (newID("pipe"), newID("stream")); 
+            PPipe pipe2 = Struct::create (newID("pipe"), sID            );
+            
+            ASSERT (pipe1 != pipe2);
+            ASSERT (sID == pipe2->getProcPatt()->queryStreamID());
+            
+            ASSERT (!find (pipe1->getPipeID()), "accidental clash of random test-IDs");
+            ASSERT (!find (pipe2->getPipeID()), "accidental clash of random test-IDs");
+            
+            // now declare that these objects should be considered "default"
+            ASSERT (Session::current->defaults.define (pipe1, Query (""))); // unrestricted default
+            ASSERT (Session::current->defaults.define (pipe1, Query ("stream("+sID+")")));
+            
+            ASSERT ( find (pipe1->getPipeID()), "failure declaring object as default");
+            ASSERT ( find (pipe2->getPipeID()), "failure declaring object as default");
+          }
+        
+        
+        const string& create ()
+          { 
+            string sID = newID ("stream");
+            Query query_for_streamID ("stream("+sID+")");
+            
+            // issue a ConfigQuery directly, without involving the DefaultsManager
+            QueryHandler& typeHandler = ConfigRules::instance();  
+            PPipe pipe1 = typeHandler.resolve (query_for_streamID);
+            ASSERT (pipe1);
+            
+            ASSERT (!find (pipe1->getPipeID()));
+            PPipe pipe2 = Session::current->defaults.create (query_for_streamID);
+            ASSERT (pipe2);
+            ASSERT (pipe2 == pipe1);
+            ASSERT ( find (pipe1->getPipeID())); // now declared as "default Pipe" for this stream-ID
+            
+            return pipe1->getPipeID();
+          }
+        
+        
+        void forget(string pID)
+          { 
+            PPipe pipe = Pipe::query ("pipe("+pID+")");
+            REQUIRE (find (pipe->getPipeID()), "need an object registered as default");
+            long cnt = pipe.use_count();
+            
+            // now de-register the pipe as "default Pipe"
+            ASSERT (Session::current->defaults.forget (pipe));
+            ASSERT (!find (pipe->getPipeID()));
+            ASSERT (cnt == pipe.use_count());   // indicates that DefaultsManager only holds a weak ref.
+          }
+      };
+    
+    
+    /** Register this test class... */
+    LAUNCHER (DefsManagerImpl_test, "function session");
+    
+    
+    
+  } // namespace test
+
+} // namespace asset
diff --git a/tests/components/proc/mobject/session/defsmanagertest.cpp b/tests/components/proc/mobject/session/defsmanagertest.cpp
index c43f00583..16c09336a 100644
--- a/tests/components/proc/mobject/session/defsmanagertest.cpp
+++ b/tests/components/proc/mobject/session/defsmanagertest.cpp
@@ -47,6 +47,17 @@ namespace asset
     using cinelerra::query::normalizeID;
     
     
+    /** shortcut: run just a query
+     *  without creating new instances
+     */
+    bool 
+    find (Query& q) 
+    { 
+      return Session::current->defaults.search (q); 
+    }
+    
+    
+    
     
     /***********************************************************************
      * @test basic behaviour of the defaults manager.
@@ -76,7 +87,7 @@ namespace asset
         
         
         
-        void retrieveSimpleDefault(string pID)
+        void retrieveSimpleDefault (string pID)
           { 
             PPipe pipe1 = Pipe::query (""); // "the default pipe"
             PPipe pipe2;
@@ -95,7 +106,7 @@ namespace asset
           }
         
         
-        void retrieveConstrainedDefault(string pID, string sID)
+        void retrieveConstrainedDefault (string pID, string sID)
           { 
             PPipe pipe1 = Pipe::query (""); // "the default pipe"
             ASSERT (sID != pipe1->getProcPatt()->queryStreamID(),
@@ -121,23 +132,24 @@ namespace asset
                                  % pipe1->getPipeID()
                                  % std::rand()
                                 ));     // make random new pipeID  
-            string query_for_new ("pipe("+new_pID+")");
-            PPipe pipe2 = Session::current->defaults(Query (query_for_new));
+            Query query_for_new ("pipe("+new_pID+")");
             
-            TODO ("a way to do only a query, without creating. Use this to check it is really added as default");
+            ASSERT (!find (query_for_new));                             // check it doesn't exist 
+            PPipe pipe2 = Session::current->defaults (query_for_new);   // triggers creation
+            ASSERT ( find (query_for_new));                             // check it exists now
             
             ASSERT (pipe1 != pipe2);
-            ASSERT (pipe2 == Pipe::query (query_for_new));
+            ASSERT (pipe2 == Session::current->defaults (query_for_new));
             return new_pID;
           }
         
         
-        void verifyRemoval(string pID)
+        void verifyRemoval (string pID)
           { 
-            string query_for_pID ("pipe("+pID+")");
+            Query query_for_pID ("pipe("+pID+")");
             size_t hash;
               {
-                PPipe pipe1 = Pipe::query (query_for_pID);
+                PPipe pipe1 = Session::current->defaults (query_for_pID);
                 hash = pipe1->getID();
               }
              // now AssetManager should have the only ref
@@ -148,9 +160,10 @@ namespace asset
             aMang.remove (assetID);
             ASSERT (!aMang.known (assetID));
             
-            TODO ("assure the bare default-query now fails...");
-            PPipe pipe2 = Session::current->defaults(Query (query_for_pID));
-            TODO ("assure the bare default-query now succeeds...");
+            
+            ASSERT (!find(query_for_pID));                              // bare default-query should fail...
+            PPipe pipe2 = Session::current->defaults (query_for_pID);   // triggers re-creation
+            ASSERT ( find(query_for_pID));                              // should succeed again
           }
       };
     
diff --git a/wiki/renderengine.html b/wiki/renderengine.html
index 35ed4e339..0f3427f05 100644
--- a/wiki/renderengine.html
+++ b/wiki/renderengine.html
@@ -842,8 +842,8 @@ This is an very important external Interface, because it links together all thre
 
[[ProcLayer and Engine]]
 
-
-
As detailed in the [[definition|DefaultsManagement]], {{{default(Obj)}}} is sort of a Joker along the lines "give me a suitable Object and I don't care for further details". Actually, default objects are implemented by the {{{mobject::session::DefsManager}}}, which remembers and keeps track of anything labeled as "default". This defaults manager is a singleton and can be accessed via the [[Session]] interface, meaning that the memory regarding defaults is part of the session state. Accessing an object via the query for an default actually //tagges// this object (stores a weak ref in the ~DefsManager). Alongside with each object successfully queried via "default", the degree of constriction is remembered, i.e. the number of additional conditions contained in the query. This enables us to search for default objects starting with the most unspecific.
+
+
As detailed in the [[definition|DefaultsManagement]], {{{default(Obj)}}} is sort of a Joker along the lines "give me a suitable Object and I don't care for further details". Actually, default objects are implemented by the {{{mobject::session::DefsManager}}}, which remembers and keeps track of anything labeled as "default". This defaults manager is a singleton and can be accessed via the [[Session]] interface, meaning that the memory track regarding defaults is part of the session state. Accessing an object via the query for an default actually //tagges// this object (storing a weak ref in the ~DefsManager). Alongside with each object successfully queried via "default", the degree of constriction is remembered, i.e. the number of additional conditions contained in the query. This enables us to search for default objects starting with the most unspecific.
 
 !Skeleton
 # ''search'': using the predicate {{{default(X)}}} enumerates existing objects of suitable type
@@ -859,7 +859,7 @@ This is an very important external Interface, because it links together all thre
 
 !!!Implementation details
 Taken precisely, the "degree of constriction" yields only a partial ordering &mdash; but as the "default"-predicate is sort of a existential quantification anyways, its sole purpose is to avoid polluting the session with unnecessary default objects, and we don't need to care for absolute precision. A suitable approximation is to count the number of predicates terms in the query and use a pqueue (separate for each Type) to store weak refs to the the objects tagged as "default"
-{{red{WARN}}} there is an interference with the (planned) Undo function. This is a general problem of the config queries; it seems reasonable we can ignore this issue.
+{{red{WARN}}} there is an interference with the (planned) Undo function. This is a general problem of the config queries; just ignoring this issue seems reasonable.
 
 !!!Problems with the (preliminary) mock implementation
 As we don't have a Prolog interpreter on board yet, we utilize a mock store with preconfigured answers. (see {{{MockConfigQuery}}}). As this preliminary solution is lacking the ability to create new objects, we need to resort to some trickery here (please look away). The overall logic is quite broken, because the system isn't capable to do any real resolution &mdash; if we ignore this fact, the rest of the algorithm can be implemented, tested and used right now.

From a3d91286c87a2400b0d977a9df32e5c651ad6cdf Mon Sep 17 00:00:00 2001
From: Ichthyostega 
Date: Fri, 29 Feb 2008 18:58:29 +0100
Subject: [PATCH 08/36] WIP defaults manager implementation

---
 src/common/configrules.hpp                    | 24 +++---
 src/common/query/mockconfigrules.hpp          | 14 ++--
 src/proc/mobject/session/defsmanager.cpp      | 79 ++++++++++++++-----
 src/proc/mobject/session/defsmanager.hpp      |  4 +-
 src/proc/mobject/session/defsregistry.cpp     | 48 +++++++++++
 src/proc/mobject/session/defsregistry.hpp     | 68 ++++++++++++++++
 .../mobject/session/defsmanagerimpltest.cpp   |  6 --
 wiki/renderengine.html                        | 10 +--
 8 files changed, 206 insertions(+), 47 deletions(-)
 create mode 100644 src/proc/mobject/session/defsregistry.cpp
 create mode 100644 src/proc/mobject/session/defsregistry.hpp

diff --git a/src/common/configrules.hpp b/src/common/configrules.hpp
index 872d34724..4dcbef8c9 100644
--- a/src/common/configrules.hpp
+++ b/src/common/configrules.hpp
@@ -50,7 +50,7 @@
 #include "common/typelistutil.hpp"
 #include "common/singletonsubclass.hpp"
 
-//TODO: is it sensible to bring in the types explicitly here? (it's not necessary, but may be convienient...)
+//TODO: is it sensible to bring in the types explicitly here? (it's not necessary, but may be convenient...)
 #include "proc/mobject/session/track.hpp"
 #include "proc/asset/procpatt.hpp"
 #include "proc/asset/pipe.hpp"
@@ -73,11 +73,11 @@ namespace cinelerra
     {
     // The intention is to support the following style of Prolog code
     //
-    // retrieve(O, Cap) :- find(T), capabilities(Cap).
-    // retrieve(O, Cap) :- make(T), capabilities(Cap).
-    // capabilities(Q) :- call(Q).
-    //
-    // stream(T, mpeg) :- type(T, track), type(P, pipe), retrieve(P, stream(P,mpeg)), place_to(P, T).
+    //  resolve(O, Cap) :- find(O), capabilities(Cap).
+    //  resolve(O, Cap) :- make(O), capabilities(Cap).
+    //  capabilities(Q) :- call(Q).
+    //  
+    //  stream(T, mpeg) :- type(T, track), type(P, pipe), resolve(P, stream(P,mpeg)), place_to(P, T).
     //
     // The type guard is inserted auomatically, while the predicate implementations for
     // find/1, make/1, stream/2, and place_to/2 are to be provided by the target types.
@@ -111,6 +111,8 @@ namespace cinelerra
      * type of object. Registering  such a TypeHandler should create
      * the necessary handler functions to be installed into 
      * the Prolog system.
+     * @todo it can't be done exactly this way, but I leave it in
+     *       as a reminder for later, to show the intention
      */  
     template
     class TypeHandler
@@ -128,7 +130,8 @@ namespace cinelerra
      * the "frontside" interface: the Proc-Layer code can
      * use this QueryHandler to retrieve instances of the
      * type TY fulfilling the given Query. To start with,
-     * we use a mock implementation-
+     * we use a mock implementation. 
+     * (this code works and is already used 2/2008)
      * @see cinelerra::query::LookupPreconfigured
      * @see cinelerra::query::MockTable
      */
@@ -140,9 +143,12 @@ namespace cinelerra
       public:
         /** try to find or create an object of type TY 
          *  fulfilling the given query.
-         *  @return empty shared-ptr if not found,
+         *  @param solution object fulfilling the query. Will be bound or
+         *         unified (in case it's already bound) with the first solution.
+         *  @query any goals to be fulfilled by the solution.
+         *  @return false if resolution failed. In this case, solution ptr is empty.
          */
-        virtual shared_ptr resolve (const Query& q) = 0;
+        virtual bool resolve (shared_ptr solution, const Query& q) = 0;
       };
 
     // TODO: the Idea is to provide specialisations for the concrete types
diff --git a/src/common/query/mockconfigrules.hpp b/src/common/query/mockconfigrules.hpp
index 51f4a4cb7..7466f7050 100644
--- a/src/common/query/mockconfigrules.hpp
+++ b/src/common/query/mockconfigrules.hpp
@@ -105,14 +105,18 @@ namespace cinelerra
         typedef typename WrapReturn::Wrapper Ret;
         
       public:
-        virtual Ret 
-        resolve (const Query& q)
+        /** (dummy) implementation of the QueryHandler interface */
+        virtual bool 
+        resolve (Ret& solution, const Query& q)
           {
             const any& entry = fetch_from_table_for (q.asKey());
             if (!isnil (entry))
-              return any_cast (entry);
-            else
-              return Ret(); // default-constructed empty smart ptr
+              if (! solution
+                 ||(solution && *solution == *candidate)    // simulates a real unification
+                 )
+                return solution = candidate;
+            
+            return solution = Ret();    // fail: return default-constructed empty smart ptr
           }
       };
     
diff --git a/src/proc/mobject/session/defsmanager.cpp b/src/proc/mobject/session/defsmanager.cpp
index 52b78437b..1a0107ff5 100644
--- a/src/proc/mobject/session/defsmanager.cpp
+++ b/src/proc/mobject/session/defsmanager.cpp
@@ -22,8 +22,7 @@
 
 
 #include "proc/mobject/session/defsmanager.hpp"
-#include "proc/asset/procpatt.hpp"
-#include "proc/asset/pipe.hpp"
+#include "proc/mobject/session/defsregistry.hpp"
 #include "common/configrules.hpp"
 #include "common/error.hpp"
 
@@ -32,52 +31,70 @@
 using boost::format;
 
 using asset::Query;
-using asset::Pipe;
-using asset::ProcPatt;
-using asset::PProcPatt;
-
 using cinelerra::ConfigRules;
 using cinelerra::query::QueryHandler;
 using cinelerra::query::CINELERRA_ERROR_CAPABILITY_QUERY;
 
+
 namespace mobject
   {
   namespace session
     {
     using std::tr1::shared_ptr;
     
+    
+    namespace // Implementation details
+      {
+      DefsRegistry& defaultsRegistry; //////////////////TODO
+    }
+    
     /** initialize the most basic internal defaults. */
     DefsManager::DefsManager ()  throw()
     {
       TODO ("setup basic defaults of the session");
     }
-
+    
+    
     template
-    shared_ptr 
+    shared_ptr
     DefsManager::search  (const Query& capabilities)
     {
-      UNIMPLEMENTED ("search for default registered object, dont create");
+      defaultsRegistry.get (capabilities);
     }
     
+    
     template
     shared_ptr 
     DefsManager::create  (const Query& capabilities)
     {
-      UNIMPLEMENTED ("retrieve object and register as default");
+      shared_ptr res;
+      QueryHandler& typeHandler = ConfigRules::instance();  
+      typeHandler.resolve (res, capabilities);
+      if (res)
+        defaultsRegistry.put (res, capabilities);
+      return res;
     }
     
+    
     template
     bool 
-    DefsManager::define  (shared_ptr& defaultObj, const Query& capabilities)
+    DefsManager::define  (const shared_ptr& defaultObj, const Query& capabilities)
     {
-      UNIMPLEMENTED ("just do the defaults registration");
+      shared_ptr candidate (defaultObj);
+      QueryHandler& typeHandler = ConfigRules::instance();  
+      typeHandler.resolve (candidate, capabilities);
+      if (!candidate)
+        return false;
+      else
+        return defaultsRegistry.put (candidate, capabilities);
     }
-
+    
+    
     template
     bool 
-    DefsManager::forget  (shared_ptr& defaultObj)
+    DefsManager::forget  (const shared_ptr& defaultObj)
     {
-      UNIMPLEMENTED ("purge defaults registration");
+      defaultsRegistry.forget (defaultObj);
     }
 
     
@@ -85,9 +102,11 @@ namespace mobject
     shared_ptr 
     DefsManager::operator() (const Query& capabilities)
     {
-      TODO ("move this code to create()");
-      QueryHandler& typeHandler = ConfigRules::instance();  
-      shared_ptr res = typeHandler.resolve (capabilities);
+      shared_ptr res (search (capabilities));
+      if (res) 
+        return res;
+      else
+        res = create (capabilities); // not yet known as default, create new
       
       if (!res)
         throw cinelerra::error::Config ( str(format("The following Query could not be resolved: %s.") 
@@ -97,14 +116,34 @@ namespace mobject
         return res;
     }
 
+  } // namespace mobject::session
+
+} // namespace mobject
     
     
    /***************************************************************/
    /* explicit template instantiations for querying various Types */
    /***************************************************************/
 
-    template shared_ptr DefsManager::operator ()(const Query&); 
-    template PProcPatt        DefsManager::operator ()(const Query&); 
+#include "proc/asset/procpatt.hpp"
+#include "proc/asset/pipe.hpp"
+
+namespace mobject
+  {
+  namespace session
+    {
+
+    using asset::Pipe;
+    using asset::PPipe;
+    using asset::ProcPatt;
+    using asset::PProcPatt;
+    
+    
+    template PPipe     DefsManager::operator() (const Query&); 
+    template PProcPatt DefsManager::operator() (const Query&); 
+    
+    template bool DefsManager::define (const PPipe&, const Query&);
+    template bool DefsManager::forget (const PPipe&);
 
   } // namespace mobject::session
 
diff --git a/src/proc/mobject/session/defsmanager.hpp b/src/proc/mobject/session/defsmanager.hpp
index 16c6a7bfc..3b01f6e6c 100644
--- a/src/proc/mobject/session/defsmanager.hpp
+++ b/src/proc/mobject/session/defsmanager.hpp
@@ -85,13 +85,13 @@ namespace mobject
          *  @note only a weak ref to the object is stored
          */ 
         template
-        bool define  (shared_ptr&, const cinelerra::Query&);
+        bool define  (const shared_ptr&, const cinelerra::Query&);
         
         /** remove the defaults registration of the given object, if there was such
          *  @return false if nothing has been changed because the object wasn't registered
          */
         template
-        bool forget  (shared_ptr&);
+        bool forget  (const shared_ptr&);
         
         
 // Q: can we have something along the line of...?
diff --git a/src/proc/mobject/session/defsregistry.cpp b/src/proc/mobject/session/defsregistry.cpp
new file mode 100644
index 000000000..c1d370bde
--- /dev/null
+++ b/src/proc/mobject/session/defsregistry.cpp
@@ -0,0 +1,48 @@
+/*
+  DefsManager  -  implementation of the default object store
+ 
+  Copyright (C)         CinelerraCV
+    2008,               Hermann Vosseler 
+ 
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 2 of the
+  License, or (at your option) any later version.
+ 
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ 
+* *****************************************************/
+
+
+#include "proc/mobject/session/defsregistry.hpp"
+#include "common/error.hpp"
+
+//#include 
+
+//using boost::format;
+
+
+
+namespace mobject
+  {
+  namespace session
+    {
+    
+    /** @todo */
+    DefsRegistry::DefsRegistry ()  throw()
+    {
+      UNIMPLEMENTED ("initialize store for default objects");
+    }
+    
+
+  } // namespace mobject::session
+
+} // namespace mobject
+
diff --git a/src/proc/mobject/session/defsregistry.hpp b/src/proc/mobject/session/defsregistry.hpp
new file mode 100644
index 000000000..33b57b634
--- /dev/null
+++ b/src/proc/mobject/session/defsregistry.hpp
@@ -0,0 +1,68 @@
+/*
+  DEFSREGISTRY.hpp  -  implementation of the default object store
+ 
+  Copyright (C)         CinelerraCV
+    2008,               Hermann Vosseler 
+ 
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 2 of the
+  License, or (at your option) any later version.
+ 
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+ 
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ 
+*/
+
+
+#ifndef MOBJECT_SESSION_DEFSREGISTRY_H
+#define MOBJECT_SESSION_DEFSREGISTRY_H
+
+
+#include "common/singleton.hpp"
+
+#include 
+
+
+
+namespace mobject
+  {
+  namespace session
+    {
+    using std::tr1::shared_ptr;
+
+
+    /**
+     * Organize a collection of preconfigured default objects.
+     * For various kinds of objects we can tweek the default parametrisation
+     * as part of the general session configuration. A ref to an instance of
+     * this class is accessible through the current session and can be used
+     * to fill in parts of the configuration of new objects, if the user 
+     * code didn't give more specific parameters. Necessary sub-objects 
+     * will be created on demand, and any default configuration, once
+     * found, will be remembered and stored with the current session.
+     */
+    class DefsRegistry
+      {
+      protected:
+        
+        DefsRegistry ();
+        friend class cinelerra::singleton::StaticCreate;
+        
+      public:
+        
+      };
+
+      
+
+  } // namespace mobject::session
+
+} // namespace mobject
+
+#endif
diff --git a/tests/components/proc/mobject/session/defsmanagerimpltest.cpp b/tests/components/proc/mobject/session/defsmanagerimpltest.cpp
index 920da9467..dc0cc22a4 100644
--- a/tests/components/proc/mobject/session/defsmanagerimpltest.cpp
+++ b/tests/components/proc/mobject/session/defsmanagerimpltest.cpp
@@ -51,12 +51,6 @@ namespace asset
     using cinelerra::query::QueryHandler;
     
     
-    /** shortcut: query without creating new instances */
-    bool 
-    find (Query& q) 
-    { 
-      return Session::current->defaults.search (q); 
-    }
     
     /** shortcut: query for given Pipe-ID */
     bool 
diff --git a/wiki/renderengine.html b/wiki/renderengine.html
index 0f3427f05..f1de96a22 100644
--- a/wiki/renderengine.html
+++ b/wiki/renderengine.html
@@ -2512,21 +2512,21 @@ Like all [[structural assets|StructAsset]], ~ProcPatt employs a special naming s
 
a given Render Engine configuration is a list of Processors. Each Processor in turn contains a Graph of ProcNode.s to do the acutal data processing. In order to cary out any calculations, the Processor needs to be called with a StateProxy containing the state information for this RenderProcess
 
-
+
//obviously, getting this one to work requires quite a lot of technical details to be planned and implemented.// This said...
 The intention is to get much more readable ("declarative") and changeable configuration as by programming the decision logic literately within the implementation of some object.
 
 !Draft
 As an example, specifying how a Track can be configured for connecting automatically to some "mpeg" bus (=pipe)
 {{{
-retrieve(O, Cap) :- find(O), capabilities(Cap).
-retrieve(O, Cap) :- make(O), capabilities(Cap).
+resolve(O, Cap) :- find(O), capabilities(Cap).
+resolve(O, Cap) :- make(O), capabilities(Cap).
 capabilities(Q) :- call(Q).
 
-stream(T, mpeg) :- type(T, track), type(P, pipe), retrieve(P, stream(P,mpeg)), place_to(P, T).
+stream(T, mpeg) :- type(T, track), type(P, pipe), resolve(P, stream(P,mpeg)), place_to(P, T).
 }}}
 
-Then, running the goal {{{:-retrieve(T, stream(T,mpeg)).}}} would search a Track object, try to retrieve a pipe object with stream-type=mpeg and associate the track with this pipe. This relies on a predicate "stream(P,mpeg)" implemented (natively) for the pipe object. So, "Cap" is the query issued from calling code &mdash; here {{{stream(T,mpeg)}}}, the type guard {{{type(T, track)}}} will probably be handled or inserted automatically, while the predicate implementations for find/1, make/1, stream/2, and place_to/2 are to be provided by the target types.
+Then, running the goal {{{:-resolve(T, stream(T,mpeg)).}}} would search a Track object, try to retrieve a pipe object with stream-type=mpeg and associate the track with this pipe. This relies on a predicate "stream(P,mpeg)" implemented (natively) for the pipe object. So, "Cap" is the query issued from calling code &mdash; here {{{stream(T,mpeg)}}}, the type guard {{{type(T, track)}}} will probably be handled or inserted automatically, while the predicate implementations for find/1, make/1, stream/2, and place_to/2 are to be provided by the target types.
 * __The supporting system__ had to combine several code snippets into one rule system to be used for running queries, with some global base rules, rules injected by each individual participating object kind and finally user provided rules added by the current session. The actual query is bound to "Cap" (and consequently run as a goal by {{{call(Q)}}}). The implementation needs to provide a symbol table associating variable terms (like "T" or "P") to C/C++ object types, enabling the participating object kinds to register their specific predicate implementations. This is crucial, because there can be no general scheme of object-provided predicates (for each object kind different predicates make sense, e.g. [[pipes|PipeHandling]] have other possibilities than [[wiring requests|WiringRequest]]). Basically, a query issues a Prolog goal, which in turn evaluates domain specific predicates provided by the participating objects and thus calls back into C/C++ code. The supporting system maintains the internal connection (via the "type" predicate) such that from Prolog viewpoint it looks as if we were binding Variables directly to object instances. (there are some nasty technical details because of the backtracking nature of Prolog evaluations which need to be hidden away)
 * Any __participating object kind__ needs a way to declare domain specific predicates, thus triggering the registration of the necessary hooks within the supporting system. Moreover, it should be able to inject further prolog code (as shown in the example above with the {{{strem(T, mpeg)}}} predicate. For each of these new domain specific predicates, there needs to be a functor which can be invoked when the C implementation of the predicate is called from Prolog (in some cases even later, when the final solution is "executed", e.g. a new instance has been created and now some properties need to be set).
 

From 0baf15ca94e88d9ee6b511a18ef48daad87427ba Mon Sep 17 00:00:00 2001
From: Ichthyostega 
Date: Mon, 10 Mar 2008 04:25:03 +0100
Subject: [PATCH 09/36] Cinelerra-3 renamed to Lumiera -- copyright and
 documentation

---
 AUTHORS                                       |   4 +-
 DIR_INFO                                      |   2 +-
 INSTALL                                       |   4 +-
 LICENSE                                       |  11 +--
 Makefile.am                                   |   2 +-
 README                                        |  29 +++---
 SConstruct                                    |   6 +-
 admin/scons/Buildhelper.py                    |   4 +-
 configure.ac                                  |   6 +-
 doc/devel/Doxyfile                            |   9 +-
 doc/devel/uml/class128138.html                |   2 +-
 doc/devel/uml/class128266.html                |   2 +-
 doc/devel/uml/class128394.html                |   2 +-
 doc/devel/uml/class135429.html                |   2 +-
 doc/devel/uml/class136453.html                |   2 +-
 doc/devel/uml/classdiagrams.html              |   2 +-
 doc/devel/uml/classes.html                    |   6 +-
 doc/devel/uml/fig129797.png                   | Bin 18443 -> 18260 bytes
 doc/devel/uml/fig130053.png                   | Bin 44088 -> 19189 bytes
 doc/devel/uml/fig130181.png                   | Bin 10688 -> 10701 bytes
 doc/devel/uml/index-withframe.html            |   2 +-
 doc/devel/uml/index.html                      |  22 ++---
 doc/devel/uml/index_60.html                   |   4 +-
 doc/devel/uml/index_65.html                   |   6 +-
 doc/devel/uml/index_66.html                   |   2 +-
 doc/devel/uml/index_67.html                   |  44 +++++----
 doc/devel/uml/index_69.html                   |   6 +-
 doc/devel/uml/index_70.html                   |   2 +-
 doc/devel/uml/index_71.html                   |   2 +-
 doc/devel/uml/index_72.html                   |   2 +-
 doc/devel/uml/index_73.html                   |   4 +-
 doc/devel/uml/index_76.html                   |   2 +
 doc/devel/uml/index_77.html                   |   2 +-
 doc/devel/uml/index_79.html                   |   6 +-
 doc/devel/uml/index_82.html                   |   2 +-
 doc/devel/uml/index_83.html                   |   2 +-
 doc/devel/uml/index_84.html                   |   6 +-
 doc/devel/uml/index_86.html                   |  16 ++--
 doc/devel/uml/navig.html                      |   2 +-
 doc/devel/uml/packages.html                   |   6 +-
 doc/devel/uml/public_properties.html          |   2 +-
 src/backend/mediaaccessfacade.cpp             |   4 +-
 src/backend/mediaaccessfacade.hpp             |   4 +-
 src/cinelerra.h                               |   4 +-
 src/common/appconfig.cpp                      |   4 +-
 src/common/appconfig.hpp                      |   4 +-
 src/common/cmdline.cpp                        |   4 +-
 src/common/cmdline.hpp                        |   4 +-
 src/common/error.cpp                          |   4 +-
 src/common/error.hpp                          |   4 +-
 src/common/factory.hpp                        |   4 +-
 src/common/multithread.hpp                    |   4 +-
 src/common/singleton.hpp                      |   4 +-
 src/common/singletonfactory.hpp               |   4 +-
 src/common/singletonpolicies.hpp              |   4 +-
 src/common/singletonpreconfigure.hpp          |   4 +-
 src/common/test/mockinjector.hpp              |   4 +-
 src/common/test/run.hpp                       |   4 +-
 src/common/test/suite.cpp                     |   4 +-
 src/common/test/suite.hpp                     |   4 +-
 src/common/test/testoption.cpp                |   4 +-
 src/common/test/testoption.hpp                |   4 +-
 src/common/time.cpp                           |   4 +-
 src/common/time.hpp                           |   4 +-
 src/common/typelist.hpp                       |   4 +-
 src/common/util.cpp                           |   4 +-
 src/common/util.hpp                           |   4 +-
 src/common/visitor.cpp                        |   4 +-
 src/common/visitor.hpp                        |   4 +-
 src/common/visitordispatcher.hpp              |   4 +-
 src/common/visitorpolicies.hpp                |   4 +-
 src/lib/Makefile.am                           |   2 +-
 src/lib/condition.c                           |   4 +-
 src/lib/condition.h                           |   4 +-
 src/lib/error.c                               |   4 +-
 src/lib/error.h                               |   4 +-
 src/lib/framerate.c                           |   4 +-
 src/lib/framerate.h                           |   4 +-
 src/lib/llist.h                               |   4 +-
 src/lib/locking.h                             |   4 +-
 src/lib/mutex.c                               |   4 +-
 src/lib/mutex.h                               |   4 +-
 src/lib/plugin.c                              |   4 +-
 src/lib/plugin.h                              |   4 +-
 src/lib/references.c                          |   4 +-
 src/lib/references.h                          |   4 +-
 src/lib/rwlock.c                              |   4 +-
 src/lib/rwlock.h                              |   4 +-
 src/lib/time.c                                |   4 +-
 src/lib/time.h                                |   4 +-
 src/main.cpp                                  |   8 +-
 src/nobugcfg.h                                |   4 +-
 src/pre.hpp                                   |   4 +-
 src/proc/asset.cpp                            |   4 +-
 src/proc/asset.hpp                            |   6 +-
 src/proc/asset/buildinstruct.cpp              |   4 +-
 src/proc/asset/buildinstruct.hpp              |   4 +-
 src/proc/asset/category.cpp                   |   4 +-
 src/proc/asset/category.hpp                   |   4 +-
 src/proc/asset/clip.cpp                       |   4 +-
 src/proc/asset/clip.hpp                       |   4 +-
 src/proc/asset/codec.cpp                      |   4 +-
 src/proc/asset/codec.hpp                      |   4 +-
 src/proc/asset/compoundmedia.cpp              |   4 +-
 src/proc/asset/compoundmedia.hpp              |   4 +-
 src/proc/asset/dataset.cpp                    |   4 +-
 src/proc/asset/dataset.hpp                    |   4 +-
 src/proc/asset/db.hpp                         |   4 +-
 src/proc/asset/effect.cpp                     |   4 +-
 src/proc/asset/effect.hpp                     |   4 +-
 src/proc/asset/media.cpp                      |   4 +-
 src/proc/asset/media.hpp                      |   4 +-
 src/proc/asset/meta.cpp                       |   4 +-
 src/proc/asset/meta.hpp                       |   4 +-
 src/proc/asset/outport.cpp                    |   4 +-
 src/proc/asset/outport.hpp                    |   4 +-
 src/proc/asset/preview.cpp                    |   4 +-
 src/proc/asset/preview.hpp                    |   4 +-
 src/proc/asset/proc.cpp                       |   4 +-
 src/proc/asset/proc.hpp                       |   4 +-
 src/proc/asset/procpatt.cpp                   |   4 +-
 src/proc/asset/procpatt.hpp                   |   4 +-
 src/proc/asset/struct.cpp                     |   4 +-
 src/proc/asset/struct.hpp                     |   4 +-
 src/proc/asset/track.cpp                      |   4 +-
 src/proc/asset/track.hpp                      |   4 +-
 src/proc/asset/unknown.cpp                    |   4 +-
 src/proc/asset/unknown.hpp                    |   4 +-
 src/proc/assetmanager.cpp                     |   4 +-
 src/proc/assetmanager.hpp                     |   4 +-
 src/proc/controllerfacade.cpp                 |   4 +-
 src/proc/controllerfacade.hpp                 |   4 +-
 src/proc/engine/aframe.cpp                    |   4 +-
 src/proc/engine/aframe.hpp                    |   4 +-
 src/proc/engine/arender.cpp                   |   4 +-
 src/proc/engine/arender.hpp                   |   4 +-
 src/proc/engine/codecadapter.cpp              |   4 +-
 src/proc/engine/codecadapter.hpp              |   4 +-
 src/proc/engine/exitnode.cpp                  |   4 +-
 src/proc/engine/exitnode.hpp                  |   4 +-
 src/proc/engine/glbuf.cpp                     |   4 +-
 src/proc/engine/glbuf.hpp                     |   4 +-
 src/proc/engine/glpipe.cpp                    |   4 +-
 src/proc/engine/glpipe.hpp                    |   4 +-
 src/proc/engine/glrender.cpp                  |   4 +-
 src/proc/engine/glrender.hpp                  |   4 +-
 src/proc/engine/hub.cpp                       |   4 +-
 src/proc/engine/hub.hpp                       |   4 +-
 src/proc/engine/link.cpp                      |   4 +-
 src/proc/engine/link.hpp                      |   4 +-
 src/proc/engine/mask.cpp                      |   4 +-
 src/proc/engine/mask.hpp                      |   4 +-
 src/proc/engine/pluginadapter.cpp             |   4 +-
 src/proc/engine/pluginadapter.hpp             |   4 +-
 src/proc/engine/processor.cpp                 |   4 +-
 src/proc/engine/processor.hpp                 |   4 +-
 src/proc/engine/procnode.cpp                  |   4 +-
 src/proc/engine/procnode.hpp                  |   4 +-
 src/proc/engine/projector.cpp                 |   4 +-
 src/proc/engine/projector.hpp                 |   4 +-
 src/proc/engine/renderengine.cpp              |   4 +-
 src/proc/engine/renderengine.hpp              |   4 +-
 src/proc/engine/source.cpp                    |   4 +-
 src/proc/engine/source.hpp                    |   4 +-
 src/proc/engine/trafo.cpp                     |   4 +-
 src/proc/engine/trafo.hpp                     |   4 +-
 src/proc/engine/vframe.cpp                    |   4 +-
 src/proc/engine/vframe.hpp                    |   4 +-
 src/proc/engine/vrender.cpp                   |   4 +-
 src/proc/engine/vrender.hpp                   |   4 +-
 src/proc/frame.cpp                            |   4 +-
 src/proc/frame.hpp                            |   4 +-
 src/proc/mobject/builder/assembler.cpp        |   4 +-
 src/proc/mobject/builder/assembler.hpp        |   4 +-
 src/proc/mobject/builder/buildertool.hpp      |   4 +-
 src/proc/mobject/builder/conmanager.cpp       |   4 +-
 src/proc/mobject/builder/conmanager.hpp       |   4 +-
 src/proc/mobject/builder/nodecreatertool.cpp  |   4 +-
 src/proc/mobject/builder/nodecreatertool.hpp  |   4 +-
 src/proc/mobject/builder/segmentationtool.cpp |   4 +-
 src/proc/mobject/builder/segmentationtool.hpp |   4 +-
 src/proc/mobject/builder/toolfactory.cpp      |   4 +-
 src/proc/mobject/builder/toolfactory.hpp      |   4 +-
 src/proc/mobject/builderfacade.cpp            |   4 +-
 src/proc/mobject/builderfacade.hpp            |   4 +-
 src/proc/mobject/controller/pathmanager.cpp   |   4 +-
 src/proc/mobject/controller/pathmanager.hpp   |   4 +-
 src/proc/mobject/controller/renderstate.cpp   |   4 +-
 src/proc/mobject/controller/renderstate.hpp   |   4 +-
 src/proc/mobject/explicitplacement.hpp        |   4 +-
 src/proc/mobject/interpolator.cpp             |   4 +-
 src/proc/mobject/interpolator.hpp             |   4 +-
 src/proc/mobject/mobject.cpp                  |   4 +-
 src/proc/mobject/mobject.hpp                  |   4 +-
 src/proc/mobject/parameter.cpp                |   4 +-
 src/proc/mobject/parameter.hpp                |   4 +-
 src/proc/mobject/paramprovider.cpp            |   4 +-
 src/proc/mobject/paramprovider.hpp            |   4 +-
 src/proc/mobject/placement.cpp                |   4 +-
 src/proc/mobject/placement.hpp                |   4 +-
 src/proc/mobject/session.hpp                  |   4 +-
 src/proc/mobject/session/abstractmo.cpp       |   4 +-
 src/proc/mobject/session/abstractmo.hpp       |   4 +-
 src/proc/mobject/session/allocation.cpp       |   4 +-
 src/proc/mobject/session/allocation.hpp       |   4 +-
 src/proc/mobject/session/auto.cpp             |   4 +-
 src/proc/mobject/session/auto.hpp             |   4 +-
 src/proc/mobject/session/clip.cpp             |   4 +-
 src/proc/mobject/session/clip.hpp             |   4 +-
 src/proc/mobject/session/compoundclip.cpp     |   4 +-
 src/proc/mobject/session/compoundclip.hpp     |   4 +-
 src/proc/mobject/session/edl.cpp              |   4 +-
 src/proc/mobject/session/edl.hpp              |   4 +-
 src/proc/mobject/session/effect.cpp           |   4 +-
 src/proc/mobject/session/effect.hpp           |   4 +-
 src/proc/mobject/session/fixedlocation.cpp    |   4 +-
 src/proc/mobject/session/fixedlocation.hpp    |   4 +-
 src/proc/mobject/session/fixture.cpp          |   4 +-
 src/proc/mobject/session/fixture.hpp          |   4 +-
 src/proc/mobject/session/label.cpp            |   4 +-
 src/proc/mobject/session/label.hpp            |   4 +-
 src/proc/mobject/session/locatingpin.cpp      |   4 +-
 src/proc/mobject/session/locatingpin.hpp      |   4 +-
 src/proc/mobject/session/meta.cpp             |   4 +-
 src/proc/mobject/session/meta.hpp             |   4 +-
 src/proc/mobject/session/mobjectfactory.cpp   |   4 +-
 src/proc/mobject/session/mobjectfactory.hpp   |   4 +-
 src/proc/mobject/session/relativelocation.cpp |   4 +-
 src/proc/mobject/session/relativelocation.hpp |   4 +-
 src/proc/mobject/session/segment.cpp          |   4 +-
 src/proc/mobject/session/segment.hpp          |   4 +-
 src/proc/mobject/session/session.cpp          |   4 +-
 src/proc/mobject/session/sessionimpl.cpp      |   4 +-
 src/proc/mobject/session/sessionimpl.hpp      |   4 +-
 src/proc/mobject/session/sessmanagerimpl.cpp  |   4 +-
 src/proc/mobject/session/simpleclip.cpp       |   4 +-
 src/proc/mobject/session/simpleclip.hpp       |   4 +-
 src/proc/mobject/session/track.cpp            |   4 +-
 src/proc/mobject/session/track.hpp            |   4 +-
 src/proc/stateproxy.cpp                       |   4 +-
 src/proc/stateproxy.hpp                       |   4 +-
 tests/Makefile.am                             |   2 +-
 tests/bugs/bugmain.c                          |   4 +-
 tests/components/backend/mediaaccessmock.cpp  |   4 +-
 tests/components/backend/mediaaccessmock.hpp  |   4 +-
 .../backend/mediaaccessmocktest.cpp           |   4 +-
 tests/components/common/appconfigtest.cpp     |   4 +-
 .../components/common/exceptionerrortest.cpp  |   4 +-
 .../components/common/factoryspecialtest.cpp  |   4 +-
 tests/components/common/factorytest.cpp       |   4 +-
 .../common/sanitizedidentifiertest.cpp        |   4 +-
 tests/components/common/singletontest.cpp     |   4 +-
 .../common/singletontestmocktest.cpp          |   4 +-
 .../common/test/cmdlinewrappertest.cpp        |   4 +-
 .../components/common/test/testoptiontest.cpp |   4 +-
 tests/components/common/testtargetobj.hpp     |   4 +-
 tests/components/common/typelisttest.cpp      |   4 +-
 .../components/common/visitingtoolconcept.cpp |   4 +-
 .../common/visitingtoolextendedtest.cpp       |   4 +-
 tests/components/common/visitingtooltest.cpp  |   4 +-
 tests/components/helloworldtest.cpp           |   4 +-
 tests/components/mainsuite.cpp                |   4 +-
 .../proc/asset/assetcategorytest.cpp          |   4 +-
 .../proc/asset/assetdiagnostics.hpp           |   4 +-
 .../proc/asset/compoundmediatest.cpp          |   4 +-
 .../components/proc/asset/createassettest.cpp |   4 +-
 .../components/proc/asset/deleteassettest.cpp |   4 +-
 .../proc/asset/dependantassetstest.cpp        |   4 +-
 .../proc/asset/identityofassetstest.cpp       |   4 +-
 tests/components/proc/asset/makecliptest.cpp  |   4 +-
 .../proc/asset/mediastructurequerytest.cpp    |   4 +-
 .../proc/asset/orderingofassetstest.cpp       |   4 +-
 tests/components/proc/asset/testasset.cpp     |   4 +-
 tests/components/proc/asset/testasset.hpp     |   4 +-
 tests/components/proc/asset/testclipasset.hpp |   4 +-
 .../components/proc/engine/sourcenodetest.cpp |   4 +-
 .../proc/mobject/builder/buildertooltest.cpp  |   4 +-
 .../proc/mobject/builder/buildsegmenttest.cpp |   4 +-
 .../mobject/controller/rendersegmenttest.cpp  |   4 +-
 .../proc/mobject/placementbasictest.cpp       |   4 +-
 .../proc/mobject/session/addcliptest.cpp      |   4 +-
 .../proc/mobject/session/deletecliptest.cpp   |   4 +-
 .../mobject/session/rebuildfixturetest.cpp    |   4 +-
 .../mobject/session/sessionmanagertest.cpp    |   4 +-
 .../mobject/session/sessionstructuretest.cpp  |   4 +-
 .../proc/mobject/session/testclip.cpp         |   4 +-
 .../proc/mobject/session/testclip.hpp         |   4 +-
 .../proc/mobject/session/testsession1.hpp     |   4 +-
 tests/error/errortest.c                       |   4 +-
 tests/library/test-llist.c                    |   4 +-
 tests/library/test-references.c               |   4 +-
 tests/locking/condition.c                     |   4 +-
 tests/locking/mutex.c                         |   4 +-
 tests/locking/test-condition.c                |   4 +-
 tests/locking/test-locking.c                  |   4 +-
 tests/plugin/Makefile.am                      |   2 +-
 tests/test.sh                                 |   2 +-
 tests/time/test-time.c                        |   4 +-
 uml/cinelerra3/DIR_INFO                       |   1 -
 uml/{cinelerra3 => lumiera}/128005            |   2 +-
 uml/{cinelerra3 => lumiera}/128005.diagram    |   0
 uml/{cinelerra3 => lumiera}/128133            |   2 +-
 uml/{cinelerra3 => lumiera}/128133.diagram    |   0
 uml/{cinelerra3 => lumiera}/128138            |   0
 uml/{cinelerra3 => lumiera}/128181.diagram    |   0
 uml/{cinelerra3 => lumiera}/128261            |   0
 uml/{cinelerra3 => lumiera}/128261.diagram    |   0
 uml/{cinelerra3 => lumiera}/128389            |   0
 uml/{cinelerra3 => lumiera}/128389.diagram    |   0
 uml/{cinelerra3 => lumiera}/128517            |  10 +-
 uml/{cinelerra3 => lumiera}/128517.diagram    |   0
 uml/{cinelerra3 => lumiera}/128645            |   4 +-
 uml/{cinelerra3 => lumiera}/128645.diagram    |   0
 uml/{cinelerra3 => lumiera}/128773            |   0
 uml/{cinelerra3 => lumiera}/128773.diagram    |   0
 uml/{cinelerra3 => lumiera}/128901            |   0
 uml/{cinelerra3 => lumiera}/128901.diagram    |   0
 uml/{cinelerra3 => lumiera}/129029            |   0
 uml/{cinelerra3 => lumiera}/129029.diagram    |   0
 uml/{cinelerra3 => lumiera}/129157            |   0
 uml/{cinelerra3 => lumiera}/129157.diagram    |   0
 uml/{cinelerra3 => lumiera}/129285            |   0
 uml/{cinelerra3 => lumiera}/129285.diagram    |   0
 uml/{cinelerra3 => lumiera}/129413            |   4 +-
 uml/{cinelerra3 => lumiera}/129413.diagram    |   0
 uml/{cinelerra3 => lumiera}/129541            |   0
 uml/{cinelerra3 => lumiera}/129541.diagram    |   0
 uml/{cinelerra3 => lumiera}/129669            |   0
 uml/{cinelerra3 => lumiera}/129669.diagram    |   0
 uml/{cinelerra3 => lumiera}/129797            |   0
 uml/{cinelerra3 => lumiera}/129797.diagram    |   2 +-
 uml/{cinelerra3 => lumiera}/129925            |   0
 uml/{cinelerra3 => lumiera}/129925.diagram    |   0
 uml/{cinelerra3 => lumiera}/130053            |   0
 uml/{cinelerra3 => lumiera}/130053.diagram    |   0
 uml/{cinelerra3 => lumiera}/130181            |   0
 uml/{cinelerra3 => lumiera}/130181.diagram    |   0
 uml/{cinelerra3 => lumiera}/130309            |   0
 uml/{cinelerra3 => lumiera}/130309.diagram    |   0
 uml/{cinelerra3 => lumiera}/130437            |   0
 uml/{cinelerra3 => lumiera}/130437.diagram    |   0
 uml/{cinelerra3 => lumiera}/130565            |   0
 uml/{cinelerra3 => lumiera}/130693            |   0
 uml/{cinelerra3 => lumiera}/130693.diagram    |   0
 uml/{cinelerra3 => lumiera}/130821            |   2 +-
 uml/{cinelerra3 => lumiera}/130821.diagram    |   0
 uml/{cinelerra3 => lumiera}/130949            |   2 +-
 uml/{cinelerra3 => lumiera}/130949.diagram    |   0
 uml/{cinelerra3 => lumiera}/131077.diagram    |   0
 uml/{cinelerra3 => lumiera}/131205.diagram    |   0
 uml/{cinelerra3 => lumiera}/131333.diagram    |   0
 uml/{cinelerra3 => lumiera}/134021.bodies     |   0
 uml/{cinelerra3 => lumiera}/5.session         |   4 +-
 uml/lumiera/DIR_INFO                          |   1 +
 uml/{cinelerra3 => lumiera}/cpp_includes      |   0
 .../generation_settings                       |   0
 uml/{cinelerra3 => lumiera}/idl_includes      |   0
 uml/{cinelerra3 => lumiera}/java_imports      |   0
 .../cinelerra3.prj => lumiera/lumiera.prj}    |   6 +-
 uml/{cinelerra3 => lumiera}/stereotypes       |   0
 uml/{cinelerra3 => lumiera}/tools             |   0
 wiki/backend.html                             |  10 +-
 wiki/index.html                               |  82 ++++++++--------
 wiki/renderengine.html                        |  36 +++----
 wiki/support_library.html                     |  88 +++++++++---------
 365 files changed, 761 insertions(+), 758 deletions(-)
 delete mode 100644 uml/cinelerra3/DIR_INFO
 rename uml/{cinelerra3 => lumiera}/128005 (98%)
 rename uml/{cinelerra3 => lumiera}/128005.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/128133 (99%)
 rename uml/{cinelerra3 => lumiera}/128133.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/128138 (100%)
 rename uml/{cinelerra3 => lumiera}/128181.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/128261 (100%)
 rename uml/{cinelerra3 => lumiera}/128261.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/128389 (100%)
 rename uml/{cinelerra3 => lumiera}/128389.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/128517 (98%)
 rename uml/{cinelerra3 => lumiera}/128517.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/128645 (98%)
 rename uml/{cinelerra3 => lumiera}/128645.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/128773 (100%)
 rename uml/{cinelerra3 => lumiera}/128773.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/128901 (100%)
 rename uml/{cinelerra3 => lumiera}/128901.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/129029 (100%)
 rename uml/{cinelerra3 => lumiera}/129029.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/129157 (100%)
 rename uml/{cinelerra3 => lumiera}/129157.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/129285 (100%)
 rename uml/{cinelerra3 => lumiera}/129285.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/129413 (98%)
 rename uml/{cinelerra3 => lumiera}/129413.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/129541 (100%)
 rename uml/{cinelerra3 => lumiera}/129541.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/129669 (100%)
 rename uml/{cinelerra3 => lumiera}/129669.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/129797 (100%)
 rename uml/{cinelerra3 => lumiera}/129797.diagram (96%)
 rename uml/{cinelerra3 => lumiera}/129925 (100%)
 rename uml/{cinelerra3 => lumiera}/129925.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/130053 (100%)
 rename uml/{cinelerra3 => lumiera}/130053.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/130181 (100%)
 rename uml/{cinelerra3 => lumiera}/130181.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/130309 (100%)
 rename uml/{cinelerra3 => lumiera}/130309.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/130437 (100%)
 rename uml/{cinelerra3 => lumiera}/130437.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/130565 (100%)
 rename uml/{cinelerra3 => lumiera}/130693 (100%)
 rename uml/{cinelerra3 => lumiera}/130693.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/130821 (98%)
 rename uml/{cinelerra3 => lumiera}/130821.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/130949 (98%)
 rename uml/{cinelerra3 => lumiera}/130949.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/131077.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/131205.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/131333.diagram (100%)
 rename uml/{cinelerra3 => lumiera}/134021.bodies (100%)
 rename uml/{cinelerra3 => lumiera}/5.session (89%)
 create mode 100644 uml/lumiera/DIR_INFO
 rename uml/{cinelerra3 => lumiera}/cpp_includes (100%)
 rename uml/{cinelerra3 => lumiera}/generation_settings (100%)
 rename uml/{cinelerra3 => lumiera}/idl_includes (100%)
 rename uml/{cinelerra3 => lumiera}/java_imports (100%)
 rename uml/{cinelerra3/cinelerra3.prj => lumiera/lumiera.prj} (97%)
 rename uml/{cinelerra3 => lumiera}/stereotypes (100%)
 rename uml/{cinelerra3 => lumiera}/tools (100%)

diff --git a/AUTHORS b/AUTHORS
index da64efbcd..e950124df 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -29,8 +29,8 @@ doudou=Sylvain Joyeux 
 rafael2k=Rafael Diniz 
 nicolasm=Nicolas Maufrais 
 
-Involved in Design Studies / Prototypes for Cinelerra-3
-=======================================================
+Involved in Lumiera development
+===============================
 cehteh=Christian Thaeter 
 ichthyo=Hermann Vosseler 
 plouj=Michael Ploujnikov 
diff --git a/DIR_INFO b/DIR_INFO
index 39fd1850f..f05e9a881 100644
--- a/DIR_INFO
+++ b/DIR_INFO
@@ -1 +1 @@
-The root dir for the cinelerra3 project
+The root dir for the Lumiera project
diff --git a/INSTALL b/INSTALL
index c6cf3ff92..7983166ec 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,5 +1,5 @@
-Running / Installing Cinelerra-3 Prototype
-==========================================
+Running / Installing Lumiera Prototype
+======================================
 
 ** to be written **
 
diff --git a/LICENSE b/LICENSE
index b93cee22f..4a684524d 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,17 +1,10 @@
-The Cinelerra source code is (C) by the original authors (see AUTHORS)
+The Lumiera source code is (C) by the original authors (see AUTHORS)
 
 =======================================================================
-Cinelerra is free software -- you may use and redistribute it under the
+Lumiera is free software -- you may use and redistribute it under the
 Terms and conditions of the GNU GENERAL PUBLIC LICENSE (GPL); 
 either version 2 of the License, or (at your option) any later version.
 =======================================================================
 For a copy of the GPL Version 2 see the file "COPYING"
       
 
-In addition to the GPL's warranty stipulation, Cinelerra is distributed WITHOUT
-GUARANTEED SUPPORT; without even the guarantee of ADDITIONAL LABOR. Support
-that is not guaranteed includes technical support, compiler troubleshooting,
-debugging, version matching, updating, among other additional labor which
-may or may not be required to meet a user's requirements.
-
-
diff --git a/Makefile.am b/Makefile.am
index 9b03ecb54..236a67f8b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-#  Copyright (C)         CinelerraCV
+#  Copyright (C)         Lumiera.org
 #    2007,               Christian Thaeter 
 #
 #  This program is free software; you can redistribute it and/or
diff --git a/README b/README
index 0ab5fe3ae..7913094ee 100644
--- a/README
+++ b/README
@@ -1,8 +1,8 @@
-======================================
-Cinelerra -- the video NLE for Linux
-======================================
+====================================
+Lumiera -- the video NLE for Linux
+====================================
 
- Cinelerra is a nonlinear video editing and compositing tool. 
+ Lumiera is a nonlinear video editing and compositing tool. 
  It understands some of the common multimedia formats
  (quicktime, avi, ogg) and audio/video compression
  codecs (divx, xvid, mpeg1/2/4, ...)
@@ -12,23 +12,30 @@ Cinelerra -- the video NLE for Linux
  and RGB-float colormodels and the ability to mix media
  with differing sizes and framerates.
 
+For more information about Lumiera visit http://lumiera.org/
 For more information about Cinelerra visit http://cinelerra.org/
 
 
-------------------------------
-"Cinelerra-3" prototype code
-------------------------------
+----------------------------
+"Lumiera" prototype code
+----------------------------
 
-**This source tree doesn't contain a working video editing application**
-Rather, it contains some design studies and prototype code for improving
-some aspects of the Cinelerra Application. This work may eventually 
-evolve into a new major release of Cinelerra.
+**This source tree doesn't yet contain a working video editing application**
+Rather, it contains the initial framework and core modules of the lower and
+middle layer of the envisioned new Application "Lumiera".
 
 As of 7/2007, we start here with some backend and render engine modules
 together with some unit tests. You should find a wiki with detailed
 design considerations and developer documentation and a UML model
 (usable with BOUML 2.29) in the sibling directories.
 
+As of 2/2008 the project has been separated completely from his ancestor "Cinelerra"
+The Community, which is largely identical to the Cinelerra-CV community, choose the
+new project name "Lumiera". The basic project infrastructure is up and running,
+and work on the new codebase is going on continuosely. We can show nothing but
+a running test suite for now. 
+
+
 
 Build Requirements
 ------------------
diff --git a/SConstruct b/SConstruct
index 5dc55580a..f3f9f0ddc 100644
--- a/SConstruct
+++ b/SConstruct
@@ -3,8 +3,8 @@
 ## SConstruct  -  SCons based build-sytem for Cinelerra
 ##
 
-#  Copyright (C)         CinelerraCV
-#    2007,               Hermann Vosseler 
+#  Copyright (C)         Lumiera.org
+#    2008,               Hermann Vosseler 
 #
 #  This program is free software; you can redistribute it and/or
 #  modify it under the terms of the GNU General Public License as
@@ -134,7 +134,7 @@ def defineCmdlineOptions():
 def prepareOptionsHelp(opts,env):
     prelude = """
 USAGE:   scons [-c] [OPTS] [key=val [key=val...]] [TARGETS]
-     Build and optionally install Cinelerra.
+     Build and optionally install Lumiera.
      Without specifying any target, just the (re)build target will run.
      Add -c to the commandline to clean up anything a given target would produce
 
diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py
index 419de6e68..f37cff630 100644
--- a/admin/scons/Buildhelper.py
+++ b/admin/scons/Buildhelper.py
@@ -3,8 +3,8 @@
 ## Buildhelper.py  -  helpers, custom builders, for SConstruct
 ##
 
-#  Copyright (C)         CinelerraCV
-#    2007,               Hermann Vosseler 
+#  Copyright (C)         Lumiera.org
+#    2008,               Hermann Vosseler 
 #
 #  This program is free software; you can redistribute it and/or
 #  modify it under the terms of the GNU General Public License as
diff --git a/configure.ac b/configure.ac
index 1730b3bdc..386bd94b0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,12 +1,12 @@
-AC_INIT(cinelerra, 3.0pre)
+AC_INIT(lumiera, 0.1pre)
 AC_CONFIG_SRCDIR(src/lib/plugin.c)
 AC_CONFIG_AUX_DIR(scripts)
 AM_INIT_AUTOMAKE
 AC_PREREQ(2.59)
 
 AC_COPYRIGHT([
-  Copyright (C)         CinelerraCV
-    2007,               Christian Thaeter 
+  Copyright (C)         Lumiera.org
+    2008,               Christian Thaeter 
 
   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
diff --git a/doc/devel/Doxyfile b/doc/devel/Doxyfile
index 7023172ca..2f90301f0 100644
--- a/doc/devel/Doxyfile
+++ b/doc/devel/Doxyfile
@@ -3,7 +3,7 @@
 #---------------------------------------------------------------------------
 # Project related configuration options
 #---------------------------------------------------------------------------
-PROJECT_NAME           = Cinelerra3
+PROJECT_NAME           = Lumiera
 PROJECT_NUMBER         = 3.0+alpha
 OUTPUT_DIRECTORY       = 
 CREATE_SUBDIRS         = YES
@@ -153,9 +153,10 @@ VERBATIM_HEADERS       = YES
 #---------------------------------------------------------------------------
 ALPHABETICAL_INDEX     = YES
 COLS_IN_ALPHA_INDEX    = 5
-IGNORE_PREFIX          = cinelerra:: \
-                         cinelerra_ \
-                         CINELERRA_
+IGNORE_PREFIX          = lumiera:: \
+                         lumiera_ \
+                         lumi_ \
+                         LUMIERA_
 #---------------------------------------------------------------------------
 # configuration options related to the HTML output
 #---------------------------------------------------------------------------
diff --git a/doc/devel/uml/class128138.html b/doc/devel/uml/class128138.html
index cf9db4338..6cbff1e37 100644
--- a/doc/devel/uml/class128138.html
+++ b/doc/devel/uml/class128138.html
@@ -16,5 +16,5 @@
 
 
 
-

Declaration :

  • C++ : class Thread

We can basically reuse the Thread class design from cinelerra2, Thread becomes a baseclass for all Threads

+

Declaration :

  • C++ : class Thread

We can basically reuse the Thread class design from Cinelerra2, Thread becomes a baseclass for all Threads

diff --git a/doc/devel/uml/class128266.html b/doc/devel/uml/class128266.html index f4fa4ec54..be0f14da2 100644 --- a/doc/devel/uml/class128266.html +++ b/doc/devel/uml/class128266.html @@ -16,7 +16,7 @@ -

Declaration :

  • C++ : class Condition

I provided a reworked Condition class in my cinelerra2 repository

+

Declaration :

  • C++ : class Condition

I provided a reworked Condition class in my Cinelerra2 repository

Class Lock
diff --git a/doc/devel/uml/class128394.html b/doc/devel/uml/class128394.html index a82ace25d..7b7e1a826 100644 --- a/doc/devel/uml/class128394.html +++ b/doc/devel/uml/class128394.html @@ -16,7 +16,7 @@ -

Declaration :

  • C++ : class Mutex

I provided a reworked Mutex class in my cinelerra2 repository

+

Declaration :

  • C++ : class Mutex

I provided a reworked Mutex class in my Cinelerra2 repository

Class Lock
diff --git a/doc/devel/uml/class135429.html b/doc/devel/uml/class135429.html index 93f554a39..538ad35b0 100644 --- a/doc/devel/uml/class135429.html +++ b/doc/devel/uml/class135429.html @@ -20,7 +20,7 @@
Attribut theApp_

Declaration :

holds the single instance and triggers initialization

-
Operation Appconfig

Declaration :

  • Uml : - Appconfig() :
  • C++ : private: Appconfig ()

perform initialization on first access.
A call is placed in static initialization code
included in cinelerra.h

+
Operation Appconfig

Declaration :

  • Uml : - Appconfig() :
  • C++ : private: Appconfig ()

perform initialization on first access.
A call is placed in static initialization code
included in lumiera.h

Operation instance

Declaration :

  • Uml : static, - instance() : Appconfig*
  • C++ : private: static Appconfig* instance ()
Operation get

Declaration :

  • Uml : static, + get(inout key : string) : string
  • C++ : public: static string get (string & key)

access the configuation value for a given key.
@return empty string for unknown keys, else the corresponding configuration value

All public operations : get

diff --git a/doc/devel/uml/class136453.html b/doc/devel/uml/class136453.html index 525aaa684..610053bbe 100644 --- a/doc/devel/uml/class136453.html +++ b/doc/devel/uml/class136453.html @@ -25,7 +25,7 @@

Declaration :

  • Uml : + name : string
  • C++ : public: const string name

element ID, comprehensible but sanitized. The tuple (category, name, org) is unique.

Relation category (<unidirectional association>)

Declaration :

  • Uml : + category : Category, multiplicity : 1
  • C++ : public: const Category* category

primary tree like classification of the asset

Attribut org
-

Declaration :

  • Uml : + org : string
  • C++ : public: const string org

origin or authorship id. Can be a project abbreviation, a package id or just the authors nickname or UID. This allows for the compnent name to be more generic (e.g. "blur"). Default for all assets provided by the core cinelerra-3 codebase is "cin3".

+

Declaration :

  • Uml : + org : string
  • C++ : public: const string org

origin or authorship id. Can be a project abbreviation, a package id or just the authors nickname or UID. This allows for the compnent name to be more generic (e.g. "blur"). Default for all assets provided by the core Lumiera codebase is "lumi".

Attribut version

Declaration :

  • Uml : + version : uint
  • C++ : public: const unsigned int version

version number of the thing or concept represented by this asset. Of each unique tuple (name, category, org) there will be only one version in the whole system. Version 0 is reserved for internal purposes. Versions are considered to be ordered, and any higher version is supposed to be fully backwards compatible to all previous versions.

Attribut groups
diff --git a/doc/devel/uml/classdiagrams.html b/doc/devel/uml/classdiagrams.html index 63f1a4fcf..03c862119 100644 --- a/doc/devel/uml/classdiagrams.html +++ b/doc/devel/uml/classdiagrams.html @@ -21,7 +21,7 @@ Builder Entities Controller Entities File MappingShows whats used to access Frames -HierarchyCinelerra Exception hierarchy +HierarchyLumiera Exception hierarchy In Memory Database interface components Media-Asset Relations diff --git a/doc/devel/uml/classes.html b/doc/devel/uml/classes.html index 48c1ea2d6..d2f240eb9 100644 --- a/doc/devel/uml/classes.html +++ b/doc/devel/uml/classes.html @@ -37,7 +37,7 @@ CodecAdapter CompoundClipClip MObject which is actually a compound of several elementary clips,
e.g. the several streams found within multichannels media. CompoundMediacompound of several elementary media tracks,
e.g. the individual media streams found in one media file -ConditionI provided a reworked Condition class in my cinelerra2 repository +ConditionI provided a reworked Condition class in my Cinelerra2 repository Config ConManagerConnection Manager, used to build the connections between render engine nodes, if these nodes need to cooperate besides the normal "data pull" operation. Esp., the Connection Manager knows how to wire up the effect's parameters with the corresponding ParamProviders (autmation) in the Session Constraint @@ -86,7 +86,7 @@ Metakey abstraction: metadata and organisational asset Meta MObjectinterface -MutexI provided a reworked Mutex class in my cinelerra2 repository +MutexI provided a reworked Mutex class in my Cinelerra2 repository NodeCreatorToolThis Tool implementation plays the central role in the buld process: given a MObject from Session, it is able to attach ProcNodes to the render engine under construction such as to reflect the properties of the MObject in the actual render. ParameterDescriptor and access object for a plugin parameter. Parameters may be provided with values from the session, and this values may be automated. ParamProviderinterfaceA facility to get the actual value of a plugin/effect parameter @@ -119,7 +119,7 @@ StateProxyinterface std::exceptionauxiliary Structkey abstraction: structural asset -ThreadWe can basically reuse the Thread class design from cinelerra2, Thread becomes a baseclass for all Threads +ThreadWe can basically reuse the Thread class design from Cinelerra2, Thread becomes a baseclass for all Threads Timedenotes a temporal position (time point), based on timeline start.

investigate posix.4 realtime timers, wrap these here Tool ToolFactory diff --git a/doc/devel/uml/fig129797.png b/doc/devel/uml/fig129797.png index e38a4cb77f27d773ec2fc418ec88b48ce2442195..229233231f800c5fc87227e88b5d09f278a16d4a 100644 GIT binary patch literal 18260 zcmeHvcU)9i)@=cjMJR%RL<MxRBnT)XQ4vv4Ns>c>5{le~B#DA#BuJJl zC?HW#Kynl$=Um~PLfh`9d%l@@Z{Ba-_rAIRh*g(+&pmgaz1LcM9sD%ZlxV1qP(dIN znoG(EO$dZo5&}7pMnMcdG20BMfk3z+mk<}U9b@MPk&m_4E5Bje)ijT&YC0y_TvxtL zXFzS6!&7`k+eU^?ZDEGQOY3CxmzRv`H!gg-tYI;mt0Xfb9!p<$;m84@4_}wQeEQf- zm16UH(~6=U>T-`*ohPd~`h>iDl=1m67M`OYTod4_6Mk3deN^EFC;)TV6MHC^BkNn3!3qT+>RuoK-^WyTP5RD)WB8WDRHU!f3-}a*b>UAnt?{UdQ zL(&7yEDST(K6+R7h;Gz;OBB$C*>Har@Gze6awdH&N`A=8nJLNp*)wpChphe%2_#)H z9RkVBC|~pKh+tSdMSE~}klDz!1OJ{{xMIZpA)VWkYI6xpiZ-~|h4iEjPwq$0ctYz` zd{{W%RzyurOh`&eRm_o(c5?Yxdt73mIB7cqd3K!Ji>glgd={N%A(ec()g|(KO!EHM zJvBx<4}IkKV$AlpxsqD*iw!Yu^E^d2amQ?uq(}+O9Lj%i;e3s9@VedkGt>|0`L10J zP(l9jt@LhmejIM1ynO(YM3b05KP+EK452ejI;X9e?4F0#f+@f@{bU4JJW;4QCf$=T z*rLA-tW)C4L$v@Ip-|x!5;WZChH;xt^-{IpBoEBee?VB1+a{qgm;6;t7Hn04lTph0 z*0CjK@c`H5uC7Du7w(AFv*+Z}vS$ob!)-@v19ul<)@bn>xN2M^Dpt;=*!XKxq06Fb z`R34*Z~^rMSpkyNb{b4la(?IPQ?9~zxwze}@#*dDcrMI~$#&#nbc9yg-NQ_(6^m6F zv~c~+x8$(Sj{~k70l9P5o;)=a{+$|e%)J8n+IQNGd1et2{@VT+?TINEOjKop8jYvZ zN^alQJ(svN%4mlVp3y=Nqbhh;N?^hP`eI)i1<@tK z14BkON)wmRyf9Lj1PaxN_ULCn?4*c5EYL0Mn~R_I!(5u6LDM3f$phP=)`%*e6}V8~ z0bEiBOiy8mUY95ISSb8UBO`MRSy>Ts=YFrHd%+dQf-=}8 zW**)SYWxJ#g|*S~$f1Y*Tn*l#V&5!1jf086xQw=jYx=jyViVj2Meo-L&r{wAGE>N5 z*k(g#z{-iMW)I%@{6c_1Ae6@@rtuuQ2-Z)|cEKy-RnE{>%bP(X9WP;`yBqyReN~mac0_JtL$AECy{h(XqH)WC@qF|-)09N~Uk^T_EH2J|&pIIPECh7ShA^V?)8r#3Rc zg#8{I)`eQd@FA`TU@lLv!Qhok<&*w0f}s*4CBw(^Z%mNGR21s{283*0HVPx$kHKK` zuucEK^3(J3WV;I0Oj3_WcjCp~QNTLG*eqXd^|q_UOKBBb=nS>H7graqC85)Bqg<)7 zJL#x*A*==K8EJ@#BEI+=*EK`0YH-7PO9t|nmm3r&M&H<`$zhf*Iyre(j}cDDb6)Q= z!t!sk4WGbIt1H|Y_h;J7y?ISjS8BA+!U(w_1?|Q34=+ePzNg@h3p}ZXF|#4$8=F9p z$g1#D!QFf`euQpHK)I1Xx~GMCutS>QdxOs>3OJn zQI$TZXSqpw<6=5Q;vSPRO(L;=(lrkbFDk2$>qLj?_(%Ld@*5W_jKjAS+E7A4b%l9Q zAuW7)G09tQ?WG}AkCKn5y$#V>ab;l>5j(ItAc-(rh{XxC{cpmsv{;OuNa#^E2dNJUPk)z5AI~2Mt zjV?h{@!23I+|Z=300bf#G2x8951U0CLP^5J6gU~Scf3>Fw2~Dk@O0bf5r{{0CmEmL z#^xNoy#-etcR_ACT(hiPpV+M0TvQ6iEMqqlbn`~=Hw(WhU%Yth{{2C6E*7-jqte8} zJgc3slg*beA2&j}xvK>~d-iNu2Wh8eKGTof`2?5S8d0y>tkf80LWm1tgYsCQATKmP9-QOG*SfA~J#N$L-7=MVS= z`E9d>@SQ!okuu*8R>@&zHa$$Uk-u_BRxWO|9qB%u=!^S0orWLw@!@M~LL`F)IXkw3x0qk6X$=F!DyYZ4+EB>j7 z>ycxO+}anW8GCI4v?+Psl!4Qj|NIjb1OP~dK~OrU7Its(&S8xo@$oKW!G58 zk|Y|EAK+2C^R+1)muuuW>aCIEeYo%zUBWN8;0}BJST-X{0_P6)>e=}tbBhCf+C!^ z1>jt83QWVo!s5}RN6yY=4dWRZ8Bp}6G<9Z1#^e;j!NkZIE9Z6-!QSAsGo8kFB`WVh zZ$3Gvqj9YlrMI^?j`!etc49<<^ZLx^&z~DOT?8LH96{Zv@DAk-X1E`7b5(X{!J*ov z$G|~$`5lAH#++`Y^EwhYg`Aw4GD2e4ExKP>vrlED#hX8RH1yiUcU+R3ma}5ihfPyU ziG@khR({$3O)}W-*S~}uqJaKt=78eW|98&v4cYh ztC-^IS?C}w>*<3+*rUYj>+A2|VN8b~nVW}tAUQww^i1KC@I`es%usS{w?;Fo*xeS? zD=CljUR2N%e0*lj5vO4JNIZ_5%T)t$w>=))sUi%n0gi0L%5%cP?Sr98=2DO+4Ji;6 z*kWeDq|4_oUrLSNJ{fNa;p5|rjEr=t90GGLtXDkuG4UcSG%l{vdc58u=gr*_?<($U z3LB|&Cyiu{Pt27@AcjO>D+^cOjUT-jHP*>R;A*Cn?RSWN7aZg7uYudxJs7H_s|lx` ztYI;`B}%|s5IZmsSrwq!@@bdCnCBJwv z((+sk+_bf=t*xnP1%AqwJ*}WX?C8;>A|kJ|vrnBo`GMtAM~8_0+zsgT{Csw1W?$Z| zi#9ekSFd&ivWgKa$-DK4%si0|WVr!#iaECe?o{NC-B})QSR5?xnOdb0za5y7n=33V zoB&6<8ydzVlaaK3At8%%b7$(eT&rFxg&fj%ba8QUcgIb9c;?G`;Q;l@>Dt$1LeR`_ zS9Nqs9G7qB_LQ48N95$>)Sz2hTDrThn_O{otHif_IQZq_-PY)9H*cB;_Lf*C^vtf) zc6WCR-7LJxXB2%}q^*IAuyfKn5rt7Sb=Z z`Fa@&Mr2fEe$Cyz3S9FD8ymCW4J*vn^2Ef%%8CuRKbSLFmyK69Uf-?{WW~*TdGesh zE^sPJcGvLAGsQW(xQvgD`Eb21phH09Q&c86x_K5kiSh)&jX!-NB7_qGIW*Ddgc5m3 z{|-S2jwbj({`kqQZZ1eEfIGka(p~JnU;5K2p?UG^%-sUC+yhX4{b&)N>qHbx^4>2# z@~}Ii-wnwyrhN*9dKe9?M$G-DZxY!&8|^;n0hsZHcFOiorG*a`40qK zCZeDO_tQAJcR$M6`!?EC=PAHgj)W7_$$x*|e6MHp`Go$3=`h8_wK0=VE+WvO<)W3q4zI)$d^=??Y z7P`1jz9~85%^a`CeZ_j3P*W50z4!`#e?gE4qZ}ZR1-kFmxb)0qE#xR7U2s&Hxw{Ip z(yWn7Ojk+4l+@?T~YHNEc0Xfb#yfpk0SAKX);YL89i|2`VtV~JK z?Nh5r=oV~jdvz*1_mIa0I(|ga^rtk-{$f=`vE}d(oCQ!ikQxjOILg+Em+(B=5vOO> z(~K}<%z7n{S{oZBomTGPN9t(dGGLS?!|u{v0%R|^dS0FKtB53rjdNbRc1<-w4jXNe zBLz-Sl^A@yG1se++i}7_(D&d~lo+@l$N*sx5%vxa)jKm;T4`!D>oX9R1MPVuns;Pm z@!wvCEL3g|_4W1XJ$hrhyD`rh!uQ$Yj6V#NBF5Vd-YV?twTEa~YZ>s6Yd;3c`X~|s?|qPuEe4Zvb?TtZ;nCvWNS>x zwIWFeE6WCpa6gd1v}-sfiKMkj!Oq$p(<24oHi+*-mG@VZY_^*E(`+B z?{h??{&P|Nae}&U(ysXRhS2sjV>JQ@W zYHOefKjYwI>=q;RiT-Mpm6g`k)^#CYbSYpYiJHe&4$Yz+LLgt5!HuVvq?(zTnY_IG?c29iRGLez#}N~s)ZqYxEp59#eE1NY zTptx29Q@j(!N+;sfNIwFU`HSUU`0i-B(zWA&mBE_fjG5tZBHTqO2b#-l#GlID@TaA zLAkneJ;vXk%A_S#HD;k~Hpg=uP-yq*lt_%*%}QrGLqkI~wYG>;dWbuC9F|sY%NW(o zj54fnIhXV~0gsuYWH=tk1$S=<<{)V>a+xmzywdc}9h5TY@ze*g0R#ewU!MJZ-yZQ> zq01Jgt1P`s6Ir`M8j@$|)RVMo$U|&3-A@05lXZLpFMw*DA3||Bl338MB1;HVT^J_; z<(X+mSb2cBaP%RKbnK$3L6zR|iHbk8=@>yWLPfe77O8@au)-1TfA6;c#d{}E9ztTE zBMKDprR6%rp7H7xAjB<=jZtUrYvRpR&i!qW7Yo|iBQ~I==I%vRlM*NGkdu@I6A-YN z?al`Mya>VGN*4zc6B9eTb%6hNk(u9v0SH*OlP&ijJrWWUG6X?_IwLM_YG%gF#Ka+O z--2wefxh6fyi6Ur)q*Kr!zjKJ`4NUrf$FTi)P;nqbBC3+G8n5CA|kZkRX z?p!0dJ7%lWWpl^1Dp4^|1OyELysJ~~?aj@rA#00AmzS60;^OK-WI3#T>+qzuw6tt* zZ%>eMS~<;wdhnM0l4SP{dMDrYMgUPS8yF0Zy$`4~Tm&IhR#rx=1YoqDo?Z~)vN$n5 zF=N{2;uhEM-_H=aJ6z>vnA-!tp{G}VuOsRHr&IvrYdn9OTgE32!fHJqJ)mb_YHBo=!M%-;Jm z0i3&J#CMSWLKp?8#oxt|&;9*u%*+xPRGc@rC>?(wOrCV42_V;7&gZ@dO61`0RWCvX zS%mzPz-~xqIP{xSuJxpZVa|zOk)-EEaDU~&ND3xJ!(?1hAXynFuOQ|sVyWs~3jDjm zp(eU7fDucxv5?c5-_y4@1+$|N8>V;u2`ROrvz-T&L3Y=y5F?-+Sel5VEGS0yv6sq$ z(B5#aTyVF4cfVhsh34hj38TUXKfmgiNd`D`~U>QUCV0M z?G->X^gyd*&|#Pf{p!`Lh=_>iVrFWwlGZbyGwkf_V4Z(Vk%)<^-311;^kRkBolOSx zJ)k2=3^|Uk_ZY#g$KG{zYC`|8?3|poU+{RkJa{~xKxSo{9@kK-#tQ@J9s~Fw#t6`( zhWGDTO$f{oaNLTtw6v0v&E*Cz5Q3Y-j)P@(atVuHBaPyvY*UdF3+0P)kH7sQG8yME zwCr429|dHmY=iP{meqPT%K@jUxU-AR_wZC+12sz9F~gY2+1%3Z;Fw}CeJH2A>6>*K~#l%L#AMs*!()_QNnm}>U5j$$+g-eB!2moP3#QhmDq z*zx1Vg@u7^5^4xJ?AoWmz`)?(Lk-sF&Yc5NvE1%l0hm7FYD}kfY*ubnSyonab>WvU zUxtQ;{>09*L16TY(A^t(IndLyxjT%(|eMf5a`iG1y@|_WO%r^%j#l z2wOS3uCduzD?5*8Vs^7`m)(@vo_Gdm6SKk2?i3Pdme5`Tv_!Dnc9p8I^Olhj5l2ky z7Y3%Q3q>uu1@VnlZo6cLH>YQ33v7+(-jc~RfxNy3v`{-K_LbQP&`4s#tu7=`SEFLYNlR!K32UT3iv*gL=Sg)#wg@viaZ&)wZS%r5;8O9ow6TkRL9VP9&LoLZyB zr>Ccfce+dBohF~3)JkP!Vj}3sd&iY{87FYn`luRojcoUUxrAF~!lVU#x13ZNj(9b% zt)0*8*63<74*TL1R`=LwOq_q@_Wb-jFa<#(eSs|Pf;}m6zcU&1G`K%o5RHf~QC6db zKuZ07!d{yu_Np#@u&_;8y8uk{Kqkk*VMI7=`lRs2z3GIL2OjObDx6yG-#j zf4ztlnOqvJ^W+H+4}bprIcQ!yJFdzvEWC*XHiytq`jCcC`<8WbV&dprZvjapgXEJX z`fIynKrPv&MdI;>?YQtI4{o2JPj^Lqv5q`cEv0=fZkJW*hwvb_`HEY zeL)GNe4xUpsHotVeBnR^$0^tm)ChWdda&*SMLmZYVbffoldS%QS+kS7T_ z8OPgjmb-jh8CdwM&7kIUxAk3Ppt>Z8qw?Y~;*yq~_1T6Hu4;$HA>7L=BPfDMQB_gl zioIXN+(;+K;fLTayUyDEina+EG@Y;0gK7$At#iV-^qdhx&7q>*PLgDom^TuP)G zouS#unw^|OI7rDM9 z@ojqg%|s(_P^0{5nV7^C>Rh*{8b=Svb7lgG%EyPyqy=E*$(H9Pfp2yf%4s>y-3bJl z+5rzlyFw@F|CsclWDSft`rzxSvUDq`Y3HUK?AJ7ZuDDLEGs%VY_eHaSa)61 zi38$ZW>$`9eXNX=DCiX}oqZZC8Em`WrGs4SP{Jl&R#Dj<3lQGXiP0DhrRZA9Ii?-^ z%T0Qx80U1CGvBuE4Pa|}Re_tT1S=N3mq%YQJH{kVA_i^SW!2@j?^s$cDn#NGEwM^2 zAMzeV`GzX>>i4F=hh#ZMXF$6%`s~AKf+n_$_rn2XzF3XNfqDesdj)Q1_UX`Zt9Oe< zJ%)P44|Ek3eNcDI%q#~=MHn|JYq%wk79Cq@!;0(g1VA1#Z?Cnl zm*83}3@NR91-~Jm>028?$y4!#o!*NoVu?A}szJ*i7!MP8*;DtSC@VX*pIPWvM7|I6 z0J0X@%woH>G+KjhYH9)y9hB8e&yI&jM($RBl~lWQ$**Dj{=g-(;J(bX7C5c{*OTVc`-SM&d|nPl)Bug!1p#H!c+X8Up=VSP0gU27++aCv^1`t9~5eNZR6Of(i zgE<6Xpl$-aobBubWi>S+e*S0?6U7nb^hIYD7I%qB26tZv-h?HAJve0c(R!nhJKLxl zfb?aT&4u-C*NZ_cCNs0M&CShI?Fk8ykyBjL!?phvN@uBGDqlW5Y>JnNbb431b(W`6 z6m{6kJnVB<*D1q_FSF~9dh=5N&agTrCRR{X)WxD@WV8sk6(uQNdZk+c0yRhk$nmSr zmAJP+omU7rtQvC`fc1xigM&|lM?mm~mxgLs%Tq;`u1RG616chq=*Q~k8NUThPT-~i z&jI)XkhC{Jb-DfCA9TOBav8{ixmomg%IS4%rbAlIE=|m5cr`r%sHwEHbW~|h@PK@J zPD{9#zb?|l&{N798U@v*_^ngMfZP|SSBS~>^`if8w#5j2CJ5cOW2Q4NfbD@olbQxc z3FSAQYCl^g)a!qrcIOA|%iK4Y_&Er3^I*h_-opa)SR1U9wv9P5KV>w2nQT&5NZ$@TNN+vlrJ;=%(AM_@oMrXJI5Q2|YI{O^oHR2R7nfu62!8tUI}Fb( z^bOAip?AoF69bJp!K$Nbr~84W#jAehYcuG?JOUn2hhaAzG8ykh{20iyE6C*!d;ZM0ZI|s8%iI&ZBnEy#AkXdQu0R@jw zE%x4n2Upb9_libIOH)&3Mn-R`^-C16N%%J=Ui8HbuUMuhx_=aomJlr*)$a;zEElx$ zj>PRJAo+MQX17tvwk{o`!GVF;*jPbWg6ql$Py}2+O>zL$keO+(8qQX`?Ws?-ygjGq z4p#8^`T6}(b2|RljORz4{N}Sx7*8IuK&eZy%H{!;128nr13m%>$u52qv%TtB!n##k zg||p(@9F9?4P4%K1$i7h%;5+L(spxm1J2p)f`BDRy<(oCqHh%(YYH{c60K-ZKo|M#7U}Q>=b8{XESwmX?U@as{KHG19w=M!Qt)?#< zzRc&jZ7BB9Rq0G_j47CR#~>;Q-3IVsVYL2`4+-h1YAZK+{lBk+9C1nwzo1Kmkim zemA~cSX?|gIhmT4<{}dx9eo6P|K2@G-~g-ndLY;%o5li+C^}^ELZ^PlzswXw-}H0g1jMR8uP*S|K6w_DL*xwgv5!E2y zUdL$or1#MSUHv}Oq6VAv-vql2E(Q{%KMHo`_rk}<$FU6>e+L^2iK^)&M5bS`?%$(i%_aQ(aeQTm9w4_Lw zIq`_K*JX5Lzu&r7Q*L(lJn$nV0M%kd8T6VJ2}eEX-a5>EvF_lHle8YoDPOp(s=Dqd zQ&dz`9|cf_+m!ThMo!KGT!n(2RkrEkS7s5tT^nd7l)1(J)9#9+SBDJ4+qlGqju+$I z3+_OP1n_@}$Nuox&5>fw@>N7lca?sf%wcn`<6rmYtTb6n8_FFh&*V+fg`&P&E+WhE z(|s&B8n?V3cXIqjkpDI`{RhzNf8SGzK*#2Mp%pt{Q!Y+qartuII$bLO2dEWgqoc)~ zN$kJ6`y4e7{vOOcJ1OXwsf)aFmE`mjpl;q+TVwIy_*JPGl_A+TAq=DYXZ|1TnU9*t zovw8he{@1dmk9LOS)AC>BpsGDz1x_2OR8!eQv<8(6sx%_;#Yzi925kkq;-7#!omVDE^Hy~ z{%rQi4aDntmK@aYJHgu3O6-+uj5|}h=4&;!x($dvK@7=#^X3iGwIxb~#Bv;e`y(YI z^B}l0k%l+HGg$x?aobq~YtK*l+O@8Ww6bSDKP-OOe;n3dVp+YCLPQ}Yqy+SR9d~(~ z=|wOP6?oh(eCONCA5;?fd_L6-f5VSGrIkBz;=~qE5`pA_3BhlL0A-MEtNN+X!!X3q zAxIz!jB9Hgi2A`=M=7tJ2E{m4J;A+IyoWHesWFevxokY3&`C9Fl%RgWkbCuH?S-c3 zzj6$fYRWV}RWWZ*mjj~!+CWKh@kWH+quwgF@`iEB(WW)(?Yl&efp=9A-KR1A?k*A8 z`xLmsUJLOZFzeBIrmwvCB6!Q|lhHL0shr3O3JaN(k3NKU(%gQQa1HpX|H{%#NDg~j z7zzHmgYW-$sA`9=C225Z6u9?}+5%PA-`^i->)CoGWWj>E`FDWz26$Myy1Jwt7Uu97 z@$vCIO2LeW54SxRO9OASwA68X~m=curbU2`t=BW^1wfD7@{Sat2;|t zR75k zN#HtIKXu5s(^d!G8gmu1#G41B5zJ2g8HI0O@ z%{5}_0L{Mi^z7-smHqwCb}0RLXM;~$#n{f21dti*Q!V(cPDTS z&{vZHJ1^`^uGreHf=!*`CN02w*PUZv5$H4?B(YGj+J;Lw2U>wf_;n*ZZnIjVe!y*W z(Dx9BXg&B&+Ay~SfA*)k8!M6uZrhu03dAPB>F~=T$X8AU_Y5VBS)f~0a(NfGW8|fR zfx{jh7PbaRKj2|Nb;E(nB7tl?GcyD9!$6Tgao8QCIUsL9AtdCYC=o*E02E6Mb>R1U zJDds{(O|*jPW|%BFCYI%m$U2(P9PgS5(zd2LlfHYsHiB=&;y-D>`G+y6%`eil@EN_ z@$W>o7atQHy<>^*v&dC_E@}$em9RgSW&Bx_`oL+t^9WD#%Y%Vr^4_RxSFhd*beb>f z0oAd}a<~fkL9BtS33w*#b|8@9!BhmG=0FO2OU?x<18B1rBqxKt!-n_o-+wOWwgY?} zh~&)7nM7aCBWooDUi)S$UK)vWwUn+P^@c#mNeF)zz;Y4nIlA{Xo~XmyL0#z`=%xW6 z&H?kR+=sCW(ql6ao7Kr752Lr{9iA~}W z0T!r$O>$SFmO#YO?&yJeci*bx0tD93ZM_TElMV?K%+ammHC&>QmbpWr_1h+Rf<>B^ z><5}`*?H;`d)$YEQ}iA~%KgGkC_!|Jc?NqSC^D8HFTX8)txz(sMDh@%HuigS`~MEh7$!4A|D4nw)$f zcz?43M?Lt@3(4mc4f1@UB&D@&47`7@GXEWihw;yC8nR$D{i&VxTgz7JIgv}_-zSUQ zW29g+#7qz`+96R8Y~MD(DXBMLQxMRsf%x7YFDr2U6G++)gP4xr0JfON3GB@trr?o)EJ4}ucz^ud*-Nm$ zCivgt=hr_}@pDhx|L>=4;rmLSen#EmhCHFzz#G{gI;z5bz(wJgzL?CH>b9CD7BWid z5M>5_NT-)MR1XQU^`i1PlSs_1ntu58I{E2;-IxBh{L~LXYfL)$VwQ)2mpQuJ5__L1 zFF?aO{5p{y1(Pt?zbu=0^OkF`Y$F%=`E|nr5iU}sel>r_X<&HS?>bR)V7bxCaBVvS zzFW?ASGEkoAjHWtlz!bYjl>|q zibv4TC;Rcdzdq=H{!4iK|GwEM1aG?ZwMhK})MHa3c>Iej2?W!W2LBslf(-Kw3bWGzkg<(yP)GLlLA(ks?JvM0zg)Vgc!3lqLv#pcDnEA|ky= z5flX}(yK@fgx->Sg5PIhzJKPwb7$t>J8NFoav77n<(z%?ex7GPCt=!}DwO2M$RQ92 zX4 z52ufG|{y7=@G;EX4o+`4|J^EdAz@c$;89dYaRjdO3!5r{}AZiViDNmnfcug(y}Lk}7NF7}j2z z{g|#@p!l-T%}ue2{9}kZ@~@|ktXK_Mj;C9F5Td*{8zEHvt!lach)|z73p{PKpg$^* zH%?C2kLLLek5i#GZg4lBR+1fs>*~#mSkNZ)E(YfAB2t2ZLMU=v~RVs3`>3T*PEn79fp&` z7a6zWM#wAqinS*>Q4bT836a{#Ew;$={@Yxk4rOM?;UC?a)H4gg>iQAyZ z%^|~D9<59tF(}ZiL07NtEb?Ee+HT)k8J7z9fK#^fEL}m2%t^a*dv`ylC>z+SLU-?N zb-+3Uw^tvJkMnMfC`_PKj*TGA;YkDiACT*e2-8tg;d>e4dW=fz5vLiyNDa1-pr&Bm zFa?IKXQ83(^jnuEy}9@9++Udu3b}fvaB=17Xi%u7D1E-%w&&2 zl^(n*gDF&q({A2<11DFK4D&EG=5{%Rnyr5u5x28pD_~x2HBw!RvcautA#giL=V$r( zLxq+b=s+G=Of^PLS?yix>}>qi3Q=8Mc7A@Anbe)bhgn`Z@(&hrqCdzC1g_;im}-kK z3($uL7Fu3t#Z2+!=JF$VC(yXnY*=T1cih!0S1RqgmZOE%U)Mq{D3pe3o@~P>dtuJu zyQM8{uwF_jQNzg>>TL*hr!ZOG;!97@O)5j7cBEIn=Cp{xU~bu=D{i?(`jc9)f{02X z(NU>Xo@-(LCX;DGQHQX9FvDcv!$*yH9-J6wcd~vHr9o8U8GyOCRe-FTelNwiyJn92 zI+bv_phD1Pa$<2&#oX5>(93HbxmQq7vs)ZGk89xQ$4%oRBckY0)7UW%Rxlx*dpMV| zdNT9v&KeH6ZJ`cXE|{=+)iwB}vu(Q%qB%NAYQ+D>(3{Dp zPp_59xLB`yte=m3lygM?MN5HFDnl!6kuuYA=&r$J8%%9-KGS&~8V23^)`=t$oLH7o z*i*HBK0>`feI?3PshSU?fntUs2&->y4Rsgt)A2vxa;pH-zXp>DVL2c4EdRyO?wq-y z+}{Cj&z(FuD}=WGII%ob-G^h8xvuD6>3usf zQE0uoCq~{)Gi7$!#}BzPU|+p!lll2siTV6p*P^1u$B!QmI13FHT5fHxp%(|4r9}gi z2|sbq3hoIUH4<{uwhnHQM^%q0XGQEP!{Nh~9;J@wCbMC4@L@)~qo}d?@~e}cQ0Uf^ zmN)7Og36N<>LcS5P&=Bf)Rq+30t_}TlQhq$14Ha-h7ls~hl+>AhRX7bUVeHl2ntW+ z5H#Ja=`ARb_gRXj=f^fz2c&JR5l8QKKR9`@*KDWCcf|~g-9UQJCx*6HOhhMmEwZlq zkjSN$%6NYr@k|J9Y;5!h+;w%dvKrNDE#F&TD5w#H9mZ`ohxELlLm72tJMX=BhCluK zUWx-d!?-j0DJv`U@VK$x3>bxeyE{2ifk;E7`8 zr^b_hsA)KSas=)~*Lu`faq=X}5ynpx@2hD2qD4rl8iturSFo>c;eu@iD(qcHWrEyd zBq(}uk_vw|K@1TTIzwBoW!;%+$0#~Ty&ctpQt#c!gDTUYvPL{EPiY0Z&CY+p$RRLD z%)`4jHW!prw|8pNw)(7Kv(b=iAC;=_mqKucHb+nJezLX8W@$Ke=`dVXmnPX%z zE`fogF@2aux`>|qtGG6EZsZg{y#lr<)WNJAb6dh*EjO3P9Jy!TA;$w72wX`HP>Ig- zsIb*aTaP@Aook1(^1}|7inB0UMu;*&FIHC(4*l#3K|m? z$Q3CG=jyFV@0uMBN=l?Zy2_S8VB1+eUR+#?F+NVB8dptQzShLjMt;OrBdt2)rAI%d z)N6M)P}G}ytG(Qf`%RGBT?+E6A7iR_hO`xq!X*UvDA!U!J*r$yGiTg-1nwI)4rQ(s z4>X=khN)R+hlcJZx8MYdjVFyzIGQcP8X49Zb&hb4(7_q+o!FK%C3Xg1UogwX(7@?=N@9wm$;->154jaOlyR?O6`&?sNis;HG(M z;5N?ADKMkb6b@2BU7gVS@~f`w8nDv&GR^wS#bT);$MtTXuEB9AJ#VRknbU1u0(pyJ zhJLH4r3A(ZkKPhE)0w~>w);@EdSn4d<9qR`%48V~)`_rd^+44y%+NeLcDFg?o14|m zS?cPQl+}VjeRyi%Qr*jfz_pcXdFZpD!m(bVs@02HTHVe_epuT2I@MOwvuDp@Mi6L9 z^PT>!4*9N{{#y!)5})6LLblq8WQUe(O{&&j8>XC|`;wp}3dc@$;!>AQ+@1=Z+;j{; zFX*CdmB!)hmEvYX7$KNcxGd}e3{%tml@k`;*womP$tJjRYlv{JS*kyhZc1-; zB_4oB@-<`l5r8QH+;ma?2RNO1!wh)_K)+f^G-8f`$>e(QJ7oSYK&?#m5(N225kkV6 zKau16JnyVfi}<%$BoG;HVMoFiVesp;=+IXzIe$=v#5FuTwf*s$G>*G{n+SsVnQyM|)o}}6zsH3ghDML$VYn6RTK$m@0h+8o zZ?H3nrvzd_{R2WI=>G4H8U zs#^F%=+r4`_pgzmSK`-JyR@`YWqsd<(^JcDj!w2dJaXhn)rN3qg7TZRQv2Sl%uG4# z=0rN;hJ`+lW0Uvq8*>@-nTXok+k=VjUq@=#XQIc%IYrbad}H9f zHKu@qiC9L^L3Ar8Au+M<%a=#7u}@=X7Z+2dU9W)yf!KL^@gaQjp_aU>H0#jNP`r(= zEPGq=uCouvXI1lKGlARN+uWBDEijVM5~NM-sn@F^q~g-jOmr)6tB3mg`3P{b7A`Iy z5e*ytmZK4&4S{w~cOD5_)+gqjxpgjx9D0g}$989Z0p_+eS{K6Zrwaf2K6#^4U5Jtj zf8<}SkW^3@8J3Ib-h+^`ClHEchIa8jIQ9tFDa>o5S7+IBQ zRw!zIe*S&3l)3kiCzf&hP9=15FR^v0n@G7nI``rv8y5@>Rgw*~A-!x0q5_ajyLvGr zNMXp22%C7TuK`1QIt*9Q)OH{FTFaDeDM#}RcDf28egv~6n1J0Urb#Xs0{ry<;HGMH zUt0)n$^F7nJA;gnKck2=UU&A}rze25bay{`^oT0NYWDLpdV2a{A)|PGW8+zmvodGT zy1BcHiHbhfw7q&YB~)BWDop`7j0+@Gfp92hl9ga-dIU{hYa1Coii<0?YK{h6p)G!4 zsG=-0GxOCeuZ_i_YV<4`?R?|Lsne(1+uH2y?fH3mdHMKgQ9V69U|7b-$0wR&5D65l z1pcsv6kUL{oz++@V@MljXJ`3@ghoniJMIu4i5D_YO-ec@t*fo=vOfQ1Yh~IN95yz- zY4Jw!-CbP|@87?FFkCW1DJUpDfBx*y|B@F>%InuY;G4I((gVLSdDpQkAAK2Gslnz8 zuGIh9)k;n69d>U=j=e*bOYK=!R#td;c<>R%uhY{A6@P@PzrVkhR*deuiDgz9uXfyr ziZ^ctoi<+DbtyBSKXe2mTwg>Y34Q+UQ(xa}j~U&Bw$gx|_2J>+T2y;`dvr8arrzbt z4>#H`ZY^-SPk#{L=fAARChbx?<>q^MZf-8&w2`R$*Y@YnpI28`TdL43-;s@UStF5j zoe}DPeAe@MW##VDSi@mzc2?11pXG6o3M0S`?Iuas4?2}?E^rD62t+UloOK$l20Bnt=6K!g9kV z3N_OpH$d7Bi@YlnNB9Rvx?*9@(OdVymB`}=Y50QF9u}r@t7JlgXwvJaba)}0@b4)# z$wim&_vHjW2omgH@9!%jf2G`C*4*{Ie{Id-2Upw@RE)pP-2V+v(-`bWOw;5uMtO^b zp<|T*!adQM#{JkI@@rlyz}LHU`uHiZAb=S{Fgk;Ok zC60IEYj2PmU1~ewuV+l}4DvnvGt(tBn=%~_0-?n^Q{O+GhGd`Bhh#9OE9&ix-le|Y zo+x7TF4i{Hw`s!~w$voiYf6{2MszNRW{MrTyPT<>0BWSDoSfX}IYJAc%3cnK;yl$p zUs_sP`R#8{0KL>w*jwc{-wNM=Zm}DWMinwJ#}Mj-it)iEVwxwapqsGqw-Jn`1yr{z zL2WKID!Hz&uOHU(Aw?$Ou84?8N=iy;X=%EN5Co^NzgF5;SJH6)&CzUBArqgUU9PTE zVfVFeiez@KS~DOuq_{=hnp=^wjV4!7o-~9zcItoF(<0)ykIwZ_3h;WGPDq#;*g~ppfwux6_ z6aG{QHKey7zhWEkQ0|kz%_b;tc?v)C$RTxJ&(&|AYEdBNx3^ykX%O+8{Tv=nj!rn; z#wQ@)c{YWOjjg=AoSB(fGrJ@|UlX2`oE+l6YB)+ddSQPx)%SyB&BxDQQe5mc-v^a0 zcKA|Uh1huY^5y5Ap2gv+fsLyGaZplH1_uZG`uaLLI-WdvQb|b(Xi)u0DJfS?P5pN_ zUC|G2bKTNMB9q}{QN*j(9+S#$jCf=@E}$ffD<|%&7-K>w{IsUC21r}p5)%A}S^Z3VE!qhK9zl7|&E$NPCJ*Szg{HUeD25f`qmyw!DG@^J44P_D5p5&z}SQ zbdT-4IO$i_`firK#>|=sC>r0s zjgrrp)}&!3jXMuR7qWw5d@Hby^u3lgCXQ_@pJR3;$X;?SJL~0{`dA z(r;1uKd1SvWdA3Ojf-#lAp#mjd^V7#r`~i9ejA$K`$7iMnKA`n0fI^$8?r1L^1RS z{01TCvUU&&S;_&9_xp$bC+7Zami?aI|7RinXD_7h^zR>p-*-9TGvh6iAaY3&xkIKw#n3fD>Y4$h(RQkVehy6;OtViHT?S5AYA5UCey@ z*7E-S`<51$vnigQp6O=Z$7gBy0QR;`nk%TOuBzI*eVF|eA0H-qbz?(HTwE65G5{8M zv{D`H>{?q|eCCUq$&Vaa!C?CP`_d}LEUeE9J6>4{7|Z|@CI?=Dnr zO9rnMP<)C6h_5s;kqHm_QtsbBPS9mWau|PDU8~+yw{vvtuDk~U`AqhqgocexrtZzT zo)-XnmEkrkK@Y=k=A?5PQ0bG?($XG2ED6~0f}ZhN8ofX*cQj*-ID-+L8hvVQS^?*a znQR3(p~7nc!!c59(-uz8&q@^%YHe%lJX~3xoo)LmLuszJKuc3IKPQLu(>CF!2>YHw z-aPXq(z&=YfwLSEFh~OSFA72vHSE9gUb}$smW3mfs?kx= z01VwxXhB!-hJcAK;XO@PmnBDs8^kozA{FB{qeb^Y;b0|hJM$BE|3k79Li$JSS-;gA zqpDy!uV2q<7)v}GcIuw$UtR#u=jf7?0{9(Coix4-MjuG zE0xg}FevMbLj#?ix+W$Shz+L^@3sA?ILg5Ab!rM=?YP+3qxAG)sz8kJ^73+ZU0$AO zu2Lt7hR9d)3OJ05ab>^_4Gn#Lw^HR045zOY`fp)?j8KcZbLS3FBR-@lC;*7Z&)+8F z31T=kH8m(G2(WK-OaV%ag8$}H z-QB|>k*Ccneb#2XVYD0^HP_!CD;p39M5wB(w`C|rXg-!kJ$`Jeqca9>!EpfGMRgp% zA;8K5h!kO$Lprb@D7CA$_MEBd;5RP6#Y3pu+Lo-qQ(-6s-tOum*e@6^U)T<251E6s z;s8lJKr0~169H=yVW}I(Yy&6a!XL14CE4vf3H=-prfoT|G;7}G^T(WyVgrZLA+-7r z;q4;Hfh-2w^wfkf8GaYhf=L;D1X*^!EP!Wi^7FhULMOLl`*N3GFR~nkB`dMRy*%R* z5X~+JW?()5ohat$ZYdktG=(0H%IS2sRu(b2hibJnqJX#Il>I#kubzyK(q;H|7nk3_AS zBAc3&p$D=f%ni4<5z%thdx*ZcIZRbgU*EG!Lu$ySf%04hx&t&T+){;bqwib4 z0=-3>s!Yti6g4K9U9F#M0M-#T1x225>AM9l1mkd_<=y59 z->s>H>GnqxY~|Cbh-lU`8L@sl3uRXY6LfFZ-5~~<$WW~cyFCY_&x8-nqQeS=oYOcH z>~?Prw%@*hHxne}>eWmk-b_H90IQ4B1xXv|ge+bsTw?SIWV8|&)$8)SuB7tadm=2y z&!I#rv}Y7Qwd`}c4O5dIt9I#sR@H|%hWr6zV1tj?Q}<48X)WV-nzl4s-j~3eK`Z5&NF?G;;ctrZ@fPg z0CZ)Xf)!Ayt*olbGoeS`qAs9tp#^|uE@s9M;QqSEURvjlWG&P%Vg*v;s()=+O z(Jeq%e%IEbo>p^+Og2?*4DSH>n+k}V z<*OSdX?yJx%XubcPQ#VH!zkx~Ig|b6JyhY15PAWKUayQBV0k!oe(+p=>_=dUIOj9+ z^4KRa^15nO%S|k>@nxT138MRUEvi<|fOtO5@{JI2Nx$V*tpy>`1y9hKL7=OofY>M? z@P5H74MgWoCQqslOhN+x-tZh2=C-@JEQ78Tlat$vmRa;cS8c@Nr?YZrv7)Q96G+Gb z0aY7L&NX}MCQju_9aiTLt>6R-Ov(hgxF%ReHk-scWW|7t0VLsf@6 zgiO6r)lv3b!u1Z}p@cg|3x$2xK`AwN{) zU0QkSNb%UtgN26U>GgdP&-sYVo~YbW2+s{W^_S4j6sSf8X@dRQ zh=_<74u!?5qArKVV8=G1iuSZE;V~$$RLkZsUCOktZSe9IqnVE-m|mgEB}EmL=0Yx~ zG8ri;ARf$9BR9e7UmnuO3*&s8oaq%6CcI!_0u5<;?VfmXfI1{iv z`1x~eY^?ZX{?`vFCI$vsv1eUIZ?#QfsCs&Pg^Y@=zqUUD%3MG|KtuHC%^Rd~O?uDw zfs$=+-`3g+np|LINMSdd6{spMjfQ%!X{O09c;OcmI6xC(rYpN@0?06rWPLGUP8vka zks~qe0k^SOY+JNxPvRh%a<-VB*;uJF(7MmHT!_1W|Ks3bUhG+4jJ26rs_twmV)2aI zWT@`!LfOc=Sr4fxw@YJ%AHd@y&-HV+cXkewkQlr$p7N@wnsBaMRtAa^sN0DJHE5NX zF1ZV0d+FpthID-DB96yiUFlhp=_s7w67ZKeD3P@lg9Pt~KvbDW?PuUWF9Q(v@9^5g z+uI}_k3%f$gO;x#3zjQvZ%Do?cra3IItI1+Ch8#HM~Bf4Q+0P=F#&?;_FTcn+8VyV z^qRWA2T8i1{Od7bT)LdC3xv7^X0OKLJo|#G^#*E%)nGo5m`Xb2S6)b_*V{m!f4ZuX zBhA@;0wcMm8grv>dD&<4c1d#e+6!l2Tk!=T8X}B@Tpppm!iPZO1K@wMwzl@ZI&z{6 zI}ySm@sWK|&H{PLp|daWbHhCv8cF{mq*Kt0xG0mYWWgIinXAC|O(E+vmT1 z(^iv^knrtz96Q30D&y@0nyI?8wYP}`6WV01n48yFw?23zW^16Y4^(=PN84a}h7&gx z-;(h2qjQ-P_@SoJ+0%{-uB-CG4zv>vcrzS@CXZf^vlB;!a^$2AiY!m(35dVjK zb>CL;A9C;e?JxnKI4XR%>a2?*S*@gEW|)o9C;vjK?ioF62loaoWiBhO2J0a5q;Cq3 znFIZ6U`u)+eEXI;@7C=CUoxX$V{`LiLFQeBl;}jHwH!C~i58hrUjO=^! zHPqD+;M7W!*c~(@s$%ht`mW^X!jW%u?^&3$IQ2-QK!W%3@Q_`qB~sX|qgFP@6g9Jh zkInTD3@8A!2Rd?k@W7?J9H8Dmmh~+zF2?MP;HsTlK~=nW@80rNv^M`iKY|KJfH(l6 zzy$-A3wWFux%EWv*1WttkbQu8BLYYjrJ<~6+!}XIqVFA>VX4aS%Gl!)>2UgYf_8j^Dz2iij8`uh6ChumQ;JZb*pF4Au*Dg@eQ z=jM`uZ>5l>ry^Z>TY2Pq%=0M!wZ5b4E;H0w5kR+!idx&72AxNugk_}V2x4Gjd3AlA zFH@FX%fuuZor^vEQB~r*F(%E?-ahwGvHd_< z$ulZ}pWx=s0{HROD@m7D-<7X&8-wnQLT0Q?Og_tR8I`Pi@{9l-p+|uRRtQJnm6fCr z15M2jpc$n!Ia+s@T5k1zXnV30Iy1rS7%ToTt?+UT48*FA%q{!u;@nrABfmybOq{BX z--n_h6yYtvXavr77I1^FU$19=29g&T;xr`IcjSTF3@_5quor(1U}Q%C%T?H$(Ndb+ zT%G`~Y+FCSZ8q=0~dz0g~iDs^BUXp66JtvsB3kG~fosAR}i8VG?s5%Rq174+aX1sWJZ?uy`Fh)TW zZ!-`lo3pCY<;&~kICq5$*cD#j?F!^|8Tt^#JKA=%%tH6N_#oR*KDIn{#VVN9Ezl&1 zoS8A+s@cmxyKqEvfj)_3kQzVk$gSIqL=85L8=QrNkck-35!sY?Klzzolw|WX5hMx9 zXG+k(pZPBYInSHGOtPUKZxa_Ee>UaAK~EVFWC0`Is7b4Z7M7+{rgt_@P9W}I%K!Wy z)r$QT`GRsN|C`udXept0+QaouZI?a-3_dAh21e~ z_L$}}HGHG=8PMex7o9R=0deqNe7unhTEIXy1-_Xc;3%SEJ1ailB25-}d5+Q7WJfIu zQz1Ovd(`aC7bgcJ(_#8j75AKYzltlH|i#V*hj)SuGR3Ee*l%b!Bt zcbkllt?U6zD$GXuPhir6>hiC)f&UhLB>}WtNI5e@%T*e2a$B*a3OmAIb+0?ohzV ze$Iu|aw`VAbPf;8<4viTvw->LNm0=!nHxqu{iXJR)&kFsD|G93Uye7-6X13rhs!mwJfPzt0){Bsll=QN&sNJF4*|(97?tKCjl_OwP=i0UL?6kn` zxB~yT6{5pJ#DdH|&J)(AQb%a2?`(B}tX&`0JTbGdppRz+pfrwbf;zgJusqD+$$Q9*jiw!Rjk&h=(sDD0(A77q9JpnU5Yz1yTnGLM z;losr$S@16_~yi?6PW1BoMigKpaTHp7|$Wk-W2(O?XSts@<^;dsbLe(WHPZZU4agB z(A`+czcUNDl={RUPL7m&vJLJP4WtcV5CPQNbNWMyX0})m{{$W8Jz-*)I+97H>E63b z4h$AoOt-~I@!EVUFzZ2JH2Ule$tNRSw(XB91{XDRoT)#i#e1nCQ$a)8i|Bx9D|h%H zllU8}TnOq^CJ@eee;GCIM-b@tP-PHG1XnWw;7qVr&dF7a*W5?BsvPiS_mMm6esR zUcGwo;6X+P3<`R9?>~GH6cm&X+D=sW9!^fqgGdh!WoBZ^dG_qfOS{X!%LzJDfbtTlDDHi1 zfb0}%o_BQIXQ&OD^pR04Qdv)*&X3fLOe{x=XW$z=&vSCFymqk+46OEUEc2b1m_YdX z#p<%hO!pO8VZDdDyMcz24Qxp7NR{j4^DYaUB##_+0A%u6QIYFRXC`p$fawP!`E4#> z1_pH%?}Oz=KYEB6sQkAJlZ(-O!&%~z(lZUg8bH6G`?q^W$-pCQ1K0@=y;b*{l`eo6 zgQiiL^T@k6e%p@Jg(^)Z={pvM)N_q0pIA;{yaE&@?vap?0DV}Qn_xepI|^=Z2+`!K&$= zRXEoz5qOSpQ$}_(WEG^(?>5d4Vh1ZeT>94{GclrLM~f=KzD^}OclVTE#UaQ!=^q}@ z{0F}|Zy)jkU&KTtUZcRW(K}r8QoTTm79Qa znTxX|L}?McVya#VZMjFuBFo;7Uk4|^$@lnzxF zP_GK_YNVfT1Di55)zr>M&fqxeuko=qRL8B-nf6^$KR;P(n<>i5*iT9 zG!lhD0^BdTA>a$Zl0IznedosL5Fwdt#r+@%w7Hmm|zU`&40T^5O7uU0of1TPv=o$6y3w^2*^6sCra1H`$Q(#o=|m4EXNr$4O;@hg)u><2TG71eOs1 z4781nfsQ}fYld*_OVc$o!|nlF1aQ;Gv zk5NZziUJbs{q{02h~H2w`^EhOI=&Y#UQ~MqddgvRJmD?Cx1gc%9yBH&JbVZ`XyBV{ z(zLT7(XNd1mT-bsg)8u|f2%f!0L^V##X{kQKQ?Nx z{~cfaO)q8_1>sU$ESmZGHql{I!36KZ>gvGO2Pc7&miPQQP>5K(4nc*$W(Y%Ppy?j5 zL2ZNzzX7U#TtWial(h-umzLz<7;b&g~9KIJSD@wU)nfJ{eS<0%SrDD50lXs3~jv7ujN%Not(*4ctNNM z@r{t8(wEs)rF2Z@>c=&*D_@!E&HvD?l}{hP%16w~saL6#dFygec&{G0 zv}%rzM&_-%KSuA*(f?~O|L5gjq4Q_x{TIJ{2_}2AE`RQ9z@gEdip3rI020V%Yz_7w z&&#!MC1n9s#O+;Ml+J$B1MBrd5W7XNXm$wdk5Gy*_>NYAANhe?RMLd!D_Y$7U&x^e AO#lD@ diff --git a/doc/devel/uml/fig130053.png b/doc/devel/uml/fig130053.png index 9e6810f94a1b94bea64180fc070e3aee068b21ae..9cee6c87a85330b18e5e63a988ec21e80931c4b2 100644 GIT binary patch literal 19189 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 K%REu75C0F%JULPT literal 44088 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 diff --git a/doc/devel/uml/fig130181.png b/doc/devel/uml/fig130181.png index 692da89b9574479fcef96bfb380b86494dc56398..fbd802a8954d5e9ef97671ae6f02b2e4a088b67e 100644 GIT binary patch literal 10701 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�ljuir&oVo*v}rK-g5mS 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 VjNKLr1Sc~g3Nos&g2%?M{tLK6dmR7( diff --git a/doc/devel/uml/index-withframe.html b/doc/devel/uml/index-withframe.html index cf6c2c73f..9844745f9 100644 --- a/doc/devel/uml/index-withframe.html +++ b/doc/devel/uml/index-withframe.html @@ -4,7 +4,7 @@ -/mnt/Lager/heim/devel/cin3/doc/devel/uml/index-withframe +/mnt/Lager/heim/devel/lumi/doc/devel/uml/index-withframe diff --git a/doc/devel/uml/index.html b/doc/devel/uml/index.html index 3853e7c4f..406fc303d 100644 --- a/doc/devel/uml/index.html +++ b/doc/devel/uml/index.html @@ -4,14 +4,14 @@ -cinelerra3 +<title>lumiera Documentation -
cinelerra3
Documentation
+
lumiera
Documentation

@@ -22,7 +22,7 @@ Documentation

All things concering the big picture.
Not a real code package, rather a container for design drafts, specifications, decisions.

1.1 Component View Architecture

-

The various Components comprising the Cinelerra3 Video editing Application

+

The various Components comprising the Lumiera Video editing Application

@@ -104,15 +104,15 @@ Documentation

This package is used to organize code generation by BOUML. It is considered useless after having generated the initial code skeleton.

1.3.1 Deployment View EXE Deployment

-

defines and lists how the Cinelerra executable has to be created

+

defines and lists how the Lumiera executable has to be created

Source Overview



-
Artifact Cinelerra3
+
Artifact Lumiera

Depends on common

Depends on gui

Depends on proc

Depends on backend

the main executable to be built

-

executable associated with : main, conmanager, clip, meta, fixedlocation, relativelocation, vrender, mobject, source, frame, placement, sessionimpl, builderfacade, controllerfacade, processor, pluginadapter, effect, buildertool, segmentationtool, aframe, assembler, trafo, explicitplacement, auto, glrender, link, parameter, renderengine, allocation, vframe, toolfactory, arender, renderstate, label, glbuf, procnode, stateproxy, hub, buildable, abstractmo, nodecreatertool, projector, interpolator, edl, fixture, glpipe, exitnode, pathmanager, track, paramprovider, mask

+

executable associated with : exitnode, pathmanager, track, paramprovider, mask, main, conmanager, clip, meta, fixedlocation, relativelocation, mobject, source, frame, placement, sessionimpl, builderfacade, controllerfacade, processor, pluginadapter, effect, buildertool, segmentationtool, aframe, assembler, trafo, explicitplacement, auto, glrender, link, parameter, renderengine, allocation, vframe, toolfactory, arender, renderstate, label, glbuf, procnode, stateproxy, hub, buildable, abstractmo, nodecreatertool, projector, interpolator, edl, fixture, glpipe, vrender

Artifact main

Artifact source

@@ -120,7 +120,7 @@ Documentation

1.3.2 Package common

    -
  • C++ namespace : cinelerra
  • +
  • C++ namespace : lumiera

sourcecode package

Common library and helper classes

Diagram : Source Overview

@@ -134,7 +134,7 @@ Documentation

Artifact source associated with : Visitable, Tool, Applicable

Artifact error
-

Cinelerra Exception Interface

+

Lumiera Exception Interface

Artifact source associated with : Error, Logic, Config, State, Invalid, External

Artifact appconfig
@@ -148,12 +148,12 @@ Documentation

1.3.2.2 Package error

    -
  • C++ namespace : cinelerra::error
  • +
  • C++ namespace : lumiera::error

Namespace for Exception Kinds

1.3.2.3 Package visitor

    -
  • C++ namespace : cinelerra::visitor
  • +
  • C++ namespace : lumiera::visitor

sub-namespace for visitor library implementation

@@ -1143,7 +1143,7 @@ reuse exiting Engine

Selection :

    Transformation

    Hierarchy



    -

    Cinelerra Exception hierarchy

    Class Error
    +

    Lumiera Exception hierarchy

    Class Error
    Class Logic
    Class Config
    Class State
    diff --git a/doc/devel/uml/index_60.html b/doc/devel/uml/index_60.html index 75ccc147d..a873c25b0 100644 --- a/doc/devel/uml/index_60.html +++ b/doc/devel/uml/index_60.html @@ -17,8 +17,8 @@ - + @@ -28,8 +28,8 @@ - + diff --git a/doc/devel/uml/index_65.html b/doc/devel/uml/index_65.html index d570a1c71..cb80221e6 100644 --- a/doc/devel/uml/index_65.html +++ b/doc/devel/uml/index_65.html @@ -28,13 +28,13 @@ - + - + @@ -54,9 +54,9 @@ - + diff --git a/doc/devel/uml/index_66.html b/doc/devel/uml/index_66.html index 9158c65e4..2d9540c91 100644 --- a/doc/devel/uml/index_66.html +++ b/doc/devel/uml/index_66.html @@ -34,8 +34,8 @@ - + diff --git a/doc/devel/uml/index_67.html b/doc/devel/uml/index_67.html index dfc4fc2d8..93dc372e2 100644 --- a/doc/devel/uml/index_67.html +++ b/doc/devel/uml/index_67.html @@ -23,39 +23,37 @@ - + - - - - - - - + - - - + + + + + + + + + + + + + + - + - - - - - - - - - + + @@ -77,7 +75,7 @@ - + @@ -90,8 +88,8 @@ - + diff --git a/doc/devel/uml/index_69.html b/doc/devel/uml/index_69.html index 6ba353281..1f6fd3f19 100644 --- a/doc/devel/uml/index_69.html +++ b/doc/devel/uml/index_69.html @@ -24,8 +24,8 @@ - + @@ -39,9 +39,9 @@ - + - + diff --git a/doc/devel/uml/index_70.html b/doc/devel/uml/index_70.html index 23907ab84..b36d60aff 100644 --- a/doc/devel/uml/index_70.html +++ b/doc/devel/uml/index_70.html @@ -33,8 +33,8 @@ - + diff --git a/doc/devel/uml/index_71.html b/doc/devel/uml/index_71.html index 23b81058d..82430e314 100644 --- a/doc/devel/uml/index_71.html +++ b/doc/devel/uml/index_71.html @@ -51,8 +51,8 @@ - +
    NameKindDescription
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    allocationartifact
    Allocationclassa directive to place a MObject in a specific way
    anchorrelation
    Appconfigoperationperform initialization on first access.
    A call is placed in static initialization code
    included in cinelerra.h; thus it will happen
    ubiquitous very early.
    Appconfigoperationperform initialization on first access.
    A call is placed in static initialization code
    included in lumiera.h; thus it will happen
    ubiquitous very early.
    appconfigartifactfor global initialization and configuration
    AppconfigclassSingleton to hold inevitable global flags and constants and for performing erarly (static) global initialization tasks.
    Applicableclass
    applyoperation
    applyoperation
    Architecturecomponent viewThe various Components comprising the Cinelerra3 Video editing Application
    Architecturecomponent viewThe various Components comprising the Lumiera Video editing Application
    ARenderclassRepresentation of a Audio render process
    arenderartifactRepresentation of a Audio Render process
    AssemblerclassThis is the actual building facility: provided the correct tools and associations, it serves to build and connect the individual ProcNode objects
    aud_Aclass instance
    aud_aclass instance
    audioclass instance
    audio1class instance
    audio1class instance
    audio1class instance
    audio1class instance
    autoartifactMedia Object holding automation data
    AutoclassAutomation data for some parameter (i.e. a time varying function)
    Automation Entitiesclass diagram
    buildableartifactmarker interface denoting any MObject able to be treated by Tools
    buildEngineoperationMain Operation of the Builder: create a render engine for a given part of the timeline
    Buildercomponent
    builderpackagesourcecode package

    The Builder creating the Render Engine,
    located within the MObject Subsystem
    Builderpackage
    builderpackagesourcecode package

    The Builder creating the Render Engine,
    located within the MObject Subsystem
    Builder Entitiesclass diagram
    Builder Workingsclass view
    BuilderFacadeclassProvides unified access to the builder functionality. While individual components of the builder subsystem may be called if necessary or suitable, it is usually better to do all extern invocations via the high level methods of this Facade
    Categoryclasstree like classification of Assets
    categoryartifacttree like classification of Assets
    causeattributea copy of the first exception encountered in this exception chain
    chainrelationChain of additional Placements further constraining the position of this MObject
    chainoperationcreate and add another Placement for this media object, thus increasingly constraining the (possible) position of this object.
    chainrelationChain of additional Placements further constraining the position of this MObject
    checked_inrelationchecked_in objects are subject of cache aging and must be not in use
    checked_outrelationthis list keeps all mappings which are in use, and thus prevents them from Cache aging
    Cinelerra3artifactthe main executable to be built
    cinelerra3package
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    clearoperationclear current session contents
    without resetting overall session config.
    Afterwards, the session will contain only one
    empty EDL, while all Assets are retained.
    Clipclassbookkeeping (asset) view of a media clip.
    CompoundClipclassClip MObject which is actually a compound of several elementary clips,
    e.g. the several streams found within multichannels media.
    CompoundMediaclasscompound of several elementary media tracks,
    e.g. the individual media streams found in one media file
    compoundmediaartifacta special clip as a compound of several elementary media tracks,
    e.g. the individual media streams found in one media file
    ConditionclassI provided a reworked Condition class in my cinelerra2 repository
    ConditionclassI provided a reworked Condition class in my Cinelerra2 repository
    Configclass
    config examplesuse case view
    configureoperation
    constraintartifactLocatingPin representing an directive by the user that
    must not be violated
    Constraintclass
    Controllercomponent
    Controllerpackage
    controllerpackagesourcecode package

    The Processing and Render Controller,
    located within the MObject Subsystem
    Controllerpackage
    Controller Entitiesclass diagram
    Controller Workingsclass view
    ControllerFacadeclassProvides unified access to the Proc-Subsystem Controller. Especially, this Facade class provides the functions to get a render engine to carry out actual renderings.
    EDL Example2object diagramMore complex example showing the Object graph in the EDL and how it is linked into the Fixture to yield the actual locations. In this example, an HUE Effect is applied on a part of the Clip
    edlsrelation
    EffectclassEffect or media processing component
    effectartifactEDL representation of a pluggable and automatable effect.
    effectartifactEffect or media processing component
    effectartifactEDL representation of a pluggable and automatable effect.
    Effectclass
    elementsrelationrelevant MObjects comprising this segment. TODO: actually necessary??
    enableoperationchange the enabled status of this asset. Note the corresponding #isActive predicate may depend on the enablement status of parent assets as well
    errorpackageNamespace for Exception Kinds
    errorclass view
    Errorclass
    errorartifactCinelerra Exception Interface
    errorartifactLumiera Exception Interface
    establish partitioningexpansion region
    EXE Deploymentdeployment viewdefines and lists how the Cinelerra executable has to be created
    EXE Deploymentdeployment viewdefines and lists how the Lumiera executable has to be created
    ExitNodeclassThe output of the render pipeline. Pulling from such exit nodes actually ivokes the render process
    exitnodeartifactspecial Processing Node providing "pullable" output
    explicitplacementartifactspecial Placement yielding an absolute location (Time,Track)-location for a MObject
    FixedLocationclass
    Fixtureactivity object
    fixtureartifactthe (low level) representation of the EDL with concrete placement data
    Fixturecomponent
    Fixtureclass
    Fixturecomponent
    fork activity nodefork activity node
    FrameclassFrames are just a low level lump of continous memory, most parts are opaque. Frames are memory sensitive, they will be small constant sized structures which can be efficently managed in a pool.
    Framenode
    GLRenderclassRepresentation of a OpenGL accelerated Video render process
    glrenderartifactRepresentation of a OpenGL accellerated Video render process
    groupsattributeadditional classification, selections or departments this asset belongs to. Groups are optional, non-exclusive and may be overlapping.
    GUIpackageGUI is here just a container to hold any entities considered to be User Interface related, which is not in focus for this Design draft
    guipackagesourcecode package

    User Interface classes go here
    GUIpackageGUI is here just a container to hold any entities considered to be User Interface related, which is not in focus for this Design draft
    diff --git a/doc/devel/uml/index_72.html b/doc/devel/uml/index_72.html index a26e1439f..bf8262c8c 100644 --- a/doc/devel/uml/index_72.html +++ b/doc/devel/uml/index_72.html @@ -20,7 +20,7 @@ handlerelationweak pointer handlesrelation handles_availableattributeinitialized to the maximum number of filehandles the backend may use for mapped files. When no handles are available, the handle which is last in the handles list is closed and (re-)used.
    Else this number is decremented for each new filehandle used and incremented for any one explicitly freed. -Hierarchyclass diagramCinelerra Exception hierarchy +Hierarchyclass diagramLumiera Exception hierarchy howtoProcoperation@return descriptor how to build a render pipeline corresponding to this media Hubclass hubartifactspecial ProcNode used to build data distributing connections diff --git a/doc/devel/uml/index_73.html b/doc/devel/uml/index_73.html index 93008767f..27e37a604 100644 --- a/doc/devel/uml/index_73.html +++ b/doc/devel/uml/index_73.html @@ -20,9 +20,9 @@ idattributeAsset primary key. In Memory Databaseclass diagram inFixtureactivity action pin -inputclass instance -inputclass instance inputclass instance +inputclass instance +inputclass instance instanceoperation instructionsrelation Interfaceclass view diff --git a/doc/devel/uml/index_76.html b/doc/devel/uml/index_76.html index 9b41469f0..0b4ef97db 100644 --- a/doc/devel/uml/index_76.html +++ b/doc/devel/uml/index_76.html @@ -31,6 +31,8 @@ Lockclass Logicclass longDescattributeuser visible qualification of the thing, unit or concept represented by this asset. perferably "in one line". To be localized. +Lumieraartifactthe main executable to be built +lumierapackage diff --git a/doc/devel/uml/index_77.html b/doc/devel/uml/index_77.html index 68bbd5cfb..3e0b915cc 100644 --- a/doc/devel/uml/index_77.html +++ b/doc/devel/uml/index_77.html @@ -40,7 +40,7 @@ MObjectpackage MObjectclass multichannel clipobject diagram -MutexclassI provided a reworked Mutex class in my cinelerra2 repository +MutexclassI provided a reworked Mutex class in my Cinelerra2 repository diff --git a/doc/devel/uml/index_79.html b/doc/devel/uml/index_79.html index 5446e9730..d1fdc83c0 100644 --- a/doc/devel/uml/index_79.html +++ b/doc/devel/uml/index_79.html @@ -18,10 +18,10 @@ - - - + + + diff --git a/doc/devel/uml/index_82.html b/doc/devel/uml/index_82.html index 3a3a83808..a76e8f590 100644 --- a/doc/devel/uml/index_82.html +++ b/doc/devel/uml/index_82.html @@ -22,8 +22,8 @@ - + diff --git a/doc/devel/uml/index_83.html b/doc/devel/uml/index_83.html index df33c880e..18c49405b 100644 --- a/doc/devel/uml/index_83.html +++ b/doc/devel/uml/index_83.html @@ -46,8 +46,8 @@ - + diff --git a/doc/devel/uml/index_84.html b/doc/devel/uml/index_84.html index 738749c2a..692cb2cac 100644 --- a/doc/devel/uml/index_84.html +++ b/doc/devel/uml/index_84.html @@ -21,7 +21,7 @@ - + @@ -43,12 +43,12 @@ + - - +
    NameKindDescription
    offsetattributeOffset the actual position by this (time) value relative to the anchor point. TODO: Representation?
    orgattributeorigin or authorship id. Can be a project abbreviation, a package id or just the authors nickname or UID. This allows for the compnent name to be more generic (e.g. "blur"). Default for all assets provided by the core cinelerra-3 codebase is "cin3".
    ouputclass instance
    ouputclass instance
    orgattributeorigin or authorship id. Can be a project abbreviation, a package id or just the authors nickname or UID. This allows for the compnent name to be more generic (e.g. "blur"). Default for all assets provided by the core Lumiera codebase is "lumi".
    ouputclass instance
    ouputclass instance
    ouputclass instance
    outPortrelationthe Port this MObject wants to be conected to
    outputrelation
    Overviewcomponent diagramThis drawing shows the top level compoents and relations
    registryrelation@internal Table or DB holding all registered asset instances.
    relativelocationartifactPlacement implemnetaion providing various ways of attaching a MObject to another one
    RelativeLocationclass
    RelTypeclassthe possible kinds of RelativePlacements
    relTypeattributethe kind of relation denoted by this Placement
    RelTypeclassthe possible kinds of RelativePlacements
    removeoperationremove the given asset <i>together with all its dependants</i> from the internal DB
    Render Entitiesclass diagram
    Render Requestactivity parameter
    SimpleClipclassElementary clip consisting of only one media stream
    SmartPointerclass
    SmartPointersclass view
    sourcerelationmedia source of this clip
    sourcerelationthe media source this clip referes to
    sourcerelationmedia source of this clip
    SourceclassSource Node: represents a media source to pull data from.
    sourceartifactRepresentation of a Media source
    Source Overviewdeployment diagram
    theApp_attributeholds the single instance and triggers initialization
    theFixturerelation
    theTimelinerelation
    ThreadclassWe can basically reuse the Thread class design from cinelerra2, Thread becomes a baseclass for all Threads
    ThreadclassWe can basically reuse the Thread class design from Cinelerra2, Thread becomes a baseclass for all Threads
    timeattribute
    timeartifactunified representation of a time point, including conversion functions
    Timeclassdenotes a temporal position (time point), based on timeline start.

    investigate posix.4 realtime timers, wrap these here
    treatoperation
    treatoperationThis operation is to be overloaded for the specific MObject subclasses to be treated.
    treatoperation
    treatoperation
    treatoperation
    treatoperation
    treatoperation
    treatoperation
    treatoperation
    treatoperation
    treatoperation
    diff --git a/doc/devel/uml/index_86.html b/doc/devel/uml/index_86.html index 2429dd829..f75b93690 100644 --- a/doc/devel/uml/index_86.html +++ b/doc/devel/uml/index_86.html @@ -20,23 +20,23 @@ versionattributeversion number of the thing or concept represented by this asset. Of each unique tuple (name, category, org) there will be only one version in the whole system. Version 0 is reserved for internal purposes. Versions are considered to be ordered, and any higher version is supposed to be fully backwards compatible to all previous versions. VFrameclass vframeartifacta buffer and render process holding a Video frame -vid1class instance vid1class instance -vid_Aclass instance +vid1class instance vid_aclass instance -vid_Aclass instance vid_aclass instance +vid_Aclass instance +vid_Aclass instance vid_Aclass instance -videoclass instance videoclass instance +videoclass instance videoclass instance videoclass instance -video1class instance -video1class instance -video1class instance -video1class instance video1class instance +video1class instance video1class instance +video1class instance +video1class instance +video1class instance Visitableclass visitorpackagesub-namespace for visitor library implementation visitorartifactAcyclic Visitor library diff --git a/doc/devel/uml/navig.html b/doc/devel/uml/navig.html index facf4a06c..74b812388 100644 --- a/doc/devel/uml/navig.html +++ b/doc/devel/uml/navig.html @@ -4,7 +4,7 @@ -/mnt/Lager/heim/devel/cin3/doc/devel/uml/navig +/mnt/Lager/heim/devel/lumi/doc/devel/uml/navig diff --git a/doc/devel/uml/packages.html b/doc/devel/uml/packages.html index aac0bc389..c9321815b 100644 --- a/doc/devel/uml/packages.html +++ b/doc/devel/uml/packages.html @@ -22,18 +22,18 @@ BackendLayer buildersrcsourcecode package

    The Builder creating the Render Engine,
    located within the MObject Subsystem Builder -cinelerra3 codegenThis package is used to organize code generation by BOUML. It is considered useless after having generated the initial code skeleton. commonsrcsourcecode package

    Common library and helper classes CommonLib -controllersrcsourcecode package

    The Processing and Render Controller,
    located within the MObject Subsystem Controller +controllersrcsourcecode package

    The Processing and Render Controller,
    located within the MObject Subsystem design designAll things concering the big picture.
    Not a real code package, rather a container for design drafts, specifications, decisions. enginesrcsourcecode package

    The Core Render Engine errorNamespace for Exception Kinds -GUIGUI is here just a container to hold any entities considered to be User Interface related, which is not in focus for this Design draft guisrcsourcecode package

    User Interface classes go here +GUIGUI is here just a container to hold any entities considered to be User Interface related, which is not in focus for this Design draft +lumiera mobjectsrcsourcecode package

    MObject Subsystem
    including the Session (EDL), Builder and Processing Controller MObject procsrcsourcecode package

    All classes belonging to the (middle) processing layer diff --git a/doc/devel/uml/public_properties.html b/doc/devel/uml/public_properties.html index 2cf2100de..6fa20439e 100644 --- a/doc/devel/uml/public_properties.html +++ b/doc/devel/uml/public_properties.html @@ -22,7 +22,7 @@ idAssetAsset primary key. nameAssetelement ID, comprehensible but sanitized. The tuple (category, name, org) is unique. nodesDoAttach -orgAssetorigin or authorship id. Can be a project abbreviation, a package id or just the authors nickname or UID. This allows for the compnent name to be more generic (e.g. "blur"). Default for all assets provided by the core cinelerra-3 codebase is "cin3". +orgAssetorigin or authorship id. Can be a project abbreviation, a package id or just the authors nickname or UID. This allows for the compnent name to be more generic (e.g. "blur"). Default for all assets provided by the core Lumiera codebase is "lumi". pointDoAttachidentifying the point where the nodes should be attached subTracksTrackChild tracks in a tree structure versionAssetversion number of the thing or concept represented by this asset. Of each unique tuple (name, category, org) there will be only one version in the whole system. Version 0 is reserved for internal purposes. Versions are considered to be ordered, and any higher version is supposed to be fully backwards compatible to all previous versions. diff --git a/src/backend/mediaaccessfacade.cpp b/src/backend/mediaaccessfacade.cpp index f6a1b8305..bd12068f9 100644 --- a/src/backend/mediaaccessfacade.cpp +++ b/src/backend/mediaaccessfacade.cpp @@ -1,8 +1,8 @@ /* MediaAccessFacade - functions for querying media file and channels. - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/backend/mediaaccessfacade.hpp b/src/backend/mediaaccessfacade.hpp index d4c0e3a0d..15579d491 100644 --- a/src/backend/mediaaccessfacade.hpp +++ b/src/backend/mediaaccessfacade.hpp @@ -1,8 +1,8 @@ /* MEDIAACCESSFACADE.hpp - functions for querying media file and channels. - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/cinelerra.h b/src/cinelerra.h index c2b95dd8c..30264a904 100644 --- a/src/cinelerra.h +++ b/src/cinelerra.h @@ -2,8 +2,8 @@ CINELERRA.h - global definitions and common types - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter Hermann Vosseler This program is free software; you can redistribute it and/or diff --git a/src/common/appconfig.cpp b/src/common/appconfig.cpp index d9475bc97..aba876966 100644 --- a/src/common/appconfig.cpp +++ b/src/common/appconfig.cpp @@ -1,8 +1,8 @@ /* Appconfig - for global initialization and configuration - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/appconfig.hpp b/src/common/appconfig.hpp index a3b0e3191..bbd50df6f 100644 --- a/src/common/appconfig.hpp +++ b/src/common/appconfig.hpp @@ -1,8 +1,8 @@ /* APPCONFIG.hpp - for global initialization and configuration - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter Hermann Vosseler This program is free software; you can redistribute it and/or diff --git a/src/common/cmdline.cpp b/src/common/cmdline.cpp index ef23743ca..bf00cf2b2 100644 --- a/src/common/cmdline.cpp +++ b/src/common/cmdline.cpp @@ -1,8 +1,8 @@ /* Cmdline - abstraction of the usual commandline, a sequence of strings - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/cmdline.hpp b/src/common/cmdline.hpp index d2ea9e72b..8d7b1e44f 100644 --- a/src/common/cmdline.hpp +++ b/src/common/cmdline.hpp @@ -1,8 +1,8 @@ /* CMDLINE.hpp - abstraction of the usual commandline, a sequence of strings - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/error.cpp b/src/common/error.cpp index 94f7ca3ed..17e18e676 100644 --- a/src/common/error.cpp +++ b/src/common/error.cpp @@ -1,8 +1,8 @@ /* Error - Cinelerra Exception Interface - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/error.hpp b/src/common/error.hpp index 3251752df..15e60f022 100644 --- a/src/common/error.hpp +++ b/src/common/error.hpp @@ -1,8 +1,8 @@ /* ERROR.hpp - Cinelerra Exception Interface - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/factory.hpp b/src/common/factory.hpp index 8c96fd14c..a4b953b3a 100644 --- a/src/common/factory.hpp +++ b/src/common/factory.hpp @@ -1,8 +1,8 @@ /* FACTORY.hpp - template for object/smart-pointer factories - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/multithread.hpp b/src/common/multithread.hpp index 0dc79e7c2..cc6eca1c6 100644 --- a/src/common/multithread.hpp +++ b/src/common/multithread.hpp @@ -1,8 +1,8 @@ /* MULTITHREAD.hpp - generic interface for multithreading primitives - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter Hermann Vosseler This program is free software; you can redistribute it and/or diff --git a/src/common/singleton.hpp b/src/common/singleton.hpp index 677b454d3..9f149214f 100644 --- a/src/common/singleton.hpp +++ b/src/common/singleton.hpp @@ -1,8 +1,8 @@ /* SINGLETON.hpp - configuration header for singleton factory - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/singletonfactory.hpp b/src/common/singletonfactory.hpp index ba2151584..319722fcf 100644 --- a/src/common/singletonfactory.hpp +++ b/src/common/singletonfactory.hpp @@ -1,8 +1,8 @@ /* SINGLETONFACTORY.hpp - template for implementing the singleton pattern - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/singletonpolicies.hpp b/src/common/singletonpolicies.hpp index 7e6f90acf..5ae31b939 100644 --- a/src/common/singletonpolicies.hpp +++ b/src/common/singletonpolicies.hpp @@ -1,8 +1,8 @@ /* SINGLETONPOLICIES.hpp - how to manage creation, lifecycle and multithreading - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/singletonpreconfigure.hpp b/src/common/singletonpreconfigure.hpp index c7f08ae6a..9f3cfb8b2 100644 --- a/src/common/singletonpreconfigure.hpp +++ b/src/common/singletonpreconfigure.hpp @@ -1,8 +1,8 @@ /* SINGLETONPRECONFIGURE - declare the configuration of some Singleton types in advance - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/test/mockinjector.hpp b/src/common/test/mockinjector.hpp index 8e567fe5d..28258e91e 100644 --- a/src/common/test/mockinjector.hpp +++ b/src/common/test/mockinjector.hpp @@ -1,8 +1,8 @@ /* MOCKINJECTOR.hpp - replacement singleton factory for injecting Test-Mock objects - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/test/run.hpp b/src/common/test/run.hpp index 0cee56674..b38729d8a 100644 --- a/src/common/test/run.hpp +++ b/src/common/test/run.hpp @@ -1,8 +1,8 @@ /* RUN.hpp - helper class for grouping, registering and invoking testcases - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter Hermann Vosseler This program is free software; you can redistribute it and/or diff --git a/src/common/test/suite.cpp b/src/common/test/suite.cpp index cca65903f..c81c88097 100644 --- a/src/common/test/suite.cpp +++ b/src/common/test/suite.cpp @@ -1,8 +1,8 @@ /* Suite - helper class for running collections of tests - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/test/suite.hpp b/src/common/test/suite.hpp index 4e525a7cd..afdb9e3d6 100644 --- a/src/common/test/suite.hpp +++ b/src/common/test/suite.hpp @@ -1,8 +1,8 @@ /* SUITE.hpp - helper class for running collections of tests - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/test/testoption.cpp b/src/common/test/testoption.cpp index 3e40a063c..aaaff32b8 100644 --- a/src/common/test/testoption.cpp +++ b/src/common/test/testoption.cpp @@ -1,8 +1,8 @@ /* Suite - helper class for running collections of tests - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/test/testoption.hpp b/src/common/test/testoption.hpp index 8b1a012d3..28a82ff55 100644 --- a/src/common/test/testoption.hpp +++ b/src/common/test/testoption.hpp @@ -1,8 +1,8 @@ /* TESTOPTION.hpp - handle cmdline for invoking Testsuite - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/time.cpp b/src/common/time.cpp index 12798a58d..c208fcb46 100644 --- a/src/common/time.cpp +++ b/src/common/time.cpp @@ -1,8 +1,8 @@ /* Time - unified representation of a time point, including conversion functions - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/time.hpp b/src/common/time.hpp index c0d832098..c4fc22244 100644 --- a/src/common/time.hpp +++ b/src/common/time.hpp @@ -1,8 +1,8 @@ /* TIME.hpp - unified representation of a time point, including conversion functions - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/typelist.hpp b/src/common/typelist.hpp index 11bfd355c..6d2720fcb 100644 --- a/src/common/typelist.hpp +++ b/src/common/typelist.hpp @@ -1,8 +1,8 @@ /* TYPELIST.hpp - typelist meta programming facilities - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/util.cpp b/src/common/util.cpp index f80b5d2b6..32e5bc84f 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -1,8 +1,8 @@ /* util.cpp - helper functions implementation - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/util.hpp b/src/common/util.hpp index 101a3ccaf..4687bd7f4 100644 --- a/src/common/util.hpp +++ b/src/common/util.hpp @@ -1,8 +1,8 @@ /* UTIL.hpp - collection of small helper functions used "everywhere" - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/visitor.cpp b/src/common/visitor.cpp index 4903b6d5d..f702f809b 100644 --- a/src/common/visitor.cpp +++ b/src/common/visitor.cpp @@ -1,8 +1,8 @@ /* Vistitable,Tool,Applicable - Acyclic Visitor library - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/visitor.hpp b/src/common/visitor.hpp index ed37c1963..251254a88 100644 --- a/src/common/visitor.hpp +++ b/src/common/visitor.hpp @@ -1,8 +1,8 @@ /* VISITOR.hpp - Generic Visitor library implementation - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/visitordispatcher.hpp b/src/common/visitordispatcher.hpp index 50d726761..0be12b2df 100644 --- a/src/common/visitordispatcher.hpp +++ b/src/common/visitordispatcher.hpp @@ -1,8 +1,8 @@ /* VISITORDISPATCHER.hpp - visitor implementation details - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/common/visitorpolicies.hpp b/src/common/visitorpolicies.hpp index 2fd0cb37f..6b9f353a5 100644 --- a/src/common/visitorpolicies.hpp +++ b/src/common/visitorpolicies.hpp @@ -1,8 +1,8 @@ /* VISITOR.hpp - Acyclic Visitor library - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index f0b6b2792..396e8ff81 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) CinelerraCV +# Copyright (C) Lumiera.org # 2007, Christian Thaeter # # This program is free software; you can redistribute it and/or diff --git a/src/lib/condition.c b/src/lib/condition.c index dfc79c7c5..2b0bc28e8 100644 --- a/src/lib/condition.c +++ b/src/lib/condition.c @@ -1,8 +1,8 @@ /* condition.c - condition variable - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/condition.h b/src/lib/condition.h index 7925fd993..73da3685f 100644 --- a/src/lib/condition.h +++ b/src/lib/condition.h @@ -1,8 +1,8 @@ /* condition.h - condition variables - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/error.c b/src/lib/error.c index d5ea88f01..df881013b 100644 --- a/src/lib/error.c +++ b/src/lib/error.c @@ -1,8 +1,8 @@ /* error.c - Cinelerra Error handling - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/error.h b/src/lib/error.h index 2b5051652..322487de1 100644 --- a/src/lib/error.h +++ b/src/lib/error.h @@ -1,8 +1,8 @@ /* error.h - Cinelerra Error handling - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/framerate.c b/src/lib/framerate.c index b70121a37..717bab4bb 100644 --- a/src/lib/framerate.c +++ b/src/lib/framerate.c @@ -1,8 +1,8 @@ /* framerate.c - framerate calculations - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/framerate.h b/src/lib/framerate.h index 1e862ed0d..c7c9d2adc 100644 --- a/src/lib/framerate.h +++ b/src/lib/framerate.h @@ -1,8 +1,8 @@ /* framerate.h - framerate calculations - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/llist.h b/src/lib/llist.h index 032210a35..4f77b20dc 100644 --- a/src/lib/llist.h +++ b/src/lib/llist.h @@ -3,8 +3,8 @@ Copyright (C) 2003, 2005 Christian Thaeter - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/locking.h b/src/lib/locking.h index 6e53fee97..2cf7f3700 100644 --- a/src/lib/locking.h +++ b/src/lib/locking.h @@ -1,8 +1,8 @@ /* locking.h - shared declarations for all locking primitives - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/mutex.c b/src/lib/mutex.c index 1425fdd02..b644c00ca 100644 --- a/src/lib/mutex.c +++ b/src/lib/mutex.c @@ -1,8 +1,8 @@ /* mutex.c - mutex - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/mutex.h b/src/lib/mutex.h index a359d9b75..4dc4bac92 100644 --- a/src/lib/mutex.h +++ b/src/lib/mutex.h @@ -1,8 +1,8 @@ /* mutex.h - mutal exclusion locking - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/plugin.c b/src/lib/plugin.c index 184b0cb06..f819f4a6a 100644 --- a/src/lib/plugin.c +++ b/src/lib/plugin.c @@ -1,8 +1,8 @@ /* plugin.c - Cinelerra Plugin loader - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/plugin.h b/src/lib/plugin.h index a31e69199..45a22bf29 100644 --- a/src/lib/plugin.h +++ b/src/lib/plugin.h @@ -1,8 +1,8 @@ /* plugin.h - Plugin loader - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/references.c b/src/lib/references.c index 6dfdcf011..a4c5eb247 100644 --- a/src/lib/references.c +++ b/src/lib/references.c @@ -1,8 +1,8 @@ /* references.c - strong and weak references - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/references.h b/src/lib/references.h index 5f5543787..a7de3f7f0 100644 --- a/src/lib/references.h +++ b/src/lib/references.h @@ -1,8 +1,8 @@ /* references.h - strong and weak references - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/rwlock.c b/src/lib/rwlock.c index 48becb14d..d60223e3c 100644 --- a/src/lib/rwlock.c +++ b/src/lib/rwlock.c @@ -1,8 +1,8 @@ /* rwlock.c - read/write locks - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/rwlock.h b/src/lib/rwlock.h index 21ad1e054..266887e24 100644 --- a/src/lib/rwlock.h +++ b/src/lib/rwlock.h @@ -1,8 +1,8 @@ /* rwlock.h - read/write locks - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/time.c b/src/lib/time.c index 6cbdde6ee..4566e44b5 100644 --- a/src/lib/time.c +++ b/src/lib/time.c @@ -1,8 +1,8 @@ /* time.h - Time and frame calculations - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/lib/time.h b/src/lib/time.h index 4203ece49..d4c05b71c 100644 --- a/src/lib/time.h +++ b/src/lib/time.h @@ -1,8 +1,8 @@ /* time.h - Time calculations - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/main.cpp b/src/main.cpp index 03ae44b61..8d564ed87 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,8 @@ /* - main.cpp - start the Cinelerra Application + main.cpp - start the Lumiera Application - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter Hermann Vosseler This program is free software; you can redistribute it and/or @@ -32,7 +32,7 @@ using cinelerra::Appconfig; int main (int argc, char* argv[]) { - cout << "*** Cinelerra NLE for Linux ***" << endl + cout << "*** Lumiera NLE for Linux ***" << endl << " Version: " << Appconfig::get("version") << endl; return 0; } diff --git a/src/nobugcfg.h b/src/nobugcfg.h index 7907d50a1..2cd719a87 100644 --- a/src/nobugcfg.h +++ b/src/nobugcfg.h @@ -2,8 +2,8 @@ NOBUGCFG.h - global configuration and definitions for NoBug - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter Hermann Vosseler This program is free software; you can redistribute it and/or diff --git a/src/pre.hpp b/src/pre.hpp index af83dd9a2..8c504c368 100644 --- a/src/pre.hpp +++ b/src/pre.hpp @@ -2,8 +2,8 @@ PRE.hpp - precompiled header collection - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter Hermann Vosseler This program is free software; you can redistribute it and/or diff --git a/src/proc/asset.cpp b/src/proc/asset.cpp index 5878936f0..d97c2fd9e 100644 --- a/src/proc/asset.cpp +++ b/src/proc/asset.cpp @@ -1,8 +1,8 @@ /* Asset} - Superinterface: bookeeping view of "things" present in the session - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset.hpp b/src/proc/asset.hpp index 2e6a1cd6c..cec77bec4 100644 --- a/src/proc/asset.hpp +++ b/src/proc/asset.hpp @@ -1,8 +1,8 @@ /* ASSET.hpp - Superinterface: bookeeping view of "things" present in the session - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -116,7 +116,7 @@ namespace asset /** * Superinterface describing especially bookeeping properties. - * As of 09/2007, there are four Kinds of Assets, each + * As of 09/2008, there are four Kinds of Assets, each * comprising a sub-Interface of the Asset Interface: *
    • asset::Media representing mediafiles
    • *
    • asset::Proc representing media data processing components (e.g. Effects)
    • diff --git a/src/proc/asset/buildinstruct.cpp b/src/proc/asset/buildinstruct.cpp index de19c647e..8a3e1f214 100644 --- a/src/proc/asset/buildinstruct.cpp +++ b/src/proc/asset/buildinstruct.cpp @@ -1,8 +1,8 @@ /* BuildInstruct - Instructions for building some configuration of render nodes. - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/buildinstruct.hpp b/src/proc/asset/buildinstruct.hpp index 0a0062e25..fc49b3a30 100644 --- a/src/proc/asset/buildinstruct.hpp +++ b/src/proc/asset/buildinstruct.hpp @@ -1,8 +1,8 @@ /* BUILDINSTRUCT.hpp - Instructions for building some configuration of render nodes. - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/category.cpp b/src/proc/asset/category.cpp index 41f6e1c03..490f1f0d6 100644 --- a/src/proc/asset/category.cpp +++ b/src/proc/asset/category.cpp @@ -1,8 +1,8 @@ /* Category - tree like classification of Assets - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/category.hpp b/src/proc/asset/category.hpp index b70f34943..9e0526cc2 100644 --- a/src/proc/asset/category.hpp +++ b/src/proc/asset/category.hpp @@ -1,8 +1,8 @@ /* CATEGORY.hpp - tree like classification of Assets - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/clip.cpp b/src/proc/asset/clip.cpp index 38e78e59a..7b42cb16d 100644 --- a/src/proc/asset/clip.cpp +++ b/src/proc/asset/clip.cpp @@ -1,8 +1,8 @@ /* Clip(Asset) - bookkeeping (asset) view of a media clip. - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/clip.hpp b/src/proc/asset/clip.hpp index 47f6e2860..f5e1ea629 100644 --- a/src/proc/asset/clip.hpp +++ b/src/proc/asset/clip.hpp @@ -1,8 +1,8 @@ /* CLIP.hpp - bookkeeping (asset) view of a media clip. - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/codec.cpp b/src/proc/asset/codec.cpp index ecfcb0313..8604a89d6 100644 --- a/src/proc/asset/codec.cpp +++ b/src/proc/asset/codec.cpp @@ -1,8 +1,8 @@ /* Codec(Asset) - description of some media data decoder or encoder facility - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/codec.hpp b/src/proc/asset/codec.hpp index 890eaa422..40ee70370 100644 --- a/src/proc/asset/codec.hpp +++ b/src/proc/asset/codec.hpp @@ -1,8 +1,8 @@ /* CODEC.hpp - description of some media data decoder or encoder facility - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/compoundmedia.cpp b/src/proc/asset/compoundmedia.cpp index 8b53c97e8..1a00458b6 100644 --- a/src/proc/asset/compoundmedia.cpp +++ b/src/proc/asset/compoundmedia.cpp @@ -1,8 +1,8 @@ /* CompoundMedia - multichannel media - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/compoundmedia.hpp b/src/proc/asset/compoundmedia.hpp index 0e7b0bd97..534993391 100644 --- a/src/proc/asset/compoundmedia.hpp +++ b/src/proc/asset/compoundmedia.hpp @@ -1,8 +1,8 @@ /* COMPOUNDMEDIA.hpp - multichannel media - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/dataset.cpp b/src/proc/asset/dataset.cpp index 7b1ddf997..f82460fed 100644 --- a/src/proc/asset/dataset.cpp +++ b/src/proc/asset/dataset.cpp @@ -1,8 +1,8 @@ /* Dataset - meta asset describing a collection of control data - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/dataset.hpp b/src/proc/asset/dataset.hpp index 8ce580cbe..31fcb8982 100644 --- a/src/proc/asset/dataset.hpp +++ b/src/proc/asset/dataset.hpp @@ -1,8 +1,8 @@ /* DATASET.hpp - meta asset describing a collection of control data - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/db.hpp b/src/proc/asset/db.hpp index 8f228d01b..9f33b01af 100644 --- a/src/proc/asset/db.hpp +++ b/src/proc/asset/db.hpp @@ -1,8 +1,8 @@ /* DB.hpp - registry holding known Asset instances. - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/effect.cpp b/src/proc/asset/effect.cpp index 7ff288876..e8203996e 100644 --- a/src/proc/asset/effect.cpp +++ b/src/proc/asset/effect.cpp @@ -1,8 +1,8 @@ /* Effect(Asset) - Effect or media processing component - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/effect.hpp b/src/proc/asset/effect.hpp index 78c990c98..5d00e44b8 100644 --- a/src/proc/asset/effect.hpp +++ b/src/proc/asset/effect.hpp @@ -1,8 +1,8 @@ /* EFFECT.hpp - Effect or media processing component - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/media.cpp b/src/proc/asset/media.cpp index 0dd34936f..1610e822e 100644 --- a/src/proc/asset/media.cpp +++ b/src/proc/asset/media.cpp @@ -1,8 +1,8 @@ /* Media(Asset) - key abstraction: media-like assets - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/media.hpp b/src/proc/asset/media.hpp index 9c1a85627..67c6a31ca 100644 --- a/src/proc/asset/media.hpp +++ b/src/proc/asset/media.hpp @@ -1,8 +1,8 @@ /* MEDIA.hpp - key abstraction: media-like assets - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/meta.cpp b/src/proc/asset/meta.cpp index 0395d3ea8..bdfd1c411 100644 --- a/src/proc/asset/meta.cpp +++ b/src/proc/asset/meta.cpp @@ -1,8 +1,8 @@ /* Meta(Asset) - key abstraction: metadata and organisational asset - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/meta.hpp b/src/proc/asset/meta.hpp index e1b2f48fc..e995f53a3 100644 --- a/src/proc/asset/meta.hpp +++ b/src/proc/asset/meta.hpp @@ -1,8 +1,8 @@ /* META.hpp - key abstraction: metadata and organisational asset - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/outport.cpp b/src/proc/asset/outport.cpp index c0a228319..d4c8b82fe 100644 --- a/src/proc/asset/outport.cpp +++ b/src/proc/asset/outport.cpp @@ -1,8 +1,8 @@ /* OutPort - structural asset corresponding to some port generating media output - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/outport.hpp b/src/proc/asset/outport.hpp index c0afd059d..ae8e5ff85 100644 --- a/src/proc/asset/outport.hpp +++ b/src/proc/asset/outport.hpp @@ -1,8 +1,8 @@ /* OUTPORT.hpp - structural asset corresponding to some port generating media output - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/preview.cpp b/src/proc/asset/preview.cpp index 888681f35..2753f8cc9 100644 --- a/src/proc/asset/preview.cpp +++ b/src/proc/asset/preview.cpp @@ -1,8 +1,8 @@ /* Preview(Asset) - alternative version of the media data, probably with lower resolution - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/preview.hpp b/src/proc/asset/preview.hpp index 2a8c3c8a3..e36e22ea4 100644 --- a/src/proc/asset/preview.hpp +++ b/src/proc/asset/preview.hpp @@ -1,8 +1,8 @@ /* PREVIEW.hpp - alternative version of the media data, probably with lower resolution - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/proc.cpp b/src/proc/asset/proc.cpp index cff302a24..87aa48da6 100644 --- a/src/proc/asset/proc.cpp +++ b/src/proc/asset/proc.cpp @@ -1,8 +1,8 @@ /* Proc(Asset) - key abstraction: media-like assets - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/proc.hpp b/src/proc/asset/proc.hpp index fb9d2f494..229f66fcd 100644 --- a/src/proc/asset/proc.hpp +++ b/src/proc/asset/proc.hpp @@ -1,8 +1,8 @@ /* PROC.hpp - key abstraction: media-like assets - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/procpatt.cpp b/src/proc/asset/procpatt.cpp index eebed7fad..79b7d46aa 100644 --- a/src/proc/asset/procpatt.cpp +++ b/src/proc/asset/procpatt.cpp @@ -1,8 +1,8 @@ /* ProcPatt - template for building some render processing network - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/procpatt.hpp b/src/proc/asset/procpatt.hpp index 77ea5cd26..2fcaba6ff 100644 --- a/src/proc/asset/procpatt.hpp +++ b/src/proc/asset/procpatt.hpp @@ -1,8 +1,8 @@ /* PROCPATT.hpp - template for building some render processing network - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/struct.cpp b/src/proc/asset/struct.cpp index 069830c27..4a5fca644 100644 --- a/src/proc/asset/struct.cpp +++ b/src/proc/asset/struct.cpp @@ -1,8 +1,8 @@ /* Struct(Asset) - key abstraction: structural asset - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/struct.hpp b/src/proc/asset/struct.hpp index 33d329979..24cc5c053 100644 --- a/src/proc/asset/struct.hpp +++ b/src/proc/asset/struct.hpp @@ -1,8 +1,8 @@ /* STRUCT.hpp - key abstraction: structural asset - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/track.cpp b/src/proc/asset/track.cpp index d7b9b8feb..fa13b1d63 100644 --- a/src/proc/asset/track.cpp +++ b/src/proc/asset/track.cpp @@ -1,8 +1,8 @@ /* Track - structural asset holding the configuration of a track in the EDL - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/track.hpp b/src/proc/asset/track.hpp index 6a7aa04e3..5f83324d1 100644 --- a/src/proc/asset/track.hpp +++ b/src/proc/asset/track.hpp @@ -1,8 +1,8 @@ /* TRACK.hpp - structural asset holding the configuration of a track in the EDL - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/unknown.cpp b/src/proc/asset/unknown.cpp index 57da632df..25d91936c 100644 --- a/src/proc/asset/unknown.cpp +++ b/src/proc/asset/unknown.cpp @@ -1,8 +1,8 @@ /* Unknown - placeholder for unknown or unavailable media source - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/asset/unknown.hpp b/src/proc/asset/unknown.hpp index 8f11518b4..aa9cd6ec3 100644 --- a/src/proc/asset/unknown.hpp +++ b/src/proc/asset/unknown.hpp @@ -1,8 +1,8 @@ /* UNKNOWN.hpp - placeholder for unknown or unavailable media source - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/assetmanager.cpp b/src/proc/assetmanager.cpp index 46717c166..bc6f42ecd 100644 --- a/src/proc/assetmanager.cpp +++ b/src/proc/assetmanager.cpp @@ -1,8 +1,8 @@ /* AssetManager - Facade for the Asset subsystem - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/assetmanager.hpp b/src/proc/assetmanager.hpp index aaf5910dd..d1b20e025 100644 --- a/src/proc/assetmanager.hpp +++ b/src/proc/assetmanager.hpp @@ -1,8 +1,8 @@ /* ASSETMANAGER.hpp - Facade for the Asset subsystem - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/controllerfacade.cpp b/src/proc/controllerfacade.cpp index 52ce4889e..cff9e43d0 100644 --- a/src/proc/controllerfacade.cpp +++ b/src/proc/controllerfacade.cpp @@ -1,8 +1,8 @@ /* ControllerFacade - Facade and service access point for the Proc Layer Controller - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/controllerfacade.hpp b/src/proc/controllerfacade.hpp index 7fd07a8aa..faa213e9b 100644 --- a/src/proc/controllerfacade.hpp +++ b/src/proc/controllerfacade.hpp @@ -1,8 +1,8 @@ /* CONTROLLERFACADE.hpp - Facade and service access point for the Proc Layer Controller - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/aframe.cpp b/src/proc/engine/aframe.cpp index 067feaf5b..e8713897b 100644 --- a/src/proc/engine/aframe.cpp +++ b/src/proc/engine/aframe.cpp @@ -1,8 +1,8 @@ /* AFrame - buffer holding a Audio samples for the render process - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/aframe.hpp b/src/proc/engine/aframe.hpp index 234bce578..0d77e15ca 100644 --- a/src/proc/engine/aframe.hpp +++ b/src/proc/engine/aframe.hpp @@ -1,8 +1,8 @@ /* AFRAME.hpp - buffer holding a Audio samples for the render process - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/arender.cpp b/src/proc/engine/arender.cpp index e9fbc4897..ac7171998 100644 --- a/src/proc/engine/arender.cpp +++ b/src/proc/engine/arender.cpp @@ -1,8 +1,8 @@ /* ARender - Representation of a Audio Render process - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/arender.hpp b/src/proc/engine/arender.hpp index 98c929c7a..79c70c460 100644 --- a/src/proc/engine/arender.hpp +++ b/src/proc/engine/arender.hpp @@ -1,8 +1,8 @@ /* ARENDER.hpp - Representation of a Audio Render process - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/codecadapter.cpp b/src/proc/engine/codecadapter.cpp index 28ce9317e..b65694679 100644 --- a/src/proc/engine/codecadapter.cpp +++ b/src/proc/engine/codecadapter.cpp @@ -1,8 +1,8 @@ /* CodecAdapter - Processing Node for (de)coding media data - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/codecadapter.hpp b/src/proc/engine/codecadapter.hpp index e6d1eec02..5b4991177 100644 --- a/src/proc/engine/codecadapter.hpp +++ b/src/proc/engine/codecadapter.hpp @@ -1,8 +1,8 @@ /* CODECADAPTER.hpp - Processing Node for (de)coding media data - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/exitnode.cpp b/src/proc/engine/exitnode.cpp index 7f1539af2..8c26b7cd9 100644 --- a/src/proc/engine/exitnode.cpp +++ b/src/proc/engine/exitnode.cpp @@ -1,8 +1,8 @@ /* ExitNode - special Processing Node providing "pullable" output - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/exitnode.hpp b/src/proc/engine/exitnode.hpp index e0b7ffc2e..1cb6e51c2 100644 --- a/src/proc/engine/exitnode.hpp +++ b/src/proc/engine/exitnode.hpp @@ -1,8 +1,8 @@ /* EXITNODE.hpp - special Processing Node providing "pullable" output - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/glbuf.cpp b/src/proc/engine/glbuf.cpp index d383174ae..6970a3114 100644 --- a/src/proc/engine/glbuf.cpp +++ b/src/proc/engine/glbuf.cpp @@ -1,8 +1,8 @@ /* GLBuf - a buffer and render process holding a Video frame for OpenGL rendering - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/glbuf.hpp b/src/proc/engine/glbuf.hpp index 59735595e..8e8ee2ea5 100644 --- a/src/proc/engine/glbuf.hpp +++ b/src/proc/engine/glbuf.hpp @@ -1,8 +1,8 @@ /* GLBUF.hpp - a buffer and render process holding a Video frame for OpenGL rendering - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/glpipe.cpp b/src/proc/engine/glpipe.cpp index 41139b7cd..9d4d28b48 100644 --- a/src/proc/engine/glpipe.cpp +++ b/src/proc/engine/glpipe.cpp @@ -1,8 +1,8 @@ /* GLPipe - specialized connection element for handling OpenGL implementation details - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/glpipe.hpp b/src/proc/engine/glpipe.hpp index b0c2c66f0..39a98a7ab 100644 --- a/src/proc/engine/glpipe.hpp +++ b/src/proc/engine/glpipe.hpp @@ -1,8 +1,8 @@ /* GLPIPE.hpp - specialized connection element for handling OpenGL implementation details - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/glrender.cpp b/src/proc/engine/glrender.cpp index a15a369e7..32420201b 100644 --- a/src/proc/engine/glrender.cpp +++ b/src/proc/engine/glrender.cpp @@ -1,8 +1,8 @@ /* GLRender - Representation of a OpenGL accellerated Video render process - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/glrender.hpp b/src/proc/engine/glrender.hpp index 99af3fb5a..e9c73c3a3 100644 --- a/src/proc/engine/glrender.hpp +++ b/src/proc/engine/glrender.hpp @@ -1,8 +1,8 @@ /* GLRENDER.hpp - Representation of a OpenGL accellerated Video render process - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/hub.cpp b/src/proc/engine/hub.cpp index 30a4b62fa..394d24197 100644 --- a/src/proc/engine/hub.cpp +++ b/src/proc/engine/hub.cpp @@ -1,8 +1,8 @@ /* Hub - special ProcNode used to build data distributing connections - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/hub.hpp b/src/proc/engine/hub.hpp index 161e8bfd8..b6ec69fcb 100644 --- a/src/proc/engine/hub.hpp +++ b/src/proc/engine/hub.hpp @@ -1,8 +1,8 @@ /* HUB.hpp - special ProcNode used to build data distributing connections - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/link.cpp b/src/proc/engine/link.cpp index 089ca35c5..aac01ed41 100644 --- a/src/proc/engine/link.cpp +++ b/src/proc/engine/link.cpp @@ -1,8 +1,8 @@ /* Link - forwarding, adapting or connecting ProcNode - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/link.hpp b/src/proc/engine/link.hpp index 78accf220..ad2f3a625 100644 --- a/src/proc/engine/link.hpp +++ b/src/proc/engine/link.hpp @@ -1,8 +1,8 @@ /* LINK.hpp - forwarding, adapting or connecting ProcNode - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/mask.cpp b/src/proc/engine/mask.cpp index 8f0b61156..beecb86d3 100644 --- a/src/proc/engine/mask.cpp +++ b/src/proc/engine/mask.cpp @@ -1,8 +1,8 @@ /* Mask - Video ProcNode for masking regions of the image (automatable) - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/mask.hpp b/src/proc/engine/mask.hpp index 2bbcedd14..ccbac5bcf 100644 --- a/src/proc/engine/mask.hpp +++ b/src/proc/engine/mask.hpp @@ -1,8 +1,8 @@ /* MASK.hpp - Video ProcNode for masking regions of the image (automatable) - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/pluginadapter.cpp b/src/proc/engine/pluginadapter.cpp index 9d9f9c621..fb57ae58a 100644 --- a/src/proc/engine/pluginadapter.cpp +++ b/src/proc/engine/pluginadapter.cpp @@ -1,8 +1,8 @@ /* PluginAdapter - Adapter for integrating various Effect processors in the render pipeline - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/pluginadapter.hpp b/src/proc/engine/pluginadapter.hpp index cfbd0ac78..b080b99ed 100644 --- a/src/proc/engine/pluginadapter.hpp +++ b/src/proc/engine/pluginadapter.hpp @@ -1,8 +1,8 @@ /* PLUGINADAPTER.hpp - Adapter for integrating various Effect processors in the render pipeline - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/processor.cpp b/src/proc/engine/processor.cpp index 4db2f793e..c8a228845 100644 --- a/src/proc/engine/processor.cpp +++ b/src/proc/engine/processor.cpp @@ -1,8 +1,8 @@ /* Processor - a single render pipeline for one segment of the timeline - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/processor.hpp b/src/proc/engine/processor.hpp index 2856fec3d..70ec33f6c 100644 --- a/src/proc/engine/processor.hpp +++ b/src/proc/engine/processor.hpp @@ -1,8 +1,8 @@ /* PROCESSOR.hpp - a single render pipeline for one segment of the timeline - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/procnode.cpp b/src/proc/engine/procnode.cpp index 0e7af64ca..48e33c498 100644 --- a/src/proc/engine/procnode.cpp +++ b/src/proc/engine/procnode.cpp @@ -1,8 +1,8 @@ /* ProcNode - Key abstraction of the Render Engine: a Processing Node - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/procnode.hpp b/src/proc/engine/procnode.hpp index 9fe4a053d..ae210f96b 100644 --- a/src/proc/engine/procnode.hpp +++ b/src/proc/engine/procnode.hpp @@ -1,8 +1,8 @@ /* PROCNODE.hpp - Key abstraction of the Render Engine: a Processing Node - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/projector.cpp b/src/proc/engine/projector.cpp index 38d44631d..14fcecabb 100644 --- a/src/proc/engine/projector.cpp +++ b/src/proc/engine/projector.cpp @@ -1,8 +1,8 @@ /* Projector - video ProcNode for scaling and translating image data - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/projector.hpp b/src/proc/engine/projector.hpp index fa60a30d8..0908eec38 100644 --- a/src/proc/engine/projector.hpp +++ b/src/proc/engine/projector.hpp @@ -1,8 +1,8 @@ /* PROJECTOR.hpp - video ProcNode for scaling and translating image data - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/renderengine.cpp b/src/proc/engine/renderengine.cpp index 23afb432a..daa7084ca 100644 --- a/src/proc/engine/renderengine.cpp +++ b/src/proc/engine/renderengine.cpp @@ -1,8 +1,8 @@ /* RenderEngine - a complete network of processing nodes usable for rendering - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/renderengine.hpp b/src/proc/engine/renderengine.hpp index 10a6e80e3..121d0618c 100644 --- a/src/proc/engine/renderengine.hpp +++ b/src/proc/engine/renderengine.hpp @@ -1,8 +1,8 @@ /* RENDERENGINE.hpp - a complete network of processing nodes usable for rendering - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/source.cpp b/src/proc/engine/source.cpp index dec53e998..73da9add5 100644 --- a/src/proc/engine/source.cpp +++ b/src/proc/engine/source.cpp @@ -1,8 +1,8 @@ /* Source - Representation of a Media source - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/source.hpp b/src/proc/engine/source.hpp index e8a6063cc..37af97841 100644 --- a/src/proc/engine/source.hpp +++ b/src/proc/engine/source.hpp @@ -1,8 +1,8 @@ /* SOURCE.hpp - Representation of a Media source - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/trafo.cpp b/src/proc/engine/trafo.cpp index ab96fae91..28c3db772 100644 --- a/src/proc/engine/trafo.cpp +++ b/src/proc/engine/trafo.cpp @@ -1,8 +1,8 @@ /* Trafo - transforming processing Node - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/trafo.hpp b/src/proc/engine/trafo.hpp index 7367415ea..8d2155661 100644 --- a/src/proc/engine/trafo.hpp +++ b/src/proc/engine/trafo.hpp @@ -1,8 +1,8 @@ /* TRAFO.hpp - transforming processing Node - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/vframe.cpp b/src/proc/engine/vframe.cpp index d96b1a07c..180faca70 100644 --- a/src/proc/engine/vframe.cpp +++ b/src/proc/engine/vframe.cpp @@ -1,8 +1,8 @@ /* VFrame - a buffer holding a Video frame for the render process - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/vframe.hpp b/src/proc/engine/vframe.hpp index ebd400dfc..6b1e8153b 100644 --- a/src/proc/engine/vframe.hpp +++ b/src/proc/engine/vframe.hpp @@ -1,8 +1,8 @@ /* VFRAME.hpp - a buffer holding a Video frame for the render process - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/vrender.cpp b/src/proc/engine/vrender.cpp index 5b13999d0..2bed41099 100644 --- a/src/proc/engine/vrender.cpp +++ b/src/proc/engine/vrender.cpp @@ -1,8 +1,8 @@ /* VRender - Representation of a Video render process - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/engine/vrender.hpp b/src/proc/engine/vrender.hpp index f47e40ca9..c6a34bda2 100644 --- a/src/proc/engine/vrender.hpp +++ b/src/proc/engine/vrender.hpp @@ -1,8 +1,8 @@ /* VRENDER.hpp - Representation of a Video render process - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/frame.cpp b/src/proc/frame.cpp index 8cc62841a..46ad06950 100644 --- a/src/proc/frame.cpp +++ b/src/proc/frame.cpp @@ -1,8 +1,8 @@ /* Frame - Key Abstraction: render process and buffer holding frame data. - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/frame.hpp b/src/proc/frame.hpp index 5072ca00b..239987e97 100644 --- a/src/proc/frame.hpp +++ b/src/proc/frame.hpp @@ -1,8 +1,8 @@ /* FRAME.hpp - Key Abstraction: render process and buffer holding frame data. - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/builder/assembler.cpp b/src/proc/mobject/builder/assembler.cpp index c20850012..8542860f3 100644 --- a/src/proc/mobject/builder/assembler.cpp +++ b/src/proc/mobject/builder/assembler.cpp @@ -1,8 +1,8 @@ /* Assembler - building facility (implementation of the build process) - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/builder/assembler.hpp b/src/proc/mobject/builder/assembler.hpp index 7f3a70a14..f0274f171 100644 --- a/src/proc/mobject/builder/assembler.hpp +++ b/src/proc/mobject/builder/assembler.hpp @@ -1,8 +1,8 @@ /* ASSEMBLER.hpp - building facility (implementation of the build process) - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/builder/buildertool.hpp b/src/proc/mobject/builder/buildertool.hpp index 61bb7913c..c4700bc0a 100644 --- a/src/proc/mobject/builder/buildertool.hpp +++ b/src/proc/mobject/builder/buildertool.hpp @@ -1,8 +1,8 @@ /* BUILDERTOOL.hpp - Interface, (visiting) tool for processing MObjects - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/builder/conmanager.cpp b/src/proc/mobject/builder/conmanager.cpp index 15b6def9c..e32ecf92b 100644 --- a/src/proc/mobject/builder/conmanager.cpp +++ b/src/proc/mobject/builder/conmanager.cpp @@ -1,8 +1,8 @@ /* ConManager - manages the creation of additional ProcNode connections for the Renderengine - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/builder/conmanager.hpp b/src/proc/mobject/builder/conmanager.hpp index d59e53d48..3cd75cc6d 100644 --- a/src/proc/mobject/builder/conmanager.hpp +++ b/src/proc/mobject/builder/conmanager.hpp @@ -1,8 +1,8 @@ /* CONMANAGER.hpp - manages the creation of additional ProcNode connections for the Renderengine - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/builder/nodecreatertool.cpp b/src/proc/mobject/builder/nodecreatertool.cpp index d4e0d78dd..89a35fa46 100644 --- a/src/proc/mobject/builder/nodecreatertool.cpp +++ b/src/proc/mobject/builder/nodecreatertool.cpp @@ -1,8 +1,8 @@ /* NodeCreaterTool - central Tool implementing the Renderengine building - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/builder/nodecreatertool.hpp b/src/proc/mobject/builder/nodecreatertool.hpp index 6eebc98c4..26a033d26 100644 --- a/src/proc/mobject/builder/nodecreatertool.hpp +++ b/src/proc/mobject/builder/nodecreatertool.hpp @@ -1,8 +1,8 @@ /* NODECREATERTOOL.hpp - central Tool implementing the Renderengine building - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/builder/segmentationtool.cpp b/src/proc/mobject/builder/segmentationtool.cpp index a98a63f83..6f07e7d4f 100644 --- a/src/proc/mobject/builder/segmentationtool.cpp +++ b/src/proc/mobject/builder/segmentationtool.cpp @@ -1,8 +1,8 @@ /* SegmentationTool - Tool for creating a partitioning of the current timeline - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/builder/segmentationtool.hpp b/src/proc/mobject/builder/segmentationtool.hpp index f913836ca..aa09d80d3 100644 --- a/src/proc/mobject/builder/segmentationtool.hpp +++ b/src/proc/mobject/builder/segmentationtool.hpp @@ -1,8 +1,8 @@ /* SEGMENTATIONTOOL.hpp - Tool for creating a partitioning of the current timeline - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/builder/toolfactory.cpp b/src/proc/mobject/builder/toolfactory.cpp index 456ee568b..8e1b14631 100644 --- a/src/proc/mobject/builder/toolfactory.cpp +++ b/src/proc/mobject/builder/toolfactory.cpp @@ -1,8 +1,8 @@ /* ToolFactory - supply of Tool implementations for the Builder - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/builder/toolfactory.hpp b/src/proc/mobject/builder/toolfactory.hpp index d39b0e7c7..2061b4fd2 100644 --- a/src/proc/mobject/builder/toolfactory.hpp +++ b/src/proc/mobject/builder/toolfactory.hpp @@ -1,8 +1,8 @@ /* TOOLFACTORY.hpp - supply of Tool implementations for the Builder - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/builderfacade.cpp b/src/proc/mobject/builderfacade.cpp index 8ebed9d08..149862f98 100644 --- a/src/proc/mobject/builderfacade.cpp +++ b/src/proc/mobject/builderfacade.cpp @@ -1,8 +1,8 @@ /* BuilderFacade - Facade and service access point for the Builder Subsystem - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/builderfacade.hpp b/src/proc/mobject/builderfacade.hpp index c0b8398e1..59023853c 100644 --- a/src/proc/mobject/builderfacade.hpp +++ b/src/proc/mobject/builderfacade.hpp @@ -1,8 +1,8 @@ /* BUILDERFACADE.hpp - Facade and service access point for the Builder Subsystem - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/controller/pathmanager.cpp b/src/proc/mobject/controller/pathmanager.cpp index b197784a6..bf3c359ab 100644 --- a/src/proc/mobject/controller/pathmanager.cpp +++ b/src/proc/mobject/controller/pathmanager.cpp @@ -1,8 +1,8 @@ /* PathManager - Manager for deciding the actual render strategy - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/controller/pathmanager.hpp b/src/proc/mobject/controller/pathmanager.hpp index fecc36021..a29cd2f94 100644 --- a/src/proc/mobject/controller/pathmanager.hpp +++ b/src/proc/mobject/controller/pathmanager.hpp @@ -1,8 +1,8 @@ /* PATHMANAGER.hpp - Manager for deciding the actual render strategy - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/controller/renderstate.cpp b/src/proc/mobject/controller/renderstate.cpp index f1db1dfbb..98ca2ccd1 100644 --- a/src/proc/mobject/controller/renderstate.cpp +++ b/src/proc/mobject/controller/renderstate.cpp @@ -1,8 +1,8 @@ /* RenderState - renderengine state manager - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/controller/renderstate.hpp b/src/proc/mobject/controller/renderstate.hpp index c73b3c647..c547772ea 100644 --- a/src/proc/mobject/controller/renderstate.hpp +++ b/src/proc/mobject/controller/renderstate.hpp @@ -1,8 +1,8 @@ /* RENDERSTATE.hpp - renderengine state manager - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/explicitplacement.hpp b/src/proc/mobject/explicitplacement.hpp index 416b1d4f1..307f38409 100644 --- a/src/proc/mobject/explicitplacement.hpp +++ b/src/proc/mobject/explicitplacement.hpp @@ -1,8 +1,8 @@ /* EXPLICITPLACEMENT.hpp - special Placement yielding an absolute location (Time,Track) for a MObject - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/interpolator.cpp b/src/proc/mobject/interpolator.cpp index 3767770ca..8ceb9ad86 100644 --- a/src/proc/mobject/interpolator.cpp +++ b/src/proc/mobject/interpolator.cpp @@ -1,8 +1,8 @@ /* Interpolator - denotes a facility to get (continuously interpolated) parameter values - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/interpolator.hpp b/src/proc/mobject/interpolator.hpp index 7ff3e371a..843cd52bc 100644 --- a/src/proc/mobject/interpolator.hpp +++ b/src/proc/mobject/interpolator.hpp @@ -1,8 +1,8 @@ /* INTERPOLATOR.hpp - denotes a facility to get (continuously interpolated) parameter values - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/mobject.cpp b/src/proc/mobject/mobject.cpp index e8692abf7..cd6c0011b 100644 --- a/src/proc/mobject/mobject.cpp +++ b/src/proc/mobject/mobject.cpp @@ -1,8 +1,8 @@ /* MObject - Key Abstraction: A Media Object in the Session - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/mobject.hpp b/src/proc/mobject/mobject.hpp index 634322470..b7c139f93 100644 --- a/src/proc/mobject/mobject.hpp +++ b/src/proc/mobject/mobject.hpp @@ -1,8 +1,8 @@ /* MOBJECT.hpp - Key Abstraction: A Media Object in the Session - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/parameter.cpp b/src/proc/mobject/parameter.cpp index b603a2055..280cbc69b 100644 --- a/src/proc/mobject/parameter.cpp +++ b/src/proc/mobject/parameter.cpp @@ -1,8 +1,8 @@ /* Parameter - representation of an automatable effect/plugin parameter - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/parameter.hpp b/src/proc/mobject/parameter.hpp index da75bb48e..00154dff5 100644 --- a/src/proc/mobject/parameter.hpp +++ b/src/proc/mobject/parameter.hpp @@ -1,8 +1,8 @@ /* PARAMETER.hpp - representation of an automatable effect/plugin parameter - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/paramprovider.cpp b/src/proc/mobject/paramprovider.cpp index e9a6b26ce..8b5da785a 100644 --- a/src/proc/mobject/paramprovider.cpp +++ b/src/proc/mobject/paramprovider.cpp @@ -1,8 +1,8 @@ /* ParamProvider - interface denoting a source for actual Parameter values - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/paramprovider.hpp b/src/proc/mobject/paramprovider.hpp index 9057167be..fdcaff2a8 100644 --- a/src/proc/mobject/paramprovider.hpp +++ b/src/proc/mobject/paramprovider.hpp @@ -1,8 +1,8 @@ /* PARAMPROVIDER.hpp - interface denoting a source for actual Parameter values - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/placement.cpp b/src/proc/mobject/placement.cpp index 7929a7a6f..452528627 100644 --- a/src/proc/mobject/placement.cpp +++ b/src/proc/mobject/placement.cpp @@ -1,8 +1,8 @@ /* Placement - Key Abstraction: a way to place and locate a Media Object - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/placement.hpp b/src/proc/mobject/placement.hpp index 63d96c0fb..71c654308 100644 --- a/src/proc/mobject/placement.hpp +++ b/src/proc/mobject/placement.hpp @@ -1,8 +1,8 @@ /* PLACEMENT.hpp - Key Abstraction: a way to place and locate a Media Object - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session.hpp b/src/proc/mobject/session.hpp index c61bc938a..48473d298 100644 --- a/src/proc/mobject/session.hpp +++ b/src/proc/mobject/session.hpp @@ -1,8 +1,8 @@ /* SESSION.hpp - holds the complete session to be edited by the user - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/abstractmo.cpp b/src/proc/mobject/session/abstractmo.cpp index 8316ae5d9..e484eee6e 100644 --- a/src/proc/mobject/session/abstractmo.cpp +++ b/src/proc/mobject/session/abstractmo.cpp @@ -1,8 +1,8 @@ /* AbstractMO - abstract base class for all Media Objects - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/abstractmo.hpp b/src/proc/mobject/session/abstractmo.hpp index bd4fd5785..45942986d 100644 --- a/src/proc/mobject/session/abstractmo.hpp +++ b/src/proc/mobject/session/abstractmo.hpp @@ -1,8 +1,8 @@ /* ABSTRACTMO.hpp - abstract base class for all Media Objects - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/allocation.cpp b/src/proc/mobject/session/allocation.cpp index 0b070a9be..ae23185b8 100644 --- a/src/proc/mobject/session/allocation.cpp +++ b/src/proc/mobject/session/allocation.cpp @@ -1,8 +1,8 @@ /* Allocation - objective to place a MObject in a specific way - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/allocation.hpp b/src/proc/mobject/session/allocation.hpp index 95a5b9a01..e668fb469 100644 --- a/src/proc/mobject/session/allocation.hpp +++ b/src/proc/mobject/session/allocation.hpp @@ -1,8 +1,8 @@ /* ALLOCATION.hpp - objective to place a MObject in a specific way - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/auto.cpp b/src/proc/mobject/session/auto.cpp index 6e046260b..a8ecf4c38 100644 --- a/src/proc/mobject/session/auto.cpp +++ b/src/proc/mobject/session/auto.cpp @@ -1,8 +1,8 @@ /* Auto - Media Object holding automation data - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/auto.hpp b/src/proc/mobject/session/auto.hpp index d0b54cad6..0fcf831aa 100644 --- a/src/proc/mobject/session/auto.hpp +++ b/src/proc/mobject/session/auto.hpp @@ -1,8 +1,8 @@ /* AUTO.hpp - Media Object holding automation data - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/clip.cpp b/src/proc/mobject/session/clip.cpp index 7ea375173..8b285e1ac 100644 --- a/src/proc/mobject/session/clip.cpp +++ b/src/proc/mobject/session/clip.cpp @@ -1,8 +1,8 @@ /* Clip - a Media Clip - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/clip.hpp b/src/proc/mobject/session/clip.hpp index fd87b1c39..a7ca8a363 100644 --- a/src/proc/mobject/session/clip.hpp +++ b/src/proc/mobject/session/clip.hpp @@ -1,8 +1,8 @@ /* CLIP.hpp - a Media Clip - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/compoundclip.cpp b/src/proc/mobject/session/compoundclip.cpp index 68694e136..caa8e83bd 100644 --- a/src/proc/mobject/session/compoundclip.cpp +++ b/src/proc/mobject/session/compoundclip.cpp @@ -1,8 +1,8 @@ /* CompoundClip - compound of several clips (multichannel) - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/compoundclip.hpp b/src/proc/mobject/session/compoundclip.hpp index 332396a48..e2dfd9fd9 100644 --- a/src/proc/mobject/session/compoundclip.hpp +++ b/src/proc/mobject/session/compoundclip.hpp @@ -1,8 +1,8 @@ /* COMPOUNDCLIP.hpp - compound of several clips (multichannel) - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/edl.cpp b/src/proc/mobject/session/edl.cpp index 84a3f6e4c..8665c5d7f 100644 --- a/src/proc/mobject/session/edl.cpp +++ b/src/proc/mobject/session/edl.cpp @@ -1,8 +1,8 @@ /* EDL - the (high level) Edit Decision List within the current Session - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/edl.hpp b/src/proc/mobject/session/edl.hpp index db3ad4971..1e9c7bece 100644 --- a/src/proc/mobject/session/edl.hpp +++ b/src/proc/mobject/session/edl.hpp @@ -1,8 +1,8 @@ /* EDL.hpp - the (high level) Edit Decision List within the current Session - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/effect.cpp b/src/proc/mobject/session/effect.cpp index 8a58ec7a6..e83f03119 100644 --- a/src/proc/mobject/session/effect.cpp +++ b/src/proc/mobject/session/effect.cpp @@ -1,8 +1,8 @@ /* Effect - EDL representation of a pluggable and automatable effect. - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/effect.hpp b/src/proc/mobject/session/effect.hpp index 5255e718b..5831098d4 100644 --- a/src/proc/mobject/session/effect.hpp +++ b/src/proc/mobject/session/effect.hpp @@ -1,8 +1,8 @@ /* EFFECT.hpp - EDL representation of a pluggable and automatable effect. - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/fixedlocation.cpp b/src/proc/mobject/session/fixedlocation.cpp index 150702bb0..238b8c011 100644 --- a/src/proc/mobject/session/fixedlocation.cpp +++ b/src/proc/mobject/session/fixedlocation.cpp @@ -1,8 +1,8 @@ /* FixedLocation - directly positioning a MObject to a fixed location - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/fixedlocation.hpp b/src/proc/mobject/session/fixedlocation.hpp index 8d4282443..c3b176d2e 100644 --- a/src/proc/mobject/session/fixedlocation.hpp +++ b/src/proc/mobject/session/fixedlocation.hpp @@ -1,8 +1,8 @@ /* FIXEDLOCATION.hpp - directly positioning a MObject to a fixed location - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/fixture.cpp b/src/proc/mobject/session/fixture.cpp index deb2a6db1..bdad3f807 100644 --- a/src/proc/mobject/session/fixture.cpp +++ b/src/proc/mobject/session/fixture.cpp @@ -1,8 +1,8 @@ /* Fixture - the (low level) representation of the EDL with explicit placement data - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/fixture.hpp b/src/proc/mobject/session/fixture.hpp index 78c0cdac5..208459b10 100644 --- a/src/proc/mobject/session/fixture.hpp +++ b/src/proc/mobject/session/fixture.hpp @@ -1,8 +1,8 @@ /* FIXTURE.hpp - the (low level) representation of the EDL with explicit placement data - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/label.cpp b/src/proc/mobject/session/label.cpp index e1f81728a..c5d85907d 100644 --- a/src/proc/mobject/session/label.cpp +++ b/src/proc/mobject/session/label.cpp @@ -1,8 +1,8 @@ /* Label - a user visible Marker or Tag - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/label.hpp b/src/proc/mobject/session/label.hpp index 54080f0f3..b968baa68 100644 --- a/src/proc/mobject/session/label.hpp +++ b/src/proc/mobject/session/label.hpp @@ -1,8 +1,8 @@ /* LABEL.hpp - a user visible Marker or Tag - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/locatingpin.cpp b/src/proc/mobject/session/locatingpin.cpp index fc290c4be..de443c3a5 100644 --- a/src/proc/mobject/session/locatingpin.cpp +++ b/src/proc/mobject/session/locatingpin.cpp @@ -1,8 +1,8 @@ /* LocatingPin - Chaining and constraining the Placement of a Media Object - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/locatingpin.hpp b/src/proc/mobject/session/locatingpin.hpp index cfa8416ba..dfc7f8696 100644 --- a/src/proc/mobject/session/locatingpin.hpp +++ b/src/proc/mobject/session/locatingpin.hpp @@ -1,8 +1,8 @@ /* LOCATINGPIN.hpp - Chaining and constraining the Placement of a Media Object - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/meta.cpp b/src/proc/mobject/session/meta.cpp index 0b6cb3ad8..cb61756d5 100644 --- a/src/proc/mobject/session/meta.cpp +++ b/src/proc/mobject/session/meta.cpp @@ -1,8 +1,8 @@ /* Meta - abstract base class of all MObjects representing meta data or processing instructions - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/meta.hpp b/src/proc/mobject/session/meta.hpp index 6810cce03..b45d30eb5 100644 --- a/src/proc/mobject/session/meta.hpp +++ b/src/proc/mobject/session/meta.hpp @@ -1,8 +1,8 @@ /* META.hpp - abstract base class of all MObjects representing meta data or processing instructions - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/mobjectfactory.cpp b/src/proc/mobject/session/mobjectfactory.cpp index c86da719b..418909b04 100644 --- a/src/proc/mobject/session/mobjectfactory.cpp +++ b/src/proc/mobject/session/mobjectfactory.cpp @@ -1,8 +1,8 @@ /* MObjectFactory - creating concrete MObject subclass instances - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/mobjectfactory.hpp b/src/proc/mobject/session/mobjectfactory.hpp index 3bc27a2a2..50602b7e5 100644 --- a/src/proc/mobject/session/mobjectfactory.hpp +++ b/src/proc/mobject/session/mobjectfactory.hpp @@ -1,8 +1,8 @@ /* MOBJECTFACTORY.hpp - creating concrete MObject subclass instances - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/relativelocation.cpp b/src/proc/mobject/session/relativelocation.cpp index 6488d4d77..7ae39ff3a 100644 --- a/src/proc/mobject/session/relativelocation.cpp +++ b/src/proc/mobject/session/relativelocation.cpp @@ -1,8 +1,8 @@ /* RelativeLocation - Placement implementation attaching MObjects relative to another one - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/relativelocation.hpp b/src/proc/mobject/session/relativelocation.hpp index 810476c04..33b857053 100644 --- a/src/proc/mobject/session/relativelocation.hpp +++ b/src/proc/mobject/session/relativelocation.hpp @@ -1,8 +1,8 @@ /* RELATIVELOCATION.hpp - Placement implementation attaching MObjects relative to another one - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/segment.cpp b/src/proc/mobject/session/segment.cpp index 7d8f3ca1a..3c34896ab 100644 --- a/src/proc/mobject/session/segment.cpp +++ b/src/proc/mobject/session/segment.cpp @@ -1,8 +1,8 @@ /* Segment - Segment of the Timeline. - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/segment.hpp b/src/proc/mobject/session/segment.hpp index 22305b5e4..46b5929d4 100644 --- a/src/proc/mobject/session/segment.hpp +++ b/src/proc/mobject/session/segment.hpp @@ -1,8 +1,8 @@ /* SEGMENT.hpp - Segment of the Timeline. - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/session.cpp b/src/proc/mobject/session/session.cpp index 6e9b8f3fe..2e81d752e 100644 --- a/src/proc/mobject/session/session.cpp +++ b/src/proc/mobject/session/session.cpp @@ -1,8 +1,8 @@ /* Session - holds the complete session to be edited by the user - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/sessionimpl.cpp b/src/proc/mobject/session/sessionimpl.cpp index d89edac15..e0cab87cc 100644 --- a/src/proc/mobject/session/sessionimpl.cpp +++ b/src/proc/mobject/session/sessionimpl.cpp @@ -1,8 +1,8 @@ /* SessionImpl - holds the complete session data to be edited by the user - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/sessionimpl.hpp b/src/proc/mobject/session/sessionimpl.hpp index 734a74a01..d145c4fe5 100644 --- a/src/proc/mobject/session/sessionimpl.hpp +++ b/src/proc/mobject/session/sessionimpl.hpp @@ -1,8 +1,8 @@ /* SESSIONIMPL.hpp - holds the complete session data to be edited by the user - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/sessmanagerimpl.cpp b/src/proc/mobject/session/sessmanagerimpl.cpp index 9031bb712..919a56294 100644 --- a/src/proc/mobject/session/sessmanagerimpl.cpp +++ b/src/proc/mobject/session/sessmanagerimpl.cpp @@ -1,8 +1,8 @@ /* SessManagerImpl - global session access and lifecycle - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/simpleclip.cpp b/src/proc/mobject/session/simpleclip.cpp index 053a5f148..97796a00e 100644 --- a/src/proc/mobject/session/simpleclip.cpp +++ b/src/proc/mobject/session/simpleclip.cpp @@ -1,8 +1,8 @@ /* SimpleClip - Elementary clip (single media stream only) - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/simpleclip.hpp b/src/proc/mobject/session/simpleclip.hpp index 446090cc1..f0dc62c02 100644 --- a/src/proc/mobject/session/simpleclip.hpp +++ b/src/proc/mobject/session/simpleclip.hpp @@ -1,8 +1,8 @@ /* SIMPLECLIP.hpp - Elementary clip (single media stream only) - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/track.cpp b/src/proc/mobject/session/track.cpp index 05b0dd31f..33dd7ed6b 100644 --- a/src/proc/mobject/session/track.cpp +++ b/src/proc/mobject/session/track.cpp @@ -1,8 +1,8 @@ /* Track - descriptor for one track in the Session - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/mobject/session/track.hpp b/src/proc/mobject/session/track.hpp index 42d5fe783..3df1e9682 100644 --- a/src/proc/mobject/session/track.hpp +++ b/src/proc/mobject/session/track.hpp @@ -1,8 +1,8 @@ /* TRACK.hpp - descriptor for one track in the Session - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/stateproxy.cpp b/src/proc/stateproxy.cpp index 9d4004d0f..f4125a41e 100644 --- a/src/proc/stateproxy.cpp +++ b/src/proc/stateproxy.cpp @@ -1,8 +1,8 @@ /* StateProxy - Key Interface representing a render process and encapsulating state - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/proc/stateproxy.hpp b/src/proc/stateproxy.hpp index c1ce6d52f..7c338bd1d 100644 --- a/src/proc/stateproxy.hpp +++ b/src/proc/stateproxy.hpp @@ -1,8 +1,8 @@ /* STATEPROXY.hpp - Key Interface representing a render process and encapsulating state - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/Makefile.am b/tests/Makefile.am index 109cd44b9..26fe4b678 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) CinelerraCV +# Copyright (C) Lumiera.org # 2007, Christian Thaeter # Hermann Vosseler # diff --git a/tests/bugs/bugmain.c b/tests/bugs/bugmain.c index 4331f4516..7823b279e 100644 --- a/tests/bugs/bugmain.c +++ b/tests/bugs/bugmain.c @@ -1,8 +1,8 @@ /* errortest.c - executable for running bug regression tests - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/backend/mediaaccessmock.cpp b/tests/components/backend/mediaaccessmock.cpp index d980c83d5..071ad5cef 100644 --- a/tests/components/backend/mediaaccessmock.cpp +++ b/tests/components/backend/mediaaccessmock.cpp @@ -1,8 +1,8 @@ /* MediaAccessMock.hpp - a test (stub) target object for testing the factories - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/backend/mediaaccessmock.hpp b/tests/components/backend/mediaaccessmock.hpp index 2b70ca3fa..e11d0a67a 100644 --- a/tests/components/backend/mediaaccessmock.hpp +++ b/tests/components/backend/mediaaccessmock.hpp @@ -1,8 +1,8 @@ /* MEDIAACCESSMOCK.hpp - a test (stub) target object for testing the factories - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/backend/mediaaccessmocktest.cpp b/tests/components/backend/mediaaccessmocktest.cpp index 110d2b3cd..327a7bc74 100644 --- a/tests/components/backend/mediaaccessmocktest.cpp +++ b/tests/components/backend/mediaaccessmocktest.cpp @@ -1,8 +1,8 @@ /* MediaAccessMock(Test) - checking our Test Mock replacing the MediaAccessFacade - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/common/appconfigtest.cpp b/tests/components/common/appconfigtest.cpp index 49266c4ae..d65e29402 100644 --- a/tests/components/common/appconfigtest.cpp +++ b/tests/components/common/appconfigtest.cpp @@ -1,8 +1,8 @@ /* Appconfig(Test) - accessing the allwasy-available Appconfig singleton - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/common/exceptionerrortest.cpp b/tests/components/common/exceptionerrortest.cpp index 51e621dbc..987c77d19 100644 --- a/tests/components/common/exceptionerrortest.cpp +++ b/tests/components/common/exceptionerrortest.cpp @@ -1,8 +1,8 @@ /* Exceptionhandlin(Test) - throwing and catching our exception type - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/common/factoryspecialtest.cpp b/tests/components/common/factoryspecialtest.cpp index e9848c599..de9eeee8b 100644 --- a/tests/components/common/factoryspecialtest.cpp +++ b/tests/components/common/factoryspecialtest.cpp @@ -1,8 +1,8 @@ /* Factory-Special(Test) - testing the more advanced features of factory - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/common/factorytest.cpp b/tests/components/common/factorytest.cpp index 4648fe6d8..875266fce 100644 --- a/tests/components/common/factorytest.cpp +++ b/tests/components/common/factorytest.cpp @@ -1,8 +1,8 @@ /* Factory(Test) - unittest for the object creating factory - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/common/sanitizedidentifiertest.cpp b/tests/components/common/sanitizedidentifiertest.cpp index a6dba2c79..416d81c58 100644 --- a/tests/components/common/sanitizedidentifiertest.cpp +++ b/tests/components/common/sanitizedidentifiertest.cpp @@ -1,8 +1,8 @@ /* SanitizedIdentifier(Test) - remove non-standard-chars and punctuation - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/common/singletontest.cpp b/tests/components/common/singletontest.cpp index ce88d5245..558d7e674 100644 --- a/tests/components/common/singletontest.cpp +++ b/tests/components/common/singletontest.cpp @@ -1,8 +1,8 @@ /* Singleton(Test) - unittest for our Singleton template - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/common/singletontestmocktest.cpp b/tests/components/common/singletontestmocktest.cpp index b33dda5d2..b90b1a73c 100644 --- a/tests/components/common/singletontestmocktest.cpp +++ b/tests/components/common/singletontestmocktest.cpp @@ -1,8 +1,8 @@ /* SingletonTestMock(Test) - using Singleton for injecting Test-Mocks - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/common/test/cmdlinewrappertest.cpp b/tests/components/common/test/cmdlinewrappertest.cpp index 84b0780c1..668ce8121 100644 --- a/tests/components/common/test/cmdlinewrappertest.cpp +++ b/tests/components/common/test/cmdlinewrappertest.cpp @@ -1,8 +1,8 @@ /* Cmdlinewrapper(Test) - build vector of tokens from cmdline, various conversions - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/common/test/testoptiontest.cpp b/tests/components/common/test/testoptiontest.cpp index aac3269f0..7f3da81c6 100644 --- a/tests/components/common/test/testoptiontest.cpp +++ b/tests/components/common/test/testoptiontest.cpp @@ -1,8 +1,8 @@ /* TestOption(Test) - parsing of cmd line options for running Testcases - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/common/testtargetobj.hpp b/tests/components/common/testtargetobj.hpp index d367f4cd6..8a0728b95 100644 --- a/tests/components/common/testtargetobj.hpp +++ b/tests/components/common/testtargetobj.hpp @@ -1,8 +1,8 @@ /* TESTTARGETOBJ.hpp - a test (stub) target object for testing the factories - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/common/typelisttest.cpp b/tests/components/common/typelisttest.cpp index ddd13c776..1a2e383e8 100644 --- a/tests/components/common/typelisttest.cpp +++ b/tests/components/common/typelisttest.cpp @@ -1,8 +1,8 @@ /* TypeList(Test) - check the typelist metaprogramming facility - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/common/visitingtoolconcept.cpp b/tests/components/common/visitingtoolconcept.cpp index dbccfe0b3..16578b6be 100644 --- a/tests/components/common/visitingtoolconcept.cpp +++ b/tests/components/common/visitingtoolconcept.cpp @@ -1,8 +1,8 @@ /* VisitingTool(Concept) - working out our own Visitor library implementation - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/common/visitingtoolextendedtest.cpp b/tests/components/common/visitingtoolextendedtest.cpp index 076a3d48e..a25ebd95a 100644 --- a/tests/components/common/visitingtoolextendedtest.cpp +++ b/tests/components/common/visitingtoolextendedtest.cpp @@ -1,8 +1,8 @@ /* VisitingToolExtended(Test) - check obscure corner cases of visitor lib implementation - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/common/visitingtooltest.cpp b/tests/components/common/visitingtooltest.cpp index 983a9ab0b..10edf233d 100644 --- a/tests/components/common/visitingtooltest.cpp +++ b/tests/components/common/visitingtooltest.cpp @@ -1,8 +1,8 @@ /* VisitingTool(Test) - check the standard visitor use case - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/helloworldtest.cpp b/tests/components/helloworldtest.cpp index 3aa516ca3..8398f19ad 100644 --- a/tests/components/helloworldtest.cpp +++ b/tests/components/helloworldtest.cpp @@ -1,8 +1,8 @@ /* HelloWorld(Test) - how to use this test framework... - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/mainsuite.cpp b/tests/components/mainsuite.cpp index dac63ba7c..924a982e3 100644 --- a/tests/components/mainsuite.cpp +++ b/tests/components/mainsuite.cpp @@ -1,8 +1,8 @@ /* mainsuite.cpp - "the" cinelerra3 self test suite - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter Hermann Vosseler This program is free software; you can redistribute it and/or diff --git a/tests/components/proc/asset/assetcategorytest.cpp b/tests/components/proc/asset/assetcategorytest.cpp index af671d91f..ef02aaafe 100644 --- a/tests/components/proc/asset/assetcategorytest.cpp +++ b/tests/components/proc/asset/assetcategorytest.cpp @@ -1,8 +1,8 @@ /* AssetCategory(Test) - verifying Asset category tuple functions - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/asset/assetdiagnostics.hpp b/tests/components/proc/asset/assetdiagnostics.hpp index c8df758f8..df852bb2e 100644 --- a/tests/components/proc/asset/assetdiagnostics.hpp +++ b/tests/components/proc/asset/assetdiagnostics.hpp @@ -1,8 +1,8 @@ /* ASSETDIAGNOSTICS.hpp - collection of test and debug helpers - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/asset/compoundmediatest.cpp b/tests/components/proc/asset/compoundmediatest.cpp index ba11c1bef..73e4056bc 100644 --- a/tests/components/proc/asset/compoundmediatest.cpp +++ b/tests/components/proc/asset/compoundmediatest.cpp @@ -1,8 +1,8 @@ /* CompoundMedia(Test) - handling multichannel Media Assets - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/asset/createassettest.cpp b/tests/components/proc/asset/createassettest.cpp index 01ae76efe..fa28d4472 100644 --- a/tests/components/proc/asset/createassettest.cpp +++ b/tests/components/proc/asset/createassettest.cpp @@ -1,8 +1,8 @@ /* CreateAsset(Test) - constructing and registering Assets - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/asset/deleteassettest.cpp b/tests/components/proc/asset/deleteassettest.cpp index 15430ce95..5a0ef2ba4 100644 --- a/tests/components/proc/asset/deleteassettest.cpp +++ b/tests/components/proc/asset/deleteassettest.cpp @@ -1,8 +1,8 @@ /* DeleteAsset(Test) - deleting and Asset with all dependencies - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/asset/dependantassetstest.cpp b/tests/components/proc/asset/dependantassetstest.cpp index 3842ad933..0b7cbd0e9 100644 --- a/tests/components/proc/asset/dependantassetstest.cpp +++ b/tests/components/proc/asset/dependantassetstest.cpp @@ -1,8 +1,8 @@ /* DependantAssets(Test) - unittest for the object creating factory - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/asset/identityofassetstest.cpp b/tests/components/proc/asset/identityofassetstest.cpp index adf7d35ea..655c4fb40 100644 --- a/tests/components/proc/asset/identityofassetstest.cpp +++ b/tests/components/proc/asset/identityofassetstest.cpp @@ -1,8 +1,8 @@ /* IdentityOfAssets(Test) - Asset object identity and versioning - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/asset/makecliptest.cpp b/tests/components/proc/asset/makecliptest.cpp index cb8999c55..83702d7c5 100644 --- a/tests/components/proc/asset/makecliptest.cpp +++ b/tests/components/proc/asset/makecliptest.cpp @@ -1,8 +1,8 @@ /* MakeClip(Test) - create a Clip from a Media Asset - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/asset/mediastructurequerytest.cpp b/tests/components/proc/asset/mediastructurequerytest.cpp index 11d758b63..866178fd4 100644 --- a/tests/components/proc/asset/mediastructurequerytest.cpp +++ b/tests/components/proc/asset/mediastructurequerytest.cpp @@ -1,8 +1,8 @@ /* MediaStructureQuery(Test) - check functionallity used for creating media assets - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/asset/orderingofassetstest.cpp b/tests/components/proc/asset/orderingofassetstest.cpp index dba64433d..26d6aa50a 100644 --- a/tests/components/proc/asset/orderingofassetstest.cpp +++ b/tests/components/proc/asset/orderingofassetstest.cpp @@ -1,8 +1,8 @@ /* OrderingOfAssets(Test) - equality and comparisons - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/asset/testasset.cpp b/tests/components/proc/asset/testasset.cpp index ffc035722..b48b64da1 100644 --- a/tests/components/proc/asset/testasset.cpp +++ b/tests/components/proc/asset/testasset.cpp @@ -1,8 +1,8 @@ /* TestClip - test clip (stub) for checking EDL/Session functionality - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/asset/testasset.hpp b/tests/components/proc/asset/testasset.hpp index 9e7e66da9..05f82c79e 100644 --- a/tests/components/proc/asset/testasset.hpp +++ b/tests/components/proc/asset/testasset.hpp @@ -1,8 +1,8 @@ /* TESTASSET.hpp - test asset (stub) for checking internal asset functionality - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/asset/testclipasset.hpp b/tests/components/proc/asset/testclipasset.hpp index 35e56525d..8bb0fa1ad 100644 --- a/tests/components/proc/asset/testclipasset.hpp +++ b/tests/components/proc/asset/testclipasset.hpp @@ -1,8 +1,8 @@ /* TESTCLIPASSET.hpp - test Media-Asset (clip) for checking Assets and MObjects - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/engine/sourcenodetest.cpp b/tests/components/proc/engine/sourcenodetest.cpp index 6177475b0..35127ab4a 100644 --- a/tests/components/proc/engine/sourcenodetest.cpp +++ b/tests/components/proc/engine/sourcenodetest.cpp @@ -1,8 +1,8 @@ /* SourceNode(Test) - unit test of the source readering render node - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/mobject/builder/buildertooltest.cpp b/tests/components/proc/mobject/builder/buildertooltest.cpp index c48b05627..8a445ef18 100644 --- a/tests/components/proc/mobject/builder/buildertooltest.cpp +++ b/tests/components/proc/mobject/builder/buildertooltest.cpp @@ -1,8 +1,8 @@ /* BuilderTool(Test) - specialized form of the acyclic visitor - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/mobject/builder/buildsegmenttest.cpp b/tests/components/proc/mobject/builder/buildsegmenttest.cpp index 2e6a8fb9b..82de68330 100644 --- a/tests/components/proc/mobject/builder/buildsegmenttest.cpp +++ b/tests/components/proc/mobject/builder/buildsegmenttest.cpp @@ -1,8 +1,8 @@ /* BuildSegment(Test) - building the render-tree for a segment of the EDL - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/mobject/controller/rendersegmenttest.cpp b/tests/components/proc/mobject/controller/rendersegmenttest.cpp index b99965946..fac5568aa 100644 --- a/tests/components/proc/mobject/controller/rendersegmenttest.cpp +++ b/tests/components/proc/mobject/controller/rendersegmenttest.cpp @@ -1,8 +1,8 @@ /* RenderSegment(Test) - Proc-Layer Integrationtest - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/mobject/placementbasictest.cpp b/tests/components/proc/mobject/placementbasictest.cpp index f26b0ab47..16b6a80d0 100644 --- a/tests/components/proc/mobject/placementbasictest.cpp +++ b/tests/components/proc/mobject/placementbasictest.cpp @@ -1,8 +1,8 @@ /* PlacementBasic(Test) - basic Placement and MObject handling - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/mobject/session/addcliptest.cpp b/tests/components/proc/mobject/session/addcliptest.cpp index cf5a11d77..ffb794e95 100644 --- a/tests/components/proc/mobject/session/addcliptest.cpp +++ b/tests/components/proc/mobject/session/addcliptest.cpp @@ -1,8 +1,8 @@ /* AddClip(Test) - adding an Clip-MObject to the EDL/Session - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/mobject/session/deletecliptest.cpp b/tests/components/proc/mobject/session/deletecliptest.cpp index bc7dc2229..6f1e387e5 100644 --- a/tests/components/proc/mobject/session/deletecliptest.cpp +++ b/tests/components/proc/mobject/session/deletecliptest.cpp @@ -1,8 +1,8 @@ /* DeleteClip(Test) - removing an Clip-MObject from the Session - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/mobject/session/rebuildfixturetest.cpp b/tests/components/proc/mobject/session/rebuildfixturetest.cpp index 48d2726ac..ffb43a32b 100644 --- a/tests/components/proc/mobject/session/rebuildfixturetest.cpp +++ b/tests/components/proc/mobject/session/rebuildfixturetest.cpp @@ -1,8 +1,8 @@ /* RebuildFixture(Test) - (re)building the explicit placements - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/mobject/session/sessionmanagertest.cpp b/tests/components/proc/mobject/session/sessionmanagertest.cpp index 409e53b46..3dcf1716d 100644 --- a/tests/components/proc/mobject/session/sessionmanagertest.cpp +++ b/tests/components/proc/mobject/session/sessionmanagertest.cpp @@ -1,8 +1,8 @@ /* SessionManager(Test) - accessing, loading and saving the Session/EDL - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/mobject/session/sessionstructuretest.cpp b/tests/components/proc/mobject/session/sessionstructuretest.cpp index 46fe59aee..d079ab01f 100644 --- a/tests/components/proc/mobject/session/sessionstructuretest.cpp +++ b/tests/components/proc/mobject/session/sessionstructuretest.cpp @@ -1,8 +1,8 @@ /* SessionStructure(Test) - verifying basic Session/EDL structure - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/mobject/session/testclip.cpp b/tests/components/proc/mobject/session/testclip.cpp index d79124020..ce659e708 100644 --- a/tests/components/proc/mobject/session/testclip.cpp +++ b/tests/components/proc/mobject/session/testclip.cpp @@ -1,8 +1,8 @@ /* TestClip - test clip (stub) for checking EDL/Session functionality - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/mobject/session/testclip.hpp b/tests/components/proc/mobject/session/testclip.hpp index 77209e84d..63ac8475a 100644 --- a/tests/components/proc/mobject/session/testclip.hpp +++ b/tests/components/proc/mobject/session/testclip.hpp @@ -1,8 +1,8 @@ /* TESTCLIP.hpp - test clip (stub) for checking EDL/Session functionality - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/components/proc/mobject/session/testsession1.hpp b/tests/components/proc/mobject/session/testsession1.hpp index b749d084d..d9c422f2f 100644 --- a/tests/components/proc/mobject/session/testsession1.hpp +++ b/tests/components/proc/mobject/session/testsession1.hpp @@ -1,8 +1,8 @@ /* TESTSESSION1.hpp - complete session configuration used for various tests - Copyright (C) CinelerraCV - 2007, Hermann Vosseler + Copyright (C) Lumiera.org + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/error/errortest.c b/tests/error/errortest.c index 96d49b851..0fd95b600 100644 --- a/tests/error/errortest.c +++ b/tests/error/errortest.c @@ -1,8 +1,8 @@ /* errortest.c - test error handling - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/library/test-llist.c b/tests/library/test-llist.c index 66cc50ade..bf6c5aed5 100644 --- a/tests/library/test-llist.c +++ b/tests/library/test-llist.c @@ -1,8 +1,8 @@ /* test-llist.c - test the linked lis lib - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/library/test-references.c b/tests/library/test-references.c index f00de97b2..f56c7c9d7 100644 --- a/tests/library/test-references.c +++ b/tests/library/test-references.c @@ -1,8 +1,8 @@ /* test-references.c - test strong and weak references - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/locking/condition.c b/tests/locking/condition.c index 72b56285c..6483ac0a9 100644 --- a/tests/locking/condition.c +++ b/tests/locking/condition.c @@ -1,8 +1,8 @@ /* test condition functions - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/locking/mutex.c b/tests/locking/mutex.c index 3e9b58d8e..ed6a050eb 100644 --- a/tests/locking/mutex.c +++ b/tests/locking/mutex.c @@ -1,8 +1,8 @@ /* test mutex functions - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/locking/test-condition.c b/tests/locking/test-condition.c index 6f0f32365..cc8e5ae14 100644 --- a/tests/locking/test-condition.c +++ b/tests/locking/test-condition.c @@ -1,8 +1,8 @@ /* test-locking.c - test locking functions - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/locking/test-locking.c b/tests/locking/test-locking.c index 78bc99779..46455764b 100644 --- a/tests/locking/test-locking.c +++ b/tests/locking/test-locking.c @@ -1,8 +1,8 @@ /* test-locking.c - test locking functions - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/tests/plugin/Makefile.am b/tests/plugin/Makefile.am index fa5d52962..2cd33997e 100644 --- a/tests/plugin/Makefile.am +++ b/tests/plugin/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) CinelerraCV +# Copyright (C) Lumiera.org # 2007, Christian Thaeter # # This program is free software; you can redistribute it and/or diff --git a/tests/test.sh b/tests/test.sh index 1e4256eb2..b692b3959 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright (C) CinelerraCV +# Copyright (C) Lumiera.org # 2007, Christian Thaeter # Hermann Vosseler # diff --git a/tests/time/test-time.c b/tests/time/test-time.c index 519a65781..01dd107ef 100644 --- a/tests/time/test-time.c +++ b/tests/time/test-time.c @@ -1,8 +1,8 @@ /* test-time.c - test time and framerate functions - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/uml/cinelerra3/DIR_INFO b/uml/cinelerra3/DIR_INFO deleted file mode 100644 index c9bfb0e73..000000000 --- a/uml/cinelerra3/DIR_INFO +++ /dev/null @@ -1 +0,0 @@ -cinelerra3 UML model diff --git a/uml/cinelerra3/128005 b/uml/lumiera/128005 similarity index 98% rename from uml/cinelerra3/128005 rename to uml/lumiera/128005 index e16107985..b6932706b 100644 --- a/uml/cinelerra3/128005 +++ b/uml/lumiera/128005 @@ -32,7 +32,7 @@ Not a real code package, rather a container for design drafts, specifications, d //component diagram settings package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default draw_component_as_icon default show_component_req_prov default show_component_rea default - comment "The various Components comprising the Cinelerra3 Video editing Application" + comment "The various Components comprising the Lumiera Video editing Application" componentdiagram 128005 "Overview" package_name_in_tab default show_context default auto_label_position default draw_all_relations no shadow default draw_component_as_icon default show_component_req_prov default show_component_rea default diff --git a/uml/cinelerra3/128005.diagram b/uml/lumiera/128005.diagram similarity index 100% rename from uml/cinelerra3/128005.diagram rename to uml/lumiera/128005.diagram diff --git a/uml/cinelerra3/128133 b/uml/lumiera/128133 similarity index 99% rename from uml/cinelerra3/128133 rename to uml/lumiera/128133 index fe9ce6164..badc25cfd 100644 --- a/uml/cinelerra3/128133 +++ b/uml/lumiera/128133 @@ -116,7 +116,7 @@ ${members}}; " java_decl "" idl_decl "" - comment "origin or authorship id. Can be a project abbreviation, a package id or just the authors nickname or UID. This allows for the compnent name to be more generic (e.g. \"blur\"). Default for all assets provided by the core cinelerra-3 codebase is \"cin3\"." + comment "origin or authorship id. Can be a project abbreviation, a package id or just the authors nickname or UID. This allows for the compnent name to be more generic (e.g. \"blur\"). Default for all assets provided by the core Lumiera codebase is \"lumi\"." end attribute 130949 "version" diff --git a/uml/cinelerra3/128133.diagram b/uml/lumiera/128133.diagram similarity index 100% rename from uml/cinelerra3/128133.diagram rename to uml/lumiera/128133.diagram diff --git a/uml/cinelerra3/128138 b/uml/lumiera/128138 similarity index 100% rename from uml/cinelerra3/128138 rename to uml/lumiera/128138 diff --git a/uml/cinelerra3/128181.diagram b/uml/lumiera/128181.diagram similarity index 100% rename from uml/cinelerra3/128181.diagram rename to uml/lumiera/128181.diagram diff --git a/uml/cinelerra3/128261 b/uml/lumiera/128261 similarity index 100% rename from uml/cinelerra3/128261 rename to uml/lumiera/128261 diff --git a/uml/cinelerra3/128261.diagram b/uml/lumiera/128261.diagram similarity index 100% rename from uml/cinelerra3/128261.diagram rename to uml/lumiera/128261.diagram diff --git a/uml/cinelerra3/128389 b/uml/lumiera/128389 similarity index 100% rename from uml/cinelerra3/128389 rename to uml/lumiera/128389 diff --git a/uml/cinelerra3/128389.diagram b/uml/lumiera/128389.diagram similarity index 100% rename from uml/cinelerra3/128389.diagram rename to uml/lumiera/128389.diagram diff --git a/uml/cinelerra3/128517 b/uml/lumiera/128517 similarity index 98% rename from uml/cinelerra3/128517 rename to uml/lumiera/128517 index 6a6b8ee00..14fa5def7 100644 --- a/uml/cinelerra3/128517 +++ b/uml/lumiera/128517 @@ -45,7 +45,7 @@ format 40 classdiagram 130181 "Hierarchy" draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - comment "Cinelerra Exception hierarchy" + comment "Lumiera Exception hierarchy" size A4 end @@ -406,7 +406,7 @@ ${class}::${name} ${(}${)}${volatile} ${throw} comment "perform initialization on first access. A call is placed in static initialization code -included in cinelerra.h; thus it will happen +included in lumiera.h; thus it will happen ubiquitous very early." end @@ -466,7 +466,7 @@ ${inlines} idl_decl "" explicit_switch_type "" - comment "We can basically reuse the Thread class design from cinelerra2, Thread becomes a baseclass for all Threads " + comment "We can basically reuse the Thread class design from Cinelerra2, Thread becomes a baseclass for all Threads " end class 128266 "Condition" @@ -479,7 +479,7 @@ ${inlines} idl_decl "" explicit_switch_type "" - comment "I provided a reworked Condition class in my cinelerra2 repository" + comment "I provided a reworked Condition class in my Cinelerra2 repository" class 128522 "Lock" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { @@ -503,7 +503,7 @@ ${inlines} idl_decl "" explicit_switch_type "" - comment "I provided a reworked Mutex class in my cinelerra2 repository" + comment "I provided a reworked Mutex class in my Cinelerra2 repository" class 128650 "Lock" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { diff --git a/uml/cinelerra3/128517.diagram b/uml/lumiera/128517.diagram similarity index 100% rename from uml/cinelerra3/128517.diagram rename to uml/lumiera/128517.diagram diff --git a/uml/cinelerra3/128645 b/uml/lumiera/128645 similarity index 98% rename from uml/cinelerra3/128645 rename to uml/lumiera/128645 index 523b89109..e1de4d311 100644 --- a/uml/cinelerra3/128645 +++ b/uml/lumiera/128645 @@ -32,14 +32,14 @@ format 40 package_name_in_tab default show_context default write_horizontally default auto_label_position default draw_all_relations default shadow default draw_component_as_icon default show_component_req_prov default show_component_rea default component_color lightred - comment "defines and lists how the Cinelerra executable has to be created" + comment "defines and lists how the Lumiera executable has to be created" deploymentdiagram 129797 "Source Overview" package_name_in_tab default show_context default write_horizontally default auto_label_position default draw_all_relations default shadow default draw_component_as_icon default show_component_req_prov default show_component_rea default size A4 end - artifact 128005 "Cinelerra3" + artifact 128005 "Lumiera" stereotype "executable" associated_artifacts artifact_ref 133509 // vrender diff --git a/uml/cinelerra3/128645.diagram b/uml/lumiera/128645.diagram similarity index 100% rename from uml/cinelerra3/128645.diagram rename to uml/lumiera/128645.diagram diff --git a/uml/cinelerra3/128773 b/uml/lumiera/128773 similarity index 100% rename from uml/cinelerra3/128773 rename to uml/lumiera/128773 diff --git a/uml/cinelerra3/128773.diagram b/uml/lumiera/128773.diagram similarity index 100% rename from uml/cinelerra3/128773.diagram rename to uml/lumiera/128773.diagram diff --git a/uml/cinelerra3/128901 b/uml/lumiera/128901 similarity index 100% rename from uml/cinelerra3/128901 rename to uml/lumiera/128901 diff --git a/uml/cinelerra3/128901.diagram b/uml/lumiera/128901.diagram similarity index 100% rename from uml/cinelerra3/128901.diagram rename to uml/lumiera/128901.diagram diff --git a/uml/cinelerra3/129029 b/uml/lumiera/129029 similarity index 100% rename from uml/cinelerra3/129029 rename to uml/lumiera/129029 diff --git a/uml/cinelerra3/129029.diagram b/uml/lumiera/129029.diagram similarity index 100% rename from uml/cinelerra3/129029.diagram rename to uml/lumiera/129029.diagram diff --git a/uml/cinelerra3/129157 b/uml/lumiera/129157 similarity index 100% rename from uml/cinelerra3/129157 rename to uml/lumiera/129157 diff --git a/uml/cinelerra3/129157.diagram b/uml/lumiera/129157.diagram similarity index 100% rename from uml/cinelerra3/129157.diagram rename to uml/lumiera/129157.diagram diff --git a/uml/cinelerra3/129285 b/uml/lumiera/129285 similarity index 100% rename from uml/cinelerra3/129285 rename to uml/lumiera/129285 diff --git a/uml/cinelerra3/129285.diagram b/uml/lumiera/129285.diagram similarity index 100% rename from uml/cinelerra3/129285.diagram rename to uml/lumiera/129285.diagram diff --git a/uml/cinelerra3/129413 b/uml/lumiera/129413 similarity index 98% rename from uml/cinelerra3/129413 rename to uml/lumiera/129413 index efe41073b..a4a3e7283 100644 --- a/uml/cinelerra3/129413 +++ b/uml/lumiera/129413 @@ -29,7 +29,7 @@ format 40 stereotype "src" cpp_h_dir "common" cpp_src_dir "common" - cpp_namespace "cinelerra" + cpp_namespace "lumiera" associated_diagram deploymentdiagram_ref 129797 // Source Overview comment "sourcecode package @@ -121,7 +121,7 @@ ${namespace_end}" class_ref 136069 // Invalid class_ref 136197 // External end - comment "Cinelerra Exception Interface" + comment "Lumiera Exception Interface" end artifact 135173 "appconfig" diff --git a/uml/cinelerra3/129413.diagram b/uml/lumiera/129413.diagram similarity index 100% rename from uml/cinelerra3/129413.diagram rename to uml/lumiera/129413.diagram diff --git a/uml/cinelerra3/129541 b/uml/lumiera/129541 similarity index 100% rename from uml/cinelerra3/129541 rename to uml/lumiera/129541 diff --git a/uml/cinelerra3/129541.diagram b/uml/lumiera/129541.diagram similarity index 100% rename from uml/cinelerra3/129541.diagram rename to uml/lumiera/129541.diagram diff --git a/uml/cinelerra3/129669 b/uml/lumiera/129669 similarity index 100% rename from uml/cinelerra3/129669 rename to uml/lumiera/129669 diff --git a/uml/cinelerra3/129669.diagram b/uml/lumiera/129669.diagram similarity index 100% rename from uml/cinelerra3/129669.diagram rename to uml/lumiera/129669.diagram diff --git a/uml/cinelerra3/129797 b/uml/lumiera/129797 similarity index 100% rename from uml/cinelerra3/129797 rename to uml/lumiera/129797 diff --git a/uml/cinelerra3/129797.diagram b/uml/lumiera/129797.diagram similarity index 96% rename from uml/cinelerra3/129797.diagram rename to uml/lumiera/129797.diagram index 7c7216678..75bed9aaf 100644 --- a/uml/cinelerra3/129797.diagram +++ b/uml/lumiera/129797.diagram @@ -1,6 +1,6 @@ format 40 -artifactcanvas 128005 artifact_ref 128005 // Cinelerra3 +artifactcanvas 128005 artifact_ref 128005 // Lumiera color midred xyz 47 45 2000 packagecanvas 128133 diff --git a/uml/cinelerra3/129925 b/uml/lumiera/129925 similarity index 100% rename from uml/cinelerra3/129925 rename to uml/lumiera/129925 diff --git a/uml/cinelerra3/129925.diagram b/uml/lumiera/129925.diagram similarity index 100% rename from uml/cinelerra3/129925.diagram rename to uml/lumiera/129925.diagram diff --git a/uml/cinelerra3/130053 b/uml/lumiera/130053 similarity index 100% rename from uml/cinelerra3/130053 rename to uml/lumiera/130053 diff --git a/uml/cinelerra3/130053.diagram b/uml/lumiera/130053.diagram similarity index 100% rename from uml/cinelerra3/130053.diagram rename to uml/lumiera/130053.diagram diff --git a/uml/cinelerra3/130181 b/uml/lumiera/130181 similarity index 100% rename from uml/cinelerra3/130181 rename to uml/lumiera/130181 diff --git a/uml/cinelerra3/130181.diagram b/uml/lumiera/130181.diagram similarity index 100% rename from uml/cinelerra3/130181.diagram rename to uml/lumiera/130181.diagram diff --git a/uml/cinelerra3/130309 b/uml/lumiera/130309 similarity index 100% rename from uml/cinelerra3/130309 rename to uml/lumiera/130309 diff --git a/uml/cinelerra3/130309.diagram b/uml/lumiera/130309.diagram similarity index 100% rename from uml/cinelerra3/130309.diagram rename to uml/lumiera/130309.diagram diff --git a/uml/cinelerra3/130437 b/uml/lumiera/130437 similarity index 100% rename from uml/cinelerra3/130437 rename to uml/lumiera/130437 diff --git a/uml/cinelerra3/130437.diagram b/uml/lumiera/130437.diagram similarity index 100% rename from uml/cinelerra3/130437.diagram rename to uml/lumiera/130437.diagram diff --git a/uml/cinelerra3/130565 b/uml/lumiera/130565 similarity index 100% rename from uml/cinelerra3/130565 rename to uml/lumiera/130565 diff --git a/uml/cinelerra3/130693 b/uml/lumiera/130693 similarity index 100% rename from uml/cinelerra3/130693 rename to uml/lumiera/130693 diff --git a/uml/cinelerra3/130693.diagram b/uml/lumiera/130693.diagram similarity index 100% rename from uml/cinelerra3/130693.diagram rename to uml/lumiera/130693.diagram diff --git a/uml/cinelerra3/130821 b/uml/lumiera/130821 similarity index 98% rename from uml/cinelerra3/130821 rename to uml/lumiera/130821 index 2823b3193..f7ca78b69 100644 --- a/uml/cinelerra3/130821 +++ b/uml/lumiera/130821 @@ -28,6 +28,6 @@ format 40 cpp_h_dir "common" cpp_src_dir "common" - cpp_namespace "cinelerra::error" + cpp_namespace "lumiera::error" comment "Namespace for Exception Kinds" end diff --git a/uml/cinelerra3/130821.diagram b/uml/lumiera/130821.diagram similarity index 100% rename from uml/cinelerra3/130821.diagram rename to uml/lumiera/130821.diagram diff --git a/uml/cinelerra3/130949 b/uml/lumiera/130949 similarity index 98% rename from uml/cinelerra3/130949 rename to uml/lumiera/130949 index 16a88747b..cd38b33c7 100644 --- a/uml/cinelerra3/130949 +++ b/uml/lumiera/130949 @@ -28,6 +28,6 @@ format 40 cpp_h_dir "common" cpp_src_dir "common" - cpp_namespace "cinelerra::visitor" + cpp_namespace "lumiera::visitor" comment "sub-namespace for visitor library implementation" end diff --git a/uml/cinelerra3/130949.diagram b/uml/lumiera/130949.diagram similarity index 100% rename from uml/cinelerra3/130949.diagram rename to uml/lumiera/130949.diagram diff --git a/uml/cinelerra3/131077.diagram b/uml/lumiera/131077.diagram similarity index 100% rename from uml/cinelerra3/131077.diagram rename to uml/lumiera/131077.diagram diff --git a/uml/cinelerra3/131205.diagram b/uml/lumiera/131205.diagram similarity index 100% rename from uml/cinelerra3/131205.diagram rename to uml/lumiera/131205.diagram diff --git a/uml/cinelerra3/131333.diagram b/uml/lumiera/131333.diagram similarity index 100% rename from uml/cinelerra3/131333.diagram rename to uml/lumiera/131333.diagram diff --git a/uml/cinelerra3/134021.bodies b/uml/lumiera/134021.bodies similarity index 100% rename from uml/cinelerra3/134021.bodies rename to uml/lumiera/134021.bodies diff --git a/uml/cinelerra3/5.session b/uml/lumiera/5.session similarity index 89% rename from uml/cinelerra3/5.session rename to uml/lumiera/5.session index af98eb2ed..2d78dfa96 100644 --- a/uml/cinelerra3/5.session +++ b/uml/lumiera/5.session @@ -11,8 +11,10 @@ diagrams end show_stereotypes selected - package_ref 129 // cinelerra3 +package_ref 129 // lumiera open + componentview_ref 128133 // interfaces + deploymentview_ref 128133 // EXE Deployment deploymentview_ref 128645 // gen class_ref 137477 // Unknown class_ref 137605 // Preview diff --git a/uml/lumiera/DIR_INFO b/uml/lumiera/DIR_INFO new file mode 100644 index 000000000..090f405b4 --- /dev/null +++ b/uml/lumiera/DIR_INFO @@ -0,0 +1 @@ +Lumiera UML model diff --git a/uml/cinelerra3/cpp_includes b/uml/lumiera/cpp_includes similarity index 100% rename from uml/cinelerra3/cpp_includes rename to uml/lumiera/cpp_includes diff --git a/uml/cinelerra3/generation_settings b/uml/lumiera/generation_settings similarity index 100% rename from uml/cinelerra3/generation_settings rename to uml/lumiera/generation_settings diff --git a/uml/cinelerra3/idl_includes b/uml/lumiera/idl_includes similarity index 100% rename from uml/cinelerra3/idl_includes rename to uml/lumiera/idl_includes diff --git a/uml/cinelerra3/java_imports b/uml/lumiera/java_imports similarity index 100% rename from uml/cinelerra3/java_imports rename to uml/lumiera/java_imports diff --git a/uml/cinelerra3/cinelerra3.prj b/uml/lumiera/lumiera.prj similarity index 97% rename from uml/cinelerra3/cinelerra3.prj rename to uml/lumiera/lumiera.prj index 9873f26df..555a8d3ba 100644 --- a/uml/cinelerra3/cinelerra3.prj +++ b/uml/lumiera/lumiera.prj @@ -1,5 +1,5 @@ format 40 -"cinelerra3" +"lumiera" revision 42 modified_by 5 "hiv" cpp_root_dir "../../src/" @@ -53,8 +53,8 @@ format 40 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. " key "CopyrightClaim" value " - Copyright (C) CinelerraCV - 2007, Christian Thaeter + Copyright (C) Lumiera.org + 2008, Christian Thaeter " key "html dir" value "/mnt/Lager/heim/devel/cin3/doc/devel/uml/" diff --git a/uml/cinelerra3/stereotypes b/uml/lumiera/stereotypes similarity index 100% rename from uml/cinelerra3/stereotypes rename to uml/lumiera/stereotypes diff --git a/uml/cinelerra3/tools b/uml/lumiera/tools similarity index 100% rename from uml/cinelerra3/tools rename to uml/lumiera/tools diff --git a/wiki/backend.html b/wiki/backend.html index 6477e47ba..3cdee6a96 100644 --- a/wiki/backend.html +++ b/wiki/backend.html @@ -766,15 +766,15 @@ Error: #f88
    This just starts as braindump, I will refine it soon:
    -* handle all files cinelerra uses at runtime (media, edl, temp data)
    -* manage filehandles, cinelerra might use more more files than available filehandles
    +* handle all files Lumiera uses at runtime (media, edl, temp data)
    +* manage filehandles, Lumiera might use more more files than available filehandles
     * manage temporary data
     * do caching
     * io will be blocked where the backend tells the core where it can expect the data (not read()/write() like)
     * kind-of garbage collector
     * do prefetching
     * no/low latency for the core the prefetcher and other things ensure that data is available in time
    -* translate any input into a format which the cinelerra core understands (demux, decode)
    +* translate any input into a format which the Lumiera core understands (demux, decode)
     * same for encoding to output formats
     * offer a plugin API for encoders/decoders
     * maybe network backend for serving data to distributed render nodes
    @@ -1217,7 +1217,7 @@ config.formatters.push( {
     //}}}
    -
    ''[[Cinelerra3|index.html]]''
    +
    ''[[Lumiera|index.html]]''
     DataBackend
     [[Overview]]
     <<fullscreen>>
    @@ -1255,7 +1255,7 @@ When to Cache and when not to cache, aka instant [[Frame]] reuse
     
    -
    Whenever cinelerra needs to access data this is done through the DataBackend described here. 
    +
    Whenever Lumiera needs to access data this is done through the DataBackend described here. 
     
     There are two main kinds how data is handled:
     * Project Description and EDL's are handled in a InMemoryDatabase which uses a [[Serializer]] for storing and logging modifications.
    diff --git a/wiki/index.html b/wiki/index.html
    index 34493fc01..f2f7f8139 100755
    --- a/wiki/index.html
    +++ b/wiki/index.html
    @@ -42,9 +42,9 @@ DAMAGE.
     
     
     
    -
    Cinelerra TiddlyWiki is loading ...

    Requires Javascript.
    +
    Lumiera TiddlyWiki is loading ...

    Requires Javascript.
    - Cinelerra3 - Distributed Developer Wiki + Lumiera - Distributed Developer Wiki
    My TiddlyWiki is loading ...

    Requires Javascript.
    + + Compatibility - Dependencies and Style + + + + + + + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Background: #fff
    +Foreground: #000
    +PrimaryPale: #8cf
    +PrimaryLight: #18f
    +PrimaryMid: #04b
    +PrimaryDark: #014
    +SecondaryPale: #ffc
    +SecondaryLight: #fe8
    +SecondaryMid: #db4
    +SecondaryDark: #841
    +TertiaryPale: #eee
    +TertiaryLight: #ccc
    +TertiaryMid: #999
    +TertiaryDark: #666
    +Error: #f88
    +
    +
    +
    /*{{{*/
    +body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
    +
    +a {color:[[ColorPalette::PrimaryMid]];}
    +a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
    +a img {border:0;}
    +
    +h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
    +h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
    +h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}
    +
    +.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
    +.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
    +.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}
    +
    +.header {background:[[ColorPalette::PrimaryMid]];}
    +.headerShadow {color:[[ColorPalette::Foreground]];}
    +.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
    +.headerForeground {color:[[ColorPalette::Background]];}
    +.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}
    +
    +.tabSelected{color:[[ColorPalette::PrimaryDark]];
    +	background:[[ColorPalette::TertiaryPale]];
    +	border-left:1px solid [[ColorPalette::TertiaryLight]];
    +	border-top:1px solid [[ColorPalette::TertiaryLight]];
    +	border-right:1px solid [[ColorPalette::TertiaryLight]];
    +}
    +.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
    +.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
    +.tabContents .button {border:0;}
    +
    +#sidebar {}
    +#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
    +#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
    +#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
    +#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
    +#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}
    +
    +.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
    +.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
    +.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
    +.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
    +	border:1px solid [[ColorPalette::PrimaryMid]];}
    +.wizardStep.wizardStepDone {background::[[ColorPalette::TertiaryLight]];}
    +.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
    +.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
    +.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
    +	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
    +.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
    +.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
    +	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}
    +
    +#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
    +#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}
    +
    +.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}
    +
    +.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
    +.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
    +.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
    +.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
    +.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
    +.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
    +.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
    +.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}
    +
    +.tiddler .defaultCommand {font-weight:bold;}
    +
    +.shadow .title {color:[[ColorPalette::TertiaryDark]];}
    +
    +.title {color:[[ColorPalette::SecondaryDark]];}
    +.subtitle {color:[[ColorPalette::TertiaryDark]];}
    +
    +.toolbar {color:[[ColorPalette::PrimaryMid]];}
    +.toolbar a {color:[[ColorPalette::TertiaryLight]];}
    +.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
    +.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}
    +
    +.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
    +.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
    +.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
    +.tagging .button, .tagged .button {border:none;}
    +
    +.footer {color:[[ColorPalette::TertiaryLight]];}
    +.selected .footer {color:[[ColorPalette::TertiaryMid]];}
    +
    +.sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
    +.sparktick {background:[[ColorPalette::PrimaryDark]];}
    +
    +.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
    +.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
    +.lowlight {background:[[ColorPalette::TertiaryLight]];}
    +
    +.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}
    +
    +.imageLink, #displayArea .imageLink {background:transparent;}
    +
    +.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}
    +
    +.viewer .listTitle {list-style-type:none; margin-left:-2em;}
    +.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
    +.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}
    +
    +.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
    +.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
    +.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}
    +
    +.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
    +.viewer code {color:[[ColorPalette::SecondaryDark]];}
    +.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}
    +
    +.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}
    +
    +.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
    +.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
    +.editorFooter {color:[[ColorPalette::TertiaryMid]];}
    +
    +#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
    +#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
    +#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
    +#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
    +#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
    +#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
    +#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
    +.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
    +.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
    +#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:'alpha(opacity:60)';}
    +/*}}}*/
    +
    +
    +
    /*{{{*/
    +* html .tiddler {height:1%;}
    +
    +body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}
    +
    +h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
    +h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
    +h4,h5,h6 {margin-top:1em;}
    +h1 {font-size:1.35em;}
    +h2 {font-size:1.25em;}
    +h3 {font-size:1.1em;}
    +h4 {font-size:1em;}
    +h5 {font-size:.9em;}
    +
    +hr {height:1px;}
    +
    +a {text-decoration:none;}
    +
    +dt {font-weight:bold;}
    +
    +ol {list-style-type:decimal;}
    +ol ol {list-style-type:lower-alpha;}
    +ol ol ol {list-style-type:lower-roman;}
    +ol ol ol ol {list-style-type:decimal;}
    +ol ol ol ol ol {list-style-type:lower-alpha;}
    +ol ol ol ol ol ol {list-style-type:lower-roman;}
    +ol ol ol ol ol ol ol {list-style-type:decimal;}
    +
    +.txtOptionInput {width:11em;}
    +
    +#contentWrapper .chkOptionInput {border:0;}
    +
    +.externalLink {text-decoration:underline;}
    +
    +.indent {margin-left:3em;}
    +.outdent {margin-left:3em; text-indent:-3em;}
    +code.escaped {white-space:nowrap;}
    +
    +.tiddlyLinkExisting {font-weight:bold;}
    +.tiddlyLinkNonExisting {font-style:italic;}
    +
    +/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
    +a.tiddlyLinkNonExisting.shadow {font-weight:bold;}
    +
    +#mainMenu .tiddlyLinkExisting,
    +	#mainMenu .tiddlyLinkNonExisting,
    +	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
    +#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}
    +
    +.header {position:relative;}
    +.header a:hover {background:transparent;}
    +.headerShadow {position:relative; padding:4.5em 0em 1em 1em; left:-1px; top:-1px;}
    +.headerForeground {position:absolute; padding:4.5em 0em 1em 1em; left:0px; top:0px;}
    +
    +.siteTitle {font-size:3em;}
    +.siteSubtitle {font-size:1.2em;}
    +
    +#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}
    +
    +#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
    +#sidebarOptions {padding-top:0.3em;}
    +#sidebarOptions a {margin:0em 0.2em; padding:0.2em 0.3em; display:block;}
    +#sidebarOptions input {margin:0.4em 0.5em;}
    +#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
    +#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
    +#sidebarOptions .sliderPanel input {margin:0 0 .3em 0;}
    +#sidebarTabs .tabContents {width:15em; overflow:hidden;}
    +
    +.wizard {padding:0.1em 1em 0em 2em;}
    +.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
    +.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
    +.wizardStep {padding:1em 1em 1em 1em;}
    +.wizard .button {margin:0.5em 0em 0em 0em; font-size:1.2em;}
    +.wizardFooter {padding:0.8em 0.4em 0.8em 0em;}
    +.wizardFooter .status {padding:0em 0.4em 0em 0.4em; margin-left:1em;}
    +.wizard .button {padding:0.1em 0.2em 0.1em 0.2em;}
    +
    +#messageArea {position:fixed; top:2em; right:0em; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
    +.messageToolbar {display:block; text-align:right; padding:0.2em 0.2em 0.2em 0.2em;}
    +#messageArea a {text-decoration:underline;}
    +
    +.tiddlerPopupButton {padding:0.2em 0.2em 0.2em 0.2em;}
    +.popupTiddler {position: absolute; z-index:300; padding:1em 1em 1em 1em; margin:0;}
    +
    +.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
    +.popup .popupMessage {padding:0.4em;}
    +.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0em;}
    +.popup li.disabled {padding:0.4em;}
    +.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
    +.listBreak {font-size:1px; line-height:1px;}
    +.listBreak div {margin:2px 0;}
    +
    +.tabset {padding:1em 0em 0em 0.5em;}
    +.tab {margin:0em 0em 0em 0.25em; padding:2px;}
    +.tabContents {padding:0.5em;}
    +.tabContents ul, .tabContents ol {margin:0; padding:0;}
    +.txtMainTab .tabContents li {list-style:none;}
    +.tabContents li.listLink { margin-left:.75em;}
    +
    +#contentWrapper {display:block;}
    +#splashScreen {display:none;}
    +
    +#displayArea {margin:1em 17em 0em 14em;}
    +
    +.toolbar {text-align:right; font-size:.9em;}
    +
    +.tiddler {padding:1em 1em 0em 1em;}
    +
    +.missing .viewer,.missing .title {font-style:italic;}
    +
    +.title {font-size:1.6em; font-weight:bold;}
    +
    +.missing .subtitle {display:none;}
    +.subtitle {font-size:1.1em;}
    +
    +.tiddler .button {padding:0.2em 0.4em;}
    +
    +.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
    +.isTag .tagging {display:block;}
    +.tagged {margin:0.5em; float:right;}
    +.tagging, .tagged {font-size:0.9em; padding:0.25em;}
    +.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
    +.tagClear {clear:both;}
    +
    +.footer {font-size:.9em;}
    +.footer li {display:inline;}
    +
    +.annotation {padding:0.5em; margin:0.5em;}
    +
    +* html .viewer pre {width:99%; padding:0 0 1em 0;}
    +.viewer {line-height:1.4em; padding-top:0.5em;}
    +.viewer .button {margin:0em 0.25em; padding:0em 0.25em;}
    +.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
    +.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}
    +
    +.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
    +.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
    +table.listView {font-size:0.85em; margin:0.8em 1.0em;}
    +table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}
    +
    +.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
    +.viewer code {font-size:1.2em; line-height:1.4em;}
    +
    +.editor {font-size:1.1em;}
    +.editor input, .editor textarea {display:block; width:100%; font:inherit;}
    +.editorFooter {padding:0.25em 0em; font-size:.9em;}
    +.editorFooter .button {padding-top:0px; padding-bottom:0px;}
    +
    +.fieldsetFix {border:0; padding:0; margin:1px 0px 1px 0px;}
    +
    +.sparkline {line-height:1em;}
    +.sparktick {outline:0;}
    +
    +.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
    +.zoomer div {padding:1em;}
    +
    +* html #backstage {width:99%;}
    +* html #backstageArea {width:99%;}
    +#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em 0.3em 0.5em;}
    +#backstageToolbar {position:relative;}
    +#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em 0.3em 0.5em;}
    +#backstageButton {display:none; position:absolute; z-index:175; top:0em; right:0em;}
    +#backstageButton a {padding:0.1em 0.4em 0.1em 0.4em; margin:0.1em 0.1em 0.1em 0.1em;}
    +#backstage {position:relative; width:100%; z-index:50;}
    +#backstagePanel {display:none; z-index:100; position:absolute; margin:0em 3em 0em 3em; padding:1em 1em 1em 1em;}
    +.backstagePanelFooter {padding-top:0.2em; float:right;}
    +.backstagePanelFooter a {padding:0.2em 0.4em 0.2em 0.4em;}
    +#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}
    +
    +.whenBackstage {display:none;}
    +.backstageVisible .whenBackstage {display:block;}
    +/*}}}*/
    +
    +
    +
    /***
    +StyleSheet for use when a translation requires any css style changes.
    +This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which use a logographic writing system and need larger font sizes.
    +***/
    +
    +/*{{{*/
    +body {font-size:0.8em;}
    +
    +#sidebarOptions {font-size:1.05em;}
    +#sidebarOptions a {font-style:normal;}
    +#sidebarOptions .sliderPanel {font-size:0.95em;}
    +
    +.subtitle {font-size:0.8em;}
    +
    +.viewer table.listView {font-size:0.95em;}
    +
    +.htmlarea .toolbarHA table {border:1px solid ButtonFace; margin:0em 0em;}
    +/*}}}*/
    +
    +
    +
    /*{{{*/
    +@media print {
    +#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton {display: none ! important;}
    +#displayArea {margin: 1em 1em 0em 1em;}
    +/* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
    +noscript {display:none;}
    +}
    +/*}}}*/
    +
    +
    +
    <!--{{{-->
    +<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
    +<div class='headerShadow'>
    +<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
    +<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
    +</div>
    +<div class='headerForeground'>
    +<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
    +<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
    +</div>
    +</div>
    +<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
    +<div id='sidebar'>
    +<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
    +<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
    +</div>
    +<div id='displayArea'>
    +<div id='messageArea'></div>
    +<div id='tiddlerDisplay'></div>
    +</div>
    +<!--}}}-->
    +
    +
    +
    <!--{{{-->
    +<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></div>
    +<div class='title' macro='view title'></div>
    +<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
    +<div class='tagging' macro='tagging'></div>
    +<div class='tagged' macro='tags'></div>
    +<div class='viewer' macro='view text wikified'></div>
    +<div class='tagClear'></div>
    +<!--}}}-->
    +
    +
    +
    <!--{{{-->
    +<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler'></div>
    +<div class='title' macro='view title'></div>
    +<div class='editor' macro='edit title'></div>
    +<div macro='annotations'></div>
    +<div class='editor' macro='edit text'></div>
    +<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>
    +<!--}}}-->
    +
    +
    +
    To get started with this blank TiddlyWiki, you'll need to modify the following tiddlers:
    +* SiteTitle & SiteSubtitle: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
    +* MainMenu: The menu (usually on the left)
    +* DefaultTiddlers: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
    +You'll also need to enter your username for signing your edits: <<option txtUserName>>
    +
    +
    +
    These InterfaceOptions for customising TiddlyWiki are saved in your browser
    +
    +Your username for signing your edits. Write it as a WikiWord (eg JoeBloggs)
    +
    +<<option txtUserName>>
    +<<option chkSaveBackups>> SaveBackups
    +<<option chkAutoSave>> AutoSave
    +<<option chkRegExpSearch>> RegExpSearch
    +<<option chkCaseSensitiveSearch>> CaseSensitiveSearch
    +<<option chkAnimate>> EnableAnimations
    +
    +----
    +Also see AdvancedOptions
    +
    +
    + +
    +
    +
    A task has a description, an estimate of how long it will take, and a record of how much time you have spent on it so far.  Here's an example, which shows a task estimated at 3 hours, with 1 hour spent on it, and ''2'' hours remaining:
    +<<<
    +<<task 3 3 1>> Add a double-click handler to the description cell that opens the editor and selects the text
    +<<<
    +If you hover the mouse over any part of the task -- the bullet, the description, or any of the numeric cells -- a tip will appear explaining it.
    +
    +Try modifying the time spent.  Suppose you've just spent one more hour and want to record it.  Just click on the second yellow cell, and enter "+1" (sans the quote marks, of course) in the popup window.  Watch the time remaining go down to 1 hour.
    +
    +In reality, I originally estimated this task at a half-hour, but it ended up taking 3.5 hours.  The macro also tracks your original estimate, if it is different from the current estimate, in a fourth cell like this:
    +<<<
    +<<task 0.5 2 1>> Add a double-click handler to the description cell that opens the editor and selects the text
    +<<<
    +You can adjust the current estimate in the same way as you adjusted the time spent.  Click on the current estimate cell (the first yellow cell), and change it to 2.5 hours by typing "2.5" or "+.5".
    +
    +You can also adjust the time remaining, which will modify either the estimate (if the time remaining increases) or the time spent (if it decreases).  Click on the time remaining and add an hour by typing "+1".
    +
    +When the time remaining goes to zero, the task is considered complete:
    +<<<
    +<<task 0.5 3.5 3.5>> Add a double-click handler to the description cell that opens the editor and selects the text
    +<<<
    +If you haven't already done so, try double-clicking the description.  Yes, it really does open up the editor and select just the text of the description.
    +
    +----
    +To continue, click the down-arrow and choose another section: <<tag TaskMacroTutorial>>
    +
    +
    +
    A task's description is a single wikified line, so it can contain any formatting that can be specified on one line:
    +<<<
    +<<task 1>> Beef up the time click handlers to allow entry of ''two'' values each: cur&spent, spent&rem. Add click handler to done tasks' spent cells too, to reopen them (like with +0, 1).
    +<<task 0.5>> Put tasksum on the ViewTemplate.
    +<<<
    +You can specify just the description of a task, and leave it unestimated.  Click the question mark to enter the estimate:
    +<<<
    +<<task>> Beef up the time click handlers to allow entry of ''two'' values each: cur&spent, spent&rem. Add click handler to done tasks' spent cells too, to reopen them (like with +0, 1).
    +<<<
    +As this task implies, you can enter two values in the popup when you click on any of the time cells.  Separate them with spaces and/or a comma.  Experiment:
    +<<<
    +<<task 1>> Beef up the time click handlers to allow entry of ''two'' values each: cur&spent, spent&rem. Add click handler to done tasks' spent cells too, to reopen them (like with +0, 1).
    +<<<
    +Finally, if you haven't already figured this out, you can double-click on a task's bullet to mark it complete, with the current estimate entered as the time spent.
    +
    +----
    +To continue, click the down-arrow and choose another section: <<tag TaskMacroTutorial>>
    +
    +
    +
    If you've been paying attention, you've noticed that I haven't discussed the actual adding of calls to the task macro within your tiddlers -- it's all been about modifying tasks that were already there.  That's because adding tasks via the taskadder macro is much easier and more intuitive than adding them by hand.
    +
    +And setting up a taskadder is simplicity itself.  Just add {{{<<taskadder>>}}} to your tiddler.  You will see this:
    +<<<
    +<<taskadder>>
    +<<<
    +Just type a task description into the first field, and your initial estimate for how long it will take into the second field.  Click the "add task" button, or just hit Enter in either of the fields, to add the new task into the tiddler.  Notice that you can just start typing a new task as soon as you're done entering the first one.
    +
    +You can have as many taskadders as you like in any tiddler.  The last one you used will capture the keyboard focus when it is redisplayed, meaning you can type a series of tasks without using the mouse.  Try adding some tasks here and in the above adder:
    +<<<
    +<<taskadder>>
    +<<<
    +Notice that the one you just used takes focus when this tiddler is redisplayed.
    +
    +A taskadder by default adds tasks above itself.  You can make it add them below by adding a {{{below}}} argument to the macro call:
    +<<<
    +<<taskadder below>>
    +<<<
    +
    +----
    +To continue, click the down-arrow and choose another section: <<tag TaskMacroTutorial>>
    +
    +
    +
    In this tutorial, we've been looking mostly at individual tasks.  In real life, though, you'll typically have a series of them, or even several series of them in the same tiddler.  In these cases you want a summary that tells you -- at a minimum -- how much time you still expect to spend on these tasks.
    +
    +To get such a summary, just add {{{<<tasksum start>>}}} before the tasks and {{{<<tasksum end>>}}} after them.  Here's an example:
    +<<<
    +<<tasksum start>>
    +<<task 0.25 0.25 0.25>> Add tooltips to the various cells
    +<<task 1 0.75 0.75>> Figure out how to add auto-updating click handlers to the time cells
    +<<task 2 2 0>> Add simple click handlers to cur, spent, rem: just allow direct setting of values
    +<<task 1 3.5 2.5>> Add a double-click handler to the desc cell that opens the editor and selects the text
    +<<task 1 1 0>> Beef up the time click handlers to allow entry of two values each: cur&spent, spent&rem. Add click handler to done tasks' spent cells too, to reopen them (like with +0, 1).
    +<<task 1 1 0>> Beef up the time click handlers to handle leading + or -
    +<<task 1 1 0>> Add a double-click handler to the status cell that functions like typing 0 into the rem cell
    +<<tasksum end>>
    +<<<
    +If you'd rather have the summary at the top, just add {{{here}}} to the start call, ie {{{<<tasksum start here>>}}}.
    +<<<
    +<<tasksum start here>>
    +<<task 0.25 0.25 0.25>> Add tooltips to the various cells
    +<<task 1 0.75 0.75>> Figure out how to add auto-updating click handlers to the time cells
    +<<task 2 2 0>> Add simple click handlers to cur, spent, rem: just allow direct setting of values
    +<<tasksum end>>
    +<<<
    +You can nest these things if you like, just be sure to match starts and ends:
    +<<<
    +<<tasksum start here>>
    +* Time cell manipulation:<<tasksum start>>
    +<<task 1 0.75 0.75>> Figure out how to add auto-updating click handlers to the time cells
    +<<task 2 2 0>> Add simple click handlers to cur, spent, rem: just allow direct setting of values
    +<<task 1 1 0>> Beef up the time click handlers to allow entry of two values each: cur&spent, spent&rem. Add click handler to done tasks' spent cells too, to reopen them (like with +0, 1).
    +<<task 1 1 0>> Beef up the time click handlers to handle leading + or -
    +<<tasksum end "Cell manipulation:">>
    +<<br>>
    +* Double-click handling:<<tasksum start>>
    +<<task 1 3.5 2.5>> Add a double-click handler to the desc cell that opens the editor and selects the text
    +<<task 1 1 0>> Add a double-click handler to the status cell that functions like typing 0 into the rem cell
    +<<tasksum end "Double-clicks:">>
    +
    +<<tasksum end>>
    +<<<
    +Finally, the simplest way to use tasksum is to add it to your view template.  See TaskSummaryViewTemplate for an example template.  Note that if no tasks are present between the start and end, nothing is displayed.
    +
    +----
    +To continue, click the down-arrow and choose another section: <<tag TaskMacroTutorial>>
    +
    +
    +
    The TaskMacroPlugin can be installed like any other TiddlyWiki plugin, and used without further effort.  However, there are two issues that may affect you.  (To get started with a brand new wiki that does not have these issues, consider downloading the [[empty LabWiki|empty_labwiki.html]].)
    +# The task macros don't play nicely with the default TiddlyWiki display of tags.  In the default view template, a tiddler's list of tags is shown in a little box that floats in the upper right corner of the tiddler.  However, this little box may interfere with the tables used by the task macros.  In Firefox, the tables are drawn right over the top of the tag box, rendering both of them illegible.  In Internet Explorer, the tag box forces the tables to be pushed down below the box, which can waste a lot of space.<<br>><<br>>Thus, I recommend changing your view template to eliminate the little box.  If you use Simon Baird's [[TagglyTagging|http://simonbaird.com/mptw/#TagglyTagging]] (as LabWiki does), then my TaskSummaryViewTemplate might be a good alternative.  Simply import it into your wiki and rename it to ViewTemplate.  This template also demonstrates how to incorporate the tasksum macro into every tiddler so any tiddler with tasks has a summary at the top.<<br>><<br>>
    +# Most view templates also add a minus sign ("-") before the "close" command.  TiddlyWiki interprets this to mean that you want the close command to be executed if you hit the Escape key from within the tiddler.<<br>><<br>>However, most tiddlers never have focus, and so never give you the opportunity to try it out.  But if you have a taskadder in your tiddler, then you suddenly enable this feature -- and you probably don't want it.  It means that if you type a nice long task description and then hit Escape, that description will be lost and the tiddler will be closed.  So I recommend that you remove the minus sign from the view template's menu altogether, as I have done in LabWiki's own ViewTemplate.
    +
    +----
    +This ends the tutorial.  To go back to any previous section, click the down-arrow and choose it: <<tag TaskMacroTutorial>>
    +
    +
    +
    PageTemplate
    +|>|SiteTitle - SiteSubtitle|
    +|>|MainMenu|
    +|DefaultTiddlers<<br>><<br>><<br>>ViewTemplate<<br>><<br>>EditTemplate|SideBarOptions|
    +|~|OptionsPanel|
    +|~|SideBarTabs|
    +|~|AdvancedOptions|
    +|~|<<tiddler Configuration.SideBarTabs>>|
    +
    +''StyleSheet:'' StyleSheetColors - StyleSheetLayout - StyleSheetPrint
    +
    +ColorPalette
    +
    +SiteUrl
    +
    +
    +
    /***
    +|Name|BetterTimelineMacro|
    +|Created by|SaqImtiaz|
    +|Location|http://tw.lewcid.org/#BetterTimelineMacro|
    +|Version|0.5 beta|
    +|Requires|~TW2.x|
    +!!!Description:
    +A replacement for the core timeline macro that offers more features:
    +*list tiddlers with only specfic tag
    +*exclude tiddlers with a particular tag
    +*limit entries to any number of days, for example one week
    +*specify a start date for the timeline, only tiddlers after that date will be listed.
    +
    +!!!Installation:
    +Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.
    +Edit the ViewTemplate to add the fullscreen command to the toolbar.
    +
    +!!!Syntax:
    +{{{<<timeline better:true>>}}}
    +''the param better:true enables the advanced features, without it you will get the old timeline behaviour.''
    +
    +additonal params:
    +(use only the ones you want)
    +{{{<<timeline better:true  onlyTag:Tag1 excludeTag:Tag2 sortBy:modified/created firstDay:YYYYMMDD maxDays:7 maxEntries:30>>}}}
    +
    +''explanation of syntax:''
    +onlyTag: only tiddlers with this tag will be listed. Default is to list all tiddlers.
    +excludeTag: tiddlers with this tag will not be listed.
    +sortBy: sort tiddlers by date modified or date created. Possible values are modified or created.
    +firstDay: useful for starting timeline from a specific date. Example: 20060701 for 1st of July, 2006
    +maxDays: limits timeline to include only tiddlers from the specified number of days. If you use a value of 7 for example, only tiddlers from the last 7 days will be listed.
    +maxEntries: limit the total number of entries in the timeline.
    +
    +
    +!!!History:
    +*28-07-06: ver 0.5 beta, first release
    +
    +!!!Code
    +***/
    +//{{{
    +// Return the tiddlers as a sorted array
    +TiddlyWiki.prototype.getTiddlers = function(field,excludeTag,includeTag)
    +{
    +          var results = [];
    +          this.forEachTiddler(function(title,tiddler)
    +          {
    +          if(excludeTag == undefined || tiddler.tags.find(excludeTag) == null)
    +                        if(includeTag == undefined || tiddler.tags.find(includeTag)!=null)
    +                                      results.push(tiddler);
    +          });
    +          if(field)
    +                   results.sort(function (a,b) {if(a[field] == b[field]) return(0); else return (a[field] < b[field]) ? -1 : +1; });
    +          return results;
    +}
    +
    +
    +
    +//this function by Udo
    +function getParam(params, name, defaultValue)
    +{
    +          if (!params)
    +          return defaultValue;
    +          var p = params[0][name];
    +          return p ? p[0] : defaultValue;
    +}
    +
    +window.old_timeline_handler= config.macros.timeline.handler;
    +config.macros.timeline.handler = function(place,macroName,params,wikifier,paramString,tiddler)
    +{
    +          var args = paramString.parseParams("list",null,true);
    +          var betterMode = getParam(args, "better", "false");
    +          if (betterMode == 'true')
    +          {
    +          var sortBy = getParam(args,"sortBy","modified");
    +          var excludeTag = getParam(args,"excludeTag",undefined);
    +          var includeTag = getParam(args,"onlyTag",undefined);
    +          var tiddlers = store.getTiddlers(sortBy,excludeTag,includeTag);
    +          var firstDayParam = getParam(args,"firstDay",undefined);
    +          var firstDay = (firstDayParam!=undefined)? firstDayParam: "00010101";
    +          var lastDay = "";
    +          var field= sortBy;
    +          var maxDaysParam = getParam(args,"maxDays",undefined);
    +          var maxDays = (maxDaysParam!=undefined)? maxDaysParam*24*60*60*1000: (new Date()).getTime() ;
    +          var maxEntries = getParam(args,"maxEntries",undefined);
    +          var last = (maxEntries!=undefined) ? tiddlers.length-Math.min(tiddlers.length,parseInt(maxEntries)) : 0;
    +          for(var t=tiddlers.length-1; t>=last; t--)
    +                  {
    +                  var tiddler = tiddlers[t];
    +                  var theDay = tiddler[field].convertToLocalYYYYMMDDHHMM().substr(0,8);
    +                  if ((theDay>=firstDay)&& (tiddler[field].getTime()> (new Date()).getTime() - maxDays))
    +                     {
    +                     if(theDay != lastDay)
    +                               {
    +                               var theDateList = document.createElement("ul");
    +                               place.appendChild(theDateList);
    +                               createTiddlyElement(theDateList,"li",null,"listTitle",tiddler[field].formatString(this.dateFormat));
    +                               lastDay = theDay;
    +                               }
    +                  var theDateListItem = createTiddlyElement(theDateList,"li",null,"listLink",null);
    +                  theDateListItem.appendChild(createTiddlyLink(place,tiddler.title,true));
    +                  }
    +                  }
    +          }
    +
    +          else
    +              {
    +              window.old_timeline_handler.apply(this,arguments);
    +              }
    +}
    +//}}}
    +
    +
    +
    ! Programming Languages
    + * C
    +  a C99 compatible compiler, some GCC extensions are used, most are optional.
    + * C++
    +  C++98 with some boost and tr1 additions
    + * bash
    +  some build scripts (test.sh, ..) use bash specific extensions
    +
    +! Build Tools
    + * scons
    + * autotools
    + * Doxygen
    + * test.sh (included)
    +
    +! Extra tools
    + * git
    + * bouml
    +
    +! Libraries
    + * boost
    + * NoBug
    + * gavl
    +
    +
    +
    +
    Background: #fff
    +Foreground: #000
    +PrimaryPale: #aaf
    +PrimaryLight: #88f
    +PrimaryMid: #00d
    +PrimaryDark: #004
    +SecondaryPale: #ffc
    +SecondaryLight: #fe8
    +SecondaryMid: #db4
    +SecondaryDark: #841
    +TertiaryPale: #eee
    +TertiaryLight: #ccc
    +TertiaryMid: #999
    +TertiaryDark: #666
    +Error: #f88
    +
    +
    +
    Overview
    +
    +
    +
    /***
    +|Name|FullScreenPlugin|
    +|Created by|SaqImtiaz|
    +|Location|http://tw.lewcid.org/#FullScreenPlugin|
    +|Version|1.1|
    +|Requires|~TW2.x|
    +!Description:
    +Toggle between viewing tiddlers fullscreen and normally. Very handy for when you need more viewing space.
    +
    +!Demo:
    +Click the ↕ button in the toolbar for this tiddler. Click it again to turn off fullscreen.
    +
    +!Installation:
    +Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.
    +Edit the ViewTemplate to add the fullscreen command to the toolbar.
    +
    +!History:
    +*25-07-06: ver 1.1
    +*20-07-06: ver 1.0
    +
    +!Code
    +***/
    +//{{{
    +var lewcidFullScreen = false;
    +
    +config.commands.fullscreen =
    +{
    +            text:" ↕ ",
    +            tooltip:"Fullscreen mode"
    +};
    +
    +config.commands.fullscreen.handler = function (event,src,title)
    +{
    +            if (lewcidFullScreen == false)
    +               {
    +                lewcidFullScreen = true;
    +                setStylesheet('#sidebar, .header, #mainMenu{display:none;} #displayArea{margin:0em 0 0 0 !important;}',"lewcidFullScreenStyle");
    +               }
    +            else
    +               {
    +                lewcidFullScreen = false;
    +                setStylesheet(' ',"lewcidFullScreenStyle");
    +               }
    +}
    +
    +config.macros.fullscreen={};
    +config.macros.fullscreen.handler =  function(place,macroName,params,wikifier,paramString,tiddler)
    +{
    +        var label = params[0]||" ↕ ";
    +        var tooltip = params[1]||"Fullscreen mode";
    +        createTiddlyButton(place,label,tooltip,config.commands.fullscreen.handler);
    +}
    +
    +var lewcid_fullscreen_closeTiddler = Story.prototype.closeTiddler;
    +Story.prototype.closeTiddler =function(title,animate,slowly)
    +{
    +           lewcid_fullscreen_closeTiddler.apply(this,arguments);
    +           if (story.isEmpty() && lewcidFullScreen == true)
    +              config.commands.fullscreen.handler();
    +}
    +
    +
    +Slider.prototype.lewcidStop = Slider.prototype.stop;
    +Slider.prototype.stop = function()
    +{
    +           this.lewcidStop();
    +           if (story.isEmpty() && lewcidFullScreen == true)
    +              config.commands.fullscreen.handler();
    +}
    +//}}}
    +
    +
    +
    ! Platform
    +We work and test on PC hardware, 32 and 64 bit. It is intended that Lumiera runs on other platforms which run GNU/Linux.
    +
    +! Graphics
    +There are no special requirements for the graphic system, using of OpenGL will likely be defined by the single plugins. Anyways it will be strictly optional.
    +
    +! Disks
    +Video editing requires decent disk speed, it is suggested to use a fast/big array of disks configured as raid.
    +
    +! Special Hardware
    +There are currently no plans to add support for propietary hardware accelerator boards. We don't have such hardware and we don't want to tie a free software program to closed hardware. This might change if the benefits are worth it, someone dontates such hardware to the developers, the specs of the hardware and the programming API are open.
    +
    +
    +
    +
    /***
    +''InlineJavascriptPlugin for ~TiddlyWiki version 1.2.x and 2.0''
    +^^author: Eric Shulman - ELS Design Studios
    +source: http://www.TiddlyTools.com/#InlineJavascriptPlugin
    +license: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^
    +
    +Insert Javascript executable code directly into your tiddler content. Lets you ''call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.
    +!!!!!Usage
    +<<<
    +When installed, this plugin adds new wiki syntax for surrounding tiddler content with {{{<script>}}} and {{{</script>}}} markers, so that it can be treated as embedded javascript and executed each time the tiddler is rendered.
    +
    +''Deferred execution from an 'onClick' link''
    +By including a label="..." parameter in the initial {{{<script>}}} marker, the plugin will create a link to an 'onclick' script that will only be executed when that specific link is clicked, rather than running the script each time the tiddler is rendered.
    +
    +''External script source files:''
    +You can also load javascript from an external source URL, by including a src="..." parameter in the initial {{{<script>}}} marker (e.g., {{{<script src="demo.js"></script>}}}). This is particularly useful when incorporating third-party javascript libraries for use in custom extensions and plugins. The 'foreign' javascript code remains isolated in a separate file that can be easily replaced whenever an updated library file becomes available.
    +
    +''Defining javascript functions and libraries:''
    +Although the external javascript file is loaded while the tiddler content is being rendered, any functions it defines will not be available for use until //after// the rendering has been completed. Thus, you cannot load a library and //immediately// use it's functions within the same tiddler. However, once that tiddler has been loaded, the library functions can be freely used in any tiddler (even the one in which it was initially loaded).
    +
    +To ensure that your javascript functions are always available when needed, you should load the libraries from a tiddler that will be rendered as soon as your TiddlyWiki document is opened. For example, you could put your {{{<script src="..."></script>}}} syntax into a tiddler called LoadScripts, and then add {{{<<tiddler LoadScripts>>}}} in your MainMenu tiddler.
    +
    +Since the MainMenu is always rendered immediately upon opening your document, the library will always be loaded before any other tiddlers that rely upon the functions it defines. Loading an external javascript library does not produce any direct output in the tiddler, so these definitions should have no impact on the appearance of your MainMenu.
    +
    +''Creating dynamic tiddler content''
    +An important difference between this implementation of embedded scripting and conventional embedded javascript techniques for web pages is the method used to produce output that is dynamically inserted into the document:
    +* In a typical web document, you use the document.write() function to output text sequences (often containing HTML tags) that are then rendered when the entire document is first loaded into the browser window.
    +* However, in a ~TiddlyWiki document, tiddlers (and other DOM elements) are created, deleted, and rendered "on-the-fly", so writing directly to the global 'document' object does not produce the results you want (i.e., replacing the embedded script within the tiddler content), and completely replaces the entire ~TiddlyWiki document in your browser window.
    +* To allow these scripts to work unmodified, the plugin automatically converts all occurences of document.write() so that the output is inserted into the tiddler content instead of replacing the entire ~TiddlyWiki document.
    +
    +If your script does not use document.write() to create dynamically embedded content within a tiddler, your javascript can, as an alternative, explicitly return a text value that the plugin can then pass through the wikify() rendering engine to insert into the tiddler display. For example, using {{{return "thistext"}}} will produce the same output as {{{document.write("thistext")}}}.
    +
    +//Note: your script code is automatically 'wrapped' inside a function, {{{_out()}}}, so that any return value you provide can be correctly handled by the plugin and inserted into the tiddler. To avoid unpredictable results (and possibly fatal execution errors), this function should never be redefined or called from ''within'' your script code.//
    +
    +''Accessing the ~TiddlyWiki DOM''
    +The plugin provides one pre-defined variable, 'place', that is passed in to your javascript code so that it can have direct access to the containing DOM element into which the tiddler output is currently being rendered.
    +
    +Access to this DOM element allows you to create scripts that can:
    +* vary their actions based upon the specific location in which they are embedded
    +* access 'tiddler-relative' information (use findContainingTiddler(place))
    +* perform direct DOM manipulations (when returning wikified text is not enough)
    +<<<
    +!!!!!Examples
    +<<<
    +an "alert" message box:
    +{{{
    +<script>alert('InlineJavascriptPlugin: this is a demonstration message');</script>
    +}}}
    +<script>alert('InlineJavascriptPlugin: this is a demonstration message');</script>
    +
    +dynamic output:
    +{{{
    +<script>return (new Date()).toString();</script>
    +}}}
    +<script>return (new Date()).toString();</script>
    +
    +wikified dynamic output:
    +{{{
    +<script>return "link to current user: [["+config.options.txtUserName+"]]";</script>
    +}}}
    +<script>return "link to current user: [["+config.options.txtUserName+"]]";</script>
    +
    +dynamic output using 'place' to get size information for current tiddler
    +{{{
    +<script>
    + if (!window.story) window.story=window;
    + var title=story.findContainingTiddler(place).id.substr(7);
    + return title+" is using "+store.getTiddlerText(title).length+" bytes";
    +</script>
    +}}}
    +<script>
    + if (!window.story) window.story=window;
    + var title=story.findContainingTiddler(place).id.substr(7);
    + return title+" is using "+store.getTiddlerText(title).length+" bytes";
    +</script>
    +
    +creating an 'onclick' button/link that runs a script
    +{{{
    +<script label="click here">
    + if (!window.story) window.story=window;
    + alert("Hello World!\nlinktext='"+place.firstChild.data+"'\ntiddler='"+story.findContainingTiddler(place).id.substr(7)+"'");
    +</script>
    +}}}
    +<script label="click here">
    + if (!window.story) window.story=window;
    + alert("Hello World!\nlinktext='"+place.firstChild.data+"'\ntiddler='"+story.findContainingTiddler(place).id.substr(7)+"'");
    +</script>
    +
    +loading a script from a source url
    +{{{
    +<script src="demo.js">return "loading demo.js..."</script>
    +<script label="click to execute demo() function">demo()</script>
    +}}}
    +where http://www.TiddlyTools.com/demo.js contains:
    +>function demo() { alert('this output is from demo(), defined in demo.js') }
    +>alert('InlineJavascriptPlugin: demo.js has been loaded');
    +<script src="demo.js">return "loading demo.js..."</script>
    +<script label="click to execute demo() function">demo()</script>
    +<<<
    +!!!!!Installation
    +<<<
    +import (or copy/paste) the following tiddlers into your document:
    +''InlineJavascriptPlugin'' (tagged with <<tag systemConfig>>)
    +<<<
    +!!!!!Revision History
    +<<<
    +''2006.01.05 [1.4.0]''
    +added support 'onclick' scripts. When label="..." param is present, a button/link is created using the indicated label text, and the script is only executed when the button/link is clicked. 'place' value is set to match the clicked button/link element.
    +''2005.12.13 [1.3.1]''
    +when catching eval error in IE, e.description contains the error text, instead of e.toString(). Fixed error reporting so IE shows the correct response text. Based on a suggestion by UdoBorkowski
    +''2005.11.09 [1.3.0]''
    +for 'inline' scripts (i.e., not scripts loaded with src="..."), automatically replace calls to 'document.write()' with 'place.innerHTML+=' so script output is directed into tiddler content
    +Based on a suggestion by BradleyMeck
    +''2005.11.08 [1.2.0]''
    +handle loading of javascript from an external URL via src="..." syntax
    +''2005.11.08 [1.1.0]''
    +pass 'place' param into scripts to provide direct DOM access 
    +''2005.11.08 [1.0.0]''
    +initial release
    +<<<
    +!!!!!Credits
    +<<<
    +This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]
    +<<<
    +!!!!!Code
    +***/
    +//{{{
    +version.extensions.inlineJavascript= {major: 1, minor: 4, revision: 0, date: new Date(2006,1,5)};
    +
    +config.formatters.push( {
    + name: "inlineJavascript",
    + match: "\\<script",
    + lookahead: "\\<script(?: src=\\\"((?:.|\\n)*?)\\\")?(?: label=\\\"((?:.|\\n)*?)\\\")?\\>((?:.|\\n)*?)\\</script\\>",
    +
    + handler: function(w) {
    + var lookaheadRegExp = new RegExp(this.lookahead,"mg");
    + lookaheadRegExp.lastIndex = w.matchStart;
    + var lookaheadMatch = lookaheadRegExp.exec(w.source)
    + if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
    + if (lookaheadMatch[1]) { // load a script library
    + // make script tag, set src, add to body to execute, then remove for cleanup
    + var script = document.createElement("script"); script.src = lookaheadMatch[1];
    + document.body.appendChild(script); document.body.removeChild(script);
    + }
    + if (lookaheadMatch[2] && lookaheadMatch[3]) { // create a link to an 'onclick' script
    + // add a link, define click handler, save code in link (pass 'place'), set link attributes
    + var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",lookaheadMatch[2]);
    + link.onclick=function(){try{return(eval(this.code))}catch(e){alert(e.description?e.description:e.toString())}}
    + link.code="function _out(place){"+lookaheadMatch[3]+"};_out(this);"
    + link.setAttribute("href","javascript:;"); link.setAttribute("title",""); link.style.cursor="pointer";
    + }
    + else if (lookaheadMatch[3]) { // run inline script code
    + var code="function _out(place){"+lookaheadMatch[3]+"};_out(w.output);"
    + code=code.replace(/document.write\(/gi,'place.innerHTML+=(');
    + try { var out = eval(code); } catch(e) { out = e.description?e.description:e.toString(); }
    + if (out && out.length) wikify(out,w.output);
    + }
    + w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
    + }
    + }
    +} )
    +//}}}
    +
    +
    +
    +
    /***
    +|''Name:''|InlineJavascriptPlugin|
    +|''Source:''|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
    +|''Author:''|Eric Shulman - ELS Design Studios|
    +|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
    +|''~CoreVersion:''|2.0.10|
    +
    +Insert Javascript executable code directly into your tiddler content. Lets you ''call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.
    +!!!!!Usage
    +<<<
    +When installed, this plugin adds new wiki syntax for surrounding tiddler content with {{{<script>}}} and {{{</script>}}} markers, so that it can be treated as embedded javascript and executed each time the tiddler is rendered.
    +
    +''Deferred execution from an 'onClick' link''
    +By including a label="..." parameter in the initial {{{<script>}}} marker, the plugin will create a link to an 'onclick' script that will only be executed when that specific link is clicked, rather than running the script each time the tiddler is rendered.
    +
    +''External script source files:''
    +You can also load javascript from an external source URL, by including a src="..." parameter in the initial {{{<script>}}} marker (e.g., {{{<script src="demo.js"></script>}}}). This is particularly useful when incorporating third-party javascript libraries for use in custom extensions and plugins. The 'foreign' javascript code remains isolated in a separate file that can be easily replaced whenever an updated library file becomes available.
    +
    +''Display script source in tiddler output''
    +By including the keyword parameter "show", in the initial {{{<script>}}} marker, the plugin will include the script source code in the output that it displays in the tiddler.
    +
    +''Defining javascript functions and libraries:''
    +Although the external javascript file is loaded while the tiddler content is being rendered, any functions it defines will not be available for use until //after// the rendering has been completed. Thus, you cannot load a library and //immediately// use it's functions within the same tiddler. However, once that tiddler has been loaded, the library functions can be freely used in any tiddler (even the one in which it was initially loaded).
    +
    +To ensure that your javascript functions are always available when needed, you should load the libraries from a tiddler that will be rendered as soon as your TiddlyWiki document is opened. For example, you could put your {{{<script src="..."></script>}}} syntax into a tiddler called LoadScripts, and then add {{{<<tiddler LoadScripts>>}}} in your MainMenu tiddler.
    +
    +Since the MainMenu is always rendered immediately upon opening your document, the library will always be loaded before any other tiddlers that rely upon the functions it defines. Loading an external javascript library does not produce any direct output in the tiddler, so these definitions should have no impact on the appearance of your MainMenu.
    +
    +''Creating dynamic tiddler content''
    +An important difference between this implementation of embedded scripting and conventional embedded javascript techniques for web pages is the method used to produce output that is dynamically inserted into the document:
    +* In a typical web document, you use the document.write() function to output text sequences (often containing HTML tags) that are then rendered when the entire document is first loaded into the browser window.
    +* However, in a ~TiddlyWiki document, tiddlers (and other DOM elements) are created, deleted, and rendered "on-the-fly", so writing directly to the global 'document' object does not produce the results you want (i.e., replacing the embedded script within the tiddler content), and completely replaces the entire ~TiddlyWiki document in your browser window.
    +* To allow these scripts to work unmodified, the plugin automatically converts all occurences of document.write() so that the output is inserted into the tiddler content instead of replacing the entire ~TiddlyWiki document.
    +
    +If your script does not use document.write() to create dynamically embedded content within a tiddler, your javascript can, as an alternative, explicitly return a text value that the plugin can then pass through the wikify() rendering engine to insert into the tiddler display. For example, using {{{return "thistext"}}} will produce the same output as {{{document.write("thistext")}}}.
    +
    +//Note: your script code is automatically 'wrapped' inside a function, {{{_out()}}}, so that any return value you provide can be correctly handled by the plugin and inserted into the tiddler. To avoid unpredictable results (and possibly fatal execution errors), this function should never be redefined or called from ''within'' your script code.//
    +
    +''Accessing the ~TiddlyWiki DOM''
    +The plugin provides one pre-defined variable, 'place', that is passed in to your javascript code so that it can have direct access to the containing DOM element into which the tiddler output is currently being rendered.
    +
    +Access to this DOM element allows you to create scripts that can:
    +* vary their actions based upon the specific location in which they are embedded
    +* access 'tiddler-relative' information (use findContainingTiddler(place))
    +* perform direct DOM manipulations (when returning wikified text is not enough)
    +<<<
    +!!!!!Examples
    +<<<
    +an "alert" message box:
    +><script show>
    + alert('InlineJavascriptPlugin: this is a demonstration message');
    +</script>
    +dynamic output:
    +><script show>
    + return (new Date()).toString();
    +</script>
    +wikified dynamic output:
    +><script show>
    + return "link to current user: [["+config.options.txtUserName+"]]";
    +</script>
    +dynamic output using 'place' to get size information for current tiddler:
    +><script show>
    + if (!window.story) window.story=window;
    + var title=story.findContainingTiddler(place).id.substr(7);
    + return title+" is using "+store.getTiddlerText(title).length+" bytes";
    +</script>
    +creating an 'onclick' button/link that runs a script:
    +><script label="click here" show>
    + if (!window.story) window.story=window;
    + alert("Hello World!\nlinktext='"+place.firstChild.data+"'\ntiddler='"+story.findContainingTiddler(place).id.substr(7)+"'");
    +</script>
    +loading a script from a source url:
    +>http://www.TiddlyTools.com/demo.js contains:
    +>>{{{function demo() { alert('this output is from demo(), defined in demo.js') } }}}
    +>>{{{alert('InlineJavascriptPlugin: demo.js has been loaded'); }}}
    +><script src="demo.js" show>
    + return "loading demo.js..."
    +</script>
    +><script label="click to execute demo() function" show>
    + demo()
    +</script>
    +<<<
    +!!!!!Installation
    +<<<
    +import (or copy/paste) the following tiddlers into your document:
    +''InlineJavascriptPlugin'' (tagged with <<tag systemConfig>>)
    +<<<
    +!!!!!Revision History
    +<<<
    +''2006.06.01 [1.5.1]'' when calling wikify() on script return value, pass hightlightRegExp and tiddler params so macros that rely on these values can render properly
    +''2006.04.19 [1.5.0]'' added 'show' parameter to force display of javascript source code in tiddler output
    +''2006.01.05 [1.4.0]'' added support 'onclick' scripts. When label="..." param is present, a button/link is created using the indicated label text, and the script is only executed when the button/link is clicked. 'place' value is set to match the clicked button/link element.
    +''2005.12.13 [1.3.1]'' when catching eval error in IE, e.description contains the error text, instead of e.toString(). Fixed error reporting so IE shows the correct response text. Based on a suggestion by UdoBorkowski
    +''2005.11.09 [1.3.0]'' for 'inline' scripts (i.e., not scripts loaded with src="..."), automatically replace calls to 'document.write()' with 'place.innerHTML+=' so script output is directed into tiddler content. Based on a suggestion by BradleyMeck
    +''2005.11.08 [1.2.0]'' handle loading of javascript from an external URL via src="..." syntax
    +''2005.11.08 [1.1.0]'' pass 'place' param into scripts to provide direct DOM access 
    +''2005.11.08 [1.0.0]'' initial release
    +<<<
    +!!!!!Credits
    +<<<
    +This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]
    +<<<
    +!!!!!Code
    +***/
    +//{{{
    +version.extensions.inlineJavascript= {major: 1, minor: 5, revision: 1, date: new Date(2006,6,1)};
    +
    +config.formatters.push( {
    + name: "inlineJavascript",
    + match: "\\<script",
    + lookahead: "\\<script(?: src=\\\"((?:.|\\n)*?)\\\")?(?: label=\\\"((?:.|\\n)*?)\\\")?( show)?\\>((?:.|\\n)*?)\\</script\\>",
    +
    + handler: function(w) {
    + var lookaheadRegExp = new RegExp(this.lookahead,"mg");
    + lookaheadRegExp.lastIndex = w.matchStart;
    + var lookaheadMatch = lookaheadRegExp.exec(w.source)
    + if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
    + if (lookaheadMatch[1]) { // load a script library
    + // make script tag, set src, add to body to execute, then remove for cleanup
    + var script = document.createElement("script"); script.src = lookaheadMatch[1];
    + document.body.appendChild(script); document.body.removeChild(script);
    + }
    + if (lookaheadMatch[4]) { // there is script code
    + if (lookaheadMatch[3]) // show inline script code in tiddler output
    + wikify("{{{\n"+lookaheadMatch[0]+"\n}}}\n",w.output);
    + if (lookaheadMatch[2]) { // create a link to an 'onclick' script
    + // add a link, define click handler, save code in link (pass 'place'), set link attributes
    + var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",lookaheadMatch[2]);
    + link.onclick=function(){try{return(eval(this.code))}catch(e){alert(e.description?e.description:e.toString())}}
    + link.code="function _out(place){"+lookaheadMatch[4]+"};_out(this);"
    + link.setAttribute("href","javascript:;"); link.setAttribute("title",""); link.style.cursor="pointer";
    + }
    + else { // run inline script code
    + var code="function _out(place){"+lookaheadMatch[4]+"};_out(w.output);"
    + code=code.replace(/document.write\(/gi,'place.innerHTML+=(');
    + try { var out = eval(code); } catch(e) { out = e.description?e.description:e.toString(); }
    + if (out && out.length) wikify(out,w.output,w.highlightRegExp,w.tiddler);
    + }
    + }
    + w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
    + }
    + }
    +} )
    +//}}}
    +
    +
    +
    ''[[Lumiera|index.html]]''
    +OperatingSystem
    +[[Hardware]]
    +[[Software]]
    +BuildDependencies
    +RuntimeDependencies
    +StyleGuide
    +[[Admin]]
    +<<fullscreen>>
    +
    +
    +
    <!--{{{-->
    +<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>
    +<!--}}}-->
    +
    +<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>My TiddlyWiki</b> is loading<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Requires Javascript.</span></div>
    +
    +
    +
    Lumiera is written for GNU/Linux. We try to make the best out of modern system programming techniques to reach the best possible performance. It is suggested to use a 64bit OS. Lumiera shall scale with the provided Hardware, the more RAM and the more/faster CPU's you have the better. Nevertheless lower end 32bit machines are supported too.
    +
    +Secondary targets will be other free operating systems which offer a decent Posix API. By coincidence it will be possible to port Lumiera to Mac OSX if anyone helps with that.
    +
    +Windows platforms are not on our target list, if someone wants to do port it, we will merge his efforts but unless that happens we will not care for windows compatibility.
    +
    +
    +
    +
     * OperatingSystem
    + * [[Hardware]]
    + * [[Software]]
    + * BuildDependencies
    + * RuntimeDependencies
    + * StyleGuide
    +
    +
    +
    +
    <!--{{{-->
    +<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
    +	<div class='headerShadow'>
    +		<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
    +		<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
    +	</div>
    +	<div class='headerForeground'>
    +		<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
    +		<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
    +	</div>
    +</div>
    +<!-- horizontal MainMenu -->
    +<div id='topMenu' refresh='content' tiddler='MainMenu'></div>
    +<!-- original MainMenu menu -->
    +<!-- <div id='mainMenu' refresh='content' tiddler='MainMenu'></div> -->
    +<div id='sidebar'>
    +	<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
    +	<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
    +</div>
    +<div id='displayArea'>
    +	<div id='messageArea'></div>
    +	<div id='tiddlerDisplay'></div>
    +</div>
    +<!--}}}-->
    +
    +
    +
    +
    /***
    +|<html><a name="Top"/></html>''Name:''|PartTiddlerPlugin|
    +|''Version:''|1.0.6 (2006-11-07)|
    +|''Source:''|http://tiddlywiki.abego-software.de/#PartTiddlerPlugin|
    +|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
    +|''Licence:''|[[BSD open source license]]|
    +|''TiddlyWiki:''|2.0|
    +|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
    +!Table of Content<html><a name="TOC"/></html>
    +* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Description',null, event)">Description, Syntax</a></html>
    +* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Applications',null, event)">Applications</a></html>
    +** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('LongTiddler',null, event)">Refering to Paragraphs of a Longer Tiddler</a></html>
    +** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Citation',null, event)">Citation Index</a></html>
    +** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('TableCells',null, event)">Creating "multi-line" Table Cells</a></html>
    +** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Tabs',null, event)">Creating Tabs</a></html>
    +** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Sliders',null, event)">Using Sliders</a></html>
    +* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Revisions',null, event)">Revision History</a></html>
    +* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Code',null, event)">Code</a></html>
    +!Description<html><a name="Description"/></html>
    +With the {{{<part aPartName> ... </part>}}} feature you can structure your tiddler text into separate (named) parts. 
    +Each part can be referenced as a "normal" tiddler, using the "//tiddlerName//''/''//partName//" syntax (e.g. "About/Features"). E.g. you may create links to the parts, use it in {{{<<tiddler...>>}}} or {{{<<tabs...>>}}} macros etc.
    +
    +''Syntax:'' 
    +|>|''<part'' //partName// [''hidden''] ''>'' //any tiddler content// ''</part>''|
    +|//partName//|The name of the part. You may reference a part tiddler with the combined tiddler name "//nameOfContainerTidder//''/''//partName//.|
    +|''hidden''|When defined the content of the part is not displayed in the container tiddler. But when the part is explicitly referenced (e.g. in a {{{<<tiddler...>>}}} macro or in a link) the part's content is displayed.|
    +|<html><i>any&nbsp;tiddler&nbsp;content</i></html>|<html>The content of the part.<br>A part can have any content that a "normal" tiddler may have, e.g. you may use all the formattings and macros defined.</html>|
    +|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|
    +<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +
    +!Applications<html><a name="Applications"/></html>
    +!!Refering to Paragraphs of a Longer Tiddler<html><a name="LongTiddler"/></html>
    +Assume you have written a long description in a tiddler and now you want to refer to the content of a certain paragraph in that tiddler (e.g. some definition.) Just wrap the text with a ''part'' block, give it a nice name, create a "pretty link" (like {{{[[Discussion Groups|Introduction/DiscussionGroups]]}}}) and you are done.
    +
    +Notice this complements the approach to first writing a lot of small tiddlers and combine these tiddlers to one larger tiddler in a second step (e.g. using the {{{<<tiddler...>>}}} macro). Using the ''part'' feature you can first write a "classic" (longer) text that can be read "from top to bottom" and later "reuse" parts of this text for some more "non-linear" reading.
    +
    +<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +
    +!!Citation Index<html><a name="Citation"/></html>
    +Create a tiddler "Citations" that contains your "citations". 
    +Wrap every citation with a part and a proper name. 
    +
    +''Example''
    +{{{
    +<part BAX98>Baxter, Ira D. et al: //Clone Detection Using Abstract Syntax Trees.// 
    +in //Proc. ICSM//, 1998.</part>
    +
    +<part BEL02>Bellon, Stefan: //Vergleich von Techniken zur Erkennung duplizierten Quellcodes.// 
    +Thesis, Uni Stuttgart, 2002.</part>
    +
    +<part DUC99>Ducasse, Stéfane et al: //A Language Independent Approach for Detecting Duplicated Code.// 
    +in //Proc. ICSM//, 1999.</part>
    +}}}
    +
    +You may now "cite" them just by using a pretty link like {{{[[Citations/BAX98]]}}} or even more pretty, like this {{{[[BAX98|Citations/BAX98]]}}}.
    +
    +<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +
    +!!Creating "multi-line" Table Cells<html><a name="TableCells"/></html>
    +You may have noticed that it is hard to create table cells with "multi-line" content. E.g. if you want to create a bullet list inside a table cell you cannot just write the bullet list
    +{{{
    +* Item 1
    +* Item 2
    +* Item 3
    +}}}
    +into a table cell (i.e. between the | ... | bars) because every bullet item must start in a new line but all cells of a table row must be in one line.
    +
    +Using the ''part'' feature this problem can be solved. Just create a hidden part that contains the cells content and use a {{{<<tiddler >>}}} macro to include its content in the table's cell.
    +
    +''Example''
    +{{{
    +|!Subject|!Items|
    +|subject1|<<tiddler ./Cell1>>|
    +|subject2|<<tiddler ./Cell2>>|
    +
    +<part Cell1 hidden>
    +* Item 1
    +* Item 2
    +* Item 3
    +</part>
    +...
    +}}}
    +
    +Notice that inside the {{{<<tiddler ...>>}}} macro you may refer to the "current tiddler" using the ".".
    +
    +BTW: The same approach can be used to create bullet lists with items that contain more than one line.
    +
    +<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +
    +!!Creating Tabs<html><a name="Tabs"/></html>
    +The build-in {{{<<tabs ...>>}}} macro requires that you defined an additional tiddler for every tab it displays. When you want to have "nested" tabs you need to define a tiddler for the "main tab" and one for every tab it contains. I.e. the definition of a set of tabs that is visually displayed at one place is distributed across multiple tiddlers.
    +
    +With the ''part'' feature you can put the complete definition in one tiddler, making it easier to keep an overview and maintain the tab sets.
    +
    +''Example''
    +The standard tabs at the sidebar are defined by the following eight tiddlers:
    +* SideBarTabs
    +* TabAll
    +* TabMore
    +* TabMoreMissing
    +* TabMoreOrphans
    +* TabMoreShadowed
    +* TabTags
    +* TabTimeline
    +
    +Instead of these eight tiddlers one could define the following SideBarTabs tiddler that uses the ''part'' feature:
    +{{{
    +<<tabs txtMainTab 
    + Timeline Timeline SideBarTabs/Timeline 
    + All 'All tiddlers' SideBarTabs/All 
    + Tags 'All tags' SideBarTabs/Tags 
    + More 'More lists' SideBarTabs/More>>
    +<part Timeline hidden><<timeline>></part>
    +<part All hidden><<list all>></part>
    +<part Tags hidden><<allTags>></part>
    +<part More hidden><<tabs txtMoreTab 
    + Missing 'Missing tiddlers' SideBarTabs/Missing 
    + Orphans 'Orphaned tiddlers' SideBarTabs/Orphans 
    + Shadowed 'Shadowed tiddlers' SideBarTabs/Shadowed>></part>
    +<part Missing hidden><<list missing>></part>
    +<part Orphans hidden><<list orphans>></part>
    +<part Shadowed hidden><<list shadowed>></part>
    +}}}
    +
    +Notice that you can easily "overwrite" individual parts in separate tiddlers that have the full name of the part.
    +
    +E.g. if you don't like the classic timeline tab but only want to see the 100 most recent tiddlers you could create a tiddler "~SideBarTabs/Timeline" with the following content:
    +{{{
    +<<forEachTiddler 
    + sortBy 'tiddler.modified' descending 
    + write '(index < 100) ? "* [["+tiddler.title+"]]\n":""'>>
    +}}}
    +<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +
    +!!Using Sliders<html><a name="Sliders"/></html>
    +Very similar to the build-in {{{<<tabs ...>>}}} macro (see above) the {{{<<slider ...>>}}} macro requires that you defined an additional tiddler that holds the content "to be slid". You can avoid creating this extra tiddler by using the ''part'' feature
    +
    +''Example''
    +In a tiddler "About" we may use the slider to show some details that are documented in the tiddler's "Details" part.
    +{{{
    +...
    +<<slider chkAboutDetails About/Details details "Click here to see more details">>
    +<part Details hidden>
    +To give you a better overview ...
    +</part>
    +...
    +}}}
    +
    +Notice that putting the content of the slider into the slider's tiddler also has an extra benefit: When you decide you need to edit the content of the slider you can just doubleclick the content, the tiddler opens for editing and you can directly start editing the content (in the part section). In the "old" approach you would doubleclick the tiddler, see that the slider is using tiddler X, have to look for the tiddler X and can finally open it for editing. So using the ''part'' approach results in a much short workflow.
    +
    +<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +
    +!Revision history<html><a name="Revisions"/></html>
    +* v1.0.6 (2006-11-07)
    +** Bugfix: cannot edit tiddler when UploadPlugin by Bidix is installed. Thanks to José Luis González Castro for reporting the bug.
    +* v1.0.5 (2006-03-02)
    +** Bugfix: Example with multi-line table cells does not work in IE6. Thanks to Paulo Soares for reporting the bug.
    +* v1.0.4 (2006-02-28)
    +** Bugfix: Shadow tiddlers cannot be edited (in TW 2.0.6). Thanks to Torsten Vanek for reporting the bug.
    +* v1.0.3 (2006-02-26)
    +** Adapt code to newly introduced Tiddler.prototype.isReadOnly() function (in TW 2.0.6). Thanks to Paulo Soares for reporting the problem.
    +* v1.0.2 (2006-02-05)
    +** Also allow other macros than the "tiddler" macro use the "." in the part reference (to refer to "this" tiddler)
    +* v1.0.1 (2006-01-27)
    +** Added Table of Content for plugin documentation. Thanks to RichCarrillo for suggesting.
    +** Bugfix: newReminder plugin does not work when PartTiddler is installed. Thanks to PauloSoares for reporting.
    +* v1.0.0 (2006-01-25)
    +** initial version
    +<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +
    +!Code<html><a name="Code"/></html>
    +<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +***/
    +//{{{
    +//============================================================================
    +// PartTiddlerPlugin
    +
    +// Ensure that the PartTiddler Plugin is only installed once.
    +//
    +if (!version.extensions.PartTiddlerPlugin) {
    +
    +
    +
    +version.extensions.PartTiddlerPlugin = {
    + major: 1, minor: 0, revision: 6,
    + date: new Date(2006, 10, 7), 
    + type: 'plugin',
    + source: "http://tiddlywiki.abego-software.de/#PartTiddlerPlugin"
    +};
    +
    +if (!window.abego) window.abego = {};
    +if (version.major < 2) alertAndThrow("PartTiddlerPlugin requires TiddlyWiki 2.0 or newer.");
    +
    +//============================================================================
    +// Common Helpers
    +
    +// Looks for the next newline, starting at the index-th char of text. 
    +//
    +// If there are only whitespaces between index and the newline 
    +// the index behind the newline is returned, 
    +// otherwise (or when no newline is found) index is returned.
    +//
    +var skipEmptyEndOfLine = function(text, index) {
    + var re = /(\n|[^\s])/g;
    + re.lastIndex = index;
    + var result = re.exec(text);
    + return (result && text.charAt(result.index) == '\n') 
    + ? result.index+1
    + : index;
    +}
    +
    +
    +//============================================================================
    +// Constants
    +
    +var partEndOrStartTagRE = /(<\/part>)|(<part(?:\s+)((?:[^>])+)>)/mg;
    +var partEndTagREString = "<\\/part>";
    +var partEndTagString = "</part>";
    +
    +//============================================================================
    +// Plugin Specific Helpers
    +
    +// Parse the parameters inside a <part ...> tag and return the result.
    +//
    +// @return [may be null] {partName: ..., isHidden: ...}
    +//
    +var parseStartTagParams = function(paramText) {
    + var params = paramText.readMacroParams();
    + if (params.length == 0 || params[0].length == 0) return null;
    + 
    + var name = params[0];
    + var paramsIndex = 1;
    + var hidden = false;
    + if (paramsIndex < params.length) {
    + hidden = params[paramsIndex] == "hidden";
    + paramsIndex++;
    + }
    + 
    + return {
    + partName: name, 
    + isHidden: hidden
    + };
    +}
    +
    +// Returns the match to the next (end or start) part tag in the text, 
    +// starting the search at startIndex.
    +// 
    +// When no such tag is found null is returned, otherwise a "Match" is returned:
    +// [0]: full match
    +// [1]: matched "end" tag (or null when no end tag match)
    +// [2]: matched "start" tag (or null when no start tag match)
    +// [3]: content of start tag (or null if no start tag match)
    +//
    +var findNextPartEndOrStartTagMatch = function(text, startIndex) {
    + var re = new RegExp(partEndOrStartTagRE);
    + re.lastIndex = startIndex;
    + var match = re.exec(text);
    + return match;
    +}
    +
    +//============================================================================
    +// Formatter
    +
    +// Process the <part ...> ... </part> starting at (w.source, w.matchStart) for formatting.
    +//
    +// @return true if a complete part section (including the end tag) could be processed, false otherwise.
    +//
    +var handlePartSection = function(w) {
    + var tagMatch = findNextPartEndOrStartTagMatch(w.source, w.matchStart);
    + if (!tagMatch) return false;
    + if (tagMatch.index != w.matchStart || !tagMatch[2]) return false;
    +
    + // Parse the start tag parameters
    + var arguments = parseStartTagParams(tagMatch[3]);
    + if (!arguments) return false;
    + 
    + // Continue processing
    + var startTagEndIndex = skipEmptyEndOfLine(w.source, tagMatch.index + tagMatch[0].length);
    + var endMatch = findNextPartEndOrStartTagMatch(w.source, startTagEndIndex);
    + if (endMatch && endMatch[1]) {
    + if (!arguments.isHidden) {
    + w.nextMatch = startTagEndIndex;
    + w.subWikify(w.output,partEndTagREString);
    + }
    + w.nextMatch = skipEmptyEndOfLine(w.source, endMatch.index + endMatch[0].length);
    + 
    + return true;
    + }
    + return false;
    +}
    +
    +config.formatters.push( {
    + name: "part",
    + match: "<part\\s+[^>]+>",
    + 
    + handler: function(w) {
    + if (!handlePartSection(w)) {
    + w.outputText(w.output,w.matchStart,w.matchStart+w.matchLength);
    + }
    + }
    +} )
    +
    +//============================================================================
    +// Extend "fetchTiddler" functionality to also recognize "part"s of tiddlers 
    +// as tiddlers.
    +
    +var currentParent = null; // used for the "." parent (e.g. in the "tiddler" macro)
    +
    +// Return the match to the first <part ...> tag of the text that has the
    +// requrest partName.
    +//
    +// @return [may be null]
    +//
    +var findPartStartTagByName = function(text, partName) {
    + var i = 0;
    + 
    + while (true) {
    + var tagMatch = findNextPartEndOrStartTagMatch(text, i);
    + if (!tagMatch) return null;
    +
    + if (tagMatch[2]) {
    + // Is start tag
    + 
    + // Check the name
    + var arguments = parseStartTagParams(tagMatch[3]);
    + if (arguments && arguments.partName == partName) {
    + return tagMatch;
    + }
    + }
    + i += tagMatch[0].length;
    + }
    +}
    +
    +// Return the part "partName" of the given parentTiddler as a "readOnly" Tiddler 
    +// object, using fullName as the Tiddler's title. 
    +//
    +// All remaining properties of the new Tiddler (tags etc.) are inherited from 
    +// the parentTiddler.
    +// 
    +// @return [may be null]
    +//
    +var getPart = function(parentTiddler, partName, fullName) {
    + var text = parentTiddler.text;
    + var startTag = findPartStartTagByName(text, partName);
    + if (!startTag) return null;
    + 
    + var endIndexOfStartTag = skipEmptyEndOfLine(text, startTag.index+startTag[0].length);
    + var indexOfEndTag = text.indexOf(partEndTagString, endIndexOfStartTag);
    +
    + if (indexOfEndTag >= 0) {
    + var partTiddlerText = text.substring(endIndexOfStartTag,indexOfEndTag);
    + var partTiddler = new Tiddler();
    + partTiddler.set(
    + fullName,
    + partTiddlerText,
    + parentTiddler.modifier,
    + parentTiddler.modified,
    + parentTiddler.tags,
    + parentTiddler.created);
    + partTiddler.abegoIsPartTiddler = true;
    + return partTiddler;
    + }
    + 
    + return null;
    +}
    +
    +// Hijack the store.fetchTiddler to recognize the "part" addresses.
    +//
    +
    +var oldFetchTiddler = store.fetchTiddler ;
    +store.fetchTiddler = function(title) {
    + var result = oldFetchTiddler.apply(this, arguments);
    + if (!result && title) {
    + var i = title.lastIndexOf('/');
    + if (i > 0) {
    + var parentName = title.substring(0, i);
    + var partName = title.substring(i+1);
    + var parent = (parentName == ".") 
    + ? currentParent 
    + : oldFetchTiddler.apply(this, [parentName]);
    + if (parent) {
    + return getPart(parent, partName, parent.title+"/"+partName);
    + }
    + }
    + }
    + return result; 
    +};
    +
    +
    +// The user must not edit a readOnly/partTiddler
    +//
    +
    +config.commands.editTiddler.oldIsReadOnlyFunction = Tiddler.prototype.isReadOnly;
    +
    +Tiddler.prototype.isReadOnly = function() {
    + // Tiddler.isReadOnly was introduced with TW 2.0.6.
    + // For older version we explicitly check the global readOnly flag
    + if (config.commands.editTiddler.oldIsReadOnlyFunction) {
    + if (config.commands.editTiddler.oldIsReadOnlyFunction.apply(this, arguments)) return true;
    + } else {
    + if (readOnly) return true;
    + }
    +
    + return this.abegoIsPartTiddler;
    +}
    +
    +config.commands.editTiddler.handler = function(event,src,title)
    +{
    + var t = store.getTiddler(title);
    + // Edit the tiddler if it either is not a tiddler (but a shadowTiddler)
    + // or the tiddler is not readOnly
    + if(!t || !t.abegoIsPartTiddler)
    + {
    + clearMessage();
    + story.displayTiddler(null,title,DEFAULT_EDIT_TEMPLATE);
    + story.focusTiddler(title,"text");
    + return false;
    + }
    +}
    +
    +// To allow the "./partName" syntax in macros we need to hijack 
    +// the invokeMacro to define the "currentParent" while it is running.
    +// 
    +var oldInvokeMacro = window.invokeMacro;
    +function myInvokeMacro(place,macro,params,wikifier,tiddler) {
    + var oldCurrentParent = currentParent;
    + if (tiddler) currentParent = tiddler;
    + try {
    + oldInvokeMacro.apply(this, arguments);
    + } finally {
    + currentParent = oldCurrentParent;
    + }
    +}
    +window.invokeMacro = myInvokeMacro;
    +
    +// Scroll the anchor anchorName in the viewer of the given tiddler visible.
    +// When no tiddler is defined use the tiddler of the target given event is used.
    +window.scrollAnchorVisible = function(anchorName, tiddler, evt) {
    + var tiddlerElem = null;
    + if (tiddler) {
    + tiddlerElem = document.getElementById(story.idPrefix + tiddler);
    + }
    + if (!tiddlerElem && evt) {
    + var target = resolveTarget(evt);
    + tiddlerElem = story.findContainingTiddler(target);
    + }
    + if (!tiddlerElem) return;
    +
    + var children = tiddlerElem.getElementsByTagName("a");
    + for (var i = 0; i < children.length; i++) {
    + var child = children[i];
    + var name = child.getAttribute("name");
    + if (name == anchorName) {
    + var y = findPosY(child);
    + window.scrollTo(0,y);
    + return;
    + }
    + }
    +}
    +
    +} // of "install only once"
    +//}}}
    +
    +/***
    +<html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +
    +!Licence and Copyright
    +Copyright (c) abego Software ~GmbH, 2006 ([[www.abego-software.de|http://www.abego-software.de]])
    +
    +Redistribution and use in source and binary forms, with or without modification,
    +are permitted provided that the following conditions are met:
    +
    +Redistributions of source code must retain the above copyright notice, this
    +list of conditions and the following disclaimer.
    +
    +Redistributions in binary form must reproduce the above copyright notice, this
    +list of conditions and the following disclaimer in the documentation and/or other
    +materials provided with the distribution.
    +
    +Neither the name of abego Software nor the names of its contributors may be
    +used to endorse or promote products derived from this software without specific
    +prior written permission.
    +
    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
    +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
    +SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
    +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
    +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
    +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
    +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
    +DAMAGE.
    +
    +<html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +***/
    +
    +
    +
    /***
    +|''Name:''|RSSReaderPlugin|
    +|''Description:''|This plugin provides a RSSReader for TiddlyWiki|
    +|''Version:''|1.1.1|
    +|''Date:''|Apr 21, 2007|
    +|''Source:''|http://tiddlywiki.bidix.info/#RSSReaderPlugin|
    +|''Documentation:''|http://tiddlywiki.bidix.info/#RSSReaderPluginDoc|
    +|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
    +|''Credit:''|BramChen for RssNewsMacro|
    +|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
    +|''~CoreVersion:''|2.2.0|
    +|''OptionalRequires:''|http://www.tiddlytools.com/#NestedSlidersPlugin|
    +***/
    +//{{{
    +version.extensions.RSSReaderPlugin = {
    +	major: 1, minor: 1, revision: 1,
    +	date: new Date("Apr 21, 2007"),
    +	source: "http://TiddlyWiki.bidix.info/#RSSReaderPlugin",
    +	author: "BidiX",
    +	coreVersion: '2.2.0'
    +};
    +
    +config.macros.rssReader = {
    +	dateFormat: "DDD, DD MMM YYYY",
    +	itemStyle: "display: block;border: 1px solid black;padding: 5px;margin: 5px;", //useed  '@@'+itemStyle+itemText+'@@'
    +	msg:{
    +		permissionDenied: "Permission to read preferences was denied.",
    +		noRSSFeed: "No RSS Feed at this address %0",
    +		urlNotAccessible: " Access to %0 is not allowed"
    +	},
    +	cache: [], 	// url => XMLHttpRequest.responseXML
    +	desc: "noDesc",
    +	
    +	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
    +		var desc = params[0];
    +		var feedURL = params[1];
    +		var toFilter = (params[2] ? true : false);
    +		var filterString = (toFilter?(params[2].substr(0,1) == ' '? tiddler.title:params[2]):'');
    +		var place = createTiddlyElement(place, "div", "RSSReader");
    +		wikify("^^<<rssFeedUpdate "+feedURL+" [[" + tiddler.title + "]]>>^^\n",place);
    +		if (this.cache[feedURL]) {
    +			this.displayRssFeed(this.cache[feedURL], feedURL, place, desc, toFilter, filterString);
    +		}
    +		else {
    +			var r = loadRemoteFile(feedURL,config.macros.rssReader.processResponse, [place, desc, toFilter, filterString]);
    +			if (typeof r == "string")
    +				displayMessage(r);
    +		}
    +		
    +	},
    +
    +	// callback for loadRemoteFile 
    +	// params : [place, desc, toFilter, filterString]
    +	processResponse: function(status, params, responseText, url, xhr) { // feedURL, place, desc, toFilter, filterString) {	
    +		if (window.netscape){
    +			try {
    +				if (document.location.protocol.indexOf("http") == -1) {
    +					netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
    +				}
    +			}
    +			catch (e) { displayMessage(e.description?e.description:e.toString()); }
    +		}
    +		if (xhr.status == httpStatus.NotFound)
    +		 {
    +			displayMessage(config.macros.rssReader.noRSSFeed.format([url]));
    +			return;
    +		}
    +		if (!status)
    +		 {
    +			displayMessage(config.macros.rssReader.noRSSFeed.format([url]));
    +			return;
    +		}
    +		if (xhr.responseXML) {
    +			// response is interpreted as XML
    +			config.macros.rssReader.cache[url] = xhr.responseXML;
    +			config.macros.rssReader.displayRssFeed(xhr.responseXML, params[0], url, params[1], params[2], params[3]);
    +		}
    +		else {
    +			if (responseText.substr(0,5) == "<?xml") {
    +				// response exists but not return as XML -> try to parse it 
    +				var dom = (new DOMParser()).parseFromString(responseText, "text/xml"); 
    +				if (dom) {
    +					// parsing successful so use it
    +					config.macros.rssReader.cache[url] = dom;
    +					config.macros.rssReader.displayRssFeed(dom, params[0], url, params[1], params[2], params[3]);
    +					return;
    +				}
    +			}
    +			// no XML display as html 
    +			wikify("<html>" + responseText + "</html>", params[0]);
    +			displayMessage(config.macros.rssReader.msg.noRSSFeed.format([url]));
    +		}
    +	},
    +
    +	// explore down the DOM tree
    +	displayRssFeed: function(xml, place, feedURL, desc, toFilter, filterString){
    +		// Channel
    +		var chanelNode = xml.getElementsByTagName('channel').item(0);
    +		var chanelTitleElement = (chanelNode ? chanelNode.getElementsByTagName('title').item(0) : null);
    +		var chanelTitle = "";
    +		if ((chanelTitleElement) && (chanelTitleElement.firstChild)) 
    +			chanelTitle = chanelTitleElement.firstChild.nodeValue;
    +		var chanelLinkElement = (chanelNode ? chanelNode.getElementsByTagName('link').item(0) : null);
    +		var chanelLink = "";
    +		if (chanelLinkElement) 
    +			chanelLink = chanelLinkElement.firstChild.nodeValue;
    +		var titleTxt = "!![["+chanelTitle+"|"+chanelLink+"]]\n";
    +		var title = createTiddlyElement(place,"div",null,"ChanelTitle",null);
    +		wikify(titleTxt,title);
    +		// ItemList
    +		var itemList = xml.getElementsByTagName('item');
    +		var article = createTiddlyElement(place,"ul",null,null,null);
    +		var lastDate;
    +		var re;
    +		if (toFilter) 
    +			re = new RegExp(filterString.escapeRegExp());
    +		for (var i=0; i<itemList.length; i++){
    +			var titleElm = itemList[i].getElementsByTagName('title').item(0);
    +			var titleText = (titleElm ? titleElm.firstChild.nodeValue : '');
    +			if (toFilter && ! titleText.match(re)) {
    +				continue;
    +			}
    +			var descText = '';
    +			descElem = itemList[i].getElementsByTagName('description').item(0);
    +			if (descElem){
    +				try{
    +					for (var ii=0; ii<descElem.childNodes.length; ii++) {
    +						descText += descElem.childNodes[ii].nodeValue;
    +					}
    +				}
    +				catch(e){}
    +				descText = descText.replace(/<br \/>/g,'\n');
    +				if (desc == "asHtml")
    +					descText = "<html>"+descText+"</html>";
    +			}
    +			var linkElm = itemList[i].getElementsByTagName("link").item(0);
    +			var linkURL = linkElm.firstChild.nodeValue;
    +			var pubElm = itemList[i].getElementsByTagName('pubDate').item(0);
    +			var pubDate;
    +			if (!pubElm) {
    +				pubElm = itemList[i].getElementsByTagName('date').item(0); // for del.icio.us
    +				if (pubElm) {
    +					pubDate = pubElm.firstChild.nodeValue;
    +					pubDate = this.formatDateString(this.dateFormat, pubDate);
    +					}
    +					else {
    +						pubDate = '0';
    +					}
    +				}
    +			else {
    +				pubDate = (pubElm ? pubElm.firstChild.nodeValue : 0);
    +				pubDate = this.formatDate(this.dateFormat, pubDate);
    +			}
    +			titleText = titleText.replace(/\[|\]/g,'');
    +			var rssText = '*'+'[[' + titleText + '|' + linkURL + ']]' + '' ;
    +			if ((desc != "noDesc") && descText){
    +				rssText = rssText.replace(/\n/g,' ');
    +				descText = '@@'+this.itemStyle+descText + '@@\n';				
    +				if (version.extensions.nestedSliders){
    +					descText = '+++[...]' + descText + '===';
    +				}
    +				rssText = rssText + descText;
    +			}
    +			var story;
    +			if ((lastDate != pubDate) && ( pubDate != '0')) {
    +				story = createTiddlyElement(article,"li",null,"RSSItem",pubDate);
    +				lastDate = pubDate;
    +			}
    +			else {
    +				lastDate = pubDate;
    +			}
    +			story = createTiddlyElement(article,"div",null,"RSSItem",null);
    +			wikify(rssText,story);
    +		}
    +	},
    +	
    +	formatDate: function(template, date){
    +		var dateString = new Date(date);
    +		// template = template.replace(/hh|mm|ss/g,'');
    +		return dateString.formatString(template);
    +	},
    +	
    +	formatDateString: function(template, date){
    +		var dateString = new Date(date.substr(0,4), date.substr(5,2) - 1, date.substr(8,2)
    +			);
    +		return dateString.formatString(template);
    +	}
    +	
    +};
    +
    +config.macros.rssFeedUpdate = {
    +	label: "Update",
    +	prompt: "Clear the cache and redisplay this RssFeed",
    +	handler: function(place,macroName,params) {
    +		var feedURL = params[0];
    +		var tiddlerTitle = params[1];
    +		createTiddlyButton(place, this.label, this.prompt, 
    +			function () {
    +				if (config.macros.rssReader.cache[feedURL]) {
    +					config.macros.rssReader.cache[feedURL] = null; 
    +			}
    +			story.refreshTiddler(tiddlerTitle,null, true);
    +		return false;});
    +	}
    +};
    +
    +//}}}
    +
    +
    +
    +
    //last update: RSSReaderPlugin v 1.1.1//
    +
    +!Description
    +This plugin provides a RSSReader for TiddlyWiki
    +* It accesses asynchronously an RSSFeed
    +*Depending on the chanel item format, each item could be written as :
    +**simple text wikified
    +**html
    +
    +!Usage
    +{{{
    +<<rssReader noDesc|asHtml|asText rssUrl ['filtering string']>>
    +	noDesc: only title of item is printed
    +
    +	asHtml: if you know that description contain html (links, img ...), 
    +		the text is enclosed with <html> </html> tags
    +
    + 	asText: if the description should not be interpreted as html the 
    +		description is wikified
    +
    +	rssUrl: the rssFeed url that could be accessed. 
    +	
    +	'filtering string': if present, the rssfeed item title must contained 
    +		this string to be displayed. 
    +		If 'filering string' contained space characters only, the tiddler 
    +		title is used for filtering.
    +
    +}}}
    +
    +For security reasons, if the TiddlyWiki is accessed from http, a ProxyService should be used to access an rssFeed from an other site.
    +
    +!examples
    +| !reader | !RSSFeed type | !working from |
    +| BidiXTWRSS | Description asHtml | file: or tiddlywiki.bidix.info |
    +| [[Le Monde]] | Description asText | file: or tiddlywiki.bidix.info using proxy |
    +| YahooNewsSport | Description asHtml | file: or tiddlywiki.bidix.info using proxy |
    +| TiddlyWikiRSS | Description asHtml | file: or tiddlywiki.bidix.info using proxy |
    +| [[Libération]] | noDesc | file: or tiddlywiki.bidix.info using proxy |
    +| [[TestComment]] | asText and filters | file: or tiddlywiki.bidix.info using proxy |
    +see : <<tag RSSFeed>> for the full list.
    +
    +!Revision history
    +* V1.1.0 (2207/04/13)
    +**No more import functions
    +* V1.0.0 (2006/11/11)
    +**refactoring using core loadRemoteFile function
    +**import using new tiddlywiki:tiddler element
    +**import and presentation preserved without EricShulman's NestedSliderPlugin
    +**better display of items 
    +* v0.3.0 (24/08/2006)
    +** Filter on RSS item title
    +** Place to display redefined for asynchronous processing
    +* v0.2.2 (22/08/2006)
    +**Haloscan feed has no pubDate.
    +* v0.2.1 (08/05/2006)
    +* v0.2.0 (01/05/2006)
    +**Small adapations for del.icio.us feed
    +* v0.1.1 (28/04/2006)
    +**Bug : Channel without title 
    +* v0.1.0 (24/04/2006)
    +** initial release
    +
    +
    +
    +
    +
    +
    Dependencies and Style
    +
    +
    +
    Compatibility
    +
    +
    +
    Lumiera expects a 'standard' desktop installation running a Xserver.
    +
    +
    +
    +
    /***
    +
    +''Inspired by [[TiddlyPom|http://www.warwick.ac.uk/~tuspam/tiddlypom.html]]''
    +
    +|Name|SplashScreenPlugin|
    +|Created by|SaqImtiaz|
    +|Location|http://tw.lewcid.org/#SplashScreenPlugin|
    +|Version|0.21 |
    +|Requires|~TW2.08+|
    +!Description:
    +Provides a simple splash screen that is visible while the TW is loading.
    +
    +!Installation
    +Copy the source text of this tiddler to your TW in a new tiddler, tag it with systemConfig and save and reload. The SplashScreen will now be installed and will be visible the next time you reload your TW.
    +
    +!Customizing
    +Once the SplashScreen has been installed and you have reloaded your TW, the splash screen html will be present in the MarkupPreHead tiddler. You can edit it and customize to your needs.
    +
    +!History
    +* 20-07-06 : version 0.21, modified to hide contentWrapper while SplashScreen is displayed.
    +* 26-06-06 : version 0.2, first release
    +
    +!Code
    +***/
    +//{{{
    +var old_lewcid_splash_restart=restart;
    +
    +restart = function()
    +{   if (document.getElementById("SplashScreen"))
    +        document.getElementById("SplashScreen").style.display = "none";
    +      if (document.getElementById("contentWrapper"))
    +        document.getElementById("contentWrapper").style.display = "block";
    +    
    +    old_lewcid_splash_restart();
    +   
    +    if (splashScreenInstall)
    +       {if(config.options.chkAutoSave)
    +			{saveChanges();}
    +        displayMessage("TW SplashScreen has been installed, please save and refresh your TW.");
    +        }
    +}
    +
    +
    +var oldText = store.getTiddlerText("MarkupPreHead");
    +if (oldText.indexOf("SplashScreen")==-1)
    +   {var siteTitle = store.getTiddlerText("SiteTitle");
    +   var splasher='\n\n<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>'+siteTitle +'</b> is loading<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Requires Javascript.</span></div>';
    +   if (! store.tiddlerExists("MarkupPreHead"))
    +       {var myTiddler = store.createTiddler("MarkupPreHead");}
    +   else
    +      {var myTiddler = store.getTiddler("MarkupPreHead");}
    +      myTiddler.set(myTiddler.title,oldText+splasher,config.options.txtUserName,null,null);
    +      store.setDirty(true);
    +      var splashScreenInstall = true;
    +}
    +//}}}
    +
    +
    +
    ! Source code formatting
    +http://www.gnu.org/prep/standards/html_node/Formatting.html#Formatting
    +
    +! Contibuting
    +
    +! Tests
    +
    +
    +
    +
    /*{{{*/
    +/* a contrasting background so I can see where one tiddler ends and the other begins */
    +body {
    +	background: [[ColorPalette::TertiaryLight]];
    +}
    +
    +/* sexy colours and font for the header */
    +.headerForeground {
    +	color: [[ColorPalette::PrimaryPale]];
    +}
    +.headerShadow, .headerShadow a {
    +	color: [[ColorPalette::PrimaryMid]];
    +}
    +.headerForeground, .headerShadow {
    +	padding: 1em 1em 0;
    +	font-family: 'Trebuchet MS' sans-serif;
    +	font-weight:bold;
    +}
    +.headerForeground .siteSubtitle {
    +	color: [[ColorPalette::PrimaryLight]];
    +}
    +.headerShadow .siteSubtitle {
    +	color: [[ColorPalette::PrimaryMid]];
    +}
    +
    +/* make shadow go and down right instead of up and left */
    +.headerShadow {
    +	left: 2px;
    +	top: 3px;
    +}
    +
    +/* prefer monospace for editing */
    +.editor textarea {
    +	font-family: 'Consolas' monospace;
    +}
    +
    +/* sexy tiddler titles */
    +.title {
    +	font-size: 250%;
    +	color: [[ColorPalette::PrimaryLight]];
    +	font-family: 'Trebuchet MS' sans-serif;
    +}
    +
    +/* more subtle tiddler subtitle */
    +.subtitle {
    +	padding:0px;
    +	margin:0px;
    +	padding-left:0.5em;
    +	font-size: 90%;
    +	color: [[ColorPalette::TertiaryMid]];
    +}
    +.subtitle .tiddlyLink {
    +	color: [[ColorPalette::TertiaryMid]];
    +}
    +
    +/* a little bit of extra whitespace */
    +.viewer {
    +	padding-bottom:3px;
    +}
    +
    +/* don't want any background color for headings */
    +h1,h2,h3,h4,h5,h6 {
    +	background: [[ColorPalette::Background]];
    +	color: [[ColorPalette::Foreground]];
    +}
    +
    +/* give tiddlers 3d style border and explicit background */
    +.tiddler {
    +	background: [[ColorPalette::Background]];
    +	border-right: 2px [[ColorPalette::TertiaryMid]] solid;
    +	border-bottom: 2px [[ColorPalette::TertiaryMid]] solid;
    +	margin-bottom: 1em;
    +	padding-bottom: 2em;
    +}
    +
    +/* make options slider look nicer */
    +#sidebarOptions .sliderPanel {
    +	border:solid 1px [[ColorPalette::PrimaryLight]];
    +}
    +
    +
    +/* the borders look wrong with the body background */
    +#sidebar .button {
    +	border-style: none;
    +}
    +
    +/* displays the list of a tiddler's tags horizontally. used in ViewTemplate */
    +.tagglyTagged li.listTitle {
    +	display:none
    +}
    +.tagglyTagged li {
    +	display: inline; font-size:90%;
    +}
    +.tagglyTagged ul {
    +	margin:0px; padding:0px;
    +}
    +
    +/* this means you can put line breaks in SidebarOptions for readability */
    +#sidebarOptions br {
    +	display:none;
    +}
    +/* undo the above in OptionsPanel */
    +#sidebarOptions .sliderPanel br {
    +	display:inline;
    +}
    +
    +/* horizontal main menu stuff */
    +#displayArea {
    +	margin: 1em 15.7em 0em 1em; /* use the freed up space */
    +}
    +#topMenu br {
    +	display: none;
    +}
    +#topMenu {
    +	background: [[ColorPalette::PrimaryMid]];
    +	color:[[ColorPalette::PrimaryPale]];
    +}
    +#topMenu {
    +	padding:2px;
    +}
    +#topMenu .button, #topMenu .tiddlyLink, #topMenu a {
    +	margin-left: 0.5em;
    +	margin-right: 0.5em;
    +	padding-left: 3px;
    +	padding-right: 3px;
    +	color: [[ColorPalette::PrimaryPale]];
    +	font-size: 115%;
    +}
    +#topMenu .button:hover, #topMenu .tiddlyLink:hover {
    +	background: [[ColorPalette::PrimaryDark]];
    +}
    +
    +/* make it print a little cleaner */
    +@media print {
    +	#topMenu {
    +		display: none ! important;
    +	}
    +	/* not sure if we need all the importants */
    +	.tiddler {
    +		border-style: none ! important;
    +		margin:0px ! important;
    +		padding:0px ! important;
    +		padding-bottom:2em ! important;
    +	}
    +	.tagglyTagging .button, .tagglyTagging .hidebutton {
    +		display: none ! important;
    +	}
    +	.headerShadow {
    +		visibility: hidden ! important;
    +	}
    +	.tagglyTagged .quickopentag, .tagged .quickopentag {
    +		border-style: none ! important;
    +	}
    +	.quickopentag a.button, .miniTag {
    +		display: none ! important;
    +	}
    +}
    +/*}}}*/
    +
    +
    +
    +
    <<timeline better:true maxDays:14 maxEntries:20>>
    +
    +
    +
    /***
    +|Name|TaskMacroPlugin|
    +|Author|<<extension TaskMacroPlugin author>>|
    +|Location|<<extension TaskMacroPlugin source>>|
    +|License|<<extension TaskMacroPlugin license>>|
    +|Version|<<extension TaskMacroPlugin versionAndDate>>|
    +!Description
    +A set of macros to help you keep track of time estimates for tasks.
    +
    +Macros defined:
    +* {{{task}}}: Displays a task description and makes it easy to estimate and track the time spent on the task.
    +* {{{taskadder}}}: Displays text entry field to simplify the adding of tasks.
    +* {{{tasksum}}}: Displays a summary of tasks sandwiched between two calls to this macro.
    +* {{{extension}}}: A simple little macro that displays information about a TiddlyWiki plugin, and that will hopefully someday migrate to the TW core in some form.
    +Core overrides:
    +* {{{wikify}}}: when wikifying a tiddler's complete text, adds refresh information so the tiddler will be refreshed when it changes
    +* {{{config.refreshers}}}: have the built-in refreshers return true; also, add a new refresher ("fullContent") that redisplays a full tiddler whenever it or any nested tiddlers it shows are changed
    +* {{{refreshElements}}}: now checks the return value from the refresher and only short-circuits the recursion if the refresher returns true
    +!Plugin Information
    +***/
    +//{{{
    +version.extensions.TaskMacroPlugin = {
    +	major: 1, minor: 1, revision: 0,
    +	date: new Date(2006,5-1,13),
    +	author: "LukeBlanshard",
    +	source: "http://labwiki.sourceforge.net/#TaskMacroPlugin",
    +	license: "http://labwiki.sourceforge.net/#CopyrightAndLicense"
    +}
    +//}}}
    +/***
    +A little macro for pulling out extension info.  Use like {{{<<extension PluginName datum>>}}}, where {{{PluginName}}} is the name you used for {{{version.extensions}}} and {{{datum}}} is either {{{versionAndDate}}} or a property of the extension description object, such as {{{source}}}.
    +***/
    +//{{{
    +config.macros.extension = {
    +	handler: function( place, macroName, params, wikifier, paramString, tiddler ) {
    +		var info  = version.extensions[params[0]]
    +		var datum = params[1]
    +		switch (params[1]) {
    +		case 'versionAndDate':
    +			createTiddlyElement( place, "span", null, null,
    +				info.major+'.'+info.minor+'.'+info.revision+', '+info.date.formatString('DD MMM YYYY') )
    +			break;
    +		default:
    +			wikify( info[datum], place )
    +			break;
    +		}
    +	}
    +}
    +//}}}
    +/***
    +!Core Overrides
    +***/
    +//{{{
    +window.wikify_orig_TaskMacroPlugin = window.wikify
    +window.wikify = function(source,output,highlightRegExp,tiddler)
    +{
    +	if ( tiddler && tiddler.text === source )
    +		addDisplayDependency( output, tiddler.title )
    +	wikify_orig_TaskMacroPlugin.apply( this, arguments )
    +}
    +config.refreshers_orig_TaskMacroPlugin = config.refreshers
    +config.refreshers = {
    +	link: function() {
    +		config.refreshers_orig_TaskMacroPlugin.link.apply( this, arguments )
    +		return true
    +	},
    +	content: function() {
    +		config.refreshers_orig_TaskMacroPlugin.content.apply( this, arguments )
    +		return true
    +	},
    +	fullContent: function( e, changeList ) {
    +		var tiddlers = e.refreshTiddlers
    +		if ( changeList == null || tiddlers == null )
    +			return false
    +		for ( var i=0; i < tiddlers.length; ++i )
    +			if ( changeList.find(tiddlers[i]) != null ) {
    +				var title = tiddlers[0]
    +				story.refreshTiddler( title, null, true )
    +				return true
    +			}
    +		return false
    +	}
    +}
    +function refreshElements(root,changeList)
    +{
    +	var nodes = root.childNodes;
    +	for(var c=0; c<nodes.length; c++)
    +		{
    +		var e = nodes[c],type;
    +		if(e.getAttribute)
    +			type = e.getAttribute("refresh");
    +		else
    +			type = null;
    +		var refresher = config.refreshers[type];
    +		if ( ! refresher || ! refresher(e, changeList) )
    +			{
    +			if(e.hasChildNodes())
    +				refreshElements(e,changeList);
    +			}
    +		}
    +}
    +//}}}
    +/***
    +!Global Functions
    +***/
    +//{{{
    +// Add the tiddler whose title is given to the list of tiddlers whose
    +// changing will cause a refresh of the tiddler containing the given element.
    +function addDisplayDependency( element, title ) {
    +	while ( element && element.getAttribute ) {
    +		var idAttr = element.getAttribute("id"), tiddlerAttr = element.getAttribute("tiddler")
    +		if ( idAttr && tiddlerAttr && idAttr == story.idPrefix+tiddlerAttr ) {
    +			var list = element.refreshTiddlers
    +			if ( list == null ) {
    +				list = [tiddlerAttr]
    +				element.refreshTiddlers = list
    +				element.setAttribute( "refresh", "fullContent" )
    +			}
    +			list.pushUnique( title )
    +			return
    +		}
    +		element = element.parentNode
    +	}
    +}
    +
    +// Lifted from Story.prototype.focusTiddler: just return the field instead of focusing it.
    +Story.prototype.findEditField = function( title, field )
    +{
    +	var tiddler = document.getElementById(this.idPrefix + title);
    +	if(tiddler != null)
    +		{
    +		var children = tiddler.getElementsByTagName("*")
    +		var e = null;
    +		for (var t=0; t<children.length; t++)
    +			{
    +			var c = children[t];
    +			if(c.tagName.toLowerCase() == "input" || c.tagName.toLowerCase() == "textarea")
    +				{
    +				if(!e)
    +					e = c;
    +				if(c.getAttribute("edit") == field)
    +					e = c;
    +				}
    +			}
    +		return e
    +		}
    +}
    +
    +// Wraps the given event function in another function that handles the
    +// event in a standard way.
    +function wrapEventHandler( otherHandler ) {
    +	return function(e) {
    +		if (!e) var e = window.event
    +		e.cancelBubble = true
    +		if (e.stopPropagation) e.stopPropagation()
    +		return otherHandler( e )
    +	}
    +}
    +//}}}
    +/***
    +!Task Macro
    +Usage:
    +> {{{<<task orig cur spent>>description}}}
    +All of orig, cur, and spent are optional numbers of hours.  The description goes through the end of the line, and is wikified.
    +***/
    +//{{{
    +config.macros.task = {
    +	NASCENT:	0, // Task not yet estimated
    +	LIVE:		1, // Estimated but with time remaining
    +	DONE:		2, // Completed: no time remaining
    +	bullets:	["\u25cb", // nascent (open circle)
    +			 "\u25ba", // live (right arrow)
    +			 "\u25a0"],// done (black square)
    +	styles:		["nascent", "live", "done"],
    +
    +	// Translatable text:
    +	lingo: {
    +		spentTooBig:	"Spent time %0 can't exceed current estimate %1",
    +		noNegative:	"Times may not be negative numbers",
    +		statusTips:	["Not yet estimated", "To do", "Done"], // Array indexed by state (NASCENT/LIVE/DONE)
    +		descClickTip:	" -- Double-click to edit task description",
    +		statusClickTip:	" -- Double-click to mark task complete",
    +		statusDoneTip:	" -- Double-click to adjust the time spent, to revive the task",
    +		origTip:	"Original estimate in hours",
    +		curTip:		"Current estimate in hours",
    +		curTip2:	"Estimate in hours", // For when orig == cur
    +		clickTip:	" -- Click to adjust",
    +		spentTip:	"Hours spent on this task",
    +		remTip:		"Hours remaining",
    +		curPrompt:	"Estimate this task in hours, or adjust the current estimate by starting with + or -.\n\nYou may optionally also set or adjust the time spent by putting a second number after the first.",
    +		spentPrompt:	"Enter the number of hours you've spent on this task, or adjust the current number by starting with + or -.\n\nYou may optionally also set or adjust the time remaining by putting a second number after the first.",
    +		remPrompt:	"Enter the number of hours it will take to finish this task, or adjust the current estimate by starting with + or -.\n\nYou may optionally also set or adjust the time spent by putting a second number after the first.",
    +		numbersOnly:	"Enter numbers only, please",
    +		notCurrent:	"The tiddler has been modified since it was displayed, please redisplay it before doing this."
    +	},
    +
    +	// The macro handler
    +	handler: function( place, macroName, params, wikifier, paramString, tiddler )
    +	{
    +		var start = wikifier.matchStart, end = wikifier.nextMatch
    +
    +		var origStr	= params.length > 0? params.shift() : "?"
    +		var orig	= +origStr // as a number
    +		var cur		= params.length > 1? +params.shift() : orig
    +		var spent	= params.length > 0? +params.shift() : 0
    +		if ( spent > cur )
    +			throw Error( this.lingo.spentTooBig.format([spent, cur]) )
    +		if ( orig < 0 || cur < 0 || spent < 0 )
    +			throw Error( this.lingo.noNegative )
    +		var rem		= cur - spent
    +		var state	= isNaN(orig+rem)? this.NASCENT : rem > 0? this.LIVE : this.DONE
    +		var table	= createTiddlyElement( place, "table", null, "task "+this.styles[state] )
    +		var tbody	= createTiddlyElement( table, "tbody" )
    +		var row		= createTiddlyElement( tbody, "tr" )
    +		var statusCell	= createTiddlyElement( row,   "td", null, "status", this.bullets[state] )
    +		var descCell	= createTiddlyElement( row,   "td", null, "description" )
    +
    +		var origCell	= state==this.NASCENT || orig==cur? null
    +				: createTiddlyElement( row, "td", null, "numeric original" )
    +		var curCell	= createTiddlyElement( row, "td", null, "numeric current" )
    +		var spentCell	= createTiddlyElement( row, "td", null, "numeric spent" )
    +		var remCell	= createTiddlyElement( row, "td", null, "numeric remaining" )
    +
    +		var sums = config.macros.tasksum.tasksums
    +		if ( sums && sums.length ) {
    +			var summary = [(state == this.NASCENT? NaN : orig), cur, spent]
    +			summary.owner = tiddler
    +			sums[0].push( summary )
    +		}
    +
    +		// The description goes to the end of the line
    +		wikifier.subWikify( descCell, "$\\n?" )
    +		var descEnd = wikifier.nextMatch
    +
    +		statusCell.setAttribute( "title", this.lingo.statusTips[state] )
    +		descCell.setAttribute(   "title", this.lingo.statusTips[state]+this.lingo.descClickTip )
    +		if (origCell) {
    +			createTiddlyElement( origCell, "div", null, null, orig )
    +			origCell.setAttribute( "title", this.lingo.origTip )
    +			curCell.setAttribute( "title", this.lingo.curTip )
    +		}
    +		else {
    +			curCell.setAttribute( "title", this.lingo.curTip2 )
    +		}
    +		var curDivContents = (state==this.NASCENT)? "?" : cur
    +		var curDiv = createTiddlyElement( curCell, "div", null, null, curDivContents )
    +		spentCell.setAttribute( "title", this.lingo.spentTip )
    +		var spentDiv = createTiddlyElement( spentCell, "div", null, null, spent )
    +		remCell.setAttribute( "title", this.lingo.remTip )
    +		var remDiv = createTiddlyElement( remCell, "div", null, null, rem )
    +
    +		// Handle double-click on the description by going
    +		// into edit mode and selecting the description
    +		descCell.ondblclick = this.editDescription( tiddler, end, descEnd )
    +
    +		function appTitle( el, suffix ) {
    +			el.setAttribute( "title", el.getAttribute("title")+suffix )
    +		}
    +
    +		// For incomplete tasks, handle double-click on the bullet by marking the task complete
    +		if ( state != this.DONE ) {
    +			appTitle( statusCell, this.lingo.statusClickTip )
    +			statusCell.ondblclick = this.markTaskComplete( tiddler, start, end, macroName, orig, cur, state )
    +		}
    +		// For complete ones, handle double-click on the bullet by letting you adjust the time spent
    +		else {
    +			appTitle( statusCell, this.lingo.statusDoneTip )
    +			statusCell.ondblclick = this.adjustTimeSpent( tiddler, start, end, macroName, orig, cur, spent )
    +		}
    +
    +		// Add click handlers for the numeric cells.
    +		if ( state != this.DONE ) {
    +			appTitle( curCell, this.lingo.clickTip )
    +			curDiv.className = "adjustable"
    +			curDiv.onclick = this.adjustCurrentEstimate( tiddler, start, end, macroName,
    +				orig, cur, spent, curDivContents )
    +		}
    +		appTitle( spentCell, this.lingo.clickTip )
    +		spentDiv.className = "adjustable"
    +		spentDiv.onclick = this.adjustTimeSpent( tiddler, start, end, macroName, orig, cur, spent )
    +		if ( state == this.LIVE ) {
    +			appTitle( remCell, this.lingo.clickTip )
    +			remDiv.className = "adjustable"
    +			remDiv.onclick = this.adjustTimeRemaining( tiddler, start, end, macroName, orig, cur, spent )
    +		}
    +	},
    +
    +	// Puts the tiddler into edit mode, and selects the range of characters
    +	// defined by start and end.  Separated for leak prevention in IE.
    +	editDescription: function( tiddler, start, end ) {
    +		return wrapEventHandler( function(e) {
    +			story.displayTiddler( null, tiddler.title, DEFAULT_EDIT_TEMPLATE )
    +			var tiddlerElement = document.getElementById( story.idPrefix + tiddler.title )
    +			window.scrollTo( 0, ensureVisible(tiddlerElement) )
    +			var element = story.findEditField( tiddler.title, "text" )
    +			if ( element && element.tagName.toLowerCase() == "textarea" ) {
    +				// Back up one char if the last char's a newline
    +				if ( tiddler.text[end-1] == '\n' )
    +					--end
    +				element.focus()
    +				if ( element.setSelectionRange != undefined ) { // Mozilla
    +					element.setSelectionRange( start, end )
    +					// Damn mozilla doesn't scroll to visible.  Approximate.
    +					var max = 0.0 + element.scrollHeight
    +					var len = element.textLength
    +					var top = max*start/len, bot = max*end/len
    +					element.scrollTop = Math.min( top, (bot+top-element.clientHeight)/2 )
    +				}
    +				else if ( element.createTextRange != undefined ) { // IE
    +					var range = element.createTextRange()
    +					range.collapse()
    +					range.moveEnd("character", end)
    +					range.moveStart("character", start)
    +					range.select()
    +				}
    +				else // Other? Too bad, just select the whole thing.
    +					element.select()
    +				return false
    +			}
    +			else
    +				return true
    +		} )
    +	},
    +
    +	// Modifies a task macro call such that the task appears complete.
    +	markTaskComplete: function( tiddler, start, end, macroName, orig, cur, state ) {
    +		var macro = this, text = tiddler.text
    +		return wrapEventHandler( function(e) {
    +			if ( text !== tiddler.text ) {
    +				alert( macro.lingo.notCurrent )
    +				return false
    +			}
    +			if ( state == macro.NASCENT )
    +				orig = cur = 0
    +			// The second "cur" in the call below bumps up the time spent
    +			// to match the current estimate.
    +			macro.replaceMacroCall( tiddler, start, end, macroName, orig, cur, cur )
    +			return false
    +		} )
    +	},
    +
    +	// Asks the user for an adjustment to the current estimate, modifies the macro call accordingly.
    +	adjustCurrentEstimate: function( tiddler, start, end, macroName, orig, cur, spent, curDivContents ) {
    +		var macro = this, text = tiddler.text
    +		return wrapEventHandler( function(e) {
    +			if ( text !== tiddler.text ) {
    +				alert( macro.lingo.notCurrent )
    +				return false
    +			}
    +			var txt = prompt( macro.lingo.curPrompt, curDivContents )
    +			if ( txt != null ) {
    +				var a = macro.breakInput( txt )
    +				cur = macro.offset( cur, a[0] )
    +				if ( a.length > 1 )
    +					spent = macro.offset( spent, a[1] )
    +				macro.replaceMacroCall( tiddler, start, end, macroName, orig, cur, spent )
    +			}
    +			return false
    +		} )
    +	},
    +
    +	// Asks the user for an adjustment to the time spent, modifies the macro call accordingly.
    +	adjustTimeSpent: function( tiddler, start, end, macroName, orig, cur, spent ) {
    +		var macro = this, text = tiddler.text
    +		return wrapEventHandler( function(e) {
    +			if ( text !== tiddler.text ) {
    +				alert( macro.lingo.notCurrent )
    +				return false
    +			}
    +			var txt = prompt( macro.lingo.spentPrompt, spent )
    +			if ( txt != null ) {
    +				var a = macro.breakInput( txt )
    +				spent = macro.offset( spent, a[0] )
    +				var rem = cur - spent
    +				if ( a.length > 1 ) {
    +					rem = macro.offset( rem, a[1] )
    +					cur = spent + rem
    +				}
    +				macro.replaceMacroCall( tiddler, start, end, macroName, orig, cur, spent )
    +			}
    +			return false
    +		} )
    +	},
    +
    +	// Asks the user for an adjustment to the time remaining, modifies the macro call accordingly.
    +	adjustTimeRemaining: function( tiddler, start, end, macroName, orig, cur, spent ) {
    +		var macro = this
    +		var text  = tiddler.text
    +		var rem   = cur - spent
    +		return wrapEventHandler( function(e) {
    +			if ( text !== tiddler.text ) {
    +				alert( macro.lingo.notCurrent )
    +				return false
    +			}
    +			var txt = prompt( macro.lingo.remPrompt, rem )
    +			if ( txt != null ) {
    +				var a = macro.breakInput( txt )
    +				var newRem = macro.offset( rem, a[0] )
    +				if ( newRem > rem || a.length > 1 )
    +					cur += (newRem - rem)
    +				else
    +					spent += (rem - newRem)
    +				if ( a.length > 1 )
    +					spent = macro.offset( spent, a[1] )
    +				macro.replaceMacroCall( tiddler, start, end, macroName, orig, cur, spent )
    +			}
    +			return false
    +		} )
    +	},
    +
    +	// Breaks input at spaces & commas, returns array
    +	breakInput: function( txt ) {
    +		var a = txt.trim().split( /[\s,]+/ )
    +		if ( a.length == 0 )
    +			a = [NaN]
    +		return a
    +	},
    +
    +	// Adds to, subtracts from, or replaces a numeric value
    +	offset: function( num, txt ) {
    +		if ( txt == "" || typeof(txt) != "string" )
    +			return NaN
    +		if ( txt.match(/^[+-]/) )
    +			return num + (+txt)
    +		return +txt
    +	},
    +
    +	// Does some error checking, then replaces the indicated macro
    +	// call within the text of the given tiddler.
    +	replaceMacroCall: function( tiddler, start, end, macroName, orig, cur, spent )
    +	{
    +		if ( isNaN(cur+spent) ) {
    +			alert( this.lingo.numbersOnly )
    +			return
    +		}
    +		if ( spent < 0 || cur < 0 ) {
    +			alert( this.lingo.noNegative )
    +			return
    +		}
    +		if ( isNaN(orig) )
    +			orig = cur
    +		if ( spent > cur )
    +			cur = spent
    +		var text = tiddler.text.substring(0,start) + "<<" + macroName + " " +
    +			orig + " " + cur + " " + spent + ">>" + tiddler.text.substring(end)
    +		var title = tiddler.title
    +		store.saveTiddler( title, title, text, config.options.txtUserName, new Date(), undefined )
    +		//story.refreshTiddler( title, null, true )
    +		if ( config.options.chkAutoSave )
    +			saveChanges()
    +	}
    +}
    +//}}}
    +/***
    +!Tasksum Macro
    +Usage:
    +> {{{<<tasksum "start" ["here" [intro]]>>}}}
    +or:
    +> {{{<<tasksum "end" [intro]>>}}}
    +Put one of the {{{<<tasksum start>>}}} lines before the tasks you want to summarize, and an {{{end}}} line after them.  By default, the summary goes at the end; if you include {{{here}}} in the start line, the summary will go at the top.  The intro argument, if supplied, replaces the default text introducing the summary.
    +***/
    +//{{{
    +config.macros.tasksum = {
    +
    +	// Translatable text:
    +	lingo: {
    +		unrecVerb:	"<<%0>> requires 'start' or 'end' as its first argument",
    +		mustMatch:	"<<%0 end>> must match a preceding <<%0 start>>",
    +		defIntro:	"Task summary:",
    +		nascentSum:	"''%0 not estimated''",
    +		doneSum:	"%0 complete (in %1 hours)",
    +		liveSum:	"%0 ongoing (%1 hours so far, ''%2 hours remaining'')",
    +		overSum:	"Total overestimate: %0%.",
    +		underSum:	"Total underestimate: %0%.",
    +		descPattern:	"%0 %1. %2",
    +                origTip:	"Total original estimates in hours",
    +		curTip:		"Total current estimates in hours",
    +		spentTip:	"Total hours spent on tasks",
    +		remTip:		"Total hours remaining"
    +	},
    +
    +	// The macro handler
    +	handler: function( place, macroName, params, wikifier, paramString, tiddler )
    +	{
    +		var sums = this.tasksums
    +		if ( params[0] == "start" ) {
    +			sums.unshift([])
    +			if ( params[1] == "here" ) {
    +				sums[0].intro = params[2] || this.lingo.defIntro
    +				sums[0].place = place
    +				sums[0].placement = place.childNodes.length
    +			}
    +		}
    +		else if ( params[0] == "end" ) {
    +			if ( ! sums.length )
    +				throw Error( this.lingo.mustMatch.format([macroName]) )
    +			var list = sums.shift()
    +			var intro = list.intro || params[1] || this.lingo.defIntro
    +			var nNascent=0, nLive=0, nDone=0, nMine=0
    +			var totLiveSpent=0, totDoneSpent=0
    +			var totOrig=0, totCur=0, totSpent=0
    +			for ( var i=0; i < list.length; ++i ) {
    +				var a = list[i]
    +				if ( a.length > 3 ) {
    +					nNascent 	+= a[0]
    +					nLive 		+= a[1]
    +					nDone 		+= a[2]
    +					totLiveSpent 	+= a[3]
    +					totDoneSpent 	+= a[4]
    +					totOrig 	+= a[5]
    +					totCur 		+= a[6]
    +					totSpent 	+= a[7]
    +					if ( a.owner == tiddler )
    +						nMine	+= a[8]
    +				}
    +				else {
    +					if ( a.owner == tiddler )
    +						++nMine
    +					if ( isNaN(a[0]) ) {
    +						++nNascent
    +					}
    +					else {
    +						if ( a[1] > a[2] ) {
    +							++nLive
    +							totLiveSpent += a[2]
    +						}
    +						else {
    +							++nDone
    +							totDoneSpent += a[2]
    +						}
    +						totOrig  += a[0]
    +						totCur   += a[1]
    +						totSpent += a[2]
    +					}
    +				}
    +			}
    +
    +			// If we're nested, push a summary outward
    +                        if ( sums.length ) {
    +				var summary = [nNascent, nLive, nDone, totLiveSpent, totDoneSpent,
    +						totOrig, totCur, totSpent, nMine]
    +				summary.owner = tiddler
    +				sums[0].push( summary )
    +			}
    +
    +			var descs = [], styles = []
    +			if ( nNascent > 0 ) {
    +				descs.push( this.lingo.nascentSum.format([nNascent]) )
    +				styles.push( "nascent" )
    +			}
    +			if ( nDone > 0 )
    +				descs.push( this.lingo.doneSum.format([nDone, totDoneSpent]) )
    +			if ( nLive > 0 ) {
    +				descs.push( this.lingo.liveSum.format([nLive, totLiveSpent, totCur-totSpent]) )
    +				styles.push( "live" )
    +			}
    +			else
    +				styles.push( "done" )
    +			var off = ""
    +			if ( totOrig > totCur )
    +				off = this.lingo.overSum.format( [Math.round(100.0*(totOrig-totCur)/totCur)] )
    +			else if ( totCur > totOrig )
    +				off = this.lingo.underSum.format( [Math.round(100.0*(totCur-totOrig)/totOrig)] )
    +
    +			var top		= (list.intro != undefined)
    +			var table	= createTiddlyElement( null, "table", null, "tasksum "+(top?"top":"bottom") )
    +			var tbody	= createTiddlyElement( table, "tbody" )
    +			var row		= createTiddlyElement( tbody, "tr", null, styles.join(" ") )
    +			var descCell	= createTiddlyElement( row,   "td", null, "description" )
    +
    +			var description = this.lingo.descPattern.format( [intro, descs.join(", "), off] )
    +			wikify( description, descCell, null, tiddler )
    +
    +			var origCell	= totOrig == totCur? null
    +					: createTiddlyElement( row, "td", null, "numeric original", totOrig )
    +			var curCell	= createTiddlyElement( row, "td", null, "numeric current", totCur )
    +			var spentCell	= createTiddlyElement( row, "td", null, "numeric spent", totSpent )
    +			var remCell	= createTiddlyElement( row, "td", null, "numeric remaining", totCur-totSpent )
    +
    +			if ( origCell )
    +				origCell.setAttribute( "title", this.lingo.origTip )
    +			curCell  .setAttribute( "title", this.lingo.curTip )
    +			spentCell.setAttribute( "title", this.lingo.spentTip )
    +			remCell  .setAttribute( "title", this.lingo.remTip )
    +
    +			// Discard the table if there are no tasks
    +			if ( list.length > 0 ) {
    +				var place = top? list.place : place
    +				var placement = top? list.placement : place.childNodes.length
    +				if ( placement >= place.childNodes.length )
    +					place.appendChild( table )
    +				else
    +					place.insertBefore( table, place.childNodes[placement] )
    +			}
    +		}
    +		else
    +			throw Error( this.lingo.unrecVerb.format([macroName]) )
    +
    +		// If we're wikifying, and are followed by end-of-line, swallow the newline.
    +		if ( wikifier && wikifier.source.charAt(wikifier.nextMatch) == "\n" )
    +			++wikifier.nextMatch
    +	},
    +
    +	// This is the stack of pending summaries
    +	tasksums: []
    +}
    +//}}}
    +/***
    +!Taskadder Macro
    +Usage:
    +> {{{<<taskadder ["above"|"below"|"focus"|"nofocus"]...>>}}}
    +Creates a line with text entry fields for a description and an estimate.  By default, puts focus in the description field and adds tasks above the entry fields.  Use {{{nofocus}}} to not put focus in the description field.  Use {{{below}}} to add tasks below the entry fields.
    +***/
    +//{{{
    +config.macros.taskadder = {
    +
    +	// Translatable text:
    +	lingo: {
    +		unrecParam:	"<<%0>> doesn't recognize '%1' as a parameter",
    +		descTip:	"Describe a new task",
    +		curTip:		"Estimate how long in hours the task will take",
    +		buttonText:	"add task",
    +		buttonTip:	"Add a new task with the description and estimate as entered",
    +		notCurrent:	"The tiddler has been modified since it was displayed, please redisplay it before adding a task this way.",
    +
    +		eol:		"eol"
    +	},
    +
    +	// The macro handler
    +	handler: function( place, macroName, params, wikifier, paramString, tiddler )
    +	{
    +		var above = true
    +		var focus = false
    +
    +		while ( params.length > 0 ) {
    +			var p = params.shift()
    +			switch (p) {
    +			case "above": 	above = true;  break
    +			case "below": 	above = false; break
    +			case "focus": 	focus = true;  break
    +			case "nofocus":	focus = false; break
    +			default:	throw Error( this.lingo.unrecParam.format([macroName, p]) )
    +			}
    +		}
    +
    +		// If we're followed by end-of-line, swallow the newline.
    +		if ( wikifier.source.charAt(wikifier.nextMatch) == "\n" )
    +			++wikifier.nextMatch
    +
    +		var where	= above? wikifier.matchStart : wikifier.nextMatch
    +
    +		var table	= createTiddlyElement( place, "table", null, "task" )
    +		var tbody	= createTiddlyElement( table, "tbody" )
    +		var row		= createTiddlyElement( tbody, "tr" )
    +		var statusCell	= createTiddlyElement( row,   "td", null, "status" )
    +		var descCell	= createTiddlyElement( row,   "td", null, "description" )
    +		var curCell	= createTiddlyElement( row,   "td", null, "numeric" )
    +		var addCell	= createTiddlyElement( row,   "td", null, "addtask" )
    +
    +		var descId	= this.generateId()
    +		var curId	= this.generateId()
    +		var descInput	= createTiddlyElement( descCell, "input", descId )
    +		var curInput	= createTiddlyElement( curCell,  "input", curId  )
    +
    +		descInput.setAttribute( "type", "text" )
    +		curInput .setAttribute( "type", "text" )
    +		descInput.setAttribute( "size", "40")
    +		curInput .setAttribute( "size", "6" )
    +		descInput.setAttribute( "autocomplete", "off" );
    +		curInput .setAttribute( "autocomplete", "off" );
    +		descInput.setAttribute( "title", this.lingo.descTip );
    +		curInput .setAttribute( "title", this.lingo.curTip  );
    +
    +		var addAction	= this.addTask( tiddler, where, descId, curId, above )
    +		var addButton	= createTiddlyButton( addCell, this.lingo.buttonText, this.lingo.buttonTip, addAction )
    +
    +		descInput.onkeypress = this.handleEnter(addAction)
    +		curInput .onkeypress = descInput.onkeypress
    +		addButton.onkeypress = this.handleSpace(addAction)
    +		if ( focus || tiddler.taskadderLocation == where ) {
    +			descInput.focus()
    +			descInput.select()
    +		}
    +	},
    +
    +	// Returns a function that inserts a new task macro into the tiddler.
    +	addTask: function( tiddler, where, descId, curId, above ) {
    +		var macro = this, oldText = tiddler.text
    +		return wrapEventHandler( function(e) {
    +			if ( oldText !== tiddler.text ) {
    +				alert( macro.lingo.notCurrent )
    +				return false
    +			}
    +			var desc	= document.getElementById(descId).value
    +			var cur		= document.getElementById(curId) .value
    +			var init	= tiddler.text.substring(0,where) + "<<task " + cur + ">> " + desc + "\n"
    +			var text	= init + tiddler.text.substring(where)
    +			var title	= tiddler.title
    +			tiddler.taskadderLocation = (above? init.length : where)
    +			try {
    +				store.saveTiddler( title, title, text, config.options.txtUserName, new Date(), undefined )
    +				//story.refreshTiddler( title, null, true )
    +			}
    +			finally {
    +				delete tiddler.taskadderLocation
    +			}
    +			if ( config.options.chkAutoSave )
    +				saveChanges()
    +		} )
    +	},
    +
    +	// Returns an event handler that delegates to two other functions: "matches" to decide
    +	// whether to consume the event, and "addTask" to actually perform the work.
    +	handleGeneric: function( addTask, matches ) {
    +		return function(e) {
    +			if (!e) var e = window.event
    +			var consume = false
    +			if ( matches(e) ) {
    +				consume = true
    +				addTask( e )
    +			}
    +			e.cancelBubble = consume;
    +			if ( consume && e.stopPropagation ) e.stopPropagation();
    +			return !consume;
    +		}
    +	},
    +
    +	// Returns an event handler that handles enter keys by calling another event handler
    +	handleEnter: function( addTask ) {
    +		return this.handleGeneric( addTask, function(e){return e.keyCode == 13 || e.keyCode == 10} ) // Different codes for Enter
    +	},
    +
    +	// Returns an event handler that handles the space key by calling another event handler
    +	handleSpace: function( addTask ) {
    +		return this.handleGeneric( addTask, function(e){return (e.charCode||e.keyCode) == 32} )
    +	},
    +
    +	counter: 0,
    +	generateId: function() {
    +		return "taskadder:" + String(this.counter++)
    +	}
    +}
    +//}}}
    +/***
    +!Stylesheet
    +***/
    +//{{{
    +var stylesheet = '\
    +.viewer table.task, table.tasksum {\
    +	width: 100%;\
    +	padding: 0;\
    +	border-collapse: collapse;\
    +}\
    +.viewer table.task {\
    +	border: none;\
    +	margin: 0;\
    +}\
    +table.tasksum, .viewer table.tasksum {\
    +	border: solid 2px #999;\
    +	margin: 3px 0;\
    +}\
    +table.tasksum td {\
    +	text-align: center;\
    +	border: 1px solid #ddd;\
    +	background-color: #ffc;\
    +	vertical-align: middle;\
    +	margin: 0;\
    +	padding: 0;\
    +}\
    +.viewer table.task tr {\
    +	border: none;\
    +}\
    +.viewer table.task td {\
    +	text-align: center;\
    +	vertical-align: baseline;\
    +	border: 1px solid #fff;\
    +	background-color: inherit;\
    +	margin: 0;\
    +	padding: 0;\
    +}\
    +td.numeric {\
    +	width: 3em;\
    +}\
    +table.task td.numeric div {\
    +	border: 1px solid #ddd;\
    +	background-color: #ffc;\
    +	margin: 1px 0;\
    +	padding: 0;\
    +}\
    +table.task td.original div {\
    +	background-color: #fdd;\
    +}\
    +table.tasksum td.original {\
    +	background-color: #fdd;\
    +}\
    +table.tasksum td.description {\
    +	background-color: #e8e8e8;\
    +}\
    +table.task td.status {\
    +	width: 1.5em;\
    +	cursor: default;\
    +}\
    +table.task td.description, table.tasksum td.description {\
    +	width: auto;\
    +	text-align: left;\
    +	padding: 0 3px;\
    +}\
    +table.task.done td.status,table.task.done td.description {\
    +	color: #ccc;\
    +}\
    +table.task.done td.current, table.task.done td.remaining {\
    +	visibility: hidden;\
    +}\
    +table.task.done td.spent div, table.tasksum tr.done td.current,\
    +table.tasksum tr.done td.spent, table.tasksum tr.done td.remaining {\
    +	background-color: #eee;\
    +	color: #aaa;\
    +}\
    +table.task.nascent td.description {\
    +	color: #844;\
    +}\
    +table.task.nascent td.current div, table.tasksum tr.nascent td.numeric.current {\
    +	font-weight: bold;\
    +	color: #c00;\
    +	background-color: #def;\
    +}\
    +table.task.nascent td.spent, table.task.nascent td.remaining {\
    +	visibility: hidden;\
    +}\
    +td.remaining {\
    +	font-weight: bold;\
    +}\
    +.adjustable {\
    +	cursor: pointer; \
    +}\
    +table.task input {\
    +	display: block;\
    +	width: 100%;\
    +	font: inherit;\
    +	margin: 2px 0;\
    +	padding: 0;\
    +	border: 1px inset #999;\
    +}\
    +table.task td.numeric input {\
    +	background-color: #ffc;\
    +	text-align: center;\
    +}\
    +table.task td.addtask {\
    +	width: 6em;\
    +	border-left: 2px solid white;\
    +	vertical-align: middle;\
    +}\
    +'
    +setStylesheet( stylesheet, "TaskMacroPluginStylesheet" )
    +//}}}
    +
    +
    +
    +
    !!Changes in 1.1.0
    +* Made the macros work in nested tiddlers (ie when one tiddler includes another using {{{<<tiddler>>}}} or something similar):
    +** Task summaries in the outer tiddler include the tasks from the inner one
    +** Using the editing shortcuts on the tasks as displayed in the outer tiddler correctly changes the inner tiddler and also redisplays the outer one
    +** Added sanity checks to the editing shortcuts so they will refuse to work if the tiddler has been modified behind their backs
    +* Made some small usability fixes:
    +** The "add task" button now responds to the Space key (hat tip: Daniel Baird)
    +** Double-clicking on a completed task's bullet now does the same thing as clicking on the elapsed time: it lets you adjust the time spent, giving you the option of resurrecting the task (hat tip: ~JackF)
    +** Reworked the focus handling of the taskadder macro so it works more intuitively, by refocusing on the same adder you just used
    +
    +
    +
    +
    The task macro provided by the TaskMacroPlugin is for planning, estimating, and tracking detailed tasks such as those required for writing software.  It is inspired by [[Joel Spolsky|http://www.joelonsoftware.com/articles/fog0000000245.html]]'s method for scheduling software development, also popularized by [[Voo2do|http://voo2do.com]] and [[XPlanner|http://xplanner.org]].
    +
    +For changes since the previous version, see the TaskMacroReleaseNotes.
    +
    +This tutorial leads you through the use of the task macro itself, and supporting macros that summarize lists of tasks and simplify the adding of tasks to a list.  Follow along by clicking the links below.  Or click the little down-arrow next to this tiddler's title, above, and choose "Open all" to have all the tutorial sections displayed at once.
    +
    +
    +
    +
    +
    <!---
    +Includes portions of [[TagglyTaggingViewTemplate|http://simonbaird.com/mptw/#TagglyTaggingViewTemplate]], v1.2 (16-Jan-2006).
    +Also adds a pair of tasksum macros around the tiddler, to summarize any contained tasks at the top.  Removes the "-" in front of closeTiddler, which can easily bite you if you have a focusable element in a tiddler, such as a taskadder entry field.
    +Portions written by Luke Blanshard are hereby released into the public domain.
    +--->
    +<!--{{{-->
    +<div class="toolbar" macro="toolbar closeTiddler closeOthers +editTiddler permalink references jump newHere"></div>
    +<div class="tagglyTagged" macro="tags"></div>
    +<div><span class="title" macro="view title"></span><span class="miniTag" macro="miniTag"></span></div>
    +<div macro="tasksum start here"></div>
    +<div class="viewer" macro="view text wikified"></div>
    +<div macro="tasksum end"></div>
    +<div class="tagglyTagging" macro="tagglyListWithSort"></div>
    +<!--}}}-->
    +
    +
    +
    +
    /***
    +''TextAreaPlugin for TiddlyWiki version 2.0''
    +^^author: Eric Shulman - ELS Design Studios
    +source: http://www.elsdesign.com/tiddlywiki/#TextAreaPlugin
    +license: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^
    +
    +This plugin 'hijacks' the TW core function, ''Story.prototype.focusTiddler()'', so it can add special 'keyDown' handlers to adjust several behaviors associated with the textarea control used in the tiddler editor.  Specifically, it:
    +* Adds text search INSIDE of edit fields.^^
    +Use ~CTRL-F for "Find" (prompts for search text), and ~CTRL-G for "Find Next" (uses previous search text)^^
    +* Enables TAB characters to be entered into field content^^
    +(instead of moving to next field)^^
    +* Option to set cursor at top of edit field instead of auto-selecting contents^^
    +(see configuration section for checkbox)^^
    +!!!!!Configuration
    +<<<
    +<<option chkDisableAutoSelect>> place cursor at start of textarea instead of pre-selecting content
    +<<option chkTextAreaExtensions>> add control-f (find), control-g (find again) and allow TABs as input in textarea
    +<<<
    +!!!!!Installation
    +<<<
    +Import (or copy/paste) the following tiddlers into your document:
    +''TextAreaPlugin'' (tagged with <<tag systemConfig>>)
    +<<<
    +!!!!!Revision History
    +<<<
    +''2006.01.22 [1.0.1]''
    +only add extra key processing for TEXTAREA elements (not other edit fields).
    +added option to enable/disable textarea keydown extensions (default is "standard keys" only)
    +''2006.01.22 [1.0.0]''
    +Moved from temporary "System Tweaks" tiddler into 'real' TextAreaPlugin tiddler.
    +<<<
    +!!!!!Code
    +***/
    +//{{{
    +version.extensions.textAreaPlugin= {major: 1, minor: 0, revision: 1, date: new Date(2006,1,23)};
    +//}}}
    +
    +//{{{
    +if (!config.options.chkDisableAutoSelect) config.options.chkDisableAutoSelect=false; // default to standard action
    +if (!config.options.chkTextAreaExtensions) config.options.chkTextAreaExtensions=false; // default to standard action
    +
    +// Focus a specified tiddler. Attempts to focus the specified field, otherwise the first edit field it finds
    +Story.prototype.focusTiddler = function(title,field)
    +{
    +	var tiddler = document.getElementById(this.idPrefix + title);
    +	if(tiddler != null)
    +		{
    +		var children = tiddler.getElementsByTagName("*")
    +		var e = null;
    +		for (var t=0; t<children.length; t++)
    +			{
    +			var c = children[t];
    +			if(c.tagName.toLowerCase() == "input" || c.tagName.toLowerCase() == "textarea")
    +				{
    +				if(!e)
    +					e = c;
    +				if(c.getAttribute("edit") == field)
    +					e = c;
    +				}
    +			}
    +		if(e)
    +			{
    +			e.focus();
    +			e.select(); // select entire contents
    +
    +			// TWEAK: add TAB and "find" key handlers
    +			if (config.options.chkTextAreaExtensions) // add extra key handlers
    +				addKeyDownHandlers(e);
    +
    +			// TWEAK: option to NOT autoselect contents
    +			if (config.options.chkDisableAutoSelect) // set cursor to start of field content
    +				if (e.setSelectionRange) e.setSelectionRange(0,0); // for FF
    +				else if (e.createTextRange) { var r=e.createTextRange(); r.collapse(true); r.select(); } // for IE
    +
    +			}
    +		}
    +}
    +//}}}
    +
    +//{{{
    +function addKeyDownHandlers(e)
    +{
    +	// exit if not textarea or element doesn't allow selections
    +	if (e.tagName.toLowerCase()!="textarea" || !e.setSelectionRange) return;
    +
    +	// utility function: exits keydown handler and prevents browser from processing the keystroke
    +	var processed=function(ev) { ev.cancelBubble=true; if (ev.stopPropagation) ev.stopPropagation(); return false; }
    +
    +	// capture keypress in edit field
    +	e.onkeydown = function(ev) { if (!ev) var ev=window.event;
    +
    +		// process TAB
    +		if (!ev.shiftKey && ev.keyCode==9) { 
    +			// replace current selection with a TAB character
    +			var start=e.selectionStart; var end=e.selectionEnd;
    +			e.value=e.value.substr(0,start)+String.fromCharCode(9)+e.value.substr(end);
    +			// update insertion point, scroll it into view
    +			e.setSelectionRange(start+1,start+1);
    +			var linecount=e.value.split('\n').length;
    +			var thisline=e.value.substr(0,e.selectionStart).split('\n').length-1;
    +			e.scrollTop=Math.floor((thisline-e.rows/2)*e.scrollHeight/linecount);
    +			return processed(ev);
    +		}
    +
    +		// process CTRL-F (find matching text) or CTRL-G (find next match)
    +		if (ev.ctrlKey && (ev.keyCode==70||ev.keyCode==71)) {
    +			// if ctrl-f or no previous search, prompt for search text (default to previous text or current selection)... if no search text, exit
    +			if (ev.keyCode==70||!e.find||!e.find.length)
    +				{ var f=prompt("find:",e.find?e.find:e.value.substring(e.selectionStart,e.selectionEnd)); e.focus(); e.find=f?f:e.find; }
    +			if (!e.find||!e.find.length) return processed(ev);
    +			// do case-insensitive match with 'wraparound'...  if not found, alert and exit 
    +			var newstart=e.value.toLowerCase().indexOf(e.find.toLowerCase(),e.selectionStart+1);
    +			if (newstart==-1) newstart=e.value.toLowerCase().indexOf(e.find.toLowerCase());
    +			if (newstart==-1) { alert("'"+e.find+"' not found"); e.focus(); return processed(ev); }
    +			// set new selection, scroll it into view, and report line position in status bar
    +			e.setSelectionRange(newstart,newstart+e.find.length);
    +			var linecount=e.value.split('\n').length;
    +			var thisline=e.value.substr(0,e.selectionStart).split('\n').length;
    +			e.scrollTop=Math.floor((thisline-1-e.rows/2)*e.scrollHeight/linecount);
    +			window.status="line: "+thisline+"/"+linecount;
    +			return processed(ev);
    +		}
    +	}
    +}
    +//}}}
    +
    +
    + + + + + + + + + + diff --git a/wiki/index.html b/wiki/index.html index f2f7f8139..7a4d039ca 100755 --- a/wiki/index.html +++ b/wiki/index.html @@ -776,72 +776,6 @@ for __Running__
    * provide central interface for setting switches and configuration options * installing of some or all created artifacts
    -
    -
    ! Lumiera design process
    -A lightweight formalized process how people can add proposals for the Lumiera development.
    -
    -
    -!! Description
    -Use the Wiki at http://www.pipapo.org/pipawiki/Lumiera/DesignProcess to make it easy to add proposals in a well defined manner.
    -
    -I'd like to introduce a slightly formalized process for the ongoing Lumiera planning:
    -* Every proposal is instantiated as 'Idea', the author gives other people the opportunity to review and comment on it with extreme prejudice, while still working out details.
    -* When the the 'Idea' in a proper form and worked out in most details it becomes a 'Draft'. This 'Draft' need to be carefully reviewed, commented, perhaps corrected and rated by the other Developers.
    -* At some point we may decide that a 'Draft' becomes a 'Final' (I leave it open how this decision shall be done for now). 'Final' Documents will be imported into the repository (this wiki, you are reading such a Document right now!).
    -
    -* Sometimes proposals will become dropped for some reason, this is indicated by changing their state to 'Dropped', they still stay in the system for further reference.
    -
    -!!! Pros
    -* simple
    -* flexible
    -* no much rules
    -* persistent and at Final stage well documented process
    -
    -!!! Cons
    -* could be abused/vandalized (but wiki can use ACL's)
    -* depends on my server, this might be unfavorable or unreliable, ymmv.
    -* will only work if all or almost all involved people agree on this process
    -
    -!!! Alternatives
    -We could use some forum, Trac, Mailinglist or whatever instead.
    -
    -Just for Design documentation I would give [[Bouml|http://bouml.free.fr/]] a try. For myself, I am not very fond of UML Design tools, while Bouml looks quite promising and we could maintain the UML model in git repositories which would be more favorable than this centralized wiki. The backside is that this needs even more agreement between the developers, everyone has to install and use Bouml (and learn its usage) and design is constrained by a external tool.
    -
    -This distributed wiki might be used instead the pipapo.org wiki, investigate that for future.
    -
    -!! Rationale
    -Wiki works. It is simple to use and just flexible enough to handle the task. I don't go to install any other software for such tasks on my server. While the design progresses I'd propose to move our work into git repositories and eventually phase this wiki pages out anyways. I'd rather like to start out distributed/git right away .. but git gives us only a fine storage layer, for a design process we need some good presentation layer (later when using git and starting the implementation everyones favorite editor serves for that) I have no better ideas yet to solve the presentation problem other than using this wiki (or maybe Bouml).
    -
    -
    -
    -
    This is the entry point to several [[TiddlyWiki]]-Pages containing the developer and design documentation for Lumiera.
    -
    -* Cehteh started GitNotes where we will collect some information about git, howto and special setups
    -* since we prefer gpg signed tags in git and not each developer knows gpg well here is a Micro-GPG-HowTo 
    -* we maintain (semi-) final design docs in DesignDocumentation
    -* Things get often worked out on IRC, see IRC-Transcripts for decisions made there and not yet put into the proper documentation places
    -
    -Please __end your tiddlers in a newline__, this makes merging in git easier since the /pre tag used in tiddlywiki will become on a single line.
    -
    -----
    -!Design Draft
    -to get started, we create design drafts emphasizing different aspects and regions of Lumiera
    -
    -* Ichthyo focuses mainly on the Render Engine and its interconnection to the EDL, [[see this separate page|renderengine.html]]
    -* Cehteh works on the data backend draft, see [[this page|backend.html]]
    -* Some tools which don't fit somewhere else and are used everywhere are put into a [[Support Library|support_library.html]]
    -* [[Description of the Test System|TestSh]]
    -
    -!Coding Structures
    -next we should //start thinking// on how to organize several aspects of the practical coding...
    -* what to do in BOUML?                          &rarr; [[more|whatInBOUML]]
    -* how to organize packages, files, includes?    &rarr; [[more|SrcTreeStructure]]
    -* how to organize the executable to be built?
    -* what coding conventions to prefer?            &rarr; [[GNU Style|DesignDocumentation]]
    -* what [[build system|BuildSystem]] to use?
    -* various [[build dependencies|BuildDependenceis]]
    -* TestSuite
    -
    LumieraWiki
     ShortCuts
    @@ -1407,9 +1341,77 @@ config.formatters.push( { } ) //}}}
    -
    +
    +
    ! Lumiera design process
    +A lightweight formalized process how people can add proposals for the Lumiera development.
    +
    +
    +!! Description
    +Use the Wiki at http://www.pipapo.org/pipawiki/Lumiera/DesignProcess to make it easy to add proposals in a well defined manner.
    +
    +I'd like to introduce a slightly formalized process for the ongoing Lumiera planning:
    +* Every proposal is instantiated as 'Idea', the author gives other people the opportunity to review and comment on it with extreme prejudice, while still working out details.
    +* When the the 'Idea' in a proper form and worked out in most details it becomes a 'Draft'. This 'Draft' need to be carefully reviewed, commented, perhaps corrected and rated by the other Developers.
    +* At some point we may decide that a 'Draft' becomes a 'Final' (I leave it open how this decision shall be done for now). 'Final' Documents will be imported into the repository (this wiki, you are reading such a Document right now!).
    +
    +* Sometimes proposals will become dropped for some reason, this is indicated by changing their state to 'Dropped', they still stay in the system for further reference.
    +
    +!!! Pros
    +* simple
    +* flexible
    +* no much rules
    +* persistent and at Final stage well documented process
    +
    +!!! Cons
    +* could be abused/vandalized (but wiki can use ACL's)
    +* depends on my server, this might be unfavorable or unreliable, ymmv.
    +* will only work if all or almost all involved people agree on this process
    +
    +!!! Alternatives
    +We could use some forum, Trac, Mailinglist or whatever instead.
    +
    +Just for Design documentation I would give [[Bouml|http://bouml.free.fr/]] a try. For myself, I am not very fond of UML Design tools, while Bouml looks quite promising and we could maintain the UML model in git repositories which would be more favorable than this centralized wiki. The backside is that this needs even more agreement between the developers, everyone has to install and use Bouml (and learn its usage) and design is constrained by a external tool.
    +
    +This distributed wiki might be used instead the pipapo.org wiki, investigate that for future.
    +
    +!! Rationale
    +Wiki works. It is simple to use and just flexible enough to handle the task. I don't go to install any other software for such tasks on my server. While the design progresses I'd propose to move our work into git repositories and eventually phase this wiki pages out anyways. I'd rather like to start out distributed/git right away .. but git gives us only a fine storage layer, for a design process we need some good presentation layer (later when using git and starting the implementation everyones favorite editor serves for that) I have no better ideas yet to solve the presentation problem other than using this wiki (or maybe Bouml).
    +
    +
    +
    +
    This is the entry point to several [[TiddlyWiki]]-Pages containing the developer and design documentation for Lumiera.
    +
    +* Cehteh started GitNotes where we will collect some information about git, howto and special setups
    +* since we prefer gpg signed tags in git and not each developer knows gpg well here is a Micro-GPG-HowTo 
    +* we maintain (semi-) final design docs in DesignDocumentation
    +* Things get often worked out on IRC, see IRC-Transcripts for decisions made there and not yet put into the proper documentation places
    +
    +Please __end your tiddlers in a newline__, this makes merging in git easier since the /pre tag used in tiddlywiki will become on a single line.
    +
    +----
    +!Design Draft
    +to get started, we create design drafts emphasizing different aspects and regions of Lumiera
    +
    +* Ichthyo focuses mainly on the Render Engine and its interconnection to the EDL, [[see this separate page|renderengine.html]]
    +* Cehteh works on the data backend draft, see [[this page|backend.html]]
    +* Some tools which don't fit somewhere else and are used everywhere are put into a [[Support Library|support_library.html]]
    +* [[Description of the Test System|TestSh]]
    +
    +!Coding Structures
    +next we should //start thinking// on how to organize several aspects of the practical coding...
    +* what to do in BOUML?                          &rarr; [[more|whatInBOUML]]
    +* how to organize packages, files, includes?    &rarr; [[more|SrcTreeStructure]]
    +* how to organize the executable to be built?
    +* what coding conventions to prefer?            &rarr; [[GNU Style|DesignDocumentation]]
    +* what [[build system|BuildSystem]] to use?
    +* various [[build dependencies|BuildDependenceis]]
    +* TestSuite
    +
    +
    GettingStarted
     [[LumieraWiki]]
    +[[Compatibility|compatibility.html]]
    +[[ToDo|todo.html]]
     [[Backend|backend.html]]
     [[Proc-Layer|renderengine.html]]
     [[Support-Library|support_library.html]]
    @@ -1432,7 +1434,7 @@ Some of these things work quite well, there is an overall friendly relation betw
     
     But there are some bad things too. Notably there is not much progress on the community development. Users don't benefit from new improvements which other people have made. There is a endlessly growing list of bugs and feature requests, when someone sends a patch to the ML he has to invest quite some time to maintain it until it might be merged. Finally we don't know what heroine virtual is working on, until we see his next tarball.
     
    -!! Solution for "Cinelerra3" / Lumiera
    +!! Solution for "Cinelerra3" / Lumiera
     Cinelerra is heroine's product, this time we should work together with him to make it pleasant and progressing for anyone.
     We are in need of a new development model which is acceptable by all involved people and benefits from the way Cinelerra development worked the years before, without maintaining the bad sides again: 
     
    diff --git a/wiki/support_library.html b/wiki/support_library.html
    index 095ca833f..8a6bc456b 100644
    --- a/wiki/support_library.html
    +++ b/wiki/support_library.html
    @@ -643,6 +643,11 @@ TertiaryMid: #999
     TertiaryDark: #666
     Error: #f88
    +
    +
    This hashing gives guaranteed O(1) lookup complexity and amortized O(1) insert and remove complexity. Hash tables by default grow and shrink automatically. It is posible to preallocate entries and turn automatic shrinking off taking out the memory management factors for insert and remove operations. This implementation uses 3 Tables which exponential growing sizes.
    +
    +Hash table utilization is commonly between 40-80% which gives better memory usage and far better locality than trees.
    +
    [[SupportLibrary]]
    @@ -2188,6 +2193,31 @@ config.macros.rssFeedUpdate = { //}}}
    +
    +
    ! Memory allocation
    +* lumiera_malloc()
    +  Succceeds or dies, no need for error handling.
    +
    +! String functions
    +Small wrapers and extensions to the string.h functions, handle NULL pointers gracefully.
    +* lumiera_strndup()
    +  Succceeds or dies, no need for error handling.
    +* lumiera_strncmp() lumiera_streq()
    +  Optimized comparing same addresses.
    +
    +! Round robin temporary buffers
    +Provides 64 buffers per thread which are recycled with each use, the idea here is to have fast buffers for temporal data without need for explicit heap management or stack waste.
    +
    +* lumiera_tmpbuf_provide ()
    + Acquire a temporary buffer. doesn't need to be freed. Stays valid for the next 63 tmpbuf calls.
    +
    +* lumiera_tmpbuf_strndup ()
    + Duplicate string to a tmpbuf.
    +
    +* lumiera_tmpbuf_sprintf ()
    + Construct a string in a tmpbuf.
    +
    +
    Each Plugin can export different Interfaces, even same interfaces with different capabilities like a effect for different color models or such.
     
    @@ -2419,7 +2449,7 @@ h1,h2,h3,h4,h5,h6 {
     /*}}}*/
     
    -
    +
    The Support Library contains all tools we need at various places, but by themselves don't defines a subsystem on their own.
     
     These things are:
    @@ -2428,8 +2458,9 @@ These things are:
     * a wrapper for POSIX Threads
     ** Thread creation joining and canceling
     ** [[Locking primitives like Condition variables and Mutexes|LockingPrimitives]]
    -* [[Frame and Time handling and calculations|FrameAndTime]]
    - 
    +* [[Some tools and wrapers around the C library|SafeCLib]]
    +* [[O(1) hashtable using Cuckoo hashing|Cuckoo]]
    +
     (... to be continued)
     
    diff --git a/wiki/todo.html b/wiki/todo.html new file mode 100644 index 000000000..7440ab36a --- /dev/null +++ b/wiki/todo.html @@ -0,0 +1,11631 @@ + + + + + + + + + + + +
    My TiddlyWiki is loading ...

    Requires Javascript.
    + + ToDo - Roadmap and tasks + + + + + + + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    Background: #fff
    +Foreground: #000
    +PrimaryPale: #8cf
    +PrimaryLight: #18f
    +PrimaryMid: #04b
    +PrimaryDark: #014
    +SecondaryPale: #ffc
    +SecondaryLight: #fe8
    +SecondaryMid: #db4
    +SecondaryDark: #841
    +TertiaryPale: #eee
    +TertiaryLight: #ccc
    +TertiaryMid: #999
    +TertiaryDark: #666
    +Error: #f88
    +
    +
    +
    /*{{{*/
    +body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
    +
    +a {color:[[ColorPalette::PrimaryMid]];}
    +a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
    +a img {border:0;}
    +
    +h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
    +h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
    +h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}
    +
    +.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
    +.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
    +.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}
    +
    +.header {background:[[ColorPalette::PrimaryMid]];}
    +.headerShadow {color:[[ColorPalette::Foreground]];}
    +.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
    +.headerForeground {color:[[ColorPalette::Background]];}
    +.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}
    +
    +.tabSelected{color:[[ColorPalette::PrimaryDark]];
    +	background:[[ColorPalette::TertiaryPale]];
    +	border-left:1px solid [[ColorPalette::TertiaryLight]];
    +	border-top:1px solid [[ColorPalette::TertiaryLight]];
    +	border-right:1px solid [[ColorPalette::TertiaryLight]];
    +}
    +.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
    +.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
    +.tabContents .button {border:0;}
    +
    +#sidebar {}
    +#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
    +#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
    +#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
    +#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
    +#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}
    +
    +.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
    +.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
    +.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
    +.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
    +	border:1px solid [[ColorPalette::PrimaryMid]];}
    +.wizardStep.wizardStepDone {background::[[ColorPalette::TertiaryLight]];}
    +.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
    +.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
    +.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
    +	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
    +.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
    +.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
    +	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}
    +
    +#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
    +#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}
    +
    +.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}
    +
    +.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
    +.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
    +.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
    +.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
    +.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
    +.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
    +.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
    +.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}
    +
    +.tiddler .defaultCommand {font-weight:bold;}
    +
    +.shadow .title {color:[[ColorPalette::TertiaryDark]];}
    +
    +.title {color:[[ColorPalette::SecondaryDark]];}
    +.subtitle {color:[[ColorPalette::TertiaryDark]];}
    +
    +.toolbar {color:[[ColorPalette::PrimaryMid]];}
    +.toolbar a {color:[[ColorPalette::TertiaryLight]];}
    +.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
    +.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}
    +
    +.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
    +.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
    +.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
    +.tagging .button, .tagged .button {border:none;}
    +
    +.footer {color:[[ColorPalette::TertiaryLight]];}
    +.selected .footer {color:[[ColorPalette::TertiaryMid]];}
    +
    +.sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
    +.sparktick {background:[[ColorPalette::PrimaryDark]];}
    +
    +.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
    +.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
    +.lowlight {background:[[ColorPalette::TertiaryLight]];}
    +
    +.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}
    +
    +.imageLink, #displayArea .imageLink {background:transparent;}
    +
    +.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}
    +
    +.viewer .listTitle {list-style-type:none; margin-left:-2em;}
    +.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
    +.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}
    +
    +.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
    +.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
    +.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}
    +
    +.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
    +.viewer code {color:[[ColorPalette::SecondaryDark]];}
    +.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}
    +
    +.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}
    +
    +.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
    +.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
    +.editorFooter {color:[[ColorPalette::TertiaryMid]];}
    +
    +#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
    +#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
    +#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
    +#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
    +#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
    +#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
    +#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
    +.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
    +.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
    +#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:'alpha(opacity:60)';}
    +/*}}}*/
    +
    +
    +
    /*{{{*/
    +* html .tiddler {height:1%;}
    +
    +body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}
    +
    +h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
    +h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
    +h4,h5,h6 {margin-top:1em;}
    +h1 {font-size:1.35em;}
    +h2 {font-size:1.25em;}
    +h3 {font-size:1.1em;}
    +h4 {font-size:1em;}
    +h5 {font-size:.9em;}
    +
    +hr {height:1px;}
    +
    +a {text-decoration:none;}
    +
    +dt {font-weight:bold;}
    +
    +ol {list-style-type:decimal;}
    +ol ol {list-style-type:lower-alpha;}
    +ol ol ol {list-style-type:lower-roman;}
    +ol ol ol ol {list-style-type:decimal;}
    +ol ol ol ol ol {list-style-type:lower-alpha;}
    +ol ol ol ol ol ol {list-style-type:lower-roman;}
    +ol ol ol ol ol ol ol {list-style-type:decimal;}
    +
    +.txtOptionInput {width:11em;}
    +
    +#contentWrapper .chkOptionInput {border:0;}
    +
    +.externalLink {text-decoration:underline;}
    +
    +.indent {margin-left:3em;}
    +.outdent {margin-left:3em; text-indent:-3em;}
    +code.escaped {white-space:nowrap;}
    +
    +.tiddlyLinkExisting {font-weight:bold;}
    +.tiddlyLinkNonExisting {font-style:italic;}
    +
    +/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
    +a.tiddlyLinkNonExisting.shadow {font-weight:bold;}
    +
    +#mainMenu .tiddlyLinkExisting,
    +	#mainMenu .tiddlyLinkNonExisting,
    +	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
    +#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}
    +
    +.header {position:relative;}
    +.header a:hover {background:transparent;}
    +.headerShadow {position:relative; padding:4.5em 0em 1em 1em; left:-1px; top:-1px;}
    +.headerForeground {position:absolute; padding:4.5em 0em 1em 1em; left:0px; top:0px;}
    +
    +.siteTitle {font-size:3em;}
    +.siteSubtitle {font-size:1.2em;}
    +
    +#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}
    +
    +#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
    +#sidebarOptions {padding-top:0.3em;}
    +#sidebarOptions a {margin:0em 0.2em; padding:0.2em 0.3em; display:block;}
    +#sidebarOptions input {margin:0.4em 0.5em;}
    +#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
    +#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
    +#sidebarOptions .sliderPanel input {margin:0 0 .3em 0;}
    +#sidebarTabs .tabContents {width:15em; overflow:hidden;}
    +
    +.wizard {padding:0.1em 1em 0em 2em;}
    +.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
    +.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
    +.wizardStep {padding:1em 1em 1em 1em;}
    +.wizard .button {margin:0.5em 0em 0em 0em; font-size:1.2em;}
    +.wizardFooter {padding:0.8em 0.4em 0.8em 0em;}
    +.wizardFooter .status {padding:0em 0.4em 0em 0.4em; margin-left:1em;}
    +.wizard .button {padding:0.1em 0.2em 0.1em 0.2em;}
    +
    +#messageArea {position:fixed; top:2em; right:0em; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
    +.messageToolbar {display:block; text-align:right; padding:0.2em 0.2em 0.2em 0.2em;}
    +#messageArea a {text-decoration:underline;}
    +
    +.tiddlerPopupButton {padding:0.2em 0.2em 0.2em 0.2em;}
    +.popupTiddler {position: absolute; z-index:300; padding:1em 1em 1em 1em; margin:0;}
    +
    +.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
    +.popup .popupMessage {padding:0.4em;}
    +.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0em;}
    +.popup li.disabled {padding:0.4em;}
    +.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
    +.listBreak {font-size:1px; line-height:1px;}
    +.listBreak div {margin:2px 0;}
    +
    +.tabset {padding:1em 0em 0em 0.5em;}
    +.tab {margin:0em 0em 0em 0.25em; padding:2px;}
    +.tabContents {padding:0.5em;}
    +.tabContents ul, .tabContents ol {margin:0; padding:0;}
    +.txtMainTab .tabContents li {list-style:none;}
    +.tabContents li.listLink { margin-left:.75em;}
    +
    +#contentWrapper {display:block;}
    +#splashScreen {display:none;}
    +
    +#displayArea {margin:1em 17em 0em 14em;}
    +
    +.toolbar {text-align:right; font-size:.9em;}
    +
    +.tiddler {padding:1em 1em 0em 1em;}
    +
    +.missing .viewer,.missing .title {font-style:italic;}
    +
    +.title {font-size:1.6em; font-weight:bold;}
    +
    +.missing .subtitle {display:none;}
    +.subtitle {font-size:1.1em;}
    +
    +.tiddler .button {padding:0.2em 0.4em;}
    +
    +.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
    +.isTag .tagging {display:block;}
    +.tagged {margin:0.5em; float:right;}
    +.tagging, .tagged {font-size:0.9em; padding:0.25em;}
    +.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
    +.tagClear {clear:both;}
    +
    +.footer {font-size:.9em;}
    +.footer li {display:inline;}
    +
    +.annotation {padding:0.5em; margin:0.5em;}
    +
    +* html .viewer pre {width:99%; padding:0 0 1em 0;}
    +.viewer {line-height:1.4em; padding-top:0.5em;}
    +.viewer .button {margin:0em 0.25em; padding:0em 0.25em;}
    +.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
    +.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}
    +
    +.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
    +.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
    +table.listView {font-size:0.85em; margin:0.8em 1.0em;}
    +table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}
    +
    +.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
    +.viewer code {font-size:1.2em; line-height:1.4em;}
    +
    +.editor {font-size:1.1em;}
    +.editor input, .editor textarea {display:block; width:100%; font:inherit;}
    +.editorFooter {padding:0.25em 0em; font-size:.9em;}
    +.editorFooter .button {padding-top:0px; padding-bottom:0px;}
    +
    +.fieldsetFix {border:0; padding:0; margin:1px 0px 1px 0px;}
    +
    +.sparkline {line-height:1em;}
    +.sparktick {outline:0;}
    +
    +.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
    +.zoomer div {padding:1em;}
    +
    +* html #backstage {width:99%;}
    +* html #backstageArea {width:99%;}
    +#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em 0.3em 0.5em;}
    +#backstageToolbar {position:relative;}
    +#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em 0.3em 0.5em;}
    +#backstageButton {display:none; position:absolute; z-index:175; top:0em; right:0em;}
    +#backstageButton a {padding:0.1em 0.4em 0.1em 0.4em; margin:0.1em 0.1em 0.1em 0.1em;}
    +#backstage {position:relative; width:100%; z-index:50;}
    +#backstagePanel {display:none; z-index:100; position:absolute; margin:0em 3em 0em 3em; padding:1em 1em 1em 1em;}
    +.backstagePanelFooter {padding-top:0.2em; float:right;}
    +.backstagePanelFooter a {padding:0.2em 0.4em 0.2em 0.4em;}
    +#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}
    +
    +.whenBackstage {display:none;}
    +.backstageVisible .whenBackstage {display:block;}
    +/*}}}*/
    +
    +
    +
    /***
    +StyleSheet for use when a translation requires any css style changes.
    +This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which use a logographic writing system and need larger font sizes.
    +***/
    +
    +/*{{{*/
    +body {font-size:0.8em;}
    +
    +#sidebarOptions {font-size:1.05em;}
    +#sidebarOptions a {font-style:normal;}
    +#sidebarOptions .sliderPanel {font-size:0.95em;}
    +
    +.subtitle {font-size:0.8em;}
    +
    +.viewer table.listView {font-size:0.95em;}
    +
    +.htmlarea .toolbarHA table {border:1px solid ButtonFace; margin:0em 0em;}
    +/*}}}*/
    +
    +
    +
    /*{{{*/
    +@media print {
    +#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton {display: none ! important;}
    +#displayArea {margin: 1em 1em 0em 1em;}
    +/* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
    +noscript {display:none;}
    +}
    +/*}}}*/
    +
    +
    +
    <!--{{{-->
    +<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
    +<div class='headerShadow'>
    +<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
    +<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
    +</div>
    +<div class='headerForeground'>
    +<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
    +<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
    +</div>
    +</div>
    +<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
    +<div id='sidebar'>
    +<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
    +<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
    +</div>
    +<div id='displayArea'>
    +<div id='messageArea'></div>
    +<div id='tiddlerDisplay'></div>
    +</div>
    +<!--}}}-->
    +
    +
    +
    <!--{{{-->
    +<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></div>
    +<div class='title' macro='view title'></div>
    +<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
    +<div class='tagging' macro='tagging'></div>
    +<div class='tagged' macro='tags'></div>
    +<div class='viewer' macro='view text wikified'></div>
    +<div class='tagClear'></div>
    +<!--}}}-->
    +
    +
    +
    <!--{{{-->
    +<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler'></div>
    +<div class='title' macro='view title'></div>
    +<div class='editor' macro='edit title'></div>
    +<div macro='annotations'></div>
    +<div class='editor' macro='edit text'></div>
    +<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>
    +<!--}}}-->
    +
    +
    +
    To get started with this blank TiddlyWiki, you'll need to modify the following tiddlers:
    +* SiteTitle & SiteSubtitle: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
    +* MainMenu: The menu (usually on the left)
    +* DefaultTiddlers: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
    +You'll also need to enter your username for signing your edits: <<option txtUserName>>
    +
    +
    +
    These InterfaceOptions for customising TiddlyWiki are saved in your browser
    +
    +Your username for signing your edits. Write it as a WikiWord (eg JoeBloggs)
    +
    +<<option txtUserName>>
    +<<option chkSaveBackups>> SaveBackups
    +<<option chkAutoSave>> AutoSave
    +<<option chkRegExpSearch>> RegExpSearch
    +<<option chkCaseSensitiveSearch>> CaseSensitiveSearch
    +<<option chkAnimate>> EnableAnimations
    +
    +----
    +Also see AdvancedOptions
    +
    +
    + +
    +
    +
    A task has a description, an estimate of how long it will take, and a record of how much time you have spent on it so far.  Here's an example, which shows a task estimated at 3 hours, with 1 hour spent on it, and ''2'' hours remaining:
    +<<<
    +<<task 3 3 1>> Add a double-click handler to the description cell that opens the editor and selects the text
    +<<<
    +If you hover the mouse over any part of the task -- the bullet, the description, or any of the numeric cells -- a tip will appear explaining it.
    +
    +Try modifying the time spent.  Suppose you've just spent one more hour and want to record it.  Just click on the second yellow cell, and enter "+1" (sans the quote marks, of course) in the popup window.  Watch the time remaining go down to 1 hour.
    +
    +In reality, I originally estimated this task at a half-hour, but it ended up taking 3.5 hours.  The macro also tracks your original estimate, if it is different from the current estimate, in a fourth cell like this:
    +<<<
    +<<task 0.5 2 1>> Add a double-click handler to the description cell that opens the editor and selects the text
    +<<<
    +You can adjust the current estimate in the same way as you adjusted the time spent.  Click on the current estimate cell (the first yellow cell), and change it to 2.5 hours by typing "2.5" or "+.5".
    +
    +You can also adjust the time remaining, which will modify either the estimate (if the time remaining increases) or the time spent (if it decreases).  Click on the time remaining and add an hour by typing "+1".
    +
    +When the time remaining goes to zero, the task is considered complete:
    +<<<
    +<<task 0.5 3.5 3.5>> Add a double-click handler to the description cell that opens the editor and selects the text
    +<<<
    +If you haven't already done so, try double-clicking the description.  Yes, it really does open up the editor and select just the text of the description.
    +
    +----
    +To continue, click the down-arrow and choose another section: <<tag TaskMacroTutorial>>
    +
    +
    +
    A task's description is a single wikified line, so it can contain any formatting that can be specified on one line:
    +<<<
    +<<task 1>> Beef up the time click handlers to allow entry of ''two'' values each: cur&spent, spent&rem. Add click handler to done tasks' spent cells too, to reopen them (like with +0, 1).
    +<<task 0.5>> Put tasksum on the ViewTemplate.
    +<<<
    +You can specify just the description of a task, and leave it unestimated.  Click the question mark to enter the estimate:
    +<<<
    +<<task>> Beef up the time click handlers to allow entry of ''two'' values each: cur&spent, spent&rem. Add click handler to done tasks' spent cells too, to reopen them (like with +0, 1).
    +<<<
    +As this task implies, you can enter two values in the popup when you click on any of the time cells.  Separate them with spaces and/or a comma.  Experiment:
    +<<<
    +<<task 1>> Beef up the time click handlers to allow entry of ''two'' values each: cur&spent, spent&rem. Add click handler to done tasks' spent cells too, to reopen them (like with +0, 1).
    +<<<
    +Finally, if you haven't already figured this out, you can double-click on a task's bullet to mark it complete, with the current estimate entered as the time spent.
    +
    +----
    +To continue, click the down-arrow and choose another section: <<tag TaskMacroTutorial>>
    +
    +
    +
    If you've been paying attention, you've noticed that I haven't discussed the actual adding of calls to the task macro within your tiddlers -- it's all been about modifying tasks that were already there.  That's because adding tasks via the taskadder macro is much easier and more intuitive than adding them by hand.
    +
    +And setting up a taskadder is simplicity itself.  Just add {{{<<taskadder>>}}} to your tiddler.  You will see this:
    +<<<
    +<<taskadder>>
    +<<<
    +Just type a task description into the first field, and your initial estimate for how long it will take into the second field.  Click the "add task" button, or just hit Enter in either of the fields, to add the new task into the tiddler.  Notice that you can just start typing a new task as soon as you're done entering the first one.
    +
    +You can have as many taskadders as you like in any tiddler.  The last one you used will capture the keyboard focus when it is redisplayed, meaning you can type a series of tasks without using the mouse.  Try adding some tasks here and in the above adder:
    +<<<
    +<<taskadder>>
    +<<<
    +Notice that the one you just used takes focus when this tiddler is redisplayed.
    +
    +A taskadder by default adds tasks above itself.  You can make it add them below by adding a {{{below}}} argument to the macro call:
    +<<<
    +<<taskadder below>>
    +<<<
    +
    +----
    +To continue, click the down-arrow and choose another section: <<tag TaskMacroTutorial>>
    +
    +
    +
    In this tutorial, we've been looking mostly at individual tasks.  In real life, though, you'll typically have a series of them, or even several series of them in the same tiddler.  In these cases you want a summary that tells you -- at a minimum -- how much time you still expect to spend on these tasks.
    +
    +To get such a summary, just add {{{<<tasksum start>>}}} before the tasks and {{{<<tasksum end>>}}} after them.  Here's an example:
    +<<<
    +<<tasksum start>>
    +<<task 0.25 0.25 0.25>> Add tooltips to the various cells
    +<<task 1 0.75 0.75>> Figure out how to add auto-updating click handlers to the time cells
    +<<task 2 2 0>> Add simple click handlers to cur, spent, rem: just allow direct setting of values
    +<<task 1 3.5 2.5>> Add a double-click handler to the desc cell that opens the editor and selects the text
    +<<task 1 1 0>> Beef up the time click handlers to allow entry of two values each: cur&spent, spent&rem. Add click handler to done tasks' spent cells too, to reopen them (like with +0, 1).
    +<<task 1 1 0>> Beef up the time click handlers to handle leading + or -
    +<<task 1 1 0>> Add a double-click handler to the status cell that functions like typing 0 into the rem cell
    +<<tasksum end>>
    +<<<
    +If you'd rather have the summary at the top, just add {{{here}}} to the start call, ie {{{<<tasksum start here>>}}}.
    +<<<
    +<<tasksum start here>>
    +<<task 0.25 0.25 0.25>> Add tooltips to the various cells
    +<<task 1 0.75 0.75>> Figure out how to add auto-updating click handlers to the time cells
    +<<task 2 2 0>> Add simple click handlers to cur, spent, rem: just allow direct setting of values
    +<<tasksum end>>
    +<<<
    +You can nest these things if you like, just be sure to match starts and ends:
    +<<<
    +<<tasksum start here>>
    +* Time cell manipulation:<<tasksum start>>
    +<<task 1 0.75 0.75>> Figure out how to add auto-updating click handlers to the time cells
    +<<task 2 2 0>> Add simple click handlers to cur, spent, rem: just allow direct setting of values
    +<<task 1 1 0>> Beef up the time click handlers to allow entry of two values each: cur&spent, spent&rem. Add click handler to done tasks' spent cells too, to reopen them (like with +0, 1).
    +<<task 1 1 0>> Beef up the time click handlers to handle leading + or -
    +<<tasksum end "Cell manipulation:">>
    +<<br>>
    +* Double-click handling:<<tasksum start>>
    +<<task 1 3.5 2.5>> Add a double-click handler to the desc cell that opens the editor and selects the text
    +<<task 1 1 0>> Add a double-click handler to the status cell that functions like typing 0 into the rem cell
    +<<tasksum end "Double-clicks:">>
    +
    +<<tasksum end>>
    +<<<
    +Finally, the simplest way to use tasksum is to add it to your view template.  See TaskSummaryViewTemplate for an example template.  Note that if no tasks are present between the start and end, nothing is displayed.
    +
    +----
    +To continue, click the down-arrow and choose another section: <<tag TaskMacroTutorial>>
    +
    +
    +
    The TaskMacroPlugin can be installed like any other TiddlyWiki plugin, and used without further effort.  However, there are two issues that may affect you.  (To get started with a brand new wiki that does not have these issues, consider downloading the [[empty LabWiki|empty_labwiki.html]].)
    +# The task macros don't play nicely with the default TiddlyWiki display of tags.  In the default view template, a tiddler's list of tags is shown in a little box that floats in the upper right corner of the tiddler.  However, this little box may interfere with the tables used by the task macros.  In Firefox, the tables are drawn right over the top of the tag box, rendering both of them illegible.  In Internet Explorer, the tag box forces the tables to be pushed down below the box, which can waste a lot of space.<<br>><<br>>Thus, I recommend changing your view template to eliminate the little box.  If you use Simon Baird's [[TagglyTagging|http://simonbaird.com/mptw/#TagglyTagging]] (as LabWiki does), then my TaskSummaryViewTemplate might be a good alternative.  Simply import it into your wiki and rename it to ViewTemplate.  This template also demonstrates how to incorporate the tasksum macro into every tiddler so any tiddler with tasks has a summary at the top.<<br>><<br>>
    +# Most view templates also add a minus sign ("-") before the "close" command.  TiddlyWiki interprets this to mean that you want the close command to be executed if you hit the Escape key from within the tiddler.<<br>><<br>>However, most tiddlers never have focus, and so never give you the opportunity to try it out.  But if you have a taskadder in your tiddler, then you suddenly enable this feature -- and you probably don't want it.  It means that if you type a nice long task description and then hit Escape, that description will be lost and the tiddler will be closed.  So I recommend that you remove the minus sign from the view template's menu altogether, as I have done in LabWiki's own ViewTemplate.
    +
    +----
    +This ends the tutorial.  To go back to any previous section, click the down-arrow and choose it: <<tag TaskMacroTutorial>>
    +
    +
    +
    PageTemplate
    +|>|SiteTitle - SiteSubtitle|
    +|>|MainMenu|
    +|DefaultTiddlers<<br>><<br>><<br>>ViewTemplate<<br>><<br>>EditTemplate|SideBarOptions|
    +|~|OptionsPanel|
    +|~|SideBarTabs|
    +|~|AdvancedOptions|
    +|~|<<tiddler Configuration.SideBarTabs>>|
    +
    +''StyleSheet:'' StyleSheetColors - StyleSheetLayout - StyleSheetPrint
    +
    +ColorPalette
    +
    +SiteUrl
    +
    +
    +
    /***
    +|Name|BetterTimelineMacro|
    +|Created by|SaqImtiaz|
    +|Location|http://tw.lewcid.org/#BetterTimelineMacro|
    +|Version|0.5 beta|
    +|Requires|~TW2.x|
    +!!!Description:
    +A replacement for the core timeline macro that offers more features:
    +*list tiddlers with only specfic tag
    +*exclude tiddlers with a particular tag
    +*limit entries to any number of days, for example one week
    +*specify a start date for the timeline, only tiddlers after that date will be listed.
    +
    +!!!Installation:
    +Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.
    +Edit the ViewTemplate to add the fullscreen command to the toolbar.
    +
    +!!!Syntax:
    +{{{<<timeline better:true>>}}}
    +''the param better:true enables the advanced features, without it you will get the old timeline behaviour.''
    +
    +additonal params:
    +(use only the ones you want)
    +{{{<<timeline better:true  onlyTag:Tag1 excludeTag:Tag2 sortBy:modified/created firstDay:YYYYMMDD maxDays:7 maxEntries:30>>}}}
    +
    +''explanation of syntax:''
    +onlyTag: only tiddlers with this tag will be listed. Default is to list all tiddlers.
    +excludeTag: tiddlers with this tag will not be listed.
    +sortBy: sort tiddlers by date modified or date created. Possible values are modified or created.
    +firstDay: useful for starting timeline from a specific date. Example: 20060701 for 1st of July, 2006
    +maxDays: limits timeline to include only tiddlers from the specified number of days. If you use a value of 7 for example, only tiddlers from the last 7 days will be listed.
    +maxEntries: limit the total number of entries in the timeline.
    +
    +
    +!!!History:
    +*28-07-06: ver 0.5 beta, first release
    +
    +!!!Code
    +***/
    +//{{{
    +// Return the tiddlers as a sorted array
    +TiddlyWiki.prototype.getTiddlers = function(field,excludeTag,includeTag)
    +{
    +          var results = [];
    +          this.forEachTiddler(function(title,tiddler)
    +          {
    +          if(excludeTag == undefined || tiddler.tags.find(excludeTag) == null)
    +                        if(includeTag == undefined || tiddler.tags.find(includeTag)!=null)
    +                                      results.push(tiddler);
    +          });
    +          if(field)
    +                   results.sort(function (a,b) {if(a[field] == b[field]) return(0); else return (a[field] < b[field]) ? -1 : +1; });
    +          return results;
    +}
    +
    +
    +
    +//this function by Udo
    +function getParam(params, name, defaultValue)
    +{
    +          if (!params)
    +          return defaultValue;
    +          var p = params[0][name];
    +          return p ? p[0] : defaultValue;
    +}
    +
    +window.old_timeline_handler= config.macros.timeline.handler;
    +config.macros.timeline.handler = function(place,macroName,params,wikifier,paramString,tiddler)
    +{
    +          var args = paramString.parseParams("list",null,true);
    +          var betterMode = getParam(args, "better", "false");
    +          if (betterMode == 'true')
    +          {
    +          var sortBy = getParam(args,"sortBy","modified");
    +          var excludeTag = getParam(args,"excludeTag",undefined);
    +          var includeTag = getParam(args,"onlyTag",undefined);
    +          var tiddlers = store.getTiddlers(sortBy,excludeTag,includeTag);
    +          var firstDayParam = getParam(args,"firstDay",undefined);
    +          var firstDay = (firstDayParam!=undefined)? firstDayParam: "00010101";
    +          var lastDay = "";
    +          var field= sortBy;
    +          var maxDaysParam = getParam(args,"maxDays",undefined);
    +          var maxDays = (maxDaysParam!=undefined)? maxDaysParam*24*60*60*1000: (new Date()).getTime() ;
    +          var maxEntries = getParam(args,"maxEntries",undefined);
    +          var last = (maxEntries!=undefined) ? tiddlers.length-Math.min(tiddlers.length,parseInt(maxEntries)) : 0;
    +          for(var t=tiddlers.length-1; t>=last; t--)
    +                  {
    +                  var tiddler = tiddlers[t];
    +                  var theDay = tiddler[field].convertToLocalYYYYMMDDHHMM().substr(0,8);
    +                  if ((theDay>=firstDay)&& (tiddler[field].getTime()> (new Date()).getTime() - maxDays))
    +                     {
    +                     if(theDay != lastDay)
    +                               {
    +                               var theDateList = document.createElement("ul");
    +                               place.appendChild(theDateList);
    +                               createTiddlyElement(theDateList,"li",null,"listTitle",tiddler[field].formatString(this.dateFormat));
    +                               lastDay = theDay;
    +                               }
    +                  var theDateListItem = createTiddlyElement(theDateList,"li",null,"listLink",null);
    +                  theDateListItem.appendChild(createTiddlyLink(place,tiddler.title,true));
    +                  }
    +                  }
    +          }
    +
    +          else
    +              {
    +              window.old_timeline_handler.apply(this,arguments);
    +              }
    +}
    +//}}}
    +
    +
    +
    Background: #fff
    +Foreground: #000
    +PrimaryPale: #aaa
    +PrimaryLight: #f00
    +PrimaryMid: #400
    +PrimaryDark: #000
    +SecondaryPale: #ffc
    +SecondaryLight: #fe8
    +SecondaryMid: #db4
    +SecondaryDark: #841
    +TertiaryPale: #eee
    +TertiaryLight: #ccc
    +TertiaryMid: #999
    +TertiaryDark: #666
    +Error: #f88
    +
    +
    +
    [[Overview]]
    +
    +
    +
    /***
    +|Name|FullScreenPlugin|
    +|Created by|SaqImtiaz|
    +|Location|http://tw.lewcid.org/#FullScreenPlugin|
    +|Version|1.1|
    +|Requires|~TW2.x|
    +!Description:
    +Toggle between viewing tiddlers fullscreen and normally. Very handy for when you need more viewing space.
    +
    +!Demo:
    +Click the ↕ button in the toolbar for this tiddler. Click it again to turn off fullscreen.
    +
    +!Installation:
    +Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.
    +Edit the ViewTemplate to add the fullscreen command to the toolbar.
    +
    +!History:
    +*25-07-06: ver 1.1
    +*20-07-06: ver 1.0
    +
    +!Code
    +***/
    +//{{{
    +var lewcidFullScreen = false;
    +
    +config.commands.fullscreen =
    +{
    +            text:" ↕ ",
    +            tooltip:"Fullscreen mode"
    +};
    +
    +config.commands.fullscreen.handler = function (event,src,title)
    +{
    +            if (lewcidFullScreen == false)
    +               {
    +                lewcidFullScreen = true;
    +                setStylesheet('#sidebar, .header, #mainMenu{display:none;} #displayArea{margin:0em 0 0 0 !important;}',"lewcidFullScreenStyle");
    +               }
    +            else
    +               {
    +                lewcidFullScreen = false;
    +                setStylesheet(' ',"lewcidFullScreenStyle");
    +               }
    +}
    +
    +config.macros.fullscreen={};
    +config.macros.fullscreen.handler =  function(place,macroName,params,wikifier,paramString,tiddler)
    +{
    +        var label = params[0]||" ↕ ";
    +        var tooltip = params[1]||"Fullscreen mode";
    +        createTiddlyButton(place,label,tooltip,config.commands.fullscreen.handler);
    +}
    +
    +var lewcid_fullscreen_closeTiddler = Story.prototype.closeTiddler;
    +Story.prototype.closeTiddler =function(title,animate,slowly)
    +{
    +           lewcid_fullscreen_closeTiddler.apply(this,arguments);
    +           if (story.isEmpty() && lewcidFullScreen == true)
    +              config.commands.fullscreen.handler();
    +}
    +
    +
    +Slider.prototype.lewcidStop = Slider.prototype.stop;
    +Slider.prototype.stop = function()
    +{
    +           this.lewcidStop();
    +           if (story.isEmpty() && lewcidFullScreen == true)
    +              config.commands.fullscreen.handler();
    +}
    +//}}}
    +
    +
    +
    /***
    +''InlineJavascriptPlugin for ~TiddlyWiki version 1.2.x and 2.0''
    +^^author: Eric Shulman - ELS Design Studios
    +source: http://www.TiddlyTools.com/#InlineJavascriptPlugin
    +license: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^
    +
    +Insert Javascript executable code directly into your tiddler content. Lets you ''call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.
    +!!!!!Usage
    +<<<
    +When installed, this plugin adds new wiki syntax for surrounding tiddler content with {{{<script>}}} and {{{</script>}}} markers, so that it can be treated as embedded javascript and executed each time the tiddler is rendered.
    +
    +''Deferred execution from an 'onClick' link''
    +By including a label="..." parameter in the initial {{{<script>}}} marker, the plugin will create a link to an 'onclick' script that will only be executed when that specific link is clicked, rather than running the script each time the tiddler is rendered.
    +
    +''External script source files:''
    +You can also load javascript from an external source URL, by including a src="..." parameter in the initial {{{<script>}}} marker (e.g., {{{<script src="demo.js"></script>}}}). This is particularly useful when incorporating third-party javascript libraries for use in custom extensions and plugins. The 'foreign' javascript code remains isolated in a separate file that can be easily replaced whenever an updated library file becomes available.
    +
    +''Defining javascript functions and libraries:''
    +Although the external javascript file is loaded while the tiddler content is being rendered, any functions it defines will not be available for use until //after// the rendering has been completed. Thus, you cannot load a library and //immediately// use it's functions within the same tiddler. However, once that tiddler has been loaded, the library functions can be freely used in any tiddler (even the one in which it was initially loaded).
    +
    +To ensure that your javascript functions are always available when needed, you should load the libraries from a tiddler that will be rendered as soon as your TiddlyWiki document is opened. For example, you could put your {{{<script src="..."></script>}}} syntax into a tiddler called LoadScripts, and then add {{{<<tiddler LoadScripts>>}}} in your MainMenu tiddler.
    +
    +Since the MainMenu is always rendered immediately upon opening your document, the library will always be loaded before any other tiddlers that rely upon the functions it defines. Loading an external javascript library does not produce any direct output in the tiddler, so these definitions should have no impact on the appearance of your MainMenu.
    +
    +''Creating dynamic tiddler content''
    +An important difference between this implementation of embedded scripting and conventional embedded javascript techniques for web pages is the method used to produce output that is dynamically inserted into the document:
    +* In a typical web document, you use the document.write() function to output text sequences (often containing HTML tags) that are then rendered when the entire document is first loaded into the browser window.
    +* However, in a ~TiddlyWiki document, tiddlers (and other DOM elements) are created, deleted, and rendered "on-the-fly", so writing directly to the global 'document' object does not produce the results you want (i.e., replacing the embedded script within the tiddler content), and completely replaces the entire ~TiddlyWiki document in your browser window.
    +* To allow these scripts to work unmodified, the plugin automatically converts all occurences of document.write() so that the output is inserted into the tiddler content instead of replacing the entire ~TiddlyWiki document.
    +
    +If your script does not use document.write() to create dynamically embedded content within a tiddler, your javascript can, as an alternative, explicitly return a text value that the plugin can then pass through the wikify() rendering engine to insert into the tiddler display. For example, using {{{return "thistext"}}} will produce the same output as {{{document.write("thistext")}}}.
    +
    +//Note: your script code is automatically 'wrapped' inside a function, {{{_out()}}}, so that any return value you provide can be correctly handled by the plugin and inserted into the tiddler. To avoid unpredictable results (and possibly fatal execution errors), this function should never be redefined or called from ''within'' your script code.//
    +
    +''Accessing the ~TiddlyWiki DOM''
    +The plugin provides one pre-defined variable, 'place', that is passed in to your javascript code so that it can have direct access to the containing DOM element into which the tiddler output is currently being rendered.
    +
    +Access to this DOM element allows you to create scripts that can:
    +* vary their actions based upon the specific location in which they are embedded
    +* access 'tiddler-relative' information (use findContainingTiddler(place))
    +* perform direct DOM manipulations (when returning wikified text is not enough)
    +<<<
    +!!!!!Examples
    +<<<
    +an "alert" message box:
    +{{{
    +<script>alert('InlineJavascriptPlugin: this is a demonstration message');</script>
    +}}}
    +<script>alert('InlineJavascriptPlugin: this is a demonstration message');</script>
    +
    +dynamic output:
    +{{{
    +<script>return (new Date()).toString();</script>
    +}}}
    +<script>return (new Date()).toString();</script>
    +
    +wikified dynamic output:
    +{{{
    +<script>return "link to current user: [["+config.options.txtUserName+"]]";</script>
    +}}}
    +<script>return "link to current user: [["+config.options.txtUserName+"]]";</script>
    +
    +dynamic output using 'place' to get size information for current tiddler
    +{{{
    +<script>
    + if (!window.story) window.story=window;
    + var title=story.findContainingTiddler(place).id.substr(7);
    + return title+" is using "+store.getTiddlerText(title).length+" bytes";
    +</script>
    +}}}
    +<script>
    + if (!window.story) window.story=window;
    + var title=story.findContainingTiddler(place).id.substr(7);
    + return title+" is using "+store.getTiddlerText(title).length+" bytes";
    +</script>
    +
    +creating an 'onclick' button/link that runs a script
    +{{{
    +<script label="click here">
    + if (!window.story) window.story=window;
    + alert("Hello World!\nlinktext='"+place.firstChild.data+"'\ntiddler='"+story.findContainingTiddler(place).id.substr(7)+"'");
    +</script>
    +}}}
    +<script label="click here">
    + if (!window.story) window.story=window;
    + alert("Hello World!\nlinktext='"+place.firstChild.data+"'\ntiddler='"+story.findContainingTiddler(place).id.substr(7)+"'");
    +</script>
    +
    +loading a script from a source url
    +{{{
    +<script src="demo.js">return "loading demo.js..."</script>
    +<script label="click to execute demo() function">demo()</script>
    +}}}
    +where http://www.TiddlyTools.com/demo.js contains:
    +>function demo() { alert('this output is from demo(), defined in demo.js') }
    +>alert('InlineJavascriptPlugin: demo.js has been loaded');
    +<script src="demo.js">return "loading demo.js..."</script>
    +<script label="click to execute demo() function">demo()</script>
    +<<<
    +!!!!!Installation
    +<<<
    +import (or copy/paste) the following tiddlers into your document:
    +''InlineJavascriptPlugin'' (tagged with <<tag systemConfig>>)
    +<<<
    +!!!!!Revision History
    +<<<
    +''2006.01.05 [1.4.0]''
    +added support 'onclick' scripts. When label="..." param is present, a button/link is created using the indicated label text, and the script is only executed when the button/link is clicked. 'place' value is set to match the clicked button/link element.
    +''2005.12.13 [1.3.1]''
    +when catching eval error in IE, e.description contains the error text, instead of e.toString(). Fixed error reporting so IE shows the correct response text. Based on a suggestion by UdoBorkowski
    +''2005.11.09 [1.3.0]''
    +for 'inline' scripts (i.e., not scripts loaded with src="..."), automatically replace calls to 'document.write()' with 'place.innerHTML+=' so script output is directed into tiddler content
    +Based on a suggestion by BradleyMeck
    +''2005.11.08 [1.2.0]''
    +handle loading of javascript from an external URL via src="..." syntax
    +''2005.11.08 [1.1.0]''
    +pass 'place' param into scripts to provide direct DOM access 
    +''2005.11.08 [1.0.0]''
    +initial release
    +<<<
    +!!!!!Credits
    +<<<
    +This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]
    +<<<
    +!!!!!Code
    +***/
    +//{{{
    +version.extensions.inlineJavascript= {major: 1, minor: 4, revision: 0, date: new Date(2006,1,5)};
    +
    +config.formatters.push( {
    + name: "inlineJavascript",
    + match: "\\<script",
    + lookahead: "\\<script(?: src=\\\"((?:.|\\n)*?)\\\")?(?: label=\\\"((?:.|\\n)*?)\\\")?\\>((?:.|\\n)*?)\\</script\\>",
    +
    + handler: function(w) {
    + var lookaheadRegExp = new RegExp(this.lookahead,"mg");
    + lookaheadRegExp.lastIndex = w.matchStart;
    + var lookaheadMatch = lookaheadRegExp.exec(w.source)
    + if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
    + if (lookaheadMatch[1]) { // load a script library
    + // make script tag, set src, add to body to execute, then remove for cleanup
    + var script = document.createElement("script"); script.src = lookaheadMatch[1];
    + document.body.appendChild(script); document.body.removeChild(script);
    + }
    + if (lookaheadMatch[2] && lookaheadMatch[3]) { // create a link to an 'onclick' script
    + // add a link, define click handler, save code in link (pass 'place'), set link attributes
    + var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",lookaheadMatch[2]);
    + link.onclick=function(){try{return(eval(this.code))}catch(e){alert(e.description?e.description:e.toString())}}
    + link.code="function _out(place){"+lookaheadMatch[3]+"};_out(this);"
    + link.setAttribute("href","javascript:;"); link.setAttribute("title",""); link.style.cursor="pointer";
    + }
    + else if (lookaheadMatch[3]) { // run inline script code
    + var code="function _out(place){"+lookaheadMatch[3]+"};_out(w.output);"
    + code=code.replace(/document.write\(/gi,'place.innerHTML+=(');
    + try { var out = eval(code); } catch(e) { out = e.description?e.description:e.toString(); }
    + if (out && out.length) wikify(out,w.output);
    + }
    + w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
    + }
    + }
    +} )
    +//}}}
    +
    +
    +
    +
    /***
    +|''Name:''|InlineJavascriptPlugin|
    +|''Source:''|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
    +|''Author:''|Eric Shulman - ELS Design Studios|
    +|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
    +|''~CoreVersion:''|2.0.10|
    +
    +Insert Javascript executable code directly into your tiddler content. Lets you ''call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.
    +!!!!!Usage
    +<<<
    +When installed, this plugin adds new wiki syntax for surrounding tiddler content with {{{<script>}}} and {{{</script>}}} markers, so that it can be treated as embedded javascript and executed each time the tiddler is rendered.
    +
    +''Deferred execution from an 'onClick' link''
    +By including a label="..." parameter in the initial {{{<script>}}} marker, the plugin will create a link to an 'onclick' script that will only be executed when that specific link is clicked, rather than running the script each time the tiddler is rendered.
    +
    +''External script source files:''
    +You can also load javascript from an external source URL, by including a src="..." parameter in the initial {{{<script>}}} marker (e.g., {{{<script src="demo.js"></script>}}}). This is particularly useful when incorporating third-party javascript libraries for use in custom extensions and plugins. The 'foreign' javascript code remains isolated in a separate file that can be easily replaced whenever an updated library file becomes available.
    +
    +''Display script source in tiddler output''
    +By including the keyword parameter "show", in the initial {{{<script>}}} marker, the plugin will include the script source code in the output that it displays in the tiddler.
    +
    +''Defining javascript functions and libraries:''
    +Although the external javascript file is loaded while the tiddler content is being rendered, any functions it defines will not be available for use until //after// the rendering has been completed. Thus, you cannot load a library and //immediately// use it's functions within the same tiddler. However, once that tiddler has been loaded, the library functions can be freely used in any tiddler (even the one in which it was initially loaded).
    +
    +To ensure that your javascript functions are always available when needed, you should load the libraries from a tiddler that will be rendered as soon as your TiddlyWiki document is opened. For example, you could put your {{{<script src="..."></script>}}} syntax into a tiddler called LoadScripts, and then add {{{<<tiddler LoadScripts>>}}} in your MainMenu tiddler.
    +
    +Since the MainMenu is always rendered immediately upon opening your document, the library will always be loaded before any other tiddlers that rely upon the functions it defines. Loading an external javascript library does not produce any direct output in the tiddler, so these definitions should have no impact on the appearance of your MainMenu.
    +
    +''Creating dynamic tiddler content''
    +An important difference between this implementation of embedded scripting and conventional embedded javascript techniques for web pages is the method used to produce output that is dynamically inserted into the document:
    +* In a typical web document, you use the document.write() function to output text sequences (often containing HTML tags) that are then rendered when the entire document is first loaded into the browser window.
    +* However, in a ~TiddlyWiki document, tiddlers (and other DOM elements) are created, deleted, and rendered "on-the-fly", so writing directly to the global 'document' object does not produce the results you want (i.e., replacing the embedded script within the tiddler content), and completely replaces the entire ~TiddlyWiki document in your browser window.
    +* To allow these scripts to work unmodified, the plugin automatically converts all occurences of document.write() so that the output is inserted into the tiddler content instead of replacing the entire ~TiddlyWiki document.
    +
    +If your script does not use document.write() to create dynamically embedded content within a tiddler, your javascript can, as an alternative, explicitly return a text value that the plugin can then pass through the wikify() rendering engine to insert into the tiddler display. For example, using {{{return "thistext"}}} will produce the same output as {{{document.write("thistext")}}}.
    +
    +//Note: your script code is automatically 'wrapped' inside a function, {{{_out()}}}, so that any return value you provide can be correctly handled by the plugin and inserted into the tiddler. To avoid unpredictable results (and possibly fatal execution errors), this function should never be redefined or called from ''within'' your script code.//
    +
    +''Accessing the ~TiddlyWiki DOM''
    +The plugin provides one pre-defined variable, 'place', that is passed in to your javascript code so that it can have direct access to the containing DOM element into which the tiddler output is currently being rendered.
    +
    +Access to this DOM element allows you to create scripts that can:
    +* vary their actions based upon the specific location in which they are embedded
    +* access 'tiddler-relative' information (use findContainingTiddler(place))
    +* perform direct DOM manipulations (when returning wikified text is not enough)
    +<<<
    +!!!!!Examples
    +<<<
    +an "alert" message box:
    +><script show>
    + alert('InlineJavascriptPlugin: this is a demonstration message');
    +</script>
    +dynamic output:
    +><script show>
    + return (new Date()).toString();
    +</script>
    +wikified dynamic output:
    +><script show>
    + return "link to current user: [["+config.options.txtUserName+"]]";
    +</script>
    +dynamic output using 'place' to get size information for current tiddler:
    +><script show>
    + if (!window.story) window.story=window;
    + var title=story.findContainingTiddler(place).id.substr(7);
    + return title+" is using "+store.getTiddlerText(title).length+" bytes";
    +</script>
    +creating an 'onclick' button/link that runs a script:
    +><script label="click here" show>
    + if (!window.story) window.story=window;
    + alert("Hello World!\nlinktext='"+place.firstChild.data+"'\ntiddler='"+story.findContainingTiddler(place).id.substr(7)+"'");
    +</script>
    +loading a script from a source url:
    +>http://www.TiddlyTools.com/demo.js contains:
    +>>{{{function demo() { alert('this output is from demo(), defined in demo.js') } }}}
    +>>{{{alert('InlineJavascriptPlugin: demo.js has been loaded'); }}}
    +><script src="demo.js" show>
    + return "loading demo.js..."
    +</script>
    +><script label="click to execute demo() function" show>
    + demo()
    +</script>
    +<<<
    +!!!!!Installation
    +<<<
    +import (or copy/paste) the following tiddlers into your document:
    +''InlineJavascriptPlugin'' (tagged with <<tag systemConfig>>)
    +<<<
    +!!!!!Revision History
    +<<<
    +''2006.06.01 [1.5.1]'' when calling wikify() on script return value, pass hightlightRegExp and tiddler params so macros that rely on these values can render properly
    +''2006.04.19 [1.5.0]'' added 'show' parameter to force display of javascript source code in tiddler output
    +''2006.01.05 [1.4.0]'' added support 'onclick' scripts. When label="..." param is present, a button/link is created using the indicated label text, and the script is only executed when the button/link is clicked. 'place' value is set to match the clicked button/link element.
    +''2005.12.13 [1.3.1]'' when catching eval error in IE, e.description contains the error text, instead of e.toString(). Fixed error reporting so IE shows the correct response text. Based on a suggestion by UdoBorkowski
    +''2005.11.09 [1.3.0]'' for 'inline' scripts (i.e., not scripts loaded with src="..."), automatically replace calls to 'document.write()' with 'place.innerHTML+=' so script output is directed into tiddler content. Based on a suggestion by BradleyMeck
    +''2005.11.08 [1.2.0]'' handle loading of javascript from an external URL via src="..." syntax
    +''2005.11.08 [1.1.0]'' pass 'place' param into scripts to provide direct DOM access 
    +''2005.11.08 [1.0.0]'' initial release
    +<<<
    +!!!!!Credits
    +<<<
    +This feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]
    +<<<
    +!!!!!Code
    +***/
    +//{{{
    +version.extensions.inlineJavascript= {major: 1, minor: 5, revision: 1, date: new Date(2006,6,1)};
    +
    +config.formatters.push( {
    + name: "inlineJavascript",
    + match: "\\<script",
    + lookahead: "\\<script(?: src=\\\"((?:.|\\n)*?)\\\")?(?: label=\\\"((?:.|\\n)*?)\\\")?( show)?\\>((?:.|\\n)*?)\\</script\\>",
    +
    + handler: function(w) {
    + var lookaheadRegExp = new RegExp(this.lookahead,"mg");
    + lookaheadRegExp.lastIndex = w.matchStart;
    + var lookaheadMatch = lookaheadRegExp.exec(w.source)
    + if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
    + if (lookaheadMatch[1]) { // load a script library
    + // make script tag, set src, add to body to execute, then remove for cleanup
    + var script = document.createElement("script"); script.src = lookaheadMatch[1];
    + document.body.appendChild(script); document.body.removeChild(script);
    + }
    + if (lookaheadMatch[4]) { // there is script code
    + if (lookaheadMatch[3]) // show inline script code in tiddler output
    + wikify("{{{\n"+lookaheadMatch[0]+"\n}}}\n",w.output);
    + if (lookaheadMatch[2]) { // create a link to an 'onclick' script
    + // add a link, define click handler, save code in link (pass 'place'), set link attributes
    + var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",lookaheadMatch[2]);
    + link.onclick=function(){try{return(eval(this.code))}catch(e){alert(e.description?e.description:e.toString())}}
    + link.code="function _out(place){"+lookaheadMatch[4]+"};_out(this);"
    + link.setAttribute("href","javascript:;"); link.setAttribute("title",""); link.style.cursor="pointer";
    + }
    + else { // run inline script code
    + var code="function _out(place){"+lookaheadMatch[4]+"};_out(w.output);"
    + code=code.replace(/document.write\(/gi,'place.innerHTML+=(');
    + try { var out = eval(code); } catch(e) { out = e.description?e.description:e.toString(); }
    + if (out && out.length) wikify(out,w.output,w.highlightRegExp,w.tiddler);
    + }
    + }
    + w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
    + }
    + }
    +} )
    +//}}}
    +
    +
    +
    ''[[Lumiera|index.html]]''
    +RoadMap
    +ToDo
    +[[Tasks]]
    +[[Admin]]
    +<<fullscreen>>
    +
    +
    +
    <!--{{{-->
    +<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>
    +<!--}}}-->
    +
    +<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>My TiddlyWiki</b> is loading<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Requires Javascript.</span></div>
    +
    +
    +
    Here we describe the things which are planned and going on.
    +
    +There is:
    + * A RoadMap which gives a coarse overview of the project.
    + * A ToDo list, showing whats left to be done on a intermediate to high level
    + * A list of detailed [[Tasks]] which are imminent to do.
    +
    +The goal of this wiki is not to track each and every task, but show whats going on and where possible contributors can pick a job.
    +
    +
    +
    +
    +
    +
    <!--{{{-->
    +<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
    +	<div class='headerShadow'>
    +		<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
    +		<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
    +	</div>
    +	<div class='headerForeground'>
    +		<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
    +		<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
    +	</div>
    +</div>
    +<!-- horizontal MainMenu -->
    +<div id='topMenu' refresh='content' tiddler='MainMenu'></div>
    +<!-- original MainMenu menu -->
    +<!-- <div id='mainMenu' refresh='content' tiddler='MainMenu'></div> -->
    +<div id='sidebar'>
    +	<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
    +	<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
    +</div>
    +<div id='displayArea'>
    +	<div id='messageArea'></div>
    +	<div id='tiddlerDisplay'></div>
    +</div>
    +<!--}}}-->
    +
    +
    +
    +
    /***
    +|<html><a name="Top"/></html>''Name:''|PartTiddlerPlugin|
    +|''Version:''|1.0.6 (2006-11-07)|
    +|''Source:''|http://tiddlywiki.abego-software.de/#PartTiddlerPlugin|
    +|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
    +|''Licence:''|[[BSD open source license]]|
    +|''TiddlyWiki:''|2.0|
    +|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
    +!Table of Content<html><a name="TOC"/></html>
    +* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Description',null, event)">Description, Syntax</a></html>
    +* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Applications',null, event)">Applications</a></html>
    +** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('LongTiddler',null, event)">Refering to Paragraphs of a Longer Tiddler</a></html>
    +** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Citation',null, event)">Citation Index</a></html>
    +** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('TableCells',null, event)">Creating "multi-line" Table Cells</a></html>
    +** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Tabs',null, event)">Creating Tabs</a></html>
    +** <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Sliders',null, event)">Using Sliders</a></html>
    +* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Revisions',null, event)">Revision History</a></html>
    +* <html><a href="javascript:;" onclick="window.scrollAnchorVisible('Code',null, event)">Code</a></html>
    +!Description<html><a name="Description"/></html>
    +With the {{{<part aPartName> ... </part>}}} feature you can structure your tiddler text into separate (named) parts. 
    +Each part can be referenced as a "normal" tiddler, using the "//tiddlerName//''/''//partName//" syntax (e.g. "About/Features"). E.g. you may create links to the parts, use it in {{{<<tiddler...>>}}} or {{{<<tabs...>>}}} macros etc.
    +
    +''Syntax:'' 
    +|>|''<part'' //partName// [''hidden''] ''>'' //any tiddler content// ''</part>''|
    +|//partName//|The name of the part. You may reference a part tiddler with the combined tiddler name "//nameOfContainerTidder//''/''//partName//.|
    +|''hidden''|When defined the content of the part is not displayed in the container tiddler. But when the part is explicitly referenced (e.g. in a {{{<<tiddler...>>}}} macro or in a link) the part's content is displayed.|
    +|<html><i>any&nbsp;tiddler&nbsp;content</i></html>|<html>The content of the part.<br>A part can have any content that a "normal" tiddler may have, e.g. you may use all the formattings and macros defined.</html>|
    +|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|
    +<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +
    +!Applications<html><a name="Applications"/></html>
    +!!Refering to Paragraphs of a Longer Tiddler<html><a name="LongTiddler"/></html>
    +Assume you have written a long description in a tiddler and now you want to refer to the content of a certain paragraph in that tiddler (e.g. some definition.) Just wrap the text with a ''part'' block, give it a nice name, create a "pretty link" (like {{{[[Discussion Groups|Introduction/DiscussionGroups]]}}}) and you are done.
    +
    +Notice this complements the approach to first writing a lot of small tiddlers and combine these tiddlers to one larger tiddler in a second step (e.g. using the {{{<<tiddler...>>}}} macro). Using the ''part'' feature you can first write a "classic" (longer) text that can be read "from top to bottom" and later "reuse" parts of this text for some more "non-linear" reading.
    +
    +<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +
    +!!Citation Index<html><a name="Citation"/></html>
    +Create a tiddler "Citations" that contains your "citations". 
    +Wrap every citation with a part and a proper name. 
    +
    +''Example''
    +{{{
    +<part BAX98>Baxter, Ira D. et al: //Clone Detection Using Abstract Syntax Trees.// 
    +in //Proc. ICSM//, 1998.</part>
    +
    +<part BEL02>Bellon, Stefan: //Vergleich von Techniken zur Erkennung duplizierten Quellcodes.// 
    +Thesis, Uni Stuttgart, 2002.</part>
    +
    +<part DUC99>Ducasse, Stéfane et al: //A Language Independent Approach for Detecting Duplicated Code.// 
    +in //Proc. ICSM//, 1999.</part>
    +}}}
    +
    +You may now "cite" them just by using a pretty link like {{{[[Citations/BAX98]]}}} or even more pretty, like this {{{[[BAX98|Citations/BAX98]]}}}.
    +
    +<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +
    +!!Creating "multi-line" Table Cells<html><a name="TableCells"/></html>
    +You may have noticed that it is hard to create table cells with "multi-line" content. E.g. if you want to create a bullet list inside a table cell you cannot just write the bullet list
    +{{{
    +* Item 1
    +* Item 2
    +* Item 3
    +}}}
    +into a table cell (i.e. between the | ... | bars) because every bullet item must start in a new line but all cells of a table row must be in one line.
    +
    +Using the ''part'' feature this problem can be solved. Just create a hidden part that contains the cells content and use a {{{<<tiddler >>}}} macro to include its content in the table's cell.
    +
    +''Example''
    +{{{
    +|!Subject|!Items|
    +|subject1|<<tiddler ./Cell1>>|
    +|subject2|<<tiddler ./Cell2>>|
    +
    +<part Cell1 hidden>
    +* Item 1
    +* Item 2
    +* Item 3
    +</part>
    +...
    +}}}
    +
    +Notice that inside the {{{<<tiddler ...>>}}} macro you may refer to the "current tiddler" using the ".".
    +
    +BTW: The same approach can be used to create bullet lists with items that contain more than one line.
    +
    +<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +
    +!!Creating Tabs<html><a name="Tabs"/></html>
    +The build-in {{{<<tabs ...>>}}} macro requires that you defined an additional tiddler for every tab it displays. When you want to have "nested" tabs you need to define a tiddler for the "main tab" and one for every tab it contains. I.e. the definition of a set of tabs that is visually displayed at one place is distributed across multiple tiddlers.
    +
    +With the ''part'' feature you can put the complete definition in one tiddler, making it easier to keep an overview and maintain the tab sets.
    +
    +''Example''
    +The standard tabs at the sidebar are defined by the following eight tiddlers:
    +* SideBarTabs
    +* TabAll
    +* TabMore
    +* TabMoreMissing
    +* TabMoreOrphans
    +* TabMoreShadowed
    +* TabTags
    +* TabTimeline
    +
    +Instead of these eight tiddlers one could define the following SideBarTabs tiddler that uses the ''part'' feature:
    +{{{
    +<<tabs txtMainTab 
    + Timeline Timeline SideBarTabs/Timeline 
    + All 'All tiddlers' SideBarTabs/All 
    + Tags 'All tags' SideBarTabs/Tags 
    + More 'More lists' SideBarTabs/More>>
    +<part Timeline hidden><<timeline>></part>
    +<part All hidden><<list all>></part>
    +<part Tags hidden><<allTags>></part>
    +<part More hidden><<tabs txtMoreTab 
    + Missing 'Missing tiddlers' SideBarTabs/Missing 
    + Orphans 'Orphaned tiddlers' SideBarTabs/Orphans 
    + Shadowed 'Shadowed tiddlers' SideBarTabs/Shadowed>></part>
    +<part Missing hidden><<list missing>></part>
    +<part Orphans hidden><<list orphans>></part>
    +<part Shadowed hidden><<list shadowed>></part>
    +}}}
    +
    +Notice that you can easily "overwrite" individual parts in separate tiddlers that have the full name of the part.
    +
    +E.g. if you don't like the classic timeline tab but only want to see the 100 most recent tiddlers you could create a tiddler "~SideBarTabs/Timeline" with the following content:
    +{{{
    +<<forEachTiddler 
    + sortBy 'tiddler.modified' descending 
    + write '(index < 100) ? "* [["+tiddler.title+"]]\n":""'>>
    +}}}
    +<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +
    +!!Using Sliders<html><a name="Sliders"/></html>
    +Very similar to the build-in {{{<<tabs ...>>}}} macro (see above) the {{{<<slider ...>>}}} macro requires that you defined an additional tiddler that holds the content "to be slid". You can avoid creating this extra tiddler by using the ''part'' feature
    +
    +''Example''
    +In a tiddler "About" we may use the slider to show some details that are documented in the tiddler's "Details" part.
    +{{{
    +...
    +<<slider chkAboutDetails About/Details details "Click here to see more details">>
    +<part Details hidden>
    +To give you a better overview ...
    +</part>
    +...
    +}}}
    +
    +Notice that putting the content of the slider into the slider's tiddler also has an extra benefit: When you decide you need to edit the content of the slider you can just doubleclick the content, the tiddler opens for editing and you can directly start editing the content (in the part section). In the "old" approach you would doubleclick the tiddler, see that the slider is using tiddler X, have to look for the tiddler X and can finally open it for editing. So using the ''part'' approach results in a much short workflow.
    +
    +<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +
    +!Revision history<html><a name="Revisions"/></html>
    +* v1.0.6 (2006-11-07)
    +** Bugfix: cannot edit tiddler when UploadPlugin by Bidix is installed. Thanks to José Luis González Castro for reporting the bug.
    +* v1.0.5 (2006-03-02)
    +** Bugfix: Example with multi-line table cells does not work in IE6. Thanks to Paulo Soares for reporting the bug.
    +* v1.0.4 (2006-02-28)
    +** Bugfix: Shadow tiddlers cannot be edited (in TW 2.0.6). Thanks to Torsten Vanek for reporting the bug.
    +* v1.0.3 (2006-02-26)
    +** Adapt code to newly introduced Tiddler.prototype.isReadOnly() function (in TW 2.0.6). Thanks to Paulo Soares for reporting the problem.
    +* v1.0.2 (2006-02-05)
    +** Also allow other macros than the "tiddler" macro use the "." in the part reference (to refer to "this" tiddler)
    +* v1.0.1 (2006-01-27)
    +** Added Table of Content for plugin documentation. Thanks to RichCarrillo for suggesting.
    +** Bugfix: newReminder plugin does not work when PartTiddler is installed. Thanks to PauloSoares for reporting.
    +* v1.0.0 (2006-01-25)
    +** initial version
    +<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +
    +!Code<html><a name="Code"/></html>
    +<html><sub><a href="javascript:;" onclick="window.scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +***/
    +//{{{
    +//============================================================================
    +// PartTiddlerPlugin
    +
    +// Ensure that the PartTiddler Plugin is only installed once.
    +//
    +if (!version.extensions.PartTiddlerPlugin) {
    +
    +
    +
    +version.extensions.PartTiddlerPlugin = {
    + major: 1, minor: 0, revision: 6,
    + date: new Date(2006, 10, 7), 
    + type: 'plugin',
    + source: "http://tiddlywiki.abego-software.de/#PartTiddlerPlugin"
    +};
    +
    +if (!window.abego) window.abego = {};
    +if (version.major < 2) alertAndThrow("PartTiddlerPlugin requires TiddlyWiki 2.0 or newer.");
    +
    +//============================================================================
    +// Common Helpers
    +
    +// Looks for the next newline, starting at the index-th char of text. 
    +//
    +// If there are only whitespaces between index and the newline 
    +// the index behind the newline is returned, 
    +// otherwise (or when no newline is found) index is returned.
    +//
    +var skipEmptyEndOfLine = function(text, index) {
    + var re = /(\n|[^\s])/g;
    + re.lastIndex = index;
    + var result = re.exec(text);
    + return (result && text.charAt(result.index) == '\n') 
    + ? result.index+1
    + : index;
    +}
    +
    +
    +//============================================================================
    +// Constants
    +
    +var partEndOrStartTagRE = /(<\/part>)|(<part(?:\s+)((?:[^>])+)>)/mg;
    +var partEndTagREString = "<\\/part>";
    +var partEndTagString = "</part>";
    +
    +//============================================================================
    +// Plugin Specific Helpers
    +
    +// Parse the parameters inside a <part ...> tag and return the result.
    +//
    +// @return [may be null] {partName: ..., isHidden: ...}
    +//
    +var parseStartTagParams = function(paramText) {
    + var params = paramText.readMacroParams();
    + if (params.length == 0 || params[0].length == 0) return null;
    + 
    + var name = params[0];
    + var paramsIndex = 1;
    + var hidden = false;
    + if (paramsIndex < params.length) {
    + hidden = params[paramsIndex] == "hidden";
    + paramsIndex++;
    + }
    + 
    + return {
    + partName: name, 
    + isHidden: hidden
    + };
    +}
    +
    +// Returns the match to the next (end or start) part tag in the text, 
    +// starting the search at startIndex.
    +// 
    +// When no such tag is found null is returned, otherwise a "Match" is returned:
    +// [0]: full match
    +// [1]: matched "end" tag (or null when no end tag match)
    +// [2]: matched "start" tag (or null when no start tag match)
    +// [3]: content of start tag (or null if no start tag match)
    +//
    +var findNextPartEndOrStartTagMatch = function(text, startIndex) {
    + var re = new RegExp(partEndOrStartTagRE);
    + re.lastIndex = startIndex;
    + var match = re.exec(text);
    + return match;
    +}
    +
    +//============================================================================
    +// Formatter
    +
    +// Process the <part ...> ... </part> starting at (w.source, w.matchStart) for formatting.
    +//
    +// @return true if a complete part section (including the end tag) could be processed, false otherwise.
    +//
    +var handlePartSection = function(w) {
    + var tagMatch = findNextPartEndOrStartTagMatch(w.source, w.matchStart);
    + if (!tagMatch) return false;
    + if (tagMatch.index != w.matchStart || !tagMatch[2]) return false;
    +
    + // Parse the start tag parameters
    + var arguments = parseStartTagParams(tagMatch[3]);
    + if (!arguments) return false;
    + 
    + // Continue processing
    + var startTagEndIndex = skipEmptyEndOfLine(w.source, tagMatch.index + tagMatch[0].length);
    + var endMatch = findNextPartEndOrStartTagMatch(w.source, startTagEndIndex);
    + if (endMatch && endMatch[1]) {
    + if (!arguments.isHidden) {
    + w.nextMatch = startTagEndIndex;
    + w.subWikify(w.output,partEndTagREString);
    + }
    + w.nextMatch = skipEmptyEndOfLine(w.source, endMatch.index + endMatch[0].length);
    + 
    + return true;
    + }
    + return false;
    +}
    +
    +config.formatters.push( {
    + name: "part",
    + match: "<part\\s+[^>]+>",
    + 
    + handler: function(w) {
    + if (!handlePartSection(w)) {
    + w.outputText(w.output,w.matchStart,w.matchStart+w.matchLength);
    + }
    + }
    +} )
    +
    +//============================================================================
    +// Extend "fetchTiddler" functionality to also recognize "part"s of tiddlers 
    +// as tiddlers.
    +
    +var currentParent = null; // used for the "." parent (e.g. in the "tiddler" macro)
    +
    +// Return the match to the first <part ...> tag of the text that has the
    +// requrest partName.
    +//
    +// @return [may be null]
    +//
    +var findPartStartTagByName = function(text, partName) {
    + var i = 0;
    + 
    + while (true) {
    + var tagMatch = findNextPartEndOrStartTagMatch(text, i);
    + if (!tagMatch) return null;
    +
    + if (tagMatch[2]) {
    + // Is start tag
    + 
    + // Check the name
    + var arguments = parseStartTagParams(tagMatch[3]);
    + if (arguments && arguments.partName == partName) {
    + return tagMatch;
    + }
    + }
    + i += tagMatch[0].length;
    + }
    +}
    +
    +// Return the part "partName" of the given parentTiddler as a "readOnly" Tiddler 
    +// object, using fullName as the Tiddler's title. 
    +//
    +// All remaining properties of the new Tiddler (tags etc.) are inherited from 
    +// the parentTiddler.
    +// 
    +// @return [may be null]
    +//
    +var getPart = function(parentTiddler, partName, fullName) {
    + var text = parentTiddler.text;
    + var startTag = findPartStartTagByName(text, partName);
    + if (!startTag) return null;
    + 
    + var endIndexOfStartTag = skipEmptyEndOfLine(text, startTag.index+startTag[0].length);
    + var indexOfEndTag = text.indexOf(partEndTagString, endIndexOfStartTag);
    +
    + if (indexOfEndTag >= 0) {
    + var partTiddlerText = text.substring(endIndexOfStartTag,indexOfEndTag);
    + var partTiddler = new Tiddler();
    + partTiddler.set(
    + fullName,
    + partTiddlerText,
    + parentTiddler.modifier,
    + parentTiddler.modified,
    + parentTiddler.tags,
    + parentTiddler.created);
    + partTiddler.abegoIsPartTiddler = true;
    + return partTiddler;
    + }
    + 
    + return null;
    +}
    +
    +// Hijack the store.fetchTiddler to recognize the "part" addresses.
    +//
    +
    +var oldFetchTiddler = store.fetchTiddler ;
    +store.fetchTiddler = function(title) {
    + var result = oldFetchTiddler.apply(this, arguments);
    + if (!result && title) {
    + var i = title.lastIndexOf('/');
    + if (i > 0) {
    + var parentName = title.substring(0, i);
    + var partName = title.substring(i+1);
    + var parent = (parentName == ".") 
    + ? currentParent 
    + : oldFetchTiddler.apply(this, [parentName]);
    + if (parent) {
    + return getPart(parent, partName, parent.title+"/"+partName);
    + }
    + }
    + }
    + return result; 
    +};
    +
    +
    +// The user must not edit a readOnly/partTiddler
    +//
    +
    +config.commands.editTiddler.oldIsReadOnlyFunction = Tiddler.prototype.isReadOnly;
    +
    +Tiddler.prototype.isReadOnly = function() {
    + // Tiddler.isReadOnly was introduced with TW 2.0.6.
    + // For older version we explicitly check the global readOnly flag
    + if (config.commands.editTiddler.oldIsReadOnlyFunction) {
    + if (config.commands.editTiddler.oldIsReadOnlyFunction.apply(this, arguments)) return true;
    + } else {
    + if (readOnly) return true;
    + }
    +
    + return this.abegoIsPartTiddler;
    +}
    +
    +config.commands.editTiddler.handler = function(event,src,title)
    +{
    + var t = store.getTiddler(title);
    + // Edit the tiddler if it either is not a tiddler (but a shadowTiddler)
    + // or the tiddler is not readOnly
    + if(!t || !t.abegoIsPartTiddler)
    + {
    + clearMessage();
    + story.displayTiddler(null,title,DEFAULT_EDIT_TEMPLATE);
    + story.focusTiddler(title,"text");
    + return false;
    + }
    +}
    +
    +// To allow the "./partName" syntax in macros we need to hijack 
    +// the invokeMacro to define the "currentParent" while it is running.
    +// 
    +var oldInvokeMacro = window.invokeMacro;
    +function myInvokeMacro(place,macro,params,wikifier,tiddler) {
    + var oldCurrentParent = currentParent;
    + if (tiddler) currentParent = tiddler;
    + try {
    + oldInvokeMacro.apply(this, arguments);
    + } finally {
    + currentParent = oldCurrentParent;
    + }
    +}
    +window.invokeMacro = myInvokeMacro;
    +
    +// Scroll the anchor anchorName in the viewer of the given tiddler visible.
    +// When no tiddler is defined use the tiddler of the target given event is used.
    +window.scrollAnchorVisible = function(anchorName, tiddler, evt) {
    + var tiddlerElem = null;
    + if (tiddler) {
    + tiddlerElem = document.getElementById(story.idPrefix + tiddler);
    + }
    + if (!tiddlerElem && evt) {
    + var target = resolveTarget(evt);
    + tiddlerElem = story.findContainingTiddler(target);
    + }
    + if (!tiddlerElem) return;
    +
    + var children = tiddlerElem.getElementsByTagName("a");
    + for (var i = 0; i < children.length; i++) {
    + var child = children[i];
    + var name = child.getAttribute("name");
    + if (name == anchorName) {
    + var y = findPosY(child);
    + window.scrollTo(0,y);
    + return;
    + }
    + }
    +}
    +
    +} // of "install only once"
    +//}}}
    +
    +/***
    +<html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +
    +!Licence and Copyright
    +Copyright (c) abego Software ~GmbH, 2006 ([[www.abego-software.de|http://www.abego-software.de]])
    +
    +Redistribution and use in source and binary forms, with or without modification,
    +are permitted provided that the following conditions are met:
    +
    +Redistributions of source code must retain the above copyright notice, this
    +list of conditions and the following disclaimer.
    +
    +Redistributions in binary form must reproduce the above copyright notice, this
    +list of conditions and the following disclaimer in the documentation and/or other
    +materials provided with the distribution.
    +
    +Neither the name of abego Software nor the names of its contributors may be
    +used to endorse or promote products derived from this software without specific
    +prior written permission.
    +
    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
    +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
    +SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
    +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
    +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
    +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
    +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
    +DAMAGE.
    +
    +<html><sub><a href="javascript:;" onclick="scrollAnchorVisible('Top',null, event)">[Top]</sub></a></html>
    +***/
    +
    +
    +
    /***
    +|''Name:''|RSSReaderPlugin|
    +|''Description:''|This plugin provides a RSSReader for TiddlyWiki|
    +|''Version:''|1.1.1|
    +|''Date:''|Apr 21, 2007|
    +|''Source:''|http://tiddlywiki.bidix.info/#RSSReaderPlugin|
    +|''Documentation:''|http://tiddlywiki.bidix.info/#RSSReaderPluginDoc|
    +|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
    +|''Credit:''|BramChen for RssNewsMacro|
    +|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
    +|''~CoreVersion:''|2.2.0|
    +|''OptionalRequires:''|http://www.tiddlytools.com/#NestedSlidersPlugin|
    +***/
    +//{{{
    +version.extensions.RSSReaderPlugin = {
    +	major: 1, minor: 1, revision: 1,
    +	date: new Date("Apr 21, 2007"),
    +	source: "http://TiddlyWiki.bidix.info/#RSSReaderPlugin",
    +	author: "BidiX",
    +	coreVersion: '2.2.0'
    +};
    +
    +config.macros.rssReader = {
    +	dateFormat: "DDD, DD MMM YYYY",
    +	itemStyle: "display: block;border: 1px solid black;padding: 5px;margin: 5px;", //useed  '@@'+itemStyle+itemText+'@@'
    +	msg:{
    +		permissionDenied: "Permission to read preferences was denied.",
    +		noRSSFeed: "No RSS Feed at this address %0",
    +		urlNotAccessible: " Access to %0 is not allowed"
    +	},
    +	cache: [], 	// url => XMLHttpRequest.responseXML
    +	desc: "noDesc",
    +	
    +	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
    +		var desc = params[0];
    +		var feedURL = params[1];
    +		var toFilter = (params[2] ? true : false);
    +		var filterString = (toFilter?(params[2].substr(0,1) == ' '? tiddler.title:params[2]):'');
    +		var place = createTiddlyElement(place, "div", "RSSReader");
    +		wikify("^^<<rssFeedUpdate "+feedURL+" [[" + tiddler.title + "]]>>^^\n",place);
    +		if (this.cache[feedURL]) {
    +			this.displayRssFeed(this.cache[feedURL], feedURL, place, desc, toFilter, filterString);
    +		}
    +		else {
    +			var r = loadRemoteFile(feedURL,config.macros.rssReader.processResponse, [place, desc, toFilter, filterString]);
    +			if (typeof r == "string")
    +				displayMessage(r);
    +		}
    +		
    +	},
    +
    +	// callback for loadRemoteFile 
    +	// params : [place, desc, toFilter, filterString]
    +	processResponse: function(status, params, responseText, url, xhr) { // feedURL, place, desc, toFilter, filterString) {	
    +		if (window.netscape){
    +			try {
    +				if (document.location.protocol.indexOf("http") == -1) {
    +					netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
    +				}
    +			}
    +			catch (e) { displayMessage(e.description?e.description:e.toString()); }
    +		}
    +		if (xhr.status == httpStatus.NotFound)
    +		 {
    +			displayMessage(config.macros.rssReader.noRSSFeed.format([url]));
    +			return;
    +		}
    +		if (!status)
    +		 {
    +			displayMessage(config.macros.rssReader.noRSSFeed.format([url]));
    +			return;
    +		}
    +		if (xhr.responseXML) {
    +			// response is interpreted as XML
    +			config.macros.rssReader.cache[url] = xhr.responseXML;
    +			config.macros.rssReader.displayRssFeed(xhr.responseXML, params[0], url, params[1], params[2], params[3]);
    +		}
    +		else {
    +			if (responseText.substr(0,5) == "<?xml") {
    +				// response exists but not return as XML -> try to parse it 
    +				var dom = (new DOMParser()).parseFromString(responseText, "text/xml"); 
    +				if (dom) {
    +					// parsing successful so use it
    +					config.macros.rssReader.cache[url] = dom;
    +					config.macros.rssReader.displayRssFeed(dom, params[0], url, params[1], params[2], params[3]);
    +					return;
    +				}
    +			}
    +			// no XML display as html 
    +			wikify("<html>" + responseText + "</html>", params[0]);
    +			displayMessage(config.macros.rssReader.msg.noRSSFeed.format([url]));
    +		}
    +	},
    +
    +	// explore down the DOM tree
    +	displayRssFeed: function(xml, place, feedURL, desc, toFilter, filterString){
    +		// Channel
    +		var chanelNode = xml.getElementsByTagName('channel').item(0);
    +		var chanelTitleElement = (chanelNode ? chanelNode.getElementsByTagName('title').item(0) : null);
    +		var chanelTitle = "";
    +		if ((chanelTitleElement) && (chanelTitleElement.firstChild)) 
    +			chanelTitle = chanelTitleElement.firstChild.nodeValue;
    +		var chanelLinkElement = (chanelNode ? chanelNode.getElementsByTagName('link').item(0) : null);
    +		var chanelLink = "";
    +		if (chanelLinkElement) 
    +			chanelLink = chanelLinkElement.firstChild.nodeValue;
    +		var titleTxt = "!![["+chanelTitle+"|"+chanelLink+"]]\n";
    +		var title = createTiddlyElement(place,"div",null,"ChanelTitle",null);
    +		wikify(titleTxt,title);
    +		// ItemList
    +		var itemList = xml.getElementsByTagName('item');
    +		var article = createTiddlyElement(place,"ul",null,null,null);
    +		var lastDate;
    +		var re;
    +		if (toFilter) 
    +			re = new RegExp(filterString.escapeRegExp());
    +		for (var i=0; i<itemList.length; i++){
    +			var titleElm = itemList[i].getElementsByTagName('title').item(0);
    +			var titleText = (titleElm ? titleElm.firstChild.nodeValue : '');
    +			if (toFilter && ! titleText.match(re)) {
    +				continue;
    +			}
    +			var descText = '';
    +			descElem = itemList[i].getElementsByTagName('description').item(0);
    +			if (descElem){
    +				try{
    +					for (var ii=0; ii<descElem.childNodes.length; ii++) {
    +						descText += descElem.childNodes[ii].nodeValue;
    +					}
    +				}
    +				catch(e){}
    +				descText = descText.replace(/<br \/>/g,'\n');
    +				if (desc == "asHtml")
    +					descText = "<html>"+descText+"</html>";
    +			}
    +			var linkElm = itemList[i].getElementsByTagName("link").item(0);
    +			var linkURL = linkElm.firstChild.nodeValue;
    +			var pubElm = itemList[i].getElementsByTagName('pubDate').item(0);
    +			var pubDate;
    +			if (!pubElm) {
    +				pubElm = itemList[i].getElementsByTagName('date').item(0); // for del.icio.us
    +				if (pubElm) {
    +					pubDate = pubElm.firstChild.nodeValue;
    +					pubDate = this.formatDateString(this.dateFormat, pubDate);
    +					}
    +					else {
    +						pubDate = '0';
    +					}
    +				}
    +			else {
    +				pubDate = (pubElm ? pubElm.firstChild.nodeValue : 0);
    +				pubDate = this.formatDate(this.dateFormat, pubDate);
    +			}
    +			titleText = titleText.replace(/\[|\]/g,'');
    +			var rssText = '*'+'[[' + titleText + '|' + linkURL + ']]' + '' ;
    +			if ((desc != "noDesc") && descText){
    +				rssText = rssText.replace(/\n/g,' ');
    +				descText = '@@'+this.itemStyle+descText + '@@\n';				
    +				if (version.extensions.nestedSliders){
    +					descText = '+++[...]' + descText + '===';
    +				}
    +				rssText = rssText + descText;
    +			}
    +			var story;
    +			if ((lastDate != pubDate) && ( pubDate != '0')) {
    +				story = createTiddlyElement(article,"li",null,"RSSItem",pubDate);
    +				lastDate = pubDate;
    +			}
    +			else {
    +				lastDate = pubDate;
    +			}
    +			story = createTiddlyElement(article,"div",null,"RSSItem",null);
    +			wikify(rssText,story);
    +		}
    +	},
    +	
    +	formatDate: function(template, date){
    +		var dateString = new Date(date);
    +		// template = template.replace(/hh|mm|ss/g,'');
    +		return dateString.formatString(template);
    +	},
    +	
    +	formatDateString: function(template, date){
    +		var dateString = new Date(date.substr(0,4), date.substr(5,2) - 1, date.substr(8,2)
    +			);
    +		return dateString.formatString(template);
    +	}
    +	
    +};
    +
    +config.macros.rssFeedUpdate = {
    +	label: "Update",
    +	prompt: "Clear the cache and redisplay this RssFeed",
    +	handler: function(place,macroName,params) {
    +		var feedURL = params[0];
    +		var tiddlerTitle = params[1];
    +		createTiddlyButton(place, this.label, this.prompt, 
    +			function () {
    +				if (config.macros.rssReader.cache[feedURL]) {
    +					config.macros.rssReader.cache[feedURL] = null; 
    +			}
    +			story.refreshTiddler(tiddlerTitle,null, true);
    +		return false;});
    +	}
    +};
    +
    +//}}}
    +
    +
    +
    +
    //last update: RSSReaderPlugin v 1.1.1//
    +
    +!Description
    +This plugin provides a RSSReader for TiddlyWiki
    +* It accesses asynchronously an RSSFeed
    +*Depending on the chanel item format, each item could be written as :
    +**simple text wikified
    +**html
    +
    +!Usage
    +{{{
    +<<rssReader noDesc|asHtml|asText rssUrl ['filtering string']>>
    +	noDesc: only title of item is printed
    +
    +	asHtml: if you know that description contain html (links, img ...), 
    +		the text is enclosed with <html> </html> tags
    +
    + 	asText: if the description should not be interpreted as html the 
    +		description is wikified
    +
    +	rssUrl: the rssFeed url that could be accessed. 
    +	
    +	'filtering string': if present, the rssfeed item title must contained 
    +		this string to be displayed. 
    +		If 'filering string' contained space characters only, the tiddler 
    +		title is used for filtering.
    +
    +}}}
    +
    +For security reasons, if the TiddlyWiki is accessed from http, a ProxyService should be used to access an rssFeed from an other site.
    +
    +!examples
    +| !reader | !RSSFeed type | !working from |
    +| BidiXTWRSS | Description asHtml | file: or tiddlywiki.bidix.info |
    +| [[Le Monde]] | Description asText | file: or tiddlywiki.bidix.info using proxy |
    +| YahooNewsSport | Description asHtml | file: or tiddlywiki.bidix.info using proxy |
    +| TiddlyWikiRSS | Description asHtml | file: or tiddlywiki.bidix.info using proxy |
    +| [[Libération]] | noDesc | file: or tiddlywiki.bidix.info using proxy |
    +| [[TestComment]] | asText and filters | file: or tiddlywiki.bidix.info using proxy |
    +see : <<tag RSSFeed>> for the full list.
    +
    +!Revision history
    +* V1.1.0 (2207/04/13)
    +**No more import functions
    +* V1.0.0 (2006/11/11)
    +**refactoring using core loadRemoteFile function
    +**import using new tiddlywiki:tiddler element
    +**import and presentation preserved without EricShulman's NestedSliderPlugin
    +**better display of items 
    +* v0.3.0 (24/08/2006)
    +** Filter on RSS item title
    +** Place to display redefined for asynchronous processing
    +* v0.2.2 (22/08/2006)
    +**Haloscan feed has no pubDate.
    +* v0.2.1 (08/05/2006)
    +* v0.2.0 (01/05/2006)
    +**Small adapations for del.icio.us feed
    +* v0.1.1 (28/04/2006)
    +**Bug : Channel without title 
    +* v0.1.0 (24/04/2006)
    +** initial release
    +
    +
    +
    +
    +
    +
    ! Foundations, not really a milestone yet
    +
    +We need following in a basically working / mockup state:
    +
    +* Proc layer, basic rendering, partly mockups
    +* Backend
    +** File backend, caching
    +** Serializer
    +** Scheduler
    +* Support Libary
    +** Plugin Loader
    +** Other tools there
    +* Infrastructure
    +** Testsuite
    +** Website
    +
    +!! Next Goals
    +
    +# Make a [[video player mockup]]
    +
    +
    +
    Roadmap and tasks
    +
    +
    +
    ToDo
    +
    +
    +
    /***
    +
    +''Inspired by [[TiddlyPom|http://www.warwick.ac.uk/~tuspam/tiddlypom.html]]''
    +
    +|Name|SplashScreenPlugin|
    +|Created by|SaqImtiaz|
    +|Location|http://tw.lewcid.org/#SplashScreenPlugin|
    +|Version|0.21 |
    +|Requires|~TW2.08+|
    +!Description:
    +Provides a simple splash screen that is visible while the TW is loading.
    +
    +!Installation
    +Copy the source text of this tiddler to your TW in a new tiddler, tag it with systemConfig and save and reload. The SplashScreen will now be installed and will be visible the next time you reload your TW.
    +
    +!Customizing
    +Once the SplashScreen has been installed and you have reloaded your TW, the splash screen html will be present in the MarkupPreHead tiddler. You can edit it and customize to your needs.
    +
    +!History
    +* 20-07-06 : version 0.21, modified to hide contentWrapper while SplashScreen is displayed.
    +* 26-06-06 : version 0.2, first release
    +
    +!Code
    +***/
    +//{{{
    +var old_lewcid_splash_restart=restart;
    +
    +restart = function()
    +{   if (document.getElementById("SplashScreen"))
    +        document.getElementById("SplashScreen").style.display = "none";
    +      if (document.getElementById("contentWrapper"))
    +        document.getElementById("contentWrapper").style.display = "block";
    +    
    +    old_lewcid_splash_restart();
    +   
    +    if (splashScreenInstall)
    +       {if(config.options.chkAutoSave)
    +			{saveChanges();}
    +        displayMessage("TW SplashScreen has been installed, please save and refresh your TW.");
    +        }
    +}
    +
    +
    +var oldText = store.getTiddlerText("MarkupPreHead");
    +if (oldText.indexOf("SplashScreen")==-1)
    +   {var siteTitle = store.getTiddlerText("SiteTitle");
    +   var splasher='\n\n<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>'+siteTitle +'</b> is loading<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Requires Javascript.</span></div>';
    +   if (! store.tiddlerExists("MarkupPreHead"))
    +       {var myTiddler = store.createTiddler("MarkupPreHead");}
    +   else
    +      {var myTiddler = store.getTiddler("MarkupPreHead");}
    +      myTiddler.set(myTiddler.title,oldText+splasher,config.options.txtUserName,null,null);
    +      store.setDirty(true);
    +      var splashScreenInstall = true;
    +}
    +//}}}
    +
    +
    +
    /*{{{*/
    +/* a contrasting background so I can see where one tiddler ends and the other begins */
    +body {
    +	background: [[ColorPalette::TertiaryLight]];
    +}
    +
    +/* sexy colours and font for the header */
    +.headerForeground {
    +	color: [[ColorPalette::PrimaryPale]];
    +}
    +.headerShadow, .headerShadow a {
    +	color: [[ColorPalette::PrimaryMid]];
    +}
    +.headerForeground, .headerShadow {
    +	padding: 1em 1em 0;
    +	font-family: 'Trebuchet MS' sans-serif;
    +	font-weight:bold;
    +}
    +.headerForeground .siteSubtitle {
    +	color: [[ColorPalette::PrimaryLight]];
    +}
    +.headerShadow .siteSubtitle {
    +	color: [[ColorPalette::PrimaryMid]];
    +}
    +
    +/* make shadow go and down right instead of up and left */
    +.headerShadow {
    +	left: 2px;
    +	top: 3px;
    +}
    +
    +/* prefer monospace for editing */
    +.editor textarea {
    +	font-family: 'Consolas' monospace;
    +}
    +
    +/* sexy tiddler titles */
    +.title {
    +	font-size: 250%;
    +	color: [[ColorPalette::PrimaryLight]];
    +	font-family: 'Trebuchet MS' sans-serif;
    +}
    +
    +/* more subtle tiddler subtitle */
    +.subtitle {
    +	padding:0px;
    +	margin:0px;
    +	padding-left:0.5em;
    +	font-size: 90%;
    +	color: [[ColorPalette::TertiaryMid]];
    +}
    +.subtitle .tiddlyLink {
    +	color: [[ColorPalette::TertiaryMid]];
    +}
    +
    +/* a little bit of extra whitespace */
    +.viewer {
    +	padding-bottom:3px;
    +}
    +
    +/* don't want any background color for headings */
    +h1,h2,h3,h4,h5,h6 {
    +	background: [[ColorPalette::Background]];
    +	color: [[ColorPalette::Foreground]];
    +}
    +
    +/* give tiddlers 3d style border and explicit background */
    +.tiddler {
    +	background: [[ColorPalette::Background]];
    +	border-right: 2px [[ColorPalette::TertiaryMid]] solid;
    +	border-bottom: 2px [[ColorPalette::TertiaryMid]] solid;
    +	margin-bottom: 1em;
    +	padding-bottom: 2em;
    +}
    +
    +/* make options slider look nicer */
    +#sidebarOptions .sliderPanel {
    +	border:solid 1px [[ColorPalette::PrimaryLight]];
    +}
    +
    +
    +/* the borders look wrong with the body background */
    +#sidebar .button {
    +	border-style: none;
    +}
    +
    +/* displays the list of a tiddler's tags horizontally. used in ViewTemplate */
    +.tagglyTagged li.listTitle {
    +	display:none
    +}
    +.tagglyTagged li {
    +	display: inline; font-size:90%;
    +}
    +.tagglyTagged ul {
    +	margin:0px; padding:0px;
    +}
    +
    +/* this means you can put line breaks in SidebarOptions for readability */
    +#sidebarOptions br {
    +	display:none;
    +}
    +/* undo the above in OptionsPanel */
    +#sidebarOptions .sliderPanel br {
    +	display:inline;
    +}
    +
    +/* horizontal main menu stuff */
    +#displayArea {
    +	margin: 1em 15.7em 0em 1em; /* use the freed up space */
    +}
    +#topMenu br {
    +	display: none;
    +}
    +#topMenu {
    +	background: [[ColorPalette::PrimaryMid]];
    +	color:[[ColorPalette::PrimaryPale]];
    +}
    +#topMenu {
    +	padding:2px;
    +}
    +#topMenu .button, #topMenu .tiddlyLink, #topMenu a {
    +	margin-left: 0.5em;
    +	margin-right: 0.5em;
    +	padding-left: 3px;
    +	padding-right: 3px;
    +	color: [[ColorPalette::PrimaryPale]];
    +	font-size: 115%;
    +}
    +#topMenu .button:hover, #topMenu .tiddlyLink:hover {
    +	background: [[ColorPalette::PrimaryDark]];
    +}
    +
    +/* make it print a little cleaner */
    +@media print {
    +	#topMenu {
    +		display: none ! important;
    +	}
    +	/* not sure if we need all the importants */
    +	.tiddler {
    +		border-style: none ! important;
    +		margin:0px ! important;
    +		padding:0px ! important;
    +		padding-bottom:2em ! important;
    +	}
    +	.tagglyTagging .button, .tagglyTagging .hidebutton {
    +		display: none ! important;
    +	}
    +	.headerShadow {
    +		visibility: hidden ! important;
    +	}
    +	.tagglyTagged .quickopentag, .tagged .quickopentag {
    +		border-style: none ! important;
    +	}
    +	.quickopentag a.button, .miniTag {
    +		display: none ! important;
    +	}
    +}
    +/*}}}*/
    +
    +
    +
    +
    <<timeline better:true maxDays:14 maxEntries:20>>
    +
    +
    +
    /***
    +|Name|TaskMacroPlugin|
    +|Author|<<extension TaskMacroPlugin author>>|
    +|Location|<<extension TaskMacroPlugin source>>|
    +|License|<<extension TaskMacroPlugin license>>|
    +|Version|<<extension TaskMacroPlugin versionAndDate>>|
    +!Description
    +A set of macros to help you keep track of time estimates for tasks.
    +
    +Macros defined:
    +* {{{task}}}: Displays a task description and makes it easy to estimate and track the time spent on the task.
    +* {{{taskadder}}}: Displays text entry field to simplify the adding of tasks.
    +* {{{tasksum}}}: Displays a summary of tasks sandwiched between two calls to this macro.
    +* {{{extension}}}: A simple little macro that displays information about a TiddlyWiki plugin, and that will hopefully someday migrate to the TW core in some form.
    +Core overrides:
    +* {{{wikify}}}: when wikifying a tiddler's complete text, adds refresh information so the tiddler will be refreshed when it changes
    +* {{{config.refreshers}}}: have the built-in refreshers return true; also, add a new refresher ("fullContent") that redisplays a full tiddler whenever it or any nested tiddlers it shows are changed
    +* {{{refreshElements}}}: now checks the return value from the refresher and only short-circuits the recursion if the refresher returns true
    +!Plugin Information
    +***/
    +//{{{
    +version.extensions.TaskMacroPlugin = {
    +	major: 1, minor: 1, revision: 0,
    +	date: new Date(2006,5-1,13),
    +	author: "LukeBlanshard",
    +	source: "http://labwiki.sourceforge.net/#TaskMacroPlugin",
    +	license: "http://labwiki.sourceforge.net/#CopyrightAndLicense"
    +}
    +//}}}
    +/***
    +A little macro for pulling out extension info.  Use like {{{<<extension PluginName datum>>}}}, where {{{PluginName}}} is the name you used for {{{version.extensions}}} and {{{datum}}} is either {{{versionAndDate}}} or a property of the extension description object, such as {{{source}}}.
    +***/
    +//{{{
    +config.macros.extension = {
    +	handler: function( place, macroName, params, wikifier, paramString, tiddler ) {
    +		var info  = version.extensions[params[0]]
    +		var datum = params[1]
    +		switch (params[1]) {
    +		case 'versionAndDate':
    +			createTiddlyElement( place, "span", null, null,
    +				info.major+'.'+info.minor+'.'+info.revision+', '+info.date.formatString('DD MMM YYYY') )
    +			break;
    +		default:
    +			wikify( info[datum], place )
    +			break;
    +		}
    +	}
    +}
    +//}}}
    +/***
    +!Core Overrides
    +***/
    +//{{{
    +window.wikify_orig_TaskMacroPlugin = window.wikify
    +window.wikify = function(source,output,highlightRegExp,tiddler)
    +{
    +	if ( tiddler && tiddler.text === source )
    +		addDisplayDependency( output, tiddler.title )
    +	wikify_orig_TaskMacroPlugin.apply( this, arguments )
    +}
    +config.refreshers_orig_TaskMacroPlugin = config.refreshers
    +config.refreshers = {
    +	link: function() {
    +		config.refreshers_orig_TaskMacroPlugin.link.apply( this, arguments )
    +		return true
    +	},
    +	content: function() {
    +		config.refreshers_orig_TaskMacroPlugin.content.apply( this, arguments )
    +		return true
    +	},
    +	fullContent: function( e, changeList ) {
    +		var tiddlers = e.refreshTiddlers
    +		if ( changeList == null || tiddlers == null )
    +			return false
    +		for ( var i=0; i < tiddlers.length; ++i )
    +			if ( changeList.find(tiddlers[i]) != null ) {
    +				var title = tiddlers[0]
    +				story.refreshTiddler( title, null, true )
    +				return true
    +			}
    +		return false
    +	}
    +}
    +function refreshElements(root,changeList)
    +{
    +	var nodes = root.childNodes;
    +	for(var c=0; c<nodes.length; c++)
    +		{
    +		var e = nodes[c],type;
    +		if(e.getAttribute)
    +			type = e.getAttribute("refresh");
    +		else
    +			type = null;
    +		var refresher = config.refreshers[type];
    +		if ( ! refresher || ! refresher(e, changeList) )
    +			{
    +			if(e.hasChildNodes())
    +				refreshElements(e,changeList);
    +			}
    +		}
    +}
    +//}}}
    +/***
    +!Global Functions
    +***/
    +//{{{
    +// Add the tiddler whose title is given to the list of tiddlers whose
    +// changing will cause a refresh of the tiddler containing the given element.
    +function addDisplayDependency( element, title ) {
    +	while ( element && element.getAttribute ) {
    +		var idAttr = element.getAttribute("id"), tiddlerAttr = element.getAttribute("tiddler")
    +		if ( idAttr && tiddlerAttr && idAttr == story.idPrefix+tiddlerAttr ) {
    +			var list = element.refreshTiddlers
    +			if ( list == null ) {
    +				list = [tiddlerAttr]
    +				element.refreshTiddlers = list
    +				element.setAttribute( "refresh", "fullContent" )
    +			}
    +			list.pushUnique( title )
    +			return
    +		}
    +		element = element.parentNode
    +	}
    +}
    +
    +// Lifted from Story.prototype.focusTiddler: just return the field instead of focusing it.
    +Story.prototype.findEditField = function( title, field )
    +{
    +	var tiddler = document.getElementById(this.idPrefix + title);
    +	if(tiddler != null)
    +		{
    +		var children = tiddler.getElementsByTagName("*")
    +		var e = null;
    +		for (var t=0; t<children.length; t++)
    +			{
    +			var c = children[t];
    +			if(c.tagName.toLowerCase() == "input" || c.tagName.toLowerCase() == "textarea")
    +				{
    +				if(!e)
    +					e = c;
    +				if(c.getAttribute("edit") == field)
    +					e = c;
    +				}
    +			}
    +		return e
    +		}
    +}
    +
    +// Wraps the given event function in another function that handles the
    +// event in a standard way.
    +function wrapEventHandler( otherHandler ) {
    +	return function(e) {
    +		if (!e) var e = window.event
    +		e.cancelBubble = true
    +		if (e.stopPropagation) e.stopPropagation()
    +		return otherHandler( e )
    +	}
    +}
    +//}}}
    +/***
    +!Task Macro
    +Usage:
    +> {{{<<task orig cur spent>>description}}}
    +All of orig, cur, and spent are optional numbers of hours.  The description goes through the end of the line, and is wikified.
    +***/
    +//{{{
    +config.macros.task = {
    +	NASCENT:	0, // Task not yet estimated
    +	LIVE:		1, // Estimated but with time remaining
    +	DONE:		2, // Completed: no time remaining
    +	bullets:	["\u25cb", // nascent (open circle)
    +			 "\u25ba", // live (right arrow)
    +			 "\u25a0"],// done (black square)
    +	styles:		["nascent", "live", "done"],
    +
    +	// Translatable text:
    +	lingo: {
    +		spentTooBig:	"Spent time %0 can't exceed current estimate %1",
    +		noNegative:	"Times may not be negative numbers",
    +		statusTips:	["Not yet estimated", "To do", "Done"], // Array indexed by state (NASCENT/LIVE/DONE)
    +		descClickTip:	" -- Double-click to edit task description",
    +		statusClickTip:	" -- Double-click to mark task complete",
    +		statusDoneTip:	" -- Double-click to adjust the time spent, to revive the task",
    +		origTip:	"Original estimate in hours",
    +		curTip:		"Current estimate in hours",
    +		curTip2:	"Estimate in hours", // For when orig == cur
    +		clickTip:	" -- Click to adjust",
    +		spentTip:	"Hours spent on this task",
    +		remTip:		"Hours remaining",
    +		curPrompt:	"Estimate this task in hours, or adjust the current estimate by starting with + or -.\n\nYou may optionally also set or adjust the time spent by putting a second number after the first.",
    +		spentPrompt:	"Enter the number of hours you've spent on this task, or adjust the current number by starting with + or -.\n\nYou may optionally also set or adjust the time remaining by putting a second number after the first.",
    +		remPrompt:	"Enter the number of hours it will take to finish this task, or adjust the current estimate by starting with + or -.\n\nYou may optionally also set or adjust the time spent by putting a second number after the first.",
    +		numbersOnly:	"Enter numbers only, please",
    +		notCurrent:	"The tiddler has been modified since it was displayed, please redisplay it before doing this."
    +	},
    +
    +	// The macro handler
    +	handler: function( place, macroName, params, wikifier, paramString, tiddler )
    +	{
    +		var start = wikifier.matchStart, end = wikifier.nextMatch
    +
    +		var origStr	= params.length > 0? params.shift() : "?"
    +		var orig	= +origStr // as a number
    +		var cur		= params.length > 1? +params.shift() : orig
    +		var spent	= params.length > 0? +params.shift() : 0
    +		if ( spent > cur )
    +			throw Error( this.lingo.spentTooBig.format([spent, cur]) )
    +		if ( orig < 0 || cur < 0 || spent < 0 )
    +			throw Error( this.lingo.noNegative )
    +		var rem		= cur - spent
    +		var state	= isNaN(orig+rem)? this.NASCENT : rem > 0? this.LIVE : this.DONE
    +		var table	= createTiddlyElement( place, "table", null, "task "+this.styles[state] )
    +		var tbody	= createTiddlyElement( table, "tbody" )
    +		var row		= createTiddlyElement( tbody, "tr" )
    +		var statusCell	= createTiddlyElement( row,   "td", null, "status", this.bullets[state] )
    +		var descCell	= createTiddlyElement( row,   "td", null, "description" )
    +
    +		var origCell	= state==this.NASCENT || orig==cur? null
    +				: createTiddlyElement( row, "td", null, "numeric original" )
    +		var curCell	= createTiddlyElement( row, "td", null, "numeric current" )
    +		var spentCell	= createTiddlyElement( row, "td", null, "numeric spent" )
    +		var remCell	= createTiddlyElement( row, "td", null, "numeric remaining" )
    +
    +		var sums = config.macros.tasksum.tasksums
    +		if ( sums && sums.length ) {
    +			var summary = [(state == this.NASCENT? NaN : orig), cur, spent]
    +			summary.owner = tiddler
    +			sums[0].push( summary )
    +		}
    +
    +		// The description goes to the end of the line
    +		wikifier.subWikify( descCell, "$\\n?" )
    +		var descEnd = wikifier.nextMatch
    +
    +		statusCell.setAttribute( "title", this.lingo.statusTips[state] )
    +		descCell.setAttribute(   "title", this.lingo.statusTips[state]+this.lingo.descClickTip )
    +		if (origCell) {
    +			createTiddlyElement( origCell, "div", null, null, orig )
    +			origCell.setAttribute( "title", this.lingo.origTip )
    +			curCell.setAttribute( "title", this.lingo.curTip )
    +		}
    +		else {
    +			curCell.setAttribute( "title", this.lingo.curTip2 )
    +		}
    +		var curDivContents = (state==this.NASCENT)? "?" : cur
    +		var curDiv = createTiddlyElement( curCell, "div", null, null, curDivContents )
    +		spentCell.setAttribute( "title", this.lingo.spentTip )
    +		var spentDiv = createTiddlyElement( spentCell, "div", null, null, spent )
    +		remCell.setAttribute( "title", this.lingo.remTip )
    +		var remDiv = createTiddlyElement( remCell, "div", null, null, rem )
    +
    +		// Handle double-click on the description by going
    +		// into edit mode and selecting the description
    +		descCell.ondblclick = this.editDescription( tiddler, end, descEnd )
    +
    +		function appTitle( el, suffix ) {
    +			el.setAttribute( "title", el.getAttribute("title")+suffix )
    +		}
    +
    +		// For incomplete tasks, handle double-click on the bullet by marking the task complete
    +		if ( state != this.DONE ) {
    +			appTitle( statusCell, this.lingo.statusClickTip )
    +			statusCell.ondblclick = this.markTaskComplete( tiddler, start, end, macroName, orig, cur, state )
    +		}
    +		// For complete ones, handle double-click on the bullet by letting you adjust the time spent
    +		else {
    +			appTitle( statusCell, this.lingo.statusDoneTip )
    +			statusCell.ondblclick = this.adjustTimeSpent( tiddler, start, end, macroName, orig, cur, spent )
    +		}
    +
    +		// Add click handlers for the numeric cells.
    +		if ( state != this.DONE ) {
    +			appTitle( curCell, this.lingo.clickTip )
    +			curDiv.className = "adjustable"
    +			curDiv.onclick = this.adjustCurrentEstimate( tiddler, start, end, macroName,
    +				orig, cur, spent, curDivContents )
    +		}
    +		appTitle( spentCell, this.lingo.clickTip )
    +		spentDiv.className = "adjustable"
    +		spentDiv.onclick = this.adjustTimeSpent( tiddler, start, end, macroName, orig, cur, spent )
    +		if ( state == this.LIVE ) {
    +			appTitle( remCell, this.lingo.clickTip )
    +			remDiv.className = "adjustable"
    +			remDiv.onclick = this.adjustTimeRemaining( tiddler, start, end, macroName, orig, cur, spent )
    +		}
    +	},
    +
    +	// Puts the tiddler into edit mode, and selects the range of characters
    +	// defined by start and end.  Separated for leak prevention in IE.
    +	editDescription: function( tiddler, start, end ) {
    +		return wrapEventHandler( function(e) {
    +			story.displayTiddler( null, tiddler.title, DEFAULT_EDIT_TEMPLATE )
    +			var tiddlerElement = document.getElementById( story.idPrefix + tiddler.title )
    +			window.scrollTo( 0, ensureVisible(tiddlerElement) )
    +			var element = story.findEditField( tiddler.title, "text" )
    +			if ( element && element.tagName.toLowerCase() == "textarea" ) {
    +				// Back up one char if the last char's a newline
    +				if ( tiddler.text[end-1] == '\n' )
    +					--end
    +				element.focus()
    +				if ( element.setSelectionRange != undefined ) { // Mozilla
    +					element.setSelectionRange( start, end )
    +					// Damn mozilla doesn't scroll to visible.  Approximate.
    +					var max = 0.0 + element.scrollHeight
    +					var len = element.textLength
    +					var top = max*start/len, bot = max*end/len
    +					element.scrollTop = Math.min( top, (bot+top-element.clientHeight)/2 )
    +				}
    +				else if ( element.createTextRange != undefined ) { // IE
    +					var range = element.createTextRange()
    +					range.collapse()
    +					range.moveEnd("character", end)
    +					range.moveStart("character", start)
    +					range.select()
    +				}
    +				else // Other? Too bad, just select the whole thing.
    +					element.select()
    +				return false
    +			}
    +			else
    +				return true
    +		} )
    +	},
    +
    +	// Modifies a task macro call such that the task appears complete.
    +	markTaskComplete: function( tiddler, start, end, macroName, orig, cur, state ) {
    +		var macro = this, text = tiddler.text
    +		return wrapEventHandler( function(e) {
    +			if ( text !== tiddler.text ) {
    +				alert( macro.lingo.notCurrent )
    +				return false
    +			}
    +			if ( state == macro.NASCENT )
    +				orig = cur = 0
    +			// The second "cur" in the call below bumps up the time spent
    +			// to match the current estimate.
    +			macro.replaceMacroCall( tiddler, start, end, macroName, orig, cur, cur )
    +			return false
    +		} )
    +	},
    +
    +	// Asks the user for an adjustment to the current estimate, modifies the macro call accordingly.
    +	adjustCurrentEstimate: function( tiddler, start, end, macroName, orig, cur, spent, curDivContents ) {
    +		var macro = this, text = tiddler.text
    +		return wrapEventHandler( function(e) {
    +			if ( text !== tiddler.text ) {
    +				alert( macro.lingo.notCurrent )
    +				return false
    +			}
    +			var txt = prompt( macro.lingo.curPrompt, curDivContents )
    +			if ( txt != null ) {
    +				var a = macro.breakInput( txt )
    +				cur = macro.offset( cur, a[0] )
    +				if ( a.length > 1 )
    +					spent = macro.offset( spent, a[1] )
    +				macro.replaceMacroCall( tiddler, start, end, macroName, orig, cur, spent )
    +			}
    +			return false
    +		} )
    +	},
    +
    +	// Asks the user for an adjustment to the time spent, modifies the macro call accordingly.
    +	adjustTimeSpent: function( tiddler, start, end, macroName, orig, cur, spent ) {
    +		var macro = this, text = tiddler.text
    +		return wrapEventHandler( function(e) {
    +			if ( text !== tiddler.text ) {
    +				alert( macro.lingo.notCurrent )
    +				return false
    +			}
    +			var txt = prompt( macro.lingo.spentPrompt, spent )
    +			if ( txt != null ) {
    +				var a = macro.breakInput( txt )
    +				spent = macro.offset( spent, a[0] )
    +				var rem = cur - spent
    +				if ( a.length > 1 ) {
    +					rem = macro.offset( rem, a[1] )
    +					cur = spent + rem
    +				}
    +				macro.replaceMacroCall( tiddler, start, end, macroName, orig, cur, spent )
    +			}
    +			return false
    +		} )
    +	},
    +
    +	// Asks the user for an adjustment to the time remaining, modifies the macro call accordingly.
    +	adjustTimeRemaining: function( tiddler, start, end, macroName, orig, cur, spent ) {
    +		var macro = this
    +		var text  = tiddler.text
    +		var rem   = cur - spent
    +		return wrapEventHandler( function(e) {
    +			if ( text !== tiddler.text ) {
    +				alert( macro.lingo.notCurrent )
    +				return false
    +			}
    +			var txt = prompt( macro.lingo.remPrompt, rem )
    +			if ( txt != null ) {
    +				var a = macro.breakInput( txt )
    +				var newRem = macro.offset( rem, a[0] )
    +				if ( newRem > rem || a.length > 1 )
    +					cur += (newRem - rem)
    +				else
    +					spent += (rem - newRem)
    +				if ( a.length > 1 )
    +					spent = macro.offset( spent, a[1] )
    +				macro.replaceMacroCall( tiddler, start, end, macroName, orig, cur, spent )
    +			}
    +			return false
    +		} )
    +	},
    +
    +	// Breaks input at spaces & commas, returns array
    +	breakInput: function( txt ) {
    +		var a = txt.trim().split( /[\s,]+/ )
    +		if ( a.length == 0 )
    +			a = [NaN]
    +		return a
    +	},
    +
    +	// Adds to, subtracts from, or replaces a numeric value
    +	offset: function( num, txt ) {
    +		if ( txt == "" || typeof(txt) != "string" )
    +			return NaN
    +		if ( txt.match(/^[+-]/) )
    +			return num + (+txt)
    +		return +txt
    +	},
    +
    +	// Does some error checking, then replaces the indicated macro
    +	// call within the text of the given tiddler.
    +	replaceMacroCall: function( tiddler, start, end, macroName, orig, cur, spent )
    +	{
    +		if ( isNaN(cur+spent) ) {
    +			alert( this.lingo.numbersOnly )
    +			return
    +		}
    +		if ( spent < 0 || cur < 0 ) {
    +			alert( this.lingo.noNegative )
    +			return
    +		}
    +		if ( isNaN(orig) )
    +			orig = cur
    +		if ( spent > cur )
    +			cur = spent
    +		var text = tiddler.text.substring(0,start) + "<<" + macroName + " " +
    +			orig + " " + cur + " " + spent + ">>" + tiddler.text.substring(end)
    +		var title = tiddler.title
    +		store.saveTiddler( title, title, text, config.options.txtUserName, new Date(), undefined )
    +		//story.refreshTiddler( title, null, true )
    +		if ( config.options.chkAutoSave )
    +			saveChanges()
    +	}
    +}
    +//}}}
    +/***
    +!Tasksum Macro
    +Usage:
    +> {{{<<tasksum "start" ["here" [intro]]>>}}}
    +or:
    +> {{{<<tasksum "end" [intro]>>}}}
    +Put one of the {{{<<tasksum start>>}}} lines before the tasks you want to summarize, and an {{{end}}} line after them.  By default, the summary goes at the end; if you include {{{here}}} in the start line, the summary will go at the top.  The intro argument, if supplied, replaces the default text introducing the summary.
    +***/
    +//{{{
    +config.macros.tasksum = {
    +
    +	// Translatable text:
    +	lingo: {
    +		unrecVerb:	"<<%0>> requires 'start' or 'end' as its first argument",
    +		mustMatch:	"<<%0 end>> must match a preceding <<%0 start>>",
    +		defIntro:	"Task summary:",
    +		nascentSum:	"''%0 not estimated''",
    +		doneSum:	"%0 complete (in %1 hours)",
    +		liveSum:	"%0 ongoing (%1 hours so far, ''%2 hours remaining'')",
    +		overSum:	"Total overestimate: %0%.",
    +		underSum:	"Total underestimate: %0%.",
    +		descPattern:	"%0 %1. %2",
    +                origTip:	"Total original estimates in hours",
    +		curTip:		"Total current estimates in hours",
    +		spentTip:	"Total hours spent on tasks",
    +		remTip:		"Total hours remaining"
    +	},
    +
    +	// The macro handler
    +	handler: function( place, macroName, params, wikifier, paramString, tiddler )
    +	{
    +		var sums = this.tasksums
    +		if ( params[0] == "start" ) {
    +			sums.unshift([])
    +			if ( params[1] == "here" ) {
    +				sums[0].intro = params[2] || this.lingo.defIntro
    +				sums[0].place = place
    +				sums[0].placement = place.childNodes.length
    +			}
    +		}
    +		else if ( params[0] == "end" ) {
    +			if ( ! sums.length )
    +				throw Error( this.lingo.mustMatch.format([macroName]) )
    +			var list = sums.shift()
    +			var intro = list.intro || params[1] || this.lingo.defIntro
    +			var nNascent=0, nLive=0, nDone=0, nMine=0
    +			var totLiveSpent=0, totDoneSpent=0
    +			var totOrig=0, totCur=0, totSpent=0
    +			for ( var i=0; i < list.length; ++i ) {
    +				var a = list[i]
    +				if ( a.length > 3 ) {
    +					nNascent 	+= a[0]
    +					nLive 		+= a[1]
    +					nDone 		+= a[2]
    +					totLiveSpent 	+= a[3]
    +					totDoneSpent 	+= a[4]
    +					totOrig 	+= a[5]
    +					totCur 		+= a[6]
    +					totSpent 	+= a[7]
    +					if ( a.owner == tiddler )
    +						nMine	+= a[8]
    +				}
    +				else {
    +					if ( a.owner == tiddler )
    +						++nMine
    +					if ( isNaN(a[0]) ) {
    +						++nNascent
    +					}
    +					else {
    +						if ( a[1] > a[2] ) {
    +							++nLive
    +							totLiveSpent += a[2]
    +						}
    +						else {
    +							++nDone
    +							totDoneSpent += a[2]
    +						}
    +						totOrig  += a[0]
    +						totCur   += a[1]
    +						totSpent += a[2]
    +					}
    +				}
    +			}
    +
    +			// If we're nested, push a summary outward
    +                        if ( sums.length ) {
    +				var summary = [nNascent, nLive, nDone, totLiveSpent, totDoneSpent,
    +						totOrig, totCur, totSpent, nMine]
    +				summary.owner = tiddler
    +				sums[0].push( summary )
    +			}
    +
    +			var descs = [], styles = []
    +			if ( nNascent > 0 ) {
    +				descs.push( this.lingo.nascentSum.format([nNascent]) )
    +				styles.push( "nascent" )
    +			}
    +			if ( nDone > 0 )
    +				descs.push( this.lingo.doneSum.format([nDone, totDoneSpent]) )
    +			if ( nLive > 0 ) {
    +				descs.push( this.lingo.liveSum.format([nLive, totLiveSpent, totCur-totSpent]) )
    +				styles.push( "live" )
    +			}
    +			else
    +				styles.push( "done" )
    +			var off = ""
    +			if ( totOrig > totCur )
    +				off = this.lingo.overSum.format( [Math.round(100.0*(totOrig-totCur)/totCur)] )
    +			else if ( totCur > totOrig )
    +				off = this.lingo.underSum.format( [Math.round(100.0*(totCur-totOrig)/totOrig)] )
    +
    +			var top		= (list.intro != undefined)
    +			var table	= createTiddlyElement( null, "table", null, "tasksum "+(top?"top":"bottom") )
    +			var tbody	= createTiddlyElement( table, "tbody" )
    +			var row		= createTiddlyElement( tbody, "tr", null, styles.join(" ") )
    +			var descCell	= createTiddlyElement( row,   "td", null, "description" )
    +
    +			var description = this.lingo.descPattern.format( [intro, descs.join(", "), off] )
    +			wikify( description, descCell, null, tiddler )
    +
    +			var origCell	= totOrig == totCur? null
    +					: createTiddlyElement( row, "td", null, "numeric original", totOrig )
    +			var curCell	= createTiddlyElement( row, "td", null, "numeric current", totCur )
    +			var spentCell	= createTiddlyElement( row, "td", null, "numeric spent", totSpent )
    +			var remCell	= createTiddlyElement( row, "td", null, "numeric remaining", totCur-totSpent )
    +
    +			if ( origCell )
    +				origCell.setAttribute( "title", this.lingo.origTip )
    +			curCell  .setAttribute( "title", this.lingo.curTip )
    +			spentCell.setAttribute( "title", this.lingo.spentTip )
    +			remCell  .setAttribute( "title", this.lingo.remTip )
    +
    +			// Discard the table if there are no tasks
    +			if ( list.length > 0 ) {
    +				var place = top? list.place : place
    +				var placement = top? list.placement : place.childNodes.length
    +				if ( placement >= place.childNodes.length )
    +					place.appendChild( table )
    +				else
    +					place.insertBefore( table, place.childNodes[placement] )
    +			}
    +		}
    +		else
    +			throw Error( this.lingo.unrecVerb.format([macroName]) )
    +
    +		// If we're wikifying, and are followed by end-of-line, swallow the newline.
    +		if ( wikifier && wikifier.source.charAt(wikifier.nextMatch) == "\n" )
    +			++wikifier.nextMatch
    +	},
    +
    +	// This is the stack of pending summaries
    +	tasksums: []
    +}
    +//}}}
    +/***
    +!Taskadder Macro
    +Usage:
    +> {{{<<taskadder ["above"|"below"|"focus"|"nofocus"]...>>}}}
    +Creates a line with text entry fields for a description and an estimate.  By default, puts focus in the description field and adds tasks above the entry fields.  Use {{{nofocus}}} to not put focus in the description field.  Use {{{below}}} to add tasks below the entry fields.
    +***/
    +//{{{
    +config.macros.taskadder = {
    +
    +	// Translatable text:
    +	lingo: {
    +		unrecParam:	"<<%0>> doesn't recognize '%1' as a parameter",
    +		descTip:	"Describe a new task",
    +		curTip:		"Estimate how long in hours the task will take",
    +		buttonText:	"add task",
    +		buttonTip:	"Add a new task with the description and estimate as entered",
    +		notCurrent:	"The tiddler has been modified since it was displayed, please redisplay it before adding a task this way.",
    +
    +		eol:		"eol"
    +	},
    +
    +	// The macro handler
    +	handler: function( place, macroName, params, wikifier, paramString, tiddler )
    +	{
    +		var above = true
    +		var focus = false
    +
    +		while ( params.length > 0 ) {
    +			var p = params.shift()
    +			switch (p) {
    +			case "above": 	above = true;  break
    +			case "below": 	above = false; break
    +			case "focus": 	focus = true;  break
    +			case "nofocus":	focus = false; break
    +			default:	throw Error( this.lingo.unrecParam.format([macroName, p]) )
    +			}
    +		}
    +
    +		// If we're followed by end-of-line, swallow the newline.
    +		if ( wikifier.source.charAt(wikifier.nextMatch) == "\n" )
    +			++wikifier.nextMatch
    +
    +		var where	= above? wikifier.matchStart : wikifier.nextMatch
    +
    +		var table	= createTiddlyElement( place, "table", null, "task" )
    +		var tbody	= createTiddlyElement( table, "tbody" )
    +		var row		= createTiddlyElement( tbody, "tr" )
    +		var statusCell	= createTiddlyElement( row,   "td", null, "status" )
    +		var descCell	= createTiddlyElement( row,   "td", null, "description" )
    +		var curCell	= createTiddlyElement( row,   "td", null, "numeric" )
    +		var addCell	= createTiddlyElement( row,   "td", null, "addtask" )
    +
    +		var descId	= this.generateId()
    +		var curId	= this.generateId()
    +		var descInput	= createTiddlyElement( descCell, "input", descId )
    +		var curInput	= createTiddlyElement( curCell,  "input", curId  )
    +
    +		descInput.setAttribute( "type", "text" )
    +		curInput .setAttribute( "type", "text" )
    +		descInput.setAttribute( "size", "40")
    +		curInput .setAttribute( "size", "6" )
    +		descInput.setAttribute( "autocomplete", "off" );
    +		curInput .setAttribute( "autocomplete", "off" );
    +		descInput.setAttribute( "title", this.lingo.descTip );
    +		curInput .setAttribute( "title", this.lingo.curTip  );
    +
    +		var addAction	= this.addTask( tiddler, where, descId, curId, above )
    +		var addButton	= createTiddlyButton( addCell, this.lingo.buttonText, this.lingo.buttonTip, addAction )
    +
    +		descInput.onkeypress = this.handleEnter(addAction)
    +		curInput .onkeypress = descInput.onkeypress
    +		addButton.onkeypress = this.handleSpace(addAction)
    +		if ( focus || tiddler.taskadderLocation == where ) {
    +			descInput.focus()
    +			descInput.select()
    +		}
    +	},
    +
    +	// Returns a function that inserts a new task macro into the tiddler.
    +	addTask: function( tiddler, where, descId, curId, above ) {
    +		var macro = this, oldText = tiddler.text
    +		return wrapEventHandler( function(e) {
    +			if ( oldText !== tiddler.text ) {
    +				alert( macro.lingo.notCurrent )
    +				return false
    +			}
    +			var desc	= document.getElementById(descId).value
    +			var cur		= document.getElementById(curId) .value
    +			var init	= tiddler.text.substring(0,where) + "<<task " + cur + ">> " + desc + "\n"
    +			var text	= init + tiddler.text.substring(where)
    +			var title	= tiddler.title
    +			tiddler.taskadderLocation = (above? init.length : where)
    +			try {
    +				store.saveTiddler( title, title, text, config.options.txtUserName, new Date(), undefined )
    +				//story.refreshTiddler( title, null, true )
    +			}
    +			finally {
    +				delete tiddler.taskadderLocation
    +			}
    +			if ( config.options.chkAutoSave )
    +				saveChanges()
    +		} )
    +	},
    +
    +	// Returns an event handler that delegates to two other functions: "matches" to decide
    +	// whether to consume the event, and "addTask" to actually perform the work.
    +	handleGeneric: function( addTask, matches ) {
    +		return function(e) {
    +			if (!e) var e = window.event
    +			var consume = false
    +			if ( matches(e) ) {
    +				consume = true
    +				addTask( e )
    +			}
    +			e.cancelBubble = consume;
    +			if ( consume && e.stopPropagation ) e.stopPropagation();
    +			return !consume;
    +		}
    +	},
    +
    +	// Returns an event handler that handles enter keys by calling another event handler
    +	handleEnter: function( addTask ) {
    +		return this.handleGeneric( addTask, function(e){return e.keyCode == 13 || e.keyCode == 10} ) // Different codes for Enter
    +	},
    +
    +	// Returns an event handler that handles the space key by calling another event handler
    +	handleSpace: function( addTask ) {
    +		return this.handleGeneric( addTask, function(e){return (e.charCode||e.keyCode) == 32} )
    +	},
    +
    +	counter: 0,
    +	generateId: function() {
    +		return "taskadder:" + String(this.counter++)
    +	}
    +}
    +//}}}
    +/***
    +!Stylesheet
    +***/
    +//{{{
    +var stylesheet = '\
    +.viewer table.task, table.tasksum {\
    +	width: 100%;\
    +	padding: 0;\
    +	border-collapse: collapse;\
    +}\
    +.viewer table.task {\
    +	border: none;\
    +	margin: 0;\
    +}\
    +table.tasksum, .viewer table.tasksum {\
    +	border: solid 2px #999;\
    +	margin: 3px 0;\
    +}\
    +table.tasksum td {\
    +	text-align: center;\
    +	border: 1px solid #ddd;\
    +	background-color: #ffc;\
    +	vertical-align: middle;\
    +	margin: 0;\
    +	padding: 0;\
    +}\
    +.viewer table.task tr {\
    +	border: none;\
    +}\
    +.viewer table.task td {\
    +	text-align: center;\
    +	vertical-align: baseline;\
    +	border: 1px solid #fff;\
    +	background-color: inherit;\
    +	margin: 0;\
    +	padding: 0;\
    +}\
    +td.numeric {\
    +	width: 3em;\
    +}\
    +table.task td.numeric div {\
    +	border: 1px solid #ddd;\
    +	background-color: #ffc;\
    +	margin: 1px 0;\
    +	padding: 0;\
    +}\
    +table.task td.original div {\
    +	background-color: #fdd;\
    +}\
    +table.tasksum td.original {\
    +	background-color: #fdd;\
    +}\
    +table.tasksum td.description {\
    +	background-color: #e8e8e8;\
    +}\
    +table.task td.status {\
    +	width: 1.5em;\
    +	cursor: default;\
    +}\
    +table.task td.description, table.tasksum td.description {\
    +	width: auto;\
    +	text-align: left;\
    +	padding: 0 3px;\
    +}\
    +table.task.done td.status,table.task.done td.description {\
    +	color: #ccc;\
    +}\
    +table.task.done td.current, table.task.done td.remaining {\
    +	visibility: hidden;\
    +}\
    +table.task.done td.spent div, table.tasksum tr.done td.current,\
    +table.tasksum tr.done td.spent, table.tasksum tr.done td.remaining {\
    +	background-color: #eee;\
    +	color: #aaa;\
    +}\
    +table.task.nascent td.description {\
    +	color: #844;\
    +}\
    +table.task.nascent td.current div, table.tasksum tr.nascent td.numeric.current {\
    +	font-weight: bold;\
    +	color: #c00;\
    +	background-color: #def;\
    +}\
    +table.task.nascent td.spent, table.task.nascent td.remaining {\
    +	visibility: hidden;\
    +}\
    +td.remaining {\
    +	font-weight: bold;\
    +}\
    +.adjustable {\
    +	cursor: pointer; \
    +}\
    +table.task input {\
    +	display: block;\
    +	width: 100%;\
    +	font: inherit;\
    +	margin: 2px 0;\
    +	padding: 0;\
    +	border: 1px inset #999;\
    +}\
    +table.task td.numeric input {\
    +	background-color: #ffc;\
    +	text-align: center;\
    +}\
    +table.task td.addtask {\
    +	width: 6em;\
    +	border-left: 2px solid white;\
    +	vertical-align: middle;\
    +}\
    +'
    +setStylesheet( stylesheet, "TaskMacroPluginStylesheet" )
    +//}}}
    +
    +
    +
    +
    !!Changes in 1.1.0
    +* Made the macros work in nested tiddlers (ie when one tiddler includes another using {{{<<tiddler>>}}} or something similar):
    +** Task summaries in the outer tiddler include the tasks from the inner one
    +** Using the editing shortcuts on the tasks as displayed in the outer tiddler correctly changes the inner tiddler and also redisplays the outer one
    +** Added sanity checks to the editing shortcuts so they will refuse to work if the tiddler has been modified behind their backs
    +* Made some small usability fixes:
    +** The "add task" button now responds to the Space key (hat tip: Daniel Baird)
    +** Double-clicking on a completed task's bullet now does the same thing as clicking on the elapsed time: it lets you adjust the time spent, giving you the option of resurrecting the task (hat tip: ~JackF)
    +** Reworked the focus handling of the taskadder macro so it works more intuitively, by refocusing on the same adder you just used
    +
    +
    +
    +
    The task macro provided by the TaskMacroPlugin is for planning, estimating, and tracking detailed tasks such as those required for writing software.  It is inspired by [[Joel Spolsky|http://www.joelonsoftware.com/articles/fog0000000245.html]]'s method for scheduling software development, also popularized by [[Voo2do|http://voo2do.com]] and [[XPlanner|http://xplanner.org]].
    +
    +For changes since the previous version, see the TaskMacroReleaseNotes.
    +
    +This tutorial leads you through the use of the task macro itself, and supporting macros that summarize lists of tasks and simplify the adding of tasks to a list.  Follow along by clicking the links below.  Or click the little down-arrow next to this tiddler's title, above, and choose "Open all" to have all the tutorial sections displayed at once.
    +
    +
    +
    +
    +
    <!---
    +Includes portions of [[TagglyTaggingViewTemplate|http://simonbaird.com/mptw/#TagglyTaggingViewTemplate]], v1.2 (16-Jan-2006).
    +Also adds a pair of tasksum macros around the tiddler, to summarize any contained tasks at the top.  Removes the "-" in front of closeTiddler, which can easily bite you if you have a focusable element in a tiddler, such as a taskadder entry field.
    +Portions written by Luke Blanshard are hereby released into the public domain.
    +--->
    +<!--{{{-->
    +<div class="toolbar" macro="toolbar closeTiddler closeOthers +editTiddler permalink references jump newHere"></div>
    +<div class="tagglyTagged" macro="tags"></div>
    +<div><span class="title" macro="view title"></span><span class="miniTag" macro="miniTag"></span></div>
    +<div macro="tasksum start here"></div>
    +<div class="viewer" macro="view text wikified"></div>
    +<div macro="tasksum end"></div>
    +<div class="tagglyTagging" macro="tagglyListWithSort"></div>
    +<!--}}}-->
    +
    +
    +
    +
    ! Things which are imminent to do
    +
    +<<task 1 1 0.25>> Testsuite: Valgrind suppression file generation, glibc/pthreads leak some memory at the end of the applications, this is ok, we have to integrate this as suppressions into the testsuite, initial work done by cehteh
    +<<task >> Testsuite: expected 'out:' and 'err:' should be shell glob or regex lines not exact strings. The output shall be matched against the current 'out:' or 'err:' line, on success the check continues with the actual expected glob, on fail the next glob is tried. When that fails the test is counted as failure.
    +<<task >> Testsuite: when no expected 'err:' statements are in a test then stderr, including valgrind reports gets ignored, this is a bug. stderr should be filtered for nobug logging events but everything else should be checked for unexpected output.
    +<<task >> Website: asciidoc switchover, git integration, rebuild website on push
    +<<taskadder>>
    +
    +
    +
    +
    /***
    +''TextAreaPlugin for TiddlyWiki version 2.0''
    +^^author: Eric Shulman - ELS Design Studios
    +source: http://www.elsdesign.com/tiddlywiki/#TextAreaPlugin
    +license: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^
    +
    +This plugin 'hijacks' the TW core function, ''Story.prototype.focusTiddler()'', so it can add special 'keyDown' handlers to adjust several behaviors associated with the textarea control used in the tiddler editor.  Specifically, it:
    +* Adds text search INSIDE of edit fields.^^
    +Use ~CTRL-F for "Find" (prompts for search text), and ~CTRL-G for "Find Next" (uses previous search text)^^
    +* Enables TAB characters to be entered into field content^^
    +(instead of moving to next field)^^
    +* Option to set cursor at top of edit field instead of auto-selecting contents^^
    +(see configuration section for checkbox)^^
    +!!!!!Configuration
    +<<<
    +<<option chkDisableAutoSelect>> place cursor at start of textarea instead of pre-selecting content
    +<<option chkTextAreaExtensions>> add control-f (find), control-g (find again) and allow TABs as input in textarea
    +<<<
    +!!!!!Installation
    +<<<
    +Import (or copy/paste) the following tiddlers into your document:
    +''TextAreaPlugin'' (tagged with <<tag systemConfig>>)
    +<<<
    +!!!!!Revision History
    +<<<
    +''2006.01.22 [1.0.1]''
    +only add extra key processing for TEXTAREA elements (not other edit fields).
    +added option to enable/disable textarea keydown extensions (default is "standard keys" only)
    +''2006.01.22 [1.0.0]''
    +Moved from temporary "System Tweaks" tiddler into 'real' TextAreaPlugin tiddler.
    +<<<
    +!!!!!Code
    +***/
    +//{{{
    +version.extensions.textAreaPlugin= {major: 1, minor: 0, revision: 1, date: new Date(2006,1,23)};
    +//}}}
    +
    +//{{{
    +if (!config.options.chkDisableAutoSelect) config.options.chkDisableAutoSelect=false; // default to standard action
    +if (!config.options.chkTextAreaExtensions) config.options.chkTextAreaExtensions=false; // default to standard action
    +
    +// Focus a specified tiddler. Attempts to focus the specified field, otherwise the first edit field it finds
    +Story.prototype.focusTiddler = function(title,field)
    +{
    +	var tiddler = document.getElementById(this.idPrefix + title);
    +	if(tiddler != null)
    +		{
    +		var children = tiddler.getElementsByTagName("*")
    +		var e = null;
    +		for (var t=0; t<children.length; t++)
    +			{
    +			var c = children[t];
    +			if(c.tagName.toLowerCase() == "input" || c.tagName.toLowerCase() == "textarea")
    +				{
    +				if(!e)
    +					e = c;
    +				if(c.getAttribute("edit") == field)
    +					e = c;
    +				}
    +			}
    +		if(e)
    +			{
    +			e.focus();
    +			e.select(); // select entire contents
    +
    +			// TWEAK: add TAB and "find" key handlers
    +			if (config.options.chkTextAreaExtensions) // add extra key handlers
    +				addKeyDownHandlers(e);
    +
    +			// TWEAK: option to NOT autoselect contents
    +			if (config.options.chkDisableAutoSelect) // set cursor to start of field content
    +				if (e.setSelectionRange) e.setSelectionRange(0,0); // for FF
    +				else if (e.createTextRange) { var r=e.createTextRange(); r.collapse(true); r.select(); } // for IE
    +
    +			}
    +		}
    +}
    +//}}}
    +
    +//{{{
    +function addKeyDownHandlers(e)
    +{
    +	// exit if not textarea or element doesn't allow selections
    +	if (e.tagName.toLowerCase()!="textarea" || !e.setSelectionRange) return;
    +
    +	// utility function: exits keydown handler and prevents browser from processing the keystroke
    +	var processed=function(ev) { ev.cancelBubble=true; if (ev.stopPropagation) ev.stopPropagation(); return false; }
    +
    +	// capture keypress in edit field
    +	e.onkeydown = function(ev) { if (!ev) var ev=window.event;
    +
    +		// process TAB
    +		if (!ev.shiftKey && ev.keyCode==9) { 
    +			// replace current selection with a TAB character
    +			var start=e.selectionStart; var end=e.selectionEnd;
    +			e.value=e.value.substr(0,start)+String.fromCharCode(9)+e.value.substr(end);
    +			// update insertion point, scroll it into view
    +			e.setSelectionRange(start+1,start+1);
    +			var linecount=e.value.split('\n').length;
    +			var thisline=e.value.substr(0,e.selectionStart).split('\n').length-1;
    +			e.scrollTop=Math.floor((thisline-e.rows/2)*e.scrollHeight/linecount);
    +			return processed(ev);
    +		}
    +
    +		// process CTRL-F (find matching text) or CTRL-G (find next match)
    +		if (ev.ctrlKey && (ev.keyCode==70||ev.keyCode==71)) {
    +			// if ctrl-f or no previous search, prompt for search text (default to previous text or current selection)... if no search text, exit
    +			if (ev.keyCode==70||!e.find||!e.find.length)
    +				{ var f=prompt("find:",e.find?e.find:e.value.substring(e.selectionStart,e.selectionEnd)); e.focus(); e.find=f?f:e.find; }
    +			if (!e.find||!e.find.length) return processed(ev);
    +			// do case-insensitive match with 'wraparound'...  if not found, alert and exit 
    +			var newstart=e.value.toLowerCase().indexOf(e.find.toLowerCase(),e.selectionStart+1);
    +			if (newstart==-1) newstart=e.value.toLowerCase().indexOf(e.find.toLowerCase());
    +			if (newstart==-1) { alert("'"+e.find+"' not found"); e.focus(); return processed(ev); }
    +			// set new selection, scroll it into view, and report line position in status bar
    +			e.setSelectionRange(newstart,newstart+e.find.length);
    +			var linecount=e.value.split('\n').length;
    +			var thisline=e.value.substr(0,e.selectionStart).split('\n').length;
    +			e.scrollTop=Math.floor((thisline-1-e.rows/2)*e.scrollHeight/linecount);
    +			window.status="line: "+thisline+"/"+linecount;
    +			return processed(ev);
    +		}
    +	}
    +}
    +//}}}
    +
    +
    +
    ! Proc layer
    + by ichtho
    +
    +! Backend
    + by cehteh
    +!! File handling
    +Opening and accessing huge files for reading and writing
    +!!! Manageing File opening, desciptors and handles
    +In progress
    +!!! Mmaping backend, caching
    +Design finished, nothing implemented yet.
    +!! Serializer
    +Some ideas, nothing done yet.
    +!! Scheduler
    +Design ideas, nothing done yet.
    +
    +! Support Libary
    +by cehteh and ichthyo
    +
    +Ongoing efforts as needed, some things already deprecated ;)
    +!! Plugin Loader
    +Basic implementation finished, not final yet.
    +
    +! Infrastructure
    +!! Testsuite
    +Needs some improvements, see [[Tasks]]
    +!! Website
    +A mockup website is online, raffa experimenting with asciidoc which looks good so far. git integration and automatic generation on push to be done see [[Tasks]]
    +!! git / mob repos
    +gitweb is up, git repos are established, mob repos are not yet up.
    +!! automatic generation and checkout of tiddlywikis and doxygen docs on the server
    +currently only a manual rsync script in admin/
    +!! automatic builds/test on server, status page
    +will be done on the 'devel' vserver. nothing done yet.
    +!! Developer Documentation
    +Someone might pickup a Doxygen-Maintainer. This is not writing actual documentation but bringing the Documentation comments in the source to a good shape, add formatting tags, ensureing that all docs are properly generated, maintaining a glossary and index, define the order etc.
    +
    +
    +
    +
    Use the backend, gmerlin/avdecoder and a Player widget to playback videos. This should be a small application which can open and playback many videos from on instance in parallel. Later on scrubbing for this videos might be supported.
    +
    +The idea here is to show and measure backend and scheduler performance and beeing a proof of concept for the design. It will run independent of the Proc layer but needs quite some work on the backend to be done.
    +
    +
    + + + + + + + + + + From c29b6bdd9af313e91e321a007313a7a7f7b0c60e Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 12 Apr 2008 03:09:28 +0200 Subject: [PATCH 31/36] fix include for testsuite (note I did a partial merge and didn't take any of the new sourcefiles, so probably this is already fixed on cehtehs branch backend) --- tests/library/test-llist.c | 2 +- tests/time/test-time.c | 147 ------------------------------------- 2 files changed, 1 insertion(+), 148 deletions(-) delete mode 100644 tests/time/test-time.c diff --git a/tests/library/test-llist.c b/tests/library/test-llist.c index c8bd00e41..12592aa4a 100644 --- a/tests/library/test-llist.c +++ b/tests/library/test-llist.c @@ -23,7 +23,7 @@ //#include #include "lib/llist.h" -#include "src/lib/error.h" +#include "lib/error.h" LUMIERA_ERROR_DEFINE(TEST, "test error"); diff --git a/tests/time/test-time.c b/tests/time/test-time.c deleted file mode 100644 index e9d8d0550..000000000 --- a/tests/time/test-time.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - test-time.c - test time and framerate functions - - Copyright (C) Lumiera.org - 2008, Christian Thaeter - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include -#include - -#include "lib/time.h" -#include "lib/framerate.h" - - -LUMIERA_ERROR_DEFINE(TEST, "test error"); - -int -main (int argc, char** argv) -{ - NOBUG_INIT; - - if (argc == 1) - return 0; - - if (!strcmp(argv[1], "init")) - { - lumiera_time time; - - lumiera_time_init (&time, atol (argv[2]), atol(argv[3])); - - printf ("%lu %lu\n", (long)lumiera_time_sec (&time), (long)lumiera_time_usec (&time)); - } - - if (!strcmp(argv[1], "todouble")) - { - lumiera_time time; - - lumiera_time_init (&time, atol (argv[2]), atol(argv[3])); - - printf ("%g\n", lumiera_time_double_get (&time)); - } - - if (!strcmp(argv[1], "todoublenull")) - { - printf ("%g\n", lumiera_time_double_get (NULL)); - } - - if (!strcmp(argv[1], "fromdouble")) - { - lumiera_time time; - - lumiera_time_set_double (&time, atof (argv[2])); - - printf ("%lu %lu\n", (long)lumiera_time_sec (&time), (long)lumiera_time_usec (&time)); - } - - if (!strcmp(argv[1], "currenttime")) - { - lumiera_time time; - - lumiera_time_current (&time); - - printf ("%lu %lu\n", (long)lumiera_time_sec (&time), (long)lumiera_time_usec (&time)); - } - - if (!strcmp(argv[1], "add")) - { - lumiera_time time1, time2; - - lumiera_time_init (&time1, 0, atol (argv[2])); - lumiera_time_init (&time2, 0, atol (argv[3])); - lumiera_time_add (&time1, &time2); - - printf ("%lu %lu\n", (long)lumiera_time_sec (&time1), (long)lumiera_time_usec (&time1)); - } - - if (!strcmp(argv[1], "sub")) - { - lumiera_time time1, time2; - - lumiera_time_init (&time1, 0, atol (argv[2])); - lumiera_time_init (&time2, 0, atol (argv[3])); - lumiera_time_sub (&time1, &time2); - - printf ("%lu %lu\n", (long)lumiera_time_sec (&time1), (long)lumiera_time_usec (&time1)); - } - - if (!strcmp(argv[1], "ntscframefromtime")) - { - lumiera_framerate ntsc = {30000, 1001}; - lumiera_time time; - - lumiera_time_init (&time, atol (argv[2]), atol (argv[3])); - - printf ("%lu\n", (long)lumiera_framerate_frame_get_time (&ntsc, &time)); - } - - if (!strcmp(argv[1], "ntscframestart")) - { - lumiera_framerate ntsc = {30000, 1001}; - lumiera_time time; - - if(lumiera_framerate_time_get_time_frame (&ntsc, &time, atol (argv[2]))) - printf ("%lu %lu\n", (long)lumiera_time_sec(&time), (long)lumiera_time_usec(&time)); - } - - if (!strcmp(argv[1], "ntscframecheck")) - { - lumiera_framerate ntsc = {30000, 1001}; - lumiera_time time1; - lumiera_time time2; - lumiera_framepos frame; - - lumiera_framepos frame1; - lumiera_framepos frame2; - - frame = atol (argv[2]); - - - if (lumiera_framerate_time_get_time_frame (&ntsc, &time1, frame)) - { - printf("frame %lu ", frame1 = lumiera_framerate_frame_get_time (&ntsc, &time1)); - - lumiera_time_init (&time2, 0, 1); - lumiera_time_sub (&time1, &time2); - printf("%lu\n", frame2 = lumiera_framerate_frame_get_time (&ntsc, &time1)); - ENSURE (frame1 == frame2+1); - } - - } - - return 0; -} From 024e3c4dbcd4252bc0ef318aac5b1ccc91785937 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 12 Apr 2008 04:55:18 +0200 Subject: [PATCH 32/36] change build to link in separate libs, also split test executable. now building liblumiback.a liblumiproc.a liblumi.a build a separate test-common executable (for everything in src/common) include a precompiled header for assets. --- SConstruct | 23 +++++---- src/pre.hpp | 1 + src/pre_a.hpp | 49 +++++++++++++++++++ src/proc/asset.hpp | 2 - src/proc/asset/db.hpp | 2 + src/proc/asset/media.hpp | 2 + src/proc/asset/meta.hpp | 2 + src/proc/asset/proc.hpp | 2 + src/proc/asset/struct.hpp | 2 + src/proc/assetmanager.hpp | 2 + tests/50components.tests | 2 +- tests/52query.tests | 2 +- .../{components => }/common/appconfigtest.cpp | 0 .../common/customsharedptrtest.cpp | 0 .../common/exceptionerrortest.cpp | 0 .../common/factoryspecialtest.cpp | 6 +-- tests/{components => }/common/factorytest.cpp | 2 +- .../{components => common}/helloworldtest.cpp | 0 tests/common/mainsuite.cpp | 42 ++++++++++++++++ .../common/query/querydiagnostics.hpp | 0 .../common/query/queryutilstest.cpp | 2 +- .../common/removefromsettest.cpp | 0 .../common/sanitizedidentifiertest.cpp | 0 .../common/singletonsubclasstest.cpp | 6 +-- .../{components => }/common/singletontest.cpp | 6 +-- .../common/singletontestmocktest.cpp | 0 .../common/test/cmdlinewrappertest.cpp | 0 .../common/test/testoptiontest.cpp | 0 .../{components => }/common/testtargetobj.hpp | 0 .../{components => }/common/typelisttest.cpp | 0 .../common/typelistutiltest.cpp | 0 .../common/visitingtoolconcept.cpp | 0 .../common/visitingtoolextendedtest.cpp | 0 .../common/visitingtooltest.cpp | 0 tests/components/mainsuite.cpp | 43 +--------------- tests/components/proc/asset/testasset.hpp | 2 + .../mobject/session/defsmanagerimpltest.cpp | 2 + .../proc/mobject/session/defsmanagertest.cpp | 2 + .../mobject/session/defsregistryimpltest.cpp | 2 +- 39 files changed, 139 insertions(+), 67 deletions(-) create mode 100644 src/pre_a.hpp rename tests/{components => }/common/appconfigtest.cpp (100%) rename tests/{components => }/common/customsharedptrtest.cpp (100%) rename tests/{components => }/common/exceptionerrortest.cpp (100%) rename tests/{components => }/common/factoryspecialtest.cpp (99%) rename tests/{components => }/common/factorytest.cpp (99%) rename tests/{components => common}/helloworldtest.cpp (100%) create mode 100644 tests/common/mainsuite.cpp rename tests/{components => }/common/query/querydiagnostics.hpp (100%) rename tests/{components => }/common/query/queryutilstest.cpp (99%) rename tests/{components => }/common/removefromsettest.cpp (100%) rename tests/{components => }/common/sanitizedidentifiertest.cpp (100%) rename tests/{components => }/common/singletonsubclasstest.cpp (99%) rename tests/{components => }/common/singletontest.cpp (99%) rename tests/{components => }/common/singletontestmocktest.cpp (100%) rename tests/{components => }/common/test/cmdlinewrappertest.cpp (100%) rename tests/{components => }/common/test/testoptiontest.cpp (100%) rename tests/{components => }/common/testtargetobj.hpp (100%) rename tests/{components => }/common/typelisttest.cpp (100%) rename tests/{components => }/common/typelistutiltest.cpp (100%) rename tests/{components => }/common/visitingtoolconcept.cpp (100%) rename tests/{components => }/common/visitingtoolextendedtest.cpp (100%) rename tests/{components => }/common/visitingtooltest.cpp (100%) mode change 100644 => 120000 tests/components/mainsuite.cpp diff --git a/SConstruct b/SConstruct index 355f2b941..cef5ebda0 100644 --- a/SConstruct +++ b/SConstruct @@ -234,18 +234,23 @@ def defineBuildTargets(env, artifacts): We use a custom function to declare a whole tree of srcfiles. """ - lumobj = ( srcSubtree(env,'$SRCDIR/backend') - + srcSubtree(env,'$SRCDIR/proc') - + srcSubtree(env,'$SRCDIR/common') - + srcSubtree(env,'$SRCDIR/lib') - ) + objback = srcSubtree(env,'$SRCDIR/backend') + objproc = srcSubtree(env,'$SRCDIR/proc') + objlib = ( srcSubtree(env,'$SRCDIR/common') + + srcSubtree(env,'$SRCDIR/lib') + ) plugobj = srcSubtree(env,'$SRCDIR/plugin', isShared=True) - core = env.StaticLibrary('$BINDIR/core.la', lumobj) - #core = lumobj # use this for linking directly + core = ( env.StaticLibrary('$BINDIR/lumiback.la', objback) + + env.StaticLibrary('$BINDIR/lumiproc.la', objproc) + + env.StaticLibrary('$BINDIR/lumi.la', objlib) + ) # use PCH to speed up building - precomp = env.PrecompiledHeader('$SRCDIR/pre') - env.Depends(lumobj, precomp) + precomp = ( env.PrecompiledHeader('$SRCDIR/pre') + + env.PrecompiledHeader('$SRCDIR/pre_a') + ) + env.Depends(objproc, precomp) + env.Depends(objlib, precomp) artifacts['lumiera'] = env.Program('$BINDIR/lumiera', ['$SRCDIR/main.cpp']+ core ) artifacts['plugins'] = env.SharedLibrary('$BINDIR/lumiera-plugin', plugobj) diff --git a/src/pre.hpp b/src/pre.hpp index 19717c2bb..203613c3d 100644 --- a/src/pre.hpp +++ b/src/pre.hpp @@ -31,6 +31,7 @@ ** building the object files including this header). ** ** @see mobject.hpp usage example + ** @see pre_a.hpp precompiled header including Asset subsystem */ #ifndef LUMIERA_PRE_HPP diff --git a/src/pre_a.hpp b/src/pre_a.hpp new file mode 100644 index 000000000..34a8e72f2 --- /dev/null +++ b/src/pre_a.hpp @@ -0,0 +1,49 @@ +/* + PRE_A.hpp - precompiled header (including assets) + + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/** @file pre.hpp + ** Precompiled Header including Asset subsystem. + ** Assortment of standard util, error handling and basic lib-boost components, + ** together with the basic asset.hpp. + ** + ** @see pre.hpp + */ + +#ifndef LUMIERA_PRE_A_HPP +#define LUMIERA_PRE_A_HPP + + +#include +#include +#include +#include +#include +#include +#include + +#include "lumiera.h" +#include "proc/asset.hpp" + + +#endif /*LUMIERA_PRE_A_HPP*/ diff --git a/src/proc/asset.hpp b/src/proc/asset.hpp index 7088b8324..ec1c64ef9 100644 --- a/src/proc/asset.hpp +++ b/src/proc/asset.hpp @@ -55,8 +55,6 @@ #define PROC_INTERFACE_ASSET_H -#include "pre.hpp" - #include "proc/asset/category.hpp" #include "common/error.hpp" #include "common/p.hpp" diff --git a/src/proc/asset/db.hpp b/src/proc/asset/db.hpp index 493a188cf..cb32868d7 100644 --- a/src/proc/asset/db.hpp +++ b/src/proc/asset/db.hpp @@ -25,6 +25,8 @@ #define ASSET_DB_H +#include "pre_a.hpp" + #include "proc/asset.hpp" #include "common/error.hpp" diff --git a/src/proc/asset/media.hpp b/src/proc/asset/media.hpp index ce43d6231..4e122cd53 100644 --- a/src/proc/asset/media.hpp +++ b/src/proc/asset/media.hpp @@ -35,6 +35,8 @@ #ifndef ASSET_MEDIA_H #define ASSET_MEDIA_H +#include "pre_a.hpp" + #include "proc/asset.hpp" #include "common/factory.hpp" #include "proc/mobject/mobject.hpp" diff --git a/src/proc/asset/meta.hpp b/src/proc/asset/meta.hpp index 89500c226..02be992db 100644 --- a/src/proc/asset/meta.hpp +++ b/src/proc/asset/meta.hpp @@ -36,6 +36,8 @@ #ifndef ASSET_META_H #define ASSET_META_H +#include "pre_a.hpp" + #include "proc/asset.hpp" #include "common/factory.hpp" diff --git a/src/proc/asset/proc.hpp b/src/proc/asset/proc.hpp index 12e69812c..05eca4ddf 100644 --- a/src/proc/asset/proc.hpp +++ b/src/proc/asset/proc.hpp @@ -35,6 +35,8 @@ #ifndef ASSET_PROC_H #define ASSET_PROC_H +#include "pre_a.hpp" + #include "proc/asset.hpp" #include "common/factory.hpp" diff --git a/src/proc/asset/struct.hpp b/src/proc/asset/struct.hpp index df6c5f1f6..7c4c4367b 100644 --- a/src/proc/asset/struct.hpp +++ b/src/proc/asset/struct.hpp @@ -37,6 +37,8 @@ #ifndef ASSET_STRUCT_H #define ASSET_STRUCT_H +#include "pre_a.hpp" + #include "proc/asset.hpp" #include "common/query.hpp" #include "common/factory.hpp" diff --git a/src/proc/assetmanager.hpp b/src/proc/assetmanager.hpp index 610e0d1dc..22138065d 100644 --- a/src/proc/assetmanager.hpp +++ b/src/proc/assetmanager.hpp @@ -36,6 +36,8 @@ #define PROC_INTERFACE_ASSETMANAGER_H +#include "pre_a.hpp" + #include "proc/asset.hpp" #include "common/error.hpp" #include "common/singleton.hpp" diff --git a/tests/50components.tests b/tests/50components.tests index d2d38e5d0..63e97cf9a 100644 --- a/tests/50components.tests +++ b/tests/50components.tests @@ -1,4 +1,4 @@ -TESTING "Component Test Suite: common and basic components" ./test-components --group=common +TESTING "Component Test Suite: common and basic components" ./test-common --group=common diff --git a/tests/52query.tests b/tests/52query.tests index 2c598b3b0..799875d7b 100644 --- a/tests/52query.tests +++ b/tests/52query.tests @@ -1,4 +1,4 @@ -TESTING "Proc Layer config rules Test Suite" ./test-components --group=query +TESTING "Proc Layer config rules Test Suite" ./test-common --group=query diff --git a/tests/components/common/appconfigtest.cpp b/tests/common/appconfigtest.cpp similarity index 100% rename from tests/components/common/appconfigtest.cpp rename to tests/common/appconfigtest.cpp diff --git a/tests/components/common/customsharedptrtest.cpp b/tests/common/customsharedptrtest.cpp similarity index 100% rename from tests/components/common/customsharedptrtest.cpp rename to tests/common/customsharedptrtest.cpp diff --git a/tests/components/common/exceptionerrortest.cpp b/tests/common/exceptionerrortest.cpp similarity index 100% rename from tests/components/common/exceptionerrortest.cpp rename to tests/common/exceptionerrortest.cpp diff --git a/tests/components/common/factoryspecialtest.cpp b/tests/common/factoryspecialtest.cpp similarity index 99% rename from tests/components/common/factoryspecialtest.cpp rename to tests/common/factoryspecialtest.cpp index ecf293cd9..eaf50fe42 100644 --- a/tests/components/common/factoryspecialtest.cpp +++ b/tests/common/factoryspecialtest.cpp @@ -21,12 +21,12 @@ * *****************************************************/ -#include "common/testtargetobj.hpp" -#include "common/factory.hpp" - #include "common/test/run.hpp" #include "common/util.hpp" +#include "testtargetobj.hpp" +#include "common/factory.hpp" + #include #include #include diff --git a/tests/components/common/factorytest.cpp b/tests/common/factorytest.cpp similarity index 99% rename from tests/components/common/factorytest.cpp rename to tests/common/factorytest.cpp index 6c96a337c..bde121a8c 100644 --- a/tests/components/common/factorytest.cpp +++ b/tests/common/factorytest.cpp @@ -21,7 +21,7 @@ * *****************************************************/ -#include "common/testtargetobj.hpp" +#include "testtargetobj.hpp" #include "common/test/run.hpp" #include "common/factory.hpp" diff --git a/tests/components/helloworldtest.cpp b/tests/common/helloworldtest.cpp similarity index 100% rename from tests/components/helloworldtest.cpp rename to tests/common/helloworldtest.cpp diff --git a/tests/common/mainsuite.cpp b/tests/common/mainsuite.cpp new file mode 100644 index 000000000..aa500cdbe --- /dev/null +++ b/tests/common/mainsuite.cpp @@ -0,0 +1,42 @@ +/* + mainsuite.cpp - "the" Lumiera self test suite + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#include "common/test/suite.hpp" +#include "common/test/testoption.hpp" + +/** run all tests or any single test specified in the first + * cmd line argument. + * Note: to ease debugging, we don't catch any exceptions. + */ +int main (int argc, char* argv[]) +{ + util::Cmdline args (argc,argv); + test::TestOption optparser (args); + test::Suite suite (optparser.getTestgroup()); + + if (optparser.getDescribe()) + suite.describe(); + else + suite.run (args); + return 0; +} diff --git a/tests/components/common/query/querydiagnostics.hpp b/tests/common/query/querydiagnostics.hpp similarity index 100% rename from tests/components/common/query/querydiagnostics.hpp rename to tests/common/query/querydiagnostics.hpp diff --git a/tests/components/common/query/queryutilstest.cpp b/tests/common/query/queryutilstest.cpp similarity index 99% rename from tests/components/common/query/queryutilstest.cpp rename to tests/common/query/queryutilstest.cpp index 05cfab7ef..fc5e914a9 100644 --- a/tests/components/common/query/queryutilstest.cpp +++ b/tests/common/query/queryutilstest.cpp @@ -26,7 +26,7 @@ #include "common/cmdline.hpp" #include "common/query.hpp" -#include "common/query/querydiagnostics.hpp" +#include "query/querydiagnostics.hpp" #include #include diff --git a/tests/components/common/removefromsettest.cpp b/tests/common/removefromsettest.cpp similarity index 100% rename from tests/components/common/removefromsettest.cpp rename to tests/common/removefromsettest.cpp diff --git a/tests/components/common/sanitizedidentifiertest.cpp b/tests/common/sanitizedidentifiertest.cpp similarity index 100% rename from tests/components/common/sanitizedidentifiertest.cpp rename to tests/common/sanitizedidentifiertest.cpp diff --git a/tests/components/common/singletonsubclasstest.cpp b/tests/common/singletonsubclasstest.cpp similarity index 99% rename from tests/components/common/singletonsubclasstest.cpp rename to tests/common/singletonsubclasstest.cpp index aad667b9f..cdbdd6934 100644 --- a/tests/components/common/singletonsubclasstest.cpp +++ b/tests/common/singletonsubclasstest.cpp @@ -21,12 +21,12 @@ * *****************************************************/ -#include "common/testtargetobj.hpp" -#include "common/singletonsubclass.hpp" - #include "common/test/run.hpp" #include "common/util.hpp" +#include "testtargetobj.hpp" +#include "common/singletonsubclass.hpp" + #include #include #include diff --git a/tests/components/common/singletontest.cpp b/tests/common/singletontest.cpp similarity index 99% rename from tests/components/common/singletontest.cpp rename to tests/common/singletontest.cpp index b531d7e9c..9960ff911 100644 --- a/tests/components/common/singletontest.cpp +++ b/tests/common/singletontest.cpp @@ -21,12 +21,12 @@ * *****************************************************/ -#include "common/testtargetobj.hpp" - #include "common/test/run.hpp" -#include "common/singleton.hpp" #include "common/util.hpp" +#include "testtargetobj.hpp" +#include "common/singleton.hpp" + #include #include #include diff --git a/tests/components/common/singletontestmocktest.cpp b/tests/common/singletontestmocktest.cpp similarity index 100% rename from tests/components/common/singletontestmocktest.cpp rename to tests/common/singletontestmocktest.cpp diff --git a/tests/components/common/test/cmdlinewrappertest.cpp b/tests/common/test/cmdlinewrappertest.cpp similarity index 100% rename from tests/components/common/test/cmdlinewrappertest.cpp rename to tests/common/test/cmdlinewrappertest.cpp diff --git a/tests/components/common/test/testoptiontest.cpp b/tests/common/test/testoptiontest.cpp similarity index 100% rename from tests/components/common/test/testoptiontest.cpp rename to tests/common/test/testoptiontest.cpp diff --git a/tests/components/common/testtargetobj.hpp b/tests/common/testtargetobj.hpp similarity index 100% rename from tests/components/common/testtargetobj.hpp rename to tests/common/testtargetobj.hpp diff --git a/tests/components/common/typelisttest.cpp b/tests/common/typelisttest.cpp similarity index 100% rename from tests/components/common/typelisttest.cpp rename to tests/common/typelisttest.cpp diff --git a/tests/components/common/typelistutiltest.cpp b/tests/common/typelistutiltest.cpp similarity index 100% rename from tests/components/common/typelistutiltest.cpp rename to tests/common/typelistutiltest.cpp diff --git a/tests/components/common/visitingtoolconcept.cpp b/tests/common/visitingtoolconcept.cpp similarity index 100% rename from tests/components/common/visitingtoolconcept.cpp rename to tests/common/visitingtoolconcept.cpp diff --git a/tests/components/common/visitingtoolextendedtest.cpp b/tests/common/visitingtoolextendedtest.cpp similarity index 100% rename from tests/components/common/visitingtoolextendedtest.cpp rename to tests/common/visitingtoolextendedtest.cpp diff --git a/tests/components/common/visitingtooltest.cpp b/tests/common/visitingtooltest.cpp similarity index 100% rename from tests/components/common/visitingtooltest.cpp rename to tests/common/visitingtooltest.cpp diff --git a/tests/components/mainsuite.cpp b/tests/components/mainsuite.cpp deleted file mode 100644 index aa500cdbe..000000000 --- a/tests/components/mainsuite.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - mainsuite.cpp - "the" Lumiera self test suite - - Copyright (C) Lumiera.org - 2008, Christian Thaeter - Hermann Vosseler - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - - -#include "common/test/suite.hpp" -#include "common/test/testoption.hpp" - -/** run all tests or any single test specified in the first - * cmd line argument. - * Note: to ease debugging, we don't catch any exceptions. - */ -int main (int argc, char* argv[]) -{ - util::Cmdline args (argc,argv); - test::TestOption optparser (args); - test::Suite suite (optparser.getTestgroup()); - - if (optparser.getDescribe()) - suite.describe(); - else - suite.run (args); - return 0; -} diff --git a/tests/components/mainsuite.cpp b/tests/components/mainsuite.cpp new file mode 120000 index 000000000..3c6dd11cb --- /dev/null +++ b/tests/components/mainsuite.cpp @@ -0,0 +1 @@ +../common/mainsuite.cpp \ No newline at end of file diff --git a/tests/components/proc/asset/testasset.hpp b/tests/components/proc/asset/testasset.hpp index e1abc57d2..9ba16a4e6 100644 --- a/tests/components/proc/asset/testasset.hpp +++ b/tests/components/proc/asset/testasset.hpp @@ -25,6 +25,8 @@ #define ASSET_TESTASSET_H +#include "pre_a.hpp" + #include "proc/asset.hpp" //#include "common/util.hpp" diff --git a/tests/components/proc/mobject/session/defsmanagerimpltest.cpp b/tests/components/proc/mobject/session/defsmanagerimpltest.cpp index 8aa773d5f..85f1c088c 100644 --- a/tests/components/proc/mobject/session/defsmanagerimpltest.cpp +++ b/tests/components/proc/mobject/session/defsmanagerimpltest.cpp @@ -21,6 +21,8 @@ * *****************************************************/ +#include "pre_a.hpp" + #include "common/test/run.hpp" #include "common/util.hpp" diff --git a/tests/components/proc/mobject/session/defsmanagertest.cpp b/tests/components/proc/mobject/session/defsmanagertest.cpp index 5f5ed686e..8c819c7f2 100644 --- a/tests/components/proc/mobject/session/defsmanagertest.cpp +++ b/tests/components/proc/mobject/session/defsmanagertest.cpp @@ -21,6 +21,8 @@ * *****************************************************/ +#include "pre_a.hpp" + #include "common/test/run.hpp" #include "common/util.hpp" diff --git a/tests/components/proc/mobject/session/defsregistryimpltest.cpp b/tests/components/proc/mobject/session/defsregistryimpltest.cpp index b67b6cbe2..0aae90b3a 100644 --- a/tests/components/proc/mobject/session/defsregistryimpltest.cpp +++ b/tests/components/proc/mobject/session/defsregistryimpltest.cpp @@ -28,7 +28,7 @@ #include "common/factory.hpp" #include "common/query.hpp" -#include "common/query/querydiagnostics.hpp" +#include "../common/query/querydiagnostics.hpp" #include #include From e91fc65a2bb5a4b91350b841bd54ef5f561b78d2 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 12 Apr 2008 06:59:24 +0200 Subject: [PATCH 33/36] supplemented some info to the wikis --- wiki/compatibility.html | 41 ++-- wiki/index.html | 438 +++++++++++++++++++++++++++++++++++++++- wiki/todo.html | 55 ++++- 3 files changed, 503 insertions(+), 31 deletions(-) diff --git a/wiki/compatibility.html b/wiki/compatibility.html index ad54ca4e8..979f2301c 100644 --- a/wiki/compatibility.html +++ b/wiki/compatibility.html @@ -747,29 +747,40 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS } //}}}
    -
    +
    ! Programming Languages
    - * C
    -  a C99 compatible compiler, some GCC extensions are used, most are optional.
    - * C++
    -  C++98 with some boost and tr1 additions
    - * bash
    +* C
    +** a C99 compatible compiler, some GCC extensions are used, most are optional.
    +* C++
    +** C++98
    +** std::tr1 (for <std::tr1::memory>)
    +** BOOST ~~(below are the DEBIAN package names)~~
    +*** libboost-dev (=1.34.1-2)
    +*** libboost-program-options-dev (=1.34.1-2)
    +*** libboost-program-options1.34.1 (=1.34.1-2) ''NOTE: binary lib dependency''
    +*** libboost-regex-dev (=1.34.1-2)
    +*** libboost-regex1.34.1 (=1.34.1-2) ''binary lib depenency''
    +** //usually, newer versions are OK//
    +
    +* bash
       some build scripts (test.sh, ..) use bash specific extensions
     
     ! Build Tools
    - * scons
    - * autotools
    - * Doxygen
    - * test.sh (included)
    +* autotools
    +* SCons
    +** //need either autotools or scons//
    +** SCons (0.96.90), Python (2.3)
    +* Doxygen
    +* test.sh (included)
     
     ! Extra tools
    - * git
    - * bouml
    +* git
    +* bouml
     
     ! Libraries
    - * boost
    - * NoBug
    - * gavl
    +* boost (see above)
    +* NoBug
    +* gavl
     
    diff --git a/wiki/index.html b/wiki/index.html index 7a4d039ca..1ed553afd 100755 --- a/wiki/index.html +++ b/wiki/index.html @@ -930,9 +930,11 @@ git push git://git.pipapo.org/lumiera/mob lumiera/mob is an anonymous account at pipapo.org where everyone can commit changes.
    -
    +
    We keep a protocol or short summary of each important discussion. The summaries of the monthly developer meetings are posted to the Mailinglist and can be found on pipapo.org too
     
    +* [[04-08 developer meeting 3.Apr.2008|IRC_2008-04-03]]
    +* [[03-08 developer meeting 6.Mar.2008|IRC_2008-03-06]]
     * [[1.official developer meeting 1.Feb.2008|IRC_2008-02-01]]
     * [[informal developer meeting 10.Aug.2007|IRC_2007-08-10]]
     
    @@ -1028,6 +1030,422 @@ Let's say, we need a person volonteering to guide/moderate the selection, going * should have one of the free top level domains (.net, .org) * should be compatible with educational institutions (sorry, no pr0nedit :) * should not obviously collide with trade marks + +
    +
    +
    ! 6. mar.2008 on #openvideo
    +21:00 - 23:30 GMT, __Participants__:
    +* hermanr
    +* cehteh
    +* ichthyo
    +* Plouj
    +* SimAV
    +* akirad
    +* _MMA_
    +* rgareus
    +* ddennedy
    +* edrz
    +* anewcomb
    +* gmerlin
    +* oracle2025
    +* gisle
    +
    +! Boilerplate
    +!! Organization of this meeting
    +* cehteh writes the protocol
    +* hermanr does chairman
    +
    +!! Leftovers from last meeting
    +We concluded there are no leftovers
    +
    +! Go through Ideas and Drafts in design process
    +
    +!! Idea: time_handling
    +http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/time_handling
    +
    +Point 1 is superseded by using gavl.
    +
    +Points 2 and 3 are still valid.
    +
    +''Ichthyo'' asked gmerlin if there are any problems according gavl for the points 2 (position of frames) and 3 (position for keyframes and automation). Gmerlin acknowledges that he doesnt see any problems.
    +
    +''Oracle2025'' brings interlacing on topic "are you aware that automations and keyframes could/should also apply to fields?". We agree that this must be handled "in interlacing, a frame is a pair of 2 subsequent fields".
    +
    +__Conclusion__:
    + Refactor the proposal according to the discussion and work it out, make it draft then. Discuss about it on the next meeting
    +
    +!! Idea: Unit tests in Python
    +http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/UnitTests_Python
    +
    +We have a testsuite based on cehtehs 'test.sh' which superseedes this proposal.
    +
    +__Conclusion__:
    + Drop it.
    +
    +!! Idea: Todo Lists
    +http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/TodoLists
    +
    +This Idea is in a very early state an not yet mature.<br/>
    +''Cehteh'' explains: "I want something which doesn't need much human care and i want one big 'milestones' thing and a small 'mini-task' thing". Ichthyo refines this as "Roadmap" and "Near time task list". We agree that this shall not be too strict. There are some ideas floating, like adding this things to the testsuite or use the wiki. Ichthyo shows how he uses the tiddlywiki's task macro ([[renderengine.html#PlanningNodeCreatorTool]]). He likes it but doubts its usefulness when it is used without guessing the hours/days of work.
    +
    +__Conclusion__:
    + We use the Tiddlywiki task macro thing for now.
    +
    +!! Draft: CCodingStyleGuide
    +http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/CCodingStyleGuide
    +
    +Ichthyo tells that the discussion on the wiki page made this clear now. Cehteh explains that he uses this style with success for diffrent projects. We make clear that this is meant for C, in C++ we use namespaces. Overall we agree that code shall be self-documenting.
    +
    +__Conclusion__:
    + Make it final.
    +
    +!! Draft: DevelopmentFramework
    +http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/DevelopmentFramework
    +
    +Cehteh explains that he will transfer this propoal to a tiddlywiki covering compatibility guides and dependencies. We conclude that this wiki must reflect the actual practice (NoBug, Doxygen, test.sh) despite the proposal is not concrete yet.
    +
    +A short discussion about build systems came up, we still use autotools and scons in parallel, delaying the decision later. oracle2025 mentioned that scons could be used for development and autotools for release. No decision about that everyone has different opinions. But we agree that it works as is.
    +
    +__Conclusion__:
    + Cehteh will make the proposed wiki which shall be maintained to reflect the state and this topic will be finalized by that.
    +
    +!! Draft: Skills Collection
    +http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/SkillsCollection
    +
    +This might be only useful if there are more developers working on the project.
    +
    +__Conclusion__:
    + Leave in draft state for now.
    +
    +!! Draft: Architecture Overview
    +http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/ArchitectureOverview
    +
    +Ichthyo drawn a diagram showing the planned architecture. Cehteh raises concerns about codecs/plugins/effects in backend. After that there was some discussion about details. Cehteh suggests to place plugins in a extra box, gmerlin suggests that 'plugins' don't fit into the diagram, there should be "filters", "sources",..; Followed by some more discussion, showing that we basically agree and understand the design but the drawing needs some refinements.
    +
    +__Conclusion__:
    + Good idea, needs some refinements, work in progress.
    +
    +
    +! Call for Design
    +
    +Ichthyo explains that he wants the overall design a bit more formalized. He put this topic on the agenda to remind that we have to work it out in DesignProcess and already started to make some design proposals.
    +
    +__Conclusion__:
    + Things need to be worked out in DesignProcess, take a look and review it.
    +
    +! Naming
    +
    +Raffa, Velmont, goibhniu and others collected and managed proposed names past weeks which finally ended in a community voting. Results are at http://www.cs.cornell.edu/w8/~andru/cgi-perl/civs/results.pl?id=E_9fad0d1d10c23d38
    +''Lumiera'' won, Lumiera.org is free and no one of in this meeting has objections against this name. Velmont offers to register and pay for the lumiera.org domain which will be hosted on our own server (see topic below). Hermanr raises concerns if it is ok when the name is registered on another site and by another person than the server, cehteh explains that he like this distribution where doable and no one other objects. Ichthyo asks about a short name for Lumiera which will be used for C++ namespaces and such kinds. After a short discussion we agree that we use the full name and no abbreviation. We now have to rename the source and the wiki. Anyone renames the sourcecode where he is responsible for. Cehteh will go over the pipapo.org wiki and rename things.
    +
    +Finally we express our great thanks to the people who put the efforts into the name selection, thanks raffa, Velmont, goibhniu & co.
    +
    +__Conclusion__:
    + ''Projectname is Lumiera'', we have a lot things to rename.
    +
    +! Project Server, setup, organization, administration
    +Some people gathered together and rented a server at 'hetzner.de' which will host some free project pages and personal sites. Cehteh is the one who signed for the server and officially respobsible for it.
    +
    +The server is split into isolated 'vservers' which are created as needed. Idea is to work cooperatively to get the best out of its resources.
    +
    +For our projects (cinelerra.org and lumiera.org) we now need volunteers who help setting it up and administrating things. Velmont offered to help with lumiera.org, hermanr takes care of cinelerra.org, raffa will help with maintaining the webpages. oracle2025 will care for developer chroots, build and test environments. cehteh will make a page on pipapo.org which reflects the current server setup http://www.pipapo.org/pipawiki/RootServerSetup . There are still a lot jobs to do!
    +
    +Cehteh asked about how to manage emergency root access on the host/root server when he is unreachable. There where several suggestions between one root key for all who pay for the server to shared key schemes. We finally agreed that anyone who payed for the server can send a ssh key to ssh to be registered for emergency access.
    +
    +The concrete server setup will be worked out next days. Ideas are one frontend proxy and a shared nameserver. A shared nameserver, A developer vserver shared between all developers. Maybe a shared mail server.
    +
    +Hermanr asked about how to handle distribution of large media files. There was some discussion about bittorrent vs http. We concluded to work that out as needed.
    +
    +In the forthcoming discussion about cehteh stresses that "it is a public server, if you place confidential information unencrypted on it, its you fault". Ssh keys shall be kept secret by the users but we can't enforce policies on those.
    +
    +Ichthyo asks about how to setup lumiera.org (wiki?), oracle2025 suggests webgit, cehteh explains that webgit isn't ready yet but should be useable in a few days (pipapo.org will use that too). Velmont suggest a 'real' website for the time when non-developers want to use it. Git will be set up on lumiera.org the same way as it is currently set up on pipapo.org.
    +
    +Hermanr asked Velmont about some help moving the bugs.cinelerra.org over, this might be little challenging since it needs an MTA and other things.
    +
    +Ichthyo asks about keeping the Lumiera project pages on pipapo.org until the server is ready, this is ok.
    +
    +__Conclusions__:
    + We have our own server which now needs volunteers for maintenance. The projects will slowly move there, until ready Lumiera stays on pipapo.org.
    +
    +
    +! GPL3 pros cons, license rationale
    +
    +Ichthyo and cehteh would like to investigate a license change to GPLv3, neither of us has experience with problems this
    +might raise. Questions are if we lock us out from potential libraries which are GPLv2 only or lock out possible contributors because of unforeseen patent clauses. The others here thinking that "GPLv2 or later" would be most-compatible. Gmerlin tells that he uses some "GPLv2 only" mplayer code in gavl which is itself "GPLv2 or later". Cehteh explains that "GPLv2 only" code is a problem, where "GPLv2 or later" is not. Ichthyo raises concerns that the Support library may need to be LGPL, cehteh mentions that it would likely be enough if we only apply that to the plugin-loader. After all it turns out that there is a lot of confusion, misunderstanding and interpretation used with licenses and no one of us knows for sure. Finally we conclude that the interpretation and license enforcement is ruled by the copyright owner.
    +
    +__Conclusion__:
    + Learn more about GPLv3, use GPLv2 or later and propose to switch to GPLv3 when we are ready to do public beta releases when possible.
    +
    +
    +! Next meeting
    +
    +The next meeting will be at thuesday 3rd april 21:00GMT (if not rescheduled see below).
    +
    +Ichthyo tells that Martin Ellison wrote he couldn't attend because of the time. So again we made a short discussion about changing/alternating timings to allow people in downunder/japan to attend. They have to speak up an make time suggestions.
    +
    +Conclusion:
    + Next meeting 3rd april 21:00GMT. But Aussies, please speak up if you want the time changed!
    +
    +
    +
    +
    ! 3. apr.2008 on #lumiera
    +21:00 - 23:30 GMT. __Participants__:
    + * cehteh
    + * gmerlin
    + * hermanr
    + * ichthyo
    + * joelholdsworth
    + * johncoswell
    + * rgareus
    + * sakalli
    +
    +! Boilerplate
    +!! Organization of this meeting
    + * sakalli writes the protocol, ichthyo will help reviewing it
    +
    +!! Recurring Topics
    +We concluded there are no leftovers and currently no Drafts from the design process to discuss
    +
    +! Call for volunteers
    +(which tasks are to do, how can we interest people...?)
    +
    +There was a sense that there are people willing to help but they might need direction or cannot do actual coding. But there is also a lot of tasks that could be done by beginners and non-programmers. These tasks are important and if someone who is not a programmer is willing to take them on that leaves more time for the programmers. Examples of such tasks:
    +* Protocol writing
    +* maintaining to do lists and isolating tasks
    +* constant code and documentation review
    +* unit/functional testing
    +* header file "task force" - some fundamentals discussed by the developers on libopenvideo should find their way into basic .h files
    +* installing and maintaining project tracking and automated builds/tests on the server
    +
    +See http://www.lumiera.org/wiki/todo.html#Tasks
    +
    +It was also noted that at current phase some basic development is still needed before we can accommodate a large number of coders doing small tasks and for now we need some subsystem owners. For GUI for example.
    +
    +To make it easier for "beginners" to get aquainted with the program it was decided that one ''official Lumiera GIT repository'' should be established.
    +
    +
    +! Project announcements/registration
    +(freshmeat, gnu, etc...) any takers?
    +
    +The discussion was about advertising the project on various sites. There were some concerns raised that it is too early to do too much publicity at the moment. That the right time should be shortly before the first public release. But there is also some value in registering to the project in planning/alpha stage to interest people such as prospective coders. It was noted that the [http://www.linux.com/feature/126441 article on linux.com] resulted in a lot of people contacting ichthyo and cehteh. [http://plot.bek.no/pipermail/piksel/2008-January/003328.html "I believe in Cinelerra"] by Leo Germani also generated a lot of traffic by developers. Some level of presence on mailing lists would be good although not too much just enough to indicate the project is going on.
    +
    +__Conclusion__: volunteer needed to coordinate publicity (not overly urgent, but helpful)
    +
    +
    +! Informal talk about the GUI
    +
    +Firstly, as SimAV was not able to be present during the meeting a proposal by him was relayed by Ichthyo: GUI and backend should be completely separated and communicate via pipes. It was agreed that the GUI should be detached but some higher level message protocol rather than bare pipes should be used. Some comments:
    +* cehteh standalone gui is a nice to have, but implementation details have to be worked out
    +* gmerlin Video playback can be separated in a separate X connection
    +* cehteh suggests to start with an conventional, attached gui and just keep it in mind to make it detachable later
    +* rgareus IMHO you want to share memory for the video-frame buffer beween the player and backend - with pipes you'll go the video-jack way.
    +
    +''joelholdsworth'' is a new developer in the group and had showed interest in developing the GUI. he stated that he is interested in seeing a GUI that uses popular toolkits and that plays by the standards to create a consistent UI with the rest of the free desktop. For this reason he was advocating using  GTKmm. There was no direct objections to GTKmm. Generally, there seems some preference for GTK. (Note this doesn't mean GNOME). Cehteh advocates the idea to use Lua-gtk, i.e. writing the GUI in a clean and lightweight scripting language.
    +
    +Cario was suggested to be used for implementing the canvas in the timeline view. 
    +
    +
    +
    +The gui should provide a skeleton. Timeline and canvas should be controllable and extensible by plugins. Tracks can be nested. Use tiling windows and dockeable views and tools palettes. For example some configuration within session/renderpipeline may cause some pluggable elements to be added to the gui. A fader or a toggle/icon and so forth. Some plugins might render additional output (e.g. in previews). A video track renders thumbnails, automation curves on top.
    +
    +Workflow is another important aspect to take into account in the design. A lot of information needs to come from editors and users in the design process. Different thoughts about the workflow:
    +* Should not make a predefined workflow. Just produce a tool that can be adapted to different workflows. It can be predefined, but should not be fixed.
    +* We dont have the resources to develop a "workflow" in the formal manner, we will go the "propose and comment" route.
    +* We should take the best ideas from popular competing products such as Final Cut Pro, AVID, Premiere plus After Effects.
    +
    +Customisation is deemed important. Some points brought up in the discussion:
    +* sakalli: would be great if we could provide a fcp configuration and a avid configuration besides the default configuration as well. That could lure a lot of users quickly. On the other side, too much flexibility can be be a problem as well. 
    +* cehteh: yes .. but such things are prolly costly to setup .. we need volunteers for anything optional
    +* Customization should be possible without recompile, but not too cheap.
    +* There should be a working skeleton or some fixed anchor but gui operations should be bound to a scripting language to achieve customization.
    +* The whole gui in a script with some performance critical widgets coded in C/C++
    +* Some parts should just be customizable, other parts should be kept fixed.
    +* cehteh suggested to start out by making a 'high level' description with no language/toolkit in mind .. what widgets do we need etc and after that to work on the skeleton mockup.
    +* cehteh / hermanr: Lumiera should allow to choose theme independently from desktop .. because what you have as your desktop-theme doesn't suit for video editing in many cases ... see ardour
    +
    +ichthyo brings up the role of customization for the middle layer and gives an overview of his plans for the new participants. :
    +He had good experiences with a rule based aproach in various projects. He wants to embed a Prolog interpreter that can answer to "configuration queries".  There is a "builder" component in the middle layer to derive the render nodes graph based on a "high level model", which is visible to the user (in the GUI) and based on these configuration queries.
    +
    +Rationale for using prolog is: The rules are very readable because they rather represent facts and relations, not the way "how dings are done" but the way "how things are related". Example: how to configure some effects when the footage is interlaced. Additionally, we want to have some global swithces, which could control these rules, like "I want maximum quality", or "I want as much as possible set up automatically". The prolog rules are stored in the session and can be editd by advanced users. Of course, there is a set of basic rules. This aspect of customisation isn't exactly a GUI issue but it would have consequences for the GUI.
    +
    +some discussion:
    +* joelholdsworth: so we just need a way of exposing properties. This is reasonably straightforward when all you want is value, colour, string etc.
    +* rules within the middle layer/session could bind to some properties exposed in the GUI
    +* gmerlin joelholdsworth: Agree, but point out that this can become difficult
    +* cehteh joelholdsworth: skeleton and plugins who attach into some gui areas, so you can add custom widgets
    +* ichthyo: also the ability to attach "tags" to various objects, so the rules can bind on those tags
    +* cehteh: maybe a standard set of widgets, not really completely custom ones (gmerlin agrees)
    +* joelholdsworth: probably you need to be able to do both well
    +* joelholdsworth in many apps the value/colour/string set works perfectly well, but in luminierra the controls will likely need to be much richer
    +
    +Some brainstorming points about usability:
    +* We need a realy good bezier widget for all sorts of curves.
    +* Faders that can be grabbed everywhere are nice like  like ardours and Blender faders. Or others which have no big knob 
    +* The controls in blender's node view would be a good modal to copy (not advocating GL UI, just using widgets and concepts).
    +
    +One extra point:
    +* we have agreed to make all of the big interfaces between the layers as plain C interfaces, because this is the most widely supported common denominator.
    +
    +!!!! GUI CONCLUSION
    +* ''joelholdsworth'' is now the official GUI maintainer for Lumiera!
    +* sakalli, hermanr, ichthyo announced interest in contributing to discussions about GUI, workflows and usability. gmerlin noted that he knows some gtk secrets and is willing to help out here too.
    +
    +
    +! Froscon application
    +[http://www.froscon.org/ Froscon] is a small nice german open source exhibition that is very very technical oriented. Cehteh will be there as well as Ichthyo. Question is wether we should have a booth, perhaps together with some other interested media projects. Could ask Richard and the ffmpeg/mplayer people. End of call for papers is in june.
    +
    +We made no decision about official presence but most likely there will be a developer meeting if nothing else.
    +
    +
    +! Timecode metadata discussion
    +This Discussion started out on the libopenvideo list: The question was wether we agree on one uniform format solution from decoder up to app level regarding timecode. And what this format would be: arithmetic or struct type. Regarding metadata (including type of timecode) the question is if we should work out a rather fixed data format, or go the route towards rather open description records.
    +
    +__Conclusion__: Gmerlin does it the way it fits best for within the decoder, and Lumiera uses a more uniform time format for representing timecode in the higher app layers. Conversion functions will be concentrated in a library. Regarding metadata we will investigate further.
    +
    +//A (shortended) digest of the timecode and metadata discussion is attached below//
    +
    +! Next meeting
    +
    +The next meeting will be at thuesday 8th may 21:00GMT
    +
    +-----------------------------
    +
    +!!!! Timecode discussion
    +{{{
    +12:51 cehteh gmerlin: did you read my last mail about generalization of metadata?
    +12:51 cehteh key/value pairs
    +12:51 gmerlin not sure about that
    +12:51 cehteh i am pretty sure that i want that in lumiera
    +12:52 cehteh if gavl does that for us it would be even better
    +12:52 gmerlin first of all 2 different things:
    +12:52 gmerlin 1. arithmetic <-> struct
    +12:53 gmerlin 2. Generic <-> format specific
    +12:53 cehteh arithmetic for sure
    +12:53 gmerlin On the decoder API side, I want to export ideally only one type 
    +12:54 gmerlin No no SMPTEXXX and ISO999908098
    +12:54 cehteh will that be attached to the frames in a intrusive way?
    +12:54 cehteh i rather leave the attaching up to the application
    +12:54 gmerlin intrusive?
    +12:55 cehteh struct frame { uint64_t timecode; }   vs...
    +12:55 cehteh struct frame { struct metadata* something; }
    +12:55 cehteh or even vs something done at a api level 
    +12:56 gmerlin struct lumiera_video_frame { gavl_video_frame_t * f; uint64_t timecode};
    +12:56 gmerlin Or add timecodes to gavl_video_frame_t
    +12:57 cehteh struct lumiera_video_frame { gavl_video_frame_t * f; struct metadata* timecode_n_stuff; }
    +12:57 ichthyo so I support a  struct metadata*
    +12:58 cehteh ichthyo: timecodes might not be regular .. they should be optional, but anyways they dont cost when using an arithmetic type
    +12:58 cehteh i mean thats the purpose of timecodes .. to tag every frame and dont make assumptions that your footage is perfect
    +12:58 ichthyo but a struct metadata* would rather mean to keep it out of basic GAVL and have a libmetadata -- which may be integrated with GAVL -- right?
    +12:59 cehteh someome may have stolen a frame :P
    +12:59 cehteh thats gmerlins decision ... 
    +12:59 gmerlin I'm against gavl integration of metadata
    +12:59 gmerlin gavl has a clear scope: Number crunching
    +01:00 cehteh gmerlin: you somehow have to pass it from the decoder to the application
    +01:01 cehteh i would prefer to introduce some sidechannel 
    +01:01 gmerlin Yes, gmerlin_avdecoder will provide a separate function for getting the next timecode
    +01:01 gmerlin bgav_get_next_timecode()
    +01:01 cehteh gavl_get_frame (gavl_frame* place the frame here, metadata* place metadata there)
    +01:01 gmerlin or: bgav_timecode_from_pts()
    +01:03 gmerlin Some higher MXF profiles allow changing timecode parameneters in one stream
    +01:06 gmerlin It's sometimes impossible to separate demuxers and codecs
    +01:06 gmerlin better have them together in one lib
    +01:06 cehteh actually i would like to cache gavls internal states into the backend
    +01:08 gmerlin Ok, so timecodes are YYYYMMDDHHMMSSFF as int64_t
    +01:08 cehteh the indexing is something i prolly have some words about 
    +01:09 cehteh timecodes are uint64_t as microseconds
    +01:09 cehteh well for lumiera :-P
    +01:10 cehteh YYYYMMDDHHMMSSFF as int64_t   isnt that much better than a struct :P
    +01:11 ichthyo now, IMHO its mostly up to gmerlin to decide how it fits into GAVL
    +01:11 cehteh ack
    +01:11 gmerlin Not gavl
    +01:11 ichthyo gmerlin?
    +01:11 gmerlin gmerlin avdecoder yes.
    +01:11 cehteh in lumiera we will use usecs
    +01:11 ichthyo yes
    +01:12 ichthyo we will have a conversion function somewhere
    +01:12 gmerlin And will it include a calendar date?
    +01:12 cehteh doing it only once (avdecoder->usec) makes some sense
    +01:12 gmerlin usecs since when?
    +01:12 ichthyo either, we get directly usecs from avdecoder, if this fits in for gmerlin,
    +01:12 ichthyo or we'll get the format which works best for him and we do the conversion ourselves
    +01:12 cehteh defined elsewhere
    +01:12 cehteh reel-start or absolute time or whatever
    +01:13 ichthyo also, what sort of timecode this was based on (drop frame or not)
    +01:13 cehteh gmerlin: thats a important point .. just uint64_t does not suffice
    +01:13 cehteh it needs a tag describing what kind of timecode was used
    +01:14 cehteh no matter how you encode it 
    +01:14 cehteh and iirc there are quite some timecodes
    +01:14 ichthyo because in this respect richard was right: we need to be able to reprocuce any value 1:1 
    +01:14 cehteh yep
    +01:15 cehteh further i want to be able to convert between any kind of timecode in a fingersnip
    +01:15 gmerlin ichthyo: and that's impossible with usecs
    +01:15 cehteh gmerlin: its not
    +01:15 ichthyo with usecs alone: agreed
    +01:16 ichthyo with usecs + metadata it should be possible
    +01:16 ichthyo modulo some extreme cases (high speed cams, weeks of footage....)
    +01:16 cehteh yes .. you need framerate and other infos depending on the metadata
    +01:17 cehteh you need to be careful to do the math right so that inverse functions dont drift
    +01:17 gmerlin I'll export something lossless, which repduces MXF, DV and Quicktime timecodes losslessly
    +01:17 gmerlin You can then do what you want with them :)
    +01:17 cehteh thats why i would like to do it at only *one* place/library .. because its delicate and bugs are easier to spot/fix there
    +01:18 ichthyo and then there is some api to get at the additional metadata
    +01:18 cehteh yeah
    +01:18 ichthyo and beyond that: lets devise a libmetadata
    +01:18 cehteh just shove the data over .. YYYYMMDDHHMMSSFF as int64_t would be ok
    +01:18 gmerlin Ok.
    +01:18 cehteh we make a libmetadata (as part of our support lib)
    +01:19 cehteh somewhat independent so that it can be spun out
    +}}}
    +
    +!!!! about Metadata
    +{{{
    +01:19 cehteh gmerlin: well .. how bout other metadata
    +01:19 cehteh your decoder needs to pass that too 
    +01:20 gmerlin like?
    +01:20 gmerlin Author, Artist title...
    +01:20 cehteh some cameras encode shutter speed, focus, gain control, colour balance
    +01:20 cehteh and other things
    +01:20 gmerlin Hmmm
    +01:20 gmerlin I think MXF exports some of these
    +01:21 ichthyo wav files can have additional chunks; whats with flac?
    +01:21 gmerlin flac has vorbis metadata
    +01:21 ichthyo important for the more modern sound formats
    +01:21 cehteh dunno .. just thinkin about pro codecs and raw film metadata
    +01:21 ichthyo just wanting to point out: things to come here, 
    +01:22 ichthyo e.g for sound: what stream is what channel
    +01:22 gmerlin Channel locations are handles by gavl
    +01:22 gmerlin If you have a multichannel stream
    +01:22 cehteh well .. note that there is per-asset metadata you want to pass .. and per frame metadata
    +01:22 cehteh maybe even some more undiscovered cases :)
    +01:23 cehteh did someone say this is easy??
    +01:23 sakalli did any of you watch the video regarding red workflow that i sent to the mailing list? redcode raw holds everyting, asa, wb, etc...  hope lumiera will be able to facilitate that as well.
    +01:23 ichthyo at some point I want to be able to support ambisonics
    +01:24 ichthyo and maybe some day there will be wave field sysnthesis in more broad use
    +01:24 cehteh the codec in the back needs to pass us these things else we cantb handle it
    +01:24 gmerlin well, the easiest would be to extend bgav_metadata_t
    +01:24 ichthyo rationale is: just be open
    +01:24 cehteh gmerlin: maybe we need to investigate this things more, nothing needs to be decided now
    +01:24 ichthyo ack
    +01:25 cehteh see my key/value metadata proposal .. at some point maybe you make a complete sidechannel just for metadata
    +01:25 cehteh decoder stuffs that in on demand and it is passed along with its own api like the bgav_timecode_from_pts()
    +01:26 cehteh that way you dont need to touch it more than necessary
    +01:26 gmerlin shouldn't that key/value stuff be unified with plugin parameters?
    +01:27 cehteh for lumiera, maybe, maybe not
    +01:27 ichthyo you mean: you have a common api for describing "values" ?
    +01:27 cehteh some plugin parameters are determined by math functions
    +01:27 gmerlin You have a key, a type and a value
    +01:27 cehteh maybe for caching them
    +01:27 cehteh the api might be unified .. but the storage not
    +01:28 gmerlin why?
    +01:28 ichthyo because any block of data could be in the metadata
    +01:28 cehteh metadata which belongs to the frame coming from the decoder is const
    +01:28 cehteh plugin parameters are volatile
    +
    +01:33 gmerlin One other point (but too late for it now) are audio timecodes. I'll adress that on libopenvideo
    +01:33 cehteh we will write a little more sophisticated timecode library 
    +01:34 cehteh gmerlin: that should be unified :)
    +}}}
    +
     
    @@ -1378,7 +1796,7 @@ This distributed wiki might be used instead the pipapo.org wiki, investigate tha Wiki works. It is simple to use and just flexible enough to handle the task. I don't go to install any other software for such tasks on my server. While the design progresses I'd propose to move our work into git repositories and eventually phase this wiki pages out anyways. I'd rather like to start out distributed/git right away .. but git gives us only a fine storage layer, for a design process we need some good presentation layer (later when using git and starting the implementation everyones favorite editor serves for that) I have no better ideas yet to solve the presentation problem other than using this wiki (or maybe Bouml).
    -
    +
    This is the entry point to several [[TiddlyWiki]]-Pages containing the developer and design documentation for Lumiera.
     
     * Cehteh started GitNotes where we will collect some information about git, howto and special setups
    @@ -1389,23 +1807,25 @@ Wiki works. It is simple to use and just flexible enough to handle the task. I d
     Please __end your tiddlers in a newline__, this makes merging in git easier since the /pre tag used in tiddlywiki will become on a single line.
     
     ----
    -!Design Draft
    +!Architecture and Subsystems
     to get started, we create design drafts emphasizing different aspects and regions of Lumiera
     
    -* Ichthyo focuses mainly on the Render Engine and its interconnection to the EDL, [[see this separate page|renderengine.html]]
    -* Cehteh works on the data backend draft, see [[this page|backend.html]]
    +* Cehteh works on the data backend, see [[this page|backend.html]]
    +* Ichthyo focuses mainly on Edit operations and Builder, [[see this separate page|renderengine.html]]
    +* Gmerlin is in charge of [[GAVL|http://gmerlin.sourceforge.net/gavl.html]] for processing of video data
    +* as of 4/08 a GuiWorkingGroup is emerging...
     * Some tools which don't fit somewhere else and are used everywhere are put into a [[Support Library|support_library.html]]
    -* [[Description of the Test System|TestSh]]
     
    -!Coding Structures
    -next we should //start thinking// on how to organize several aspects of the practical coding...
    +!Coding &mdash; Building &mdash; Testing
    +how to organize several aspects of the practical coding...
     * what to do in BOUML?                          &rarr; [[more|whatInBOUML]]
     * how to organize packages, files, includes?    &rarr; [[more|SrcTreeStructure]]
     * how to organize the executable to be built?
     * what coding conventions to prefer?            &rarr; [[GNU Style|DesignDocumentation]]
     * what [[build system|BuildSystem]] to use?
     * various [[build dependencies|BuildDependenceis]]
    -* TestSuite
    +* we embrace __Test Driven Development__. &rarr; Description of [[Test System|TestSh]] and TestSuite +
    GettingStarted
    diff --git a/wiki/todo.html b/wiki/todo.html
    index 7440ab36a..d6caf66be 100644
    --- a/wiki/todo.html
    +++ b/wiki/todo.html
    @@ -1979,12 +1979,20 @@ see : <<tag RSSFeed>> for the full list.
     
     
    -
    +
    ! Foundations, not really a milestone yet
     
     We need following in a basically working / mockup state:
     
    -* Proc layer, basic rendering, partly mockups
    +* GUI
    +** define a outline (most important views and modes)
    +** define the foundations for communicating with the lower layers
    +* Proc layer
    +** basic assets, create a clip object //(done)//
    +** interface/stub for ~ConfigQuery subsystem //(done)//
    +** add simple clip to EDL/Session, invoke builder
    +** build render nodes for very simple session (partly mockups)
    +** preliminary support for composite clips (video+audio)
     * Backend
     ** File backend, caching
     ** Serializer
    @@ -1996,9 +2004,19 @@ We need following in a basically working / mockup state:
     ** Testsuite
     ** Website
     
    -!! Next Goals
    +!!! Next Goals
     
    -# Make a [[video player mockup]]
    +# Make a [[video player mockup]] + +! Second round +//all rather brainstorming for now, feel free to modify...// + +* save and load session +* integrate YAP Prolog instead of the mock impl +* load and wire some plugins +* send output to a window in GUI + +
    Roadmap and tasks
    @@ -3261,9 +3279,32 @@ function addKeyDownHandlers(e) } //}}}
    -
    +
    ! Proc layer
      by ichtho
    +!! Asset Manager, Asset and ~MObject
    +Design roughly finished, mem management with smart-ptrs and object dependencies working, Asset Manager (automatic registry) working. Relation of Assets and MObjects needs some clarification. Object creation could use some refactoring (work in progress)
    +!! Support for Media Bins, high-level Resource manager
    +not even concrete plans yet. Needing a volounteer to take this subsystem
    +!! Session, EDL, edit operations
    +Session Manager (access point/interface) done. Basic operations (how to address objects in the EDL, how to add objects...) only drafted, need detailed design (but is difficult before the builder is more clear, so I'll probably work bottom up here)
    +!! Framework for storing/loading objects
    +Just a draft in a separate branch, nothing finished.
    +!! Defaults Manager ~ConfigQuery subsystem
    +Defaults Manager done, using a mock implementation of for config queries. Need to understand better what queries we need to support, what predicates to define, how to describe capabilities. Basically it's too early to nail down a design
    +!! integrating YAP Prolog or another resolution system
    +blocked because of the preceeding. But it would be possible to implement the basics (i.e. calling in, passing rule code....)
    +!! create Fixture from all ~EDLs
    +Design partially done, nothing implemented yet.
    +!! create Partitioning of Fixture
    +Some ideas; blocked because of incomplete design of the EDL
    +!! Builder core
    +support framework done. Design/planning of node creater tool partially done, implementation just started
    +!! Render nodes
    +nothing but a preliminary object hierarchy. Need to work out the interface.
    +!! Automation handling
    +just a draft. Need to work out interface for describing automatable "parameters"
    +
     
     ! Backend
      by cehteh
    @@ -3300,8 +3341,8 @@ will be done on the 'devel' vserver. nothing done yet.
     Someone might pickup a Doxygen-Maintainer. This is not writing actual documentation but bringing the Documentation comments in the source to a good shape, add formatting tags, ensureing that all docs are properly generated, maintaining a glossary and index, define the order etc.
     
    -
    -
    Use the backend, gmerlin/avdecoder and a Player widget to playback videos. This should be a small application which can open and playback many videos from on instance in parallel. Later on scrubbing for this videos might be supported.
    +
    +
    Use the backend, gmerlin/avdecoder and a Player widget to playback videos. This should be a small application which can open and playback many videos from one instance in parallel. Later on scrubbing for this videos might be supported.
     
     The idea here is to show and measure backend and scheduler performance and beeing a proof of concept for the design. It will run independent of the Proc layer but needs quite some work on the backend to be done.
    From ce72947d0cb5fd378d6c20406623941b7962424c Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 13 Apr 2008 03:39:18 +0200 Subject: [PATCH 34/36] brought proc layer introductory pages up-to-date --- doc/devel/uml/fig128005.png | Bin 42604 -> 34040 bytes uml/lumiera/128005 | 15 +++++++++--- uml/lumiera/128005.diagram | 45 +++++++++++++++++++++++------------- uml/lumiera/128261 | 15 +++++++++++- uml/lumiera/129285 | 2 +- uml/lumiera/130053.diagram | 16 ++++++------- uml/lumiera/5.session | 25 ++++---------------- uml/lumiera/lumiera.prj | 2 +- wiki/draw/Proc.builder1.png | Bin 12065 -> 12692 bytes wiki/renderengine.html | 40 ++++++++++++++++++-------------- 10 files changed, 92 insertions(+), 68 deletions(-) diff --git a/doc/devel/uml/fig128005.png b/doc/devel/uml/fig128005.png index 7290793c8a6a17876c0d310300a50540f5f28411..e9bef762483a2bf308f117a2af21c3a3df5c28f0 100644 GIT binary patch literal 34040 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 diff --git a/uml/lumiera/128005 b/uml/lumiera/128005 index b6932706b..dc0adfe5f 100644 --- a/uml/lumiera/128005 +++ b/uml/lumiera/128005 @@ -1,6 +1,6 @@ format 40 "design" // design - revision 10 + revision 11 modified_by 5 "hiv" // class settings //class diagram settings @@ -54,7 +54,7 @@ Not a real code package, rather a container for design drafts, specifications, d end required_classes class_ref 128261 // Fixture - class_ref 128005 // Session + class_ref 128005 // SessionImpl end end @@ -65,7 +65,7 @@ Not a real code package, rather a container for design drafts, specifications, d class_ref 128261 // Fixture class_ref 128517 // MObject class_ref 134661 // ParamProvider - class_ref 128005 // Session + class_ref 128005 // SessionImpl end component 128389 "EDL" stereotype "entity" @@ -92,6 +92,9 @@ Not a real code package, rather a container for design drafts, specifications, d end component 128773 "Dispatcher" + provided_classes + class_ref 141957 // ProcDispatcher + end end component 128901 "Engine" @@ -140,6 +143,12 @@ Not a real code package, rather a container for design drafts, specifications, d component 130309 "AssetDB" stereotype "service" end + + component 131077 "client code" + required_classes + class_ref 141957 // ProcDispatcher + end + end end componentview 128133 "interfaces" diff --git a/uml/lumiera/128005.diagram b/uml/lumiera/128005.diagram index a16e8f676..26b59ec1a 100644 --- a/uml/lumiera/128005.diagram +++ b/uml/lumiera/128005.diagram @@ -1,7 +1,7 @@ format 40 fragment 128005 "UI Layer" - xyzwh 321 22 2000 829 100 + xyzwh 322 22 1994 828 100 end fragment 128133 "Processing Layer" xyzwh 64 156 2000 1089 655 @@ -21,59 +21,72 @@ packagecanvas 128645 xyzwh 94 551 2005 458 235 componentcanvas 128773 component_ref 128005 // Builder draw_component_as_icon default show_component_req_prov default show_component_rea default - xyzwh 121 419 2015 229 105 + xyzwh 122 419 2015 228 105 componentcanvas 128901 component_ref 128133 // Session draw_component_as_icon default show_component_req_prov default show_component_rea default - xyzwh 122 243 2011 323 156 + xyzwh 122 243 2011 322 155 componentcanvas 129029 component_ref 128261 // Controller draw_component_as_icon default show_component_req_prov default show_component_rea default - xyzwh 372 419 2011 189 105 + xyzwh 373 419 2011 188 105 componentcanvas 129157 component_ref 128389 // EDL draw_component_as_icon default show_component_req_prov default show_component_rea default - xyzwh 288 302 2016 153 79 + xyzwh 288 303 2016 152 78 componentcanvas 129285 component_ref 128517 // Fixture draw_component_as_icon default show_component_req_prov default show_component_rea default - xyzwh 124 319 2016 153 75 + xyzwh 125 319 2016 152 75 note 129541 "Structures edited by the User" xyzwh 43 269 2016 181 41 componentcanvas 129669 component_ref 128645 // AssetManagement draw_component_as_icon default show_component_req_prov default show_component_rea default - xyzwh 577 232 2010 217 201 + xyzwh 578 233 2010 216 200 componentcanvas 129797 component_ref 128773 // Dispatcher draw_component_as_icon default show_component_req_prov default show_component_rea default - xyzwh 406 31 2005 193 75 + xyzwh 357 133 2005 192 75 componentcanvas 129925 component_ref 128901 // Engine draw_component_as_icon default show_component_req_prov default show_component_rea default - xyzwh 118 602 2010 235 176 + xyzwh 118 601 2010 235 175 componentcanvas 130053 component_ref 129029 // Frame (Stream) Provider draw_component_as_icon default show_component_req_prov default show_component_rea default - xyzwh 121 876 2005 229 75 + xyzwh 122 875 2005 228 75 componentcanvas 130181 component_ref 129157 // Cache draw_component_as_icon default show_component_req_prov default show_component_rea default - xyzwh 391 876 2005 193 75 -note 131717 "Coordinates Playback and Rendering" + xyzwh 392 875 2005 192 75 +note 131717 "Coordinates Building and Rendering" xyzwh 483 494 2016 149 63 note 131845 "border of the low-level, performance-critical part of the system" xyzwh 666 450 2006 167 84 note 131973 "just works, never decides" xyzwh 317 668 2015 110 59 -note 132101 "codecs, stream I/O here" - xyzwh 376 592 2005 166 39 +note 132101 "codecs, effects, stream I/O here" + xyzwh 618 876 2005 200 36 componentcanvas 132229 component_ref 130181 // MediaFactory draw_component_as_icon default show_component_req_prov default show_component_rea default - xyzwh 593 354 2015 158 67 + xyzwh 593 355 2015 157 66 componentcanvas 132357 component_ref 130309 // AssetDB draw_component_as_icon default show_component_req_prov default show_component_rea default xyzwh 629 289 2020 155 63 +componentcanvas 132485 component_ref 131077 // client code + draw_component_as_icon default show_component_req_prov default show_component_rea default + xyzwh 600 27 2005 156 63 +arrowjunctioncanvas 132997 class_ref 141957 // ProcDispatcher + xyz 473 83 2000 label_xy 441 100 +arrowjunctioncanvas 133253 class_ref 141957 // ProcDispatcher + xyz 475 71 2000 label_xy 863 37 simplerelationcanvas 131205 simplerelation_ref 128005 from ref 130053 z 2004 to ref 130181 simplerelationcanvas 131333 simplerelation_ref 128133 from ref 129925 z 2004 to ref 130053 +line 133125 ---O + from ref 129797 z 1999 to ref 132997 +line 133381 ---( geometry VHr + from ref 132485 z 1999 to point 480 56 + line 133509 z 1999 to ref 133253 line 130309 -_-_ from ref 129797 z 2004 to ref 128901 line 130821 -_-_ geometry HVr - from ref 129797 z 2004 to point 493 469 + from ref 129797 z 2004 to point 450 469 line 130949 z 2004 to ref 129029 line 131077 -_-_ from ref 129797 z 2004 to ref 129669 +preferred_whz 852 640 0.8 end diff --git a/uml/lumiera/128261 b/uml/lumiera/128261 index 6394cfca5..f016cf9c4 100644 --- a/uml/lumiera/128261 +++ b/uml/lumiera/128261 @@ -1,6 +1,6 @@ format 40 "MObject" // ProcessingLayer::MObject - revision 30 + revision 31 modified_by 5 "hiv" // class settings //class diagram settings @@ -1172,6 +1172,19 @@ ${inlines} b multiplicity "" parent class_ref 139909 // LocatingPin end end + + class 141957 "ProcDispatcher" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + end end package_ref 128901 // Builder diff --git a/uml/lumiera/129285 b/uml/lumiera/129285 index 1a005d8e9..28f619bb6 100644 --- a/uml/lumiera/129285 +++ b/uml/lumiera/129285 @@ -1,6 +1,6 @@ format 40 "ProcessingLayer" // ProcessingLayer - revision 13 + revision 14 modified_by 5 "hiv" // class settings //class diagram settings diff --git a/uml/lumiera/130053.diagram b/uml/lumiera/130053.diagram index da938cd73..b8ef0a19a 100644 --- a/uml/lumiera/130053.diagram +++ b/uml/lumiera/130053.diagram @@ -24,7 +24,7 @@ packagecanvas 129413 show_context_mode namespace xyzwh 41 428 1990 385 315 componentcanvas 129541 component_ref 128261 // Controller draw_component_as_icon default show_component_req_prov default show_component_rea default - xyzwh 88 546 2010 151 63 + xyzwh 87 546 2010 151 63 arrowjunctioncanvas 131973 class_ref 130565 // BuilderFacade xyz 316 456 2000 label_xy 230 507 arrowjunctioncanvas 132229 class_ref 130565 // BuilderFacade @@ -38,10 +38,10 @@ componentcanvas 132869 component_ref 129925 // CommonLib arrowjunctioncanvas 132997 class_ref 134917 // Time xyz 830 211 2000 label_xy 828 233 arrowjunctioncanvas 133253 class_ref 130309 // ControllerFacade - xyz 480 158 2000 label_xy 448 179 + xyz 481 157 2000 label_xy 449 178 componentcanvas 133509 component_ref 128133 // Session draw_component_as_icon default show_component_req_prov default show_component_rea default - xyzwh 694 526 2005 156 63 + xyzwh 694 526 2005 155 63 arrowjunctioncanvas 134533 class_ref 128133 // EDL xyz 591 603 2000 label_xy 590 624 arrowjunctioncanvas 134789 class_ref 128261 // Fixture @@ -53,30 +53,30 @@ arrowjunctioncanvas 135301 class_ref 134661 // ParamProvider componentcanvas 135685 component_ref 128005 // Builder draw_component_as_icon default show_component_req_prov default show_component_rea default xyzwh 136 954 2005 151 63 -arrowjunctioncanvas 135813 class_ref 128005 // Session +arrowjunctioncanvas 135813 class_ref 128005 // SessionImpl xyz 571 765 2000 label_xy 562 787 arrowjunctioncanvas 136197 class_ref 132741 // StateProxy xyz 535 978 2000 label_xy 517 999 -arrowjunctioncanvas 136453 class_ref 128005 // Session +arrowjunctioncanvas 136453 class_ref 128005 // SessionImpl xyz 526 801 2000 label_xy 517 823 packagecanvas 136709 package_ref 130309 // engine show_context_mode namespace xyzwh 16 1309 1994 561 265 componentcanvas 136837 component_ref 128901 // Engine draw_component_as_icon default show_component_req_prov default show_component_rea default - xyzwh 103 1402 2005 156 63 + xyzwh 103 1401 2005 156 63 arrowjunctioncanvas 136965 class_ref 132741 // StateProxy xyz 535 1224 2000 label_xy 517 1245 componentcanvas 137349 component_ref 130053 // ProcNode draw_component_as_icon default show_component_req_prov default show_component_rea default - xyzwh 377 1494 2000 123 63 + xyzwh 376 1494 2000 123 63 arrowjunctioncanvas 137477 class_ref 134533 // Parameter xyz 623 1379 2000 label_xy 607 1400 arrowjunctioncanvas 137733 class_ref 134661 // ParamProvider xyz 684 1368 2000 label_xy 658 1389 componentcanvas 138373 component_ref 129797 // ConManager draw_component_as_icon default show_component_req_prov default show_component_rea default - xyzwh 136 1070 2005 156 63 + xyzwh 135 1070 2005 156 63 arrowjunctioncanvas 138501 class_ref 134661 // ParamProvider xyz 586 1094 2000 label_xy 560 1115 componentcanvas 138757 component_ref 129285 // RenderPathManager diff --git a/uml/lumiera/5.session b/uml/lumiera/5.session index 89c760008..fc9677d8c 100644 --- a/uml/lumiera/5.session +++ b/uml/lumiera/5.session @@ -1,31 +1,14 @@ window_sizes 1140 830 270 860 680 71 diagrams - classdiagram_ref 130309 // Asset Kinds - 860 633 100 4 158 0 - classdiagram_ref 128133 // Session structure - 860 633 100 4 349 0 - classdiagram_ref 128389 // Render Entities - 743 538 100 4 184 0 - classdiagram_ref 131205 // Struct-Asset Relations - 555 620 100 4 60 0 - classdiagram_ref 131461 // Rules access - 688 627 100 4 0 0 - componentdiagram_ref 131589 // components - 688 544 100 4 0 0 - active usecasediagram_ref 131717 // when to query - 624 495 100 4 0 0 - collaborationdiagram_ref 131845 // "default" object - 626 551 100 4 0 0 + active componentdiagram_ref 128005 // Overview + 702 640 80 4 2 0 end show_stereotypes selected package_ref 129 // lumiera open - - package_ref 128005 // design - - package_ref 129285 // ProcessingLayer - componentview_ref 128261 // Query System overview + componentview_ref 128133 // interfaces + classview_ref 128005 // Session class_ref 140677 // QueryHandler class_ref 140805 // TypeHandler class_ref 140933 // ResolverBase diff --git a/uml/lumiera/lumiera.prj b/uml/lumiera/lumiera.prj index 8eec4bb57..dcdd63301 100644 --- a/uml/lumiera/lumiera.prj +++ b/uml/lumiera/lumiera.prj @@ -1,6 +1,6 @@ format 40 "lumiera" - revision 43 + revision 44 modified_by 5 "hiv" cpp_root_dir "../../src/" diff --git a/wiki/draw/Proc.builder1.png b/wiki/draw/Proc.builder1.png index 84dfa904eaa598db4d89548342ab18d5b8a4b7a5..145f98e3fce821b6adde2b46bdc23386fe4f6227 100644 GIT binary patch literal 12692 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 La-xO8x}W|(AK-je literal 12065 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 E4`nwziU0rr diff --git a/wiki/renderengine.html b/wiki/renderengine.html index c60cbb53b..7e922bde6 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -564,8 +564,8 @@ For every Asset we generate a __Ident tuple__ and a long ID (hash) derived from
    The Asset Manager provides an Interface to some internal Database holding all Assets in the current Session and System state. It may be a real Database at some point (and for the moment it's a Hashtable). Each [[Asset]] is registered automatically with the Asset Manager; it can be queried either by it's //identification tuple// or by it's unique ID.
    -
    -
    Placing an MObject relatively to another object such that it should be handled as //attached // to the latter results in several implementation problems. The typical use case is that of an effect attached to a clip or processing pipe.
    +
    +
    Placing an MObject relatively to another object such that it should be handled as //attached&nbsp;// to the latter results in several implementation problems. The typical use case is that of an effect attached to a clip or processing pipe.
     * this attachment is not a globally fixed relation, rather, it typically exists only for some limited time span (e.g. the duration of the basic clip the effect is attached to)
     * the order of attachment is important and the attached placement may create a fork in the signal flow, so we need a way for specifying reproducibly how the resulting wiring should be
     * when building, we access the information in reversed direction: we have the target object and need to query for all attachements
    @@ -578,7 +578,7 @@ The first step towards an solution is to isolate the problem; obviously we //nee
     [img[how to implement Automation|uml/fig129669.png]]
     
    -
    +
    Starting out from the concepts of Objects, Placement to Tracks, render Pipes and connection properties (&rarr; see [[here|TrackPipeEDL]]) within the EDL, we can identify the elementary operations occuring within the Builder. Overall, the Builder is organized as application of //visiting tools// to a collection of objects, so finally we have to consider some object kind appearing in the working function of the given builder tool, which holds at this moment some //context//. The job now is to organize this context such as to create a predictable build process from this //event driven// approach.
     
     !Builder working Situations
    @@ -589,7 +589,7 @@ The first step towards an solution is to isolate the problem; obviously we //nee
     ##* effectively this is an application of effects
     ## at this point we have to process (and maybe generate on-the-fly) the [[source port of this clip|ClipSourcePort]]
     ##* the output of the source reading and preprocessing defined thus far is delivered as input to this port, which is done by a ~WiringRequest (see below)
    -##* as every port, it is the entry point to a [[processing pipe|Pipe], thus the source port has a processing pattern, typically inserting the camera (transformation effect) at this point
    +##* as every port, it is the entry point to a [[processing pipe|Pipe]], thus the source port has a processing pattern, typically inserting the camera (transformation effect) at this point
     ## followed by the application of effects
     ##* separately for every effect chain rooted (placed) directly onto the clip
     ##* and regarding the chaining order
    @@ -1734,8 +1734,13 @@ But because I know the opinions on this topc are varying (users tend to be delig
     My proposed aproach is to treat OpenGL as a separate video raw data type, requiring separete and specialized [[Processing Nodes|ProcNode]] for all calculations. Thus the Builder could connect OpenGL nodes if it is possible to cover the whole render path for preview and fall back to the normal ~ProcNodes for all relevant renders
     
    -
    +
    The Lumiera Processing Layer is comprised of various subsystems and can be separated into a low-level and a high-level part. At the low-level end is the [[Render Engine|OverviewRenderEngine]] which basically is a network of render nodes cooperating closely with the Backend Layer in order to carry out the actual playback and media transforming calculations. Whereas on the high-level side we find several different [[Media Objects|MObjects]] that can be placed into the [[EDL]], edited and manipulated. This is complemented by the [[Asset Management|Asset]], which is the "bookkeeping view" of all the different "things" within each [[Session|SessionOverview]].
    +
    +There is rather strong separation between these two levels, and &mdash; <br/>correspondingly you'll encounter the data held within the Processing Layer organized in two different views, the ''high-level-model'' and the ''low-level-model''
    +* from users (and GUI) perspective, you'll see a [[Session|SessionOverview]] with a timeline-like structure, where various [[Media Objects|MObjects]] are arranged and [[placed|Placement]]. By looking closer, you'll find that there are data connections and all processing is organized around processing chains or [[pipes|Pipe]], which can be either global (in the Session) or local (in real or [[virtual|VirtualClip]] clips)
    +* when dealing with the actual calculations in the Engine (&rarr; see OverviewRenderEngine), you won't find any Tracks, Media Objects or Pipes &mdash; rather you'll find a network of interconnected [[render nodes|ProcNode]] forming the low level model. Each structurally constant segment of the timeline corresponds to a separate node network providing an ExitNode corresponding to each of the global pipes; pulling frames from them means running the engine.
    +* it is the job of the [[Builder]] create and wire up this render nodes network when provided with a given hig-level-model. So, actually the builder (together with the so called [[Fixture]]) form an isolation layer in the middle, separating the //editing part&nbsp;// from the //processing part.//
     [img[Block Diagram|uml/fig128005.png]]
     
    @@ -2508,7 +2513,7 @@ Besides, they provide an important __inward interface__ for the [[ProcNode]]s, w
    -
    +
    The Render Engine is the part of the application doing the actual video calculations. Its operations are guided by the Objects and Parameters edited by the user in [[the EDL|EDL]] and it retrieves the raw audio and video data from the [[Data backend|backend.html]]. Because the inner workings of the Render Engine are closely related to the structures used in the EDL, this design covers [[the aspect of objects placed into the EDL|MObjects]] as well.
     <<<
     ''Status'': started out as design draft in summer '07, Ichthyo is now in the middle of a implementing the foundations and main structures in C++
    @@ -2526,8 +2531,9 @@ The system is ''open'' inasmuch every part mirrors the structure of correspondin
     
     !!see also
     &rarr; [[Overview]] of Subsystems and Components, and DesignGoals
    -&rarr; [[An Introduction|WalkThrough]] discussing the key features
    -&rarr; [[Overview Render Engine|OverviewRenderEngine]]
    +&rarr; [[An Introduction|WalkThrough]] discussing the central points of this design
    +&rarr; [[Overview Session (high level model)|SessionOverview]]
    +&rarr; [[Overview Render Engine (low level model)|OverviewRenderEngine]]
     &rarr; BuildProcess and RenderProcess
     &rarr; [[Two Examples|Examples]] (Object diagrams) 
     &rarr; how [[Automation]] works
    @@ -2835,7 +2841,7 @@ The Session object is a singleton &mdash; actually it is a »~PImpl«-Facade
     * a collection of ''global Pipes''
     * the ''Fixture'' with a possibility to [[(re)build it|PlanningBuildFixture]]
    -
    +
    The [[Session]] (sometimes also called //Project//) contains all informations and objects to be edited by the User. It can be saved and loaded. The individual Objects within the Session, i.e. Clips, Media, Effects, are contained in one (or several) collections within the Session, which we call [[EDL (Edit Decision List)|EDL]]. Moreover, the sesion contains references to all the Media files used, and it contains various default or user defined configuration, all being represented as [[Asset]]. At any given time, there is //only one current session// opened within the application.
     
     !!!larger projects
    @@ -2845,14 +2851,14 @@ For larger editing projects the simple structure of a session containing "t
     With all the structural complexities possible within such a session, we need an isolation layer to provide __one__ definitive state where all configuration has been made explicit. Thus the session manages one special object list, the [[Fixture]], which can be seen as all currently active objects placed onto a single timeline.
     
     !!!organisational devices
    -The possibility of having multiple ~EDLs helps organizing larger projects. Each [[EDL]] is just a logical grouping; because all effective properties of any MObject within this EDL are defined by the ~MObject itself and the [[Placement]], by which the object is anchored to some time point, some track, can be connected to some pipe, or linked to another object. In a similar manner, Tracks are just another organisational aid for grouping objects, disabling them and defining common output pipes.
    +The possibility of having multiple ~EDLs helps organizing larger projects. Each [[EDL]] is just a logical grouping; because all effective properties of any MObject within this EDL are defined by the ~MObject itself and the [[Placement]], by which the object is anchored to some time point, some track, can be connected to some pipe, or linked to another object. In a similar manner, [[Tracks|Track]] are just another organisational aid for grouping objects, disabling them and defining common output pipes.
     
     !!!global pipes
    -Any session should contain a number of global [[(destination) pipes|Pipe]], typically video out and audio out. The goal is, to get any content producing or transforming object in some way connected to one of these outputs, either //by [[placing|Placement]] it directly// to some pipe, or by //placing it to a track// and having the track refer to some pipe. Besides the global destination pipes, we can use internal pipes to form busses or subgroups, either on a global (session) level, or by using the processing pipe within a [[virtual clip|VirtualClip]], which can be placed freely within the ~EDLs. Normally, pipes just gather and mix data, but of course any pipe can have an attached effect chain. (&rarr; see [[more on Tracks and Pipes within the EDL|TrackPipeEDL]])
    +[>img[draw/Proc.builder1.png]] Any session should contain a number of global [[(destination) pipes|Pipe]], typically video out and audio out. The goal is, to get any content producing or transforming object in some way connected to one of these outputs, either //by [[placing|Placement]] it directly// to some pipe, or by //placing it to a track// and having the track refer to some pipe. Besides the global destination pipes, we can use internal pipes to form busses or subgroups, either on a global (session) level, or by using the processing pipe within a [[virtual clip|VirtualClip]], which can be placed freely within the EDL(s). Normally, pipes just gather and mix data, but of course any pipe can have an attached effect chain. (&rarr; see [[more on Tracks and Pipes within the EDL|TrackPipeEDL]])
     
     !!!default configuration
    -[>img[draw/Proc.builder1.png]]While all these possibilities may seem daunting, there is a simple default configuration loaded into any pristine new session:
    -It will contain a global video and audio out pipe, just one EDL with one track; this track will have a internal video and audio pipe (bus) configured with one fading device sending to the global output ports. So, by adding some clip with a simple absolute placement to this track and some time position, the clip gets connected and rendered, after [[(re)building|PlanningBuildFixture]] the [[Fixture]] and passing the result to the [[Builder]] &mdash; and using the resulting render nodes network (Render Engine).
    +While all these possibilities may seem daunting, there is a simple default configuration loaded into any pristine new session:
    +It will contain a global video and audio out pipe, just one EDL with a single track; this track will have a internal video and audio pipe (bus) configured with one fading device sending to the global output ports. So, by adding some clip with a simple absolute placement to this track and some time position, the clip gets connected and rendered, after [[(re)building|PlanningBuildFixture]] the [[Fixture]] and passing the result to the [[Builder]] &mdash; and using the resulting render nodes network (Render Engine).
     
    @@ -4265,7 +4271,7 @@ generally speaking, visitors are preferable when the underlying element type hie To see an simple example of our "visiting tool", have a look at {{{tests/components/common/visitingtooltest.cpp}}}
    -
    +
    The Intention of this text is to help you understanding the design and to show some notable details.
     
     !!!!Starting Point
    @@ -4282,15 +4288,15 @@ Design is an experiment to find out how things are related. We can't //plan// a
     !!!!Concepts and Interfaces
     This design strives to build each level and subsystem around some central concepts, which are directly expressed as Interfaces. Commonly used Interfaces clamp the different layers.
     * MObject gives an uniform view on all the various entities to be arranged in the EDL.
    -* all the arranging and relating of ~MObjects is abstracted as [[Placement]]. The contract of a Placement is that it always has a related Subject, that we can call some test methods on it (still to be defined), and, finally, that we can get an ExplicitPlacement from it.
    -* albeit being a special form of a Placement, the ExplicitPlacement is treated as a separate concept. With respect to edit operations within the EDL, it can stand for any sort of Placement. On the other hand the Builder takes a list of ~ExplicitPlacements as input for building up the Render Engine(s). This corresponds to the fact that the render process needs to organize the things to be done on a simple two dimensional grid of (output channel / time). The (extended) contract of an ~ExplicitPlacement provides us with this information (track,time).
    +* all the arranging and relating of ~MObjects is abstracted as [[Placement]]. The contract of a Placement is that it always has a related Subject, that we can change the //way of placement&nbsp;// by adding and removing [["locating pins"|LocatingPin]], call some test methods on it (still to be defined), and, finally, that we can get an ExplicitPlacement from it.
    +* albeit being a special form of a Placement, the ExplicitPlacement is treated as a separate concept. With respect to edit operations within the EDL, it can stand for any sort of Placement. On the other hand the Builder takes a list of ~ExplicitPlacements as input for building up the Render Engine(s). This corresponds to the fact that the render process needs to organize the things to be done on a simple two dimensional grid of (output channel / time). The (extended) contract of an ~ExplicitPlacement provides us with this (output,time).
     * on the lower end of the builder, everything is organized around the Concept of a ProcNode, which enables us to //pull// one (freely addressable) Frame of calculated data. Further, the ProcNode has the ability to be wired with other nodes and [[Parameter Providers|ParamProvider]]
     * the various types of data to be processed are abstracted away under the notion of a [[Frame]]. Basically, a Frame is an Buffer containing an Array of raw data and it can be located by some generic scheme, including (at least) the absolute starting time (and probably some type or channel id).
     * All sorts of (target domain) [[Parameters]] are treated uniformly. There is a distinction between Parameters (which //could// be variable) and Configuration (which is considered to be fixed). In this context, Automation just appears as a special kind of ParamProvider.
     * and finally, the calculation //process// together with its current state is represented by a StateProxy. I call this a "proxy", because it should encapsulate and hide all tedious details of communication, be it even asynchronous communication with some Controller or Dispatcher running in another Thread. In order to maintain a view on the current state of the render process, it could eventually be necessary to register as an observer somewhere or to send notifications to other parts of the system.
     
     !!!!Handling Diversity
    -An important goal of this approach is to be able to push down the treatment of variations and special cases. We don't need to know what kind of Placement links one MObject to another, because it is sufficient for us to get an ExplicitPlacement. The Render Engine doesn't need to know if it is pulling audio Frames or video Frames or GOPs or OpenGL textures. It simply relies on the Builder wiring together the correct node types. And the Builder in turn does so by using some overloaded function of an iterator or visitor. There is no need for the video [[ProcNodes|ProcNode]] to test for the colormodel on every screen line, because the Data Frame can be a Template parametrized by the colormodel. All of this reduces complexity and quite some misconceptions can be detected already by the compiler.
    +An important goal of this approach is to be able to push down the treatment of variations and special cases. We don't need to know what kind of Placement links one MObject to another, because it is sufficient for us to get an ExplicitPlacement. The Render Engine doesn't need to know if it is pulling audio Frames or video Frames or GOPs or OpenGL textures. It simply relies on the Builder wiring together the correct node types. And the Builder in turn does so by using some overloaded function of an iterator or visitor. At many instances, instead of doing decisions in-code or using hard wired defaults, a system of [[configuration rules|ConfigRules]] is invoked to get a suitable default as a solution (and, as a plus, this provides points of customisation for advanced users). At engine level, there is no need for the video processing node to test for the colormodel on every screen line, because the Builder has already wired up the fitting implementation routine. All of this helps reducing complexity and quite some misconceptions can be detected already by the compiler.
     
     !!!!Explicit structural differences
     In case it's not already clear: we don't have "the" Render Engine, rather we construct a Render Engine for each structurally differing part of the timeline. (please relate this to the current Cinelerra code base, which constructs and builds up the render pipeline for each frame separately). No need to call back from within the pipeline to find out if a given plugin is enabled or to see if there are any automation keyframes. We don't need to pose any constraints on the structuring of the objects in the EDL, besides the requirement to get an ExplicitPlacement for each. We could even loosen the use of the common metaphor of placing media sequences on fixed tracks, if we want to get at a more advanced GUI at some point in the future.
    
    From 85189d3f4c384758f95e137d744abefbbc44ce7a Mon Sep 17 00:00:00 2001
    From: Ichthyostega 
    Date: Sun, 13 Apr 2008 23:54:39 +0200
    Subject: [PATCH 35/36] extend Appconfig class to provide Lifecycle callback
     hooks esp. for automatic triggering the initialisation of very basic struff
     (like NoBug...)
    
    ---
     doc/devel/uml/class141957.html   |  20 ++++++
     src/common/appconfig.cpp         |  81 +++++++++++++++++++++----
     src/common/appconfig.hpp         |  88 +++++++++++++++++++++------
     src/common/lifecycleregistry.hpp | 101 +++++++++++++++++++++++++++++++
     src/proc/asset.hpp               |   2 +-
     src/proc/mobject/session.hpp     |   2 +-
     tests/50components.tests         |   5 ++
     tests/common/appconfigtest.cpp   |   5 +-
     tests/common/lifecycletest.cpp   |  78 ++++++++++++++++++++++++
     9 files changed, 347 insertions(+), 35 deletions(-)
     create mode 100644 doc/devel/uml/class141957.html
     create mode 100644 src/common/lifecycleregistry.hpp
     create mode 100644 tests/common/lifecycletest.cpp
    
    diff --git a/doc/devel/uml/class141957.html b/doc/devel/uml/class141957.html
    new file mode 100644
    index 000000000..9158a22a5
    --- /dev/null
    +++ b/doc/devel/uml/class141957.html
    @@ -0,0 +1,20 @@
    +
    +
    +
    +
    +
    +
    +Class ProcDispatcher
    +
    +
    +
    +
    +
    +
    Class ProcDispatcher
    +

    + + + + +

    Declaration :

    • C++ : class ProcDispatcher

    Component(s) : Dispatcher

    + diff --git a/src/common/appconfig.cpp b/src/common/appconfig.cpp index 17a245cdf..b708d42d0 100644 --- a/src/common/appconfig.cpp +++ b/src/common/appconfig.cpp @@ -33,29 +33,37 @@ using util::isnil; +using util::cStr; namespace lumiera { #ifndef LUMIERA_VERSION -#define LUMIERA_VERSION 3++devel +#define LUMIERA_VERSION 0++devel #endif - /** perform initialization on first access. - * A call is placed in static initialization code - * included in lumiera.h; thus it will happen - * probably very early. + /** perform initialization triggered on first access. + * Will execute the ON_BASIC_INIT hook, but under typical + * circumstances this is a NOP, because when callbacks are + * added to this hook, the Appconfig singleton instance has + * already been created. For this reason, there is special + * treatment for the ON_BASIC_INIT in LifecycleHook::add, + * causing the provided callbacks being fired immediately. + * (btw, this is nothing to be worried of, for the client + * code it just behaves like intended). */ Appconfig::Appconfig() - : configParam_ (new Configmap) + : configParam_ (new Configmap), + lifecycleHooks_(new LifecycleRegistry) { ////////// NOBUG_INIT; ////////// INFO(config, "Basic application configuration triggered."); + lifecycleHooks_->execute (ON_BASIC_INIT); // note in most cases a NOP // install our own handler for undeclared exceptions std::set_unexpected (lumiera::error::lumiera_unexpectedException); @@ -67,11 +75,8 @@ namespace lumiera - /** access the configuation value for a given key. - * @return empty string for unknown keys, else the corresponding configuration value - */ const string & - Appconfig::get (const string & key) throw() + Appconfig::get (const string & key) { try { @@ -82,10 +87,64 @@ namespace lumiera catch (...) { ERROR(config, "error while accessing configuration parameter \"%s\".", key.c_str()); - throw lumiera::error::Fatal (); + static string NOTFOUND (""); + return NOTFOUND; } } + void + Appconfig::lifecycle (Symbol event_label) + { + instance().lifecycleHooks_->execute(event_label); + } + + + // ==== implementation LifecycleHook class ======= + + typedef LifecycleRegistry::Hook Callback; + + + LifecycleHook::LifecycleHook (Symbol eventLabel, Callback callbackFun) + { + this->add (eventLabel,callbackFun); + } + + LifecycleHook& + LifecycleHook::add (Symbol eventLabel, Callback callbackFun) + { + Appconfig::instance().lifecycleHooks_->enroll (eventLabel,callbackFun); + + if (!strcmp(ON_BASIC_INIT, eventLabel)) + callbackFun(); // when this code executes, + // then per definition we are already post "basic init" + // (which happens in the Appconfig ctor); thus fire it immediately + return *this; + } + + + } // namespace lumiera + +// ==== implementation C interface ======= + +void +lumiera_LifecycleHook_add (const char* eventLabel, void callbackFun(void)) +{ + lumiera::LifecycleHook (eventLabel, callbackFun); +} + + +void +lumiera_Lifecycle_execute (const char* eventLabel) +{ + lumiera::Appconfig::lifecycle (eventLabel); +} + + +const char* +lumiera_Appconfig_get (const char* key) +{ + return cStr (lumiera::Appconfig::get(key)); +} diff --git a/src/common/appconfig.hpp b/src/common/appconfig.hpp index 984236755..92180fe60 100644 --- a/src/common/appconfig.hpp +++ b/src/common/appconfig.hpp @@ -22,15 +22,18 @@ */ /** @file appconfig.hpp - ** This header is special, as it causes global system initialisation - ** to happen. On inclusion, it places static initialisation code, - ** which on first run will create the Appconfig singleton instance. - ** Additionally, the inclusion, configuration and initialisation - ** of the NoBug library is handled here. Global definitions - ** for NoBug are placed into the corresponding translation unit - ** appconfig.cpp" + ** Registering and managing some application-global services. + ** Besides \link Appconfig::get querying \endlink for some + ** "Application property" constants, there is a mechanism for + ** registering and firing off application lifecycle event hooks. + ** The implementation of some subsystem can define a static instance + ** variable of class LifecycleHook, which will place the provided + ** callback function into a central registry accessable through + ** the Appconfig singleton instance. ** - ** @see nobugcfg.h + ** @see lumiera.cpp + ** @see nobugcfg.cpp + ** @see sessmanagerimpl.cpp */ @@ -40,6 +43,8 @@ #include #include #include +#include +#include "common/lifecycleregistry.hpp" #include "nobugcfg.h" @@ -49,6 +54,7 @@ namespace lumiera { using std::string; using boost::scoped_ptr; + using boost::noncopyable; /** @@ -59,14 +65,14 @@ namespace lumiera * @warning don't use Appconfig in destuctors. */ class Appconfig + : private noncopyable { private: /** perform initialization on first access. - * @see #instance() for Lifecycle */ + * @see #instance() */ Appconfig (); - Appconfig (const Appconfig&); ///< copy prohibited, not implemented - ~Appconfig () throw() {}; ///< deletion prohibited + ~Appconfig () throw() {}; ///< deletion prohibited friend void boost::checked_delete(Appconfig*); @@ -85,24 +91,70 @@ namespace lumiera /** access the configuation value for a given key. * @return empty string for unknown keys, config value else - * @todo do we need such a facility? */ - static const string & get (const string& key) throw(); + static const string & get (const string& key); // never throws + /** fire off all lifecycle callbacks + * registered under the given label */ + static void lifecycle (Symbol eventLabel); + + // note: if necessary, we can add support + // for querying the current lifecycle phase... private: typedef std::map Configmap; - typedef std::auto_ptr PConfig; + typedef scoped_ptr PConfig; + typedef scoped_ptr PLife; - /** @todo the following is just placeholder code! - * Appconfig could do such things if necessary, - * or provide similar "allways available" services. - */ PConfig configParam_; + PLife lifecycleHooks_; + friend class LifecycleHook; + + }; + + + Symbol ON_BASIC_INIT ("ON_BASIC_INIT"); ///< automatic static init. treated specially + Symbol ON_GLOBAL_INIT ("ON_GLOBAL_INIT"); ///< to be triggered in main() @note no magic! + Symbol ON_GLOBAL_SHUTDOWN ("ON_GLOBAL_SHUTDOWN"); ///< to be triggered at the end of main() @note no magic! + + // client code is free to register and use additional lifecycle events + + + /** + * define and register a callback for some lifecycle event. + * The purpose of this class is to be defined as a static variable + * in the implementation of some subsystem (i.e. in the cpp file), + * providing the ctor with the pointer to a callback function. + * Thus the callback gets enrolled when the corresponding object + * file is loaded. The event ON_BASIC_INIT is handled specifically, + * firing off the referred callback function as soon as possible. + * All other lables are just arbitrary (string) constants and it + * is necessary that "someone" cares to fire off the lifcycle events + * at the right place. For example, lumiera-main (and the test runner) + * calls \c Appconfig::instance().execute(ON_GLOBAL_INIT) (and..SHUTDOWN) + */ + class LifecycleHook + : private noncopyable + { + public: + LifecycleHook (Symbol eventLabel, LifecycleRegistry::Hook callbackFun); + + LifecycleHook& add (Symbol eventLabel, LifecycleRegistry::Hook callbackFun); ///< for chained calls (add multiple callbacks) }; } // namespace lumiera + + +extern "C" { //TODO provide a separate header if some C code happens to need this... + + void lumiera_LifecycleHook_add (const char* eventLabel, void callbackFun(void)); + void lumiera_Lifecycle_execute (const char* eventLabel); + const char* lumiera_Appconfig_get (const char* key); + +} + + #endif diff --git a/src/common/lifecycleregistry.hpp b/src/common/lifecycleregistry.hpp new file mode 100644 index 000000000..8b17a33b6 --- /dev/null +++ b/src/common/lifecycleregistry.hpp @@ -0,0 +1,101 @@ +/* + LIFECYCLEREGISTRY.hpp - registry for application lifecycle callbacks + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/** @file lifecycleregistry.hpp + ** Helper for registering lifecycle event callbacks, which are + ** provided as a global service by lumiera::Appconfig. This service + ** allows to enroll functions under a given label and then to call + ** all those registered functions. + ** @note this is in fact an event mechanism, and if we start using + ** more than just this basic functionallity, we should switch to + ** boost::signals. (which has the downside of being an binary + ** dependency). + ** + ** @see appconfig.hpp + */ + + +#ifndef LUMIERA_LIFECYCLE_H +#define LUMIERA_LIFECYCLE_H + +#include +#include +//#include +//#include +#include +#include + + + +namespace lumiera + { +// using std::string; +// using boost::scoped_ptr; + using boost::noncopyable; + using boost::function; + + typedef const char * const Symbol; + + + /** + * Registry of callback functions accessable by a label (ID) + * provided at registration. Registered functions will be added + * to a list, which can be triggered via label. Used by Appconfig + * to implement the lumiera lifecycle (init, shutdown) hooks. + */ + class LifecycleRegistry + : private noncopyable + { + public: + typedef boost::function Hook; + typedef std::vector Callbacks; + typedef Callbacks::iterator Iter; + + + void enroll (Symbol label, Hook& toCall) + { + table_[label].push_back(toCall); + } + + void execute (Symbol label) + { + Callbacks& cbs (table_[label]); + Iter e = cbs.end(); + for (Iter p = cbs.begin(); + p != e; ++p) + (*p)(); // invoke callback + } + + + private: + std::map table_; + + LifecycleRegistry () {} + friend class Appconfig; + + }; + + + +} // namespace lumiera +#endif diff --git a/src/proc/asset.hpp b/src/proc/asset.hpp index ec1c64ef9..2ed5141c8 100644 --- a/src/proc/asset.hpp +++ b/src/proc/asset.hpp @@ -61,7 +61,7 @@ #include #include -#include +#include #include #include diff --git a/src/proc/mobject/session.hpp b/src/proc/mobject/session.hpp index 7b9dfd4ef..d91e5f32a 100644 --- a/src/proc/mobject/session.hpp +++ b/src/proc/mobject/session.hpp @@ -37,7 +37,7 @@ #include "proc/mobject/session/defsmanager.hpp" #include "common/singleton.hpp" -#include +#include #include diff --git a/tests/50components.tests b/tests/50components.tests index 63e97cf9a..2bac409cb 100644 --- a/tests/50components.tests +++ b/tests/50components.tests @@ -107,6 +107,11 @@ out: dtor ~TargetObj(12) successfull END +TEST "LifeCycle_test" LifeCycle_test < [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ] out: removed 0 ---> [ 1, 2, 3, 4, 5, 6, 7, 8, 9, ] diff --git a/tests/common/appconfigtest.cpp b/tests/common/appconfigtest.cpp index 6cab57de8..215c8c46c 100644 --- a/tests/common/appconfigtest.cpp +++ b/tests/common/appconfigtest.cpp @@ -1,5 +1,5 @@ /* - Appconfig(Test) - accessing the allwasy-available Appconfig singleton + Appconfig(Test) - accessing the allways-available Appconfig singleton Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -28,9 +28,6 @@ #include "common/util.hpp" -#include -using std::cout; - namespace lumiera diff --git a/tests/common/lifecycletest.cpp b/tests/common/lifecycletest.cpp new file mode 100644 index 000000000..5e5a779a1 --- /dev/null +++ b/tests/common/lifecycletest.cpp @@ -0,0 +1,78 @@ +/* + LifeCycle(Test) - checking the lifecycle callback hooks provided by Appconfig + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + + + +#include "common/appconfig.hpp" + +#include "common/test/run.hpp" +#include "common/util.hpp" + + + + +namespace lumiera + { + namespace test + { + + bool basicInit (false); + bool customCallback (false); + + void basicInitHook () { basicInit = true; } + void myCallback() { customCallback = true; } + + Symbol MY_MAGIC_MEGA_EVENT = "dial M for murder"; + + + namespace // register them to be invoced by lifecycle event id + { + LifecycleHook _schedule1 (ON_BASIC_INIT, &basicInitHook); + LifecycleHook _schedule2 (MY_MAGIC_MEGA_EVENT, &myCallback); + } + + + /** @test the global lifecycle hooks got registered, + * the ON_BASIC_INIT hook has been already called, + * while our custom callback can be trigged at our will + */ + class LifeCycle_test : public Test + { + virtual void + run (Arg arg) + { + ASSERT (basicInit, "the basic-init callback hasn't been invoked automatically"); + + ASSERT (!customCallback); + Appconfig::lifecycle (MY_MAGIC_MEGA_EVENT); + ASSERT ( customCallback); + } + + }; + + LAUNCHER (LifeCycle_test, "function common"); + + + } // namespace test + +} // namespace util + From 3e8996005e6b9525e7ee8642607927e89d740d7f Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 14 Apr 2008 05:15:16 +0200 Subject: [PATCH 36/36] start using the new lifecycle hooks. remove global nobugcfg.h Now using proc/lumiera.hpp and proc/nobugcfg.hpp (i.e. only for the proc-Layer). Using ON_BASIC_INIT to pull up NoBug automatically and for installing the unknown-exception handler. Add calls for ON_GLOBAL_INIT and ON_GLOBAL_SHUTDOWN hooks to main() and to the testrunner --- src/common/cmdline.cpp | 2 +- src/common/configrules.cpp | 2 +- src/common/error.cpp | 5 +++ src/common/error.hpp | 10 ++++- src/common/multithread.hpp | 2 +- src/common/query.cpp | 2 +- src/common/query/mockconfigrules.cpp | 2 +- src/common/singletonfactory.hpp | 2 +- src/common/test/run.hpp | 2 +- src/common/test/suite.cpp | 2 +- src/common/test/testoption.cpp | 1 - src/{common => lib}/appconfig.cpp | 36 +++++++----------- src/{common => lib}/appconfig.hpp | 23 +++++------- src/{common => lib}/lifecycleregistry.hpp | 27 ++++++++------ src/main.cpp | 12 +++++- src/pre.hpp | 2 +- src/pre_a.hpp | 2 +- src/proc/asset/category.cpp | 2 +- src/proc/asset/media.cpp | 2 +- src/proc/asset/meta.cpp | 2 +- src/proc/asset/proc.cpp | 2 +- src/proc/asset/struct.cpp | 2 +- src/proc/engine/processor.hpp | 2 +- src/{lumiera.h => proc/lumiera.hpp} | 26 ++----------- src/proc/mobject/mobject.hpp | 2 +- src/proc/mobject/session/fixture.cpp | 2 +- src/proc/mobject/session/locatingpin.hpp | 2 +- src/proc/mobject/session/segment.hpp | 2 +- src/proc/nobugcfg.cpp | 45 +++++++++++++++++++++++ src/{nobugcfg.h => proc/nobugcfg.hpp} | 44 ++++++++++------------ tests/common/appconfigtest.cpp | 4 +- tests/common/exceptionerrortest.cpp | 9 ++--- tests/common/lifecycletest.cpp | 15 ++++---- tests/common/mainsuite.cpp | 9 +++++ 34 files changed, 171 insertions(+), 135 deletions(-) rename src/{common => lib}/appconfig.cpp (76%) rename src/{common => lib}/appconfig.hpp (87%) rename src/{common => lib}/lifecycleregistry.hpp (78%) rename src/{lumiera.h => proc/lumiera.hpp} (68%) create mode 100644 src/proc/nobugcfg.cpp rename src/{nobugcfg.h => proc/nobugcfg.hpp} (74%) diff --git a/src/common/cmdline.cpp b/src/common/cmdline.cpp index bf00cf2b2..1e8e1849f 100644 --- a/src/common/cmdline.cpp +++ b/src/common/cmdline.cpp @@ -24,7 +24,7 @@ #include "common/cmdline.hpp" #include "common/util.hpp" -#include "nobugcfg.h" +#include "proc/nobugcfg.hpp" #include #include diff --git a/src/common/configrules.cpp b/src/common/configrules.cpp index 3a1ae1bdd..02a0bfcb6 100644 --- a/src/common/configrules.cpp +++ b/src/common/configrules.cpp @@ -24,7 +24,7 @@ #include "common/configrules.hpp" #include "common/query/mockconfigrules.hpp" //#include "common/util.hpp" -#include "nobugcfg.h" +#include "proc/nobugcfg.hpp" diff --git a/src/common/error.cpp b/src/common/error.cpp index e708c5d3a..d27e60904 100644 --- a/src/common/error.cpp +++ b/src/common/error.cpp @@ -189,6 +189,11 @@ namespace lumiera } + void install_unexpectedException_handler () + { + std::set_unexpected (lumiera_unexpectedException); + } + } // namespace error } // namespace lumiera diff --git a/src/common/error.hpp b/src/common/error.hpp index 71e5f79dc..687425ec2 100644 --- a/src/common/error.hpp +++ b/src/common/error.hpp @@ -25,7 +25,7 @@ #define LUMIERA_ERROR_HPP_ #include -#include "nobugcfg.h" +#include "proc/nobugcfg.hpp" #include "lib/error.h" @@ -150,6 +150,14 @@ namespace lumiera LUMIERA_EXCEPTION_DECLARE (External, Error, LUMIERA_ERROR_EXTERNAL); + /** install our own handler for undeclared exceptions. Will be + * called automatically ON_BASIC_INIT when including errror.hpp + * @see appconfig.hpp */ + void install_unexpectedException_handler (); + namespace { + LifecycleHook schedule_ (ON_BASIC_INIT, &install_unexpectedException_handler); + } + } // namespace error } // namespace lumiera diff --git a/src/common/multithread.hpp b/src/common/multithread.hpp index 0e936964c..8cdbe8002 100644 --- a/src/common/multithread.hpp +++ b/src/common/multithread.hpp @@ -26,7 +26,7 @@ #ifndef LUMIERA_MULTITHREAD_H #define LUMIERA_MULTITHREAD_H -#include "nobugcfg.h" +#include "proc/nobugcfg.hpp" #include "common/util.hpp" diff --git a/src/common/query.cpp b/src/common/query.cpp index 67873a5e8..255061476 100644 --- a/src/common/query.cpp +++ b/src/common/query.cpp @@ -23,7 +23,7 @@ #include "common/query.hpp" #include "common/util.hpp" -#include "nobugcfg.h" +#include "proc/nobugcfg.hpp" #include #include diff --git a/src/common/query/mockconfigrules.cpp b/src/common/query/mockconfigrules.cpp index c8b9f774b..0ae7f29ed 100644 --- a/src/common/query/mockconfigrules.cpp +++ b/src/common/query/mockconfigrules.cpp @@ -28,8 +28,8 @@ #include "proc/asset/pipe.hpp" +#include "proc/nobugcfg.hpp" #include "common/util.hpp" -#include "nobugcfg.h" using util::isnil; diff --git a/src/common/singletonfactory.hpp b/src/common/singletonfactory.hpp index 9fdf21d21..0065227df 100644 --- a/src/common/singletonfactory.hpp +++ b/src/common/singletonfactory.hpp @@ -38,7 +38,7 @@ This code is heavily inspired by #include "common/singletonpolicies.hpp" ///< several Policies usable together with SingletonFactory #include "common/util.hpp" -#include "nobugcfg.h" +#include "proc/nobugcfg.hpp" diff --git a/src/common/test/run.hpp b/src/common/test/run.hpp index 529896d0b..b1dbd08b6 100644 --- a/src/common/test/run.hpp +++ b/src/common/test/run.hpp @@ -28,7 +28,7 @@ #include "pre.hpp" -#include "nobugcfg.h" +#include "proc/nobugcfg.hpp" #include "common/test/suite.hpp" #include "common/util.hpp" diff --git a/src/common/test/suite.cpp b/src/common/test/suite.cpp index 897a7d04f..37a303ef6 100644 --- a/src/common/test/suite.cpp +++ b/src/common/test/suite.cpp @@ -30,7 +30,7 @@ #include #include -#include "nobugcfg.h" +#include "proc/nobugcfg.hpp" #include "common/cmdline.hpp" #include "common/test/suite.hpp" #include "common/test/run.hpp" diff --git a/src/common/test/testoption.cpp b/src/common/test/testoption.cpp index 8b1199887..c591e895d 100644 --- a/src/common/test/testoption.cpp +++ b/src/common/test/testoption.cpp @@ -24,7 +24,6 @@ #include "common/test/testoption.hpp" #include "common/test/suite.hpp" -#include "nobugcfg.h" #include "common/error.hpp" diff --git a/src/common/appconfig.cpp b/src/lib/appconfig.cpp similarity index 76% rename from src/common/appconfig.cpp rename to src/lib/appconfig.cpp index b708d42d0..ad114fb56 100644 --- a/src/common/appconfig.cpp +++ b/src/lib/appconfig.cpp @@ -2,7 +2,7 @@ Appconfig - for global initialization and configuration Copyright (C) Lumiera.org - 2008, Christian Thaeter + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -21,16 +21,10 @@ * *****************************************************/ -#include "common/appconfig.hpp" +#include "lib/appconfig.hpp" #include "common/error.hpp" #include "common/util.hpp" -#define NOBUG_INIT_DEFS_ -#include "nobugcfg.h" -#undef NOBUG_INIT_DEFS_ - -#include - using util::isnil; using util::cStr; @@ -43,6 +37,10 @@ namespace lumiera #define LUMIERA_VERSION 0++devel #endif + Symbol ON_BASIC_INIT ("ON_BASIC_INIT"); + Symbol ON_GLOBAL_INIT ("ON_GLOBAL_INIT"); + Symbol ON_GLOBAL_SHUTDOWN ("ON_GLOBAL_SHUTDOWN"); + /** perform initialization triggered on first access. * Will execute the ON_BASIC_INIT hook, but under typical @@ -50,24 +48,16 @@ namespace lumiera * added to this hook, the Appconfig singleton instance has * already been created. For this reason, there is special * treatment for the ON_BASIC_INIT in LifecycleHook::add, - * causing the provided callbacks being fired immediately. - * (btw, this is nothing to be worried of, for the client - * code it just behaves like intended). + * causing the provided callbacks to be fired immediately. + * (btw, this is nothing to be worried of, because from + * client codes POV it just behaves like intended). */ Appconfig::Appconfig() : configParam_ (new Configmap), lifecycleHooks_(new LifecycleRegistry) { - ////////// - NOBUG_INIT; - ////////// - - INFO(config, "Basic application configuration triggered."); lifecycleHooks_->execute (ON_BASIC_INIT); // note in most cases a NOP - // install our own handler for undeclared exceptions - std::set_unexpected (lumiera::error::lumiera_unexpectedException); - (*configParam_)["version"] = STRINGIFY (LUMIERA_VERSION); } @@ -81,12 +71,12 @@ namespace lumiera try { const string& val = (*instance().configParam_)[key]; - WARN_IF( isnil(val), config, "undefined config parameter \"%s\" requested.", key.c_str()); + WARN_IF ( isnil(val), config, "undefined config parameter \"%s\" requested.", key.c_str()); return val; } catch (...) { - ERROR(config, "error while accessing configuration parameter \"%s\".", key.c_str()); + ERROR (config, "error while accessing configuration parameter \"%s\".", key.c_str()); static string NOTFOUND (""); return NOTFOUND; } } @@ -114,9 +104,9 @@ namespace lumiera LifecycleHook& LifecycleHook::add (Symbol eventLabel, Callback callbackFun) { - Appconfig::instance().lifecycleHooks_->enroll (eventLabel,callbackFun); + bool isNew = Appconfig::instance().lifecycleHooks_->enroll (eventLabel,callbackFun); - if (!strcmp(ON_BASIC_INIT, eventLabel)) + if (isNew && !strcmp(ON_BASIC_INIT, eventLabel)) callbackFun(); // when this code executes, // then per definition we are already post "basic init" // (which happens in the Appconfig ctor); thus fire it immediately diff --git a/src/common/appconfig.hpp b/src/lib/appconfig.hpp similarity index 87% rename from src/common/appconfig.hpp rename to src/lib/appconfig.hpp index 92180fe60..b82c3fa2b 100644 --- a/src/common/appconfig.hpp +++ b/src/lib/appconfig.hpp @@ -2,8 +2,7 @@ APPCONFIG.hpp - for global initialization and configuration Copyright (C) Lumiera.org - 2008, Christian Thaeter - Hermann Vosseler + 2008, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -44,9 +43,7 @@ #include #include #include -#include "common/lifecycleregistry.hpp" - -#include "nobugcfg.h" +#include "lib/lifecycleregistry.hpp" @@ -69,7 +66,8 @@ namespace lumiera { private: /** perform initialization on first access. - * @see #instance() */ + * @see #instance() + */ Appconfig (); ~Appconfig () throw() {}; ///< deletion prohibited @@ -79,7 +77,7 @@ namespace lumiera public: /** get the (single) Appconfig instance. * Implemented as Meyers singleton. - * @warning don't use it in destruction code! + * @warning don't use it after the end of main()! */ static Appconfig& instance() { @@ -90,12 +88,11 @@ namespace lumiera /** access the configuation value for a given key. - * @return empty string for unknown keys, config value else - */ + * @return empty string for unknown keys, config value else */ static const string & get (const string& key); // never throws /** fire off all lifecycle callbacks - * registered under the given label */ + * registered under the given label */ static void lifecycle (Symbol eventLabel); // note: if necessary, we can add support @@ -114,9 +111,9 @@ namespace lumiera }; - Symbol ON_BASIC_INIT ("ON_BASIC_INIT"); ///< automatic static init. treated specially - Symbol ON_GLOBAL_INIT ("ON_GLOBAL_INIT"); ///< to be triggered in main() @note no magic! - Symbol ON_GLOBAL_SHUTDOWN ("ON_GLOBAL_SHUTDOWN"); ///< to be triggered at the end of main() @note no magic! + extern Symbol ON_BASIC_INIT; ///< automatic static init. treated specially + extern Symbol ON_GLOBAL_INIT; ///< to be triggered in main() @note no magic! + extern Symbol ON_GLOBAL_SHUTDOWN; ///< to be triggered at the end of main() @note no magic! // client code is free to register and use additional lifecycle events diff --git a/src/common/lifecycleregistry.hpp b/src/lib/lifecycleregistry.hpp similarity index 78% rename from src/common/lifecycleregistry.hpp rename to src/lib/lifecycleregistry.hpp index 8b17a33b6..285c95fac 100644 --- a/src/common/lifecycleregistry.hpp +++ b/src/lib/lifecycleregistry.hpp @@ -39,22 +39,23 @@ #define LUMIERA_LIFECYCLE_H #include -#include -//#include -//#include +#include +#include #include #include +#include "common/util.hpp" namespace lumiera { -// using std::string; -// using boost::scoped_ptr; using boost::noncopyable; using boost::function; + using util::contains; + using std::string; - typedef const char * const Symbol; + typedef const char * const Symbol; //TODO define a real Symbol class, i.e. same literal string==same pointer, + // so we don't have to store string keys in the map... /** @@ -67,17 +68,19 @@ namespace lumiera : private noncopyable { public: - typedef boost::function Hook; - typedef std::vector Callbacks; + typedef void (*Hook)(void); + typedef std::set Callbacks; typedef Callbacks::iterator Iter; - void enroll (Symbol label, Hook& toCall) + bool enroll (const string label, Hook toCall) { - table_[label].push_back(toCall); + return table_[label] + .insert(toCall) + .second; // true if actually stored } - void execute (Symbol label) + void execute (const string label) { Callbacks& cbs (table_[label]); Iter e = cbs.end(); @@ -88,7 +91,7 @@ namespace lumiera private: - std::map table_; + std::map table_; LifecycleRegistry () {} friend class Appconfig; diff --git a/src/main.cpp b/src/main.cpp index 398cdc3df..0e04ef89f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,16 +23,24 @@ #include -#include "lumiera.h" +#include "proc/lumiera.hpp" using std::cout; using std::endl; using lumiera::Appconfig; +using lumiera::ON_GLOBAL_INIT; +using lumiera::ON_GLOBAL_SHUTDOWN; int main (int argc, char* argv[]) { cout << "*** Lumiera NLE for Linux ***" << endl - << " Version: " << Appconfig::get("version") << endl; + << " Version: " << Appconfig::get("version") << "\n"; + + Appconfig::lifecycle (ON_GLOBAL_INIT); + + // great things are happening here.... + + Appconfig::lifecycle (ON_GLOBAL_SHUTDOWN); return 0; } diff --git a/src/pre.hpp b/src/pre.hpp index 203613c3d..ca948b7d6 100644 --- a/src/pre.hpp +++ b/src/pre.hpp @@ -45,7 +45,7 @@ #include #include -#include "lumiera.h" +#include "proc/lumiera.hpp" diff --git a/src/pre_a.hpp b/src/pre_a.hpp index 34a8e72f2..6174b83e8 100644 --- a/src/pre_a.hpp +++ b/src/pre_a.hpp @@ -42,7 +42,7 @@ #include #include -#include "lumiera.h" +#include "proc/lumiera.hpp" #include "proc/asset.hpp" diff --git a/src/proc/asset/category.cpp b/src/proc/asset/category.cpp index 490f1f0d6..dcb767ccf 100644 --- a/src/proc/asset/category.cpp +++ b/src/proc/asset/category.cpp @@ -23,7 +23,7 @@ #include "proc/asset/category.hpp" #include "common/util.hpp" -#include "nobugcfg.h" +#include "proc/nobugcfg.hpp" #include diff --git a/src/proc/asset/media.cpp b/src/proc/asset/media.cpp index 477ac4d9d..a91e8284b 100644 --- a/src/proc/asset/media.cpp +++ b/src/proc/asset/media.cpp @@ -29,7 +29,7 @@ #include "proc/mobject/session/clip.hpp" #include "proc/mobject/session/mobjectfactory.hpp" #include "common/util.hpp" -#include "nobugcfg.h" +#include "proc/nobugcfg.hpp" #include #include diff --git a/src/proc/asset/meta.cpp b/src/proc/asset/meta.cpp index bdfd1c411..ec58b493c 100644 --- a/src/proc/asset/meta.cpp +++ b/src/proc/asset/meta.cpp @@ -24,7 +24,7 @@ #include "proc/assetmanager.hpp" #include "proc/asset/meta.hpp" #include "common/util.hpp" -#include "nobugcfg.h" +#include "proc/nobugcfg.hpp" namespace asset diff --git a/src/proc/asset/proc.cpp b/src/proc/asset/proc.cpp index 87aa48da6..3720f0993 100644 --- a/src/proc/asset/proc.cpp +++ b/src/proc/asset/proc.cpp @@ -24,7 +24,7 @@ #include "proc/assetmanager.hpp" #include "proc/asset/proc.hpp" #include "common/util.hpp" -#include "nobugcfg.h" +#include "proc/nobugcfg.hpp" namespace asset diff --git a/src/proc/asset/struct.cpp b/src/proc/asset/struct.cpp index 10eaf15ef..6e85c50c2 100644 --- a/src/proc/asset/struct.cpp +++ b/src/proc/asset/struct.cpp @@ -31,7 +31,7 @@ #include "proc/asset/structfactoryimpl.hpp" #include "common/util.hpp" -#include "nobugcfg.h" +#include "proc/nobugcfg.hpp" #include diff --git a/src/proc/engine/processor.hpp b/src/proc/engine/processor.hpp index 6b7317886..164fa8bfa 100644 --- a/src/proc/engine/processor.hpp +++ b/src/proc/engine/processor.hpp @@ -24,7 +24,7 @@ #ifndef ENGINE_PROCESSOR_H #define ENGINE_PROCESSOR_H -#include "lumiera.h" +#include "proc/lumiera.hpp" #include "proc/stateproxy.hpp" diff --git a/src/lumiera.h b/src/proc/lumiera.hpp similarity index 68% rename from src/lumiera.h rename to src/proc/lumiera.hpp index 12b1578b9..b56ab69b6 100644 --- a/src/lumiera.h +++ b/src/proc/lumiera.hpp @@ -1,5 +1,5 @@ /* - LUMIERA.h - global definitions and common types + LUMIERA.hpp - global definitions and common types for the Proc-Layer Copyright (C) Lumiera.org @@ -27,31 +27,13 @@ -#ifdef __cplusplus -extern "C" { -#endif /* ========================== common C Part ============ */ - - -#ifdef __cplusplus -} -#endif /* ==================== (End) common C Part ============ */ - - - - - -#ifndef __cplusplus -#include "nobugcfg.h" - -#else /* ========================== C++-Part ================= */ - /* common types frequently used... */ #include "common/util.hpp" #include "common/time.hpp" -#include "common/appconfig.hpp" // includes NoBug via "nobugcfg.h" -#include "common/error.hpp" +#include "common/error.hpp" ///< pulls in NoBug via nobugcfg.hpp +#include "lib/appconfig.hpp" namespace lumiera @@ -61,6 +43,4 @@ namespace lumiera } // namespace lumiera -#endif /* ===================== (End) C++-Part ================= */ - #endif /*LUMIERA_H*/ diff --git a/src/proc/mobject/mobject.hpp b/src/proc/mobject/mobject.hpp index 3d0222a3d..a8c02c761 100644 --- a/src/proc/mobject/mobject.hpp +++ b/src/proc/mobject/mobject.hpp @@ -29,7 +29,7 @@ #include #include -#include "lumiera.h" +#include "proc/lumiera.hpp" #include "proc/mobject/builder/buildertool.hpp" #include "proc/mobject/placement.hpp" #include "proc/asset.hpp" // TODO finally not needed? diff --git a/src/proc/mobject/session/fixture.cpp b/src/proc/mobject/session/fixture.cpp index bdad3f807..19ba84970 100644 --- a/src/proc/mobject/session/fixture.cpp +++ b/src/proc/mobject/session/fixture.cpp @@ -22,7 +22,7 @@ #include "proc/mobject/session/fixture.hpp" -#include "nobugcfg.h" +#include "proc/nobugcfg.hpp" namespace mobject { diff --git a/src/proc/mobject/session/locatingpin.hpp b/src/proc/mobject/session/locatingpin.hpp index 009778eb3..f978d4f4e 100644 --- a/src/proc/mobject/session/locatingpin.hpp +++ b/src/proc/mobject/session/locatingpin.hpp @@ -42,7 +42,7 @@ #define MOBJECT_SESSION_LOCATINGPIN_H -#include "lumiera.h" +#include "proc/lumiera.hpp" #include #include diff --git a/src/proc/mobject/session/segment.hpp b/src/proc/mobject/session/segment.hpp index 0b8a6025b..4d978f810 100644 --- a/src/proc/mobject/session/segment.hpp +++ b/src/proc/mobject/session/segment.hpp @@ -26,7 +26,7 @@ #include -#include "lumiera.h" +#include "proc/lumiera.hpp" #include "proc/mobject/explicitplacement.hpp" diff --git a/src/proc/nobugcfg.cpp b/src/proc/nobugcfg.cpp new file mode 100644 index 000000000..7dc68a9bb --- /dev/null +++ b/src/proc/nobugcfg.cpp @@ -0,0 +1,45 @@ +/* + NoBugCfg - NoBug definitions and initialisation for the Proc-Layer + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + + +#include "proc/nobugcfg.hpp" + +#define NOBUG_INIT_DEFS_ +#include "proc/nobugcfg.hpp" +#undef NOBUG_INIT_DEFS_ + + +namespace lumiera + { + void + initialize_NoBug () + { + NOBUG_INIT; + +#ifdef DEBUG + static uint callCount = 0; + ASSERT ( 0 == callCount++ ); +#endif + } + +} + diff --git a/src/nobugcfg.h b/src/proc/nobugcfg.hpp similarity index 74% rename from src/nobugcfg.h rename to src/proc/nobugcfg.hpp index 916f28663..567838320 100644 --- a/src/nobugcfg.h +++ b/src/proc/nobugcfg.hpp @@ -1,5 +1,5 @@ /* - NOBUGCFG.h - global configuration and definitions for NoBug + NOBUGCFG.hpp - NoBug definitions and initialisation for the Proc-Layer Copyright (C) Lumiera.org @@ -22,17 +22,20 @@ */ -/** @file nobugcfg.h +/** @file nobugcfg.hpp ** This header is for including and configuring NoBug. ** The idea is that configuration and some globally used flag ** declarations are to be kept in one central location. Normally, - ** this header will be included by appconfig.hpp, which in turn gets - ** included by lumiera.h + ** this header will be included via some of the basic headers like + ** error.hpp, which in turn gets included by proc/lumiera.hpp + ** ** @par Besides the usual guarded declarations, this header contains ** one section with the corresponding definitions. This section - ** is to be called by appconfig.cpp only, which deals with application - ** wide configuration values contained in the Singleton class Appconfig. - ** Incidentally, the constructor of Appconfig issues the NOBUG_INIT call + ** is to be included once by some translation unit (currently this is + ** nobugcfg.cpp) in order to generate the necessary definitions. + ** + ** @note this header assures automatic initialisation of NoBug + ** by placing a static ctor call. ** */ @@ -41,10 +44,9 @@ #define NOBUGCFG_H #include - - /* configuration of NoBug goes here... */ - #include +#include "lib/appconfig.hpp" +#include "common/error.hpp" ///< make assertions throw instead of abort() /* declare flags used throughout the code base... */ @@ -54,8 +56,13 @@ NOBUG_DECLARE_FLAG(singleton); NOBUG_DECLARE_FLAG(assetmem); NOBUG_DECLARE_FLAG(mobjectmem); - - + + +namespace lumiera { + void initialize_NoBug (); + namespace { + LifecycleHook schedule_ (ON_BASIC_INIT, &initialize_NoBug); +} } #endif /*NOBUGCFG_H ======= (End) Part 1: DECLARATIONS ======== */ @@ -65,15 +72,6 @@ #ifdef NOBUG_INIT_DEFS_ /*========== Part 2: DEFINITIONS ========= */ -/* ================================= common C Part ========= */ - - - - - - -#ifdef __cplusplus /* ============== C++-Part ============== */ - /* flags used throughout the code base... */ NOBUG_CPP_DEFINE_FLAG(config); @@ -83,11 +81,7 @@ NOBUG_CPP_DEFINE_FLAG_LIMIT(assetmem, LOG_WARNING); NOBUG_CPP_DEFINE_FLAG_LIMIT(mobjectmem, LOG_WARNING); -#include "common/error.hpp" -#endif /* ===================== (End) C++-Part ============= */ - - #endif /*NOBUG_INIT_DEFS_ ==== (End) Part 2: DEFINITIONS ========= */ diff --git a/tests/common/appconfigtest.cpp b/tests/common/appconfigtest.cpp index 215c8c46c..c51b413bc 100644 --- a/tests/common/appconfigtest.cpp +++ b/tests/common/appconfigtest.cpp @@ -22,11 +22,11 @@ -#include "common/appconfig.hpp" - #include "common/test/run.hpp" #include "common/util.hpp" +#include "lib/appconfig.hpp" + diff --git a/tests/common/exceptionerrortest.cpp b/tests/common/exceptionerrortest.cpp index 75a13d0ee..6bc97afbb 100644 --- a/tests/common/exceptionerrortest.cpp +++ b/tests/common/exceptionerrortest.cpp @@ -24,7 +24,6 @@ #include "lib/error.h" #include "common/error.hpp" -#include "common/appconfig.hpp" #include "common/test/run.hpp" #include "common/util.hpp" @@ -182,13 +181,11 @@ namespace lumiera /** @test terminate the Application by throwing an undclared exception. * this should result in the global unknown() handler to be called, * so usually it will terminate the testrun. - * @note because we call Appconfig::instance(), our own unknown() handler - * gets installed and invoked, which gives additional diagnostics.*/ + * @note inside error.hpp, an initialisation hook has been installed into + * Appconfig, causing our own unknown() handler to be installed and + * invoked, which gives additional diagnostics.*/ void terminateUnknown () throw() { - lumiera::Appconfig::instance(); - // will cause initialisation of Appconfig, - throw Error("You'll never get me, won't you?"); } diff --git a/tests/common/lifecycletest.cpp b/tests/common/lifecycletest.cpp index 5e5a779a1..21a33dce5 100644 --- a/tests/common/lifecycletest.cpp +++ b/tests/common/lifecycletest.cpp @@ -22,11 +22,11 @@ -#include "common/appconfig.hpp" - #include "common/test/run.hpp" #include "common/util.hpp" +#include "lib/appconfig.hpp" + @@ -35,11 +35,11 @@ namespace lumiera namespace test { - bool basicInit (false); - bool customCallback (false); + uint basicInit (0); + uint customCallback (0); - void basicInitHook () { basicInit = true; } - void myCallback() { customCallback = true; } + void basicInitHook () { ++basicInit; } + void myCallback() { ++customCallback; } Symbol MY_MAGIC_MEGA_EVENT = "dial M for murder"; @@ -61,10 +61,11 @@ namespace lumiera run (Arg arg) { ASSERT (basicInit, "the basic-init callback hasn't been invoked automatically"); + ASSERT (1 == basicInit, "the basic-init callback has been invoked more than once"); ASSERT (!customCallback); Appconfig::lifecycle (MY_MAGIC_MEGA_EVENT); - ASSERT ( customCallback); + ASSERT ( 1 == customCallback); } }; diff --git a/tests/common/mainsuite.cpp b/tests/common/mainsuite.cpp index aa500cdbe..3ef740744 100644 --- a/tests/common/mainsuite.cpp +++ b/tests/common/mainsuite.cpp @@ -23,6 +23,12 @@ #include "common/test/suite.hpp" #include "common/test/testoption.hpp" +#include "lib/appconfig.hpp" + +using lumiera::Appconfig; +using lumiera::ON_GLOBAL_INIT; +using lumiera::ON_GLOBAL_SHUTDOWN; + /** run all tests or any single test specified in the first * cmd line argument. @@ -33,10 +39,13 @@ int main (int argc, char* argv[]) util::Cmdline args (argc,argv); test::TestOption optparser (args); test::Suite suite (optparser.getTestgroup()); + Appconfig::lifecycle(ON_GLOBAL_INIT); if (optparser.getDescribe()) suite.describe(); else suite.run (args); + + Appconfig::lifecycle(ON_GLOBAL_SHUTDOWN); return 0; }