|
Jun
6
|
I already touched on a neat feature of OpenID - you can have a plain old web page URI act as a proxy / alias for your openid. Well now the Sun OpenID IdP is up and running, I can test the theory.
Per the FAQ, you need to add a couple of lines to your web page - in the case of a Roller template this needs to be close to the outside of the HTML; in my case that's in the _decorator template.

OK, let's try it. First over to LiveJournal :
Click, over to the Sun IdP :

I type in my credentials and ...
Yes I do, and I'm in :

Yeah - it works !!
|
Apr
27
|
Today, blogs.sun.com is three years old - that should be young I guess - old seems wrong - this is still a very new medium to many and b.s.c feels anything but old. Anyway, congratulations to everyone who has made it a success - the people who run it and to the 3,000 plus employees (and alumni) who make it an interesting place.
I was a bit of a laggard compared to some of my colleagues (and ex-colleagues) - I didn't join the fray until July 2004. In that time I've posted 303 entries, spent some time helping Eduardo and Carla getting The Aquarium (es, ch, ja) up and running and spent way too much time playing around with Roller templates.
As an added bonus, and to my surprise someone actually reads my blog - in fact, occasionally a lot of people. Looking back at my statcounter logs - there have been a couple of notable peaks -
- When one of my rants about the middleware market got picked up on TSS
- One of my posts got highlighted on Ajaxian (this was a big peak - 4k hits in a day; even now it draws 20-30 hits a day)
- An entry about Zimbra got linked to by Tim Bray (which was pretty humbling knowing how much traffic someone like Tim draws)
- I got linked by the Big Boss (FWIW - this drew far fewer referrers than Tim Bray's link - sorry Jonathan)
I don't write much that I expect will be of earth shattering importance and am fairly limited to what I can talk about work-wise so it's nice to know that some of what I write here is interesting to someone way down on the outer-reaches of the long tail.
Here's to the next 3 years of blogs.sun.com.
|
Apr
1
|
This is Part 2 (of 3) of my notes from O'Reilly Emerging Technology Conference, 2007 in San Diego. (see Part 1)
Day two (Tuesday) was supposed to start with Kathy Sierra - but she was forced to cancel due to her online death-threat incident. That was a shame in many ways and means I still haven't had the pleasure of listening to Kathy Sierra talk. Instead of Kathy, Jeff Jonas was back talking about data and how to get the most out of it. A bit of a repeat but he did go into a little more detail.
Next up was Werner Vogels who talked about Amazon Web Services. This was really interesting - Amazon seem to be really leading the way in delivering a web platform vision. It's taken them a decade and $2 billion - if you were thinking of trying this at home. Their goals are to turn huge, fixed costs into lower variable costs, provide unlimited scalability all with datacenter reliability.
Rightscaling is the term Werner used to describe the cost-efective scaling - I heard an example of a startup laying down just $85 for their first 3 months of IT operations; yet could easily dip into the (virtually unlimited) pool to scale up as demand required.
Werner really only talked about the infrastructure layers, which (if you're not familiar with AWS) consists of EC2 (Elastic Computing Cloud), Messaging (Simple Queuing Service) and Storage (S3 - Simple Storage Service) - they use metered pricing for everything - eg. $0.15/Gb/Month for storage or $0.10/Instance/Hour for EC2).
The way they do provisioning for EC2 was pretty neat - you basically assign an AMI (Amazon Machine Image) to the physical units you want to provision; the AMI defines the OS and software you want installed (ie. you might choose Fedora, Apache and PHP or Fedora and Ruby on Rails). The AMIs are stored on S3 and you can either define your own or use pre-configured images.
The deployments can be tiered (for security) in the same way you might in your own DC - ie. only the Web or Proxy tier would be exposed to the public internet; whereas the database tier would be completely inaccessible.
I had to skip the rest of the morning due to a couple of meetings but Phil Windley has some great coverage of Jane McGonigal's talk on Creating Alternate Realities.
In the afternoon there was a pretty good demo from Apple showing how easy it is manipulate pictures and video. All you need is a moderately powered super-computer - ie. like the one you're reading this text on.
Jeff Hawkins (inventor of the Palm Pilot and Treo) talked about Hierarchical Temporal Memory - the idea of HTM is to replicate some of the human brains congnitive functions - they learn from exposure to sensory data, discover cause and make predictions based on the sensory data and inferences. Some of this seemed a bit far-fetched - but hey, this is Jeff Hawkins (the inventor of the Palm Pilot and Treo).
Note to self - I must give "On Intelligence" another try - I wasn't sufficiently motivated to get past the first hour.
Much later in the day I attended a couple of (related) BoFs. The first was lead by Joe Gregorio covering APP (Atom Publishing Protocol) - I was interested in knowing where APP was in terms of adoption - it seems there's a bit of a chicken and egg situation - there won't be many clients supporting APP until there are some services and the services won't support APP without clients. Apparently APP (even before the RFC is final). There was some interesting side-chat about APP / Atom / RSS over Jabber / XMPI - apparently IM services aren't censored any where near as much as HTTP and VOIP - so it may well be the only truly universal transport.
Matt Mullenweg of WordPress claimed that WordPress would be supporting APP real soon - so hopefuly the cycle will be broken and the Web will get it's universal publish button. Anyone know when Roller will support APP ?
Next (in the same room) was the Microformats BoF run by Kevin Marks; who, significantly, works at Google. Most of the people in the room (me included) were merely there to learn a bit more but there was one guy (sorry I'm lousy with names) who was using rel-tag extensively. There was some discussion about how well microformats fit with APP; how microformats could deliver some of the power that Metaweb promises. This is another area I need to investigate a little more.
|
Mar
4
|
It's been a busy week and didn't get time to blog (maybe I'm becoming a weekend blogger). If I had, here are 3 things I would've blogged about :
First - here's the most lucid argument for net neutrality I've read in a while . According to Tim Berners-Lee (and he should know), the success of the web and the applications we've come to rely on is a direct result of it's open nature. Nobody has to seek permission before they launch the next killer app.
This question should scare the heck out of anyone who's experienced the dismal state of the US cell phone networks (currently stuck in the 1990's) :
"What if the Internet
wasn't designed the way it was? What if it worked more like cell phone
or satellite TV networks do here in the United States?"
Just thinking about this sends shivers down my spine.
Turn this around - what if the networks (cable and cell) worked like the Internet - what if I could get to Vodaphone, Verizon or Comcast content from my Cingular TTUP (Thing That Used to be a Phone). Who wouldn't win in this ideal world ?
Second - I seem to have given up on Performancing (for Firefox) - I'm now using the native Roller editor - AFAIK it does everything Performancing does and I no longer have to modify posted entries to add tags and remove unwanted breaks.
Third, Sun announced the fifth release of Java ES (official blurb here). Pat and Don cover some of the Identity Management Features and Alexis has the full skinny.
|
Jan
23
|
Two things to be pissed-off about this morning. First Performancing (which produce the spiffy Firefox blog editor plugin I use) looks like they''ve gone belly-up. According to TechCrunch the demise may not be as swift and as clean as you might hope for. I hope the blog editor lives on - I rather like it (though support for the Roller's tags would be nice).
Second blogrant - I'll be on the road for some of this week and next so was just setting everything up for working on the road when I noticed my Treo wasn't able to collect mail from Sun's edge mail service. I tried a bunch of stuff (that mere mortals shouldn't have to know about) but couldn't make it work. The Treo just kept insisting it was out of memory shortly after connecting to the IMAP server. I'm not one to give up easily (especially when fighting electronic stuff) but don't really have time to debug right now. So instead, I installed ChatterMail and was up and running in no time. In hindsight - I probably should have switched from VersaMail a long time ago - ChatterMail is a fine piece of software and I'll probably buy it when my 30-days are up. This is a pretty common complaint I hear about Palm's products - the included apps are generally OK - but you probably want to replace them with much better commercial apps. of which there is an abundance. Kudos to Palm for creating the business ecosystem to allow that - I wonder if that's the path that Apple will take with the iPhone.
|
Jan
8
|
OK, I just tidied up the tag cloud code a bit; there's now some scaling to ensure the 'intensity' is sensible. The template code relies on some styles which set the font size and opacity.
<div class="tagcloud">
#set ( $maxtags = 25)
#set($mytags = $model.weblog.getPopularTags(-1, $maxtags))
#set($maxtagcount = 0)
#set($mintagcount = 99999)
## number of styles s1-s10
#set($steps = 10)
## determine min and max tag count so we can scale the fonts and opacity
#foreach ($tag in $mytags)
#if($tag.count > $maxtagcount)
#set($maxtagcount=$tag.count)
#end
#if($tag.count < $mintagcount)
#set($mintagcount=$tag.count)
#end
#end
## generate the link for each tag assigning style accordinly
## the styles : s1-s10 increase in font size and opacity
#foreach ($tag in $mytags)
#set ($intensity=(${tag.count}-${mintagcount})*${steps}/(${maxtagcount}-${mintagcount}))
<a class="tag s${intensity}" href="$url.tag($tag.name)"
title="$tag.count entries">$tag.name</a>
#end
</div>
Relevant fragments from the stylesheet follow, first I set the abolsute position of the tag cloud then reduce the line-height for effect. Then I define s1-s10, increasing the font size and opacity proportionally. The opacity requires different hacks for different browsers and I still don't think I have all the IE versions covered. Sigh.
div.tagcloud
{
line-height:18px;
position: absolute;
text-align: right;
top: 90px;
right: 20px;
left: 600px;
}
.s1 {
font-size:18px;
filter:alpha(opacity=20);
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=20);
opacity:.2;
}
|
Dec
27
|
The Christmas break gave me some time to play around with Roller's new tagging support - a feature I've been wanting for quite a while. I don't see any need for categories anymore so I've removed the Dojo-enabled category chooser and replaced it with a tag cloud. The code is simpler and it doesn't need a big wad of JavaScript to run. The only tricky bit is my choice to use transparent text (using CSS's opacity property) or rather the fact that as with most things you have to code for Mozilla and various versions of Explorer. I'll rant about that at some future point when I've debugged the Explorer CSS code a bit more.
The macro to get at the tags is $model.weblog.getPopularTags(a1, a2) - I've no idea what the first argument is but -1 seems to work; the second argument specifies the number of tags to return. There another entry you can use within a post that will display the tags associated with the post - #showEntryTags($entry) - unfortunately the resulting markup doesn't have any styles associated so I may need to override the macro and add some.
The one thing that's still bugging me is the default Roller pager (ie. the text that says "Main | Next page >>") - I'll need to customize that macro so it says something like "Latest | Older >" and ensure it sits in one of the CSS containers so I can control it's location easier.
At some point I'll post the code - but I'll need to tidy it up a little first and make it a smart enough to scale as tag counts increase.
|
Dec
3
|
A couple of months ago I added a category chooser that uses Dojo (a powerful JavaScript library) to create a Fisheye effect. So, somewhat belatedly and as promised here's the code and a bit of explanation. Note, this was pre-Roller 3.0 so uses some of the old Roller macros.
First, you need to pull in the right JS libraries. On blogs.sun.com - the Dojo library is installed under roller-ui/dojo.
<script type="text/javascript">
var djConfig = {isDebug: true, debugAtAllCosts: false};
</script>
<script type="text/javascript" src="$url.absoluteSite/roller-ui/dojo/dojo.js"></script>
<script language="JavaScript" type="text/javascript">
dojo.require("dojo.widget.FisheyeList");
dojo.hostenv.writeIncludes();
</script>
Next is a little JS function to display a category :
<SCRIPT LANGUAGE="JavaScript" type="text/javascript">
function selectCategory(catname){
var url;
if (catname == 'All' ) {
url="$url.home"
}
else {
url="${url.home}category/"+catname
}
window.location.replace ( url );
}
</SCRIPT>
Next you create the Dojo Fisheye component :
<div class="chooser">
<div class="dojo-FisheyeList"
dojo:itemWidth="110" dojo:itemHeight="40"
dojo:itemMaxWidth="250" dojo:itemMaxHeight="90"
dojo:orientation="horizontal"
dojo:effectUnits="1"
dojo:itemPadding="0"
dojo:attachEdge="top"
dojo:labelEdge="bottom"
dojo:enableCrappySvgSupport="false" >
<div class="dojo-FisheyeListItem" onClick="selectCategory('All');"
dojo:iconsrc="$IMAGES/cat-All.png"
</div>
<div class="dojo-FisheyeListItem" onClick="selectCategory('About Me');"
dojo:iconsrc="$IMAGES/cat-AboutMe.png">
</div>
<div class="dojo-FisheyeListItem" onClick="selectCategory('Books');"
dojo:iconsrc="$IMAGES/cat-Books.png">
</div>
<div class="dojo-FisheyeListItem" onClick="selectCategory('Roller');"
dojo:iconsrc="$IMAGES/cat-Hacking.png">
</div>
<div class="dojo-FisheyeListItem" onClick="selectCategory('General');"
dojo:iconsrc="$IMAGES/cat-General.png">
</div>
<div class="dojo-FisheyeListItem" onClick="selectCategory('Java');"
dojo:iconsrc="$IMAGES/cat-Java.png">
</div>
<div class="dojo-FisheyeListItem" onClick="selectCategory('Home Life');"
dojo:iconsrc="$IMAGES/cat-HomeLife.png">
</div>
<div class="dojo-FisheyeListItem" onClick="selectCategory('Gadgets');"
dojo:iconsrc="$IMAGES/cat-Gadgets.png">
</div>
<div class="dojo-FisheyeListItem" onClick="selectCategory('W3');"
dojo:iconsrc="$IMAGES/cat-W3.png">
</div>
</div>
</div>
You should make this code generic by iterating through the categories but you'd need to label your images consistently. The only reason I did this cut and paste iteration was to aid debugging. I'll tidy it up at some point.
All the code above is in the Weblog template - which I have uploaded here. You'll also need some CSS so I've uploaded my template here. Feel free to hack, use, abuse as you see fit but shoot me a mail or leave a comment if you make any useful improvements.
I'm well aware this doesn't work in MS IE - I have no idea why; and don't have the tools to debug it. As Dojo is browser independent (or claims to be) - the problem is likely mine. Leave a comment if you can see what is wrong.
|
Nov
6
|
Finally - b.s.c now has support for tags. It even does delicious style completion in the built-in editors! I've been waiting for tags for a loooong time. At the weekend I mucked about with the macros for displaying tags - when I get time - I'm going to see if I can produce some tag eye-candy. I also think I'm going to remove the categories - I think they're a bit redundant. That of course means the Dojo fisheye category chooser has to go
One problem I now have is that I can't post from Performancing as it doesn't support Roller's tags. Wouldn't it be nice if there we're one universal publishing protocol for the web. Wouldn't it be nice if I could choose any tool for publishing to any repository - too much to ask ? Oh wait.
|
Sep
6
|
[note for non-US readers - by pimped I mean - 'tricked out' or 'blingbling' as in Pimp My Ride - nothing to do with prostitution]
Recently, I managed to convince the nice folks that run blogs.sun.com to host the Dojo toolkit - which they did. Subsequently I've been meaning to find the time to add some Dojo widgets to this blog and finally got around to it - see the Fisheye Category chooser at the top of the page. Hold off with the feedback for now - this is just a first hack and I know it needs some buffing.
What I thought might take an hour or so took much longer. My initial inclination was to use a tabbed layout for the categories but I ran into considerable 'impedence mismatch' between Roller's model and Dojo's so I dropped it and went for the much less intrusive FishEye instead. The tabbed layout will be a much better fit for the right-hand nav bar (and save space too). There are some other layout containers that might be a good fit for actual entries.
I've noticed that the image scaling is rather sucky with Firefox but is much cleaner on IE - though on IE the whole thing is badly broken - sorry IE users - you'll need one of these
- I probably need to experiment with larger image sizes but I was trying to keep them as lean as possible. Note - I used transparent PNGs (ie. they have no background) - that's a pretty neat Photoshop trick.
I'll post some code when it's been tidied up a bit
Technorati Tags: dojo, javascript, roller, pimped
|
Jul
28
|
To keep things clean and save space on The Aquarium - I compressed the entry timestamp like this :
This involved a simple trick - I simply extract the month and day in month parts of the timestamp then applied some styles - with a background image (the orange bit). I got the inspiration from here.
Here are the styles :
.ta-cal {
display:block;
float:left;
width:44px;
height:47px;
background:url("http://blogs.sun.com/roller/resources/theaquarium/cal.gif") no-repeat;
text-align:center;
margin-top:-10px;
margin-right:8px;
}
.ta-cal-month {
color:#fff;
font:bold 13px Arial, Verdana;
text-transform:uppercase;
margin:4px;
}
.ta-cal-day {
color:#fff;
font:bold 26px Arial, Verdana;
margin:-10px 0 0 0;
}
I'm sure there;s some redundancy in there and don't doubt this could be simplified - but it works. The way you use them is nest the ta-cal-month and ta-cal-day styled elements inside the ta-cal styled element, eg.
<div class="ta-cal">
<div class="ta-cal-month">#formatDate ( "MMM" $day )</div>
<div class="ta-cal-day">#formatDate ( "d" $day )</div>
</div>
$day is provided by Roller and the handy #formatDate macro is used to extract various bits of the timestamp (using java.text.SimpleDateFormat patterns).
Technorati Tags: roller velocity css|
Jul
23
|
Apologies for the mess.
I decided to give my blog a bit of a face-lift over the weekend but unfortunately ran out of time before I'd finished. Hopefully - I'll get it ship-shape over the next week (time permitting).
- Rich
|
Jul
21
|
I'm sharing some my experiences of hacking Roller templates in support of The Aquarium. Previous entries in the series :
Something I did recently was tidy up the _day template; I replaced some of the text links with icons and added icons for sending an entry to the reader's favourite social bookmarking service. Here's what the icons look like :
From left to right : del.icio.us, digg, Furl, simpy, Add or view comments and Edit the entry.
The comment and edit icons came from the Silk icons collection - which are very neat and very free.
OK, here's the code behind the icons. The tough part was understanding the request formats for each particular service - none of them are well documented so I had to hunt around a fair bit; which means youwon't have to (unless they change).
1 #macro ( entryButtons $entry ) 2 3 #set ( $IMAGES = "http://blogs.sun.com/roller/resources/theaquarium/" ) 4 5 #set ( $entryURL = "$absBaseURL/page/$userName?anchor=$entry.anchor" ) 6 #set ( $commentCount = $pageModel.getCommentCount($entry.id) ) 7 8 #if ( $commentCount == 1 ) 9 #set($numCommentsStr="1 Comment") 10 #set($commentIcon="commentAdded.gif") 11 #elseif ($commentCount > 1) 12 #set($numCommentsStr="$commentCount Comments") 13 #set($commentIcon="commentAdded.gif") 14 #else 15 #set($numCommentsStr="No Comments") 16 #set($commentIcon="comment.gif") 17 #end 18 19 #set ( $catname = $entry.Category.Name ) 20 21 <div class="ta-entry-footer"> 22 23 <a href="http://del.icio.us/post?url=$entryURL;title=$entry.title"> 24 <img src="$IMAGES/delicious.gif" title="Post to de.licio.us"></a> 25 26 <a href="http://digg.com/submit?phase=2&url=$entryURL&title=$entry.title"> 27 <img src="$IMAGES/digg.png" title="Digg this entry"></a> 28 29 <a href="http://www.furl.net/storeIt.jsp?t=$entry.title&u=$entryURL=$entry.anchor"> 30 <img src="$IMAGES/furl.png" title="Save to furl"></a> 31 32 <a href="http://www.simpy.com/simpy/LinkAdd.do?title=$entry.title&href=$entryURL=$entry.anchor"> 33 <img src="$IMAGES/simpy-icon-16x16.png" title="Save to Simpy"></a> 34 35 <a href="$entryURL#comments"> 36 <img src="$IMAGES/$commentIcon" title="$numCommentsStr"></a> 37 38 39 #if ($pageHelper.isUserAuthorizedToEdit()) 40 <a href="$pageHelper.getEntryEditUrl($entry)"> 41 <img src="$IMAGES/page_white_edit.png" title="Edit entry"></a> 42 #end 43 44 </div> 45 #end
OK, some of this requires a bit of an explanation, the macro takes one argument - the current $entry.
Lines 3-6 just define some convenient vars. to make the code a little less unreadable.
Lines 8-17 uses the comment count of the current entry to determine which icon to use (there's a different icon if comments already exist) as well as set the floatover text (which indicates the number of comments).
Lines 23-33 display the icons and form the URLs for each service - typically each service has a post / submit method followed by a title and URL parameter.
Lines 39-41 check to see if the current logged in user is authorized to edit entries and if so displays the edit button and link.
I also apply the following style :
.ta-entry-footer {
margin: 15px 30px;
padding-bottom: 15px;
border-bottom: 5px
}
That's it.
|
Jul
14
|
Previous entries in the series :
Before we dive into example code - a necessary preamble :
Disclaimer : If, as a result of following these tips or using this code, you break your blog, crash your machine or ruin your marriage - it's not my fault, or my employer's (Sun Microsystems).
License : You have my persmission to use, modify and re-distribute this code for fun, love or profit. If you improve it - please share the improvements.
Sorry about that.
The Aquarium covers a lot of subjects so we have a lot of categories. At some point Roller will have true tagging support so our use of categories will diminish. I wanted to keep the main page fairly clean (the content being the focus) so I knocked up a little JavaScript pulldown menu, populated from The Aquarium's category list.
Roller template code is not nice, it mixes VTL (Velocity Template Language), JavaScript and HTML in a way that can be a bit hard on the eyes.
First the JavaScript handler :
<SCRIPT LANGUAGE="JavaScript" type="text/javascript">Most of it is standard JavaScript but there's some VTL in there as well - the line that begins with "#" just defines a VTL variable which specifies the URL of the roller site. As you can see, string concatenation in VTL is pretty flexible but you do have to be aware of the various ways to escape VTL variables under certain circumstances. In this case nothing special is needed.
function selectCategory(catname){
var url;
#set( $blogURL = "$baseURL/page/$userName" )
if (catname == "All" )
{url="$blogURL" }
else
{ url="$blogURL/?catname=/"+catname }
window.location.replace ( url ); }
</SCRIPT>
Next is a bit of VTL to build the category list :
<FORM style="margin:0;padding:0">Nothing too complex here - I generally find the hardest bit is determining what information roller gives you access to; which is a lot. I haven't found a comprehensive list yet and usually resort to the Roller JavaDocs - things like $pageModel are just Java objects (beans) maintained by Roller (eg. you could equally well just call $cat.getName())
<p><SELECT Id="categ" ONCHANGE="selectCategory(this.value)">
<OPTION>--Select a Category--</OPTION>
<OPTION value="All">All</OPTION>
#set( $catlist = $pageModel.getWeblogCategories("/") )
#foreach( $cat in $catlist )
<OPTION value="$cat.Name">$cat.Name</OPTION>
#end
</SELECT></p>
</FORM>
Anyway, you can throw this code into your Weblog template and it should work but to ensure the template is readable you'd probably want to turn it into a macro and hide it somewhere. Exactly how to do that I'll touch on some other time.
|
Jul
14
|
Inbetween my day job and family life I'm a contributing editor with The Aquarium. I'm also the 'webmaster' - funny how, out of a group of super smart, senior engineers - the marketing guy ended up being the hacker :)
Anyway - I've invested a fair amount of time hacking Roller templates (Roller is the blogging software that powers blogs.sun.com among others) and thought it would be good to share some of my experiences here (where else but my Roller powered blog). I'm doing this for a number of reasons. Firstly - I didn't find many code fragments and samples on the web so I'd like to improve that situation; secondly - I really hacked some of this stuff together - I'm certain there are numerous better ways of doing some of these things - let me know.
OK, onto today's subject - what's a template and how to you modify it ?
Roller uses the Velocity template language which allows you to render Roller's object model onto your customized blog page. If you are familiar with JSP, PHP or other templating languages - nothing about Velocity will surprise you.
When you start out with Roller - you're going to be using an existing theme (there are 18 to choose from) and you access them under "Preference | Templates"
The first time you do this you won't see any templates because by default roller shares templates with other roller users until such time you need to modify your own local copy. I don't remember how Roller presents this but I seem to think it was pretty obvious what you have to do to get your own copy of the templates.
You'll now have a list of the templates. The exact list you'll see depends on which template you use. But the ones you're most likely to want to modify are Weblog and _day - these are standard templates that all themes require.
The _day template iterates through the blog entries for 1 day and presents them - so this is where you want to make changes the change the way blog entries are rendered.
The Weblog template is where you make changes to the site page (eg banners and side menus). Some templates may break this template into searate sub-templates to handle sidebars, headers and footers.
Another slightly interesting template is _decorator - (or it could be called _header) which wraps the Weblog template and defines things at the <head> / <body> level for your site. Eg. if you wanted to add <meta> tags or include stylesheets.
OK, that's a start - maybe some code next time.








