afuna: Cat under a blanket. Text: "Cats are just little people with Fur and Fangs" (Default)
afuna ([personal profile] afuna) wrote in [site community profile] changelog2009-08-05 07:12 am

[dw-free] Kill the portal

[commit: http://hg.dwscoalition.org/dw-free/rev/981e9adf07eb]

http://bugs.dwscoalition.org/show_bug.cgi?id=1551

Remove portal-related code.

Patch by denise.

Files modified:
  • bin/upgrading/en.dat
  • bin/upgrading/proplists.dat
  • cgi-bin/Apache/LiveJournal.pm
  • cgi-bin/LJ/ConfCheck/General.pm
  • cgi-bin/LJ/Portal.pm
  • cgi-bin/LJ/Portal/Box.pm
  • cgi-bin/LJ/Portal/Box/Birthdays.pm
  • cgi-bin/LJ/Portal/Box/CProd.pm
  • cgi-bin/LJ/Portal/Box/Debug.pm
  • cgi-bin/LJ/Portal/Box/FAQ.pm
  • cgi-bin/LJ/Portal/Box/Friends.pm
  • cgi-bin/LJ/Portal/Box/FriendsPage.pm
  • cgi-bin/LJ/Portal/Box/Manage.pm
  • cgi-bin/LJ/Portal/Box/NewUser.pm
  • cgi-bin/LJ/Portal/Box/Note.pm
  • cgi-bin/LJ/Portal/Box/Notifications.pm
  • cgi-bin/LJ/Portal/Box/PopWithFriends.pm
  • cgi-bin/LJ/Portal/Box/RandomUser.pm
  • cgi-bin/LJ/Portal/Box/Reader.pm
  • cgi-bin/LJ/Portal/Box/RecentComments.pm
  • cgi-bin/LJ/Portal/Box/Tags.pm
  • cgi-bin/LJ/Portal/Box/TextMessage.pm
  • cgi-bin/LJ/Portal/Box/UpdateJournal.pm
  • cgi-bin/LJ/Portal/Config.pm
  • cgi-bin/LJ/User.pm
  • cgi-bin/ljdefaults.pl
  • cgi-bin/ljlib.pl
  • cgi-bin/modperl_subs.pl
  • doc/raw/appendices/glossary.xml
  • doc/raw/build/ljconfig/ljconfig2db.pl
  • doc/raw/entities/ljp.book.ent
  • doc/raw/lj.book/install/ljconfig.disabled.xml
  • doc/raw/ljp.book/int/index.xml
  • doc/raw/ljp.book/int/memcache_keys_list.xml
  • doc/raw/ljp.book/int/portal_modules.xml
  • doc/raw/memcache-keys.txt
  • htdocs/js/portal.js
  • htdocs/portal/alter.bml
  • htdocs/portal/box.bml
  • htdocs/portal/get.bml
  • htdocs/portal/ig.bml
  • htdocs/portal/index.bml
  • htdocs/portal/index.bml.text
  • htdocs/portal/moz.bml
  • htdocs/portal/selectmodule.bml
  • htdocs/stc/portal/Dystopia.css
  • htdocs/stc/portal/MainStyle.css
--------------------------------------------------------------------------------
diff -r 1e10c8cffe6c -r 981e9adf07eb bin/upgrading/en.dat
--- a/bin/upgrading/en.dat	Wed Aug 05 07:06:56 2009 +0000
+++ b/bin/upgrading/en.dat	Wed Aug 05 07:10:05 2009 +0000
@@ -2383,108 +2383,6 @@ polls.link=poll creation wizard
 
 polls.text=[[user]], did you know you can post a poll in your journal using our [[link]]?  Find out what your friends <em>really</em> think about that shirt you bought last week. [[poll]]
 
-portal.bdays.count.des=By default, the 5 friends with the soonest birthdays are shown.
-
-portal.bdays.count.name=Birthdays to Display
-
-portal.bdays.portalname=Birthdays
-
-portal.bdays.portaltitle=Birthdays
-
-portal.login.portalname=Login Box
-
-portal.memories.entriesnoun=entries
-
-portal.memories.entrynoun=entry
-
-portal.memories.portalname=Memorable Posts
-
-portal.memories.portaltitle=Memorable Posts
-
-portal.ministats.active=Active:
-
-portal.ministats.title=User Stats
-
-portal.ministats.total=Total:
-
-portal.popfaq.portalname=10 Most Viewed FAQs
-
-portal.popfaq.portaltitle=10 Most Viewed FAQs
-
-portal.popwithfriends.accttype=Your account type does not permit use of this feature.
-
-portal.randuser.count.des=By default, 1 random user is shown, but you can have up to 10 vertically in the narrow columns, or 5 horizontally in a wide column
-
-portal.randuser.count.name=Number of random users to show
-
-portal.randuser.error.tableempty=There are no random users. Contact admin.
-
-portal.randuser.hidename.des=By default, the random user name is shown.  Check this to remove it.
-
-portal.randuser.hidename.name=Hide Name
-
-portal.randuser.hidepic.des=By default, the random user picture is shown, if available.  Check this to remove it.
-
-portal.randuser.hidepic.name=Hide User Picture
-
-portal.randuser.portalname=Random User
-
-portal.randuser.portaltitle=Random User
-
-portal.randuser.portaltitleplural=Random Users
-
-portal.recent.error.noentries=Sorry. No entries.
-
-portal.recent.error.notsetup=You have to configure this box.  Click the plus symbol to setup the journal you'd like to watch here.
-
-portal.recent.error.userstatus=User has deleted or suspended their account.
-
-portal.recent.items.description=By default, only the most recent entry is shown.
-
-portal.recent.items.name=Items to display
-
-portal.recent.journal.description=What journal do you want to see the recent items from?
-
-portal.recent.journal.name=Journal
-
-portal.recent.nosubject=(No Subject)
-
-portal.recent.permlink=Link
-
-portal.recent.portalname=Recent Entry View
-
-portal.recent.portaltitle=Recent Entry Box
-
-portal.recent.showtext.description=By default only subjects will be shown.
-
-portal.recent.showtext.name=Include Text
-
-portal.stats.journalentyest=Journal entries yesterday
-
-portal.stats.portalname=Site Statistics
-
-portal.stats.portaltitle=Statistics
-
-portal.stats.totalusers=Total users
-
-portal.update.entry=Entry:
-
-portal.update.mode.des=Full mode gives you a ton of extra posting options ... including posting in communities and setting your current mood, music, and picture.  Simple mode is nicer if you hardly use those features and would prefer not to see it all.
-
-portal.update.mode.full=Full
-
-portal.update.mode.name=Mode
-
-portal.update.mode.simple=Simple
-
-portal.update.moreopts=More Options
-
-portal.update.portalname=Journal Update
-
-portal.update.portaltitle=Update Your Journal
-
-portal.update.subject=Subject:
-
 protocol.bad_password=Your password is too easy to guess.  It's recommended that you change it, otherwise you risk having your journal hijacked.  Visit [[siteroot]]/changepassword.bml to change your password.
 
 protocol.hello_test=
diff -r 1e10c8cffe6c -r 981e9adf07eb bin/upgrading/proplists.dat
--- a/bin/upgrading/proplists.dat	Wed Aug 05 07:06:56 2009 +0000
+++ b/bin/upgrading/proplists.dat	Wed Aug 05 07:10:05 2009 +0000
@@ -854,14 +854,6 @@ userproplist.opt_show_captcha_to:
   multihomed: 0
   prettyname: Show CAPTHCHA on commenting
 
-userproplist.portalinit:
-  cldversion: 4
-  datatype: num
-  des: Has the user had their portal initialized yet?
-  indexed: 0
-  multihomed: 0
-  prettyname: Portal Init
-
 userproplist.profile_collapsed_headers:
   cldversion: 4
   datatype: char
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/Apache/LiveJournal.pm
--- a/cgi-bin/Apache/LiveJournal.pm	Wed Aug 05 07:06:56 2009 +0000
+++ b/cgi-bin/Apache/LiveJournal.pm	Wed Aug 05 07:10:05 2009 +0000
@@ -778,10 +778,6 @@ sub trans
 
             return $bml_handler->("$LJ::HOME/htdocs/extcss/index.bml");
 
-        } elsif ($func eq 'portal') {
-            # if this is a "portal" subdomain then prepend the portal URL
-            return redir($r, "$LJ::SITEROOT/portal/");
-
         } elsif ($func eq 'support') {
             return redir($r, "$LJ::SITEROOT/support/");
 
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/ConfCheck/General.pm
--- a/cgi-bin/LJ/ConfCheck/General.pm	Wed Aug 05 07:06:56 2009 +0000
+++ b/cgi-bin/LJ/ConfCheck/General.pm	Wed Aug 05 07:10:05 2009 +0000
@@ -523,24 +523,6 @@ add_conf('$LDAP_BASE',
 add_conf('$LDAP_BASE',
          type => '',
          des => "");
-add_conf('$PORTAL_TYPEMAP',
-         type => '',
-         des => "");
-add_conf('%PORTAL_TYPEMAP',
-         type => '',
-         des => "");
-add_conf('$PORTAL_DEBUG_CONTENT',
-         type => '',
-         des => "");
-add_conf('$PORTAL_BOX_PROFILE_START',
-         type => '',
-         des => "");
-add_conf('%PORTAL_PROFILED_BOX',
-         type => '',
-         des => "");
-add_conf('$PORTAL_BOX_PROFILE_END',
-         type => '',
-         des => "");
 add_conf('%COMMON_CODE',
          type => '',
          des => "");
@@ -602,18 +584,6 @@ add_conf('%POST_WITHOUT_AUTH',
          type => '',
          des => "");
 add_conf('$ALLOW_PICS_OVER_QUOTA',
-         type => '',
-         des => "");
-add_conf('@PORTAL_COLS',
-         type => '',
-         des => "");
-add_conf('$PORTAL_LOGGED_IN',
-         type => '',
-         des => "");
-add_conf('$PORTAL_LOGGED_OUT',
-         type => '',
-         des => "");
-add_conf('$PORTAL_URI',
          type => '',
          des => "");
 add_conf('$SYSBAN_IP_REFRESH',
@@ -724,9 +694,6 @@ add_conf('%MOGILEFS_CONFIG',
 add_conf('%MOGILEFS_CONFIG',
          type => '',
          des => "");
-add_conf('%PORTAL_DEFAULTBOXSTATES',
-         type => '',
-         des => "");
 add_conf('%SUPPORT_ABSTRACTS',
          type => '',
          des => "");
@@ -734,9 +701,6 @@ add_conf('%MINIMAL_STYLE',
          type => '',
          des => "");
 add_conf('%USERPROP_DEF',
-         type => '',
-         des => "");
-add_conf('@PORTAL_BOXES_HIDDEN',
          type => '',
          des => "");
 add_conf('@RBL_LIST',
@@ -752,9 +716,6 @@ add_conf('%DISABLED',
          type => '',
          des => "");
 add_conf('%HELPURL',
-         type => '',
-         des => "");
-add_conf('@PORTAL_BOXES',
          type => '',
          des => "");
 add_conf('@INITIAL_OPTIONAL_FRIENDS',
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal.pm
--- a/cgi-bin/LJ/Portal.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,567 +0,0 @@
-#!/usr/bin/perl
-
-package LJ::Portal;
-
-use strict;
-
-use lib "$LJ::HOME/cgi-bin";
-use LJ::Portal::Config;
-use LJ::Portal::Box;
-
-sub new {
-    my LJ::Portal $self = shift;
-
-    bless $self, "LJ::Portal";
-    return $self;
-}
-
-
-# Make sure that there is a typeid loaded for $class, and
-# insert one into the DB if none exists.
-# also loads typemaps from DB into $LJ::PORTAL_TYPEMAP
-
-# args: portal classname to look up ID for
-sub load_box_typeid {
-    my ($self, $class) = @_;
-
-    die "No portal box class defined" unless $class;
-
-    # is it process-cached?
-    return 1 if $LJ::PORTAL_TYPEMAP{$class};
-
-    # is it memcached?
-    my $memcached_typemap = LJ::MemCache::get("portal_typemap");
-    if ($memcached_typemap) {
-        # process-cache it
-        %LJ::PORTAL_TYPEMAP = %$memcached_typemap;
-
-        # if we have the class, we're cool
-        return 1 if $LJ::PORTAL_TYPEMAP{$class};
-    }
-
-    my $dbr = LJ::get_db_reader();
-    return undef unless $dbr;
-
-    # load typemap from DB
-    my $sth = $dbr->prepare("SELECT id, class_name FROM portal_typemap");
-    return undef unless $sth;
-    $sth->execute;
-
-    while (my $idmap = $sth->fetchrow_hashref) {
-        $LJ::PORTAL_TYPEMAP{$idmap->{'class_name'}} = $idmap->{'id'};
-    }
-
-    my $classid = $LJ::PORTAL_TYPEMAP{$class};
-
-    # do we have this class's ID?
-    if (!$classid) {
-        my $dbh = LJ::get_db_writer();
-        # box does not have an ID registered for itself in the DB
-        # try to insert
-
-        $dbh->do("INSERT IGNORE INTO portal_typemap (class_name) VALUES (?)",
-                 undef, $class);
-
-        if ($dbh->{'mysql_insertid'}) {
-            # inserted fine, get ID
-            $classid = $dbh->{'mysql_insertid'};
-        } else {
-            # race condition, try to select again
-            $classid = $dbh->selectrow_array("SELECT id FROM portal_typemap WHERE class_name = ?",
-                                           undef, $class)
-                or die "Portal typemap should have found ID after race";
-        }
-
-        # we had better have a classid by now... big trouble if we don't
-        die "Could not create typeid for portal module $class" unless $classid;
-
-        # save new classid
-        $LJ::PORTAL_TYPEMAP{$class} = $classid;
-    }
-
-    # memcache typeids
-    LJ::MemCache::set("portal_typemap", \%LJ::PORTAL_TYPEMAP, 120);
-
-    return $classid;
-}
-
-sub load_portal_boxes {
-    my $self = shift;
-
-    foreach my $boxclass (@LJ::PORTAL_BOXES) {
-        require "LJ/Portal/Box/${boxclass}.pm";
-    }
-}
-
-sub get_close_button {
-    return qq{<img src="$LJ::IMGPREFIX/portal/PortalConfigCloseButton.gif" width=19 height=19 title="Close" title="Close" valign="middle" />};
-}
-
-# get a little faq link and help icon
-sub get_faq_link {
-    my LJ::Portal $self = shift;
-    my $faqkey = shift;
-
-    return qq {
-        <a href="$LJ::HELPURL{$faqkey}"><img src="$LJ::IMGPREFIX/silk/site/help.png" class="PortalFaqLink" title="Help" /></a>
-    };
-}
-
-sub create_button {
-    my LJ::Portal $self = shift;
-    my ($text, $action) = @_;
-    $text = LJ::ehtml($text);
-    return qq{
-        <div class="PortalButton" onmousedown="this.className='PortalButton PortalButtonMouseDown';" onclick="$action" onmouseup="this.className='PortalButton';">$text</div>
-        };
-}
-
-sub get_portal_box_display_script {
-    my LJ::Portal $self = shift;
-    my ($id, $class_name, $inner_html, $parent) = @_;
-
-    # escape everything
-    $class_name = LJ::ejs($class_name);
-    $inner_html = LJ::ejs($inner_html);
-    $id = LJ::ejs($id);
-    $parent = LJ::ejs($parent);
-
-    return qq{
-        var boxelement = xCreateElement("div");
-        var parentelement = xGetElementById("$parent");
-        if (boxelement && parentelement) {
-            boxelement.id = "$id";
-            boxelement.className = "$class_name PortalBox";
-            boxelement.innerHTML = '$inner_html';
-            xAppendChild(parentelement, boxelement);
-            fadeIn(boxelement, 200);
-        }
-    };
-}
-
-sub get_portal_box_update_script {
-    my LJ::Portal $self = shift;
-    my ($config, $box) = @_;
-
-    my $pboxid = $box->pboxid();
-
-    # does this box have a handler to generate extra javascript to be executed
-    # when the box is reloaded?
-    my $onreload = '';
-    if ($box->can('box_updated')) {
-        $onreload = $box->box_updated;
-    }
-
-    my $newcontents = LJ::ejs($config->generate_box_insides($pboxid), 1);
-
-    return
-        qq{
-            var box = xGetElementById('pbox$pboxid');
-            if (box) {
-                box.innerHTML = "$newcontents";
-            }
-            if (box_reloading && box_reloading[$pboxid]) box_reloading[$pboxid]=0;
-            $onreload
-        };
-}
-
-sub get_portal_box_titlebar_update_script {
-    my LJ::Portal $self = shift;
-    my ($config, $box) = @_;
-
-    my $pboxid = $box->pboxid();
-    my $newcontents = LJ::ejs($config->generate_box_titlebar($box));
-    return
-        qq{
-            var bar = xGetElementById('pboxtitlebar$pboxid');
-            if (bar) {
-                bar.innerHTML = "$newcontents";
-            }
-        };
-}
-
-sub get_portal_config_box_update_script {
-    my LJ::Portal $self = shift;
-    my $box = shift;
-    return unless $box;
-
-    my $pboxid = $box->pboxid;
-    my $newcontents = LJ::ejs($box->generate_box_config_dialog(1));
-    return qq{
-            var confbox = xGetElementById('PortalFensterContentconfig$pboxid');
-            if (confbox) {
-                confbox.innerHTML = "$newcontents";
-            }
-        };
-}
-
-sub create_fenster {
-    my LJ::Portal $self = shift;
-    my ($id, $class_name, $inner_html, $parent, $title) = @_;
-
-    # escape everything
-    $title = LJ::ehtml($title);
-    $class_name = LJ::ejs($class_name);
-    $inner_html = LJ::ejs($inner_html);
-    $id = LJ::ejs($id);
-    $parent = LJ::ejs($parent);
-
-    my $titlebar_html = LJ::ejs(qq{
-        <div class="PortalPatternedTitleBar" id="portalbar$id">
-            <span class="PortalTitleBarText">$title</span>
-            </div>
-        });
-    return qq{
-        var boxelement    = xCreateElement("div");
-        var parentelement = xGetElementById("$parent");
-        if (boxelement && parentelement) {
-            xAppendChild(document.body, boxelement);
-            boxelement.id = "$id";
-            boxelement.style.position='absolute';
-            boxelement.className = "$class_name PortalFenster";
-            boxelement.innerHTML = '$titlebar_html <div class=\"PortalFensterContent NormalCursor\" id=\"PortalFensterContent$id\">$inner_html</div>';
-            fadeIn(boxelement);
-            boxelement.style.zIndex=4;
-        }
-    };
-}
-
-
-### XML HTTP Request Fun Stuff
-
-sub addbox {
-    my LJ::Portal $self = shift;
-    my ($portalconfig, $boxtype, $boxcol) = @_;
-
-    my $returncode = '';
-
-    if ($boxtype =~ /^\w+$/ && $boxcol =~ /^\w$/) {
-        my $newbox = $portalconfig->add_box("$boxtype", $boxcol);
-        if ($newbox) {
-            my $pboxid = $newbox->pboxid;
-            my $innerHTML = $portalconfig->generate_box_insides($pboxid);
-            my $boxclass = $newbox->box_class;
-            $returncode .= LJ::Portal->get_portal_box_display_script("pbox$pboxid", "PortalBox $boxclass", $innerHTML, "PortalCol$boxcol");
-
-            # update the arrows on the last box in the column
-            my $prevbox = $portalconfig->prev_box($newbox);
-            if ($prevbox) {
-                $returncode .= LJ::Portal->get_portal_box_titlebar_update_script($portalconfig, $prevbox);
-            }
-
-            $returncode = 'alert("Could not add box.");' if ! $returncode;
-        } else {
-            $returncode = 'alert("Could not create a box of that type.");';
-        }
-    } else {
-        $returncode = 'alert("Invalid box creation parameters.");';
-    }
-
-    # update add module menu in background
-    $returncode .= "\nupdateAddPortalModuleMenu();\n";
-
-    return $returncode;
-}
-
-sub configbox {
-    my LJ::Portal $self = shift;
-    my ($pboxid, $portalconfig, $jsmode) = @_;
-
-    my $box = $portalconfig->get_box_by_id($pboxid);
-    my $configboxhtml;
-    my $returncode;
-
-    if ($box) {
-        $configboxhtml = $box->generate_box_config_dialog($jsmode);
-
-        my $insertConfigBox =
-            LJ::Portal->create_fenster(
-                                       "config$pboxid", 'PortalBoxConfig',
-                                       $configboxhtml, "pbox$pboxid",
-                                       "Configure " . $box->box_name,
-                                       );
-
-        my $configboxjs = $insertConfigBox . qq{
-            var pbox = xGetElementById("pbox$pboxid");
-            var configbox = xGetElementById("config$pboxid");
-            if (pbox && configbox) {
-                xTop(configbox, xPageY(pbox));
-                centerBoxX(configbox);
-            }
-        };
-        $returncode = $configboxjs;
-    } else {
-        $returncode = 'alert("Could not load box properties.");';
-    }
-
-    return ($returncode, $configboxhtml);
-}
-
-sub movebox {
-    my LJ::Portal $self = shift;
-    my ($pboxid, $portalconfig, $boxcol,
-        $boxcolpos, $moveUp, $moveDown) = @_;
-
-    my $returncode;
-    my $oldSwapBox = undef;
-
-    if (($boxcolpos || $moveUp || $moveDown || $boxcol =~ /^\w$/) && $pboxid) {
-        my $box = $portalconfig->get_box_by_id($pboxid);
-        if ($box) {
-            my $inserted = 0;
-            my $oldPrevBox = $portalconfig->prev_box($box);
-            my $oldNextBox = $portalconfig->next_box($box);
-
-            if ($moveUp) {
-                $oldSwapBox = $portalconfig->move_box_up($box);
-            } elsif ($moveDown) {
-                $oldSwapBox = $portalconfig->move_box_down($box);
-            } else {
-                if ($boxcolpos) {
-                    # insert this box instead of append
-                    my $insertbeforebox = $portalconfig->find_box_by_col_order($boxcol, $boxcolpos+1);
-                    if ($insertbeforebox && $boxcol ne $box->col) {
-                        my $newsortorder = $insertbeforebox->sortorder;
-                        $portalconfig->insert_box(
-                                                  $box, $boxcol,
-                                                  $newsortorder
-                                                  );
-                        $inserted = 1;
-                        $oldSwapBox = $insertbeforebox;
-                    } else {
-                        # nothing to insert before, append
-                        $oldSwapBox = $portalconfig->move_box($box, $boxcol);
-                    }
-                } else {
-                    $oldSwapBox = $portalconfig->move_box($box, $boxcol);
-                }
-            }
-
-            $returncode = LJ::Portal->get_portal_box_titlebar_update_script($portalconfig, $box);
-
-            if ($oldPrevBox) {
-                $returncode .= LJ::Portal->get_portal_box_titlebar_update_script($portalconfig, $oldPrevBox);
-            }
-            if ($oldNextBox) {
-                $returncode .= LJ::Portal->get_portal_box_titlebar_update_script($portalconfig, $oldNextBox);
-            }
-
-            # if this box is going where a box already exists do a swap
-            if ($oldSwapBox) {
-                if ($inserted) {
-                    my $nextid = $oldSwapBox->pboxid;
-                    $returncode .= qq {
-                        var nextbox = xGetElementById("pbox$nextid");
-                        var toinsert = xGetElementById("pbox$pboxid");
-                        if (toinsert) {
-                            var par = xParent(toinsert, true);
-                            if (nextbox)
-                                par.insertBefore(toinsert, nextbox);
-                            else
-                                par.appendChild(toinsert);
-                        }
-                    };
-                }
-            }
-
-            # update the arrows on all adjacent boxes
-            my $prevbox = $portalconfig->prev_box($box);
-            my $nextbox = $portalconfig->next_box($box);
-            $returncode .= LJ::Portal->get_portal_box_titlebar_update_script($portalconfig, $prevbox) if ($prevbox && $prevbox != $oldPrevBox && $prevbox != $oldNextBox);
-            $returncode .= LJ::Portal->get_portal_box_titlebar_update_script($portalconfig, $nextbox) if ($nextbox && $nextbox != $oldPrevBox && $nextbox != $oldNextBox);
-        } else {
-            $returncode = 'alert("Box not found.");';
-        }
-    } else {
-        $returncode = 'alert("Invalid move parameters.");';
-    }
-
-    return $returncode;
-}
-
-sub getmenu {
-    my LJ::Portal $self = shift;
-    my ($portalconfig, $menu) = @_;
-
-    my $returncode;
-
-    if ($menu) {
-        if ($menu eq 'addbox') {
-            my @classes = $portalconfig->get_box_classes;
-
-            my $addboxtitle = BML::ml('/portal/index.bml.addbox');
-
-            $returncode .= qq{
-                    <div class="DropDownMenuContent PortalMenuItem">
-                    <table style="width:100%;" class="PortalMenuItem">
-                };
-
-            my $row = 0;
-            @classes = sort { "LJ::Portal::Box::$a"->box_name cmp "LJ::Portal::Box::$b"->box_name } @classes;
-            foreach my $boxclass (@classes) {
-                my $fullboxclass = "LJ::Portal::Box::$boxclass";
-                # if there can only be one of these boxes at a time and there
-                # already is one, don't show it
-                if ($portalconfig->get_box_unique($boxclass)) {
-                    next if $portalconfig->find_box_by_class($boxclass);
-                }
-
-                # is this box hidden from users?
-                # either box_hidden returns true or the box is in
-                # @LJ::PORTAL_BOXES_HIDDEN
-                if ( (@LJ::PORTAL_BOXES_HIDDEN && grep { $_ eq $boxclass }
-                      @LJ::PORTAL_BOXES_HIDDEN) || ($fullboxclass->can('box_hidden') &&
-                                                    $fullboxclass->box_hidden) ) {
-                    next;
-                }
-
-                my $boxname = $fullboxclass->box_name;
-                my $boxdesc = $fullboxclass->box_description;
-                my $boxcol  = $portalconfig->get_box_default_col($boxclass);
-                my $boxicon = $fullboxclass->box_icon;
-                my $addlink = qq{href="$LJ::SITEROOT/portal/index.bml?addbox=1&boxtype=$boxclass&boxcol=$boxcol" onclick="if(addPortalBox('$boxclass', '$boxcol')) return true; hidePortalMenu('addbox'); return false;"};
-                my $rowmod = $row % 2 + 1;
-                $returncode .= qq{
-                    <tr class="PortalMenuRow$rowmod PortalMenuItem">
-                        <td class="PortalMenuItem">
-                          <a $addlink class="PortalMenuItem">
-                            $boxicon <span class="PortalBoxTitleText PortalMenuItem">$boxname</span>
-                          </a>
-                          <div class="BoxDescription PortalMenuItem">$boxdesc</div>
-                        </td>
-                        <td align="center" valign="middle" class="PortalMenuItem">
-                          <a $addlink class="PortalMenuItem">
-                              <img src="$LJ::IMGPREFIX/portal/AddIcon.gif" title="Add this module" width="25" height="25" class="PortalMenuItem" />
-                          </a>
-                        </td>
-                        </tr>
-                        <br/>};
-                $row++;
-            }
-
-            my $resetask = LJ::ejs(BML::ml('/portal/index.bml.resetall'));
-
-            $returncode .= qq {
-                      <tr class="PortalMenuItem"><td colspan="2" class="PortalMenuItem">
-                          <div id="PortalResetAllButton" class="PortalMenuItem">
-                            <form action="$LJ::SITEROOT/portal/index.bml" method="POST" style="display: inline;">
-                                <input type="Submit" value="Reset..." name="resetall" onclick="return askResetAll('$resetask');" />
-                            </form>
-                          </div>
-                      </td></tr>
-                    </table>
-                </div>
-            };
-        }
-    } else {
-        $returncode = 'alert("Menu not specified.");';
-    }
-
-    return $returncode;
-}
-
-sub saveconfig {
-    my LJ::Portal $self = shift;
-    my ($portalconfig, $pboxid, $realform, $postvars) = @_;
-
-    my $box = $portalconfig->get_box_by_id($pboxid);
-    my $returncode;
-
-    if ($box) {
-        my $configprops = $box->config_props;
-        foreach my $propkey (keys %$configprops) {
-            if ($propkey) {
-                # slightly different format for non-POST submitted data
-                my $postkey = $realform ? "$propkey$pboxid" : $propkey;
-                my $propval = LJ::ehtml($postvars->{$postkey});
-
-                my $type = $configprops->{$propkey}->{'type'};
-                next if $type eq 'hidden';
-
-                # check to see if value is valid:
-                my $invalid = 0;
-
-                if ($type eq 'integer') {
-                    $invalid = 1 if ($propval != int($propval));
-                    $propval = int($propval);
-                    my $min = $configprops->{$propkey}->{'min'};
-                    my $max = $configprops->{$propkey}->{'max'};
-                    $invalid = 1 if ($min && $propval < $min);
-                    $invalid = 1 if ($max && $propval > $max);
-                } else {
-                    $propval = LJ::ehtml($propval);
-                }
-
-                if (!$invalid) {
-                    unless ($box->set_prop($propkey, $propval)) {
-                        return 'alert("Error saving configuration");';
-                    }
-                } else {
-                    return 'alert("Invalid input");';
-                }
-            }
-        }
-        $returncode .= LJ::Portal->get_portal_box_update_script($portalconfig, $box);
-        $returncode .= "hideConfigPortalBox($pboxid);";
-    } else {
-        $returncode = 'alert("Box not found.");';
-    }
-
-    return $returncode;
-}
-
-sub delbox {
-    my LJ::Portal $self = shift;
-    my ($portalconfig, $pboxid) = @_;
-
-    my $returncode;
-
-    if ($pboxid) {
-        my $box = $portalconfig->get_box_by_id($pboxid);
-        if ($box) {
-            $portalconfig->remove_box($pboxid);
-
-            # update the arrows on nearby boxes
-            my $prevbox = $portalconfig->prev_box($box);
-            my $nextbox = $portalconfig->next_box($box);
-            $returncode .= LJ::Portal->get_portal_box_titlebar_update_script($portalconfig, $prevbox) if ($prevbox);
-            $returncode .= LJ::Portal->get_portal_box_titlebar_update_script($portalconfig, $nextbox) if ($nextbox);
-        } else {
-            $returncode = 'alert("Box not found.");';
-        }
-    } else {
-        $returncode = 'alert("Box not specified.");';
-    }
-
-    # update add module menu in background
-    $returncode .= "\nupdateAddPortalModuleMenu();\n";
-
-    return $returncode;
-}
-
-sub resetbox {
-    my LJ::Portal $self = shift;
-    my ($pboxid, $portalconfig) = @_;
-
-    my $returncode;
-
-    if ($pboxid) {
-        my $box = $portalconfig->get_box_by_id($pboxid);
-
-        if ($box) {
-            $box->set_default_props;
-
-            $returncode .= LJ::Portal->get_portal_box_update_script($portalconfig, $box);
-            $returncode .= LJ::Portal->get_portal_config_box_update_script($box);
-            $returncode .= "hideConfigPortalBox($pboxid);\n";
-        } else {
-            $returncode = 'alert("Box not found.");';
-        }
-    } else {
-        $returncode = 'alert("Box not specified.");';
-    }
-
-    return $returncode;
-}
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box.pm
--- a/cgi-bin/LJ/Portal/Box.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,565 +0,0 @@
-# Portal box abstract base class
-# Subclass Box to create useful modules for portal
-
-# The box is responsible for managing all of its state in memory
-# and in the database.
-
-# Box contains lots of handy functions for setting and getting
-# per-box configuration options, displaying, making a config dialog,
-# moving around and more.
-
-package LJ::Portal::Box;
-use strict;
-use LJ::Portal::Config;
-use fields qw(pboxid col sortorder u boxprops);
-
-sub new {
-    my LJ::Portal::Box $self = shift;
-    $self = fields::new($self) unless ref $self;
-
-    my $pboxid = shift;
-    my $u = shift;
-
-    $self->{'u'} = $u if defined $u;
-    $self->{'pboxid'} = $pboxid if defined $pboxid;
-
-    # if called with $pboxid then load box config
-    $self->load_config if ($pboxid && $u);
-
-    return $self;
-}
-
-# box's display name
-sub box_name { '(no name)'; }
-# short description of what the box does
-sub box_description { '(no description)'; }
-# box class
-sub box_class { print STDERR "box class not defined!\n"; }
-
-#optional:
-    #sub initialize
-    #sub config_props
-    #sub prop_keys
-    #sub handle_request($get, $post)
-
-#####################################################
-
-# opts->{'force'} = don't load from memcache
-sub load_config {
-    my LJ::Portal::Box $self = shift;
-
-    my $pboxid = shift;
-    my $u = shift;
-    my $opts = shift || {};
-
-    $self->{'u'} ||= $u;
-    $self->{'pboxid'} ||= $pboxid;
-
-    return unless $self->{'u'} || $self->{'pboxid'};
-
-    my $state = $self->get_memcache_state;
-    if ($state && !$opts->{'force'}) {
-        $self->{'col'} = $state->{'col'};
-        $self->{'sortorder'} = $state->{'sortorder'};
-    } else {
-        my $sth = $self->{'u'}->prepare("SELECT col, sortorder FROM portal_config WHERE userid=? AND pboxid=?");
-        $sth->execute($self->{'u'}->{'userid'}, $self->{'pboxid'});
-        my ($col, $sortorder) = $sth->fetchrow_array;
-        $self->{'col'} = $col;
-        $self->{'sortorder'} = $sortorder;
-    }
-
-    # don't let the box load things if it's disabled
-    unless ($self->box_is_disabled) {
-        $self->load_props;
-
-        # tell subclass to initialize itself
-        $self->initialize if $self->can('initialize');
-    }
-}
-
-# delete self
-sub delete {
-    my LJ::Portal::Box $self = shift;
-
-    # delete this box from DB
-    $self->{'u'}->do("DELETE FROM portal_config WHERE pboxid=? AND userid=?",
-                     undef, $self->pboxid, $self->{'u'}->{'userid'});
-
-    LJ::MemCache::delete($self->memcache_key);
-    $self->delete_memcached_contents;
-    $self->delete_all_props;
-}
-
-# remove cached contents
-sub delete_memcached_contents {
-    my $self = shift;
-    LJ::MemCache::delete($self->contents_memcache_key) if $self->contents_memcache_key;
-}
-
-# memcache key for caching contents
-sub contents_memcache_key {
-    my $self = shift;
-
-    my $globalcache = 0;
-
-    # global if explicitly defined, otherwise per-box
-    $globalcache = 1 if ($self->can('cache_global') && $self->cache_global);
-
-    # calculate memcache key
-    if ($globalcache) {
-        return [$self->type_id, 'prtcong:' . $self->type_id];
-    }
-
-    return [$self->{'u'}->{'userid'}, 'prtconu:' .
-            $self->{'u'}->{'userid'} . ':' . $self->pboxid ];
-}
-
-# create a new box and save it
-# args: u, col, sortorder
-sub create {
-    my LJ::Portal::Box $self = shift;
-    my ($u, $col, $sortorder) = @_;
-
-    my $userid = $u->{'userid'};
-    return unless ($userid && $self->type_id);
-
-    $col ||= 'L';
-    $sortorder ||= 0;
-    my $pboxid = LJ::alloc_user_counter($u, 'O');
-    return unless $pboxid;
-
-    # save this box in the DB, then get the pboxid
-    $u->do("INSERT INTO portal_config (col, sortorder, type, userid, pboxid) VALUES (?, ?, ?, ?, ?)",
-                     undef, $col, $sortorder, $self->type_id,
-                     $userid, $pboxid);
-    if ($u->errstr) {
-        print STDERR "Error: " . $u->errstr . "\n"; # where should these go?
-        return undef;
-    }
-
-    $self->{'col'} = $col;
-    $self->{'sortorder'} = $sortorder;
-    $self->{'u'} = $u;
-    $self->{'pboxid'} = $pboxid;
-
-    $self->update_memcache_state;
-
-    return $self;
-}
-
-# returns an image of the icon for this box if one exists
-sub box_icon {
-    my LJ::Portal::Box $self = shift;
-    my $boxclass = $self->box_class;
-
-    # is there an icon for this box?
-    my $boxicon;
-    if (-e "$LJ::HTDOCS/img/portal/ModuleIcons/$boxclass.gif") {
-        $boxicon = "<span class=\"PortalBoxIcon\"><img src=\"$LJ::IMGPREFIX/portal/ModuleIcons/$boxclass.gif\" valign=\"bottom\" /></span>";
-    }
-
-    return $boxicon;
-}
-
-sub type_id {
-    my LJ::Portal::Box $self = shift;
-    return LJ::Portal::Config->type_string_to_id($self->box_class);
-}
-
-sub pboxid {
-    my LJ::Portal::Box $self = shift;
-    return $self->{'pboxid'};
-}
-
-sub box_is_disabled {
-    my LJ::Portal::Box $self = shift;
-
-    my $type = $self->box_class;
-    return ! LJ::is_enabled("portal-$type");
-}
-
-# getter and setter
-sub col {
-    my LJ::Portal::Box $self = shift;
-    if ( $_[0] ) {
-        my $newcol = shift if $_[0] =~ /^[A-Z]$/i;
-        $self->{'col'} = $newcol;
-        $self->{'u'}->do("UPDATE portal_config SET col=? WHERE userid=? AND pboxid=?",
-                          undef, $self->{'col'}, $self->{'u'}->{'userid'}, $self->{'pboxid'});
-        $self->update_memcache_state;
-    }
-    return $self->{'col'};
-}
-
-# getter and setter
-sub sortorder {
-    my LJ::Portal::Box $self = shift;
-    my $userid = $self->{'u'}->{'userid'};
-    if ( $_[0] ) {
-        my $neworder = shift if $_[0] =~ /^\d$/;
-        $self->{'sortorder'} = $neworder;
-        $self->{'u'}->do("UPDATE portal_config SET sortorder=? WHERE userid=? AND pboxid=?",
-                          undef, $self->{'sortorder'}, $userid, $self->{'pboxid'});
-        $self->update_memcache_state;
-    }
-
-    return $self->{'sortorder'};
-}
-
-sub update_memcache_state {
-    my LJ::Portal::Box $self = shift;
-    LJ::MemCache::set($self->memcache_key, $self->get_state) if $self->memcache_key;
-}
-
-sub get_memcache_state {
-    my LJ::Portal::Box $self = shift;
-    my $state = LJ::MemCache::get($self->memcache_key);
-    return $state;
-}
-
-sub memcache_key {
-    my LJ::Portal::Box $self = shift;
-    if ($self->{'u'} && $self->{'pboxid'}) {
-        my $key = [ $self->{'u'}->{'userid'}, "prtbox:$self->{'u'}->{'userid'}:" . $self->pboxid ];
-        return $key;
-    }
-    return undef;
-}
-
-# return a representation of the current box for storage
-sub get_state {
-    my LJ::Portal::Box $self = shift;
-    my $state = {
-                 'col'       => $self->{'col'},
-                 'sortorder' => $self->{'sortorder'},
-                 'pboxid'    => $self->{'pboxid'},
-                 'boxprops'  => $self->{'boxprops'},
-                };
-    return $state;
-}
-
-sub move {
-    my LJ::Portal::Box $self = shift;
-    my ($col, $sortorder) = @_;
-    return unless $self->{'u'};
-    return if (!$col && !$sortorder);
-
-    $self->{'col'} = $col if $col;
-    $self->{'sortorder'} = $sortorder if $sortorder;
-
-    # save settings
-    $self->{'u'}->do("UPDATE portal_config SET col=?, sortorder=? WHERE pboxid=? AND userid=?",
-                     undef, $self->{'col'}, $self->{'sortorder'},
-                     $self->{'pboxid'}, $self->{'u'}->{'userid'});
-
-    $self->update_memcache_state;
-}
-
-sub load_props {
-    my LJ::Portal::Box $self = shift;
-    my $userid = $self->{'u'}->{'userid'};
-    my $pboxid = $self->{'pboxid'};
-
-    return if ref $self->{'boxprops'};
-
-    $self->{'boxprops'} = {};
-
-    return unless ($userid && $pboxid);
-
-    my $state = $self->get_memcache_state;
-    if ($state) {
-        $self->{'boxprops'} = $state->{'boxprops'};
-    } else {
-        my $sth = $self->{'u'}->prepare("SELECT propvalue,ppropid FROM portal_box_prop WHERE userid=? AND pboxid=?");
-        $sth->execute($userid, $pboxid);
-
-        while (my $row = $sth->fetchrow_hashref) {
-            $self->{'boxprops'}->{$row->{'ppropid'}} = $row->{'propvalue'};
-        }
-    }
-    $self->update_memcache_state;
-}
-
-sub box_props {
-    my LJ::Portal::Box $self = shift;
-    return $self->{'boxprops'};
-}
-
-sub get_props {
-    my LJ::Portal::Box $self = shift;
-    my $boxprops = $self->prop_keys;
-
-    my $props = {};
-    map { $props->{$_} = $self->get_prop($_) } keys %$boxprops;
-
-    return $props;
-}
-
-sub get_prop {
-    my LJ::Portal::Box $self = shift;
-    my $propstr = shift;
-
-    my $propid = $self->get_prop_id($propstr);
-    my $propval = $self->{'boxprops'}->{$propid};
-    my $_config_props = $self->config_props;
-
-    my $default = $_config_props->{$propstr}->{'default'};
-    $propval = defined $propval ? $propval : $default;
-
-    return $propval;
-}
-
-# return a propid for a string
-sub get_prop_id {
-    my LJ::Portal::Box $self = shift;
-    my $propname = shift;
-
-    my $configprops = $self->prop_keys;
-    return $configprops->{$propname};
-}
-
-sub set_default_props {
-    my LJ::Portal::Box $self = shift;
-
-    return unless $self->can('config_props') && $self->can('prop_keys');
-
-    my $_config_props = $self->config_props;
-    my $propkeys = $self->prop_keys;
-    my $default_props = {};
-    foreach my $propkey (keys %$_config_props) {
-        my $default = $_config_props->{$propkey}->{'default'};
-        $default_props->{$propkey} = $default if defined $default;
-    }
-    $self->set_props($default_props) if $default_props != {};
-    $self->delete_memcached_contents;
-    $self->update_memcache_state;
-}
-
-sub set_prop {
-    my LJ::Portal::Box $self = shift;
-    my ($propstr, $propval) = @_;
-
-    my $propid = $self->get_prop_id($propstr);
-    my $u = $self->{'u'};
-
-    $propid += 0;
-    return undef unless ($self->{'pboxid'} || $u || $propid);
-
-    # don't update memcache and do query if setting prop to the current value
-    if ($self->{'boxprops'}->{$propid} ne $propval) {
-        $self->{'boxprops'}->{$propid} = $propval;
-
-        #save prop
-        $u->do("REPLACE INTO portal_box_prop (propvalue,ppropid,userid,pboxid) VALUES " .
-                         "(?, ?, ?, ?)",
-                         undef, $propval, $propid, $u->{'userid'}, $self->pboxid);
-
-        if ($u->errstr) {
-            print STDERR "Error: " . $u->errstr . "\n";
-            return undef;
-        }
-
-        $self->update_memcache_state;
-        $self->delete_memcached_contents;
-    }
-
-    return 1;
-}
-
-sub delete_prop {
-    my LJ::Portal::Box $self = shift;
-    my $propid = shift;
-
-    $propid += 0;
-    $self->{'u'}->do("DELETE FROM portal_box_prop WHERE userid=? AND pboxid=? AND ppropid=?",
-                     undef, $self->{'u'}->{'userid'}, $self->pboxid, $propid);
-    delete $self->{'boxprops'}->{$propid};
-    $self->update_memcache_state;
-}
-
-sub delete_all_props {
-    my LJ::Portal::Box $self = shift;
-
-    foreach my $propid (keys %{$self->{'boxprops'} || {}}) {
-        delete $self->{'boxprops'}->{$propid};
-    }
-
-    $self->{'u'}->do("DELETE FROM portal_box_prop WHERE userid=? AND pboxid=?",
-                     undef, $self->{'u'}->{'userid'}, $self->pboxid);
-
-    $self->update_memcache_state;
-}
-
-# TODO: optimize query?
-sub set_props {
-    my LJ::Portal::Box $self = shift;
-    my $props = shift;
-
-    foreach my $propstr (keys %$props) {
-        $self->set_prop($propstr, $props->{$propstr});
-    }
-}
-
-# create the html for a box that contains a config dialog for this box.
-# When the user clicks save, it will try to do an XML HTTP request to save
-# the config, and if that fails then a normal submit.
-sub generate_box_config_dialog {
-    my LJ::Portal::Box $self = shift;
-    my $jsmode = shift;
-
-    return unless $self->config_props;
-
-    my $pboxid = $self->pboxid;
-    my $props = $self->box_props;
-    my $configopts = $self->config_props;
-    my $formelements = '';
-    my $config = '';
-    my $selflink = '/portal/index.bml';
-
-    $config .= qq {
-        <form action='$selflink' method='POST' name='configform$pboxid' id='configform$pboxid' style='display: inline;'>
-            <div class="PortalBoxConfigContent">
-        };
-
-    $config .= "<table><tbody>";
-    $config .= LJ::html_hidden({'name' => 'realform', 'value' => 1, 'id' => "realform$pboxid"},
-                               {'name' => 'pboxid', 'value' => $pboxid});
-
-    my @opts = sort {$self->get_prop_id($a) <=> $self->get_prop_id($b)} keys %$configopts;
-
-    foreach my $optkey (@opts) {
-        my $opt = $configopts->{$optkey};
-        my $name = LJ::ehtml($optkey);
-        my $type = $opt->{'type'};
-        my $disabled = $opt->{disabled} ? ((ref $opt->{disabled} eq 'CODE') ? $opt->{disabled}->($self) : '') : '';
-        my $desc = LJ::ehtml($opt->{'desc'});
-        my $propkey = $optkey;
-        my $propval = LJ::ehtml($self->get_prop($propkey) || $opt->{'default'});
-
-        my $inputfield;
-
-        $config .= '<tr><td>';
-
-        if ($type eq 'checkbox') {
-
-            $inputfield .= "<label for='$name$pboxid'>";
-            $inputfield .= "$desc: </td><td>";
-
-            # checkboxes are dumb.
-            if ($self->get_prop($propkey)) {
-                $inputfield .= LJ::html_check({
-                    'name' => $name . $pboxid,
-                    'id' => $name . $pboxid,
-                    'checked' => 1,
-                    'disabled' => $disabled,
-                });
-            } else {
-                $inputfield .= LJ::html_check({
-                    'name' => $name . $pboxid,
-                    'id' => $name . $pboxid,
-                    'disabled' => $disabled,
-                });
-            }
-
-            $inputfield .= "</label>";
-
-        } elsif ($type eq 'dropdown') {
-
-            $inputfield = "$desc: </td><td>";
-
-            # make a dropdown menu composed of items
-            my $selected = '';
-
-            $inputfield .= "<select name='$name$pboxid' id='$name$pboxid'>\n";
-
-            my $items = $opt->{'items'};
-
-            foreach my $item (keys %$items) {
-                if ($self->get_prop($propkey) eq $item) {
-                    $selected = 'selected';
-                } else {
-                    $selected = '';
-                }
-
-                $item = LJ::ehtml($item);
-                my $itemtitle = LJ::ehtml($items->{$item});
-                $inputfield .= "<option value='$item' $selected>$itemtitle</option>\n";
-            }
-            $inputfield .= '</select>';
-
-        } elsif ($type eq 'integer') {
-
-            $inputfield = "$desc: </td><td>";
-
-            $inputfield .= LJ::html_text({'id' => $name . $pboxid,
-                                          'value' => $propval,
-                                          'maxlength' => $opt->{'maxlength'},
-                                          'size' => $opt->{'maxlength'} || 3,
-                                          'max' => $opt->{'max'},
-                                          'min' => $opt->{'min'},
-                                          'name' => $name . $pboxid,
-                                      });
-       } elsif ($type eq 'string') {
-
-            $inputfield = "$desc: </td><td>";
-
-            $inputfield .= LJ::html_text({'id' => $name . $pboxid,
-                                          'value' => $propval,
-                                          'maxlength' => $opt->{'maxlength'},
-                                          'size' => $opt->{'maxlength'} || 3,
-                                          'name' => $name . $pboxid,
-                                      });
-
-        } elsif ($type eq 'hidden') {
-            #do nothing
-        } else {
-            print STDERR "Warning: unknown box config type $type\n";
-        }
-
-        $formelements .= $name . ',' unless $type eq 'hidden';
-        $config .= "<div>$inputfield</div></td></tr>";
-    }
-    $config .= '</tbody></table>';
-
-    chop $formelements;
-
-    my $buttons = '<div class="PortalConfigSubmitButtons">';
-
-    $buttons .= "<span class=\"PortalConfigResetButton\">";
-
-    # text link for non-javascript browsers
-    if (!$jsmode) {
-        $buttons .= "<a href=\"$selflink?resetbox=1&pboxid=$pboxid\" onclick=\"return resetBox($pboxid);\">Reset</a>";
-    } else {
-        $buttons .= qq {
-            <input type="Button" value="Reset" onclick="return resetBox($pboxid);" />
-            };
-    }
-    $buttons .= "</span>";
-
-    $buttons .= qq {
-        <span class="PortalConfigCancelButton">
-            <input type="button" value="Cancel" onclick="fadeOut('config$pboxid'); return false;" />
-        </span>
-    } if $jsmode;
-
-    $buttons .= '<span class="PortalConfigSubmitButton">';
-    $buttons .= LJ::html_submit('saveconfig', 'Save Settings', {'raw' => "onclick=\"if(savePortalBoxConfig($pboxid)) configform$pboxid.submit(); else return false;\""});
-    $buttons .= qq{<input type="hidden" id="box_config_elements$pboxid" value="$formelements"/>};
-    $buttons .= qq {
-          </span>
-        </div>
-      </form>
-  };
-
-    my $dialogbox = qq{
-            $config
-        </div>
-        $buttons
-    };
-
-    return $dialogbox;
-}
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box/Birthdays.pm
--- a/cgi-bin/LJ/Portal/Box/Birthdays.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-package LJ::Portal::Box::Birthdays; # <--- Change this
-use base 'LJ::Portal::Box';
-use strict;
-
-######################## override this stuff ######################
-
-our $_box_class = "Birthdays";
-our $_prop_keys = { 'Show' => 1 };
-our $_config_props = {
-    'Show' => { 'type'    => 'integer',
-                'desc'    => 'Maximum number of friends to show',
-                'max'     => 50,
-                'min'     => 1,
-                'maxlength' => 2,
-                'default' => 5} };
-our $_box_description = 'Show upcoming birthdays of your friends.';
-our $_box_name = "Friends' Birthdays";
-
-sub generate_content {
-    my $self = shift;
-    my $u = $self->{'u'};
-    my @bdays = $u->get_birthdays
-        or return "(No upcoming friends' birthdays.)";
-
-    my $content = '';
-
-    my $now = $u->time_now;
-
-    # cut the list down
-    my $show = $self->get_prop('Show');
-    if (@bdays > $show) { @bdays = @bdays[0..$show-1]; }
-
-    $content .= "<table width='100%'>";
-    my $add_ord = BML::get_language() =~ /^en/i;
-    foreach my $bi (@bdays)
-    {
-        my $mon = LJ::Lang::month_short_ml( $bi->[0] );
-        my $day = $bi->[1];
-        $day .= LJ::Lang::day_ord($bi->[1]) if $add_ord;
-
-        # if their birthday is today then say so
-        my $datestr = ($bi->[1] == $now->day && $bi->[0] == $now->month) ? 'Today' : "$mon $day";
-
-        $content .= "<tr><td nowrap='nowrap'><b>" . LJ::ljuser($bi->[2]) . "</b></td>";
-        $content .= "<td align='right' nowrap='nowrap'>$datestr</td>";
-        my $birthday_extra = LJ::run_hook("birthday_extra_html", $bi->[2]);
-        $content .= $birthday_extra ? "<td>$birthday_extra</td>" : '';
-        $content .= '</tr>';
-    }
-    $content .= "</table>";
-
-    return $content;
-}
-
-
-#######################################
-
-
-sub box_description { $_box_description; }
-sub box_name { $_box_name; };
-sub config_props { $_config_props; }
-sub prop_keys { $_prop_keys; }
-sub box_class { $_box_class; }
-
-# caching options
-sub cache_global { 0; } # cache per-user
-sub cache_time { 30 * 60; } # check etag every 30 minutes
-sub etag {
-    my $self = shift;
-    my $now = DateTime->now;
-
-    return $self->get_prop('Show') + $now->day;
-}
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box/CProd.pm
--- a/cgi-bin/LJ/Portal/Box/CProd.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-package LJ::Portal::Box::CProd; # <--- Change this
-use base 'LJ::Portal::Box';
-use strict;
-
-######################## override this stuff ######################
-
-our $_box_class = "CProd";
-our $_box_description = 'Frank the Goat thinks you might enjoy these features';
-our $_box_name = "What else has LJ been hiding?";
-
-sub generate_content {
-    my $self = shift;
-
-    my $u = $self->{u};
-    my $box = LJ::CProd->full_box_for($u, style => 'plain');
-    return $box;
-}
-
-# mark this cprod as having been viewed
-sub box_updated {
-    my $self = shift;
-
-    my $u = $self->{u};
-    my $prod = LJ::CProd->prod_to_show($u);
-    LJ::CProd->mark_acked($u, $prod) if $prod;
-    return 'CProd.attachNextClickListener();';
-}
-
-#######################################
-
-sub box_description { $_box_description; }
-sub box_name { $_box_name; }
-sub box_class { $_box_class; }
-sub can_refresh { 1 }
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box/Debug.pm
--- a/cgi-bin/LJ/Portal/Box/Debug.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-package LJ::Portal::Box::Debug; # <--- Change this
-use base 'LJ::Portal::Box';
-use strict;
-
-######################## override this stuff ######################
-
-our $_box_description = 'Debug';
-our $_box_name = "Debug";
-our $_box_class = "Debug";
-
-sub generate_content {
-    my $self = shift;
-
-    if ($LJ::PORTAL_DEBUG_CONTENT) {
-        return qq {
-            <pre>$LJ::PORTAL_DEBUG_CONTENT
-            </pre>
-        };
-    }
-
-    return "No debug data.";
-}
-
-
-#######################################
-
-
-sub box_description { $_box_description; }
-sub box_name { $_box_name; };
-sub box_class { $_box_class; }
-
-# hide this box in the add module menu
-sub box_hidden { 1; };
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box/FAQ.pm
--- a/cgi-bin/LJ/Portal/Box/FAQ.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-package LJ::Portal::Box::FAQ; # <--- Change this
-use base 'LJ::Portal::Box';
-use strict;
-
-######################## override this stuff ######################
-
-our $_box_description = "Frequently asked questions";
-our $_box_name = "FAQs";
-our $_box_class = "FAQ";
-
-our $_prop_keys = {
-    'show_top_ten' => 1,
-    'show_faq_of_day' => 2,
-};
-
-our $_config_props = {
-    'show_top_ten' => {
-        'type'      => 'checkbox',
-        'desc'      => 'Display the top ten frequently asked questions',
-        'default'   => 1,
-    },
-    'show_faq_of_day' => {
-        'type'      => 'checkbox',
-        'desc'      => 'Display FAQ of the day',
-        'default'   => 1,
-    },
-};
-
-sub generate_content {
-    my $self = shift;
-    my $pboxid = $self->{'pboxid'};
-    my $u = $self->{'u'};
-    my $content;
-
-    my $showtopten = $self->get_prop('show_top_ten');
-    my $showFOD = $self->get_prop('show_faq_of_day');
-
-    my $dbr = LJ::get_db_reader();
-    return "Could not load DB reader." unless $dbr;
-
-    if ($showtopten) {
-        my $remote = LJ::get_remote();
-        my $user;
-        my $user_url;
-
-        # Get remote username and journal URL, or example user's username and
-        # journal URL
-        if ($remote) {
-            $user = $remote->user;
-            $user_url = $remote->journal_base;
-        } else {
-            my $u = LJ::load_user($LJ::EXAMPLE_USER_ACCOUNT);
-            $user = $u ? $u->user : "<b>[Unknown or undefined example username]</b>";
-            $user_url = $u ? $u->journal_base : "<b>[Unknown or undefined example username]</b>";
-        }
-
-        my $sth = $dbr->prepare("SELECT statkey, statval FROM stats WHERE statcat='pop_faq' ORDER BY statval DESC LIMIT 10");
-        $sth->execute;
-
-        $content .= qq {
-            <b>Most popular FAQs:</b>
-            <ul>
-            };
-
-        while (my $s = $sth->fetchrow_hashref) {
-            my $f = LJ::Faq->load($s->{statkey}, lang => BML::get_language());
-            $f->render_in_place({user => $user, url => $user_url});
-            my $q = $f->question_html;
-            $q =~ s/^\s+//; $q =~ s/\s+$//;
-            $q =~ s/\n/<BR>/g;
-            $content .= "<li><a href='/support/faqbrowse.bml?faqid="
-                . $f->faqid . "'>$q</a> <i>($s->{statval})</i></li>\n";
-        }
-        $content .= "</ul>\n";
-    }
-
-    if ($showFOD) {
-        # pick a random FAQ.
-        my $sth = $dbr->prepare( qq {
-            SELECT faqid, question, faqcat FROM faq f WHERE f.faqcat<>'int-abuse' AND f.faqcat<>''
-            } );
-        $sth->execute;
-
-        my $faqs = $sth->fetchall_arrayref;
-        return 'Could not load FAQs' unless $faqs;
-
-        my $randfaqindex = int(rand(scalar @$faqs));
-        my $randfaq = $faqs->[$randfaqindex];
-        my $faqid = $randfaq->[0];
-        my $question = $randfaq->[1];
-
-        $content .= qq {
-            <b>FAQ of the Day:</b>
-            <ul>
-                <li>
-                <a href="/support/faqbrowse.bml?faqid=$faqid">$question</a>
-                </li>
-            </ul>
-        };
-    }
-
-    my $currlang = BML::get_language()|| $LJ::DEFAULT_LANG;
-
-    $content .= qq {
-            <b>FAQ Search:</b>
-            <form action="$LJ::SITEROOT/support/faqsearch.bml" method="GET">
-            <input type="hidden" name="lang" value="$currlang" />
-            <div style="padding: 5px;">
-              } . LJ::html_text({ name => 'q' }) . qq {
-                  &nbsp;<input type='submit' value='Search' /><br/>
-            </div>
-            </form>
-        };
-
-    return $content;
-}
-
-# caching options
-sub cache_global { 0; } # cache per-user
-sub cache_time { 60 * 60; } # check etag every hour
-sub etag {
-    my $self = shift;
-
-    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
-    return "$year-$mon-$mday"; # recalculate contents every day (with new random FAQ and stats)
-}
-
-#######################################
-
-
-sub box_description { $_box_description; }
-sub box_name { $_box_name; };
-sub box_class { $_box_class; }
-sub config_props { $_config_props; }
-sub prop_keys { $_prop_keys; }
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box/Friends.pm
--- a/cgi-bin/LJ/Portal/Box/Friends.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-package LJ::Portal::Box::Friends; # <--- Change this
-use base 'LJ::Portal::Box';
-use strict;
-
-######################## override this stuff ######################
-
-our $_box_description = 'Show your friends';
-our $_box_name = "Friends";
-our $_box_class = "Friends";
-our $_prop_keys = {
-    'showsyn' => 3,
-    'maxshow' => 5,
-    'showcomm' => 4,
-};
-
-our $_config_props = {
-    'showsyn' => {
-        'type'      => 'checkbox',
-        'desc'      => 'Show syndicated accounts',
-        'default'   => '1',
-    },
-    'showcomm' => {
-        'type'      => 'checkbox',
-        'desc'      => 'Show communities',
-        'default'   => '1',
-    },
-    'maxshow' => {
-        'type'    => 'integer',
-        'desc'    => 'Maximum number of friends to show',
-        'default' => 150,
-        'min'     => 1,
-        'max'     => 1000,
-    },
-};
-
-sub generate_content {
-    my $self = shift;
-    my $pboxid = $self->{'pboxid'};
-    my $u = $self->{'u'};
-
-    my $usericonguy = "<img src=\"$LJ::SITEROOT/img/silk/identity/user.png\" />";
-
-    my $content;
-
-    my $showsyn= $self->get_prop('showsyn');
-    my $showcomm= $self->get_prop('showcomm');
-    my $maxshow= $self->get_prop('maxshow');
-
-    # display current friends of u
-    my $friends_u = $u->circle_users;
-    my $friendcount = 0;
-    my $foundfriends = 0;
-    my $friendlist;
-    my $displaying;
-
-    if ($friends_u) {
-        grep { $friendcount++ if $friends_u->{$_}->is_person; } keys %$friends_u;
-        my @sortedfriends = sort { $friends_u->{$a}->{'user'} cmp $friends_u->{$b}->{'user'} } keys %$friends_u;
-
-        foreach my $fid (@sortedfriends) {
-            my $fu = $friends_u->{$fid};
-            next unless $fu->is_person;
-
-            unless ($foundfriends < $maxshow) {
-                chop $friendlist;
-                chop $friendlist;
-                $friendlist .= "... (<a href=\"$LJ::SITEROOT/userinfo.bml?user=$u->{user}\">See all</a>)  ";
-                last;
-            }
-            $foundfriends++;
-
-            my $journallink = $fu->journal_base();
-
-            $friendlist .= "<a href=\"$journallink\">$fu->{user}</a>, ";
-        }
-    } else {
-        # haha they have no friends
-        my $addfriendpic = "<img src=\"$LJ::SITEROOT/img/btn_addfriend.gif\" />";
-        $friendlist .= "To add journals or communities to your Friends list, click the " .
-            "$addfriendpic icon on their userinfo page.";
-    }
-
-    $content .= qq {
-        <div class="FriendsCurrentTitle">
-          Friends ($friendcount):
-          <span class="FriendsEditButton">
-            (<a href="$LJ::SITEROOT/manage/circle/edit.bml">Edit Friends</a>)
-          </span>
-        </div>
-    };
-
-    if ($foundfriends) {
-        chop $friendlist;
-        chop $friendlist;
-    }
-
-    if ($foundfriends < $friendcount) {
-        $displaying = " Displaying $foundfriends";
-    }
-
-    $content .= qq {
-        <div class="FriendsList">
-            $usericonguy($friendcount)$displaying: <br />
-            $friendlist
-        </div>
-    };
-
-    # display communities
-    my $commcount=0, my $commlist;
-
-    if ($showcomm) {
-        if ($friends_u) {
-            grep { $commcount++ if $friends_u->{$_}->is_community; } keys %$friends_u;
-            my @sortedfriends = sort { $friends_u->{$a}->{'user'} cmp $friends_u->{$b}->{'user'} } keys %$friends_u;
-
-            foreach my $fid (@sortedfriends) {
-                my $fu = $friends_u->{$fid};
-
-                next unless $fu->is_community;
-
-                my $journallink = $fu->journal_base();
-                $commlist .= "<a href=\"$journallink\">$fu->{user}</a>, ";
-            }
-        }
-
-        if (!$commcount) {
-            $commlist .= "You have no communities listed as friends.";
-        }
-
-        if ($commcount) {
-            chop $commlist;
-            chop $commlist;
-        }
-        $content .= qq {
-            <div class="FriendsList">
-                <img src="$LJ::SITEROOT/img/silk/identity/community.png" /> ($commcount): <br />
-                $commlist
-            </div>
-        };
-    }
-
-    # display syndicated buddies
-    my $syncount=0, my $synlist;
-
-    if ($showsyn) {
-        if ($friends_u) {
-            grep { $syncount++ if $friends_u->{$_}->is_syndicated; } keys %$friends_u;
-            my @sortedfriends = sort { $friends_u->{$a}->{'user'} cmp $friends_u->{$b}->{'user'} } keys %$friends_u;
-
-            foreach my $fid (@sortedfriends) {
-                my $fu = $friends_u->{$fid};
-
-                next unless $fu->is_syndicated;
-
-                my $journallink = $fu->journal_base();
-                $synlist .= "<a href=\"$journallink\">$fu->{user}</a>, ";
-            }
-        }
-
-        if (!$syncount) {
-            $synlist .= "You have no syndicated feeds.";
-        }
-
-        if ($syncount) {
-            chop $synlist;
-            chop $synlist;
-        }
-        $content .= qq {
-            <div class="FriendsList">
-                <img src="$LJ::SITEROOT/img/silk/identity/feed.png" /> ($syncount): <br />
-                $synlist
-            </div>
-        };
-    }
-
-    return $content;
-}
-
-
-#######################################
-
-
-sub box_description { $_box_description; }
-sub box_name { $_box_name; }
-sub box_class { $_box_class; }
-sub config_props { $_config_props; }
-sub prop_keys { $_prop_keys; }
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box/FriendsPage.pm
--- a/cgi-bin/LJ/Portal/Box/FriendsPage.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-package LJ::Portal::Box::FriendsPage; # <--- Change this
-use base 'LJ::Portal::Box';
-use strict;
-
-######################## override this stuff ######################
-
-our $_box_description = 'Read Your Friends Page';
-our $_box_name = "View Friends Page";
-our $_box_class = "FriendsPage";
-our $_prop_keys = {
-    'showgroups' => 2,
-    'itemshow'   => 1,
-    'imageplaceholders' => 3,
-};
-
-our $_config_props = {
-    'showgroups' => {
-        'type'      => 'checkbox',
-        'desc'      => 'Show friend groups?',
-        'default'   => '0',
-    },
-    'itemshow' => {
-        'type'      => 'integer',
-        'desc'      => 'Display how many recent entries?',
-        'default'   => '3',
-        'min'       => '1',
-        'max'       => '25',
-    },
-    'imageplaceholders' => {
-        'type'      => 'checkbox',
-        'desc'      => 'Use placeholders for images?',
-        'default'   => '0',
-    },
-};
-
-sub generate_content {
-    my $self = shift;
-    my $pboxid = $self->{'pboxid'};
-    my $u = $self->{'u'};
-
-    my $content;
-
-    my $showgroups = $self->get_prop('showgroups');
-    my $itemshow = $self->get_prop('itemshow');
-    my $useplaceholders = $self->get_prop('imageplaceholders');
-
-    my $frpagefaqbtn = LJ::Portal->get_faq_link('friendspage');
-
-    # get latest friends page entries
-    # filter by "default view" if it exists
-    my $grp = LJ::get_friend_group($u, { 'name'=> 'Default View' });
-    my $bit = $grp ? $grp->{'groupnum'} : 0;
-    my $filter = $bit ? (1 << $bit) : undef;
-
-    my @entries = LJ::get_friend_items( {
-        'remoteid'         => $u->{'userid'},
-        'itemshow'         => $itemshow,
-        'skip'             => 0,
-        'showtypes'        => 'PYC',
-        'u'                => $u,
-        'userid'           => $u->{'userid'},
-        'filter'           => $filter,
-    } );
-
-    # correct pluralization (translationableness would be cool at some point)
-    my $entrytext = @entries == 1 ? 'entry' : 'entries';
-
-    # link to friends' page
-    my $friendspageurl = $u->journal_base . '/read/';
-
-    $content .= "<div class=\"FriendsPageTitle\"><img src='$LJ::SITEROOT/img/silk/identity/user.png' /> <a href=\"$friendspageurl\">Latest Friends page $entrytext: $frpagefaqbtn</a></div>";
-
-    my $entriescontent;
-
-    foreach my $entryinfo (@entries) {
-        next unless $entryinfo;
-
-        my $entry;
-
-        if ($entryinfo->{'ditemid'}) {
-            $entry = LJ::Entry->new($entryinfo->{'journalid'},
-                                    ditemid => $entryinfo->{'ditemid'});
-        } elsif ($entryinfo->{'itemid'} && $entryinfo->{'anum'}) {
-            $entry = LJ::Entry->new($entryinfo->{'journalid'},
-                                    jitemid => $entryinfo->{'itemid'},
-                                    anum    => $entryinfo->{'anum'});
-        }
-
-        next unless $entry;
-
-        my $subject    = $entry->subject_html;
-        my $entrylink  = $entry->url;
-
-        my $event      = $useplaceholders ?
-            $entry->event_html( { 'extractimages' => 1,
-                                  'cuturl' => $entrylink } ) :
-            $entry->event_html( { 'cuturl' => $entrylink  } );
-
-        my $posteru    = $entry->poster;
-
-        next if $posteru && $posteru->is_inactive;
-
-        my $poster     = $posteru->ljuser_display;
-        my $props      = $entry->props;
-        my $pickeyword = $props->{'picture_keyword'};
-        my $replycount = $props->{'replycount'};
-        my $picinfo;
-
-        my $journalid = $entryinfo->{journalid};
-        my $posterid = $entry->posterid;
-
-        # is this a post in a comm?
-        if ($journalid != $posterid) {
-            my $journalu = LJ::load_userid($journalid);
-            if ($journalu) {
-                $poster = $poster . " posting in ";
-                $poster .= $journalu->ljuser_display;
-            }
-        }
-
-        my $replyurl = LJ::Talk::talkargs($entrylink, "mode=reply");
-
-        # security icon
-        my $sec = "";
-        if ($entry->security eq "private") {
-            $sec = BML::fill_template("securityprivate");
-        } elsif ($entry->security eq "usemask") {
-            $sec = BML::fill_template("securityprotected");
-        }
-
-        # replies link/reply link
-        my $readlinktext = 'No replies';
-        if ($replycount == 1) {
-            $readlinktext = "1 Reply";
-        } elsif ($replycount > 1) {
-            $readlinktext = "$replycount replies";
-        }
-        my $replylink = "<a href=\"$replyurl\">Reply</a>";
-        my $readlink = "<a href=\"$entrylink\">$readlinktext</a>";
-
-        # load userpic
-        my $pichtml;
-        if ($pickeyword) {
-            $picinfo = LJ::get_pic_from_keyword($posteru, $pickeyword);
-        } else {
-            my $picid = $posteru->{'defaultpicid'};
-            my %pic;
-            LJ::load_userpics(\%pic, [ $posteru, $picid ]);
-            $picinfo = $pic{$picid};
-            $picinfo->{'picid'} = $picid;
-        }
-
-        if ($picinfo && $picinfo->{picid}) {
-            my $width = $picinfo->{'width'} ? "width=\"" . int($picinfo->{'width'} / 2) . '"' : '';
-            my $height = $picinfo->{'height'} ? "height=\"" . int($picinfo->{'height'} / 2) . '"' : '';
-
-            # FIXME: This functionality is untested, because I
-            # don't believe this module is currently functional.
-            # Replace the pichtml assignment with the one below
-            # once this code is operational and testable. 
-            # $pichtml .= $picinfo->imgtag;
-            $pichtml .= "<img src='$LJ::USERPIC_ROOT/$picinfo->{'picid'}/$posteru->{'userid'}' $width $height align='absmiddle' />";
-        }
-
-        $entriescontent .= qq {
-            <div class="PortalFriendsPageMeta">
-                <span class="PortalFriendsPageUserpic">$pichtml</span>
-                <span class="PortalFriendsPagePoster">$poster</span>
-                </div>
-                <div class="PortalFriendsPageSubject">
-                <span class="PortalFriendsPageSecurityIcon">$sec</span>
-                $subject
-                </div>
-                <div class="PortalFriendsPageEntry">
-                $event
-                </div>
-                <div class="PortalFriendsPageLinks">
-                $readlink | $replylink
-                </div>
-            };
-    }
-
-    if (! scalar @entries) {
-        $entriescontent .= "There have been no recent posts by your friends.";
-    }
-
-    $content .= qq {
-        <div class="FriendsPageEntry">
-            $entriescontent
-        </div>
-    };
-
-    if ($showgroups) {
-        my $groups = LJ::get_friend_group($u);
-        my $foundgroups = 0;
-
-        if ($groups) {
-            my $groupcount = scalar (keys %$groups);
-            my @sortedgroups = sort
-            {$groups->{$a}->{'sortorder'} <=>
-                 $groups->{$b}->{'sortorder'}}
-            keys %$groups;
-            $content .= "<div class=\"FriendsPageTitle\"><img src='$LJ::SITEROOT/img/friendgroup.gif' /> Friend Groups ($groupcount):</div>";
-            $content .= '<div class="FriendsPageEntry">';
-
-            foreach my $group (@sortedgroups) {
-                my $journalbase = LJ::journal_base($u);
-                my $groupname = $groups->{$group}->{'groupname'};
-                $content .= qq { <a href="$journalbase/read/$groupname">$groupname</a>, };
-                $foundgroups = 1;
-            }
-        }
-
-        if ($foundgroups) {
-            chop $content;
-            chop $content;
-        } else {
-            $content .= "You have no friend groups defined.";
-        }
-
-        $content .= "<br />(<a href=\"$LJ::SITEROOT/manage/circle/editfilters.bml\">Edit Friend Groups</a>)";
-
-        $content .= '</div>';
-    }
-
-    return $content;
-}
-
-
-sub can_refresh { 1; }
-
-#######################################
-
-
-sub box_description { $_box_description; }
-sub box_name { $_box_name; };
-sub box_class { $_box_class; }
-sub config_props { $_config_props; }
-sub prop_keys { $_prop_keys; }
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box/Manage.pm
--- a/cgi-bin/LJ/Portal/Box/Manage.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-package LJ::Portal::Box::Manage; # <--- Change this
-use base 'LJ::Portal::Box';
-use strict;
-
-######################## override this stuff ######################
-
-our $_box_class = "Manage";
-our $_box_description = "Useful links";
-our $_box_name = "Quick Links";
-
-# list of links to choose from
-our $_prop_keys = {
-    'EditFriends' => 1,
-    'EditProfile' => 2,
-    'EditPics' => 3,
-    'ManageCom' => 4,
-    'ManageMood' => 5,
-    'ChangePassword' => 6,
-    'LinkList' => 7,
-    'EmailGateway' => 8,
-    'VoicePost' => 9,
-    'InviteFriend' => 10,
-    'TextMessage' => 11,
-    'Memories' => 12,
-    'EditFriendGroups' => 14,
-    'FriendsFilter' => 15,
-    'CommSearch' => 16,
-    'CommInvite' => 17,
-    'EditStyles' => 18,
-    'BuyFriends' => 19,
-    'Syndication' => 20,
-    'Tags' => 21,
-    'SearchRegion' => 22,
-    'AdvancedSearch' => 23,
-    'InterestSearch' => 24,
-    'EditEntries' => 25,
-};
-
-# Prop => [URL, Text, Default] mapping
-our $linkinfo = {
-    'EditFriends'    => [ '/manage/circle/edit.bml', 'Edit Friends', 1 ],
-    'EditProfile'    => [ "/manage/profile/", 'Edit Profile', 1 ],
-    'EditPics'       => [ '/editpics.bml', 'Upload and Manage Your Userpics', 1 ],
-    'ManageCom'      => [ '/community/manage.bml', 'Manage Communities', 1 ],
-    'ManageMood'     => [ '/customize/', 'Set Your Mood Theme', 1 ],
-    'ChangePassword' => [ '/changepassword.bml', 'Change Account Password', 1 ],
-
-    'LinkList'       => [ '/customize/options.bml?group=linkslist', 'Create Link List', 0 ],
-    'EmailGateway'   => [ '/manage/emailpost.bml', 'Mobile Post Settings', 0 ],
-    'VoicePost'      => [ '/manage/voicepost.bml', 'Voice Post Settings', 0 ],
-    'InviteFriend'   => [ '/manage/circle/invite.bml', 'Invite a Friend', 0 ],
-    'TextMessage'    => [ '/tools/textmessage.bml', 'Text Message Tool', 0 ],
-    'Memories'       => [ '/tools/memories.bml', 'Memorable Posts', 0 ],
-    'EditFriendGroups' => [ '/manage/circle/editfilters.bml', 'Edit Your Friends Groups', 0 ],
-    'FriendsFilter'  => [ '/manage/circle/filter.bml', 'Friends Filter', 0 ],
-    'CommSearch'     => [ '/community/search.bml', 'Community Search', 0 ],
-    'CommInvite'  => [ '/manage/invites.bml', 'Community Invitations', 0 ],
-    'EditStyles'  => [ '/styles/edit.bml', 'Edit Styles', 0 ],
-    'BuyFriends'  => [ '/paidaccounts/friends.bml', 'Buy for Friends', 0 ],
-    'Syndication' => [ '/syn', 'Syndication', 0 ],
-    'Tags'        => [ '/manage/tags.bml', 'Manage Your Journal Tags', 0 ],
-    'SearchRegion'   => [ '/directory.bml', 'Search by Region', 0 ],
-    'AdvancedSearch' => [ '/directorysearch.bml', 'Advanced Search', 0 ],
-    'InterestSearch' => [ '/interests.bml', 'Search by Interests', 0 ],
-    'EditEntries'    => [ '/editjournal.bml', 'Edit Your Journal Entries', 0 ],
-};
-
-our $_config_props;
-
-foreach my $info (keys %$linkinfo) {
-    $_config_props->{$info} = { 'type'    => 'checkbox',
-                                'desc'    => $linkinfo->{$info}->[1],
-                                'default' => $linkinfo->{$info}->[2] || 0,
-                            };
-}
-
-sub generate_content {
-    my $self = shift;
-    my $content = '';
-    my $pboxid = $self->pboxid;
-    my $u = $self->{'u'};
-
-    my $props = $self->get_props;
-
-    $content .= qq {
-        <table style="width: 100%;">
-        };
-
-    # print links
-    my $col = 0;
-    foreach my $link (keys %$linkinfo) {
-        next unless $props->{$link};
-
-        my $linkurl = $linkinfo->{$link}->[0];
-        my $linktext = $linkinfo->{$link}->[1];
-
-        if ($col++ % 2 == 0) {
-            $content .= qq { <tr><td><a href="$LJ::SITEROOT$linkurl">$linktext</a></td> };
-        } else {
-            $content .= qq { <td><a href="$LJ::SITEROOT$linkurl">$linktext</a></td></tr> };
-        }
-    }
-
-    $content .= qq {
-        </table>
-    };
-
-    return $content;
-}
-
-
-#######################################
-
-
-sub box_description { $_box_description; }
-sub box_name { $_box_name; };
-sub box_class { $_box_class; }
-sub config_props { $_config_props; }
-sub prop_keys { $_prop_keys; }
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box/NewUser.pm
--- a/cgi-bin/LJ/Portal/Box/NewUser.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-package LJ::Portal::Box::NewUser; # <--- Change this
-use base 'LJ::Portal::Box';
-use strict;
-
-######################## override this stuff ######################
-
-our $_box_class = "NewUser";
-our $_box_description = "New Users - Start Here";
-our $_box_name = "New Users - Start Here";
-
-sub generate_content {
-    my $self = shift;
-    my $content = '';
-    my $pboxid = $self->pboxid;
-    my $u = $self->{'u'};
-
-    my $profile_url = $u->profile_url;
-    my $base = $u->journal_base;
-
-    $content .= qq {
-        <table style="width: 100%; border: 0px;">
-            <tr>
-                <td style="width: 50%;">
-                    1) <a href="$LJ::SITEROOT/update.bml">Write</a> a journal entry<br />
-                    2) <a href="$LJ::SITEROOT/editpics.bml">Upload</a> userpics<br />
-                    3) <a href="$LJ::SITEROOT/manage/profile/">Fill out</a> your <a href="$profile_url">profile</a><br />
-                </td>
-                <td style="width: 50%;">
-                     4) <a href="$LJ::SITEROOT/customize/">Customize</a> the look of your journal<br />
-                     5) <a href="$LJ::SITEROOT/interests.bml">Find</a> friends and communities by interests<br />
-                     6) <a href="$base/read">Read</a> your Friends page<br />
-                </td>
-            </tr>
-        </table>
-    <span class="NewUserMoreLink"><a href="$LJ::SITEROOT/manage/">more</a></span>
-    };
-
-    return $content;
-}
-
-# add by default if new user (account created after portal goes live date)
-sub default_added {
-    my ($self, $u) = @_;
-
-    return 1;
-}
-
-#######################################
-
-sub box_description { $_box_description; }
-sub box_name { $_box_name; };
-sub box_class { $_box_class; }
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box/Note.pm
--- a/cgi-bin/LJ/Portal/Box/Note.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-package LJ::Portal::Box::Note; # <--- Change this
-use base 'LJ::Portal::Box';
-use strict;
-
-######################## override this stuff ######################
-
-our $_box_description = 'Save a little note for yourself';
-our $_box_name = "Note To Self";
-our $_box_class = "Note";
-
-our $_prop_keys = { 'note' => 1 };
-our $_config_props = {
-    'note' => { 'type'    => 'hidden',
-                'desc'    => 'Note',
-                'default' => ''} };
-
-sub generate_content {
-    my $self = shift;
-    my $pboxid = $self->pboxid;
-    my $note = $self->get_prop('note');
-
-    my $saveRequest = qq{portalboxaction=$pboxid};
-
-    return qq {
-        <textarea style="width: 90%; height: 100px; margin-left: auto; margin-right: auto;
-display: block;" id="note$pboxid">$note</textarea>
-        <input type="button" value="Save" onclick="evalXrequest('$saveRequest&note='+encodeURIComponent(xGetElementById('note$pboxid').value));" /> <span style="display: none" id="statusbox$pboxid"></span>
-          };
-}
-
-sub handle_request {
-    my ($self, $GET, $POST) = @_;
-    my $pboxid = $self->pboxid;
-
-    my $enote = LJ::ehtml($POST->{'note'});
-
-    # since props have a maximum length of 255 bytes we must truncate before
-    # setting the prop because otherwise the full-length string will be stored
-    # in memcache and the truncated string stored in the DB
-    $enote = LJ::text_trim($enote, 255, 0);
-
-    $self->set_prop('note', $enote);
-
-    return qq {
-        var stat = xGetElementById('statusbox$pboxid');
-        if (stat) {
-            stat.style.display = "inline";
-            stat.innerHTML = "Note saved.";
-        }
-    };
-}
-
-
-#######################################
-
-
-sub box_description { $_box_description; }
-sub box_name { $_box_name; };
-sub box_class { $_box_class; }
-
-sub config_props { $_config_props; }
-sub prop_keys { $_prop_keys; }
-
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box/Notifications.pm
--- a/cgi-bin/LJ/Portal/Box/Notifications.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +0,0 @@
-package LJ::Portal::Box::Notifications; # <--- Change this
-use base 'LJ::Portal::Box';
-use strict;
-
-######################## override this stuff ######################
-
-our $_box_class = "Notifications";
-our $_box_name = "Message Center";
-our $_box_description = "See a preview of what's in your Message Center";
-our $_prop_keys = {
-    'maxnotices' => 2,
-    'daysold'    => 1,
-};
-our $_config_props = {
-    'maxnotices'  => {
-        'type'    => 'integer',
-        'desc'    => 'Maximum number of messages to display',
-        'default' => 15,
-        'min'     => 1,
-        'max'     => 60,
-    },
-    'daysold'  => {
-        'type'    => 'integer',
-        'desc'    => 'How many days to save messages',
-        'default' => 60,
-        'min'     => 1,
-        'max'     => 365,
-    },
-};
-
-sub handle_request {
-    my ($self, $GET, $POST) = @_;
-
-    # process any deletions
-    if ($GET->{'delete_note'} || $POST->{'delete_note'}) {
-        my $qid = int($GET->{'del_note_qid'} || $POST->{'del_note_qid'});
-        my $qitem = LJ::NotificationItem->new($self->{u}, $qid) or return undef;
-        $qitem->delete;
-    }
-
-    return undef;
-}
-
-sub queue {
-    my $self = shift;
-    return $self->{u}->notification_inbox;
-}
-
-sub generate_content {
-    my $self = shift;
-
-    my $pboxid = $self->pboxid;
-    my $u = $self->{u};
-
-    my $content = '';
-    my $maxnotices = $self->get_prop('maxnotices');
-    my $daysold    = $self->get_prop('daysold');
-
-    my $q = $self->queue;
-    return "Could not retreive inbox." unless $q;
-
-    $content .= qq {
-        <div class="ESN_Links"><a href="$LJ::SITEROOT/inbox/">Message Center</a> |
-            <a href="$LJ::SITEROOT/manage/subscriptions/">Manage Settings</a></div>
-
-        <table style="width: 100%;">
-            <tr class="PortalTableHeader"><td>Notification</td><td>Date</td><td>Delete</td></tr>
-        };
-
-    my $noticecount = 0;
-
-    foreach my $item ($q->items) {
-        my $evt = $item->event;
-        my $qid = $item->qid;
-
-        my $desc = $item->title;
-        my $delrequest = "portalboxaction=$pboxid&delete_note=1&del_note_qid=$qid";
-
-        my $delicon = "<img src=\"$LJ::IMGPREFIX/portal/btn_del.gif\" align=\"center\" />";
-
-        my $cutoff_date = time() - $daysold * 24 * 60 * 60;
-
-        next if $item->when_unixtime < $cutoff_date;
-
-        my $timeago = $item->when_unixtime ?
-            LJ::ago_text(time() - $item->when_unixtime) :
-            "(?)";
-
-        my $rowmod = $noticecount % 2 + 1;
-        $content .= qq {
-            <tr class="PortalRow$rowmod">
-                <td>$desc</td>
-                <td>$timeago</td>
-                <td align="center"><a href="/portal/index.bml?$delrequest" onclick="return evalXrequest('$delrequest', null);">$delicon</a></td>
-            </tr>
-            };
-
-        $noticecount++;
-        last if $noticecount >= $maxnotices;
-    }
-
-    $content .= qq {
-        <tr><td colspan="3">(No new notices)</td></tr>
-        } unless $noticecount;
-
-    $content .= '</table>';
-
-    return $content;
-}
-
-
-#######################################
-
-sub can_refresh { 1; }
-sub box_description { $_box_description; }
-sub box_name { $_box_name; };
-sub box_class { $_box_class; }
-sub config_props { $_config_props; }
-sub prop_keys { $_prop_keys; }
-
-# caching options
-sub cache_global { 0; } # cache per-user
-sub cache_time { 1 * 60; } # check etag every minute
-sub etag {
-    my $self = shift;
-
-    my $daysold = $self->get_prop('daysold');
-    my $maxnotices = $self->get_prop('maxnotices');
-
-    my $q = $self->queue or return undef;
-
-    my @items = $q->items;
-    my @qids = map { $_->qid } @items;
-
-    return "$daysold-" . join('-', @qids);
-}
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box/PopWithFriends.pm
--- a/cgi-bin/LJ/Portal/Box/PopWithFriends.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-package LJ::Portal::Box::PopWithFriends; # <--- Change this
-use base 'LJ::Portal::Box';
-use strict;
-
-######################## override this stuff ######################
-
-our $_box_class = "PopWithFriends";
-our $_box_description = 'See who\'s popular';
-our $_box_name = "Popular With Your Friends";
-our $_prop_keys = {
-    'showpeople' => 0,
-    'showcoms' => 1,
-    'showsyn' => 2,
-    'showown' => 3,
-    'limit' => 4,
-};
-
-our $_config_props = {
-    'limit' => {
-        'type'      => 'integer',
-        'desc'      => 'Maximum number of users to display',
-        'min'       => 1,
-        'max'       => 50,
-        'default'   => 10,
-    },
-    'showcoms'  => {
-        'type'    => 'checkbox',
-        'desc'    => 'Show communities',
-        'default' => 1,
-    },
-    'showpeople'=> {
-        'type'    => 'checkbox',
-        'desc'    => 'Show users',
-        'default' => 1,
-    },
-    'showsyn'   => {
-        'type'    => 'checkbox',
-        'desc'    => 'Show syndicated accounts',
-        'default' => 1,
-    },
-    'showown'   => {
-        'type'    => 'checkbox',
-        'desc'    => 'Show my own friends',
-        'default' => 0,
-    },
-};
-
-sub generate_content {
-    my $self = shift;
-    my $content = '';
-    my $u = $self->{'u'};
-    my $maxitems = $self->get_prop('limit');
-    my $showsyn = $self->get_prop('showsyn');
-    my $showpeople = $self->get_prop('showpeople');
-    my $showown = $self->get_prop('showown');
-    my $showcoms = $self->get_prop('showcoms');
-
-    my $LIMIT=300;
-
-    return 'Sorry, this feature is disabled.' unless LJ::is_enabled('friendspopwithfriends');
-
-    unless (LJ::get_cap($u, "friendspopwithfriends")) {
-        return BML::ml("portal.popwithfriends.accttype");
-    }
-
-    # load user's friends
-    my @ids = $u->circle_userids or return 'No friends found.';
-    my %fr = map { $_ => 1 } @ids;
-    splice(@ids, 0, $LIMIT) if @ids > $LIMIT;
-
-    my $fus = LJ::load_userids(@ids);
-
-    # show friends of users only
-    @ids = grep { $fus->{$_}{journaltype} eq "P" } @ids;
-
-    my %count;
-
-    my $MAX_DELAY = 4;
-
-    # count friends of friends
-    my $start = time();
-    while (@ids && time() < $start + $MAX_DELAY) {
-        my $fid = shift @ids;
-        my $fu = $fus->{$fid} or next;
-        $count{$_}++ foreach ($fu->circle_userids);
-    }
-
-    my @pop = (sort { $count{$b} <=> $count{$a} } keys %count);
-
-    my $rows;
-    my $shown;
-
-    my $fofus = LJ::load_userids(@pop);
-
-    my $displayed = 0;
-    foreach my $popid (@pop) {
-        # don't show self
-        next if ($popid eq $u->{'userid'});
-
-        # don't show own friends if option set
-        next if ($fr{$popid} && !$showown);
-
-        my $fofu = $fofus->{$popid};
-
-        next if $fofu->is_individual && !$showpeople;
-        next if $fofu->is_community  && !$showcoms;
-        next if $fofu->is_syndicated && !$showsyn;
-
-        my $friendcount = $count{$popid};
-        next if $friendcount == 0;
-
-        last if $displayed++ >= $maxitems;
-
-        $rows .= "<tr><td>" . LJ::ljuser($fofu) . " - " . LJ::ehtml($fofu->{name}) .
-            "</td><td align='right'>$friendcount</td>";
-        $rows .= "<td><a href=\"$LJ::SITEROOT/manage/circle/add.bml?user=$fofu->{user}\"><img src=\"$LJ::IMGPREFIX/btn_addfriend.gif\" alt=\"Add this user as a friend\" /></a></td>" if !$fr{$fofu->{userid}};
-        $rows .= "</tr>\n";
-    }
-
-    if ($rows) {
-        $content .= "<div class=\"PopWithFriendsHeader\">The following friends are " .
-            "listed often by your friends, but not by you.</div>";
-        $content .= "<table cellpadding='3' style='width:100%;'>\n";
-        $content .= "<tr><td><b>User</b></td><td><b>Count</b></td><td><b>Add</b></td></tr>\n";
-        $content .= $rows;
-        $content .= "</table>\n";
-
-    } else {
-        return 'You have no friends of friends.';
-    }
-
-    return $content;
-}
-
-
-#######################################
-
-
-sub box_description { $_box_description; }
-sub box_name { $_box_name; };
-sub box_class { $_box_class; }
-sub config_props { $_config_props; }
-sub prop_keys { $_prop_keys; }
-
-# caching options
-sub cache_global { 0; } # cache per-user
-sub cache_time { 60 * 60; } # cache for an hour
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box/RandomUser.pm
--- a/cgi-bin/LJ/Portal/Box/RandomUser.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-package LJ::Portal::Box::RandomUser; # <--- Change this
-use base 'LJ::Portal::Box';
-use strict;
-
-######################## override this stuff ######################
-
-our $_box_class = "RandomUser";
-our $_box_description = "See a random user's journal (May contain offensive content)";
-our $_box_name = "Random User";
-
-sub generate_content {
-    my $self = shift;
-    my $content = '';
-    my $pboxid = $self->pboxid;
-    my $u = $self->{'u'};
-
-    my $try = 5;
-    my $tries = 0;
-
-    my $done = 0;
-    while (!$done && $tries < $try) {
-        $tries++;
-
-        my $user = LJ::User->load_random_user();
-        next unless $user;
-
-        # get most recent post
-        my @items = $user->recent_items(
-            remote => $u,
-            clusterid => $user->{clusterid},
-            skip => 0,
-            itemshow => 1,
-        );
-
-        my $entryinfo = $items[0];
-        next unless $entryinfo;
-
-        my $entry;
-
-        if ($entryinfo->{'ditemid'}) {
-            $entry = LJ::Entry->new($user,
-                                    ditemid => $entryinfo->{'ditemid'});
-        } elsif ($entryinfo->{'itemid'} && $entryinfo->{'anum'}) {
-            $entry = LJ::Entry->new($user,
-                                    jitemid => $entryinfo->{'itemid'},
-                                    anum    => $entryinfo->{'anum'});
-        } else {
-            next;
-        }
-
-        next unless $entry;
-
-        my $subject    = $entry->subject_html;
-        my $entrylink  = $entry->url;
-        my $event      = $entry->event_html( { 'cuturl' => $entrylink  } );
-        my $posteru    = $entry->poster;
-        my $poster     = $posteru->ljuser_display;
-        my $journalid  = $entryinfo->{journalid};
-        my $posterid   = $entry->posterid;
-
-        $content .= qq {
-            $poster:<br/>
-                $event
-        };
-        $done = 1;
-    }
-
-    return $content;
-}
-
-
-#######################################
-
-
-sub box_description { $_box_description; }
-sub box_name { $_box_name; };
-sub box_class { $_box_class; }
-sub can_refresh { 1; }
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box/Reader.pm
--- a/cgi-bin/LJ/Portal/Box/Reader.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-package LJ::Portal::Box::Reader; # <--- Change this
-use base 'LJ::Portal::Box';
-use strict;
-
-######################## override this stuff ######################
-
-our $_box_description = 'Watch a journal, community or syndicated feed';
-our $_box_name = "Reader";
-our $_box_class = "Reader";
-our $_prop_keys = {
-    'username'   => 2,
-    'itemshow'   => 1,
-};
-
-our $_config_props = {
-    'username' => {
-        'type'      => 'string',
-        'desc'      => 'User, community, or syndicated feed name',
-        'default'   => '',
-        'size'      => 16,
-        'maxlength' => 16,
-    },
-    'itemshow' => {
-        'type'      => 'integer',
-        'desc'      => 'Display how many recent entries',
-        'default'   => '3',
-        'min'       => '1',
-        'max'       => '25',
-    },
-};
-
-sub generate_content {
-    my $self = shift;
-    my $pboxid = $self->{'pboxid'};
-    my $u = $self->{'u'};
-
-    my $content;
-
-    my $username = $self->get_prop('username');
-    my $itemshow = $self->get_prop('itemshow');
-
-    return 'You must define a user, community or syndicated feed to watch.' if (!$username || $username eq '');
-
-    my $wu = LJ::load_user($username);
-
-    return "The user, community or syndicated account <b>$username</b> does not exist." unless $wu;
-
-    # get latest entries
-    my $err;
-    my @entries = $wu->recent_items(
-        remote           => $u,
-        itemshow         => $itemshow,
-        skip             => 0,
-        showtypes        => 'PYC',
-        err              => \$err,
-        clusterid        => $wu->{clusterid},
-    );
-
-    return "Error fetching latest entries: $err" if $err;
-
-    # correct pluralization (translationableness would be cool at some point)
-    my $entrytext = @entries == 1 ? 'entry' : 'entries';
-
-    # link to journal
-    my $wuuser = LJ::ljuser($wu);
-
-    $content .= "<div class=\"ReaderPageTitle\">$wuuser</div>";
-
-    my $entriescontent;
-
-    foreach my $entryinfo (@entries) {
-        next unless $entryinfo;
-
-        my $entry = LJ::Entry->new($wu->{userid},
-                                   jitemid => $entryinfo->{'itemid'},
-                                   anum    => $entryinfo->{'anum'});
-
-        next unless $entry;
-
-        my $subject    = $entry->subject_html;
-        my $entrylink  = $entry->url;
-
-        my $event = $entry->event_html( { 'cuturl' => $entrylink  } );
-
-        my $posteru    = $entry->poster;
-        my $poster     = $posteru->ljuser_display;
-        my $props      = $entry->props;
-        my $pickeyword = $props->{'picture_keyword'};
-        my $replycount = $props->{'replycount'};
-        my $picinfo;
-
-        my $journalid = $wu->{userid};
-        my $posterid = $entry->posterid;
-
-        # is this a post in a comm?
-        if ($journalid != $posterid) {
-            $poster = $poster . " posting in ";
-            $poster .= $wu->ljuser_display;
-        }
-
-        my $replyurl = LJ::Talk::talkargs($entrylink, "mode=reply");
-
-        # security icon
-        my $sec = "";
-        if ($entry->security eq "private") {
-            $sec = BML::fill_template("securityprivate");
-        } elsif ($entry->security eq "usemask") {
-            $sec = BML::fill_template("securityprotected");
-        }
-
-        # replies link/reply link
-        my $readlinktext = 'No replies';
-        if ($replycount == 1) {
-            $readlinktext = "1 Reply";
-        } elsif ($replycount > 1) {
-            $readlinktext = "$replycount replies";
-        }
-        my $replylink = "<a href=\"$replyurl\">Reply</a>";
-        my $readlink = "<a href=\"$entrylink\">$readlinktext</a>";
-
-        # load userpic
-        my $pichtml;
-        if ($pickeyword) {
-            $picinfo = LJ::get_pic_from_keyword($posteru, $pickeyword);
-        } else {
-            my $picid = $posteru->{'defaultpicid'};
-            my %pic;
-            LJ::load_userpics(\%pic, [ $posteru, $picid ]);
-            $picinfo = $pic{$picid};
-            $picinfo->{'picid'} = $picid;
-        }
-
-        if ($picinfo) {
-            my $width = $picinfo->{'width'} ? "width=\"" . int($picinfo->{'width'} / 2) . '"' : '';
-            my $height = $picinfo->{'height'} ? "height=\"" . int($picinfo->{'height'} / 2) . '"' : '';
-
-            # FIXME: This functionality is untested, because I
-            # don't believe this module is currently functional.
-            # Replace the pichtml assignment with the one below
-            # once this code is operational and testable. 
-            # $pichtml .= $picinfo->imgtag;
-            $pichtml .= "<img src='$LJ::USERPIC_ROOT/$picinfo->{'picid'}/$posteru->{'userid'}' $width $height align='absmiddle' />";
-        }
-
-        $entriescontent .= qq {
-            <div class="PortalFriendsPageMeta">
-                <span class="PortalFriendsPageUserpic">$pichtml</span>
-                <span class="PortalFriendsPagePoster">$poster</span>
-                </div>
-                <div class="PortalFriendsPageSubject">
-                <span class="PortalFriendsPageSecurityIcon">$sec</span>
-                $subject
-                </div>
-                <div class="PortalFriendsPageEntry">
-                $event
-                </div>
-                <div class="PortalFriendsPageLinks">
-                $readlink | $replylink
-                </div>
-            };
-    }
-
-    if (! scalar @entries) {
-        $entriescontent .= "There have been no recent posts by $wuuser";
-    }
-
-    $content .= qq {
-        <div class="ReaderEntry">
-            $entriescontent
-        </div>
-    };
-
-    return $content;
-}
-
-
-sub can_refresh { 1; }
-
-#######################################
-
-
-sub box_description { $_box_description; }
-sub box_name { $_box_name; };
-sub box_class { $_box_class; }
-sub config_props { $_config_props; }
-sub prop_keys { $_prop_keys; }
-
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box/RecentComments.pm
--- a/cgi-bin/LJ/Portal/Box/RecentComments.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,237 +0,0 @@
-package LJ::Portal::Box::RecentComments; # <--- Change this
-use base 'LJ::Portal::Box';
-use strict;
-
-######################## override this stuff ######################
-
-our $_box_class = "RecentComments";
-our $_prop_keys = { 'maxshow' => 1 };
-our $_config_props = {
-    'maxshow' => { 'type'      => 'integer',
-                   'desc'      => 'Maximum number of recent comments to display',
-                   'max'       => 15,
-                   'min'       => 1,
-                   'maxlength' => 2,
-                   'default'   => 5,
-               },
-};
-our $_box_description = 'Show latest comments received';
-our $_box_name = "Recent Comments";
-
-our $cmtinfodata = {};
-
-sub generate_content {
-    my $self = shift;
-    my $content = '';
-    my $u = $self->{'u'};
-
-    my $pboxid = $self->pboxid;
-
-    my $count = 0;
-
-    my $maxshow = $self->get_prop('maxshow');
-
-    if (!LJ::get_cap($u, "tools_recent_comments_display")) {
-        return "Sorry, your account type cannot view recent comments.";
-    }
-
-    my (@recv, @talkids);
-    my %need_userid;
-    my @need_logids;
-
-    my $jargent = "journal=$u->{'user'}&amp;";
-
-    $self->retreive_received_comments(\@recv, $maxshow + 10, $maxshow);
-
-    foreach my $post (@recv) {
-        $need_userid{$post->{posterid}} = 1 if $post->{posterid};
-        push @talkids, $post->{jtalkid};
-        push @need_logids, [$post->{journalid}, $post->{nodeid}];
-        $count++;
-    }
-
-    $count = ($count > $maxshow) ? $maxshow : $count;
-
-    $content .= "<a href=\"$LJ::SITEROOT/tools/recent_comments.bml\">";
-
-    my $lastcom = $count == 1 ? 'comment' : "$count comments";
-
-    $content .= (@talkids ? "Last $lastcom posted in </a>" : "No comments have been posted in </a>") . LJ::ljuser($u) . ":<br />";
-
-    @recv = sort { $b->{datepostunix} <=> $a->{datepostunix} } @recv;
-
-    my $us = LJ::load_userids(keys %need_userid);
-
-    # setup the parameter to get_logtext2multi
-    my $need_logtext = {};
-    foreach my $need (@need_logids) {
-        my $ju = $us->{$need->[0]};
-        next unless $ju;
-        push @{$need_logtext->{$ju->{clusterid}} ||= []}, $need;
-    }
-
-    my $talk_text = LJ::get_talktext2($u, @talkids);
-    my $log_text = LJ::get_logtext2multi($need_logtext);
-    my $root = LJ::journal_base($u);
-
-    my $commentcount = 0;
-
-    my %LJ_cmtinfo;
-
-    $LJ_cmtinfo{'canAdmin'} = 1;
-    $LJ_cmtinfo{'remote'} = $u->{user};
-    $LJ_cmtinfo{'journal'} = $u->{user};
-    $LJ_cmtinfo{'disableInlineDelete'} = 1;
-
-    $content .= "<table style='width: 100%' cellpadding='5' cellspacing='0'>";
-    foreach my $r (@recv) {
-        last unless $commentcount++ < $maxshow;
-
-        my $pu = $us->{$r->{posterid}};
-        next if $pu && ( $pu->is_suspended || $pu->is_expunged) ;
-        my $jtalkid = $r->{'jtalkid'};
-
-        # get entry info for linking
-        my $lrow = $log_text->{"$u->{userid} $r->{nodeid}"} ||= LJ::get_log2_row($u, $r->{'nodeid'});
-
-        # get comment subject and body
-        my $trow = $talk_text->{$jtalkid} || [];
-        my ($subject, $body) = (@$trow[0,1]);
-
-        $subject ||= '';
-        $body = (!defined $body || $body eq '') ? '(No comment text)' : $body;
-
-        my $date = LJ::ago_text(time() - $r->{'datepostunix'});
-
-        my $talkid = ($r->{'jtalkid'} << 8) + $lrow->{'anum'};
-
-        my $managebtns;
-        my $ljcmt = $LJ_cmtinfo{$talkid} = {};
-        $ljcmt->{u} = $pu ? $pu->{user} : "";
-
-        # comment manage buttons
-        $managebtns .= "<a href='$LJ::SITEROOT/delcomment.bml?${jargent}id=$talkid'>" . LJ::img("btn_del", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . "</a>";
-        if ($r->{'state'} ne 'F') {
-            $managebtns .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=freeze&amp;${jargent}talkid=$talkid'>" . LJ::img("btn_freeze", "", { align => 'absmiddle', hspace => 2, vspace => }) . "</a>";
-        }
-
-        if ($r->{'state'} eq 'F') {
-            $managebtns .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=unfreeze&amp;${jargent}talkid=$talkid'>" . LJ::img("btn_unfreeze", "", { align => 'absmiddle', hspace => 2, vspace => }) . "</a>";
-        }
-
-        if ($r->{'state'} ne 'S') {
-            $managebtns .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=screen&amp;${jargent}talkid=$talkid'>" . LJ::img("btn_scr", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . "</a>";
-        }
-
-        if ($r->{'state'} eq 'S') {
-            $managebtns .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=unscreen&amp;${jargent}talkid=$talkid'>" . LJ::img("btn_unscr", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . "</a>";
-        }
-
-        # print out comment w/ links
-        my $posturl  = "$root/$lrow->{ditemid}.html";
-        my $replyurl = LJ::Talk::talkargs( $posturl, "replyto=$talkid" );
-        my $talkurl  = LJ::Talk::talkargs( $posturl, "thread=$talkid" ) . LJ::Talk::comment_anchor( $talkid );
-        my $userlink = LJ::isu($pu) ? LJ::ljuser($pu) : "<i>(Anonymous)</i>";
-        my $htmlid   = LJ::Talk::comment_htmlid( $talkid );
-
-        # clean comment subject/text
-        LJ::CleanHTML::clean_subject_all(\$subject);
-        LJ::CleanHTML::clean_comment(\$body);
-
-        $content .= qq {
-            <tr id="$htmlid">
-                <td>
-
-                  <span class="RecentCommentTitle">$userlink </span>
-                  <span class="RecentCommentDate"><a href="$talkurl">$date</a></span>
-                  <div class="RecentCommentSubject">$subject</div>
-                  <br style="clear: both;" />
-
-                  <div class="RecentCommentItem">
-                      <div class="RecentCommentBody">
-                        $body
-                      </div>
-                      <div class="RecentCommentLinks">
-                        $managebtns
-                        <a href="$replyurl">Reply</a> | <a href="$posturl">Entry Link</a>
-                      </div>
-                  </div>
-                </td>
-            </tr>
-        };
-    }
-
-    $content .= '</table>';
-
-    $cmtinfodata = LJ::js_dumper(\%LJ_cmtinfo);
-
-    $content .= qq {
-        <script>
-            LJ_cmtinfo = $cmtinfodata;
-            current_pboxid = $pboxid;
-        </script>
-    };
-
-
-    return $content;
-}
-
-sub retreive_received_comments {
-    my ($self, $recv, $maxshow, $orig_maxshow) = @_;
-
-    # how far back do we want to go?
-    my $max_recurse_comments = 60;
-
-    return if $maxshow > $max_recurse_comments;
-
-    my %found_comments;
-
-    # Retrieve received
-    my $u = $self->{'u'};
-    my @recent_talkitems = $u->get_recent_talkitems($maxshow);
-    push @$recv, @recent_talkitems;
-
-    my $beforecount = scalar @$recv;
-    # weed out non-comments, deleted comments and repeats
-    @$recv = grep { $_->{nodetype} eq 'L' && $_->{state} ne 'D' &&
-                        !exists($found_comments{"$_->{nodeid} $_->{jtalkid}"}) &&
-                            ($found_comments{"$_->{nodeid} $_->{jtalkid}"} = 1) } @$recv;
-
-    # if comments got weeded out, get some more until we've fufulled our quota
-    if (scalar @$recv < $beforecount && scalar @$recv < $orig_maxshow) {
-        # oh noes, we got too few. get some more.
-        $self->retreive_received_comments($recv, $maxshow + 15, $orig_maxshow);
-    }
-}
-
-# when box is reloaded, execute this javascript
-sub box_updated {
-    my $self = shift;
-    my $pboxid = $self->pboxid;
-
-    return qq {
-        LJ_cmtinfo = $cmtinfodata;
-        current_pboxid = $pboxid;
-        setupAjax();
-    };
-}
-
-# added by default if user has cap
-sub default_added {
-    my ($self, $u) = @_;
-    if (LJ::isu($u)) {
-        return LJ::get_cap($u, "tools_recent_comments_display");
-    }
-    return 0;
-}
-
-#######################################
-
-sub can_refresh { 1; }
-sub box_description { $_box_description; }
-sub box_name { $_box_name; };
-sub config_props { $_config_props; }
-sub prop_keys { $_prop_keys; }
-sub box_class { $_box_class; }
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box/Tags.pm
--- a/cgi-bin/LJ/Portal/Box/Tags.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-package LJ::Portal::Box::Tags;
-use base 'LJ::Portal::Box';
-use strict;
-
-######################## configuration data ######################
-
-our $_box_class = "Tags";
-our $_prop_keys = { 'Show' => 1 };
-our $_config_props = {
-    'Show' => { 'type'    => 'integer',
-                'desc'    => 'Number of tags to show, sorted by most used first',
-                'max'     => 9999,
-                'min'     => 1,
-                'maxlength' => 4,
-                'default' => 10 } };
-our $_box_description = 'Show your most frequently used tags.';
-our $_box_name = "Frequent Tags";
-
-sub generate_content {
-    my $self = shift;
-    my $u = $self->{'u'};
-
-    # get tags, sort by use, filter
-    my $tags = LJ::Tags::get_usertags($u);
-    unless ($tags && %$tags) {
-        return "You haven't used any tags yet!";
-    }
-
-    my $show = $self->get_prop('Show');
-    my @sorted = sort { $tags->{$b}->{uses} <=> $tags->{$a}->{uses} } keys %$tags;
-    @sorted = splice(@sorted, 0, $show) if $show;
-
-    my $content = "<table width='100%'>";
-    foreach my $id (@sorted) {
-        $content .= "<tr><td nowrap='nowrap'>";
-        $content .= "<a href='";
-        $content .= LJ::journal_base($u) . '/tag/' . LJ::eurl($tags->{$id}->{name});
-        $content .= "'>";
-        $content .= LJ::ehtml($tags->{$id}->{name});
-        $content .= "</a> - " . $tags->{$id}->{uses} . " uses";
-        $content .= "</td></tr>";
-    }
-    $content .= "</table>";
-
-    return $content;
-}
-
-
-#######################################
-
-
-sub box_description { $_box_description; }
-sub box_name { $_box_name; };
-sub config_props { $_config_props; }
-sub prop_keys { $_prop_keys; }
-sub box_class { $_box_class; }
-
-# caching options
-sub cache_global { 0; } # cache per-user
-sub cache_time { 30 * 60; } # check etag every 30 minutes
-sub etag { time(); } # refreshes every 30 minutes
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box/TextMessage.pm
--- a/cgi-bin/LJ/Portal/Box/TextMessage.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-package LJ::Portal::Box::TextMessage; # <--- Change this
-use base 'LJ::Portal::Box';
-use strict;
-
-######################## override this stuff ######################
-
-our $_box_class = "TextMessage";
-our $_box_description = "Send a text message to other $LJ::SITENAMESHORT users who have enabled this feature.";
-our $_box_name = "Text Message";
-
-sub handle_request {
-    my ($self, $get, $post) = @_;
-
-    my $pboxid = $self->pboxid;
-    my $user = $post->{'user'};
-
-    my $genjs = sub {
-        my ($html, $showmsg, $maxlen) = @_;
-        $html = LJ::ejs($html);
-        $showmsg ||= 0;
-        $maxlen ||= '0';
-        my $returncode = qq {
-            tmbox = xGetElementById("tmresult$pboxid");
-            if (tmbox) {
-                tmbox.innerHTML = "$html";
-                xDisplay(tmbox, "block");
-            }
-
-            if ($showmsg) {
-                tmmsg = xGetElementById("tmmsg$pboxid");
-                if (tmmsg) {
-                    xDisplay(tmmsg, "block");
-                    var messagefield = xGetElementById('textmessagebody$pboxid');
-                    if (messagefield) {
-                        messagefield.maxLength = $maxlen;
-                    }
-                }
-            } else {
-                tmmsg = xGetElementById("tmmsg$pboxid");
-                if (tmmsg)
-                    xDisplay(tmmsg, "none");
-            }
-        };
-        return $returncode;
-    };
-
-    my $u = LJ::load_user($user);
-    return $genjs->("No such user $user", 0) if !$u;
-
-    my $tminfo;
-    if ($u->{'txtmsg_status'} eq "on") {
-        $tminfo = LJ::TextMessage->tm_info($u);
-    }
-
-    unless ($tminfo) {
-        return $genjs->("<p>This user has not set up their text messaging information at $LJ::SITENAMESHORT, or they've turned it off.</p>", 0);
-    }
-
-    # are they authorized?
-
-    if ($tminfo->{'security'} ne "all") {
-        my $remote = $self->{'u'};
-
-        if ($tminfo->{'security'} eq "friends" && $u->{'userid'} != $remote->{'userid'}) {
-            unless ( $u->trusts_or_has_member( $remote ) ) {
-                return $genjs->("<p>User <B>$u->{'user'}</B> has selected \"friends only\" as the security level required to send text messages to them.</p>", 0);
-            }
-        }
-    }
-
-    # send the message?
-    my $message = $post->{'message'};
-    if ($message) {
-        my $inputfrom = $post->{'from'};
-        my $from = $tminfo->{'security'} eq "all" ? $inputfrom : $self->{'u'}->{'user'};
-
-        my $phone = new LJ::TextMessage { 'provider' => $tminfo->{'provider'},
-                                          'number' => $tminfo->{'number'},
-                                          'mailcommand' => $LJ::SENDMAIL,
-                                          'smtp' => $LJ::SMTP_SERVER,
-                                      };
-        my @errors;
-        $phone->send({ 'from' => $from,
-                       'message' => $message, },
-                     \@errors);
-
-        # strip numbers from error messages
-        s/(\d{3,})/'x'x length $1/eg foreach @errors;
-
-        return $genjs->(LJ::bad_input(@errors)) if @errors;
-
-        return $genjs->("<h2>Success</h2><p>Your text message was sent.</p>");
-    }
-
-    my $pinfo = LJ::TextMessage::provider_info($tminfo->{'provider'});
-
-    my $maxlen = $pinfo->{'totlimit'};
-    if ($pinfo->{'msglimit'} < $maxlen) {
-        $maxlen = $pinfo->{'msglimit'};
-    }
-    $maxlen -= length($self->{'u'}->{'user'});
-
-    # code to send message request
-    my $jssubmit = qq {
-        var userfield = xGetElementById('textmessageuser$pboxid');
-        var messagefield = xGetElementById('textmessagebody$pboxid');
-        if (userfield && messagefield) {
-            return evalXrequest('portalboxaction=$pboxid&user='+userfield.value+'&message='+messagefield.value);
-        }
-        return true;
-    };
-
-    return $genjs->( qq {
-        <p>(max <tt>$maxlen</tt> characters ... type until it stops you)<br />
-            <p><input type='submit' value="Send Message!" onclick="$jssubmit" /></p>
-        }, 1, $maxlen );
-}
-
-sub generate_content {
-    my $self = shift;
-    my $content = '';
-    my $pboxid = $self->pboxid;
-    my $u = $self->{'u'};
-    my $helplink = LJ::Portal->get_faq_link('textmessage');
-
-    my $jssubmit = qq {
-        var userfield = xGetElementById('textmessageuser$pboxid');
-        if (userfield) {
-            return evalXrequest('portalboxaction=$pboxid&user='+userfield.value);
-        }
-        return true;
-    };
-
-    my $form_auth = LJ::form_auth();
-
-    $content = qq {
-<form method='POST' action='$LJ::SITEROOT/tools/textmessage.bml' id='tmform$pboxid'>
-$form_auth
-Username: <input type='text' size='15' maxlength='15' name='user' id='textmessageuser$pboxid'/>
-<input type='submit' value="Proceed..." onclick="$jssubmit" />
-<div id="tmmsg$pboxid" style="display: none;">
-<b>Message:</b><br /><input type="text" id="textmessagebody$pboxid" maxlength=42 />
-</div>
-<div id="tmresult$pboxid" class="tmform"></div>
-<input type="hidden" name="from" value="$u->{'user'}" />
-</form>
-<div class="TextMessageDisclaimer">$helplink <B>Disclaimer:</B> The reliability of text messaging should not be trusted in dealing with emergencies.</div>
-    };
-
-    return $content;
-}
-
-
-#######################################
-
-
-sub box_description { $_box_description; }
-sub box_name { $_box_name; };
-sub box_class { $_box_class; }
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Box/UpdateJournal.pm
--- a/cgi-bin/LJ/Portal/Box/UpdateJournal.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-package LJ::Portal::Box::UpdateJournal; # <--- Change this
-use base 'LJ::Portal::Box';
-use strict;
-
-######################## override this stuff ######################
-
-our $_box_description = 'A handy box for updating your journal.';
-our $_box_name = "Quick Update";
-our $_box_class = "UpdateJournal";
-
-sub generate_content {
-    my $self = shift;
-
-    my $content = '';
-    my $pboxid = $self->pboxid;
-    my $u = $self->{'u'};
-
-    my $subjectwidget = LJ::entry_form_subject_widget('UpdateBoxSubject');
-    my $entrywidget = LJ::entry_form_entry_widget('UpdateBoxEvent');
-    my $postto = LJ::entry_form_postto_widget($u, 'UpdateBoxPostTo');
-    my $securitywidget = LJ::entry_form_security_widget($u, 'UpdateBoxSecurity');
-    my $tagswidget = LJ::entry_form_tags_widget();
-
-    $postto = $postto ? $postto . '<br/><br/>' : '';
-
-    my $formauth = LJ::form_auth();
-
-    $content .= "<form action='$LJ::SITEROOT/update.bml' method='POST' name='updateform'>";
-
-    # translation stuff:
-    my $subjecttitle =  BML::ml('portal.update.subject');
-    my $eventtitle = BML::ml('portal.update.entry');
-    my $updatetitle = BML::ml('/update.bml.btn.update');
-    my $moreoptstitle = BML::ml('portal.update.moreopts');
-
-    my $posttotitle = BML::ml('entryform.postto');
-    my $securitytitle = BML::ml('entryform.security');
-    my $tagstitle = BML::ml('entryform.tags');
-
-    my $posttowidget = '';
-
-    if ($postto) {
-        $posttowidget = qq {
-                <tr>
-                <td valign="bottom" align="left" width="20%">
-                $posttotitle</td><td>$postto</td>
-                </tr>
-            };
-    }
-
-    $content .= qq {
-            $formauth
-                <input type="hidden" name="realform" value="1" />
-
-                <b>$subjecttitle</b><br/>
-                $subjectwidget<br/>
-
-                <b>$eventtitle</b><br/>
-                $entrywidget<br/>
-
-                <table width="100%">
-
-                $posttowidget
-
-                <tr>
-                <td valign="bottom" align="left" width="20%">
-                $securitytitle</td><td>$securitywidget</td>
-                </tr>
-
-                <tr>
-                <td valign="bottom" align="left" width="20%">
-                $tagstitle</td><td>$tagswidget</td>
-                </tr>
-
-                </table>
-
-                <br/>
-                <input type="submit" value="$updatetitle" name="postentry" onclick="return portal_settime();" /> <input type="submit" name="moreoptsbtn" value="$moreoptstitle"/>
-                </form>
-            };
-
-    return $content;
-}
-
-
-#######################################
-
-
-sub box_description { $_box_description; }
-sub box_name { $_box_name; };
-sub box_class { $_box_class; }
-#sub config_props { $_config_props; }
-#sub prop_keys { $_prop_keys; }
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/Portal/Config.pm
--- a/cgi-bin/LJ/Portal/Config.pm	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,781 +0,0 @@
-#!/usr/bin/perl
-
-# A portal Config object is a class designed for wrangling Box objects.
-# It loads a user's box configuration and is responsible for arranging
-# and maintaining a list of the current portal box configuration in memory.
-
-package LJ::Portal::Config;
-
-use lib "$LJ::HOME/cgi-bin";
-use LJ::Portal::Box;
-
-# u: user object that is who this config is for
-# boxes: arrayref of loaded Box objects for the user
-# boxlist: arrayref of pboxid => type boxes for this user (memcached)
-use fields qw(u boxes boxconfig boxlist profile);
-
-use strict;
-
-sub get_box_classes {
-    # if someone is calling this function they want to do something
-    # with all the modules available. To make sure nothing bad happens,
-    # we need to "require" all the modules specified in ljconfig. If
-    # the module is already loaded, splendid. If not, require will make
-    # sure that it's loaded so errors don't get thrown.
-
-    # require everything
-    LJ::Portal->load_portal_boxes(); # requires all modules in config
-
-    # return boxes, which should now all be loaded
-    return @LJ::PORTAL_BOXES;
-}
-
-# args: $u, $profile
-# profile: time the loading of boxes (value = how many times to benchmark)
-sub new {
-    my LJ::Portal::Config $self = shift;
-    $self = fields::new($self) unless ref $self;
-
-    my $u = shift;
-
-    $self->{'u'} = {};
-    $self->{'boxes'} = {};
-    $self->{'boxlist'} = {};
-
-    my $profile = shift;
-    $profile ||= 0;
-    $self->{'profile'} = $profile;
-
-    # if called with $u then load config for user
-    $self->load_config($u) if $u;
-
-    return $self;
-}
-
-# arguments: takes a user to load configuration for
-# opts hashref (options: 'force' = force load from DB and don't
-#  even try memcache)
-sub load_config {
-    my LJ::Portal::Config $self = shift;
-    my $u = shift;
-    my $opts = shift || {};
-
-    $self->{'u'} = $u if $u;
-    return unless $self->{'u'};
-
-    # get all portal boxes for this user:
-    $self->{'boxlist'} = LJ::MemCache::get($self->memcache_key) unless $opts->{'force'};
-
-    if (!$self->{'boxlist'}) {
-        $self->{'boxlist'} = {};
-        my $sth = $u->prepare("SELECT pboxid,type FROM portal_config WHERE userid=?");
-        $sth->execute($self->{'u'}->{'userid'});
-        while (my $row = $sth->fetchrow_hashref) {
-            my $pboxid = $row->{'pboxid'};
-            my $typeid = $row->{'type'};
-            next unless ($pboxid && $typeid);
-
-            $self->{'boxlist'}->{$pboxid} = $typeid;
-        }
-
-        # no boxes for user
-        if (!%{$self->{'boxlist'}}) {
-            # do we need to load the default state?
-            if (!$u->prop('portalinit')) {
-                # load default state
-                $self->load_default_boxes;
-                $u->set_prop('portalinit', localtime());
-            }
-        }
-
-        $self->update_memcache_state;
-    }
-
-    # load the boxes themselves
-    foreach my $pboxid (keys %{$self->{'boxlist'}}) {
-        my $typeid = $self->{'boxlist'}->{$pboxid};
-        next unless ($pboxid && $typeid);
-
-        my $box = $self->new_box_by_type($typeid);
-        next unless $box;
-
-        $box->load_config($pboxid, $self->{'u'});
-        $self->{'boxes'}->{$pboxid} = $box;
-    }
-
-    return 1;
-}
-
-# get the default column for a box class
-# default is 'R' unless defined
-sub get_box_default_col {
-    my LJ::Portal::Config $self = shift;
-    my $boxclass = shift;
-
-    return $LJ::PORTAL_DEFAULTBOXSTATES{$boxclass}->{'col'} || 'R';
-}
-
-# get whether or not you can have more than one of a box
-sub get_box_unique {
-    my LJ::Portal::Config $self = shift;
-    my $boxclass = shift;
-
-    return $LJ::PORTAL_DEFAULTBOXSTATES{$boxclass}->{'notunique'} ? 0 : 1;
-}
-
-# add all the default boxes
-sub load_default_boxes {
-    my LJ::Portal::Config $self = shift;
-
-    my @classes = $self->get_box_classes;
-
-    foreach my $boxclass (sort @classes) {
-        # check to see if the box has it's own code that needs to be run to determine
-        # if it should be added by default
-        my $fullboxclass = "LJ::Portal::Box::$boxclass";
-        my $toadd;
-        if ($fullboxclass->can('default_added')) {
-            $toadd = $fullboxclass->default_added($self->{'u'});
-        } else {
-            $toadd = $LJ::PORTAL_DEFAULTBOXSTATES{$boxclass} && $LJ::PORTAL_DEFAULTBOXSTATES{$boxclass}->{'added'};
-        }
-
-        if ($toadd) {
-            my $col = $self->get_box_default_col($boxclass);
-            my $order = $LJ::PORTAL_DEFAULTBOXSTATES{$boxclass}->{'sort'};
-
-            my $box = $self->add_box($boxclass, $col);
-            # does it have a default position in the column? (it should, but...)
-            if ($order && $box) {
-                $box->move(undef, $order);
-            }
-        }
-    }
-}
-
-# reset all of a user's settings
-sub reset_all {
-    my LJ::Portal::Config $self = shift;
-
-    foreach my $pboxid (keys %{$self->{'boxlist'}}) {
-        $self->remove_box($pboxid);
-    }
-
-    $self->load_default_boxes;
-    $self->update_memcache_state;
-}
-
-# retreive all loaded boxes
-sub get_boxes {
-    my LJ::Portal::Config $self = shift;
-    return $self->{'boxes'};
-}
-
-sub get_box_by_id {
-    my LJ::Portal::Config $self = shift;
-    my $id = shift;
-
-    return $self->{'boxes'}->{$id};
-}
-
-# return the key for portal config memcache
-sub memcache_key {
-    my LJ::Portal::Config $self = shift;
-    if ($self->{'u'}) {
-        my $key = [ $self->{'u'}->{'userid'}, "prtcfg:$self->{'u'}->{'userid'}" ];
-        return $key;
-    }
-    return undef;
-}
-sub update_memcache_state {
-    my LJ::Portal::Config $self = shift;
-    LJ::MemCache::set($self->memcache_key, $self->{'boxlist'})
-        if $self->memcache_key && $self->{'boxlist'};
-}
-
-# return a new box object of type type
-sub new_box_by_type {
-    my LJ::Portal::Config $self = shift;
-    my $type = shift;
-
-    my $typeid = int($type) ? $type : $self->type_string_to_id($type);
-
-    return undef unless (my $typename = $self->type_id_to_string($typeid));
-
-    my $class = "LJ::Portal::Box::$typename";
-
-    # if a box of this type already exists and this box type can only have one
-    # at a time, don't do it
-    if ($self->get_box_unique($typename)) {
-        return undef if $self->find_box_by_class($typename);
-    }
-
-    my $box = $class->new;
-    return $box;
-}
-
-# add a box
-sub add_box {
-    my LJ::Portal::Config $self = shift;
-    my ($type, $column) = @_;
-    return unless ($type && $column && $self->{'u'});
-
-    # if this is a unique box, make sure we aren't duplicating it
-    if ($self->get_box_unique($type)) {
-        return if $self->find_box_by_class($type);
-    }
-
-    my $box = $self->new_box_by_type($type);
-    return unless $box;
-    my $sortorder = $self->max_sortorder($column)+1;
-
-    if ($box->create($self->{'u'}, $column, $sortorder)) {
-        # save box in self
-        $self->{'boxes'}->{$box->pboxid} = $box;
-
-        # save in memcache
-        my $typeid = int($type) ? $type : $self->type_string_to_id($type);
-        $self->{'boxlist'}->{$box->pboxid} = $typeid;
-        $self->update_memcache_state;
-    }
-
-    return $box;
-}
-
-# insert a box at the sortorder and shift all the boxes below down
-sub insert_box {
-    my LJ::Portal::Config $self = shift;
-    my ($box, $col, $sortorder) = @_;
-
-    return unless ($box && $col && $sortorder);
-
-    my $insertbefore = $self->find_box($col, $sortorder);
-    if ($insertbefore) {
-        # increase the sortorder of all the boxes underneath by 1
-        my @colboxes = $self->get_col_boxes($col);
-        foreach my $cbox (@colboxes) {
-            if ($cbox->sortorder >= $sortorder && $cbox->pboxid != $box->pboxid) {
-                my $neworder = $cbox->sortorder+1;
-                $cbox->move($col, $neworder);
-            }
-        }
-
-        $self->update_memcache_state;
-    }
-    return $self->move_box($box, $col, $sortorder);
-}
-
-# returns a box that the current box replaced
-sub move_box {
-    my LJ::Portal::Config $self = shift;
-    my ($box, $col, $sortorder) = @_;
-    return unless ($box && ($col || defined $sortorder));
-
-    # if no col defined use the col the box is currently in
-    $col ||= $box->col;
-
-    # put box at end of list if moving cols
-    $sortorder = $self->max_sortorder($col)+1 if !defined $sortorder;
-
-    my $samebox = $self->find_box($col, $sortorder);
-
-    if ($samebox) {
-        $samebox->move($col, $box->sortorder);
-    }
-
-    $box->move($col, $sortorder);
-    return $samebox;
-}
-
-sub move_box_up {
-    my LJ::Portal::Config $self = shift;
-    my $box = shift;
-
-    my $sort = $box->sortorder;
-    my $prevbox = $self->prev_box($box);
-    return undef unless $prevbox;
-
-    $self->move_box($box, $box->col, $prevbox->sortorder);
-
-    return $prevbox;
-}
-
-sub move_box_down {
-    my LJ::Portal::Config $self = shift;
-    my $box = shift;
-
-    my $sort = $box->sortorder;
-    my $nextbox = $self->next_box($box);
-    return undef unless $nextbox;
-
-    $self->move_box($box, $box->col, $nextbox->sortorder);
-
-    return $nextbox;
-}
-
-
-sub next_box {
-    my LJ::Portal::Config $self = shift;
-    my $box = shift;
-
-    my $sortorder = $box->sortorder;
-
-    return undef if ($sortorder >= $self->max_sortorder($box->col));
-
-    my $boxes = $self->get_boxes;
-
-    # get the boxes in this column sorted by sortorder then
-    # iterate through the boxes until we find the first one that
-    # has a greater sortorder
-    my @colboxes = $self->get_col_boxes($box->col); # returns sorted by sortorder
-    foreach my $pbox (@colboxes) {
-        next unless $pbox;
-        return $pbox if ($pbox->sortorder > $sortorder);
-    }
-
-    return undef;
-}
-
-sub prev_box {
-    my LJ::Portal::Config $self = shift;
-    my $box = shift;
-
-    my $sortorder = $box->sortorder;
-
-    return undef if ($sortorder <= $self->min_sortorder($box->col));
-
-    my $boxes = $self->get_boxes;
-
-    # see next_box
-    my @colboxes = reverse $self->get_col_boxes($box->col); # returns sorted by sortorder
-    foreach my $pbox (@colboxes) {
-        next unless $pbox;
-        return $pbox if ($pbox->sortorder < $sortorder);
-    }
-
-    return undef;
-}
-
-# returns what position in a column a box is in (not the same as sortorder)
-sub col_order {
-    my LJ::Portal::Config $self = shift;
-    my $box = shift;
-
-    my $boxes = $self->get_boxes;
-
-    my @colboxes = $self->get_col_boxes($box->col); # returns sorted by sortorder
-    my $colorder = 1;
-    foreach my $cbox (@colboxes) {
-        last if ($cbox->pboxid == $box->pboxid);
-        $colorder++;
-    }
-    return $colorder;
-}
-
-sub find_box_by_col_order {
-    my LJ::Portal::Config $self = shift;
-    my ($col, $order) = @_;
-    my $boxes = $self->get_boxes;
-
-    my @colboxes = $self->get_col_boxes($col); # returns sorted by sortorder
-    foreach my $box (@colboxes) {
-        return $box if ($self->col_order($box) == $order);
-    }
-
-    return undef;
-}
-
-sub get_col_boxes {
-    my LJ::Portal::Config $self = shift;
-    my $col = shift;
-
-    my $boxes = $self->get_boxes;
-
-    # courtesy b-wizzle
-    return grep { $_->col eq $col }
-           map  { $boxes->{$_} }
-           sort { $boxes->{$a}->sortorder <=> $boxes->{$b}->sortorder ||
-                  $boxes->{$a}->pboxid    <=> $boxes->{$b}->pboxid }
-           keys %$boxes;
-}
-
-# return all of the columns that have boxes
-# ex. return value: ('R', 'L')
-sub get_cols {
-    my LJ::Portal::Config $self = shift;
-
-    my $boxes = $self->get_boxes;
-    my %cols;
-
-    foreach my $boxkey (keys %$boxes) {
-        my $col = $boxes->{$boxkey}->col;
-        if (!$cols{$col}) {
-            $cols{$col} = 1;
-        }
-    }
-
-    return keys %cols;
-}
-
-# find a box based on col, sortorder
-sub find_box {
-    my LJ::Portal::Config $self = shift;
-    my ($col, $sortorder) = @_;
-
-    return undef unless $col && defined $sortorder;
-
-    my $boxes = $self->get_boxes;
-
-    my @colboxes = $self->get_col_boxes($col);
-    foreach my $box (@colboxes) {
-        next unless ($box);
-        return $box if ($box->sortorder == $sortorder);
-    }
-    return undef;
-}
-
-# remove a box (id or object)
-sub remove_box {
-    my LJ::Portal::Config $self = shift;
-    my $delbox = shift;
-
-    # if delbox is an id then get the box, otherwise it should be
-    # a box object
-    my $box = int($delbox) ? $self->{'boxes'}->{$delbox} : $delbox;
-    return unless $box;
-
-    my $pboxid = $box->pboxid;
-    my $userid = $self->{'u'}->{'userid'};
-    return unless $pboxid && $userid;
-
-    delete $self->{'boxes'}->{$box->{'pboxid'}};
-
-    # update memcache state:
-    delete $self->{'boxlist'}->{$box->{'pboxid'}};
-    $self->update_memcache_state;
-
-    # tell box to clean itself up and self-destruct
-    $box->delete;
-}
-
-sub type_string_to_id {
-    my LJ::Portal::Config $self = shift;
-    my $typestring = shift;
-
-    if (!$LJ::PORTAL_TYPEMAP{$typestring}) {
-        LJ::Portal->load_box_typeid($typestring);
-    }
-
-    my $typeid = $LJ::PORTAL_TYPEMAP{$typestring} || undef;
-    die "Invalid box type $typestring\n" unless $typeid;
-    return $typeid;
-}
-
-sub type_id_to_string {
-    my LJ::Portal::Config $self = shift;
-    my $typeid = shift;
-
-    foreach my $typestring ($self->get_box_classes) {
-        if (!$LJ::PORTAL_TYPEMAP{$typestring}) {
-            LJ::Portal->load_box_typeid($typestring);
-        }
-
-        if ($LJ::PORTAL_TYPEMAP{$typestring} == $typeid) {
-            return $typestring;
-        }
-    }
-
-    # box could not be mapped, die silently
-    return undef;
-}
-
-# look to see if there are any boxes of this class instantiated and return
-# the first match if there is one
-sub find_box_by_class {
-    my LJ::Portal::Config $self = shift;
-    my $class = shift;
-
-    my $boxes = $self->get_boxes;
-
-    foreach my $box (keys %$boxes) {
-        return $box if ($boxes->{$box}->box_class eq $class);
-    }
-
-    return undef;
-}
-
-sub min_sortorder {
-    my LJ::Portal::Config $self = shift;
-    my $col = shift;
-
-    my $boxes = $self->get_boxes;
-
-    my @colboxes = $self->get_col_boxes($col);
-
-    my $minsort = $self->max_sortorder($col);
-    foreach my $box (@colboxes) {
-        next unless $box;
-        $minsort = $box->sortorder if ($box->sortorder < $minsort);
-    }
-
-    return $minsort;
-}
-
-sub max_sortorder {
-    my LJ::Portal::Config $self = shift;
-    my $col = shift;
-
-    my $boxes = $self->get_boxes;
-
-    my @colboxes = $self->get_col_boxes($col);
-    my $maxsort = 0;
-    foreach my $box (@colboxes) {
-        next unless $box;
-        $maxsort = $box->sortorder if ($box->sortorder > $maxsort);
-    }
-
-    return $maxsort;
-}
-
-sub last_box {
-    my LJ::Portal::Config $self = shift;
-    my $col = shift;
-
-    my $lastsort = $self->max_sortorder($col);
-    return $self->find_box($col, $lastsort);
-}
-
-sub generate_box_with_container {
-    my LJ::Portal::Config $self = shift;
-    my $boxid = shift;
-
-    my $box = $self->{'boxes'}->{$boxid};
-    return unless $box;
-
-    my $pboxid = $box->pboxid;
-    my $boxinsides = $self->generate_box_insides($pboxid);
-
-    return qq{
-            <div class="PortalBox" id="pbox$pboxid" pboxid="$pboxid">
-              $boxinsides
-            </div>
-        };
-}
-
-sub generate_box_titlebar {
-    my LJ::Portal::Config $self = shift;
-    my $box = shift;
-
-    my $boxhtml = "";
-    my $pboxid = $box->{'pboxid'};
-    my $post_url = "$LJ::SITEROOT/portal/index.bml";
-    my $boxtitle = $box->box_name;
-    my $col = $box->col;
-    my $colorder = $self->col_order($box);
-
-    my $sort = $box->sortorder;
-    my $maxsort = $self->max_sortorder($col);
-    my $minsort = $self->min_sortorder($col);
-
-    my $editable;
-
-    if ($box->can('config_props')) {
-        my $props = $box->config_props;
-        $editable = grep { $props->{$_}->{type} ne 'hidden' } keys %$props;
-    }
-
-    # is there an icon for this box?
-    my $moduleicon = $box->box_icon;
-
-    my $closebutton = qq {
-        <a onclick="return deletePortalBox($pboxid);" href="$post_url?delbox=1&pboxid=$pboxid">
-            <img src="$LJ::IMGPREFIX/portal/PortalBoxClose.gif" title="Remove this module" />
-            </a>
-        };
-
-    my $refreshbutton = '';
-
-    if ($box->can('can_refresh') && $box->can_refresh) {
-        $refreshbutton = qq {
-            <a onclick="return reloadPortalBox($pboxid);" href="">
-                <img src="$LJ::IMGPREFIX/portal/PortalBoxRefresh.gif" title="Reload the contents of this module" id='refresh$pboxid' />
-            </a>
-        };
-    }
-
-    my $configlink;
-
-    if ($editable) {
-        $configlink = qq {
-            <a onclick="return showConfigPortalBox($pboxid);" href="$post_url?configbox=1&pboxid=$pboxid">
-                <img src="$LJ::IMGPREFIX/portal/PortalBoxConfig.gif" title="Edit this module"
-                id = 'edit$pboxid' />
-            </a>
-        };
-    }
-
-    # buttons to move box around
-    my $moveBoxButtons = '';
-
-    my $leftcol = '';
-    if ($col eq 'R') {
-        $leftcol = 'L';
-    }
-    my $rightcol = '';
-    if ($col eq 'L') {
-        $rightcol = 'R';
-    }
-
-    my $colpos = $self->col_order($box);
-
-    if ($leftcol) {
-        $moveBoxButtons .= qq{
-            <a onclick="return movePortalBoxToCol($pboxid, '$leftcol', $colpos);" href="$post_url?movebox=1&pboxid=$pboxid&boxcol=$leftcol&boxcolpos=$colpos">
-                <img src="$LJ::IMGPREFIX/portal/PortalBoxArrowLeft.gif" title="Move this module left" class="toolbutton" />
-            </a>
-        };
-    }
-    if ($rightcol) {
-        $moveBoxButtons .= qq{
-            <a onclick="return movePortalBoxToCol($pboxid, '$rightcol', $colpos);" href="$post_url?movebox=1&pboxid=$pboxid&boxcol=$rightcol&boxcolpos=$colpos">
-                <img src="$LJ::IMGPREFIX/portal/PortalBoxArrowRight.gif" title="Move this module right" class="toolbutton" />
-            </a>
-        };
-    }
-
-    if (!($sort <= $minsort)) {
-        $moveBoxButtons .= qq{
-            <a onclick="return movePortalBoxUp($pboxid);" href="$post_url?movebox=1&pboxid=$pboxid&up=1">
-                <img src="$LJ::IMGPREFIX/portal/PortalBoxArrowUp.gif" title="Move this module up" class="toolbutton" />
-            </a>
-        }
-    }
-
-    if (!($sort >= $maxsort)) {
-        $moveBoxButtons .= qq{
-            <a onclick="return movePortalBoxDown($pboxid);" href="$post_url?movebox=1&pboxid=$pboxid&down=1">
-                <img src="$LJ::IMGPREFIX/portal/PortalBoxArrowDown.gif" title="Move this module down" class="toolbutton" />
-            </a>
-        }
-    }
-
-    my $titlebarhtml = qq {
-            $moduleicon<span class="PortalBoxTitleText">$boxtitle</span>
-            <span class="PortalBoxMoveButtons" id="PortalBoxMoveButtons$pboxid">$closebutton $refreshbutton $moveBoxButtons $configlink</span>
-        };
-
-    return $titlebarhtml;
-}
-
-# args: boxid, force?
-# force: don't use cached box contents
-sub generate_box_insides {
-    my LJ::Portal::Config $self = shift;
-    my $boxid = shift;
-    my $force = shift;
-
-    $force ||= 0;
-
-    my $box = $self->{'boxes'}->{$boxid};
-    return 'Could not find box.' unless $box;
-
-    my $sort = $box->sortorder;
-    my $boxclass = $box->can('box_class') ? $box->box_class : '';
-    my $titlebar = $self->generate_box_titlebar($box);
-    my $content;
-
-    # don't let the box do anything if it's disabled
-    if ($box->box_is_disabled) {
-        $content = 'Sorry, this feature is disabled at this time.';
-    }
-
-    my $passback;
-
-    if ($LJ::PORTAL_BOX_PROFILE_START) {
-        $passback = $LJ::PORTAL_BOX_PROFILE_START->($box);
-    }
-
-    my $gencont = sub {
-        my $usecache = shift;
-        $usecache ||= 0;
-        if (!$content) {
-            $content = $self->get_box_cached_contents($box) if $usecache;
-            $content = $box->generate_content if !$content;
-        }
-    };
-
-    if ($LJ::IS_DEV_SERVER && $self->{'profile'}) {
-        eval "use Benchmark ':hireswallclock';";
-
-        return if $LJ::PORTAL_PROFILED_BOX{$boxclass};
-
-        my $runtime = Benchmark::timeit($self->{'profile'}, $gencont);
-        $LJ::PORTAL_DEBUG_CONTENT .= sprintf("%20s%40s", $boxclass, ": " .
-                                             Benchmark::timestr($runtime) . "\n");
-
-        $LJ::PORTAL_PROFILED_BOX{$boxclass} = 1;
-    } else {
-        $gencont->(!$force);
-    }
-
-    if ($LJ::PORTAL_BOX_PROFILE_END) {
-        $LJ::PORTAL_BOX_PROFILE_END->($passback);
-    }
-
-    my $ret = qq{
-        <div class="PortalBoxTitleBar" id="pboxtitlebar$boxid">
-            $titlebar
-        </div>
-        <div class="PortalBoxContent $boxclass">
-            $content
-        </div>
-        };
-
-    return $ret;
-}
-
-sub get_box_cached_contents {
-    my ($self, $box) = @_;
-
-    # is this box supposed to be memcached?
-    return undef unless ($box->can('cache_global'));
-
-    my $content;
-
-    my $memcachekey = $box->contents_memcache_key;
-
-    # firstly, check if there is a cache in memory
-    my $box_cached = LJ::MemCache::get($memcachekey);
-
-    my $time = time();
-
-    my $etag = $box->can('etag') ? $box->etag : 1;
-
-    # are the contents of this box cached?
-    if ($box_cached) {
-        my $boxcontent_cached;
-        my $etag_cached;
-        ($etag_cached, $time, $boxcontent_cached) = @$box_cached;
-
-        # is it time to check to see if this content has been modified?
-        if (time() > $time) {
-            # compare etags. if they don't match, regenerate contents
-            if ($box->can('etag') && $etag && $box->etag == $etag_cached && $boxcontent_cached) {
-                $content = $boxcontent_cached;
-            }
-
-            # reset time
-            $time = time() + $box->cache_time if $box->can('cache_time');
-        } else {
-            $content = $boxcontent_cached ? $boxcontent_cached : undef;
-        }
-    }
-
-    # update memcache
-    $content = $box->generate_content if !$content;
-    LJ::MemCache::set($memcachekey, [$etag, $time, $content]);
-
-    return $content;
-}
-
-1;
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/LJ/User.pm
--- a/cgi-bin/LJ/User.pm	Wed Aug 05 07:06:56 2009 +0000
+++ b/cgi-bin/LJ/User.pm	Wed Aug 05 07:10:05 2009 +0000
@@ -5866,7 +5866,7 @@ sub unset_remote
 # $dom: 'L' == log, 'T' == talk, 'M' == modlog, 'S' == session,
 #       'R' == memory (remembrance), 'K' == keyword id,
 #       'P' == phone post, 'C' == pending comment
-#       'O' == pOrtal box id, 'V' == 'vgift', 'E' == ESN subscription id
+#       'V' == 'vgift', 'E' == ESN subscription id
 #       'Q' == Notification Inbox, 
 #       'D' == 'moDule embed contents', 'I' == Import data block
 #       'Z' == import status item, 'X' == eXternal account
@@ -5976,9 +5976,6 @@ sub alloc_user_counter
         $newmax = ($ppemax > $userblobmax) ? $ppemax : $userblobmax;
     } elsif ($dom eq "C") {
         $newmax = $u->selectrow_array("SELECT MAX(pendid) FROM pendcomments WHERE jid=?",
-                                      undef, $uid);
-    } elsif ($dom eq "O") {
-        $newmax = $u->selectrow_array("SELECT MAX(pboxid) FROM portal_config WHERE userid=?",
                                       undef, $uid);
     } elsif ($dom eq "V") {
         $newmax = $u->selectrow_array("SELECT MAX(giftid) FROM vgifts WHERE userid=?",
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/ljdefaults.pl
--- a/cgi-bin/ljdefaults.pl	Wed Aug 05 07:06:56 2009 +0000
+++ b/cgi-bin/ljdefaults.pl	Wed Aug 05 07:10:05 2009 +0000
@@ -209,96 +209,6 @@
 
     $DEFAULT_EDITOR ||= 'rich';
 
-    # Portal boxes
-    unless(scalar(@LJ::PORTAL_BOXES)) {
-        @PORTAL_BOXES = (
-                         'Birthdays',
-                         'UpdateJournal',
-                         'TextMessage',
-                         'PopWithFriends',
-                         'Friends',
-                         'Manage',
-                         'RecentComments',
-                         'NewUser',
-                         'FriendsPage',
-                         'FAQ',
-                         'Debug',
-                         'Note',
-                         'RandomUser',
-                         'Tags',
-                         'Reader',
-                         );
-    }
-
-    unless(scalar(@LJ::PORTAL_BOXES_HIDDEN)) {
-        @PORTAL_BOXES_HIDDEN = (
-                                'Debug',
-                                );
-    }
-
-    unless (keys %LJ::PORTAL_DEFAULTBOXSTATES) {
-        %PORTAL_DEFAULTBOXSTATES = (
-                                    'Birthdays' => {
-                                        'added' => 1,
-                                        'sort'  => 4,
-                                        'col'   => 'R',
-                                    },
-                                    'FriendsPage' => {
-                                        'added' => 1,
-                                        'sort'  => 6,
-                                        'col'   => 'L',
-                                    },
-                                    'FAQ' => {
-                                        'added' => 1,
-                                        'sort'  => 8,
-                                        'col'   => 'R',
-                                    },
-                                    'Friends' => {
-                                        'added' => 1,
-                                        'sort'  => 10,
-                                        'col'   => 'R',
-                                    },
-                                    'Manage' => {
-                                        'added' => 1,
-                                        'sort'  => 12,
-                                        'col'   => 'L',
-                                    },
-                                    'PopWithFriends' => {
-                                        'added' => 0,
-                                        'col'   => 'R',
-                                    },
-                                    'RecentComments' => {
-                                        'added' => 1,
-                                        'sort'  => 10,
-                                        'col'   => 'L',
-                                    },
-                                    'UpdateJournal' => {
-                                        'added' => 1,
-                                        'sort'  => 4,
-                                        'col'   => 'L',
-                                    },
-                                    'NewUser' => {
-                                        'added' => 1,
-                                        'sort'  => 2,
-                                        'col'   => 'L',
-                                    },
-                                    'TextMessage' => {
-                                        'added'  => 1,
-                                        'sort'   => 12,
-                                        'col'    => 'R',
-                                    },
-                                    'Frank' => {
-                                        'notunique' => 1,
-                                    },
-                                    'Note' => {
-                                        'notunique' => 1,
-                                    },
-                                    'Reader' => {
-                                        'notunique' => 1,
-                                    },
-                                    );
-    }
-
     unless (@LJ::EVENT_TYPES) {
         @LJ::EVENT_TYPES = qw (
                                AddedToCircle
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/ljlib.pl
--- a/cgi-bin/ljlib.pl	Wed Aug 05 07:06:56 2009 +0000
+++ b/cgi-bin/ljlib.pl	Wed Aug 05 07:10:05 2009 +0000
@@ -90,8 +90,7 @@ sub END { LJ::end_request(); }
                     "s2stylelayers2", "s2compiled2", "userlog",
                     "logtags", "logtagsrecent", "logkwsum",
                     "recentactions", "usertags", "pendcomments",
-                    "user_schools", "portal_config", "portal_box_prop",
-                    "loginlog", "active_user", "userblobcache",
+                    "user_schools", "loginlog", "active_user", "userblobcache",
                     "notifyqueue", "cprod", "urimap",
                     "jabroster", "jablastseen", "random_user_set",
                     "poll2", "pollquestion2", "pollitem2",
diff -r 1e10c8cffe6c -r 981e9adf07eb cgi-bin/modperl_subs.pl
--- a/cgi-bin/modperl_subs.pl	Wed Aug 05 07:06:56 2009 +0000
+++ b/cgi-bin/modperl_subs.pl	Wed Aug 05 07:10:05 2009 +0000
@@ -25,7 +25,6 @@ use Image::Size ();
 use Image::Size ();
 use POSIX ();
 
-use LJ::Portal ();
 use LJ::Blob;
 use LJ::Captcha;
 use LJ::Faq;
@@ -117,7 +116,6 @@ sub setup_start {
         }
         DBI->install_driver("mysql");
         LJ::CleanHTML::helper_preload();
-        LJ::Portal->load_portal_boxes;
     }
 
     # set this before we fork
diff -r 1e10c8cffe6c -r 981e9adf07eb doc/raw/appendices/glossary.xml
--- a/doc/raw/appendices/glossary.xml	Wed Aug 05 07:06:56 2009 +0000
+++ b/doc/raw/appendices/glossary.xml	Wed Aug 05 07:10:05 2009 +0000
@@ -213,11 +213,6 @@ Terms, definitions, and insight.</para>
     </glossentry>
 
     <glossentry>
-    <glossterm>Portlets</glossterm>
-    <glossdef><para>Portal boxes/widgets, only more cutely named.</para></glossdef>
-    </glossentry>
-
-    <glossentry>
     <glossterm>Scheme</glossterm>
     <glossdef><para>A collection of &bml; templates that comprise a unique layout.</para></glossdef>
     </glossentry>
diff -r 1e10c8cffe6c -r 981e9adf07eb doc/raw/build/ljconfig/ljconfig2db.pl
--- a/doc/raw/build/ljconfig/ljconfig2db.pl	Wed Aug 05 07:06:56 2009 +0000
+++ b/doc/raw/build/ljconfig/ljconfig2db.pl	Wed Aug 05 07:10:05 2009 +0000
@@ -808,98 +808,6 @@ Please see &lt;a href='http://status.exa
             },
         },
 
-        'portal' => {
-            'name' => "Portal Configuration",
-            'portal_boxes' => {
-                    'desc' => "The default portal boxes (&apos;portlets&apos;) a user will see.",
-                    'type' => "array",
-                    'default' => "(
-        'Birthdays',
-        'UpdateJournal',
-        'TextMessage',
-        'PopWithFriends',
-        'Friends',
-        'Manage',
-        'RecentComments',
-        'NewUser',
-        'FriendsPage',
-        'FAQ',
-        'Debug',
-        'Note',
-        'RandomUser',
-        'Tags',
-        'Reader',
-);",
-            },
-            'portal_defaultboxstates' => {
-                    'desc' => "The default sizes and positions of the boxes.",
-                    'type' => "hash",
-                    'default' => "(
-            'Birthdays' => {
-                    'added' => 1,
-                    'sort'  => 4,
-                    'col'   => 'R',
-            },
-            'FriendsPage' => {
-                    'added' => 1,
-                    'sort'  => 6,
-                    'col'   => 'L',
-            },
-            'FAQ' => {
-                    'added' => 1,
-                    'sort'  => 8,
-                    'col'   => 'R',
-            },
-            'Friends' => {
-                    'added' => 1,
-                    'sort'  => 10,
-                    'col'   => 'R',
-            },
-            'Manage' => {
-                    'added' => 1,
-                    'sort'  => 12,
-                    'col'   => 'L',
-            },
-            'PopWithFriends' => {
-                    'added' => 0,
-                    'col'   => 'R',
-            },
-            'RecentComments' => {
-                    'added' => 1,
-                    'sort'  => 10,
-                    'col'   => 'L',
-            },
-            'UpdateJournal' => {
-                    'added' => 1,
-                    'sort'  => 4,
-                    'col'   => 'L',
-            },
-            'NewUser' => {
-                    'added' => 1,
-                    'sort'  => 2,
-                    'col'   => 'L',
-            },
-            'TextMessage' => {
-                    'added'  => 1,
-                    'sort'   => 12,
-                    'col'    => 'R',
-            },
-            'Note' => {
-                    'notunique'  => 1,
-            },
-            'Reader' => {
-                    'notunique'  => 1,
-            },
-);",
-            },
-            'portal_boxes_hidden' => {
-                    'desc' => "A list of boxes that do not appear to users, by default.",
-                    'type' => "array",
-                    'default' => "('Debug',
-);",
-            },
-        },
-
         'styling' => {
             'name' => "Styling Related",
             'default_style' => {
diff -r 1e10c8cffe6c -r 981e9adf07eb doc/raw/entities/ljp.book.ent
--- a/doc/raw/entities/ljp.book.ent	Wed Aug 05 07:06:56 2009 +0000
+++ b/doc/raw/entities/ljp.book.ent	Wed Aug 05 07:10:05 2009 +0000
@@ -19,7 +19,6 @@
 <!ENTITY ljp.int.index                               SYSTEM "../ljp.book/int/index.xml">
 <!ENTITY ljp.int.cap_classes                    SYSTEM "../ljp.book/int/cap_classes.xml">
 <!ENTITY ljp.int.cap_list                           SYSTEM "../ljp.book/int/cap.ref.gen.xml">
-<!ENTITY ljp.int.portal_modules                SYSTEM "../ljp.book/int/portal_modules.xml">
 <!ENTITY ljp.int.cookie_scheme               SYSTEM "../ljp.book/int/cookie_scheme.xml">
 <!ENTITY ljp.int.oh_crumbs                      SYSTEM "../ljp.book/int/crumbs.xml">
 <!ENTITY ljp.int.statusvis                         SYSTEM "../ljp.book/int/statusvis.xml">
diff -r 1e10c8cffe6c -r 981e9adf07eb doc/raw/lj.book/install/ljconfig.disabled.xml
--- a/doc/raw/lj.book/install/ljconfig.disabled.xml	Wed Aug 05 07:06:56 2009 +0000
+++ b/doc/raw/lj.book/install/ljconfig.disabled.xml	Wed Aug 05 07:10:05 2009 +0000
@@ -76,10 +76,6 @@
     <varlistentry>
       <term>ljmaint_tasks</term>
       <listitem><simpara>Enable running of maintenance tasks by <filename>ljmaint.pl</filename>.</simpara></listitem>
-    </varlistentry>
-    <varlistentry>
-      <term>portal</term>
-      <listitem><simpara>Show the <quote>Portal</quote>, which acts as a one-stop-shop of features, for users.</simpara></listitem>
     </varlistentry>
     <varlistentry>
       <term>qbufferd_jobs</term>
@@ -271,10 +267,6 @@
       <listitem><simpara>Allow custom-defined offsite journal search, created through a hook of the same name. This is in addition to <quote>feedster_search</quote>, which can still be separately disabled.</simpara></listitem>
     </varlistentry>
    <varlistentry>
-      <term>portal_fade</term>
-      <listitem><simpara>Use a fade-in/fade-out effect on Portal boxes.</simpara></listitem>
-    </varlistentry>
-   <varlistentry>
       <term>rte_buttons</term>
       <listitem><simpara>Continue to show buttons on the rich text editor that have been disabled.</simpara></listitem>
     </varlistentry>
diff -r 1e10c8cffe6c -r 981e9adf07eb doc/raw/ljp.book/int/index.xml
--- a/doc/raw/ljp.book/int/index.xml	Wed Aug 05 07:06:56 2009 +0000
+++ b/doc/raw/ljp.book/int/index.xml	Wed Aug 05 07:10:05 2009 +0000
@@ -6,7 +6,6 @@
     </para>
   </partintro>
   &ljp.int.cap_classes;
-  &ljp.int.portal_modules;
   &ljp.int.cookie_scheme;
   &ljp.int.oh_crumbs;
   &ljp.int.statusvis;
diff -r 1e10c8cffe6c -r 981e9adf07eb doc/raw/ljp.book/int/memcache_keys_list.xml
--- a/doc/raw/ljp.book/int/memcache_keys_list.xml	Wed Aug 05 07:06:56 2009 +0000
+++ b/doc/raw/ljp.book/int/memcache_keys_list.xml	Wed Aug 05 07:10:05 2009 +0000
@@ -506,34 +506,6 @@
     </row>
     <row>
         <entry>uid</entry>
-        <entry>prtcfg:&lt;uid&gt;</entry>
-        <entry>arrayref of the portal box configuration for this userid</entry>
-        <entry>livejournal</entry>
-        <entry></entry>
-    </row>
-    <row>
-        <entry>uid</entry>
-        <entry>prtbox:&lt;uid&gt;:&lt;pboxid&gt;</entry>
-        <entry>arrayref of the state of a LJ::Portal::Box object</entry>
-        <entry>livejournal</entry>
-        <entry></entry>
-    </row>
-    <row>
-        <entry>uid</entry>
-        <entry>prtconu:&lt;uid&gt;:&lt;pboxid&gt;</entry>
-        <entry>[etag, maxtime, html] - per-user box content caching</entry>
-        <entry>livejournal</entry>
-        <entry></entry>
-    </row>
-    <row>
-        <entry>typeid</entry>
-        <entry>prtcong:&lt;typeid&gt;</entry>
-        <entry>[etag, maxtime, html] - global box content caching</entry>
-        <entry>livejournal</entry>
-        <entry></entry>
-    </row>
-    <row>
-        <entry>uid</entry>
         <entry>saui:&lt;uid&gt;</entry>
         <entry>{ schoolid =&gt; { year_start =&gt; &hellip;, year_end =&gt; &hellip; } }</entry>
         <entry>livejournal</entry>
diff -r 1e10c8cffe6c -r 981e9adf07eb doc/raw/ljp.book/int/portal_modules.xml
--- a/doc/raw/ljp.book/int/portal_modules.xml	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-<chapter id="ljp.int.portal_modules">
-
-<title>Portal Modules</title>
-
-<subtitle>Introduction &mdash; Everything you wanted to know about portal modules but were afraid to ask.</subtitle>
-
-<formalpara><title>What is the minimum I need to do to write a portal box?</title>
-<para>Subclass LJ::Portal::Box and override these methods:</para>
-</formalpara>
-
-<informaltable>
-<tgroup cols="2">
-<tbody>
-<row>
-<entry>LJ::Portal::Box::initialize()</entry>
-<entry>Called when class is instantiated. Good place to set things up</entry>
-</row>
-<row>
-<entry>LJ::Portal::Box::generate_content()</entry>
-<entry>Return &html; to be displayed in the box</entry>
-</row>
-<row>
-<entry>LJ::Portal::Box::box_description()</entry>
-<entry>A short description of the module for the user</entry>
-</row>
-<row>
-<entry>LJ::Portal::Box::box_name()</entry>
-<entry>Short title to be displayed</entry>
-</row>
-<row>
-<entry>LJ::Portal::Box::box_class()</entry>
-<entry>Both &css; class and perl class of the module</entry>
-</row>
-<row>
-<entry>LJ::Portal::Box::box_class()</entry>
-<entry>Both &css; class and perl class of the module</entry>
-</row>
-</tbody>
-</tgroup>
-</informaltable>
-
-<para><emphasis role='strong'>Optional methods</emphasis>:</para>
-
-<informaltable>
-<tgroup cols="2">
-<tbody>
-<row>
-<entry>LJ::Portal::Box::can_refresh()</entry>
-<entry>Show a little refresh box button</entry>
-</row>
-<row>
-<entry>LJ::Portal::Box::config_props()</entry>
-<entry>Hashref of options the user can configure. See below.</entry>
-</row>
-<row>
-<entry>LJ::Portal::Box::prop_keys()</entry>
-<entry>Hashref of config name => prop id # (can be any number)</entry>
-</row>
-<row>
-<entry>LJ::Portal::Box::handle_request($GET, $POST)</entry>
-<entry>If you want your module to be interactive, you can do GETs or POSTs
-with portalboxaction=$pboxid set to get this method called. 
-Return &js; to execute or undef to just have the box be updated</entry>
-</row>
-<row>
-<entry>LJ::Portal::Box::default_added($u)</entry>
-<entry>If this returns true, then this box should be added by default</entry>
-</row>
-<row>
-<entry>LJ::Portal::Box::box_updated()</entry>
-<entry>This is called when the box is reloaded on the page, and any &js;
-it returns will be executed</entry>
-</row>
-<row>
-<entry>LJ::Portal::Box::cache_global</entry>
-<entry>Return 1 if box contents should be cached globally, otherwise contents
-cached per-user (if the cache functions are defined)</entry>
-</row>
-<row>
-<entry>LJ::Portal::Box::cache_time</entry>
-<entry>How long (in seconds) before comparing etags to determine if the content
-needs to be re-generated</entry>
-</row>
-<row>
-<entry>LJ::Portal::Box::etag</entry>
-<entry>A tag which is easily calculated which reflects the current state of the box,
-used to determine if the box cache is out of date</entry>
-</row>
-</tbody>
-</tgroup>
-</informaltable>
-
-<para><emphasis role='strong'>config_props</emphasis> &mdash; hashref with the following options:</para>
-
-<informaltable>
-<tgroup cols="2">
-<tbody>
-<row>
-<entry>type</entry>
-<entry>checkbox, dropdown, integer, hidden</entry>
-</row>
-<row>
-<entry>desc</entry>
-<entry>translation string that describes the prop</entry>
-</row>
-<row>
-<entry>default</entry>
-<entry>default state</entry>
-</row>
-<row>
-<entry>min/max</entry>
-<entry>integer min/max values</entry>
-</row>
-<row>
-<entry>items</entry>
-<entry>hashref of options for dropdown menu</entry>
-</row>
-<row>
-<entry>maxlength</entry>
-<entry>textfield maxlength</entry>
-</row>
-</tbody>
-</tgroup>
-</informaltable>
-
-<para><emphasis role="strong">Methods and fields available to modules:</emphasis></para>
-
-<informaltable>
-<tgroup cols="2">
-<tbody>
-<row>
-<entry>get_prop(propname)</entry>
-<entry>return the value for a box property</entry>
-</row>
-<row>
-<entry>set_prop(propname)</entry>
-<entry>set &quot; &quot;</entry>
-</row>
-<row>
-<entry>pboxid()</entry>
-<entry>this box&apos;s <acronym>ID</acronym></entry>
-</row>
-<row>
-<entry>sortorder()</entry>
-<entry>what order this box is in its column</entry>
-</row>
-<row>
-<entry>set_default_props()</entry>
-<entry>reset all props to their default state</entry>
-</row>
-<row>
-<entry>delete_prop(propid)</entry>
-<entry>delete prop by id</entry>
-</row>
-<row>
-<entry>set_props(props)</entry>
-<entry>hashref of props by propname =&gt; value to set</entry>
-</row>
-</tbody>
-</tgroup>
-</informaltable>
- 
-<tip><para>Handy &js;:</para>
-<simpara>evalXrequest(str) send an &xml; &http; POST request, usually to be handled by handle_request
-and do a <abbrev>JS</abbrev> eval of what is returned.</simpara></tip>
-
-</chapter>
-
diff -r 1e10c8cffe6c -r 981e9adf07eb doc/raw/memcache-keys.txt
--- a/doc/raw/memcache-keys.txt	Wed Aug 05 07:06:56 2009 +0000
+++ b/doc/raw/memcache-keys.txt	Wed Aug 05 07:10:05 2009 +0000
@@ -92,11 +92,6 @@ includefile:<name> == text of BML includ
 
 <uid>   lastcomm:<uid> -- id of the last comment the user posted via quickreply
 
-<uid>    prtcfg:<uid>   -- arrayref of the portal box configuration for this userid
-<uid>    prtbox:<uid>:<pboxid>  --  arrayref of the state of a LJ::Portal::Box object
-<uid>    prtconu:<uid>:<pboxid>  --  [etag, maxtime, html] - per-user box content caching
-<typeid> prtcong:<typeid> -- [etag, maxtime, html] - global box content caching
-
 <uid> saui:<uid> == { schoolid => { year_start => .., year_end => .. } }
 <schoolid> saal:<schoolid> == [ userid, ... ]; userids at a school
 <schoolid> saaly:<schoolid>:<year> == [ userid, ... ]; userids at a school in this year
diff -r 1e10c8cffe6c -r 981e9adf07eb htdocs/js/portal.js
--- a/htdocs/js/portal.js	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,785 +0,0 @@
-var portalAnimating = {};
-var portalFading = {};
-var box_reloading = {};
-var add_portal_module_menu_html = "";
-var boxControlsVisible = null;
-
-// for comment management
-var LJ_cmtinfo;
-var current_pboxid;
-
-function userhook_delete_comment_ARG (talkid) {
-  hideElement('ljcmt'+talkid);
-  if(current_pboxid)
-    updatePortalBox(current_pboxid);
-}
-
-// handle clicks
-function portalDoClick(e) {
-  var evt = new xEvent(e);
-
-  if (!evt)
-    return;
-
-  // hide the menu unless they clicked on it
-  var menu = getPortalMenu('addbox');
-
-  var parent = xParent(evt.target, true);
-  var targetClasses = evt.target.className;
-  if (parent && xDef(parent.className))
-    targetClasses += parent.className;
-
-  // don't mess with menu stuff if the menu was clicked
-  if (targetClasses && targetClasses.indexOf('PortalMenuItem') != -1)
-    return;
-
-  if (menu && menu.isOpen == 1) {
-    hidePortalMenu('addbox');
-  }
-}
-
-// run when page is loaded
-function setupPortal() {
-  updateAddPortalModuleMenu();
-
-  // if safari or IE Windows, use fading prefs
-  // otherwise disable, because other guys can't handle it right
-  var safari = xUA.indexOf('safari');
-  if (safari == -1 && !(xIE4Up && !xMac)) {
-    if (Site.doFade)
-      Site.doFade = 0;
-  }
-
-  portalRegEvent(document.body, "mousemove", portalMouseMove);
-}
-
-function portalGetXTR () {
-  var xtr;
-  var ex;
-
-  if (typeof(XMLHttpRequest) != "undefined") {
-    xtr = new XMLHttpRequest();
-  } else {
-    try {
-      xtr = new ActiveXObject("Msxml2.XMLHTTP.4.0");
-    } catch (ex) {
-      try {
-        xtr = new ActiveXObject("Msxml2.XMLHTTP");
-      } catch (ex) {
-      }
-    }
-  }
-
-  // let me explain this.  Opera 8 does XMLHttpRequest, but not setRequestHeader.
-  // no problem, we thought:  we'll test for setRequestHeader and if it's not present
-  // then fall back to the old behavior (treat it as not working).  BUT --- IE6 won't
-  // let you even test for setRequestHeader without throwing an exception (you need
-  // to call .open on the .xtr first or something)
-  try {
-    if (xtr && ! xtr.setRequestHeader)
-      xtr = null;
-  } catch (ex) { }
-
-  return xtr;
-}
-
-function doXrequest (postdata, finishcallback) {
-  var state_callback = function () {
-    if (xtr && xtr.readyState == 4) {
-      if (xtr.status == 200) {
-        var result = xtr.responseText;
-        if (result) {
-          if (finishcallback)
-            finishcallback(result);
-          return false;
-        }
-      } else {
-        return true;
-      }
-    }
-  };
-
-  var xtr = portalGetXTR();
-
-  if (!xtr)
-    return true;
-
-  xtr.open("POST", Site.postUrl, true);
-
-  xtr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
-  postdata = "jsmode=1&" + postdata;
-  xtr.send(postdata);
-  xtr.onreadystatechange = state_callback;
-  return false;
-}
-
-function deletePortalBox (pboxid) {
-  var delbox = xGetElementById("pbox" + pboxid);
-
-  if (delbox)
-    animateClose(delbox);
-
-  return evalXrequest("delbox=1&pboxid=" + pboxid);
-}
-
-function addPortalBox (type, col, sortorder) {
-  return evalXrequest("addbox=1&boxtype=" + type + "&boxcol=" + col);
-}
-
-function resetBox (pboxid) {
-  return evalXrequest("resetbox=1&pboxid="+pboxid);
-}
-
-function evalXrequest(request, widget) {
-  var hourglass = null;
-  if (widget) {
-    hourglass = new Hourglass(widget);
-  }
-
-  var doEval = function(result) {
-    if (hourglass)
-      hourglass.hide();
-
-    eval(result);
-  };
-
-  return doXrequest(request, doEval);
-}
-
-// ask if they want to reset their portal
-function askResetAll(confirmtext) {
-
-  // clicked cancel? don't do anything
-  if (!confirm(confirmtext))
-    return false;
-
-  // do a post to reset everything
-  if (evalXrequest("resetalldo=1&resetyes=Yes")) {
-    return true;
-  }
-
-  return false;
-}
-
-function showConfigPortalBox (pboxid) {
-  var box = xGetElementById("config"+pboxid);
-
-  if (!box) {
-    if(!evalXrequest("configbox=1&pboxid="+pboxid, xGetElementById("edit"+pboxid))) {
-      return false;
-    }
-  } else {
-    animateOpen(box);
-    return false;
-  }
-
-  return true;
-}
-
-function hideConfigPortalBox (pboxid) {
-  var box = xGetElementById("config"+pboxid);
-  if (box) {
-    fadeOut(box);
-  }
-  return false;
-}
-
-function savePortalBoxConfig (pboxid) {
-  // check to see if this is an actual form instead of us wanting to do an XML HTTP request
-  var formelements = xGetElementById("box_config_elements"+pboxid);
-  if (formelements) {
-    var elementlist = formelements.value.split(',');
-    var postdata = "saveconfig=1&pboxid="+pboxid+"&";
-    var valuesfound = false;
-    for(var i=0; i<elementlist.length; i++) {
-      var element = xGetElementById(elementlist[i]+pboxid);
-      var value = "";
-      if (element) {
-        if (element.type == 'checkbox') {
-          value = element.checked ? "1" : "0";
-        } else {
-          value = escape(element.value);
-        }
-
-        // if min and max values defined, check them
-        var minvalue = element.getAttribute('min');
-        var maxvalue = element.getAttribute('max');
-        if (minvalue && maxvalue) {
-          element.value = parseInt(element.value);
-          if (element.value > parseInt(maxvalue) || element.value < parseInt(minvalue)) {
-            alert("You must enter a value between "+minvalue+" and "+maxvalue+".");
-            return false; // do not do submit, let the user correct their mistake
-          }
-        }
-        postdata += elementlist[i] + "=" + value + "&";
-        valuesfound = true;
-      }
-    }
-    if (valuesfound) {
-      //remove trailing "&"
-      postdata = postdata.substr(0, postdata.length-1);
-      return evalXrequest(postdata, xGetElementById("pbox"+pboxid));
-    }
-  }
-
-  return true;
-}
-
-function centerBoxX (obj) {
-  xLeft(obj, (xClientWidth()/2) - (xWidth(obj))/2);
-}
-
-function xRight (obj) {
-  if (obj.style.position != "absolute") {
-    return xLeft(obj) + xWidth(obj);
-  } else {
-    return xPageX(obj) + xWidth(obj);
-  }
-}
-function xBottom (obj) {
-  if (obj.style.position != "absolute") {
-    return xTop(obj) + xHeight(obj);
-  } else {
-    return xPageY(obj) + xHeight(obj);
-  }
-}
-
-// update the date/time for update box so that it's correct for the browser
-function portal_settime() {
-  now = new Date();
-  if (! now) return true;
-
-  var year_field = xGetElementById('update_year');
-  var mon_field = xGetElementById('update_mon');
-  var day_field = xGetElementById('update_day');
-  var hour_field = xGetElementById('update_hour');
-  var min_field = xGetElementById('update_min');
-
-  if (!year_field || !mon_field || !day_field || !hour_field || !min_field)
-    return true;
-
-  year_field.value = now.getYear() < 1900 ? now.getYear() + 1900 : now.getYear();
-  mon_field.value = now.getMonth() + 1;
-  day_field.value = now.getDate();
-  hour_field.value = now.getHours();
-  min_field.value = now.getMinutes();
-
-  return true;
-}
-
-
-function openConfigMenu() {
-  var configbar = xGetElementById('PortalConfigMenuBar');
-  var configbuttonbar = xGetElementById('PortalConfigButtonBar');
-
-  if (!configbar || !configbuttonbar) return true;
-
-  showBox(configbar);
-  hideBox(configbuttonbar);
-
-  return false;
-}
-
-function hideMe(e) {
-  xDisplay(e, 'none');
-}
-
-function closeConfigMenu() {
-  var configbar = xGetElementById('PortalConfigMenuBar');
-  var configbuttonbar = xGetElementById('PortalConfigButtonBar');
-  var content = xGetElementById('PortalContentContainer');
-  if (!configbar || !content || !configbuttonbar) return;
-
-  hideBox(configbar);
-  // make sure all open menus are closed
-  hidePortalMenu();
-  showBox(configbuttonbar);
-}
-
-//change the opacity for different browsers
-function changeOpac(opacity, id) {
-  var e =  xGetElementById(id);
-  if (e && xDef(e.style)) {
-    var object = e.style;
-    if (object) {
-      //reduce flicker
-      if (opacity == 1 && (navigator.userAgent.indexOf('Gecko') != -1 && navigator.userAgent.indexOf('Safari') == -1)) opacity = 99.99;
-
-      object.filter = "alpha(opacity=" + opacity * 100 + ")";
-      object.opacity = opacity;
-    }
-  }
-}
-
-function updateAddPortalModuleMenu(e) {
-  var finish_callback = function (menuhtml) {
-    if (menuhtml) {
-      add_portal_module_menu_html = menuhtml;
-      var menuelement = getPortalMenu('addbox');
-
-      // no sense causing flicker on the box if it isn't changing
-      if (menuelement && menuelement.innerHTML != menuhtml) {
-        menuelement.innerHTML = menuhtml;
-      }
-
-    } else {
-      alert("Error retrieving menu.");
-    }
-  };
-
-  xStopPropagation(e);
-
-  return doXrequest("getmenu=1&menu=addbox", finish_callback);
-}
-
-function dropDownMenu(e, menu) {
-  // no other menus yet
-  if (menu != 'addbox') {
-    alert("No such menu " + menu);
-    return true;
-  }
-
-  // do we already have the menu contents loaded?
-  if (add_portal_module_menu_html) {
-    doDropDownMenu(e, add_portal_module_menu_html);
-    return false;
-  }
-
-  var finish_callback = function (menuhtml) {
-    if (menuhtml)
-      doDropDownMenu(e, menuhtml);
-    else
-      alert("Error retrieving menu.");
-  };
-
-  return doXrequest("getmenu=1&menu="+menu, finish_callback);
-}
-
-function doDropDownMenu(e, menuHTML) {
-  var menuBox = xGetElementById('PortalConfigMenu');
-
-  if (!menuBox) {
-    menuBox = xCreateElement('div');
-  }
-
-  if (!xDef(menuBox))
-    return;
-
-  if (menuBox.isOpen) {
-    hidePortalMenu('addbox');
-    return;
-  }
-
-  xAppendChild(document.body, menuBox);
-  menuBox.innerHTML = menuHTML;
-  menuBox.id = "PortalConfigMenu";
-  menuBox.className = "DropDownMenu";
-  menuBox.newRight = xRight(menuBox);
-  menuBox.newBottom = xBottom(menuBox);
-
-  fadeIn(menuBox);
-  xTop(menuBox, xPageY(e) + xHeight(e));
-  xLeft(menuBox, xPageX(e) - xWidth(menuBox) + xWidth(e));
-
-  menuBox.isOpen = 1;
-
-  /* var addbutton = xGetElementById("AddPortalMenuButtonImage");
-  if (addbutton && Site.imgprefix) {
-    addbutton.src = Site.imgprefix + "/portal/PortalAddButtonSelected.gif";
-    }*/
-
-  // keep menu up to date
-  updateAddPortalModuleMenu();
-}
-
-function getPortalMenu(menu) {
-  return xGetElementById('PortalConfigMenu');
-}
-
-function hidePortalMenu(menu) {
-  var menuelement = getPortalMenu(menu);
-
-  if (menuelement && menuelement.isOpen) {
-
-    var callback = "xGetElementById('" +
-      menuelement.id + "').isOpen = 0; xVisibility('" + menuelement.id + "', false);";
-
-    fadeOut('PortalConfigMenu', 500, callback);
-
-    /* var addbutton = xGetElementById("AddPortalMenuButtonImage");
-    if (addbutton && Site.imgprefix) {
-      addbutton.src = Site.imgprefix + "/portal/PortalAddButton.gif";
-      }*/
-  }
-}
-
-function showAddPortalBoxMenu() {
-  return dropDownMenu(xGetElementById('AddPortalMenuButton'), 'addbox');
-}
-
-function movePortalBoxUp(pboxid) {
-  var box = xGetElementById("pbox"+pboxid);
-
-  if (!box) return true;
-
-  var prevbox = xPrevSib(box);
-  if (prevbox) {
-    swapnodes(prevbox, box);
-  }
-
-  return evalXrequest ("movebox=1&pboxid="+pboxid+"&up=1");
-}
-
-function movePortalBoxDown(pboxid) {
-  var box = xGetElementById("pbox"+pboxid);
-
-  if (!box) return true;
-
-  var nextbox = xNextSib(box);
-  if (nextbox) {
-    swapnodes(nextbox, box);
-  }
-
-  return evalXrequest ("movebox=1&pboxid="+pboxid+"&down=1");
-}
-
-function movePortalBoxToCol(pboxid, col, boxcolpos) {
-  var box = xGetElementById("pbox"+pboxid);
-  var colelement = xGetElementById("PortalCol"+col);
-  if (!boxcolpos)
-    boxcolpos = "";
-
-  if (colelement && box) {
-    xAppendChild(colelement, box);
-    return evalXrequest ("movebox=1&pboxid="+pboxid+"&boxcol="+col+"&boxcolpos="+boxcolpos);
-  }
-  return true;
-}
-
-function swapnodes (orig, to_swap) {
-  var orig_pn = xParent(orig, true);
-  var to_swap_pn = xParent(to_swap, true);
-  var orig_next_sibling = xNextSib(orig);
-  var to_swap_next_sibling = xNextSib(to_swap);
-  if (!to_swap_pn || !orig_pn) {
-    return;
-  }
-
-  // if next to each other
-  if ( orig_next_sibling == to_swap ) {
-    orig_pn.insertBefore(to_swap, orig);
-    return;
-  } else if ( to_swap_next_sibling == orig ) {
-    orig_pn.insertBefore(orig, to_swap);
-    return;
-  }
-
-  to_swap_pn.removeChild(to_swap);
-  orig_pn.removeChild(orig);
-
-  if (xDef(orig_next_sibling))
-    orig_pn.insertBefore(to_swap, orig_next_sibling);
-  else
-    orig_pn.appendChild(to_swap);
-
-  if (xDef(to_swap_next_sibling))
-    to_swap_pn.insertBefore(orig, to_swap_next_sibling);
-  else
-    to_swap_pn.appendChild(orig);
-}
-
-function swapBoxes(pboxid1, pboxid2) {
-  var e1 = xGetElementById("pbox"+pboxid1);
-  var e2 = xGetElementById("pbox"+pboxid2);
-
-  if (e1 && e2) {
-    swapnodes(e1,e2);
-  }
-}
-
-function updatePortalBox(pboxid) {
-  var pbox = xGetElementById("pbox"+pboxid);
-
-  if (!pbox) return true;
-
-  return evalXrequest("updatebox=1&pboxid="+pboxid, xGetElementById("refresh"+pboxid));
-}
-
-function reloadPortalBox(pboxid) {
-  // don't let user double-click portal update
-  if (!box_reloading[pboxid]) {
-    box_reloading[pboxid] = 1;
-    return updatePortalBox(pboxid);
-  }
-
-  return false;
-}
-
-function regEvent (target, evt, func) {
-  if (! target) return;
-  if (target.attachEvent)
-    target.attachEvent("on"+evt, func);
-  if (target.addEventListener)
-    target.addEventListener(evt, func, false);
-}
-
-function hideBox (e) {
-  var target = xGetElementById(e);
-
-  var callback = "xDisplay('" + target.id + "', 'none');";
-  fadeOut(target, 500, callback);
-}
-function showBox (e) {
-  var target = xGetElementById(e);
-
-  xDisplay(target, 'block');
-  xShow(target);
-
-  if (xDef(target.oldwidth) && target.oldwidth > 0)
-    xWidth(target, target.oldwidth);
-
-  if (xDef(target.oldheight) && target.oldheight > 0)
-    xHeight(target, target.oldheight);
-}
-
-function animateClose(target, speed) {
-  target = xGetElementById(target);
-  fadeOut(target, speed / 1.5, "1;");
-  animateCollapse(target, speed);
-}
-
-function animateOpen(target, speed) {
-  target = xGetElementById(target);
-  fadeIn(target, speed);
-}
-
-function fadeIn(target, speed) {
-  var targetelement = xGetElementById(target);
-  if (!speed) speed = 500;
-
-  if (portalFading[targetelement.id]) {
-    showBox(targetelement);
-    return;
-  }
-
-  showBox(targetelement);
-
-  var opp = 0.0;
-
-  var fadeInCallback = function () {
-    opp += 0.10;
-
-    if (opp <= 1) {
-      changeOpac(opp, targetelement);
-      window.setTimeout(fadeInCallback, 1000/speed);
-    } else {
-      portalFading[targetelement.id] = 0;
-    }
-  };
-
-  if (Site.doFade) {
-    portalFading[targetelement.id] = 1;
-    changeOpac(0.0, targetelement);
-    fadeInCallback();
-  }
-}
-
-function fadeOut(target, speed, callback) {
-  var targetelement = xGetElementById(target);
-  var targetid = targetelement.id;
-
-  if (!speed) speed = 500;
-
-  if (!callback)
-    callback = "hideMe('"+targetid+"')";
-
-  var fadedelta = 0.05;
-
-  if (Site.doFade) {
-    var opp = 1.0;
-
-    var fadeOutCallback = function () {
-      opp -= fadedelta;
-
-      if (opp >= 0) {
-        changeOpac(opp, targetelement);
-        window.setTimeout(fadeOutCallback, 1000/speed);
-      } else {
-        portalFading[targetelement.id] = 0;
-        eval(callback);
-      }
-    };
-
-    if (!portalFading[targetelement.id]) {
-      fadeOutCallback();
-      portalFading[targetelement.id] = 1;
-    }
-
-  } else {
-    eval(callback);
-  }
-}
-
-function animateCollapse(target, speed, callback) {
-  var targetelement = xGetElementById(target);
-
-  if (!callback)
-    callback = function () { hideMe(targetelement); };
-
-  if (portalAnimating)
-    callback();
-
-  if (xHeight(targetelement)>0) {
-    if (!speed) speed = 500;
-
-    targetelement.oldheight = xHeight(targetelement);
-    targetelement.oldwidth = xWidth(targetelement);
-
-    if (Site.doAnimate) {
-      xSlideCornerTo2(targetelement, "se", xRight(targetelement), xTop(targetelement), speed);
-      targetelement.onslideend = callback;
-    } else {
-      callback();
-    }
-  } else {
-    callback();
-  }
-}
-
-// xSlideCornerTo, Copyright 2005 Michael Foster (Cross-Browser.com)
-// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL
-
-function xSlideCornerTo2(e, corner, targetX, targetY, totalTime)
-{
-  if (!(e=xGetElementById(e))) return;
-  if (!e.timeout) e.timeout = 25;
-  e.xT = targetX;
-  e.yT = targetY;
-  e.slideTime = totalTime;
-  e.corner = corner.toLowerCase();
-  e.stop = false;
-  switch(e.corner) { // A = distance, D = initial position
-  case 'nw': e.xA = e.xT - xLeft(e); e.yA = e.yT - xTop(e); e.xD = xLeft(e); e.yD = xTop(e); break;
-  case 'sw': e.xA = e.xT - xLeft(e); e.yA = e.yT - (xTop(e) + xHeight(e)); e.xD = xLeft(e); e.yD = xTop(e) + xHeight(e); break;
-  case 'ne': e.xA = e.xT - (xLeft(e) + xWidth(e)); e.yA = e.yT - xTop(e); e.xD = xLeft(e) + xWidth(e); e.yD = xTop(e); break;
-  case 'se': e.xA = e.xT - (xLeft(e) + xWidth(e)); e.yA = e.yT - (xTop(e) + xHeight(e)); e.xD = xLeft(e) + xWidth(e); e.yD = xTop(e) + xHeight(e); break;
-  default: alert("xSlideCornerTo: Invalid corner"); return;
-  }
-  if (e.slideLinear) e.B = 1/e.slideTime;
-  else e.B = Math.PI / (2 * e.slideTime); // B = period
-  var d = new Date();
-  e.C = d.getTime();
-  if (!e.moving) _xSlideCornerTo2(e);
-}
-
-function _xSlideCornerTo2(e)
-{
-  if (!(e=xGetElementById(e))) return;
-  var now, seX, seY;
-  now = new Date();
-  t = now.getTime() - e.C;
-  if (e.stop) { e.moving = false; e.stop = false; return; }
-  else if (t < e.slideTime) {
-    portalAnimating = 1;
-    setTimeout("_xSlideCornerTo2('"+e.id+"')", e.timeout);
-
-    s = e.B * t;
-    if (!e.slideLinear) s = Math.sin(s);
-
-    newX = Math.round(e.xA * s + e.xD);
-    newY = Math.round(e.yA * s + e.yD);
-  }
-  else { newX = e.xT; newY = e.yT; }
-  seX = xRight(e);
-  seY = xBottom(e);
-  switch(e.corner) {
-  case 'nw': xMoveTo(e, newX, newY); xResizeTo(e, seX - xLeft(e), seY - xTop(e)); break;
-  case 'sw': if (e.xT != xLeft(e)) { xLeft(e, newX); xWidth(e, seX - xLeft(e)); } xHeight(e, newY - xTop(e)); break;
-  case 'ne': xWidth(e, newX - xLeft(e)); if (e.yT != xTop(e)) { xTop(e, newY); xHeight(e, seY - xTop(e)); } break;
-  case 'se': xWidth(e, newX - xLeft(e)); xHeight(e, newY - xTop(e)); break;
-  default: e.stop = true;
-  }
-  e.moving = true;
-  if (t >= e.slideTime) {
-    e.moving = false;
-    if (e.onslideend) e.onslideend();
-    e.onslideend=null;
-    portalAnimating = 0;
-  }
-}
-
-// handle mouse movement on portal boxes. if mouse is in the box then
-// show the move buttons, otherwise hide them
-function portalMouseMove (evt) {
-  Event.prep(evt);
-
-  if (!evt.target)
-    return true;
-
-  var ancestors = DOM.getAncestorsByClassName(evt.target, "PortalBox", true);
-  // does the event have PortalBox as an ancestor? if so show the controls
-  if (ancestors.length) {
-    // Show controls
-    portalShowControls(ancestors[0]);
-  } else {
-    portalHideControls();
-  }
-
-  return true;
-}
-
-function portalShowControls (box) {
-  if (!box) return;
-
-  var pboxid = box.getAttribute("pboxid");
-  if (!pboxid) return;
-
-  if (pboxid != boxControlsVisible) portalHideControls();
-
-  var controls = xGetElementById("PortalBoxMoveButtons"+pboxid);
-
-  if (!controls) return;
-
-  xVisibility(controls, true);
-
-  boxControlsVisible = pboxid;
-}
-
-function portalHideControls () {
-  if (!boxControlsVisible) return;
-
-  var boxes = DOM.filterElementsByClassName(document.getElementsByTagName("div"), "PortalBox");
-  if (!boxes.length) return;
-
-  for (var i=0; i<boxes.length; i++) {
-    var box = boxes[i];
-    if (!box) return;
-
-    var pboxid = box.getAttribute("pboxid");
-    if (!pboxid) return;
-
-    var controls = xGetElementById("PortalBoxMoveButtons"+pboxid);
-
-    if (!controls) return;
-
-    xVisibility(controls, false);
-  }
-
-  boxControlsVisible = null;
-}
-
-// set up some events
-function portalRegEvent (target, evt, func) {
-  if (! target)
-    return;
-
-  if (target.attachEvent)
-    target.attachEvent("on"+evt, func);
-  if (target.addEventListener)
-    target.addEventListener(evt, func, false);
-}
-
-if (document.getElementById) {
-  portalRegEvent(window, "load", setupPortal);
-  portalRegEvent(document, "click", portalDoClick);
-}
diff -r 1e10c8cffe6c -r 981e9adf07eb htdocs/portal/alter.bml
--- a/htdocs/portal/alter.bml	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-<?_code
-
- $title = "";
- $body = "";
-
- my $remote = LJ::get_remote();
- 
- unless ($remote) { $body = "<?needlogin?>"; return; }
-
- my $op = $FORM{'op'};
- my $t = $FORM{'t'};
- my ($bname, $loc, $pos) = split(/-/, $t);
- $pos += 0;
-
- my $portopts = LJ::Portal::load_portopts($remote);
- 
- if ($op eq "x")
- {
-     LJ::Portal::delete_box($portopts, $loc, $pos, $bname);
-     LJ::Portal::save_portopts($remote, $portopts);
-     if ($loc eq "moz") {
-         return BML::redirect("$LJ::SITEROOT/portal/moz");
-     } else {
-         return BML::redirect("$LJ::SITEROOT$LJ::PORTAL_URI");
-     }
- }
-
- if ($op eq "u" || $op eq "d")
- {
-     LJ::Portal::move_box($portopts, $loc, $pos, $bname, $op);
-     LJ::Portal::save_portopts($remote, $portopts);
-     if ($loc eq "moz") {
-         return BML::redirect("$LJ::SITEROOT/portal/moz");
-     } else {
-         return BML::redirect("$LJ::SITEROOT$LJ::PORTAL_URI");
-     }
- }
-
- if ($op eq "a")
- {
-     $title = "Customize Homepage";
-     
-     $body .= "<?h1 Welcome! h1?>";
-     $body .= "<?p By clicking the little plus sign on the main page you can do several things.  You can change the settings for the box you clicked, you can add a new box, or you can reset your settings back to the default. p?>";
-
-     $body .= "<?h1 Change Box Settings h1?>";
-     $body .= "<?p Change the settings for the box you just clicked:<ul>\n";
-     {
-         my $modform = LJ::Portal::make_box_modify_form($portopts, $loc, $pos);
-         if ($modform) {
-             $body .= $modform;
-         } else {
-             $body .= "<i>No options for this box.</i>";
-         }
-     }
-     $body .= "</ul> p?>";
-     
-     $body .= "<?h1 Add New Box h1?><?p You can create a new box to show on the main page:<ul>";
-     foreach my $loc (@LJ::PORTAL_COLS)
-     {
-         $body .= "<form method='post' action='alter'>";
-         $body .= LJ::html_hidden("op", "addnew",
-                                  "loc", $loc);
-         $body .= "<p><b>$LJ::Portal::colname{$loc}</b><br>";
-         $body .= LJ::html_select({ 'name' => "bname",
-                                    'noescape' => 1,
-                                  },
-                                  "", "(Pick Box Type)",
-                                  LJ::Portal::get_box_types($loc));
-         $body .= " <input type=submit value=\"Proceed --&gt;\"></form>";
-     }
-     $body .= "</ul> p?>";
-     return;
- }
-
- if ($op eq "addnew") 
- {
-     my $bname = $FORM{'bname'};
-     my $loc = $FORM{'loc'};
-
-     my $pos = LJ::Portal::create_new_box($portopts, $bname, $loc);
-     LJ::Portal::save_portopts($remote, $portopts);
-     
-     my $modform =  LJ::Portal::make_box_modify_form($portopts, $loc, $pos);
-     if ($modform) 
-     {
-         $title = "Configure Box";
-         $body .= $modform;
-         return;
-     } 
-     else
-     {
-         if ($loc eq "moz") {
-             $op = "mozadd";
-         } else {
-             return BML::redirect("$LJ::SITEROOT$LJ::PORTAL_URI");
-         }
-     }
- }
-
- if ($op eq "modbox")
- {
-     my $newargs = LJ::Portal::modify_box($remote, $portopts, $FORM{'loc'}, $FORM{'pos'}, \%FORM);
-     if ($FORM{'loc'} eq "moz") {
-         $op = "mozadd";
-     } else {
-         return BML::redirect("$LJ::SITEROOT$LJ::PORTAL_URI");
-     }
- }
-
- ## add sidebar to mozilla
- if ($op eq "mozadd")
- {
-     $title = "Add Mozilla Sidebar";
-     $body = "If you're running Mozilla or Netscape &gt;= 6.0 you can click the link below to add this LJ portal box to your Mozilla sidebar.  If you're using Internet Explorer, sorry.<p>";
-     $body .= "<ul>";
-
-     $body .= "<a href=\"javascript:sidebar.addPanel('$LJ::SITENAME','$LJ::SITEROOT/portal/moz','')\"><b>&lt;--- Add $LJ::SITENAME Mozilla Sidebar</b></a>";
-     $body .= "</ul>";
-     $body .= "If you just added a new box to the sidebar or changed a setting and the $LJ::SITENAME sidebar is already open, hit the reload link in the sidebar.";
-     return;
- }
-
- return;
-
-_code?><?page
-title=><?_code return $title; _code?>
-body=><?_code return $body; _code?>
-page?>
diff -r 1e10c8cffe6c -r 981e9adf07eb htdocs/portal/box.bml
--- a/htdocs/portal/box.bml	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-<?_code
-
- my $remote = LJ::get_remote();
-
- $title = "Mozilla sidebar";
- $body = "";
- $head = "";
- $bodyopts = "";
-
- my $opts = { 'body' => \$body,
-              'head' => \$head,
-              'bodyopts' => \$bodyopts,
-              'remote' => $remote,
-          };
- 
- LJ::Portal::make_mozilla_box($remote, \%FORM, $opts);
-
- return "<html><head>$head<title>$title</title><body marginwidth=0 marginheight=0 $bodyopts><base target=_content>$body</body></html>";
-
-_code?>
diff -r 1e10c8cffe6c -r 981e9adf07eb htdocs/portal/get.bml
--- a/htdocs/portal/get.bml	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-<?_code
-{
-    use strict;
-    use vars qw(%FORM $head $body);
-    use LJ::Portal::Config;
-
-    my $remote = LJ::get_remote();
-
-    unless ( LJ::is_enabled('portal', $remote) ) {
-        $body = 'Sorry, the portal is disabled at this time.';
-        return;
-    }
-
-    # browser caching causes lots of issues
-    $head = '<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">';
-
-    if (!$remote) {
-        $body = "Sorry, you must be <a href=\"$LJ::SITEROOT/login\">logged in</a> and have cookies enabled to use your modules.";
-        return;
-    }
-
-    # include the default style:
-    LJ::need_res('stc/portal/MainStyle.css');
-    # javascript crap
-    LJ::need_res('js/x/x_core.js');
-    LJ::need_res('js/x/x_dom.js');
-    LJ::need_res('js/portal.js');
-    LJ::need_res('js/x/x_event.js');
-    LJ::need_res('js/commentmanage.js');
-    LJ::need_res('js/dom.js');
-    LJ::need_res('js/core.js');
-    LJ::need_res('js/hourglass.js');
-
-    # get the current scheme and load the correct style
-    my $scheme = BML::get_scheme();
-    if ($scheme eq 'dystopia' && -e "$LJ::HOME/htdocs/stc/portal/Dystopia.css") {
-        LJ::need_res('stc/portal/Dystopia.css');
-    } elsif (-e "$LJ::HOME/htdocs/stc/portal/XColibur.css") {
-        LJ::need_res('stc/portal/XColibur.css');
-    }
-
-    #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-    # this is the url to do XML HTTP posts to
-    my $selflink = $LJ::SITEROOT . BML::get_uri();
-    $selflink =~ s/\?.*//;
-
-    # fading special effects?
-    my $doFadeDefault = 1;
-    my $doFade = LJ::is_enabled('portal_fade') && $doFadeDefault;
-
-    # parameters for portal.js
-    $head .= qq{
-        <script language="JavaScript">
-            var Site;
-        if (!Site)
-            Site = new Object();
-        Site.postUrl = "$LJ::SITEROOT/portal/index";
-        Site.doFade = $doFade;
-        Site.doAnimate = 1;
-        Site.imgprefix = "$LJ::IMGPREFIX";
-        </script>
-        };
-
-    my $portalconfig = LJ::Portal::Config->new($remote);
-    return unless $portalconfig;
-
-    my $pboxid = $FORM{'pboxid'}+0;
-    if (!$pboxid) {
-        $body = "No module ID specified.";
-        return;
-    }
-
-    my $box = $portalconfig->get_box_by_id($pboxid);
-    if (!$box) {
-        $body = "No module with ID $pboxid found.";
-        return;
-    }
-
-    $body = $box->generate_content;
-}
-
-#_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
-
-return;
-_code?>
-<html>
-    <head>
-       <?_code return $head; _code?>
-       <?_code return LJ::res_includes; _code?>
-    </head>
-    <body>
-    <?_code return $body; _code?>
-    </body>
-</html>
diff -r 1e10c8cffe6c -r 981e9adf07eb htdocs/portal/ig.bml
--- a/htdocs/portal/ig.bml	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-<?_code
-{
-    use strict;
-    use vars qw(%FORM);
-    use LJ::Portal::Config;
-
-    BML::set_content_type("text/xml");
-
-    my $returncontent = sub {
-        my $error = shift;
-        BML::noparse();
-        return qq {<?xml version="1.0" encoding="UTF-8" ?>
-                <Module>
-                <ModulePrefs title="Error" />
-                <Content type="html">
-                 <![CDATA[
-                         Error: $error
-                 ]]>
-                </Content>
-                </Module>
-            };
-    };
-
-    my $remote = LJ::get_remote();
-
-    unless ( LJ::is_enabled('portal', $remote) ) {
-        return $returncontent->('Sorry, the portal is disabled at this time.');
-    }
-
-    if (!$remote) {
-        return $returncontent->("Sorry, you must be <a href=\"$LJ::SITEROOT/login\">logged in</a> and have cookies enabled to use your modules.");
-    }
-
-    my $portalconfig = LJ::Portal::Config->new($remote);
-    return unless $portalconfig;
-
-    my $pboxid = $FORM{'pboxid'}+0;
-    if (!$pboxid) {
-        return $returncontent->("No module ID specified.");
-    }
-
-    my $box = $portalconfig->get_box_by_id($pboxid);
-    if (!$box) {
-        return $returncontent->("No module with ID $pboxid found.");
-    }
-
-    my $title = $box->box_name;
-
-    BML::noparse();
-    return qq {<?xml version="1.0"?>
-<Module>
-<ModulePrefs title="$title" />
-<Content type="url" href="$LJ::SITEROOT/portal/get?pboxid=$pboxid" />
-</Module>
-    };
-
-}
-
-_code?>
diff -r 1e10c8cffe6c -r 981e9adf07eb htdocs/portal/index.bml
--- a/htdocs/portal/index.bml	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,359 +0,0 @@
-<?_code
-{
-    use strict;
-    use vars qw($title $body $bodyopts $head %GET %POST);
-    use LJ::Portal::Config;
-
-    my $remote = LJ::get_remote();
-
-    unless ( LJ::is_enabled('portal', $remote) ) {
-        $title = 'Disabled';
-        $body = 'Sorry, the portal is disabled at this time.';
-        return;
-    }
-
-    $title = BML::ml('.pagetitle', { 'sitenameabbrev' => $LJ::SITENAMEABBREV });
-    $body = '';
-    $bodyopts = '';
-
-    # browser caching causes lots of issues
-    $head = '<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">';
-
-
-    if (!$remote) {
-        $body = "<?needlogin?>";
-        return;
-    }
-
-    my $returnjs = sub {
-        my $response = shift;
-        BML::set_content_type('text/javascript; charset=utf-8');
-        BML::finish();
-        BML::noparse();
-        return $response;
-    };
-
-    # include the default style:
-    LJ::need_res('stc/portal/MainStyle.css');
-    # lj base css
-    LJ::need_res('stc/lj_base.css');
-    # javascript crap
-    LJ::need_res('js/core.js');
-    LJ::need_res('js/dom.js');
-    LJ::need_res('js/hourglass.js');
-    LJ::need_res('js/x/x_core.js');
-    LJ::need_res('js/x/x_dom.js');
-    LJ::need_res('js/portal.js');
-    LJ::need_res('js/x/x_event.js');
-    LJ::need_res('js/commentmanage.js');
-
-    # get the current scheme and load the correct style
-    my $scheme = BML::get_scheme();
-    if ($scheme eq 'dystopia' && -e "$LJ::HOME/htdocs/stc/portal/Dystopia.css") {
-        LJ::need_res('stc/portal/Dystopia.css');
-    } elsif (-e "$LJ::HOME/htdocs/stc/portal/XColibur.css") {
-        LJ::need_res('stc/portal/XColibur.css');
-    }
-
-    #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-    # this is the url to do XML HTTP posts to
-    my $selflink = $LJ::SITEROOT . BML::get_uri();
-    $selflink =~ s/\?.*//;
-
-    # fading special effects?
-   my $doFadeDefault = 1;
-    my $doFade = LJ::is_enabled('portal_fade') && $doFadeDefault;
-
-    # parameters for portal.js
-    $head .= qq{
-        <script language="JavaScript">
-            var Site;
-        if (!Site)
-            Site = new Object();
-        Site.postUrl = "$selflink";
-        Site.doFade = $doFade;
-        Site.doAnimate = 1;
-        </script>
-        };
-
-    # reset debug output
-    $LJ::PORTAL_DEBUG_CONTENT = '';
-
-    # do profiling? requires siteadmin portal priv
-    my $profile = $GET{'profile'} + 0 && LJ::check_priv($remote, 'siteadmin', 'portal') ;
-    $profile = $profile > 9999999 ? 9999999 : $profile;
-
-    my $portalconfig = LJ::Portal::Config->new($remote, $profile);
-    return unless $portalconfig; # should never happen!
-
-    # if profiling, add debug box
-    $portalconfig->add_box('Debug', 'R') if $profile;
-
-    # see if there was a request to be handled by a module:
-    my $portalboxaction = ($POST{'portalboxaction'} || $GET{'portalboxaction'}) + 0;
-    my $actionbox = $portalconfig->get_box_by_id($portalboxaction);
-
-    # verify it's a action for a valid module
-    if ($portalboxaction && $actionbox && LJ::check_referer('/portal')) {
-        if ($actionbox->can('handle_request')) {
-            my $returncode = $actionbox->handle_request(\%GET, \%POST);
-            return $returnjs->($returncode) if $returncode;
-
-            # if it was a post then return update
-            my $updatescript = LJ::Portal->get_portal_box_update_script($portalconfig, $actionbox);
-            return $returnjs->($updatescript) if $POST{'portalboxaction'};
-        }
-    }
-
-    # super-secret add hidden module URL option:
-    if ($GET{'addmodule'}) {
-        my $module = $GET{'addmodule'};
-        $module =~ s/\W+//g;
-        LJ::Portal->addbox($portalconfig, $module, 'R');
-      }
-
-    # firstly process any box changes:
-    my @actions = ('addbox', 'configbox', 'delbox', 'getmenu', 'movebox',
-                   'resetbox', 'saveconfig', 'updatebox', 'resetalldo');
-
-    for(@actions) {
-
-        # if a POST request then it was an XML HTTP request. Do processing and return
-        # to the client info.
-        # if it was a GET, then the client cannot do XML HTTP requests. Do processing
-        # and display the new page.
-
-        # did they do a POST or GET?
-        my $didpost = $POST{$_} ? 1 : undef;
-        my $didget  = $GET{$_}  ? 1 : undef;
-        my $action  = $_;
-
-        if (($didget || $didpost) && LJ::check_referer('/portal')) {
-            # request to create a new box
-            if ($action eq 'addbox') {
-                my $boxtype = $POST{'boxtype'} || $GET{'boxtype'};
-                my $boxcol  = $POST{'boxcol'}  || $GET{'boxcol'};
-
-                my $returncode = LJ::Portal->addbox($portalconfig, $boxtype, $boxcol);
-                return $returnjs->($returncode) if $returncode && $didpost;
-            }
-
-            # request to get a dialog box for configuring box props
-            if ($action eq 'configbox') {
-                my $pboxid = ($POST{'pboxid'} || $GET{'pboxid'}) + 0;
-                my $jsmode = $POST{'jsmode'};
-
-                my ($returncode, $configboxhtml) = LJ::Portal->configbox($pboxid, $portalconfig, $jsmode);
-
-                if ($didget && $configboxhtml) {
-                    # just print out the config box for non-JS people
-                    my $box = $portalconfig->get_box_by_id($pboxid);
-                    if ($box) {
-                        $title = "Configure " . $box->box_name;
-                        $body = $configboxhtml;
-                        my $returnlinktext = BML::ml('.returnlink',
-                                     { 'sitenameabbrev' => $LJ::SITENAMEABBREV });
-                        $body .= "<div class='PortalReturn'><b><a href=\"$LJ::SITEROOT/portal\">$returnlinktext</a></b></div>";
-                    } else {
-                        $title = "Error.";
-                        $body = "Could not load box.";
-                    }
-                    return;
-                }
-
-                return $returnjs->($returncode);
-            }
-            # request to move a box
-            if ($action eq 'movebox') {
-                my $pboxid    = ($POST{'pboxid'}        || $GET{'pboxid'})+ 0;
-                my $boxcol    =  $POST{'boxcol'}        || $GET{'boxcol'};
-                my $boxcolpos = ($POST{'boxcolpos'}     || $GET{'boxcolpos'}) + 0;
-                my $moveUp    =  $POST{'up'}            || $GET{'up'};
-                my $moveDown  =  $POST{'down'}          || $GET{'down'};
-
-                my $returncode = LJ::Portal->movebox($pboxid, $portalconfig, $boxcol,
-                                                     $boxcolpos, $moveUp, $moveDown);
-
-                return $returnjs->($returncode) if $returncode && $didpost;
-            }
-            # request to retreive a config menu
-            if ($action eq 'getmenu') {
-                my $menu = $POST{'menu'} || $GET{'menu'};
-
-                my $returncode = LJ::Portal->getmenu($portalconfig, $menu);
-
-                if ($didpost) {
-                    return $returnjs->($returncode);
-                } else {
-                    if ($menu eq 'addbox') {
-                        $title = 'Add Module';
-                    }
-
-                    $body = $returncode;
-                    my $returnlinktext = BML::ml('.returnlink',
-                                     { 'sitenameabbrev' => $LJ::SITENAMEABBREV });
-                    $body .= "<div class='PortalReturn'><b><a href=\"$LJ::SITEROOT/portal\">$returnlinktext</a></b></div>";
-                    return;
-                }
-            }
-            # reset default box settings
-            if ($action eq 'resetbox') {
-                my $pboxid = ($POST{'pboxid'} || $GET{'pboxid'}) + 0;
-                my $returncode = LJ::Portal->resetbox($pboxid, $portalconfig);
-                return $returnjs->($returncode) if $returncode && $didpost;
-            }
-            # request to save box props
-            # only POST
-            if ($action eq 'saveconfig' && $didpost) {
-                my $pboxid = $POST{'pboxid'} + 0;
-
-                # was this submitted by an actual form instead of a XML
-                # HTTP request? if so then don't return XML.
-                my $realform = $POST{'realform'} + 0;
-
-                # there has got to be a better way to do this instead of passing POST
-                my $returncode = LJ::Portal->saveconfig($portalconfig, $pboxid, $realform, \%POST);
-                return $returnjs->($returncode) if !$realform;
-            }
-            # request to delete a box
-            if ($action eq 'delbox') {
-                my $pboxid = ($POST{'pboxid'} || $GET{'pboxid'}) + 0;
-                my $returncode;
-
-                $returncode = LJ::Portal->delbox($portalconfig, $pboxid);
-                return $returnjs->($returncode) if $didpost && $returncode;
-            }
-            # request to get code to update the contents of a box
-            # only POST
-            if ($action eq 'updatebox' && $didpost) {
-                my $pboxid =  $POST{'pboxid'} + 0;
-                my $box = $portalconfig->get_box_by_id($pboxid);
-                if ($box) {
-                    return $returnjs->(LJ::Portal->get_portal_box_update_script($portalconfig, $box));
-                } else {
-                    return $returnjs->('alert("Box not found.");');
-                }
-            }
-            # reset entire portal?
-            # only POST
-            if ($action eq 'resetalldo' && $didpost && $POST{'resetyes'}) {
-                $portalconfig->reset_all;
-
-                # tell browser to reload now that everything's finished resetting
-                # (if we're using JS)
-                if ($POST{'jsmode'}) {
-                    return $returnjs->( qq {
-                        // reload the page
-                            window.location.href = Site.postUrl;
-                    } );
-                }
-            }
-
-            # make sure we're at /portal/ because of referral checking
-            BML::redirect($selflink);
-        }
-    }
-
-    # create the hidden menu at the top
-    my $configmenu = qq {
-        <span id="PortalConfigMenuBar">
-            <div id="AddPortalMenuButton" class="midalign PortalMenuItem" onclick="return showAddPortalBoxMenu();">
-            <a href="$selflink?getmenu=1&menu=addbox" class="PortalMenuItem">Add Content Module</a></div>
-            </span>
-        };
-
-    # user pressed "reset all"
-    # are they sure?
-    if ($POST{'resetall'}) {
-        my $returnlinktext = BML::ml('.returnlink',
-                                     { 'sitenameabbrev' => $LJ::SITENAMEABBREV });
-        $title = BML::ml('.resetalltitle', { 'sitenameabbrev' => $LJ::SITENAMEABBREV });
-        $body .= qq {
-            <p><?_ml .resetall _ml?></p>
-                <div class="standout">
-            <form action="$selflink" method="POST">
-                <input type="hidden" name="resetalldo" value="1" />
-                <input type="Submit" name="resetyes" value="Yes" />
-                <input type="Submit" name="resetno" value="No" />
-            </form>
-            </div>
-            <b><a href=\"$LJ::SITEROOT/portal\">$returnlinktext</a></b>
-        };
-
-    } elsif ($GET{'mode'} eq 'config') {
-
-        # the config page for non-JS users
-        my $returnlinktext = BML::ml('.returnlink',
-                                     { 'sitenameabbrev' => $LJ::SITENAMEABBREV });
-        $title = BML::ml('.configtitle', { 'sitenameabbrev' => $LJ::SITENAMEABBREV });
-        $body .= "<ul><li><a href=\"$selflink?getmenu=1&menu=addbox\"><?_ml .addbox _ml?></a></li></ul>";
-        $body .= "<b><a href=\"$LJ::SITEROOT/portal\">$returnlinktext</a></b>";
-    } else {
-        $body .= $configmenu;
-
-        $body .= '<div id="PortalContentContainer">';
-
-        # print out each column with boxes
-        my $cols = {};
-        map { $cols->{$_} = 1 if $_ } $portalconfig->get_cols;
-        my $debugbox;
-        foreach my $col (keys %$cols) {
-            next unless $col;
-
-            my @colboxes = $portalconfig->get_col_boxes($col);
-            $body .= "<div id='PortalCol$col'>";
-            foreach my $box (@colboxes) {
-                next unless $box;
-                if ($box) {
-                    # if it's the debug module, generate it last
-                    if ($box->box_class eq 'Debug') {
-                        $debugbox = $box;
-                        next;
-                    }
-
-                    # get the contents of the box
-                    $body .= $portalconfig->generate_box_with_container($box->pboxid);
-                }
-            }
-            $body .= '</div>';
-        }
-
-        # print out columns that didn't have boxes so you can move boxes around
-        for (('L', 'R')) {
-            if (!$cols->{$_}) {
-                $body .= "<div id='PortalCol$_'></div>";
-            }
-        }
-
-        $body .= '<div class="clearing" />&nbsp;</div></div>';
-
-        if ($debugbox) {
-            $body .= "<div style=\"z-index: 5; position: absolute; width: 80%; height: 300; overflow-Y: auto;\"> ";
-            my $debug = $portalconfig->generate_box_with_container($debugbox->pboxid);
-            $body .= $debug;
-            $body .= "</div>";
-        }
-
-        %LJ::PORTAL_PROFILED_BOX = ();
-    }
-}
-
-#_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
-
-return;
-
-_code?><?page
-    title=><?_code return $title; _code?>
-    head<=
-    <?_c TODO: configurable meta tags could go here? _c?>
-    <?_code return $head; _code?>
-    <?_code return (! LJ::get_remote() &&
-                    ! $LJ::IS_SSL &&
-                    ! $LJ::REQ_HEAD_HAS{'chalresp_js'}++) ?
-    $LJ::COMMON_CODE{'chalresp_js'} : "";
-_code?>
-    <=head
-    bodyopts=><?_code return $bodyopts; _code?>
-    body=><?_code return $body; _code?>
-    page?>
diff -r 1e10c8cffe6c -r 981e9adf07eb htdocs/portal/index.bml.text
--- a/htdocs/portal/index.bml.text	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-;; -*- coding: utf-8 -*-
-.addbox=Add a module
-
-.configtitle=Configure My [[sitenameabbrev]] Options
-
-.pagetitle=My [[sitenameabbrev]]
-
-.resetall=Are you sure you want to reset all your portal modules to their default settings?
-
-.resetalltitle=Reset?
-
-.returnlink=Return to My [[sitenameabbrev]]
-
diff -r 1e10c8cffe6c -r 981e9adf07eb htdocs/portal/moz.bml
--- a/htdocs/portal/moz.bml	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-<?_code
-
- my $remote = LJ::get_remote();
-
- $title = "Mozilla sidebar";
- $body = "";
- $head = "";
- $bodyopts = "";
-
- my $opts = { 'body' => \$body,
-              'head' => \$head,
-              'bodyopts' => \$bodyopts,
-              'remote' => $remote,
-          };
- 
- LJ::Portal::make_mozilla_bar($remote, \%FORM, $opts);
-
- return "<html><head>$head<title>$title</title><body marginwidth=2 marginheight=2 $bodyopts><base target=_content><center><font size=-1><a href=\"$LJ::SITEROOT/\">$LJ::SITENAME</a><br>(<a target=_self href=\"javascript:location.reload(true)\">Reload</a> | <a href=\"$LJ::SITEROOT/portal/alter?op=a\">Add Box</a>)</font><br>$body</body></html>";
-
-_code?>
diff -r 1e10c8cffe6c -r 981e9adf07eb htdocs/portal/selectmodule.bml
--- a/htdocs/portal/selectmodule.bml	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-<?_code
-{
-    use strict;
-    use vars qw(%FORM $head $body);
-    use LJ::Portal::Config;
-
-    my $remote = LJ::get_remote();
-
-    unless ( LJ::is_enabled('portal', $remote) ) {
-        $body = 'Sorry, the portal is disabled at this time.';
-        return;
-    }
-
-    # browser caching causes lots of issues
-    $head = '<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">';
-
-    if (!$remote) {
-        $body = "Sorry, you must be <a href=\"$LJ::SITEROOT/login\">logged in</a> and have cookies enabled to use your modules.";
-        return;
-    }
-
-    # include the default style:
-    LJ::need_res('stc/portal/MainStyle.css');
-    # javascript crap
-    LJ::need_res('js/x/x_core.js');
-    LJ::need_res('js/x/x_dom.js');
-    LJ::need_res('js/portal.js');
-    LJ::need_res('js/x/x_event.js');
-    LJ::need_res('js/commentmanage.js');
-    LJ::need_res('js/dom.js');
-    LJ::need_res('js/core.js');
-    LJ::need_res('js/hourglass.js');
-
-    # get the current scheme and load the correct style
-    my $scheme = BML::get_scheme();
-    if ($scheme eq 'dystopia' && -e "$LJ::HOME/htdocs/stc/portal/Dystopia.css") {
-        LJ::need_res('stc/portal/Dystopia.css');
-    } elsif (-e "$LJ::HOME/htdocs/stc/portal/XColibur.css") {
-        LJ::need_res('stc/portal/XColibur.css');
-    }
-
-    #-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-    # this is the url to do XML HTTP posts to
-    my $selflink = $LJ::SITEROOT . BML::get_uri();
-    $selflink =~ s/\?.*//;
-
-    # fading special effects?
-    my $doFadeDefault = 1;
-    my $doFade = LJ::is_enabled('portal_fade') && $doFadeDefault;
-
-    # parameters for portal.js
-    $head .= qq{
-        <script language="JavaScript">
-            var Site;
-        if (!Site)
-            Site = new Object();
-        Site.postUrl = "$LJ::SITEROOT/portal/index";
-        Site.doFade = $doFade;
-        Site.doAnimate = 1;
-        Site.imgprefix = "$LJ::IMGPREFIX";
-        </script>
-        };
-
-    my $portalconfig = LJ::Portal::Config->new($remote);
-    return unless $portalconfig;
-
-    my $boxes = $portalconfig->get_boxes;
-    unless (scalar keys %$boxes) {
-        $body = 'You have no modules defined.';
-        return;
-    }
-
-    $body .= '<table cellpadding="2" border="1">';
-
-    foreach my $pboxid (keys %$boxes) {
-        my $box = $boxes->{$pboxid};
-        my $classname = $box->box_class || '';
-        $body .= qq {
-            <tr>
-            <td>
-                <div class="PortalBox PortalBoxContent $classname">
-                    } . $box->generate_content . qq {
-                </div>
-            </td>
-            <td>
-                <div><a href="get?pboxid=$pboxid">Module Link</a></div>
-                <div><a href="ig?pboxid=$pboxid">ig</a></div>
-            </td>
-            </tr>
-        };
-    }
-
-    $body .= '</table>';
-
-    return;
-}
-
-#_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
-
-return;
-_code?>
-<html>
-    <head>
-       <?_code return $head; _code?>
-       <?_code return LJ::res_includes; _code?>
-    </head>
-    <body>
-    <?_code return $body; _code?>
-    </body>
-</html>
diff -r 1e10c8cffe6c -r 981e9adf07eb htdocs/stc/portal/Dystopia.css
--- a/htdocs/stc/portal/Dystopia.css	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,207 +0,0 @@
-/* The default color scheme for Dystopia.                     */
-
-
-/*-------------------- Configuration Menus -------------------*/ 
- 
-.DropDownMenu {
-	background-color: #FFF;
-	border: 2px solid #c1272c;
-	}
-	
-.BoxDescription {
-	background-color: #fff;
-	}
-	
-.DropDownMenuContent table tbody tr td a:link {
-	color: #336699;
-	}
-	
-.DropDownMenuContent table tbody tr td {
-	color: #666;
-	}
-	
-.PortalFenster {
-	border: 2px solid #c1272c;
-	background-color: #fff;
-	}
-	
-.PortalPatternedTitleBar {
-	background-color: #336699;
-	}
-	
-.PortalBoxTitleBar {
-	background-color: #336699;
-	color: #fff;
-	}
-	
-.PortalPatternedTitleBar span {
-	color: #fff !important;
-	}
-	
-.PortalTitleBarText {
-	color: #fff;
-	}
-
-.PortalFensterContent {
-	color: #000;
-	}
-	
-.PortalConfigSubmitButtons {
-	background-color: #ccc;
-	border: 1px solid #999;
-	}
-	
-.PortalConfigResetButton a:link {
-	color: #fff;
-	}
-	
-.PortalConfigResetButton a:hover {
-	color: #666;
-	}
-	
-.PortalBoxContent a:link, .PortalBoxContent a:visited {
-	color: #000066 !important;
-	}
-	
-.PortalMenuRow1, .PortalMenuRow2 {
-	background: #336699;
-	}
-
-.PortalMenuRow1:hover, .PortalMenuRow2:hover {
-	background: #cc6600 !important;
-	}
-	
-.PortalMenuRow1 a, .PortalMenuRow2 a {
-	color: #fff !important;
-	}
-	
-.PortalMenuRow1 a:hover, .PortalMenuRow2 a:hover {
-	color: #fff !important;
-	}
-	
-#AddPortalMenuButton {
-    background: #336699 url(http://pics.livejournal.com/veroz/pic/00051xwq) no-repeat 4% 50% !important;
-	}
-	
-#AddPortalMenuButton:hover {
-    background-color: #c1272c !important;
-    }
-
-#PortalResetAllButton {
-	background: #CCC;
-	border: 1px solid #AAA;
-	}
-
-	
-
-/*------------------ End Configuration Menus -----------------*/
-/*------------------------------------------------------------*/
- 
- 
- 
-/*------------------ General Module Styling ------------------*/
-
-.PortalBox {
-	border: 1px solid #ccc;
-	border-bottom: 2px solid #bbb;
-	border-right: 1px solid #ccc;
-	}
-	
-.PortalBoxContent {
-	background-color: #fff;
-	}
-	
-.PortalBoxContent a:link, .PortalBoxContent a:visited {
-	color: #336699;
- 	}
-  
-.PortalBoxContent a:hover {
-	color: #c1272c;
-	}
-	
-
- /*---------------- End General Module Styling ----------------*/ 
- /*------------------------------------------------------------*/
- 
- 
- 
- 
- /*------------------ Specific Module Stylings ------------------*/
- /*																 */
- /*                This is where the magic happens.				 */
- /*																 */
- /*--------------------------------------------------------------*/
- 
-
-
-/*----------------------- Account Management --------------------*/
-
- .Manage table a {
-	border-left: 3px solid #336699;
-	}
-	
-/*------------------------- Announcements -----------------------*/
-
-.PortalTableHeader td {
-	background-color: #4284c6 !important;
-	color: #fff !important;
-	}
-	
-.Announcements table tbody tr td {
-	color: #000;
-	}
-	
-.AnnouncementRow1 {
-	background-color: #fff;
-	}
-	
-.PortalRow2 td {
-	border: 1px solid #dfecfa;
-	}
-
-.PortalRow1 td {
-	border: 1px solid #dfecfa;
-	}
-
-.PortalRow1:hover, .PortalRow2:hover {
-	background-color: #9bc9f6;
-	}
-	
-.AnnouncementRow1:hover a, .AnnouncementRow2:hover a {
-	color: #fff;
-	}
-	
- 
-/*----------------------- Recent Comments ----------------------*/
- 
- .RecentCommentTitle {
- 	color: #c1272c;
- 	}
- 	
- .RecentCommentDate {
- 	color: #ccc;
- 	}
- 	
- .RecentCommentItem {
- 	background-color: #fff;
- 	color: #c1272c;
- 	border: 1px solid #dfecfa;
- 	}
- 	
- .RecentCommentLinks {
- 	color: #fff;
- 	background-color: #dfecfa;
- 	}	
-	
-/*------------------------ Account Status -------------------------*/
-	
-.standout table {
-	background-color: #fff !important;
-	border: 0px solid !important;
-}
-
-/*------------------------- Friends Page --------------------------*/
-
-.PortalFriendsPageEntry {
-	color: #333;
-	}
\ No newline at end of file
diff -r 1e10c8cffe6c -r 981e9adf07eb htdocs/stc/portal/MainStyle.css
--- a/htdocs/stc/portal/MainStyle.css	Wed Aug 05 07:06:56 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,557 +0,0 @@
-/* The default portal stylesheet. By Mischa Spiegelmock, 2005
-   featuring added sexiness by Andy Mai.                      
-
-   This is the main global stylesheet for portal. It contains
-   all the layout, positioning, and font attributes.          */
-
-
-
-/*--------------------------- Global -------------------------*/
-
-#PortalColL {
-	width: 68%;
-	float: left;
-	margin: 0px;
-  	}
-
-#PortalColR {
-	width: 30%;
-	float: right;
-	margin: 0px;
-	}
-
-img {
-	border: 0px;
-  	}
-  
-#Content h1 {
-	}
-	
-#Content {
-    width: 93% !important;
-    margin-left: auto !important;
-    margin-right: auto !important;
-    }
-
-#PortalContentContainer {
-    font-size: 12px;
-    clear: both;
-    }
-
-.PortalFaqLink {
-    display: inline;
- 	}
-
-.LoadingText {
-    vertical-align: middle;
-    font-size: xx-large;
-    font-weight: bold;
-    font-family: Arial, Verdna;
-    text-align: center;
-	}
-
-.LoadingBox {
-    width: 100%;
-    height: 100%;
-	}
-	
-#PortalAdBox {
-    float: right;
-    height: 120px;
-    width: 728px;
-    margin: 0px;
-    }
-
-/*------------------------ End Global ------------------------*/
-/*------------------------------------------------------------*/
- 
- 
- 
- 
-/*-------------------- Configuration Menus -------------------*/ 
- 
-.DropDownMenu {
-	z-index: 2;
-	position: absolute;
-	margin-left: 273px;
-	overflow: hidden;
-	display: none;
-	padding: 0px;
-	width: auto;
-	max-width: 400px;
-	_width: 400px;
-	}
-	
-.DropDownMenu br {
-	display: none;
-	}
-	
-.BoxDescription {
-	padding: 5px 10px 5px 10px;
-	font-style: italic;
-	}
-	
-.DropDownMenuContent {
-	margin: 0;
-	}
-	
-.DropDownMenuContent table tbody tr td a:link {
-	display: block;
-	width: 100%;
-	font-weight: bold;
-	text-decoration: none;
-	}
-	
-.DropDownMenuContent table br {
-	display: none;
-	}
-	
-.DropDownMenuContent table tbody tr td {
-	margin: 0px;
-    padding: 0px;
-	}
-	
-.PortalFenster {
-	padding: 2px;
-	margin: 0px;
-	z-index: 1;
-	position: absolute;
-	width: 320px;
-	height: auto;
-	}
-
-.PortalFenster img {
-	_margin-top: -15px;
-	float: right;
-	}
-	
-.PortalPatternedTitleBar {
-	display: table;
-	width: 100%;
-	_margin-right: 1px;
-	padding: 2px 0px 2px 2px;
-	}
-	
-.PortalBoxTitleBar {
-	display: table;
-	width: 100%;
-	padding: 2px;
-	height: 15px;
-	}
-
-.PortalPatternedTitleBar span {
-	display: table-cell;
-	vertical-align: middle;
-	padding: 0px;
-	font-weight: bold;
-	font-family: Arial, Verdana, sans-serif;
-	}
-	
-.PortalResetAllButton {
-	float: right;
-	padding: 0;
-	}
-
-.PortalFensterContent {
-	padding: 0px;
-	width: 318px;
-	_width: 320px;
-	font-size: smaller;
-	}
-	
-.PortalBoxConfigContent {
-	height: auto;
-	_height: 200px;
-	max-height: 200px;
-	overflow: auto;
-	margin-top: 2px;
-	}
-	
-.PortalBoxConfigContent table {
-	width: 100%
-	}
-	
-.PortalBoxConfigContent div {
-	padding: 2px;
-	}
-	
-.PortalConfigSubmitButtons {
-	display: block;
-	margin-top: 2px;
-	margin-bottom: 0px;
-	width: 318px;
-	padding: 0px;
-	}
-	
-.PortalConfigResetButton {
-	vertical-align: middle;
-	text-decoration: none;
-	float: right;
-	margin: 0;
-	font-weight: bold;
-	}
-
-.PortalFensterResButton {
-	display: none;
-	}
-
-.PortalFensterBarMaxButton {
-	display: none;
-	}
-
-#PortalConfigMenuBar { 
-    float: left;
-    margin: 0 0 10px 0;
-	}
-
-#AddPortalMenuButton {
-	text-align: right;
-    margin: 10px -4px 15px 0;
-    background: #f4717a url(http://pics.livejournal.com/veroz/pic/00051xwq) no-repeat 4% 50%;
-    width: 125px;
-    padding: 3px;
-	}
-	
-#AddPortalMenuButton a:link, #AddPortalMenuButton a:visited {
-    text-decoration: none;
-    font-weight: bold;
-    color: #fff;
-    font-size: smaller;
-    }
-
-/*------------------ End Configuration Menus -----------------*/
-/*------------------------------------------------------------*/
- 
- 
- 
-/*------------------ General Module Styling ------------------*/
-
-.PortalBox {
-	width: 100%;
-	margin-bottom: 10px;
-	overflow: hidden;
-	padding: 1px !important;
-	}
-	
-.PortalBoxIcon {
-        vertical-align: middle;
-        width: 15px;
-        height: 15px;
-        display: none;
-	}
-	
-.PortalBoxTitleText {
-	display: table-cell;
-	vertical-align: middle;
-	position: static;
-	font-weight: bold;
-	font-family: arial, verdana, sans-serif;
-	padding: 0 0 0 5px;
-	_width: 120px;
-	}
-
-.PortalBoxTitleText a, .PortalBoxTitleText a:visited, .PortalBoxTitleText a:link, .PortalBoxTitleText a:active {
-        color: #FFFFFF;
-}
-
-.PortalBoxMoveButtons {
-        display: inline;
-        float: right;
-        width: 115px;
-        margin-right: 2px;
-        visibility: hidden;
-}
-* html .PortalBoxMoveButtons {
-    margin-top: -16px; /* Lame IE6 hack to fix positioning -- need to find a better workaround */
-}
-*:first-child+html .PortalBoxMoveButtons {
-    margin-top: -16px; /* Lame IE7 hack to fix positioning -- need to find a better workaround */
-}
-
-.PortalBoxMoveButtons a {
-	float: right;
-	margin-left: 2px;
-	}
-	
-.PortalBoxMoveButtons:hover {
-	visibility: visible;
-	}
-	
-.PortalBoxContent {
-	font-family: Verdana, Arial, san-serif !important;
-	padding: 2px;
-	width: 100%;
-	margin: 0 auto;
-	}
-	
-.PortalBoxContent a:link, .PortalBoxContent a:visited {
-	font-size: 12px !important;
-	text-decoration: none;
- 	}
-
-.PortalBoxContent a:hover {
-	font-size: 12px !important;
-	text-decoration: underline;
- 	}
-	
-
- /*---------------- End General Module Styling ----------------*/ 
- /*------------------------------------------------------------*/
- 
- 
- 
- 
- /*------------------ Specific Module Stylings ------------------*/
- /*																 */
- /*                This is where the magic happens.				 */
- /*																 */
- /*--------------------------------------------------------------*/
- 
- 
- /*------------------------ Update Journal ----------------------*/
- 
- .UpdateBoxSubject {
- 	width: 99%;
- 	}
- 	
- .UpdateBoxEvent {
- 	width: 99%;
- 	}
- 
-.UpdateJournal table {
-	background-color: #dfdfdf;
-	border: 1px outset #000;
-	width: 99%;
-	}
-	
-.UpdateJournal table td {
-	font-weight: bold;
-	}
-
-.UpdateJournal table br {
-	display: none;
-	}
-	
-/*--------------- Account Management (Quick Links) --------------*/
-
- .Manage table a {
-	line-height: 125%;
-	margin-left: 20px;
-	}
-	
-/*------------------------- Announcements -----------------------*/
-
-.Announcements {
-	padding: 1px 0px 0px 0px !important;
-	}
-	
-.PortalTableHeader td {
-	padding: 2px;
-	font-size: smaller !important;
-	font-weight: bold !important;
-	text-transform: uppercase;
-	}
-	
-.Announcements table {
-	width: 100%;
-	}
-	
-.Announcements table tbody tr td {
-	padding: 3px;
-	border-spacing: 0;
-	border-collapse: separate;
-	}
-	
-.ljuser a:link {
-	display: inline !important;
-	}
-	
-.Announcements table tbody tr td a:link {
-	display: block;
-	width: 100%;
-	}
-	
- 
-/*----------------------- Recent Comments ----------------------*/
-
- .RecentCommentTitle {
- 	font-weight: bold;
- 	}
- 	
- .RecentCommentSubject {
-    font-weight: bold;
-    }
-
- .RecentCommentDate a:link, .RecentCommentDate a:visited {
- 	font-size: xx-small !important;
- 	color: #666 !important;
- 	}
-
- .RecentCommentItem {
-    font-size: 90%;
- 	font-style: italic;
- 	padding: 0px;
- 	margin-top: -15px;
- 	}
- 	
- .RecentCommentBody {
-    padding: 5px;
-    font-style: normal;
-    }
-    
- .RecentCommentLinks {
- 	padding: 2px 5px 2px 2px;
- 	text-align: right;
- 	color: #ccc;
- 	font-size: x-small;
- 	}
- 	
- .RecentCommentLinks a:link, .RecentCommentLinks a:visited {
- 	font-size: x-small !important;
- 	font-style: normal;
- 	color: #666 !important;
- 	}
-
- /*------------------------ PopWithFriends ---------------------*/
- 
- .PopWithFriends {
- 	padding: 3px;
- 	}
- 	
- .PopWithFriends table td {
- 	text-align: left;
- 	}
- 	
- 
- 	
- /*------------------------- Text Message -----------------------*/
- 
-.TextMessage {
-	padding: 3px;
-	}
-	
-.TextMessage input {
-	display: inline;
-	}
-	
-.TextMessageDisclaimer {
-	font-size: smaller;
-	margin-top: 3px;
-	}
-	
- /*--------------------------- New User --------------------------*/
- 
- .NewUserBlurb {
- 	font-size: small !important;
- 	font-style: italic;
- 	}
- 	
- .NewUserMoreLink {
- 	display: block;
- 	text-align: right;
- 	width: 99%;
- 	}
- 	
- .NewUser {
- 	padding: 5px 5px 5px 5px;
- 	}
- 	
- /*---------------------------- Frank -----------------------------*/
- 
-.Frank img {
-	display: block;
-	margin-left: auto;
-	margin-right: auto;
-	}
- 	
-/*------------------------ Manage Friends -------------------------*/
-  
-	
-.FriendsList br {
-	display: none;
-	}
-  
-.FriendsCurrentTitle {
-  	font-size: smaller !important;
-  	font-weight: bold !important;
-  	margin-bottom: 5px;
-  	}
-  	
-.FriendsList {
-	margin-bottom: 10px;
-	}
-	
-/*------------------------ Account Status -------------------------*/
-	
-.standout table {
-	width: 100% !important;
-	}
-
-
-/*------------------------- Friends Page --------------------------*/
-
-.FriendsPage {
-    width: 99%;
-    }
-    
-.PortalFriendsPageUserpic {
-    float: left;
-    }
-
-.FriendsPageTitle {
-	font-weight: bold;
-	margin-bottom: 5px;
-	}
-	
-.FriendsPageEntry {
-	_height: 300px;
-	max-height: 300px;
-	overflow-y: scroll;
-	overflow-x: hidden;
-	overflow: scroll;
-	}
-	
-.PortalFriendsPageEntry {
-    margin-top: 15px;
-    }
-	
-.PortalFriendsPageSubject {
-	font-weight: bold;
-	}
-	
-.PortalFriendsPageLinks {
-    padding: 5px 5px 5px 2px;
-    font-size: x-small;
-    color: #ccc;
-	margin-bottom: 10px;
-	padding-right: 5px;
-	}
-	
-.PortalFriendsPageLinks a:link, .PortalFriendsPageLinks a:visited {
- 	font-size: x-small !important;
- 	font-style: normal;
- 	color: #666 !important;
-    }
-
-.PortalFriendsPagePoster {
-    margin: 0px;
-    padding: 0px;
-    vertical-align: bottom;
-    }
-	
-/*----------------------- Friends Birthdays -----------------------*/
-	
-.Birthdays table td {
-	text-align: left;
-	}
-
-/*----------------------- CProd             -----------------------*/
-
-.CProd .CProd_box_content {
-        width: 100% !important;
-}
-
-.ESN_Links {
-	text-align: right;
-	margin-right: 5px;
-	}
--------------------------------------------------------------------------------

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org