sysmodellibs/sysmodelgen/src/svg/Draw.xsl
changeset 6 5b32dc297d05
parent 3 e7e0ae78773e
child 7 3c36c452f013
equal deleted inserted replaced
3:e7e0ae78773e 6:5b32dc297d05
     1 <?xml version="1.0"?>
       
     2  <xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:doc="tooldoc"  xmlns="http://www.w3.org/2000/svg"  xmlns:s="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:exslt="http://exslt.org/common" xmlns:m="http://exslt.org/math" exclude-result-prefixes="doc s m exslt" >
       
     3 	  <xsl:key name="color" match="legend/cbox" use="@value"/>
       
     4 	  <xsl:key name="color-value" match="component" use="@ts"/>
       
     5 	  <xsl:key name="lgrp-bottom" match="layer-group" use="@from"/>
       
     6 	  <xsl:key name="lgrp-top" match="layer-group" use="@to"/>
       
     7 	  <xsl:key name="layer" match="layer" use="@name"/>
       
     8 	  <xsl:key name="ldg-use" match="group" use="@style-id"/>
       
     9 	  <xsl:key name="styled" match="group|group/*" use="@style-id"/>	  
       
    10 	<xsl:output method="xml" cdata-section-elements="script s:script" indent="yes"/>
       
    11 
       
    12 <xsl:param name="Use-as-name" doc:desc="The attribute to use as the item name. Falls back to 'name'" select="'long-name'"/>
       
    13 <xsl:param name="Base" doc:desc="The base URL for hyperlinks." select="/SystemDefinition/systemModel/@link"/>
       
    14 <xsl:param name="Page-width" select="/SystemDefinition/systemModel/@page-width" doc:desc="The width (specify units) of the page. This overrrides the values specified in the model. The model will automatically adjust from landspace to portrait if its dimensions are more appropriate to portrait."/>
       
    15 <xsl:param name="Detail" doc:desc="The level of detail to show in the diagram. Value is the name of the lowest element to show. If the Static parameter is set to false, mousing-over an item will show its detailed content. by default this is 'component'">
       
    16 <xsl:choose>
       
    17 	<xsl:when test="/SystemDefinition/systemModel/@detail"><xsl:value-of select="/SystemDefinition/systemModel/@detail"/></xsl:when>
       
    18 	<xsl:otherwise>component</xsl:otherwise>
       
    19 </xsl:choose>
       
    20 </xsl:param>
       
    21 <xsl:variable name="pre-Static"><xsl:choose><xsl:when test="/SystemDefinition/systemModel/@static='true'">1</xsl:when><xsl:otherwise>0</xsl:otherwise></xsl:choose></xsl:variable>
       
    22 <xsl:param name="Static" doc:desc="Set to '1' to get no mouseover or animation efffects" select="$pre-Static='1'"/>
       
    23 
       
    24 <!-- ====== Constants ============= -->
       
    25 <xsl:variable name="groupDx" select="number('2.1')"/> <!-- the horizontal distance between groups (mm) -->
       
    26 <xsl:variable name="groupDy" select="number('3.2')"/> <!-- the vertical distance between groups (mm) -->
       
    27 <xsl:variable name="cSize" select="number('9.3')"/> <!-- the width and height of a component (mm) -->
       
    28 <xsl:variable name="mSize" select="number('15.6')"/> <!-- the height and minimum width of a collection (mm) -->
       
    29 <xsl:variable name="inlineLabel" select="3 * $cSize"/> <!-- the max width of an inline label. 3 time width of a collection. I don't like this. Should compute somehow and make local variable -->
       
    30 <xsl:variable name="detail-block-space" select="6"/>
       
    31 <xsl:variable name="legendDx" select="number('5')"/><!-- the horizontal distance between items in a legend (mm) -->
       
    32 <xsl:variable name="lgrpDx" select="number('5')"/> <!-- the width of a layer group border (mm)-->
       
    33 <xsl:variable name="lgrpLabelDx" select="number('15')"/> <!-- the width of a layer group title (mm) -->
       
    34 <xsl:variable name="large-width" select="500"/> <!-- cutoff width to be considered a wide model and thus need larger title size -->
       
    35 <!-- ====== Computed values ============= -->
       
    36 
       
    37 
       
    38 	<!-- Space separated ordered list of version numbers. Not all need be valid. Used to determine if a component is deprecated or not -->
       
    39 <xsl:variable name="Versions">
       
    40 	<xsl:choose>
       
    41 		<xsl:when test="/*/systemModel/@version-list"><xsl:value-of select="/*/systemModel/@version-list"/></xsl:when>
       
    42 		<xsl:otherwise>ER5 ER5U 6.0 6.1 6.2 7.0 7.0s 8.0 8.0a 8.0b 8.1 8.1a 8.1b 9.0 9.1 9.2 9.3 9.4 9.5 9.6 Future</xsl:otherwise>
       
    43 	</xsl:choose>
       
    44 </xsl:variable>
       
    45 
       
    46 
       
    47  <!-- the full horizontal width of a layer (mm). This is computed from the width of the widest layer, and SHOULD have a min value of 388.5 -->
       
    48 <xsl:variable name="full-width"><!-- the width  of the model -->
       
    49 	<xsl:call-template name="max-from-list">
       
    50 		<xsl:with-param name="list">
       
    51 			<xsl:for-each select="//layer">
       
    52 				<xsl:variable name="span-width"> <!-- space taken up by spanning layers-->
       
    53 					<xsl:call-template name="sum-list">
       
    54 						<xsl:with-param name="list">0 <xsl:for-each select="following-sibling::layer">
       
    55 							<xsl:if test="@span and position() - @span &lt;= 0"><xsl:apply-templates select="." mode="min-width"/><xsl:value-of select="concat(' ',$groupDx,' ')"/></xsl:if></xsl:for-each>
       
    56 						</xsl:with-param> 
       
    57 					</xsl:call-template>
       
    58 				</xsl:variable>	
       
    59 				<xsl:variable name="w"><xsl:apply-templates select="." mode="min-width"/></xsl:variable><!-- the width of the content -->
       
    60 				<xsl:value-of select="concat($span-width + $w,' ')"/>
       
    61 			</xsl:for-each>
       
    62 		</xsl:with-param>
       
    63 	</xsl:call-template>
       
    64 </xsl:variable>
       
    65 
       
    66 <xsl:variable name="right-borders">
       
    67 	<xsl:call-template name="max-from-list">
       
    68 		<xsl:with-param name="list">
       
    69 			<xsl:text>0 </xsl:text>
       
    70 			<xsl:for-each select="//systemModel/layer-group">
       
    71 				<xsl:apply-templates select="." mode="right-border"/><xsl:text> </xsl:text>
       
    72 			</xsl:for-each>
       
    73 		</xsl:with-param>
       
    74 	</xsl:call-template>
       
    75 </xsl:variable>
       
    76 <xsl:variable name="left-borders">
       
    77 	<xsl:call-template name="max-from-list">
       
    78 		<xsl:with-param name="list">
       
    79 			<xsl:text>0 </xsl:text>
       
    80 			<xsl:for-each select="//systemModel/layer-group">
       
    81 				<xsl:apply-templates select="." mode="left-border"/><xsl:text> </xsl:text>
       
    82 			</xsl:for-each>
       
    83 		</xsl:with-param>
       
    84 	</xsl:call-template>
       
    85 </xsl:variable>
       
    86 <xsl:variable name="view-width" select="$full-width +  12.8 +  2 * $groupDy + $left-borders + $right-borders"/><!-- the horizontal width of the page in pixels,including empty margins -->
       
    87 
       
    88 <!-- ==================== draw ==================== -->
       
    89 
       
    90 <!-- well known patterns -->
       
    91 
       
    92 <xsl:template name="default-new-pattern">
       
    93 	<radialGradient id="Patternradial-grad"  gradientUnits="userSpaceOnUse"  cx="10" cy="10" r="14">
       
    94 		<stop offset="0%" stop-color="white" stop-opacity="1"/>
       
    95 		<stop offset="100%" stop-opacity="0" stop-color="white" />
       
    96 	</radialGradient>
       
    97 </xsl:template>
       
    98 
       
    99 <xsl:template name="default-ref-pattern"> 	<!-- diagonal line pattern -->
       
   100 	<linearGradient id="Patternstriped-diag-up" spreadMethod="repeat" gradientUnits="userSpaceOnUse" x1="0%" x2="15%" y1="0%" y2="15%">
       
   101 		<stop offset="0%" stop-opacity="0" stop-color="white" />
       
   102 		<stop offset="20%" stop-color="#ccc" stop-opacity="1" />
       
   103 		<stop offset="40%" stop-opacity="0" stop-color="white" />
       
   104 		<stop offset="100%" stop-opacity="0" stop-color="white" />
       
   105 	</linearGradient>
       
   106 </xsl:template>
       
   107 
       
   108 <xsl:template name="default-X-pattern"> 	<!-- big dark X -->
       
   109 	<pattern id="Patternbig-X" patternUnits="userSpaceOnUse" x="0" y="0" width="100%" height="100%" viewBox="0 0 10 10">
       
   110 		<path d="M 1 1 L 9 9 M 1 9  L 9 1" stroke="#555" stroke-width="1.15" stroke-linecap="round"/>
       
   111 	</pattern> 
       
   112 </xsl:template>
       
   113 
       
   114 <!-- well-known border shapes -->
       
   115 
       
   116 
       
   117 <xsl:template name="default-box-border">
       
   118     <symbol id="Borderbox" viewBox="0 0 20 20">
       
   119       <path d="M 0 0 L 0 20 L 20 20 L 20 0 z" stroke="black"/>
       
   120     </symbol>
       
   121 </xsl:template>
       
   122 <xsl:template name="default-clipLB-border">
       
   123     <symbol id="Borderbox-clipLB" viewBox="0 0 20 20">
       
   124       <path d="M 0 0 L 0 15 L 5 20 L 20 20 L 20 0 z" stroke="black"/>
       
   125     </symbol>
       
   126 </xsl:template>
       
   127 <xsl:template name="default-clipLT-border">
       
   128     <symbol id="Borderbox-clipLT" viewBox="0 0 20 20">
       
   129       <path d="M 5 0 L 0 5 L 0 20 L 20 20 L 20 0 z" stroke="black"/>
       
   130     </symbol>
       
   131 </xsl:template>
       
   132 <xsl:template name="default-clipRB-border">
       
   133     <symbol id="Borderbox-clipRB" viewBox="0 0 20 20">
       
   134       <path d="M 0 0 L 0 20 L 15 20 L 20 15 L 20 0 z" stroke="black"/>
       
   135     </symbol>
       
   136 </xsl:template>
       
   137 <xsl:template name="default-clipRT-border">
       
   138     <symbol id="Borderbox-clipRT" viewBox="0 0 20 20">
       
   139       <path d="M 0 0 L 0 20 L 20 20 L 20 5 L 15 0 z" stroke="black"/>
       
   140     </symbol>
       
   141 </xsl:template>
       
   142 <xsl:template name="default-clipAll-border">
       
   143     <symbol id="Borderbox-clipAll" viewBox="0 0 20 20">
       
   144       <path d="M 5 0 L 0 5 L 0 15 L 5 20 L 15 20 L 20 15 L 20 5 L 15 0 z" stroke="black"/>
       
   145     </symbol>
       
   146 </xsl:template>
       
   147 <xsl:template name="default-round-border">
       
   148 	<symbol id="Borderround" viewBox="0 0 20 20">
       
   149 		<circle cx="10" cy="10" r="10" stroke="black" />
       
   150 	</symbol>
       
   151 </xsl:template>
       
   152 <xsl:template name="default-hexagon-border">
       
   153 	<symbol id="Borderhexagon" viewBox="0 0 20 20">
       
   154 		<path d="M 0 10 L 5.8 0 L 14.2 0 L 20 10 L 14.2 20 L 5.8 20 z" stroke="black" />
       
   155 	</symbol>
       
   156 </xsl:template>
       
   157 
       
   158 <!-- end borders -->
       
   159 
       
   160 		<!-- overridden by output of shapes.xsl -->
       
   161 <xsl:template match="SystemDefinition" mode="shapes">
       
   162 	<xsl:call-template name="default-new-pattern"/>
       
   163 	<xsl:call-template name="default-ref-pattern"/>
       
   164 	<xsl:call-template name="default-X-pattern"/> 
       
   165 		<!-- borders to use for OSD components -->
       
   166 
       
   167 	<xsl:call-template name="default-box-border"/>
       
   168 	<xsl:call-template name="default-clipLB-border"/>
       
   169 	<xsl:call-template name="default-clipLT-border"/>
       
   170 	<xsl:call-template name="default-clipRB-border"/>
       
   171 	<xsl:call-template name="default-clipRT-border"/>
       
   172 	<xsl:call-template name="default-clipAll-border"/>
       
   173 </xsl:template>
       
   174 
       
   175 <xsl:template match="*" mode="filter"/> <!-- filters for all items -->
       
   176 <xsl:template match="*" mode="text-filter"/> <!-- fitler for just text -->
       
   177 
       
   178 <xsl:template match="/SystemDefinition">
       
   179 <xsl:if test="systemModel/@resolution"><xsl:processing-instruction name="AdobeSVGViewer">resolution="<xsl:value-of select="systemModel/@resolution"/>"</xsl:processing-instruction></xsl:if>
       
   180 <svg  version="1.1" onload="wrapalltext()">
       
   181 	<xsl:attribute name="class">
       
   182 		<xsl:value-of select="$Detail"/>
       
   183 		<xsl:if test="/SystemDefinition/systemModel/@detail-type">-<xsl:value-of select="/SystemDefinition/systemModel/@detail-type"/></xsl:if>
       
   184 	</xsl:attribute>
       
   185 	<xsl:copy-of select="@xml:lang"/> <!-- localized language -->
       
   186 	<xsl:variable name="page-height">
       
   187 		<xsl:call-template name="sum-list">
       
   188 			<xsl:with-param name="list">
       
   189 				<xsl:value-of select="concat($groupDy,' ')"/>
       
   190 				<xsl:for-each select="systemModel/layer[not(@span)] | systemModel/legend-layer">
       
   191 					<xsl:apply-templates select="." mode="height"/>
       
   192 					<xsl:value-of select="concat(' ',$groupDy + $lgrpDx * (count(key('lgrp-top',@name)) +  count(key('lgrp-bottom',@name))),' ')"/>
       
   193 				</xsl:for-each>
       
   194 			</xsl:with-param>
       
   195 		</xsl:call-template>
       
   196 	</xsl:variable>
       
   197 		 <!-- has groupDy margin around all edges -->
       
   198 	<xsl:attribute name="viewBox"><xsl:value-of select="concat(-$groupDy - $left-borders ,' 0 ',$view-width ,' ', $page-height)"/></xsl:attribute>
       
   199 	
       
   200 	<xsl:if test="$Page-width!=''">
       
   201 		<xsl:attribute name="width"><xsl:value-of select="$Page-width"/></xsl:attribute>
       
   202 		<xsl:variable name="unit" select="translate($Page-width,'0123456789-.','')"/>
       
   203 		<xsl:attribute name="height">
       
   204 			<xsl:choose>
       
   205 				<xsl:when test="$page-height &gt; ($view-width *  297 div 210)"><xsl:value-of select="297 * number(substring-before($Page-width,$unit)) div 210"/></xsl:when>
       
   206 				<xsl:otherwise><xsl:value-of select="210 * number(substring-before($Page-width,$unit)) div 297"/></xsl:otherwise>
       
   207 			</xsl:choose>
       
   208 		<xsl:value-of select="$unit"/></xsl:attribute>
       
   209 	
       
   210 	</xsl:if>
       
   211 	<xsl:apply-templates select="systemModel" mode="title"/>
       
   212 	<defs>
       
   213 
       
   214     <style type="text/css">
       
   215     text.layer, text.block, text.subblock, text.collection, text.component,
       
   216     text.cbox, text.lgrp, text.label, text.lgd {
       
   217 		fill:black;
       
   218 		font-family: <xsl:call-template name="default-font"/>;
       
   219     }
       
   220     text.title {
       
   221 		fill:red;
       
   222 		font-weight: bold;
       
   223 		font-size: <xsl:call-template name="title-line-height"/>px;	
       
   224 		font-family: <xsl:call-template name="default-font"/>;
       
   225     }    
       
   226     text.component {		
       
   227 		font-size: 1.940px;  /*  5.5pt  */
       
   228 		font-weight: bold
       
   229 	}
       
   230  	text.lgd, 
       
   231 	text.layer, text.block {
       
   232 		font-size: 4.233px;  /*  12pt  */
       
   233 		font-weight: bold;
       
   234 	}
       
   235 	text.label {		
       
   236 		font-size: 1.940px;  /*  5.5pt  */
       
   237 		font-weight: bold
       
   238 	}
       
   239 	text.cbox {		
       
   240 		font-size: 1.411px;  /*  4pt  */
       
   241 		font-weight: bold
       
   242 	}
       
   243 	text.lgrp {
       
   244 		font-size: 12.699px;  /*  36pt  */
       
   245 		font-weight: normal;
       
   246 	}
       
   247 <!-- block font sizes -->
       
   248 svg.subblock text.block,
       
   249 svg.subblock-fixed text.block {
       
   250 		font-size: 7.7605px;  /*  22pt  */
       
   251 	}
       
   252 svg.block text.block,
       
   253 svg.block-fixed text.block {
       
   254 		font-size: 11.288px;  /*  32pt  */
       
   255 		font-weight: normal;
       
   256 	}
       
   257 
       
   258 svg.subblock-fixed text.block, 
       
   259 svg.block-fixed text.block {
       
   260 	}
       
   261 
       
   262 <!-- subblock font sizes -->
       
   263 	text.subblock {
       
   264 		font-size: 2.822px;  /*  8pt  */
       
   265 	}
       
   266 	
       
   267 	svg.collection text.subblock,
       
   268 	svg.collection-fixed text.subblock  {
       
   269 		font-size: 4.233px;  /*  12pt  */
       
   270 	}
       
   271 	
       
   272 	svg.subblock text.subblock,
       
   273 	svg.subblock-fixed text.subblock  {
       
   274 		font-size: 7.055px;  /*  20pt  */
       
   275 	}
       
   276 <!-- collection font sizes -->
       
   277 	text.collection {
       
   278 		font-size: 2.469px;  /*  7pt  */
       
   279 	}
       
   280 	
       
   281 	svg.collection text.collection,
       
   282 	svg.collection-fixed text.collection  {
       
   283 		font-size: 3.7035px;  /*  10.5pt  */
       
   284 	} 
       
   285 <!-- borders -->
       
   286 	/* thin border */
       
   287 	rect.legend, rect.collection, rect.cbox {
       
   288 		stroke-width: 0.0882px;  /*  0.25pt  */
       
   289 		stroke: black
       
   290 	}
       
   291 	/* thick border */
       
   292 	rect.layer, rect.subblock, rect.block  {
       
   293 		stroke-width: 0.2469px;  /*  0.7pt  */
       
   294 		stroke: black
       
   295 	}
       
   296 	rect.layer {
       
   297 		fill: #e6e6e6
       
   298 	}
       
   299 	rect.block {
       
   300 		fill: #b3b3b3
       
   301 	}
       
   302 	rect.subblock {
       
   303 		fill: #e6e6e6
       
   304 	}
       
   305 	rect.collection {
       
   306 		fill: white
       
   307 	}
       
   308 	rect.legend {
       
   309 		fill: white
       
   310 	}
       
   311  </style>	
       
   312  		<xsl:apply-templates select="." mode="shapes"/>
       
   313  
       
   314 	</defs>
       
   315 		<!-- next line is a hack for Xalan -->
       
   316 		<xsl:comment>Drawing in static mode: <xsl:value-of select="$pre-Static=1"/></xsl:comment>	
       
   317 
       
   318 <script type="text/ecmascript"> 
       
   319 <!-- for creating / finding elements by namespace -->
       
   320 var svgns="http://www.w3.org/2000/svg";
       
   321 
       
   322 <!-- for pop-ups which can only appear one at a time. 
       
   323 In general, one would want to use 
       
   324 	onmouseover="on('blah') onmouseout="off('blah')"
       
   325 for stuff which appears and disappears based on the position of the mouse (like dependency arrows)
       
   326 
       
   327 for stuff which appears based on a mouseover or button press, but does not 
       
   328 disappear until some other trigger (and only one can appear at a time), use one of:
       
   329 	onmouseover="on(clear('blah'))"
       
   330 	onclick="on(clear('blah'))"
       
   331 -->
       
   332 var curId = '';
       
   333 function clear(id) {
       
   334 	if(curId != '') off(curId);
       
   335 	return curId=id;
       
   336 }
       
   337 
       
   338 <!--  for showing and hiding : 
       
   339 	not used by default, but used by higher-detailed versions when Static is not set
       
   340 	also used by post-processed versions for showing pop-up data.-->
       
   341 function on(id) {
       
   342 	var cur =document.getElementById(id)
       
   343 	cur.setAttribute('visibility','visible');
       
   344 	<xsl:if test="$Detail!='component'"><!-- this is needed to wrap text which is initially hidden -->
       
   345 	if(!cur.hasAttribute('wrapenated')) {
       
   346 		cur.setAttribute('wrapenated','true');
       
   347 		wrapalltext(cur)
       
   348 	}
       
   349 	</xsl:if>
       
   350 	return cur;
       
   351 }
       
   352 
       
   353 function off(id) {
       
   354 	document.getElementById(id).setAttribute('visibility','hidden');
       
   355 }
       
   356 
       
   357 <xsl:if test="not($Static)"><!-- show level lables -->
       
   358 <!--function resizeLabel(node) {
       
   359 	var list = node.getElementsByTagNameNS(svgns,'text');
       
   360 	if(list.length==0) return;
       
   361 	var txt = list.item(0);
       
   362 	node=node.firstChild;
       
   363 	while(node &amp;&amp; node.nodeType!=1) node=node.nextSibling;
       
   364 	if(!node || node==txt) return;
       
   365 	if(node.hasAttribute('transform')) return;
       
   366 	var scale  = (1.6+txt.getComputedTextLength()) / 20;
       
   367 	var x = Number(txt.getAttribute('x'))
       
   368 	node.setAttribute('transform', 'translate('+ x+') scale('+scale+' 1) translate('+ (-x)+') ');
       
   369 }-->
       
   370 </xsl:if>
       
   371 
       
   372 <!--  for wrapping: breaks text up into an array of words -->
       
   373 function splitup(txt) {
       
   374 	var a = new Array;
       
   375 	var t = txt;
       
   376 	var found		<!-- \u4e00-\ufa2 is the unicode range for kanjii, \u3041-\u309 is katakana and e\u30a1-\u30fe is hiragana-->
       
   377 	while((found = t.match(/(^[\u3041-\u309e\u30a1-\u30fe\u4e00-\ufa2d])([\u3041-\u309e\u30a1-\u30fe\u4e00-\ufa2d].*)$/))|| ( found = t.match(/^([^ \u200b\xad-]+[ \u200b\xad-]+)(.*)$/))) {
       
   378 			a.push(found[1]);
       
   379 			t=found[2];
       
   380 	}
       
   381 	a.push(t);
       
   382 	return a;
       
   383 }
       
   384 
       
   385 
       
   386 
       
   387 <!--  the remainder of the scripts also are for wrapping -->
       
   388 <![CDATA[
       
   389 function splitable(node) {
       
   390  	return node.firstChild.nodeType == 3 && node.firstChild.data.match(/[\t\n\r \u200b\xad-]/);
       
   391 }
       
   392 
       
   393 function crush(node, len) {
       
   394 	node.setAttribute('letter-spacing','-0.1');
       
   395 	if( node.getComputedTextLength() > len) 
       
   396 		node.setAttribute('letter-spacing','-0.2');
       
   397 }
       
   398 
       
   399 function whatSize(txt) { // convert a length into pixels
       
   400 	if(txt.match(/^[0-9.-]+$/)) return txt;
       
   401 	var a = document.createElementNS(svgns,'rect');
       
   402 	a.setAttribute('x',0);
       
   403 	a.setAttribute('y',0);
       
   404 	a.setAttribute('width',txt);
       
   405 	var l = a.getBBox().width;
       
   406 	delete a;
       
   407 	return l;
       
   408 }
       
   409 
       
   410 function wrapalltext(node) {
       
   411     if(!node) node= document;
       
   412     var all = node.getElementsByTagNameNS(svgns,'text');
       
   413     var i=0;
       
   414     for (i=0; i<all.length; i++) {
       
   415 	var cur = all.item(i);
       
   416 	var w =0;
       
   417 	if(cur.hasAttribute('ref')) {
       
   418 		w = document.getElementById(cur.getAttribute('ref')).getBBox().width * 0.9;
       
   419 	} else if (cur.hasAttribute('width')) {
       
   420 		w = whatSize(cur.getAttribute('width'));
       
   421 	}
       
   422 	if (w)	wraptext(cur,w)
       
   423 	}
       
   424 }
       
   425 
       
   426 
       
   427 function wraptext(cur,l) {
       
   428 	if(cur.firstChild.nodeType != 3)  return; // must be just a text node
       
   429 	if(cur.getBBox().width < l )  {
       
   430 		cur.firstChild.data = cur.firstChild.data.replace(/[\xad\u200b]/g,"");
       
   431 		return; // no need -- won't wrap
       
   432 	}
       
   433 	var t = cur.firstChild.data.replace(/\s+/," ");  // normalize all spaces
       
   434 	t = t.replace(/^ +/,"").replace(/ +$/,"");  // trim spaces
       
   435 	var words =splitup(t); 	// each word ends with the split character (if any)
       
   436 	if (words.length<2)  {
       
   437 		crush(cur, l);
       
   438 		return;
       
   439 	}
       
   440 	cur.removeChild(cur.firstChild)
       
   441 	var tspan = document.createElementNS(svgns,'tspan');
       
   442 	cur.appendChild(tspan);
       
   443 	var txt = document.createTextNode(words[0]);
       
   444 	tspan.appendChild(txt);
       
   445 	tspan.setAttribute('x',cur.getAttribute('x'));	// Opera needs this
       
   446 	var nlines=1;
       
   447 	var zero =0;
       
   448 	for (i =1;i< words.length;i++) {
       
   449 		var was = txt.data;
       
   450 		txt.data+=words[i];
       
   451 		if (tspan.getComputedTextLength() -zero > l) { // if the line with this word at the end is bigger than the available space...
       
   452 			txt.data=was.replace(/ +$/,"").replace(/\xad(.)/,"$1").replace(/\u200b/g,""); // remove zero-width spaces and trailing spaces and soft hyphens
       
   453 			// if it's still too big then decrease the letter spacing
       
   454 			if( tspan.getComputedTextLength() > l ) 	crush(tspan,l);
       
   455 			tspan = document.createElementNS(svgns,'tspan');
       
   456 			tspan.setAttribute('dy',"1em");
       
   457 			nlines++;
       
   458 			tspan.setAttribute('x',cur.getAttribute('x'));
       
   459 			cur.appendChild(tspan);
       
   460 			txt = document.createTextNode('');
       
   461 			tspan.appendChild(txt);
       
   462 			zero = tspan.getComputedTextLength();
       
   463 			txt.data+=words[i];
       
   464 		}
       
   465 	}
       
   466 	txt.data=txt.data.replace(/ +$/,"").replace(/\xad(.)/,"$1").replace(/\u200b/g,""); // remove zero-width spaces and trailing spaces and soft hyphens
       
   467 	var align =cur.getAttribute('dominant-baseline');
       
   468 	if(align=='' || align=='ideographic') {
       
   469 		cur.setAttribute('dy',(1-nlines)+"em");
       
   470 	 } else{
       
   471 	 	 if(align=='mathematical')
       
   472 			cur.setAttribute('dy',((1-nlines ) / 2 )+"em");
       
   473 		else if(align=='hanging') 
       
   474 			cur.setAttribute('dy',"0em")
       
   475 	 }
       
   476 }
       
   477   ]]> </script>
       
   478 <xsl:apply-templates select="systemModel/*[last()]">
       
   479 	<xsl:with-param name="y" select="$groupDy"/>
       
   480 </xsl:apply-templates>
       
   481 	<xsl:apply-templates mode="validate"/>
       
   482 </svg>
       
   483 </xsl:template>
       
   484 
       
   485 <xsl:template match="component|collection|subblock|block|layer" mode="id"><xsl:value-of select="translate(@name,' ','')"/></xsl:template>
       
   486 
       
   487 <xsl:template name="linkable-content"><xsl:param name="show"/>
       
   488 	<xsl:choose> <!-- don't use <a> unless there is a valid link -->
       
   489 		<xsl:when test="string-length($Base)=0 or self::cmp">
       
   490 			<xsl:copy-of select="$show"/>				
       
   491 		</xsl:when>
       
   492 		<xsl:otherwise>
       
   493 			<a>
       
   494 				<xsl:apply-templates select="." mode="link-label"/>
       
   495 				<xsl:copy-of select="$show"/>
       
   496 			</a>
       
   497 		</xsl:otherwise>
       
   498 	</xsl:choose>
       
   499 </xsl:template>
       
   500 
       
   501 
       
   502 <xsl:template name="display-name">
       
   503 	<xsl:apply-templates select="." mode="text-filter"/>
       
   504 	<xsl:if test="@font">
       
   505 		<xsl:attribute name="style">font-family: '<xsl:value-of select="@font"/>'</xsl:attribute>
       
   506 	</xsl:if>
       
   507 	<xsl:call-template name="name-value"/>
       
   508 </xsl:template>
       
   509 
       
   510 <xsl:template name="name-value">
       
   511 	<xsl:choose>
       
   512 		<xsl:when test="self::cmp or self::cbox  or self::legend or self::note or self::layer[legend|note]">
       
   513 			<xsl:apply-templates select="." mode="name"/>
       
   514 		</xsl:when>
       
   515 		<xsl:when test="@abbrev"><xsl:value-of select="@abbrev"/></xsl:when>
       
   516 		<xsl:when test="self::component[name]"><xsl:value-of select="name"/></xsl:when>		<!-- deprecated abbrev forms for components -->
       
   517 		<xsl:when test="@label"><xsl:value-of select="@label"/></xsl:when> <!-- for legends -->
       
   518 		<xsl:when test="@lookup"><xsl:value-of select="@lookup"/></xsl:when> <!-- for legends -->
       
   519 		<xsl:when test="$Use-as-name!='name' and @*[name()=$Use-as-name]"><xsl:value-of select="@*[name()=$Use-as-name]"/></xsl:when>
       
   520 		<xsl:otherwise><xsl:value-of select="@name"/></xsl:otherwise>
       
   521 	</xsl:choose>
       
   522 </xsl:template>
       
   523 
       
   524 <!-- ============ Detail options============ -->
       
   525 
       
   526 <!-- don't show when not enough detail -->
       
   527 <xsl:template match="component[$Detail!='component' and ($Static or /SystemDefinition/systemModel/@detail-type='fixed')]" priority="9"/>
       
   528 <xsl:template match="collection[$Detail!='component' and $Detail!='collection' and ($Static  or /SystemDefinition/systemModel/@detail-type='fixed')]" priority="9"/>
       
   529 <xsl:template match="block[$Detail='layer'  and ($Static  or /SystemDefinition/systemModel/@detail-type='fixed') ]" priority="9"/>
       
   530 <xsl:template match="subblock[($Detail='block' or $Detail='layer') and ($Static  or /SystemDefinition/systemModel/@detail-type='fixed')]" priority="9"/>
       
   531 
       
   532 <xsl:template match="*[$Detail='component' ]" mode="detail-stuff" priority="9"/>
       
   533 <xsl:template match="*" mode="detail-stuff" priority="-5"/>
       
   534 
       
   535 <xsl:template match="*[boolean($Static)]" mode="detail-stuff" priority="7"/>
       
   536 <xsl:template match="*[/SystemDefinition/systemModel/@detail-type='fixed']" mode="detail-stuff" priority="8">
       
   537 	<xsl:param name="s" select="'content'"/>
       
   538 	<xsl:if test="$s='mouseover' and (name()=$Detail or (self::block and not(subblock) and $Detail='subblock') or  (self::layer and not(block) and ($Detail='subblock' or $Detail='block')))">
       
   539 <!-- 		<xsl:attribute name="id"><xsl:apply-templates select="." mode="id"/></xsl:attribute>-->
       
   540 	</xsl:if>
       
   541 </xsl:template>
       
   542 <xsl:template match="collection[$Detail!='collection'] | *[($Detail='collection') and not(self::collection)] | subblock[$Detail='block']" mode="detail-stuff" priority="5"/>
       
   543 
       
   544 <xsl:template match="collection|subblock|block[not(subblock) or $Detail='block'] | layer[$Detail=name()]" mode="detail-stuff"><xsl:param name="s" select="'content'"/>
       
   545 	<xsl:choose>
       
   546 		<xsl:when test="$s='mouseover'">
       
   547 <!-- 			<xsl:attribute name="id"><xsl:apply-templates select="." mode="id"/></xsl:attribute>-->
       
   548 			<xsl:attribute name="onmouseover">on('<xsl:value-of select="name()"/>-content-<xsl:apply-templates select="." mode="id"/>');off('<xsl:value-of select="name()"/>-label-<xsl:apply-templates select="." mode="id"/>');</xsl:attribute>
       
   549 			<xsl:attribute name="onmouseout">off('<xsl:value-of select="name()"/>-content-<xsl:apply-templates select="." mode="id"/>');on('<xsl:value-of select="name()"/>-label-<xsl:apply-templates select="." mode="id"/>');</xsl:attribute>
       
   550 		</xsl:when>
       
   551 		<xsl:when test="$s='text'">
       
   552 			<xsl:attribute name="id"><xsl:value-of select="name()"/>-label-<xsl:apply-templates select="." mode="id"/></xsl:attribute>
       
   553 		</xsl:when>
       
   554 		<xsl:otherwise>
       
   555 			<xsl:attribute name="id"><xsl:value-of select="name()"/>-content-<xsl:apply-templates select="." mode="id"/></xsl:attribute>
       
   556 			<xsl:attribute name="visibility">hidden</xsl:attribute>
       
   557 		</xsl:otherwise>
       
   558 	</xsl:choose>
       
   559 </xsl:template>
       
   560 
       
   561 <xsl:template match="block[$Detail='subblock' and collection and subblock] | layer[($Detail='block' or $Detail='subblock')  and collection and block]" mode="detail-stuff"><xsl:param name="s" select="'content'"/>
       
   562 	<xsl:if test="$s='mouseover'">
       
   563 		<xsl:attribute name="onmouseover"><xsl:for-each select="collection">on('<xsl:value-of select="name()"/>-content-<xsl:apply-templates select="." mode="id"/>');</xsl:for-each></xsl:attribute>
       
   564 		<xsl:attribute name="onmouseout"><xsl:for-each select="collection">off('<xsl:value-of select="name()"/>-content-<xsl:apply-templates select="." mode="id"/>');</xsl:for-each></xsl:attribute>
       
   565 	</xsl:if>
       
   566 </xsl:template>
       
   567 
       
   568 <xsl:template priority="8" match="block[subblock and $Detail='subblock']/collection | layer[block  and ($Detail='subblock' or $Detail='block')]/collection" mode="detail-stuff"><xsl:param name="s" select="'content'"/>
       
   569 	<xsl:if test="$s='mouseover'">
       
   570 		<xsl:attribute name="id"><xsl:value-of select="name()"/>-content-<xsl:apply-templates select="." mode="id"/></xsl:attribute>
       
   571 		<xsl:attribute name="visibility">hidden</xsl:attribute>
       
   572 	</xsl:if>
       
   573 </xsl:template>
       
   574 
       
   575 
       
   576 <xsl:template match="layer[$Detail=name() or not(block|subblock)]" mode="detail-stuff"><xsl:param name="s" select="'content'"/>
       
   577 	<xsl:choose>
       
   578 		<xsl:when test="$s='mouseover'">
       
   579 			<xsl:if test="$Detail=name()"><!-- <xsl:attribute name="id"><xsl:apply-templates select="." mode="id"/></xsl:attribute>--></xsl:if>	
       
   580 			<xsl:attribute name="onmouseover">on('<xsl:value-of select="name()"/>-content-<xsl:apply-templates select="." mode="id"/>')</xsl:attribute>
       
   581 			<xsl:attribute name="onmouseout">off('<xsl:value-of select="name()"/>-content-<xsl:apply-templates select="." mode="id"/>')</xsl:attribute>
       
   582 		</xsl:when>
       
   583 		<xsl:when test="$s!='text'">
       
   584 			<xsl:attribute name="id"><xsl:value-of select="name()"/>-content-<xsl:apply-templates select="." mode="id"/></xsl:attribute>
       
   585 			<xsl:attribute name="visibility">hidden</xsl:attribute>
       
   586 		</xsl:when>
       
   587 	</xsl:choose>
       
   588 </xsl:template>
       
   589 <xsl:template match="*[$Detail='layer' and not(self::layer)]" mode="detail-stuff"/>
       
   590 
       
   591 
       
   592 <!-- ============ labelclass ============ -->
       
   593 
       
   594 <xsl:template match="*" mode="label-class">
       
   595 	<xsl:attribute name="class"><xsl:choose>
       
   596 	<xsl:when test="self::block">block</xsl:when>
       
   597 	<xsl:when test="self::subblock">subblock</xsl:when>
       
   598 	<xsl:when test="self::layer">layer</xsl:when>
       
   599 	<xsl:when test="self::component">component</xsl:when>
       
   600 	<xsl:when test="self::collection">collection</xsl:when>
       
   601 	<xsl:otherwise><xsl:message>Error</xsl:message></xsl:otherwise>
       
   602 </xsl:choose></xsl:attribute>
       
   603 </xsl:template>
       
   604 
       
   605 
       
   606 <!-- ============ hyperlinks ============ -->
       
   607 
       
   608 <xsl:template match="*" mode="link-label"/>
       
   609 <xsl:template match="*[@name]" mode="link-label">
       
   610 <xsl:attribute name="target">details</xsl:attribute>
       
   611 <xsl:attribute name="xlink:href"><xsl:value-of select="$Base"/>/<xsl:choose>
       
   612 	<xsl:when test="self::block">Blocks</xsl:when>
       
   613 	<xsl:when test="self::subblock">SubBlocks</xsl:when>
       
   614 	<xsl:when test="self::layer">Layers</xsl:when>
       
   615 	<xsl:when test="self::component">Components</xsl:when>
       
   616 	<xsl:when test="self::collection">Collections</xsl:when>
       
   617 	<xsl:otherwise><xsl:message>Error</xsl:message></xsl:otherwise>
       
   618 </xsl:choose>/<xsl:value-of select="@name"/>.html</xsl:attribute>
       
   619 </xsl:template>
       
   620 
       
   621 <!-- ============ styles ============ -->
       
   622 
       
   623 <xsl:template name="default-font">
       
   624 	<xsl:choose>
       
   625 		<xsl:when test="//systemModel[@font]">'<xsl:value-of select="//systemModel/@font"/>'</xsl:when>
       
   626 		<xsl:otherwise>Arial</xsl:otherwise>
       
   627 	</xsl:choose>
       
   628 </xsl:template>
       
   629 
       
   630 
       
   631 
       
   632 
       
   633 <!-- ============ display styles ============ -->
       
   634 
       
   635 <xsl:template name="styles"><xsl:param name="for" select="'bg'"/>
       
   636 	<xsl:variable name="st0">
       
   637 		<xsl:apply-templates select="." mode="display-style"/></xsl:variable>
       
   638 	<xsl:variable name="st1">
       
   639 		<xsl:choose>
       
   640 			<xsl:when test="$for='label' and @label-bg">fill:<xsl:value-of select="@label-bg"/>!important;</xsl:when>
       
   641 			<xsl:when test="@bg">fill:<xsl:value-of select="@bg"/>!important;</xsl:when>
       
   642 		</xsl:choose>
       
   643 	</xsl:variable>
       
   644 	<xsl:if test="$st0!='' or $st1!=''">
       
   645 	<xsl:attribute name="style">
       
   646 		<xsl:value-of select="$st0"/>
       
   647 		<xsl:if test="$st0!='' and $st1!='' and substring($st,string-length($st0))!=';'">;</xsl:if>
       
   648 		<xsl:value-of select="$st1"/>
       
   649 	</xsl:attribute>
       
   650 	</xsl:if>
       
   651 </xsl:template>
       
   652 
       
   653 <xsl:template name="gradient-direction"> <!-- calaulate the x1, etc attrbiutes from the dir ratio string. clip each to the range -1..1 -->
       
   654   <xsl:param name="dx" select="1"/>
       
   655   <xsl:param name="dy" select="0"/>
       
   656       <xsl:if test="$dx!='' and $dy!=''">
       
   657         <xsl:attribute  name="x1">
       
   658           <xsl:choose>
       
   659             <xsl:when test="$dx &lt; -1">100%</xsl:when>
       
   660             <xsl:when test="$dx &gt;= 0">0%</xsl:when>
       
   661             <xsl:otherwise><xsl:value-of select="-$dx * 100"/>%</xsl:otherwise>          
       
   662           </xsl:choose>
       
   663        </xsl:attribute>
       
   664         <xsl:attribute  name="x2">
       
   665           <xsl:choose>
       
   666             <xsl:when test="$dx &gt; 1">100%</xsl:when>
       
   667             <xsl:when test="$dx &lt;= 0">0%</xsl:when>
       
   668             <xsl:otherwise><xsl:value-of select="$dx * 100"/>%</xsl:otherwise>          
       
   669           </xsl:choose>
       
   670        </xsl:attribute>
       
   671         <xsl:attribute  name="y1">
       
   672           <xsl:choose>
       
   673             <xsl:when test="$dy &lt; -1">100%</xsl:when>
       
   674             <xsl:when test="$dy &gt;= 0">0%</xsl:when>
       
   675             <xsl:otherwise><xsl:value-of select="-$dy * 100"/>%</xsl:otherwise>          
       
   676           </xsl:choose>
       
   677        </xsl:attribute>
       
   678         <xsl:attribute  name="y2">
       
   679           <xsl:choose>
       
   680             <xsl:when test="$dy &gt;1">100%</xsl:when>
       
   681             <xsl:when test="$dy &lt;= 0">0%</xsl:when>
       
   682             <xsl:otherwise><xsl:value-of select="$dy * 100"/>%</xsl:otherwise>          
       
   683           </xsl:choose>
       
   684        </xsl:attribute>  
       
   685       </xsl:if>
       
   686 </xsl:template>
       
   687 
       
   688 <xsl:template name="gradient-angle"> <!-- calaulate the x1, etc attrbiutes from the dir ratio string. clip each to the range -1..1 -->
       
   689   <xsl:param name="theta" select="0"/>
       
   690 	<xsl:call-template name="gradient-direction">
       
   691 	  <xsl:with-param name="dx" select="m:cos($theta * m:constant('PI',6) div 180)"/>
       
   692 	  <xsl:with-param name="dy" select="-m:sin($theta * m:constant('PI',6) div 180)"/>
       
   693 	</xsl:call-template>
       
   694 </xsl:template>
       
   695 
       
   696 
       
   697 <!-- provide a gradient of multiple colours for the fill of an item -->
       
   698 <xsl:template name="multi-color-grad">
       
   699 	<xsl:param name="c" /> <!--  nodeset of either values or values to look up in $key -->
       
   700 	<xsl:param name="key" /> <!-- the style ID to lookup the value. Optional. If not set, the value of $c is the value -->
       
   701 	<xsl:param name="blur" /> <!-- % to blur 100% mean to blur to the full size of each gradient section -->
       
   702 	<xsl:param name="dir" /> <!-- direction ratio in the form dx:dy, where each has a range from -1..1 -->
       
   703 	<xsl:param name="angle" /> <!-- angle : use this instead of dir when possible -->
       
   704 	<xsl:if test="($key!='' and count(key($key,$c)/@value) &gt; 1) or ($key='' and count($c) &gt; 1)  "><!-- only define if there's more than one match -->
       
   705 		<linearGradient>
       
   706 	        <xsl:attribute  name="id">bg<xsl:apply-templates select="." mode="id"/></xsl:attribute>
       
   707 			<xsl:choose>
       
   708 				<xsl:when test="function-available('m:sin') and function-available('m:cos') and function-available('m:constant') and $angle!=''">
       
   709 					<xsl:call-template name="gradient-angle">
       
   710 						<xsl:with-param name="theta" select="$angle" />
       
   711 					</xsl:call-template>
       
   712 				</xsl:when>
       
   713 				<xsl:otherwise>
       
   714 					<xsl:call-template name="gradient-direction">
       
   715 					  <xsl:with-param name="dx" select="substring-before($dir,':')"/>
       
   716 					  <xsl:with-param name="dy" select="substring-after($dir,':')"/>
       
   717 					</xsl:call-template>
       
   718 				</xsl:otherwise>
       
   719 			</xsl:choose>
       
   720 			<xsl:variable name="blur0" select="$blur div count($c)" />
       
   721 			<xsl:for-each select="$c">
       
   722 				<xsl:sort />
       
   723 				<xsl:variable name="value">
       
   724 					<xsl:choose>
       
   725 						<xsl:when test="$key=''"><xsl:value-of select="."/></xsl:when>
       
   726 						<xsl:otherwise><xsl:value-of select="key($key,.)/@value"/></xsl:otherwise>
       
   727 					</xsl:choose>
       
   728 				 </xsl:variable>
       
   729 				<stop offset="{100* (position()-1) div  last() + $blur0}%" stop-color="{$value}" />
       
   730 				<xsl:if test="position()!=last()">
       
   731 					<stop offset="{100* position() div  last() - $blur0}%" stop-color="{$value}" />
       
   732 				</xsl:if>
       
   733 			</xsl:for-each>
       
   734 		</linearGradient>
       
   735 	</xsl:if>
       
   736 </xsl:template>
       
   737 <xsl:template mode="multi-color" match="*" priority="-1"/> <!-- this is handled in the generated XSLT, so do nothing by default -->
       
   738 
       
   739 <xsl:template mode="multi-color" match="*[generator-color]">
       
   740   <xsl:call-template name="multi-color-grad">
       
   741    <xsl:with-param name="key" select="'styled'"/>
       
   742    <xsl:with-param name="c" select="generator-color/@ref"/>
       
   743    <xsl:with-param name="blur" select="0"/>
       
   744   </xsl:call-template>
       
   745 </xsl:template>
       
   746 
       
   747 <!-- ============ utilities ============ -->
       
   748 
       
   749 <xsl:template name="sum-list"><xsl:param name="list"/> <!--  space-separated and terminated -->
       
   750 	<xsl:variable name="cur" select="substring-before($list,' ')"/>
       
   751 	<xsl:variable name="next" select="substring-after($list,' ')"/>
       
   752 	<xsl:variable name="add"><xsl:choose>
       
   753 		<xsl:when test="$next=''">0</xsl:when>
       
   754 		<xsl:otherwise><xsl:call-template name="sum-list">
       
   755 			<xsl:with-param name="list" select="$next"/>
       
   756 		</xsl:call-template></xsl:otherwise>
       
   757 	</xsl:choose></xsl:variable>
       
   758 	<xsl:value-of select="$cur + $add"/>
       
   759 </xsl:template>
       
   760 
       
   761 
       
   762 <xsl:template name="max-from-list"><xsl:param name="list"/>
       
   763 	<xsl:variable name="cur" select="substring-before($list,' ')"/>
       
   764 	<xsl:variable name="next" select="substring-after($list,' ')"/>
       
   765 	<xsl:variable name="max"><xsl:choose>
       
   766 		<xsl:when test="$next=''">0</xsl:when>
       
   767 		<xsl:otherwise><xsl:call-template name="max-from-list">
       
   768 			<xsl:with-param name="list" select="$next"/>
       
   769 		</xsl:call-template></xsl:otherwise>
       
   770 	</xsl:choose></xsl:variable>
       
   771 	<xsl:choose>
       
   772 		<xsl:when test="$cur &gt; $max"><xsl:value-of select="$cur"/></xsl:when>
       
   773 		<xsl:otherwise><xsl:value-of select="$max"/></xsl:otherwise>
       
   774 	</xsl:choose>
       
   775 </xsl:template>
       
   776 
       
   777 
       
   778 <xsl:template name="min-from-list"><xsl:param name="list"/>
       
   779 	<xsl:variable name="cur" select="substring-before($list,' ')"/>
       
   780 	<xsl:variable name="next" select="substring-after($list,' ')"/>
       
   781 	<xsl:variable name="min"><xsl:choose>
       
   782 		<xsl:when test="$next=''"><xsl:value-of select="$cur + 1"/></xsl:when>
       
   783 		<xsl:otherwise><xsl:call-template name="min-from-list">
       
   784 			<xsl:with-param name="list" select="$next"/>
       
   785 		</xsl:call-template></xsl:otherwise>
       
   786 	</xsl:choose></xsl:variable>
       
   787 	<xsl:choose>
       
   788 		<xsl:when test="$cur &lt; $min"><xsl:value-of select="$cur"/></xsl:when>
       
   789 		<xsl:otherwise><xsl:value-of select="$min"/></xsl:otherwise>
       
   790 	</xsl:choose>
       
   791 </xsl:template>
       
   792 
       
   793 
       
   794 <!-- returns the first smallest value -->
       
   795 <xsl:template name="min-from-list-with-index"><xsl:param name="list"/><xsl:param name="start" select="0"/>
       
   796 	<xsl:variable name="cur" select="substring-before($list,' ')"/>
       
   797 	<xsl:variable name="next" select="substring-after($list,' ')"/>
       
   798 	<xsl:variable name="min"><xsl:choose>
       
   799 		<xsl:when test="$next=''"><xsl:value-of select="concat($cur,':',$start)"/></xsl:when>
       
   800 		<xsl:otherwise><xsl:call-template name="min-from-list-with-index">
       
   801 			<xsl:with-param name="list" select="$next"/>
       
   802 			<xsl:with-param name="start" select="$start + 1"/>
       
   803 		</xsl:call-template></xsl:otherwise>
       
   804 	</xsl:choose></xsl:variable>
       
   805 	<xsl:choose>
       
   806 		<xsl:when test="$cur &lt;= substring-before($min,':')"><xsl:value-of select="concat($cur,':',$start)"/></xsl:when>
       
   807 		<xsl:otherwise><xsl:value-of select="$min"/></xsl:otherwise>
       
   808 	</xsl:choose>
       
   809 </xsl:template>
       
   810 
       
   811 <xsl:template name="list-range"><xsl:param name="list"/><xsl:param name="from" select="0"/><xsl:param name="to"/>
       
   812 	<xsl:if test="$from &lt; 1"><xsl:value-of select="concat(substring-before($list,' '),' ' )"/></xsl:if>
       
   813 	<xsl:if test="$to &gt; 0">
       
   814 		<xsl:call-template name="list-range">
       
   815 			<xsl:with-param name="list" select="substring-after($list,' ')"/>
       
   816 			<xsl:with-param name="from" select="$from - 1"/>
       
   817 			<xsl:with-param name="to" select="$to - 1"/>
       
   818 		</xsl:call-template>
       
   819 	</xsl:if>
       
   820 </xsl:template>
       
   821 
       
   822 <!-- modes:
       
   823 
       
   824 n-levels:	the number of levels available to children of that item
       
   825 level-range: 	the bottom and top level this item spans in its parent
       
   826 -->
       
   827 
       
   828 <xsl:template mode="validate" match="node()" priority="-4"/>
       
   829 <xsl:template mode="validate" match="*" priority="-2"><xsl:apply-templates mode="validate" select="*"/></xsl:template>
       
   830 
       
   831 <!-- ====== Components ============= -->
       
   832 
       
   833 <xsl:template match="*" mode="display-style-color" priority="-2"/>
       
   834 <xsl:template match="*" mode="animate-color" priority="-2"/><!-- change back to -2 to enable -->
       
   835 
       
   836 
       
   837 <xsl:template match="*[@generator-color]" mode="animate-color" priority="4">
       
   838 	<xsl:if test="not($Static)">
       
   839 		<set attributeName="opacity" attributeType="XML" to="0.5" fill="remove" begin="{@generator-color}.mouseover" end="{@generator-color}.mouseout"/>		
       
   840 	</xsl:if>
       
   841 </xsl:template>
       
   842 <xsl:template match="*[generator-color]" mode="animate-color" priority="4">
       
   843 	<xsl:if test="not($Static)">
       
   844 		<xsl:for-each select="generator-color">
       
   845 			<set attributeName="opacity" attributeType="XML" to="0.5" fill="remove" begin="{@ref}.mouseover" end="{@ref}.mouseout"/>		
       
   846 		</xsl:for-each>
       
   847 	</xsl:if>
       
   848 </xsl:template>
       
   849 
       
   850 <!-- for legend-copy generated legend items -->
       
   851 
       
   852 <xsl:template match="cmp[@generated-color]" mode="display-style-color" priority="8"><!-- colour in legend -->
       
   853 	<xsl:value-of select="@generated-color"/>
       
   854 </xsl:template>
       
   855 
       
   856 <xsl:template match="cmp[@generated-overlay]" mode="overlay-style" priority="8">
       
   857 	<xsl:text>fill: url(</xsl:text>
       
   858 	<xsl:value-of select="@generated-overlay"/>
       
   859 	<xsl:text>); stroke: none; stroke-width: 0;</xsl:text>
       
   860 </xsl:template>
       
   861 
       
   862 <xsl:template match="cmp[@generated-border]" mode="shape" priority="8">
       
   863 	<xsl:value-of select="@generated-border"/>
       
   864 </xsl:template>
       
   865 
       
   866 <xsl:template match="cmp[@generated-text-highlight]" mode="text-filter"  priority="8">
       
   867 		<xsl:attribute name="filter">url(<xsl:value-of select="@generated-text-highlight"/>)</xsl:attribute>
       
   868 </xsl:template>
       
   869 
       
   870 <xsl:template match="cmp[@generated-highlight]" mode="filter" priority="8">
       
   871 	<xsl:attribute name="filter">url(<xsl:value-of select="@generated-highlight"/>)</xsl:attribute>
       
   872 </xsl:template>
       
   873 
       
   874 <!-- end legend-copy  items -->
       
   875 
       
   876 <xsl:template match="cmp" mode="display-style">
       
   877 	<xsl:variable name="color"><xsl:apply-templates select="." mode="display-style-color"/></xsl:variable>
       
   878 	<xsl:if test="$color!=''">fill:<xsl:value-of select="$color"/>;</xsl:if>
       
   879 	<xsl:for-each select="@generated-style | generated-style/@value"><xsl:value-of select="."/>;</xsl:for-each>
       
   880 	<xsl:apply-templates select="." mode="display-style-aux"/>
       
   881 </xsl:template>
       
   882 
       
   883 <!--  generated overrides -->
       
   884   
       
   885 
       
   886 <xsl:template match="*[@generator-color]" mode="display-style-color" priority="8">
       
   887 	<xsl:for-each select="key('styled',@generator-color)">
       
   888 		<xsl:value-of select="@value | @default"/>	<!-- can't have both -->
       
   889 	</xsl:for-each>
       
   890 </xsl:template>
       
   891 
       
   892 
       
   893 <xsl:template match="*[count(generator-color)=1]" mode="display-style-color" priority="8">
       
   894 	<xsl:for-each select="key('styled',generator-color/@ref)">
       
   895 		<xsl:value-of select="@value | @default"/>	<!-- can't have both -->
       
   896 	</xsl:for-each>
       
   897 </xsl:template>
       
   898 
       
   899 <xsl:template match="*[count(generator-color) &gt; 1]" mode="display-style-color" priority="8">
       
   900 	<xsl:variable name="ref" select="key('styled',generator-color/@ref)"/>
       
   901 	<xsl:choose>
       
   902 		<xsl:when test="count($ref/@value)=1">
       
   903 			<xsl:value-of select="$ref/@value"/>
       
   904 		</xsl:when>
       
   905 		<xsl:when test="count($ref/@value)=0">
       
   906 			<xsl:value-of select="$ref/@default[last()]"/>
       
   907 		</xsl:when>
       
   908 		<xsl:otherwise>
       
   909 			<xsl:text>url(#bg</xsl:text><xsl:apply-templates select="." mode="id"/><xsl:text>)</xsl:text>
       
   910 		</xsl:otherwise>
       
   911 	</xsl:choose>
       
   912 </xsl:template>
       
   913 
       
   914 
       
   915 <xsl:template match="*[@generator-text-highlight]" mode="text-filter"  priority="8">
       
   916 		<xsl:attribute name="filter">url(<xsl:for-each select="key('styled',@generator-text-highlight)">
       
   917 		<xsl:value-of select="@value | @default"/>	<!-- can't have both -->
       
   918 	</xsl:for-each>)</xsl:attribute>
       
   919 </xsl:template>
       
   920 
       
   921 <xsl:template match="*[@generator-highlight]" mode="filter" priority="8">
       
   922 	<xsl:attribute name="filter">url(<xsl:for-each select="key('styled',@generator-highlight)">
       
   923 		<xsl:value-of select="@value | @default"/>	<!-- can't have both -->
       
   924 	</xsl:for-each>)</xsl:attribute>
       
   925 </xsl:template>
       
   926 
       
   927 <xsl:template match="*[@generator-overlay]" mode="overlay-style" priority="8">
       
   928 	<xsl:text>fill: url(</xsl:text>
       
   929 	<xsl:for-each select="key('styled',@generator-overlay)">
       
   930 		<xsl:value-of select="@value | @default"/>	<!-- can't have both -->
       
   931 	</xsl:for-each>	
       
   932 	<xsl:text>); stroke: none; stroke-width: 0;</xsl:text>
       
   933 </xsl:template>
       
   934 
       
   935 <xsl:template match="*[@generator-border]" mode="shape" priority="8">
       
   936 	<xsl:for-each select="key('styled',@generator-border)">
       
   937 		<xsl:value-of select="@value | @default"/>	<!-- can't have both -->
       
   938 	</xsl:for-each>
       
   939 </xsl:template>
       
   940 
       
   941 <xsl:template match="*" mode="display-style">
       
   942 	<xsl:variable name="color"><xsl:apply-templates select="." mode="display-style-color"/></xsl:variable>
       
   943 	<xsl:if test="$color!=''">fill:<xsl:value-of select="$color"/>;</xsl:if>
       
   944 	<xsl:for-each select="@generator-style | generator-style/@ref">
       
   945 		<xsl:for-each select="key('styled',.)">
       
   946 			<xsl:value-of select="concat(@value | @default,';')"/><!-- can't have both -->
       
   947 		</xsl:for-each>
       
   948 	</xsl:for-each>
       
   949 	<xsl:apply-templates select="." mode="display-style-aux"/>
       
   950 
       
   951 </xsl:template>
       
   952   
       
   953 <!--  defaults -->
       
   954   
       
   955 <xsl:template match="*" mode="display-style-aux" priority="-2"/>
       
   956 <xsl:template match="component" mode="display-style-aux" priority="-1">stroke-width:<xsl:choose>
       
   957 	<xsl:when test="@plugin">2</xsl:when>
       
   958 	<xsl:otherwise>0.4</xsl:otherwise>
       
   959 </xsl:choose>;</xsl:template>
       
   960 
       
   961 <xsl:template match="component" mode="display-style-color" priority="-1">
       
   962 	<xsl:variable name="c"><xsl:value-of select="key('color',@ts)/@color"/></xsl:variable>
       
   963 	<xsl:choose>
       
   964 		<xsl:when test="$c!=''"><xsl:value-of select="$c"/></xsl:when>
       
   965 		<xsl:otherwise>grey</xsl:otherwise>
       
   966 	</xsl:choose>
       
   967 </xsl:template>
       
   968 
       
   969 
       
   970 <xsl:template match="component" mode="overlay-style" priority="-2"> <!-- since deprecated, replaced with introduced -->
       
   971 	<xsl:if test="@introduced = //systemModel/@ver or @since = //systemModel/@ver or @ref">
       
   972 		<xsl:text>fill:</xsl:text>
       
   973 		<xsl:choose>
       
   974 			<xsl:when test="@since = //systemModel/@ver">url(#Patternradial-grad)</xsl:when> <!-- to be removed -->
       
   975 			<xsl:when test="@introduced = //systemModel/@ver">url(#Patternradial-grad)</xsl:when>
       
   976 			<xsl:when test="@ref">url(#Patternstriped-diag-up)</xsl:when>
       
   977 			<xsl:otherwise>none</xsl:otherwise>
       
   978 		</xsl:choose>
       
   979 		<xsl:text>; stroke: none; stroke-width: 0;</xsl:text>
       
   980 	</xsl:if>
       
   981 </xsl:template>
       
   982 
       
   983 
       
   984 <xsl:template match="component|cmp" mode="overlay-style" priority="-3">fill: none; stroke: none; stroke-width: 0;</xsl:template>
       
   985 
       
   986 <xsl:template match="component|cmp" mode="shape" priority="-1">#Borderbox<xsl:choose>
       
   987       <xsl:when test="self::cmp"/>
       
   988       <xsl:when test="s12/@osd='CS'">-clipLB</xsl:when>
       
   989       <xsl:when test="s12/@osd='OS'">-clipLT</xsl:when>
       
   990       <xsl:when test="s12/@osd='CR'">-clipRB</xsl:when>
       
   991       <xsl:when test="s12/@osd='OR'">-clipRT</xsl:when>
       
   992       <xsl:when test="s12/@osd='T-R'">-clipAll</xsl:when>
       
   993 	</xsl:choose>
       
   994 </xsl:template>
       
   995 
       
   996 
       
   997 <xsl:template match="component|cmp">
       
   998 	<xsl:param name="spacing" select="0"/>
       
   999 	<xsl:variable name="x-pos" select="($cSize + $spacing) * (position() - 1)"/>
       
  1000 	<g class="component"><xsl:apply-templates select="." mode="filter"/>
       
  1001 		<xsl:attribute name="id"><xsl:apply-templates select="." mode="id"/></xsl:attribute>
       
  1002 		<xsl:if test="parent::collection">
       
  1003 			<xsl:apply-templates select="." mode="animate-color"/>
       
  1004 	        <xsl:apply-templates select="." mode="multi-color"/>			
       
  1005 		</xsl:if>
       
  1006 		<xsl:variable name="ref"><xsl:apply-templates select="." mode="shape"/></xsl:variable>
       
  1007 		<use width="{$cSize}" height="{$cSize}" x="{$x-pos}" y="0" xlink:href="{$ref}">
       
  1008 			<xsl:variable name="style"><xsl:apply-templates select="." mode="display-style"/></xsl:variable>
       
  1009 			<xsl:if test="string-length($style) &gt; 1">
       
  1010 				<xsl:attribute name="style"><xsl:value-of select="$style"/></xsl:attribute>
       
  1011 			</xsl:if>
       
  1012 		</use>
       
  1013 		<xsl:variable name="overlay"><xsl:apply-templates select="." mode="overlay-style"/></xsl:variable>
       
  1014 		<xsl:if test="$overlay!=''">
       
  1015 			<use width="{$cSize}" height="{$cSize}" x="{$x-pos}" y="0" style="{$overlay}" xlink:href="{$ref}"/>
       
  1016 		</xsl:if>
       
  1017 		<xsl:call-template name="linkable-content">
       
  1018 			<xsl:with-param name="show">
       
  1019 				<text text-anchor="middle" dominant-baseline="mathematical"  class="component" y="4.8">
       
  1020 					<xsl:attribute name="x"><xsl:value-of select="$x-pos + 0.5 * $cSize"/></xsl:attribute>
       
  1021 					<xsl:apply-templates select="." mode="wrap"><xsl:with-param name="w" select="$cSize"/></xsl:apply-templates>
       
  1022 					<xsl:call-template name="display-name"/>
       
  1023 				</text>
       
  1024 			</xsl:with-param>
       
  1025 		</xsl:call-template>
       
  1026 	</g>
       
  1027 </xsl:template>
       
  1028 
       
  1029 
       
  1030 <xsl:template match="component|cmp" mode="wrap"><xsl:param name="w"/>
       
  1031 	<xsl:variable name="s"><xsl:call-template name="name-value"/></xsl:variable>
       
  1032 	<!-- 7 is a pretty arbitrary limit. But not bad -->
       
  1033 	<xsl:if test=" string-length($s) &gt; 7"><xsl:attribute name="width"><xsl:value-of select="$w"/></xsl:attribute></xsl:if>
       
  1034 </xsl:template>
       
  1035 
       
  1036 <!-- ====== Collections ============= -->
       
  1037 
       
  1038 <xsl:template match="collection" mode="height"><xsl:value-of select="$mSize"/></xsl:template>
       
  1039 
       
  1040 <xsl:template match="collection" mode="width">
       
  1041 	<xsl:variable name="num" select="count(component)"/>
       
  1042 	<xsl:choose>
       
  1043 		<xsl:when test="$Detail=name() and /SystemDefinition/systemModel/@detail-type='fixed'">
       
  1044 			<xsl:value-of select="$mSize"/>
       
  1045 		</xsl:when>
       
  1046 		<xsl:when test="$num=0">0</xsl:when>	
       
  1047 		<xsl:when test="$num=1"><xsl:value-of select="$mSize"/></xsl:when> <!-- cannot be thinner than square-->
       
  1048 		<xsl:otherwise><xsl:value-of select="$num * $cSize"/></xsl:otherwise>
       
  1049 	</xsl:choose>
       
  1050 </xsl:template>
       
  1051 
       
  1052 <xsl:template match="collection"><xsl:param name="levels"/>
       
  1053 	<xsl:variable name="w" ><xsl:apply-templates mode="width"  select="."/></xsl:variable>
       
  1054 	<xsl:variable name="index"><xsl:apply-templates select="." mode="level-index"/></xsl:variable>
       
  1055 
       
  1056 	<xsl:variable name="y">
       
  1057 		<xsl:call-template name="level-top">
       
  1058 			<xsl:with-param name="index" select="$index"/>
       
  1059 		</xsl:call-template>
       
  1060 	</xsl:variable>
       
  1061 	<xsl:variable name="x">
       
  1062 		<xsl:call-template name="x-pos">
       
  1063 			<xsl:with-param name="levels" select="$levels"/>
       
  1064 			<xsl:with-param name="range" select="concat($index,' ',$index)"/>
       
  1065 		</xsl:call-template>
       
  1066 	</xsl:variable>
       
  1067 	
       
  1068 	<g class="{name()}"><xsl:apply-templates select="." mode="filter"/>
       
  1069 		<xsl:attribute name="id"><xsl:apply-templates select="." mode="id"/></xsl:attribute>
       
  1070 		<xsl:attribute name="transform">translate(<xsl:value-of select="concat($x,' ',$y)"/>)</xsl:attribute>
       
  1071 		<xsl:apply-templates select="." mode="detail-stuff"><xsl:with-param name="s" select="'mouseover'"/></xsl:apply-templates>
       
  1072 		<xsl:apply-templates select="." mode="animate-color"/>
       
  1073         <xsl:apply-templates select="." mode="multi-color"/>
       
  1074 		<rect class="{name()}" x="0" y="0" height="{$mSize}" width="{$w}">
       
  1075 			<xsl:call-template name="styles"/>
       
  1076 		</rect>
       
  1077 		<xsl:call-template name="linkable-content">
       
  1078 			<xsl:with-param name="show">
       
  1079 				<text  text-anchor="start" dominant-baseline="hanging" class="collection" y="0.4" x="1.4">
       
  1080 					<xsl:apply-templates select="." mode="detail-stuff"><xsl:with-param name="s" select="'text'"/></xsl:apply-templates>
       
  1081 					<xsl:attribute name="width"><xsl:value-of select="$w - 1.4"/></xsl:attribute>
       
  1082 					<xsl:if test="$Detail='collection' ">
       
  1083 						<xsl:attribute name='text-anchor'>middle</xsl:attribute>
       
  1084 						<xsl:attribute name='x'><xsl:value-of select="$w * 0.5"/></xsl:attribute>
       
  1085 						<xsl:attribute name='dominant-baseline'>mathematical</xsl:attribute>						
       
  1086 						<xsl:attribute name="y"><xsl:value-of select="$mSize * 0.5"/></xsl:attribute>
       
  1087 					</xsl:if>
       
  1088 					<xsl:call-template name="display-name"/>
       
  1089 				</text>
       
  1090 			</xsl:with-param>
       
  1091 		</xsl:call-template>
       
  1092 		<g transform="translate(0 {$mSize - $cSize})">
       
  1093 			<xsl:apply-templates select="." mode="detail-stuff"/>
       
  1094 			<xsl:apply-templates select="*"/>
       
  1095 		</g>
       
  1096 	</g>
       
  1097 	<xsl:apply-templates select="following-sibling::*[1]">
       
  1098 		<xsl:with-param name="levels">
       
  1099 			<xsl:call-template name="sum-levels">
       
  1100 				<xsl:with-param name="levels" select="$levels"/>
       
  1101 				<xsl:with-param name="range" select="concat($index,' ',$index)"/>
       
  1102 				<xsl:with-param name="width" select="$w"/>
       
  1103 			</xsl:call-template>
       
  1104 		</xsl:with-param>
       
  1105 	</xsl:apply-templates>
       
  1106 </xsl:template>
       
  1107 
       
  1108 <xsl:template match="collection" mode="post-levels"><xsl:param name="levels"/>
       
  1109 	<xsl:variable name="index"><xsl:apply-templates select="." mode="level-index"/></xsl:variable>
       
  1110 	<xsl:variable name="next">
       
  1111 		<xsl:call-template name="sum-levels">
       
  1112 			<xsl:with-param name="levels" select="$levels"/>
       
  1113 			<xsl:with-param name="range" select="concat($index,' ',$index)"/>
       
  1114 			<xsl:with-param name="width"><xsl:apply-templates mode="width"  select="."/></xsl:with-param>
       
  1115 		</xsl:call-template>
       
  1116 	</xsl:variable>
       
  1117 	
       
  1118 	<xsl:if test="not(following-sibling::*)"><xsl:value-of select="$next"/></xsl:if>
       
  1119 	<xsl:apply-templates select="following-sibling::*[1]" mode="post-levels">
       
  1120 		<xsl:with-param name="levels" select="$next"/>
       
  1121 	</xsl:apply-templates>
       
  1122 </xsl:template>
       
  1123 
       
  1124 
       
  1125 <!-- if no levels, it can only be at index 0 -->
       
  1126 <xsl:template match="collection[not(ancestor::*[@levels])]" mode="level-index" priority="4">0</xsl:template>
       
  1127 
       
  1128 
       
  1129 <xsl:template match="collection[not(@level) and ancestor::block[@level and not(@levels)]]" mode="level-index" priority="3">
       
  1130 	<!-- this is in a block with a level (but no levels), so use that level -->
       
  1131 	<xsl:for-each select="ancestor::block">
       
  1132 		<xsl:call-template name="level-index"/>
       
  1133 	</xsl:for-each>
       
  1134 </xsl:template>
       
  1135 
       
  1136 <xsl:template match="collection[not(@level)]" mode="level-index" priority="2">
       
  1137 	<!-- this has an ancestor with levels, so this is on the (extra) top level -->
       
  1138 	<xsl:variable name="n"><xsl:apply-templates select="ancestor::*[@levels][1]" mode="n-levels"/></xsl:variable> <!-- n = number of levels this collection can see -->
       
  1139 	<xsl:value-of select="$n - 1"/>
       
  1140 	<!-- warning: no level -->
       
  1141 </xsl:template>
       
  1142 
       
  1143 <xsl:template mode="validate" match="collection[not(@level) and ancestor::*[@levels] and not(ancestor::block[@level])]">
       
  1144 	<xsl:call-template name="Caller-Warning"><xsl:with-param name="text">
       
  1145 		<xsl:value-of select="name()"/> with no level (<xsl:value-of select="@name"/>)</xsl:with-param></xsl:call-template>
       
  1146 </xsl:template>
       
  1147 
       
  1148 <xsl:template mode="validate" match="collection[not(@level) and ancestor::block[@level]]">
       
  1149 	<xsl:if test="$Verbose">
       
  1150 		<xsl:call-template name="Caller-Note"><xsl:with-param name="text">
       
  1151 			<xsl:value-of select="name()"/> with no level (<xsl:value-of select="@name"/>) given same level as parent</xsl:with-param></xsl:call-template>
       
  1152 	</xsl:if>
       
  1153 </xsl:template>
       
  1154 
       
  1155 <!--xsl:template mode="validate" match="collection[@level and not(contains(ancestor::*/@levels,'level'))]">
       
  1156 	<xsl:message>&#xa;Error: invalid level on <xsl:value-of select="name()"/> (<xsl:value-of select="@name"/>)</xsl:message>
       
  1157 </xsl:template-->
       
  1158 
       
  1159 <xsl:template match="collection" mode="level-index">
       
  1160 	<!-- thiis has a level and an ancestor with levels -->
       
  1161 	<xsl:call-template name="level-index"/>
       
  1162 </xsl:template>
       
  1163 
       
  1164 <!-- ====== Sub-blocks ============= -->
       
  1165 
       
  1166 <xsl:template match="subblock[/SystemDefinition/systemModel/@detail-type='fixed' and $Detail=name()]" priority="5" mode="width">
       
  1167 	<xsl:value-of select="$mSize * 3"/>
       
  1168 </xsl:template>
       
  1169 
       
  1170 <xsl:template match="block[/SystemDefinition/systemModel/@detail-type='fixed' and $Detail=name()]" priority="5" mode="width">
       
  1171 	<xsl:value-of select="$mSize * 5"/>
       
  1172 </xsl:template>
       
  1173 
       
  1174 <xsl:template match="block[/SystemDefinition/systemModel/@detail-type='fixed' and not(subblock) and ($Detail='subblock')]" priority="5" mode="width">
       
  1175 	<xsl:value-of select="$mSize * 3"/>
       
  1176 </xsl:template>
       
  1177 
       
  1178 <xsl:template match="subblock|block" mode="width">
       
  1179 	<xsl:variable name="n"><xsl:apply-templates mode="n-levels" select="."/></xsl:variable>
       
  1180 	<xsl:variable name="levels">	
       
  1181 		<xsl:apply-templates select="*[1]" mode="post-levels">
       
  1182 			<xsl:with-param name="levels">
       
  1183 				<xsl:call-template name="zeros">
       
  1184 					<xsl:with-param name="n" select="$n"/>
       
  1185 				</xsl:call-template>
       
  1186 			</xsl:with-param>
       
  1187 		</xsl:apply-templates>
       
  1188 	</xsl:variable>
       
  1189 	<xsl:variable name="w-base">
       
  1190 		<xsl:call-template name="max-from-list">
       
  1191 			<xsl:with-param name="list" select="$levels"/>	
       
  1192 		</xsl:call-template>
       
  1193 	</xsl:variable>
       
  1194 
       
  1195 	<xsl:variable name="range">
       
  1196 		<xsl:choose>
       
  1197 			<xsl:when test="@levels">0 <xsl:value-of select="$n - 1"/></xsl:when>
       
  1198 			<xsl:otherwise><xsl:apply-templates select="." mode="level-range"/></xsl:otherwise>
       
  1199 		</xsl:choose>
       
  1200 	</xsl:variable>
       
  1201 	<xsl:variable name="r0" select="number(substring-before($range,' '))"/>		
       
  1202 	<xsl:variable name="min">
       
  1203 		<xsl:call-template name="min-from-list-with-index">
       
  1204 			<xsl:with-param name="list">
       
  1205 				<xsl:call-template name="list-range">
       
  1206 					<xsl:with-param name="list" select="$levels"/>
       
  1207 					<xsl:with-param name="from" select="$r0"/>
       
  1208 					<xsl:with-param name="to" select="substring-after($range,' ')"/>
       
  1209 				</xsl:call-template>
       
  1210 			</xsl:with-param>
       
  1211 		</xsl:call-template>
       
  1212 	</xsl:variable>
       
  1213 	<xsl:variable name="min-label-width">
       
  1214 		<xsl:apply-templates select="." mode="min-label-width"/>
       
  1215 	</xsl:variable>
       
  1216 	<xsl:variable name="min-level-width" select="substring-before($min,':')"/>
       
  1217 	<xsl:choose>
       
  1218 		<xsl:when test="($w-base - $min-level-width) &lt; $min-label-width"><xsl:value-of select="$min-level-width +  $min-label-width"/></xsl:when>
       
  1219 		<xsl:when test="/SystemDefinition/systemModel/@detail-type='fixed' and ($Detail='collection') and $w-base &lt; 2*$mSize">
       
  1220 			<xsl:value-of select="2*$mSize"/></xsl:when>
       
  1221 		<xsl:otherwise><xsl:value-of select="$w-base"/></xsl:otherwise>
       
  1222 	</xsl:choose>	
       
  1223 </xsl:template>
       
  1224 
       
  1225 <xsl:template match="subblock" mode="height">
       
  1226 	<xsl:variable name="range"><xsl:apply-templates select="." mode="level-range"/></xsl:variable>
       
  1227 	<xsl:variable name="r0" select="number(substring-before($range,' '))"/>	
       
  1228 	<xsl:variable name="r1" select="number(substring-after($range,' '))"/>
       
  1229 	<!-- height is from number of levels -->
       
  1230 	<xsl:value-of select="($r1 - $r0 + 1) * ($mSize +  $groupDy) - $groupDy"/>
       
  1231 </xsl:template>
       
  1232 
       
  1233 <!-- ============= range of levels ============= -->
       
  1234 
       
  1235 <!-- spans full height of parent, so uses parent's range -->
       
  1236 <xsl:template match="subblock" mode="level-range">
       
  1237 	<xsl:apply-templates select=".." mode="level-range"/>
       
  1238 </xsl:template>
       
  1239 <xsl:template match="block[@levels]/subblock" mode="level-range" priority="1">
       
  1240 	<xsl:variable name="n"><xsl:apply-templates mode="n-levels" select=".."/></xsl:variable>
       
  1241 	<xsl:value-of select="concat('0 ',$n - 1)"/>
       
  1242 </xsl:template>
       
  1243 
       
  1244 <xsl:template mode="n-levels" match="subblock">
       
  1245 	<xsl:apply-templates select=".." mode="n-levels"/>
       
  1246 </xsl:template>
       
  1247 <!-- ============= draw ============= -->
       
  1248 
       
  1249 <xsl:template match="subblock"><xsl:param name="levels"/> <!-- can contain only collections -->
       
  1250 	<xsl:variable name="width"><xsl:apply-templates select="." mode="width"/></xsl:variable>
       
  1251 	<xsl:variable name="range"><xsl:apply-templates select="." mode="level-range"/></xsl:variable>
       
  1252 	<xsl:variable name="r1" select="number(substring-after($range,' '))"/>	
       
  1253 	<xsl:variable name="x"><xsl:call-template name="x-pos">
       
  1254 			<xsl:with-param name="levels" select="$levels"/>
       
  1255 			<xsl:with-param name="range" select="$range"/>
       
  1256 		</xsl:call-template>
       
  1257 	</xsl:variable>
       
  1258 	<xsl:variable name="y">
       
  1259 		<xsl:call-template name="level-top">
       
  1260 			<xsl:with-param name="index" select="$r1"/>
       
  1261 		</xsl:call-template>
       
  1262 	</xsl:variable>	
       
  1263 	
       
  1264 	<g class="{name()}" transform="translate({$x})"><xsl:apply-templates select="." mode="filter"/>
       
  1265 		<xsl:attribute name="id"><xsl:apply-templates select="." mode="id"/></xsl:attribute>	
       
  1266 		<xsl:apply-templates select="." mode="detail-stuff"><xsl:with-param name="s" select="'mouseover'"/></xsl:apply-templates>		
       
  1267 		<xsl:attribute name="transform">translate( <xsl:value-of select="$x"/>)</xsl:attribute>
       
  1268 		<xsl:apply-templates select="." mode="animate-color"/>
       
  1269         <xsl:apply-templates select="." mode="multi-color"/>		
       
  1270 		<xsl:variable name="height"><xsl:apply-templates select="." mode="height"/></xsl:variable> 
       
  1271 		<rect class="{name()}" x="0" height="{$height}" width="{$width}" y ="{$y}">
       
  1272 			<xsl:if test="$Detail=name()">
       
  1273 				<!-- to make room for the block label -->
       
  1274 				<xsl:attribute name="height"><xsl:value-of select="$height - $detail-block-space"/></xsl:attribute>
       
  1275 			</xsl:if>
       
  1276 			<xsl:call-template name="styles"/>
       
  1277 		</rect>
       
  1278 
       
  1279 		<xsl:call-template name="linkable-content">
       
  1280 			<xsl:with-param name="show">		
       
  1281 				<!-- default is for not showing detail, since it's easy to calculate -->
       
  1282 				<text text-anchor="middle" class="subblock" dominant-baseline="mathematical" x="{$width * 0.5}" width="{$width}" y="{$y + 0.5 * ($height - $detail-block-space)}">
       
  1283 					<xsl:apply-templates select="." mode="detail-stuff"><xsl:with-param name="s" select="'text'"/></xsl:apply-templates>
       
  1284 					<xsl:apply-templates select="." mode="label">
       
  1285 						<xsl:with-param name="width" select="$width"/>
       
  1286 					</xsl:apply-templates>
       
  1287 					<xsl:call-template name="display-name"/>
       
  1288 				</text>
       
  1289 			</xsl:with-param>
       
  1290 		</xsl:call-template>
       
  1291 		<g><xsl:apply-templates select="." mode="detail-stuff"/>
       
  1292 			<xsl:apply-templates select="*[1]">
       
  1293 				<xsl:with-param name="levels">
       
  1294 					<xsl:call-template name="zeros"><xsl:with-param name="n" select="string-length($levels) - string-length(translate($levels,' ',''))"/></xsl:call-template>
       
  1295 				</xsl:with-param>
       
  1296 			</xsl:apply-templates>
       
  1297 		</g>	
       
  1298 	</g>	
       
  1299 	<xsl:apply-templates select="following-sibling::*[1]">
       
  1300 		<xsl:with-param name="levels">
       
  1301 			<xsl:call-template name="sum-levels">
       
  1302 				<xsl:with-param name="levels" select="$levels"/>
       
  1303 				<xsl:with-param name="range" select="$range"/>
       
  1304 				<xsl:with-param name="width" select="$width"/>
       
  1305 			</xsl:call-template>
       
  1306 		</xsl:with-param>
       
  1307 	</xsl:apply-templates>	
       
  1308 </xsl:template>
       
  1309 
       
  1310 
       
  1311 <xsl:template match="subblock" mode="post-levels"><xsl:param name="levels"/>
       
  1312 	<xsl:variable name="range"><xsl:apply-templates select="." mode="level-range"/></xsl:variable>
       
  1313 	<xsl:variable name="next">
       
  1314 		<xsl:call-template name="sum-levels">
       
  1315 			<xsl:with-param name="levels" select="$levels"/>
       
  1316 			<xsl:with-param name="range" select="$range"/>
       
  1317 			<xsl:with-param name="width"><xsl:apply-templates mode="width"  select="."/></xsl:with-param>
       
  1318 		</xsl:call-template>
       
  1319 	</xsl:variable>
       
  1320 	
       
  1321 	<xsl:if test="not(following-sibling::*)"><xsl:value-of select="$next"/></xsl:if>
       
  1322 	<xsl:apply-templates select="following-sibling::*[1]" mode="post-levels">
       
  1323 		<xsl:with-param name="levels" select="$next"/>
       
  1324 	</xsl:apply-templates>
       
  1325 </xsl:template>
       
  1326 
       
  1327 <xsl:template match="subblock" mode="min-label-width">
       
  1328 	<xsl:value-of select="$inlineLabel"/>
       
  1329 </xsl:template>
       
  1330 
       
  1331 <xsl:template match="subblock" mode="label"><xsl:param name="width"/>
       
  1332 	<xsl:call-template name="inline-label">
       
  1333 		<xsl:with-param name="width" select="$width"/>
       
  1334 	</xsl:call-template>
       
  1335 </xsl:template>
       
  1336 
       
  1337 <xsl:template match="subblock[$Detail=name()]" mode="label" priority="4"/>
       
  1338 
       
  1339 <!-- ====== Blocks  ============= -->
       
  1340 
       
  1341 <!-- height determined by: (in order) 
       
  1342 @levels => height of the levels
       
  1343 @span => eight spanned 
       
  1344 not(@levels) and not(@level) => full of parent
       
  1345 -->
       
  1346 
       
  1347 
       
  1348 
       
  1349 	<!-- min-height is always independent of parent -->
       
  1350 <xsl:template match="block[@levels]" mode="min-height" priority="6">
       
  1351 	<xsl:variable name="h"><xsl:apply-templates mode="level-heights" select="."/></xsl:variable>
       
  1352 	<xsl:call-template name="sum-list">
       
  1353 		<xsl:with-param name="list">
       
  1354 			<xsl:value-of select="$groupDy * (string-length($h)  - string-length(translate($h,' ','')) - 1)"/> <!-- spacing between levels: needed? -->
       
  1355 			<xsl:value-of select="concat(' ',$h)"/>
       
  1356 		</xsl:with-param>
       
  1357 	</xsl:call-template>
       
  1358 </xsl:template>
       
  1359 
       
  1360 <xsl:template match="block" mode="min-height" priority="5">
       
  1361 	<xsl:variable name="range"><xsl:apply-templates select="." mode="level-range"/></xsl:variable>
       
  1362 	<xsl:variable name="n" select="number(substring-after($range,' ')) - number(substring-before($range,' ')) + 1"/>
       
  1363 	<xsl:value-of select="$n * ($mSize + $groupDy)  - $groupDy "/>
       
  1364 </xsl:template>
       
  1365 
       
  1366 <!-- if a spanned layer contains just a single block, then increase the size to fill the entire layer -->
       
  1367 <xsl:template match="layer[@span &gt; 0]/block[not(@level) and count(../*)=1]" mode="max-height" priority="4">
       
  1368 	<xsl:variable name="h"><xsl:apply-templates mode="height" select=".."/></xsl:variable>
       
  1369 	<xsl:variable name="padding"><xsl:apply-templates select=".." mode="padding"/></xsl:variable>
       
  1370 	<xsl:value-of select="$h - substring-before($padding,' ') - substring-after($padding,' ')"/>
       
  1371 </xsl:template>
       
  1372 
       
  1373 
       
  1374 <!-- max-height is always dependent on parent -->
       
  1375 <xsl:template match="block" mode="max-height">
       
  1376 	<xsl:variable name="h">
       
  1377 		<xsl:apply-templates mode="level-heights" select="..">
       
  1378 			<xsl:with-param name="range">
       
  1379 				<xsl:apply-templates select="." mode="level-range"/>
       
  1380 			</xsl:with-param>
       
  1381 		</xsl:apply-templates>
       
  1382 	</xsl:variable>
       
  1383 	<xsl:call-template name="sum-list">
       
  1384 		<xsl:with-param name="list">
       
  1385 			<xsl:value-of select="$groupDy * (string-length($h)  - string-length(translate($h,' ','')) - 1)"/> <!-- spacing between levels: needed? -->
       
  1386 			<xsl:value-of select="concat(' ',$h)"/><!-- insert some border here-->
       
  1387 		</xsl:with-param>
       
  1388 	</xsl:call-template>	
       
  1389 </xsl:template>
       
  1390 
       
  1391 
       
  1392 	<!-- independent of parent -->
       
  1393 <xsl:template match="layer[not(@levels)]/block[@levels]" mode="height" priority="7">
       
  1394 	<xsl:call-template name="max-from-list">
       
  1395 		<xsl:with-param name="list">
       
  1396 			<xsl:for-each select="../block[@levels]">
       
  1397 				<xsl:apply-templates mode="min-height" select="."/><xsl:text> </xsl:text>
       
  1398 			</xsl:for-each>
       
  1399 		</xsl:with-param>
       
  1400 	</xsl:call-template>	
       
  1401 </xsl:template>
       
  1402 
       
  1403 	<!-- NOT independent of parent -->
       
  1404 <xsl:template match="block[@levels]" mode="height" priority="6">
       
  1405 	<xsl:variable name="h0"><xsl:apply-templates mode="min-height" select="."/></xsl:variable>
       
  1406 	<xsl:variable name="h1"><xsl:apply-templates mode="max-height" select="."/></xsl:variable>
       
  1407 	<xsl:choose>
       
  1408 		<xsl:when test="$h1 &gt; $h0"><xsl:value-of select="$h1"/></xsl:when>
       
  1409 		<xsl:otherwise><xsl:value-of select="$h0"/></xsl:otherwise>
       
  1410 	</xsl:choose>
       
  1411 </xsl:template>
       
  1412 
       
  1413 	<!-- no @levels, so height depends on number of levels spanned and size of levels in parent-->
       
  1414 <xsl:template match="block" mode="height" priority="5">
       
  1415 	<xsl:apply-templates mode="max-height" select="."/>
       
  1416 </xsl:template>
       
  1417 
       
  1418 
       
  1419 
       
  1420 <xsl:template match="block"><xsl:param name="levels"/>
       
  1421 	<xsl:variable name="w"><xsl:apply-templates select="." mode="width"/></xsl:variable>
       
  1422 	<xsl:variable name="h"><xsl:apply-templates select="." mode="height"/></xsl:variable>
       
  1423 	<xsl:variable name="range"><xsl:apply-templates select="." mode="level-range"/></xsl:variable>
       
  1424 	<xsl:variable name="r0" select="number(substring-before($range,' '))"/>		
       
  1425 	<xsl:variable name="r1" select="number(substring-after($range,' '))"/>		
       
  1426 	
       
  1427 	<xsl:variable name="x">
       
  1428 		<xsl:call-template name="x-pos">
       
  1429 			<xsl:with-param name="levels" select="$levels"/>
       
  1430 			<xsl:with-param name="range" select="$range"/>
       
  1431 		</xsl:call-template>
       
  1432 	</xsl:variable>
       
  1433 
       
  1434 	<!-- if this has a level, top ends at that level, otherwise this goes all the way to top of layer -->
       
  1435 	<xsl:variable name="y"> <!-- the start of the box -->
       
  1436 		<xsl:apply-templates select="ancestor::layer" mode="level-top">
       
  1437 			<xsl:with-param name="index" select="$r1"/>
       
  1438 		</xsl:apply-templates>
       
  1439 	</xsl:variable>
       
  1440 
       
  1441 	<xsl:variable name="translate-y">
       
  1442 		<xsl:choose>
       
  1443 			<xsl:when test="@levels"><xsl:value-of select="$y"/></xsl:when>
       
  1444 			<xsl:otherwise>0</xsl:otherwise>
       
  1445 		</xsl:choose>
       
  1446 	</xsl:variable>
       
  1447 	
       
  1448 	<xsl:variable name="padding"><xsl:apply-templates select=".." mode="padding"/></xsl:variable>
       
  1449 	<xsl:variable name="n"><xsl:apply-templates mode="n-levels" select=".."/></xsl:variable>	
       
  1450 	<xsl:variable name="padding-top">
       
  1451 		<xsl:choose>
       
  1452 			<xsl:when test="$r1 = number($n) - 1"><xsl:value-of select="substring-before($padding,' ')"/></xsl:when>
       
  1453 			<xsl:otherwise>0</xsl:otherwise>
       
  1454 		</xsl:choose>
       
  1455 	</xsl:variable> 
       
  1456 	<xsl:variable name="padding-bottom">
       
  1457 		<xsl:choose>
       
  1458 			<xsl:when test="$r0 = 0"><xsl:value-of select="substring-after($padding,' ')"/></xsl:when>
       
  1459 			<xsl:otherwise>0</xsl:otherwise>
       
  1460 		</xsl:choose>
       
  1461 	</xsl:variable> 
       
  1462 
       
  1463 	<g class="{name()}">
       
  1464 		<xsl:attribute name="id"><xsl:apply-templates select="." mode="id"/></xsl:attribute>
       
  1465 		<xsl:apply-templates select="." mode="detail-stuff"><xsl:with-param name="s" select="'mouseover'"/></xsl:apply-templates>
       
  1466 		<xsl:apply-templates select="." mode="filter"/>	
       
  1467 		<xsl:attribute name="transform">translate( <xsl:value-of select="concat($x,' ',$translate-y)"/>)</xsl:attribute>
       
  1468 		<xsl:apply-templates select="." mode="animate-color"/>
       
  1469         <xsl:apply-templates select="." mode="multi-color"/>		
       
  1470 		<rect class="{name()}" x="0" width="{$w}" height="{$h +  $padding-top + $padding-bottom}" y="{$y - $translate-y - $padding-top}">
       
  1471 			<xsl:call-template name="styles"/>
       
  1472 		</rect>		
       
  1473 		<xsl:variable name="text-off"> <!--  middle-align if not showing children -->
       
  1474 			<xsl:choose>
       
  1475 				<xsl:when test="($Detail=name()) and $n!=1"><xsl:value-of select="$h *0.5 + $padding-bottom div 2"/></xsl:when>
       
  1476 				
       
  1477 				<xsl:when test="($Detail='subblock' and not(subblock)) or $Detail='block'"><xsl:value-of select="$h *0.5 + $padding-bottom div 2"/></xsl:when>
       
  1478 				<xsl:otherwise>0</xsl:otherwise>
       
  1479 			</xsl:choose>
       
  1480 		</xsl:variable>
       
  1481 		<xsl:variable name="text-align"> <!--  middle-align if not showing children -->
       
  1482 			<xsl:choose>
       
  1483 				<xsl:when test="($Detail=name()) and $n!=1">mathematical</xsl:when>				
       
  1484 				<xsl:when test="($Detail='subblock' and not(subblock)) or $Detail='block'">mathematical</xsl:when>
       
  1485 				<xsl:otherwise>ideographic</xsl:otherwise>
       
  1486 			</xsl:choose>
       
  1487 		</xsl:variable>
       
  1488 		<xsl:variable name="min-h"> <!-- height of this if it were the only block in the layer -->
       
  1489 			<xsl:apply-templates select="." mode="min-height"/>
       
  1490 		</xsl:variable>
       
  1491 	<!-- label goes here -->
       
  1492 		<xsl:call-template name="linkable-content">
       
  1493 			<xsl:with-param name="show">
       
  1494 				<text text-anchor="middle" class="block" width="{$w}" x="{$w div 2}" y="{ $y + $h - $text-off + $padding-bottom  - $translate-y - 1 }" dominant-baseline="{$text-align}">
       
  1495 					<xsl:apply-templates select="." mode="detail-stuff"><xsl:with-param name="s" select="'text'"/></xsl:apply-templates>
       
  1496 					<xsl:choose>
       
  1497 						<xsl:when test="$mSize  &lt;= $h - $min-h "/>  <!--  plenty of room on bottom, no need for inline label -->
       
  1498 						<xsl:when test="$Detail='collection' or $Detail='component'  or $Detail='layer'  or ( ($Detail='subblock') and subblock )">
       
  1499 							<xsl:apply-templates select="." mode="label">
       
  1500 								<xsl:with-param name="width" select="$w"/>
       
  1501 							</xsl:apply-templates>
       
  1502 						</xsl:when>
       
  1503 					</xsl:choose>
       
  1504 					<xsl:call-template name="display-name"/>
       
  1505 				</text>
       
  1506 			</xsl:with-param>
       
  1507 		</xsl:call-template>
       
  1508 		<g><xsl:apply-templates select="." mode="detail-stuff"/>
       
  1509 	<!--<xsl:if test="@levels">
       
  1510 		<xsl:call-template name="levels-labels">
       
  1511 		<xsl:call-template>
       
  1512 		<xsl:message/>
       
  1513 	</xsl:if>-->
       
  1514 		
       
  1515 			<xsl:apply-templates select="*[1]">
       
  1516 				<xsl:with-param name="levels">
       
  1517 					<xsl:call-template name="zeros">
       
  1518 						<xsl:with-param name="n"><xsl:apply-templates mode="n-levels" select="."/></xsl:with-param>
       
  1519 					</xsl:call-template>				
       
  1520 				</xsl:with-param>
       
  1521 			</xsl:apply-templates>	
       
  1522 		</g>
       
  1523 	</g>
       
  1524 	<xsl:apply-templates select="following-sibling::*[1]">
       
  1525 		<xsl:with-param name="levels">
       
  1526 			<xsl:call-template name="sum-levels">
       
  1527 				<xsl:with-param name="levels" select="$levels"/>
       
  1528 				<xsl:with-param name="range" select="$range"/>
       
  1529 				<xsl:with-param name="width" select="$w"/>
       
  1530 			</xsl:call-template>
       
  1531 		</xsl:with-param>
       
  1532 	</xsl:apply-templates>	
       
  1533 </xsl:template>
       
  1534 
       
  1535 
       
  1536 <xsl:template match="block" mode="post-levels"><xsl:param name="levels"/>
       
  1537 	<xsl:variable name="range"><xsl:apply-templates select="." mode="level-range"/></xsl:variable>
       
  1538 	<xsl:variable name="next">
       
  1539 		<xsl:call-template name="sum-levels">
       
  1540 			<xsl:with-param name="levels" select="$levels"/>
       
  1541 			<xsl:with-param name="range" select="$range"/>
       
  1542 			<xsl:with-param name="width"><xsl:apply-templates mode="width"  select="."/></xsl:with-param>
       
  1543 		</xsl:call-template>
       
  1544 	</xsl:variable>
       
  1545 	
       
  1546 	<xsl:if test="not(following-sibling::*)"><xsl:value-of select="$next"/></xsl:if>
       
  1547 	<xsl:apply-templates select="following-sibling::*[1]" mode="post-levels">
       
  1548 		<xsl:with-param name="levels" select="$next"/>
       
  1549 	</xsl:apply-templates>
       
  1550 </xsl:template>
       
  1551 
       
  1552 <xsl:template match="block" mode="min-label-width">
       
  1553 	<xsl:variable name="range"><xsl:apply-templates select="." mode="level-range"/></xsl:variable>
       
  1554 	<xsl:variable name="r0" select="number(substring-before($range,' '))"/>		
       
  1555 	<xsl:variable name="padding"><xsl:apply-templates select=".." mode="padding"/></xsl:variable>
       
  1556 	
       
  1557 	
       
  1558 	<xsl:variable name="h"><xsl:apply-templates select="." mode="height"/></xsl:variable>
       
  1559 	<xsl:variable name="mh"><xsl:apply-templates select="." mode="min-height"/></xsl:variable>
       
  1560 	<xsl:choose>
       
  1561 		<xsl:when test="$mSize  &lt;= $h - $mh ">0</xsl:when>  <!--  plenty of room on bottom, no need for inline label -->
       
  1562 		<xsl:when test="$r0 != 0 or number(substring-after($padding,' '))=0"><xsl:value-of select="$inlineLabel"/></xsl:when>
       
  1563 		<xsl:otherwise>0</xsl:otherwise>
       
  1564 	</xsl:choose>
       
  1565 </xsl:template>
       
  1566 
       
  1567 <xsl:template name="inline-label"><xsl:param name="width"/>
       
  1568 	<xsl:variable name="n"><xsl:apply-templates mode="n-levels" select="."/></xsl:variable>
       
  1569 	<xsl:variable name="widths">
       
  1570 		<xsl:apply-templates select="*[1]" mode="post-levels">
       
  1571 			<xsl:with-param name="levels">
       
  1572 				<xsl:call-template name="zeros">
       
  1573 					<xsl:with-param name="n" select="$n"/>
       
  1574 				</xsl:call-template>
       
  1575 			</xsl:with-param>
       
  1576 		</xsl:apply-templates>	
       
  1577 	</xsl:variable>
       
  1578 	<xsl:variable name="range">
       
  1579 		<xsl:choose>
       
  1580 			<xsl:when test="@levels">0 <xsl:value-of select="$n - 1"/></xsl:when>
       
  1581 			<xsl:otherwise><xsl:apply-templates select="." mode="level-range"/></xsl:otherwise>
       
  1582 		</xsl:choose>
       
  1583 	</xsl:variable>
       
  1584 	<xsl:variable name="r0" select="number(substring-before($range,' '))"/>		
       
  1585 
       
  1586 	<xsl:variable name="min">
       
  1587 		<xsl:call-template name="min-from-list-with-index">
       
  1588 			<xsl:with-param name="list">
       
  1589 				<xsl:call-template name="list-range">
       
  1590 					<xsl:with-param name="list" select="$widths"/>
       
  1591 					<xsl:with-param name="from" select="$r0"/>										
       
  1592 					<xsl:with-param name="to" select="substring-after($range,' ')"/>
       
  1593 				</xsl:call-template>
       
  1594 			</xsl:with-param>
       
  1595 		</xsl:call-template>
       
  1596 	</xsl:variable>
       
  1597 	<xsl:variable name="w0" select="$width - substring-before($min,':')"/>
       
  1598 	<xsl:variable name="level" select="$r0 +  number(substring-after($min,':'))"/>
       
  1599 	<xsl:variable name="x-center" select="$width - 0.5 * $w0"/>
       
  1600 	<xsl:variable name="y">
       
  1601 		<xsl:for-each select="*[1]">
       
  1602 			<xsl:call-template name="level-top">
       
  1603 				<xsl:with-param name="index" select="$level"/>
       
  1604 			</xsl:call-template>
       
  1605 		</xsl:for-each>
       
  1606 	</xsl:variable>
       
  1607 	<xsl:variable name="h"><xsl:choose>
       
  1608 		<xsl:when test="ancestor::block[@levels]">
       
  1609 			<xsl:apply-templates select="ancestor::block" mode="level-height">
       
  1610 				<xsl:with-param name="index" select="$level"/>
       
  1611 			</xsl:apply-templates>
       
  1612 		</xsl:when>
       
  1613 		<xsl:otherwise>
       
  1614 			<xsl:apply-templates select="ancestor::layer" mode="level-height">
       
  1615 				<xsl:with-param name="index" select="$level"/>
       
  1616 			</xsl:apply-templates>
       
  1617 		</xsl:otherwise>
       
  1618 	</xsl:choose></xsl:variable>
       
  1619 
       
  1620 	<xsl:attribute name="dominant-baseline">mathematical</xsl:attribute>
       
  1621 	<xsl:attribute name="width"><xsl:value-of select="$w0"/></xsl:attribute>
       
  1622 	<xsl:attribute name="x"><xsl:value-of select="$x-center"/></xsl:attribute>
       
  1623 	<xsl:attribute name="y"><xsl:value-of select="$y +  0.5 * $h"/></xsl:attribute>
       
  1624 </xsl:template>
       
  1625 
       
  1626 
       
  1627 <xsl:template match="block" mode="label"><xsl:param name="width"/>
       
  1628 	<xsl:variable name="range"><xsl:apply-templates select="." mode="level-range"/></xsl:variable>
       
  1629 	<xsl:variable name="r0" select="number(substring-before($range,' '))"/>		
       
  1630 	<xsl:variable name="padding"><xsl:apply-templates select=".." mode="padding"/></xsl:variable>
       
  1631 	<xsl:if test="$r0 != 0 or number(substring-after($padding,' '))=0">
       
  1632 		<!-- need to put label on a level -->
       
  1633 		<xsl:call-template name="inline-label">
       
  1634 			<xsl:with-param name="width" select="$width"/>
       
  1635 		</xsl:call-template>
       
  1636 	</xsl:if>
       
  1637 </xsl:template>
       
  1638 
       
  1639 <xsl:template match="block" mode="level-height"><xsl:param name="level"/>
       
  1640 	<xsl:apply-templates select="descendant::collection[1]" mode="height"/>
       
  1641 </xsl:template>
       
  1642 
       
  1643 <xsl:template mode="n-levels" match="block[not(@levels)]" priority="2">
       
  1644 	<xsl:apply-templates select=".." mode="n-levels"/>
       
  1645 </xsl:template>
       
  1646 
       
  1647 <xsl:template mode="n-levels" match="block">
       
  1648 	<xsl:variable name="levels" select="normalize-space(@levels)"/>
       
  1649 	<xsl:variable name="n" select="string-length($levels)  - string-length(translate($levels,' ','')) +1"/> <!-- number of spaces +1 -->
       
  1650 	<xsl:choose>
       
  1651 			<!-- if there are no levels, there is one implicit level -->
       
  1652 		<xsl:when test="$levels='' ">1</xsl:when>
       
  1653 			<!-- if there are any collections with no level, we add an extra on top -->
       
  1654 		<xsl:when test="descendant::collection[not(@level)]"><xsl:value-of select="$n + 1"/></xsl:when>
       
  1655 		<xsl:otherwise><xsl:value-of select="$n"/></xsl:otherwise>
       
  1656 	</xsl:choose>		
       
  1657 </xsl:template>
       
  1658 
       
  1659 
       
  1660 <!-- ============= range of levels ============= -->
       
  1661 
       
  1662 <!-- no levels in parent, always spans full height (of one) -->
       
  1663 <xsl:template match="layer[not(@levels)]/block" mode="level-range" priority="7">0 0</xsl:template>
       
  1664 
       
  1665 <!-- explictly specifies the @level and @span -->
       
  1666 <!-- a block with a @level means all on a single level or spans a number of levels down-->
       
  1667 <xsl:template match="block[@level]" mode="level-range" priority="5">
       
  1668 	<xsl:variable name="level"><xsl:call-template name="level-index"/></xsl:variable>
       
  1669 	<xsl:choose>
       
  1670 		<xsl:when test="@span &gt; 0">
       
  1671 			<xsl:value-of select="$level - @span + 1"/>
       
  1672 		</xsl:when>
       
  1673 		<xsl:otherwise>
       
  1674 			<xsl:value-of select="$level"/>
       
  1675 		</xsl:otherwise>
       
  1676 	</xsl:choose>
       
  1677 	<xsl:value-of select="concat(' ',$level)"/>
       
  1678 </xsl:template>
       
  1679 
       
  1680 <!-- no @level but @levels in parent, is full range of parent -->
       
  1681 <xsl:template match="block" mode="level-range">
       
  1682 	<xsl:variable name="n"><xsl:apply-templates mode="n-levels" select=".."/></xsl:variable>
       
  1683 	<xsl:value-of select="concat('0 ',$n - 1)"/>
       
  1684 </xsl:template>
       
  1685 
       
  1686 <!-- ====== Layers ============= -->
       
  1687 
       
  1688 <xsl:template match="layer[@span&gt;0]" mode="height">
       
  1689 	<xsl:call-template name="sum-list">
       
  1690 		<xsl:with-param name="list">
       
  1691 			<xsl:variable name="span" select="@span"/>
       
  1692 			<xsl:text>0 </xsl:text>
       
  1693 	 		<xsl:for-each select="preceding-sibling::layer[position() &lt;= $span]">
       
  1694 				<xsl:if test="not(@span) or @span=0">		
       
  1695 					<xsl:apply-templates select="." mode="height"/>
       
  1696 					<xsl:text> </xsl:text>
       
  1697 					<xsl:if test="position()!=last()">
       
  1698 						<xsl:value-of select="concat($lgrpDx * count(key('lgrp-top',@name)),' ')"/>
       
  1699 					</xsl:if>								
       
  1700 					<xsl:if test="position()!=1">
       
  1701 						<xsl:value-of select="concat($groupDy + $lgrpDx * count(key('lgrp-bottom',@name)),' ')"/>
       
  1702 					</xsl:if>
       
  1703 				</xsl:if>
       
  1704 			</xsl:for-each>
       
  1705 		</xsl:with-param>
       
  1706 	</xsl:call-template>
       
  1707 </xsl:template>
       
  1708 
       
  1709 
       
  1710 <xsl:template match="layer" mode="height">
       
  1711 	<xsl:variable name="pre"> <!-- space on top -->
       
  1712 		<xsl:value-of select="concat($groupDy,' ')"/>
       
  1713 	</xsl:variable>
       
  1714 	
       
  1715 	<xsl:variable name="post"> <!-- space on bottom -->
       
  1716 		<xsl:value-of select="concat($groupDy,' ')"/>
       
  1717 	</xsl:variable>
       
  1718 
       
  1719 	<xsl:variable name="h"><xsl:apply-templates mode="level-heights" select="."/></xsl:variable>
       
  1720 	<xsl:call-template name="sum-list">
       
  1721 		<xsl:with-param name="list">
       
  1722 			<xsl:value-of select="$groupDy * (string-length($h)  - string-length(translate($h,' ','')) - 1)"/> <!-- spacing between levels -->
       
  1723 			<xsl:value-of select="concat(' ',$pre,$post)"/>
       
  1724 			<xsl:apply-templates mode="padding" select="."/>
       
  1725 			<xsl:value-of select="concat(' ',$h)"/>
       
  1726 		</xsl:with-param>
       
  1727 	</xsl:call-template>	
       
  1728 </xsl:template>
       
  1729 
       
  1730 
       
  1731 <xsl:template match="layer" mode="min-width">
       
  1732 	<xsl:call-template name="max-from-list">
       
  1733 		<xsl:with-param name="list">	
       
  1734 			<xsl:apply-templates select="*[1]" mode="post-levels">
       
  1735 				<xsl:with-param name="levels">
       
  1736 					<xsl:call-template name="zeros">
       
  1737 						<xsl:with-param name="n">
       
  1738 							<xsl:apply-templates mode="n-levels" select="."/>
       
  1739 						</xsl:with-param>
       
  1740 					</xsl:call-template>
       
  1741 				</xsl:with-param>
       
  1742 			</xsl:apply-templates>
       
  1743 		</xsl:with-param>
       
  1744 	</xsl:call-template>
       
  1745 </xsl:template>
       
  1746 
       
  1747 
       
  1748 <xsl:template match="layer" mode="padding">0 0</xsl:template>
       
  1749 <xsl:template match="layer[block and not(collection)]" mode="padding" priority="1">
       
  1750 	<xsl:value-of select="concat($groupDy,' ',$groupDy + 4.23)"/>
       
  1751 </xsl:template>
       
  1752 
       
  1753 
       
  1754 
       
  1755 <xsl:template match="layer"><xsl:param name="y" select="0"/>
       
  1756 
       
  1757 	<xsl:variable name="top-space" select="$lgrpDx * count(key('lgrp-top',@name))"/>
       
  1758 	<xsl:variable name="bottom-space" select="$lgrpDx * count(key('lgrp-bottom',@name))"/>
       
  1759 
       
  1760 	<xsl:variable name="h"><xsl:apply-templates select="." mode="height"/></xsl:variable>
       
  1761 	<xsl:variable name="w"><xsl:apply-templates select="." mode="min-width"/></xsl:variable><!-- the width of the content -->
       
  1762 	<xsl:variable name="span-width"> <!-- space taken up by spanning layers-->
       
  1763 		<xsl:call-template name="sum-list">
       
  1764 			<xsl:with-param name="list">0 <xsl:for-each select="following-sibling::layer">
       
  1765 				<xsl:if test="@span and position() - @span &lt;= 0"><xsl:apply-templates select="." mode="min-width"/><xsl:value-of select="concat(' ',$groupDx,' ')"/></xsl:if></xsl:for-each>
       
  1766 			</xsl:with-param>
       
  1767 		</xsl:call-template>
       
  1768 	</xsl:variable>	
       
  1769 	<xsl:variable name="my-width" select="$full-width - $span-width"/> <!-- the width of this layer -->
       
  1770 	<g class="{name()}" transform="translate(0 {$y + $top-space})"><xsl:apply-templates select="." mode="filter"/>
       
  1771 		<xsl:attribute name="id"><xsl:apply-templates select="." mode="id"/></xsl:attribute>	
       
  1772 		<xsl:apply-templates select="." mode="animate-color"/>	
       
  1773         <xsl:apply-templates select="." mode="multi-color"/>		
       
  1774 		<xsl:call-template name="linkable-content">
       
  1775 			<xsl:with-param name="show">
       
  1776 				<rect x="0.3" y="0.3" width="9.3" rx="4.65" ry="4.65" class="{name()}" height="{$h}">
       
  1777 					<xsl:call-template name="styles"><xsl:with-param name="for" select="'label'"/></xsl:call-template>
       
  1778 				</rect>
       
  1779 				<text  text-anchor="middle" dominant-baseline="mathematical" class="layer" transform="rotate(-90)" 
       
  1780 					 y="4.95" width="{$h}" x="{ -($h div 2 ) -  0.3}">
       
  1781 					<xsl:call-template name="display-name"/>
       
  1782 				</text>
       
  1783 			</xsl:with-param>
       
  1784 		</xsl:call-template>
       
  1785 		<xsl:variable name="x-off">
       
  1786 			<xsl:choose>
       
  1787 				<xsl:when test="$my-width &lt;= $w">0</xsl:when> <!-- should never be less than -->
       
  1788 				<xsl:when test="@align='left'">0</xsl:when>
       
  1789 				<xsl:when test="@align='right'"><xsl:value-of select="$my-width - $w"/></xsl:when>
       
  1790 				<xsl:otherwise><xsl:value-of select="0.5 * ($my-width - $w)"/></xsl:otherwise> <!-- align='center' -->
       
  1791 			</xsl:choose>
       
  1792 		</xsl:variable>
       
  1793 
       
  1794 		<xsl:variable name="padding"><xsl:apply-templates select="." mode="padding"/></xsl:variable>
       
  1795 		<g class="layer-detail" transform="translate({12.8 + $x-off} {$groupDy +  substring-before($padding,' ')})">
       
  1796 			<xsl:apply-templates select="." mode="detail-stuff"><xsl:with-param name="s" select="'mouseover'"/></xsl:apply-templates>
       
  1797 			<rect x="{-$x-off}" class="{name()}" y="{- $groupDy - substring-before($padding,' ')}" width="{$my-width}" height="{$h}">
       
  1798 				<xsl:call-template name="styles"/>
       
  1799 			</rect>
       
  1800 			<g><xsl:apply-templates select="." mode="detail-stuff"/>
       
  1801 				<xsl:apply-templates select="*[1]">
       
  1802 					<xsl:with-param name="levels">
       
  1803 						<xsl:call-template name="zeros">
       
  1804 							<xsl:with-param name="n">
       
  1805 								<xsl:apply-templates mode="n-levels" select="."/>
       
  1806 							</xsl:with-param>
       
  1807 						</xsl:call-template>
       
  1808 					</xsl:with-param>
       
  1809 				</xsl:apply-templates>
       
  1810 			</g>
       
  1811 		</g>			
       
  1812 	</g>
       
  1813 	<xsl:apply-templates select="preceding-sibling::*[1]">
       
  1814 		<xsl:with-param name="y" select="$y + $h + $groupDy + $top-space + $bottom-space"/>
       
  1815 	</xsl:apply-templates>
       
  1816 </xsl:template>
       
  1817 
       
  1818 <xsl:template match="layer[@span &gt; 0]"><xsl:param name="y" select="0"/>
       
  1819 	<xsl:variable name="top-space" select="$lgrpDx * count(key('lgrp-top',preceding-sibling::layer[not(@span)][1]/@name))"/>
       
  1820 	<xsl:variable name="h"><xsl:apply-templates select="." mode="height"/></xsl:variable>
       
  1821 	<xsl:variable name="w"><xsl:apply-templates select="." mode="min-width"/></xsl:variable><!-- the width of the content -->
       
  1822 	<xsl:variable name="span-width"> <!-- space taken up by spanning layers-->
       
  1823 		<xsl:call-template name="sum-list">
       
  1824 			<xsl:with-param name="list">0 <xsl:for-each select="following-sibling::layer">
       
  1825 				<xsl:if test="@span and position() - @span &lt;= 0"><xsl:apply-templates select="." mode="min-width"/><xsl:value-of select="concat(' ',$groupDx,' ')"/></xsl:if></xsl:for-each>
       
  1826 			</xsl:with-param>
       
  1827 		</xsl:call-template>
       
  1828 	</xsl:variable>		
       
  1829 	<xsl:variable name="padding"><xsl:apply-templates select="." mode="padding"/></xsl:variable>
       
  1830 	<xsl:variable name="x-off" select="$full-width - $w - $span-width"/>
       
  1831 	<g class="{name()}" transform="translate(0 {$y + $top-space})"><xsl:apply-templates select="." mode="filter"/>
       
  1832 		<g class="layer-detail">
       
  1833 			<xsl:attribute name="transform">translate(<xsl:value-of select="concat(12.8 + $x-off,' ')"/>
       
  1834 				<xsl:choose>
       
  1835 					<xsl:when test="count(*)&gt;1 or not(block)"><xsl:value-of select="$groupDy + substring-before($padding,' ')"/></xsl:when>
       
  1836 					<xsl:otherwise><xsl:value-of select="substring-before($padding,' ')"/></xsl:otherwise>
       
  1837 				</xsl:choose>)</xsl:attribute>
       
  1838 			<xsl:apply-templates select="." mode="detail-stuff"><xsl:with-param name="s" select="'mouseover'"/></xsl:apply-templates>
       
  1839 			<rect x="0" class="{name()}" y="{-$groupDy - substring-before($padding,' ') }" width="{$w}" height="{$h}">
       
  1840 				<xsl:if test="count(*)=1 and block"><xsl:attribute name="y"><xsl:value-of select=" -number(substring-before($padding,' '))"/></xsl:attribute></xsl:if>
       
  1841 				<xsl:call-template name="styles"/>
       
  1842 			</rect>
       
  1843 				<xsl:call-template name="linkable-content">
       
  1844 					<xsl:with-param name="show">
       
  1845 						<text  text-anchor="middle" dominant-baseline="ideographic" class="layer" width="{$w}" x="{$w div 2}">
       
  1846 							<xsl:attribute name="y"><xsl:value-of select="$h - $groupDy - 2.3"/></xsl:attribute>
       
  1847 							<xsl:call-template name="display-name"/>
       
  1848 						</text>
       
  1849 					</xsl:with-param>
       
  1850 				</xsl:call-template>		
       
  1851 			<g><xsl:apply-templates select="." mode="detail-stuff"/>					
       
  1852 				<xsl:apply-templates select="*[1]">
       
  1853 					<xsl:with-param name="levels">
       
  1854 						<xsl:call-template name="zeros">
       
  1855 							<xsl:with-param name="n">
       
  1856 								<xsl:apply-templates mode="n-levels" select="."/>
       
  1857 							</xsl:with-param>
       
  1858 						</xsl:call-template>
       
  1859 					</xsl:with-param>
       
  1860 				</xsl:apply-templates>
       
  1861 			</g>
       
  1862 		</g>
       
  1863 	</g>
       
  1864 	<xsl:apply-templates select="preceding-sibling::*[1]">
       
  1865 		<xsl:with-param name="y" select="$y"/>
       
  1866 	</xsl:apply-templates>
       
  1867 </xsl:template>
       
  1868 
       
  1869 <!-- return a list of the heights of all the levels. should only be called on a layer or block -->
       
  1870 
       
  1871 
       
  1872 <xsl:template match="layer-group"><xsl:param name="y" select="0"/>
       
  1873 	<xsl:apply-templates select="." mode="lgrp"/>
       
  1874 	<xsl:apply-templates select="preceding-sibling::*[1]">
       
  1875 		<xsl:with-param name="y" select="$y"/>
       
  1876 	</xsl:apply-templates>
       
  1877 </xsl:template>
       
  1878 
       
  1879 <xsl:template match="layer-group" mode="right-border">
       
  1880 	<xsl:variable name="d"><xsl:apply-templates select="." mode="depth"/></xsl:variable>
       
  1881 	<xsl:value-of select="$d * $lgrpDx"/>
       
  1882 </xsl:template>
       
  1883 
       
  1884 <xsl:template match="layer-group" mode="depth">
       
  1885 	<xsl:variable name="d">
       
  1886 		<xsl:call-template name="max-from-list">
       
  1887 			<xsl:with-param name="list">
       
  1888 				<xsl:text>0 </xsl:text>
       
  1889 				<xsl:for-each select="layer-group">
       
  1890 					<xsl:apply-templates select="." mode="depth"/><xsl:text> </xsl:text>
       
  1891 				</xsl:for-each>
       
  1892 			</xsl:with-param>
       
  1893 		</xsl:call-template>
       
  1894 	</xsl:variable>
       
  1895 	<xsl:value-of select="$d + 1"/>
       
  1896 </xsl:template>
       
  1897 
       
  1898 
       
  1899 <xsl:template match="layer-group" mode="left-border">
       
  1900 	<xsl:variable name="child-border">
       
  1901 		<xsl:call-template name="max-from-list">
       
  1902 			<xsl:with-param name="list">
       
  1903 				<xsl:text>0 </xsl:text>
       
  1904 				<xsl:for-each select="layer-group">
       
  1905 					<xsl:apply-templates select="." mode="left-border"/><xsl:text> </xsl:text>
       
  1906 				</xsl:for-each>
       
  1907 			</xsl:with-param>
       
  1908 		</xsl:call-template>
       
  1909 	</xsl:variable>
       
  1910 	<xsl:choose>
       
  1911 		<xsl:when test="@label"><xsl:value-of select="$child-border + $lgrpLabelDx"/></xsl:when>
       
  1912 		<xsl:otherwise><xsl:value-of select="$child-border + 0.75 * $lgrpDx"/></xsl:otherwise>
       
  1913 	</xsl:choose>
       
  1914 </xsl:template>
       
  1915 
       
  1916 
       
  1917 <xsl:template match="layer-group" mode="lgrp"><xsl:param name="left" select="- $left-borders"/><xsl:param name="right" select="$view-width - $left-borders - 2 * $groupDy"/>
       
  1918 	<!-- use indexes to make life easier -->
       
  1919 	<xsl:variable name="from" select="1 +  count(key('layer',@from)/preceding-sibling::layer)"/>
       
  1920 	<xsl:variable name="to" select="1 +  count(key('layer',@to)/preceding-sibling::layer)"/>
       
  1921 	<xsl:choose>
       
  1922 		<xsl:when test="not(key('layer',@from))">
       
  1923 			<xsl:message>&#xa;Error:  layer "<xsl:value-of select="@from"/>" does not exist"</xsl:message>
       
  1924 		</xsl:when>
       
  1925 		<xsl:when test="not(key('layer',@to))">
       
  1926 			<xsl:message>&#xa;Error:  layer "<xsl:value-of select="@to"/>" does not exist"</xsl:message>
       
  1927 		</xsl:when>
       
  1928 		<xsl:when test="$from &gt; $to">
       
  1929 			<xsl:message>&#xa;Error: "<xsl:value-of select="@from"/>" is after "<xsl:value-of select="@to"/>"</xsl:message>
       
  1930 		</xsl:when>
       
  1931 		<xsl:when test="key('layer',@to)[@span]">
       
  1932 			<xsl:message>&#xa;Error: Layer group cannot be bounded by spanned layer "<xsl:value-of select="@to"/>"</xsl:message>
       
  1933 		</xsl:when>
       
  1934 		<xsl:when test="key('layer',@from)[@span]">
       
  1935 			<xsl:message>&#xa;Error: Layer group cannot be bounded by spanned layer "<xsl:value-of select="@from"/>"</xsl:message>
       
  1936 		</xsl:when>
       
  1937 		<xsl:otherwise>
       
  1938 			<xsl:variable name="to-name" select="@to"/>
       
  1939 			<xsl:variable name="from-name" select="@from"/>
       
  1940 			<xsl:variable name="parent-to" select="count(ancestor::layer-group[@to=$to-name])"/>
       
  1941 			<xsl:variable name="child-to" select="1+ count(descendant::layer-group[@to=$to-name])"/>
       
  1942 			<xsl:variable name="child-from" select="1+ count(descendant::layer-group[@from=$from-name])"/>
       
  1943 			<xsl:variable name="start">
       
  1944 				<xsl:call-template name="sum-list">
       
  1945 					<xsl:with-param name="list">
       
  1946 						<xsl:value-of select="concat($groupDy + $lgrpDx *  $parent-to,' ')"/>
       
  1947 						<xsl:for-each select="key('layer',@to)/following-sibling::layer[not(@span)]">
       
  1948 							<xsl:apply-templates select="." mode="height"/>
       
  1949 							<xsl:value-of select="concat(' ',$groupDy + $lgrpDx* (count(key('lgrp-top',@name))+ count(key('lgrp-bottom',@name))),' ')"/>
       
  1950 						</xsl:for-each>
       
  1951 					</xsl:with-param>
       
  1952 				</xsl:call-template>
       
  1953 			</xsl:variable>
       
  1954 			<xsl:variable name="height">
       
  1955 				<xsl:call-template name="sum-list">
       
  1956 					<xsl:with-param name="list">
       
  1957 						<xsl:value-of select="concat($lgrpDx *  ($child-to+ $child-from),' ')"/>					
       
  1958 						<xsl:for-each select="//systemModel/layer[position() &gt;= $from and position() &lt;= $to][not(@span)]">
       
  1959 							<xsl:apply-templates select="." mode="height"/>
       
  1960 							<xsl:text> </xsl:text>
       
  1961 							<xsl:if test="position()!=last()">
       
  1962 								<xsl:value-of select="concat($lgrpDx * count(key('lgrp-top',@name)),' ')"/>
       
  1963 							</xsl:if>								
       
  1964 							<xsl:if test="position()!=1">
       
  1965 								<xsl:value-of select="concat($groupDy + $lgrpDx * count(key('lgrp-bottom',@name)),' ')"/>
       
  1966 							</xsl:if>
       
  1967 						</xsl:for-each>
       
  1968 					</xsl:with-param>
       
  1969 				</xsl:call-template>
       
  1970 			</xsl:variable>
       
  1971 			<g class="{name()}">
       
  1972 				<rect width="{$right - $left}" height="{$height}" x="{$left}" y="{$start }" rx="4.65"  fill="{@color}"/>
       
  1973 				<xsl:if test="@label">
       
  1974 					<text text-anchor="middle" dominant-baseline="mathematical" class="lgrp" transform="rotate(-90)" y="{$left + 0.5 * $lgrpLabelDx}" width="{$height}" x="{- ($start + 0.5 * $height)}">
       
  1975 						<xsl:value-of select="@label"/>
       
  1976 					</text>
       
  1977 				</xsl:if>
       
  1978 			</g>
       
  1979 			<xsl:variable name="dx">
       
  1980 				<xsl:choose>
       
  1981 					<xsl:when test="@label"><xsl:value-of select="$lgrpLabelDx"/></xsl:when>
       
  1982 					<xsl:otherwise><xsl:value-of select="$lgrpDx * 0.75"/></xsl:otherwise>
       
  1983 				</xsl:choose>
       
  1984 			</xsl:variable>		
       
  1985 			<xsl:apply-templates select="layer-group" mode="lgrp">
       
  1986 				<xsl:with-param name="left" select="$left + $dx"/>
       
  1987 				<xsl:with-param name="right" select="$right - $lgrpDx"/>
       
  1988 			</xsl:apply-templates>
       
  1989 		</xsl:otherwise>
       
  1990 	</xsl:choose>
       
  1991 
       
  1992 </xsl:template>
       
  1993 
       
  1994 <!--level should always be '0', so ignore it and just give height of layer -->
       
  1995 <xsl:template mode="level-height" match="layer[not(@levels)]" priority="5">
       
  1996 	<xsl:call-template name="max-from-list">
       
  1997 		<xsl:with-param name="list">
       
  1998 			<xsl:value-of select="concat($mSize,' ')"/> <!-- min size is one collection height -->
       
  1999 		<xsl:for-each select="*[@levels]">
       
  2000 			<xsl:apply-templates select="." mode="height"/>
       
  2001 			<xsl:text> </xsl:text>
       
  2002 		</xsl:for-each>
       
  2003 		</xsl:with-param>
       
  2004 	</xsl:call-template>
       
  2005 </xsl:template>
       
  2006 
       
  2007 <!-- layer has levels -->
       
  2008 <xsl:template mode="level-height" match="layer"><xsl:param name="level"/>
       
  2009 <!--	 find all blocks which this contains and use a factor of their heights,
       
  2010 	min is height of collection -->
       
  2011 	<xsl:call-template name="max-from-list">
       
  2012 		<xsl:with-param name="list">
       
  2013 			<xsl:value-of select="concat($mSize, ' ')"/>
       
  2014 			<xsl:for-each select="block[@levels]"> <!-- only check self-heighted stuff -->
       
  2015 				<xsl:variable name="range"><xsl:apply-templates select="." mode="level-range"/></xsl:variable>
       
  2016 				<xsl:variable name="r0" select="number(substring-before($range,' '))"/>
       
  2017 				<xsl:variable name="r1" select="number(substring-after($range,' '))"/>		
       
  2018 				<xsl:if test="($r0 &lt;=$level)  and ($r1 &gt;=$level)">
       
  2019 					<xsl:variable name="h"><xsl:apply-templates select="." mode="min-height"/></xsl:variable>
       
  2020 					<xsl:value-of select="concat($h div ($r1 - $r0 +1), ' ')"/>
       
  2021 				</xsl:if>
       
  2022 			</xsl:for-each>
       
  2023 		</xsl:with-param>
       
  2024 	</xsl:call-template>
       
  2025 </xsl:template>
       
  2026 
       
  2027 
       
  2028 
       
  2029 
       
  2030 <xsl:template mode="n-levels" match="layer"> <!-- number of levels available to children of this layer -->
       
  2031 	<xsl:variable name="levels" select="normalize-space(@levels)"/>
       
  2032 	<xsl:variable name="n" select="string-length($levels)  - string-length(translate($levels,' ','')) +1"/> <!-- number of spaces +1 -->
       
  2033 	<xsl:choose>
       
  2034 			<!-- if there are no levels, there is one implicit level -->
       
  2035 		<xsl:when test="$levels='' ">1</xsl:when>
       
  2036 			<!-- if there are any collections with no level, we add an extra on top -->
       
  2037 		<xsl:when test="collection[not(@level)] or block[not(@levels) and not(@level)]/descendant::collection[not(@level)]"><xsl:value-of select="$n + 1"/></xsl:when>
       
  2038 		<xsl:otherwise><xsl:value-of select="$n"/></xsl:otherwise>
       
  2039 	</xsl:choose>		
       
  2040 </xsl:template>
       
  2041 
       
  2042 <!-- should never be called -->
       
  2043 <xsl:template match="layer" mode="level-range">0 0</xsl:template>
       
  2044 
       
  2045 
       
  2046 <!-- ====== Levels ============= -->
       
  2047 
       
  2048 <!--
       
  2049 options: 
       
  2050 	layer[@levels]/block[@levels]/collection[@level]
       
  2051 		use collection/@level in context of block/@levels
       
  2052 	layer[@levels]/block[@levels]/collection[not(@level)]
       
  2053 		use '' (unnamed top level, increase n-levels in block) in context of block/@levels
       
  2054 	layer[@levels]/block[not(@levels) and not(@level)]/collection[@level]
       
  2055 		use collection/@level in context of layer/@levels
       
  2056 	layer[@levels]/block[not(@levels) and not(@level)]/collection[not(@level)]
       
  2057 		use '' (unnamed top level, increase n-levels in layer) in context of layer/@levels
       
  2058 	layer[@levels]/block[not(@levels) and @level]/collection[@level]
       
  2059 		use collection/@level in context of layer/@levels (warning if @level is not in range of parent)
       
  2060 	layer[@levels]/block[not(@levels) and @level]/collection[not(@level)]
       
  2061 		use block/@level in context of layer/@levels (raise warning)
       
  2062 	layer[not(@levels)]/block[not(@levels) and not(@level)]/collection[@level]
       
  2063 		use '' (raise warning)
       
  2064 	layer[not(@levels)]/block[not(@levels) and not(@level)]/collection[not(@level)]
       
  2065 		use ''
       
  2066 	layer[not(@levels)]/block[not(@levels) and @level]/collection[@level]
       
  2067 		use '' (raise warning)
       
  2068 	layer[not(@levels)]/block[not(@levels) and @level]/collection[not(@level)]
       
  2069 		use '' (raise warning)
       
  2070 -->
       
  2071 
       
  2072 <!-- any collection means on a single level -->
       
  2073 <xsl:template match="collection" mode="level-range">
       
  2074 	<xsl:variable name="level"><xsl:apply-templates select="." mode="level-index"/></xsl:variable>
       
  2075 	<xsl:value-of select="concat($level,' ',$level)"/>
       
  2076 </xsl:template>
       
  2077 
       
  2078 <xsl:template name="level-index">
       
  2079 	<!-- this must have a @level and an ancestor with @levels -->
       
  2080 	<xsl:variable name="levels"><xsl:value-of select="concat(' ',normalize-space(ancestor::*[@levels][1]/@levels),' ')"/></xsl:variable>
       
  2081 	<xsl:variable name="level" select="concat(' ',@level,' ')"/>
       
  2082 	<xsl:choose>
       
  2083 		<xsl:when test="contains($levels,$level)">
       
  2084 			<xsl:variable name="pre" select="substring-before($levels,$level)"/>
       
  2085 			<xsl:value-of select="string-length($pre) - string-length(translate($pre,' ',''))"/>
       
  2086 		</xsl:when>
       
  2087 		<xsl:otherwise>
       
  2088 			<xsl:message>&#xa;error: invalid level name: <xsl:value-of select="@level"/> in <xsl:value-of select="name()"/> "<xsl:value-of select="@name"/>" [<xsl:value-of select="$levels"/>]</xsl:message>
       
  2089 			<xsl:value-of select="string-length($levels) - string-length(translate($levels,' ','')) - 1"/>
       
  2090 		</xsl:otherwise>
       
  2091 	</xsl:choose>
       
  2092 </xsl:template>
       
  2093 
       
  2094 <!-- by default use height of all levels -->
       
  2095 <xsl:template mode="level-heights" match="layer|block[@levels]">
       
  2096 	<xsl:param name="range">
       
  2097 		<xsl:variable name="level"><xsl:apply-templates select="." mode="n-levels"/></xsl:variable>
       
  2098 		<xsl:value-of select="concat('0 ',$level - 1)"/>
       
  2099 	</xsl:param>
       
  2100 	<xsl:variable name="r0" select="number(substring-before($range,' '))"/>
       
  2101 	<xsl:variable name="r1" select="number(substring-after($range,' '))"/>
       
  2102 	<xsl:apply-templates select="." mode="level-height">
       
  2103 		<xsl:with-param name="level" select="$r0"/>
       
  2104 	</xsl:apply-templates>	
       
  2105 	<xsl:text> </xsl:text>
       
  2106 	<xsl:if test="$r1 &gt; $r0">
       
  2107 		<xsl:apply-templates select="." mode="level-heights">
       
  2108 			<xsl:with-param name="range" select="concat($r0 + 1,' ' ,$r1)"/>
       
  2109 		</xsl:apply-templates>			
       
  2110 	</xsl:if>
       
  2111 </xsl:template>
       
  2112 
       
  2113 <!-- the y-position for level $index -->
       
  2114 <xsl:template match="layer|block[@levels]" mode="level-top"><xsl:param name="index"/>
       
  2115 	<xsl:variable name="n"><xsl:apply-templates select="." mode="n-levels"/></xsl:variable>
       
  2116 	<xsl:choose>
       
  2117 		<xsl:when test="number($index) = number($n) - 1">0</xsl:when> <!-- it's the top level, so y = 0 -->
       
  2118 		<xsl:otherwise>
       
  2119 			<xsl:variable name="h">
       
  2120 				<xsl:apply-templates mode="level-heights" select=".">
       
  2121 					<xsl:with-param name="range" select="concat($index +  1,' ' ,$n - 1)"/>
       
  2122 				</xsl:apply-templates>
       
  2123 			</xsl:variable>
       
  2124 			<xsl:call-template name="sum-list">
       
  2125 				<xsl:with-param name="list">
       
  2126 					<xsl:value-of select="$groupDy * (string-length($h)  - string-length(translate($h,' ','')))"/>
       
  2127 					<xsl:value-of select="concat(' ',$h)"/>
       
  2128 				</xsl:with-param>
       
  2129 			</xsl:call-template>				
       
  2130 		</xsl:otherwise>
       
  2131 	</xsl:choose>
       
  2132 </xsl:template>
       
  2133 <xsl:template match="block[not(@levels)]" mode="level-top"><xsl:message>
       
  2134 Error! This template should not have been called</xsl:message>
       
  2135 </xsl:template>
       
  2136 
       
  2137 <!-- the y-coord of the top of the level. If not specified uses level of current node -->
       
  2138 <xsl:template name="level-top"><xsl:param name="index"/>
       
  2139 	<xsl:choose>
       
  2140 		<xsl:when test="ancestor::block[@levels]">
       
  2141 			<xsl:apply-templates select="ancestor::block" mode="level-top">
       
  2142 				<xsl:with-param name="index" select="$index"/>
       
  2143 			</xsl:apply-templates>
       
  2144 		</xsl:when>
       
  2145 		<xsl:otherwise>
       
  2146 			<xsl:apply-templates select="ancestor::layer" mode="level-top">
       
  2147 				<xsl:with-param name="index" select="$index"/>
       
  2148 			</xsl:apply-templates>
       
  2149 		</xsl:otherwise>
       
  2150 	</xsl:choose>
       
  2151 </xsl:template>
       
  2152 
       
  2153 <xsl:template name="x-pos"><xsl:param name="levels"/><xsl:param name="range"/>
       
  2154 	<!-- flush the box at the level ranges in $range against the level array -->
       
  2155 	 <!--pick  largest value in range  -->
       
  2156 	<xsl:variable name="right">
       
  2157 		<xsl:call-template name="max-from-list">
       
  2158 			<xsl:with-param name="list">
       
  2159 				<xsl:call-template name="list-range">
       
  2160 					<xsl:with-param name="list" select="$levels"/>
       
  2161 					<xsl:with-param name="from" select="substring-before($range,' ')"/>
       
  2162 					<xsl:with-param name="to" select="substring-after($range,' ')"/>
       
  2163 				</xsl:call-template>
       
  2164 			</xsl:with-param>
       
  2165 		</xsl:call-template>
       
  2166 	</xsl:variable>
       
  2167 	<xsl:choose>
       
  2168 		<xsl:when test="$right=0">0</xsl:when>
       
  2169 		<xsl:otherwise><xsl:value-of select=" $groupDx + $right"/></xsl:otherwise>
       
  2170 	</xsl:choose>
       
  2171 </xsl:template>	
       
  2172 
       
  2173 
       
  2174 <!-- ============= list handlers ============= -->
       
  2175 
       
  2176 <xsl:template name="sum-levels"><xsl:param name="levels"/> 
       
  2177 	<xsl:param name="range"/><xsl:param name="width"/> 
       
  2178 
       
  2179 
       
  2180 	<!-- add a box with levels indexes in range to level array -->
       
  2181 	<xsl:variable name="left">
       
  2182 		<xsl:call-template name="x-pos">
       
  2183 			<xsl:with-param name="levels" select="$levels"/>
       
  2184 			<xsl:with-param name="range" select="$range"/>
       
  2185 		</xsl:call-template>
       
  2186 	</xsl:variable>
       
  2187 	<xsl:call-template name="list-replace">
       
  2188 		<xsl:with-param name="list" select="$levels"/>
       
  2189 		<xsl:with-param name="from" select="substring-before($range,' ')"/>
       
  2190 		<xsl:with-param name="to" select="substring-after($range,' ')"/>
       
  2191 		<xsl:with-param name="value" select="$left + $width"/>
       
  2192 	</xsl:call-template>
       
  2193 </xsl:template>
       
  2194 
       
  2195 <xsl:template name="list-replace"><xsl:param name="list"/><xsl:param name="from"/><xsl:param name="to"/><xsl:param name="value"/>
       
  2196 	<xsl:choose>
       
  2197 		<xsl:when test="$from &lt; 1 and $to &gt;= 0"><xsl:value-of select="$value"/></xsl:when>
       
  2198 		<xsl:otherwise><xsl:value-of select="substring-before($list,' ')"/></xsl:otherwise>
       
  2199 	</xsl:choose>
       
  2200 	<xsl:text> </xsl:text>
       
  2201 	<xsl:if test="contains(substring-after($list,' '),' ')">
       
  2202 		<xsl:call-template name="list-replace">
       
  2203 			<xsl:with-param name="list" select="substring-after($list,' ')"/>
       
  2204 			<xsl:with-param name="from" select="$from - 1"/>
       
  2205 			<xsl:with-param name="to" select="$to - 1"/>
       
  2206 			<xsl:with-param name="value" select="$value"/>
       
  2207 		</xsl:call-template>
       
  2208 	</xsl:if>
       
  2209 </xsl:template>
       
  2210 
       
  2211 <!--  last item in space-separated list -->
       
  2212 <xsl:template name="last-in-list"><xsl:param name="str"/>
       
  2213 	<xsl:choose>
       
  2214 		<xsl:when test="contains($str,' ')">
       
  2215 			<xsl:call-template name="last-in-list">
       
  2216 				<xsl:with-param name="str" select="substring-after($str,' ')"/>
       
  2217 			</xsl:call-template>
       
  2218 		</xsl:when>
       
  2219 		<xsl:otherwise><xsl:value-of select="$str"/></xsl:otherwise>
       
  2220 	</xsl:choose>
       
  2221 </xsl:template>
       
  2222 
       
  2223 <!-- a list of n zeros -->
       
  2224 <xsl:template name="zeros"><xsl:param name="n"/>
       
  2225 	<xsl:text>0 </xsl:text>
       
  2226 	<xsl:if test="$n &gt; 1">
       
  2227 		<xsl:call-template name="zeros">
       
  2228 			<xsl:with-param name="n" select="$n - 1"/>
       
  2229 		</xsl:call-template>
       
  2230 	</xsl:if>
       
  2231 </xsl:template>
       
  2232 
       
  2233 
       
  2234 <!-- ====== legend ============= -->
       
  2235 
       
  2236 <xsl:include href="legend.xsl"/>
       
  2237 <!-- end legend -->
       
  2238 
       
  2239 
       
  2240 <xsl:template match="logo" mode="width">
       
  2241 	<xsl:variable name="b" select="normalize-space(@viewBox)"/>
       
  2242 	<xsl:variable name="x0" select="- number(substring-before($b,' '))"/>
       
  2243 	<xsl:variable name="x1" select="number(substring-before(substring-after(substring-after($b,' '),' '),' '))"/>
       
  2244 	<xsl:choose> <!--  is it really y1+ y0 or should it be - ? -->
       
  2245 		<xsl:when test="@width"><xsl:value-of select="@width"/></xsl:when>
       
  2246 		<xsl:when test="@height and $b!=''">
       
  2247 			<xsl:variable name="y0" select="- number(substring-before(substring-after($b,' '),' '))"/>
       
  2248 			<xsl:variable name="y1" select="number(substring-after(substring-after(substring-after($b,' '),' '),' '))"/>
       
  2249 			<xsl:value-of select="($x1 + $x0) * number(@height) div ($y1 + $y0)"/>
       
  2250 		</xsl:when>
       
  2251 		<xsl:when test="$b!=''"><xsl:value-of select="$x1 + $x0"/></xsl:when>
       
  2252 		<xsl:otherwise>?</xsl:otherwise>	<!-- cannot be determined -->
       
  2253 	</xsl:choose>
       
  2254 </xsl:template>
       
  2255 <xsl:template match="logo" mode="height">
       
  2256 	<xsl:variable name="b" select="normalize-space(@viewBox)"/>
       
  2257 	<xsl:variable name="y0" select="- number(substring-before(substring-after($b,' '),' '))"/>
       
  2258 	<xsl:variable name="y1" select="number(substring-after(substring-after(substring-after($b,' '),' '),' '))"/>
       
  2259 	<xsl:choose> <!--  is it really y1+ y0 or should it be - ? -->
       
  2260 		<xsl:when test="@height"><xsl:value-of select="@height"/></xsl:when>
       
  2261 		<xsl:when test="@width and $b!=''">
       
  2262 			<xsl:variable name="x0" select="- number(substring-before($b,' '))"/>
       
  2263 			<xsl:variable name="x1" select="number(substring-before(substring-after(substring-after($b,' '),' '),' '))"/>
       
  2264 			<xsl:value-of select="($y1 + $y0) * number(@width) div ($x1 + $x0)"/>
       
  2265 		</xsl:when>
       
  2266 		<xsl:when test="$b!=''"><xsl:value-of select="$y1 + $y0"/></xsl:when>
       
  2267 		<xsl:otherwise>?</xsl:otherwise>	<!-- cannot be determined -->
       
  2268 	</xsl:choose>
       
  2269 </xsl:template>
       
  2270 
       
  2271 
       
  2272 <xsl:template match="logo"><xsl:param name="y" select="0"/>
       
  2273 	<g class="logo" transform="translate({- $left-borders} {$y})">
       
  2274 	<xsl:attribute name="transform">translate(<xsl:value-of select="concat(- $left-borders,' ',$y)"/>) <xsl:if test="@viewBox">
       
  2275 		<xsl:variable name="b" select="normalize-space(@viewBox)"/>
       
  2276 		<xsl:variable name="x0" select="- number(substring-before($b,' '))"/>
       
  2277 		<xsl:variable name="y0" select="- number(substring-before(substring-after($b,' '),' '))"/>
       
  2278 		<xsl:variable name="x1" select="number(substring-before(substring-after(substring-after($b,' '),' '),' '))"/>
       
  2279 		<xsl:variable name="y1" select="number(substring-after(substring-after(substring-after($b,' '),' '),' '))"/>
       
  2280 		<xsl:text> scale(</xsl:text>
       
  2281 		<xsl:if test="@width"><xsl:value-of select="number(@width) div ($x1 + $x0)"/></xsl:if>
       
  2282 		<xsl:if test="@height">
       
  2283 			<xsl:text> </xsl:text><xsl:value-of select="@height div ($y1 + $y0)"/>
       
  2284 		</xsl:if>
       
  2285 		<xsl:if test="not(@width | @height)">1</xsl:if>
       
  2286 		<xsl:text>)</xsl:text>
       
  2287 		<xsl:if test="not($x0=0 and $y0=0)"> translate(<xsl:value-of select="concat($x0,' ', $y0)"/>)</xsl:if>
       
  2288 	</xsl:if></xsl:attribute>
       
  2289 	<xsl:choose>
       
  2290 		<xsl:when test="@src">
       
  2291 			<image  x="0" y="0" width="{@width}" height="{@height}" xlink:href="{@src}"/>
       
  2292 		</xsl:when>
       
  2293 		<xsl:otherwise>
       
  2294 			<xsl:copy-of select="*"/>
       
  2295 		</xsl:otherwise>
       
  2296 	</xsl:choose>
       
  2297 	</g>
       
  2298 	<xsl:apply-templates select="preceding-sibling::*[1]">
       
  2299 		<xsl:with-param name="y" select="$y"/>
       
  2300 	</xsl:apply-templates>
       
  2301 </xsl:template>
       
  2302 
       
  2303 </xsl:stylesheet>