summaryrefslogtreecommitdiff
path: root/torrus/templates
diff options
context:
space:
mode:
Diffstat (limited to 'torrus/templates')
-rw-r--r--torrus/templates/aclexport.xml40
-rw-r--r--torrus/templates/adminfo.html38
-rw-r--r--torrus/templates/default-chooser.html37
-rw-r--r--torrus/templates/default-dir.html74
-rw-r--r--torrus/templates/default-helptext.html39
-rw-r--r--torrus/templates/default-login.html59
-rw-r--r--torrus/templates/default-recursivedir.html52
-rw-r--r--torrus/templates/default-rrd.html134
-rw-r--r--torrus/templates/default-tset.html56
-rw-r--r--torrus/templates/email-alarm.txt27
-rw-r--r--torrus/templates/expanded-dir.html52
-rw-r--r--torrus/templates/globalsearch.html43
-rw-r--r--torrus/templates/html-incblocks.txt356
-rw-r--r--torrus/templates/overview-subleaves.html47
-rw-r--r--torrus/templates/report-index.html29
-rw-r--r--torrus/templates/report-monthly.html132
-rw-r--r--torrus/templates/report-serviceid.html147
-rw-r--r--torrus/templates/report-yearly.html31
-rw-r--r--torrus/templates/search.html43
-rw-r--r--torrus/templates/tset-list.html38
20 files changed, 1474 insertions, 0 deletions
diff --git a/torrus/templates/aclexport.xml b/torrus/templates/aclexport.xml
new file mode 100644
index 000000000..b27b4d373
--- /dev/null
+++ b/torrus/templates/aclexport.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+
+<!-- Torrus Access Control Lists export -->
+
+<aclexport>
+ <file-info>
+ <format-version>1.1</format-version>
+ </file-info>
+
+ <groups>
+ [% FOREACH group = groups() %]
+ <group name="[% group %]">
+ [% privhash = privileges(group);
+ FOREACH object = privhash.keys.sort;
+ FOREACH priv = privhash.$object.keys.sort %]
+ <privilege object="[% object %]" name="[% priv %]"/>
+ [% END;
+ END;
+ FOREACH attr = gattrlist(group); %]
+ <attribute name="[% attr %]" value="[% xmlnorm(gattr(group, attr)) %]"/>
+ [% END; %]
+ </group>
+ [% END %]
+ </groups>
+
+ <users>
+ [% FOREACH uid = users() %]
+ <user uid="[% uid %]">
+ [% FOREACH group = memberof(uid) %]
+ <member-of group="[% group %]"/>
+ [% END;
+ FOREACH attr = uattrlist(uid);
+ IF attr != 'uid' %]
+ <attribute name="[% attr %]" value="[% xmlnorm(uattr(uid, attr)) %]"/>
+ [% END;
+ END %]
+ </user>
+ [% END %]
+ </users>
+</aclexport>
diff --git a/torrus/templates/adminfo.html b/torrus/templates/adminfo.html
new file mode 100644
index 000000000..a041e0033
--- /dev/null
+++ b/torrus/templates/adminfo.html
@@ -0,0 +1,38 @@
+[% PROCESS 'html-incblocks.txt' %]
+[% INCLUDE htmlstart
+ title='Administrative information: ' _ path(token)
+ contentClass="SingleColumnContent"
+ noTopMenu=1 %]
+
+<H1>Administrative information</H1>
+[% INCLUDE treename %]
+<P>Path: [% path(token) %]</P>
+
+[%
+FOREACH category = adminfo.keys.sort;
+%]
+<H2>[% category %]</H2>
+<DIV CLASS="Listing">
+[%
+ counter = 0;
+ evenRow = 0;
+
+ FOREACH pname = adminfo.$category.keys.sort;
+ counter = counter + 1;
+ IF counter % 2 == 0;
+ evenRow = 1;
+ ELSE;
+ evenRow = 0;
+ END;
+%]
+ <DIV CLASS="[% evenRow ? 'ListRowEven' : 'ListRow' %]">
+ <SPAN CLASS="NodeName">[% pname %]</SPAN>
+ <SPAN CLASS="NodeDescr">[% adminfo.$category.$pname %]</SPAN>
+ </SPAN>
+ </DIV>
+[% END %]
+</DIV>
+[%
+END %]
+
+[% INCLUDE htmlend %]
diff --git a/torrus/templates/default-chooser.html b/torrus/templates/default-chooser.html
new file mode 100644
index 000000000..f49b7899f
--- /dev/null
+++ b/torrus/templates/default-chooser.html
@@ -0,0 +1,37 @@
+[% PROCESS 'html-incblocks.txt' %]
+[% INCLUDE htmlstart
+ title="Torrus Top: " _ companyName
+ contentClass="SingleColumnContent"
+ noTopMenu=1 %]
+
+<P>Choose the datasource tree</P>
+
+<DIV CLASS="Listing">
+[% counter = 0;
+ evenRow = 0;
+
+ FOREACH tree = treeNames();
+
+ IF not userAuth or mayDisplayTree(tree);
+ counter = counter + 1;
+
+ IF counter % 2 == 0;
+ evenRow = 1;
+ ELSE;
+ evenRow = 0;
+ END;
+%]
+
+ <DIV CLASS="[% evenRow ? 'ListRowEven' : 'ListRow' %]">
+ <SPAN CLASS="NodeName"><A HREF="[%url(tree)%]">[% tree %]</A></SPAN>
+ <SPAN CLASS="NodeDescr">[% xmlnorm(treeDescr(tree)) %]</SPAN>
+ </DIV>
+ [% END %]
+[% END %]
+</DIV>
+
+</DIV><!-- Content -->[% global.contentFinished = 1 %]
+<DIV CLASS="BottomMenu">
+[% INCLUDE globalsearchdialog %]
+</DIV>
+[% INCLUDE htmlend %]
diff --git a/torrus/templates/default-dir.html b/torrus/templates/default-dir.html
new file mode 100644
index 000000000..ef6358d1e
--- /dev/null
+++ b/torrus/templates/default-dir.html
@@ -0,0 +1,74 @@
+[% PROCESS 'html-incblocks.txt' %]
+[% thepath=path(token) %]
+[% INCLUDE htmlstart title=thepath printpath=1 %]
+
+<H1>[% xmlnorm(nodeParam(token,'comment')) %]</H1>
+
+[% INCLUDE legend %]
+
+<P>Directories you can jump to:</P>
+<DIV CLASS="Listing">
+[% hasLeaves = 0; hasSubtrees = 0;
+ childCounter = 0;
+ evenRow = 0;
+ FOREACH child = sortTokens(children(token));
+ hidden = 0;
+ IF nodeParam(child,'hidden') == 'yes';
+ hidden = 1;
+ END;
+ comment = nodeParam(child,'comment',1);
+ IF not hidden or variables.SHOWHIDDEN;
+ childCounter = childCounter + 1;
+ evenRow = childCounter % 2 == 0;
+ IF isLeaf(child);
+ hasLeaves = hasLeaves + 1;
+ ELSE;
+ IF isAlias(child);
+ thisIsAlias = 1;
+ urlTitle=' TITLE="Symbolic link to ' _ path(isAlias(child)) _'"';
+ IF isLeaf(isAlias(child));
+ hasLeaves = hasLeaves + 1;
+ END;
+ ELSE;
+ hasSubtrees = 1;
+ urlTitle = '';
+ END;
+ END;
+%]
+ <DIV CLASS="[% evenRow ? 'ListRowEven' : 'ListRow' %]">
+ <SPAN CLASS="NodeName">
+ [% thisIsAlias ? '<EM CLASS="Alias">':'';
+ hidden ? '<EM CLASS="ShowHidden">':'' %]
+ <A HREF="[%url(child)%]"[%urlTitle%]>[% nodeName(child) %]</A>
+ [% hidden ? '</EM>':'';
+ thisIsAlias ? '</EM>':''; %]
+ </SPAN>
+ [% IF comment %]
+ <SPAN CLASS="NodeDescr">
+ [% hidden ? '<EM CLASS="ShowHidden">':'' %]
+ [% xmlnorm(comment) %]
+ [% hidden ? '</EM>':'' %]
+ </SPAN>
+ [% END %]
+ </DIV>
+ [% END %]
+ [% END %]
+</DIV>
+
+<DIV CLASS="BottomShortcuts">
+[% IF hasLeaves > 1;
+ INCLUDE shortcut url=url(token, 'expanded-dir-html')
+ text="Expand leaves"
+ title="Show all leaf graphs in one page";
+ END;
+ IF hasSubtrees and nodeParam(token,'show-recursive',1) == 'yes';
+ INCLUDE shortcut url=url(token, 'recursive-dir-html')
+ text="Recursive view"
+ title="Show all subtrees and leaves in one page";
+
+ END;
+ INCLUDE overviewShortcuts %]
+</DIV>
+
+[% INCLUDE bottomline %]
+[% INCLUDE htmlend %]
diff --git a/torrus/templates/default-helptext.html b/torrus/templates/default-helptext.html
new file mode 100644
index 000000000..3f9cb15bd
--- /dev/null
+++ b/torrus/templates/default-helptext.html
@@ -0,0 +1,39 @@
+[%# #### We don't need the standard header and footer ####### %]
+[% PROCESS 'html-incblocks.txt' %]
+[% thepath=path(token) %]
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<HTML>
+<!-- Torrus Copyright (c) 2004 Stanislav Sinyagin -->
+<HEAD>
+<TITLE>Help: [%thepath%]</TITLE>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
+<STYLE type="text/css" media="all">
+ @import url( [% plainURL _ style('stylesheet') %] );
+ [% cssoverlay = style('cssoverlay'); IF cssoverlay; %]
+ @import url( [% cssoverlay %] );
+ [% END %]
+</STYLE>
+</HEAD>
+<BODY>
+<DIV CLASS="HelpContent">
+
+<DIV CLASS="HelpHeader">
+Torrus Help
+</DIV>
+
+<DIV CLASS="HelpPathHeader">
+[% thepath %]
+</DIV>
+
+[% helptext=nodeParam(token, 'help-text', 1); %]
+<DIV CLASS="HelpMessage">
+[% markup( helptext ) %]
+</DIV>
+
+<DIV CLASS="HelpFooter">
+<A HREF="javascript:window.close()">Close window</A>
+</DIV>
+</DIV>
+</BODY>
+</HTML>
diff --git a/torrus/templates/default-login.html b/torrus/templates/default-login.html
new file mode 100644
index 000000000..47dc61070
--- /dev/null
+++ b/torrus/templates/default-login.html
@@ -0,0 +1,59 @@
+[% PROCESS 'html-incblocks.txt' %]
+[% INCLUDE htmlstart
+ title="Torrus Login: " _ companyName
+ contentClass="SingleColumnContent"
+ noTopMenu=1 %]
+
+[% IF authFailed %]
+<P>Incorrect username or password.</P>
+[% END %]
+
+<P>Please authenticate yourself</P>
+
+<FORM CLASS="LoginForm" METHOD="POST" ACTION="[%url%]">
+ [% IF urlPassParams.token.defined AND urlPassParams.token.length > 0 %]
+ <INPUT TYPE="HIDDEN" NAME="token" VALUE="[%urlPassParams.token%]"/>
+ [% ELSE;
+ IF urlPassParams.path.defined AND urlPassParams.path.length > 0 %]
+ <INPUT TYPE="HIDDEN" NAME="path" VALUE="[%urlPassParams.path%]"/>
+ [% ELSE;
+ IF urlPassParams.nodeid.defined AND urlPassParams.nodeid.length > 0 %]
+ <INPUT TYPE="HIDDEN" NAME="nodeid" VALUE="[%urlPassParams.nodeid%]"/>
+ [% END;
+ END;
+ END %]
+ [% IF urlPassParams.view.defined AND urlPassParams.view.length > 0 %]
+ <INPUT TYPE="HIDDEN" NAME="view" VALUE="[% urlPassParams.view %]"/>
+ [% END %]
+ <DIV CLASS="LoginRow">
+ <SPAN CLASS="LoginTitle">Username:</SPAN>
+ <SPAN CLASS="LoginInput">
+ <INPUT CLASS="Username" TYPE="TEXT" NAME="uid"/>
+ </SPAN>
+ </DIV>
+ <DIV CLASS="LoginRow">
+ <SPAN CLASS="LoginTitle">Password:</SPAN>
+ <SPAN CLASS="LoginInput">
+ <INPUT CLASS="Password" TYPE="PASSWORD" NAME="password"/>
+ </SPAN>
+ </DIV>
+ <DIV CLASS="LoginRow">
+ <SPAN CLASS="LoginTitle">
+ &nbsp;
+ </SPAN>
+ <SPAN CLASS="LoginInput">
+ <INPUT CLASS="Remember" TYPE="CHECKBOX" NAME="remember"/>
+ remember me
+ </SPAN>
+ </DIV>
+ <DIV CLASS="LoginRow">
+ <INPUT CLASS="Submit" TYPE="SUBMIT" VALUE="Login"/>
+ </DIV>
+</FORM>
+[% IF lostPasswordURL %]
+ <DIV CLASS="LoginRow">
+ <A HREF="[% lostPasswordURL %]">Lost password?</A>
+ </DIV>
+[% END %]
+
+[% INCLUDE htmlend %]
diff --git a/torrus/templates/default-recursivedir.html b/torrus/templates/default-recursivedir.html
new file mode 100644
index 000000000..eed649322
--- /dev/null
+++ b/torrus/templates/default-recursivedir.html
@@ -0,0 +1,52 @@
+[% PROCESS 'html-incblocks.txt' %]
+[% thepath=path(token) %]
+[% INCLUDE htmlstart title=thepath printpath=1 %]
+
+<H1>[% xmlnorm(nodeParam(token,'comment')) %]</H1>
+
+[% INCLUDE legend %]
+
+[%# ########### Recursively print the children ################ %]
+
+[% BLOCK recursiveChildren;
+ FOREACH child = sortTokens(children(token));
+ hidden = 0;
+ IF nodeParam(child,'hidden') == 'yes';
+ hidden = 1;
+ END;
+ IF isAlias(child);
+ thisIsAlias = 1;
+ urlTitle = 'Symbolic link to ' _ path(isAlias(child));
+ ELSE;
+ urlTitle = nodeParam(child,'comment',1);
+ END;
+ IF not hidden or variables.SHOWHIDDEN; %]
+<DIV CLASS="RecursiveListRow">
+ <SPAN CLASS="NodeName">
+ [% thisIsAlias ? '<EM CLASS="Alias">':'';
+ hidden ? '<EM CLASS="ShowHidden">':'' %]
+ <A HREF="[%url(child)%]"
+ TITLE="[%urlTitle%]">[% nodeName(child) %]</A>
+ [% hidden ? '</EM>':''; thisIsAlias ? '</EM>':''; %]
+ </SPAN>
+ [% INCLUDE recursiveChildren token=child %]
+</DIV>
+ [% END;
+ END;
+ END %]
+
+
+<P>Directories you can jump to:</P>
+<DIV CLASS="Listing">
+[% INCLUDE recursiveChildren token=token %]
+</DIV>
+
+<DIV CLASS="BottomShortcuts">
+[% INCLUDE shortcut url=url(token) text="Default view"
+ title="Restore default subtree view";
+ INCLUDE overviewShortcuts
+%]
+</DIV>
+
+[% INCLUDE bottomline %]
+[% INCLUDE htmlend %]
diff --git a/torrus/templates/default-rrd.html b/torrus/templates/default-rrd.html
new file mode 100644
index 000000000..cfbdbce8d
--- /dev/null
+++ b/torrus/templates/default-rrd.html
@@ -0,0 +1,134 @@
+[% PROCESS 'html-incblocks.txt' %]
+[% INCLUDE setdate %]
+[% INCLUDE htmlstart title='Graphs for ' _ path(token) printpath=1 %]
+
+[% parentComment = nodeParam(parent(token),'comment') %]
+[% IF parentComment %]<H1>Graphs for [% xmlnorm(parentComment) %]</H1>[% END %]
+
+[% INCLUDE variables %]
+
+<P>[% xmlnorm(nodeParam(token,'comment')) %]</P>
+
+[% INCLUDE legend %]
+
+[% monitors = nodeParam(token,'monitor');
+ IF monitors != '';
+ moncount = monitors.split(',').size %]
+<DIV CLASS="Monitors">
+<DIV CLASS="MonitorsTitle">
+<STRONG>Monitor[% (moncount > 1) ? 's' : '' %]:</STRONG>
+[% (moncount > 1) ? moncount : '' %]
+[% FOREACH monitor = monitors.split(',');
+ mondesc = param(monitor, 'comment') %]
+ <DIV CLASS="MonitorLine">
+ <SPAN CLASS="MonitorName">[% monitor %]</SPAN>
+ [% IF mondesc; %]<SPAN CLASS="MonitorDesc">([% mondesc %])</SPAN>[% END %]
+ </DIV>
+[% END %]
+</DIV>
+</DIV>
+[% END %]
+
+[% IF nodeParam(token, 'ds-type') != 'rrd-multigraph' %]
+ [% dayValues = rrprint(token, 'rrd-print-daily') %]
+ [% lastValue = rrprint(token, 'rrd-print-last') %]
+
+ <P>Min: [% scale('%.1f', dayValues.0) %], &nbsp;
+ Avg: [% scale('%.1f', dayValues.1) %], &nbsp;
+ Max: <STRONG>[% scale('%.1f', dayValues.2) %]</STRONG>, &nbsp;
+ Last: [% scale('%.1f', lastValue) %]
+ </P>
+[% END %]
+
+[%
+ graphvars = [];
+ graphviews = nodeParam(token,'rrgraph-views').split(',');
+ dayView = graphviews.1;
+ weekView = graphviews.2;
+ monthView = graphviews.3;
+ yearView = graphviews.4;
+ IF nodeParam(token, 'rrd-hwpredict') == 'enabled' and
+ ( param(view, 'rrd-hwpredict') == 'disabled' or variables.NOHW );
+ graphvars = ['NOHW', 1];
+ END;
+%]
+
+<DIV CLASS="Graph">
+<H2>Last day graph</H2>
+[% INCLUDE rrgraph view=dayView vars=graphvars %]
+</DIV>
+
+<DIV CLASS="Graph">
+<H2>Last week graph</H2>
+[% INCLUDE rrgraph view=weekView vars=graphvars %]
+</DIV>
+
+[% longterm = param(view, 'longterm') %]
+[% IF longterm %]
+
+<DIV CLASS="Graph">
+<H2>Last month graph</H2>
+[% INCLUDE rrgraph view=monthView %]
+</DIV>
+
+<DIV CLASS="Graph">
+<H2>Last year graph</H2>
+[% INCLUDE rrgraph view=yearView %]
+</DIV>
+
+[% END %]
+
+<DIV CLASS="BottomShortcuts">
+[%
+ IF longterm;
+ hwview='longterm-rrd-html';
+ termview='default-rrd-html';
+ ELSE;
+ hwview='default-rrd-html';
+ termview='longterm-rrd-html';
+ END;
+ hwvars = [];
+ termvars = [];
+ IF nodeParam(token, 'rrd-hwpredict') == 'enabled' and
+ param(view, 'rrd-hwpredict') != 'disabled';
+ IF not variables.NOHW;
+ hwaction = 'Disable';
+ hwvars = ['NOHW', 1];
+ termvars = ['NOHW', ''];
+ ELSE;
+ hwaction = 'Enable';
+ hwvars = ['NOHW', ''];
+ termvars = ['NOHW', 1];
+ END;
+ INCLUDE shortcut url=url(token, hwview, hwvars)
+ text=hwaction _ " Holt-Winters"
+ title="Switch Holt-Winters prediction boundaries";
+ ELSE;
+ IF longterm;
+ termview='default-rrd-html';
+ ELSE;
+ termview='longterm-rrd-html';
+ END;
+ END;
+
+ IF longterm;
+ termstr='Short';
+ sctitle="View last day and last week graphs";
+ ELSE;
+ termstr='Long';
+ sctitle="View last day, week, month, and year graphs";
+ END;
+
+ INCLUDE shortcut url=url(token, termview, termvars)
+ text=termstr _ "term view"
+ title=sctitle;
+
+ INCLUDE shortcut url=plainURL _ 'explain-rrdgraph.html'
+ text='Explain graph'
+ title='Describe graph elements and values'
+ newwindow=1;
+%]
+</DIV>
+
+[% INCLUDE bottomline %]
+[% INCLUDE htmlend %]
diff --git a/torrus/templates/default-tset.html b/torrus/templates/default-tset.html
new file mode 100644
index 000000000..6cf79111a
--- /dev/null
+++ b/torrus/templates/default-tset.html
@@ -0,0 +1,56 @@
+[% PROCESS 'html-incblocks.txt' %]
+[% INCLUDE setdate %]
+[% comment = xmlnorm(param(token, 'comment')) %]
+[% INCLUDE htmlstart title=comment contentClass="SingleColumnContent" %]
+
+<H1>[% comment %]</H1>
+
+[% INCLUDE treename %]
+
+[% INCLUDE variables %]
+
+[% SET pos = 1; SET global.hwpredict = 0 %]
+[% FOREACH node = sortTokens(tsetMembers(token)) %]
+ [% IF pos == 1 %]
+<DIV CLASS="ShortLeft">
+ [% ELSE %]
+<DIV CLASS="ShortRight">
+ [% END %]
+ [% nodename=nodeParam(node,'descriptive-nickname');
+ IF nodename=='';
+ nodename=path(node);
+ END;
+ INCLUDE shortgraph
+ token=node
+ nodename=nodename
+ comment=nodeParam(parent(node),'comment',1)
+ %]
+</DIV>
+ [% IF pos == 1 %]
+ [% SET pos = 2 %]
+ [% ELSE %]
+ [% SET pos = 1 %]
+ [% END %]
+[% END %]
+
+<DIV CLASS="BottomShortcuts">
+[%
+ IF global.hwpredict;
+ IF variables.NOHW;
+ INCLUDE shortcut url=url(token, view, 'NOHW', '')
+ text="Enable Holt-Winters"
+ title="Switch Holt-Winters prediction boundaries";
+ ELSE;
+ INCLUDE shortcut url=url(token, view, 'NOHW', 1)
+ text="Disable Holt-Winters"
+ title="Switch Holt-Winters prediction boundaries";
+ END;
+ END
+%]
+
+[% INCLUDE shortcut url=url('SS') text="Back to tokensets list"
+ title="List of non-empty tokensets"%]
+</DIV>
+
+[% INCLUDE tsetbottomline %]
+[% INCLUDE htmlend %]
diff --git a/torrus/templates/email-alarm.txt b/torrus/templates/email-alarm.txt
new file mode 100644
index 000000000..59c603688
--- /dev/null
+++ b/torrus/templates/email-alarm.txt
@@ -0,0 +1,27 @@
+Subject: Monitor event: [%event%], [% nickname %]
+
+This is automatic Torrus event notification.
+
+Event timestamp: [% timestamp %]
+
+Tree name: [% tree %]
+Node path: [% path %]
+Node description: [% npcomment %]
+Monitor name: [% monitor %]
+Monitor description: [% mcomment %]
+
+Event type: [% event %]
+
+You can browse the node up-to-date graphs at this URL:
+ [% url %]
+
+
+
+Event types description:
+ set Alarm condition is met first time
+ repeat Alarm condition repeats
+ clear Alarm condition is no longer met
+ forget Information about this alarm has expired
+
+Torrus home page and documentation:
+ http://torrus.sourceforge.net \ No newline at end of file
diff --git a/torrus/templates/expanded-dir.html b/torrus/templates/expanded-dir.html
new file mode 100644
index 000000000..844a2c37c
--- /dev/null
+++ b/torrus/templates/expanded-dir.html
@@ -0,0 +1,52 @@
+[% PROCESS 'html-incblocks.txt' %]
+[% INCLUDE setdate %]
+[% thepath=path(token) %]
+[% INCLUDE htmlstart title=thepath printpath=1 %]
+
+<H1>[% xmlnorm(nodeParam(token,'comment')) %]</H1>
+
+[% INCLUDE variables %]
+
+[% INCLUDE legend %]
+
+<H2>Leaf nodes:</H2>
+[%
+ FOREACH child = sortTokens(children(token));
+ IF isLeaf(child);
+ INCLUDE shortgraph
+ token=child
+ nodename=nodeName(child)
+ comment=nodeParam(child,'comment',1);
+ ELSIF isAlias(child);
+ atoken=isAlias(child);
+ IF isLeaf(atoken);
+ INCLUDE shortgraph
+ token=atoken
+ nodename=nodeName(atoken)
+ comment=path(atoken);
+ END;
+ END;
+ END;
+%]
+
+<DIV CLASS="BottomShortcuts">
+[%
+ IF global.hwpredict;
+ IF variables.NOHW;
+ INCLUDE shortcut url=url(token, view, 'NOHW', '')
+ text="Enable Holt-Winters"
+ title="Switch Holt-Winters prediction boundaries";
+ ELSE;
+ INCLUDE shortcut url=url(token, view, 'NOHW', 1)
+ text="Disable Holt-Winters"
+ title="Switch Holt-Winters prediction boundaries";
+ END;
+ END
+%]
+
+[% INCLUDE shortcut url=url(token) text="Default view"
+ title="Restore default subtree view" %]
+</DIV>
+
+[% INCLUDE bottomline %]
+[% INCLUDE htmlend %]
diff --git a/torrus/templates/globalsearch.html b/torrus/templates/globalsearch.html
new file mode 100644
index 000000000..c01c3d4ed
--- /dev/null
+++ b/torrus/templates/globalsearch.html
@@ -0,0 +1,43 @@
+[% PROCESS 'html-incblocks.txt' %]
+[% global.SearchString = variables.SEARCH; clearVar('SEARCH') %]
+[% INCLUDE htmlstart
+ title='Global Search results: ' _ global.SearchString
+ contentClass="SingleColumnContent"
+ noTopMenu=1 %]
+
+<DIV CLASS="TopMenu">
+[% INCLUDE shortcut url=url() text="Top"
+ title="Choose from the list of trees"%]
+</DIV>
+
+<H1>Global Search results: [% global.SearchString %]</H1>
+<DIV CLASS="Listing">
+[% results = searchResults( global.SearchString );
+ counter = 0;
+
+ FOREACH entry = results;
+
+ counter = counter + 1;
+ IF counter % 2 == 0;
+ evenRow = 1;
+ ELSE;
+ evenRow = 0;
+ END;
+
+%]
+ <DIV CLASS="[% evenRow ? 'ListRowEven' : 'ListRow' %]">
+ <SPAN CLASS="NodeName">[%entry.0%]:
+ <A HREF="[%persistentUrl(entry.0, entry.1)%]">
+ [% entry.1 %]</A>
+ </SPAN>
+ </DIV>
+[% END %]
+</DIV>
+
+
+</DIV><!-- Content -->[% global.contentFinished = 1 %]
+<DIV CLASS="BottomMenu">
+[% INCLUDE globalsearchdialog %]
+</DIV>
+
+[% INCLUDE htmlend %]
diff --git a/torrus/templates/html-incblocks.txt b/torrus/templates/html-incblocks.txt
new file mode 100644
index 000000000..ca5540e69
--- /dev/null
+++ b/torrus/templates/html-incblocks.txt
@@ -0,0 +1,356 @@
+[%#
+ $Id: html-incblocks.txt,v 1.1 2010-12-27 00:04:03 ivan Exp $
+ All BLOCK statements are defined here
+%]
+
+[%# ########### Initialize globals ################ %]
+[% global.setDateDialog = 0; %]
+
+
+[%# ########### Print the starting HTML blahblah ################ %]
+
+[% BLOCK htmlstart;
+ IF ! contentClass; contentClass="Content"; END %]
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<HTML>
+<!-- Torrus Copyright (c) 2003-2004 Stanislav Sinyagin -->
+<HEAD>
+<SCRIPT language="JavaScript">
+<!--
+function helpwindow()
+{
+window.open('[%url(token) _ '&view=helptext-html'%]','helpwindow',
+'width=600,height=400,resizable=yes,left=200,top=100');
+}
+//-->
+</SCRIPT>
+<TITLE>[% title %]</TITLE>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
+[% IF expires %]<META HTTP-EQUIV="Refresh" CONTENT="[% expires %]"/>[% END %]
+<STYLE type="text/css" media="all">
+ @import url( [% plainURL _ style('stylesheet') %] );
+ [% cssoverlay = style('cssoverlay'); IF cssoverlay; %]
+ @import url( [% cssoverlay %] );
+ [% END %]
+</STYLE>
+</HEAD>
+<BODY>
+
+<DIV CLASS="Header">
+
+<SPAN CLASS="CompanyInfo">
+<A TITLE="company info"
+HREF="[%companyURL%]">[% IF companyLogo %]<IMG SRC="[%companyLogo%]"
+ALT=[%companyName%] STYLE="border:0">[% ELSE; companyName; END %]</A>
+</SPAN>
+
+[% IF siteInfo %]
+<SPAN CLASS="SiteInfo">
+[% siteInfo %]
+</SPAN>
+[% END %]
+
+[% IF treeName and treeInfo %]
+<SPAN CLASS="TreeInfo">
+[% treeInfo %]
+</SPAN>
+[% END %]
+
+[% IF userAuth and uid;
+ commonname = userAttr('cn');
+ IF commonname == ''; commonname = uid; END; %]
+<DIV CLASS="LoginInfo">
+<SPAN CLASS="UserName">[% commonname %]</SPAN>
+<SPAN CLASS="Logout"><A HREF="[% topURL _ '?LOGOUT=1' %]">Logout</A></SPAN>
+</DIV>
+[% END %]
+</DIV>
+<DIV CLASS="CurrentTime">[% timestamp %]</DIV>
+[% IF printpath %]
+ <DIV CLASS="PathMenu">
+ [% INCLUDE treename %]
+ <DIV CLASS="CurrentPath">
+ <SPAN CLASS="PathMenuHeader">Current path:</SPAN>
+ <SPAN CLASS="PathURLs">[% splitUrls(token) %]</SPAN>
+ </DIV>
+ </DIV>
+[% END %]
+[% IF not noTopMenu %]
+<DIV CLASS="TopMenu">
+[% INCLUDE shortcut url=topURL text="Top"
+ title="Choose from the list of trees"%]
+[% theParent=parent(token);
+ IF theParent and theParent != token;
+ INCLUDE shortcut url=url(theParent) text="Up"
+ title="Climb up the tree";
+ END %]
+[% INCLUDE helpshortcut %]
+[% IF mayDisplayAdmInfo(token);
+ INCLUDE shortcut url=url(token,'adminfo')
+ text="AdmInfo"
+ title="Administrative details"
+ newwindow=1;
+ END
+%]
+
+</DIV>
+[% END %]
+<DIV CLASS="[%contentClass%]">
+[% global.contentFinished = 0 %]
+[% IF global.printError %]
+<DIV CLASS="ErrorMessage">[% global.printError %]</DIV>
+[% global.printError = '' %]
+[% END %]
+[% END %]
+
+[%# ########### Print the legend ################ %]
+
+[% BLOCK legend %]
+[% legend = nodeParam(token, 'legend') %]
+[% IF legend.length > 0 %]
+<DIV CLASS="Legend">
+[% FOREACH legpairstring = legend.split(';') %]
+[% SET legpair = legpairstring.split(':') %]
+ <DIV CLASS="LegendRow">
+ <SPAN CLASS="LegendName">[% xmlnorm(legpair.0) %]:</SPAN>
+ <SPAN CLASS="LegendValue">[% xmlnorm(legpair.1) %]</SPAN>
+ </DIV>
+[% END %]
+</DIV>
+[% END %]
+[% END %]
+
+[%# ########### Print the TZ and NOW variables ################ %]
+
+[% BLOCK variables %]
+[% IF variables.TZ or variables.NOW %]
+<P CLASS="Variables">
+[% IF variables.TZ %]
+ <SPAN CLASS="VariableName">Timezone:</SPAN>
+ <SPAN CLASS="VariableValue">[% variables.TZ %].</SPAN>
+[% END %]
+[% IF variables.NOW %]
+ <SPAN CLASS="VariableName">Report date:</SPAN>
+ <SPAN CLASS="VariableValue">[% variables.NOW %].</SPAN>
+[% END %]
+</P>
+[% END %]
+[% END %]
+
+
+[%# ########### Print the current tree name ################ %]
+
+[% BLOCK treename %]
+ <DIV CLASS="CurrentTree">
+ <SPAN CLASS="PathMenuHeader">Tree:</SPAN>
+ <SPAN CLASS="TreeName">[% treeName %]</SPAN>
+ </DIV>
+[% END %]
+
+[%# ########### Print the shortcut ################ %]
+
+[% BLOCK shortcut %]
+ <SPAN CLASS="Shortcut">
+ [&nbsp;<A TITLE="[%title%]" HREF="[%url%]"
+ [%IF newwindow; 'TARGET="_blank"'; END%]>[%text%]</A>&nbsp;]
+ </SPAN>
+[% END %]
+
+[%# ########### Print the Help shortcut ################ %]
+[% BLOCK helpshortcut;
+ IF nodeParam(token, 'help-text', 1);
+ INCLUDE shortcut
+ url="javascript:helpwindow()"
+ text="Help"
+ title="Open a help window for this page";
+ END;
+ END %]
+
+[%# ########### Print the common bottomline ################ %]
+
+[% BLOCK bottomline %]
+</DIV><!-- Content -->[% global.contentFinished = 1 %]
+<DIV CLASS="BottomMenu">
+[% INCLUDE shortcut url=persistentUrl(token,view,global.bookmarkVars)
+ text="Bookmark"
+ title="Permanent link to this page"%]
+[% INCLUDE shortcut url=url('SS') text="Tokensets"
+ title="List of non-empty tokensets"%]
+[% INCLUDE shortcut url=url(token,view,'MEDIA','printer','OVS',ovs)
+ text="Printable view"
+ title="Prepare this page for printing"
+ newwindow=1%]
+[% IF mayDisplayReports();
+ INCLUDE shortcut url=reportsUrl
+ text="Reports"
+ title="Show reports page"
+ newwindow=1;
+ END %]
+[% IF global.setDateDialog; INCLUDE enterdate; END %]
+[% INCLUDE searchdialog %]
+</DIV>
+[% END %]
+
+[%# ########### Print the Tokensets bottomline ################ %]
+
+[% BLOCK tsetbottomline %]
+</DIV><!-- Content -->[% global.contentFinished = 1 %]
+<DIV CLASS="BottomMenu">
+[% INCLUDE shortcut url=url(pathToken('/')) text="Datasources tree"
+ title="Back to the datasources tree" %]
+[% INCLUDE shortcut url=url(token,view,'MEDIA','printer')
+ text="Printable view"
+ title="Prepare this page for printing"
+ newwindow=1%]
+[% INCLUDE helpshortcut %]
+[% INCLUDE searchdialog %]
+</DIV>
+[% END %]
+
+
+[%# ########### Print the ending HTML blahblah ################ %]
+
+[% BLOCK htmlend %]
+[% IF ! global.contentFinished %]</DIV><!-- Content -->[% END %]
+<DIV CLASS="Footer">
+ Powered by <A HREF="http://torrus.org">Torrus</A> [% version %]
+</DIV>
+</BODY>
+</HTML>
+[% END %]
+
+[%# ######## Print the RRD graph image ####### %]
+
+[% BLOCK rrgraph %]
+<DIV CLASS="GraphImage">
+<IMG SRC="[%url(token, view, vars)%]"
+ ALT="[% param(view, 'description') %]">
+</DIV>
+[% END %]
+
+
+[%# ######## Print the short-term RRD graph image ####### %]
+
+[% BLOCK shortgraph %]
+[%
+ hidden = 0;
+ IF nodeParam(token,'hidden') == 'yes';
+ hidden = 1;
+ END;
+ IF not hidden or variables.SHOWHIDDEN
+%]
+<DIV CLASS="ShortGraph">
+ [% IF not urltoken; urltoken = token; END %]
+ [% hidden ? '<SPAN CLASS="ShowHidden">':'' %]
+ <DIV CLASS="NodeName">
+ <A HREF="[%url(urltoken,urlview)%]">[% nodename %]</A>
+ </DIV>
+ [%IF comment%]<DIV CLASS="NodeDescr">[%xmlnorm(comment)%]</DIV>[%END%]
+ [% hidden ? '</SPAN>':'' %]
+
+ [%
+ shortView = nodeParam(token,'rrgraph-views').split(',').0;
+ shortvars = [];
+ IF nodeParam(token, 'rrd-hwpredict') == 'enabled' and
+ param(view, 'rrd-hwpredict') != 'disabled';
+ global.hwpredict = 1;
+ IF variables.NOHW;
+ shortvars = ['NOHW', 1];
+ ELSE;
+ shortvars = ['NOHW', ''];
+ END;
+ END
+ %]
+ <DIV CLASS="GraphImage">
+ <A HREF="[%url(urltoken,urlview)%]">
+ <IMG SRC="[%url(token, shortView, shortvars)%]"
+ ALT="[% param(shortView, 'description') %]">
+ </A>
+ </DIV>
+</DIV>
+ [% END %]
+[% END %]
+
+
+[%# ######## Print the overview shortcuts ####### %]
+[% BLOCK overviewShortcuts %]
+[%
+ IF nodeParam(token, 'has-overview-shortcuts', 1) == 'yes';
+ FOREACH ovs = nodeParam(token,'overview-shortcuts').split('\s*,\s*');
+ p1 = 'overview-shortcut-text-' _ ovs;
+ p2 = 'overview-shortcut-title-' _ ovs;
+ INCLUDE shortcut
+ url=url(token, 'overview-subleaves-html', 'OVS', ovs)
+ text=nodeParam(token, p1, 1)
+ title=nodeParam(token, p2, 1);
+ END;
+ END %]
+[% END %]
+
+
+[%# ######## Set the date variable ####### %]
+[% BLOCK setdate %]
+[% IF variables.SETDATE == 1;
+ thedate = verifyDate( variables.SETDATEV );
+ IF thedate.length == 0;
+ global.printError = 'Incorrect date format';
+ clearVar('SETDATE');
+ ELSE;
+ variables.NOW = thedate;
+ END;
+ ELSE;
+ clearVar('NOW');
+ clearVar('SETDATE');
+ clearVar('SETDATEV');
+ END;
+ global.setDateDialog = 1;
+%]
+[% END %]
+
+
+[%# ######## Print the date selection elements ####### %]
+[% BLOCK enterdate %]
+<SPAN CLASS="SetDateDialog">
+<FORM METHOD=GET ACTION="[%topUrl()%]">
+<INPUT TYPE="hidden" NAME="token" VALUE="[%token%]"/>
+<INPUT TYPE="hidden" NAME="view" VALUE="[%view%]"/>
+[% IF ovs %]<INPUT TYPE="hidden" NAME="OVS" VALUE="[%ovs%]"/>[% END %]
+<LABEL>
+<INPUT TYPE="checkbox" NAME="SETDATE" VALUE="1"
+[%variables.SETDATE ? 'CHECKED':''%]/>
+Set date</LABEL>
+<INPUT TYPE="text" NAME="SETDATEV" SIZE="22" VALUE="[%variables.SETDATEV%]"/>
+<INPUT TYPE="submit" VALUE="&gt;"/>
+</FORM>
+</SPAN>
+[% END %]
+
+
+[%# ######## Print the searchform HTML ####### %]
+[% BLOCK searchdialog %]
+[% IF searchEnabled %]
+<SPAN CLASS="SearchDialog">
+<FORM METHOD=GET ACTION="[%topUrl()%]">
+<INPUT TYPE="hidden" NAME="token" VALUE="[%pathToken('/')%]"/>
+<INPUT TYPE="hidden" NAME="view" VALUE="search"/>
+<LABEL>Search</LABEL>
+<INPUT TYPE="text" NAME="SEARCH" SIZE="22" VALUE=""/>
+<INPUT TYPE="submit" VALUE="&gt;"/>
+</FORM>
+</SPAN>
+[% END %]
+[% END %]
+
+[%# ######## Print the Global searchform HTML ####### %]
+[% BLOCK globalsearchdialog %]
+[% IF mayGlobalSearch() %]
+<SPAN CLASS="SearchDialog">
+<FORM METHOD=GET ACTION="[%topUrl()%]">
+<LABEL>Search</LABEL>
+<INPUT TYPE="text" NAME="SEARCH" SIZE="22" VALUE=""/>
+<INPUT TYPE="submit" VALUE="&gt;"/>
+</FORM>
+</SPAN>
+[% END %]
+[% END %]
diff --git a/torrus/templates/overview-subleaves.html b/torrus/templates/overview-subleaves.html
new file mode 100644
index 000000000..345e06fd9
--- /dev/null
+++ b/torrus/templates/overview-subleaves.html
@@ -0,0 +1,47 @@
+[% PROCESS 'html-incblocks.txt' %]
+[% INCLUDE setdate %]
+[% ovs=variables.OVS; clearVar('OVS'); global.bookmarkVars=['OVS',ovs];
+ thepath=path(token) %]
+[% INCLUDE htmlstart title=thepath printpath=1 %]
+
+<H1>[% p = 'overview-page-title-' _ ovs; nodeParam(token, p, 1) %]</H1>
+
+[% INCLUDE variables %]
+
+[% INCLUDE legend %]
+
+[%
+ FOREACH child = sortTokens(children(token));
+ childpath = path(child);
+ p = 'overview-subleave-name-' _ ovs;
+ FOREACH childname = nodeParam(token, p,1).split('\s*,\s*');
+ ovwpath = childpath _ childname;
+ IF nodeExists(ovwpath);
+ ovwtoken = pathToken(ovwpath);
+
+ urltoken = ovwtoken;
+ p = 'overview-direct-link-' _ ovs;
+ IF nodeParam(token, p, 1) == 'yes';
+ urltoken = child;
+ p = 'overview-direct-link-view-' _ ovs;
+ urlview = nodeParam(token, p, 1);
+ END;
+
+ INCLUDE shortgraph
+ token=ovwtoken
+ urltoken=urltoken
+ urlview=urlview
+ nodename=nodeName(child)
+ comment=nodeParam(child,'comment',1);
+ END;
+ END;
+ END
+%]
+
+<DIV CLASS="BottomShortcuts">
+[% INCLUDE shortcut url=url(token) text="Default view"
+ title="Restore default subtree view" %]
+</DIV>
+
+[% INCLUDE bottomline %]
+[% INCLUDE htmlend %]
diff --git a/torrus/templates/report-index.html b/torrus/templates/report-index.html
new file mode 100644
index 000000000..7bc41a66d
--- /dev/null
+++ b/torrus/templates/report-index.html
@@ -0,0 +1,29 @@
+[% PROCESS 'html-incblocks.txt' %]
+[% INCLUDE htmlstart
+ title="Torrus Reports"
+ contentClass="SingleColumnContent"
+ noTopMenu=1 %]
+
+<H1>Torrus reports</H1>
+
+[% INCLUDE treename %]
+
+<TABLE CLASS="ReportTable">
+<CAPTION CLASS="ReportTable"></CAPTION>
+<TR CLASS="ReportHeadrow">
+<TD CLASS="ReportHeadCell">Year</TD>
+</TR>
+[% rowCount = 0;
+ FOREACH yr = data.keys.sort;
+ rowCount = rowCount + 1;
+ IF rowCount % 2 %]
+<TR CLASS="ReportEvenRow">
+[% ELSE %]
+<TR CLASS="ReportRow">
+[% END %]
+<TD CLASS="ReportFirstCell"><A HREF="[% yearlyUrl(yr) %]">[% yr %]</A></TD>
+</TR>
+[% END %]
+</TABLE>
+
+[% INCLUDE htmlend %]
diff --git a/torrus/templates/report-monthly.html b/torrus/templates/report-monthly.html
new file mode 100644
index 000000000..c302f932d
--- /dev/null
+++ b/torrus/templates/report-monthly.html
@@ -0,0 +1,132 @@
+[% PROCESS 'html-incblocks.txt' %]
+[% INCLUDE htmlstart
+ title="Torrus Reports: " _ year
+ contentClass="SingleColumnContent"
+ noTopMenu=1 %]
+
+<H1>Torrus report: [% monthName(month) %]
+<A HREF="[% yearlyUrl(year) %]">[% year %]</A></H1>
+
+[% INCLUDE treename %]
+
+[% FOREACH reportname = data.keys.sort;
+ fieldshash = data.$reportname;
+ IF reportname == 'MonthlyUsage' %]
+
+<TABLE CLASS="ReportTable">
+<CAPTION CLASS="ReportTable">Monthly usage</CAPTION>
+<TR CLASS="ReportHeadRow">
+<TD CLASS="ReportHeadCell">Service ID</TD>
+<TD CLASS="ReportHeadCell">Average</TD>
+<TD CLASS="ReportHeadCell">95th<BR/>Percentile</TD>
+<TD CLASS="ReportHeadCell">Maximum</TD>
+<TD CLASS="ReportHeadCell">Unavailable<BR/>samples</TD>
+<TD CLASS="ReportHeadCell">Volume</TD>
+</TR>
+[% rowCount = 0;
+ FOREACH serviceid = fieldshash.keys.sort;
+ rowCount = rowCount + 1;
+ IF rowCount % 2 %]
+<TR CLASS="ReportEvenRow">
+[% ELSE %]
+<TR CLASS="ReportRow">
+[% END %]
+<TD CLASS="ReportFirstCell">
+<A HREF="[% srvIdUrl(serviceid) %]">[% serviceid %]</A>
+</TD>
+[% FOREACH varname = ['AVG', '95TH_PERCENTILE', 'MAX',
+ 'UNAVAIL', 'VOLUME'] %]
+<TD CLASS="ReportCell">
+[% formatValue( fieldshash.$serviceid.$varname ) %]
+</TD>
+[% END %]
+</TR>
+[% END %]
+</TABLE>
+
+[% ELSE %]
+
+<TABLE CLASS="ReportTable">
+<CAPTION CLASS="ReportTable">[% reportname %]</CAPTION>
+<TR CLASS="ReportHeadRow">
+<TD CLASS="ReportHeadCell">Service ID</TD>
+<TD CLASS="ReportHeadCell">Field</TD>
+<TD CLASS="ReportHeadCell">Value</TD>
+</TR>
+[% rowCount = 0;
+ FOREACH serviceid = fieldshash.keys.sort;
+ FOREACH varname = fieldshash.$serviceid.keys.sort;
+ rowCount = rowCount + 1;
+ IF rowCount % 2 %]
+<TR CLASS="ReportEvenRow">
+[% ELSE %]
+<TR CLASS="ReportRow">
+[% END %]
+<TD CLASS="ReportFirstCell">
+<A HREF="[% srvIdUrl(serviceid) %]">[% serviceid %]</A>
+</TD>
+<TD CLASS="ReportCell">
+[% varname %]
+</TD>
+<TD CLASS="ReportCell">
+[% formatValue( fieldshash.$serviceid.$varname ) %]
+</TD>
+</TR>
+[% END;
+ END %]
+</TABLE>
+
+[% END;
+ END %]
+
+<DIV CLASS="ReportLegend">
+
+<DIV CLASS="ReportLegendLine">
+<SPAN CLASS="ReportLegendTerm">
+Average:
+</SPAN>
+<SPAN CLASS="ReportLegendDef">
+the monthly average of 5-minute samples.
+</SPAN>
+</DIV>
+
+<DIV CLASS="ReportLegendLine">
+<SPAN CLASS="ReportLegendTerm">
+95th percentile:
+</SPAN>
+<SPAN CLASS="ReportLegendDef">
+95% of the time, the usage is at or below this amount.
+</SPAN>
+</DIV>
+
+<DIV CLASS="ReportLegendLine">
+<SPAN CLASS="ReportLegendTerm">
+Maximum:
+</SPAN>
+<SPAN CLASS="ReportLegendDef">
+the maximum value among 5-minute samples.
+</SPAN>
+</DIV>
+
+<DIV CLASS="ReportLegendLine">
+<SPAN CLASS="ReportLegendTerm">
+Unavailable samples:
+</SPAN>
+<SPAN CLASS="ReportLegendDef">
+how many 5-minute samples were missed from the measurements.
+</SPAN>
+</DIV>
+
+<DIV CLASS="ReportLegendLine">
+<SPAN CLASS="ReportLegendTerm">
+Volume:
+</SPAN>
+<SPAN CLASS="ReportLegendDef">
+for traffic usage, this is the absolut volume of data in avaiable 5-minute
+samples.
+</SPAN>
+</DIV>
+
+</DIV>
+
+[% INCLUDE htmlend %]
diff --git a/torrus/templates/report-serviceid.html b/torrus/templates/report-serviceid.html
new file mode 100644
index 000000000..bd392ca01
--- /dev/null
+++ b/torrus/templates/report-serviceid.html
@@ -0,0 +1,147 @@
+[% PROCESS 'html-incblocks.txt' %]
+[% INCLUDE htmlstart
+ title="Torrus Reports: " _ year
+ contentClass="SingleColumnContent"
+ noTopMenu=1 %]
+
+<H1>Torrus report: <A HREF="[% yearlyUrl(year) %]">[% year %]</A>,
+[% serviceid %]</H1>
+
+[% INCLUDE treename %]
+
+[% FOREACH reportname = data.keys.sort;
+ fieldshash = data.$reportname;
+ IF reportname == 'MonthlyUsage' %]
+
+<TABLE CLASS="ReportTable">
+<CAPTION CLASS="ReportTable">Monthly usage</CAPTION>
+<TR CLASS="ReportHeadRow">
+<TD CLASS="ReportHeadCell">Month</TD>
+<TD CLASS="ReportHeadCell">Average</TD>
+<TD CLASS="ReportHeadCell">95th<BR/>Percentile</TD>
+<TD CLASS="ReportHeadCell">Maximum</TD>
+<TD CLASS="ReportHeadCell">Unavailable<BR/>samples</TD>
+<TD CLASS="ReportHeadCell">Volume</TD>
+<TD CLASS="ReportHeadCell">Extrapolated<BR/>volume</TD>
+</TR>
+[% rowCount = 0;
+ FOREACH mth = fieldshash.keys.sort;
+ rowCount = rowCount + 1;
+ IF rowCount % 2 %]
+<TR CLASS="ReportEvenRow">
+[% ELSE %]
+<TR CLASS="ReportRow">
+[% END %]
+<TD CLASS="ReportFirstCell">
+<A HREF="[% monthlyUrl(mth) %]">[% monthName(mth) %]</A>
+</TD>
+[% FOREACH varname = ['AVG', '95TH_PERCENTILE', 'MAX',
+ 'UNAVAIL', 'VOLUME'] %]
+<TD CLASS="ReportCell">
+[% formatValue( fieldshash.$mth.$varname ) %]
+</TD>
+[% END %]
+<TD CLASS="ReportCell">
+[% extr.value = fieldshash.$mth.VOLUME.value * 100 /
+ ( 100 - fieldshash.$mth.UNAVAIL.value );
+ extr.units = fieldshash.$mth.VOLUME.units;
+ formatValue( extr ) %]
+</TD>
+</TR>
+[% END %]
+</TABLE>
+
+[% ELSE %]
+
+<TABLE CLASS="ReportTable">
+<CAPTION CLASS="ReportTable">[% reportname %]</CAPTION>
+<TR CLASS="ReportHeadRow">
+<TD CLASS="ReportHeadCell">Month</TD>
+<TD CLASS="ReportHeadCell">Field</TD>
+<TD CLASS="ReportHeadCell">Value</TD>
+</TR>
+[% rowCount = 0;
+ FOREACH mth = fieldshash.keys.sort;
+ FOREACH varname = fieldshash.$mth.keys.sort;
+ rowCount = rowCount + 1;
+ IF rowCount % 2 %]
+<TR CLASS="ReportEvenRow">
+[% ELSE %]
+<TR CLASS="ReportRow">
+[% END %]
+<TD CLASS="ReportFirstCell">
+<A HREF="[% monthlyUrl(mth) %]">[% monthName(mth) %]</A>
+</TD>
+<TD CLASS="ReportCell">
+[% varname %]
+</TD>
+<TD CLASS="ReportCell">
+[% formatValue( fieldshash.$mth.$varname ) %]
+</TD>
+</TR>
+[% END;
+ END %]
+</TABLE>
+[% END;
+ END %]
+
+<DIV CLASS="ReportLegend">
+
+<DIV CLASS="ReportLegendLine">
+<SPAN CLASS="ReportLegendTerm">
+Average:
+</SPAN>
+<SPAN CLASS="ReportLegendDef">
+the monthly average of 5-minute samples.
+</SPAN>
+</DIV>
+
+<DIV CLASS="ReportLegendLine">
+<SPAN CLASS="ReportLegendTerm">
+95th percentile:
+</SPAN>
+<SPAN CLASS="ReportLegendDef">
+95% of the time, the usage is at or below this amount.
+</SPAN>
+</DIV>
+
+<DIV CLASS="ReportLegendLine">
+<SPAN CLASS="ReportLegendTerm">
+Maximum:
+</SPAN>
+<SPAN CLASS="ReportLegendDef">
+the maximum value among 5-minute samples.
+</SPAN>
+</DIV>
+
+<DIV CLASS="ReportLegendLine">
+<SPAN CLASS="ReportLegendTerm">
+Unavailable samples:
+</SPAN>
+<SPAN CLASS="ReportLegendDef">
+how many 5-minute samples were missed from the measurements.
+</SPAN>
+</DIV>
+
+<DIV CLASS="ReportLegendLine">
+<SPAN CLASS="ReportLegendTerm">
+Volume:
+</SPAN>
+<SPAN CLASS="ReportLegendDef">
+for traffic usage, this is the absolut volume of data in avaiable 5-minute
+samples.
+</SPAN>
+</DIV>
+
+<DIV CLASS="ReportLegendLine">
+<SPAN CLASS="ReportLegendTerm">
+Extrapolated volume:
+</SPAN>
+<SPAN CLASS="ReportLegendDef">
+for traffic usage, this is the volume of data extrapolated to the whole
+time range.
+</SPAN>
+</DIV>
+</DIV>
+
+[% INCLUDE htmlend %]
diff --git a/torrus/templates/report-yearly.html b/torrus/templates/report-yearly.html
new file mode 100644
index 000000000..6f9078db2
--- /dev/null
+++ b/torrus/templates/report-yearly.html
@@ -0,0 +1,31 @@
+[% PROCESS 'html-incblocks.txt' %]
+[% INCLUDE htmlstart
+ title="Torrus Reports: " _ year
+ contentClass="SingleColumnContent"
+ noTopMenu=1 %]
+
+<H1><A HREF="[% indexUrl() %]">Torrus reports</A>: [% year %]</H1>
+
+[% INCLUDE treename %]
+
+<TABLE CLASS="ReportTable">
+<CAPTION CLASS="ReportTable">Monthly reports</CAPTION>
+<TR CLASS="ReportHeadRow">
+<TD CLASS="ReportHeadCell">Month</TD>
+</TR>
+[% rowCount = 0;
+ FOREACH mth = data.months;
+ rowCount = rowCount + 1;
+ IF rowCount % 2 %]
+<TR CLASS="ReportEvenRow">
+[% ELSE %]
+<TR CLASS="ReportRow">
+[% END %]
+<TD CLASS="ReportFirstCell">
+<A HREF="[% monthlyUrl(mth) %]">[% monthName(mth) _ ' ' _ year %]</A>
+</TD>
+</TR>
+[% END %]
+</TABLE>
+
+[% INCLUDE htmlend %]
diff --git a/torrus/templates/search.html b/torrus/templates/search.html
new file mode 100644
index 000000000..b5ce5857e
--- /dev/null
+++ b/torrus/templates/search.html
@@ -0,0 +1,43 @@
+[% PROCESS 'html-incblocks.txt' %]
+[% global.SearchString = variables.SEARCH; clearVar('SEARCH') %]
+[% INCLUDE htmlstart
+ title='Search results: ' _ global.SearchString
+ contentClass="SingleColumnContent" %]
+
+<H1>Search results: [% global.SearchString %]</H1>
+[% INCLUDE treename %]
+<DIV CLASS="Listing">
+[% results = searchResults(global.SearchString);
+ counter = 0;
+
+ FOREACH entry = results;
+
+ counter = counter + 1;
+ IF counter % 2 == 0;
+ evenRow = 1;
+ ELSE;
+ evenRow = 0;
+ END;
+
+ etoken = pathToken(entry.0);
+%]
+ <DIV CLASS="[% evenRow ? 'ListRowEven' : 'ListRow' %]">
+ <SPAN CLASS="NodeName"><A HREF="[%persistentUrl(etoken)%]">
+ [% entry.0 %]</A></SPAN>
+ <SPAN CLASS="NodeDescr">
+ [% IF entry.1; entry.1 _ ': ' _ xmlnorm(nodeParam(etoken, entry.1));
+ END %]
+ </SPAN>
+ </DIV>
+[% END %]
+</DIV>
+
+
+</DIV><!-- Content -->[% global.contentFinished = 1 %]
+<DIV CLASS="BottomMenu">
+[% INCLUDE shortcut url=url(pathToken('/')) text="Datasources tree"
+ title="Back to the datasources tree" %]
+[% INCLUDE searchdialog %]
+</DIV>
+
+[% INCLUDE htmlend %]
diff --git a/torrus/templates/tset-list.html b/torrus/templates/tset-list.html
new file mode 100644
index 000000000..a3785785b
--- /dev/null
+++ b/torrus/templates/tset-list.html
@@ -0,0 +1,38 @@
+[% PROCESS 'html-incblocks.txt' %]
+[% INCLUDE htmlstart
+ title="Non-empty tokensets"
+ contentClass="SingleColumnContent" %]
+
+<H1>Non-empty tokensets</H1>
+
+[% INCLUDE treename %]
+
+<DIV CLASS="Listing">
+[% counter = 0;
+ evenRow = 0;
+
+ FOREACH tset = tsetList();
+ sz = tsetMembers(tset).size;
+
+ IF sz.length > 0 AND sz > 0;
+
+ counter = counter + 1;
+
+ IF counter % 2 == 0;
+ evenRow = 1;
+ ELSE;
+ evenRow = 0;
+ END;
+%]
+ <DIV CLASS="[% evenRow ? 'ListRowEven' : 'ListRow' %]">
+ <SPAN CLASS="TokensetDescr">
+ <A HREF="[%url(tset)%]">[% xmlnorm(param(tset, 'comment')) %]</A>
+ ([% sz %])
+ </SPAN>
+ </DIV>
+ [% END %]
+ [% END %]
+</DIV>
+
+[% INCLUDE tsetbottomline %]
+[% INCLUDE htmlend %]