--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/GPL Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,131 @@
+Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+== Preamble ==
+
+The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too.
+
+When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification follow.
+
+== Terms and conditions for copying, distribution and modification ==
+
+0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
+
+1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
+
+* You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
+* You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
+* If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
+
+3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
+
+* Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
+* Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
+* Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
+
+If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
+
+5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
+
+This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
+
+9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
+
+== No Warranty ==
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+
+== How to Apply These Terms to Your New Programs ==
+
+If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/KNOWN_BUGS Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,75 @@
+Enano 1.0RC2 - Known Issues and Bugs
+---------------------------------------------------------------------
+
+In the Javascripted Access Control List editor, the text "on this
+page" appears at the top of the editor window, even if the user
+selected that the rule affect the entire site. This does not affect
+the behavior of the rule; it will still affect the entire site. This
+bug has been fixed in upstream.
+
+The Javascripted ACL editor currently is not supported in Internet
+Explorer. The safe (non-JS) version of the editor is used instead.
+There is no planned fix for this, the workaround is to use Firefox.
+
+On seemingly random occasions, the "more options" menu on some pages
+does not show when the mouse is hovered over it. The only known
+workaround at this point is to reload the page. The bug seems to be
+more prevalent on Windows systems.
+
+The RenderMan class is in a state of transition - the wikiFormat
+method is unchanged but a new next_gen_wiki_format method has been
+added. The new method is parameter-incompatible with the old
+wikiFormat, so developers should continue to use wikiFormat for the
+time being. This transition will be finalized in Banshee.
+
+The Moderators group never got included in the schema. Whoops...
+To create it just create a group as normal in the admin panel and
+MAKE SURE IT HAS group_id 3! If it doesn't then do a manual SQL
+query to set it to group_id 3. This will be fixed in the gold
+release for sure.
+
+The search box is visually distorted. The cause of this is not known.
+
+The Links sidebar block is empty by default. Want to contribute some
+filler HTML that doesn't suck? Be my guest!
+
+The files table is borked. I don't know how or why, but somehow the
+updated structure apparently didn't make it into RC1 OR RC2. This
+applies ONLY to installations, and not upgrades. Fixed in 1.0.
+
+It is possible to inject PHP into pages by using the <?php and ?>
+tags as normal, even when not logged in.
+
+OK, I was only KIDDING on that last one.
+
+
+Enano 1.0RC1 - Known Issues and Bugs
+---------------------------------------------------------------------
+
+First and foremost, changing a user's password, either from the
+preferences page or the admin panel, DOES NOT work. The password
+reset feature is working properly. A fix for this issue will be
+included in RC2 (Clurichaun).
+
+The Javascripted ACL editor currently is not supported in Internet
+Explorer. The safe (non-JS) version of the editor is used instead.
+
+Uploaded files are checked based on their extension, not with a
+MIME magic file like they used to be. Depending on what kind of
+feedback I get, I can re-enable FileInfo support. Much of the code
+is already there, just commented out.
+
+Setting up Enano on servers running IIS is currently very difficult,
+but it is doable. Make sure that you use a newer version of PHP (5.x)
+because PHP4 has some issues with the MySQL client library.
+
+Reverting file creation doesn't work. Need to rewrite rollback code
+for the files table.
+
+There's more. I can't think of it right now, but the bugs are there.
+If you find anything, please report it on
+http://bugzilla.enanocms.org.
+
+(Note - the bug tracker itself is still being set up, so that might
+not work either)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TODO Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,74 @@
+Enano Banshee - TODO
+------------------------------------------
+
+[ ] COPPA compliance
+[x] Add in Moderators group
+ [x] Create default ACL rule for mods
+[x] Fix invalid HTML in SF.net logo
+[ ] Clean up the wikitext parser - a lot. It needs some serious work.
+ We need a way to detect whether the text is mostly HTML, and if
+ so, then leave stuff like automatic adding of <p> and <br /> out
+ of the picture. Continue to parse wikilinks.
+[x] Add a system_group column and if it's set to 1, give (at least) a
+ stern warning before deleting the group. Maybe disable the delete
+ button altogether?
+[x] SQL exporter: fix structure exporting when an auto column is defined
+ and it's a named key (see pun_search_words)
+[x] Possibly add these fields: AIM, Yahoo, MSN, XMPP messenger icons, then homepage, location, occupation, hobbies, allow public e-mail display
+ [ ] Put it in a user_extra table and have an option to enable or disable these fields in the admin panel
+ [Y] Delay until RC3 or Banshee?
+ [ ] When added, put a box on the user page that shows the information
+[x] Fix "this page" bug in ACL editor
+ [x] The problem itself got fixed BUT there seem to be deeper problems related to scope selection
+ This needs to be FIXED and WORKING PERFECTLY in Banshee!
+[x] Change the string shown on a successful re-auth into elevated privileges
+ [x] ...and write a function that converts a numeric userlevel to a string
+[x] Make Special:Login remember parameters (target level, target page) even on auth fail
+
+
+Enano Clurichaun - TODO
+------------------------------------------
+
+[x] Finish rewriting userprefs panel
+ Remaining components:
+ [x] Signature
+ [x] Real name
+[x] When a user's level is set to Moderator or Administrator, automatically add them to the respective group
+[x] Fix de-authentication button in admin panel
+[x] Merge newer artwork into installer; make trademark notices
+[x] Case-insensitive usernames for login
+[x] Mass e-mail function in admin panel
+
+Enano Leprechaun - TODO
+------------------------------------------
+[x] Make a frontend for creating/managing usergroups in the admin panel
+[x] Make a frontend for group mods to add/remove group members in a new special page
+[x] Create ACL editing frontends - preferably a "Manage access" button on every page and in the user admin panel
+ [x] Need no-Javascript version of ACL editor
+[x] Make absolutely everything check for the proper access - do a complete audit of index.php and pageutils.php
+ [x] Also need to check RenderMan::getPage, and require view_source privileges to get pages without wiki
+ formatting or without PHP/HTML code
+ [x] Check permissions for uploaded files and category editing - if the category is protected and the user doesn't have
+ even_when_protected rights, lock down the category from adding/removing articles
+ [x] For this to work, need SessionManager's ability to calculate effective permissions for a page implemented
+[x] Update installation schema to create the default Everyone, Administrators, and Moderators groups and insert the
+ admin user into Moderators and Administrators
+[x] Update the upgrade schema - last point plus add in table creation for e_groups, e_group_members, and e_acl
+[x] AJAX: Access control list editor
+ [x] Write a template parsing class in Javascript
+ [x] Use JSON to transport template data, permission types, etc. to the javascript client
+ [x] Use JSON to send the updated permissions back to the server
+[x] File uploads: Rewrite Special:UploadFile to work with new storage system
+[x] Implement password reset
+[x] Fix empty group bug in javascripted ACL editor
+
+Delayed:
+
+[x] REWRITE Special:Preferences - settle for nothing less than perfect on this one! (DELAYED until RC2 - put password reset issues in known bugs)
+[ ] Implement ACL presets (DELAYED until RC2)
+
+Website-related:
+
+[ ] Enano website: add versioning rules page (like linux: x.y.z: x is major release, y is minor, and z is revision; if y is odd then its a beta)
+[ ] Enano website: create codename tracker page (PARTIALLY DONE)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ajax.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,216 @@
+<?php
+/*
+ * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
+ * Version 1.0 (Banshee)
+ * Copyright (C) 2006-2007 Dan Fuhry
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+ require('includes/common.php');
+
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if(!isset($_GET['_mode'])) die('This script cannot be accessed directly.');
+
+ $_ob = '';
+
+ switch($_GET['_mode']) {
+ case "checkusername":
+ echo PageUtils::checkusername($_GET['name']);
+ break;
+ case "getsource":
+ $p = ( isset($_GET['pagepass']) ) ? $_GET['pagepass'] : false;
+ echo PageUtils::getsource($paths->page, $p);
+ break;
+ case "getpage":
+ // echo PageUtils::getpage($paths->page, false, ( (isset($_GET['oldid'])) ? $_GET['oldid'] : false ));
+ $page = new PageProcessor( $paths->cpage['urlname_nons'], $paths->namespace );
+ $page->send();
+ break;
+ case "savepage":
+ $summ = ( isset($_POST['summary']) ) ? $_POST['summary'] : '';
+ $minor = isset($_POST['minor']);
+ $e = PageUtils::savepage($paths->cpage['urlname_nons'], $paths->namespace, $_POST['text'], $summ, $minor);
+ if($e=='good')
+ {
+ $page = new PageProcessor($paths->cpage['urlname_nons'], $paths->namespace);
+ $page->send();
+ }
+ else
+ {
+ echo 'Error saving the page: '.$e;
+ }
+ break;
+ case "protect":
+ echo PageUtils::protect($paths->cpage['urlname_nons'], $paths->namespace, (int)$_POST['level'], $_POST['reason']);
+ break;
+ case "histlist":
+ echo PageUtils::histlist($paths->cpage['urlname_nons'], $paths->namespace);
+ break;
+ case "rollback":
+ echo PageUtils::rollback( (int)$_GET['id'] );
+ break;
+
+ /*
+ * This is old code and should not be used. It's badly broken and a perfect example of bad database organization.
+
+ case "addcomment":
+ $cc = ( isset($_POST['captcha_code']) ) ? $_POST['captcha_code'] : false;
+ $ci = ( isset($_POST['captcha_id'] ) ) ? $_POST['captcha_id'] : false;
+ if(!isset($_POST['text']) ||
+ !isset($_POST['subj']) ||
+ !isset($_POST['name'])) die('alert(\'Error in POST DATA string, aborting\');');
+ if($_POST['text']=='' ||
+ $_POST['name']=='' ||
+ $_POST['subj']=='') die('alert(\'One or more POST DATA fields was empty, aborting post submission\')');
+ echo PageUtils::addcomment($paths->cpage['urlname_nons'], $paths->namespace, $_POST['name'], $_POST['subj'], $_POST['text'], $cc, $ci);
+ break;
+ case "comments":
+ echo PageUtils::comments($paths->cpage['urlname_nons'], $paths->namespace, ( isset($_GET['action']) ? $_GET['action'] : false ), Array(
+ 'name' => ( isset($_POST['name']) ) ? $_POST['name'] : '',
+ 'subj' => ( isset($_POST['subj']) ) ? $_POST['subj'] : '',
+ 'text' => ( isset($_POST['text']) ) ? $_POST['text'] : ''
+ ));
+ break;
+ case "savecomment":
+ echo PageUtils::savecomment($paths->cpage['urlname_nons'], $paths->namespace, $_POST['s'], $_POST['t'], $_POST['os'], $_POST['ot'], $_POST['id']);
+ break;
+ case "deletecomment":
+ echo PageUtils::deletecomment($paths->cpage['urlname_nons'], $paths->namespace, $_POST['name'], $_POST['subj'], $_POST['text'], $_GET['id']);
+ break;
+ */
+
+ case "comments":
+ $comments = new Comments($paths->cpage['urlname_nons'], $paths->namespace);
+ if ( isset($_POST['data']) )
+ {
+ $comments->process_json($_POST['data']);
+ }
+ else
+ {
+ die('{ "mode" : "error", "error" : "No input" }');
+ }
+ break;
+ case "rename":
+ echo PageUtils::rename($paths->cpage['urlname_nons'], $paths->namespace, $_POST['newtitle']);
+ break;
+ case "flushlogs":
+ echo PageUtils::flushlogs($paths->cpage['urlname_nons'], $paths->namespace);
+ break;
+ case "deletepage":
+ echo PageUtils::deletepage($paths->cpage['urlname_nons'], $paths->namespace);
+ break;
+ case "delvote":
+ echo PageUtils::delvote($paths->cpage['urlname_nons'], $paths->namespace);
+ break;
+ case "resetdelvotes":
+ echo PageUtils::resetdelvotes($paths->cpage['urlname_nons'], $paths->namespace);
+ break;
+ case "getstyles":
+ echo PageUtils::getstyles($_GET['id']);
+ break;
+ case "catedit":
+ echo PageUtils::catedit($paths->cpage['urlname_nons'], $paths->namespace);
+ break;
+ case "catsave":
+ echo PageUtils::catsave($paths->cpage['urlname_nons'], $paths->namespace, $_POST);
+ break;
+ case "setwikimode":
+ echo PageUtils::setwikimode($paths->cpage['urlname_nons'], $paths->namespace, (int)$_GET['mode']);
+ break;
+ case "setpass":
+ echo PageUtils::setpass($paths->cpage['urlname_nons'], $paths->namespace, $_POST['password']);
+ break;
+ case "wikihelp":
+ $html = file_get_contents('http://www.enanocms.org/ajax.php?title=Help:Wiki_formatting&_mode=getpage&nofooters');
+ $html = str_replace('src="/Special', 'src="http://www.enanocms.org/Special', $html);
+ echo '<div class="contentDiv"><h2>Wiki formatting guide</h2>'.$html.'</div>';
+ break;
+ case "fillusername":
+ $name = (isset($_GET['name'])) ? $db->escape($_GET['name']) : false;
+ if(!$name) die('userlist = new Array(); errorstring=\'Invalid URI\'');
+ $q = $db->sql_query('SELECT username,user_id FROM '.table_prefix.'users WHERE username LIKE \'%'.$name.'%\';');
+ if(!$q) die('userlist = new Array(); errorstring=\'MySQL error selecting username data: '.addslashes(mysql_error()).'\'');
+ if($db->numrows() < 1) die('userlist = new Array(); errorstring=\'No usernames found.\'');
+ echo 'var errorstring = false; userlist = new Array();';
+ $i=0;
+ while($r = $db->fetchrow())
+ {
+ echo "userlist[$i] = '".addslashes($r['username'])."'; ";
+ $i++;
+ }
+ $db->free_result();
+ break;
+ case "fillpagename":
+ $name = (isset($_GET['name'])) ? $_GET['name'] : false;
+ if(!$name) die('userlist = new Array(); namelist = new Array(); errorstring=\'Invalid URI\'');
+ $nd = RenderMan::strToPageID($name);
+ $c = 0;
+ $u = Array();
+ $n = Array();
+ for($i=0;$i<sizeof($paths->pages)/2;$i++)
+ {
+ if( (
+ preg_match('#'.preg_quote($name).'(.*)#i', $paths->pages[$i]['name']) ||
+ preg_match('#'.preg_quote($name).'(.*)#i', $paths->pages[$i]['urlname']) ||
+ preg_match('#'.preg_quote($name).'(.*)#i', $paths->pages[$i]['urlname_nons']) ||
+ preg_match('#'.preg_quote(str_replace(' ', '_', $name)).'(.*)#i', $paths->pages[$i]['name']) ||
+ preg_match('#'.preg_quote(str_replace(' ', '_', $name)).'(.*)#i', $paths->pages[$i]['urlname']) ||
+ preg_match('#'.preg_quote(str_replace(' ', '_', $name)).'(.*)#i', $paths->pages[$i]['urlname_nons'])
+ ) &&
+ ( ( $nd[1] != 'Article' && $paths->pages[$i]['namespace'] == $nd[1] ) || $nd[1] == 'Article' )
+ && $paths->pages[$i]['visible']
+ )
+ {
+ $c++;
+ $u[] = $paths->pages[$i]['name'];
+ $n[] = $paths->pages[$i]['urlname'];
+ }
+ }
+ if($c > 0)
+ {
+ echo 'userlist = new Array(); namelist = new Array(); errorstring = false; '."\n";
+ for($i=0;$i<sizeof($u);$i++) // Can't use foreach because we need the value of $i and we need to use both $u and $n
+ {
+ echo "userlist[$i] = '".addslashes($n[$i])."';\n";
+ echo "namelist[$i] = '".addslashes($u[$i])."';\n";
+ }
+ } else {
+ die('userlist = new Array(); namelist = new Array(); errorstring=\'No page matches found.\'');
+ }
+ break;
+ case "preview":
+ echo PageUtils::genPreview($_POST['text']);
+ break;
+ case "pagediff":
+ $id1 = ( isset($_GET['diff1']) ) ? (int)$_GET['diff1'] : false;
+ $id2 = ( isset($_GET['diff2']) ) ? (int)$_GET['diff2'] : false;
+ if(!$id1 || !$id2) { echo '<p>Invalid request.</p>'; $template->footer(); break; }
+ if(!preg_match('#^([0-9]+)$#', (string)$_GET['diff1']) ||
+ !preg_match('#^([0-9]+)$#', (string)$_GET['diff2'] )) { echo '<p>SQL injection attempt</p>'; $template->footer(); break; }
+ echo PageUtils::pagediff($paths->cpage['urlname_nons'], $paths->namespace, $id1, $id2);
+ break;
+ case "jsres":
+ die('// ERROR: this section is deprecated and has moved to includes/clientside/static/enano-lib-basic.js.');
+ break;
+ case "rdns":
+ if(!$session->get_permissions('mod_misc')) die('Go somewhere else for your reverse DNS info!');
+ $ip = $_GET['ip'];
+ $rdns = gethostbyaddr($ip);
+ if($rdns == $ip) echo 'Unable to get reverse DNS information. Perhaps the IP address does not exist anymore.';
+ else echo $rdns;
+ break;
+ case 'acljson':
+ $parms = ( isset($_POST['acl_params']) ) ? rawurldecode($_POST['acl_params']) : false;
+ echo PageUtils::acl_json($parms);
+ break;
+ default:
+ die('Hacking attempt');
+ break;
+ }
+
+?>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cache/.htaccess Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,1 @@
+Deny from all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cache/index.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,13 @@
+<?php
+
+$_GET['title'] = 'Enano:Access_denied';
+require('../includes/common.php');
+header('HTTP/1.1 403 Forbidden');
+$session->perms['edit_page'] = AUTH_DENY;
+$session->perms['view_source'] = AUTH_DENY;
+$template->tpl_strings['PAGE_NAME'] = 'Access denied';
+
+$template->header();
+echo '<p>The administrator has flagged the page "' . $_SERVER['REQUEST_URI'] . '" so that it cannot be accessed from the web. Perhaps this is because this is a cache or includes directory and only needs to be accessed by scripts.</p><p>HTTP error: 403 Forbidden</p>';
+$template->footer();
+$db->close();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/files/.htaccess Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,1 @@
+Deny from all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/files/index.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,13 @@
+<?php
+
+$_GET['title'] = 'Enano:Access_denied';
+require('../includes/common.php');
+header('HTTP/1.1 403 Forbidden');
+$session->perms['edit_page'] = AUTH_DENY;
+$session->perms['view_source'] = AUTH_DENY;
+$template->tpl_strings['PAGE_NAME'] = 'Access denied';
+
+$template->header();
+echo '<p>The administrator has flagged the page "' . $_SERVER['REQUEST_URI'] . '" so that it cannot be accessed from the web. Perhaps this is because this is a cache or includes directory and only needs to be accessed by scripts.</p><p>HTTP error: 403 Forbidden</p>';
+$template->footer();
+$db->close();
Binary file images/about-powered-enano-hover.png has changed
Binary file images/about-powered-enano.png has changed
Binary file images/about-powered-mysql.png has changed
Binary file images/about-powered-php.png has changed
Binary file images/bad.gif has changed
Binary file images/delete.png has changed
Binary file images/disenable.png has changed
Binary file images/edit.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/enano-artwork/README Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,8 @@
+The images in this directory are copyright (C) 2007 Dan Fuhry. Except
+as permitted by applicable law, they may not be used in any way other
+than to promote the unmodified Enano CMS. You also may not modify and
+then distribute the images in this directory, or distribute them sep-
+arately from the Enano packages. The goal here is to establish a uni-
+que identity for Enano through the use of a logo, and that identity
+would be confused if this logo is used for unofficial Enano distros.
+
Binary file images/enano-artwork/installer-greeting-blue.png has changed
Binary file images/enano-artwork/installer-greeting-green.png has changed
Binary file images/error.png has changed
Binary file images/good.gif has changed
Binary file images/grippy.gif has changed
Binary file images/icons/empty.gif has changed
Binary file images/icons/join.gif has changed
Binary file images/icons/joinbottom.gif has changed
Binary file images/icons/line.gif has changed
Binary file images/icons/minus.gif has changed
Binary file images/icons/minusbottom.gif has changed
Binary file images/icons/page.gif has changed
Binary file images/icons/plus.gif has changed
Binary file images/icons/plusbottom.gif has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/index.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,13 @@
+<?php
+
+$_GET['title'] = 'Enano:Access_denied';
+require('../includes/common.php');
+header('HTTP/1.1 403 Forbidden');
+$session->perms['edit_page'] = AUTH_DENY;
+$session->perms['view_source'] = AUTH_DENY;
+$template->tpl_strings['PAGE_NAME'] = 'Access denied';
+
+$template->header();
+echo '<p>The administrator has flagged the page "' . $_SERVER['REQUEST_URI'] . '" so that it cannot be accessed from the web. Perhaps this is because this is a cache or includes directory and only needs to be accessed by scripts.</p><p>HTTP error: 403 Forbidden</p>';
+$template->footer();
+$db->close();
Binary file images/info.png has changed
Binary file images/loading-big.gif has changed
Binary file images/loading.gif has changed
Binary file images/lock.png has changed
Binary file images/lock16.png has changed
Binary file images/minus.gif has changed
Binary file images/move.png has changed
Binary file images/plus.gif has changed
Binary file images/question.png has changed
Binary file images/redirector.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/LICENSE Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,4 @@
+The images in this folder are from the Tango Desktop Project at
+http://tango.freedesktop.org. The SVG files and the rendered PNGs are available
+under the Creative Commons Attribution-ShareAlike license, which can be viewed
+in the /licenses directory in the Enano package.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/convert.sh Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,7 @@
+#!/bin/bash
+for f in *.svg; do
+ echo Converting $f
+ fname=`echo $f | cut -d '.' -f 1`
+ rm -f $fname.png
+ inkscape -z -f $f -w 22 -h 22 -e ./$fname.png
+done
Binary file images/smilies/face-angel.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/face-angel.svg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,358 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="face-angel.svg"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/emotes"
+ inkscape:version="0.42+devel"
+ sodipodi:version="0.32"
+ id="svg4376"
+ height="48px"
+ width="48px">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient3179">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3181" />
+ <stop
+ style="stop-color:#f6e76a;stop-opacity:1;"
+ offset="1"
+ id="stop3185" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3451">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3453" />
+ <stop
+ id="stop4936"
+ offset="0.5"
+ style="stop-color:#fefc9a;stop-opacity:0.62886596;" />
+ <stop
+ style="stop-color:#fefc9a;stop-opacity:0;"
+ offset="1"
+ id="stop3455" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3451"
+ id="radialGradient3468"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.166667,7.650132e-16,8.709935)"
+ cx="25.127777"
+ cy="10.451922"
+ fx="25.127777"
+ fy="10.451922"
+ r="15.076666" />
+ <linearGradient
+ id="linearGradient3050">
+ <stop
+ style="stop-color:#a40000;stop-opacity:1;"
+ offset="0"
+ id="stop3052" />
+ <stop
+ style="stop-color:#ec0000;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3054" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3290">
+ <stop
+ id="stop3292"
+ offset="0.0000000"
+ style="stop-color:#fffcde;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#f6e76a;stop-opacity:1.0000000;"
+ offset="0.64485979"
+ id="stop3294" />
+ <stop
+ id="stop3296"
+ offset="1.0000000"
+ style="stop-color:#ffb738;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ r="8.9020796"
+ fy="15.755712"
+ fx="29.158466"
+ cy="15.720984"
+ cx="29.288071"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2714"
+ xlink:href="#linearGradient3179"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient2509">
+ <stop
+ style="stop-color:#fffbd5;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2511" />
+ <stop
+ style="stop-color:#edd400;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2513" />
+ </linearGradient>
+ <radialGradient
+ gradientTransform="matrix(1.250000,0.000000,0.000000,1.250000,-6.479446,-13.37211)"
+ id="aigrd2"
+ cx="25.0527"
+ cy="39.5928"
+ r="15.7572"
+ fx="25.0527"
+ fy="39.5928"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#777777;stop-opacity:1.0000000;"
+ id="stop8602" />
+ <stop
+ offset="1"
+ style="stop-color:#000000"
+ id="stop8604" />
+ </radialGradient>
+ <linearGradient
+ id="linearGradient4565"
+ inkscape:collect="always">
+ <stop
+ id="stop4567"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop4569"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3824">
+ <stop
+ id="stop3826"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop3828"
+ offset="1.0000000"
+ style="stop-color:#c9c9c9;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3800">
+ <stop
+ id="stop3802"
+ offset="0.0000000"
+ style="stop-color:#ffeed6;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#e49c2f;stop-opacity:1.0000000;"
+ offset="0.50000000"
+ id="stop8664" />
+ <stop
+ id="stop3804"
+ offset="1.0000000"
+ style="stop-color:#ffc66c;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,0.000000,25.71429)"
+ r="19.714285"
+ fy="38.571430"
+ fx="24.714285"
+ cy="38.571430"
+ cx="24.714285"
+ id="radialGradient4571"
+ xlink:href="#linearGradient4565"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3050"
+ id="linearGradient3384"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.356785,-4.136152e-17,4.888137e-17,0.421652,15.59796,22.41694)"
+ x1="23.031250"
+ y1="24.312500"
+ x2="23.031250"
+ y2="36.249878" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3050"
+ id="linearGradient3388"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.277603,-9.832923e-2,0.112086,0.340135,19.04250,26.33855)"
+ x1="23.377983"
+ y1="21.840229"
+ x2="23.591845"
+ y2="31.634424" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3050"
+ id="linearGradient3394"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.277603,-9.832923e-2,0.112086,0.340135,19.04250,26.33855)"
+ x1="23.377983"
+ y1="21.840229"
+ x2="23.591845"
+ y2="31.634424" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-y="330"
+ inkscape:window-x="569"
+ inkscape:window-height="614"
+ inkscape:window-width="872"
+ inkscape:showpageshadow="false"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ showgrid="false"
+ inkscape:current-layer="layer1"
+ inkscape:cy="23.689514"
+ inkscape:cx="41.558678"
+ inkscape:zoom="4.9245777"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ borderopacity="0.19607843"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ fill="#edd400" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Face - Angel</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>emoticon</rdf:li>
+ <rdf:li>emote</rdf:li>
+ <rdf:li>smiley</rdf:li>
+ <rdf:li>angel</rdf:li>
+ <rdf:li>0:)</rdf:li>
+ <rdf:li>0:-)</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ <dc:description />
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Corey Woodworth</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ id="layer1">
+ <path
+ d="M 44.428570 38.571430 A 19.714285 6.5714288 0 1 1 5.0000000,38.571430 A 19.714285 6.5714288 0 1 1 44.428570 38.571430 z"
+ sodipodi:ry="6.5714288"
+ sodipodi:rx="19.714285"
+ sodipodi:cy="38.571430"
+ sodipodi:cx="24.714285"
+ id="path4563"
+ style="opacity:0.53164557;color:#000000;fill:url(#radialGradient4571);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.40487173;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.083142,0.000000,0.000000,2.083142,-40.54715,-16.49224)"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4320"
+ style="overflow:visible;display:inline;visibility:visible;stroke-opacity:1;stroke-dashoffset:0.0000000;stroke-dasharray:none;stroke-miterlimit:4.0000000;marker-end:none;marker-mid:none;marker-start:none;marker:none;stroke-linejoin:round;stroke-linecap:round;stroke-width:0.48004404;stroke:#e49a17;fill-rule:evenodd;fill-opacity:1.0;fill:url(#radialGradient2714);color:#000000;opacity:1.0000000"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(1.175809,0.000000,0.000000,2.582227,-5.280449,-20.47780)"
+ d="M 40.204443 10.451922 A 15.076666 2.5127776 0 1 1 10.051111,10.451922 A 15.076666 2.5127776 0 1 1 40.204443 10.451922 z"
+ sodipodi:ry="2.5127776"
+ sodipodi:rx="15.076666"
+ sodipodi:cy="10.451922"
+ sodipodi:cx="25.127777"
+ id="path3423"
+ style="opacity:1;color:#000000;fill:url(#radialGradient3468);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.00150537;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(1.979782,0.000000,0.000000,1.979782,-37.33128,-14.52746)"
+ sodipodi:type="arc"
+ style="opacity:0.4;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.50510627;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4322"
+ sodipodi:cx="31.112698"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="8.6620579"
+ sodipodi:ry="8.6620579"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z" />
+ <path
+ sodipodi:nodetypes="czczc"
+ id="path2659"
+ d="M 37.284637,24.719966 C 34.268170,29.944639 30.741134,33.710005 24.462492,33.710005 C 18.362475,33.710005 13.896955,29.370308 11.110016,24.543189 C 13.659429,27.599109 17.392948,31.109501 24.197327,31.109501 C 32.327531,31.109501 33.749103,28.202646 37.284637,24.719966 z "
+ style="opacity:0.35999998;color:#000000;fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
+ <path
+ style="fill:url(#aigrd2);fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
+ d="M 37.284637,24.012862 C 34.268170,29.237535 30.741134,33.002901 24.462492,33.002901 C 18.362475,33.002901 13.896955,28.663204 11.110016,23.836085 C 13.659429,26.892005 17.392948,30.402397 24.197327,30.402397 C 32.327531,30.402397 33.749103,27.495542 37.284637,24.012862 z "
+ id="path8606"
+ sodipodi:nodetypes="czczc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#c3b400;stroke-width:2.32432675;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="path1453"
+ sodipodi:cx="25.127777"
+ sodipodi:cy="10.451922"
+ sodipodi:rx="15.076666"
+ sodipodi:ry="2.5127776"
+ d="M 40.204443 10.451922 A 15.076666 2.5127776 0 1 1 10.051111,10.451922 A 15.076666 2.5127776 0 1 1 40.204443 10.451922 z"
+ transform="matrix(1.012503,0.000000,0.000000,1.645326,-1.176935,-10.68538)" />
+ <path
+ transform="matrix(1.014856,0.000000,0.000000,1.611564,-1.206928,-10.33866)"
+ d="M 40.204443 10.451922 A 15.076666 2.5127776 0 1 1 10.051111,10.451922 A 15.076666 2.5127776 0 1 1 40.204443 10.451922 z"
+ sodipodi:ry="2.5127776"
+ sodipodi:rx="15.076666"
+ sodipodi:cy="10.451922"
+ sodipodi:cx="25.127777"
+ id="path2472"
+ style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffff06;stroke-width:0.78194094;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ style="opacity:1;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.0000006;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 25.203063,17.578559 C 26.982405,21.949412 31.532943,22.064182 33.134299,17.728635 C 30.310009,19.967515 27.713179,19.322697 25.203063,17.578559 z "
+ id="path1336"
+ sodipodi:nodetypes="ccc" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path1458"
+ d="M 23.134299,17.578559 C 21.354957,21.949412 16.804419,22.064182 15.203063,17.728635 C 18.027353,19.967515 20.624183,19.322697 23.134299,17.578559 z "
+ style="opacity:1;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.0000006;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ </g>
+</svg>
Binary file images/smilies/face-crying.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/face-crying.svg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,326 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="face-crying.svg"
+ sodipodi:docbase="/home/tigert/cvs/freedesktop.org/tango-icon-theme/scalable/emotes"
+ inkscape:version="0.43+devel"
+ sodipodi:version="0.32"
+ id="svg4376"
+ height="48px"
+ width="48px"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient5125"
+ inkscape:collect="always">
+ <stop
+ id="stop5127"
+ offset="0"
+ style="stop-color:#729fcf;stop-opacity:1;" />
+ <stop
+ id="stop5129"
+ offset="1"
+ style="stop-color:#729fcf;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3290">
+ <stop
+ style="stop-color:#fffcde;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop3292" />
+ <stop
+ id="stop3294"
+ offset="0.64485979"
+ style="stop-color:#f6e76a;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#ffb738;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3296" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2729"
+ inkscape:collect="always">
+ <stop
+ id="stop2731"
+ offset="0"
+ style="stop-color:#d6e0f8;stop-opacity:1;" />
+ <stop
+ id="stop2733"
+ offset="1"
+ style="stop-color:#d6e0f8;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ gradientTransform="matrix(1.250000,0.000000,0.000000,-1.250000,-6.479446,73.66448)"
+ id="aigrd2"
+ cx="25.0527"
+ cy="39.5928"
+ r="15.7572"
+ fx="25.0527"
+ fy="39.5928"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#777777;stop-opacity:1.0000000;"
+ id="stop8602" />
+ <stop
+ offset="1"
+ style="stop-color:#000000"
+ id="stop8604" />
+ </radialGradient>
+ <linearGradient
+ id="linearGradient4565"
+ inkscape:collect="always">
+ <stop
+ id="stop4567"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop4569"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4565"
+ id="radialGradient1375"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,0.000000,25.71429)"
+ cx="24.714285"
+ cy="38.571430"
+ fx="24.714285"
+ fy="38.571430"
+ r="19.714285" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3290"
+ id="radialGradient1377"
+ gradientUnits="userSpaceOnUse"
+ cx="29.288071"
+ cy="15.720984"
+ fx="29.158466"
+ fy="15.755712"
+ r="8.9020796" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd2"
+ id="radialGradient1379"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.250000,0.000000,0.000000,-1.250000,-6.479446,73.66448)"
+ cx="25.0527"
+ cy="39.5928"
+ fx="25.0527"
+ fy="39.5928"
+ r="15.7572" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2729"
+ id="linearGradient1391"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6.010408,0.176777)"
+ x1="36.592773"
+ y1="18.228588"
+ x2="35.032169"
+ y2="13.809171" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5125"
+ id="linearGradient1394"
+ gradientUnits="userSpaceOnUse"
+ x1="29.807129"
+ y1="13.022821"
+ x2="29.807129"
+ y2="8.1614628" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2729"
+ id="radialGradient1398"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.369875,2.306855e-15,-4.790962e-15,2.845006,-5.054248,-35.24141)"
+ cx="13.664760"
+ cy="20.541668"
+ fx="13.664760"
+ fy="20.541668"
+ r="4.3085900" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5125"
+ id="linearGradient1401"
+ gradientUnits="userSpaceOnUse"
+ x1="17.616745"
+ y1="14.613358"
+ x2="16.829033"
+ y2="9.0223665" />
+ </defs>
+ <sodipodi:namedview
+ stroke="#729fcf"
+ inkscape:window-y="93"
+ inkscape:window-x="188"
+ inkscape:window-height="767"
+ inkscape:window-width="736"
+ inkscape:showpageshadow="false"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ showgrid="false"
+ inkscape:current-layer="layer1"
+ inkscape:cy="27.363514"
+ inkscape:cx="25.865750"
+ inkscape:zoom="11.313708"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ borderopacity="0.19607843"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ fill="#729fcf" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Face - Crying</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>emoticon</rdf:li>
+ <rdf:li>emote</rdf:li>
+ <rdf:li>smiley</rdf:li>
+ <rdf:li>crying</rdf:li>
+ <rdf:li>:~(</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-nc-sa/2.0/" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-nc-sa/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:prohibits
+ rdf:resource="http://web.resource.org/cc/CommercialUse" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ id="layer1">
+ <path
+ d="M 44.428570 38.571430 A 19.714285 6.5714288 0 1 1 5.0000000,38.571430 A 19.714285 6.5714288 0 1 1 44.428570 38.571430 z"
+ sodipodi:ry="6.5714288"
+ sodipodi:rx="19.714285"
+ sodipodi:cy="38.571430"
+ sodipodi:cx="24.714285"
+ id="path4563"
+ style="opacity:0.53164560;color:#000000;fill:url(#radialGradient1375);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.40487173;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1.0000000;color:#000000;fill:url(#radialGradient1377);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#9c8c0a;stroke-width:0.48004404;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4320"
+ sodipodi:cx="31.112698"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="8.6620579"
+ sodipodi:ry="8.6620579"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ transform="matrix(2.083142,0.000000,0.000000,2.083142,-40.59375,-16.52317)" />
+ <path
+ transform="matrix(1.979782,0.000000,0.000000,1.979782,-37.33128,-14.52746)"
+ sodipodi:type="arc"
+ style="opacity:0.67721522;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.50510627;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4322"
+ sodipodi:cx="31.112698"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="8.6620579"
+ sodipodi:ry="8.6620579"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z" />
+ <g
+ transform="matrix(0.663775,0.000000,0.000000,0.663775,8.254630,14.97512)"
+ id="g2300">
+ <path
+ style="opacity:0.35999998;color:#000000;fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ d="M 34.014268,32.036842 C 30.290694,27.872830 28.451859,26.405561 24.462492,26.405561 C 20.561313,26.405561 17.962820,28.093607 15.087492,32.390396 C 18.520789,30.041583 20.397124,28.740900 24.197327,28.740900 C 27.909166,28.740900 29.948404,29.791599 34.014268,32.036842 z "
+ id="path1387"
+ sodipodi:nodetypes="czczc" />
+ <path
+ sodipodi:nodetypes="czczc"
+ id="path8606"
+ d="M 34.014268,31.329738 C 30.290694,27.165726 28.451859,25.698457 24.462492,25.698457 C 20.561313,25.698457 17.962820,27.386503 15.087492,31.683292 C 18.520789,29.334479 20.397124,28.033796 24.197327,28.033796 C 27.909166,28.033796 29.948404,29.084495 34.014268,31.329738 z "
+ style="fill:url(#radialGradient1379);fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
+ </g>
+ <path
+ id="path2296"
+ d="M 21.000000,8.8749999 L 14.875000,13.625000 L 15.250000,10.375000 L 21.000000,8.8749999 z "
+ style="opacity:0.43670884;color:#000000;fill:#000000;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
+ <path
+ style="opacity:0.43670884;color:#000000;fill:#000000;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ d="M 26.375000,8.8749999 L 32.500000,13.625000 L 32.125000,10.375000 L 26.375000,8.8749999 z "
+ id="path2298" />
+ <path
+ style="opacity:1.0000000;color:#000000;fill:url(#linearGradient1401);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ d="M 20.806508,9.0223664 C 20.806508,9.0223664 19.555063,13.829673 19.083077,15.591149 C 18.646644,17.219940 17.218913,20.038229 18.008159,23.224582 C 18.997766,27.219831 17.198733,28.599337 15.251807,28.684789 C 13.457005,28.763565 11.351172,27.899994 11.431808,24.721607 C 11.547252,20.259605 16.459844,20.287573 18.212021,15.896009 C 19.872584,11.734062 14.971795,13.412606 14.971795,13.412606 C 14.971795,13.412606 20.806508,9.0223664 20.806508,9.0223664 z "
+ id="path2314"
+ sodipodi:nodetypes="czszsscc" />
+ <path
+ sodipodi:nodetypes="cssssscc"
+ id="path2310"
+ d="M 20.625000,9.1249999 C 20.625000,9.1249999 19.433058,13.630362 18.558058,16.536612 C 17.683058,19.442862 16.396267,20.013161 17.256281,23.358534 C 17.702556,25.094498 16.698856,27.000000 15.125000,27.000000 C 13.492505,27.000000 12.113408,26.032093 12.213388,23.926777 C 12.399719,20.003143 15.911602,20.579760 17.562500,17.031250 C 20.222272,11.301015 15.090386,13.431981 15.090386,13.431981 L 20.625000,9.1249999 z "
+ style="opacity:1.0000000;color:#000000;fill:url(#radialGradient1398);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
+ <path
+ transform="translate(-0.500000,-0.625000)"
+ d="M 15.625000 24.437500 A 1.1875000 1.1875000 0 1 1 13.250000,24.437500 A 1.1875000 1.1875000 0 1 1 15.625000 24.437500 z"
+ sodipodi:ry="1.1875000"
+ sodipodi:rx="1.1875000"
+ sodipodi:cy="24.437500"
+ sodipodi:cx="14.437500"
+ id="path2312"
+ style="opacity:1.0000000;color:#000000;fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="czsscc"
+ id="path2739"
+ d="M 26.507547,8.9188131 C 26.507547,8.9188131 28.172228,16.560698 28.565519,18.415939 C 29.046534,20.684992 33.175015,22.173621 33.105853,19.838569 C 33.011593,16.656119 30.190183,16.806635 29.906762,16.096933 C 28.688962,13.047804 32.599050,13.611854 32.599050,13.611854 C 32.599050,13.611854 26.507547,8.9188131 26.507547,8.9188131 z "
+ style="opacity:1.0000000;color:#000000;fill:url(#linearGradient1394);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
+ <path
+ sodipodi:nodetypes="cszsc"
+ id="path2743"
+ d="M 27.577164,12.114331 C 27.577164,12.114331 28.598544,16.869773 28.991377,17.992156 C 29.300736,18.876040 29.730588,19.647960 31.068504,19.538952 C 32.186786,19.447838 32.015107,17.859026 30.582368,17.064079 C 28.214634,15.750355 27.577164,12.202720 27.577164,12.114331 z "
+ style="opacity:1.0000000;color:#000000;fill:url(#linearGradient1391);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1.0000000;color:#000000;fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path2741"
+ sodipodi:cx="14.437500"
+ sodipodi:cy="24.437500"
+ sodipodi:rx="1.1875000"
+ sodipodi:ry="1.1875000"
+ d="M 15.625000 24.437500 A 1.1875000 1.1875000 0 1 1 13.250000,24.437500 A 1.1875000 1.1875000 0 1 1 15.625000 24.437500 z"
+ transform="matrix(0.553405,0.000000,0.000000,0.553405,22.82988,4.234059)" />
+ </g>
+</svg>
Binary file images/smilies/face-devil-grin.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/face-devil-grin.svg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,425 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48.000000px"
+ height="48.000000px"
+ id="svg4376"
+ sodipodi:version="0.32"
+ inkscape:version="0.43+devel"
+ sodipodi:docbase="/home/tigert/cvs/freedesktop.org/tango-icon-theme/scalable/emotes"
+ sodipodi:docname="face-devil-grin.svg"
+ inkscape:export-filename="/home/tigert/Desktop/face-grin.png"
+ inkscape:export-xdpi="90.000000"
+ inkscape:export-ydpi="90.000000"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient2337">
+ <stop
+ style="stop-color:#cc0000;stop-opacity:1;"
+ offset="0"
+ id="stop2339" />
+ <stop
+ id="stop2345"
+ offset="0.27586207"
+ style="stop-color:#c84a00;stop-opacity:1;" />
+ <stop
+ style="stop-color:#be0000;stop-opacity:1;"
+ offset="1"
+ id="stop2341" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2319">
+ <stop
+ style="stop-color:#f2d565;stop-opacity:1;"
+ offset="0"
+ id="stop2321" />
+ <stop
+ style="stop-color:#f2d565;stop-opacity:0;"
+ offset="1"
+ id="stop2323" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2311">
+ <stop
+ style="stop-color:#ffd93c;stop-opacity:1;"
+ offset="0"
+ id="stop2313" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop2315" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2291">
+ <stop
+ style="stop-color:#ffa107;stop-opacity:1;"
+ offset="0"
+ id="stop2293" />
+ <stop
+ style="stop-color:#cc0000;stop-opacity:1;"
+ offset="1"
+ id="stop2295" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2283">
+ <stop
+ style="stop-color:#730000;stop-opacity:1;"
+ offset="0"
+ id="stop2285" />
+ <stop
+ style="stop-color:#ff0202;stop-opacity:1;"
+ offset="1"
+ id="stop2287" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2102">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2104" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop2106" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3068">
+ <stop
+ style="stop-color:#cccccc;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop3070" />
+ <stop
+ id="stop3076"
+ offset="0.34579438"
+ style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.72486681"
+ id="stop3078" />
+ <stop
+ style="stop-color:#cecece;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3072" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4565">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop4567" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop4569" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4565"
+ id="radialGradient1360"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.333333,-1.239242e-15,25.71429)"
+ cx="24.714285"
+ cy="38.571430"
+ fx="24.714285"
+ fy="38.571430"
+ r="19.714285" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2102"
+ id="linearGradient2112"
+ gradientUnits="userSpaceOnUse"
+ x1="14.000000"
+ y1="21.062500"
+ x2="14"
+ y2="34.305527"
+ gradientTransform="matrix(1,0,0,1.404523,6.545492,-7.966331)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2102"
+ id="linearGradient2116"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.171895,-1.454508,-3.141166)"
+ x1="14.000000"
+ y1="21.062500"
+ x2="13.500000"
+ y2="33.426670" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2102"
+ id="linearGradient2120"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.159815,14.54551,-2.815047)"
+ x1="14.000000"
+ y1="21.062500"
+ x2="14.500000"
+ y2="33.431156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3068"
+ id="linearGradient2132"
+ x1="9.7892637"
+ y1="29.629091"
+ x2="38.390732"
+ y2="29.629091"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.048897,0,0,1,-5.222439,0)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2283"
+ id="linearGradient2289"
+ x1="39.125"
+ y1="33.375"
+ x2="46.625"
+ y2="16.5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.780746,0,0,0.780746,9.900195,9.256071)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2291"
+ id="radialGradient2297"
+ cx="30.561104"
+ cy="15.699058"
+ fx="30.561104"
+ fy="15.699058"
+ r="8.9020799"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.771216,8.401156e-17,-8.401156e-17,0.771216,6.991896,3.591695)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2311"
+ id="linearGradient2317"
+ x1="32.098553"
+ y1="6.1454587"
+ x2="31.775375"
+ y2="8.044363"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2319"
+ id="linearGradient2325"
+ x1="28.764467"
+ y1="12.221258"
+ x2="38.070023"
+ y2="38.297359"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2311"
+ id="linearGradient2327"
+ gradientUnits="userSpaceOnUse"
+ x1="7.2235508"
+ y1="6.0204587"
+ x2="8.0878754"
+ y2="8.044363" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2337"
+ id="linearGradient2343"
+ x1="30.525612"
+ y1="7.3609705"
+ x2="32.311508"
+ y2="9.4234705"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2337"
+ id="linearGradient2347"
+ gradientUnits="userSpaceOnUse"
+ x1="10.400612"
+ y1="7.6109705"
+ x2="8.8115082"
+ y2="9.6734705" />
+ </defs>
+ <sodipodi:namedview
+ fill="#cc0000"
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.19607843"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="8"
+ inkscape:cx="23.679146"
+ inkscape:cy="21.279725"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="872"
+ inkscape:window-height="710"
+ inkscape:window-x="717"
+ inkscape:window-y="411"
+ stroke="#a40000" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Face - Devil Grin</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>emoticon</rdf:li>
+ <rdf:li>emote</rdf:li>
+ <rdf:li>smiley</rdf:li>
+ <rdf:li>laugh</rdf:li>
+ <rdf:li>grin</rdf:li>
+ <rdf:li>>:-D</rdf:li>
+ <rdf:li>>:D</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Tuomas Kuosmanen</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ style="opacity:1;color:#000000;fill:url(#linearGradient2289);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999988;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 27.435547,37.514338 C 27.435547,37.514338 44.227293,38.187142 46.595268,31.409748 C 48.183817,26.863153 41.593613,24.041455 41.032451,20.967267 C 40.47129,17.893077 44.350623,18.673824 44.350623,18.673824 L 44.984979,19.942537 L 47.278422,17.209925 L 43.179504,16.673162 L 43.96025,17.990671 C 43.96025,17.990671 40.178509,17.380713 40.056519,20.674487 C 39.934527,23.96826 46.709243,28.164771 44.367004,31.409748 C 42.024765,34.654725 30.687562,33.654393 30.687562,33.654393 L 27.435547,37.514338 z "
+ id="path2281"
+ sodipodi:nodetypes="csscccccsscc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.53164559;color:#000000;fill:url(#radialGradient1360);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.40487173;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="path4563"
+ sodipodi:cx="24.714285"
+ sodipodi:cy="38.57143"
+ sodipodi:rx="19.714285"
+ sodipodi:ry="6.5714288"
+ d="M 44.42857 38.57143 A 19.714285 6.5714288 0 1 1 5,38.57143 A 19.714285 6.5714288 0 1 1 44.42857 38.57143 z"
+ transform="matrix(1.163647,0,0,1,-4.772741,-0.795495)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;color:#000000;fill:url(#radialGradient2297);fill-opacity:1.0;fill-rule:evenodd;stroke:#a40000;stroke-width:0.48004404;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="path4320"
+ sodipodi:cx="31.112698"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="8.6620579"
+ sodipodi:ry="8.6620579"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.45064,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ transform="matrix(2.083142,0,0,2.083142,-44.50164,-16.49224)" />
+ <path
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.45064,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4322"
+ style="opacity:0.43181818;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2325);stroke-width:0.50510627;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc"
+ transform="matrix(1.979782,0,0,1.979782,-41.28577,-14.52746)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path1364"
+ sodipodi:cx="-3.8125"
+ sodipodi:cy="1.875"
+ sodipodi:rx="2.9375"
+ sodipodi:ry="2.875"
+ d="M -0.875,1.875 A 2.9375,2.875 0 0 1 -6.3564497,3.3124999"
+ sodipodi:start="0"
+ sodipodi:end="2.6179939"
+ sodipodi:open="true"
+ transform="matrix(-0.965926,-0.258819,0.258819,-0.965926,20.57993,17.20131)" />
+ <path
+ transform="matrix(-0.965926,-0.258819,0.258819,-0.965926,11.82993,17.20131)"
+ sodipodi:open="true"
+ sodipodi:end="2.6179939"
+ sodipodi:start="0"
+ d="M -0.875,1.875 A 2.9375,2.875 0 0 1 -6.3564497,3.3124999"
+ sodipodi:ry="2.875"
+ sodipodi:rx="2.9375"
+ sodipodi:cy="1.875"
+ sodipodi:cx="-3.8125"
+ id="path2094"
+ style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="czcc"
+ id="path2096"
+ d="M 5.2330302,21.044769 C 3.6940488,28.612147 9.9250666,38.212295 20.084179,38.212295 C 30.331677,38.212295 36.589707,29.781871 34.804219,21.107269 L 5.2330302,21.044769 z "
+ style="opacity:1;color:#000000;fill:url(#linearGradient2132);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ id="path2110"
+ d="M 20.545492,21.528657 L 20.545492,38.382936"
+ style="opacity:0.18181817;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient2112);stroke-width:0.99999988px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ style="opacity:0.18181817;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient2116);stroke-width:1.00000024px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 12.545492,21.468635 L 12.545492,35.531381"
+ id="path2114" />
+ <path
+ id="path2118"
+ d="M 28.545492,21.541107 L 28.545492,35.458909"
+ style="opacity:0.18181817;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient2120);stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#a40000;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 5.4864345,20.615864 C 3.7057799,29.43779 10.645446,38.703673 20.295493,38.703673 C 30.299038,38.703673 36.947709,29.12529 34.667055,20.553364 L 5.4864345,20.615864 z "
+ id="path2756"
+ sodipodi:nodetypes="czcc" />
+ <path
+ style="color:#000000;fill:url(#linearGradient2343);fill-opacity:1.0;fill-rule:evenodd;stroke:#a40000;stroke-width:0.99999946;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 34.535409,4.733087 C 34.409741,4.7565977 34.289131,4.8018267 34.17899,4.8667442 L 28.208969,8.1413452 C 27.900649,8.3181155 27.588424,8.638695 27.661315,8.986539 C 28.098501,11.072856 29.745255,12.500002 31.965366,12.74992 C 32.299533,12.787537 32.577313,12.472421 32.731037,12.173337 L 35.693771,6.314697 C 35.87989,5.9453698 35.843224,5.5028759 35.598856,5.1692189 C 35.354488,4.8355619 34.943682,4.6670854 34.535409,4.733087 z "
+ id="path2276"
+ sodipodi:nodetypes="cccssccsc" />
+ <path
+ sodipodi:nodetypes="cccssccsc"
+ id="path2279"
+ d="M 6.9267157,4.858087 C 7.0523837,4.8815977 7.1729937,4.9268267 7.2831347,4.9917442 L 13.253153,8.2663452 C 13.561473,8.4431155 13.873698,8.763695 13.800807,9.111539 C 13.363621,11.197856 11.716867,12.625002 9.4967596,12.87492 C 9.1625926,12.912537 8.884812,12.597421 8.7310877,12.298337 L 5.7683537,6.439697 C 5.5822347,6.0703698 5.6189007,5.6278759 5.8632687,5.2942189 C 6.1076367,4.9605619 6.5184427,4.7920854 6.9267157,4.858087 z "
+ style="color:#000000;fill:url(#linearGradient2347);fill-opacity:1;fill-rule:evenodd;stroke:#a40000;stroke-width:0.99999946;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;opacity:1;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="ccssccc"
+ id="path2299"
+ d="M 34.550143,5.7962029 L 28.942862,8.8331689 C 28.751833,8.9553613 28.700764,8.9588269 28.763169,9.1964382 C 29.043277,10.262955 30.424664,11.448342 31.495276,11.709487 C 31.721107,11.764572 31.918285,11.628151 32.024546,11.421409 L 34.779643,5.9132168 C 34.908298,5.6579194 34.626278,5.7513287 34.550143,5.7962029 z "
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2317);stroke-width:0.99999946;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;opacity:0.64772727" />
+ <path
+ style="opacity:0.64772728;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2327);stroke-width:0.99999946;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;stroke-dasharray:none"
+ d="M 6.9035211,5.9729796 L 12.510802,9.0099456 C 12.701831,9.132138 12.7529,9.1356036 12.690495,9.3732149 C 12.410387,10.439732 11.029,11.625119 9.9583881,11.886264 C 9.7325571,11.941349 9.5353791,11.804928 9.4291181,11.598186 L 6.6740211,6.0899935 C 6.5453661,5.8346961 6.8273861,5.9281054 6.9035211,5.9729796 z "
+ id="path2301"
+ sodipodi:nodetypes="ccssccc" />
+ </g>
+</svg>
Binary file images/smilies/face-embarassed.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/face-embarassed.svg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,386 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="face-embarassed.svg"
+ sodipodi:docbase="/home/dan/emotes"
+ inkscape:version="0.45"
+ sodipodi:version="0.32"
+ id="svg4376"
+ height="48px"
+ width="48px"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ sodipodi:modified="true">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient5125"
+ inkscape:collect="always">
+ <stop
+ id="stop5127"
+ offset="0"
+ style="stop-color:#729fcf;stop-opacity:1;" />
+ <stop
+ id="stop5129"
+ offset="1"
+ style="stop-color:#729fcf;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5125"
+ id="linearGradient1394"
+ gradientUnits="userSpaceOnUse"
+ x1="29.807129"
+ y1="13.022821"
+ x2="29.807129"
+ y2="8.1614628"
+ gradientTransform="translate(0.6954057,5.597891)" />
+ <linearGradient
+ id="linearGradient2729"
+ inkscape:collect="always">
+ <stop
+ id="stop2731"
+ offset="0"
+ style="stop-color:#d6e0f8;stop-opacity:1;" />
+ <stop
+ id="stop2733"
+ offset="1"
+ style="stop-color:#d6e0f8;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2729"
+ id="linearGradient1391"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-5.3150023,5.774668)"
+ x1="36.592773"
+ y1="18.228588"
+ x2="35.032169"
+ y2="13.809171" />
+ <linearGradient
+ id="linearGradient2102">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2104" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop2106" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3068">
+ <stop
+ style="stop-color:#cccccc;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop3070" />
+ <stop
+ id="stop3076"
+ offset="0.34579438"
+ style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.72486681"
+ id="stop3078" />
+ <stop
+ style="stop-color:#cecece;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3072" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient8156">
+ <stop
+ style="stop-color:#ac0000;stop-opacity:0.62127662;"
+ offset="0"
+ id="stop8158" />
+ <stop
+ style="stop-color:#ac0000;stop-opacity:0;"
+ offset="1"
+ id="stop8160" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3290">
+ <stop
+ id="stop3292"
+ offset="0.0000000"
+ style="stop-color:#fffcde;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#f6e76a;stop-opacity:1.0000000;"
+ offset="0.64485979"
+ id="stop3294" />
+ <stop
+ id="stop3296"
+ offset="1.0000000"
+ style="stop-color:#ffb738;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ r="8.9020796"
+ fy="15.755712"
+ fx="29.158466"
+ cy="15.720984"
+ cx="29.288071"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2714"
+ xlink:href="#linearGradient3290"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient2509">
+ <stop
+ style="stop-color:#fffbd5;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2511" />
+ <stop
+ style="stop-color:#edd400;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2513" />
+ </linearGradient>
+ <radialGradient
+ gradientTransform="matrix(1.25,0,0,1.2206272,-7.11902,-8.367206)"
+ id="aigrd2"
+ cx="25.0527"
+ cy="39.5928"
+ r="15.7572"
+ fx="25.0527"
+ fy="39.5928"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#777777;stop-opacity:1.0000000;"
+ id="stop8602" />
+ <stop
+ offset="1"
+ style="stop-color:#000000"
+ id="stop8604" />
+ </radialGradient>
+ <linearGradient
+ id="linearGradient4565"
+ inkscape:collect="always">
+ <stop
+ id="stop4567"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop4569"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3824">
+ <stop
+ id="stop3826"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop3828"
+ offset="1.0000000"
+ style="stop-color:#c9c9c9;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3800">
+ <stop
+ id="stop3802"
+ offset="0.0000000"
+ style="stop-color:#ffeed6;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#e49c2f;stop-opacity:1.0000000;"
+ offset="0.50000000"
+ id="stop8664" />
+ <stop
+ id="stop3804"
+ offset="1.0000000"
+ style="stop-color:#ffc66c;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,0.000000,25.71429)"
+ r="19.714285"
+ fy="38.571430"
+ fx="24.714285"
+ cy="38.571430"
+ cx="24.714285"
+ id="radialGradient4571"
+ xlink:href="#linearGradient4565"
+ inkscape:collect="always" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8156"
+ id="radialGradient8164"
+ cx="15.153078"
+ cy="28.062902"
+ fx="15.153078"
+ fy="28.062902"
+ r="5.0579581"
+ gradientTransform="matrix(1,0,0,1.3196488,0,-8.9702732)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8156"
+ id="radialGradient8170"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.3196488,0,-8.9702732)"
+ cx="15.153078"
+ cy="28.062902"
+ fx="15.153078"
+ fy="28.062902"
+ r="5.0579581" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-y="0"
+ inkscape:window-x="192"
+ inkscape:window-height="735"
+ inkscape:window-width="822"
+ inkscape:showpageshadow="false"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ showgrid="false"
+ inkscape:current-layer="layer1"
+ inkscape:cy="23.205326"
+ inkscape:cx="25.411306"
+ inkscape:zoom="7.9999997"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ borderopacity="0.19607843"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ fill="#edd400" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Face - Happy</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>emoticon</rdf:li>
+ <rdf:li>emote</rdf:li>
+ <rdf:li>smiley</rdf:li>
+ <rdf:li>happy</rdf:li>
+ <rdf:li>:)</rdf:li>
+ <rdf:li>:-)</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ id="layer1">
+ <path
+ d="M 44.428570 38.571430 A 19.714285 6.5714288 0 1 1 5.0000000,38.571430 A 19.714285 6.5714288 0 1 1 44.428570 38.571430 z"
+ sodipodi:ry="6.5714288"
+ sodipodi:rx="19.714285"
+ sodipodi:cy="38.571430"
+ sodipodi:cx="24.714285"
+ id="path4563"
+ style="opacity:0.53164557;color:#000000;fill:url(#radialGradient4571);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.40487173;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.083142,0.000000,0.000000,2.083142,-40.54715,-16.49224)"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4320"
+ style="overflow:visible;display:inline;visibility:visible;stroke-opacity:1.0000000;stroke-dashoffset:0.0000000;stroke-dasharray:none;stroke-miterlimit:4.0000000;marker-end:none;marker-mid:none;marker-start:none;marker:none;stroke-linejoin:round;stroke-linecap:round;stroke-width:0.48004404;stroke:#9c8c0a;fill-rule:evenodd;fill-opacity:1.0000000;fill:url(#radialGradient2714);color:#000000;opacity:1.0000000"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient8164);fill-opacity:1;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path7181"
+ sodipodi:cx="15.153078"
+ sodipodi:cy="28.062902"
+ sodipodi:rx="4.8079581"
+ sodipodi:ry="6.4247284"
+ d="M 19.961036 28.062902 A 4.8079581 6.4247284 0 1 1 10.34512,28.062902 A 4.8079581 6.4247284 0 1 1 19.961036 28.062902 z"
+ transform="translate(1.3689692,-1.2295478)" />
+ <path
+ transform="matrix(1.979782,0,0,1.979782,-37.364426,-14.556923)"
+ sodipodi:type="arc"
+ style="opacity:0.67721522;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.50510627;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="path4322"
+ sodipodi:cx="31.112698"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="8.6620579"
+ sodipodi:ry="8.6620579"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.45064,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient8170);fill-opacity:1;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path8168"
+ sodipodi:cx="15.153078"
+ sodipodi:cy="28.062902"
+ sodipodi:rx="4.8079581"
+ sodipodi:ry="6.4247284"
+ d="M 19.961036 28.062902 A 4.8079581 6.4247284 0 1 1 10.34512,28.062902 A 4.8079581 6.4247284 0 1 1 19.961036 28.062902 z"
+ transform="translate(15.957913,-1.2761064)" />
+ <path
+ style="fill:url(#aigrd2);fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
+ d="M 33.374694,34.580329 C 29.65112,30.416317 27.812285,28.949048 23.822918,28.949048 C 19.921739,28.949048 17.323246,30.637094 14.447918,34.933883 C 17.881215,32.58507 19.75755,31.284387 23.557753,31.284387 C 27.269592,31.284387 29.30883,32.335086 33.374694,34.580329 z "
+ id="path8606"
+ sodipodi:nodetypes="czczc" />
+ <path
+ id="path2296"
+ d="M 21.695405,14.472891 L 15.570405,19.222891 L 15.945405,15.972891 L 21.695405,14.472891 z "
+ style="opacity:0.43670882;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ style="opacity:0.43670882;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 27.070405,14.472891 L 33.195405,19.222891 L 32.820405,15.972891 L 27.070405,14.472891 z "
+ id="path2298" />
+ <path
+ sodipodi:nodetypes="czsscc"
+ id="path2739"
+ d="M 27.202952,14.516704 C 27.202952,14.516704 28.867633,22.158589 29.260924,24.01383 C 29.741939,26.282883 33.87042,27.771512 33.801258,25.43646 C 33.706998,22.25401 30.885588,22.404526 30.602167,21.694824 C 29.384367,18.645695 33.294455,19.209745 33.294455,19.209745 C 33.294455,19.209745 27.202952,14.516704 27.202952,14.516704 z "
+ style="opacity:1;color:#000000;fill:url(#linearGradient1394);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ sodipodi:nodetypes="cszsc"
+ id="path2743"
+ d="M 28.272569,17.712222 C 28.272569,17.712222 29.293949,22.467664 29.686782,23.590047 C 29.996141,24.473931 30.425993,25.245851 31.763909,25.136843 C 32.882191,25.045729 32.710512,23.456917 31.277773,22.66197 C 28.910039,21.348246 28.272569,17.800611 28.272569,17.712222 z "
+ style="opacity:1;color:#000000;fill:url(#linearGradient1391);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="path2741"
+ sodipodi:cx="14.4375"
+ sodipodi:cy="24.4375"
+ sodipodi:rx="1.1875"
+ sodipodi:ry="1.1875"
+ d="M 15.625 24.4375 A 1.1875 1.1875 0 1 1 13.25,24.4375 A 1.1875 1.1875 0 1 1 15.625 24.4375 z"
+ transform="matrix(0.553405,0,0,0.553405,23.525285,9.8319504)" />
+ </g>
+</svg>
Binary file images/smilies/face-glasses.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/face-glasses.svg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,386 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="face-glasses.svg"
+ sodipodi:docbase="/home/jimmac/gfx/ximian/tango-icon-theme/scalable/emotes"
+ inkscape:version="0.43+devel"
+ sodipodi:version="0.32"
+ id="svg4376"
+ height="48px"
+ width="48px">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient4467">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop4469" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.24761905;"
+ offset="1.0000000"
+ id="stop4471" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4467"
+ id="radialGradient5122"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.913572,-5.717108e-24,-4.217183e-24,1.662023,4.360788,-11.71828)"
+ cx="15.414371"
+ cy="13.078408"
+ fx="15.414371"
+ fy="13.078408"
+ r="6.6562500" />
+ <linearGradient
+ id="linearGradient4454">
+ <stop
+ style="stop-color:#729fcf;stop-opacity:0.20784314;"
+ offset="0.0000000"
+ id="stop4456" />
+ <stop
+ style="stop-color:#729fcf;stop-opacity:0.67619050;"
+ offset="1.0000000"
+ id="stop4458" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4454"
+ id="radialGradient4460"
+ cx="18.240929"
+ cy="21.817987"
+ fx="18.240929"
+ fy="21.817987"
+ r="8.3085051"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient3290">
+ <stop
+ id="stop3292"
+ offset="0.0000000"
+ style="stop-color:#fffcde;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#f6e76a;stop-opacity:1.0000000;"
+ offset="0.64485979"
+ id="stop3294" />
+ <stop
+ id="stop3296"
+ offset="1.0000000"
+ style="stop-color:#ffb738;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ r="8.9020796"
+ fy="15.755712"
+ fx="29.158466"
+ cy="15.720984"
+ cx="29.288071"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2714"
+ xlink:href="#linearGradient3290"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient2509">
+ <stop
+ style="stop-color:#fffbd5;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2511" />
+ <stop
+ style="stop-color:#edd400;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2513" />
+ </linearGradient>
+ <radialGradient
+ gradientTransform="matrix(0.617019,0,0,0.617019,9.054796,7.969543)"
+ id="aigrd2"
+ cx="25.0527"
+ cy="39.5928"
+ r="15.7572"
+ fx="25.0527"
+ fy="39.5928"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#777777;stop-opacity:1.0000000;"
+ id="stop8602" />
+ <stop
+ offset="1"
+ style="stop-color:#000000"
+ id="stop8604" />
+ </radialGradient>
+ <linearGradient
+ id="linearGradient4565"
+ inkscape:collect="always">
+ <stop
+ id="stop4567"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop4569"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3824">
+ <stop
+ id="stop3826"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop3828"
+ offset="1.0000000"
+ style="stop-color:#c9c9c9;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3800">
+ <stop
+ id="stop3802"
+ offset="0.0000000"
+ style="stop-color:#ffeed6;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#e49c2f;stop-opacity:1.0000000;"
+ offset="0.50000000"
+ id="stop8664" />
+ <stop
+ id="stop3804"
+ offset="1.0000000"
+ style="stop-color:#ffc66c;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,0.000000,25.71429)"
+ r="19.714285"
+ fy="38.571430"
+ fx="24.714285"
+ cy="38.571430"
+ cx="24.714285"
+ id="radialGradient4571"
+ xlink:href="#linearGradient4565"
+ inkscape:collect="always" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4454"
+ id="radialGradient5150"
+ gradientUnits="userSpaceOnUse"
+ cx="18.240929"
+ cy="21.817987"
+ fx="18.240929"
+ fy="21.817987"
+ r="8.3085051" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4467"
+ id="radialGradient5152"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.913572,-5.717108e-24,-4.217183e-24,1.662023,-20.16955,-11.71828)"
+ cx="15.414371"
+ cy="13.078408"
+ fx="15.414371"
+ fy="13.078408"
+ r="6.6562500" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-y="282"
+ inkscape:window-x="571"
+ inkscape:window-height="739"
+ inkscape:window-width="872"
+ inkscape:showpageshadow="false"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ showgrid="false"
+ inkscape:current-layer="layer1"
+ inkscape:cy="34.650275"
+ inkscape:cx="46.379937"
+ inkscape:zoom="5.6568542"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ borderopacity="0.19607843"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ fill="#edd400" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Face - Happy</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>emoticon</rdf:li>
+ <rdf:li>emote</rdf:li>
+ <rdf:li>smiley</rdf:li>
+ <rdf:li>happy</rdf:li>
+ <rdf:li>:)</rdf:li>
+ <rdf:li>:-)</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ id="layer1">
+ <path
+ d="M 44.428570 38.571430 A 19.714285 6.5714288 0 1 1 5.0000000,38.571430 A 19.714285 6.5714288 0 1 1 44.428570 38.571430 z"
+ sodipodi:ry="6.5714288"
+ sodipodi:rx="19.714285"
+ sodipodi:cy="38.571430"
+ sodipodi:cx="24.714285"
+ id="path4563"
+ style="opacity:0.53164557;color:#000000;fill:url(#radialGradient4571);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.40487173;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.083142,0.000000,0.000000,2.083142,-40.54715,-16.49224)"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4320"
+ style="overflow:visible;display:inline;visibility:visible;stroke-opacity:1.0000000;stroke-dashoffset:0.0000000;stroke-dasharray:none;stroke-miterlimit:4.0000000;marker-end:none;marker-mid:none;marker-start:none;marker:none;stroke-linejoin:round;stroke-linecap:round;stroke-width:0.48004404;stroke:#9c8c0a;fill-rule:evenodd;fill-opacity:1.0000000;fill:url(#radialGradient2714);color:#000000;opacity:1.0000000"
+ sodipodi:type="arc" />
+ <g
+ id="g5201">
+ <path
+ transform="translate(-2.875,-0.625)"
+ d="M 38.375 19.1875 A 2.375 0.5625 0 1 1 33.625,19.1875 A 2.375 0.5625 0 1 1 38.375 19.1875 z"
+ sodipodi:ry="0.5625"
+ sodipodi:rx="2.375"
+ sodipodi:cy="19.1875"
+ sodipodi:cx="36"
+ id="path5197"
+ style="opacity:1;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999946;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999946;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="path5199"
+ sodipodi:cx="36"
+ sodipodi:cy="19.1875"
+ sodipodi:rx="2.375"
+ sodipodi:ry="0.5625"
+ d="M 38.375 19.1875 A 2.375 0.5625 0 1 1 33.625,19.1875 A 2.375 0.5625 0 1 1 38.375 19.1875 z"
+ transform="translate(-20.25,-0.625)" />
+ </g>
+ <path
+ transform="matrix(1.979782,0.000000,0.000000,1.979782,-37.33128,-14.52746)"
+ sodipodi:type="arc"
+ style="opacity:0.67721519;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.50510627;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4322"
+ sodipodi:cx="31.112698"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="8.6620579"
+ sodipodi:ry="8.6620579"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z" />
+ <path
+ sodipodi:nodetypes="czczc"
+ id="path2659"
+ d="M 30.657426,26.772382 C 29.168451,29.351362 27.427451,31.210005 24.328216,31.210005 C 21.317153,31.210005 19.112903,29.067863 17.737227,26.685122 C 18.995657,28.193572 20.83858,29.926356 24.197327,29.926356 C 28.210521,29.926356 28.912231,28.491487 30.657426,26.772382 z "
+ style="opacity:0.36000001;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ style="fill:url(#aigrd2);fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
+ d="M 30.657426,26.423345 C 29.168451,29.002324 27.427451,30.860968 24.328216,30.860968 C 21.317153,30.860968 19.112903,28.718826 17.737227,26.336085 C 18.995657,27.844534 20.83858,29.577318 24.197327,29.577318 C 28.210521,29.577318 28.912231,28.14245 30.657426,26.423345 z "
+ id="path8606"
+ sodipodi:nodetypes="czczc" />
+ <g
+ id="g1506"
+ transform="translate(0.375,2.75)"
+ style="stroke:#414141;stroke-opacity:1">
+ <path
+ d="M 21.036428 12.467883 A 9.5459423 9.5459423 0 1 1 1.9445438,12.467883 A 9.5459423 9.5459423 0 1 1 21.036428 12.467883 z"
+ sodipodi:ry="9.5459423"
+ sodipodi:rx="9.5459423"
+ sodipodi:cy="12.467883"
+ sodipodi:cx="11.490486"
+ id="path1500"
+ style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#414141;stroke-width:0.99999946;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(24.57196,0)"
+ sodipodi:type="arc"
+ style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#414141;stroke-width:0.99999946;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="path1502"
+ sodipodi:cx="11.490486"
+ sodipodi:cy="12.467883"
+ sodipodi:rx="9.5459423"
+ sodipodi:ry="9.5459423"
+ d="M 21.036428 12.467883 A 9.5459423 9.5459423 0 1 1 1.9445438,12.467883 A 9.5459423 9.5459423 0 1 1 21.036428 12.467883 z" />
+ <path
+ sodipodi:open="true"
+ sodipodi:end="1.3891474"
+ sodipodi:start="0"
+ d="M 21.036428,12.467883 A 9.5459423,9.5459423 0 0 1 13.214976,21.856767"
+ sodipodi:ry="9.5459423"
+ sodipodi:rx="9.5459423"
+ sodipodi:cy="12.467883"
+ sodipodi:cx="11.490486"
+ id="path1504"
+ style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#414141;stroke-width:1.59850872;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc"
+ transform="matrix(-0.40175,-0.479532,0.479532,-0.40175,22.40521,22.90045)" />
+ </g>
+ <path
+ transform="matrix(1.032158,0,0,1.032158,18.26107,-3.8646)"
+ d="M 25.897786 18.478292 A 8.3085051 8.3085051 0 1 1 9.280776,18.478292 A 8.3085051 8.3085051 0 1 1 25.897786 18.478292 z"
+ sodipodi:ry="8.3085051"
+ sodipodi:rx="8.3085051"
+ sodipodi:cy="18.478292"
+ sodipodi:cx="17.589281"
+ id="path4452"
+ style="color:#000000;fill:url(#radialGradient4460);fill-opacity:1;fill-rule:evenodd;stroke:#3063a3;stroke-width:0.968844;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dashoffset:0;stroke-opacity:1;visibility:visible"
+ sodipodi:type="arc" />
+ <path
+ id="path4462"
+ d="M 36.254111,7.7185784 C 32.41098,7.7185784 29.298923,10.830635 29.298923,14.673768 C 29.298923,15.783682 29.609104,16.804907 30.071721,17.736342 C 30.99596,18.077005 31.977761,18.308785 33.019806,18.308785 C 37.573888,18.308785 41.210928,14.720961 41.491971,10.237329 C 40.214543,8.7277552 38.385018,7.7185784 36.254111,7.7185784 z "
+ style="opacity:0.83422457;color:#000000;fill:url(#radialGradient5122);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:url(#radialGradient5150);fill-opacity:1;fill-rule:evenodd;stroke:#3063a3;stroke-width:0.968844;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dashoffset:0;stroke-opacity:1;visibility:visible"
+ id="path5146"
+ sodipodi:cx="17.589281"
+ sodipodi:cy="18.478292"
+ sodipodi:rx="8.3085051"
+ sodipodi:ry="8.3085051"
+ d="M 25.897786 18.478292 A 8.3085051 8.3085051 0 1 1 9.280776,18.478292 A 8.3085051 8.3085051 0 1 1 25.897786 18.478292 z"
+ transform="matrix(1.032158,0,0,1.032158,-6.269258,-3.8646)" />
+ <path
+ style="opacity:0.83422457;color:#000000;fill:url(#radialGradient5152);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 11.723783,7.7185784 C 7.8806502,7.7185784 4.7685932,10.830635 4.7685932,14.673768 C 4.7685932,15.783682 5.0787742,16.804907 5.5413912,17.736342 C 6.4656302,18.077005 7.4474312,18.308785 8.4894762,18.308785 C 13.04356,18.308785 16.6806,14.720961 16.961643,10.237329 C 15.684215,8.7277552 13.85469,7.7185784 11.723783,7.7185784 z "
+ id="path5148" />
+ </g>
+</svg>
Binary file images/smilies/face-grin.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/face-grin.svg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,316 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48.000000px"
+ height="48.000000px"
+ id="svg4376"
+ sodipodi:version="0.32"
+ inkscape:version="0.42+devel"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/emotes"
+ sodipodi:docname="face-grin.svg"
+ inkscape:export-filename="/home/tigert/Desktop/face-grin.png"
+ inkscape:export-xdpi="90.000000"
+ inkscape:export-ydpi="90.000000">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient2102">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2104" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop2106" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3290">
+ <stop
+ style="stop-color:#fffcde;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop3292" />
+ <stop
+ id="stop3294"
+ offset="0.64485979"
+ style="stop-color:#f6e76a;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#ffb738;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3296" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3068">
+ <stop
+ style="stop-color:#cccccc;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop3070" />
+ <stop
+ id="stop3076"
+ offset="0.34579438"
+ style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.72486681"
+ id="stop3078" />
+ <stop
+ style="stop-color:#cecece;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3072" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4565">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop4567" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop4569" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4565"
+ id="radialGradient1360"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,0.000000,25.71429)"
+ cx="24.714285"
+ cy="38.571430"
+ fx="24.714285"
+ fy="38.571430"
+ r="19.714285" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3290"
+ id="radialGradient1362"
+ gradientUnits="userSpaceOnUse"
+ cx="29.288071"
+ cy="15.720984"
+ fx="29.158466"
+ fy="15.755712"
+ r="8.9020796" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2102"
+ id="linearGradient2108"
+ x1="14.000000"
+ y1="21.062500"
+ x2="14.000000"
+ y2="32.875000"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,1.033654,1.500000,-0.627404)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2102"
+ id="linearGradient2112"
+ gradientUnits="userSpaceOnUse"
+ x1="14.000000"
+ y1="21.062500"
+ x2="14"
+ y2="34.305527"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,1.404523,10.50000,-7.966331)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2102"
+ id="linearGradient2116"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,1.171895,2.500000,-3.141166)"
+ x1="14.000000"
+ y1="21.062500"
+ x2="13.500000"
+ y2="33.426670" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2102"
+ id="linearGradient2120"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,1.159815,18.50000,-2.815047)"
+ x1="14.000000"
+ y1="21.062500"
+ x2="14.500000"
+ y2="33.431156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2102"
+ id="linearGradient2124"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,1.071351,-22.50000,-3.854623)"
+ x1="14.000000"
+ y1="21.062500"
+ x2="14.000000"
+ y2="35.744175" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3068"
+ id="linearGradient2132"
+ x1="9.7892637"
+ y1="29.629091"
+ x2="38.390732"
+ y2="29.629091"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.048897,0.000000,0.000000,1.000000,-1.267931,0.000000)" />
+ </defs>
+ <sodipodi:namedview
+ fill="#a40000"
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.19607843"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="23.514119"
+ inkscape:cy="28.588454"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="1010"
+ inkscape:window-height="1181"
+ inkscape:window-x="123"
+ inkscape:window-y="34"
+ stroke="#8f5902" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Face - Laughing</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>emoticon</rdf:li>
+ <rdf:li>emote</rdf:li>
+ <rdf:li>smiley</rdf:li>
+ <rdf:li>laughing</rdf:li>
+ <rdf:li>:-D</rdf:li>
+ <rdf:li>:D</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Tuomas Kuosmanen</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.53164560;color:#000000;fill:url(#radialGradient1360);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.40487173;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4563"
+ sodipodi:cx="24.714285"
+ sodipodi:cy="38.571430"
+ sodipodi:rx="19.714285"
+ sodipodi:ry="6.5714288"
+ d="M 44.428570 38.571430 A 19.714285 6.5714288 0 1 1 5.0000000,38.571430 A 19.714285 6.5714288 0 1 1 44.428570 38.571430 z" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1.0000000;color:#000000;fill:url(#radialGradient1362);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#9c8c0a;stroke-width:0.48004404;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4320"
+ sodipodi:cx="31.112698"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="8.6620579"
+ sodipodi:ry="8.6620579"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ transform="matrix(2.083142,0.000000,0.000000,2.083142,-40.54715,-16.49224)" />
+ <path
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4322"
+ style="opacity:0.67721522;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.50510627;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc"
+ transform="matrix(1.979782,0.000000,0.000000,1.979782,-37.33128,-14.52746)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;fill-opacity:1.0000000;stroke:#555753;stroke-width:1.0000000;stroke-linecap:butt;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
+ id="path1364"
+ sodipodi:cx="-3.8125000"
+ sodipodi:cy="1.8750000"
+ sodipodi:rx="2.9375000"
+ sodipodi:ry="2.8750000"
+ d="M -0.87500000,1.8750000 A 2.9375000,2.8750000 0 0 1 -6.3564497,3.3124999"
+ sodipodi:start="0.0000000"
+ sodipodi:end="2.6179939"
+ sodipodi:open="true"
+ transform="matrix(-0.965926,-0.258819,0.258819,-0.965926,24.53442,17.20131)" />
+ <path
+ transform="matrix(-0.965926,-0.258819,0.258819,-0.965926,15.78442,17.20131)"
+ sodipodi:open="true"
+ sodipodi:end="2.6179939"
+ sodipodi:start="0.0000000"
+ d="M -0.87500000,1.8750000 A 2.9375000,2.8750000 0 0 1 -6.3564497,3.3124999"
+ sodipodi:ry="2.8750000"
+ sodipodi:rx="2.9375000"
+ sodipodi:cy="1.8750000"
+ sodipodi:cx="-3.8125000"
+ id="path2094"
+ style="fill:none;fill-opacity:1.0000000;stroke:#555753;stroke-width:1.0000000;stroke-linecap:butt;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="czcc"
+ id="path2096"
+ d="M 9.1875355,21.044769 C 7.6485541,28.612147 13.879571,38.212295 24.038687,38.212295 C 34.286185,38.212295 40.544215,29.781871 38.758727,21.107269 L 9.1875355,21.044769 z "
+ style="opacity:1.0000000;color:#000000;fill:url(#linearGradient2132);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000001;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
+ <path
+ id="path2110"
+ d="M 24.500000,21.528657 L 24.500000,38.382936"
+ style="opacity:0.18181818;fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:url(#linearGradient2112);stroke-width:0.99999988px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ style="opacity:0.18181818;fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:url(#linearGradient2116);stroke-width:1.0000002px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ d="M 16.500000,21.468635 L 16.500000,35.531381"
+ id="path2114" />
+ <path
+ id="path2118"
+ d="M 32.500000,21.541107 L 32.500000,35.458909"
+ style="opacity:0.18181818;fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:url(#linearGradient2120);stroke-width:1.0000005px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:nonzero;stroke:#8f5902;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ d="M 9.4409398,20.615864 C 7.6602852,29.43779 14.599952,38.703673 24.250001,38.703673 C 34.253546,38.703673 40.902217,29.12529 38.621563,20.553364 L 9.4409398,20.615864 z "
+ id="path2756"
+ sodipodi:nodetypes="czcc" />
+ </g>
+</svg>
Binary file images/smilies/face-kiss.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/face-kiss.svg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,407 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48px"
+ height="48px"
+ id="svg4376"
+ sodipodi:version="0.32"
+ inkscape:version="0.43+devel"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/emotes"
+ sodipodi:docname="face-kiss.svg">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient3287">
+ <stop
+ id="stop3289"
+ offset="0"
+ style="stop-color:#fa9292;stop-opacity:1" />
+ <stop
+ id="stop3291"
+ offset="1"
+ style="stop-color:#cc0000" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3076">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop3078" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop3080" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2349">
+ <stop
+ style="stop-color:#ef2929"
+ offset="0"
+ id="stop2351" />
+ <stop
+ style="stop-color:#ef2929;stop-opacity:0;"
+ offset="1"
+ id="stop2353" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2319">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop2321" />
+ <stop
+ style="stop-color:#cc0000;stop-opacity:0;"
+ offset="1"
+ id="stop2323" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3110">
+ <stop
+ style="stop-color:#fcc2c2;stop-opacity:1"
+ offset="0"
+ id="stop3112" />
+ <stop
+ style="stop-color:#cc0000"
+ offset="1"
+ id="stop3114" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3290">
+ <stop
+ style="stop-color:#fffcde;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop3292" />
+ <stop
+ id="stop3294"
+ offset="0.64485979"
+ style="stop-color:#f6e76a;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#ffb738;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3296" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4565">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop4567" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop4569" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4565"
+ id="radialGradient1360"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,0.000000,25.71429)"
+ cx="24.714285"
+ cy="38.571430"
+ fx="24.714285"
+ fy="38.571430"
+ r="19.714285" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3290"
+ id="radialGradient1362"
+ gradientUnits="userSpaceOnUse"
+ cx="29.288071"
+ cy="15.720984"
+ fx="29.158466"
+ fy="15.755712"
+ r="8.9020796" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3287"
+ id="radialGradient2303"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(5.377271e-3,-0.373242,0.791975,1.141123e-2,1.832141,36.92856)"
+ cx="27.643423"
+ cy="29.13448"
+ fx="27.643423"
+ fy="29.13448"
+ r="7.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3110"
+ id="radialGradient3056"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-5.343385e-7,-0.317037,0.972031,-4.735123e-7,0.99978,36.47238)"
+ cx="47.651241"
+ cy="24.283606"
+ fx="47.651241"
+ fy="24.283606"
+ r="7.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3076"
+ id="radialGradient3082"
+ cx="24.319336"
+ cy="36.861725"
+ fx="24.319336"
+ fy="36.861725"
+ r="8.7498105"
+ gradientTransform="matrix(1.353561,5.943389e-8,-6.380732e-8,1.453164,-8.598368,-19.22848)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ fill="#ef2929"
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.19607843"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="5.6568542"
+ inkscape:cx="28.085084"
+ inkscape:cy="25.967717"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="false"
+ inkscape:document-units="px"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="929"
+ inkscape:window-height="850"
+ inkscape:window-x="829"
+ inkscape:window-y="221"
+ stroke="#ef2929"
+ inkscape:grid-points="true"
+ gridspacingx="0.5px"
+ gridspacingy="0.5px"
+ gridempspacing="2"
+ showguides="true"
+ inkscape:guide-bbox="true" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Face - Kiss</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>emoticon</rdf:li>
+ <rdf:li>emote</rdf:li>
+ <rdf:li>smiley</rdf:li>
+ <rdf:li>kiss</rdf:li>
+ <rdf:li>:-*</rdf:li>
+ <rdf:li>:*</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Lapo Calamandrei</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.27058824;color:#000000;fill:url(#radialGradient1360);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.40487173;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4563"
+ sodipodi:cx="24.714285"
+ sodipodi:cy="38.571430"
+ sodipodi:rx="19.714285"
+ sodipodi:ry="6.5714288"
+ d="M 44.428570 38.571430 A 19.714285 6.5714288 0 1 1 5.0000000,38.571430 A 19.714285 6.5714288 0 1 1 44.428570 38.571430 z" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;color:#000000;fill:url(#radialGradient1362);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#9c8c0a;stroke-width:0.48004404;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4320"
+ sodipodi:cx="31.112698"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="8.6620579"
+ sodipodi:ry="8.6620579"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ transform="matrix(2.083142,0.000000,0.000000,2.083142,-40.54715,-16.49224)" />
+ <path
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4322"
+ style="opacity:0.67721522;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.50510627;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc"
+ transform="matrix(1.979782,0.000000,0.000000,1.979782,-37.33128,-14.52746)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;fill-opacity:1.0000000;stroke:#555753;stroke-width:1.0000000;stroke-linecap:butt;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
+ id="path1364"
+ sodipodi:cx="-3.8125000"
+ sodipodi:cy="1.8750000"
+ sodipodi:rx="2.9375000"
+ sodipodi:ry="2.8750000"
+ d="M -0.87500000,1.8750000 A 2.9375000,2.8750000 0 0 1 -6.3564497,3.3124999"
+ sodipodi:start="0.0000000"
+ sodipodi:end="2.6179939"
+ sodipodi:open="true"
+ transform="matrix(-0.965926,-0.258819,0.258819,-0.965926,24.53442,17.20131)" />
+ <path
+ transform="matrix(-0.965926,-0.258819,0.258819,-0.965926,15.78442,17.20131)"
+ sodipodi:open="true"
+ sodipodi:end="2.6179939"
+ sodipodi:start="0.0000000"
+ d="M -0.87500000,1.8750000 A 2.9375000,2.8750000 0 0 1 -6.3564497,3.3124999"
+ sodipodi:ry="2.8750000"
+ sodipodi:rx="2.9375000"
+ sodipodi:cy="1.8750000"
+ sodipodi:cx="-3.8125000"
+ id="path2094"
+ style="fill:none;fill-opacity:1.0000000;stroke:#555753;stroke-width:1.0000000;stroke-linecap:butt;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
+ sodipodi:type="arc" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ sodipodi:nodetypes="csssccc"
+ id="path3066"
+ d="M 15.569526,26.222096 C 15.569526,26.222096 20.308098,24.892973 21.988095,24.873536 C 23.668091,24.854099 22.289512,26.144342 24.507945,26.118675 C 26.663515,26.093735 25.653861,25.056586 27.255269,25.038057 C 28.856676,25.019529 33.069147,26.019619 33.069147,26.019619 C 30.7796,30.353035 32.883855,35.670178 24.488994,35.670178 C 15.330963,35.670178 18.590936,29.30734 15.569526,26.222096 z "
+ style="fill:url(#radialGradient3082);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1.00000048;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;opacity:0.20555556" />
+ <path
+ style="opacity:1;color:#000000;fill:url(#radialGradient3056);fill-opacity:1;fill-rule:evenodd;stroke:#a40000;stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 16.110241,26.303277 C 16.110241,26.303277 32.597941,26.490777 32.597941,26.490777 C 30.217201,25 29.946346,21.213388 28.154513,21 C 25.205629,22.104671 24.054215,22.193885 21.141375,21 C 19.287043,21.489277 17.994148,25.144057 16.110241,26.303277 z "
+ id="path3047"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:url(#radialGradient2303);fill-opacity:1;fill-rule:evenodd;stroke:#a40000;stroke-width:1.00000048;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 17.160516,26.255438 C 17.160516,26.255438 21.109269,25.24186 22.509246,25.227037 C 23.909222,25.212215 25,26.5 25,26.5 C 25,26.5 25.564007,25.36663 26.898494,25.3525 C 28.232981,25.33837 31.743322,26.101031 31.743322,26.101031 C 29.835394,29.405659 31.588914,33.460469 24.593299,33.460469 C 16.961716,33.460469 19.678321,28.60822 17.160516,26.255438 z "
+ id="path1360"
+ sodipodi:nodetypes="cscsccc"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ transform="matrix(-0.314376,0.949299,0.949299,0.314376,29.0954,15.15051)"
+ sodipodi:open="true"
+ sodipodi:end="1.7329598"
+ sodipodi:start="0"
+ d="M -0.875,1.875 A 2.9375,2.875 0 0 1 -4.2867702,4.7122808"
+ sodipodi:ry="2.875"
+ sodipodi:rx="2.9375"
+ sodipodi:cy="1.875"
+ sodipodi:cx="-3.8125"
+ id="path3092"
+ style="fill:none;fill-opacity:1;stroke:#555753;stroke-width:1;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ sodipodi:type="arc"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ sodipodi:type="arc"
+ style="fill:none;fill-opacity:1;stroke:#555753;stroke-width:1.29058444;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path3094"
+ sodipodi:cx="-3.8125"
+ sodipodi:cy="1.875"
+ sodipodi:rx="2.9375"
+ sodipodi:ry="2.875"
+ d="M -0.875,1.875 A 2.9375,2.875 0 0 1 -4.1789771,4.7275381"
+ sodipodi:start="0"
+ sodipodi:end="1.6958804"
+ sodipodi:open="true"
+ transform="matrix(-0.243592,0.735557,0.735557,0.243592,28.13302,13.86608)" />
+ <path
+ transform="matrix(-0.243592,0.735557,0.735557,0.243592,25.63302,13.61608)"
+ sodipodi:open="true"
+ sodipodi:end="1.7544278"
+ sodipodi:start="0.43025654"
+ d="M -1.1427273,3.0741739 A 2.9375,2.875 0 0 1 -4.348891,4.7016628"
+ sodipodi:ry="2.875"
+ sodipodi:rx="2.9375"
+ sodipodi:cy="1.875"
+ sodipodi:cx="-3.8125"
+ id="path3096"
+ style="fill:none;fill-opacity:1;stroke:#555753;stroke-width:1.29058444;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ sodipodi:type="arc"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ sodipodi:type="arc"
+ style="fill:none;fill-opacity:1;stroke:#555753;stroke-width:1;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path3098"
+ sodipodi:cx="-3.8125"
+ sodipodi:cy="1.875"
+ sodipodi:rx="2.9375"
+ sodipodi:ry="2.875"
+ d="M -0.875,1.875 A 2.9375,2.875 0 0 1 -4.2867702,4.7122808"
+ sodipodi:start="0"
+ sodipodi:end="1.7329598"
+ sodipodi:open="true"
+ transform="matrix(0.314376,0.949299,-0.949299,0.314376,19.43113,15.15051)" />
+ <path
+ transform="matrix(0.243592,0.735557,-0.735557,0.243592,20.39351,13.86608)"
+ sodipodi:open="true"
+ sodipodi:end="1.6958804"
+ sodipodi:start="0"
+ d="M -0.875,1.875 A 2.9375,2.875 0 0 1 -4.1789771,4.7275381"
+ sodipodi:ry="2.875"
+ sodipodi:rx="2.9375"
+ sodipodi:cy="1.875"
+ sodipodi:cx="-3.8125"
+ id="path3100"
+ style="fill:none;fill-opacity:1;stroke:#555753;stroke-width:1.29058444;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ sodipodi:type="arc"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ sodipodi:type="arc"
+ style="fill:none;fill-opacity:1;stroke:#555753;stroke-width:1.29058444;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path3102"
+ sodipodi:cx="-3.8125"
+ sodipodi:cy="1.875"
+ sodipodi:rx="2.9375"
+ sodipodi:ry="2.875"
+ d="M -1.1427273,3.0741739 A 2.9375,2.875 0 0 1 -4.348891,4.7016628"
+ sodipodi:start="0.43025654"
+ sodipodi:end="1.7544278"
+ sodipodi:open="true"
+ transform="matrix(0.243592,0.735557,-0.735557,0.243592,22.89351,13.61608)" />
+ </g>
+</svg>
Binary file images/smilies/face-oops.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/face-oops.svg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,475 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="face-oops.svg"
+ sodipodi:docbase="/home/dan/emotes"
+ inkscape:version="0.45"
+ sodipodi:version="0.32"
+ id="svg4376"
+ height="48px"
+ width="48px"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ sodipodi:modified="true">
+ <defs
+ id="defs3">
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2102"
+ id="linearGradient2120"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.159815,18.5,-2.815047)"
+ x1="14.000000"
+ y1="21.062500"
+ x2="14.500000"
+ y2="33.431156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2102"
+ id="linearGradient2116"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.171895,2.5,-3.141166)"
+ x1="14.000000"
+ y1="21.062500"
+ x2="13.500000"
+ y2="33.426670" />
+ <linearGradient
+ id="linearGradient2102">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2104" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop2106" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2102"
+ id="linearGradient2112"
+ gradientUnits="userSpaceOnUse"
+ x1="14.000000"
+ y1="21.062500"
+ x2="14"
+ y2="34.305527"
+ gradientTransform="matrix(1,0,0,1.404523,10.5,-7.966331)" />
+ <linearGradient
+ id="linearGradient3068">
+ <stop
+ style="stop-color:#cccccc;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop3070" />
+ <stop
+ id="stop3076"
+ offset="0.34579438"
+ style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.72486681"
+ id="stop3078" />
+ <stop
+ style="stop-color:#cecece;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3072" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3068"
+ id="linearGradient2132"
+ x1="9.7892637"
+ y1="29.629091"
+ x2="38.390732"
+ y2="29.629091"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.048897,0,0,1,-1.267931,0)" />
+ <linearGradient
+ id="linearGradient8156">
+ <stop
+ style="stop-color:#ac0000;stop-opacity:0.62127662;"
+ offset="0"
+ id="stop8158" />
+ <stop
+ style="stop-color:#ac0000;stop-opacity:0;"
+ offset="1"
+ id="stop8160" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3290">
+ <stop
+ id="stop3292"
+ offset="0.0000000"
+ style="stop-color:#fffcde;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#f6e76a;stop-opacity:1.0000000;"
+ offset="0.64485979"
+ id="stop3294" />
+ <stop
+ id="stop3296"
+ offset="1.0000000"
+ style="stop-color:#ffb738;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ r="8.9020796"
+ fy="15.755712"
+ fx="29.158466"
+ cy="15.720984"
+ cx="29.288071"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2714"
+ xlink:href="#linearGradient3290"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient2509">
+ <stop
+ style="stop-color:#fffbd5;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2511" />
+ <stop
+ style="stop-color:#edd400;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2513" />
+ </linearGradient>
+ <radialGradient
+ gradientTransform="matrix(1.25,0,0,1.2206272,-6.479446,-11.617797)"
+ id="aigrd2"
+ cx="25.0527"
+ cy="39.5928"
+ r="15.7572"
+ fx="25.0527"
+ fy="39.5928"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#777777;stop-opacity:1.0000000;"
+ id="stop8602" />
+ <stop
+ offset="1"
+ style="stop-color:#000000"
+ id="stop8604" />
+ </radialGradient>
+ <linearGradient
+ id="linearGradient4565"
+ inkscape:collect="always">
+ <stop
+ id="stop4567"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop4569"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3824">
+ <stop
+ id="stop3826"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop3828"
+ offset="1.0000000"
+ style="stop-color:#c9c9c9;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3800">
+ <stop
+ id="stop3802"
+ offset="0.0000000"
+ style="stop-color:#ffeed6;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#e49c2f;stop-opacity:1.0000000;"
+ offset="0.50000000"
+ id="stop8664" />
+ <stop
+ id="stop3804"
+ offset="1.0000000"
+ style="stop-color:#ffc66c;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,0.000000,25.71429)"
+ r="19.714285"
+ fy="38.571430"
+ fx="24.714285"
+ cy="38.571430"
+ cx="24.714285"
+ id="radialGradient4571"
+ xlink:href="#linearGradient4565"
+ inkscape:collect="always" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8156"
+ id="radialGradient8164"
+ cx="15.153078"
+ cy="28.062902"
+ fx="15.153078"
+ fy="28.062902"
+ r="5.0579581"
+ gradientTransform="matrix(1,0,0,1.3196488,0,-8.9702732)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8156"
+ id="radialGradient8170"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.3196488,0,-8.9702732)"
+ cx="15.153078"
+ cy="28.062902"
+ fx="15.153078"
+ fy="28.062902"
+ r="5.0579581" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2102"
+ id="linearGradient2226"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.609351,0,0,0.34239,20.743344,20.335896)"
+ x1="14.000000"
+ y1="21.062500"
+ x2="14.500000"
+ y2="33.431156" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2102"
+ id="linearGradient2229"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.609351,0,0,0.3526107,10.993725,20.017144)"
+ x1="14.000000"
+ y1="21.062500"
+ x2="13.500000"
+ y2="33.426670" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2102"
+ id="linearGradient2232"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.609351,0,0,0.4226059,15.868535,18.565304)"
+ x1="14.000000"
+ y1="21.062500"
+ x2="14"
+ y2="34.305527" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3068"
+ id="linearGradient2235"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6446665,0,0,0.2104377,8.5621255,24.461994)"
+ x1="9.7892637"
+ y1="29.629091"
+ x2="38.390732"
+ y2="29.629091" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3068"
+ id="linearGradient2252"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6446665,0,0,0.2104377,8.5621255,24.461994)"
+ x1="9.7892637"
+ y1="29.629091"
+ x2="38.390732"
+ y2="29.629091" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2102"
+ id="linearGradient2254"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.609351,0,0,0.4226059,15.868535,18.565304)"
+ x1="14.000000"
+ y1="21.062500"
+ x2="14"
+ y2="34.305527" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2102"
+ id="linearGradient2256"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.609351,0,0,0.3526107,10.993725,20.017144)"
+ x1="14.000000"
+ y1="21.062500"
+ x2="13.500000"
+ y2="33.426670" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2102"
+ id="linearGradient2258"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.609351,0,0,0.34239,20.743344,20.335896)"
+ x1="14.000000"
+ y1="21.062500"
+ x2="14.500000"
+ y2="33.431156" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-y="0"
+ inkscape:window-x="50"
+ inkscape:window-height="735"
+ inkscape:window-width="822"
+ inkscape:showpageshadow="false"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ showgrid="false"
+ inkscape:current-layer="layer1"
+ inkscape:cy="25.694057"
+ inkscape:cx="25.411306"
+ inkscape:zoom="11.313708"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ borderopacity="0.19607843"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ fill="#edd400" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Face - Happy</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>emoticon</rdf:li>
+ <rdf:li>emote</rdf:li>
+ <rdf:li>smiley</rdf:li>
+ <rdf:li>happy</rdf:li>
+ <rdf:li>:)</rdf:li>
+ <rdf:li>:-)</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ id="layer1">
+ <path
+ d="M 44.428570 38.571430 A 19.714285 6.5714288 0 1 1 5.0000000,38.571430 A 19.714285 6.5714288 0 1 1 44.428570 38.571430 z"
+ sodipodi:ry="6.5714288"
+ sodipodi:rx="19.714285"
+ sodipodi:cy="38.571430"
+ sodipodi:cx="24.714285"
+ id="path4563"
+ style="opacity:0.53164557;color:#000000;fill:url(#radialGradient4571);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.40487173;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.083142,0.000000,0.000000,2.083142,-40.54715,-16.49224)"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4320"
+ style="overflow:visible;display:inline;visibility:visible;stroke-opacity:1.0000000;stroke-dashoffset:0.0000000;stroke-dasharray:none;stroke-miterlimit:4.0000000;marker-end:none;marker-mid:none;marker-start:none;marker:none;stroke-linejoin:round;stroke-linecap:round;stroke-width:0.48004404;stroke:#9c8c0a;fill-rule:evenodd;fill-opacity:1.0000000;fill:url(#radialGradient2714);color:#000000;opacity:1.0000000"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient8164);fill-opacity:1;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path7181"
+ sodipodi:cx="15.153078"
+ sodipodi:cy="28.062902"
+ sodipodi:rx="4.8079581"
+ sodipodi:ry="6.4247284"
+ d="M 19.961036 28.062902 A 4.8079581 6.4247284 0 1 1 10.34512,28.062902 A 4.8079581 6.4247284 0 1 1 19.961036 28.062902 z"
+ transform="translate(-0.6518641,-3.2816311)" />
+ <path
+ transform="matrix(1.979782,0.000000,0.000000,1.979782,-37.33128,-14.52746)"
+ sodipodi:type="arc"
+ style="opacity:0.67721519;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.50510627;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4322"
+ sodipodi:cx="31.112698"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="8.6620579"
+ sodipodi:ry="8.6620579"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z" />
+ <g
+ transform="matrix(1,0,0,0.7991174,0.353553,4.4409911)"
+ id="g8666">
+ <path
+ style="opacity:0.36000001;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
+ d="M 21.398158,15.321428 C 21.398158,17.821428 20.273158,19.821428 18.898158,19.821428 C 17.523158,19.821428 16.273158,17.821428 16.273158,15.321428 C 16.273158,12.821428 17.398158,10.821428 18.773158,10.821428 C 20.148158,10.821428 21.273158,12.821428 21.273158,15.321428 L 21.398158,15.321428 z "
+ id="path8610" />
+ <path
+ style="opacity:0.36000001;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
+ d="M 30.688512,15.321428 C 30.688512,17.821428 29.563512,19.821428 28.188512,19.821428 C 26.813512,19.821428 25.688512,17.821428 25.688512,15.321428 C 25.688512,12.821428 26.813512,10.821428 28.188512,10.821428 C 29.563512,10.821428 30.688512,12.821428 30.688512,15.321428 z "
+ id="path8612" />
+ <path
+ style="fill:#000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
+ d="M 21.398158,14.696428 C 21.398158,17.196428 20.273158,19.196428 18.898158,19.196428 C 17.523158,19.196428 16.398158,17.196428 16.398158,14.696428 C 16.398158,12.196428 17.523158,10.196428 18.898158,10.196428 C 20.273158,10.196428 21.398158,12.196428 21.398158,14.696428 z "
+ id="path8614" />
+ <path
+ style="fill:#000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
+ d="M 30.688512,14.696428 C 30.688512,17.196428 29.563512,19.196428 28.188512,19.196428 C 26.813512,19.196428 25.688512,17.196428 25.688512,14.696428 C 25.688512,12.196428 26.813512,10.196428 28.188512,10.196428 C 29.563512,10.196428 30.688512,12.196428 30.688512,14.696428 z "
+ id="path8616" />
+ </g>
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient8170);fill-opacity:1;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path8168"
+ sodipodi:cx="15.153078"
+ sodipodi:cy="28.062902"
+ sodipodi:rx="4.8079581"
+ sodipodi:ry="6.4247284"
+ d="M 19.961036 28.062902 A 4.8079581 6.4247284 0 1 1 10.34512,28.062902 A 4.8079581 6.4247284 0 1 1 19.961036 28.062902 z"
+ transform="translate(17.957913,-3.2761064)" />
+ <g
+ id="g2237"
+ transform="translate(0,2)">
+ <path
+ style="color:#000000;fill:url(#linearGradient2252);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 14.988198,28.890608 C 15.179727,31.617118 17.87199,32.503303 24.115922,32.503303 C 30.414173,32.503303 33.174136,31.055189 33.16306,28.90376 C 33.151844,26.725175 14.796672,26.164096 14.988198,28.890608 z "
+ id="path2096"
+ sodipodi:nodetypes="czzz" />
+ <path
+ style="opacity:0.18181817;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient2254);stroke-width:0.42819062px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 24.39945,27.440031 L 24.39945,32.511304"
+ id="path2110" />
+ <path
+ id="path2114"
+ d="M 19.524642,27.421971 L 19.524642,31.653301"
+ style="opacity:0.18181817;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient2256);stroke-width:0.42819077px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ style="opacity:0.18181817;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient2258);stroke-width:0.42413118px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 29.274259,27.526098 L 29.274259,31.634785"
+ id="path2118" />
+ <path
+ sodipodi:nodetypes="czzz"
+ id="path2756"
+ d="M 15.143945,28.80035 C 15.223926,31.330376 18.314745,32.606706 24.245798,32.606706 C 30.394114,32.606706 33.063062,30.724409 33.078757,28.787198 C 33.094451,26.849987 15.063964,26.270323 15.143945,28.80035 z "
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#8f5902;stroke-width:0.35963577;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ </g>
+ </g>
+</svg>
Binary file images/smilies/face-plain.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/face-plain.svg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,303 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="face-plain.svg"
+ sodipodi:docbase="/home/steven/projects/tango/Experiments/faces/scalable"
+ inkscape:version="0.43"
+ sodipodi:version="0.32"
+ id="svg4376"
+ height="48px"
+ width="48px"
+ inkscape:export-filename="/home/steven/face-plain4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient3290">
+ <stop
+ id="stop3292"
+ offset="0.0000000"
+ style="stop-color:#fffcde;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#f6e76a;stop-opacity:1.0000000;"
+ offset="0.64485979"
+ id="stop3294" />
+ <stop
+ id="stop3296"
+ offset="1.0000000"
+ style="stop-color:#ffb738;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ r="8.9020796"
+ fy="15.755712"
+ fx="29.158466"
+ cy="15.720984"
+ cx="29.288071"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2714"
+ xlink:href="#linearGradient3290"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient2509">
+ <stop
+ style="stop-color:#fffbd5;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2511" />
+ <stop
+ style="stop-color:#edd400;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2513" />
+ </linearGradient>
+ <radialGradient
+ gradientTransform="matrix(1.25,0,0,1.25,53.52055,-13.37211)"
+ id="aigrd2"
+ cx="25.0527"
+ cy="39.5928"
+ r="15.7572"
+ fx="25.0527"
+ fy="39.5928"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#777777;stop-opacity:1.0000000;"
+ id="stop8602" />
+ <stop
+ offset="1"
+ style="stop-color:#000000"
+ id="stop8604" />
+ </radialGradient>
+ <linearGradient
+ id="linearGradient4565"
+ inkscape:collect="always">
+ <stop
+ id="stop4567"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop4569"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3824">
+ <stop
+ id="stop3826"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop3828"
+ offset="1.0000000"
+ style="stop-color:#c9c9c9;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3800">
+ <stop
+ id="stop3802"
+ offset="0.0000000"
+ style="stop-color:#ffeed6;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#e49c2f;stop-opacity:1.0000000;"
+ offset="0.50000000"
+ id="stop8664" />
+ <stop
+ id="stop3804"
+ offset="1.0000000"
+ style="stop-color:#ffc66c;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,0.000000,25.71429)"
+ r="19.714285"
+ fy="38.571430"
+ fx="24.714285"
+ cy="38.571430"
+ cx="24.714285"
+ id="radialGradient4571"
+ xlink:href="#linearGradient4565"
+ inkscape:collect="always" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd2"
+ id="radialGradient2211"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.25,39.41053,-19.20819)"
+ cx="25.0527"
+ cy="39.5928"
+ fx="25.0527"
+ fy="39.5928"
+ r="15.7572" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd2"
+ id="radialGradient2213"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.357899,0,0,0.416667,55.84561,15.2093)"
+ cx="-23.452122"
+ cy="38.602852"
+ fx="-23.452122"
+ fy="38.602852"
+ r="15.7572" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd2"
+ id="radialGradient1342"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.28431,0,0,0.416667,30.45155,18.23307)"
+ cx="-23.452122"
+ cy="38.602852"
+ fx="-23.452122"
+ fy="38.602852"
+ r="15.7572" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-y="174"
+ inkscape:window-x="373"
+ inkscape:window-height="771"
+ inkscape:window-width="1055"
+ inkscape:showpageshadow="false"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ showgrid="false"
+ inkscape:current-layer="layer1"
+ inkscape:cy="22.183359"
+ inkscape:cx="28.123476"
+ inkscape:zoom="1"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ borderopacity="0.19607843"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ fill="#edd400" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Face - Plain</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>emoticon</rdf:li>
+ <rdf:li>emote</rdf:li>
+ <rdf:li>face</rdf:li>
+ <rdf:li>plain</rdf:li>
+ <rdf:li>:|</rdf:li>
+ <rdf:li>:-|</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Steven Garrity</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://www.tango-project.org</dc:source>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Based on face-smile by jimmac</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ id="layer1">
+ <path
+ d="M 44.428570 38.571430 A 19.714285 6.5714288 0 1 1 5.0000000,38.571430 A 19.714285 6.5714288 0 1 1 44.428570 38.571430 z"
+ sodipodi:ry="6.5714288"
+ sodipodi:rx="19.714285"
+ sodipodi:cy="38.571430"
+ sodipodi:cx="24.714285"
+ id="path4563"
+ style="opacity:0.53164557;color:#000000;fill:url(#radialGradient4571);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.40487173;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.083142,0.000000,0.000000,2.083142,-40.54715,-16.49224)"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4320"
+ style="overflow:visible;display:inline;visibility:visible;stroke-opacity:1.0000000;stroke-dashoffset:0.0000000;stroke-dasharray:none;stroke-miterlimit:4.0000000;marker-end:none;marker-mid:none;marker-start:none;marker:none;stroke-linejoin:round;stroke-linecap:round;stroke-width:0.48004404;stroke:#9c8c0a;fill-rule:evenodd;fill-opacity:1.0000000;fill:url(#radialGradient2714);color:#000000;opacity:1.0000000"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(1.979782,0.000000,0.000000,1.979782,-37.33128,-14.52746)"
+ sodipodi:type="arc"
+ style="opacity:0.67721519;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.50510627;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4322"
+ sodipodi:cx="31.112698"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="8.6620579"
+ sodipodi:ry="8.6620579"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z" />
+ <g
+ transform="matrix(1,0,0,0.74952,0.353553,7.357569)"
+ id="g8666">
+ <path
+ style="opacity:0.36000001;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
+ d="M 21.398158,15.321428 C 21.398158,17.821428 20.273158,19.821428 18.898158,19.821428 C 17.523158,19.821428 16.273158,17.821428 16.273158,15.321428 C 16.273158,12.821428 17.398158,10.821428 18.773158,10.821428 C 20.148158,10.821428 21.273158,12.821428 21.273158,15.321428 L 21.398158,15.321428 z "
+ id="path8610" />
+ <path
+ style="opacity:0.36000001;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
+ d="M 30.688512,15.321428 C 30.688512,17.821428 29.563512,19.821428 28.188512,19.821428 C 26.813512,19.821428 25.688512,17.821428 25.688512,15.321428 C 25.688512,12.821428 26.813512,10.821428 28.188512,10.821428 C 29.563512,10.821428 30.688512,12.821428 30.688512,15.321428 z "
+ id="path8612" />
+ <path
+ style="fill:#000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
+ d="M 21.398158,14.696428 C 21.398158,17.196428 20.273158,19.196428 18.898158,19.196428 C 17.523158,19.196428 16.398158,17.196428 16.398158,14.696428 C 16.398158,12.196428 17.523158,10.196428 18.898158,10.196428 C 20.273158,10.196428 21.398158,12.196428 21.398158,14.696428 z "
+ id="path8614" />
+ <path
+ style="fill:#000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
+ d="M 30.688512,14.696428 C 30.688512,17.196428 29.563512,19.196428 28.188512,19.196428 C 26.813512,19.196428 25.688512,17.196428 25.688512,14.696428 C 25.688512,12.196428 26.813512,10.196428 28.188512,10.196428 C 29.563512,10.196428 30.688512,12.196428 30.688512,14.696428 z "
+ id="path8616" />
+ </g>
+ <rect
+ style="opacity:1;color:#000000;fill:url(#radialGradient2213);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="rect2453"
+ width="20"
+ height="1"
+ x="14"
+ y="29"
+ rx="0.5"
+ ry="0.5" />
+ <rect
+ style="opacity:0.36000001;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="rect1336"
+ width="20"
+ height="1"
+ x="14"
+ y="30"
+ rx="0.5"
+ ry="0.5" />
+ </g>
+</svg>
Binary file images/smilies/face-sad.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/face-sad.svg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,282 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="face-sad.svg"
+ sodipodi:docbase="/home/jimmac/gfx/ximian/tango-desktop-theme/scalable/emotes"
+ inkscape:version="0.41+cvs"
+ sodipodi:version="0.32"
+ id="svg4376"
+ height="48px"
+ width="48px">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient3290">
+ <stop
+ style="stop-color:#fffcde;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop3292" />
+ <stop
+ id="stop3294"
+ offset="0.64485979"
+ style="stop-color:#f6e76a;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#ffb738;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3296" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3290"
+ id="radialGradient2714"
+ gradientUnits="userSpaceOnUse"
+ cx="29.288071"
+ cy="15.720984"
+ fx="29.158466"
+ fy="15.755712"
+ r="8.9020796" />
+ <linearGradient
+ id="linearGradient2509">
+ <stop
+ style="stop-color:#fffbd5;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2511" />
+ <stop
+ style="stop-color:#edd400;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2513" />
+ </linearGradient>
+ <radialGradient
+ gradientTransform="matrix(1.250000,0.000000,0.000000,-1.250000,-6.479446,73.66448)"
+ id="aigrd2"
+ cx="25.0527"
+ cy="39.5928"
+ r="15.7572"
+ fx="25.0527"
+ fy="39.5928"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#777777;stop-opacity:1.0000000;"
+ id="stop8602" />
+ <stop
+ offset="1"
+ style="stop-color:#000000"
+ id="stop8604" />
+ </radialGradient>
+ <linearGradient
+ id="linearGradient4565"
+ inkscape:collect="always">
+ <stop
+ id="stop4567"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop4569"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3824">
+ <stop
+ id="stop3826"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop3828"
+ offset="1.0000000"
+ style="stop-color:#c9c9c9;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3800">
+ <stop
+ id="stop3802"
+ offset="0.0000000"
+ style="stop-color:#ffeed6;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#e49c2f;stop-opacity:1.0000000;"
+ offset="0.50000000"
+ id="stop8664" />
+ <stop
+ id="stop3804"
+ offset="1.0000000"
+ style="stop-color:#ffc66c;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,0.000000,25.71429)"
+ r="19.714285"
+ fy="38.571430"
+ fx="24.714285"
+ cy="38.571430"
+ cx="24.714285"
+ id="radialGradient4571"
+ xlink:href="#linearGradient4565"
+ inkscape:collect="always" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-y="184"
+ inkscape:window-x="223"
+ inkscape:window-height="739"
+ inkscape:window-width="700"
+ inkscape:showpageshadow="false"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ showgrid="false"
+ inkscape:current-layer="layer1"
+ inkscape:cy="24.058534"
+ inkscape:cx="25.411306"
+ inkscape:zoom="11.313708"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ borderopacity="0.19607843"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ fill="#edd400" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF
+ id="RDF5">
+ <cc:Work
+ id="Work6"
+ rdf:about="">
+ <dc:format
+ id="format7">image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage"
+ id="type9" />
+ <dc:title
+ id="title8909">Face - Sad</dc:title>
+ <dc:subject
+ id="subject8911">
+ <rdf:Bag
+ id="Bag8913">
+ <rdf:li
+ id="li3283">emoticon</rdf:li>
+ <rdf:li
+ id="li3285">emote</rdf:li>
+ <rdf:li
+ id="li3287">smiley</rdf:li>
+ <rdf:li
+ id="li3289">sad</rdf:li>
+ <rdf:li
+ id="li3291">:(</rdf:li>
+ <rdf:li
+ id="li3293">:-(</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-nc-sa/2.0/"
+ id="license9103" />
+ <dc:creator
+ id="creator9121">
+ <cc:Agent
+ id="Agent9123">
+ <dc:title
+ id="title9125">Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source
+ id="source9127">http://jimmac.musichall.cz</dc:source>
+ </cc:Work>
+ <cc:License
+ id="License9105"
+ rdf:about="http://creativecommons.org/licenses/by-nc-sa/2.0/">
+ <cc:permits
+ id="permits9107"
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ id="permits9109"
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ id="requires9111"
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ id="requires9113"
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:prohibits
+ id="prohibits9115"
+ rdf:resource="http://web.resource.org/cc/CommercialUse" />
+ <cc:permits
+ id="permits9117"
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ id="requires9119"
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ id="layer1">
+ <path
+ d="M 44.428570 38.571430 A 19.714285 6.5714288 0 1 1 5.0000000,38.571430 A 19.714285 6.5714288 0 1 1 44.428570 38.571430 z"
+ sodipodi:ry="6.5714288"
+ sodipodi:rx="19.714285"
+ sodipodi:cy="38.571430"
+ sodipodi:cx="24.714285"
+ id="path4563"
+ style="opacity:0.53164557;color:#000000;fill:url(#radialGradient4571);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.40487173;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.083142,0.000000,0.000000,2.083142,-40.54715,-16.49224)"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4320"
+ style="opacity:1.0000000;color:#000000;fill:url(#radialGradient2714);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#9c8c0a;stroke-width:0.48004404;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(1.979782,0.000000,0.000000,1.979782,-37.33128,-14.52746)"
+ sodipodi:type="arc"
+ style="opacity:0.67721519;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.50510627;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4322"
+ sodipodi:cx="31.112698"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="8.6620579"
+ sodipodi:ry="8.6620579"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z" />
+ <path
+ sodipodi:nodetypes="czczc"
+ id="path1387"
+ d="M 34.014268,32.036842 C 30.290694,27.872830 28.451859,26.405561 24.462492,26.405561 C 20.561313,26.405561 17.962820,28.093607 15.087492,32.390396 C 18.520789,30.041583 20.397124,28.740900 24.197327,28.740900 C 27.909166,28.740900 29.948404,29.791599 34.014268,32.036842 z "
+ style="overflow:visible;display:inline;visibility:visible;stroke-opacity:1.0000000;stroke-dashoffset:0.0000000;stroke-dasharray:none;marker-end:none;marker-mid:none;marker-start:none;marker:none;stroke-linejoin:miter;stroke-linecap:butt;stroke-width:1.0000000;fill-opacity:1.0000000;color:#000000;opacity:0.35999998;stroke-miterlimit:4.0000000;stroke:none;fill-rule:nonzero;fill:#ffffff" />
+ <path
+ style="fill:url(#aigrd2);fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
+ d="M 34.014268,31.329738 C 30.290694,27.165726 28.451859,25.698457 24.462492,25.698457 C 20.561313,25.698457 17.962820,27.386503 15.087492,31.683292 C 18.520789,29.334479 20.397124,28.033796 24.197327,28.033796 C 27.909166,28.033796 29.948404,29.084495 34.014268,31.329738 z "
+ id="path8606"
+ sodipodi:nodetypes="czczc" />
+ <g
+ transform="translate(0.353553,2.392706)"
+ id="g8666">
+ <path
+ style="opacity:0.35999998;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
+ d="M 21.398158,15.321428 C 21.398158,17.821428 20.273158,19.821428 18.898158,19.821428 C 17.523158,19.821428 16.273158,17.821428 16.273158,15.321428 C 16.273158,12.821428 17.398158,10.821428 18.773158,10.821428 C 20.148158,10.821428 21.273158,12.821428 21.273158,15.321428 L 21.398158,15.321428 z "
+ id="path8610" />
+ <path
+ style="opacity:0.35999998;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
+ d="M 30.688512,15.321428 C 30.688512,17.821428 29.563512,19.821428 28.188512,19.821428 C 26.813512,19.821428 25.688512,17.821428 25.688512,15.321428 C 25.688512,12.821428 26.813512,10.821428 28.188512,10.821428 C 29.563512,10.821428 30.688512,12.821428 30.688512,15.321428 z "
+ id="path8612" />
+ <path
+ style="fill:#000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
+ d="M 21.398158,14.696428 C 21.398158,17.196428 20.273158,19.196428 18.898158,19.196428 C 17.523158,19.196428 16.398158,17.196428 16.398158,14.696428 C 16.398158,12.196428 17.523158,10.196428 18.898158,10.196428 C 20.273158,10.196428 21.398158,12.196428 21.398158,14.696428 z "
+ id="path8614" />
+ <path
+ style="fill:#000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
+ d="M 30.688512,14.696428 C 30.688512,17.196428 29.563512,19.196428 28.188512,19.196428 C 26.813512,19.196428 25.688512,17.196428 25.688512,14.696428 C 25.688512,12.196428 26.813512,10.196428 28.188512,10.196428 C 29.563512,10.196428 30.688512,12.196428 30.688512,14.696428 z "
+ id="path8616" />
+ </g>
+ </g>
+</svg>
Binary file images/smilies/face-sick.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/face-sick.svg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,342 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="face-sick.svg"
+ sodipodi:docbase="/home/dan/emotes"
+ inkscape:version="0.45"
+ sodipodi:version="0.32"
+ id="svg4376"
+ height="48px"
+ width="48px"
+ inkscape:export-filename="/home/steven/face-plain4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ sodipodi:modified="true">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient3290">
+ <stop
+ id="stop3292"
+ offset="0"
+ style="stop-color:#eaffde;stop-opacity:1;" />
+ <stop
+ style="stop-color:#7ce76a;stop-opacity:1;"
+ offset="0.64485979"
+ id="stop3294" />
+ <stop
+ id="stop3296"
+ offset="1"
+ style="stop-color:#5fb738;stop-opacity:1;" />
+ </linearGradient>
+ <radialGradient
+ r="8.9020796"
+ fy="15.755712"
+ fx="29.158466"
+ cy="15.720984"
+ cx="29.288071"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2714"
+ xlink:href="#linearGradient3290"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient2509">
+ <stop
+ style="stop-color:#fffbd5;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2511" />
+ <stop
+ style="stop-color:#edd400;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2513" />
+ </linearGradient>
+ <radialGradient
+ gradientTransform="matrix(1.25,0,0,1.25,53.52055,-13.37211)"
+ id="aigrd2"
+ cx="25.0527"
+ cy="39.5928"
+ r="15.7572"
+ fx="25.0527"
+ fy="39.5928"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#777777;stop-opacity:1.0000000;"
+ id="stop8602" />
+ <stop
+ offset="1"
+ style="stop-color:#000000"
+ id="stop8604" />
+ </radialGradient>
+ <linearGradient
+ id="linearGradient4565"
+ inkscape:collect="always">
+ <stop
+ id="stop4567"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop4569"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3824">
+ <stop
+ id="stop3826"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop3828"
+ offset="1.0000000"
+ style="stop-color:#c9c9c9;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3800">
+ <stop
+ id="stop3802"
+ offset="0.0000000"
+ style="stop-color:#ffeed6;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#e49c2f;stop-opacity:1.0000000;"
+ offset="0.50000000"
+ id="stop8664" />
+ <stop
+ id="stop3804"
+ offset="1.0000000"
+ style="stop-color:#ffc66c;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,0.000000,25.71429)"
+ r="19.714285"
+ fy="38.571430"
+ fx="24.714285"
+ cy="38.571430"
+ cx="24.714285"
+ id="radialGradient4571"
+ xlink:href="#linearGradient4565"
+ inkscape:collect="always" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd2"
+ id="radialGradient2211"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.25,0,0,1.25,39.41053,-19.20819)"
+ cx="25.0527"
+ cy="39.5928"
+ fx="25.0527"
+ fy="39.5928"
+ r="15.7572" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd2"
+ id="radialGradient1342"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.28431,0,0,0.416667,30.45155,18.23307)"
+ cx="-23.452122"
+ cy="38.602852"
+ fx="-23.452122"
+ fy="38.602852"
+ r="15.7572" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd2"
+ id="radialGradient3708"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.357899,0,0,0.416667,43.593456,21.78782)"
+ cx="-23.452122"
+ cy="38.602852"
+ fx="-23.452122"
+ fy="38.602852"
+ r="15.7572" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd2"
+ id="radialGradient3710"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3905938,0,0,0.4181379,-0.6770913,4.946314)"
+ cx="-23.452122"
+ cy="38.602852"
+ fx="-23.452122"
+ fy="38.602852"
+ r="15.7572" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-y="0"
+ inkscape:window-x="0"
+ inkscape:window-height="740"
+ inkscape:window-width="1024"
+ inkscape:showpageshadow="false"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ showgrid="false"
+ inkscape:current-layer="layer1"
+ inkscape:cy="22.183359"
+ inkscape:cx="28.123476"
+ inkscape:zoom="8"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ borderopacity="0.19607843"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ fill="#edd400" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Face - Plain</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>emoticon</rdf:li>
+ <rdf:li>emote</rdf:li>
+ <rdf:li>face</rdf:li>
+ <rdf:li>plain</rdf:li>
+ <rdf:li>:|</rdf:li>
+ <rdf:li>:-|</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Steven Garrity</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://www.tango-project.org</dc:source>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Based on face-smile by jimmac</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ id="layer1">
+ <path
+ d="M 44.428570 38.571430 A 19.714285 6.5714288 0 1 1 5.0000000,38.571430 A 19.714285 6.5714288 0 1 1 44.428570 38.571430 z"
+ sodipodi:ry="6.5714288"
+ sodipodi:rx="19.714285"
+ sodipodi:cy="38.571430"
+ sodipodi:cx="24.714285"
+ id="path4563"
+ style="opacity:0.53164557;color:#000000;fill:url(#radialGradient4571);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.40487173;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.083142,0,0,2.083142,-40.562775,-16.559948)"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.45064,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4320"
+ style="opacity:1;color:#000000;fill:url(#radialGradient2714);fill-opacity:1;fill-rule:evenodd;stroke:#518c0a;stroke-width:0.48004404;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(1.979782,0.000000,0.000000,1.979782,-37.33128,-14.52746)"
+ sodipodi:type="arc"
+ style="opacity:0.67721519;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.50510627;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4322"
+ sodipodi:cx="31.112698"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="8.6620579"
+ sodipodi:ry="8.6620579"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z" />
+ <g
+ transform="matrix(1,0,0,0.74952,0.353553,7.357569)"
+ id="g8666">
+ <path
+ style="opacity:0.36000001;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
+ d="M 21.398158,15.321428 C 21.398158,17.821428 20.273158,19.821428 18.898158,19.821428 C 17.523158,19.821428 16.273158,17.821428 16.273158,15.321428 C 16.273158,12.821428 17.398158,10.821428 18.773158,10.821428 C 20.148158,10.821428 21.273158,12.821428 21.273158,15.321428 L 21.398158,15.321428 z "
+ id="path8610" />
+ <path
+ style="opacity:0.36000001;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
+ d="M 30.688512,15.321428 C 30.688512,17.821428 29.563512,19.821428 28.188512,19.821428 C 26.813512,19.821428 25.688512,17.821428 25.688512,15.321428 C 25.688512,12.821428 26.813512,10.821428 28.188512,10.821428 C 29.563512,10.821428 30.688512,12.821428 30.688512,15.321428 z "
+ id="path8612" />
+ <path
+ style="fill:#000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
+ d="M 21.398158,14.696428 C 21.398158,17.196428 20.273158,19.196428 18.898158,19.196428 C 17.523158,19.196428 16.398158,17.196428 16.398158,14.696428 C 16.398158,12.196428 17.523158,10.196428 18.898158,10.196428 C 20.273158,10.196428 21.398158,12.196428 21.398158,14.696428 z "
+ id="path8614" />
+ <path
+ style="fill:#000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
+ d="M 30.688512,14.696428 C 30.688512,17.196428 29.563512,19.196428 28.188512,19.196428 C 26.813512,19.196428 25.688512,17.196428 25.688512,14.696428 C 25.688512,12.196428 26.813512,10.196428 28.188512,10.196428 C 29.563512,10.196428 30.688512,12.196428 30.688512,14.696428 z "
+ id="path8616" />
+ </g>
+ <g
+ id="g3702"
+ transform="matrix(1,0,0,1.20117,0,-6.1600994)">
+ <rect
+ style="opacity:0.36000001;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="rect3698"
+ width="20.48155"
+ height="1.00353"
+ x="-43.530239"
+ y="19.789228"
+ rx="0.51203877"
+ ry="0.50176501"
+ transform="matrix(-0.9376335,-0.3476254,-0.3645073,0.9312005,0,0)" />
+ <rect
+ transform="matrix(0.9344877,-0.3559953,0.3559953,0.9344877,0,0)"
+ ry="0.5"
+ rx="0.5"
+ y="35.578522"
+ x="1.7478458"
+ height="1"
+ width="20"
+ id="rect2453"
+ style="opacity:1;color:#000000;fill:url(#radialGradient3708);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <rect
+ transform="matrix(0.9344877,-0.3559953,0.3559953,0.9344877,0,0)"
+ ry="0.5"
+ rx="0.5"
+ y="36.578522"
+ x="1.7478458"
+ height="1"
+ width="20"
+ id="rect1336"
+ style="opacity:0.36000001;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <rect
+ style="opacity:1;color:#000000;fill:url(#radialGradient3710);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="rect3696"
+ width="20.48155"
+ height="1.00353"
+ x="-43.530239"
+ y="18.785698"
+ rx="0.51203877"
+ ry="0.50176501"
+ transform="matrix(-0.9376335,-0.3476254,-0.3645073,0.9312005,0,0)" />
+ </g>
+ </g>
+</svg>
Binary file images/smilies/face-smile-big.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/face-smile-big.svg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,257 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48px"
+ height="48px"
+ id="svg4376"
+ sodipodi:version="0.32"
+ inkscape:version="0.43+devel"
+ sodipodi:docbase="/home/tigert/cvs/freedesktop.org/tango-icon-theme/scalable/emotes"
+ sodipodi:docname="face-smile-big.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient3290">
+ <stop
+ style="stop-color:#fffcde;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop3292" />
+ <stop
+ id="stop3294"
+ offset="0.64485979"
+ style="stop-color:#f6e76a;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#ffb738;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3296" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3068">
+ <stop
+ style="stop-color:#696969;stop-opacity:1;"
+ offset="0"
+ id="stop3070" />
+ <stop
+ id="stop3076"
+ offset="0.34579438"
+ style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.72486681"
+ id="stop3078" />
+ <stop
+ style="stop-color:#5c5c5c;stop-opacity:1;"
+ offset="1"
+ id="stop3072" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3050">
+ <stop
+ style="stop-color:#a40000;stop-opacity:1;"
+ offset="0"
+ id="stop3052" />
+ <stop
+ style="stop-color:#ec0000;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3054" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4565">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop4567" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop4569" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4565"
+ id="radialGradient1360"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,0.000000,25.71429)"
+ cx="24.714285"
+ cy="38.571430"
+ fx="24.714285"
+ fy="38.571430"
+ r="19.714285" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3290"
+ id="radialGradient1362"
+ gradientUnits="userSpaceOnUse"
+ cx="29.288071"
+ cy="15.720984"
+ fx="29.158466"
+ fy="15.755712"
+ r="8.9020796" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3068"
+ id="linearGradient1372"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.900635,0,0,0.512797,2.616633,10.42827)"
+ x1="11.250000"
+ y1="26.093750"
+ x2="36.875000"
+ y2="26.093750" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3050"
+ id="linearGradient1375"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.900634,0,0,0.512797,2.420862,9.703722)"
+ x1="23.031250"
+ y1="24.312500"
+ x2="23.031250"
+ y2="36.249878" />
+ </defs>
+ <sodipodi:namedview
+ fill="#a40000"
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.19607843"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="5.6568542"
+ inkscape:cx="39.083834"
+ inkscape:cy="29.929519"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="872"
+ inkscape:window-height="767"
+ inkscape:window-x="234"
+ inkscape:window-y="186"
+ stroke="#a40000" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Face - Laughing</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>emoticon</rdf:li>
+ <rdf:li>emote</rdf:li>
+ <rdf:li>smiley</rdf:li>
+ <rdf:li>laughing</rdf:li>
+ <rdf:li>:-D</rdf:li>
+ <rdf:li>:D</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.53164560;color:#000000;fill:url(#radialGradient1360);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.40487173;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4563"
+ sodipodi:cx="24.714285"
+ sodipodi:cy="38.571430"
+ sodipodi:rx="19.714285"
+ sodipodi:ry="6.5714288"
+ d="M 44.428570 38.571430 A 19.714285 6.5714288 0 1 1 5.0000000,38.571430 A 19.714285 6.5714288 0 1 1 44.428570 38.571430 z" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1.0000000;color:#000000;fill:url(#radialGradient1362);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#9c8c0a;stroke-width:0.48004404;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4320"
+ sodipodi:cx="31.112698"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="8.6620579"
+ sodipodi:ry="8.6620579"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ transform="matrix(2.083142,0.000000,0.000000,2.083142,-40.54715,-16.49224)" />
+ <path
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4322"
+ style="opacity:0.67721522;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.50510627;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc"
+ transform="matrix(1.979782,0.000000,0.000000,1.979782,-37.33128,-14.52746)" />
+ <path
+ style="opacity:1;color:#000000;fill:url(#linearGradient1375);fill-opacity:1;fill-rule:nonzero;stroke:#a40000;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 12.46856,21.582101 C 9.8316492,20.960126 14.333556,28.420831 24.261236,28.420831 C 34.091034,28.420831 38.930429,20.977414 36.053912,21.582101 C 28.547558,23.160051 18.888402,23.096367 12.46856,21.582101 z "
+ id="path2756"
+ sodipodi:nodetypes="czss" />
+ <path
+ style="opacity:1;color:#000000;fill:url(#linearGradient1372);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 13.536826,24.177654 L 35.068859,24.117737 C 35.851954,23.198123 36.967052,21.745691 36.121189,21.874738 C 28.097871,23.098802 19.550104,23.670967 12.259336,21.774407 C 11.09799,21.472303 12.411126,23.397376 13.536826,24.177654 z "
+ id="path3058"
+ sodipodi:nodetypes="ccssc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;fill-opacity:1.0000000;stroke:#555753;stroke-width:1.0000000;stroke-linecap:butt;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
+ id="path1364"
+ sodipodi:cx="-3.8125000"
+ sodipodi:cy="1.8750000"
+ sodipodi:rx="2.9375000"
+ sodipodi:ry="2.8750000"
+ d="M -0.87500000,1.8750000 A 2.9375000,2.8750000 0 0 1 -6.3564497,3.3124999"
+ sodipodi:start="0.0000000"
+ sodipodi:end="2.6179939"
+ sodipodi:open="true"
+ transform="matrix(-0.965926,-0.258819,0.258819,-0.965926,24.53442,17.20131)" />
+ <path
+ transform="matrix(-0.965926,-0.258819,0.258819,-0.965926,15.78442,17.20131)"
+ sodipodi:open="true"
+ sodipodi:end="2.6179939"
+ sodipodi:start="0.0000000"
+ d="M -0.87500000,1.8750000 A 2.9375000,2.8750000 0 0 1 -6.3564497,3.3124999"
+ sodipodi:ry="2.8750000"
+ sodipodi:rx="2.9375000"
+ sodipodi:cy="1.8750000"
+ sodipodi:cx="-3.8125000"
+ id="path2094"
+ style="fill:none;fill-opacity:1.0000000;stroke:#555753;stroke-width:1.0000000;stroke-linecap:butt;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
+ sodipodi:type="arc" />
+ </g>
+</svg>
Binary file images/smilies/face-smile.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/face-smile.svg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,254 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="face-happy.svg"
+ sodipodi:docbase="/home/jimmac/gfx/ximian/tango-icon-theme/scalable/emotes"
+ inkscape:version="0.42+devel"
+ sodipodi:version="0.32"
+ id="svg4376"
+ height="48px"
+ width="48px">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient3290">
+ <stop
+ id="stop3292"
+ offset="0.0000000"
+ style="stop-color:#fffcde;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#f6e76a;stop-opacity:1.0000000;"
+ offset="0.64485979"
+ id="stop3294" />
+ <stop
+ id="stop3296"
+ offset="1.0000000"
+ style="stop-color:#ffb738;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ r="8.9020796"
+ fy="15.755712"
+ fx="29.158466"
+ cy="15.720984"
+ cx="29.288071"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2714"
+ xlink:href="#linearGradient3290"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient2509">
+ <stop
+ style="stop-color:#fffbd5;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2511" />
+ <stop
+ style="stop-color:#edd400;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2513" />
+ </linearGradient>
+ <radialGradient
+ gradientTransform="matrix(1.250000,0.000000,0.000000,1.250000,-6.479446,-13.37211)"
+ id="aigrd2"
+ cx="25.0527"
+ cy="39.5928"
+ r="15.7572"
+ fx="25.0527"
+ fy="39.5928"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#777777;stop-opacity:1.0000000;"
+ id="stop8602" />
+ <stop
+ offset="1"
+ style="stop-color:#000000"
+ id="stop8604" />
+ </radialGradient>
+ <linearGradient
+ id="linearGradient4565"
+ inkscape:collect="always">
+ <stop
+ id="stop4567"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop4569"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3824">
+ <stop
+ id="stop3826"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop3828"
+ offset="1.0000000"
+ style="stop-color:#c9c9c9;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3800">
+ <stop
+ id="stop3802"
+ offset="0.0000000"
+ style="stop-color:#ffeed6;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#e49c2f;stop-opacity:1.0000000;"
+ offset="0.50000000"
+ id="stop8664" />
+ <stop
+ id="stop3804"
+ offset="1.0000000"
+ style="stop-color:#ffc66c;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,0.000000,25.71429)"
+ r="19.714285"
+ fy="38.571430"
+ fx="24.714285"
+ cy="38.571430"
+ cx="24.714285"
+ id="radialGradient4571"
+ xlink:href="#linearGradient4565"
+ inkscape:collect="always" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-y="184"
+ inkscape:window-x="223"
+ inkscape:window-height="739"
+ inkscape:window-width="770"
+ inkscape:showpageshadow="false"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ showgrid="false"
+ inkscape:current-layer="layer1"
+ inkscape:cy="24.058534"
+ inkscape:cx="25.411306"
+ inkscape:zoom="11.313708"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ borderopacity="0.19607843"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ fill="#edd400" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Face - Happy</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>emoticon</rdf:li>
+ <rdf:li>emote</rdf:li>
+ <rdf:li>smiley</rdf:li>
+ <rdf:li>happy</rdf:li>
+ <rdf:li>:)</rdf:li>
+ <rdf:li>:-)</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ id="layer1">
+ <path
+ d="M 44.428570 38.571430 A 19.714285 6.5714288 0 1 1 5.0000000,38.571430 A 19.714285 6.5714288 0 1 1 44.428570 38.571430 z"
+ sodipodi:ry="6.5714288"
+ sodipodi:rx="19.714285"
+ sodipodi:cy="38.571430"
+ sodipodi:cx="24.714285"
+ id="path4563"
+ style="opacity:0.53164557;color:#000000;fill:url(#radialGradient4571);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.40487173;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.083142,0.000000,0.000000,2.083142,-40.54715,-16.49224)"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4320"
+ style="overflow:visible;display:inline;visibility:visible;stroke-opacity:1.0000000;stroke-dashoffset:0.0000000;stroke-dasharray:none;stroke-miterlimit:4.0000000;marker-end:none;marker-mid:none;marker-start:none;marker:none;stroke-linejoin:round;stroke-linecap:round;stroke-width:0.48004404;stroke:#9c8c0a;fill-rule:evenodd;fill-opacity:1.0000000;fill:url(#radialGradient2714);color:#000000;opacity:1.0000000"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(1.979782,0.000000,0.000000,1.979782,-37.33128,-14.52746)"
+ sodipodi:type="arc"
+ style="opacity:0.67721519;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.50510627;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4322"
+ sodipodi:cx="31.112698"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="8.6620579"
+ sodipodi:ry="8.6620579"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z" />
+ <path
+ sodipodi:nodetypes="czczc"
+ id="path2659"
+ d="M 37.284637,24.719966 C 34.268170,29.944639 30.741134,33.710005 24.462492,33.710005 C 18.362475,33.710005 13.896955,29.370308 11.110016,24.543189 C 13.659429,27.599109 17.392948,31.109501 24.197327,31.109501 C 32.327531,31.109501 33.749103,28.202646 37.284637,24.719966 z "
+ style="opacity:0.35999998;color:#000000;fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
+ <path
+ style="fill:url(#aigrd2);fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
+ d="M 37.284637,24.012862 C 34.268170,29.237535 30.741134,33.002901 24.462492,33.002901 C 18.362475,33.002901 13.896955,28.663204 11.110016,23.836085 C 13.659429,26.892005 17.392948,30.402397 24.197327,30.402397 C 32.327531,30.402397 33.749103,27.495542 37.284637,24.012862 z "
+ id="path8606"
+ sodipodi:nodetypes="czczc" />
+ <g
+ transform="translate(0.353553,2.392706)"
+ id="g8666">
+ <path
+ style="opacity:0.35999998;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
+ d="M 21.398158,15.321428 C 21.398158,17.821428 20.273158,19.821428 18.898158,19.821428 C 17.523158,19.821428 16.273158,17.821428 16.273158,15.321428 C 16.273158,12.821428 17.398158,10.821428 18.773158,10.821428 C 20.148158,10.821428 21.273158,12.821428 21.273158,15.321428 L 21.398158,15.321428 z "
+ id="path8610" />
+ <path
+ style="opacity:0.35999998;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
+ d="M 30.688512,15.321428 C 30.688512,17.821428 29.563512,19.821428 28.188512,19.821428 C 26.813512,19.821428 25.688512,17.821428 25.688512,15.321428 C 25.688512,12.821428 26.813512,10.821428 28.188512,10.821428 C 29.563512,10.821428 30.688512,12.821428 30.688512,15.321428 z "
+ id="path8612" />
+ <path
+ style="fill:#000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
+ d="M 21.398158,14.696428 C 21.398158,17.196428 20.273158,19.196428 18.898158,19.196428 C 17.523158,19.196428 16.398158,17.196428 16.398158,14.696428 C 16.398158,12.196428 17.523158,10.196428 18.898158,10.196428 C 20.273158,10.196428 21.398158,12.196428 21.398158,14.696428 z "
+ id="path8614" />
+ <path
+ style="fill:#000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
+ d="M 30.688512,14.696428 C 30.688512,17.196428 29.563512,19.196428 28.188512,19.196428 C 26.813512,19.196428 25.688512,17.196428 25.688512,14.696428 C 25.688512,12.196428 26.813512,10.196428 28.188512,10.196428 C 29.563512,10.196428 30.688512,12.196428 30.688512,14.696428 z "
+ id="path8616" />
+ </g>
+ </g>
+</svg>
Binary file images/smilies/face-surprise.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/face-surprise.svg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,252 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48px"
+ height="48px"
+ id="svg4376"
+ sodipodi:version="0.32"
+ inkscape:version="0.42+devel"
+ sodipodi:docbase="/home/jimmac/gfx/ximian/tango-icon-theme/scalable/emotes"
+ sodipodi:docname="face-shocked.svg">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient3290">
+ <stop
+ id="stop3292"
+ offset="0.0000000"
+ style="stop-color:#fffcde;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#f6e76a;stop-opacity:1.0000000;"
+ offset="0.64485979"
+ id="stop3294" />
+ <stop
+ id="stop3296"
+ offset="1.0000000"
+ style="stop-color:#ffb738;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ r="8.9020796"
+ fy="15.755712"
+ fx="29.158466"
+ cy="15.720984"
+ cx="29.288071"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2714"
+ xlink:href="#linearGradient3290"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient2509">
+ <stop
+ id="stop2511"
+ offset="0.0000000"
+ style="stop-color:#fffbd5;stop-opacity:1.0000000;" />
+ <stop
+ id="stop2513"
+ offset="1.0000000"
+ style="stop-color:#edd400;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ fy="39.5928"
+ fx="25.0527"
+ r="15.7572"
+ cy="39.5928"
+ cx="25.0527"
+ id="aigrd2"
+ gradientTransform="matrix(1.250000,0.000000,0.000000,1.250000,-6.214281,-8.428572)">
+ <stop
+ id="stop8602"
+ style="stop-color:#777777;stop-opacity:1.0000000;"
+ offset="0.0000000" />
+ <stop
+ id="stop8604"
+ style="stop-color:#000000"
+ offset="1" />
+ </radialGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4565">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop4567" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop4569" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3824">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3826" />
+ <stop
+ style="stop-color:#c9c9c9;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3828" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3800">
+ <stop
+ style="stop-color:#ffeed6;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop3802" />
+ <stop
+ id="stop8664"
+ offset="0.50000000"
+ style="stop-color:#e49c2f;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#ffc66c;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3804" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4565"
+ id="radialGradient4571"
+ cx="24.714285"
+ cy="38.571430"
+ fx="24.714285"
+ fy="38.571430"
+ r="19.714285"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,0.000000,25.71429)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ fill="#edd400"
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.19607843"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="11.313708"
+ inkscape:cx="25.411306"
+ inkscape:cy="24.058534"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="770"
+ inkscape:window-height="739"
+ inkscape:window-x="223"
+ inkscape:window-y="184" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Face - Shocked</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>emoticon</rdf:li>
+ <rdf:li>emote</rdf:li>
+ <rdf:li>smiley</rdf:li>
+ <rdf:li>stare</rdf:li>
+ <rdf:li>shocked</rdf:li>
+ <rdf:li>:O</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.53164557;color:#000000;fill:url(#radialGradient4571);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.40487173;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4563"
+ sodipodi:cx="24.714285"
+ sodipodi:cy="38.571430"
+ sodipodi:rx="19.714285"
+ sodipodi:ry="6.5714288"
+ d="M 44.428570 38.571430 A 19.714285 6.5714288 0 1 1 5.0000000,38.571430 A 19.714285 6.5714288 0 1 1 44.428570 38.571430 z" />
+ <path
+ sodipodi:type="arc"
+ style="overflow:visible;display:inline;visibility:visible;stroke-opacity:1.0000000;stroke-dashoffset:0.0000000;stroke-dasharray:none;stroke-miterlimit:4.0000000;marker-end:none;marker-mid:none;marker-start:none;marker:none;stroke-linejoin:round;stroke-linecap:round;stroke-width:0.48004404;stroke:#9c8c0a;fill-rule:evenodd;fill-opacity:1.0000000;fill:url(#radialGradient2714);color:#000000;opacity:1.0000000"
+ id="path4320"
+ sodipodi:cx="31.112698"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="8.6620579"
+ sodipodi:ry="8.6620579"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ transform="matrix(2.083142,0.000000,0.000000,2.083142,-40.54715,-16.49224)" />
+ <path
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4322"
+ style="opacity:0.67721519;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.50510627;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc"
+ transform="matrix(1.979782,0.000000,0.000000,1.979782,-37.33128,-14.52746)" />
+ <path
+ id="path8599"
+ d="M 33.660715,32.696428 C 33.660715,36.196428 29.410715,38.946428 24.285715,38.946428 C 19.160715,38.946428 14.910715,36.196428 14.910715,32.696428 C 14.910715,29.196428 19.160715,26.446428 24.285715,26.446428 C 29.410715,26.446428 33.660715,29.196428 33.660715,32.696428 z "
+ style="opacity:0.35999998;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
+ <path
+ id="path8606"
+ d="M 33.660715,31.696428 C 33.660715,35.196428 29.410715,37.946428 24.285715,37.946428 C 19.160715,37.946428 14.910715,35.196428 14.910715,31.696428 C 14.910715,28.196428 19.160715,25.446428 24.285715,25.446428 C 29.410715,25.446428 33.660715,28.196428 33.660715,31.696428 z "
+ style="fill:url(#aigrd2);fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
+ <g
+ id="g8666"
+ transform="translate(0.265165,0.000000)">
+ <path
+ id="path8610"
+ d="M 21.398158,15.321428 C 21.398158,17.821428 20.273158,19.821428 18.898158,19.821428 C 17.523158,19.821428 16.273158,17.821428 16.273158,15.321428 C 16.273158,12.821428 17.398158,10.821428 18.773158,10.821428 C 20.148158,10.821428 21.273158,12.821428 21.273158,15.321428 L 21.398158,15.321428 z "
+ style="opacity:0.35999998;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
+ <path
+ id="path8612"
+ d="M 30.688512,15.321428 C 30.688512,17.821428 29.563512,19.821428 28.188512,19.821428 C 26.813512,19.821428 25.688512,17.821428 25.688512,15.321428 C 25.688512,12.821428 26.813512,10.821428 28.188512,10.821428 C 29.563512,10.821428 30.688512,12.821428 30.688512,15.321428 z "
+ style="opacity:0.35999998;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
+ <path
+ id="path8614"
+ d="M 21.398158,14.696428 C 21.398158,17.196428 20.273158,19.196428 18.898158,19.196428 C 17.523158,19.196428 16.398158,17.196428 16.398158,14.696428 C 16.398158,12.196428 17.523158,10.196428 18.898158,10.196428 C 20.273158,10.196428 21.398158,12.196428 21.398158,14.696428 z "
+ style="fill:#000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
+ <path
+ id="path8616"
+ d="M 30.688512,14.696428 C 30.688512,17.196428 29.563512,19.196428 28.188512,19.196428 C 26.813512,19.196428 25.688512,17.196428 25.688512,14.696428 C 25.688512,12.196428 26.813512,10.196428 28.188512,10.196428 C 29.563512,10.196428 30.688512,12.196428 30.688512,14.696428 z "
+ style="fill:#000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
+ </g>
+ </g>
+</svg>
Binary file images/smilies/face-tongue-out.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/face-tongue-out.svg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,298 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48px"
+ height="48px"
+ id="svg4376"
+ sodipodi:version="0.32"
+ inkscape:version="0.45"
+ sodipodi:docbase="/home/dan/emotes"
+ sodipodi:docname="face-smile-big.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ sodipodi:modified="true">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient3976">
+ <stop
+ id="stop3978"
+ offset="0"
+ style="stop-color:#a40000;stop-opacity:1;" />
+ <stop
+ id="stop3980"
+ offset="1"
+ style="stop-color:#6a0000;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3290">
+ <stop
+ style="stop-color:#fffcde;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop3292" />
+ <stop
+ id="stop3294"
+ offset="0.64485979"
+ style="stop-color:#f6e76a;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#ffb738;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3296" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3068">
+ <stop
+ style="stop-color:#696969;stop-opacity:1;"
+ offset="0"
+ id="stop3070" />
+ <stop
+ id="stop3076"
+ offset="0.34579438"
+ style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.72486681"
+ id="stop3078" />
+ <stop
+ style="stop-color:#5c5c5c;stop-opacity:1;"
+ offset="1"
+ id="stop3072" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3050">
+ <stop
+ style="stop-color:#a40000;stop-opacity:1;"
+ offset="0"
+ id="stop3052" />
+ <stop
+ style="stop-color:#ec0000;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3054" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4565">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop4567" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop4569" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4565"
+ id="radialGradient1360"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,0.000000,25.71429)"
+ cx="24.714285"
+ cy="38.571430"
+ fx="24.714285"
+ fy="38.571430"
+ r="19.714285" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3290"
+ id="radialGradient1362"
+ gradientUnits="userSpaceOnUse"
+ cx="29.288071"
+ cy="15.720984"
+ fx="29.158466"
+ fy="15.755712"
+ r="8.9020796" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3068"
+ id="linearGradient1372"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.900635,0,0,0.512797,2.616633,10.42827)"
+ x1="11.250000"
+ y1="26.093750"
+ x2="36.875000"
+ y2="26.093750" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3050"
+ id="linearGradient1375"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.900634,0,0,0.512797,2.420862,9.703722)"
+ x1="23.031250"
+ y1="24.312500"
+ x2="23.031250"
+ y2="36.249878" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3050"
+ id="linearGradient3966"
+ x1="24.692268"
+ y1="36.41777"
+ x2="24.692268"
+ y2="26.339582"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.5820313,-1.4726563)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3976"
+ id="linearGradient3974"
+ x1="23.838776"
+ y1="25.481133"
+ x2="23.838776"
+ y2="36.279236"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.5820313,-1.4726563)" />
+ </defs>
+ <sodipodi:namedview
+ fill="#a40000"
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.19607843"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="7.9999999"
+ inkscape:cx="24.321501"
+ inkscape:cy="24"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="1024"
+ inkscape:window-height="740"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ stroke="#a40000" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Face - Laughing</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>emoticon</rdf:li>
+ <rdf:li>emote</rdf:li>
+ <rdf:li>smiley</rdf:li>
+ <rdf:li>laughing</rdf:li>
+ <rdf:li>:-D</rdf:li>
+ <rdf:li>:D</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.53164560;color:#000000;fill:url(#radialGradient1360);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.40487173;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4563"
+ sodipodi:cx="24.714285"
+ sodipodi:cy="38.571430"
+ sodipodi:rx="19.714285"
+ sodipodi:ry="6.5714288"
+ d="M 44.428570 38.571430 A 19.714285 6.5714288 0 1 1 5.0000000,38.571430 A 19.714285 6.5714288 0 1 1 44.428570 38.571430 z" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1.0000000;color:#000000;fill:url(#radialGradient1362);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#9c8c0a;stroke-width:0.48004404;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4320"
+ sodipodi:cx="31.112698"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="8.6620579"
+ sodipodi:ry="8.6620579"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ transform="matrix(2.083142,0.000000,0.000000,2.083142,-40.54715,-16.49224)" />
+ <path
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4322"
+ style="opacity:0.67721522;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.50510627;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc"
+ transform="matrix(1.979782,0.000000,0.000000,1.979782,-37.33128,-14.52746)" />
+ <path
+ style="opacity:1;color:#000000;fill:url(#linearGradient1375);fill-opacity:1;fill-rule:nonzero;stroke:#a40000;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 12.46856,21.582101 C 9.8316492,20.960126 14.333556,28.420831 24.261236,28.420831 C 34.091034,28.420831 38.930429,20.977414 36.053912,21.582101 C 28.547558,23.160051 18.888402,23.096367 12.46856,21.582101 z "
+ id="path2756"
+ sodipodi:nodetypes="czss" />
+ <path
+ style="opacity:1;color:#000000;fill:url(#linearGradient1372);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 13.536826,24.177654 L 35.068859,24.117737 C 35.851954,23.198123 36.967052,21.745691 36.121189,21.874738 C 28.097871,23.098802 19.550104,23.670967 12.259336,21.774407 C 11.09799,21.472303 12.411126,23.397376 13.536826,24.177654 z "
+ id="path3058"
+ sodipodi:nodetypes="ccssc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;fill-opacity:1.0000000;stroke:#555753;stroke-width:1.0000000;stroke-linecap:butt;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
+ id="path1364"
+ sodipodi:cx="-3.8125000"
+ sodipodi:cy="1.8750000"
+ sodipodi:rx="2.9375000"
+ sodipodi:ry="2.8750000"
+ d="M -0.87500000,1.8750000 A 2.9375000,2.8750000 0 0 1 -6.3564497,3.3124999"
+ sodipodi:start="0.0000000"
+ sodipodi:end="2.6179939"
+ sodipodi:open="true"
+ transform="matrix(-0.965926,-0.258819,0.258819,-0.965926,24.53442,17.20131)" />
+ <path
+ transform="matrix(-0.965926,-0.258819,0.258819,-0.965926,15.78442,17.20131)"
+ sodipodi:open="true"
+ sodipodi:end="2.6179939"
+ sodipodi:start="0.0000000"
+ d="M -0.87500000,1.8750000 A 2.9375000,2.8750000 0 0 1 -6.3564497,3.3124999"
+ sodipodi:ry="2.8750000"
+ sodipodi:rx="2.9375000"
+ sodipodi:cy="1.8750000"
+ sodipodi:cx="-3.8125000"
+ id="path2094"
+ style="fill:none;fill-opacity:1.0000000;stroke:#555753;stroke-width:1.0000000;stroke-linecap:butt;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
+ sodipodi:type="arc" />
+ <path
+ style="fill:url(#linearGradient3966);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3974);stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 20.746765,24.465604 C 20.720179,24.443774 19.4343,30.356408 20.839213,32.80155 C 21.198259,33.601658 21.843112,35.125247 23.883409,35.125247 C 25.923707,35.125247 26.510689,34.47698 27.452089,32.643008 C 28.684434,30.068783 27.19429,24.450133 27.19429,24.450133 L 20.746765,24.465604 z "
+ id="path2989"
+ sodipodi:nodetypes="ccsccc" />
+ <path
+ style="fill:#360000;fill-opacity:1;fill-rule:evenodd;stroke:#460000;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 24.303289,25.52862 C 24.303289,25.52862 23.056987,28.928613 24.02065,33.856952 C 23.075842,28.78291 24.280044,25.448151 24.303289,25.52862 z "
+ id="path4951"
+ sodipodi:nodetypes="ccc" />
+ </g>
+</svg>
Binary file images/smilies/face-wink.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/smilies/face-wink.svg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,268 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="face-wink.svg"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/emotes"
+ inkscape:version="0.42+devel"
+ sodipodi:version="0.32"
+ id="svg4376"
+ height="48px"
+ width="48px">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient3290">
+ <stop
+ id="stop3292"
+ offset="0.0000000"
+ style="stop-color:#fffcde;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#f6e76a;stop-opacity:1.0000000;"
+ offset="0.64485979"
+ id="stop3294" />
+ <stop
+ id="stop3296"
+ offset="1.0000000"
+ style="stop-color:#ffb738;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ r="8.9020796"
+ fy="15.755712"
+ fx="29.158466"
+ cy="15.720984"
+ cx="29.288071"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2714"
+ xlink:href="#linearGradient3290"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient2509">
+ <stop
+ style="stop-color:#fffbd5;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2511" />
+ <stop
+ style="stop-color:#edd400;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2513" />
+ </linearGradient>
+ <radialGradient
+ gradientTransform="matrix(1.250000,0.000000,0.000000,1.250000,-6.479446,-13.37211)"
+ id="aigrd2"
+ cx="25.0527"
+ cy="39.5928"
+ r="15.7572"
+ fx="25.0527"
+ fy="39.5928"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0.0000000"
+ style="stop-color:#777777;stop-opacity:1.0000000;"
+ id="stop8602" />
+ <stop
+ offset="1"
+ style="stop-color:#000000"
+ id="stop8604" />
+ </radialGradient>
+ <linearGradient
+ id="linearGradient4565"
+ inkscape:collect="always">
+ <stop
+ id="stop4567"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop4569"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3824">
+ <stop
+ id="stop3826"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop3828"
+ offset="1.0000000"
+ style="stop-color:#c9c9c9;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3800">
+ <stop
+ id="stop3802"
+ offset="0.0000000"
+ style="stop-color:#ffeed6;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#e49c2f;stop-opacity:1.0000000;"
+ offset="0.50000000"
+ id="stop8664" />
+ <stop
+ id="stop3804"
+ offset="1.0000000"
+ style="stop-color:#ffc66c;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.333333,0.000000,25.71429)"
+ r="19.714285"
+ fy="38.571430"
+ fx="24.714285"
+ cy="38.571430"
+ cx="24.714285"
+ id="radialGradient4571"
+ xlink:href="#linearGradient4565"
+ inkscape:collect="always" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd2"
+ id="radialGradient3279"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.250000,0.000000,0.000000,1.250000,-6.479446,-13.37211)"
+ cx="25.0527"
+ cy="39.5928"
+ fx="25.0527"
+ fy="39.5928"
+ r="15.7572" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-y="108"
+ inkscape:window-x="556"
+ inkscape:window-height="739"
+ inkscape:window-width="872"
+ inkscape:showpageshadow="false"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ showgrid="false"
+ inkscape:current-layer="layer1"
+ inkscape:cy="37.652189"
+ inkscape:cx="23.88386"
+ inkscape:zoom="1"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ borderopacity="0.19607843"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ fill="#edd400" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Face - Wink</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>emoticon</rdf:li>
+ <rdf:li>emote</rdf:li>
+ <rdf:li>winkie</rdf:li>
+ <rdf:li>wink</rdf:li>
+ <rdf:li>;)</rdf:li>
+ <rdf:li>;-)</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ <dc:description />
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Corey Woodworth</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ id="layer1">
+ <path
+ d="M 44.428570 38.571430 A 19.714285 6.5714288 0 1 1 5.0000000,38.571430 A 19.714285 6.5714288 0 1 1 44.428570 38.571430 z"
+ sodipodi:ry="6.5714288"
+ sodipodi:rx="19.714285"
+ sodipodi:cy="38.571430"
+ sodipodi:cx="24.714285"
+ id="path4563"
+ style="opacity:0.53164557;color:#000000;fill:url(#radialGradient4571);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:0.40487173;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.083142,0.000000,0.000000,2.083142,-40.54715,-16.49224)"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4320"
+ style="overflow:visible;display:inline;visibility:visible;stroke-opacity:1.0000000;stroke-dashoffset:0.0000000;stroke-dasharray:none;stroke-miterlimit:4.0000000;marker-end:none;marker-mid:none;marker-start:none;marker:none;stroke-linejoin:round;stroke-linecap:round;stroke-width:0.48004404;stroke:#9c8c0a;fill-rule:evenodd;fill-opacity:1.0000000;fill:url(#radialGradient2714);color:#000000;opacity:1.0000000"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(1.979782,0.000000,0.000000,1.979782,-37.33128,-14.52746)"
+ sodipodi:type="arc"
+ style="opacity:0.67721519;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.50510627;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ id="path4322"
+ sodipodi:cx="31.112698"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="8.6620579"
+ sodipodi:ry="8.6620579"
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.450640,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z" />
+ <g
+ id="g3267"
+ transform="matrix(0.969372,0.245598,-0.245598,0.969372,6.456937,-5.230004)">
+ <path
+ style="opacity:0.35999998;color:#000000;fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
+ d="M 37.284637,24.719966 C 34.268170,29.944639 30.741134,33.710005 24.462492,33.710005 C 18.362475,33.710005 13.896955,29.370308 11.110016,24.543189 C 13.659429,27.599109 17.392948,31.109501 24.197327,31.109501 C 32.327531,31.109501 33.749103,28.202646 37.284637,24.719966 z "
+ id="path2659"
+ sodipodi:nodetypes="czczc" />
+ <path
+ sodipodi:nodetypes="czczc"
+ id="path8606"
+ d="M 37.284637,24.012862 C 34.268170,29.237535 30.741134,33.002901 24.462492,33.002901 C 18.362475,33.002901 13.896955,28.663204 11.110016,23.836085 C 13.659429,26.892005 17.392948,30.402397 24.197327,30.402397 C 32.327531,30.402397 33.749103,27.495542 37.284637,24.012862 z "
+ style="fill:url(#radialGradient3279);fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
+ </g>
+ <path
+ id="path8612"
+ d="M 31.042065,17.714134 C 31.042065,20.214134 29.917065,22.214134 28.542065,22.214134 C 27.167065,22.214134 26.042065,20.214134 26.042065,17.714134 C 26.042065,15.214134 27.167065,13.214134 28.542065,13.214134 C 29.917065,13.214134 31.042065,15.214134 31.042065,17.714134 z "
+ style="opacity:0.35999998;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
+ <path
+ id="path8616"
+ d="M 31.042065,17.089134 C 31.042065,19.589134 29.917065,21.589134 28.542065,21.589134 C 27.167065,21.589134 26.042065,19.589134 26.042065,17.089134 C 26.042065,14.589134 27.167065,12.589134 28.542065,12.589134 C 29.917065,12.589134 31.042065,14.589134 31.042065,17.089134 z "
+ style="fill:#000000;fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
+ <path
+ style="opacity:1;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.0000006;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 15.924926,17.535184 C 17.28643,14.190727 20.768376,14.102908 21.99369,17.42035 C 19.832621,15.70722 17.845598,16.200617 15.924926,17.535184 z "
+ id="path1336"
+ sodipodi:nodetypes="ccc" />
+ </g>
+</svg>
Binary file images/spacer.gif has changed
Binary file images/thumbnail.png has changed
Binary file images/unknown.gif has changed
Binary file images/wait.png has changed
Binary file images/warning.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/index.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,425 @@
+<?php
+/**
+ * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
+ * @version 1.0 (Banshee)
+ * Copyright (C) 2006-2007 Dan Fuhry
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ */
+
+ // Set up gzip encoding before any output is sent
+
+ $aggressive_optimize_html = true;
+
+ global $do_gzip;
+ $do_gzip = false;
+
+ if(isset($_SERVER['PATH_INFO'])) $v = $_SERVER['PATH_INFO'];
+ elseif(isset($_GET['title'])) $v = $_GET['title'];
+ else $v = '';
+
+ error_reporting(E_ALL);
+
+ // if(!strstr($v, 'CSS') && !strstr($v, 'UploadFile') && !strstr($v, 'DownloadFile')) // These pages are blacklisted because we can't have debugConsole's HTML output disrupting the flow of header() calls and whatnot
+ // {
+ // $do_gzip = ( function_exists('gzcompress') && ( isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') ) ) ? true : false;
+ // // Uncomment the following line to enable debugConsole (requires PHP 5 or later)
+ // // define('ENANO_DEBUG', '');
+ // }
+
+ if(defined('ENANO_DEBUG')) $do_gzip = false;
+
+ if($aggressive_optimize_html || $do_gzip)
+ {
+ ob_start();
+ }
+
+ require('includes/common.php');
+
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ if(!isset($_GET['do'])) $_GET['do'] = 'view';
+ switch($_GET['do'])
+ {
+ default:
+ die_friendly('Invalid action', '<p>The action "'.$_GET['do'].'" is not defined. Return to <a href="'.makeUrl($paths->page).'">viewing this page\'s text</a>.</p>');
+ break;
+ case 'view':
+ // echo PageUtils::getpage($paths->page, true, ( (isset($_GET['oldid'])) ? $_GET['oldid'] : false ));
+ $page = new PageProcessor( $paths->cpage['urlname_nons'], $paths->namespace );
+ $page->send_headers = true;
+ $page->send();
+ break;
+ case 'comments':
+ $template->header();
+ $sub = ( isset ($_GET['sub']) ) ? $_GET['sub'] : false;
+ switch($sub)
+ {
+ case 'admin':
+ default:
+ $act = ( isset ($_GET['action']) ) ? $_GET['action'] : false;
+ $id = ( isset ($_GET['id']) ) ? intval($_GET['id']) : -1;
+ echo PageUtils::comments_html($paths->cpage['urlname_nons'], $paths->namespace, $act, Array('id'=>$id));
+ break;
+ case 'postcomment':
+ if(empty($_POST['name']) ||
+ empty($_POST['subj']) ||
+ empty($_POST['text'])
+ ) { echo 'Invalid request'; break; }
+ $cid = ( isset($_POST['captcha_id']) ) ? $_POST['captcha_id'] : false;
+ $cin = ( isset($_POST['captcha_input']) ) ? $_POST['captcha_input'] : false;
+ PageUtils::addcomment($paths->cpage['urlname_nons'], $paths->namespace, $_POST['name'], $_POST['subj'], $_POST['text'], $cin, $cid); // All filtering, etc. is handled inside this method
+ echo PageUtils::comments_html($paths->cpage['urlname_nons'], $paths->namespace);
+ break;
+ case 'editcomment':
+ if(!isset($_GET['id']) || ( isset($_GET['id']) && !preg_match('#^([0-9]+)$#', $_GET['id']) )) { echo '<p>Invalid comment ID</p>'; break; }
+ $q = $db->sql_query('SELECT subject,comment_data,comment_id FROM '.table_prefix.'comments WHERE comment_id='.$_GET['id']);
+ if(!$q) $db->_die('The comment data could not be selected.');
+ $row = $db->fetchrow();
+ $db->free_result();
+ echo '<form action="'.makeUrl($paths->page, 'do=comments&sub=savecomment').'" method="post">';
+ echo "<br /><div class='tblholder'><table border='0' width='100%' cellspacing='1' cellpadding='4'>
+ <tr><td class='row1'>Subject:</td><td class='row1'><input type='text' name='subj' value='{$row['subject']}' /></td></tr>
+ <tr><td class='row2'>Comment:</td><td class='row2'><textarea rows='10' cols='40' style='width: 98%;' name='text'>{$row['comment_data']}</textarea></td></tr>
+ <tr><td class='row1' colspan='2' class='row1' style='text-align: center;'><input type='hidden' name='id' value='{$row['comment_id']}' /><input type='submit' value='Save Changes' /></td></tr>
+ </table></div>";
+ echo '</form>';
+ break;
+ case 'savecomment':
+ if(empty($_POST['subj']) || empty($_POST['text'])) { echo '<p>Invalid request</p>'; break; }
+ $r = PageUtils::savecomment_neater($paths->cpage['urlname_nons'], $paths->namespace, $_POST['subj'], $_POST['text'], (int)$_POST['id']);
+ if($r != 'good') { echo "<pre>$r</pre>"; break; }
+ echo PageUtils::comments_html($paths->cpage['urlname_nons'], $paths->namespace);
+ break;
+ case 'deletecomment':
+ if(!empty($_GET['id']))
+ {
+ PageUtils::deletecomment_neater($paths->cpage['urlname_nons'], $paths->namespace, (int)$_GET['id']);
+ }
+ echo PageUtils::comments_html($paths->cpage['urlname_nons'], $paths->namespace);
+ break;
+ }
+ $template->footer();
+ break;
+ case 'edit':
+ if(isset($_POST['_cancel'])) { header('Location: '.makeUrl($paths->page)); echo '<html><head><title>Redirecting...</title></head><body>If you haven\'t been redirected yet, <a href="'.makeUrl($paths->page).'">click here</a>.'; break; }
+ if(isset($_POST['_save'])) {
+ $e = PageUtils::savepage($paths->cpage['urlname_nons'], $paths->namespace, $_POST['page_text'], $_POST['edit_summary'], isset($_POST['minor']));
+ header('Location: '.makeUrl($paths->page)); echo '<html><head><title>Redirecting...</title></head><body>If you haven\'t been redirected yet, <a href="'.makeUrl($paths->page).'">click here</a>.'; break;
+ }
+ $template->header();
+ if(isset($_POST['_preview']))
+ {
+ $text = $_POST['page_text'];
+ echo PageUtils::genPreview($_POST['page_text']);
+ }
+ else $text = RenderMan::getPage($paths->cpage['urlname_nons'], $paths->namespace, 0, false, false, false, false);
+ echo '
+ <form action="'.makeUrl($paths->page, 'do=edit').'" method="post" enctype="multipart/form-data">
+ <br />
+ <textarea name="page_text" rows="20" cols="60" style="width: 97%;">'.$text.'</textarea><br />
+ <br />
+ ';
+ if($paths->wiki_mode)
+ echo 'Edit summary: <input name="edit_summary" type="text" size="40" /><br /><label><input type="checkbox" name="minor" /> This is a minor edit</label><br />';
+ echo '<br />
+ <input type="submit" name="_save" value="Save changes" style="font-weight: bold;" />
+ <input type="submit" name="_preview" value="Preview changes" />
+ <input type="submit" name="_revert" value="Revert changes" />
+ <input type="submit" name="_cancel" value="Cancel" />
+ </form>
+ ';
+ $template->footer();
+ break;
+ case 'viewsource':
+ $template->header();
+ $text = RenderMan::getPage($paths->cpage['urlname_nons'], $paths->namespace, 0, false, false, false, false);
+ echo '
+ <form action="'.makeUrl($paths->page, 'do=edit').'" method="post">
+ <br />
+ <textarea readonly="readonly" name="page_text" rows="20" cols="60" style="width: 97%;">'.$text.'</textarea>';
+ echo '<br />
+ <input type="submit" name="_cancel" value="Close viewer" />
+ </form>
+ ';
+ $template->footer();
+ break;
+ case 'history':
+ $hist = PageUtils::histlist($paths->cpage['urlname_nons'], $paths->namespace);
+ $template->header();
+ echo $hist;
+ $template->footer();
+ break;
+ case 'rollback':
+ $id = (isset($_GET['id'])) ? $_GET['id'] : false;
+ if(!$id || !preg_match('#^([0-9]+)$#', $id)) die_friendly('Invalid action ID', '<p>The URL parameter "id" is not an integer. Exiting to prevent nasties like SQL injection, etc.</p>');
+ $rb = PageUtils::rollback( (int) $id );
+ $template->header();
+ echo '<p>'.$rb.' <a href="'.makeUrl($paths->page).'">Return to the page</a>.</p>';
+ $template->footer();
+ break;
+ case 'catedit':
+ if(isset($_POST['__enanoSaveButton']))
+ {
+ unset($_POST['__enanoSaveButton']);
+ $val = PageUtils::catsave($paths->cpage['urlname_nons'], $paths->namespace, $_POST);
+ if($val == 'GOOD')
+ {
+ header('Location: '.makeUrl($paths->page)); echo '<html><head><title>Redirecting...</title></head><body>If you haven\'t been redirected yet, <a href="'.makeUrl($paths->page).'">click here</a>.'; break;
+ } else {
+ die_friendly('Error saving category information', '<p>'.$val.'</p>');
+ }
+ }
+ elseif(isset($_POST['__enanoCatCancel']))
+ {
+ header('Location: '.makeUrl($paths->page)); echo '<html><head><title>Redirecting...</title></head><body>If you haven\'t been redirected yet, <a href="'.makeUrl($paths->page).'">click here</a>.'; break;
+ }
+ $template->header();
+ $c = PageUtils::catedit_raw($paths->cpage['urlname_nons'], $paths->namespace);
+ echo $c[1];
+ $template->footer();
+ break;
+ case 'moreoptions':
+ $template->header();
+ echo '<div class="pagebar" id="pagebarpopup2" style="width: 150px; padding: 0;">'.$template->tpl_strings['TOOLBAR_EXTRAS'].'</div>';
+ $template->footer();
+ break;
+ case 'protect':
+ if (!isset($_REQUEST['level'])) die_friendly('Invalid request', '<p>No protection level specified</p>');
+ if(!empty($_POST['reason']))
+ {
+ if(!preg_match('#^([0-2]*){1}$#', $_POST['level'])) die_friendly('Error protecting page', '<p>Request validation failed</p>');
+ PageUtils::protect($paths->cpage['urlname_nons'], $paths->namespace, intval($_POST['level']), $_POST['reason']);
+ die_friendly('Page protected', '<p>The protection setting has been applied. <a href="'.makeUrl($paths->page).'">Return to the page</a>.</p>');
+ }
+ $template->header();
+ ?>
+ <form action="<?php echo makeUrl($paths->page, 'do=protect'); ?>" method="post">
+ <input type="hidden" name="level" value="<?php echo $_REQUEST['level']; ?>" />
+ <?php if(isset($_POST['reason'])) echo '<p style="color: red;">Error: you must enter a reason for protecting this page.</p>'; ?>
+ <p>Reason for protecting the page:</p>
+ <p><input type="text" name="reason" size="40" /><br />
+ Protecion level to be applied: <b><?php
+ switch($_REQUEST['level'])
+ {
+ case '0':
+ echo 'No protection';
+ break;
+ case '1':
+ echo 'Full protection';
+ break;
+ case '2':
+ echo 'Semi-protection';
+ break;
+ default:
+ echo 'None;</b> Warning: request validation will fail after clicking submit<b>';
+ }
+ ?></b></p>
+ <p><input type="submit" value="Protect page" style="font-weight: bold;" /></p>
+ </form>
+ <?php
+ $template->footer();
+ break;
+ case 'rename':
+ if(!empty($_POST['newname']))
+ {
+ $r = PageUtils::rename($paths->cpage['urlname_nons'], $paths->namespace, $_POST['newname']);
+ die_friendly('Page renamed', '<p>'.nl2br($r).' <a href="'.makeUrl($paths->page).'">Return to the page</a>.</p>');
+ }
+ $template->header();
+ ?>
+ <form action="<?php echo makeUrl($paths->page, 'do=rename'); ?>" method="post">
+ <?php if(isset($_POST['newname'])) echo '<p style="color: red;">Error: you must enter a new name for this page.</p>'; ?>
+ <p>Please enter a new name for this page:</p>
+ <p><input type="text" name="newname" size="40" /></p>
+ <p><input type="submit" value="Rename page" style="font-weight: bold;" /></p>
+ </form>
+ <?php
+ $template->footer();
+ break;
+ case 'flushlogs':
+ if(!$session->get_permissions('clear_logs')) die_friendly('Access denied', '<p>Flushing the logs for a page <u>requires</u> administrative rights.</p>');
+ if(isset($_POST['_downthejohn']))
+ {
+ $template->header();
+ $result = PageUtils::flushlogs($paths->cpage['urlname_nons'], $paths->namespace);
+ echo '<p>'.$result.' <a href="'.makeUrl($paths->page).'">Return to the page</a>.</p>';
+ $template->footer();
+ break;
+ }
+ $template->header();
+ ?>
+ <form action="<?php echo makeUrl($paths->page, 'do=flushlogs'); ?>" method="post">
+ <h3>You are about to <span style="color: red;">destroy</span> all logged edits and actions on this page.</h3>
+ <p>Unlike deleting or editing this page, this action is <u>not reversible</u>! You should only do this if you are desperate for
+ database space.</p>
+ <p>Do you really want to continue?</p>
+ <p><input type="submit" name="_downthejohn" value="Flush logs" style="color: red; font-weight: bold;" /></p>
+ </form>
+ <?php
+ $template->footer();
+ break;
+ case 'delvote':
+ if(isset($_POST['_ballotbox']))
+ {
+ $template->header();
+ $result = PageUtils::delvote($paths->cpage['urlname_nons'], $paths->namespace);
+ echo '<p>'.$result.' <a href="'.makeUrl($paths->page).'">Return to the page</a>.</p>';
+ $template->footer();
+ break;
+ }
+ $template->header();
+ ?>
+ <form action="<?php echo makeUrl($paths->page, 'do=delvote'); ?>" method="post">
+ <h3>Your vote counts.</h3>
+ <p>If you think that this page is not relavent to the content on this site, or if it looks like this page was only created in
+ an attempt to spam the site, you can request that this page be deleted by an administrator.</p>
+ <p>After you vote, you should leave a comment explaining the reason for your vote, especially if you are the first person to
+ vote against this page.</p>
+ <p>So far, <?php echo ( $paths->cpage['delvotes'] == 1 ) ? $paths->cpage['delvotes'] . ' person has' : $paths->cpage['delvotes'] . ' people have'; ?> voted to delete this page.</p>
+ <p><input type="submit" name="_ballotbox" value="Vote to delete this page" /></p>
+ </form>
+ <?php
+ $template->footer();
+ break;
+ case 'resetvotes':
+ if(!$session->get_permissions('vote_reset')) die_friendly('Access denied', '<p>Resetting the deletion votes against this page <u>requires</u> admin rights.</p>');
+ if(isset($_POST['_youmaylivealittlelonger']))
+ {
+ $template->header();
+ $result = PageUtils::resetdelvotes($paths->cpage['urlname_nons'], $paths->namespace);
+ echo '<p>'.$result.' <a href="'.makeUrl($paths->page).'">Return to the page</a>.</p>';
+ $template->footer();
+ break;
+ }
+ $template->header();
+ ?>
+ <form action="<?php echo makeUrl($paths->page, 'do=resetvotes'); ?>" method="post">
+ <p>This action will reset the number of votes against this page to zero. Are you sure you want to do this?</p>
+ <p><input type="submit" name="_youmaylivealittlelonger" value="Reset votes" /></p>
+ </form>
+ <?php
+ $template->footer();
+ break;
+ case 'deletepage':
+ if(!$session->get_permissions('delete_page')) die_friendly('Access denied', '<p>Deleting pages <u>requires</u> admin rights.</p>');
+ if(isset($_POST['_adiossucker']))
+ {
+ $template->header();
+ $result = PageUtils::deletepage($paths->cpage['urlname_nons'], $paths->namespace);
+ echo '<p>'.$result.' <a href="'.makeUrl($paths->page).'">Return to the page</a>.</p>';
+ $template->footer();
+ break;
+ }
+ $template->header();
+ ?>
+ <form action="<?php echo makeUrl($paths->page, 'do=deletepage'); ?>" method="post">
+ <h3>You are about to <span style="color: red;">destroy</span> this page.</h3>
+ <p>While the deletion of the page itself is completely reversible, it is impossible to recover any comments or category information on this page. If this is a file page, the file along with all older revisions of it will be permanently deleted. Also, any custom information that this page is tagged with, such as a custom name, protection status, or additional settings such as whether to allow comments, will be permanently lost.</p>
+ <p>Are you <u>absolutely sure</u> that you want to continue?<br />
+ You will not be asked again.</p>
+ <p><input type="submit" name="_adiossucker" value="Delete this page" style="color: red; font-weight: bold;" /></p>
+ </form>
+ <?php
+ $template->footer();
+ break;
+ case 'setwikimode':
+ if(!$session->get_permissions('set_wiki_mode')) die_friendly('Access denied', '<p>Changing the wiki mode setting <u>requires</u> admin rights.</p>');
+ if(!isset($_GET['level']) || ( isset($_GET['level']) && !preg_match('#^([0-9])$#', $_GET['level']))) die_friendly('Invalid request', '<p>Level not specified</p>');
+ $template->header();
+ $template->footer();
+ break;
+ case 'diff':
+ $template->header();
+ $id1 = ( isset($_GET['diff1']) ) ? (int)$_GET['diff1'] : false;
+ $id2 = ( isset($_GET['diff2']) ) ? (int)$_GET['diff2'] : false;
+ if(!$id1 || !$id2) { echo '<p>Invalid request.</p>'; $template->footer(); break; }
+ if(!preg_match('#^([0-9]+)$#', (string)$_GET['diff1']) ||
+ !preg_match('#^([0-9]+)$#', (string)$_GET['diff2'] )) { echo '<p>SQL injection attempt</p>'; $template->footer(); break; }
+ echo PageUtils::pagediff($paths->cpage['urlname_nons'], $paths->namespace, $id1, $id2);
+ $template->footer();
+ break;
+ case 'aclmanager':
+ $data = ( isset($_POST['data']) ) ? $_POST['data'] : Array('mode' => 'listgroups');
+ PageUtils::aclmanager($data);
+ break;
+ }
+
+ //
+ // Optimize HTML by replacing newlines with spaces (excludes <pre>, <script>, and <style> blocks)
+ //
+ if ($aggressive_optimize_html)
+ {
+ // Load up the HTML
+ $html = ob_get_contents();
+ ob_end_clean();
+
+ // Which tags to strip - you can change this if needed
+ $strip_tags = Array('pre', 'script', 'style', 'enano:no-opt');
+ $strip_tags = implode('|', $strip_tags);
+
+ // Strip out the tags and replace with placeholders
+ preg_match_all("#<($strip_tags)(.*?)>(.*?)</($strip_tags)>#is", $html, $matches);
+ $seed = md5(microtime() . mt_rand()); // Random value used for placeholders
+ for ($i = 0;$i < sizeof($matches[1]); $i++)
+ {
+ $html = str_replace("<{$matches[1][$i]}{$matches[2][$i]}>{$matches[3][$i]}</{$matches[4][$i]}>", "{DONT_STRIP_ME_NAKED:$seed:$i}", $html);
+ }
+
+ // Finally, process the HTML
+ $html = preg_replace("#\n([ ]*)#", " ", $html);
+
+ // Remove annoying spaces between tags
+ $html = preg_replace("#>([ ]*?){2,}<#", "> <", $html);
+
+ // Re-insert untouchable tags
+ for ($i = 0;$i < sizeof($matches[1]); $i++)
+ {
+ $html = str_replace("{DONT_STRIP_ME_NAKED:$seed:$i}", "<{$matches[1][$i]}{$matches[2][$i]}>{$matches[3][$i]}</{$matches[4][$i]}>", $html);
+ }
+
+ // Remove <enano:no-opt> blocks (can be used by themes that don't want their HTML optimized)
+ $html = preg_replace('#<(\/|)enano:no-opt(.*?)>#', '', $html);
+
+ // Tell snoopish users what's going on
+ $html = str_replace('<html>', "\n<!-- NOTE: This HTML document has been Aggressively Optimized(TM) by Enano to make page loading faster. -->\n<html>", $html);
+
+ // Re-enable output buffering to allow the Gzip function (below) to work
+ ob_start();
+
+ // Done, send it to the user
+ echo( $html );
+ }
+
+ //
+ // Compress buffered output if required and send to browser
+ //
+ if ( $do_gzip )
+ {
+ //
+ // Copied from phpBB, which was in turn borrowed from php.net
+ //
+ $gzip_contents = ob_get_contents();
+ ob_end_clean();
+
+ $gzip_size = strlen($gzip_contents);
+ $gzip_crc = crc32($gzip_contents);
+
+ $gzip_contents = gzcompress($gzip_contents, 9);
+ $gzip_contents = substr($gzip_contents, 0, strlen($gzip_contents) - 4);
+
+ header('Content-encoding: gzip');
+ echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
+ echo $gzip_contents;
+ echo pack('V', $gzip_crc);
+ echo pack('V', $gzip_size);
+ }
+
+ $db->close();
+
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/install.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,1017 @@
+<?php
+/*
+ * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
+ * Version 1.0 (Banshee)
+ * Copyright (C) 2006-2007 Dan Fuhry
+ * install.php - handles everything related to installation and initial configuration
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+//@include('config.php');
+if( ( defined('ENANO_INSTALLED') || defined('MIDGET_INSTALLED') ) && ((isset($_GET['mode']) && ($_GET['mode']!='finish' && $_GET['mode']!='css')) || !isset($_GET['mode']))) {
+ $_GET['title'] = 'Enano:WhoCaresWhatThisIs';
+ require('includes/common.php');
+ die_friendly('Installation locked', '<p>The Enano installer has found a Enano installation in this directory. You MUST delete config.php if you want to re-install Enano.</p><p>If you wish to upgrade an older Enano installation to this version, please use the <a href="upgrade.php">upgrade script</a>.</p>');
+ exit;
+}
+
+define('IN_ENANO_INSTALL', 'true');
+
+define('ENANO_VERSION', '1.0');
+// In beta versions, define ENANO_BETA_VERSION here
+
+if(!defined('scriptPath')) {
+ $sp = dirname($_SERVER['REQUEST_URI']);
+ if($sp == '/' || $sp == '\\') $sp = '';
+ define('scriptPath', $sp);
+}
+
+if(!defined('contentPath')) {
+ $sp = dirname($_SERVER['REQUEST_URI']);
+ if($sp == '/' || $sp == '\\') $sp = '';
+ define('contentPath', $sp);
+}
+global $_starttime, $this_page, $sideinfo;
+$_starttime = microtime(true);
+
+define('ENANO_ROOT', dirname(__FILE__));
+
+function is_page($p) { return true; }
+require('includes/wikiformat.php');
+require('includes/constants.php');
+require('includes/rijndael.php');
+require('includes/functions.php');
+
+//die('Key size: ' . AES_BITS . '<br />Block size: ' . AES_BLOCKSIZE);
+
+if(!function_exists('wikiFormat')) {
+function wikiFormat($message, $filter_links = true) {
+ $wiki = & Text_Wiki::singleton('Mediawiki');
+ $wiki->setRenderConf('Xhtml', 'code', 'css_filename', 'codefilename');
+ $wiki->setRenderConf('Xhtml', 'wikilink', 'view_url', contentPath);
+ $result = $wiki->transform($message, 'Xhtml');
+
+ // HTML fixes
+ $result = preg_replace('#<tr>([\s]*?)<\/tr>#is', '', $result);
+ $result = preg_replace('#<p>([\s]*?)<\/p>#is', '', $result);
+ $result = preg_replace('#<br />([\s]*?)<table#is', '<table', $result);
+
+ return $result;
+}
+}
+
+global $failed, $warned;
+$failed = false;
+$warned = false;
+function not($var) { if($var) return false; else return true; }
+function run_test($code, $desc, $extended_desc, $warn = false)
+{
+ global $failed, $warned;
+ static $cv = true;
+ $cv = not($cv);
+ $val = eval($code);
+ if($val)
+ {
+ if($cv) $color='CCFFCC'; else $color='AAFFAA';
+ echo "<tr><td style='background-color: #$color; width: 500px;'>$desc</td><td style='padding-left: 10px;'><img alt='Test passed' src='images/good.gif' /></td></tr>";
+ } elseif(!$val && $warn) {
+ if($cv) $color='FFFFCC'; else $color='FFFFAA';
+ echo "<tr><td style='background-color: #$color; width: 500px;'>$desc<br /><b>$extended_desc</b></td><td style='padding-left: 10px;'><img alt='Test passed with warning' src='images/unknown.gif' /></td></tr>";
+ $warned = true;
+ } else {
+ if($cv) $color='FFCCCC'; else $color='FFAAAA';
+ echo "<tr><td style='background-color: #$color; width: 500px;'>$desc<br /><b>$extended_desc</b></td><td style='padding-left: 10px;'><img alt='Test failed' src='images/bad.gif' /></td></tr>";
+ $failed = true;
+ }
+}
+function is_apache() { $r = strstr($_SERVER['SERVER_SOFTWARE'], 'Apache') ? true : false; return $r; }
+
+require_once('includes/template.php');
+
+if(!isset($_GET['mode'])) $_GET['mode'] = 'welcome';
+switch($_GET['mode'])
+{
+ case 'mysql_test':
+ error_reporting(0);
+ $dbhost = rawurldecode($_POST['host']);
+ $dbname = rawurldecode($_POST['name']);
+ $dbuser = rawurldecode($_POST['user']);
+ $dbpass = rawurldecode($_POST['pass']);
+ $dbrootuser = rawurldecode($_POST['root_user']);
+ $dbrootpass = rawurldecode($_POST['root_pass']);
+ if($dbrootuser != '')
+ {
+ $conn = mysql_connect($dbhost, $dbrootuser, $dbrootpass);
+ if(!$conn)
+ {
+ $e = mysql_error();
+ if(strstr($e, "Lost connection"))
+ die('host'.$e);
+ else
+ die('root'.$e);
+ }
+ $rsp = 'good';
+ $q = mysql_query('USE '.$dbname, $conn);
+ if(!$q)
+ {
+ $e = mysql_error();
+ if(strstr($e, 'Unknown database'))
+ {
+ $rsp .= '_creating_db';
+ }
+ }
+ mysql_close($conn);
+ $conn = mysql_connect($dbhost, $dbuser, $dbpass);
+ if(!$conn)
+ {
+ $e = mysql_error();
+ if(strstr($e, "Lost connection"))
+ die('host'.$e);
+ else
+ $rsp .= '_creating_user';
+ }
+ mysql_close($conn);
+ die($rsp);
+ }
+ else
+ {
+ $conn = mysql_connect($dbhost, $dbuser, $dbpass);
+ if(!$conn)
+ {
+ $e = mysql_error();
+ if(strstr($e, "Lost connection"))
+ die('host'.$e);
+ else
+ die('auth'.$e);
+ }
+ $q = mysql_query('USE '.$dbname, $conn);
+ if(!$q)
+ {
+ $e = mysql_error();
+ if(strstr($e, 'Unknown database'))
+ {
+ die('name'.$e);
+ }
+ else
+ {
+ die('perm'.$e);
+ }
+ }
+ }
+ $v = mysql_get_server_info();
+ if(version_compare($v, '4.1.17', '<')) die('vers'.$v);
+ mysql_close($conn);
+ die('good');
+ break;
+ default:
+ break;
+}
+
+$template = new template_nodb();
+$template->load_theme('oxygen', 'bleu', false);
+
+$modestrings = Array(
+ 'welcome' => 'Welcome',
+ 'license' => 'License Agreement',
+ 'sysreqs' => 'Server requirements',
+ 'database'=> 'Database information',
+ 'website' => 'Website configuration',
+ 'login' => 'Administration login',
+ 'confirm' => 'Confirm installation',
+ 'install' => 'Database installation',
+ 'finish' => 'Installation complete'
+ );
+
+$sideinfo = '';
+$vars = $template->extract_vars('elements.tpl');
+$p = $template->makeParserText($vars['sidebar_button']);
+foreach ( $modestrings as $id => $str )
+{
+ if ( $_GET['mode'] == $id )
+ {
+ $flags = 'style="font-weight: bold; text-decoration: underline;"';
+ $this_page = $str;
+ }
+ else
+ {
+ $flags = '';
+ }
+ $p->assign_vars(Array(
+ 'HREF' => '#',
+ 'FLAGS' => $flags . ' onclick="return false;"',
+ 'TEXT' => $str
+ ));
+ $sideinfo .= $p->run();
+}
+
+$template->init_vars();
+
+if(isset($_GET['mode']) && $_GET['mode'] == 'css')
+{
+ header('Content-type: text/css');
+ echo $template->get_css();
+ exit;
+}
+
+$template->header();
+if(!isset($_GET['mode'])) $_GET['mode'] = 'license';
+switch($_GET['mode'])
+{
+ default:
+ case 'welcome':
+ ?>
+ <div style="text-align: center; margin-top: 10px;">
+ <img alt="[ Enano CMS Project logo ]" src="images/enano-artwork/installer-greeting-blue.png" style="display: block; margin: 0 auto; padding-left: 100px;" />
+ <h2>Welcome to Enano</h2>
+ <h3>version 1.0 – stable<br />
+ <span style="font-weight: normal;">also affectionately known as "banshee" <tt>:)</tt></span></h3>
+ <?php
+ if ( file_exists('./_nightly.php') )
+ {
+ echo '<div class="warning-box" style="text-align: left; margin: 10px 0;"><b>You are about to install a NIGHTLY BUILD of Enano.</b><br />Nightly builds are NOT upgradeable and may contain serious flaws, security problems, or extraneous debugging information. Installing this version of Enano on a production site is NOT recommended.</div>';
+ }
+ ?>
+ <form action="install.php?mode=license" method="post">
+ <input type="submit" value="Start installation" />
+ </form>
+ </div>
+ <?php
+ break;
+ case "license":
+ ?>
+ <h3>Welcome to the Enano installer.</h3>
+ <p>Thank you for choosing Enano as your CMS. You've selected the finest in design, the strongest in security, and the latest in Web 2.0 toys. Trust us, you'll like it.</p>
+ <p>To get started, please read and accept the following license agreement. You've probably seen it before.</p>
+ <div style="height: 500px; clip: rect(0px,auto,500px,auto); overflow: auto; padding: 10px; border: 1px dashed #456798; margin: 1em;">
+ <h2>GNU General Public License</h2>
+ <h3>Declaration of license usage</h3>
+ <p>Enano is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.</p>
+ <p>This program is distributed in the hope that it will be useful, but <u>without any warranty</u>; without even the implied warranty of <u>merchantability</u> or <u>fitness for a particular purpose</u>. See the GNU General Public License (below) for more details.</p>
+ <h3>Human-readable version</h3>
+ <p>Enano is distributed under certain licensing terms that we believe make it of the greatest possible use to the public. The license we distribute it under, the GNU General Public License, provides certain terms and conditions that, rather than limit your use of Enano, allow you to get the most out of it. If you would like to read the full text, it can be found below. Here is a human-readable version that we think is a little easier to understand.</p>
+ <ul>
+ <li>You may to run Enano for any purpose.</li>
+ <li>You may study how Enano works and adapt it to your needs.</li>
+ <li>You may redistribute copies so you can help your neighbor.</li>
+ <li>You may improve Enano and release your improvements to the public, so that the whole community benefits.</li>
+ </ul>
+ <p>You may exercise the freedoms specified here provided that you comply with the express conditions of this license. The principal conditions are:</p>
+ <ul>
+ <li>You must conspicuously and appropriately publish on each copy distributed an appropriate copyright notice and disclaimer of warranty and keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of Enano a copy of the GNU General Public License along with Enano. Any translation of the GNU General Public License must be accompanied by the GNU General Public License.</li>
+ <li>If you modify your copy or copies of Enano or any portion of it, or develop a program based upon it, you may distribute the resulting work provided you do so under the GNU General Public License. Any translation of the GNU General Public License must be accompanied by the GNU General Public License.</li>
+ <li>If you copy or distribute Enano, you must accompany it with the complete corresponding machine-readable source code or with a written offer, valid for at least three years, to furnish the complete corresponding machine-readable source code.</li>
+ </ul>
+ <p><b>Disclaimer</b>: The above text is not a license. It is simply a handy reference for understanding the Legal Code (the full license) – it is a human-readable expression of some of its key terms. Think of it as the user-friendly interface to the Legal Code beneath. The above text itself has no legal value, and its contents do not appear in the actual license.<br /><span style="color: #CCC">Text copied from the <a href="http://creativecommons.org/licenses/GPL/2.0/">Creative Commons GPL Deed page</a></span></p>
+ <?php
+ if ( defined('ENANO_BETA_VERSION') )
+ {
+ ?>
+ <h3>Notice for prerelease versions</h3>
+ <p>This version of Enano is designed only for testing and evaluation purposes. <b>It is not yet completely stable, and should not be used on production websites.</b> As with any Enano version, Dan Fuhry and the Enano team cannot be responsible for any damage, physical or otherwise, to any property as a result of the use of Enano. While security is a number one priority, sometimes things slip through.</p>
+ <?php
+ }
+ ?>
+ <h3>Lawyer-readable version</h3>
+ <?php echo wikiFormat(file_get_contents(ENANO_ROOT . '/GPL')); ?>
+ </div>
+ <div class="pagenav">
+ <form action="install.php?mode=sysreqs" method="post">
+ <table border="0">
+ <tr>
+ <td><input type="submit" value="Continue" /></td><td><p><span style="font-weight: bold;">Before clicking continue:</span><br />• Ensure that you agree with the terms of the license<br />• Have your database host, name, username, and password available</p></td>
+ </tr>
+ </table>
+ </form>
+ </div>
+ <?php
+ break;
+ case "sysreqs":
+ error_reporting(E_ALL);
+ ?>
+ <h3>Checking your server</h3>
+ <p>Enano has several requirements that must be met before it can be installed. If all is good then note any warnings and click Continue below.</p>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <?php
+ run_test('return version_compare(\'4.3.0\', PHP_VERSION, \'<\');', 'PHP Version >=4.3.0', 'It seems that the version of PHP that your server is running is too old to support Enano properly. If this is your server, please upgrade to the most recent version of PHP, remembering to use the --with-mysql configure option if you compile it yourself. If this is not your server, please contact your webhost and ask them if it would be possible to upgrade PHP. If this is not possible, you will need to switch to a different webhost in order to use Enano.');
+ run_test('return function_exists(\'mysql_connect\');', 'MySQL extension for PHP', 'It seems that your PHP installation does not have the MySQL extension enabled. If this is your own server, you may need to just enable the "libmysql.so" extension in php.ini. If you do not have the MySQL extension installed, you will need to either use your distribution\'s package manager to install it, or you will have to compile PHP from source. If you compile PHP from source, please remember to use the "--with-mysql" configure option, and you will have to have the MySQL development files installed (they usually are). If this is not your server, please contact your hosting company and ask them to install the PHP MySQL extension.');
+ run_test('return @ini_get(\'file_uploads\');', 'File upload support', 'It seems that your server does not support uploading files. Enano *requires* this functionality in order to work properly. Please ask your server administrator to set the "file_uploads" option in php.ini to "On".');
+ run_test('return is_apache();', 'Apache HTTP Server', 'Apparently your server is running a web server other than Apache. Enano will work nontheless, but there are some known bugs with non-Apache servers, and the "fancy" URLs will not work properly. The "Standard URLs" option will be set on the website configuration page, only change it if you are absolutely certain that your server is running Apache.', true);
+ //run_test('return function_exists(\'finfo_file\');', 'Fileinfo PECL extension', 'The MIME magic PHP extension is used to determine the type of a file by looking for a certain "magic" string of characters inside it. This functionality is used by Enano to more effectively prevent malicious file uploads. The MIME magic option will be disabled by default.', true);
+ run_test('return is_writable(ENANO_ROOT.\'/config.php\');', 'Configuration file writable', 'It looks like the configuration file, config.php, is not writable. Enano needs to be able to write to this file in order to install.<br /><br /><b>If you are installing Enano on a SourceForge web site:</b><br />SourceForge mounts the web partitions read-only now, so you will need to use the project shell service to symlink config.php to a file in the /tmp/persistent directory.');
+ run_test('return file_exists(\'/usr/bin/convert\');', 'ImageMagick support', 'Enano uses ImageMagick to scale images into thumbnails. Because ImageMagick was not found on your server, Enano will use the width= and height= attributes on the <img> tag to scale images. This can cause somewhat of a performance increase, but bandwidth usage will be higher, especially if you use high-resolution images on your site.<br /><br />If you are sure that you have ImageMagick, you can set the location of the "convert" program using the administration panel after installation is complete.', true);
+ run_test('return is_writable(ENANO_ROOT.\'/cache/\');', 'Cache directory writable', 'Apparently the cache/ directory is not writable. Enano will still work, but you will not be able to cache thumbnails, meaning the server will need to re-render them each time they are requested. In some cases, this can cause a significant slowdown.', true);
+ echo '</table>';
+ if(!$failed)
+ {
+ ?>
+
+ <div class="pagenav">
+ <?php
+ if($warned) {
+ echo '<table border="0" cellspacing="0" cellpadding="0">';
+ run_test('return false;', 'Some scalebacks were made due to your server configuration.', 'Enano has detected that some of the features or configuration settings on your server are not optimal for the best behavior and/or performance for Enano. As a result, certain features or enhancements that are part of Enano have been disabled to prevent further errors. You have seen those "fatal error" notices that spew from PHP, haven\'t you?<br /><br />Fatal error:</b> call to undefined function wannahokaloogie() in file <b>'.__FILE__.'</b> on line <b>'.__LINE__.'', true);
+ echo '</table>';
+ } else {
+ echo '<table border="0" cellspacing="0" cellpadding="0">';
+ run_test('return true;', '<b>Your server meets all the requirements for running Enano.</b><br />Click the button below to continue the installation.', 'You should never see this text. Congratulations for being a Enano hacker!');
+ echo '</table>';
+ }
+ ?>
+ <form action="install.php?mode=database" method="post">
+ <table border="0">
+ <tr>
+ <td><input type="submit" value="Continue" /></td><td><p><span style="font-weight: bold;">Before clicking continue:</span><br />• Ensure that you are satisfied with any scalebacks that may have been made to accomodate your server configuration<br />• Have your database host, name, username, and password available</p></td>
+ </tr>
+ </table>
+ </form>
+ </div>
+ <?php
+ } else {
+ if($failed) {
+ echo '<div class="pagenav"><table border="0" cellspacing="0" cellpadding="0">';
+ run_test('return false;', 'Your server does not meet the requirements for Enano to run.', 'As a precaution, Enano will not install until the above requirements have been met. Contact your server administrator or hosting company and convince them to upgrade. Good luck.');
+ echo '</table></div>';
+ }
+ }
+ ?>
+ <?php
+ break;
+ case "database":
+ ?>
+ <script type="text/javascript">
+ function ajaxGet(uri, f) {
+ if (window.XMLHttpRequest) {
+ ajax = new XMLHttpRequest();
+ } else {
+ if (window.ActiveXObject) {
+ ajax = new ActiveXObject("Microsoft.XMLHTTP");
+ } else {
+ alert('Enano client-side runtime error: No AJAX support, unable to continue');
+ return;
+ }
+ }
+ ajax.onreadystatechange = f;
+ ajax.open('GET', uri, true);
+ ajax.send(null);
+ }
+
+ function ajaxPost(uri, parms, f) {
+ if (window.XMLHttpRequest) {
+ ajax = new XMLHttpRequest();
+ } else {
+ if (window.ActiveXObject) {
+ ajax = new ActiveXObject("Microsoft.XMLHTTP");
+ } else {
+ alert('Enano client-side runtime error: No AJAX support, unable to continue');
+ return;
+ }
+ }
+ ajax.onreadystatechange = f;
+ ajax.open('POST', uri, true);
+ ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+ ajax.setRequestHeader("Content-length", parms.length);
+ ajax.setRequestHeader("Connection", "close");
+ ajax.send(parms);
+ }
+ function ajaxTestConnection()
+ {
+ v = verify();
+ if(!v)
+ {
+ alert('One or more of the form fields is incorrect. Please correct any information in the form that has an "X" next to it.');
+ return false;
+ }
+ var frm = document.forms.dbinfo;
+ db_host = escape(frm.db_host.value.replace('+', '%2B'));
+ db_name = escape(frm.db_name.value.replace('+', '%2B'));
+ db_user = escape(frm.db_user.value.replace('+', '%2B'));
+ db_pass = escape(frm.db_pass.value.replace('+', '%2B'));
+ db_root_user = escape(frm.db_root_user.value.replace('+', '%2B'));
+ db_root_pass = escape(frm.db_root_pass.value.replace('+', '%2B'));
+
+ parms = 'host='+db_host+'&name='+db_name+'&user='+db_user+'&pass='+db_pass+'&root_user='+db_root_user+'&root_pass='+db_root_pass;
+ ajaxPost('<?php echo scriptPath; ?>/install.php?mode=mysql_test', parms, function() {
+ if(ajax.readyState==4)
+ {
+ s = ajax.responseText.substr(0, 4);
+ t = ajax.responseText.substr(4, ajax.responseText.length);
+ if(s.substr(0, 4)=='good')
+ {
+ document.getElementById('s_db_host').src='images/good.gif';
+ document.getElementById('s_db_name').src='images/good.gif';
+ document.getElementById('s_db_auth').src='images/good.gif';
+ document.getElementById('s_db_root').src='images/good.gif';
+ if(t.match(/_creating_db/)) document.getElementById('e_db_name').innerHTML = '<b>Warning:<\/b> The database you specified does not exist. It will be created during installation.';
+ if(t.match(/_creating_user/)) document.getElementById('e_db_auth').innerHTML = '<b>Warning:<\/b> The specified regular user does not exist or the password is incorrect. The user will be created during installation. If the user already exists, the password will be reset.';
+ document.getElementById('s_mysql_version').src='images/good.gif';
+ document.getElementById('e_mysql_version').innerHTML = 'Your version of MySQL meets Enano requirements.';
+ }
+ else
+ {
+ switch(s)
+ {
+ case 'host':
+ document.getElementById('s_db_host').src='images/bad.gif';
+ document.getElementById('s_db_name').src='images/unknown.gif';
+ document.getElementById('s_db_auth').src='images/unknown.gif';
+ document.getElementById('s_db_root').src='images/unknown.gif';
+ document.getElementById('e_db_host').innerHTML = '<b>Error:<\/b> The database server "'+document.forms.dbinfo.db_host.value+'" couldn\'t be contacted.<br \/>'+t;
+ document.getElementById('e_mysql_version').innerHTML = 'The MySQL version that your server is running could not be determined.';
+ break;
+ case 'auth':
+ document.getElementById('s_db_host').src='images/good.gif';
+ document.getElementById('s_db_name').src='images/unknown.gif';
+ document.getElementById('s_db_auth').src='images/bad.gif';
+ document.getElementById('s_db_root').src='images/unknown.gif';
+ document.getElementById('e_db_auth').innerHTML = '<b>Error:<\/b> Access to MySQL under the specified credentials was denied.<br \/>'+t;
+ document.getElementById('e_mysql_version').innerHTML = 'The MySQL version that your server is running could not be determined.';
+ break;
+ case 'perm':
+ document.getElementById('s_db_host').src='images/good.gif';
+ document.getElementById('s_db_name').src='images/bad.gif';
+ document.getElementById('s_db_auth').src='images/good.gif';
+ document.getElementById('s_db_root').src='images/unknown.gif';
+ document.getElementById('e_db_name').innerHTML = '<b>Error:<\/b> Access to the specified database using those login credentials was denied.<br \/>'+t;
+ document.getElementById('e_mysql_version').innerHTML = 'The MySQL version that your server is running could not be determined.';
+ break;
+ case 'name':
+ document.getElementById('s_db_host').src='images/good.gif';
+ document.getElementById('s_db_name').src='images/bad.gif';
+ document.getElementById('s_db_auth').src='images/good.gif';
+ document.getElementById('s_db_root').src='images/unknown.gif';
+ document.getElementById('e_db_name').innerHTML = '<b>Error:<\/b> The specified database does not exist<br \/>'+t;
+ document.getElementById('e_mysql_version').innerHTML = 'The MySQL version that your server is running could not be determined.';
+ break;
+ case 'root':
+ document.getElementById('s_db_host').src='images/good.gif';
+ document.getElementById('s_db_name').src='images/unknown.gif';
+ document.getElementById('s_db_auth').src='images/unknown.gif';
+ document.getElementById('s_db_root').src='images/bad.gif';
+ document.getElementById('e_db_root').innerHTML = '<b>Error:<\/b> Access to MySQL under the specified credentials was denied.<br \/>'+t;
+ document.getElementById('e_mysql_version').innerHTML = 'The MySQL version that your server is running could not be determined.';
+ break;
+ case 'vers':
+ document.getElementById('s_db_host').src='images/good.gif';
+ document.getElementById('s_db_name').src='images/good.gif';
+ document.getElementById('s_db_auth').src='images/good.gif';
+ document.getElementById('s_db_root').src='images/good.gif';
+ if(t.match(/_creating_db/)) document.getElementById('e_db_name').innerHTML = '<b>Warning:<\/b> The database you specified does not exist. It will be created during installation.';
+ if(t.match(/_creating_user/)) document.getElementById('e_db_auth').innerHTML = '<b>Warning:<\/b> The specified regular user does not exist or the password is incorrect. The user will be created during installation. If the user already exists, the password will be reset.';
+
+ document.getElementById('e_mysql_version').innerHTML = '<b>Error:<\/b> Your version of MySQL ('+t+') is older than 4.1.17. Enano will still work, but there is a known bug with the comment system and MySQL 4.1.11 that involves some comments not being displayed, due to an issue with the PHP function mysql_fetch_row().';
+ document.getElementById('s_mysql_version').src='images/bad.gif';
+ default:
+ alert(t);
+ break;
+ }
+ }
+ }
+ });
+ }
+ function verify()
+ {
+ document.getElementById('e_db_host').innerHTML = '';
+ document.getElementById('e_db_auth').innerHTML = '';
+ document.getElementById('e_db_name').innerHTML = '';
+ document.getElementById('e_db_root').innerHTML = '';
+ var frm = document.forms.dbinfo;
+ ret = true;
+ if(frm.db_host.value != '')
+ {
+ document.getElementById('s_db_host').src='images/unknown.gif';
+ }
+ else
+ {
+ document.getElementById('s_db_host').src='images/bad.gif';
+ ret = false;
+ }
+ if(frm.db_name.value.match(/^([a-z0-9_]+)$/g))
+ {
+ document.getElementById('s_db_name').src='images/unknown.gif';
+ }
+ else
+ {
+ document.getElementById('s_db_name').src='images/bad.gif';
+ ret = false;
+ }
+ if(frm.db_user.value != '')
+ {
+ document.getElementById('s_db_auth').src='images/unknown.gif';
+ }
+ else
+ {
+ document.getElementById('s_db_auth').src='images/bad.gif';
+ ret = false;
+ }
+ if(frm.table_prefix.value.match(/^([a-z0-9_]*)$/g))
+ {
+ document.getElementById('s_table_prefix').src='images/good.gif';
+ }
+ else
+ {
+ document.getElementById('s_table_prefix').src='images/bad.gif';
+ ret = false;
+ }
+ if(frm.db_root_user.value == '')
+ {
+ document.getElementById('s_db_root').src='images/good.gif';
+ }
+ else if(frm.db_root_user.value != '' && frm.db_root_pass.value == '')
+ {
+ document.getElementById('s_db_root').src='images/bad.gif';
+ ret = false;
+ }
+ else
+ {
+ document.getElementById('s_db_root').src='images/unknown.gif';
+ }
+ if(ret) frm._cont.disabled = false;
+ else frm._cont.disabled = true;
+ return ret;
+ }
+ window.onload = verify;
+ </script>
+ <p>Now we need some information that will allow Enano to contact your database server. Enano uses MySQL as a data storage backend,
+ and we need to have access to a MySQL server in order to continue.</p>
+ <p>If you do not have access to a MySQL server, and you are using your own server, you can download MySQL for free from
+ <a href="http://www.mysql.com/">MySQL.com</a>. <b>Please note that, like Enano, MySQL is licensed under the GNU GPL.</b>
+ If you need to modify MySQL and then distribute your modifications, you must either distribute them under the terms of the GPL
+ or purchase a proprietary license.</p>
+ <form name="dbinfo" action="install.php?mode=website" method="post">
+ <table border="0">
+ <tr><td colspan="3" style="text-align: center"><h3>Database information</h3></td></tr>
+ <tr><td><b>Database hostname</b><br />This is the hostname (or sometimes the IP address) of your MySQL server. In many cases, this is "localhost".<br /><span style="color: #993300" id="e_db_host"></span></td><td><input onkeyup="verify();" name="db_host" size="30" type="text" /></td><td><img id="s_db_host" alt="Good/bad icon" src="images/bad.gif" /></td></tr>
+ <tr><td><b>Database name</b><br />The name of the actual database. If you don't already have a database, you can create one here, if you have the username and password of a MySQL user with administrative rights.<br /><span style="color: #993300" id="e_db_name"></span></td><td><input onkeyup="verify();" name="db_name" size="30" type="text" /></td><td><img id="s_db_name" alt="Good/bad icon" src="images/bad.gif" /></td></tr>
+ <tr><td rowspan="2"><b>Database login</b><br />These fields should be the username and password of a user with "select", "insert", "update", "delete", "create table", and "replace" privileges for your database.<br /><span style="color: #993300" id="e_db_auth"></span></td><td><input onkeyup="verify();" name="db_user" size="30" type="text" /></td><td rowspan="2"><img id="s_db_auth" alt="Good/bad icon" src="images/bad.gif" /></td></tr>
+ <tr><td><input name="db_pass" size="30" type="password" /></td></tr>
+ <tr><td colspan="3" style="text-align: center"><h3>Optional information</h3></td></tr>
+ <tr><td><b>Table prefix</b><br />The value that you enter here will be added to the beginning of the name of each Enano table. You may use lowercase letters (a-z), numbers (0-9), and underscores (_).</td><td><input onkeyup="verify();" name="table_prefix" size="30" type="text" /></td><td><img id="s_table_prefix" alt="Good/bad icon" src="images/good.gif" /></td></tr>
+ <tr><td rowspan="2"><b>Database administrative login</b><br />If the MySQL database or username that you entered above does not exist yet, you can create them here, assuming that you have the login information for an administrative user (such as root). Leave these fields blank unless you need to use them.<br /><span style="color: #993300" id="e_db_root"></span></td><td><input onkeyup="verify();" name="db_root_user" size="30" type="text" /></td><td rowspan="2"><img id="s_db_root" alt="Good/bad icon" src="images/good.gif" /></td></tr>
+ <tr><td><input onkeyup="verify();" name="db_root_pass" size="30" type="password" /></td></tr>
+ <tr><td><b>MySQL version</b></td><td id="e_mysql_version">MySQL version information will be checked when you click "Test Connection".</td><td><img id="s_mysql_version" alt="Good/bad icon" src="images/unknown.gif" /></td></tr>
+ <tr><td><b>Delete existing tables?</b><br />If this option is checked, all the tables that will be used by Enano will be dropped (deleted) before the schema is executed. Do NOT use this option unless specifically instructed to.</td><td><input type="checkbox" name="drop_tables" id="dtcheck" /> <label for="dtcheck">Drop existing tables</label></td></tr>
+ <tr><td colspan="3" style="text-align: center"><input type="button" value="Test connection" onclick="ajaxTestConnection();" /></td></tr>
+ </table>
+ <div class="pagenav">
+ <table border="0">
+ <tr>
+ <td><input type="submit" value="Continue" onclick="return verify();" name="_cont" /></td><td><p><span style="font-weight: bold;">Before clicking continue:</span><br />• Check your MySQL connection using the "Test Connection" button.<br />• Be aware that your database information will be transmitted unencrypted several times.</p></td>
+ </tr>
+ </table>
+ </div>
+ </form>
+ <?php
+ break;
+ case "website":
+ if(!isset($_POST['_cont'])) {
+ echo 'No POST data signature found. Please <a href="install.php?mode=license">restart the installation</a>.';
+ $template->footer();
+ exit;
+ }
+ unset($_POST['_cont']);
+ ?>
+ <script type="text/javascript">
+ function verify()
+ {
+ var frm = document.forms.siteinfo;
+ ret = true;
+ if(frm.sitename.value.match(/^([A-z0-9 ]+)$/g) && frm.sitename.value != 'Enano')
+ {
+ document.getElementById('s_name').src='images/good.gif';
+ }
+ else
+ {
+ document.getElementById('s_name').src='images/bad.gif';
+ ret = false;
+ }
+ if(frm.sitedesc.value.match(/^(.+)$/g))
+ {
+ document.getElementById('s_desc').src='images/good.gif';
+ }
+ else
+ {
+ document.getElementById('s_desc').src='images/bad.gif';
+ ret = false;
+ }
+ if(frm.copyright.value.match(/^(.+)$/g))
+ {
+ document.getElementById('s_copyright').src='images/good.gif';
+ }
+ else
+ {
+ document.getElementById('s_copyright').src='images/bad.gif';
+ ret = false;
+ }
+ if(ret) frm._cont.disabled = false;
+ else frm._cont.disabled = true;
+ return ret;
+ }
+ window.onload = verify;
+ </script>
+ <form name="siteinfo" action="install.php?mode=login" method="post">
+ <?php
+ $k = array_keys($_POST);
+ for($i=0;$i<sizeof($_POST);$i++) {
+ echo '<input type="hidden" name="'.$k[$i].'" value="'.$_POST[$k[$i]].'" />'."\n";
+ }
+ ?>
+ <p>The next step is to enter some information about your website. You can always change this information later, using the administration panel.</p>
+ <table border="0">
+ <tr><td><b>Website name</b><br />The display name of your website. Allowed characters are uppercase and lowercase letters, numerals, and spaces. This must not be blank or "Enano".</td><td><input onkeyup="verify();" name="sitename" type="text" size="30" /></td><td><img id="s_name" alt="Good/bad icon" src="images/bad.gif" /></td></tr>
+ <tr><td><b>Website description</b><br />This text will be shown below the name of your website.</td><td><input onkeyup="verify();" name="sitedesc" type="text" size="30" /></td><td><img id="s_desc" alt="Good/bad icon" src="images/bad.gif" /></td></tr>
+ <tr><td><b>Copyright info</b><br />This should be a one-line legal notice that will appear at the bottom of all your pages.</td><td><input onkeyup="verify();" name="copyright" type="text" size="30" /></td><td><img id="s_copyright" alt="Good/bad icon" src="images/bad.gif" /></td></tr>
+ <tr><td><b>Wiki mode</b><br />This feature allows people to create and edit pages on your site. Enano keeps a history of all page modifications, and you can protect pages to prevent editing.</td><td><input name="wiki_mode" type="checkbox" id="wmcheck" /> <label for="wmcheck">Yes, make my website a wiki.</label></td><td></td></tr>
+ <tr><td><b>URL scheme</b><br />Choose how the page URLs will look. Depending on your server configuration, you may need to select the first option. If you don't know, select the first option, and you can always change it later.</td><td colspan="2"><input type="radio" <?php if(!is_apache()) echo 'checked="checked" '; ?>name="urlscheme" value="ugly" id="ugly"> <label for="ugly">Standard URLs - compatible with any web server (www.example.com/index.php?title=Page_name)</label><br /><input type="radio" <?php if(is_apache()) echo 'checked="checked" '; ?>name="urlscheme" value="short" id="short"> <label for="short">Short URLs - requires Apache with a PHP module (www.example.com/index.php/Page_name)</label><br /><input type="radio" name="urlscheme" value="tiny" id="petite"> <label for="petite">Tiny URLs - requires Apache on Linux/Unix/BSD with PHP module and mod_rewrite enabled (www.example.com/Page_name)</label></td></tr>
+ </table>
+ <div class="pagenav">
+ <table border="0">
+ <tr>
+ <td><input type="submit" value="Continue" onclick="return verify();" name="_cont" /></td><td><p><span style="font-weight: bold;">Before clicking continue:</span><br />• Verify that your site information is correct. Again, all of the above settings can be changed from the administration panel.</p></td>
+ </tr>
+ </table>
+ </div>
+ </form>
+ <?php
+ break;
+ case "login":
+ if(!isset($_POST['_cont'])) {
+ echo 'No POST data signature found. Please <a href="install.php?mode=license">restart the installation</a>.';
+ $template->footer();
+ exit;
+ }
+ unset($_POST['_cont']);
+ require('config.php');
+ $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE);
+ if(!isset($cryptkey) || ( isset($cryptkey) && strlen($cryptkey) != AES_BITS / 4) )
+ {
+ $cryptkey = $aes->gen_readymade_key();
+ $handle = @fopen(ENANO_ROOT.'/config.php', 'w');
+ if(!$handle)
+ {
+ echo '<p>ERROR: Cannot open config.php for writing - exiting!</p>';
+ $template->footer();
+ exit;
+ }
+ fwrite($handle, '<?php $cryptkey = \''.$cryptkey.'\'; ?>');
+ fclose($handle);
+ }
+ ?>
+ <script type="text/javascript">
+ function verify()
+ {
+ var frm = document.forms.login;
+ ret = true;
+ if(frm.admin_user.value.match(/^([A-z0-9_\-\.]+)$/g))
+ {
+ document.getElementById('s_user').src = 'images/good.gif';
+ }
+ else
+ {
+ document.getElementById('s_user').src = 'images/bad.gif';
+ ret = false;
+ }
+ if(frm.admin_pass.value.length >= 6 && frm.admin_pass.value == frm.admin_pass_confirm.value)
+ {
+ document.getElementById('s_password').src = 'images/good.gif';
+ }
+ else
+ {
+ document.getElementById('s_password').src = 'images/bad.gif';
+ ret = false;
+ }
+ if(frm.admin_email.value.match(/^(?:[\w\d]+\.?)+@(?:(?:[\w\d]\-?)+\.)+\w{2,4}$/))
+ {
+ document.getElementById('s_email').src = 'images/good.gif';
+ }
+ else
+ {
+ document.getElementById('s_email').src = 'images/bad.gif';
+ ret = false;
+ }
+ if(ret) frm._cont.disabled = false;
+ else frm._cont.disabled = true;
+ return ret;
+ }
+ window.onload = verify;
+
+ function cryptdata()
+ {
+ if(!verify()) return false;
+ }
+ </script>
+ <form name="login" action="install.php?mode=confirm" method="post" onsubmit="runEncryption();">
+ <?php
+ $k = array_keys($_POST);
+ for($i=0;$i<sizeof($_POST);$i++) {
+ echo '<input type="hidden" name="'.$k[$i].'" value="'.$_POST[$k[$i]].'" />'."\n";
+ }
+ ?>
+ <p>Next, enter your desired username and password. The account you create here will be used to administer your site.</p>
+ <table border="0">
+ <tr><td><b>Administration username</b><br />The administration username you will use to log into your site.</td><td><input onkeyup="verify();" name="admin_user" type="text" size="30" /></td><td><img id="s_user" alt="Good/bad icon" src="images/bad.gif" /></td></tr>
+ <tr><td>Administration password:</td><td><input onkeyup="verify();" name="admin_pass" type="password" size="30" /></td><td rowspan="2"><img id="s_password" alt="Good/bad icon" src="images/bad.gif" /></td></tr>
+ <tr><td>Enter it again to confirm:</td><td><input onkeyup="verify();" name="admin_pass_confirm" type="password" size="30" /></td></tr>
+ <tr><td>Your e-mail address:</td><td><input onkeyup="verify();" name="admin_email" type="text" size="30" /></td><td><img id="s_email" alt="Good/bad icon" src="images/bad.gif" /></td></tr>
+ <tr><td colspan="3">If your browser supports Javascript, the password you enter here will be encrypted with AES before it is sent to the server.</td></tr>
+ </table>
+ <div class="pagenav">
+ <table border="0">
+ <tr>
+ <td><input type="submit" value="Continue" onclick="return cryptdata();" name="_cont" /></td><td><p><span style="font-weight: bold;">Before clicking continue:</span><br />• Remember the username and password you enter here! You will not be able to administer your site without the information you enter on this page.</p></td>
+ </tr>
+ </table>
+ </div>
+ <div id="cryptdebug"></div>
+ <input type="hidden" name="use_crypt" value="no" />
+ <input type="hidden" name="crypt_key" value="<?php echo $cryptkey; ?>" />
+ <input type="hidden" name="crypt_data" value="" />
+ </form>
+ <script type="text/javascript">
+ // <![CDATA[
+ disableJSONExts();
+ str = '';
+ for(i=0;i<keySizeInBits/4;i++) str+='0';
+ var key = hexToByteArray(str);
+ var pt = hexToByteArray(str);
+ var ct = rijndaelEncrypt(pt, key, "ECB");
+ var ect = byteArrayToHex(ct);
+ switch(keySizeInBits)
+ {
+ case 128:
+ v = '66e94bd4ef8a2c3b884cfa59ca342b2e';
+ break;
+ case 192:
+ v = 'aae06992acbf52a3e8f4a96ec9300bd7aae06992acbf52a3e8f4a96ec9300bd7';
+ break;
+ case 256:
+ v = 'dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a21492842087';
+ break;
+ }
+ var testpassed = ( ect == v && md5_vm_test() );
+ var frm = document.forms.login;
+ if(testpassed)
+ {
+ frm.use_crypt.value = 'yes';
+ var cryptkey = frm.crypt_key.value;
+ frm.crypt_key.value = '';
+ if(cryptkey != byteArrayToHex(hexToByteArray(cryptkey)))
+ {
+ alert('Byte array conversion SUCKS');
+ testpassed = false;
+ }
+ cryptkey = hexToByteArray(cryptkey);
+ if(!cryptkey || ( ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ) && cryptkey.length != keySizeInBits / 8 )
+ {
+ frm._cont.disabled = true;
+ len = ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ? '\nLen: '+cryptkey.length : '';
+ alert('The key is messed up\nType: '+typeof(cryptkey)+len);
+ }
+ }
+ frm.admin_user.focus();
+ function runEncryption()
+ {
+ if(testpassed)
+ {
+ pass = frm.admin_pass.value;
+ pass = stringToByteArray(pass);
+ cryptstring = rijndaelEncrypt(pass, cryptkey, 'ECB');
+ //decrypted = rijndaelDecrypt(cryptstring, cryptkey, 'ECB');
+ //decrypted = byteArrayToString(decrypted);
+ //return false;
+ if(!cryptstring)
+ {
+ return false;
+ }
+ cryptstring = byteArrayToHex(cryptstring);
+ document.getElementById('cryptdebug').innerHTML = '<pre>Data: '+cryptstring+'<br />Key: '+byteArrayToHex(cryptkey)+'</pre>';
+ frm.crypt_data.value = cryptstring;
+ frm.admin_pass.value = '';
+ frm.admin_pass_confirm.value = '';
+ }
+ return false;
+ }
+ // ]]>
+ </script>
+ <?php
+ break;
+ case "confirm":
+ if(!isset($_POST['_cont'])) {
+ echo 'No POST data signature found. Please <a href="install.php?mode=license">restart the installation</a>.';
+ $template->footer();
+ exit;
+ }
+ unset($_POST['_cont']);
+ ?>
+ <form name="confirm" action="install.php?mode=install" method="post">
+ <?php
+ $k = array_keys($_POST);
+ for($i=0;$i<sizeof($_POST);$i++) {
+ echo '<input type="hidden" name="'.$k[$i].'" value="'.$_POST[$k[$i]].'" />'."\n";
+ }
+ ?>
+ <h3>Enano is ready to install.</h3>
+ <p>The wizard has finished collecting information and is ready to install the database schema. Please review the information below,
+ and then click the button below to install the database.</p>
+ <ul>
+ <li>Database hostname: <?php echo $_POST['db_host']; ?></li>
+ <li>Database name: <?php echo $_POST['db_name']; ?></li>
+ <li>Database user: <?php echo $_POST['db_user']; ?></li>
+ <li>Database password: <hidden></li>
+ <li>Site name: <?php echo $_POST['sitename']; ?></li>
+ <li>Site description: <?php echo $_POST['sitedesc']; ?></li>
+ <li>Administration username: <?php echo $_POST['admin_user']; ?></li>
+ <li>Cipher strength: <?php echo (string)AES_BITS; ?>-bit AES<br /><small>Cipher strength is defined in the file constants.php; if you desire to change the cipher strength, you may do so and then restart installation. Unless your site is mission-critical, changing the cipher strength is not necessary.</small></li>
+ </ul>
+ <div class="pagenav">
+ <table border="0">
+ <tr>
+ <td><input type="submit" value="Install Enano!" name="_cont" /></td><td><p><span style="font-weight: bold;">Before clicking continue:</span><br />• Pray.</p></td>
+ </tr>
+ </table>
+ </div>
+ </form>
+ <?php
+ break;
+ case "install":
+ if(!isset($_POST['db_host']) ||
+ !isset($_POST['db_name']) ||
+ !isset($_POST['db_user']) ||
+ !isset($_POST['db_pass']) ||
+ !isset($_POST['sitename']) ||
+ !isset($_POST['sitedesc']) ||
+ !isset($_POST['copyright']) ||
+ !isset($_POST['admin_user']) ||
+ !isset($_POST['admin_pass']) ||
+ !isset($_POST['urlscheme'])
+ )
+ {
+ echo 'The installer has detected that one or more required form values is not set. Please <a href="install.php?mode=license">restart the installation</a>.';
+ $template->footer();
+ exit;
+ }
+ switch($_POST['urlscheme'])
+ {
+ case "ugly":
+ default:
+ $cp = scriptPath.'/index.php?title=';
+ break;
+ case "short":
+ $cp = scriptPath.'/index.php/';
+ break;
+ case "tiny":
+ $cp = scriptPath.'/';
+ break;
+ }
+ function err($t) { global $template; echo $t; $template->footer(); exit; }
+
+ echo 'Connecting to MySQL...';
+ if($_POST['db_root_user'] != '')
+ {
+ $conn = mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']);
+ if(!$conn) err('Error connecting to MySQL: '.mysql_error());
+ $q = mysql_query('USE '.$_POST['db_name']);
+ if(!$q)
+ {
+ $q = mysql_query('CREATE DATABASE '.$_POST['db_name']);
+ if(!$q) err('Error initializing database: '.mysql_error());
+ }
+ $q = mysql_query('GRANT ALL PRIVILEGES ON '.$_POST['db_name'].'.* TO \''.$_POST['db_user'].'\'@\'localhost\' IDENTIFIED BY \''.$_POST['db_pass'].'\' WITH GRANT OPTION;');
+ if(!$q) err('Could not create the user account');
+ $q = mysql_query('GRANT ALL PRIVILEGES ON '.$_POST['db_name'].'.* TO \''.$_POST['db_user'].'\'@\'%\' IDENTIFIED BY \''.$_POST['db_pass'].'\' WITH GRANT OPTION;');
+ if(!$q) err('Could not create the user account');
+ mysql_close($conn);
+ }
+ $conn = mysql_connect($_POST['db_host'], $_POST['db_user'], $_POST['db_pass']);
+ if(!$conn) err('Error connecting to MySQL: '.mysql_error());
+ $q = mysql_query('USE '.$_POST['db_name']);
+ if(!$q) err('Error selecting database: '.mysql_error());
+ echo 'done!<br />';
+
+ // Are we supposed to drop any existing tables? If so, do it now
+ if(isset($_POST['drop_tables']))
+ {
+ echo 'Dropping existing Enano tables...';
+ // Our list of tables included in Enano
+ $tables = Array( 'mdg_categories', 'mdg_comments', 'mdg_config', 'mdg_logs', 'mdg_page_text', 'mdg_session_keys', 'mdg_pages', 'mdg_users', 'mdg_themes', 'mdg_buddies', 'mdg_banlist', 'mdg_files', 'mdg_privmsgs', 'mdg_sidebar', 'mdg_hits', 'mdg_search_index', 'mdg_groups', 'mdg_group_members', 'mdg_acl', 'mdg_search_cache' );
+ $tables = implode(', ', $tables);
+ $tables = str_replace('mdg_', $_POST['table_prefix'], $tables);
+ $query_of_death = 'DROP TABLE '.$tables.';';
+ mysql_query($query_of_death); // We won't check for errors here because if this operation fails it probably means the tables didn't exist
+ echo 'done!<br />';
+ }
+
+ $cacheonoff = is_writable(ENANO_ROOT.'/cache/') ? '1' : '0';
+
+ echo 'Decrypting administration password...';
+ require('config.php');
+ $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE);
+ $key = $aes->hexToByteArray($cryptkey);
+ $enc = $aes->hexToByteArray($_POST['crypt_data']);
+ $dec = $aes->rijndaelDecrypt($enc, $key, 'ECB');
+ $dec = $aes->byteArrayToString($dec);
+ echo 'done!<br />Generating '.AES_BITS.'-bit AES private key...';
+ $privkey = $aes->gen_readymade_key();
+ $pkba = hexdecode($privkey);
+ $encpass = $aes->encrypt($dec, $pkba, ENC_HEX);
+
+ echo 'done!<br />Preparing for schema execution...';
+ $schema = file_get_contents('schema.sql');
+ $schema = str_replace('{{SITE_NAME}}', mysql_real_escape_string($_POST['sitename'] ), $schema);
+ $schema = str_replace('{{SITE_DESC}}', mysql_real_escape_string($_POST['sitedesc'] ), $schema);
+ $schema = str_replace('{{COPYRIGHT}}', mysql_real_escape_string($_POST['copyright'] ), $schema);
+ $schema = str_replace('{{ADMIN_USER}}', mysql_real_escape_string($_POST['admin_user'] ), $schema);
+ $schema = str_replace('{{ADMIN_PASS}}', mysql_real_escape_string($encpass ), $schema);
+ $schema = str_replace('{{ADMIN_EMAIL}}', mysql_real_escape_string($_POST['admin_email']), $schema);
+ $schema = str_replace('{{ENABLE_CACHE}}', mysql_real_escape_string($cacheonoff ), $schema);
+ $schema = str_replace('{{REAL_NAME}}', '', $schema);
+ $schema = str_replace('{{TABLE_PREFIX}}', $_POST['table_prefix'], $schema);
+ $schema = str_replace('{{VERSION}}', ENANO_VERSION, $schema);
+ // Not anymore! :-D
+ // $schema = str_replace('{{BETA_VERSION}}', ENANO_BETA_VERSION, $schema);
+
+ if(isset($_POST['wiki_mode'])) $schema = str_replace('{{WIKI_MODE}}', '1', $schema);
+ else $schema = str_replace('{{WIKI_MODE}}', '0', $schema);
+
+ // Build an array of queries
+ $schema = explode(";\n", $schema);
+ echo 'done!<br />Executing schema.sql...';
+
+ // OK, do the loop, baby!!!
+ foreach($schema as $q)
+ {
+ $r = mysql_query($q, $conn);
+ if(!$r) err('Error during mainstream installation: '.mysql_error());
+ }
+
+ echo 'done!<br />Writing configuration files...';
+ if($_POST['urlscheme']=='tiny')
+ {
+ $ht = fopen(dirname(__FILE__).'/.htaccess', 'a+');
+ if(!$ht) err('Error opening file .htaccess for writing');
+ fwrite($ht, '
+RewriteEngine on
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteRule ^(.+) '.scriptPath.'/index.php/$1 [L,QSA]
+RewriteRule \.(php|html|gif|jpg|png|css|js)$ - [L]
+');
+ fclose($ht);
+ }
+
+ $config_file = '<?php
+/* Enano auto-generated configuration file - editing not recommended! */
+$dbhost = \''.addslashes($_POST['db_host']).'\';
+$dbname = \''.addslashes($_POST['db_name']).'\';
+$dbuser = \''.addslashes($_POST['db_user']).'\';
+$dbpasswd = \''.addslashes($_POST['db_pass']).'\';
+if(!defined(\'ENANO_CONSTANTS\')) {
+define(\'ENANO_CONSTANTS\', \'\');
+define(\'table_prefix\', \''.$_POST['table_prefix'].'\');
+define(\'scriptPath\', \''.scriptPath.'\');
+define(\'contentPath\', \''.$cp.'\');
+define(\'ENANO_INSTALLED\', \'true\');
+}
+$crypto_key = \''.$privkey.'\';
+?>';
+
+ $cf_handle = fopen(dirname(__FILE__).'/config.php', 'w');
+ if(!$cf_handle) err('Couldn\'t open file config.php for writing');
+ fwrite($cf_handle, $config_file);
+ fclose($cf_handle);
+
+ echo 'done!<br />Initializing logs...';
+
+ $q = mysql_query('INSERT INTO ' . $_POST['table_prefix'] . 'logs(log_type,action,time_id,date_string,author,page_text,edit_summary) VALUES(\'security\', \'install_enano\', ' . time() . ', \'' . date('d M Y h:i a') . '\', \'' . mysql_real_escape_string($_POST['admin_user']) . '\', \'' . mysql_real_escape_string(ENANO_VERSION) . '\', \'' . mysql_real_escape_string($_SERVER['REMOTE_ADDR']) . '\');', $conn);
+ if ( !$q )
+ err('Error setting up logs: '.mysql_error());
+
+ echo 'done!<h3>Installation of Enano is complete.</h3><p>Review any warnings above, and then <a href="install.php?mode=finish">click here to finish the installation</a>.';
+
+ // echo '<script type="text/javascript">window.location="'.scriptPath.'/install.php?mode=finish";</script>';
+
+ break;
+ case "finish":
+ echo '<h3>Congratulations!</h3>
+ <p>You have finished installing Enano on this server.</p>
+ <h3>Now what?</h3>
+ <p>Click the link below to see the main page for your website. Where to go from here:</p>
+ <ul>
+ <li>The first thing you should do is log into your site using the Log in link on the sidebar.</li>
+ <li>Go into the Administration panel, expand General, and click General Configuration. There you will be able to configure some basic information about your site.</li>
+ <li>Visit the <a href="http://enanocms.org/Category:Plugins" onclick="window.open(this.href); return false;">Enano Plugin Gallery</a> to download and use plugins on your site.</li>
+ <li>Periodically create a backup of your database and filesystem, in case something goes wrong. This should be done at least once a week – more for wiki-based sites.</li>
+ <li>Hire some moderators, to help you keep rowdy users tame.</li>
+ <li>Tell the <a href="http://enanocms.org/Contact_us">Enano team</a> what you think.</li>
+ <li><b>Spread the word about Enano by adding a link to the Enano homepage on your sidebar!</b> You can enable this option in the General Configuration section of the administration panel.</li>
+ </ul>
+ <p><a href="index.php">Go to your website...</a></p>';
+ break;
+}
+$template->footer();
+
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/licenses/bsdlic.html Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,102 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml111.dtd">
+<html>
+<head>
+<title>BSD License</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+body {
+ margin: 0;
+ padding: 0;
+ background-color: #FFFFFF;
+ color: #000000;
+}
+body div.main {
+ border: 1px solid #cccccc;
+ background-color: #F1F3F5;
+ margin: 10px;
+ padding: 10px;
+}
+* {
+ font-family: verdana, tahoma, arial, helvetica, sans-serif;
+ font-size: 8pt;
+}
+p {
+ margin-left: 1.5em;
+}
+h1, h2, h3 {
+ color: #50A0D0;
+ font-weight: normal;
+ font-family: 'trebuchet ms', verdana, tahoma, arial, helvetica, sans-serif;
+}
+h1 {
+ font-size: 16pt;
+}
+h2 {
+ font-size: 12pt;
+ margin-left: 0.5em;
+}
+h3 {
+ font-size: 10pt;
+ margin-left: 1em;
+}
+a:link, a:visited, a:active {
+ color: #3080B0;
+ text-decoration: none;
+ border-bottom: 1px dotted #50A0D0;
+}
+a:hover {
+ color: #50A0D0;
+ border-bottom: 1px solid #50A0D0;
+}
+pre {
+ font-family: 'courier new', monospace;
+ background-color: #F8F8F8;
+ margin: 10px 10px 10px 30px;
+ max-height: 150px;
+ clip: rect(0px,auto,auto,0px);
+ overflow: auto;
+ padding: 10px;
+ border: 1px solid #3060B0;
+}
+ul li {
+ list-style-type: square;
+}
+div.copyright {
+ text-align: right;
+ font-size: smaller;
+}
+div.copyright * {
+ font-size: smaller;
+}
+</style>
+</head>
+<body>
+
+<div class="main">
+
+<h1>The BSD license</h1>
+
+<!-- BEGIN LICENSE TEXT -->
+
+<p>Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:</p>
+<p>Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.</p>
+<p>Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.</p>
+<p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</p>
+
+<h2>Extra copyright information for the Javascript MD5 algorithm</h2>
+
+<p>The JavaScript code implementing the algorithm is derived from the C code in RFC 1321 and is covered by the following copyright:</p>
+<p>License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function.</p>
+<p>License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work.</p>
+<p>RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind.</p>
+<p>These notices must be retained in any copies of any part of this documentation and/or software.</p>
+<p>This copyright does not prohibit distribution of the JavaScript MD5 code under the BSD license.</p>
+
+<!-- END LICENSE TEXT -->
+
+<div class="copyright">valid <a href="http://validator.w3.org/check/referer">xhtml</a> and <a href="http://jigsaw.w3.org/css-validator/validator?uri=referer">css</a> | design by <a href="http://enano.homelinux.org/User:dandaman32">dan fuhry</a> and <a href="http://www.fusionnerd.com/">manoj maddali</a></div>
+
+</div>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/licenses/cc-by-2.0.html Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,222 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml111.dtd">
+<html>
+<head>
+<title>Creative Commons Attribution 2.0 License</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+body {
+ margin: 0;
+ padding: 0;
+ background-color: #FFFFFF;
+ color: #000000;
+}
+body div.main {
+ border: 1px solid #cccccc;
+ background-color: #F1F3F5;
+ margin: 10px;
+ padding: 10px;
+}
+* {
+ font-family: verdana, tahoma, arial, helvetica, sans-serif;
+ font-size: 8pt;
+}
+p {
+ margin-left: 1.5em;
+}
+h1, h2, h3 {
+ color: #50A0D0;
+ font-weight: normal;
+ font-family: 'trebuchet ms', verdana, tahoma, arial, helvetica, sans-serif;
+}
+h1 {
+ font-size: 16pt;
+}
+h2 {
+ font-size: 12pt;
+ margin-left: 0.5em;
+}
+h3 {
+ font-size: 10pt;
+ margin-left: 1em;
+}
+a:link, a:visited, a:active {
+ color: #3080B0;
+ text-decoration: none;
+ border-bottom: 1px dotted #50A0D0;
+}
+a:hover {
+ color: #50A0D0;
+ border-bottom: 1px solid #50A0D0;
+}
+pre {
+ font-family: 'courier new', monospace;
+ background-color: #F8F8F8;
+ margin: 10px 10px 10px 30px;
+ max-height: 150px;
+ clip: rect(0px,auto,auto,0px);
+ overflow: auto;
+ padding: 10px;
+ border: 1px solid #3060B0;
+}
+ul li {
+ list-style-type: square;
+}
+div.copyright {
+ text-align: right;
+ font-size: smaller;
+}
+div.copyright * {
+ font-size: smaller;
+}
+</style>
+</head>
+<body>
+
+<div class="main">
+
+<h1>Creative Commons Attribution 2.0 License</h1>
+
+<!-- BEGIN LICENSE TEXT -->
+
+<p>THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. </p>
+
+<p>BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. </p>
+
+
+<p><strong>1. Definitions</strong> </p>
+
+<ol type="a">
+
+<li>
+<strong>"Collective Work"</strong> means a work, such as a periodical issue, anthology or encyclopedia, in which the Work in its entirety in unmodified form, along with a number of other contributions, constituting separate and independent works in themselves, are assembled into a collective whole. A work that constitutes a Collective Work will not be considered a Derivative Work (as defined below) for the purposes of this License.
+</li>
+
+<li>
+<strong>"Derivative Work"</strong> means a work based upon the Work or upon the Work and other pre-existing works, such as a translation, musical arrangement, dramatization, fictionalization, motion picture version, sound recording, art reproduction, abridgment, condensation, or any other form in which the Work may be recast, transformed, or adapted, except that a work that constitutes a Collective Work will not be considered a Derivative Work for the purpose of this License. For the avoidance of doubt, where the Work is a musical composition or sound recording, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered a Derivative Work for the purpose of this License.</li>
+
+<li>
+<strong>"Licensor"</strong> means the individual or entity that offers the Work under the terms of this License.
+</li>
+
+<li>
+<strong>"Original Author"</strong> means the individual or entity who created the Work.
+</li>
+
+<li>
+<strong>"Work"</strong> means the copyrightable work of authorship offered under the terms of this License.
+</li>
+
+<li>
+<strong>"You"</strong> means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
+
+</li>
+</ol>
+
+<p><strong>2. Fair Use Rights.</strong> Nothing in this license is intended to reduce, limit, or restrict any rights arising from fair use, first sale or other limitations on the exclusive rights of the copyright owner under copyright law or other applicable laws. </p>
+
+
+<p><strong>3. License Grant.</strong> Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: </p>
+
+
+<ol type="a">
+<li>
+
+to reproduce the Work, to incorporate the Work into one or more Collective Works, and to reproduce the Work as incorporated in the Collective Works;
+</li>
+
+<li>
+to create and reproduce Derivative Works;
+</li>
+
+<li>
+to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission the Work including as incorporated in Collective Works;
+
+</li>
+
+<li>
+to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission Derivative Works.
+</li>
+
+<li><p>For the avoidance of doubt, where the work is a musical composition:</p>
+
+<ol type="i">
+<li><strong>Performance Royalties Under Blanket Licenses</strong>. Licensor waives the exclusive right to collect, whether individually or via a performance rights society (e.g. ASCAP, BMI, SESAC), royalties for the public performance or public digital performance (e.g. webcast) of the Work.</li>
+
+<li><strong>Mechanical Rights and Statutory Royalties</strong>. Licensor waives the exclusive right to collect, whether individually or via a music rights agency or designated agent (e.g. Harry Fox Agency), royalties for any phonorecord You create from the Work ("cover version") and distribute, subject to the compulsory license created by 17 USC Section 115 of the US Copyright Act (or the equivalent in other jurisdictions).</li></ol></li>
+
+<li><strong>Webcasting Rights and Statutory Royalties</strong>. For the avoidance of doubt, where the Work is a sound recording, Licensor waives the exclusive right to collect, whether individually or via a performance-rights society (e.g. SoundExchange), royalties for the public digital performance (e.g. webcast) of the Work, subject to the compulsory license created by 17 USC Section 114 of the US Copyright Act (or the equivalent in other jurisdictions).</li>
+
+</ol>
+
+
+<p>The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. All rights not expressly granted by Licensor are hereby reserved.</p>
+
+<p><strong>4. Restrictions.</strong>The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: </p>
+
+
+<ol type="a">
+<li>
+You may distribute, publicly display, publicly perform, or publicly digitally perform the Work only under the terms of this License, and You must include a copy of, or the Uniform Resource Identifier for, this License with every copy or phonorecord of the Work You distribute, publicly display, publicly perform, or publicly digitally perform. You may not offer or impose any terms on the Work that alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute, publicly display, publicly perform, or publicly digitally perform the Work with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License Agreement. The above applies to the Work as incorporated in a Collective Work, but this does not require the Collective Work apart from the Work itself to be made subject to the terms of this License. If You create a Collective Work, upon notice from any Licensor You must, to the extent practicable, remove from the Collective Work any reference to such Licensor or the Original Author, as requested. If You create a Derivative Work, upon notice from any Licensor You must, to the extent practicable, remove from the Derivative Work any reference to such Licensor or the Original Author, as requested.
+</li>
+
+
+<li>
+If you distribute, publicly display, publicly perform, or publicly digitally perform the Work or any Derivative Works or Collective Works, You must keep intact all copyright notices for the Work and give the Original Author credit reasonable to the medium or means You are utilizing by conveying the name (or pseudonym if applicable) of the Original Author if supplied; the title of the Work if supplied; to the extent reasonably practicable, the Uniform Resource Identifier, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and in the case of a Derivative Work, a credit identifying the use of the Work in the Derivative Work (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). Such credit may be implemented in any reasonable manner; provided, however, that in the case of a Derivative Work or Collective Work, at a minimum such credit will appear where any other comparable authorship credit appears and in a manner at least as prominent as such other comparable authorship credit.
+</li>
+
+</ol>
+
+<p><strong>5. Representations, Warranties and Disclaimer</strong></p>
+
+<p>UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.</p>
+
+
+<p><strong>6. Limitation on Liability.</strong> EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. </p>
+
+<p><strong>7. Termination</strong> </p>
+
+<ol type="a">
+
+<li>
+This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Derivative Works or Collective Works from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
+</li>
+
+<li>
+Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.
+</li>
+</ol>
+
+<p><strong>8. Miscellaneous</strong> </p>
+
+<ol type="a">
+
+<li>
+Each time You distribute or publicly digitally perform the Work or a Collective Work, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
+</li>
+
+<li>
+Each time You distribute or publicly digitally perform a Derivative Work, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
+</li>
+
+<li>
+If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+</li>
+
+<li>
+No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
+
+</li>
+
+<li>
+This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
+</li>
+</ol>
+
+<!-- END LICENSE TEXT -->
+
+<div class="copyright">valid <a href="http://validator.w3.org/check/referer">xhtml</a> and <a href="http://jigsaw.w3.org/css-validator/validator?uri=referer">css</a> | design by <a href="http://enano.homelinux.org/User:dandaman32">dan fuhry</a> and <a href="http://www.fusionnerd.com/">manoj maddali</a></div>
+
+</div>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/licenses/gpl.html Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,190 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml111.dtd">
+<html>
+<head>
+<title>GNU General Public License</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+body {
+ margin: 0;
+ padding: 0;
+ background-color: #FFFFFF;
+ color: #000000;
+}
+body div.main {
+ border: 1px solid #cccccc;
+ background-color: #F1F3F5;
+ margin: 10px;
+ padding: 10px;
+}
+* {
+ font-family: verdana, tahoma, arial, helvetica, sans-serif;
+ font-size: 8pt;
+}
+p {
+ margin-left: 1.5em;
+}
+h1, h2, h3 {
+ color: #50A0D0;
+ font-weight: normal;
+ font-family: 'trebuchet ms', verdana, tahoma, arial, helvetica, sans-serif;
+}
+h1 {
+ font-size: 16pt;
+}
+h2 {
+ font-size: 12pt;
+ margin-left: 0.5em;
+}
+h3 {
+ font-size: 10pt;
+ margin-left: 1em;
+}
+a:link, a:visited, a:active {
+ color: #3080B0;
+ text-decoration: none;
+ border-bottom: 1px dotted #50A0D0;
+}
+a:hover {
+ color: #50A0D0;
+ border-bottom: 1px solid #50A0D0;
+}
+pre {
+ font-family: 'courier new', monospace;
+ background-color: #F8F8F8;
+ margin: 10px 10px 10px 30px;
+ max-height: 150px;
+ clip: rect(0px,auto,auto,0px);
+ overflow: auto;
+ padding: 10px;
+ border: 1px solid #3060B0;
+}
+li {
+ list-style-type: square;
+}
+div.copyright {
+ text-align: right;
+ font-size: smaller;
+}
+div.copyright * {
+ font-size: smaller;
+}
+</style>
+</head>
+<body>
+
+<div class="main">
+
+<h1>GNU General Public License</h1>
+
+<p>Version 2, June 1991</p>
+
+<pre>Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.</pre>
+
+<h2 id="toc0">Preamble</h2>
+<p>The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too.</p>
+<p>When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.</p>
+<p>To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.</p>
+<p>For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</p>
+<p>We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.</p>
+<p>Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.</p>
+<p>Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.</p>
+<p>The precise terms and conditions for copying, distribution and modification follow.</p>
+
+<h2 id="toc1">Terms and conditions for copying, distribution and modification</h2>
+
+<p>0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".</p>
+<p>Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.</p>
+<p>1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.</p>
+<p>You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.</p>
+<p>2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:</p>
+
+<ul>
+<li>You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.</li>
+<li>You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.</li>
+<li>If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)</li>
+</ul>
+
+<p>These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.</p>
+<p>Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.</p>
+<p>In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.</p>
+<p>3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:</p>
+
+<ul>
+<li>Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,</li>
+<li>Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,</li>
+<li>Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)</li>
+</ul>
+
+<p>The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.</p>
+<p>If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.</p>
+<p>4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.</p>
+<p>5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.</p>
+<p>6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.</p>
+<p>7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.</p>
+<p>If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.</p>
+<p>It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.</p>
+<p>This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.</p>
+<p>8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.</p>
+<p>9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</p>
+<p>Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.</p>
+<p>10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.</p>
+
+<h2 id="toc2">No Warranty</h2>
+
+<p style="font-weight: bold;">11. Because the program is licensed free of charge, there is no warranty for the program, to the extent permitted by applicable law. Except when otherwise stated in writing the copyright holders and/or other parties provide the program “as is” without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. The entire risk as to the quality and performance of the program is with you. Should the program prove defective, you assume the cost of all necessary servicing, repair, or correction.</p>
+<p style="font-weight: bold;">12. In no event unless required by applicable law or agreed to in writing will any copyright holder, or any other party who may modify and/or redistribute the program as permitted above, be liable to you for damages, including any general, special, incidental or consequential damages arising out of the use or inability to use the program (including but not limited to loss of data or data being rendered inaccurate or losses sustained by you or third parties or a failure of the program to operate with any other programs), even if such holder or other party has been advised of the possibility of such damages.</p>
+
+<p>END OF TERMS AND CONDITIONS</p>
+
+<h2 id="toc3">How to Apply These Terms to Your New Programs</h2>
+<p>If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.</p>
+<p>To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.</p>
+
+<pre><one line to give the program's name and a brief idea of what it does.>
+Copyright (C) <year> <name of author>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</pre>
+
+<p>Also add information on how to contact you by electronic and paper mail.</p>
+
+<p>If the program is interactive, make it output a short notice like this when it starts in an interactive mode:</p>
+
+<pre>Gnomovision version 69, Copyright (C) <year> <name of author>
+Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+This is free software, and you are welcome to redistribute it
+under certain conditions; type `show c' for details.</pre>
+
+<p>The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program.</p>
+<p>You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names:</p>
+
+<pre>Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+`Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+<signature of Ty Coon>, 1 April 1989
+Ty Coon, President of Vice</pre>
+
+<p>This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the <a href="lgpl.html">GNU Lesser General Public License</a> instead of this License.</p>
+
+<div class="copyright">valid <a href="http://validator.w3.org/check/referer">xhtml</a> and <a href="http://jigsaw.w3.org/css-validator/validator?uri=referer">css</a> | design by <a href="http://enano.homelinux.org/User:dandaman32">dan fuhry</a> and <a href="http://www.fusionnerd.com/">manoj maddali</a></div>
+
+</div>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/licenses/index.html Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,133 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml111.dtd">
+<html>
+<head>
+<title>Enano third-party libraries</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+body {
+ margin: 0;
+ padding: 0;
+ background-color: #FFFFFF;
+ color: #000000;
+}
+body div.main {
+ border: 1px solid #cccccc;
+ background-color: #F1F3F5;
+ margin: 10px;
+ padding: 10px;
+}
+* {
+ font-family: verdana, tahoma, arial, helvetica, sans-serif;
+ font-size: 8pt;
+}
+p {
+ margin-left: 1.5em;
+}
+h1, h2, h3 {
+ color: #50A0D0;
+ font-weight: normal;
+ font-family: 'trebuchet ms', verdana, tahoma, arial, helvetica, sans-serif;
+}
+h1 {
+ font-size: 16pt;
+}
+h2 {
+ font-size: 12pt;
+ margin-left: 0.5em;
+}
+h3 {
+ font-size: 10pt;
+ margin-left: 1em;
+}
+a:link, a:visited, a:active {
+ color: #3080B0;
+ text-decoration: none;
+ border-bottom: 1px dotted #50A0D0;
+}
+a:hover {
+ color: #50A0D0;
+ border-bottom: 1px solid #50A0D0;
+}
+pre {
+ font-family: 'courier new', monospace;
+ background-color: #F8F8F8;
+ margin: 10px 10px 10px 30px;
+ max-height: 150px;
+ clip: rect(0px,auto,auto,0px);
+ overflow: auto;
+ padding: 10px;
+ border: 1px solid #3060B0;
+}
+ul li {
+ list-style-type: square;
+}
+div.copyright {
+ text-align: right;
+ font-size: smaller;
+}
+div.copyright * {
+ font-size: smaller;
+}
+</style>
+</head>
+<body>
+
+<div class="main">
+
+<h1>OK, so I didn't write all of Enano's code.</h1>
+<p>Enano relies on some third-party libraries for some of its functionality. Not all of these libraries are licensed under the same terms as Enano; a list of third-party libraries is available below, sorted by which license the library is under.</p>
+
+<h2>GNU General Public License</h2>
+<p><a href="gpl.html">View the text of this license</a></p>
+<ul>
+ <li><a href="http://phpwiki.sourceforge.net/">phpWiki</a> - just the diff engine, which is also used in MediaWiki</li>
+ <li><a href="http://www.mediawiki.org/">MediaWiki</a>'s table parsing engine (the Text_Wiki one doesn't work in PHP 5.2.0)</li>
+ <li>One of the CAPTCHA easter eggs was ported from the phpBB <a href="http://phpbbhacks.com/download/6276">Advanced Visual Confirmation Mod</a>. The strange thing here is this: The installation instructions expressly state that the MOD is distributed under the GPL, but immediately afterwards it says that the MOD "can be freely used, but not distributed, without permission." Sorry buddy, but I'm with the FSF on this one, I'm legally allowed to distribute/modify it under the GPL.
+ <li>The <a href="http://www.jracademy.com/~jtucek/">e-mail address encryption</a> routine was originally written by Jim Tucek, and ported to PHP by Dan Fuhry. Jim allowed the code to be released under the GPL specifically for Enano.</li>
+</ul>
+
+<h2>GNU Lesser General Public License</h2>
+<p><a href="lgpl.html">View the text of this license</a></p>
+<ul>
+ <li><a href="http://wiki.ciaweb.net/yawiki/index.php?area=Text_Wiki">Text_Wiki</a>, the wiki-formatting parser</li>
+ <li><a href="http://www.debugconsole.de/">debugConsole</a></li>
+</ul>
+
+<h2>Creative Commons Licenses</h2>
+<p>View text: <a href="cc-by-2.0.html">Attribution 2.0</a> [<a href="http://creativecommons.org/licenses/by/2.0/">deed</a>]</p>
+<ul>
+ <li><a href="http://boring.youngpup.net/">youngpup</a>'s DOM-Drag class</li>
+</ul>
+
+<h2>The PHP License</h2>
+<p><a href="phplic.html">View the text of this license</a></p>
+<ul>
+ <li><a href="http://www.phpclasses.org/browse/package/1567.html">BarGraph</a> for PHP</li>
+</ul>
+
+<h2>The BSD License</h2>
+<p><a href="bsdlic.html">View the text of this license</a></p>
+<ul>
+ <li><a href="http://pajhome.org.uk/">Paul Johnston</a>'s implementations of the MD5 and SHA1 algorithms in Javascript</li>
+</ul>
+
+<h2>The MIT/X License</h2>
+<p><a href="mitlic.html">View the text of this license</a></p>
+<ul>
+ <li><a href="http://www.3site.it/">FastJSON</a> - a JSON encoder/decoder. Copyright © 2006 - 2007 Andrea Giammarchi.</li>
+</ul>
+
+<h2>Unknown license</h2>
+<p>For the following libraries, the license was either not formally stated or could not be found.</p>
+<ul>
+ <li><a href="http://www.thecodebehind.com/code/slide-in-slide-out-ala-digg.aspx">Slide-in-slide-out, ala Digg</a> - used for the collapsible sidebar headings in the Oxygen theme. The original author says the code may be used "for whatever you want."</li>
+ <li><a href="http://szewo.com/php/graph">Graph Generator for PHP</a> - only used when the GD-based graph generator won't work (e.g. no GD support)</li>
+ <li><a href="http://www.softcomplex.com/products/tigra_tree_menu/">Tigra Tree Menu</a> - a modified version that remembers the state of the tree. The license terms are stated <a href="http://www.softcomplex.com/products/tigra_tree_menu/docs/#terms_cond">here</a>. I believe that these terms are GPL-compatible, at least to a point where the code can be used in GPL-licensed programs. If you believe this is not the case then please <a href="http://enano.homelinux.org/Contact_us">contact me</a>.</li>
+</ul>
+
+<div class="copyright">valid <a href="http://validator.w3.org/check/referer">xhtml</a> and <a href="http://jigsaw.w3.org/css-validator/validator?uri=referer">css</a> | design by <a href="http://enano.homelinux.org/User:dandaman32">dan fuhry</a> and <a href="http://www.fusionnerd.com/">manoj maddali</a></div>
+
+</div>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/licenses/lgpl.html Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,646 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml111.dtd">
+<html>
+<head>
+<title>GNU Lesser General Public License</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+body {
+ margin: 0;
+ padding: 0;
+ background-color: #FFFFFF;
+ color: #000000;
+}
+body div.main {
+ border: 1px solid #cccccc;
+ background-color: #F1F3F5;
+ margin: 10px;
+ padding: 10px;
+}
+* {
+ font-family: verdana, tahoma, arial, helvetica, sans-serif;
+ font-size: 8pt;
+}
+p {
+ margin-left: 1.5em;
+}
+h1, h2, h3 {
+ color: #50A0D0;
+ font-weight: normal;
+ font-family: 'trebuchet ms', verdana, tahoma, arial, helvetica, sans-serif;
+}
+h1 {
+ font-size: 16pt;
+}
+h2 {
+ font-size: 12pt;
+ margin-left: 0.5em;
+}
+h3 {
+ font-size: 10pt;
+ margin-left: 1em;
+}
+a:link, a:visited, a:active {
+ color: #3080B0;
+ text-decoration: none;
+ border-bottom: 1px dotted #50A0D0;
+}
+a:hover {
+ color: #50A0D0;
+ border-bottom: 1px solid #50A0D0;
+}
+pre {
+ font-family: 'courier new', monospace;
+ background-color: #F8F8F8;
+ margin: 10px 10px 10px 30px;
+ max-height: 150px;
+ clip: rect(0px,auto,auto,0px);
+ overflow: auto;
+ padding: 10px;
+ border: 1px solid #3060B0;
+}
+li {
+ list-style-type: square;
+}
+div.copyright {
+ text-align: right;
+ font-size: smaller;
+}
+div.copyright * {
+ font-size: smaller;
+}
+</style>
+</head>
+<body>
+
+<div class="main">
+
+<h1>GNU Lesser General Public License</h1>
+
+<!-- BEGIN LICENSE TEXT -->
+
+<p>Version 2.1, February 1999</p>
+
+<pre>
+Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+</pre>
+
+<h2>Preamble</h2>
+
+<p>The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General
+Public Licenses are intended to guarantee your freedom to share
+and change free software--to make sure the software is free for
+all its users.</p>
+
+<p>This license, the Lesser General Public License, applies to
+some specially designated software packages--typically
+libraries--of the Free Software Foundation and other authors who
+decide to use it. You can use it too, but we suggest you first
+think carefully about whether this license or the ordinary
+General Public License is the better strategy to use in any
+particular case, based on the explanations below.</p>
+
+<p>When we speak of free software, we are referring to freedom of
+use, not price. Our General Public Licenses are designed to make
+sure that you have the freedom to distribute copies of free
+software (and charge for this service if you wish); that you
+receive source code or can get it if you want it; that you can
+change the software and use pieces of it in new free programs;
+and that you are informed that you can do these things.</p>
+
+<p>To protect your rights, we need to make restrictions that
+forbid distributors to deny you these rights or to ask you to
+surrender these rights. These restrictions translate to certain
+responsibilities for you if you distribute copies of the library
+or if you modify it.</p>
+
+<p>For example, if you distribute copies of the library, whether
+gratis or for a fee, you must give the recipients all the rights
+that we gave you. You must make sure that they, too, receive or
+can get the source code. If you link other code with the library,
+you must provide complete object files to the recipients, so that
+they can relink them with the library after making changes to the
+library and recompiling it. And you must show them these terms so
+they know their rights.</p>
+
+<p>We protect your rights with a two-step method: (1) we
+copyright the library, and (2) we offer you this license, which
+gives you legal permission to copy, distribute and/or modify the
+library.</p>
+
+<p>To protect each distributor, we want to make it very clear
+that there is no warranty for the free library. Also, if the
+library is modified by someone else and passed on, the recipients
+should know that what they have is not the original version, so
+that the original author's reputation will not be affected by
+problems that might be introduced by others.</p>
+
+<p>Finally, software patents pose a constant threat to the
+existence of any free program. We wish to make sure that a
+company cannot effectively restrict the users of a free program
+by obtaining a restrictive license from a patent holder.
+Therefore, we insist that any patent license obtained for a
+version of the library must be consistent with the full freedom
+of use specified in this license.</p>
+
+<p>Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries,
+and is quite different from the ordinary General Public License.
+We use this license for certain libraries in order to permit
+linking those libraries into non-free programs.</p>
+
+<p>When a program is linked with a library, whether statically or
+using a shared library, the combination of the two is legally
+speaking a combined work, a derivative of the original library.
+The ordinary General Public License therefore permits such
+linking only if the entire combination fits its criteria of
+freedom. The Lesser General Public License permits more lax
+criteria for linking other code with the library.</p>
+
+<p>We call this license the "Lesser" General Public License
+because it does Less to protect the user's freedom than the
+ordinary General Public License. It also provides other free
+software developers Less of an advantage over competing non-free
+programs. These disadvantages are the reason we use the ordinary
+General Public License for many libraries. However, the Lesser
+license provides advantages in certain special circumstances.</p>
+
+<p>For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that
+it becomes a de-facto standard. To achieve this, non-free
+programs must be allowed to use the library. A more frequent case
+is that a free library does the same job as widely used non-free
+libraries. In this case, there is little to gain by limiting the
+free library to free software only, so we use the Lesser General
+Public License.</p>
+
+<p>In other cases, permission to use a particular library in
+non-free programs enables a greater number of people to use a
+large body of free software. For example, permission to use the
+GNU C Library in non-free programs enables many more people to
+use the whole GNU operating system, as well as its variant, the
+GNU/Linux operating system.</p>
+
+<p>Although the Lesser General Public License is Less protective
+of the users' freedom, it does ensure that the user of a program
+that is linked with the Library has the freedom and the
+wherewithal to run that program using a modified version of the
+Library.</p>
+
+<p>The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference
+between a "work based on the library" and a "work that uses the
+library". The former contains code derived from the library,
+whereas the latter must be combined with the library in order to
+run.</p>
+
+<h2>Terms and conditions for copying, distribution and modification</h2>
+
+<p><b>0.</b> This License Agreement applies to any software
+library or other program which contains a notice placed by the
+copyright holder or other authorized party saying it may be
+distributed under the terms of this Lesser General Public License
+(also called "this License"). Each licensee is addressed as
+"you".</p>
+
+<p>A "library" means a collection of software functions and/or
+data prepared so as to be conveniently linked with application
+programs (which use some of those functions and data) to form
+executables.</p>
+
+<p>The "Library", below, refers to any such software library or
+work which has been distributed under these terms. A "work based
+on the Library" means either the Library or any derivative work
+under copyright law: that is to say, a work containing the
+Library or a portion of it, either verbatim or with modifications
+and/or translated straightforwardly into another language.
+(Hereinafter, translation is included without limitation in the
+term "modification".)</p>
+
+<p>"Source code" for a work means the preferred form of the work
+for making modifications to it. For a library, complete source
+code means all the source code for all modules it contains, plus
+any associated interface definition files, plus the scripts used
+to control compilation and installation of the library.</p>
+
+<p>Activities other than copying, distribution and modification
+are not covered by this License; they are outside its scope. The
+act of running a program using the Library is not restricted, and
+output from such a program is covered only if its contents
+constitute a work based on the Library (independent of the use of
+the Library in a tool for writing it). Whether that is true
+depends on what the Library does and what the program that uses
+the Library does.</p>
+
+<p><b>1.</b> You may copy and distribute verbatim copies of the
+Library's complete source code as you receive it, in any medium,
+provided that you conspicuously and appropriately publish on each
+copy an appropriate copyright notice and disclaimer of warranty;
+keep intact all the notices that refer to this License and to the
+absence of any warranty; and distribute a copy of this License
+along with the Library.</p>
+
+<p>You may charge a fee for the physical act of transferring a
+copy, and you may at your option offer warranty protection in
+exchange for a fee.</p>
+
+<p><b>2.</b> You may modify your copy or copies of the Library or
+any portion of it, thus forming a work based on the Library, and
+copy and distribute such modifications or work under the terms of
+Section 1 above, provided that you also meet all of these
+conditions:</p>
+
+<ul>
+<li><b>a)</b> The modified work must itself be a software
+library.</li>
+
+<li><b>b)</b> You must cause the files modified to carry
+prominent notices stating that you changed the files and the date
+of any change.</li>
+
+<li><b>c)</b> You must cause the whole of the work to be licensed
+at no charge to all third parties under the terms of this
+License.</li>
+
+<li><b>d)</b> If a facility in the modified Library refers to a
+function or a table of data to be supplied by an application
+program that uses the facility, other than as an argument passed
+when the facility is invoked, then you must make a good faith
+effort to ensure that, in the event an application does not
+supply such function or table, the facility still operates, and
+performs whatever part of its purpose remains meaningful.
+
+<p>(For example, a function in a library to compute square roots
+has a purpose that is entirely well-defined independent of the
+application. Therefore, Subsection 2d requires that any
+application-supplied function or table used by this function must
+be optional: if the application does not supply it, the square
+root function must still compute square roots.)</p>
+
+<p>These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the
+Library, and can be reasonably considered independent and
+separate works in themselves, then this License, and its terms,
+do not apply to those sections when you distribute them as
+separate works. But when you distribute the same sections as part
+of a whole which is a work based on the Library, the distribution
+of the whole must be on the terms of this License, whose
+permissions for other licensees extend to the entire whole, and
+thus to each and every part regardless of who wrote it.</p>
+
+<p>Thus, it is not the intent of this section to claim rights or
+contest your rights to work written entirely by you; rather, the
+intent is to exercise the right to control the distribution of
+derivative or collective works based on the Library.</p>
+
+<p>In addition, mere aggregation of another work not based on the
+Library with the Library (or with a work based on the Library) on
+a volume of a storage or distribution medium does not bring the
+other work under the scope of this License.</p>
+</li>
+</ul>
+
+<p><b>3.</b> You may opt to apply the terms of the ordinary GNU
+General Public License instead of this License to a given copy of
+the Library. To do this, you must alter all the notices that
+refer to this License, so that they refer to the ordinary GNU
+General Public License, version 2, instead of to this License.
+(If a newer version than version 2 of the ordinary GNU General
+Public License has appeared, then you can specify that version
+instead if you wish.) Do not make any other change in these
+notices.</p>
+
+<p>Once this change is made in a given copy, it is irreversible
+for that copy, so the ordinary GNU General Public License applies
+to all subsequent copies and derivative works made from that
+copy.</p>
+
+<p>This option is useful when you wish to copy part of the code
+of the Library into a program that is not a library.</p>
+
+<p><b>4.</b> You may copy and distribute the Library (or a
+portion or derivative of it, under Section 2) in object code or
+executable form under the terms of Sections 1 and 2 above
+provided that you accompany it with the complete corresponding
+machine-readable source code, which must be distributed under the
+terms of Sections 1 and 2 above on a medium customarily used for
+software interchange.</p>
+
+<p>If distribution of object code is made by offering access to
+copy from a designated place, then offering equivalent access to
+copy the source code from the same place satisfies the
+requirement to distribute the source code, even though third
+parties are not compelled to copy the source along with the
+object code.</p>
+
+<p><b>5.</b> A program that contains no derivative of any portion
+of the Library, but is designed to work with the Library by being
+compiled or linked with it, is called a "work that uses the
+Library". Such a work, in isolation, is not a derivative work of
+the Library, and therefore falls outside the scope of this
+License.</p>
+
+<p>However, linking a "work that uses the Library" with the
+Library creates an executable that is a derivative of the Library
+(because it contains portions of the Library), rather than a
+"work that uses the library". The executable is therefore covered
+by this License. Section 6 states terms for distribution of such
+executables.</p>
+
+<p>When a "work that uses the Library" uses material from a
+header file that is part of the Library, the object code for the
+work may be a derivative work of the Library even though the
+source code is not. Whether this is true is especially
+significant if the work can be linked without the Library, or if
+the work is itself a library. The threshold for this to be true
+is not precisely defined by law.</p>
+
+<p>If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small
+inline functions (ten lines or less in length), then the use of
+the object file is unrestricted, regardless of whether it is
+legally a derivative work. (Executables containing this object
+code plus portions of the Library will still fall under Section
+6.)</p>
+
+<p>Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of
+Section 6. Any executables containing that work also fall under
+Section 6, whether or not they are linked directly with the
+Library itself.</p>
+
+<p><b>6.</b> As an exception to the Sections above, you may also
+combine or link a "work that uses the Library" with the Library
+to produce a work containing portions of the Library, and
+distribute that work under terms of your choice, provided that
+the terms permit modification of the work for the customer's own
+use and reverse engineering for debugging such modifications.</p>
+
+<p>You must give prominent notice with each copy of the work that
+the Library is used in it and that the Library and its use are
+covered by this License. You must supply a copy of this License.
+If the work during execution displays copyright notices, you must
+include the copyright notice for the Library among them, as well
+as a reference directing the user to the copy of this License.
+Also, you must do one of these things:</p>
+
+<ul>
+<li><b>a)</b> Accompany the work with the complete corresponding
+machine-readable source code for the Library including whatever
+changes were used in the work (which must be distributed under
+Sections 1 and 2 above); and, if the work is an executable linked
+with the Library, with the complete machine-readable "work that
+uses the Library", as object code and/or source code, so that the
+user can modify the Library and then relink to produce a modified
+executable containing the modified Library. (It is understood
+that the user who changes the contents of definitions files in
+the Library will not necessarily be able to recompile the
+application to use the modified definitions.)</li>
+
+<li><b>b)</b> Use a suitable shared library mechanism for linking
+with the Library. A suitable mechanism is one that (1) uses at
+run time a copy of the library already present on the user's
+computer system, rather than copying library functions into the
+executable, and (2) will operate properly with a modified version
+of the library, if the user installs one, as long as the modified
+version is interface-compatible with the version that the work
+was made with.</li>
+
+<li><b>c)</b> Accompany the work with a written offer, valid for
+at least three years, to give the same user the materials
+specified in Subsection 6a, above, for a charge no more than the
+cost of performing this distribution.</li>
+
+<li><b>d)</b> If distribution of the work is made by offering
+access to copy from a designated place, offer equivalent access
+to copy the above specified materials from the same place.</li>
+
+<li><b>e)</b> Verify that the user has already received a copy of
+these materials or that you have already sent this user a
+copy.</li>
+</ul>
+
+<p>For an executable, the required form of the "work that uses
+the Library" must include any data and utility programs needed
+for reproducing the executable from it. However, as a special
+exception, the materials to be distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of
+the operating system on which the executable runs, unless that
+component itself accompanies the executable.</p>
+
+<p>It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you
+cannot use both them and the Library together in an executable
+that you distribute.</p>
+
+<p><b>7.</b> You may place library facilities that are a work
+based on the Library side-by-side in a single library together
+with other library facilities not covered by this License, and
+distribute such a combined library, provided that the separate
+distribution of the work based on the Library and of the other
+library facilities is otherwise permitted, and provided that you
+do these two things:</p>
+
+<ul>
+<li><b>a)</b> Accompany the combined library with a copy of the
+same work based on the Library, uncombined with any other library
+facilities. This must be distributed under the terms of the
+Sections above.</li>
+
+<li><b>b)</b> Give prominent notice with the combined library of
+the fact that part of it is a work based on the Library, and
+explaining where to find the accompanying uncombined form of the
+same work.</li>
+</ul>
+
+<p><b>8.</b> You may not copy, modify, sublicense, link with, or
+distribute the Library except as expressly provided under this
+License. Any attempt otherwise to copy, modify, sublicense, link
+with, or distribute the Library is void, and will automatically
+terminate your rights under this License. However, parties who
+have received copies, or rights, from you under this License will
+not have their licenses terminated so long as such parties remain
+in full compliance.</p>
+
+<p><b>9.</b> You are not required to accept this License, since
+you have not signed it. However, nothing else grants you
+permission to modify or distribute the Library or its derivative
+works. These actions are prohibited by law if you do not accept
+this License. Therefore, by modifying or distributing the Library
+(or any work based on the Library), you indicate your acceptance
+of this License to do so, and all its terms and conditions for
+copying, distributing or modifying the Library or works based on
+it.</p>
+
+<p><b>10.</b> Each time you redistribute the Library (or any work
+based on the Library), the recipient automatically receives a
+license from the original licensor to copy, distribute, link with
+or modify the Library subject to these terms and conditions. You
+may not impose any further restrictions on the recipients'
+exercise of the rights granted herein. You are not responsible
+for enforcing compliance by third parties with this License.</p>
+
+<p><b>11.</b> If, as a consequence of a court judgment or
+allegation of patent infringement or for any other reason (not
+limited to patent issues), conditions are imposed on you (whether
+by court order, agreement or otherwise) that contradict the
+conditions of this License, they do not excuse you from the
+conditions of this License. If you cannot distribute so as to
+satisfy simultaneously your obligations under this License and
+any other pertinent obligations, then as a consequence you may
+not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the
+Library by all those who receive copies directly or indirectly
+through you, then the only way you could satisfy both it and this
+License would be to refrain entirely from distribution of the
+Library.</p>
+
+<p>If any portion of this section is held invalid or
+unenforceable under any particular circumstance, the balance of
+the section is intended to apply, and the section as a whole is
+intended to apply in other circumstances.</p>
+
+<p>It is not the purpose of this section to induce you to
+infringe any patents or other property right claims or to contest
+validity of any such claims; this section has the sole purpose of
+protecting the integrity of the free software distribution system
+which is implemented by public license practices. Many people
+have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent
+application of that system; it is up to the author/donor to
+decide if he or she is willing to distribute software through any
+other system and a licensee cannot impose that choice.</p>
+
+<p>This section is intended to make thoroughly clear what is
+believed to be a consequence of the rest of this License.</p>
+
+<p><b>12.</b> If the distribution and/or use of the Library is
+restricted in certain countries either by patents or by
+copyrighted interfaces, the original copyright holder who places
+the Library under this License may add an explicit geographical
+distribution limitation excluding those countries, so that
+distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation
+as if written in the body of this License.</p>
+
+<p><b>13.</b> The Free Software Foundation may publish revised
+and/or new versions of the Lesser General Public License from
+time to time. Such new versions will be similar in spirit to the
+present version, but may differ in detail to address new problems
+or concerns.</p>
+
+<p>Each version is given a distinguishing version number. If the
+Library specifies a version number of this License which applies
+to it and "any later version", you have the option of following
+the terms and conditions either of that version or of any later
+version published by the Free Software Foundation. If the Library
+does not specify a license version number, you may choose any
+version ever published by the Free Software Foundation.</p>
+
+<p><b>14.</b> If you wish to incorporate parts of the Library
+into other free programs whose distribution conditions are
+incompatible with these, write to the author to ask for
+permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we
+sometimes make exceptions for this. Our decision will be guided
+by the two goals of preserving the free status of all derivatives
+of our free software and of promoting the sharing and reuse of
+software generally.</p>
+
+<p><b>NO WARRANTY</b></p>
+
+<p><b>15.</b> BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE,
+THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE
+COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS
+IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE
+RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
+YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</p>
+
+<p><b>16.</b> IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR
+AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER
+PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED
+ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
+SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO
+LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES
+SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO
+OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER
+PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</p>
+
+<h2>END OF TERMS AND CONDITIONS</h2>
+
+<h2>How to Apply These Terms to Your New Libraries</h2>
+
+<p>If you develop a new library, and you want it to be of the
+greatest possible use to the public, we recommend making it free
+software that everyone can redistribute and change. You can do so
+by permitting redistribution under these terms (or,
+alternatively, under the terms of the ordinary General Public
+License).</p>
+
+<p>To apply these terms, attach the following notices to the
+library. It is safest to attach them to the start of each source
+file to most effectively convey the exclusion of warranty; and
+each file should have at least the "copyright" line and a pointer
+to where the full notice is found.</p>
+
+<pre>
+<one line to give the library's name and an idea of what it does.>
+Copyright (C) <year> <name of author>
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+</pre>
+
+<p>Also add information on how to contact you by electronic and
+paper mail.</p>
+
+<p>You should also get your employer (if you work as a
+programmer) or your school, if any, to sign a "copyright
+disclaimer" for the library, if necessary. Here is a sample;
+alter the names:</p>
+
+<pre>
+Yoyodyne, Inc., hereby disclaims all copyright interest in
+the library `Frob' (a library for tweaking knobs) written
+by James Random Hacker.
+
+<signature of Ty Coon>, 1 April 1990
+Ty Coon, President of Vice
+</pre>
+
+<p>That's all there is to it!</p>
+
+<!-- END LICENSE TEXT -->
+
+<div class="copyright">valid <a href="http://validator.w3.org/check/referer">xhtml</a> and <a href="http://jigsaw.w3.org/css-validator/validator?uri=referer">css</a> | design by <a href="http://enano.homelinux.org/User:dandaman32">dan fuhry</a> and <a href="http://www.fusionnerd.com/">manoj maddali</a></div>
+
+</div>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/licenses/mitlic.html Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,93 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml111.dtd">
+<html>
+<head>
+<title>MIT/X License</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+body {
+ margin: 0;
+ padding: 0;
+ background-color: #FFFFFF;
+ color: #000000;
+}
+body div.main {
+ border: 1px solid #cccccc;
+ background-color: #F1F3F5;
+ margin: 10px;
+ padding: 10px;
+}
+* {
+ font-family: verdana, tahoma, arial, helvetica, sans-serif;
+ font-size: 8pt;
+}
+p {
+ margin-left: 1.5em;
+}
+h1, h2, h3 {
+ color: #50A0D0;
+ font-weight: normal;
+ font-family: 'trebuchet ms', verdana, tahoma, arial, helvetica, sans-serif;
+}
+h1 {
+ font-size: 16pt;
+}
+h2 {
+ font-size: 12pt;
+ margin-left: 0.5em;
+}
+h3 {
+ font-size: 10pt;
+ margin-left: 1em;
+}
+a:link, a:visited, a:active {
+ color: #3080B0;
+ text-decoration: none;
+ border-bottom: 1px dotted #50A0D0;
+}
+a:hover {
+ color: #50A0D0;
+ border-bottom: 1px solid #50A0D0;
+}
+pre {
+ font-family: 'courier new', monospace;
+ background-color: #F8F8F8;
+ margin: 10px 10px 10px 30px;
+ max-height: 150px;
+ clip: rect(0px,auto,auto,0px);
+ overflow: auto;
+ padding: 10px;
+ border: 1px solid #3060B0;
+}
+ul li {
+ list-style-type: square;
+}
+div.copyright {
+ text-align: right;
+ font-size: smaller;
+}
+div.copyright * {
+ font-size: smaller;
+}
+</style>
+</head>
+<body>
+
+<div class="main">
+
+<h1>The MIT/X license</h1>
+
+<!-- BEGIN LICENSE TEXT -->
+
+<p>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:</p>
+<p>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</p>
+<p><strong>The software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.</strong></p>
+
+<!-- END LICENSE TEXT -->
+
+<div class="copyright">valid <a href="http://validator.w3.org/check/referer">xhtml</a> and <a href="http://jigsaw.w3.org/css-validator/validator?uri=referer">css</a> | design by <a href="http://enano.homelinux.org/User:dandaman32">dan fuhry</a> and <a href="http://www.fusionnerd.com/">manoj maddali</a></div>
+
+</div>
+
+</body>
+</html>
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/licenses/phplic.html Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,154 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml111.dtd">
+<html>
+<head>
+<title>The PHP License</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+body {
+ margin: 0;
+ padding: 0;
+ background-color: #FFFFFF;
+ color: #000000;
+}
+body div.main {
+ border: 1px solid #cccccc;
+ background-color: #F1F3F5;
+ margin: 10px;
+ padding: 10px;
+}
+* {
+ font-family: verdana, tahoma, arial, helvetica, sans-serif;
+ font-size: 8pt;
+}
+p {
+ margin-left: 1.5em;
+}
+h1, h2, h3 {
+ color: #50A0D0;
+ font-weight: normal;
+ font-family: 'trebuchet ms', verdana, tahoma, arial, helvetica, sans-serif;
+}
+h1 {
+ font-size: 16pt;
+}
+h2 {
+ font-size: 12pt;
+ margin-left: 0.5em;
+}
+h3 {
+ font-size: 10pt;
+ margin-left: 1em;
+}
+a:link, a:visited, a:active {
+ color: #3080B0;
+ text-decoration: none;
+ border-bottom: 1px dotted #50A0D0;
+}
+a:hover {
+ color: #50A0D0;
+ border-bottom: 1px solid #50A0D0;
+}
+pre {
+ font-family: 'courier new', monospace;
+ background-color: #F8F8F8;
+ margin: 10px 10px 10px 30px;
+ max-height: 150px;
+ clip: rect(0px,auto,auto,0px);
+ overflow: auto;
+ padding: 10px;
+ border: 1px solid #3060B0;
+}
+ul li {
+ list-style-type: square;
+}
+div.copyright {
+ text-align: right;
+ font-size: smaller;
+}
+div.copyright * {
+ font-size: smaller;
+}
+</style>
+</head>
+<body>
+
+<div class="main">
+
+<h1>The PHP license, version 3.01</h1>
+
+<!-- BEGIN LICENSE TEXT -->
+
+<p>Copyright (c) 1999 - 2006 The PHP Group. All rights reserved.</p>
+
+<p>Redistribution and use in source and binary forms, with or without
+modification, is permitted provided that the following conditions
+are met:</p>
+<ol>
+<li>
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.</li>
+
+<li>Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the
+distribution.</li>
+
+<li>The name "PHP" must not be used to endorse or promote products
+derived from this software without prior written permission. For
+written permission, please contact group@php.net.</li>
+
+<li>Products derived from this software may not be called "PHP", nor
+may "PHP" appear in their name, without prior written permission
+from group@php.net. You may indicate that your software works in
+conjunction with PHP by saying "Foo for PHP" instead of calling
+it "PHP Foo" or "phpfoo"</li>
+
+<li>The PHP Group may publish revised and/or new versions of the
+license from time to time. Each version will be given a
+distinguishing version number.<br />
+Once covered code has been published under a particular version
+of the license, you may always continue to use it under the terms
+of that version. You may also choose to use such covered code
+under the terms of any subsequent version of the license
+published by the PHP Group. No one other than the PHP Group has
+the right to modify the terms applicable to covered code created
+under this License.</li>
+
+<li>Redistributions of any form whatsoever must retain the following
+acknowledgment:
+"This product includes PHP software, freely available from
+<<a href="http://www.php.net/software/">http://www.php.net/software/</a>>".</li>
+
+<li><b>This software is provided by the PHP development team “as is” and
+any expressed or implied warranties, including, but not limited to,
+the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed. In no event shall the PHP
+development team or its contributors be liable for any direct,
+indirect, incidental, special, exemplary, or consequential damages
+(including, but not limited to, procurement of substitute goods or
+services; loss of use, data, or profits; or business interruption)
+however caused and on any theory of liability, whether in contract,
+strict liability, or tort (including negligence or otherwise)
+arising in any way out of the use of this software, even if advised
+of the possibility of such damage.</b></li>
+</ol>
+
+<p>This software consists of voluntary contributions made by many
+individuals on behalf of the PHP Group.</p>
+
+<p>The PHP Group can be contacted via Email at group@php.net.</p>
+
+<p>For more information on the PHP Group and the PHP project,
+please see <<a href="http://www.php.net">http://www.php.net</a>>.</p>
+
+<p>PHP includes the Zend Engine, freely available at
+<<a href="http://www.zend.com">http://www.zend.com</a>>.</p>
+
+<!-- END LICENSE TEXT -->
+
+<div class="copyright">valid <a href="http://validator.w3.org/check/referer">xhtml</a> and <a href="http://jigsaw.w3.org/css-validator/validator?uri=referer">css</a> | design by <a href="http://enano.homelinux.org/User:dandaman32">dan fuhry</a> and <a href="http://www.fusionnerd.com/">manoj maddali</a></div>
+
+</div>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/#Untitled-1# Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,1 @@
+ MAUMEE, OH, US 06/12/2007 11:26 P.M. ARRIVAL SCAN
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/Decir.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,92 @@
+<?php
+/*
+Plugin Name: Decir
+Plugin URI: javascript: // No URL yet, stay tuned!
+Description: Decir is an advanced bulletin board system (forum) for Enano.
+Author: Dan Fuhry
+Version: 0.1
+Author URI: http://www.enanocms.org/
+*/
+
+/*
+ * Decir
+ * Version 0.1
+ * Copyright (C) 2007 Dan Fuhry
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+define('ENANO_DECIR_VERSION', '0.1');
+define('DECIR_ROOT', ENANO_ROOT . '/decir');
+
+$plugins->attachHook('acl_rule_init', 'decir_early_init($this, $session);');
+$plugins->attachHook('base_classes_initted', '
+ $paths->add_page(Array(
+ \'name\'=>\'Forum\',
+ \'urlname\'=>\'Forum\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ ');
+
+function decir_early_init(&$paths, &$session)
+{
+ $paths->addAdminNode('Decir forum configuration', 'General settings', 'DecirGeneral');
+ $paths->nslist['DecirForum'] = $paths->nslist['Special'] . 'Forum/ViewForum/';
+ $paths->nslist['DecirPost'] = $paths->nslist['Special'] . 'Forum/Post/';
+ $paths->nslist['DecirTopic'] = $paths->nslist['Special'] . 'Forum/Topic/';
+
+ $session->register_acl_type('decir_see_forum', AUTH_ALLOW, 'See forum in index', Array('read'), 'DecirForum');
+ $session->register_acl_type('decir_view_forum', AUTH_ALLOW, 'View forum', Array('decir_see_forum'), 'DecirForum');
+ $session->register_acl_type('decir_post', AUTH_ALLOW, 'Post new topics', Array('decir_view_forum'), 'DecirForum');
+ $session->register_acl_type('decir_reply', AUTH_ALLOW, 'Reply to topics', Array('decir_post'), 'DecirTopic');
+}
+
+function page_Special_Forum()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ if ( getConfig('decir_version') != ENANO_DECIR_VERSION || isset($_POST['do_install_finish']) )
+ {
+ require(DECIR_ROOT . '/install.php');
+ }
+
+ $act = strtolower( ( $n = $paths->getParam(0) ) ? $n : 'Index' );
+
+ $curdir = getcwd();
+ chdir(DECIR_ROOT);
+
+ switch($act)
+ {
+ case 'index':
+ default:
+ require('forum_index.php');
+ break;
+ case 'viewforum':
+ require('viewforum.php');
+ break;
+ case 'topic':
+ case 'post':
+ case 'viewtopic':
+ require('viewtopic.php');
+ break;
+ case 'new':
+ require('posting.php');
+ break;
+ }
+
+ chdir($curdir);
+
+}
+
+function page_Admin_DecirGeneral()
+{
+ global $db, $session, $paths, $template, $plugins; if($session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN) { header('Location: '.makeUrl($paths->nslist['Special'].'Administration'.urlSeparator.'noheaders')); die('Hacking attempt'); }
+ echo 'Hello world!';
+}
+
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/EnanoPress.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,767 @@
+<?php
+/*
+Plugin Name: EnanoPress
+Plugin URI: http://enano.homelinux.org/EnanoPress
+Description: Adds WordPress-like blogging functionality to the site. The blog can be viewed on the page Special:Blog, and posts can be written with Special:WriteBlogPost.
+Author: Dan Fuhry
+Version: 1.0
+Author URI: http://enano.homelinux.org/
+*/
+
+global $db, $session, $paths, $template, $plugins; // Common objects
+
+$plugins->attachHook('base_classes_initted', '
+ $paths->add_page(Array(
+ \'name\'=>\'Site Blog\',
+ \'urlname\'=>\'Blog\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ $paths->add_page(Array(
+ \'name\'=>\'Write blog post\',
+ \'urlname\'=>\'WriteBlogPost\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ $paths->addAdminNode(\'Plugin configuration\', \'EnanoPress settings\', \'EnanoPress\');
+ ');
+
+$plugins->attachHook('compile_template', 'global $template; $template->tpl_bool[\'in_blog\'] = false;');
+$plugins->attachHook('paths_init_before', 'global $paths; $paths->create_namespace("Blog", "BlogPost:");');
+$plugins->attachHook('page_not_found', 'return EnanoPress_BlogNamespaceHandler();');
+$plugins->attachHook('page_type_string_set', 'global $paths, $template; if($paths->namespace == "Blog") $template->namespace_string = "blog post";');
+
+define('BLOG_POST_PUBLISHED', 1);
+define('BLOG_POST_DRAFT', 0);
+define('BLOG_POSTS_PER_PAGE', 20);
+
+function EnanoPress_BlogNamespaceHandler()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $pid = intval($paths->cpage['urlname_nons']);
+ if($pid == 0) return null;
+ $q = $db->sql_query('SELECT post_id, post_title, post_content, time, author FROM '.table_prefix.'blog WHERE status='.BLOG_POST_PUBLISHED.' AND post_id='.$pid.';');
+ if(!$q) $db->_die('');
+ if($db->numrows() < 1) return null;
+ $row = $db->fetchrow($q);
+ $paths->cpage['name'] = $row['post_title'];
+ $template->header();
+ echo EnanoPress_FormatBlogPost($row['post_title'], RenderMan::render($row['post_content']), $row['time'], $row['author'], 0, $row['post_id']);
+ echo EnanoPress_Separator();
+ $sub = ( isset ($_GET['sub']) ) ? $_GET['sub'] : false;
+ $act = ( isset ($_GET['action']) ) ? $_GET['action'] : false;
+ $id = ( isset ($_GET['id']) ) ? intval($_GET['id']) : -1;
+ $comments = EnanoPress_GetComments($id);
+ echo $comments;
+ $template->footer();
+ return true;
+}
+
+function page_Special_Blog()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if(!getConfig('blog_table_version'))
+ {
+ $q = $db->sql_query('CREATE TABLE '.table_prefix.'blog ( post_id mediumint(8) NOT NULL auto_increment, post_title text, post_content text, time int(12), status tinyint(1) NOT NULL DEFAULT 0, author varchar(63) NOT NULL, num_comments mediumint(8) NOT NULL DEFAULT 0, PRIMARY KEY ( post_id ) );');
+ if(!$q) $db->_die('The blog table could not be created');
+ setConfig('blog_table_version', '1');
+ }
+ if($n = getConfig('blog_name')) $paths->cpage['name'] = $n;
+ if(!defined('ENANO_TEMPLATE_LOADED'))
+ $template->init_vars();
+ $template->tpl_bool['in_blog'] = true;
+ $template->header();
+ if($s = $paths->getParam(0))
+ {
+ if($s == 'archive')
+ {
+ $y = (int)$paths->getParam(1);
+ $m = (int)$paths->getParam(2);
+ $d = (int)$paths->getParam(3);
+ $t = $paths->getParam(4);
+ if(!$y || !$m || !$d || !$t)
+ {
+ echo '<p>Invalid permalink syntax</p>';
+ $template->footer();
+ return false;
+ }
+ $t = $db->escape(str_replace(Array('-', '_'), Array('_', '_'), $t)); // It's impossible to reconstruct the title from the URL, so let MySQL do it for us using wildcards
+ // Determine the valid UNIX timestamp values
+ $lower_limit = mktime(0, 0, 0, $m, $d, $y);
+ // EnanoPress will officially stop working on February 29, 2052. To extend the date, add more leap years here.
+ $leapyears = Array(2000,2004,2008,2012,2016,2020,2024,2028,2032,2040,2044,2048);
+ // add one to the day
+ // 30 days hath September, April, June, and November, all the rest have 31, except el enano, February :-P
+ if (in_array($m, Array(4, 6, 9, 11)) && $d == 30) $m++;
+ elseif(in_array($m, Array(1, 3, 5, 7, 8, 10, 12)) && $d == 31) $m++;
+ elseif($m == 2 && in_array($y, $leapyears) && $d == 29) $m++;
+ elseif($m == 2 && !in_array($y, $leapyears) && $d == 28) $m++;
+ else $d++;
+ $upper_limit = mktime(0, 0, 0, $m, $d, $y);
+ $q = $db->sql_query('SELECT b.post_id, b.post_title, b.post_content, b.time, COUNT(c.comment_id) AS num_comments, b.author FROM '.table_prefix.'blog AS b LEFT JOIN '.table_prefix.'comments AS c ON (c.page_id=b.post_id AND c.namespace=\'Blog\' AND c.approved=1) WHERE b.status='.BLOG_POST_PUBLISHED.' AND b.post_title LIKE \''.$t.'\' AND b.time >= '.$lower_limit.' AND b.time <= '.$upper_limit.' GROUP BY b.post_id ORDER BY b.time DESC;');
+ if(!$q)
+ {
+ echo $db->get_error();
+ $template->footer();
+ return;
+ }
+ if($db->numrows() < 1)
+ {
+ // Try it with no date specifiation
+ $q = $db->sql_query('SELECT b.post_id, b.post_title, b.post_content, b.time, COUNT(c.comment_id) AS num_comments, b.author FROM '.table_prefix.'blog AS b LEFT JOIN '.table_prefix.'comments AS c ON (c.page_id=b.post_id AND c.namespace=\'Blog\' AND c.approved=1) WHERE b.status='.BLOG_POST_PUBLISHED.' AND b.post_title LIKE \''.$t.'\' GROUP BY b.post_id ORDER BY b.time DESC;');
+ if(!$q)
+ {
+ echo $db->get_error();
+ $template->footer();
+ return;
+ }
+ if($db->numrows() < 1)
+ {
+ echo '<p>No posts matching that permalink could be found.</p>';
+ $template->footer();
+ return;
+ }
+ }
+ $row = $db->fetchrow();
+ echo EnanoPress_FormatBlogPost($row['post_title'], RenderMan::render($row['post_content']), $row['time'], $row['author'], (int)$row['num_comments'], (int)$row['post_id']);
+ echo EnanoPress_Separator();
+ $sub = ( isset ($_GET['sub']) ) ? $_GET['sub'] : false;
+ $act = ( isset ($_GET['action']) ) ? $_GET['action'] : false;
+ $id = ( isset ($_GET['id']) ) ? intval($_GET['id']) : -1;
+ $comments = EnanoPress_GetComments((int)$row['post_id']);
+ if(is_array($comments))
+ {
+ $comments = EnanoPress_FormatComments($comments);
+ echo $comments;
+ }
+ $template->footer();
+ return;
+ }
+ else
+ {
+ $start = intval($s);
+ }
+ }
+ else $start = 0;
+ $end = $start + BLOG_POSTS_PER_PAGE + 1;
+ $q = $db->sql_query('SELECT b.post_id, b.post_title, b.post_content, b.time, b.author, COUNT(c.comment_id) AS num_comments FROM '.table_prefix.'blog AS b LEFT JOIN '.table_prefix.'comments AS c ON (c.page_id=b.post_id AND c.namespace=\'Blog\' AND c.approved=1) WHERE b.status='.BLOG_POST_PUBLISHED.' GROUP BY b.post_id ORDER BY b.time DESC LIMIT '.$start.','. $end .';');
+ if(!$q) { echo $db->get_error('The blog data could not be selected'); $template->footer(); return false; }
+ $numrows = $db->numrows();
+ if($numrows == BLOG_POSTS_PER_PAGE+1)
+ {
+ $nextpage = true;
+ $numrows = BLOG_POSTS_PER_PAGE;
+ }
+ if($numrows < 1)
+ {
+ echo '<p>No posts yet! <a href="'.makeUrlNS('Special', 'WriteBlogPost').'">Write a post...</a></p>';
+ }
+ else
+ {
+ $i = 0;
+ while($row = $db->fetchrow())
+ {
+ $i++;
+ if($i == BLOG_POSTS_PER_PAGE+1) break;
+ echo EnanoPress_FormatBlogPost($row['post_title'], RenderMan::render($row['post_content']), $row['time'], $row['author'], (int)$row['num_comments'], (int)$row['post_id']);
+ if($i < $numrows) echo EnanoPress_Separator();
+ }
+ if($session->user_level >= USER_LEVEL_MOD) echo '<h2>More actions</h2><p><a href="'.makeUrlNS('Special', 'WriteBlogPost').'">Write a post...</a></p>';
+ }
+ $template->footer();
+}
+
+function page_Special_WriteBlogPost()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if($session->user_level < USER_LEVEL_MOD) die_friendly('Access denied', '<p>You are not authorized to post blog messages.</p>');
+ $errors = Array();
+ $template->header();
+ $editing = false;
+ if(isset($_POST['__save'])) $status = BLOG_POST_DRAFT;
+ if(isset($_POST['__publish'])) $status = BLOG_POST_PUBLISHED;
+ if(isset($_POST['__save']) || isset($_POST['__publish']))
+ {
+ $text = RenderMan::preprocess_text($_POST['content'], false, true);
+ $title = $db->escape(htmlspecialchars($_POST['title']));
+ $author = $db->escape($session->username);
+ $time = time();
+ if($text == '') $errors[] = 'You must enter a post.';
+ if($title == '') $errors[] = 'You must enter a title for your post.';
+ if(sizeof($errors) < 1)
+ {
+ if(isset($_POST['edit_id']) && preg_match('#^([0-9]+)$#', $_POST['edit_id']))
+ {
+ $q = $db->sql_query('UPDATE '.table_prefix."blog SET post_title='{$title}',post_content='{$text}',time={$time},author='{$author}',status=".$status." WHERE post_id={$_POST['edit_id']};");
+ }
+ else
+ {
+ $q = $db->sql_query('INSERT INTO '.table_prefix."blog(post_title,post_content,time,author,status) VALUES('{$title}', '{$text}', {$time}, '{$author}', ".$status.");");
+ }
+ if(!$q)
+ {
+ echo $db->get_error();
+ $template->footer();
+ return;
+ }
+ $q = $db->sql_query('SELECT post_id FROM '.table_prefix.'blog WHERE time='.$time.' ORDER BY post_id DESC;');
+ if(!$q) { echo $db->get_error(); $template->footer(); return false; }
+ if($db->numrows() > 0)
+ {
+ $row = $db->fetchrow();
+ $editing = $row['post_id'];
+ }
+ switch($status):
+ case BLOG_POST_DRAFT:
+ echo '<div class="info-box">Your post has been saved; however it will not appear on the main blog page until it is published.</div>';
+ break;
+ case BLOG_POST_PUBLISHED:
+ echo '<div class="info-box">Your post has been published to the main blog page.</div>';
+ break;
+ endswitch;
+ }
+
+ $text =& $_POST['content'];
+ $title =& $_POST['title'];
+ }
+ elseif(isset($_POST['__delete']) && isset($_POST['del_confirm']))
+ {
+ $pid = intval($_POST['edit_id']);
+ if($pid > 0)
+ {
+ $q = $db->sql_query('DELETE FROM '.table_prefix.'blog WHERE post_id='.$pid.';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ $template->footer();
+ return;
+ }
+ else
+ echo '<div class="info-box">Your post has been deleted.</div>';
+ }
+ $text = '';
+ $title = '';
+ $editing = false;
+ }
+ elseif($t = $paths->getParam(0))
+ {
+ $id = intval($t);
+ if($t == 0) die('SQL injection attempt');
+ $q = $db->sql_query('SELECT post_title,post_content FROM '.table_prefix.'blog WHERE post_id='.$t.';');
+ if(!$q) { echo $db->get_error(); $template->footer(); return false; }
+ if($db->numrows() > 0)
+ {
+ $row = $db->fetchrow();
+ $text =& $row['post_content'];
+ $title =& $row['post_title'];
+ $editing = $t;
+ }
+ else
+ {
+ $text = '';
+ $title = '';
+ }
+ }
+ elseif(isset($_POST['__preview']))
+ {
+ $text = RenderMan::preprocess_text($_POST['content'], false, false);
+ $text = RenderMan::render($text);
+ ob_start();
+ eval('?>'.$text);
+ $text = ob_get_contents();
+ ob_end_clean();
+ echo '<div class="warning-box"><b>Reminder:</b><br />This is only a preview - your changes to this post will not be saved until you click Save Draft or Save and Publish below.</div>'
+ . PageUtils::scrollBox(EnanoPress_FormatBlogPost($_POST['title'], $text, time(), $session->username, 0, false));
+ $text =& $_POST['content'];
+ $title = $_POST['title'];
+ }
+ else
+ {
+ $text = '';
+ $title = '';
+ }
+ if(sizeof($errors) > 0)
+ {
+ echo '<div class="error-box"><b>The following errors were encountered:</b><br />' . implode('<br />', $errors) . '</div>';
+ }
+ $q = $db->sql_query('SELECT post_id, post_title FROM '.table_prefix.'blog WHERE status='.BLOG_POST_DRAFT.' ORDER BY post_title ASC;');
+ if(!$q) { echo $db->get_error('The blog data could not be selected'); $template->footer(); return false; }
+ $n = $db->numrows();
+ if($n > 0)
+ {
+ echo '<br /><div class="mdg-comment"><b>Your drafts: </b>';
+ $posts = Array();
+ while($r = $db->fetchrow())
+ {
+ $posts[$r['post_id']] = $r['post_title'];
+ }
+ $i=0;
+ foreach($posts as $id => $t)
+ {
+ $i++;
+ echo '<a href="'.makeUrlNS('Special', 'WriteBlogPost/'.$id).'">'.$t.'</a>';
+ if($i < $n) echo ' » ';
+ }
+ echo '</div>';
+ }
+ $idthing = ( $editing ) ? '<input type="hidden" name="edit_id" value="'.$editing.'" />' : '';
+ $delbtn = ( $editing ) ? ' <input onclick="return confirm(\'Are you REALLY sure you want to delete this post?\')" type="submit" name="__delete" value="Delete this post" style="color: red; font-weight: bold;" /> <label><input type="checkbox" name="del_confirm" /> I\'m sure</label>' : '';
+ $textarea = $template->tinymce_textarea('content', $text);
+ echo '<form action="'.makeUrl($paths->page).'" method="post">'
+ . '<p>Post title:<br /><input type="text" name="title" size="60" style="width: 98%;" value="'.htmlspecialchars($title).'" /><br /><br />Post:<br />'
+ . $textarea
+ . '<p>The following information will be added to your post:</p><ul><li>Date and time: '.date('F d, Y h:i a').'</li><li>Username: '.$session->username.'</li></ul>'
+ . '<p><input type="submit" name="__preview" value="Show preview" title="Allows you to preview your blog post before it is saved or posted" /> <input title="Saves the post but prevents it from being shown on the main blog page" type="submit" name="__save" value="Save Draft" /> <input title="Saves the blog post and shows it on the main blog page" type="submit" name="__publish" value="Save and Publish" />'
+ . $delbtn
+ . '</p>'
+ . $idthing
+ . '</form>';
+ $template->footer();
+}
+
+/**
+ * Convert a blog post to HTML
+ * @param string $title the name of the blog post
+ * @param string $text the content, needs to be HTML formatted as no renderer is called
+ * @param int $time UNIX timestamp for the time of the post
+ * @param string $author [user]name of the person who wrote the post
+ * @param int $num_comments The number of comments attached to the post
+ * @param int $post_id The numerical ID of the post
+ * @return string
+ */
+
+function EnanoPress_FormatBlogPost($title, $text, $time, $author, $num_comments = 0, $post_id)
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ static $cached_template = false;
+ if(!$cached_template)
+ {
+ if(file_exists(ENANO_ROOT.'/themes/'.$session->theme.'/blogpost.tpl'))
+ $cached_template = file_get_contents(ENANO_ROOT.'/themes/'.$session->theme.'/blogpost.tpl', 'r');
+ if(!$cached_template)
+ $cached_template = <<<TPLCODE
+ <div>
+ <div style="border-bottom: 1px solid #AAAAAA;">
+ <p style="float: right; background-color: #F0F0F0; margin: 3px 10px 0 0; padding: 8px 3px; width: 55px; text-align: center;">{D} {j} {M} {Y}</p>
+ <div style="margin-bottom: 16px;"><h3 style="margin-bottom: 0;"><a href="{PERMALINK}" rel="bookmark" title="Permanent link to this post">{TITLE}</a></h3>Posted by <a href="{AUTHOR_LINK}" {AUTHOR_USERPAGE_CLASS}>{AUTHOR}</a><br /><a href="{COMMENT_LINK}">{COMMENT_LINK_TEXT}</a><!-- BEGIN can_edit --> | <a href="{EDIT_LINK}">edit this post</a><!-- END can_edit --></div>
+ </div>
+ <div>
+ {CONTENT}
+ </div>
+ </div>
+TPLCODE;
+ }
+ $parser = $template->makeParserText($cached_template);
+ $datechars = 'dDjlSwzWFmMntLYyaABGhHisIOTZrU'; // A list of valid metacharacters for date()
+ $datechars = enano_str_split($datechars);
+ $datevals = Array();
+ foreach($datechars as $d)
+ {
+ $datevals[$d] = date($d, $time);
+ }
+ unset($datechars);
+ $parser->assign_vars($datevals);
+ $parser->assign_bool(Array(
+ 'can_edit'=> ( $session->user_level >= USER_LEVEL_MOD ),
+ ));
+ $permalink = makeUrlNS('Special', 'Blog/archive/'.date('Y', $time).'/'.date('m', $time).'/'.date('d', $time).'/'.enanopress_sanitize_title($title));
+ $commentlink = $permalink . '#post-comments';
+ if($num_comments == 0) $ctext = 'No comments';
+ elseif($num_comments == 1) $ctext = '1 comment';
+ else $ctext = $num_comments . ' comments';
+ $edit_link = ( is_int($post_id) ) ? makeUrlNS('Special', 'WriteBlogPost/'.$post_id) : '#" onclick="return false;';
+ $parser->assign_vars(Array(
+ 'TITLE' => $title,
+ 'PERMALINK' => $permalink,
+ 'AUTHOR' => $author,
+ 'AUTHOR_LINK' => makeUrlNS('User', $author),
+ 'AUTHOR_USERPAGE_CLASS' => ( isset($paths->pages[$paths->nslist['User'].$author]) ) ? '' : ' class="wikilink-nonexistent" ',
+ 'COMMENT_LINK' => $commentlink,
+ 'COMMENT_LINK_TEXT' => $ctext,
+ 'CONTENT' => $text,
+ 'EDIT_LINK' => $edit_link,
+ ));
+ return $parser->run();
+}
+
+/**
+ * Draws a separator for use between blog posts - searches for the appropriate template file
+ * @return string
+ */
+
+function EnanoPress_Separator()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ static $cached_template = false;
+ if(!$cached_template)
+ {
+ if(file_exists(ENANO_ROOT.'/themes/'.$session->theme.'/blogseparator.tpl'))
+ $cached_template = file_get_contents(ENANO_ROOT.'/themes/'.$session->theme.'/blogseparator.tpl');
+ if(!$cached_template)
+ $cached_template = <<<TPLCODE
+ <div style="border-bottom: 1px dashed #666666; margin: 15px auto; width: 200px;"></div>
+TPLCODE;
+ }
+ $parser = $template->makeParserText($cached_template);
+ return $parser->run();
+}
+
+/**
+ * Make a blog post title acceptable for URLs
+ * @param string $text the input text
+ * @return string
+ */
+
+function enanopress_sanitize_title($text)
+{
+ $text = strtolower(str_replace(' ', '_', $text));
+ $badchars = '/*+-,.?!@#$%^&*|{}[];:\'"`~';
+ $badchars = enano_str_split($badchars);
+ $dash = Array();
+ foreach($badchars as $i => $b) $dash[] = "-";
+ $text = str_replace($badchars, $dash, $text);
+ return $text;
+}
+
+/**
+ * Fetch comments for a post
+ * @param int $post_id The numerical ID of the post to get comments for
+ * @return array A hierarchial array - numbered keys, each key is a subarray with keys "name", "subject", "text", "time", and "comment_id" with time being a UNIX timestamp
+ */
+
+function EnanoPress_GetComments($post_id)
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ if(!is_int($post_id)) return false;
+
+ if(isset($_GET['sub']))
+ {
+ $e = $db->sql_query('SELECT comment_id,name,subject,comment_data,user_id FROM '.table_prefix.'comments WHERE comment_id='.intval($_REQUEST['id']).';');
+ if($e)
+ {
+ $comment = $db->fetchrow();
+ $auth_edit = ( ( intval($comment['user_id']) == $session->user_id && $session->user_logged_in ) || $session->user_level >= USER_LEVEL_MOD );
+ if($auth_edit)
+ {
+ switch($_GET['sub'])
+ {
+ case 'editcomment':
+ if(!isset($_GET['id']) || ( isset($_GET['id']) && !preg_match('#^([0-9]+)$#', $_GET['id']) )) { echo '<p>Invalid comment ID</p>'; break; }
+ $row =& $comment;
+ echo '<h3>Edit comment</h3><form action="'.makeUrl($paths->fullpage, 'sub=savecomment').'" method="post">';
+ echo "<br /><div class='mdg-comment' style='padding: 0;'><table border='0' width='100%' cellspacing='1' cellpadding='4'>
+ <tr><td class='row1'>Subject:</td><td class='row1'><input type='text' name='subj' value='{$row['subject']}' /></td></tr>
+ <tr><td class='row2'>Comment:</td><td class='row2'><textarea rows='10' cols='40' style='width: 98%;' name='text'>{$row['comment_data']}</textarea></td></tr>
+ <tr><td class='row1' colspan='2' class='row1' style='text-align: center;'><input type='hidden' name='id' value='{$row['comment_id']}' /><input type='submit' value='Save Changes' /></td></tr>
+ </table></div>";
+ echo '</form>';
+ return false;
+ break;
+ case 'savecomment':
+ if(empty($_POST['subj']) || empty($_POST['text'])) { echo '<p>Invalid request</p>'; break; }
+ $r = PageUtils::savecomment_neater((string)$post_id, 'Blog', $_POST['subj'], $_POST['text'], (int)$_POST['id']);
+ if($r != 'good') { echo "<pre>$r</pre>"; return false; }
+ break;
+ case 'deletecomment':
+ if(isset($_GET['id']))
+ {
+ $q = 'DELETE FROM '.table_prefix.'comments WHERE comment_id='.intval($_GET['id']).' LIMIT 1;';
+ $e=$db->sql_query($q);
+ if(!$e)
+ {
+ echo 'Error during query: '.mysql_error().'<br /><br />Query:<br />'.$q;
+ return false;
+ }
+ $e=$db->sql_query('UPDATE '.table_prefix.'blog SET num_comments=num_comments-1 WHERE post_id='.$post_id.';');
+ if(!$e)
+ {
+ echo 'Error during query: '.mysql_error().'<br /><br />Query:<br />'.$q;
+ return false;
+ }
+ }
+ break;
+ case 'admin':
+ if(isset($_GET['action']) && $session->user_level >= USER_LEVEL_MOD) // Nip hacking attempts in the bud
+ {
+ switch($_GET['action']) {
+ case "delete":
+ if(isset($_GET['id']))
+ {
+ $q = 'DELETE FROM '.table_prefix.'comments WHERE comment_id='.intval($_GET['id']).' LIMIT 1;';
+ $e=$db->sql_query($q);
+ if(!$e)
+ {
+ echo 'Error during query: '.mysql_error().'<br /><br />Query:<br />'.$q;
+ return false;
+ }
+ $e=$db->sql_query('UPDATE '.table_prefix.'blog SET num_comments=num_comments-1 WHERE post_id='.$post_id.';');
+ if(!$e)
+ {
+ echo 'Error during query: '.mysql_error().'<br /><br />Query:<br />'.$q;
+ return false;
+ }
+ }
+ break;
+ case "approve":
+ if(isset($_GET['id']))
+ {
+ $where = 'comment_id='.intval($_GET['id']);
+ $q = 'SELECT approved FROM '.table_prefix.'comments WHERE '.$where.' LIMIT 1;';
+ $e = $db->sql_query($q);
+ if(!$e) die('alert(unesape(\''.rawurlencode('Error selecting approval status: '.mysql_error().'\n\nQuery:\n'.$q).'\'));');
+ $r = $db->fetchrow();
+ $a = ( $r['approved'] ) ? '0' : '1';
+ $q = 'UPDATE '.table_prefix.'comments SET approved='.$a.' WHERE '.$where.';';
+ $e=$db->sql_query($q);
+ if(!$e)
+ {
+ echo 'Error during query: '.mysql_error().'<br /><br />Query:<br />'.$q;
+ return false;
+ }
+ if($a == '1')
+ {
+ $q = 'UPDATE '.table_prefix.'blog SET num_comments=num_comments+1 WHERE post_id='.$post_id.';';
+ }
+ else
+ {
+ $q = 'UPDATE '.table_prefix.'blog SET num_comments=num_comments-1 WHERE post_id='.$post_id.';';
+ }
+ $e=$db->sql_query($q);
+ if(!$e)
+ {
+ echo 'Error during query: '.mysql_error().'<br /><br />Query:<br />'.$q;
+ return false;
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+ else
+ {
+ echo '<div class="error-box">You are not authorized to perform this action.</div>';
+ }
+ }
+ }
+
+ if(isset($_POST['__doPostBack']))
+ {
+ if(getConfig('comments_need_login') == '2' && !$session->user_logged_in) echo('Access denied to post comments: you need to be logged in first.');
+ else
+ {
+ $cb=false;
+ if(getConfig('comments_need_login') == '1' && !$session->user_logged_in)
+ {
+ if(!isset($_POST['captcha_input']) || !isset($_POST['captcha_id']))
+ {
+ echo('BUG: PageUtils::addcomment: no CAPTCHA data passed to method');
+ $cb=true;
+ }
+ else
+ {
+ $result = $session->get_captcha($_POST['captcha_id']);
+ if($_POST['captcha_input'] != $result) { $cb=true; echo('The confirmation code you entered was incorrect.'); }
+ }
+ }
+ if(!$cb)
+ {
+ $text = RenderMan::preprocess_text($_POST['text']);
+ $name = $session->user_logged_in ? RenderMan::preprocess_text($session->username) : RenderMan::preprocess_text($_POST['name']);
+ $subj = RenderMan::preprocess_text($_POST['subj']);
+ if(getConfig('approve_comments')=='1') $appr = '0'; else $appr = '1';
+ $q = 'INSERT INTO '.table_prefix.'comments(page_id,namespace,subject,comment_data,name,user_id,approved,time) VALUES(\''.$post_id.'\',\'Blog\',\''.$subj.'\',\''.$text.'\',\''.$name.'\','.$session->user_id.','.$appr.','.time().')';
+ $e = $db->sql_query($q);
+ if(!$e) echo 'Error inserting comment data: '.mysql_error().'<br /><br />Query:<br />'.$q;
+ else
+ {
+ echo '<div class="info-box">Your comment has been posted.</div>';
+ if(getConfig('approve_comments')=='1')
+ {
+ $e=$db->sql_query('UPDATE '.table_prefix.'blog SET num_comments=num_comments+1 WHERE post_id='.$post_id.';');
+ if(!$e)
+ {
+ echo 'Error during query: '.mysql_error().'<br /><br />Query:<br />'.$q;
+ return false;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ $apprv_clause = ( $session->user_level >= USER_LEVEL_MOD ) ? '' : 'AND approved=1';
+
+ $q = $db->sql_query('SELECT c.comment_id,c.subject,c.comment_data,c.name,c.time,c.approved,c.time,u.signature,u.user_level,u.user_id FROM '.table_prefix.'comments AS c
+ LEFT JOIN '.table_prefix.'users AS u
+ ON u.user_id=c.user_id
+ WHERE page_id='.$post_id.'
+ AND namespace=\'Blog\'
+ '.$apprv_clause.'
+ ORDER BY time DESC;');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return false;
+ }
+ $posts = Array();
+ while($row = $db->fetchrow())
+ {
+ $row['text'] =& $row['comment_data'];
+ $posts[] = $row;
+ }
+ return $posts;
+}
+
+/**
+ * Formats a comments array from EnanoPress_GetComments() as HTML
+ * @param array $comments The array of fetched comments
+ * @return string
+ */
+
+function EnanoPress_FormatComments($comments)
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ ob_start();
+ $tpl = $template->makeParser('comment.tpl');
+
+ $seed = substr(md5(microtime() . mt_rand()), 0, 12);
+
+ ?>
+ <script type="text/javascript">
+ function toggleCommentForm()
+ {
+ document.getElementById('commentform_<?php echo $seed; ?>').style.display = 'block';
+ document.getElementById('commentlink_<?php echo $seed; ?>').style.display = 'none';
+ }
+ </script>
+ <?php
+
+ echo "<h3 id='post-comments'>Post comments</h3>";
+ if ( count($comments) < 1 )
+ {
+ $commentlink = ( getConfig('comments_need_login') == '2' && !$session->user_logged_in ) ? '<a href="'.makeUrl('Special:Login/'.$paths->fullpage).'">Log in to post a comment...</a>' : '<a href="'.makeUrl($paths->fullpage, 'act=postcomment', true).'" id="commentlink_'.$seed.'" onclick="toggleCommentForm(); return false;">Leave a comment...</a>' ;
+ echo '<p>There are no comments on this post. Yours could be the first! '.$commentlink.'</p>';
+ }
+ $i = -1;
+
+ foreach($comments as $comment)
+ {
+ $auth_edit = ( ( intval($comment['user_id']) == $session->user_id && $session->user_logged_in ) || $session->user_level >= USER_LEVEL_MOD );
+ $auth_mod = ( $session->user_level >= USER_LEVEL_MOD );
+
+ // Comment ID (used in the Javascript apps)
+ $strings['ID'] = (string)$i;
+
+ // Determine the name, and whether to link to the user page or not
+ $name = '';
+ if($comment['user_id'] > 0) $name .= '<a href="'.makeUrlNS('User', str_replace(' ', '_', $comment['name'])).'">';
+ $name .= $comment['name'];
+ if($comment['user_id'] > 0) $name .= '</a>';
+ $strings['NAME'] = $name; unset($name);
+
+ // Subject
+ $s = $comment['subject'];
+ if(!$comment['approved']) $s .= ' <span style="color: #D84308">(Unapproved)</span>';
+ $strings['SUBJECT'] = $s;
+
+ // Date and time
+ $strings['DATETIME'] = date('F d, Y h:i a', $comment['time']);
+
+ // User level
+ switch($comment['user_level'])
+ {
+ default:
+ case USER_LEVEL_GUEST:
+ $l = 'Guest';
+ break;
+ case USER_LEVEL_MEMBER:
+ $l = 'Member';
+ break;
+ case USER_LEVEL_MOD:
+ $l = 'Moderator';
+ break;
+ case USER_LEVEL_ADMIN:
+ $l = 'Administrator';
+ break;
+ }
+ $strings['USER_LEVEL'] = $l; unset($l);
+
+ // The actual comment data
+ $strings['DATA'] = RenderMan::render($comment['text']);
+
+ // Edit link
+ $strings['EDIT_LINK'] = '<a href="'.makeUrl($paths->fullpage, 'sub=editcomment&id='.$comment['comment_id']).'" id="editbtn_'.$i.'">edit</a>';
+
+ // Delete link
+ $strings['DELETE_LINK'] = '<a href="'.makeUrl($paths->fullpage, 'sub=deletecomment&id='.$comment['comment_id']).'">delete</a>';
+
+ // Send PM link
+ $strings['SEND_PM_LINK'] = ( $session->user_logged_in && $comment['user_id'] > 0 ) ? '<a href="'.makeUrlNS('Special', 'PrivateMessages/Compose/To/'.$comment['name']).'">Send private message</a>' : '';
+
+ // Add Buddy link
+ $strings['ADD_BUDDY_LINK'] = ( $session->user_logged_in && $comment['user_id'] > 0 ) ? '<a href="'.makeUrlNS('Special', 'PrivateMessages/FriendList/Add/'.$comment['name']).'">Add Buddy</a>' : '';
+
+ // Mod links
+ $applink = '';
+ $applink .= '<a href="'.makeUrl($paths->fullpage, 'sub=admin&action=approve&id='.$comment['comment_id']).'" id="mdgApproveLink'.$i.'">';
+ if($comment['approved']) $applink .= 'Unapprove';
+ else $applink .= 'Approve';
+ $applink .= '</a>';
+ $strings['MOD_APPROVE_LINK'] = $applink;
+ unset($applink);
+ $strings['MOD_DELETE_LINK'] = '<a href="'.makeUrl($paths->fullpage, 'sub=admin&action=delete&id='.$comment['comment_id']).'">Delete</a>';
+
+ // Signature
+ $strings['SIGNATURE'] = '';
+ if($comment['signature'] != '') $strings['SIGNATURE'] = RenderMan::render($comment['signature']);
+
+ $bool['auth_mod'] = $auth_mod;
+ $bool['can_edit'] = $auth_edit;
+ $bool['signature'] = ( $strings['SIGNATURE'] == '' ) ? false : true;
+
+ $tpl->assign_vars($strings);
+ $tpl->assign_bool($bool);
+ echo $tpl->run();
+ }
+
+ $sn = $session->user_logged_in ? $session->username . '<input name="name" id="mdgScreenName" type="hidden" value="'.$session->username.'" />' : '<input name="name" id="mdgScreenName" type="text" size="35" />';
+ if(getConfig('comments_need_login') == '1')
+ {
+ $session->kill_captcha();
+ $captcha = $session->make_captcha();
+ }
+ $captcha = ( getConfig('comments_need_login') == '1' && !$session->user_logged_in ) ? '<tr><td>Visual confirmation:<br /><small>Please enter the code you see on the right.</small></td><td><img src="'.makeUrlNS('Special', 'Captcha/'.$captcha).'" alt="Visual confirmation" style="cursor: pointer;" onclick="this.src = \''.makeUrlNS("Special", "Captcha/".$captcha).'/\'+Math.floor(Math.random() * 100000);" /><input name="captcha_id" id="mdgCaptchaID" type="hidden" value="'.$captcha.'" /><br />Code: <input name="captcha_input" id="mdgCaptchaInput" type="text" size="10" /><br /><small><script type="text/javascript">document.write("If you can\'t read the code, click on the image to generate a new one.");</script><noscript>If you can\'t read the code, please refresh this page to generate a new one.</noscript></small></td></tr>' : '';
+
+ echo '<div id="commentform_'.$seed.'">
+ '.EnanoPress_Separator().'
+ <form action="'.makeUrl($paths->fullpage, 'act=postcomment', true).'" method="post">
+ <table border="0">
+ <tr><td>Your name or screen name:</td><td>'.$sn.'</td></tr>
+ <tr><td>Comment subject:</td><td><input name="subj" id="mdgSubject" type="text" size="35" /></td></tr>
+ '.$captcha.'
+ <tr><td valign="top">Comment text:<br />(most HTML will be stripped)</td><td><textarea name="text" id="mdgCommentArea" rows="10" cols="40"></textarea></td></tr>
+ <tr><td colspan="2" style="text-align: center;"><input type="submit" name="__doPostBack" value="Submit Comment" /></td></tr>
+ </table>
+ </form>
+ </div>
+ <script type="text/javascript">
+ document.getElementById(\'commentform_'.$seed.'\').style.display = \'none\';
+ </script>
+';
+
+ $ret = ob_get_contents();
+ ob_end_clean();
+ return $ret;
+}
+
+function page_Admin_EnanoPress()
+{
+ global $db, $session, $paths, $template, $plugins; if($session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN) { header('Location: '.makeUrl($paths->nslist['Special'].'Administration'.urlSeparator.'noheaders')); die('Hacking attempt'); }
+ echo '<p>Coming soon!</p>';
+}
+
+?>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/Newsboy.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,1033 @@
+<?php
+/*
+Plugin Name: Newsboy
+Plugin URI: javascript: // No URL yet, stay tuned!
+Description: Newsboy adds a news management system to Enano. It can integrate with the Feed Me plugin to provide an additional RSS feed.
+Author: Dan Fuhry
+Version: 0.1
+Author URI: http://www.enanocms.org/
+*/
+
+/*
+ * Newsboy
+ * Version 0.1
+ * Copyright (C) 2007 Dan Fuhry
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+// Insert our News namespace
+$plugins->attachHook('acl_rule_init', 'NewsBoy_namespace_setup($this);');
+
+// Hook into page rendering
+$plugins->attachHook('page_not_found', 'NewsBoy_namespace_handler();');
+$plugins->attachHook('send_page_footers', 'NewsBoy_PortalLink();');
+
+// String to determine page type string
+$plugins->attachHook('page_type_string_set', 'NewsBoy_set_page_string();');
+
+// Attach to the Feed Me plugin, if it's loaded (if not, the feed handler simply won't get called)
+$plugins->attachHook('feed_me_request', 'NewsBoy_feed_handler($mode);');
+
+function NewsBoy_namespace_setup(&$paths)
+{
+ $paths->create_namespace('NewsBoy', 'News:');
+ $paths->addAdminNode('Newsboy portal', 'Configuration', 'NewsboyConfiguration');
+ $paths->addAdminNode('Newsboy portal', 'Manage news items', 'NewsboyItemManager');
+
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ $session->acl_extend_scope('read', 'NewsBoy', $paths);
+ $session->acl_extend_scope('post_comments', 'NewsBoy', $paths);
+ $session->acl_extend_scope('edit_comments', 'NewsBoy', $paths);
+ $session->acl_extend_scope('edit_page', 'NewsBoy', $paths);
+ $session->acl_extend_scope('view_source', 'NewsBoy', $paths);
+ $session->acl_extend_scope('mod_comments', 'NewsBoy', $paths);
+ $session->acl_extend_scope('history_view', 'NewsBoy', $paths);
+ $session->acl_extend_scope('history_rollback', 'NewsBoy', $paths);
+ $session->acl_extend_scope('history_rollback_extra', 'NewsBoy', $paths);
+ $session->acl_extend_scope('protect', 'NewsBoy', $paths);
+ $session->acl_extend_scope('rename', 'NewsBoy', $paths);
+ $session->acl_extend_scope('clear_logs', 'NewsBoy', $paths);
+ $session->acl_extend_scope('vote_delete', 'NewsBoy', $paths);
+ $session->acl_extend_scope('vote_reset', 'NewsBoy', $paths);
+ $session->acl_extend_scope('delete_page', 'NewsBoy', $paths);
+ $session->acl_extend_scope('set_wiki_mode', 'NewsBoy', $paths);
+ $session->acl_extend_scope('password_set', 'NewsBoy', $paths);
+ $session->acl_extend_scope('password_reset', 'NewsBoy', $paths);
+ $session->acl_extend_scope('mod_misc', 'NewsBoy', $paths);
+ $session->acl_extend_scope('edit_cat', 'NewsBoy', $paths);
+ $session->acl_extend_scope('even_when_protected', 'NewsBoy', $paths);
+ $session->acl_extend_scope('upload_files', 'NewsBoy', $paths);
+ $session->acl_extend_scope('upload_new_version', 'NewsBoy', $paths);
+ $session->acl_extend_scope('create_page', 'NewsBoy', $paths);
+ $session->acl_extend_scope('php_in_pages', 'NewsBoy', $paths);
+ $session->acl_extend_scope('edit_acl', 'NewsBoy', $paths);
+
+}
+
+function NewsBoy_namespace_handler()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ if ( defined('ENANO_FEEDBURNER_INCLUDED') )
+ {
+ $template->add_header('<link rel="alternate" title="'.getConfig('site_name').' News feed" href="'.makeUrlNS('Special', 'RSS/news', null, true).'" type="application/rss+xml" />');
+ }
+
+ if ( $paths->namespace != 'NewsBoy' )
+ return;
+
+ $chk = $paths->page;
+ $chk1 = substr($chk, 0, ( strlen($paths->nslist['NewsBoy']) + 8 ));
+ $chk2 = substr($chk, 0, ( strlen($paths->nslist['NewsBoy']) + 7 ));
+
+ if ( $paths->cpage['urlname_nons'] == 'Portal' || $paths->cpage['urlname_nons'] == 'Archive' || $chk1 == $paths->nslist['NewsBoy'] . 'Archive/' || $chk2 == $paths->nslist['NewsBoy'] . 'Archive' )
+ {
+
+ // Add admin opener Javascript function
+ $template->add_header('<!-- NewsBoy: admin panel nav function -->
+ <script type="text/javascript">
+ function newsboy_open_admin()
+ {
+ if ( auth_level < USER_LEVEL_ADMIN )
+ {
+ ajaxPromptAdminAuth(function(k) {
+ ENANO_SID = k;
+ auth_level = USER_LEVEL_ADMIN;
+ var loc = String(window.location + \'\');
+ window.location = append_sid(loc);
+ var loc = makeUrlNS(\'Special\', \'Administration\', \'module=\' + namespace_list[\'Admin\'] + \'NewsboyItemManager\');
+ if ( (ENANO_SID + \' \').length > 1 )
+ window.location = loc;
+ }, 9);
+ return false;
+ }
+ var loc = makeUrlNS(\'Special\', \'Administration\', \'module=\' + namespace_list[\'Admin\'] + \'NewsboyItemManager\');
+ window.location = loc;
+ }
+ </script>');
+
+ $x = getConfig('nb_portal_title');
+
+ $template->tpl_strings['PAGE_NAME'] = ( $paths->cpage['urlname_nons'] == 'Portal' ) ?
+ ( ( empty($x) ) ?
+ 'Welcome to ' . getConfig('site_name') :
+ $x ) :
+ 'News Archive';
+
+ if ( !$session->get_permissions('read') )
+ {
+ die_friendly('Access denied', '<div class="error-box"><b>Access to this page is denied.</b><br />This may be because you are not logged in or you have not met certain criteria for viewing this page.</div>');
+ }
+
+ $paths->cpage['comments_on'] = 0;
+
+ $template->header();
+ ( $paths->cpage['urlname_nons'] == 'Portal' ) ? NewsBoy_portal() : NewsBoy_archive();
+ $template->footer();
+ }
+}
+
+function NewsBoy_set_page_string()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $paths->namespace == 'NewsBoy' )
+ {
+ if ( $paths->cpage['urlname_nons'] == 'Portal' )
+ {
+ $template->namespace_string = 'portal';
+
+ // block editing
+ $perm_arr = Array('edit_page' => AUTH_DENY, 'view_source' => AUTH_DENY);
+ $session->acl_merge_with_current($perm_arr, false, 2);
+ }
+ else
+ {
+ $template->namespace_string = 'news item';
+ }
+ }
+}
+
+function NewsBoy_format_title($title)
+{
+ $title = strtolower($title);
+ $title = preg_replace('/\W/', '-', $title);
+ $title = preg_replace('/([-]+)/', '-', $title);
+ $title = trim($title, '-');
+ return $title;
+}
+
+function NewsBoy_feed_handler($mode)
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ if ( $mode != 'news' )
+ return;
+
+ $limit = ( $x = $paths->getParam(1) ) ? $x : 20;
+ $limit = intval($limit);
+ if ( $limit > 50 )
+ $limit = 50;
+
+ $title = getConfig('site_name') . ': Site news';
+
+ $x = getConfig('nb_portal_title');
+ $desc = ( empty($x) ) ? 'Welcome to ' . getConfig('site_name') : $x;
+
+ $link = makeUrlComplete('NewsBoy', 'Portal');
+ $generator = 'Enano CMS ' . enano_version() . ' - NewsBoy plugin';
+ $email = getConfig('contact_email');
+
+ $rss = new RSS($title, $desc, $link, $generator, $email);
+
+ $sql = 'SELECT p.*, l.time_id, l.author, u.user_level,COUNT(c.comment_id) AS num_comments,t.page_text FROM '.table_prefix.'pages AS p
+ LEFT JOIN '.table_prefix.'comments AS c
+ ON ( c.page_id=p.urlname AND c.namespace=p.namespace )
+ LEFT JOIN '.table_prefix.'logs AS l
+ ON ( l.page_id=p.urlname AND l.namespace=p.namespace )
+ LEFT JOIN '.table_prefix.'users AS u
+ ON ( u.username=l.author )
+ LEFT JOIN '.table_prefix.'page_text AS t
+ ON ( t.page_id=p.urlname AND t.namespace=p.namespace )
+ WHERE p.namespace=\'NewsBoy\'
+ AND l.action=\'create\'
+ AND p.urlname REGEXP \'^([0-9]+)$\'
+ AND p.visible=1
+ GROUP BY p.urlname
+ ORDER BY urlname DESC
+ LIMIT '.$limit.';';
+
+ $q = $db->sql_unbuffered_query($sql);
+
+ if ( !$q )
+ $db->_die();
+
+ $formatter = new NewsBoyFormatter();
+
+ if ( $row = $db->fetchrow() )
+ {
+ do {
+
+ $title = $row['name'];
+ $link = makeUrlComplete('NewsBoy', $row['urlname']);
+ $desc = RenderMan::render($row['page_text']);
+ $time = intval($row['urlname']);
+
+ $rss->add_item($title, $link, $desc, $time);
+
+ } while ( $row = $db->fetchrow() );
+ }
+ else
+ {
+ $rss->add_item('Error', $link, 'No news items yet.', time());
+ }
+
+ echo $rss->render();
+
+}
+
+function NewsBoy_portal()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ $news_template = <<<TPLCODE
+ <div class="tblholder news">
+ <table border="0" cellspacing="1" cellpadding="4" style="width: 100%;">
+ <tr>
+ <th><a href="{LINK}" style="color: inherit;">{TITLE}</a></th>
+ </tr>
+ <tr>
+ <td class="row3">
+ {CONTENT}
+ </td>
+ </tr>
+ <tr>
+ <th class="subhead" style="font-weight: normal; font-size: 67%;">
+ Posted by {USER_LINK} on {DATE}<br />
+ [ {NUM_COMMENTS} comment{COMMENT_S} | {COMMENT_LINK} ]
+ </th>
+ </tr>
+ </table>
+ </div>
+TPLCODE;
+
+ /*
+ $p = RenderMan::strToPageID(getConfig('main_page'));
+ if ( $p[1] != 'NewsBoy' )
+ {
+ echo RenderMan::getPage($p[0], $p[1]);
+ }
+ else
+ { */
+ /*
+ $s = $paths->nslist['NewsBoy'] . 'Announce';
+ if ( isPage($s) )
+ {
+ $p = RenderMan::getPage('Announce', 'NewsBoy');
+ echo $p;
+ }
+ /* } */
+
+ $s = $paths->nslist['NewsBoy'] . 'Announce';
+ $announce_page = getConfig('nb_announce_page');
+ if ( !empty($announce_page) && isPage($announce_page) )
+ {
+ $s = $announce_page;
+ }
+ else if ( !isPage($s) )
+ {
+ $s = false;
+ }
+ if ( $s )
+ {
+ $stuff = RenderMan::strToPageID($s);
+ $p = RenderMan::getPage($stuff[0], $stuff[1]);
+ echo $p;
+ }
+
+ echo '<h2>Latest news</h2>';
+
+ $q = $db->sql_unbuffered_query('SELECT p.*, COUNT(c.comment_id) AS num_comments, t.page_text, l.time_id, l.author, u.user_level FROM '.table_prefix.'pages AS p
+ LEFT JOIN '.table_prefix.'comments AS c
+ ON ( c.page_id=p.urlname AND c.namespace=p.namespace )
+ LEFT JOIN '.table_prefix.'page_text AS t
+ ON ( t.page_id=p.urlname AND t.namespace=p.namespace )
+ LEFT JOIN '.table_prefix.'logs AS l
+ ON ( l.page_id=p.urlname AND l.namespace=p.namespace )
+ LEFT JOIN '.table_prefix.'users AS u
+ ON ( u.username=l.author OR u.user_id=1 )
+ WHERE p.namespace=\'NewsBoy\'
+ AND l.action=\'create\'
+ AND p.urlname!=\'Announce\'
+ AND p.visible=1
+ GROUP BY p.urlname
+ ORDER BY urlname DESC;');
+ if ( !$q )
+ $db->_die();
+
+ if ( $row = $db->fetchrow() )
+ {
+ $i = 0;
+ $parser = $template->makeParserText($news_template);
+ do
+ {
+ if ( $i < 5 )
+ {
+ $title = htmlspecialchars($row['name']);
+ $content = RenderMan::render($row['page_text']);
+ if ( strlen($content) > 400 )
+ {
+ $content = nb_trim_paragraph($content, 400, $trimmed);
+ }
+ if ( $trimmed )
+ {
+ $content .= ' <a href="' . makeUrlNS('NewsBoy', $row['urlname'], false, true) . '">Read more...</a>';
+ }
+ $user_link = nb_make_username_link($row['author'], $row['user_level']);
+ $date = date('F d, Y h:i:s a', $row['urlname']);
+ $num_comments = $row['num_comments'];
+ $comment_s = ( $num_comments == 1 ) ? '' : 's';
+ $comment_link = '<a href="' . makeUrlNS('NewsBoy', $row['urlname'], false, true) . '#do:comments" style="color: inherit;">add a comment</a>';
+ $parser->assign_vars(array(
+ 'TITLE' => $title,
+ 'LINK' => makeUrlNS('NewsBoy', $row['urlname']),
+ 'CONTENT' => $content,
+ 'USER_LINK' => $user_link,
+ 'DATE' => $date,
+ 'NUM_COMMENTS' => $num_comments,
+ 'COMMENT_S' => $comment_s,
+ 'COMMENT_LINK' => $comment_link
+ ));
+ echo $parser->run();
+ }
+ else
+ {
+ echo '<p><a href="'.makeUrlNS('NewsBoy', 'Archive').'">Older news...</a></p>';
+ break;
+ }
+ $i++;
+ } while ( $row = $db->fetchrow() );
+ }
+ else
+ {
+ echo '<p>No news items yet.</p>';
+ }
+ if ( $session->user_level >= USER_LEVEL_ADMIN )
+ {
+ echo '<div class="tblholder" style="margin: 10px auto 0 auto; display: table;">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr>
+ <th>Administrative tools:</th>
+ <td class="row3" style="text-align: center;"><a style="color: inherit;" href="' . makeUrlNS('NewsBoy', 'Announce', '', true) . '#do:edit">Edit announcement »</a></td>
+ <td class="row3" style="text-align: center;"><a style="color: inherit;" href="' . makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'NewsboyItemManager', true) . '" onclick="newsboy_open_admin(); return false;">Portal Administration</a></td>
+ </tr>
+ </table>
+ </div><br />';
+ }
+}
+
+/**
+ * Formats row data in the archive.
+ * @package Enano
+ * @subpackage Newsboy
+ * @license GNU General Public License
+ */
+
+class NewsBoyFormatter
+{
+ function article_link($name, $row)
+ {
+ $article_link = '<a href="' . makeUrlNS('NewsBoy', $row['urlname']) . '">' . $row['name'] . '</a>';
+ return $article_link;
+ }
+ function format_date($date, $row)
+ {
+ $date = date('Y-m-j g:m', intval ( $date ));
+ return $date;
+ }
+ function format_username($x, $row)
+ {
+ $ul = intval($row['user_level']);
+ $author = nb_make_username_link($row['author'], $ul);
+ return $author;
+ }
+ function format_commentlink($x, $row)
+ {
+ $comments = '<a href="' . makeUrlNS('NewsBoy', $row['urlname']) . '#do:comments">' . $row['num_comments'] . '</a>';
+ return $comments;
+ }
+}
+
+function NewsBoy_archive()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ $lower_limit = ( isset($_GET['start']) ) ? intval($_GET['start']) : ( ( $xx = $paths->getParam(0) ) ? intval($xx) : 0 );
+ $entries_per_page = 50;
+
+ $row_count = $entries_per_page + 1;
+
+ // Determine number of total news entries
+ $q = $db->sql_query('SELECT urlname FROM '.table_prefix.'pages WHERE namespace=\'NewsBoy\' AND urlname REGEXP \'^([0-9]+)$\' AND visible=1;');
+ if ( !$q )
+ $db->_die();
+ $r = $db->fetchrow();
+ $num_total = intval($db->numrows());
+ $db->free_result();
+
+ if ( $lower_limit >= $num_total )
+ $lower_limit = 0;
+
+ $sql = 'SELECT p.*, l.time_id, l.author, u.user_level,COUNT(c.comment_id) AS num_comments FROM '.table_prefix.'pages AS p
+ LEFT JOIN '.table_prefix.'comments AS c
+ ON ( c.page_id=p.urlname AND c.namespace=p.namespace )
+ LEFT JOIN '.table_prefix.'logs AS l
+ ON ( l.page_id=p.urlname AND l.namespace=p.namespace )
+ LEFT JOIN '.table_prefix.'users AS u
+ ON ( u.username=l.author )
+ WHERE p.namespace=\'NewsBoy\'
+ AND l.action=\'create\'
+ AND p.urlname REGEXP \'^([0-9]+)$\'
+ AND p.visible=1
+ GROUP BY p.urlname
+ ORDER BY urlname DESC;';
+
+ $q = $db->sql_unbuffered_query($sql);
+
+ if ( !$q )
+ $db->_die();
+
+ $formatter = new NewsBoyFormatter();
+
+ $callers = Array(
+ 'name' => Array($formatter, 'article_link'),
+ 'urlname' => Array($formatter, 'format_date'),
+ 'author' => Array($formatter, 'format_username'),
+ 'num_comments' => Array($formatter, 'format_commentlink')
+ );
+
+ $head = '<div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr>
+ <th>Article</th><th>Date</th><th>Author</th><th>Comments</th>
+ </tr>';
+ $foot = "</table></div>";
+
+ $content = paginate($q, "\n".'<tr><td class="{_css_class}">{name}</td><td class="{_css_class}">{urlname}</td><td class="{_css_class}">{author}</td><td class="{_css_class}">{num_comments}</td></tr>',
+ $num_total, makeUrlNS('NewsBoy', 'Archive/%s'), $lower_limit, 20, $callers, $head, $foot);
+ echo $content;
+
+ $code = $plugins->setHook('send_page_footers');
+ foreach ( $code as $cmd )
+ {
+ eval($cmd);
+ }
+
+}
+
+function nb_make_username_link($username, $user_level)
+{
+ $color = '#0000AA';
+ $user_level = intval($user_level);
+ if ( $user_level < USER_LEVEL_MEMBER ) return $username;
+ if ( $user_level >= USER_LEVEL_MOD ) $color = '#00AA00';
+ if ( $user_level >= USER_LEVEL_ADMIN ) $color = '#AA0000';
+ $link = '<a style="color: ' . $color . '" href="' . makeUrlNS('User', str_replace(' ', '_', $username) ) . '">' . $username . '</a>';
+ return $link;
+}
+
+function NewsBoy_PortalLink()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $paths->namespace == 'NewsBoy' )
+ echo '<div class="tblholder"><table border="0" style="width: 100%;" cellspacing="1" cellpadding="4"><tr><th><a style="color: inherit;" href="' . makeUrlNS('NewsBoy', 'Portal') . '">« Return to News Portal</a></th></tr></table></div><br />';
+}
+
+// Administration panel
+function page_Admin_NewsboyItemManager()
+{
+ global $db, $session, $paths, $template, $plugins; if($session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN) { redirect(makeUrlNS('Special', 'Administration', 'noheaders', true), '', '', 0); die('Hacking attempt'); }
+
+ $done = false;
+
+ if ( isset( $_GET['act'] ) )
+ {
+ switch ( $_GET['act'] )
+ {
+ case 'edit':
+
+ // Error list
+ $errors = Array();
+
+ if ( isset ( $_POST['submitting'] ) )
+ {
+ // Generate timestamp
+ $year = intval($_POST['pub_year']);
+ $month = intval($_POST['pub_month']);
+ $day = intval($_POST['pub_day']);
+ $hour = intval($_POST['pub_hour']);
+ $minute = intval($_POST['pub_minute']);
+ $second = intval($_POST['pub_second']);
+
+ // Validation
+ if ( $year < 1500 || $year > 10000 )
+ $errors[] = 'Invalid year.';
+
+ if ( $month < 1 || $month > 12 )
+ $errors[] = 'Invalid month.';
+
+ if ( $day < 1 || $day > 31 )
+ $errors[] = 'Invalid day.';
+
+ if ( $hour < 0 || $hour > 23 )
+ $errors[] = 'Invalid hour.';
+
+ if ( $minute < 0 || $minute > 60 )
+ $errors[] = 'Invalid minute.';
+
+ if ( $second < 0 || $second > 60 )
+ $errors[] = 'Invalid second.';
+
+ $name = $_POST['article_name'];
+ $name = $db->escape($name);
+
+ $author = $_POST['author'];
+ $author = $db->escape($author);
+
+ if ( count($errors) < 1 )
+ {
+ $time = mktime($hour, $minute, $second, $month, $day, $year);
+ }
+
+ if ( isset($paths->pages[ $paths->nslist['NewsBoy'] . $time ]) && $paths->pages[ $paths->nslist['NewsBoy'] . $time ] != $paths->pages[ $paths->nslist['NewsBoy'] . $_POST['page_id'] ] )
+ $errors[] = 'You cannot have two news articles with the same publish time.';
+
+ if ( count($errors) < 1 )
+ {
+ $publ = ( isset($_POST['published']) ) ? '1' : '0';
+ $sql = 'UPDATE '.table_prefix.'pages SET name=\'' . $name . '\',visible='.$publ.',urlname=\''.$time.'\' WHERE urlname=\'' . $db->escape($_POST['page_id']) . '\' AND namespace=\'NewsBoy\';';
+ $q = $db->sql_query($sql);
+
+ if ( !$q )
+ $db->_die();
+
+ // Update author
+ $q = $db->sql_query('UPDATE '.table_prefix.'logs SET author=\'' . $author . '\' WHERE page_id=\'' . $db->escape($_POST['page_id']) . '\' AND namespace=\'NewsBoy\' AND action=\'create\';');
+
+ if ( !$q )
+ $db->_die();
+
+ // Update other tables with urlname info
+ $q = $db->sql_query('UPDATE '.table_prefix.'logs SET page_id=\'' . $time . '\' WHERE page_id=\'' . $db->escape($_POST['page_id']) . '\' AND namespace=\'NewsBoy\';');
+ if ( !$q )
+ $db->_die();
+
+ $q = $db->sql_query('UPDATE '.table_prefix.'comments SET page_id=\'' . $time . '\' WHERE page_id=\'' . $db->escape($_POST['page_id']) . '\' AND namespace=\'NewsBoy\';');
+ if ( !$q )
+ $db->_die();
+
+ $q = $db->sql_query('UPDATE '.table_prefix.'page_text SET page_id=\'' . $time . '\' WHERE page_id=\'' . $db->escape($_POST['page_id']) . '\' AND namespace=\'NewsBoy\';');
+ if ( !$q )
+ $db->_die();
+
+ $q = $db->sql_query('UPDATE '.table_prefix.'categories SET page_id=\'' . $time . '\' WHERE page_id=\'' . $db->escape($_POST['page_id']) . '\' AND namespace=\'NewsBoy\';');
+ if ( !$q )
+ $db->_die();
+
+ echo '<div class="info-box">Your changes have been saved.</div>';
+
+ break;
+ }
+ }
+
+ if ( count($errors) > 0 )
+ echo '<div class="warning-box">Errors encountered while saving data:<ul><li>' . implode('</li><li>', $errors) . '</li></ul></div>';
+
+ // Obtain page information
+ if ( !isset($paths->pages[ $paths->nslist['NewsBoy'] . $_GET['id'] ]) )
+ {
+ echo 'Invalid ID';
+ return false;
+ }
+ $page_info =& $paths->pages[ $paths->nslist['NewsBoy'] . $_GET['id'] ];
+ $time = intval($page_info['urlname_nons']);
+
+ // Get author
+ $q = $db->sql_query('SELECT author FROM '.table_prefix.'logs WHERE page_id=\'' . $db->escape($page_info['urlname_nons']) . '\' AND namespace=\'NewsBoy\' AND action=\'create\' ORDER BY time_id DESC LIMIT 1;');
+
+ if ( !$q )
+ $db->_die();
+
+ $row = $db->fetchrow();
+ $author = ( isset($row['author']) ) ? $row['author'] : '';
+ if ( empty($author) )
+ $author = 'Anonymous';
+
+ // Set date & time
+ $month = date('n', $time);
+ $year = date('Y', $time);
+ $day = date('j', $time);
+ $hour = date('G', $time);
+ $minute = date('m', $time);
+ $second = date('s', $time);
+
+ echo '<form id="nb_edit_form" action="'.makeUrlNS('Special', 'Administration', (( isset($_GET['sqldbg'])) ? 'sqldbg&' : '') .'module='.$paths->cpage['module'] . '&act=edit').'" method="post" onsubmit="if ( !submitAuthorized ) return false;">';
+ echo '<div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2">Editing news article</th>
+ </tr>
+ <tr>
+ <td class="row1">Article name:</td><td class="row2"><input name="article_name" value="' . htmlspecialchars($page_info['name']) . '" /></td>
+ </tr>
+ <tr>
+ <td class="row1">Published date:</td>
+ <td class="row2">
+ <input name="pub_year" type="text" size="5" value="'.$year.'" />-<select name="pub_month">';
+ for ( $i = 1; $i <= 12; $i++ )
+ {
+ $m = "[$i] ";
+ switch ( $i )
+ {
+ case 1: $m .= 'January'; break;
+ case 2: $m .= 'February'; break;
+ case 3: $m .= 'March'; break;
+ case 4: $m .= 'April'; break;
+ case 5: $m .= 'May'; break;
+ case 6: $m .= 'June'; break;
+ case 7: $m .= 'July'; break;
+ case 8: $m .= 'August'; break;
+ case 9: $m .= 'September'; break;
+ case 10: $m .= 'October'; break;
+ case 11: $m .= 'November'; break;
+ case 12: $m .= 'December'; break;
+ default: $m .= 'Fuhrober'; break;
+ }
+ if ( $month == $i )
+ echo ' <option selected="selected" value="' . $i . '">'.$m.'</option>';
+ else
+ echo ' <option value="' . $i . '">'.$m.'</option>';
+ }
+ echo ' </select>
+ <input name="pub_day" type="text" size="3" value="' . $day . '" />, time:
+ <input name="pub_hour" type="text" size="3" value="' . $hour . '" /> : <input name="pub_minute" type="text" size="3" value="' . $minute . '" /> : <input name="pub_second" type="text" size="3" value="' . $second . '" /><br />
+ <small>Note: Hours are in 24-hour format.</small>
+ </td>
+ </tr>
+ <!-- Inline developer blog, episode 1:
+ Right about the time I got here, I started sneezing like crazy. Must have caught it Friday night. Great... now
+ my life is officially stuck on pause for the next 3 days. I\'d swear here but (a) Mommy taught me better, and
+ (b) I wouldn\'t want to offend you hackers. (j/k)
+
+ Oh crap. And no, I don\'t give towels with my showers.
+
+ -Dan
+ -->
+ <tr>
+ <td class="row1">Publish article:</td><td class="row2"><label><input name="published" type="checkbox" ' . ( $page_info['visible'] == 1 ? 'checked="checked"' : '' ) . ' /> Article is published (shown to the public)</label></td>
+ </tr>
+ <tr>
+ <td class="row1">Article author:</td><td class="row2">' . $template->username_field('author', $author) . '</td></tr>
+ </tr>
+ <tr>
+ <td class="row3" style="text-align: center;" colspan="2">
+ <a href="#" onclick="var frm = document.getElementById(\'nb_edit_form\'); frm.submit(); return false;">Save changes</a> <a href="#" onclick="ajaxPage(\'' . $paths->cpage['module'] . '\');">Return to main menu</a>
+ </td>
+ </tr>
+ </table>
+ </div>
+ <input type="hidden" name="submitting" value="yes" />
+ <input type="hidden" name="page_id" value="' . $_GET['id'] . '" />';
+ echo '</form>';
+ $done = true;
+ break;
+ case 'del':
+ if ( isset( $_POST['confirmed'] ) )
+ {
+ $page_id = $_POST['page_id'];
+ $namespace = 'NewsBoy';
+
+ $e = $db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,page_id,namespace,author) VALUES('.time().', \''.date('d M Y h:i a').'\', \'page\', \'delete\', \''.$page_id.'\', \''.$namespace.'\', \''.$session->username.'\')');
+ if(!$e) $db->_die('The page log entry could not be inserted.');
+ $e = $db->sql_query('DELETE FROM '.table_prefix.'categories WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\'');
+ if(!$e) $db->_die('The page categorization entries could not be deleted.');
+ $e = $db->sql_query('DELETE FROM '.table_prefix.'comments WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\'');
+ if(!$e) $db->_die('The page comments could not be deleted.');
+ $e = $db->sql_query('DELETE FROM '.table_prefix.'page_text WHERE page_id=\''.$page_id.'\' AND namespace=\''.$namespace.'\'');
+ if(!$e) $db->_die('The page text entry could not be deleted.');
+ $e = $db->sql_query('DELETE FROM '.table_prefix.'pages WHERE urlname=\''.$page_id.'\' AND namespace=\''.$namespace.'\'');
+ if(!$e) $db->_die('The page entry could not be deleted.');
+ $e = $db->sql_query('DELETE FROM '.table_prefix.'files WHERE page_id=\''.$page_id.'\'');
+ if(!$e) $db->_die('The file entry could not be deleted.');
+
+ $result = 'This page has been deleted. Note that there is still a log of edits and actions in the database, and anyone with admin rights can raise this page from the dead unless the log is cleared. If the deleted file is an image, there may still be cached thumbnails of it in the cache/ directory, which is inaccessible to users.';
+
+ echo $result . '<br />
+ <br />
+ <a href="#" onclick="ajaxPage(\'' . $paths->cpage['module'] . '\');">Return to Newsboy</a>';
+ }
+ else
+ {
+ echo '<form id="nb_delete_form" action="'.makeUrlNS('Special', 'Administration', (( isset($_GET['sqldbg'])) ? 'sqldbg&' : '') .'module='.$paths->cpage['module'] . '&act=del').'" method="post">';
+ echo '<div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr>
+ <th>Confirm deletion</th>
+ </tr>
+ <tr>
+ <td class="row1" style="text-align: center;">
+ <p>Are you sure you want to delete this news article?</p>
+ </td>
+ </tr>
+ <tr>
+ <td class="row3" style="text-align: center;">
+ <a href="#" onclick="var frm = document.getElementById(\'nb_delete_form\'); frm.submit(); return false;">Delete</a> <a href="#" onclick="ajaxPage(\'' . $paths->cpage['module'] . '\');">Cancel</a>
+ </td>
+ </tr>
+ </table>
+ </div>
+ <input type="hidden" name="confirmed" value="yes" />
+ <input type="hidden" name="page_id" value="' . intval ( $_GET['id'] ) . '" />';
+ echo '</form>';
+ }
+ $done = true;
+ break;
+ case 'create':
+
+ // Error list
+ $errors = Array();
+
+ if ( isset ( $_POST['submitting'] ) )
+ {
+ // Generate timestamp
+ $year = intval($_POST['pub_year']);
+ $month = intval($_POST['pub_month']);
+ $day = intval($_POST['pub_day']);
+ $hour = intval($_POST['pub_hour']);
+ $minute = intval($_POST['pub_minute']);
+ $second = intval($_POST['pub_second']);
+
+ // Validation
+ if ( $year < 1500 || $year > 10000 )
+ $errors[] = 'Invalid year.';
+
+ if ( $month < 1 || $month > 12 )
+ $errors[] = 'Invalid month.';
+
+ if ( $day < 1 || $day > 31 )
+ $errors[] = 'Invalid day.';
+
+ if ( $hour < 0 || $hour > 23 )
+ $errors[] = 'Invalid hour.';
+
+ if ( $minute < 0 || $minute > 60 )
+ $errors[] = 'Invalid minute.';
+
+ if ( $second < 0 || $second > 60 )
+ $errors[] = 'Invalid second.';
+
+ $name = $_POST['article_name'];
+ $name = $db->escape($name);
+
+ $author = $_POST['author'];
+ $author = $db->escape($author);
+
+ if ( count($errors) < 1 )
+ {
+ $time = mktime($hour, $minute, $second, $month, $day, $year);
+ }
+
+ if ( isset($paths->pages[ $paths->nslist['NewsBoy'] . $time ]) && $paths->pages[ $paths->nslist['NewsBoy'] . $time ] != $paths->pages[ $paths->nslist['NewsBoy'] . $_POST['page_id'] ] )
+ $errors[] = 'You cannot have two news articles with the same publish time.';
+
+ if ( count($errors) < 1 )
+ {
+ $publ = ( isset($_POST['published']) ) ? 1 : 0;
+ $result = PageUtils::createpage( (string)$time, 'NewsBoy', $name, $publ );
+
+ // Set content
+ $content = RenderMan::preprocess_text($_POST['content'], true); // this also SQL-escapes it
+
+ $q = $db->sql_query('UPDATE '.table_prefix.'page_text SET page_text=\'' . $content . '\' WHERE page_id=\'' . $time . '\' AND namespace=\'NewsBoy\';');
+ if ( !$q )
+ $db->_die();
+
+ if ( $result )
+ echo '<div class="info-box">Your changes have been saved.</div>';
+ else
+ $errors[] = 'PageUtils::createpage returned an error.';
+
+ break;
+ }
+ }
+
+ if ( count($errors) > 0 )
+ echo '<div class="warning-box">Errors encountered while preparing data:<ul><li>' . implode('</li><li>', $errors) . '</li></ul></div>';
+
+ $time = time();;
+
+ // Get author
+ $author = $session->username;
+
+ if ( empty($author) )
+ $author = 'Anonymous';
+
+ // Set date & time
+ $month = date('n', $time);
+ $year = date('Y', $time);
+ $day = date('j', $time);
+ $hour = date('G', $time);
+ $minute = date('m', $time);
+ $second = date('s', $time);
+
+ echo '<form id="nb_create_form" action="'.makeUrlNS('Special', 'Administration', (( isset($_GET['sqldbg'])) ? 'sqldbg&' : '') .'module='.$paths->cpage['module'] . '&act=create').'" method="post" onsubmit="if ( !submitAuthorized ) return false;">';
+ echo '<div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2">Creating news article</th>
+ </tr>
+ <tr>
+ <td class="row1">Article name:</td><td class="row2"><input name="article_name" value="" /></td>
+ </tr>
+ <tr>
+ <td class="row1">Published datestamp:</td>
+ <td class="row2">
+ <input name="pub_year" type="text" size="5" value="'.$year.'" />-<select name="pub_month">';
+ for ( $i = 1; $i <= 12; $i++ )
+ {
+ $m = "[$i] ";
+ switch ( $i )
+ {
+ case 1: $m .= 'January'; break;
+ case 2: $m .= 'February'; break;
+ case 3: $m .= 'March'; break;
+ case 4: $m .= 'April'; break;
+ case 5: $m .= 'May'; break;
+ case 6: $m .= 'June'; break;
+ case 7: $m .= 'July'; break;
+ case 8: $m .= 'August'; break;
+ case 9: $m .= 'September'; break;
+ case 10: $m .= 'October'; break;
+ case 11: $m .= 'November'; break;
+ case 12: $m .= 'December'; break;
+ default: $m .= 'Fuhrober'; break;
+ }
+ if ( $month == $i )
+ echo ' <option selected="selected" value="' . $i . '">'.$m.'</option>';
+ else
+ echo ' <option value="' . $i . '">'.$m.'</option>';
+ }
+ echo ' </select>
+ <input name="pub_day" type="text" size="3" value="' . $day . '" />, time:
+ <input name="pub_hour" type="text" size="3" value="' . $hour . '" /> : <input name="pub_minute" type="text" size="3" value="' . $minute . '" /> : <input name="pub_second" type="text" size="3" value="' . $second . '" /><br />
+ <small>Note: Hours are in 24-hour format.</small>
+ </td>
+ </tr>
+ <tr>
+ <td class="row1">Publish article:</td><td class="row2"><label><input name="published" type="checkbox" /> Article is published (shown to the public)</label></td>
+ </tr>
+ <tr>
+ <td class="row1">Article author:</td><td class="row2">' . $template->username_field('author', $author) . '</td></tr>
+ </tr>
+ <tr>
+ <td class="row1">Initial content:<br /><small>You can always edit this later.</small></td><td class="row2"><textarea name="content" rows="15" cols="60" style="width: 100%;"></textarea></td>
+ </tr>
+ <tr>
+ <td class="row3" style="text-align: center;" colspan="2">
+ <a href="#" onclick="var frm = document.getElementById(\'nb_create_form\'); frm.submit(); return false;">Create article</a> <a href="#" onclick="ajaxPage(\'' . $paths->cpage['module'] . '\');">Return to main menu</a>
+ </td>
+ </tr>
+ </table>
+ </div>
+ <input type="hidden" name="submitting" value="yes" />';
+ echo '</form>';
+
+ $done = true;
+ break;
+ }
+ }
+
+ if ( !$done )
+ {
+
+ // Start output
+ echo '<div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr>
+ <th>Name</th>
+ <th>Date published</th>
+ <th colspan="3">Actions</th>
+ </tr>';
+
+ $row_class = 'row2';
+
+ // List existing news entries
+ $q = $db->sql_query('SELECT name,urlname FROM '.table_prefix.'pages WHERE namespace="NewsBoy" AND urlname!="Announce" ORDER BY name ASC;');
+
+ if ( !$q )
+ $db->_die();
+
+ if ( $row = $db->fetchrow($q) )
+ {
+ do {
+ $row_class = ( $row_class == 'row1' ) ? 'row2' : 'row1';
+ $ts = intval($row['urlname']);
+ $date = date('F d, Y h:i a', $ts);
+ $edit_url = makeUrlNS('Special', 'Administration', "module={$paths->cpage['module']}&act=edit&id={$row['urlname']}", true);
+ $dele_url = makeUrlNS('Special', 'Administration', "module={$paths->cpage['module']}&act=del&id={$row['urlname']}", true);
+ $page_url = makeUrlNS('NewsBoy', $row['urlname']);
+ echo "<tr>
+ <td class='$row_class' style='width: 50%;'>
+ {$row['name']}
+ </td>
+ <td class='$row_class' style='width: 40%;'>
+ $date
+ </td>
+ <td class='$row_class'>
+ <a href='$edit_url'>Settings</a>
+ </td>
+ <td class='$row_class'>
+ <a href='$page_url' onclick='window.open(this.href); return false;'>Page</a>
+ </td>
+ <td class='$row_class'>
+ <a href='$dele_url'>Delete</a>
+ </td>
+ </tr>";
+ } while ( $row = $db->fetchrow($q) );
+ }
+ else
+ {
+ echo '<tr><td class="row3" colspan="5" style="text-align: center;">No news items yet.</td></tr>';
+ }
+ echo '<tr><th class="subhead" colspan="5"><a href="' . makeUrlNS('Special', 'Administration', "module={$paths->cpage['module']}&act=create", true) . '" style="color: inherit;">Create new entry</a></th></tr>
+ </table></div>';
+ $db->free_result();
+
+ }
+
+}
+
+function page_Admin_NewsboyConfiguration()
+{
+ global $db, $session, $paths, $template, $plugins; if($session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN) { redirect(makeUrlNS('Special', 'Administration', 'noheaders', true), '', '', 0); die('Hacking attempt'); }
+ if ( isset($_POST['submit']) )
+ {
+ setConfig('nb_portal_title', $_POST['portal_name']);
+ if ( isPage($_POST['announce_page']) )
+ setConfig('nb_announce_page', $_POST['announce_page']);
+ else
+ setConfig('nb_announce_page', '');
+ // Submit
+ echo '<div class="info-box">Your changes have been saved.</div>';
+ }
+ echo '<form name="main" action="'.htmlspecialchars(makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module'])).'" method="post">';
+ echo '<div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2">
+ Newsboy portal: General configuration
+ </th>
+ </tr>
+ <tr>
+ <td class="row2">
+ Portal title:<br />
+ <small>This is the text that will be shown as the page title on the<br />
+ portal. If you don\'t enter anything here, a default will be used.</small>
+ </td>
+ <td class="row1"><input type="text" size="30" name="portal_name" value="' . htmlspecialchars(getConfig('nb_portal_title')) . '"></td>
+ </tr>
+ <tr>
+ <td class="row2">
+ Page to embed as announcement:<br />
+ <small>The page you enter here will always be shown at the top of the<br />
+ portal. The default is "' . $paths->nslist['NewsBoy'] . 'Announce".</small>
+ </td>
+ <td class="row1">
+ ' . $template->pagename_field('announce_page', htmlspecialchars(getConfig('nb_announce_page'))) . '
+ </td>
+ </tr>
+ <tr>
+ <th class="subhead" colspan="2">
+ <input type="submit" name="submit" value="Save changes" />
+ </th>
+ </tr>
+ </table>
+ </div>';
+ echo '</form>';
+}
+
+/**
+ * Trims a wad of text to the specified length.
+ * @todo make HTML friendly (don't break tags)
+ * @param string The text to trim
+ * @param int The maximum length to trim the text to.
+ * @param bool Reference. Set to true if the text was trimmed, otherwise set to false.
+ */
+
+function nb_trim_paragraph($text, $len = 500, &$trimmed = false)
+{
+ $trimmed = false;
+ if ( strlen($text) <= $len )
+ return $text;
+ $trimmed = true;
+ $text = substr($text, 0, $len);
+ for ( $i = $len; $i > 0; $i-- )
+ {
+ $chr = $text{$i-1};
+ if ( preg_match('/[\s]/', $chr) )
+ {
+ $text = substr($text, 0, $i - 1);
+ $text .= '...';
+ return $text;
+ }
+ $text = substr($text, 0, $i);
+ }
+ return $text;
+}
+
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/PrivateMessages.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,547 @@
+<?php
+/*
+Plugin Name: Private Message frontend
+Plugin URI: http://enano.homelinux.org/
+Description: Provides the page Special:PrivateMessages, which is used to manage private message functions. Also handles buddy lists.
+Author: Dan Fuhry
+Version: 1.0
+Author URI: http://enano.homelinux.org/
+*/
+
+/*
+ * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
+ * Version 1.0 release candidate 2
+ * Copyright (C) 2006-2007 Dan Fuhry
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+global $db, $session, $paths, $template, $plugins; // Common objects
+
+$plugins->attachHook('base_classes_initted', '
+ global $paths;
+ $paths->add_page(Array(
+ \'name\'=>\'Private Messages\',
+ \'urlname\'=>\'PrivateMessages\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ ');
+
+function page_Special_PrivateMessages()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if(!$session->user_logged_in) die_friendly('Access denied', '<p>You need to <a href="'.makeUrlNS('Special', 'Login/'.$paths->page).'">log in</a> to view your private messages.</p>');
+ $argv = Array();
+ $argv[] = $paths->getParam(0);
+ $argv[] = $paths->getParam(1);
+ $argv[] = $paths->getParam(2);
+ if(!$argv[0]) $argv[0] = 'InVaLiD';
+ switch($argv[0])
+ {
+ default:
+ header('Location: '.makeUrlNS('Special', 'PrivateMessages/Folder/Inbox'));
+ break;
+ case 'View':
+ $id = $argv[1];
+ if(!preg_match('#^([0-9]+)$#', $id)) die_friendly('Message error', '<p>Invalid message ID</p>');
+ $q = $db->sql_query('SELECT p.message_from, p.message_to, p.subject, p.message_text, p.date, p.folder_name, u.signature FROM '.table_prefix.'privmsgs AS p LEFT JOIN '.table_prefix.'users AS u ON (p.message_from=u.username) WHERE message_id='.$id.'');
+ if(!$q) $db->_die('The message data could not be selected.');
+ $r = $db->fetchrow();
+ $db->free_result();
+ if( ($r['message_to'] != $session->username && $r['message_from'] != $session->username ) || $r['folder_name']=='drafts' ) die_friendly('Access denied', '<p>You are not authorized to view this message.</p>');
+ if($r['message_to'] == $session->username)
+ {
+ $q = $db->sql_query('UPDATE '.table_prefix.'privmsgs SET message_read=1 WHERE message_id='.$id.'');
+ $db->free_result();
+ if(!$q) $db->_die('Could not mark message as read');
+ }
+ $template->header();
+ userprefs_show_menu();
+ ?>
+ <br />
+ <div class="tblholder"><table border="0" width="100%" cellspacing="1" cellpadding="4">
+ <tr><th colspan="2">Private message from <?php echo $r['message_from']; ?></th></tr>
+ <tr><td class="row1">Subject:</td><td class="row1"><?php echo $r['subject']; ?></td></tr>
+ <tr><td class="row2">Date:</td><td class="row2"><?php echo date('M j, Y G:i', $r['date']); ?></td></tr>
+ <tr><td class="row1">Message:</td><td class="row1"><?php echo RenderMan::render($r['message_text']);
+ if($r['signature'] != '')
+ {
+ echo '<hr style="margin-left: 1em; width: 200px;" />';
+ echo RenderMan::render($r['signature']);
+ }
+ ?></td></tr>
+ <tr><td colspan="2" class="row3"><a href="<?php echo makeUrlNS('Special', 'PrivateMessages/Compose/ReplyTo/'.$id); ?>">Send reply</a> | <a href="<?php echo makeUrlNS('Special', 'PrivateMessages/Delete/'.$id); ?>">Delete message</a> | <?php if($r['folder_name'] != 'archive') { ?><a href="<?php echo makeUrlNS('Special', 'PrivateMessages/Move/'.$id.'/Archive'); ?>">Archive message</a> | <?php } ?><a href="<?php echo makeUrlNS('Special', 'PrivateMessages/Folder/Inbox') ?>">Return to inbox</a></td></tr>
+ </table></div>
+ <?php
+ $template->footer();
+ break;
+ case 'Move':
+ $id = $argv[1];
+ if(!preg_match('#^([0-9]+)$#', $id)) die_friendly('Message error', '<p>Invalid message ID</p>');
+ $q = $db->sql_query('SELECT message_to FROM '.table_prefix.'privmsgs WHERE message_id='.$id.'');
+ if(!$q) $db->_die('The message data could not be selected.');
+ $r = $db->fetchrow();
+ $db->free_result();
+ if($r['message_to'] != $session->username) die_friendly('Access denied', '<p>You are not authorized to alter this message.</p>');
+ $fname = $argv[2];
+ if(!$fname || ( $fname != 'Inbox' && $fname != 'Outbox' && $fname != 'Sent' && $fname != 'Drafts' && $fname != 'Archive' ) ) die_friendly('Invalid request', '<p>The folder name "'.$fname.'" is invalid.</p>');
+ $q = $db->sql_query('UPDATE '.table_prefix.'privmsgs SET folder_name=\''.strtolower($fname).'\' WHERE message_id='.$id.';');
+ $db->free_result();
+ if(!$q) $db->_die('The message was not successfully moved.');
+ die_friendly('Message status', '<p>Your message has been moved to the folder "'.$fname.'".</p><p><a href="'.makeUrlNS('Special', 'PrivateMessages/Folder/Inbox').'">Return to inbox</a></p>');
+ break;
+ case 'Delete':
+ $id = $argv[1];
+ if(!preg_match('#^([0-9]+)$#', $id)) die_friendly('Message error', '<p>Invalid message ID</p>');
+ $q = $db->sql_query('SELECT message_to FROM '.table_prefix.'privmsgs WHERE message_id='.$id.'');
+ if(!$q) $db->_die('The message data could not be selected.');
+ $r = $db->fetchrow();
+ if($r['message_to'] != $session->username) die_friendly('Access denied', '<p>You are not authorized to delete this message.</p>');
+ $q = $db->sql_query('DELETE FROM '.table_prefix.'privmsgs WHERE message_id='.$id.';');
+ if(!$q) $db->_die('The message was not successfully deleted.');
+ $db->free_result();
+ die_friendly('Message status', '<p>The message has been deleted.</p><p><a href="'.makeUrlNS('Special', 'PrivateMessages/Folder/Inbox').'">Return to inbox</a></p>');
+ break;
+ case 'Compose':
+ if($argv[1]=='Send' && isset($_POST['_send']))
+ {
+ // Check each POST DATA parameter...
+ if(!isset($_POST['to']) || ( isset($_POST['to']) && $_POST['to'] == '')) die_friendly('Sending of message failed', '<p>Please enter the username to which you want to send your message.</p>');
+ if(!isset($_POST['subject']) || ( isset($_POST['subject']) && $_POST['subject'] == '')) die_friendly('Sending of message failed', '<p>Please enter a subject for your message.</p>');
+ if(!isset($_POST['message']) || ( isset($_POST['message']) && $_POST['message'] == '')) die_friendly('Sending of message failed', '<p>Please enter a message to send.</p>');
+ $namelist = $_POST['to'];
+ $namelist = str_replace(', ', ',', $namelist);
+ $namelist = explode(',', $namelist);
+ foreach($namelist as $n) { $n = $db->escape($n); }
+ $subject = RenderMan::preprocess_text($_POST['subject']);
+ $message = RenderMan::preprocess_text($_POST['message']);
+ $base_query = 'INSERT INTO '.table_prefix.'privmsgs(message_from,message_to,date,subject,message_text,folder_name,message_read) VALUES';
+ foreach($namelist as $n)
+ {
+ $base_query .= '(\''.$session->username.'\', \''.$n.'\', '.time().', \''.$subject.'\', \''.$message.'\', \'inbox\', 0),';
+ }
+ $base_query = substr($base_query, 0, strlen($base_query)-1) . ';';
+ $result = $db->sql_query($base_query);
+ $db->free_result();
+ if(!$result) $db->_die('The message could not be sent.');
+ else die_friendly('Message status', '<p>Your message has been sent. You may edit the message if you wish; one copy for each recipient will be in your outbox until each recipient has read it. Return to your <a href="'.makeUrlNS('Special', 'PrivateMessages/Folder/Inbox').'">inbox</a>.</p>');
+ return;
+ } elseif($argv[1]=='Send' && isset($_POST['_savedraft'])) {
+ // Check each POST DATA parameter...
+ if(!isset($_POST['to']) || ( isset($_POST['to']) && $_POST['to'] == '')) die_friendly('Sending of message failed', '<p>Please enter the username to which you want to send your message.</p>');
+ if(!isset($_POST['subject']) || ( isset($_POST['subject']) && $_POST['subject'] == '')) die_friendly('Sending of message failed', '<p>Please enter a subject for your message.</p>');
+ if(!isset($_POST['message']) || ( isset($_POST['message']) && $_POST['message'] == '')) die_friendly('Sending of message failed', '<p>Please enter a message to send.</p>');
+ $namelist = $_POST['to'];
+ $namelist = str_replace(', ', ',', $namelist);
+ $namelist = explode(',', $namelist);
+ foreach($namelist as $n) { $n = $db->escape($n); }
+ if(count($namelist) > MAX_PMS_PER_BATCH && $session->get_permssions('mod_misc')) die_friendly('Limit exceeded', '<p>You can only send this message to a maximum of '.MAX_PMS_PER_BATCH.' users.</p>');
+ $subject = $db->escape($_POST['subject']);
+ $message = RenderMan::preprocess_text($_POST['message']);
+ $base_query = 'INSERT INTO '.table_prefix.'privmsgs(message_from,message_to,date,subject,message_text,folder_name,message_read) VALUES';
+ foreach($namelist as $n)
+ {
+ $base_query .= '(\''.$session->username.'\', \''.$n.'\', '.time().', \''.$subject.'\', \''.$message.'\', \'drafts\', 0),';
+ }
+ $base_query = substr($base_query, 0, strlen($base_query)-1) . ';';
+ $result = $db->sql_query($base_query);
+ $db->free_result();
+ if(!$result) $db->_die('The message could not be saved.');
+ } elseif(isset($_POST['_inbox'])) {
+ header('Location: '.makeUrlNS('Special', 'PrivateMessages/Folder/Inbox'));
+ }
+ if($argv[1] == 'ReplyTo' && preg_match('#^([0-9]+)$#', $argv[2]))
+ {
+ $to = '';
+ $text = '';
+ $subj = '';
+ $id = $argv[2];
+ $q = $db->sql_query('SELECT p.message_from, p.message_to, p.subject, p.message_text, p.date, p.folder_name, u.signature FROM '.table_prefix.'privmsgs AS p LEFT JOIN '.table_prefix.'users AS u ON (p.message_from=u.username) WHERE message_id='.$id.';');
+ if(!$q) $db->_die('The message data could not be selected.');
+ $r = $db->fetchrow();
+ $db->free_result();
+ if( ($r['message_to'] != $session->username && $r['message_from'] != $session->username ) || $r['folder_name']=='drafts' ) die_friendly('Access denied', '<p>You are not authorized to view the contents of this message.</p>');
+ $subj = 'Re: ' . $r['subject'];
+ $text = "\n\n\nOn ".date('M j, Y G:i', $r['date']).", ".$r['message_from']." wrote:\n> ".str_replace("\n", "\n> ", $r['message_text']); // Way less complicated than using a regex ;-)
+
+ $tbuf = $text;
+ while( preg_match("/\n([\> ]*?)\> \>/", $text) )
+ {
+ $text = preg_replace("/\n([\> ]*?)\> \>/", '\\1>>', $text);
+ if ( $text == $tbuf )
+ break;
+ $tbuf = $text;
+ }
+
+ $to = $r['message_from'];
+ } else {
+ if($argv[1]=='to' && $argv[2]) $to = $argv[2];
+ else $to = '';
+ $text = '';
+ $subj = '';
+ }
+ $template->header();
+ userprefs_show_menu();
+ echo '<form action="'.makeUrlNS('Special', 'PrivateMessages/Compose/Send').'" method="post" onsubmit="if(!submitAuthorized) return false;">';
+ ?>
+ <br />
+ <div class="tblholder"><table border="0" width="100%" cellspacing="1" cellpadding="4">
+ <tr><th colspan="2">Compose new private message</th></tr>
+ <tr><td class="row1">To:<br /><small>Separate multiple names with a single comma; you<br />can send this message to up to <b><?php echo (string)MAX_PMS_PER_BATCH; ?></b> users.</small></td><td class="row1"><?php echo $template->username_field('to', (isset($_POST['_savedraft'])) ? $_POST['to'] : $to ); ?></td></tr>
+ <tr><td class="row2">Subject:</td><td class="row2"><input name="subject" type="text" size="30" value="<?php if(isset($_POST['_savedraft'])) echo $_POST['subject']; else echo $subj; ?>" /></td></tr>
+ <tr><td class="row1">Message:</td><td class="row1" style="min-width: 80%;"><textarea rows="20" cols="40" name="message" style="width: 100%;"><?php if(isset($_POST['_savedraft'])) echo $_POST['message']; else echo $text; ?></textarea></td></tr>
+ <tr><th colspan="2"><input type="submit" name="_send" value="Send message" /> <input type="submit" name="_savedraft" value="Save as draft" /> <input type="submit" name="_inbox" value="Back to Inbox" /></th></tr>
+ </table></div>
+ <?php
+ echo '</form>';
+ $template->footer();
+ break;
+ case 'Edit':
+ $id = $argv[1];
+ if(!preg_match('#^([0-9]+)$#', $id)) die_friendly('Message error', '<p>Invalid message ID</p>');
+ $q = $db->sql_query('SELECT message_from, message_to, subject, message_text, date, folder_name, message_read FROM '.table_prefix.'privmsgs WHERE message_id='.$id.'');
+ if(!$q) $db->_die('The message data could not be selected.');
+ $r = $db->fetchrow();
+ $db->free_result();
+ if($r['message_from'] != $session->username || $r['message_read'] == 1 ) die_friendly('Access denied', '<p>You are not authorized to edit this message.</p>');
+ $fname = $argv[2];
+
+ if(isset($_POST['_send']))
+ {
+ // Check each POST DATA parameter...
+ if(!isset($_POST['to']) || ( isset($_POST['to']) && $_POST['to'] == '')) die_friendly('Sending of message failed', '<p>Please enter the username to which you want to send your message.</p>');
+ if(!isset($_POST['subject']) || ( isset($_POST['subject']) && $_POST['subject'] == '')) die_friendly('Sending of message failed', '<p>Please enter a subject for your message.</p>');
+ if(!isset($_POST['message']) || ( isset($_POST['message']) && $_POST['message'] == '')) die_friendly('Sending of message failed', '<p>Please enter a message to send.</p>');
+ $namelist = $_POST['to'];
+ $namelist = str_replace(', ', ',', $namelist);
+ $namelist = explode(',', $namelist);
+ foreach($namelist as $n) { $n = $db->escape($n); }
+ $subject = RenderMan::preprocess_text($_POST['subject']);
+ $message = RenderMan::preprocess_text($_POST['message']);
+ $base_query = 'UPDATE '.table_prefix.'privmsgs SET subject=\''.$subject.'\',message_to=\''.$namelist[0].'\',message_text=\''.$message.'\',folder_name=\'inbox\' WHERE message_id='.$id.';';
+ $result = $db->sql_query($base_query);
+ $db->free_result();
+ if(!$result) $db->_die('The message could not be sent.');
+ else die_friendly('Message status', '<p>Your message has been sent. You may edit the message if you wish; one copy for each recipient will be in your outbox until each recipient has read it. Return to your <a href="'.makeUrlNS('Special', 'PrivateMessages/Folder/Inbox').'">inbox</a>.</p>');
+ return;
+ } elseif(isset($_POST['_savedraft'])) {
+ // Check each POST DATA parameter...
+ if(!isset($_POST['to']) || ( isset($_POST['to']) && $_POST['to'] == '')) die_friendly('Sending of message failed', '<p>Please enter the username to which you want to send your message.</p>');
+ if(!isset($_POST['subject']) || ( isset($_POST['subject']) && $_POST['subject'] == '')) die_friendly('Sending of message failed', '<p>Please enter a subject for your message.</p>');
+ if(!isset($_POST['message']) || ( isset($_POST['message']) && $_POST['message'] == '')) die_friendly('Sending of message failed', '<p>Please enter a message to send.</p>');
+ $namelist = $_POST['to'];
+ $namelist = str_replace(', ', ',', $namelist);
+ $namelist = explode(',', $namelist);
+ foreach($namelist as $n) { $n = $db->escape($n); }
+ $subject = $db->escape($_POST['subject']);
+ $message = RenderMan::preprocess_text($_POST['message']);
+ $base_query = 'UPDATE '.table_prefix.'privmsgs SET subject=\''.$subject.'\',message_to=\''.$namelist[0].'\',message_text=\''.$message.'\' WHERE message_id='.$id.';';
+ $result = $db->sql_query($base_query);
+ $db->free_result();
+ if(!$result) $db->_die('The message could not be saved.');
+ }
+ if($argv[1]=='to' && $argv[2]) $to = $argv[2];
+ else $to = '';
+ $template->header();
+ userprefs_show_menu();
+ echo '<form action="'.makeUrlNS('Special', 'PrivateMessages/Edit/'.$id).'" method="post">';
+ ?>
+ <br />
+ <div class="tblholder"><table border="0" width="100%" cellspacing="1" cellpadding="4">
+ <tr><th colspan="2">Edit draft</th></tr>
+ <tr><td class="row1">To:<br /><small>Separate multiple names with a single comma</small></td><td class="row1"><input name="to" type="text" size="30" value="<?php if(isset($_POST['_savedraft'])) echo $_POST['to']; else echo $r['message_to']; ?>" /></td></tr>
+ <tr><td class="row2">Subject:</td><td class="row2"><input name="subject" type="text" size="30" value="<?php if(isset($_POST['_savedraft'])) echo $_POST['subject']; else echo $r['subject']; ?>" /></td></tr>
+ <tr><td class="row1">Message:</td><td class="row1"><textarea rows="20" cols="40" name="message" style="width: 100%;"><?php if(isset($_POST['_savedraft'])) echo $_POST['message']; else echo $r['message_text']; ?></textarea></td></tr>
+ <tr><th colspan="2"><input type="submit" name="_send" value="Send message" /> <input type="submit" name="_savedraft" value="Save as draft" /></th></tr>
+ </table></div>
+ <?php
+ echo '</form>';
+ $template->footer();
+ break;
+ case 'Folder':
+ $template->header();
+ userprefs_show_menu();
+ switch($argv[1])
+ {
+ default:
+ echo '<p>The folder "'.$argv[1].'" does not exist. Return to your <a href="'.makeUrlNS('Special', 'PrivateMessages/Folder/Inbox').'">inbox</a>.</p>';
+ break;
+ case 'Inbox':
+ case 'Outbox':
+ case 'Sent':
+ case 'Drafts':
+ case 'Archive':
+ ?>
+ <table border="0" width="100%" cellspacing="10" cellpadding="0">
+ <tr>
+ <td style="padding: 0px; width: 120px;" valign="top" >
+ <div class="tblholder" style="width: 120px;"><table border="0" width="120" cellspacing="1" cellpadding="4">
+ <tr><th><small>Private messages</small></th></tr>
+ <tr><td class="row1"><small><a href="<?php echo $session->append_sid('Inbox'); ?>">Inbox</a> </small></td></tr>
+ <tr><td class="row2"><small><a href="<?php echo $session->append_sid('Outbox'); ?>">Outbox</a> </small></td></tr>
+ <tr><td class="row1"><small><a href="<?php echo $session->append_sid('Sent'); ?>">Sent Items</a></small></td></tr>
+ <tr><td class="row2"><small><a href="<?php echo $session->append_sid('Drafts'); ?>">Drafts</a> </small></td></tr>
+ <tr><td class="row1"><small><a href="<?php echo $session->append_sid('Archive'); ?>">Archive</a></small></td></tr>
+ <tr><th><small>Buddies</small></th></tr>
+ <tr><td class="row2"><small><a href="<?php echo makeUrlNS('Special', 'PrivateMessages/FriendList'); ?>">Friend list</a></small></td></tr>
+ <tr><td class="row1"><small><a href="<?php echo makeUrlNS('Special', 'PrivateMessages/FoeList'); ?>">Foe list</a></small></td></tr>
+ </table></div>
+ </td>
+ <td valign="top">
+ <?php
+ $fname = strtolower($argv[1]);
+ switch($argv[1])
+ {
+ case 'Inbox':
+ case 'Archive':
+ default:
+ $q = $db->sql_query('SELECT p.message_id, p.message_from, p.message_to, p.date, p.subject, p.message_read FROM '.table_prefix.'privmsgs AS p WHERE p.folder_name=\''.$fname.'\' AND p.message_to=\''.$session->username.'\' ORDER BY date DESC;');
+ break;
+ case 'Outbox':
+ $q = $db->sql_query('SELECT p.message_id, p.message_from, p.message_to, p.date, p.subject, p.message_read FROM '.table_prefix.'privmsgs AS p WHERE p.message_from=\''.$session->username.'\' AND message_read=0 ORDER BY date DESC;');
+ break;
+ case 'Sent':
+ $q = $db->sql_query('SELECT p.message_id, p.message_from, p.message_to, p.date, p.subject, p.message_read FROM '.table_prefix.'privmsgs AS p WHERE p.message_from=\''.$session->username.'\' AND message_read=1 ORDER BY date DESC;');
+ break;
+ case 'Drafts':
+ $q = $db->sql_query('SELECT p.message_id, p.message_from, p.message_to, p.date, p.subject, p.message_read FROM '.table_prefix.'privmsgs AS p WHERE p.folder_name=\''.$fname.'\' AND p.message_from=\''.$session->username.'\' ORDER BY date DESC;');
+ break;
+ }
+ if($argv[1] == 'Drafts' || $argv[1] == 'Outbox') $act = 'Edit';
+ else $act = 'View';
+ if(!$q) $db->_die('The private message data could not be selected.');
+ echo '<form action="'.makeUrlNS('Special', 'PrivateMessages/PostHandler').'" method="post"><div class="tblholder"><table border="0" width="100%" cellspacing="1" cellpadding="4"><tr><th colspan="4" style="text-align: left;">Folder: '.$argv[1].'</th></tr><tr><th class="subhead">';
+ if($fname == 'drafts' || $fname == 'Outbox') echo 'To'; else echo 'From';
+ echo '</th><th class="subhead">Subject</th><th class="subhead">Date</th><th class="subhead">Mark</th></tr>';
+ if($db->numrows() < 1)
+ echo '<tr><td style="text-align: center;" class="row1" colspan="4">No messages in this folder.</td></tr>';
+ else {
+ $cls = 'row2';
+ while($r = $db->fetchrow())
+ {
+ if($cls == 'row2') $cls='row1';
+ else $cls = 'row2';
+ $mto = str_replace(' ', '_', $r['message_to']);
+ $mfr = str_replace(' ', '_', $r['message_from']);
+ echo '<tr><td class="'.$cls.'"><a href="'.makeUrlNS('User', ( $fname == 'drafts') ? $mto : $mfr).'">';
+ if($fname == 'drafts' || $fname == 'outbox') echo $r['message_to']; else echo $r['message_from'];
+ echo '</a></td><td class="'.$cls.'"><a href="'.makeUrlNS('Special', 'PrivateMessages/'.$act.'/'.$r['message_id']).'">';
+ if($r['message_read'] == 0) echo '<b>';
+ echo $r['subject'];
+ if($r['message_read'] == 0) echo '</b>';
+ echo '</a></td><td class="'.$cls.'">'.date('M j, Y G:i', $r['date']).'</td><td class="'.$cls.'" style="text-align: center;"><input name="marked_'.$r['message_id'].'" type="checkbox" /></td></tr>';
+ }
+ $db->free_result();
+ }
+ echo '<tr><th style="text-align: right;" colspan="4"><input type="hidden" name="folder" value="'.$fname.'" /><input type="submit" name="archive" value="Archive selected" /> <input type="submit" name="delete" value="Delete selected" /> <input type="submit" name="deleteall" value="Delete all" /></th></tr>';
+ echo '</table></div></form>
+ <br />
+ <a href="'.makeUrlNS('Special', 'PrivateMessages/Compose/').'">New message</a>
+ </td></tr></table>';
+ break;
+ }
+ $template->footer();
+ break;
+ case 'PostHandler':
+ $fname = $db->escape(strtolower($_POST['folder']));
+ if($fname=='drafts' || $fname=='outbox')
+ {
+ $q = $db->sql_query('SELECT p.message_id, p.message_from, p.message_to, p.date, p.subject FROM '.table_prefix.'privmsgs AS p WHERE p.folder_name=\''.$fname.'\' AND p.message_from=\''.$session->username.'\' ORDER BY date DESC;');
+ } else {
+ $q = $db->sql_query('SELECT p.message_id, p.message_from, p.message_to, p.date, p.subject FROM '.table_prefix.'privmsgs AS p WHERE p.folder_name=\''.$fname.'\' AND p.message_to=\''.$session->username.'\' ORDER BY date DESC;');
+ }
+ if(!$q) $db->_die('The private message data could not be selected.');
+
+ if(isset($_POST['archive'])) {
+ while($row = $db->fetchrow($q))
+ {
+ if(isset($_POST['marked_'.$row['message_id']]))
+ {
+ $e = $db->sql_query('UPDATE '.table_prefix.'privmsgs SET folder_name=\'archive\' WHERE message_id='.$row['message_id'].';');
+ if(!$e) $db->_die('Message '.$row['message_id'].' was not successfully moved.');
+ $db->free_result();
+ }
+ }
+ } elseif(isset($_POST['delete'])) {
+ while($row = $db->fetchrow($q))
+ {
+ if(isset($_POST['marked_'.$row['message_id']]))
+ {
+ $e = $db->sql_query('DELETE FROM '.table_prefix.'privmsgs WHERE message_id='.$row['message_id'].';');
+ if(!$e) $db->_die('Message '.$row['message_id'].' was not successfully moved.');
+ $db->free_result();
+ }
+ }
+ } elseif(isset($_POST['deleteall'])) {
+ while($row = $db->fetchrow($q))
+ {
+ $e = $db->sql_query('DELETE FROM '.table_prefix.'privmsgs WHERE message_id='.$row['message_id'].';');
+ if(!$e) $db->_die('Message '.$row['message_id'].' was not successfully moved.');
+ $db->free_result();
+ }
+ } else {
+ die_friendly('Invalid request', 'This section can only be accessed from within another Private Message section.');
+ }
+ $db->free_result($q);
+ header('Location: '.makeUrlNS('Special', 'PrivateMessages/Folder/'. substr(strtoupper($_POST['folder']), 0, 1) . substr(strtolower($_POST['folder']), 1, strlen($_POST['folder'])) ));
+ break;
+ case 'FriendList':
+ if($argv[1] == 'Add')
+ {
+ if(isset($_POST['_go']))
+ $buddyname = $_POST['buddyname'];
+ elseif($argv[2])
+ $buddyname = $argv[2];
+ else
+ die_friendly('Error adding buddy', '<p>No name specified</p>');
+ $q = $db->sql_query('SELECT user_id FROM '.table_prefix.'users WHERE username=\''.$db->escape($buddyname).'\'');
+ if(!$q) $db->_die('The buddy\'s user ID could not be selected.');
+ if($db->numrows() < 1) echo '<h3>Error adding buddy</h3><p>The username you entered is not in use by any registered user.</p>';
+ {
+ $r = $db->fetchrow();
+ $db->free_result();
+ $q = $db->sql_query('INSERT INTO '.table_prefix.'buddies(user_id,buddy_user_id,is_friend) VALUES('.$session->user_id.', '.$r['user_id'].', 1);');
+ if(!$q) echo '<h3>Warning:</h3><p>Buddy could not be added: '.mysql_error().'</p>';
+ $db->free_result();
+ }
+ } elseif($argv[1] == 'Remove' && preg_match('#^([0-9]+)$#', $argv[2])) {
+ // Using WHERE user_id prevents users from deleting others' buddies
+ $q = $db->sql_query('DELETE FROM '.table_prefix.'buddies WHERE user_id='.$session->user_id.' AND buddy_id='.$argv[2].';');
+ $db->free_result();
+ if(!$q) echo '<h3>Warning:</h3><p>Buddy could not be deleted: '.mysql_error().'</p>';
+ if(mysql_affected_rows() < 1) echo '<h3>Warning:</h3><p>No rows were affected. Either the selected buddy ID does not exist or you tried to delete someone else\'s buddy.</p>';
+ }
+ $template->header();
+ userprefs_show_menu();
+ ?>
+ <table border="0" width="100%" cellspacing="10" cellpadding="0">
+ <tr>
+ <td style="padding: 0px; width: 120px;" valign="top" >
+ <div class="tblholder" style="width: 120px;"><table border="0" width="120" cellspacing="1" cellpadding="4">
+ <tr><th><small>Private messages</small></th></tr>
+ <tr><td class="row1"><small><a href="<?php echo $session->append_sid('Inbox'); ?>">Inbox</a> </small></td></tr>
+ <tr><td class="row2"><small><a href="<?php echo $session->append_sid('Outbox'); ?>">Outbox</a> </small></td></tr>
+ <tr><td class="row1"><small><a href="<?php echo $session->append_sid('Sent'); ?>">Sent Items</a></small></td></tr>
+ <tr><td class="row2"><small><a href="<?php echo $session->append_sid('Drafts'); ?>">Drafts</a> </small></td></tr>
+ <tr><td class="row1"><small><a href="<?php echo $session->append_sid('Archive'); ?>">Archive</a></small></td></tr>
+ <tr><th><small>Buddies</small></th></tr>
+ <tr><td class="row2"><small><a href="<?php echo makeUrlNS('Special', 'PrivateMessages/FriendList'); ?>">Friend list</a></small></td></tr>
+ <tr><td class="row1"><small><a href="<?php echo makeUrlNS('Special', 'PrivateMessages/FoeList'); ?>">Foe list</a></small></td></tr>
+ </table></div>
+ </td>
+ <td valign="top">
+ <?php
+ $q = $db->sql_query('SELECT u.username,b.buddy_id FROM '.table_prefix.'buddies AS b LEFT JOIN '.table_prefix.'users AS u ON ( u.user_id=b.buddy_user_id ) WHERE b.user_id='.$session->user_id.' AND is_friend=1;');
+ if(!$q) $db->_die('The buddy list could not be selected.');
+ else
+ {
+ $allbuds = '';
+ echo '<br /><div class="tblholder"><table border="0" width="100%" cellspacing="1" cellpadding="4"><tr><th colspan="3">Buddy list for '.$session->username.'</th></tr>';
+ if($db->numrows() < 1) echo '<tr><td class="row3">No buddies in your list.</td></tr>';
+ $cls = 'row2';
+ while ( $row = $db->fetchrow() )
+ {
+ if($cls=='row2') $cls = 'row1';
+ else $cls = 'row2';
+ echo '<tr><td class="'.$cls.'"><a href="'.makeUrlNS('User', str_replace(' ', '_', $row['username'])).'" '. ( isPage($paths->nslist['User'].str_replace(' ', '_', $row['username'])) ? '' : 'class="wikilink-nonexistent" ' ) .'>'.$row['username'].'</a></td><td class="'.$cls.'"><a href="'.makeUrlNS('Special', 'PrivateMessages/Compose/to/'.str_replace(' ', '_', $row['username'])).'">Send private message</a></td><td class="'.$cls.'"><a onclick="return confirm(\'Are you sure you want to delete this user from your buddy list?\')" href="'.makeUrlNS('Special', 'PrivateMessages/FriendList/Remove/'.$row['buddy_id']).'">Remove</a></td></tr>';
+ $allbuds .= str_replace(' ', '_', $row['username']).',';
+ }
+ $db->free_result();
+ $allbuds = substr($allbuds, 0, strlen($allbuds)-1);
+ if($cls=='row2') $cls = 'row1';
+ else $cls = 'row2';
+ echo '<tr><td colspan="3" class="'.$cls.'" style="text-align: center;"><a href="'.makeUrlNS('Special', 'PrivateMessages/Compose/to/'.$allbuds).'">Send a PM to all buddies</a></td></tr>';
+ echo '</table></div>';
+ }
+ echo '<form action="'.makeUrlNS('Special', 'PrivateMessages/FriendList/Add').'" method="post" onsubmit="if(!submitAuthorized) return false;">
+ <h3>Add a new friend</h3>';
+ echo '<p>Username: '.$template->username_field('buddyname').' <input type="submit" name="_go" value="Add" /></p>';
+ echo '</form>';
+ ?>
+ </td>
+ </tr>
+ </table>
+ <?php
+ $template->footer();
+ break;
+ case 'FoeList':
+ if($argv[1] == 'Add' && isset($_POST['_go']))
+ {
+ $q = $db->sql_query('SELECT user_id FROM '.table_prefix.'users WHERE username=\''.$db->escape($_POST['buddyname']).'\'');
+ if(!$q) $db->_die('The buddy\'s user ID could not be selected.');
+ if($db->numrows() < 1) echo '<h3>Error adding buddy</h3><p>The username you entered is not in use by any registered user.</p>';
+ {
+ $r = $db->fetchrow();
+ $q = $db->sql_query('INSERT INTO '.table_prefix.'buddies(user_id,buddy_user_id,is_friend) VALUES('.$session->user_id.', '.$r['user_id'].', 0);');
+ if(!$q) echo '<h3>Warning:</h3><p>Buddy could not be added: '.mysql_error().'</p>';
+ }
+ $db->free_result();
+ } elseif($argv[1] == 'Remove' && preg_match('#^([0-9]+)$#', $argv[2])) {
+ // Using WHERE user_id prevents users from deleting others' buddies
+ $q = $db->sql_query('DELETE FROM '.table_prefix.'buddies WHERE user_id='.$session->user_id.' AND buddy_id='.$argv[2].';');
+ $db->free_result();
+ if(!$q) echo '<h3>Warning:</h3><p>Buddy could not be deleted: '.mysql_error().'</p>';
+ if(mysql_affected_rows() < 1) echo '<h3>Warning:</h3><p>No rows were affected. Either the selected buddy ID does not exist or you tried to delete someone else\'s buddy.</p>';
+ }
+ $template->header();
+ userprefs_show_menu();
+ ?>
+ <table border="0" width="100%" cellspacing="10" cellpadding="0">
+ <tr>
+ <td style="padding: 0px; width: 120px;" valign="top" >
+ <div class="tblholder" style="width: 120px;"><table border="0" width="120" cellspacing="1" cellpadding="4">
+ <tr><th><small>Private messages</small></th></tr>
+ <tr><td class="row1"><small><a href="<?php echo $session->append_sid('Inbox'); ?>">Inbox</a> </small></td></tr>
+ <tr><td class="row2"><small><a href="<?php echo $session->append_sid('Outbox'); ?>">Outbox</a> </small></td></tr>
+ <tr><td class="row1"><small><a href="<?php echo $session->append_sid('Sent'); ?>">Sent Items</a></small></td></tr>
+ <tr><td class="row2"><small><a href="<?php echo $session->append_sid('Drafts'); ?>">Drafts</a> </small></td></tr>
+ <tr><td class="row1"><small><a href="<?php echo $session->append_sid('Archive'); ?>">Archive</a></small></td></tr>
+ <tr><th><small>Buddies</small></th></tr>
+ <tr><td class="row2"><small><a href="<?php echo makeUrlNS('Special', 'PrivateMessages/FriendList'); ?>">Friend list</a></small></td></tr>
+ <tr><td class="row1"><small><a href="<?php echo makeUrlNS('Special', 'PrivateMessages/FoeList'); ?>">Foe list</a></small></td></tr>
+ </table></div>
+ </td>
+ <td valign="top">
+ <?php
+ $q = $db->sql_query('SELECT u.username,b.buddy_id FROM '.table_prefix.'buddies AS b LEFT JOIN '.table_prefix.'users AS u ON ( u.user_id=b.buddy_user_id ) WHERE b.user_id='.$session->user_id.' AND is_friend=0;');
+ if(!$q) $db->_die('The buddy list could not be selected.');
+ else
+ {
+ $allbuds = '';
+ echo '<br /><div class="tblholder"><table border="0" width="100%" cellspacing="1" cellpadding="4"><tr><th colspan="3">Foe list for '.$session->username.'</th></tr>';
+ if($db->numrows() < 1) echo '<tr><td class="row2">No foes in your list.</td></tr>';
+ $cls = 'row2';
+ while ( $row = $db->fetchrow() )
+ {
+ if($cls=='row2') $cls = 'row1';
+ else $cls = 'row2';
+ echo '<tr><td class="'.$cls.'"><a href="'.makeUrlNS('User', str_replace(' ', '_', $row['username'])).'" '. ( isPage($paths->nslist['User'].str_replace(' ', '_', $row['username'])) ? '' : 'class="wikilink-nonexistent" ' ) .'>'.$row['username'].'</a></td><td class="'.$cls.'"><a href="'.makeUrlNS('Special', 'PrivateMessages/Compose/to/'.str_replace(' ', '_', $row['username'])).'">Send private message</a></td><td class="'.$cls.'"><a onclick="return confirm(\'Are you sure you want to delete this user from your buddy list?\')" href="'.makeUrlNS('Special', 'PrivateMessages/FriendList/Remove/'.$row['buddy_id']).'">Remove</a></td></tr>';
+ $allbuds .= str_replace(' ', '_', $row['username']).',';
+ }
+ $allbuds = substr($allbuds, 0, strlen($allbuds)-1);
+ if($cls=='row2') $cls = 'row1';
+ else $cls = 'row2';
+ //echo '<tr><td colspan="3" class="'.$cls.'" style="text-align: center;"><a href="'.makeUrlNS('Special', 'PrivateMessages/Compose/to/'.$allbuds).'">Send a PM to all buddies</a></td></tr>';
+ echo '</table></div>';
+ }
+ $db->free_result();
+ echo '<form action="'.makeUrlNS('Special', 'PrivateMessages/FoeList/Add').'" method="post" onsubmit="if(!submitAuthorized) return false;">
+ <h3>Add a new foe</h3>';
+ echo '<p>Username: '.$template->username_field('buddyname').' <input type="submit" name="_go" value="Add" /></p>';
+ echo '</form>';
+ ?>
+ </td>
+ </tr>
+ </table>
+ <?php
+ $template->footer();
+ break;
+ }
+}
+
+?>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/SpecialAdmin.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,2722 @@
+<?php
+/*
+Plugin Name: Runt - the Enano administration panel
+Plugin URI: http://enanocms.org/
+Description: Provides the page Special:Administration, which is the AJAX frontend to the various Admin:
+Author: Dan Fuhry
+Version: 1.0
+Author URI: http://enanocms.org/
+*/
+
+/*
+ * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
+ * Version 1.0 release candidate 2
+ * Copyright (C) 2006-2007 Dan Fuhry
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+global $db, $session, $paths, $template, $plugins; // Common objects
+
+$plugins->attachHook('base_classes_initted', '
+ global $paths;
+ $paths->add_page(Array(
+ \'name\'=>\'Administration\',
+ \'urlname\'=>\'Administration\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'Manage the Sidebar\',
+ \'urlname\'=>\'EditSidebar\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ ');
+
+// function names are IMPORTANT!!! The name pattern is: page_<namespace ID>_<page URLname, without namespace>
+
+function page_Admin_Home() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+
+ // Basic information
+ echo RenderMan::render(
+'== Welcome to Runt, the Enano administration panel. ==
+
+Thank you for choosing Enano as your CMS. This screen allows you to see some information about your website, plus some details about how your site is doing statistically.
+
+Using the links on the left you can control every aspect of your website\'s look and feel, plus you can manage users, work with pages, and install plugins to make your Enano installation even better.');
+
+ // Check for the installer scripts
+ if(file_exists(ENANO_ROOT.'/install.php') || file_exists(ENANO_ROOT.'/schema.sql'))
+ {
+ echo '<div class="error-box"><b>NOTE:</b> It appears that your install.php and/or schema.sql files still exist. It is HIGHLY RECOMMENDED that you delete or rename these files, to prevent getting your server hacked.</div>';
+ }
+
+ // Inactive users
+ $q = $db->sql_query('SELECT * FROM '.table_prefix.'logs WHERE log_type=\'admin\' AND action=\'activ_req\';');
+ if($q)
+ if($db->numrows() > 0)
+ {
+ $n = $db->numrows();
+ if($n == 1) $s = $n . ' user is';
+ else $s = $n . ' users are';
+ echo '<div class="warning-box">It appears that '.$s.' awaiting account activation. You can activate those accounts by going to the <a href="#" onclick="ajaxPage(\''.$paths->nslist['Admin'].'UserManager\'); return false;">User Manager</a>.</div>';
+ }
+ $db->free_result();
+ // Stats
+ if(getConfig('log_hits') == '1')
+ {
+ $stats = stats_top_pages(10);
+ $c = 0;
+ $cls = 'row2';
+ echo '<h3>Most requested pages</h3><div class="tblholder"><table style="width: 100%;" border="0" cellspacing="1" cellpadding="4"><tr><th>Page</th><th>Hits</th></tr>';
+ foreach($stats as $page => $count)
+ {
+ if(isset($paths->pages[$page]))
+ {
+ echo '<tr>';
+ $cls = ( $cls == 'row1' ) ? 'row2' : 'row1';
+ echo '<td class="'.$cls.'"><a href="'.makeUrl($page).'">'.$paths->pages[$page]['name'].'</a></td><td style="text-align: center;" class="'.$cls.'">'.$count.'</td>';
+ echo '</tr>';
+ }
+ }
+ echo '</table></div>';
+ }
+
+ // Security log
+ echo '<h3>Security log</h3>';
+ echo '<div class="tblholder" style="/* max-height: 500px; clip: rect(0px,auto,auto,0px); overflow: auto; */"><table border="0" cellspacing="1" cellpadding="4" width="100%">';
+ $cls = 'row2';
+ echo '<tr><th style="width: 60%;">Type</th><th>Date</th><th>Username</th><th>IP Address</th></tr>';
+ if(isset($_GET['fulllog']))
+ {
+ $l = 'SELECT action,date_string,author,edit_summary,time_id,page_text FROM '.table_prefix.'logs WHERE log_type=\'security\' ORDER BY time_id DESC, action ASC;';
+ }
+ else
+ {
+ $l = 'SELECT action,date_string,author,edit_summary,time_id,page_text FROM '.table_prefix.'logs WHERE log_type=\'security\' ORDER BY time_id DESC, action ASC LIMIT 5';
+ }
+ $q = $db->sql_query($l);
+ while($r = $db->fetchrow())
+ {
+ if($cls == 'row2') $cls = 'row1';
+ else $cls = 'row2';
+ echo '<tr><td class="'.$cls.'">';
+ switch($r['action']) {
+ case "admin_auth_good": echo 'Successful elevated authentication'; if ( !empty($r['page_text']) ) { $level = $session->userlevel_to_string( intval($r['page_text']) ); echo "<br /><small>Authentication level: $level</small>"; } break;
+ case "admin_auth_bad": echo 'Failed administration logon'; break;
+ case "activ_good": echo 'Successful account activation'; break;
+ case "auth_good": echo 'Successful regular user logon'; break;
+ case "activ_bad": echo 'Failed account activation'; break;
+ case "auth_bad": echo 'Failed regular user logon'; break;
+ case "sql_inject": echo 'SQL injection attempt<div style="max-width: 90%; clip: rect(0px,auto,auto,0px); overflow: auto; display: block; font-size: smaller;">Offending query: ' . htmlspecialchars($r['page_text']) . '</div>'; break;
+ case "db_backup": echo 'Database backup created<br /><small>Tables: ' . $r['page_text'] . '</small>'; break;
+ case "install_enano": echo "Installed Enano version {$r['page_text']}"; break;
+ }
+ echo '</td><td class="'.$cls.'">'.date('d M Y h:i a', $r['time_id']).'</td><td class="'.$cls.'">'.$r['author'].'</td><td class="'.$cls.'" style="cursor: pointer;" onclick="ajaxReverseDNS(this);" title="Click for reverse DNS info">'.$r['edit_summary'].'</td></tr>';
+ }
+ $db->free_result();
+ echo '</table></div>';
+ if(!isset($_GET['fulllog'])) echo '<p><a href="#" onclick="ajaxPage(\''.$paths->nslist['Admin'].'Home&fulllog\'); return false;">Full security log</a></p>';
+
+}
+
+function page_Admin_GeneralConfig() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ if(isset($_POST['submit'])) {
+
+ // Global site options
+ setConfig('site_name', $_POST['site_name']);
+ setConfig('site_desc', $_POST['site_desc']);
+ setConfig('main_page', str_replace(' ', '_', $_POST['main_page']));
+ setConfig('copyright_notice', $_POST['copyright']);
+ setConfig('contact_email', $_POST['contact_email']);
+
+ // Wiki mode
+ if(isset($_POST['wikimode'])) setConfig('wiki_mode', '1');
+ else setConfig('wiki_mode', '0');
+ if(isset($_POST['wiki_mode_require_login'])) setConfig('wiki_mode_require_login', '1');
+ else setConfig('wiki_mode_require_login', '0');
+ if(isset($_POST['editmsg'])) setConfig('wiki_edit_notice', '1');
+ else setConfig('wiki_edit_notice', '0');
+ setConfig('wiki_edit_notice_text', $_POST['editmsg_text']);
+
+ // Stats
+ if(isset($_POST['log_hits'])) setConfig('log_hits', '1');
+ else setConfig('log_hits', '0');
+
+ // Disablement
+ if(isset($_POST['site_disabled'])) { setConfig('site_disabled', '1'); setConfig('site_disabled_notice', $_POST['site_disabled_notice']); }
+ else setConfig('site_disabled', '0');
+
+ // Account activation
+ setConfig('account_activation', $_POST['account_activation']);
+
+ // W3C compliance buttons
+ if(isset($_POST['w3c-vh32'])) setConfig("w3c_vh32", "1");
+ else setConfig("w3c_vh32", "0");
+ if(isset($_POST['w3c-vh40'])) setConfig("w3c_vh40", "1");
+ else setConfig("w3c_vh40", "0");
+ if(isset($_POST['w3c-vh401'])) setConfig("w3c_vh401", "1");
+ else setConfig("w3c_vh401", "0");
+ if(isset($_POST['w3c-vxhtml10'])) setConfig("w3c_vxhtml10", "1");
+ else setConfig("w3c_vxhtml10", "0");
+ if(isset($_POST['w3c-vxhtml11'])) setConfig("w3c_vxhtml11", "1");
+ else setConfig("w3c_vxhtml11", "0");
+ if(isset($_POST['w3c-vcss'])) setConfig("w3c_vcss", "1");
+ else setConfig("w3c_vcss", "0");
+
+ // SourceForge.net logo
+ if(isset($_POST['showsf'])) setConfig('sflogo_enabled', '1');
+ else setConfig('sflogo_enabled', '0');
+ setConfig('sflogo_groupid', $_POST['sfgroup']);
+ setConfig('sflogo_type', $_POST['sflogo']);
+
+ // Comment options
+ if(isset($_POST['comment-approval'])) setConfig('approve_comments', '1');
+ else setConfig('approve_comments', '0');
+ if(isset($_POST['enable-comments'])) setConfig('enable_comments', '1');
+ else setConfig('enable_comments', '0');
+ setConfig('comments_need_login', $_POST['comments_need_login']);
+
+ // Powered by link
+ if ( isset($_POST['enano_powered_link']) ) setConfig('powered_btn', '1');
+ else setConfig('powered_btn', '0');
+
+ if(isset($_POST['dbdbutton'])) setConfig('dbd_button', '1');
+ else setConfig('dbd_button', '0');
+
+ if($_POST['emailmethod'] == 'phpmail') setConfig('smtp_enabled', '0');
+ else setConfig('smtp_enabled', '1');
+
+ setConfig('smtp_server', $_POST['smtp_host']);
+ setConfig('smtp_user', $_POST['smtp_user']);
+ if($_POST['smtp_pass'] != 'XXXXXXXXXXXX') setConfig('smtp_password', $_POST['smtp_pass']);
+
+ echo '<div class="info-box">Your changes to the site configuration have been saved.</div><br />';
+
+ }
+ echo('<form name="main" action="'.htmlspecialchars(makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module'])).'" method="post" onsubmit="if(!submitAuthorized) return false;">');
+ ?>
+ <div class="tblholder">
+ <table border="0" width="100%" cellspacing="1" cellpadding="4">
+
+ <!-- Global options -->
+
+ <tr><th colspan="2">Global site options</th></tr>
+ <tr><th colspan="2" class="subhead">These options control the entire site.</th></tr>
+
+ <tr><td class="row1" style="width: 50%;">Site name:</td> <td class="row1" style="width: 50%;"><input name="site_name" size="30" value="<?php echo getConfig('site_name'); ?>" /></td></tr>
+ <tr><td class="row2">Site description:</td> <td class="row2"><input name="site_desc" size="30" value="<?php echo getConfig('site_desc'); ?>" /></td></tr>
+ <tr><td class="row1">Main page:</td> <td class="row1"><?php echo $template->pagename_field('main_page', str_replace('_', ' ', getConfig('main_page'))); ?></td></tr>
+ <tr><td class="row2">Copyright notice shown on pages:</td><td class="row2"><input name="copyright" size="30" value="<?php echo getConfig('copyright_notice'); ?>" /></td></tr>
+ <tr><td class="row1" colspan="2">Hint: If you're using Windows, you can make a "©" symbol by holding ALT and pressing 0169 on the numeric keypad.</td></tr>
+ <tr><td class="row2">Contact e-mail<br /><small>All e-mail sent from this site will appear to have come from the address shown here.</small></td><td class="row2"><input name="contact_email" type="text" size="40" value="<?php echo htmlspecialchars(getConfig('contact_email')); ?>" /></td></tr>
+
+ <!-- Wiki mode -->
+
+ <tr><th colspan="2">Wiki mode</th></tr>
+
+ <tr>
+ <td class="row3" rowspan="2">
+ Enano can also act as a wiki, meaning anyone can edit and create pages. To enable Wiki Mode, check the box to the right.<br /><br />
+ In Wiki Mode, certain HTML tags such as <script> and <object> are disabled, and all PHP code is disabled, except if the person editing the page is an administrator.<br /><br />
+ Also, Enano keeps complete page history, which makes restoring vandalized pages easy. You can also protect pages so that they cannot be edited.
+ </td>
+ <td class="row1">
+ <input type="checkbox" name="wikimode" id="wikimode" <?php if(getConfig('wiki_mode')=='1') echo('CHECKED '); ?> /><label for="wikimode">Enable Wiki Mode</label>
+ </td>
+ </tr>
+
+ <tr><td class="row2"><label><input type="checkbox" name="wiki_mode_require_login"<?php if(getConfig('wiki_mode_require_login')=='1') echo('CHECKED '); ?>/> Only for logged in users</label></td></tr>
+
+ <tr>
+ <td class="row3" rowspan="2">
+ <b>Edit page notice</b><br />
+ When Wiki Mode is enabled, anyone can edit pages. Check the box below and enter a message to display it whenever the page editor is opened.
+ </td>
+ <td class="row1">
+ <input onclick="if(this.checked) document.getElementById('editmsg_text').style.display='block'; else document.getElementById('editmsg_text').style.display='none';" type="checkbox" name="editmsg" id="editmsg" <?php if(getConfig('wiki_edit_notice')=='1') echo('CHECKED '); ?>/> <label for="editmsg">Show a message whenever pages are edited</label>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="row2">
+ <textarea <?php if(getConfig('wiki_edit_notice')!='1') echo('style="display:none" '); ?>rows="5" cols="30" name="editmsg_text" id="editmsg_text"><?php echo getConfig('wiki_edit_notice_text'); ?></textarea>
+ </td>
+ </tr>
+
+ <!-- Site statistics -->
+
+ <tr><th colspan="2">Statistics and hit counting</th></tr>
+
+ <tr>
+ <td class="row1">Enano has the ability to show statistics for every page on the site. This allows you to keep very close track of who is visiting your site, and from where.<br /><br />Unfortunately, some users don't like being logged. For this reason, you should state clearly what is logged (usually the username or IP address, current time, page name, and referer URL) in your privacy policy. If your site is primarily geared towards children, and you are a United States citizen, you are required to have a privacy policy stating exactly what is being logged under the terms of the Childrens' Online Privacy Protection Act.</td>
+ <td class="row1"><label><input type="checkbox" name="log_hits" <?php if(getConfig('log_hits') == '1') echo 'checked="checked" '; ?>/> Log all page hits</label><br /><small>This excludes special and administration pages.</small></td>
+ </tr>
+
+ <!-- Comment options -->
+
+ <tr><th colspan="2">Comment system</th></tr>
+ <tr><td class="row1"><label for="enable-comments"><b>Enable the comment system</b></label> </td><td class="row1"><input name="enable-comments" id="enable-comments" type="checkbox" <?php if(getConfig('enable_comments')=='1') echo('CHECKED '); ?>/></td></tr>
+ <tr><td class="row2"><label for="comment-approval">Require approval before article comments can be shown</label></td><td class="row2"><input name="comment-approval" id="comment-approval" type="checkbox" <?php if(getConfig('approve_comments')=='1') echo('CHECKED '); ?>/></td></tr>
+ <tr><td class="row1">Guest comment posting allowed </td><td class="row1"><label><input name="comments_need_login" type="radio" value="0" <?php if(getConfig('comments_need_login')=='0') echo 'CHECKED '; ?>/> Yes</label>
+ <label><input name="comments_need_login" type="radio" value="1" <?php if(getConfig('comments_need_login')=='1') echo 'CHECKED '; ?>/> Require visual confirmation</label>
+ <!-- Default permissions --> <label><input name="comments_need_login" type="radio" value="2" <?php if(getConfig('comments_need_login')=='2') echo 'CHECKED '; ?>/> No (require login)</label></td></tr>
+
+ <!--
+
+ READ: Do not try to enable this, backend support for it has been disabled. To edit default
+ permissions, select The Entire Website in any permissions editor window.
+
+ <tr><th colspan="2">Default permissions for pages</th></tr>
+
+ <tr>
+ <td class="row1">You can edit the default set of permissions used when no other permissions are available. Permissions set here are used when no other permissions are available. As with other ACL rules, you can assign these defaults to every user or one specific user or group.</td>
+ <td class="row1"><a href="#" onclick="ajaxOpenACLManager('__DefaultPermissions', 'Special'); return false;">Manage default permissions</a></td>
+ </tr>
+
+ -->
+
+ <!-- enanocms.org link -->
+
+ <tr>
+ <th colspan="2">Promote Enano</th>
+ </tr>
+ <tr>
+ <td class="row3">
+ If you think Enano is nice, or if you want to show your support for the Enano team, you can do so by placing a link to the Enano
+ homepage in your Links sidebar block. You absolutely don't have to do this, and you won't get degraded support if you don't. Because
+ Enano is still relatively new in the CMS world, it needs all the attention it can get - and you can easily help to spread the word
+ using this link.
+ </td>
+ <td class="row1">
+ <label>
+ <input name="enano_powered_link" type="checkbox" <?php if(getConfig('powered_btn') == '1') echo 'checked="checked"'; ?> /> Place a link to www.enanocms.org on the sidebar
+ </label>
+ </td>
+ </tr>
+
+ <!-- Site disablement -->
+
+ <tr><th colspan="2">Disable all site access</th></tr>
+
+ <tr>
+ <td class="row3" rowspan="2">Disabling the site allows you to work on the site without letting non-administrators see or use it.</td>
+ <td class="row1"><label><input onclick="if(this.checked) document.getElementById('site_disabled_notice').style.display='block'; else document.getElementById('site_disabled_notice').style.display='none';" type="checkbox" name="site_disabled" <?php if(getConfig('site_disabled') == '1') echo 'checked="checked" '; ?>/> Disable this site</label></td>
+ </tr>
+ <tr>
+ <td class="row2">
+ <div id="site_disabled_notice">
+ Message to show to users:<br />
+ <textarea name="site_disabled_notice" rows="7" cols="30"><?php echo getConfig('site_disabled_notice'); ?></textarea>
+ </div>
+ </td>
+ </tr>
+
+ <!-- Account activation -->
+
+ <tr><th colspan="2">User account activation</th></tr>
+
+ <tr>
+ <td class="row3" colspan="2">
+ If you would like to require users to confirm their e-mail addresses by way of account activation, you can enable this behavior here. If this option is set to "None", users will be able to register and use this site without confirming their e-mail addresses. If this option is set to "User", users will automatically be sent e-mails upon registration with a link to activate their accounts. And lastly, if this option is set to "Admin", users' accounts will not be active until an administrator activates the account.<br /><br />
+ You may also disable registration completely if needed.<br /><br />
+ <b>Note: because of abuse by project administrators, sending account activation e-mails will not work on SourceForge.net servers.</b>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="row1">Account activation:</td><td class="row1">
+ <?php
+ echo '<label><input'; if(getConfig('account_activation') == 'disable') echo ' checked="checked"'; echo ' type="radio" name="account_activation" value="disable" /> Disable registration</label><br />';
+ echo '<label><input'; if(getConfig('account_activation') != 'user' && getConfig('account_activation') != 'admin') echo ' checked="checked"'; echo ' type="radio" name="account_activation" value="none" /> None</label>';
+ echo '<label><input'; if(getConfig('account_activation') == 'user') echo ' checked="checked"'; echo ' type="radio" name="account_activation" value="user" /> User</label>';
+ echo '<label><input'; if(getConfig('account_activation') == 'admin') echo ' checked="checked"'; echo ' type="radio" name="account_activation" value="admin" /> Admin</label>';
+ ?>
+ </td>
+ </tr>
+
+ <!-- E-mail options -->
+
+ <tr><th colspan="2">E-mail sent from the site</th></tr>
+ <tr><td class="row1">E-mail sending method:<br /><small>Try using the built-in e-mail method first. If that doesn't work, you will need to enter valid SMTP information here.</small></td>
+ <td class="row1"><label><input <?php if(getConfig('smtp_enabled') != '1') echo 'checked="checked"'; ?> type="radio" name="emailmethod" value="phpmail" />PHP's built-in mail() function</label><br />
+ <label><input <?php if(getConfig('smtp_enabled') == '1') echo 'checked="checked"'; ?> type="radio" name="emailmethod" value="smtp" />Use an external SMTP server</label></td>
+ </tr>
+ <tr><td class="row2">SMTP hostname:<br /><small>This option only applies to the external SMTP mode.</small></td>
+ <td class="row2"><input value="<?php echo getConfig('smtp_server'); ?>" name="smtp_host" type="text" size="30" /></td>
+ </tr>
+ <tr><td class="row1">SMTP credentials:<br /><small>This option only applies to the external SMTP mode.</small></td>
+ <td class="row1">Username: <input value="<?php echo getConfig('smtp_user'); ?>" name="smtp_user" type="text" size="30" /><br />
+ Password: <input value="<?php if(getConfig('smtp_password') != false) echo 'XXXXXXXXXXXX'; ?>" name="smtp_pass" type="password" size="30" /></td>
+ </tr>
+
+ <!-- SourceForge.net logo -->
+
+ <tr><th colspan="2">SourceForge.net logo</th></tr>
+
+ <tr>
+ <td colspan="2" class="row3">
+ All projects hosted by SourceForge.net are required to display an official SourceForge.net logo on their pages. If you want
+ to display a SourceForge.net logo on the sidebar, check the box below, enter your group ID, and select an image type.
+ </td>
+ </tr>
+
+ <?php
+ if(getConfig("sflogo_enabled")=='1') $c='CHECKED ';
+ else $c='';
+ if(getConfig("sflogo_groupid")) $g=getConfig("sflogo_groupid");
+ else $g='';
+ if(getConfig("sflogo_type")) $t=getConfig("sflogo_type");
+ else $t='1';
+ ?>
+
+ <tr>
+ <td class="row1">Display the SourceForge.net logo on the right sidebar</td>
+ <td class="row1"><input type=checkbox name="showsf" id="showsf" <?php echo $c; ?> /></td>
+ </tr>
+
+ <tr>
+ <td class="row2">Group ID:</td>
+ <td class="row2"><input value="<?php echo $g; ?>" type=text size=15 name=sfgroup /></td>
+ </tr>
+
+ <tr>
+ <td class="row1">Logo style:</td>
+ <td class="row1">
+ <select name="sflogo">
+ <option <?php if($t=='1') echo('SELECTED '); ?>value=1>88x31px, white</option>
+ <option <?php if($t=='2') echo('SELECTED '); ?>value=2>125x37px, white</option>
+ <option <?php if($t=='3') echo('SELECTED '); ?>value=3>125x37px, black</option>
+ <option <?php if($t=='4') echo('SELECTED '); ?>value=4>125x37px, blue</option>
+ <option <?php if($t=='5') echo('SELECTED '); ?>value=5>210x62px, white</option>
+ <option <?php if($t=='6') echo('SELECTED '); ?>value=6>210x62px, black</option>
+ <option <?php if($t=='7') echo('SELECTED '); ?>value=7>210x62px, blue</option>
+ </select>
+ </td>
+ </tr>
+
+ <!-- W3C validator buttons -->
+
+ <tr><th colspan="2">W3C compliance logos</th></tr>
+ <tr><th colspan="2" class="subhead">Enano generates (by default) Valid XHTML 1.1 code, plus valid CSS. If you want to show this off, check the appropriate boxes below.</th></tr>
+
+ <tr><td class="row1"><label for="w3c-vh32">HTML 3.2</label> </td><td class="row1"><input type="checkbox" <?php if(getConfig('w3c_vh32')=='1') echo('CHECKED '); ?> id="w3c-vh32" name="w3c-vh32" /></td></tr>
+ <tr><td class="row2"><label for="w3c-vh40">HTML 4.0</label> </td><td class="row2"><input type="checkbox" <?php if(getConfig('w3c_vh40')=='1') echo('CHECKED '); ?> id="w3c-vh40" name="w3c-vh40" /></td></tr>
+ <tr><td class="row1"><label for="w3c-vh401">HTML 4.01</label> </td><td class="row1"><input type="checkbox" <?php if(getConfig('w3c_vh401')=='1') echo('CHECKED '); ?> id="w3c-vh401" name="w3c-vh401" /></td></tr>
+ <tr><td class="row2"><label for="w3c-vxhtml10">XHTML 1.0</label></td><td class="row2"><input type="checkbox" <?php if(getConfig('w3c_vxhtml10')=='1') echo('CHECKED '); ?> id="w3c-vxhtml10" name="w3c-vxhtml10" /></td></tr>
+ <tr><td class="row1"><label for="w3c-vxhtml11">XHTML 1.1</label></td><td class="row1"><input type="checkbox" <?php if(getConfig('w3c_vxhtml11')=='1') echo('CHECKED '); ?> id="w3c-vxhtml11" name="w3c-vxhtml11" /></td></tr>
+ <tr><td class="row2"><label for="w3c-vcss">CSS</label> </td><td class="row2"><input type="checkbox" <?php if(getConfig('w3c_vcss')=='1') echo('CHECKED '); ?> id="w3c-vcss" name="w3c-vcss" /></td></tr>
+
+ <!-- DefectiveByDesign.org ad -->
+
+ <tr><th colspan="2">Defective By Design Anti-DRM button</th></tr>
+ <tr><td colspan="2" class="row3"><b>The Enano project is strongly against Digital Restrictions Management.</b> DRM removes the freedoms that every consumer should have: to freely copy and use digital media items they legally purchased to their own devices. Showing your opposition to DRM is as easy as checking the box below to place a link to <a href="http://www.defectivebydesign.org">DefectiveByDesign.org</a> on your sidebar.</td></tr>
+ <tr><td class="row1"><label for="dbdbutton">Help stop DRM by placing a link to DBD on the sidebar!</label></td><td class="row1"><input type="checkbox" name="dbdbutton" id="dbdbutton" <?php if(getConfig('dbd_button')=='1') echo('checked="checked" '); ?>/></td></tr>
+
+ <!-- Save button -->
+
+ <tr><th style="text-align: right" class="subhead" colspan="2"><input type=submit name=submit value="Save changes" /></th></tr>
+
+ </table>
+ </div>
+</form>
+ <?php
+}
+
+function page_Admin_UploadConfig()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ if(isset($_POST['save']))
+ {
+ if(isset($_POST['enable_uploads'])) setConfig('enable_uploads', '1'); else setConfig('enable_uploads', '0');
+ if(isset($_POST['enable_imagemagick'])) setConfig('enable_imagemagick', '1'); else setConfig('enable_imagemagick', '0');
+ if(isset($_POST['cache_thumbs'])) setConfig('cache_thumbs', '1'); else setConfig('cache_thumbs', '0');
+ if(isset($_POST['file_history'])) setConfig('file_history', '1'); else setConfig('file_history', '0');
+ if(file_exists($_POST['imagemagick_path'])) setConfig('imagemagick_path', $_POST['imagemagick_path']);
+ else echo '<span style="color: red"><b>Warning:</b> the file "'.$_POST['imagemagick_path'].'" was not found, and the ImageMagick file path was not updated.</span>';
+ $max_upload = floor((float)$_POST['max_file_size'] * (int)$_POST['fs_units']);
+ setConfig('max_file_size', $max_upload.'');
+ }
+ echo '<form name="main" action="'.htmlspecialchars(makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module'])).'" method="post">';
+ ?>
+ <h3>File upload configuration</h3>
+ <p>Enano supports the ability to upload files to your website and store the files in the database. This enables you to embed images
+ and such into pages without manually writing the HTML. However, the upload feature can sometimes pose a risk to your site, as viruses
+ and executable files can sometimes be uploaded.</p>
+ <p><label><input type="checkbox" name="enable_uploads" <?php if(getConfig('enable_uploads')=='1') echo 'checked="checked"'; ?> /> <b>Enable file uploads</b></label></p>
+ <p>Maximum file size: <input name="max_file_size" onkeyup="if(!this.value.match(/^([0-9\.]+)$/ig)) this.value = this.value.substr(0,this.value.length-1);" value="<?php echo getConfig('max_file_size'); ?>" /> <select name="fs_units"><option value="1" selected="selected">bytes</option><option value="1024">KB</option><option value="1048576">MB</option></select></p>
+ <p>You can allow Enano to generate thumbnails of images automatically. This feature requires ImageMagick to work properly. If your server
+ does not have ImageMagick on it, Enano will simply make your users' browsers scale the images. In most cases this is fine, but if you
+ are uploading large (>100KB) images and embedding them inside of pages, you should try to enable ImageMagick because transferring these
+ large images many times can cost you quite a lot of bandwidth.</p>
+ <p><label><input type="checkbox" name="enable_imagemagick" <?php if(getConfig('enable_imagemagick')=='1') echo 'checked="checked"'; ?> /> Use ImageMagick to scale images</label><br />
+ Path to ImageMagick: <input type="text" name="imagemagick_path" value="<?php if(getConfig('imagemagick_path')) echo getConfig('imagemagick_path'); else echo '/usr/bin/convert'; ?>" /><br />
+ On Linux and Unix servers, the most likely options here are /usr/bin/convert and /usr/local/bin/convert. If you server runs Windows, then
+ ImageMagick is most likely to be C:\Windows\Convert.exe or C:\Windows\System32\Convert.exe.
+ </p>
+ <p>If you use ImageMagick to scale images, your server will be very busy constantly scaling images if your website is busy, and your site
+ may experience slowdowns. You can dramatically speed up this scaling process if you use a directory to cache thumbnail images.</p>
+ <p><b>Please note:</b> the cache/ directory on your server <u>must</u> be writable by the server. While this is not usually a problem on
+ Windows servers, most Linux/Unix servers will require you to CHMOD the cache/ directory to 777. See your FTP client's user guide for
+ more information on how to do this.<?php if(!is_writable(ENANO_ROOT.'/cache/')) echo ' <b>At present, it seems that the cache directory
+ is not writable. The checkbox below has been disabled to maintain the stability of Enano.</b>'; ?></p>
+ <p><label><input type="checkbox" name="cache_thumbs" <?php if(getConfig('cache_thumbs')=='1' && is_writable(ENANO_ROOT.'/cache/')) echo 'checked="checked"'; elseif(!is_writable(ENANO_ROOT.'/cache/')) echo 'readonly="readonly"'; ?> /> Cache thumbnailed images</label></p>
+ <p>Lastly, you can choose whether file history will be saved. If this option is turned on, you will be able to roll back any malicious
+ changes made to uploaded files, but this requires a significant amount of database storage. You should probably leave this option
+ enabled unless you have less than 250MB of MySQL database space.</p>
+ <p><label><input type="checkbox" name="file_history" <?php if(getConfig('file_history')=='1' && is_writable(ENANO_ROOT.'/cache/')) echo 'checked="checked"'; ?> /> Keep a history of uploaded files</label></p>
+ <hr style="margin-left: 1em;" />
+ <p><input type="submit" name="save" value="Save changes" style="font-weight: bold;" /></p>
+ <?php
+ echo '</form>';
+}
+
+function page_Admin_PluginManager() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+
+ if(isset($_GET['action'])) {
+ switch($_GET['action']) {
+ case "enable":
+ setConfig('plugin_'.$_GET['plugin'], '1');
+ break;
+ case "disable":
+ if($_GET['plugin']!='admin.php') setConfig('plugin_'.$_GET['plugin'], '0');
+ else echo('<h3>Error disabling plugin</h3><p>The administration panel plugin cannot be disabled.</p>');
+ break;
+ }
+ }
+ $dir = './plugins/';
+ $plugin_list = Array();
+ $system = Array();
+ if (is_dir($dir)) {
+ if ($dh = opendir($dir)) {
+ while (($file = readdir($dh)) !== false) {
+ if(preg_match('#^(.*?)\.php$#is', $file) && $file != 'index.php')
+ {
+ if ( in_array($file, $plugins->system_plugins) )
+ {
+ $thelist =& $system;
+ continue;
+ }
+ else
+ {
+ $thelist =& $plugin_list;
+ }
+ $f = file_get_contents($dir . $file);
+ $f = explode("\n", $f);
+ $f = array_slice($f, 2, 7);
+ $f[0] = substr($f[0], 13, strlen($f[0]));
+ $f[1] = substr($f[1], 12, strlen($f[1]));
+ $f[2] = substr($f[2], 13, strlen($f[2]));
+ $f[3] = substr($f[3], 8, strlen($f[3]));
+ $f[4] = substr($f[4], 9, strlen($f[4]));
+ $f[5] = substr($f[5], 12, strlen($f[5]));
+ $thelist[$file] = Array();
+ $thelist[$file]['name'] = $f[0];
+ $thelist[$file]['uri'] = $f[1];
+ $thelist[$file]['desc'] = $f[2];
+ $thelist[$file]['auth'] = $f[3];
+ $thelist[$file]['vers'] = $f[4];
+ $thelist[$file]['aweb'] = $f[5];
+ }
+ }
+ closedir($dh);
+ }
+ }
+ echo('<div class="tblholder"><table border="0" width="100%" cellspacing="1" cellpadding="4">
+ <tr><th>Plugin filename</th><th>Plugin name</th><th>Description</th><th>Author</th><th>Version</th><th></th></tr>');
+ $plugin_files = array_keys($plugin_list);
+ $cls = 'row2';
+ for ( $i = 0; $i < sizeof($plugin_files); $i++ )
+ {
+ $cls = ( $cls == 'row2' ) ? 'row3' : 'row2';
+ echo '<tr>
+ <td class="'.$cls.'">'.$plugin_files[$i].'</td>
+ <td class="'.$cls.'"><a href="'.$plugin_list[$plugin_files[$i]]['uri'].'">'.$plugin_list[$plugin_files[$i]]['name'].'</a></td>
+ <td class="'.$cls.'">'.$plugin_list[$plugin_files[$i]]['desc'].'</td>
+ <td class="'.$cls.'"><a href="'.$plugin_list[$plugin_files[$i]]['aweb'].'">'.$plugin_list[$plugin_files[$i]]['auth'].'</a></td>
+ <td class="'.$cls.'">'.$plugin_list[$plugin_files[$i]]['vers'].'</td>
+ <td class="'.$cls.'">';
+ if ( getConfig('plugin_'.$plugin_files[$i]) == '1' )
+ {
+ echo '<a href="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'&action=disable&plugin='.$plugin_files[$i].'">Disable</a>';
+ }
+ else
+ {
+ echo '<a href="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'&action=enable&plugin='.$plugin_files[$i].'">Enable</a>';
+ }
+ echo '</td></tr>';
+ }
+ echo '</table></div>';
+}
+
+function page_Admin_UploadAllowedMimeTypes()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ global $mime_types, $mimetype_exps, $mimetype_extlist;
+ if(isset($_POST['save']))
+ {
+ $bits = '';
+ $keys = array_keys($mime_types);
+ foreach($keys as $i => $k)
+ {
+ if(isset($_POST['ext_'.$k])) $bits .= '1';
+ else $bits .= '0';
+ }
+ $bits = compress_bitfield($bits);
+ setConfig('allowed_mime_types', $bits);
+ echo '<div class="info-box">Your changes have been saved.</div>';
+ }
+ $allowed = fetch_allowed_extensions();
+ ?>
+ <h3>Allowed file types</h3>
+ <p>Using the form below, you can decide which file types are allowed to be uploaded to this site.</p>
+ <?php
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', (( isset($_GET['sqldbg'])) ? 'sqldbg&' : '') .'module='.$paths->cpage['module']).'" method="post">';
+ $c = -1;
+ $t = -1;
+ $cl = 'row1';
+ echo "\n".' <div class="tblholder">'."\n".' <table cellspacing="1" cellpadding="2" style="margin: 0; padding: 0;" border="0">'."\n".' <tr>'."\n ";
+ foreach($mime_types as $e => $m)
+ {
+ $c++;
+ $t++;
+ if($c == 3)
+ {
+ $c = 0;
+ $cl = ( $cl == 'row1' ) ? 'row2' : 'row1';
+ echo '</tr>'."\n".' <tr>'."\n ";
+ }
+ $seed = "extchkbx_{$e}_".md5(microtime() . mt_rand());
+ $chk = (!empty($allowed[$e])) ? ' checked="checked"' : '';
+ echo " <td class='$cl'>\n <label><input id='{$seed}' type='checkbox' name='ext_{$e}'{$chk} />.{$e}\n ({$m})</label>\n </td>\n ";
+ }
+ while($c < 2)
+ {
+ $c++;
+ echo " <td class='{$cl}'></td>\n ";
+ }
+ echo '<tr><th class="subhead" colspan="3"><input type="submit" name="save" value="Save changes" /></th></tr>';
+ echo '</tr>'."\n".' </table>'."\n".' </div>';
+ echo '</form>';
+ ?>
+ <?php
+}
+
+function page_Admin_Sidebar()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ ?>
+ <h2>Editing and managing the Enano sidebar</h2>
+ <p>The Enano sidebar is a versatile tool when scripted correctly. You don't have to be a programmer to enjoy the features the Sidebar
+ provides; however, editing the sidebar requires a small bit of programming knowledge and an understanding of Enano's system message
+ markup language.
+ </p>
+ <p>The Enano system markup language is somewhat similar to HTML, in that it uses tags (<example>like this</example>) for the
+ main syntax. However, Enano uses curly brackets ({ and }) as opposed to less-than and greater-than signs (< and >).</p>
+ <p>Programming the Enano sidebar requires the use of two tags: {slider} and {if}. The {slider} tag is used to create a new heading
+ on the sidebar, and all text enclosed in that tag will be collapsed when the heading is clicked. To specify the text on the heading,
+ use an equals sign (=) after the "slider" text. Then insert any links (they should be wiki-formatted) to internal Enano pages and
+ external sites.</p>
+ <p>So here is what the language for the default sidebar's "Navigation" heading looks like:</p>
+ <pre>{slider=Navigation}
+ [[Main Page|Home]]
+ [[Enano:Sidebar|Edit the sidebar]]
+{/slider}</pre>
+ <p>Pretty simple, huh? Good, now we're going to learn another common aspect of Enano programming: conditionals. The {if} tag allows you
+ to decide whether a portion of the sidebar will be displayed based on a template variable. Currently the only available conditions are
+ "user_logged_in" and "auth_admin", but more will be added soon. To use a conditional, enter {if conditional_name}, and then the
+ wiki-formatted text that you want to be under that condition, and then close the tag with {/if}. In the same way, you can reverse the
+ effect with {!if}. With {!if}, the closing tag is still {/if}, so keep that in mind. An {else} tag will be supported soon.</p>
+ <p>Now it's time for some real fun: variables. All template variables can be accessed from the sidebar. A variable is simply the
+ variable name, prefixed by a dollar sign ($). Some of the most common variables are $USERNAME, $SITE_NAME, $SITE_DESC, and $PAGE_NAME.
+ The sidebar also has some special variables that it uses for some of its links. The logout link can be added with $LOGOUT_LINK, and
+ the "change theme" button can be added with $STYLE_LINK.</p>
+ <p>So here is the Enano markup for the portion of the sidebar that contains the user tools:</p>
+ <pre>{slider=$USERNAME}
+ [[User:$USERNAME|User page]]
+ [[Special:Contributions?user=$USERNAME|My Contributions]]
+ {if user_logged_in}
+ [[Special:Preferences|Preferences]]
+ $THEME_LINK
+ {/if}
+ {if auth_admin}
+ [[Special:Administration|Administration]]
+ {/if}
+ {if user_logged_in}
+ $LOGOUT_LINK
+ {/if}
+ {!if user_logged_in}
+ Create an account
+ Log in
+ {/if}
+{/slider}</pre>
+ <?php
+}
+
+function page_Admin_UserManager() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ if(isset($_POST['go'])) {
+ // We need the user ID before we can do anything
+ $q = $db->sql_query('SELECT user_id,username,email,real_name,style,user_level FROM '.table_prefix.'users WHERE username=\'' . $db->escape($_POST['username']) . '\'');
+ if(!$q) die('Error selecting user ID: '.mysql_error());
+ if($db->numrows() < 1) { echo('User does not exist, please enter another username.'); return; }
+ $r = $db->fetchrow();
+ $db->free_result();
+ if(isset($_POST['save']))
+ {
+ $_POST['level'] = intval($_POST['level']);
+
+ $new_level = $_POST['level'];
+ $old_level = intval($r['user_level']);
+
+ $re = $session->update_user((int)$r['user_id'], $_POST['new_username'], false, $_POST['new_pass'], $_POST['email'], $_POST['real_name'], false, $_POST['level']);
+
+ if($re == 'success')
+ {
+
+ if ( $new_level != $old_level )
+ {
+ $user_id = intval($r['user_id']);
+ // We need to update group memberships
+ if ( $old_level == USER_LEVEL_ADMIN )
+ {
+ $session->remove_user_from_group($user_id, GROUP_ID_ADMIN);
+ }
+ else if ( $old_level == USER_LEVEL_MOD )
+ {
+ $session->remove_user_from_group($user_id, GROUP_ID_MOD);
+ }
+
+ if ( $new_level == USER_LEVEL_ADMIN )
+ {
+ $session->add_user_to_group($user_id, GROUP_ID_ADMIN, false);
+ }
+ else if ( $new_level == USER_LEVEL_MOD )
+ {
+ $session->add_user_to_group($user_id, GROUP_ID_MOD, false);
+ }
+ }
+
+ echo('<div class="info-box">Your changes have been saved.</div>');
+ }
+ else
+ {
+ echo('<div class="error-box">Error saving changes: '.implode('<br />', $re).'</div>');
+ }
+ $q = $db->sql_query('SELECT user_id,username,email,real_name,style,user_level FROM '.table_prefix.'users WHERE username=\''.$db->escape($_POST['username']).'\'');
+ if ( !$q )
+ {
+ die('Error selecting user ID: '.mysql_error());
+ }
+ if($db->numrows($q) < 1)
+ {
+ die('User does not exist, please enter another username.');
+ }
+ $r = mysql_fetch_object($q);
+ $db->free_result();
+ }
+ elseif(isset($_POST['deleteme']) && isset($_POST['delete_conf']))
+ {
+ $q = $db->sql_query('DELETE FROM users WHERE user_id='.$r['user_id'].';');
+ if($q)
+ {
+ echo '<div class="error-box">The user account "'.$r['username'].'" was deleted.</div>';
+ }
+ else
+ {
+ echo '<div class="error-box">The user account "'.$r['username'].'" could not be deleted due to a database error.<br /><br />'.$db->get_error().'</div>';
+ }
+ }
+ else
+ {
+ echo('
+ <h3>Edit User Info</h3>
+ <form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post">
+ <table border="0" style="margin-left: 0.2in;">
+ <tr><td>Username:</td><td><input type="text" name="new_username" value="'.$r['username'].'" /></td></tr>
+ <tr><td>New Password:</td><td><input type="password" name="new_pass" /></td></tr>
+ <tr><td>E-mail:</td><td><input type="text" name="email" value="'.$r['email'].'" /></td></tr>
+ <tr><td>Real Name:</td><td><input type="text" name="real_name" value="'.$r['real_name'].'" /></td></tr>
+ <tr><td>User level:</td><td><select name="level"><option '); if($r['user_level']==USER_LEVEL_CHPREF) echo('SELECTED'); echo(' value="'.USER_LEVEL_CHPREF.'">Regular User</option><option '); if($r['user_level']==USER_LEVEL_MOD) echo('SELECTED'); echo(' value="'.USER_LEVEL_MOD.'">Moderator</option><option '); if($r['user_level']==USER_LEVEL_ADMIN) echo('SELECTED'); echo(' value="'.USER_LEVEL_ADMIN.'">Administrator</option></select></td></tr>
+ <tr><td>Delete user:</td><td><input type="hidden" name="go" /><input type="hidden" name="username" value="'.$r['username'].'" /><input onclick="return confirm(\'This is your last warning.\n\nAre you sure you want to delete this user account? Even if you delete this user account, the username will be shown in page edit history, comments, and other areas of the site.\n\nDeleting a user account CANNOT BE UNDONE and should only be done in extreme circumstances.\n\nIf the user has violated the site policy, deleting the account will not prevent him from using the site, for that you need to add a new ban rule.\n\nContinue deleting this user account?\')" type="submit" name="deleteme" value="Delete this user" style="color: red;" /> <label><input type="checkbox" name="delete_conf" /> I\'m absolutely sure</label>
+ <tr><td align="center" colspan="2">
+ <input type="submit" name="save" value="Save Changes" /></td></tr>
+ </table>
+ </form>
+ ');
+ }
+ } elseif(isset($_POST['clearsessions'])) {
+ // Get the current session information so the user doesn't get logged out
+ $aes = new AESCrypt();
+ $sk = md5($session->sid_super);
+ $qb = $db->sql_query('SELECT session_key,salt,auth_level,source_ip,time FROM '.table_prefix.'session_keys WHERE session_key=\''.$sk.'\' AND user_id='.$session->user_id.' AND auth_level='.USER_LEVEL_ADMIN);
+ if(!$qb) die('Error selecting session key info block B: '.$db->get_error());
+ if($db->numrows($qb) < 1) die('Error: cannot read admin session info block B, aborting table clear process');
+ $qa = $db->sql_query('SELECT session_key,salt,auth_level,source_ip,time FROM '.table_prefix.'session_keys WHERE session_key=\''.md5($session->sid).'\' AND user_id='.$session->user_id.' AND auth_level='.USER_LEVEL_MEMBER);
+ if(!$qa) die('Error selecting session key info block A: '.$db->get_error());
+ if($db->numrows($qa) < 1) die('Error: cannot read user session info block A, aborting table clear process');
+ $ra = mysql_fetch_object($qa);
+ $rb = mysql_fetch_object($qb);
+ $db->free_result($qa);
+ $db->free_result($qb);
+ $db->sql_query('DELETE FROM '.table_prefix.'session_keys;');
+ $db->sql_query('INSERT INTO '.table_prefix.'session_keys( session_key,salt,user_id,auth_level,source_ip,time ) VALUES( \''.$ra->session_key.'\', \''.$ra->salt.'\', \''.$session->user_id.'\', \''.$ra->auth_level.'\', \''.$ra->source_ip.'\', '.$ra->time.' ),( \''.$rb->session_key.'\', \''.$rb->salt.'\', \''.$session->user_id.'\', \''.$rb->auth_level.'\', \''.$rb->source_ip.'\', '.$rb->time.' )');
+ echo('
+ <div class="info-box">The session key table has been cleared. Your database should be a little bit smaller now.</div>
+ ');
+ }
+ echo('
+ <h3>User Management</h3>
+ <form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;">
+ <p>Username: '.$template->username_field('username').' <input type="submit" name="go" value="Go" /></p>
+ <h3>Clear session keys table</h3>
+ <p>It\'s a good idea to clean out your session keys table every once in a while, since this helps to reduce database size. During this process you will be logged off and (hopefully) logged back on automatically. The side effects of this include all users except you being logged off.</p>
+ <p><input type="submit" name="clearsessions" value="Clear session keys table" /></p>
+ </form>
+ ');
+ if(isset($_GET['action']) && isset($_GET['user']))
+ {
+ switch($_GET['action'])
+ {
+ case "activate":
+ $e = $db->sql_query('SELECT activation_key FROM '.table_prefix.'users WHERE username=\'' . $db->escape($_GET['user']) . '\'');
+ if($e)
+ {
+ $row = $db->fetchrow();
+ $db->free_result();
+ if($session->activate_account($_GET['user'], $row['activation_key'])) { echo '<div class="info-box">The user account "'.$_GET['user'].'" has been activated.</div>'; $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE time_id=' . $db->escape($_GET['logid'])); }
+ else echo '<div class="warning-box">The user account "'.$_GET['user'].'" has NOT been activated, possibly because the account is already active.</div>';
+ } else echo '<div class="error-box">Error activating account: '.mysql_error().'</div>';
+ break;
+ case "sendemail":
+ if($session->send_activation_mail($_GET['user'])) { echo '<div class="info-box">The user "'.$_GET['user'].'" has been sent an e-mail with an activation link.</div>'; $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE time_id=' . $db->escape($_GET['logid'])); }
+ else echo '<div class="error-box">The user account "'.$_GET['user'].'" has not been activated, probably because of a bad SMTP configuration.</div>';
+ break;
+ case "deny":
+ $e = $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE log_type=\'admin\' AND action=\'activ_req\' AND edit_summary=\'' . $db->escape($_GET['user']) . '\';');
+ if(!$e) echo '<div class="error-box">Error during row deletion: '.mysql_error().'</div>';
+ else echo '<div class="info-box">All activation requests for the user "'.$_GET['user'].'" have been deleted.</div>';
+ break;
+ }
+ }
+ $q = $db->sql_query('SELECT log_type, action, time_id, date_string, author, edit_summary FROM '.table_prefix.'logs WHERE log_type=\'admin\' AND action=\'activ_req\' ORDER BY time_id DESC;');
+ if($q)
+ {
+ if($db->numrows() > 0)
+ {
+ $n = $db->numrows();
+ if($n == 1) $s = $n . ' user is';
+ else $s = $n . ' users are';
+ echo '<h3>'.$s . ' awaiting account activation</h3>';
+ echo '<div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4" width="100%">
+ <tr><th>Date of request</th><th>Requested by</th><th>Requested for</th><th colspan="3">Actions</th></tr>';
+ $cls = 'row2';
+ while($row = $db->fetchrow())
+ {
+ if($cls == 'row2') $cls = 'row1';
+ else $cls = 'row2';
+ echo '<tr><td class="'.$cls.'">'.date('F d, Y h:i a', $row['time_id']).'</td><td class="'.$cls.'">'.$row['author'].'</td><td class="'.$cls.'">'.$row['edit_summary'].'</td><td class="'.$cls.'" style="text-align: center;"><a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'UserManager&action=activate&user='.$row['edit_summary'].'&logid='.$row['time_id']).'">Activate now</a></td><td class="'.$cls.'" style="text-align: center;"><a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'UserManager&action=sendemail&user='.$row['edit_summary'].'&logid='.$row['time_id']).'">Send activation e-mail</a></td><td class="'.$cls.'" style="text-align: center;"><a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'UserManager&action=deny&user='.$row['edit_summary'].'&logid='.$row['time_id']).'">Deny request</a></td></tr>';
+ }
+ echo '</table>';
+ }
+ $db->free_result();
+ }
+}
+
+function page_Admin_GroupManager()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ if(isset($_POST['do_create_stage1']))
+ {
+ if(!preg_match('/^([A-z0-9 -]+)$/', $_POST['create_group_name']))
+ {
+ echo '<p>The group name you chose is invalid.</p>';
+ return;
+ }
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;" enctype="multipart/form-data">';
+ echo '<div class="tblholder">
+ <table border="0" style="width:100%;" cellspacing="1" cellpadding="4">
+ <tr><th colspan="2">Creating group: '.$_POST['create_group_name'].'</th></tr>
+ <tr>
+ <td class="row1">Group moderator</td><td class="row1">' . $template->username_field('group_mod') . '</td>
+ </tr>
+ <tr><td class="row2">Group status</td><td class="row2">
+ <label><input type="radio" name="group_status" value="'.GROUP_CLOSED.'" checked="checked" /> Closed to new members</label><br />
+ <label><input type="radio" name="group_status" value="'.GROUP_REQUEST.'" /> Members can ask to be added</label><br />
+ <label><input type="radio" name="group_status" value="'.GROUP_OPEN.'" /> Members can join freely</label><br />
+ <label><input type="radio" name="group_status" value="'.GROUP_HIDDEN.'" /> Group is hidden</label>
+ </td></tr>
+ <tr>
+ <th class="subhead" colspan="2">
+ <input type="hidden" name="create_group_name" value="'.$_POST['create_group_name'].'" />
+ <input type="submit" name="do_create_stage2" value="Create group" />
+ </th>
+ </tr>
+ </table>
+ </div>';
+ echo '</form>';
+ return;
+ }
+ elseif(isset($_POST['do_create_stage2']))
+ {
+ if(!preg_match('/^([A-z0-9 -]+)$/', $_POST['create_group_name']))
+ {
+ echo '<p>The group name you chose is invalid.</p>';
+ return;
+ }
+ if(!in_array(intval($_POST['group_status']), Array(GROUP_CLOSED, GROUP_OPEN, GROUP_HIDDEN, GROUP_REQUEST)))
+ {
+ echo '<p>Hacking attempt</p>';
+ return;
+ }
+ $e = $db->sql_query('SELECT group_id FROM '.table_prefix.'groups WHERE group_name=\''.$db->escape($_POST['create_group_name']).'\';');
+ if(!$e)
+ {
+ echo $db->get_error();
+ return;
+ }
+ if($db->numrows() > 0)
+ {
+ echo '<p>The group name you entered already exists.</p>';
+ return;
+ }
+ $db->free_result();
+ $q = $db->sql_query('INSERT INTO '.table_prefix.'groups(group_name,group_type) VALUES( \''.$db->escape($_POST['create_group_name']).'\', ' . intval($_POST['group_status']) . ' )');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ $e = $db->sql_query('SELECT user_id FROM '.table_prefix.'users WHERE username=\''.$db->escape($_POST['group_mod']).'\';');
+ if(!$e)
+ {
+ echo $db->get_error();
+ return;
+ }
+ if($db->numrows() < 1)
+ {
+ echo '<p>The username you entered could not be found.</p>';
+ return;
+ }
+ $row = $db->fetchrow();
+ $id = $row['user_id'];
+ $db->free_result();
+ $e = $db->sql_query('SELECT group_id FROM '.table_prefix.'groups WHERE group_name=\''.$db->escape($_POST['create_group_name']).'\';');
+ if(!$e)
+ {
+ echo $db->get_error();
+ return;
+ }
+ if($db->numrows() < 1)
+ {
+ echo '<p>The group ID could not be looked up.</p>';
+ return;
+ }
+ $row = $db->fetchrow();
+ $gid = $row['group_id'];
+ $db->free_result();
+ $e = $db->sql_query('INSERT INTO '.table_prefix.'group_members(group_id,user_id,is_mod) VALUES('.$gid.', '.$id.', 1);');
+ if(!$e)
+ {
+ echo $db->get_error();
+ return;
+ }
+ echo "<div class='info-box'>
+ <b>Information</b><br />
+ The group {$_POST['create_group_name']} has been created successfully.
+ </div>";
+ }
+ if(isset($_POST['do_edit']) || isset($_POST['edit_do']))
+ {
+ // Fetch the group name
+ $q = $db->sql_query('SELECT group_name,system_group FROM '.table_prefix.'groups WHERE group_id='.intval($_POST['group_edit_id']).';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ if($db->numrows() < 1)
+ {
+ echo '<p>Error: couldn\'t look up group name</p>';
+ }
+ $row = $db->fetchrow();
+ $name = $row['group_name'];
+ $db->free_result();
+ if(isset($_POST['edit_do']))
+ {
+ if(isset($_POST['edit_do']['del_group']))
+ {
+ if ( $row['system_group'] == 1 )
+ {
+ echo '<div class="error-box">The group "' . $name . '" could not be deleted because it is a system group required for site functionality.</div>';
+ }
+ else
+ {
+ $q = $db->sql_query('DELETE FROM '.table_prefix.'group_members WHERE group_id='.intval($_POST['group_edit_id']).';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ $q = $db->sql_query('DELETE FROM '.table_prefix.'groups WHERE group_id='.intval($_POST['group_edit_id']).';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ echo '<div class="info-box">The group "'.$name.'" has been deleted. Return to the <a href="javascript:ajaxPage(\'Admin:GroupManager\');">group manager</a>.</div>';
+ return;
+ }
+ }
+ if(isset($_POST['edit_do']['save_name']))
+ {
+ if(!preg_match('/^([A-z0-9 -]+)$/', $_POST['group_name']))
+ {
+ echo '<p>The group name you chose is invalid.</p>';
+ return;
+ }
+ $q = $db->sql_query('UPDATE '.table_prefix.'groups SET group_name=\''.$db->escape($_POST['group_name']).'\'
+ WHERE group_id='.intval($_POST['group_edit_id']).';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ else
+ {
+ echo '<div class="info-box" style="margin: 0 0 10px 0;"">
+ The group name has been updated.
+ </div>';
+ }
+ $name = $_POST['group_name'];
+
+ }
+ $q = $db->sql_query('SELECT member_id FROM '.table_prefix.'group_members
+ WHERE group_id='.intval($_POST['group_edit_id']).';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ if($db->numrows() > 0)
+ {
+ while($row = $db->fetchrow($q))
+ {
+ if(isset($_POST['edit_do']['del_' . $row['member_id']]))
+ {
+ $e = $db->sql_query('DELETE FROM '.table_prefix.'group_members WHERE member_id='.$row['member_id']);
+ if(!$e)
+ {
+ echo $db->get_error();
+ return;
+ }
+ }
+ }
+ }
+ $db->free_result();
+ if(isset($_POST['edit_do']['add_member']))
+ {
+ $q = $db->sql_query('SELECT user_id FROM '.table_prefix.'users WHERE username=\''.$db->escape($_POST['edit_add_username']).'\';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ if($db->numrows() > 0)
+ {
+ $row = $db->fetchrow();
+ $user_id = $row['user_id'];
+ $is_mod = ( isset( $_POST['add_mod'] ) ) ? '1' : '0';
+ $q = $db->sql_query('INSERT INTO '.table_prefix.'group_members(group_id,user_id,is_mod) VALUES('.intval($_POST['group_edit_id']).','.$user_id.','.$is_mod.');');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ else
+ {
+ echo '<div class="info-box" style="margin: 0 0 10px 0;"">
+ The user "'.$_POST['edit_add_username'].'" has been added to this usergroup.
+ </div>';
+ }
+ }
+ else
+ echo '<div class="warning-box"><b>The user "'.$_POST['edit_add_username'].'" could not be added.</b><br />This username does not exist.</div>';
+ }
+ }
+ $sg_disabled = ( $row['system_group'] == 1 ) ? ' value="Can\'t delete system group" disabled="disabled" style="color: #FF9773" ' : ' value="Delete this group" style="color: #FF3713" ';
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;" enctype="multipart/form-data">';
+ echo '<div class="tblholder">
+ <table border="0" style="width:100%;" cellspacing="1" cellpadding="4">
+ <tr><th>Edit group name</th></tr>
+ <tr>
+ <td class="row1">
+ Group name: <input type="text" name="group_name" value="'.$name.'" />
+ </td>
+ </tr>
+ <tr>
+ <th class="subhead">
+ <input type="submit" name="edit_do[save_name]" value="Save name" />
+ <input type="submit" name="edit_do[del_group]" '.$sg_disabled.' />
+ </th>
+ </tr>
+ </table>
+ </div>
+ <input type="hidden" name="group_edit_id" value="'.$_POST['group_edit_id'].'" />';
+ echo '</form>';
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;" enctype="multipart/form-data">';
+ echo '<div class="tblholder">
+ <table border="0" style="width:100%;" cellspacing="1" cellpadding="4">
+ <tr><th colspan="3">Edit group members</th></tr>';
+ $q = $db->sql_query('SELECT m.member_id,m.is_mod,u.username FROM '.table_prefix.'group_members AS m
+ LEFT JOIN '.table_prefix.'users AS u
+ ON u.user_id=m.user_id
+ WHERE m.group_id='.intval($_POST['group_edit_id']).'
+ ORDER BY m.is_mod DESC, u.username ASC;');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ if($db->numrows() < 1)
+ {
+ echo '<tr><td colspan="3" class="row1">This group has no members.</td></tr>';
+ }
+ else
+ {
+ $cls = 'row2';
+ while($row = $db->fetchrow())
+ {
+ $cls = ( $cls == 'row1' ) ? 'row2' : 'row1';
+ $mod = ( $row['is_mod'] == 1 ) ? 'Mod' : '';
+ echo '<tr>
+ <td class="'.$cls.'" style="width: 100%;">
+ ' . $row['username'] . '
+ </td>
+ <td class="'.$cls.'">
+ '.$mod.'
+ </td>
+ <td class="'.$cls.'">
+ <input type="submit" name="edit_do[del_'.$row['member_id'].']" value="Remove member" />
+ </td>
+ </tr>';
+ }
+ }
+ $db->free_result();
+ echo '</table>
+ </div>
+ <input type="hidden" name="group_edit_id" value="'.$_POST['group_edit_id'].'" />';
+ echo '</form>';
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;" enctype="multipart/form-data">';
+ echo '<div class="tblholder">
+ <table border="0" style="width:100%;" cellspacing="1" cellpadding="4">
+ <tr>
+ <th>Add a new member</th>
+ </tr>
+ <tr>
+ <td class="row1">
+ Username: ' . $template->username_field('edit_add_username') . '
+ </td>
+ </tr>
+ <tr>
+ <td class="row2">
+ <label><input type="checkbox" name="add_mod" /> Is a group moderator</label> (can add and delete other members)
+ </td>
+ </tr>
+ <tr>
+ <th class="subhead">
+ <input type="submit" name="edit_do[add_member]" value="Add user to group" />
+ </th>
+ </tr>
+ </table>
+ </div>
+ <input type="hidden" name="group_edit_id" value="'.$_POST['group_edit_id'].'" />';
+ echo '</form>';
+ return;
+ }
+ echo '<h3>Manage Usergroups</h3>';
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;" enctype="multipart/form-data">';
+ $q = $db->sql_query('SELECT group_id,group_name FROM '.table_prefix.'groups ORDER BY group_name ASC;');
+ if(!$q)
+ {
+ echo $db->get_error();
+ }
+ else
+ {
+ echo '<div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4" style="width: 100%;">
+ <tr>
+ <th>Edit an existing group</th>
+ </tr>';
+ echo '<tr><td class="row2"><select name="group_edit_id">';
+ while ( $row = $db->fetchrow() )
+ {
+ if ( $row['group_name'] != 'Everyone' )
+ {
+ echo '<option value="' . $row['group_id'] . '">' . htmlspecialchars( $row['group_name'] ) . '</option>';
+ }
+ }
+ $db->free_result();
+ echo '</select></td></tr>';
+ echo '<tr><td class="row1" style="text-align: center;"><input type="submit" name="do_edit" value="Edit group" /></td></tr>
+ </table>
+ </div>
+ </form><br />';
+ }
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;" enctype="multipart/form-data">';
+ echo '<div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4" style="width: 100%;">
+ <tr>
+ <th colspan="2">Create a new group</th>
+ </tr>';
+ echo '<tr><td class="row2">Group name:</td><td class="row2"><input type="text" name="create_group_name" /></td></tr>';
+ echo '<tr><td colspan="2" class="row1" style="text-align: center;"><input type="submit" name="do_create_stage1" value="Continue >" /></td></tr>
+ </table>
+ </div>';
+ echo '</form>';
+}
+
+function page_Admin_PageManager()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+
+ echo '<h2>Page management</h2>';
+
+ if(isset($_POST['search']) || isset($_POST['select']) || ( isset($_GET['source']) && $_GET['source'] == 'ajax' )) {
+ // The object of the game: using only the text a user entered, guess the page ID and namespace. *sigh* I HATE writing search algorithms...
+ $source = ( isset($_GET['source']) ) ? $_GET['source'] : false;
+ if ( $source == 'ajax' )
+ {
+ $_POST['search'] = true;
+ $_POST['page_url'] = $_GET['page_id'];
+ }
+ if(isset($_POST['search'])) $pid = $_POST['page_url'];
+ elseif(isset($_POST['select'])) $pid = $_POST['page_force_url'];
+ else { echo 'Internal error selecting page search terms'; return false; }
+ // Look for a namespace prefix in the urlname, and assign a different namespace, if necessary
+ $k = array_keys($paths->nslist);
+ for($i=0;$i<sizeof($paths->nslist);$i++)
+ {
+ $ln = strlen($paths->nslist[$k[$i]]);
+ if(substr($pid, 0, $ln) == $paths->nslist[$k[$i]])
+ {
+ $ns = $k[$i];
+ $page_id = substr($pid, $ln, strlen($pid));
+ }
+ }
+ // The namespace is in $ns and the page name or ID (we don't know which yet) is in $page_id
+ // Now, iterate through $paths->pages searching for a page with this name or ID
+ for($i=0;$i<sizeof($paths->pages)/2;$i++)
+ {
+ if(!isset($final_pid))
+ {
+ if ($paths->pages[$i]['urlname_nons'] == str_replace(' ', '_', $page_id)) $final_pid = str_replace(' ', '_', $page_id);
+ elseif($paths->pages[$i]['name'] == $page_id) $final_pid = $paths->pages[$i]['urlname_nons'];
+ elseif(strtolower($paths->pages[$i]['urlname_nons']) == strtolower(str_replace(' ', '_', $page_id))) $final_pid = $paths->pages[$i]['urlname_nons'];
+ elseif(strtolower($paths->pages[$i]['name']) == strtolower(str_replace('_', ' ', $page_id))) $final_pid = $paths->pages[$i]['urlname_nons'];
+ if(isset($final_pid)) { $_POST['name'] = $paths->pages[$i]['name']; $_POST['urlname'] = $paths->pages[$i]['urlname_nons']; }
+ }
+ }
+ if(!isset($final_pid)) { echo 'The page you searched for cannot be found. <a href="#" onclick="ajaxPage(\''.$paths->nslist['Admin'].'PageManager\'); return false;">Back</a>'; return false; }
+ $_POST['namespace'] = $ns;
+ $_POST['old_namespace'] = $ns;
+ $_POST['page_id'] = $final_pid;
+ $_POST['old_page_id'] = $final_pid;
+ if(!isset($paths->pages[$paths->nslist[$_POST['namespace']].$_POST['urlname']])) { echo 'The page you searched for cannot be found. <a href="#" onclick="ajaxPage(\''.$paths->nslist['Admin'].'PageManager\'); return false;">Back</a>'; return false; }
+ }
+
+ if(isset($_POST['page_id']) && isset($_POST['namespace']) && !isset($_POST['cancel']))
+ {
+ $cpage = $paths->pages[$paths->nslist[$_POST['namespace']].$_POST['old_page_id']];
+ if(isset($_POST['submit']))
+ {
+ // Create a list of things to update
+ $page_info = Array(
+ 'name'=>$_POST['name'],
+ 'urlname'=>$_POST['page_id'],
+ 'namespace'=>$_POST['namespace'],
+ 'special'=>isset($_POST['special']) ? '1' : '0',
+ 'visible'=>isset($_POST['visible']) ? '1' : '0',
+ 'comments_on'=>isset($_POST['comments_on']) ? '1' : '0',
+ 'protected'=>isset($_POST['protected']) ? '1' : '0'
+ );
+ // Build the query
+ $q = 'UPDATE '.table_prefix.'pages SET ';
+ $k = array_keys($page_info);
+ foreach($k as $c)
+ {
+ $q .= $c.'=\''.$db->escape($page_info[$c]).'\',';
+ }
+ $q = substr($q, 0, strlen($q)-1);
+ // Build the WHERE statements
+ $q .= ' WHERE ';
+ $k = array_keys($cpage);
+ foreach($k as $c)
+ {
+ if($c != 'urlname_nons' && $c != 'urlname' && $c != 'really_protected') $q .= $c.'=\''.$cpage[$c].'\' AND ';
+ elseif($c == 'urlname') $q .= $c.'=\''.$cpage['urlname_nons'].'\' AND ';
+ }
+ $q = substr($q, 0, strlen($q)-5) . ';';
+ // Send the completed query to MySQL
+ $e = $db->sql_query($q);
+ if(!$e) $db->_die('The page data could not be updated.');
+ // Update any additional tables
+ $q = Array(
+ 'UPDATE '.table_prefix.'categories SET page_id=\''.$page_info['urlname'].'\',namespace=\''.$page_info['namespace'].'\' WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';',
+ 'UPDATE '.table_prefix.'comments SET page_id=\''.$page_info['urlname'].'\',namespace=\''.$page_info['namespace'].'\' WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';',
+ 'UPDATE '.table_prefix.'logs SET page_id=\''.$page_info['urlname'].'\',namespace=\''.$page_info['namespace'].'\' WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';',
+ 'UPDATE '.table_prefix.'page_text SET page_id=\''.$page_info['urlname'].'\',namespace=\''.$page_info['namespace'].'\' WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';',
+ );
+ foreach($q as $cq)
+ {
+ $e = $db->sql_query($cq);
+ if(!$e) $db->_die('Some of the additional tables containing page information could not be updated.');
+ }
+ // Update $cpage
+ $cpage = $page_info;
+ $cpage['urlname_nons'] = $cpage['urlname'];
+ $cpage['urlname'] = $paths->nslist[$cpage['namespace']].$cpage['urlname'];
+ $_POST['old_page_id'] = $page_info['urlname'];
+ $_POST['old_namespace'] = $page_info['namespace'];
+ echo '<div class="info-box">Your changes have been saved.</div>';
+ } elseif(isset($_POST['delete'])) {
+ $q = Array(
+ 'DELETE FROM '.table_prefix.'categories WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';',
+ 'DELETE FROM '.table_prefix.'comments WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';',
+ 'DELETE FROM '.table_prefix.'logs WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';',
+ 'DELETE FROM '.table_prefix.'page_text WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';',
+ );
+ foreach($q as $cq)
+ {
+ $e = $db->sql_query($cq);
+ if(!$e) $db->_die('Some of the additional tables containing page information could not be updated.');
+ }
+
+ if(!$db->sql_query(
+ 'DELETE FROM '.table_prefix.'pages WHERE urlname="'.$db->escape($_POST['old_page_id']).'" AND namespace="'.$db->escape($_POST['old_namespace']).'";'
+ )) $db->_die('The page could not be deleted.');
+ echo '<div class="info-box">This page has been deleted.</p><p><a href="javascript:ajaxPage(\''.$paths->nslist['Admin'].'PageManager\');">Return to Page manager</a><br /><a href="javascript:ajaxPage(\''.$paths->nslist['Admin'].'Home\');">Admin home</a></div>';
+ return;
+ }
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration'.htmlspecialchars(urlSeparator).(( isset($_GET['sqldbg']) ) ? 'sqldbg&' : '') .'module='.$paths->cpage['module']).'" method="post">';
+ ?>
+ <h3>Modify page: <?php echo $_POST['name']; ?></h3>
+ <table border="0">
+ <tr><td>Namespace:</td><td><select name="namespace"><?php $nm = array_keys($paths->nslist); foreach($nm as $ns) { if($ns != 'Special' && $ns != 'Admin') { echo '<option '; if($_POST['namespace']==$ns) echo 'selected="selected" '; echo 'value="'.$ns.'">'; if($paths->nslist[$ns] == '') echo '[No prefix]'; else echo $paths->nslist[$ns]; echo '</option>'; } } ?></select></td></tr>
+ <tr><td>Page title:</td><td><input type="text" name="name" value="<?php echo $cpage['name']; ?>" /></td></tr>
+ <tr><td>Page URL string:<br /><small>No spaces, and don't enter the namespace prefix (e.g. User:).<br />Changing this value is usually not a good idea, especially for templates and project pages.</small></td><td><input type="text" name="page_id" value="<?php echo $cpage['urlname_nons']; ?>" /></td></tr>
+ <tr><td></td><td><input <?php if($cpage['comments_on']) echo 'checked="checked"'; ?> name="comments_on" type="checkbox" id="cmt" /> <label for="cmt">Enable comments for this page</label></td></tr>
+ <tr><td></td><td><input <?php if($cpage['special']) echo 'checked="checked"'; ?> name="special" type="checkbox" id="spc" /> <label for="spc">Bypass the template engine for this page</label><br /><small>This option enables you to use your own HTML headers and other code. It is recommended that only advanced users enable this feature. As with other Enano pages, you may use PHP code in your pages, meaning you can use Enano's API on the page.</small></td></tr>
+ <tr><td></td><td><input <?php if($cpage['visible']) echo 'checked="checked"'; ?> name="visible" type="checkbox" id="vis" /> <label for="vis">Allow this page to be shown in page lists</label><br /><small>Unchecking this checkbox prevents the page for being indexed for searching. The index is rebuilt each time a page is saved, and you can force an index rebuild by going to the page <?php echo $paths->nslist['Special']; ?>SearchRebuild.</small></td></tr>
+ <tr><td></td><td><input <?php if($cpage['protected']) echo 'checked="checked"'; ?> name="protected" type="checkbox" id="prt" /> <label for="prt">Prevent non-administrators from editing this page</label><br /><small>This option only has an effect when Wiki Mode is enabled.</small></td></tr>
+ <tr><td></td><td><input type="submit" name="delete" value="Delete page" style="color: red" onclick="return confirm('Do you REALLY want to delete this page?')" /></td></tr>
+ <tr><td colspan="2" style="text-align: center;"><hr /></td></tr>
+ <tr><td colspan="2" style="text-align: right;">
+ <input type="hidden" name="old_page_id" value="<?php echo $_POST['old_page_id']; ?>" />
+ <input type="hidden" name="old_namespace" value="<?php echo $_POST['old_namespace']; ?>" />
+ <input type="Submit" name="submit" value="Save changes" style="font-weight: bold;" /> <input type="submit" name="cancel" value="Cancel changes" /></td></tr>
+ </table>
+ <?php
+ echo '</form>';
+ } else {
+ echo '<h3>Please select a page</h3>';
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;" enctype="multipart/form-data">';
+ ?>
+ <p>Search for page title (remember prefixes like User: and File:) <?php echo $template->pagename_field('page_url'); ?> <input type="submit" style="font-weight: bold;" name="search" value="Search" /></p>
+ <p>Select page title from a list: <select name="page_force_url">
+ <?php
+ for($i=0;$i<sizeof($paths->pages)/2;$i++)
+ {
+ if($paths->pages[$i]['namespace'] != 'Admin' && $paths->pages[$i]['namespace'] != 'Special') echo '<option value="'.$paths->nslist[$paths->pages[$i]['namespace']].$paths->pages[$i]['urlname_nons'].'">'.$paths->nslist[$paths->pages[$i]['namespace']].$paths->pages[$i]['name'].'</option>'."\n";
+ }
+ ?>
+ </select> <input type="submit" name="select" value="Select" /></p>
+ <?php
+ echo '</form>';
+
+ }
+}
+
+function page_Admin_PageEditor()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+
+ echo '<h2>Edit page content</h2>';
+
+ if(isset($_POST['search']) || isset($_POST['select'])) {
+ // The object of the game: using only the text a user entered, guess the page ID and namespace. *sigh* I HATE writing search algorithms...
+ if(isset($_POST['search'])) $pid = $_POST['page_url'];
+ elseif(isset($_POST['select'])) $pid = $_POST['page_force_url'];
+ else { echo 'Internal error selecting page search terms'; return false; }
+ // Look for a namespace prefix in the urlname, and assign a different namespace, if necessary
+ $k = array_keys($paths->nslist);
+ for($i=0;$i<sizeof($paths->nslist);$i++)
+ {
+ $ln = strlen($paths->nslist[$k[$i]]);
+ if(substr($pid, 0, $ln) == $paths->nslist[$k[$i]])
+ {
+ $ns = $k[$i];
+ $page_id = substr($pid, $ln, strlen($pid));
+ }
+ }
+ // The namespace is in $ns and the page name or ID (we don't know which yet) is in $page_id
+ // Now, iterate through $paths->pages searching for a page with this name or ID
+ for($i=0;$i<sizeof($paths->pages)/2;$i++)
+ {
+ if(!isset($final_pid))
+ {
+ if ($paths->pages[$i]['urlname_nons'] == str_replace(' ', '_', $page_id)) $final_pid = str_replace(' ', '_', $page_id);
+ elseif($paths->pages[$i]['name'] == $page_id) $final_pid = $paths->pages[$i]['urlname_nons'];
+ elseif(strtolower($paths->pages[$i]['urlname_nons']) == strtolower(str_replace(' ', '_', $page_id))) $final_pid = $paths->pages[$i]['urlname_nons'];
+ elseif(strtolower($paths->pages[$i]['name']) == strtolower(str_replace('_', ' ', $page_id))) $final_pid = $paths->pages[$i]['urlname_nons'];
+ if(isset($final_pid)) { $_POST['name'] = $paths->pages[$i]['name']; $_POST['urlname'] = $paths->pages[$i]['urlname_nons']; }
+ }
+ }
+ if(!isset($final_pid)) { echo 'The page you searched for cannot be found. <a href="#" onclick="ajaxPage(\''.$paths->nslist['Admin'].'PageManager\'); return false;">Back</a>'; return false; }
+ $_POST['namespace'] = $ns;
+ $_POST['page_id'] = $final_pid;
+ if(!isset($paths->pages[$paths->nslist[$_POST['namespace']].$_POST['urlname']])) { echo 'The page you searched for cannot be found. <a href="#" onclick="ajaxPage(\''.$paths->nslist['Admin'].'PageManager\'); return false;">Back</a>'; return false; }
+ }
+
+ if(isset($_POST['page_id']) && !isset($_POST['cancel']))
+ {
+ echo '<form name="main" action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post">';
+ if(!isset($_POST['content']) || isset($_POST['revert'])) $content = RenderMan::getPage($_POST['page_id'], $_POST['namespace'], 0, false, false, false, false);
+ else $content = $_POST['content'];
+ if(isset($_POST['save']))
+ {
+ $data = $content;
+ $id = md5( microtime() . mt_rand() );
+
+ $minor = isset($_POST['minor']) ? 'true' : 'false';
+ $q='INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,page_id,namespace,page_text,char_tag,author,edit_summary,minor_edit) VALUES(\'page\', \'edit\', '.time().', \''.date('d M Y h:i a').'\', \'' . $db->escape($_POST['page_id']) . '\', \'' . $db->escape($_POST['namespace']) . '\', \''.$data.'\', \''.$id.'\', \''.$session->username.'\', \''.$db->escape(htmlspecialchars($_POST['summary'])).'\', '.$minor.');';
+ if(!$db->sql_query($q)) $db->_die('The history (log) entry could not be inserted into the logs table.');
+
+ $query = 'UPDATE '.table_prefix.'page_text SET page_text=\''.$db->escape($data).'\',char_tag=\''.$id.'\' WHERE page_id=\'' . $db->escape($_POST['page_id']) . '\' AND namespace=\'' . $db->escape($_POST['namespace']) . '\';';
+ $e = $db->sql_query($query);
+ if(!$e) echo '<div class="warning-box">The page data could not be saved. MySQL said: '.mysql_error().'<br /><br />Query:<br /><pre>'.$query.'</pre></div>';
+ else echo '<div class="info-box">Your page has been saved. <a href="'.makeUrlNS($_POST['namespace'], $_POST['page_id']).'">View page...</a></div>';
+ } elseif(isset($_POST['preview'])) {
+ echo '<h3>Preview</h3><p><b>Reminder:</b> This is only a preview; your changes to this page have not yet been saved.</p><div style="margin: 1em; padding: 10px; border: 1px dashed #606060; background-color: #F8F8F8; max-height: 200px; overflow: auto;">'.RenderMan::render($content).'</div>';
+ }
+ ?>
+ <p>
+ <textarea name="content" rows="20" cols="60" style="width: 100%;"><?php echo htmlspecialchars($content); ?></textarea><br />
+ Edit summary: <input name="summary" value="<?php if(isset($_POST['summary'])) echo $_POST['summary']; ?>" size="40" /><br />
+ <label><input type="checkbox" name="minor" <?php if(isset($_POST['minor'])) echo 'checked="checked" '; ?>/> This is a minor edit</label>
+ </p>
+ <p>
+ <input type="hidden" name="page_id" value="<?php echo $_POST['page_id']; ?>" />
+ <input type="hidden" name="namespace" value="<?php echo $_POST['namespace']; ?>" />
+ <input type="submit" name="save" value="Save changes" style="font-weight: bold;" /> <input type="submit" name="preview" value="Show preview" /> <input type="submit" name="revert" value="Revert changes" onclick="return confirm('Do you really want to revert your changes?');" /> <input type="submit" name="cancel" value="Cancel" onclick="return confirm('Do you really want to cancel your changes?');" />
+ </p>
+ <?php
+ echo '</form>';
+ } else {
+ echo '<h3>Please select a page</h3>';
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;" enctype="multipart/form-data">';
+ ?>
+ <p>Search for page title (remember prefixes like User: and File:) <?php echo $template->pagename_field('page_url'); ?> <input type="submit" style="font-weight: bold;" name="search" value="Search" /></p>
+ <p>Select page title from a list: <select name="page_force_url">
+ <?php
+ for($i=0;$i<sizeof($paths->pages)/2;$i++)
+ {
+ if($paths->pages[$i]['namespace'] != 'Admin' && $paths->pages[$i]['namespace'] != 'Special') echo '<option value="'.$paths->nslist[$paths->pages[$i]['namespace']].$paths->pages[$i]['urlname_nons'].'">'.$paths->nslist[$paths->pages[$i]['namespace']].$paths->pages[$i]['name'].'</option>'."\n";
+ }
+ ?>
+ </select> <input type="submit" name="select" value="Select" /></p>
+ <?php
+ echo '</form>';
+ }
+}
+
+function page_Admin_ThemeManager()
+{
+
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+
+ // Get the list of styles in the themes/ dir
+ $h = opendir('./themes');
+ $l = Array();
+ if(!$h) die('Error opening directory "./themes" for reading.');
+ while(false !== ($n = readdir($h))) {
+ if($n != '.' && $n != '..' && is_dir('./themes/'.$n))
+ $l[] = $n;
+ }
+ closedir($h);
+ echo('
+ <h3>Theme Management</h3>
+ <p>Install, uninstall, and manage Enano themes.</p>
+ ');
+ if(isset($_POST['disenable'])) {
+ $q = 'SELECT enabled FROM '.table_prefix.'themes WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\'';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error selecting enabled/disabled state value: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $r = $db->fetchrow_num($s);
+ $db->free_result();
+ if($r[0] == 1) $e = 0;
+ else $e = 1;
+ $s=true;
+ if($e==0)
+ {
+ $c = $db->sql_query('SELECT * FROM '.table_prefix.'themes WHERE enabled=1');
+ if(!$c) $db->_die('The backup check for having at least on theme enabled failed.');
+ if($db->numrows() <= 1) { echo '<div class="warning-box">You cannot disable the last remaining theme.</div>'; $s=false; }
+ }
+ $db->free_result();
+ if($s) {
+ $q = 'UPDATE '.table_prefix.'themes SET enabled='.$e.' WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\'';
+ $a = $db->sql_query($q);
+ if(!$a) die('Error updating enabled/disabled state value: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ else echo('<div class="info-box">The theme "'.$_POST['theme_id'].'" has been '. ( ( $e == '1' ) ? 'enabled' : 'disabled' ).'.</div>');
+ }
+ }
+ elseif(isset($_POST['edit'])) {
+
+ $dir = './themes/'.$_POST['theme_id'].'/css/';
+ $list = Array();
+ // Open a known directory, and proceed to read its contents
+ if (is_dir($dir)) {
+ if ($dh = opendir($dir)) {
+ while (($file = readdir($dh)) !== false) {
+ if(preg_match('#^(.*?)\.css$#is', $file) && $file != '_printable.css') {
+ $list[$file] = capitalize_first_letter(substr($file, 0, strlen($file)-4));
+ }
+ }
+ closedir($dh);
+ }
+ }
+ $lk = array_keys($list);
+
+ $q = 'SELECT theme_name,default_style FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\'';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error selecting name value: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $r = $db->fetchrow_num($s);
+ $db->free_result();
+ echo('<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post">');
+ echo('<div class="question-box">
+ Theme name displayed to users: <input type="text" name="name" value="'.$r[0].'" /><br /><br />
+ Default stylesheet: <select name="defaultcss">');
+ foreach ($lk as $l)
+ {
+ if($r[1] == $l) $v = ' selected="selected"';
+ else $v = '';
+ echo "<option value='{$l}'$v>{$list[$l]}</option>";
+ }
+ echo('</select><br /><br />
+ <input type="submit" name="editsave" value="OK" /><input type="hidden" name="theme_id" value="'.$_POST['theme_id'].'" />
+ </div>');
+ echo('</form>');
+ }
+ elseif(isset($_POST['editsave'])) {
+ $q = 'UPDATE '.table_prefix.'themes SET theme_name=\'' . $db->escape($_POST['name']) . '\',default_style=\''.$db->escape($_POST['defaultcss']).'\' WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\'';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error updating name value: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ else echo('<div class="info-box">Theme data updated.</div>');
+ }
+ elseif(isset($_POST['up'])) {
+ // If there is only one theme or if the selected theme is already at the top, do nothing
+ $q = 'SELECT theme_order FROM '.table_prefix.'themes ORDER BY theme_order;';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error selecting order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $q = 'SELECT theme_order FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\'';
+ $sn = $db->sql_query($q);
+ if(!$sn) die('Error selecting order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $r = $db->fetchrow_num($sn);
+ if( /* check for only one theme... */ $db->numrows($s) < 2 || $r[0] == 1 /* ...and check if this theme is already at the top */ ) { echo('<div class="warning-box">This theme is already at the top of the list, or there is only one theme installed.</div>'); } else {
+ // Get the order IDs of the selected theme and the theme before it
+ $q = 'SELECT theme_order FROM '.table_prefix.'themes WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\'';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error selecting order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $r = $db->fetchrow_num($s);
+ $r = $r[0];
+ $rb = $r - 1;
+ // Thank God for jEdit's rectangular selection and the ablity to edit multiple lines at the same time ;)
+ $q = 'UPDATE '.table_prefix.'themes SET theme_order=0 WHERE theme_order='.$rb.''; /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$rb.' WHERE theme_order='.$r.''; /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$r.' WHERE theme_order=0'; /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ echo('<div class="info-box">Theme moved up.</div>');
+ }
+ $db->free_result($s);
+ $db->free_result($sn);
+ }
+ elseif(isset($_POST['down'])) {
+ // If there is only one theme or if the selected theme is already at the top, do nothing
+ $q = 'SELECT theme_order FROM '.table_prefix.'themes ORDER BY theme_order;';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error selecting order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $r = $db->fetchrow_num($s);
+ if( /* check for only one theme... */ $db->numrows($s) < 2 || $r[0] == $db->numrows($s) /* ...and check if this theme is already at the bottom */ ) { echo('<div class="warning-box">This theme is already at the bottom of the list, or there is only one theme installed.</div>'); } else {
+ // Get the order IDs of the selected theme and the theme before it
+ $q = 'SELECT theme_order FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\'';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error selecting order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $r = $db->fetchrow_num($s);
+ $r = $r[0];
+ $rb = $r + 1;
+ // Thank God for jEdit's rectangular selection and the ablity to edit multiple lines at the same time ;)
+ $q = 'UPDATE '.table_prefix.'themes SET theme_order=0 WHERE theme_order='.$rb.''; /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$rb.' WHERE theme_order='.$r.''; /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$r.' WHERE theme_order=0'; /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ echo('<div class="info-box">Theme moved down.</div>');
+ }
+ }
+ else if(isset($_POST['uninstall']))
+ {
+ $q = 'SELECT * FROM '.table_prefix.'themes;';
+ $s = $db->sql_query($q);
+ if ( !$s )
+ {
+ die('Error getting theme count: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ }
+ $n = $db->numrows($s);
+ $db->free_result();
+
+ if ( $_POST['theme_id'] == 'oxygen' )
+ {
+ echo '<div class="error-box">The Oxygen theme is used by Enano for installation, upgrades, and error messages, and cannot be uninstalled.</div>';
+ }
+ else
+ {
+ if($n < 2)
+ {
+ echo '<div class="error-box">The theme could not be uninstalled because it is the only theme left.</div>';
+ }
+ else
+ {
+ $q = 'DELETE FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\' LIMIT 1;';
+ $s = $db->sql_query($q);
+ if ( !$s )
+ {
+ die('Error deleting theme data: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ }
+ else
+ {
+ echo('<div class="info-box">Theme uninstalled.</div>');
+ }
+ }
+ }
+ }
+ elseif(isset($_POST['install'])) {
+ $q = 'SELECT * FROM '.table_prefix.'themes;';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error getting theme count: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $n = $db->numrows($s);
+ $n++;
+ $theme_id = $_POST['theme_id'];
+ $theme = Array();
+ include('./themes/'.$theme_id.'/theme.cfg');
+ $q = 'INSERT INTO '.table_prefix.'themes(theme_id,theme_name,theme_order,enabled) VALUES(\''.$theme['theme_id'].'\', \''.$theme['theme_name'].'\', '.$n.', 1)';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error inserting theme data: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ else echo('<div class="info-box">Theme "'.$theme['theme_name'].'" installed.</div>');
+ }
+ echo('
+ <h3>Currently installed themes</h3>
+ <form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post">
+ <p>
+ <select name="theme_id">
+ ');
+ $q = 'SELECT theme_id,theme_name,enabled FROM '.table_prefix.'themes ORDER BY theme_order';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error selecting theme data: '.mysql_error().'<br /><u>Attempted SQL:</u><br />'.$q);
+ while ( $r = $db->fetchrow_num($s) ) {
+ if($r[2] < 1) $r[1] .= ' (disabled)';
+ echo('<option value="'.$r[0].'">'.$r[1].'</option>');
+ }
+ $db->free_result();
+ echo('
+ </select> <input type="submit" name="disenable" value="Enable/Disable" /> <input type="submit" name="edit" value="Change settings" /> <input type="submit" name="up" value="Move up" /> <input type="submit" name="down" value="Move down" /> <input type="submit" name="uninstall" value="Uninstall" style="color: #DD3300; font-weight: bold;" />
+ </p>
+ </form>
+ <h3>Install a new theme</h3>
+ ');
+ $theme = Array();
+ $obb = '';
+ for($i=0;$i<sizeof($l);$i++) {
+ if(is_file('./themes/'.$l[$i].'/theme.cfg') && file_exists('./themes/'.$l[$i].'/theme.cfg')) {
+ include('./themes/'.$l[$i].'/theme.cfg');
+ $q = 'SELECT * FROM '.table_prefix.'themes WHERE theme_id=\''.$theme['theme_id'].'\'';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error selecting list of currently installed themes: '.mysql_error().'<br /><u>Attempted SQL:</u><br />'.$q);
+ if($db->numrows($s) < 1) {
+ $obb .= '<option value="'.$theme['theme_id'].'">'.$theme['theme_name'].'</option>';
+ }
+ $db->free_result();
+ }
+ }
+ if($obb != '') {
+ echo('<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post"><p>');
+ echo('<select name="theme_id">');
+ echo($obb);
+ echo('</select>');
+ echo('
+ <input type="submit" name="install" value="Install this theme" />
+ </p></form>');
+ } else echo('<p>All themes are currently installed.</p>');
+}
+
+function page_Admin_BanControl()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ if(isset($_GET['action']) && $_GET['action'] == 'delete' && isset($_GET['id']) && $_GET['id'] != '')
+ {
+ $e = $db->sql_query('DELETE FROM '.table_prefix.'banlist WHERE ban_id=' . $db->escape($_GET['id']) . '');
+ if(!$e) $db->_die('The ban list entry was not deleted.');
+ }
+ if(isset($_POST['create']))
+ {
+ $q = 'INSERT INTO '.table_prefix.'banlist(ban_type,ban_value,reason,is_regex) VALUES( ' . $db->escape($_POST['type']) . ', \'' . $db->escape($_POST['value']) . '\', \''.$db->escape($_POST['reason']).'\'';
+ if(isset($_POST['regex'])) $q .= ', 1';
+ else $q .= ', 0';
+ $q .= ');';
+ $e = $db->sql_query($q);
+ if(!$e) $db->_die('The banlist could not be updated.');
+ }
+ $q = $db->sql_query('SELECT ban_id,ban_type,ban_value,is_regex FROM '.table_prefix.'banlist ORDER BY ban_type;');
+ if(!$q) $db->_die('The banlist data could not be selected.');
+ echo '<table border="0" cellspacing="1" cellpadding="4">';
+ echo '<tr><th>Type</th><th>Value</th><th>Regular Expression</th><th></th></tr>';
+ if($db->numrows() < 1) echo '<td colspan="4">No ban rules yet.</td>';
+ while($r = $db->fetchrow())
+ {
+ if($r['ban_type']==BAN_IP) $t = 'IP address';
+ elseif($r['ban_type']==BAN_USER) $t = 'Username';
+ elseif($r['ban_type']==BAN_EMAIL) $t = 'E-mail address';
+ if($r['is_regex']) $g = 'Yes'; else $g = 'No';
+ echo '<tr><td>'.$t.'</td><td>'.$r['ban_value'].'</td><td>'.$g.'</td><td><a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'BanControl&action=delete&id='.$r['ban_id']).'">Delete</a></td></tr>';
+ }
+ $db->free_result();
+ echo '</table>';
+ echo '<h3>Create new ban rule</h3>';
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post">';
+ ?>
+ Type: <select name="type"><option value="<?php echo BAN_IP; ?>">IP address</option><option value="<?php echo BAN_USER; ?>">Username</option><option value="<?php echo BAN_EMAIL; ?>">E-mail address</option></select><br />
+ Rule: <input type="text" name="value" size="30" /><br />
+ Reason to show to the banned user: <textarea name="reason" rows="7" cols="20"></textarea><br />
+ <input type="checkbox" name="regex" id="regex" /> <label for="regex">This rule is a regular expression</label> (advanced users only)<br />
+ <input type="submit" style="font-weight: bold;" name="create" value="Create new ban rule" />
+ <?php
+ echo '</form>';
+}
+
+function page_Admin_MassEmail()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ global $enano_config;
+ if ( isset($_POST['do_send']) )
+ {
+ $use_smtp = getConfig('smtp_enabled') == '1';
+
+ //
+ // Let's do some checking to make sure that mass mail functions
+ // are working in win32 versions of php. (copied from phpBB)
+ //
+ if ( preg_match('/[c-z]:\\\.*/i', getenv('PATH')) && !$use_smtp)
+ {
+ $ini_val = ( @phpversion() >= '4.0.0' ) ? 'ini_get' : 'get_cfg_var';
+
+ // We are running on windows, force delivery to use our smtp functions
+ // since php's are broken by default
+ $use_smtp = true;
+ $enano_config['smtp_server'] = @$ini_val('SMTP');
+ }
+
+ $mail = new emailer( !empty($use_smtp) );
+
+ // Validate subject/message body
+ $subject = stripslashes(trim($_POST['subject']));
+ $message = stripslashes(trim($_POST['message']));
+
+ if ( empty($subject) )
+ $errors[] = 'Please enter a subject.';
+ if ( empty($message) )
+ $errors[] = 'Please enter a message.';
+
+ // Get list of members
+ if ( !empty($_POST['userlist']) )
+ {
+ $userlist = str_replace(', ', ',', $_POST['userlist']);
+ $userlist = explode(',', $userlist);
+ foreach ( $userlist as $k => $u )
+ {
+ if ( $u == $session->username )
+ {
+ // Message is automatically sent to the sender
+ unset($userlist[$k]);
+ }
+ else
+ {
+ $userlist[$k] = $db->escape($u);
+ }
+ }
+ $userlist = 'WHERE username=\'' . implode('\' OR username=\'', $userlist) . '\'';
+
+ $q = $db->sql_query('SELECT email FROM '.table_prefix.'users ' . $userlist . ';');
+ if ( !$q )
+ $db->_die();
+
+ if ( $row = $db->fetchrow() )
+ {
+ do {
+ $mail->cc($row['email']);
+ } while ( $row = $db->fetchrow() );
+ }
+
+ $db->free_result();
+
+ }
+ else
+ {
+ // Sending to a usergroup
+
+ $group_id = intval($_POST['group_id']);
+ if ( $group_id < 1 )
+ {
+ $errors[] = 'Invalid group ID';
+ }
+ else
+ {
+ $q = $db->sql_query('SELECT u.email FROM '.table_prefix.'group_members AS g
+ LEFT JOIN '.table_prefix.'users AS u
+ ON (u.user_id=g.user_id)
+ WHERE g.group_id=' . $group_id . ';');
+ if ( !$q )
+ $db->_die();
+
+ if ( $row = $db->fetchrow() )
+ {
+ do {
+ $mail->cc($row['email']);
+ } while ( $row = $db->fetchrow() );
+ }
+
+ $db->free_result();
+ }
+ }
+
+ if ( sizeof($errors) < 1 )
+ {
+
+ $mail->from(getConfig('contact_email'));
+ $mail->replyto(getConfig('contact_email'));
+ $mail->set_subject($subject);
+ $mail->email_address(getConfig('contact_email'));
+
+ // Copied/modified from phpBB
+ $email_headers = 'X-AntiAbuse: Website server name - ' . $_SERVER['SERVER_NAME'] . "\n";
+ $email_headers .= 'X-AntiAbuse: User_id - ' . $session->user_id . "\n";
+ $email_headers .= 'X-AntiAbuse: Username - ' . $session->username . "\n";
+ $email_headers .= 'X-AntiAbuse: User IP - ' . $_SERVER['REMOTE_ADDR'] . "\n";
+
+ $mail->extra_headers($email_headers);
+
+ $tpl = 'The following message was mass-mailed by {SENDER}, one of the administrators from {SITE_NAME}. If this message contains spam or any comments which you find abusive or offensive, please contact the administration team at:
+
+{CONTACT_EMAIL}
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+{MESSAGE}
+';
+
+ $mail->use_template($tpl);
+
+ $mail->assign_vars(array(
+ 'SENDER' => $session->username,
+ 'SITE_NAME' => getConfig('site_name'),
+ 'CONTACT_EMAIL' => getConfig('contact_email'),
+ 'MESSAGE' => $message
+ ));
+
+ //echo '<pre>'.print_r($mail,true).'</pre>';
+
+ // All done
+ $mail->send();
+ $mail->reset();
+
+ echo '<div class="info-box">Your message has been sent.</div>';
+
+ }
+ else
+ {
+ echo '<div class="warning-box">Could not send message for the following reason(s):<ul><li>' . implode('</li><li>', $errors) . '</li></ul></div>';
+ }
+
+ }
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post">';
+ ?>
+ <div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2">Send mass e-mail</th>
+ </tr>
+ <tr>
+ <td class="row2" rowspan="2" style="width: 30%; min-width: 200px;">
+ Send message to:<br />
+ <small>
+ By default, this message will be sent to the group selected here. You may instead send the message to a specific
+ list of users by entering them in the second row, with usernames separated by a single comma (no space).
+ </small>
+ </td>
+ <td class="row1">
+ <select name="group_id">
+ <?php
+ $q = $db->sql_query('SELECT group_name,group_id FROM '.table_prefix.'groups ORDER BY group_name ASC;');
+ if ( !$q )
+ $db->_die();
+ while ( $row = $db->fetchrow() )
+ {
+ echo '<option value="' . $row['group_id'] . '">' . $row['group_name'] . '</option>';
+ }
+ ?>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td class="row1">
+ Usernames: <input type="text" name="userlist" size="50" />
+ </td>
+ </tr>
+ <tr>
+ <td class="row2" style="width: 30%; min-width: 200px;">
+ Subject:
+ </td>
+ <td class="row1">
+ <input name="subject" type="text" size="50" />
+ </td>
+ </tr>
+ <tr>
+ <td class="row2" style="width: 30%; min-width: 200px;">
+ Message:
+ </td>
+ <td class="row1">
+ <textarea name="message" rows="30" cols="60" style="width: 100%;"></textarea>
+ </td>
+ </tr>
+ <tr>
+ <th class="subhead" colspan="2" style="text-align: left;" valign="middle">
+ <div style="float: right;"><input type="submit" name="do_send" value="Send message" /></div>
+ <small style="font-weight: normal;">Please be warned: it may take a LONG time to send this message. <b>Please do not stop the script until the process is finished.</b></small>
+ </th>
+ </tr>
+
+ </table>
+ </div>
+ <?php
+ echo '</form>';
+}
+
+function page_Admin_DBBackup()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ global $system_table_list;
+ if(isset($_GET['submitting']) && $_GET['submitting'] == 'yes')
+ {
+
+ if(defined('SQL_BACKUP_CRYPT'))
+ // Try to increase our time limit
+ @set_time_limit(300); // five minutes
+ // Do the actual export
+ $aesext = ( defined('SQL_BACKUP_CRYPT') ) ? '.tea' : '';
+ $filename = 'enano_backup_' . date('dmy') . '.sql' . $aesext;
+ ob_start();
+ header('Content-disposition: attachment, filename="'.$filename.'";');
+ header('Content-type: application/transact-sql');
+ // Spew some headers
+ $headdate = date('F d, Y \a\t h:i a');
+ echo <<<HEADER
+-- Enano CMS SQL backup
+-- Generated on {$headdate} by {$session->username}
+
+HEADER;
+ // build the table list
+ $base = ( isset($_POST['do_system_tables']) ) ? $system_table_list : Array();
+ $add = ( isset($_POST['additional_tables'])) ? $_POST['additional_tables'] : Array();
+ $tables = array_merge($base, $add);
+
+ // Log it!
+ $e = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'db_backup\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($session->username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', \'' . $db->escape(implode(', ', $tables)) . '\')');
+ if ( !$e )
+ $db->_die();
+
+ foreach($tables as $i => $t)
+ {
+ if(!preg_match('#^([a-z0-9_]+)$#i', $t))
+ die('Hacking attempt');
+ // if($t == table_prefix.'files' && isset($_POST['do_data']))
+ // unset($tables[$i]);
+ }
+ foreach($tables as $t)
+ {
+ // Sorry folks - this script CAN'T backup enano_files, enano_search_index, and enano_search_cache due to the sheer size of the tables.
+ // If encryption is enabled the log data will be excluded too.
+ echo export_table(
+ $t,
+ isset($_POST['do_struct']),
+ ( isset($_POST['do_data']) /* && $t != table_prefix.'files' && $t != table_prefix.'search_index' && $t != table_prefix.'search_cache' && ( !defined('SQL_BACKUP_CRYPT') || ( defined('SQL_BACKUP_CRYPT') && $t != table_prefix.'logs' ) ) */ ),
+ false
+ ) . "\n";
+ }
+ $data = ob_get_contents();
+ ob_end_clean();
+ if(defined('SQL_BACKUP_CRYPT'))
+ {
+ // Free some memory, we don't need this stuff any more
+ $db->close();
+ unset($paths, $db, $template, $plugins);
+ $tea = new TEACrypt();
+ $data = $tea->encrypt($data, $session->private_key);
+ }
+ header('Content-length: '.strlen($data));
+ echo $data;
+ exit;
+ }
+ else
+ {
+ // Show the UI
+ echo '<form action="'.makeUrlNS('Admin', 'DBBackup', 'submitting=yes', true).'" method="post" enctype="multipart/form-data">';
+ ?>
+ <p>This page allows you to back up your Enano database should something go miserably wrong.</p>
+ <p><label><input type="checkbox" name="do_system_tables" checked="checked" /> Export tables that are part of the Enano core</label><p>
+ <p>Additional tables to export:</p>
+ <p><select name="additional_tables[]" multiple="multiple">
+ <?php
+ $q = $db->sql_query('SHOW TABLES;') or $db->_die('Somehow we were denied the request to get the list of tables.');
+ while($row = $db->fetchrow_num())
+ {
+ if(!in_array($row[0], $system_table_list)) echo '<option value="'.$row[0].'">'.$row[0].'</option>';
+ }
+ ?>
+ </select>
+ </p>
+ <p><label><input type="checkbox" name="do_struct" checked="checked" /> Include table structure</label><br />
+ <label><input type="checkbox" name="do_data" checked="checked" /> Include table data</label>
+ </p>
+ <p><input type="submit" value="Create backup" /></p>
+ <?php
+ echo '</form>';
+ }
+}
+
+function page_Admin_AdminLogout()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ $session->logout(USER_LEVEL_ADMIN);
+ echo '<h3>You have now been logged out of the administration panel.</h3><p>You will continue to be logged into the website, but you will need to re-authenticate before you can access the administration panel again.</p><p>Return to the <a href="'.makeUrl(getConfig('main_page')).'">Main Page</a>.</p>';
+}
+
+function page_Special_Administration()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ if($session->auth_level < USER_LEVEL_ADMIN) {
+ redirect(makeUrlNS('Special', 'Login/'.$paths->page, 'level='.USER_LEVEL_ADMIN), 'Not authorized', 'You need an authorization level of '.USER_LEVEL_ADMIN.' to use this page, your auth level is: ' . $session->auth_level, 0);
+ exit;
+ }
+ else
+ {
+ $template->load_theme('admin', 'default');
+ $template->init_vars();
+ if( !isset( $_GET['noheaders'] ) )
+ {
+ $template->header();
+ }
+ echo 'Administer your Enano website.';
+ ?>
+ <script type="text/javascript">
+ function ajaxPage(t)
+ {
+ if ( t == namespace_list.Admin + 'AdminLogout' )
+ {
+ var mb = new messagebox(MB_YESNO|MB_ICONQUESTION, 'Are you sure you want to de-authenticate?', 'If you de-authenticate, you will no longer be able to use the administration panel until you re-authenticate again. You may do so at any time using the Administration button on the sidebar.');
+ mb.onclick['Yes'] = function() {
+ var tigraentry = document.getElementById('i_div0_0').parentNode;
+ var tigraobj = $(tigraentry);
+ var div = document.createElement('div');
+ div.style.backgroundColor = '#FFFFFF';
+ domObjChangeOpac(70, div);
+ div.style.position = 'absolute';
+ var top = tigraobj.Top();
+ var left = tigraobj.Left();
+ var width = tigraobj.Width();
+ var height = tigraobj.Height();
+ div.style.top = top + 'px';
+ div.style.left = left + 'px';
+ div.style.width = width + 'px';
+ div.style.height = height + 'px';
+ var body = document.getElementsByTagName('body')[0];
+ enlighten(true);
+ body.appendChild(div);
+ ajaxPageBin(namespace_list.Admin + 'AdminLogout');
+ }
+ return;
+ }
+ ajaxPageBin(t);
+ }
+ function ajaxPageBin(t)
+ {
+ document.getElementById('ajaxPageContainer').innerHTML = '<div class="wait-box">Loading page...</div>';
+ ajaxGet('<?php echo scriptPath; ?>/ajax.php?title='+t+'&_mode=getpage&noheaders&auth=<?php echo $session->sid_super; ?>', function() {
+ if(ajax.readyState == 4) {
+ document.getElementById('ajaxPageContainer').innerHTML = ajax.responseText;
+ fadeInfoBoxes();
+ }
+ });
+ }
+ function _enanoAdminOnload() { ajaxPage('<?php echo $paths->nslist['Admin']; ?>Home'); }
+ var TREE_TPL = {
+ 'target' : '_self', // name of the frame links will be opened in
+ // other possible values are: _blank, _parent, _search, _self and _top
+
+ 'icon_e' : '<?php echo scriptPath; ?>/images/icons/empty.gif', // empty image
+ 'icon_l' : '<?php echo scriptPath; ?>/images/icons/line.gif', // vertical line
+ 'icon_32' : '<?php echo scriptPath; ?>/images/icons/base.gif', // root leaf icon normal
+ 'icon_36' : '<?php echo scriptPath; ?>/images/icons/base.gif', // root leaf icon selected
+ 'icon_48' : '<?php echo scriptPath; ?>/images/icons/base.gif', // root icon normal
+ 'icon_52' : '<?php echo scriptPath; ?>/images/icons/base.gif', // root icon selected
+ 'icon_56' : '<?php echo scriptPath; ?>/images/icons/base.gif', // root icon opened
+ 'icon_60' : '<?php echo scriptPath; ?>/images/icons/base.gif', // root icon selected
+ 'icon_16' : '<?php echo scriptPath; ?>/images/icons/folder.gif', // node icon normal
+ 'icon_20' : '<?php echo scriptPath; ?>/images/icons/folderopen.gif', // node icon selected
+ 'icon_24' : '<?php echo scriptPath; ?>/images/icons/folder.gif', // node icon opened
+ 'icon_28' : '<?php echo scriptPath; ?>/images/icons/folderopen.gif', // node icon selected opened
+ 'icon_0' : '<?php echo scriptPath; ?>/images/icons/page.gif', // leaf icon normal
+ 'icon_4' : '<?php echo scriptPath; ?>/images/icons/page.gif', // leaf icon selected
+ 'icon_8' : '<?php echo scriptPath; ?>/images/icons/page.gif', // leaf icon opened
+ 'icon_12' : '<?php echo scriptPath; ?>/images/icons/page.gif', // leaf icon selected
+ 'icon_2' : '<?php echo scriptPath; ?>/images/icons/joinbottom.gif', // junction for leaf
+ 'icon_3' : '<?php echo scriptPath; ?>/images/icons/join.gif', // junction for last leaf
+ 'icon_18' : '<?php echo scriptPath; ?>/images/icons/plusbottom.gif', // junction for closed node
+ 'icon_19' : '<?php echo scriptPath; ?>/images/icons/plus.gif', // junction for last closed node
+ 'icon_26' : '<?php echo scriptPath; ?>/images/icons/minusbottom.gif',// junction for opened node
+ 'icon_27' : '<?php echo scriptPath; ?>/images/icons/minus.gif' // junction for last opended node
+ };
+ <?php
+ echo $paths->parseAdminTree(); // Make a Javascript array that defines the tree
+ if(!isset($_GET['module'])) { echo 'addOnloadHook(_enanoAdminOnload);'; } ?>
+ </script>
+ <table border="0" width="100%">
+ <tr>
+ <td class="holder" valign="top">
+ <div class="pad" style="padding-right: 20px;">
+ <script type="text/javascript">
+ new tree(TREE_ITEMS, TREE_TPL);
+ </script>
+ </div>
+ </td>
+ <td width="100%" valign="top">
+ <div class="pad" id="ajaxPageContainer">
+ <?php
+ if(isset($_GET['module']))
+ {
+ // Look for a namespace prefix in the urlname, and assign a different namespace, if necessary
+ $k = array_keys($paths->nslist);
+ for ( $i = 0; $i < sizeof($paths->nslist); $i++ )
+ {
+ $ln = strlen( $paths->nslist[ $k[ $i ] ] );
+ if ( substr($_GET['module'], 0, $ln) == $paths->nslist[$k[$i]] )
+ {
+ $ns = $k[$i];
+ $nm = substr($_GET['module'], $ln, strlen($_GET['module']));
+ }
+ }
+ $fname = 'page_'.$ns.'_'.$nm;
+ $s = strpos($fname, '?noheaders');
+ if($s) $fname = substr($fname, 0, $s);
+ $paths->cpage['module'] = $_GET['module'];
+ if ( function_exists($fname) && $_GET['module'] != $paths->nslist['Special'] . 'Administration' )
+ {
+ eval($fname.'();');
+ }
+ }
+ else
+ {
+ echo '<div class="wait-box">Please wait while the administration panel loads. You need to be using a recent browser with AJAX support in order to use Runt.</div>';
+ }
+ ?>
+ </div>
+ </td>
+ </tr>
+ </table>
+
+ <?php
+ }
+ if(!isset($_GET['noheaders']))
+ {
+ $template->footer();
+ }
+}
+
+function page_Special_EditSidebar()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ if($session->auth_level < USER_LEVEL_ADMIN)
+ {
+ redirect(makeUrlNS('Special', 'Login/'.$paths->page, 'level='.USER_LEVEL_ADMIN), '', '', false);
+ exit;
+ }
+ else
+ {
+
+ $template->add_header('<script type="text/javascript" src="'.scriptPath.'/includes/clientside/dbx.js"></script>');
+ $template->add_header('<script type="text/javascript" src="'.scriptPath.'/includes/clientside/dbx-key.js"></script>');
+ $template->add_header('<script type="text/javascript" src="'.scriptPath.'/includes/clientside/sbedit.js"></script>');
+ $template->add_header('<link rel="stylesheet" type="text/css" href="'.scriptPath.'/includes/clientside/dbx.css" />');
+
+ // Knock the sidebars dead to keep javascript in plugins from interfering
+ $template->tpl_strings['SIDEBAR_LEFT'] = '';
+ $template->tpl_strings['SIDEBAR_RIGHT'] = '';
+
+ $template->load_theme('oxygen', 'bleu');
+ $template->init_vars();
+
+ $template->header();
+
+ if(isset($_POST['save']))
+ {
+ // Write the new block order to the database
+ // The only way to do this is with tons of queries (one per block + one select query at the start to count everything) but afaik its safe...
+ // Anyone know a better way to do this?
+ $q = $db->sql_query('SELECT item_order,item_id,sidebar_id FROM '.table_prefix.'sidebar ORDER BY sidebar_id ASC, item_order ASC;');
+ if ( !$q )
+ {
+ $db->_die('The sidebar order data could not be selected.');
+ }
+ $orders = Array();
+ while($row = $db->fetchrow())
+ {
+ $orders[] = Array(
+ count($orders),
+ $row['item_id'],
+ $row['sidebar_id'],
+ );
+ }
+ $db->free_result();
+
+ // We now have an array with each sidebar ID in its respective order. Explode the order string in $_POST['order_(left|right)'] and use it to build a set of queries.
+ $ol = explode(',', $_POST['order_left']);
+ $odr = explode(',', $_POST['order_right']);
+ $om = array_merge($ol, $odr);
+ unset($ol, $odr);
+ $queries = Array();
+ foreach($orders as $k => $v)
+ {
+ $queries[] = 'UPDATE '.table_prefix.'sidebar SET item_order='.$om[$k].' WHERE item_id='.$v[1].';';
+ }
+ foreach($queries as $sql)
+ {
+ $q = $db->sql_query($sql);
+ if(!$q)
+ {
+ $t = $db->get_error();
+ echo $t;
+ $template->footer();
+ exit;
+ }
+ }
+ echo '<div class="info-box" style="margin: 10px 0;">The sidebar order information was updated successfully.</div>';
+ }
+ elseif(isset($_POST['create']))
+ {
+ switch((int)$_POST['type'])
+ {
+ case BLOCK_WIKIFORMAT:
+ $content = $_POST['wikiformat_content'];
+ break;
+ case BLOCK_TEMPLATEFORMAT:
+ $content = $_POST['templateformat_content'];
+ break;
+ case BLOCK_HTML:
+ $content = $_POST['html_content'];
+ break;
+ case BLOCK_PHP:
+ $content = $_POST['php_content'];
+ break;
+ case BLOCK_PLUGIN:
+ $content = $_POST['plugin_id'];
+ break;
+ }
+ // Get the value of item_order
+
+ $q = $db->sql_query('SELECT * FROM '.table_prefix.'sidebar WHERE sidebar_id='.$db->escape($_POST['sidebar_id']).';');
+ if(!$q) $db->_die('The order number could not be selected');
+ $io = $db->numrows();
+
+ $db->free_result();
+
+ $q = 'INSERT INTO '.table_prefix.'sidebar(block_name, block_type, sidebar_id, block_content, item_order) VALUES ( \''.$db->escape($_POST['title']).'\', \''.$db->escape($_POST['type']).'\', \''.$db->escape($_POST['sidebar_id']).'\', \''.$db->escape($content).'\', '.$io.' );';
+ $result = $db->sql_query($q);
+ if(!$result)
+ {
+ echo $db->get_error();
+ $template->footer();
+ exit;
+ }
+
+ echo '<div class="info-box" style="margin: 10px 0;">The item was added.</div>';
+
+ }
+
+ if(isset($_GET['action']) && isset($_GET['id']))
+ {
+ if(preg_match('#^([0-9]*)$#', $_GET['id']))
+ {
+ } else {
+ echo '<div class="warning-box">Error with action: $_GET["id"] was not an integer, aborting to prevent SQL injection</div>';
+ }
+ switch($_GET['action'])
+ {
+ case 'new':
+ ?>
+ <script type="text/javascript">
+ function setType(input)
+ {
+ val = input.value;
+ if(!val)
+ {
+ return false;
+ }
+ var divs = getElementsByClassName(document, 'div', 'sbadd_block');
+ for(var i in divs)
+ {
+ if(divs[i].id == 'blocktype_'+val) divs[i].style.display = 'block';
+ else divs[i].style.display = 'none';
+ }
+ }
+ </script>
+
+ <form action="<?php echo makeUrl($paths->page); ?>" method="post">
+
+ <p>
+ What type of block should this be?
+ </p>
+ <p>
+ <select name="type" onchange="setType(this)"> <?php /* (NOT WORKING, at least in firefox 2) onload="var thingy = this; setTimeout('setType(thingy)', 500);" */ ?>
+ <option value="<?php echo BLOCK_WIKIFORMAT; ?>">Wiki-formatted block</option>
+ <option value="<?php echo BLOCK_TEMPLATEFORMAT; ?>">Template-formatted block (old pre-beta 3 behavior)</option>
+ <option value="<?php echo BLOCK_HTML; ?>">Raw HTML block</option>
+ <option value="<?php echo BLOCK_PHP; ?>">PHP code block (danger, Will Robinson!)</option>
+ <option value="<?php echo BLOCK_PLUGIN; ?>">Use code from a plugin</option>
+ </select>
+ </p>
+
+ <p>
+
+ Block title: <input name="title" type="text" size="40" /><br />
+ Which sidebar: <select name="sidebar_id"><option value="<?php echo SIDEBAR_LEFT; ?>">Left</option><option value="<?php echo SIDEBAR_RIGHT; ?>">Right</option></select>
+
+ </p>
+
+ <div class="sbadd_block" id="blocktype_<?php echo BLOCK_WIKIFORMAT; ?>">
+ <p>
+ Wikitext:
+ </p>
+ <p>
+ <textarea style="width: 98%;" name="wikiformat_content" rows="15" cols="50"></textarea>
+ </p>
+ </div>
+
+ <div class="sbadd_block" id="blocktype_<?php echo BLOCK_TEMPLATEFORMAT; ?>">
+ <p>
+ Template code:
+ </p>
+ <p>
+ <textarea style="width: 98%;" name="templateformat_content" rows="15" cols="50"></textarea>
+ </p>
+ </div>
+
+ <div class="sbadd_block" id="blocktype_<?php echo BLOCK_HTML; ?>">
+ <p>
+ HTML to place inside the sidebar:
+ </p>
+ <p>
+ <textarea style="width: 98%;" name="html_content" rows="15" cols="50"></textarea>
+ </p>
+ </div>
+
+ <div class="sbadd_block" id="blocktype_<?php echo BLOCK_PHP; ?>">
+ <p>
+ <b>WARNING:</b> If you don't know what you're doing, or if you are not fluent in PHP, stop now and choose a different block type. You will brick your Enano installation if you are not careful here.
+ ALWAYS remember to write secure code! The Enano team is not responsible if someone drops all your tables because of an SQL injection vulnerability in your sidebar code. You are probably better off using the template-formatted block type.
+ </p>
+ <p>
+ <span style="color: red;">
+ It is especially important to note that this code is NOT checked for errors! If there is a syntax error in your code here, it will prevent any pages from loading AT ALL. So you need to use an external PHP editor (like <a href="http://www.jedit.org">jEdit</a>) to check your syntax before you hit save.
+ </span> You have been warned.
+ </p>
+ <p>
+ Also, you should avoid using output buffering functions (ob_[start|end|get_contents|clean]) here, because Enano uses those to track output from this script.
+ </p>
+ <p>
+ The standard <?php and ?> tags work here. Don't use an initial "<?php" or it will cause a parse error.
+ </p>
+ <p>
+ PHP code:
+ </p>
+ <p>
+ <textarea style="width: 98%;" name="php_content" rows="15" cols="50"></textarea>
+ </p>
+ </div>
+
+ <div class="sbadd_block" id="blocktype_<?php echo BLOCK_PLUGIN; ?>">
+ <p>
+ Plugin:
+ </p>
+ <p>
+ <select name="plugin_id">
+ <?php
+ foreach($template->plugin_blocks as $k => $c)
+ {
+ echo '<option value="'.$k.'">'.$k.'</option>';
+ }
+ ?>
+ </select>
+ </p>
+ </div>
+
+ <p>
+
+ <input type="submit" name="create" value="Create new block" style="font-weight: bold;" />
+ <input type="submit" name="cancel" value="Cancel" />
+
+ </p>
+
+ </form>
+
+ <script type="text/javascript">
+ var divs = getElementsByClassName(document, 'div', 'sbadd_block');
+ for(var i in divs)
+ {
+ if(divs[i].id != 'blocktype_<?php echo BLOCK_WIKIFORMAT; ?>') setTimeout("document.getElementById('"+divs[i].id+"').style.display = 'none';", 500);
+ }
+ </script>
+
+ <?php
+ $template->footer();
+ return;
+ break;
+ case 'move':
+ if( !isset($_GET['side']) || ( isset($_GET['side']) && !preg_match('#^([0-9]+)$#', $_GET['side']) ) )
+ {
+ echo '<div class="warning-box" style="margin: 10px 0;">$_GET[\'side\'] contained an SQL injection attempt</div>';
+ break;
+ }
+ $query = $db->sql_query('UPDATE '.table_prefix.'sidebar SET sidebar_id=' . $db->escape($_GET['side']) . ' WHERE item_id=' . $db->escape($_GET['id']) . ';');
+ if(!$query)
+ {
+ echo $db->get_error();
+ $template->footer();
+ exit;
+ }
+ echo '<div class="info-box" style="margin: 10px 0;">Item moved.</div>';
+ break;
+ case 'delete':
+ $query = $db->sql_query('DELETE FROM '.table_prefix.'sidebar WHERE item_id=' . $db->escape($_GET['id']) . ';'); // Already checked for injection attempts ;-)
+ if(!$query)
+ {
+ echo $db->get_error();
+ $template->footer();
+ exit;
+ }
+ if(isset($_GET['ajax']))
+ {
+ ob_end_clean();
+ die('GOOD');
+ }
+ echo '<div class="error-box" style="margin: 10px 0;">Item deleted.</div>';
+ break;
+ case 'disenable';
+ $q = $db->sql_query('SELECT item_enabled FROM '.table_prefix.'sidebar WHERE item_id=' . $db->escape($_GET['id']) . ';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ $template->footer();
+ exit;
+ }
+ $r = $db->fetchrow();
+ $db->free_result();
+ $e = ( $r['item_enabled'] == 1 ) ? '0' : '1';
+ $q = $db->sql_query('UPDATE '.table_prefix.'sidebar SET item_enabled='.$e.' WHERE item_id=' . $db->escape($_GET['id']) . ';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ $template->footer();
+ exit;
+ }
+ if(isset($_GET['ajax']))
+ {
+ ob_end_clean();
+ die('GOOD');
+ }
+ break;
+ case 'getsource':
+ $q = $db->sql_query('SELECT block_content,block_type FROM '.table_prefix.'sidebar WHERE item_id=' . $db->escape($_GET['id']) . ';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ $template->footer();
+ exit;
+ }
+ ob_end_clean();
+ $r = $db->fetchrow();
+ $db->free_result();
+ if($r['block_type'] == BLOCK_PLUGIN) die('HOUSTON_WE_HAVE_A_PLUGIN');
+ die($r['block_content']);
+ break;
+ case 'save':
+ $q = $db->sql_query('UPDATE '.table_prefix.'sidebar SET block_content=\''.$db->escape(rawurldecode($_POST['content'])).'\' WHERE item_id=' . $db->escape($_GET['id']) . ';');
+ if(!$q)
+ {
+ echo 'var status=unescape(\''.hexencode($db->get_error()).'\');';
+ exit;
+ }
+ $q = $db->sql_query('SELECT block_type,block_content FROM '.table_prefix.'sidebar WHERE item_id=' . $db->escape($_GET['id']) . ';');
+ if(!$q)
+ {
+ echo 'var status=unescape(\''.hexencode($db->get_error()).'\');';
+ exit;
+ }
+ $row = $db->fetchrow();
+ $db->free_result();
+ switch($row['block_type'])
+ {
+ case BLOCK_WIKIFORMAT:
+ default:
+ $c = RenderMan::render($row['block_content']);
+ break;
+ case BLOCK_TEMPLATEFORMAT:
+ $c = $template->tplWikiFormat($row['block_content'], false, 'sidebar-editor.tpl');
+ $c = preg_replace('#<a (.*?)>(.*?)</a>#is', '<a href="#" onclick="return false;">\\2</a>', $c);
+ break;
+ case BLOCK_HTML:
+ $c = $row['block_content'];
+ $c = preg_replace('#<a (.*?)>(.*?)</a>#is', '<a href="#" onclick="return false;">\\2</a>', $c);
+ break;
+ case BLOCK_PHP:
+ ob_start();
+ eval($row['block_content']);
+ $c = ob_get_contents();
+ ob_end_clean();
+ $c = preg_replace('#<a (.*?)>(.*?)</a>#is', '<a href="#" onclick="return false;">\\2</a>', $c);
+ break;
+ case BLOCK_PLUGIN:
+ $c = ($template->fetch_block($row['block_content'])) ? $template->fetch_block($row['block_content']) : 'Can\'t find plugin block';
+ break;
+ }
+ die('var status = \'GOOD\'; var content = unescape(\''.hexencode($c).'\');');
+ break;
+ }
+ }
+
+ $q = $db->sql_query('SELECT item_id,sidebar_id,item_enabled,block_name,block_type,block_content FROM '.table_prefix.'sidebar ORDER BY sidebar_id ASC, item_order ASC;');
+ if(!$q) $db->_die('The sidebar text data could not be selected.');
+
+ $vars = $template->extract_vars('sidebar-editor.tpl');
+
+ $parser = $template->makeParserText($vars['sidebar_button']);
+ $parser->assign_vars(Array(
+ 'HREF'=>'#',
+ 'FLAGS'=>'onclick="return false;"',
+ 'TEXT'=>'Change theme'
+ ));
+ $template->tpl_strings['THEME_LINK'] = $parser->run();
+ $parser->assign_vars(Array(
+ 'TEXT'=>'Log out',
+ ));
+ $template->tpl_strings['LOGOUT_LINK'] = $parser->run();
+
+ $n1 = Array();
+ $n2 = Array();
+ $n =& $n1;
+
+ echo '<table border="0"><tr><td valign="top"><div class="dbx-group" id="sbedit_left">';
+ //if(isset($vars['sidebar_top'])) echo $template->parse($vars['sidebar_top']);
+
+ // Time for the loop
+ // what this loop does is fetch the row data, then send it out to the appropriate parser for formatting,
+ // then puts the result into $c, which is then sent to the template compiler for insertion into the TPL code.
+ while($row = $db->fetchrow())
+ {
+ if(isset($current_side))
+ {
+ if($current_side != $row['sidebar_id'])
+ {
+ // Time to switch!
+ //if(isset($vars['sidebar_top'])) echo $template->parse($vars['sidebar_bottom']);
+ echo '</div></td><td valign="top"><div class="dbx-group" id="sbedit_right">';
+ //echo '</td><td valign="top">';
+ //if(isset($vars['sidebar_top'])) echo $template->parse($vars['sidebar_top']);
+ $n =& $n2;
+ }
+ }
+ $n[] = count($n);
+ $current_side = $row['sidebar_id'];
+ switch($row['block_type'])
+ {
+ case BLOCK_WIKIFORMAT:
+ default:
+ $parser = $template->makeParserText($vars['sidebar_section']);
+ $c = RenderMan::render($row['block_content']);
+ break;
+ case BLOCK_TEMPLATEFORMAT:
+ $parser = $template->makeParserText($vars['sidebar_section']);
+ $c = $template->tplWikiFormat($row['block_content'], false, 'sidebar-editor.tpl');
+ $c = preg_replace('#<a (.*?)>(.*?)</a>#is', '<a href="#" onclick="return false;">\\2</a>', $c);
+ break;
+ case BLOCK_HTML:
+ $parser = $template->makeParserText($vars['sidebar_section_raw']);
+ $c = $row['block_content'];
+ $c = preg_replace('#<a (.*?)>(.*?)</a>#is', '<a href="#" onclick="return false;">\\2</a>', $c);
+ break;
+ case BLOCK_PHP:
+ $parser = $template->makeParserText($vars['sidebar_section_raw']);
+ ob_start();
+ eval($row['block_content']);
+ $c = ob_get_contents();
+ ob_end_clean();
+ $c = preg_replace('#<a (.*?)>(.*?)</a>#is', '<a href="#" onclick="return false;">\\2</a>', $c);
+ break;
+ case BLOCK_PLUGIN:
+ $parser = $template->makeParserText($vars['sidebar_section_raw']);
+ $c = ($template->fetch_block($row['block_content'])) ? $template->fetch_block($row['block_content']) : 'Can\'t find plugin block';
+ break;
+ }
+ $t = $template->tplWikiFormat($row['block_name']);
+ if($row['item_enabled'] == 0) $t .= ' <span id="disabled_'.$row['item_id'].'" style="color: red;">(disabled)</span>';
+ else $t .= ' <span id="disabled_'.$row['item_id'].'" style="color: red; display: none;">(disabled)</span>';
+ $side = ( $row['sidebar_id'] == SIDEBAR_LEFT ) ? SIDEBAR_RIGHT : SIDEBAR_LEFT;
+ $tb = '<a title="Enable or disable this block" href="'.makeUrl($paths->page, 'action=disenable&id='.$row['item_id'].'' , true).'" onclick="ajaxDisenableBlock(\''.$row['item_id'].'\'); return false;" ><img alt="Enable/disable this block" style="border-width: 0;" src="'.scriptPath.'/images/disenable.png" /></a>
+ <a title="Edit the contents of this block" href="'.makeUrl($paths->page, 'action=edit&id='.$row['item_id'].'' , true).'" onclick="ajaxEditBlock(\''.$row['item_id'].'\', this); return false;"><img alt="Edit this block" style="border-width: 0;" src="'.scriptPath.'/images/edit.png" /></a>
+ <a title="Permanently delete this block" href="'.makeUrl($paths->page, 'action=delete&id='.$row['item_id'].'' , true).'" onclick="if(confirm(\'Do you really want to delete this block?\')) { ajaxDeleteBlock(\''.$row['item_id'].'\', this); } return false;"><img alt="Delete this block" style="border-width: 0;" src="'.scriptPath.'/images/delete.png" /></a>
+ <a title="Move this block to the other sidebar" href="'.makeUrl($paths->page, 'action=move&id='.$row['item_id'].'&side='.$side, true).'"><img alt="Move this block" style="border-width: 0;" src="'.scriptPath.'/images/move.png" /></a>';
+ $as = '';
+ $ae = ' '.$tb;
+ $parser->assign_vars(Array('CONTENT'=>$c,'TITLE'=>$t,'ADMIN_START'=>$as,'ADMIN_END'=>$ae));
+ echo $parser->run();
+ unset($parser);
+
+ }
+ $db->free_result();
+ //if(isset($vars['sidebar_top'])) echo $template->parse($vars['sidebar_bottom']);
+ echo '</div></td></tr></table>';
+ echo '<form action="'.makeUrl($paths->page).'" method="post">';
+ $order = implode(',', $n1);
+ echo "<input type='hidden' id='divOrder_Left' name='order_left' value='{$order}' />";
+ $order = implode(',', $n2);
+ echo "<input type='hidden' id='divOrder_Right' name='order_right' value='{$order}' />";
+ echo '
+ <div style="margin: 0 auto 0 auto; text-align: center;">
+ <input type="submit" name="save" style="font-weight: bold;" value="Save changes" />
+ <input type="submit" name="revert" style="font-weight: normal;" value="Revert" onclick="return confirm(\'Do you really want to revert your changes?\nNote: this does not revert edits or deletions, those are saved as soon as you confirm the action.\')" />
+ <br />
+ <a href="'.makeUrl($paths->page, 'action=new&id=0', true).'">Create new block</a> | <a href="'.makeUrl(getConfig('main_page'), false, true).'">Main Page</a>
+ </div>
+ </form>
+ ';
+ }
+
+ $template->footer();
+}
+
+?>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/SpecialAdmin.php~ Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,2722 @@
+<?php
+/*
+Plugin Name: Runt - the Enano administration panel
+Plugin URI: http://enanocms.org/
+Description: Provides the page Special:Administration, which is the AJAX frontend to the various Admin:
+Author: Dan Fuhry
+Version: 1.0
+Author URI: http://enanocms.org/
+*/
+
+/*
+ * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
+ * Version 1.0 release candidate 2
+ * Copyright (C) 2006-2007 Dan Fuhry
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+global $db, $session, $paths, $template, $plugins; // Common objects
+
+$plugins->attachHook('base_classes_initted', '
+ global $paths;
+ $paths->add_page(Array(
+ \'name\'=>\'Administration\',
+ \'urlname\'=>\'Administration\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'Manage the Sidebar\',
+ \'urlname\'=>\'EditSidebar\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ ');
+
+// function names are IMPORTANT!!! The name pattern is: page_<namespace ID>_<page URLname, without namespace>
+
+function page_Admin_Home() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+
+ // Basic information
+ echo RenderMan::render(
+'== Welcome to Runt, the Enano administration panel. ==
+
+Thank you for choosing Enano as your CMS. This screen allows you to see some information about your website, plus some details about how your site is doing statistically.
+
+Using the links on the left you can control every aspect of your website\'s look and feel, plus you can manage users, work with pages, and install plugins to make your Enano installation even better.');
+
+ // Check for the installer scripts
+ if(file_exists(ENANO_ROOT.'/install.php') || file_exists(ENANO_ROOT.'/schema.sql'))
+ {
+ echo '<div class="error-box"><b>NOTE:</b> It appears that your install.php and/or schema.sql files still exist. It is HIGHLY RECOMMENDED that you delete or rename these files, to prevent getting your server hacked.</div>';
+ }
+
+ // Inactive users
+ $q = $db->sql_query('SELECT * FROM '.table_prefix.'logs WHERE log_type=\'admin\' AND action=\'activ_req\';');
+ if($q)
+ if($db->numrows() > 0)
+ {
+ $n = $db->numrows();
+ if($n == 1) $s = $n . ' user is';
+ else $s = $n . ' users are';
+ echo '<div class="warning-box">It appears that '.$s.' awaiting account activation. You can activate those accounts by going to the <a href="#" onclick="ajaxPage(\''.$paths->nslist['Admin'].'UserManager\'); return false;">User Manager</a>.</div>';
+ }
+ $db->free_result();
+ // Stats
+ if(getConfig('log_hits') == '1')
+ {
+ $stats = stats_top_pages(10);
+ $c = 0;
+ $cls = 'row2';
+ echo '<h3>Most requested pages</h3><div class="tblholder"><table style="width: 100%;" border="0" cellspacing="1" cellpadding="4"><tr><th>Page</th><th>Hits</th></tr>';
+ foreach($stats as $page => $count)
+ {
+ if(isset($paths->pages[$page]))
+ {
+ echo '<tr>';
+ $cls = ( $cls == 'row1' ) ? 'row2' : 'row1';
+ echo '<td class="'.$cls.'"><a href="'.makeUrl($page).'">'.$paths->pages[$page]['name'].'</a></td><td style="text-align: center;" class="'.$cls.'">'.$count.'</td>';
+ echo '</tr>';
+ }
+ }
+ echo '</table></div>';
+ }
+
+ // Security log
+ echo '<h3>Security log</h3>';
+ echo '<div class="tblholder" style="/* max-height: 500px; clip: rect(0px,auto,auto,0px); overflow: auto; */"><table border="0" cellspacing="1" cellpadding="4" width="100%">';
+ $cls = 'row2';
+ echo '<tr><th style="width: 60%;">Type</th><th>Date</th><th>Username</th><th>IP Address</th></tr>';
+ if(isset($_GET['fulllog']))
+ {
+ $l = 'SELECT action,date_string,author,edit_summary,time_id,page_text FROM '.table_prefix.'logs WHERE log_type=\'security\' ORDER BY time_id DESC, action ASC;';
+ }
+ else
+ {
+ $l = 'SELECT action,date_string,author,edit_summary,time_id,page_text FROM '.table_prefix.'logs WHERE log_type=\'security\' ORDER BY time_id DESC, action ASC LIMIT 5';
+ }
+ $q = $db->sql_query($l);
+ while($r = $db->fetchrow())
+ {
+ if($cls == 'row2') $cls = 'row1';
+ else $cls = 'row2';
+ echo '<tr><td class="'.$cls.'">';
+ switch($r['action']) {
+ case "admin_auth_good": echo 'Successful elevated authentication'; if ( !empty($r['page_text']) ) { $level = $session->userlevel_to_string( intval($r['page_text']) ); echo "<br /><small>Authentication level: $level</small>"; } break;
+ case "admin_auth_bad": echo 'Failed administration logon'; break;
+ case "activ_good": echo 'Successful account activation'; break;
+ case "auth_good": echo 'Successful regular user logon'; break;
+ case "activ_bad": echo 'Failed account activation'; break;
+ case "auth_bad": echo 'Failed regular user logon'; break;
+ case "sql_inject": echo 'SQL injection attempt<div style="max-width: 90%; clip: rect(0px,auto,auto,0px); overflow: auto; display: block; font-size: smaller;">Offending query: ' . htmlspecialchars($r['page_text']) . '</div>'; break;
+ case "db_backup": echo 'Database backup created<br /><small>Tables: ' . $r['page_text'] . '</small>'; break;
+ case "install_enano": echo "Installed Enano version {$r['page_text']}"; break;
+ }
+ echo '</td><td class="'.$cls.'">'.date('d M Y h:i a', $r['time_id']).'</td><td class="'.$cls.'">'.$r['author'].'</td><td class="'.$cls.'" style="cursor: pointer;" onclick="ajaxReverseDNS(this);" title="Click for reverse DNS info">'.$r['edit_summary'].'</td></tr>';
+ }
+ $db->free_result();
+ echo '</table></div>';
+ if(!isset($_GET['fulllog'])) echo '<p><a href="#" onclick="ajaxPage(\''.$paths->nslist['Admin'].'Home&fulllog\'); return false;">Full security log</a></p>';
+
+}
+
+function page_Admin_GeneralConfig() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ if(isset($_POST['submit'])) {
+
+ // Global site options
+ setConfig('site_name', $_POST['site_name']);
+ setConfig('site_desc', $_POST['site_desc']);
+ setConfig('main_page', str_replace(' ', '_', $_POST['main_page']));
+ setConfig('copyright_notice', $_POST['copyright']);
+ setConfig('contact_email', $_POST['contact_email']);
+
+ // Wiki mode
+ if(isset($_POST['wikimode'])) setConfig('wiki_mode', '1');
+ else setConfig('wiki_mode', '0');
+ if(isset($_POST['wiki_mode_require_login'])) setConfig('wiki_mode_require_login', '1');
+ else setConfig('wiki_mode_require_login', '0');
+ if(isset($_POST['editmsg'])) setConfig('wiki_edit_notice', '1');
+ else setConfig('wiki_edit_notice', '0');
+ setConfig('wiki_edit_notice_text', $_POST['editmsg_text']);
+
+ // Stats
+ if(isset($_POST['log_hits'])) setConfig('log_hits', '1');
+ else setConfig('log_hits', '0');
+
+ // Disablement
+ if(isset($_POST['site_disabled'])) { setConfig('site_disabled', '1'); setConfig('site_disabled_notice', $_POST['site_disabled_notice']); }
+ else setConfig('site_disabled', '0');
+
+ // Account activation
+ setConfig('account_activation', $_POST['account_activation']);
+
+ // W3C compliance buttons
+ if(isset($_POST['w3c-vh32'])) setConfig("w3c_vh32", "1");
+ else setConfig("w3c_vh32", "0");
+ if(isset($_POST['w3c-vh40'])) setConfig("w3c_vh40", "1");
+ else setConfig("w3c_vh40", "0");
+ if(isset($_POST['w3c-vh401'])) setConfig("w3c_vh401", "1");
+ else setConfig("w3c_vh401", "0");
+ if(isset($_POST['w3c-vxhtml10'])) setConfig("w3c_vxhtml10", "1");
+ else setConfig("w3c_vxhtml10", "0");
+ if(isset($_POST['w3c-vxhtml11'])) setConfig("w3c_vxhtml11", "1");
+ else setConfig("w3c_vxhtml11", "0");
+ if(isset($_POST['w3c-vcss'])) setConfig("w3c_vcss", "1");
+ else setConfig("w3c_vcss", "0");
+
+ // SourceForge.net logo
+ if(isset($_POST['showsf'])) setConfig('sflogo_enabled', '1');
+ else setConfig('sflogo_enabled', '0');
+ setConfig('sflogo_groupid', $_POST['sfgroup']);
+ setConfig('sflogo_type', $_POST['sflogo']);
+
+ // Comment options
+ if(isset($_POST['comment-approval'])) setConfig('approve_comments', '1');
+ else setConfig('approve_comments', '0');
+ if(isset($_POST['enable-comments'])) setConfig('enable_comments', '1');
+ else setConfig('enable_comments', '0');
+ setConfig('comments_need_login', $_POST['comments_need_login']);
+
+ // Powered by link
+ if ( isset($_POST['enano_powered_link']) ) setConfig('powered_btn', '1');
+ else setConfig('powered_btn', '0');
+
+ if(isset($_POST['dbdbutton'])) setConfig('dbd_button', '1');
+ else setConfig('dbd_button', '0');
+
+ if($_POST['emailmethod'] == 'phpmail') setConfig('smtp_enabled', '0');
+ else setConfig('smtp_enabled', '1');
+
+ setConfig('smtp_server', $_POST['smtp_host']);
+ setConfig('smtp_user', $_POST['smtp_user']);
+ if($_POST['smtp_pass'] != 'XXXXXXXXXXXX') setConfig('smtp_password', $_POST['smtp_pass']);
+
+ echo '<div class="info-box">Your changes to the site configuration have been saved.</div><br />';
+
+ }
+ echo('<form name="main" action="'.htmlspecialchars(makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module'])).'" method="post" onsubmit="if(!submitAuthorized) return false;">');
+ ?>
+ <div class="tblholder">
+ <table border="0" width="100%" cellspacing="1" cellpadding="4">
+
+ <!-- Global options -->
+
+ <tr><th colspan="2">Global site options</th></tr>
+ <tr><th colspan="2" class="subhead">These options control the entire site.</th></tr>
+
+ <tr><td class="row1" style="width: 50%;">Site name:</td> <td class="row1" style="width: 50%;"><input name="site_name" size="30" value="<?php echo getConfig('site_name'); ?>" /></td></tr>
+ <tr><td class="row2">Site description:</td> <td class="row2"><input name="site_desc" size="30" value="<?php echo getConfig('site_desc'); ?>" /></td></tr>
+ <tr><td class="row1">Main page:</td> <td class="row1"><?php echo $template->pagename_field('main_page', str_replace('_', ' ', getConfig('main_page'))); ?></td></tr>
+ <tr><td class="row2">Copyright notice shown on pages:</td><td class="row2"><input name="copyright" size="30" value="<?php echo getConfig('copyright_notice'); ?>" /></td></tr>
+ <tr><td class="row1" colspan="2">Hint: If you're using Windows, you can make a "©" symbol by holding ALT and pressing 0169 on the numeric keypad.</td></tr>
+ <tr><td class="row2">Contact e-mail<br /><small>All e-mail sent from this site will appear to have come from the address shown here.</small></td><td class="row2"><input name="contact_email" type="text" size="40" value="<?php echo htmlspecialchars(getConfig('contact_email')); ?>" /></td></tr>
+
+ <!-- Wiki mode -->
+
+ <tr><th colspan="2">Wiki mode</th></tr>
+
+ <tr>
+ <td class="row3" rowspan="2">
+ Enano can also act as a wiki, meaning anyone can edit and create pages. To enable Wiki Mode, check the box to the right.<br /><br />
+ In Wiki Mode, certain HTML tags such as <script> and <object> are disabled, and all PHP code is disabled, except if the person editing the page is an administrator.<br /><br />
+ Also, Enano keeps complete page history, which makes restoring vandalized pages easy. You can also protect pages so that they cannot be edited.
+ </td>
+ <td class="row1">
+ <input type="checkbox" name="wikimode" id="wikimode" <?php if(getConfig('wiki_mode')=='1') echo('CHECKED '); ?> /><label for="wikimode">Enable Wiki Mode</label>
+ </td>
+ </tr>
+
+ <tr><td class="row2"><label><input type="checkbox" name="wiki_mode_require_login"<?php if(getConfig('wiki_mode_require_login')=='1') echo('CHECKED '); ?>/> Only for logged in users</label></td></tr>
+
+ <tr>
+ <td class="row3" rowspan="2">
+ <b>Edit page notice</b><br />
+ When Wiki Mode is enabled, anyone can edit pages. Check the box below and enter a message to display it whenever the page editor is opened.
+ </td>
+ <td class="row1">
+ <input onclick="if(this.checked) document.getElementById('editmsg_text').style.display='block'; else document.getElementById('editmsg_text').style.display='none';" type="checkbox" name="editmsg" id="editmsg" <?php if(getConfig('wiki_edit_notice')=='1') echo('CHECKED '); ?>/> <label for="editmsg">Show a message whenever pages are edited</label>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="row2">
+ <textarea <?php if(getConfig('wiki_edit_notice')!='1') echo('style="display:none" '); ?>rows="5" cols="30" name="editmsg_text" id="editmsg_text"><?php echo getConfig('wiki_edit_notice_text'); ?></textarea>
+ </td>
+ </tr>
+
+ <!-- Site statistics -->
+
+ <tr><th colspan="2">Statistics and hit counting</th></tr>
+
+ <tr>
+ <td class="row1">Enano has the ability to show statistics for every page on the site. This allows you to keep very close track of who is visiting your site, and from where.<br /><br />Unfortunately, some users don't like being logged. For this reason, you should state clearly what is logged (usually the username or IP address, current time, page name, and referer URL) in your privacy policy.</td>
+ <td class="row1"><label><input type="checkbox" name="log_hits" <?php if(getConfig('log_hits') == '1') echo 'checked="checked" '; ?>/> Log all page hits</label><br /><small>This excludes special and administration pages.</small></td>
+ </tr>
+
+ <!-- Comment options -->
+
+ <tr><th colspan="2">Comment system</th></tr>
+ <tr><td class="row1"><label for="enable-comments"><b>Enable the comment system</b></label> </td><td class="row1"><input name="enable-comments" id="enable-comments" type="checkbox" <?php if(getConfig('enable_comments')=='1') echo('CHECKED '); ?>/></td></tr>
+ <tr><td class="row2"><label for="comment-approval">Require approval before article comments can be shown</label></td><td class="row2"><input name="comment-approval" id="comment-approval" type="checkbox" <?php if(getConfig('approve_comments')=='1') echo('CHECKED '); ?>/></td></tr>
+ <tr><td class="row1">Guest comment posting allowed </td><td class="row1"><label><input name="comments_need_login" type="radio" value="0" <?php if(getConfig('comments_need_login')=='0') echo 'CHECKED '; ?>/> Yes</label>
+ <label><input name="comments_need_login" type="radio" value="1" <?php if(getConfig('comments_need_login')=='1') echo 'CHECKED '; ?>/> Require visual confirmation</label>
+ <!-- Default permissions --> <label><input name="comments_need_login" type="radio" value="2" <?php if(getConfig('comments_need_login')=='2') echo 'CHECKED '; ?>/> No (require login)</label></td></tr>
+
+ <!--
+
+ READ: Do not try to enable this, backend support for it has been disabled. To edit default
+ permissions, select The Entire Website in any permissions editor window.
+
+ <tr><th colspan="2">Default permissions for pages</th></tr>
+
+ <tr>
+ <td class="row1">You can edit the default set of permissions used when no other permissions are available. Permissions set here are used when no other permissions are available. As with other ACL rules, you can assign these defaults to every user or one specific user or group.</td>
+ <td class="row1"><a href="#" onclick="ajaxOpenACLManager('__DefaultPermissions', 'Special'); return false;">Manage default permissions</a></td>
+ </tr>
+
+ -->
+
+ <!-- enanocms.org link -->
+
+ <tr>
+ <th colspan="2">Promote Enano</th>
+ </tr>
+ <tr>
+ <td class="row3">
+ If you think Enano is nice, or if you want to show your support for the Enano team, you can do so by placing a link to the Enano
+ homepage in your Links sidebar block. You absolutely don't have to do this, and you won't get degraded support if you don't. Because
+ Enano is still relatively new in the CMS world, it needs all the attention it can get - and you can easily help to spread the word
+ using this link.
+ </td>
+ <td class="row1">
+ <label>
+ <input name="enano_powered_link" type="checkbox" <?php if(getConfig('powered_btn') == '1') echo 'checked="checked"'; ?> /> Place a link to www.enanocms.org on the sidebar
+ </label>
+ </td>
+ </tr>
+
+ <!-- Site disablement -->
+
+ <tr><th colspan="2">Disable all site access</th></tr>
+
+ <tr>
+ <td class="row3" rowspan="2">Disabling the site allows you to work on the site without letting non-administrators see or use it.</td>
+ <td class="row1"><label><input onclick="if(this.checked) document.getElementById('site_disabled_notice').style.display='block'; else document.getElementById('site_disabled_notice').style.display='none';" type="checkbox" name="site_disabled" <?php if(getConfig('site_disabled') == '1') echo 'checked="checked" '; ?>/> Disable this site</label></td>
+ </tr>
+ <tr>
+ <td class="row2">
+ <div id="site_disabled_notice">
+ Message to show to users:<br />
+ <textarea name="site_disabled_notice" rows="7" cols="30"><?php echo getConfig('site_disabled_notice'); ?></textarea>
+ </div>
+ </td>
+ </tr>
+
+ <!-- Account activation -->
+
+ <tr><th colspan="2">User account activation</th></tr>
+
+ <tr>
+ <td class="row3" colspan="2">
+ If you would like to require users to confirm their e-mail addresses by way of account activation, you can enable this behavior here. If this option is set to "None", users will be able to register and use this site without confirming their e-mail addresses. If this option is set to "User", users will automatically be sent e-mails upon registration with a link to activate their accounts. And lastly, if this option is set to "Admin", users' accounts will not be active until an administrator activates the account.<br /><br />
+ You may also disable registration completely if needed.<br /><br />
+ <b>Note: because of abuse by project administrators, sending account activation e-mails will not work on SourceForge.net servers.</b>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="row1">Account activation:</td><td class="row1">
+ <?php
+ echo '<label><input'; if(getConfig('account_activation') == 'disable') echo ' checked="checked"'; echo ' type="radio" name="account_activation" value="disable" /> Disable registration</label><br />';
+ echo '<label><input'; if(getConfig('account_activation') != 'user' && getConfig('account_activation') != 'admin') echo ' checked="checked"'; echo ' type="radio" name="account_activation" value="none" /> None</label>';
+ echo '<label><input'; if(getConfig('account_activation') == 'user') echo ' checked="checked"'; echo ' type="radio" name="account_activation" value="user" /> User</label>';
+ echo '<label><input'; if(getConfig('account_activation') == 'admin') echo ' checked="checked"'; echo ' type="radio" name="account_activation" value="admin" /> Admin</label>';
+ ?>
+ </td>
+ </tr>
+
+ <!-- E-mail options -->
+
+ <tr><th colspan="2">E-mail sent from the site</th></tr>
+ <tr><td class="row1">E-mail sending method:<br /><small>Try using the built-in e-mail method first. If that doesn't work, you will need to enter valid SMTP information here.</small></td>
+ <td class="row1"><label><input <?php if(getConfig('smtp_enabled') != '1') echo 'checked="checked"'; ?> type="radio" name="emailmethod" value="phpmail" />PHP's built-in mail() function</label><br />
+ <label><input <?php if(getConfig('smtp_enabled') == '1') echo 'checked="checked"'; ?> type="radio" name="emailmethod" value="smtp" />Use an external SMTP server</label></td>
+ </tr>
+ <tr><td class="row2">SMTP hostname:<br /><small>This option only applies to the external SMTP mode.</small></td>
+ <td class="row2"><input value="<?php echo getConfig('smtp_server'); ?>" name="smtp_host" type="text" size="30" /></td>
+ </tr>
+ <tr><td class="row1">SMTP credentials:<br /><small>This option only applies to the external SMTP mode.</small></td>
+ <td class="row1">Username: <input value="<?php echo getConfig('smtp_user'); ?>" name="smtp_user" type="text" size="30" /><br />
+ Password: <input value="<?php if(getConfig('smtp_password') != false) echo 'XXXXXXXXXXXX'; ?>" name="smtp_pass" type="password" size="30" /></td>
+ </tr>
+
+ <!-- SourceForge.net logo -->
+
+ <tr><th colspan="2">SourceForge.net logo</th></tr>
+
+ <tr>
+ <td colspan="2" class="row3">
+ All projects hosted by SourceForge.net are required to display an official SourceForge.net logo on their pages. If you want
+ to display a SourceForge.net logo on the sidebar, check the box below, enter your group ID, and select an image type.
+ </td>
+ </tr>
+
+ <?php
+ if(getConfig("sflogo_enabled")=='1') $c='CHECKED ';
+ else $c='';
+ if(getConfig("sflogo_groupid")) $g=getConfig("sflogo_groupid");
+ else $g='';
+ if(getConfig("sflogo_type")) $t=getConfig("sflogo_type");
+ else $t='1';
+ ?>
+
+ <tr>
+ <td class="row1">Display the SourceForge.net logo on the right sidebar</td>
+ <td class="row1"><input type=checkbox name="showsf" id="showsf" <?php echo $c; ?> /></td>
+ </tr>
+
+ <tr>
+ <td class="row2">Group ID:</td>
+ <td class="row2"><input value="<?php echo $g; ?>" type=text size=15 name=sfgroup /></td>
+ </tr>
+
+ <tr>
+ <td class="row1">Logo style:</td>
+ <td class="row1">
+ <select name="sflogo">
+ <option <?php if($t=='1') echo('SELECTED '); ?>value=1>88x31px, white</option>
+ <option <?php if($t=='2') echo('SELECTED '); ?>value=2>125x37px, white</option>
+ <option <?php if($t=='3') echo('SELECTED '); ?>value=3>125x37px, black</option>
+ <option <?php if($t=='4') echo('SELECTED '); ?>value=4>125x37px, blue</option>
+ <option <?php if($t=='5') echo('SELECTED '); ?>value=5>210x62px, white</option>
+ <option <?php if($t=='6') echo('SELECTED '); ?>value=6>210x62px, black</option>
+ <option <?php if($t=='7') echo('SELECTED '); ?>value=7>210x62px, blue</option>
+ </select>
+ </td>
+ </tr>
+
+ <!-- W3C validator buttons -->
+
+ <tr><th colspan="2">W3C compliance logos</th></tr>
+ <tr><th colspan="2" class="subhead">Enano generates (by default) Valid XHTML 1.1 code, plus valid CSS. If you want to show this off, check the appropriate boxes below.</th></tr>
+
+ <tr><td class="row1"><label for="w3c-vh32">HTML 3.2</label> </td><td class="row1"><input type="checkbox" <?php if(getConfig('w3c_vh32')=='1') echo('CHECKED '); ?> id="w3c-vh32" name="w3c-vh32" /></td></tr>
+ <tr><td class="row2"><label for="w3c-vh40">HTML 4.0</label> </td><td class="row2"><input type="checkbox" <?php if(getConfig('w3c_vh40')=='1') echo('CHECKED '); ?> id="w3c-vh40" name="w3c-vh40" /></td></tr>
+ <tr><td class="row1"><label for="w3c-vh401">HTML 4.01</label> </td><td class="row1"><input type="checkbox" <?php if(getConfig('w3c_vh401')=='1') echo('CHECKED '); ?> id="w3c-vh401" name="w3c-vh401" /></td></tr>
+ <tr><td class="row2"><label for="w3c-vxhtml10">XHTML 1.0</label></td><td class="row2"><input type="checkbox" <?php if(getConfig('w3c_vxhtml10')=='1') echo('CHECKED '); ?> id="w3c-vxhtml10" name="w3c-vxhtml10" /></td></tr>
+ <tr><td class="row1"><label for="w3c-vxhtml11">XHTML 1.1</label></td><td class="row1"><input type="checkbox" <?php if(getConfig('w3c_vxhtml11')=='1') echo('CHECKED '); ?> id="w3c-vxhtml11" name="w3c-vxhtml11" /></td></tr>
+ <tr><td class="row2"><label for="w3c-vcss">CSS</label> </td><td class="row2"><input type="checkbox" <?php if(getConfig('w3c_vcss')=='1') echo('CHECKED '); ?> id="w3c-vcss" name="w3c-vcss" /></td></tr>
+
+ <!-- DefectiveByDesign.org ad -->
+
+ <tr><th colspan="2">Defective By Design Anti-DRM button</th></tr>
+ <tr><td colspan="2" class="row3"><b>The Enano project is strongly against Digital Restrictions Management.</b> DRM removes the freedoms that every consumer should have: to freely copy and use digital media items they legally purchased to their own devices. Showing your opposition to DRM is as easy as checking the box below to place a link to <a href="http://www.defectivebydesign.org">DefectiveByDesign.org</a> on your sidebar.</td></tr>
+ <tr><td class="row1"><label for="dbdbutton">Help stop DRM by placing a link to DBD on the sidebar!</label></td><td class="row1"><input type="checkbox" name="dbdbutton" id="dbdbutton" <?php if(getConfig('dbd_button')=='1') echo('checked="checked" '); ?>/></td></tr>
+
+ <!-- Save button -->
+
+ <tr><th style="text-align: right" class="subhead" colspan="2"><input type=submit name=submit value="Save changes" /></th></tr>
+
+ </table>
+ </div>
+</form>
+ <?php
+}
+
+function page_Admin_UploadConfig()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ if(isset($_POST['save']))
+ {
+ if(isset($_POST['enable_uploads'])) setConfig('enable_uploads', '1'); else setConfig('enable_uploads', '0');
+ if(isset($_POST['enable_imagemagick'])) setConfig('enable_imagemagick', '1'); else setConfig('enable_imagemagick', '0');
+ if(isset($_POST['cache_thumbs'])) setConfig('cache_thumbs', '1'); else setConfig('cache_thumbs', '0');
+ if(isset($_POST['file_history'])) setConfig('file_history', '1'); else setConfig('file_history', '0');
+ if(file_exists($_POST['imagemagick_path'])) setConfig('imagemagick_path', $_POST['imagemagick_path']);
+ else echo '<span style="color: red"><b>Warning:</b> the file "'.$_POST['imagemagick_path'].'" was not found, and the ImageMagick file path was not updated.</span>';
+ $max_upload = floor((float)$_POST['max_file_size'] * (int)$_POST['fs_units']);
+ setConfig('max_file_size', $max_upload.'');
+ }
+ echo '<form name="main" action="'.htmlspecialchars(makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module'])).'" method="post">';
+ ?>
+ <h3>File upload configuration</h3>
+ <p>Enano supports the ability to upload files to your website and store the files in the database. This enables you to embed images
+ and such into pages without manually writing the HTML. However, the upload feature can sometimes pose a risk to your site, as viruses
+ and executable files can sometimes be uploaded.</p>
+ <p><label><input type="checkbox" name="enable_uploads" <?php if(getConfig('enable_uploads')=='1') echo 'checked="checked"'; ?> /> <b>Enable file uploads</b></label></p>
+ <p>Maximum file size: <input name="max_file_size" onkeyup="if(!this.value.match(/^([0-9\.]+)$/ig)) this.value = this.value.substr(0,this.value.length-1);" value="<?php echo getConfig('max_file_size'); ?>" /> <select name="fs_units"><option value="1" selected="selected">bytes</option><option value="1024">KB</option><option value="1048576">MB</option></select></p>
+ <p>You can allow Enano to generate thumbnails of images automatically. This feature requires ImageMagick to work properly. If your server
+ does not have ImageMagick on it, Enano will simply make your users' browsers scale the images. In most cases this is fine, but if you
+ are uploading large (>100KB) images and embedding them inside of pages, you should try to enable ImageMagick because transferring these
+ large images many times can cost you quite a lot of bandwidth.</p>
+ <p><label><input type="checkbox" name="enable_imagemagick" <?php if(getConfig('enable_imagemagick')=='1') echo 'checked="checked"'; ?> /> Use ImageMagick to scale images</label><br />
+ Path to ImageMagick: <input type="text" name="imagemagick_path" value="<?php if(getConfig('imagemagick_path')) echo getConfig('imagemagick_path'); else echo '/usr/bin/convert'; ?>" /><br />
+ On Linux and Unix servers, the most likely options here are /usr/bin/convert and /usr/local/bin/convert. If you server runs Windows, then
+ ImageMagick is most likely to be C:\Windows\Convert.exe or C:\Windows\System32\Convert.exe.
+ </p>
+ <p>If you use ImageMagick to scale images, your server will be very busy constantly scaling images if your website is busy, and your site
+ may experience slowdowns. You can dramatically speed up this scaling process if you use a directory to cache thumbnail images.</p>
+ <p><b>Please note:</b> the cache/ directory on your server <u>must</u> be writable by the server. While this is not usually a problem on
+ Windows servers, most Linux/Unix servers will require you to CHMOD the cache/ directory to 777. See your FTP client's user guide for
+ more information on how to do this.<?php if(!is_writable(ENANO_ROOT.'/cache/')) echo ' <b>At present, it seems that the cache directory
+ is not writable. The checkbox below has been disabled to maintain the stability of Enano.</b>'; ?></p>
+ <p><label><input type="checkbox" name="cache_thumbs" <?php if(getConfig('cache_thumbs')=='1' && is_writable(ENANO_ROOT.'/cache/')) echo 'checked="checked"'; elseif(!is_writable(ENANO_ROOT.'/cache/')) echo 'readonly="readonly"'; ?> /> Cache thumbnailed images</label></p>
+ <p>Lastly, you can choose whether file history will be saved. If this option is turned on, you will be able to roll back any malicious
+ changes made to uploaded files, but this requires a significant amount of database storage. You should probably leave this option
+ enabled unless you have less than 250MB of MySQL database space.</p>
+ <p><label><input type="checkbox" name="file_history" <?php if(getConfig('file_history')=='1' && is_writable(ENANO_ROOT.'/cache/')) echo 'checked="checked"'; ?> /> Keep a history of uploaded files</label></p>
+ <hr style="margin-left: 1em;" />
+ <p><input type="submit" name="save" value="Save changes" style="font-weight: bold;" /></p>
+ <?php
+ echo '</form>';
+}
+
+function page_Admin_PluginManager() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+
+ if(isset($_GET['action'])) {
+ switch($_GET['action']) {
+ case "enable":
+ setConfig('plugin_'.$_GET['plugin'], '1');
+ break;
+ case "disable":
+ if($_GET['plugin']!='admin.php') setConfig('plugin_'.$_GET['plugin'], '0');
+ else echo('<h3>Error disabling plugin</h3><p>The administration panel plugin cannot be disabled.</p>');
+ break;
+ }
+ }
+ $dir = './plugins/';
+ $plugin_list = Array();
+ $system = Array();
+ if (is_dir($dir)) {
+ if ($dh = opendir($dir)) {
+ while (($file = readdir($dh)) !== false) {
+ if(preg_match('#^(.*?)\.php$#is', $file) && $file != 'index.php')
+ {
+ if ( in_array($file, $plugins->system_plugins) )
+ {
+ $thelist =& $system;
+ continue;
+ }
+ else
+ {
+ $thelist =& $plugin_list;
+ }
+ $f = file_get_contents($dir . $file);
+ $f = explode("\n", $f);
+ $f = array_slice($f, 2, 7);
+ $f[0] = substr($f[0], 13, strlen($f[0]));
+ $f[1] = substr($f[1], 12, strlen($f[1]));
+ $f[2] = substr($f[2], 13, strlen($f[2]));
+ $f[3] = substr($f[3], 8, strlen($f[3]));
+ $f[4] = substr($f[4], 9, strlen($f[4]));
+ $f[5] = substr($f[5], 12, strlen($f[5]));
+ $thelist[$file] = Array();
+ $thelist[$file]['name'] = $f[0];
+ $thelist[$file]['uri'] = $f[1];
+ $thelist[$file]['desc'] = $f[2];
+ $thelist[$file]['auth'] = $f[3];
+ $thelist[$file]['vers'] = $f[4];
+ $thelist[$file]['aweb'] = $f[5];
+ }
+ }
+ closedir($dh);
+ }
+ }
+ echo('<div class="tblholder"><table border="0" width="100%" cellspacing="1" cellpadding="4">
+ <tr><th>Plugin filename</th><th>Plugin name</th><th>Description</th><th>Author</th><th>Version</th><th></th></tr>');
+ $plugin_files = array_keys($plugin_list);
+ $cls = 'row2';
+ for ( $i = 0; $i < sizeof($plugin_files); $i++ )
+ {
+ $cls = ( $cls == 'row2' ) ? 'row3' : 'row2';
+ echo '<tr>
+ <td class="'.$cls.'">'.$plugin_files[$i].'</td>
+ <td class="'.$cls.'"><a href="'.$plugin_list[$plugin_files[$i]]['uri'].'">'.$plugin_list[$plugin_files[$i]]['name'].'</a></td>
+ <td class="'.$cls.'">'.$plugin_list[$plugin_files[$i]]['desc'].'</td>
+ <td class="'.$cls.'"><a href="'.$plugin_list[$plugin_files[$i]]['aweb'].'">'.$plugin_list[$plugin_files[$i]]['auth'].'</a></td>
+ <td class="'.$cls.'">'.$plugin_list[$plugin_files[$i]]['vers'].'</td>
+ <td class="'.$cls.'">';
+ if ( getConfig('plugin_'.$plugin_files[$i]) == '1' )
+ {
+ echo '<a href="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'&action=disable&plugin='.$plugin_files[$i].'">Disable</a>';
+ }
+ else
+ {
+ echo '<a href="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'&action=enable&plugin='.$plugin_files[$i].'">Enable</a>';
+ }
+ echo '</td></tr>';
+ }
+ echo '</table></div>';
+}
+
+function page_Admin_UploadAllowedMimeTypes()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ global $mime_types, $mimetype_exps, $mimetype_extlist;
+ if(isset($_POST['save']))
+ {
+ $bits = '';
+ $keys = array_keys($mime_types);
+ foreach($keys as $i => $k)
+ {
+ if(isset($_POST['ext_'.$k])) $bits .= '1';
+ else $bits .= '0';
+ }
+ $bits = compress_bitfield($bits);
+ setConfig('allowed_mime_types', $bits);
+ echo '<div class="info-box">Your changes have been saved.</div>';
+ }
+ $allowed = fetch_allowed_extensions();
+ ?>
+ <h3>Allowed file types</h3>
+ <p>Using the form below, you can decide which file types are allowed to be uploaded to this site.</p>
+ <?php
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', (( isset($_GET['sqldbg'])) ? 'sqldbg&' : '') .'module='.$paths->cpage['module']).'" method="post">';
+ $c = -1;
+ $t = -1;
+ $cl = 'row1';
+ echo "\n".' <div class="tblholder">'."\n".' <table cellspacing="1" cellpadding="2" style="margin: 0; padding: 0;" border="0">'."\n".' <tr>'."\n ";
+ foreach($mime_types as $e => $m)
+ {
+ $c++;
+ $t++;
+ if($c == 3)
+ {
+ $c = 0;
+ $cl = ( $cl == 'row1' ) ? 'row2' : 'row1';
+ echo '</tr>'."\n".' <tr>'."\n ";
+ }
+ $seed = "extchkbx_{$e}_".md5(microtime() . mt_rand());
+ $chk = (!empty($allowed[$e])) ? ' checked="checked"' : '';
+ echo " <td class='$cl'>\n <label><input id='{$seed}' type='checkbox' name='ext_{$e}'{$chk} />.{$e}\n ({$m})</label>\n </td>\n ";
+ }
+ while($c < 2)
+ {
+ $c++;
+ echo " <td class='{$cl}'></td>\n ";
+ }
+ echo '<tr><th class="subhead" colspan="3"><input type="submit" name="save" value="Save changes" /></th></tr>';
+ echo '</tr>'."\n".' </table>'."\n".' </div>';
+ echo '</form>';
+ ?>
+ <?php
+}
+
+function page_Admin_Sidebar()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ ?>
+ <h2>Editing and managing the Enano sidebar</h2>
+ <p>The Enano sidebar is a versatile tool when scripted correctly. You don't have to be a programmer to enjoy the features the Sidebar
+ provides; however, editing the sidebar requires a small bit of programming knowledge and an understanding of Enano's system message
+ markup language.
+ </p>
+ <p>The Enano system markup language is somewhat similar to HTML, in that it uses tags (<example>like this</example>) for the
+ main syntax. However, Enano uses curly brackets ({ and }) as opposed to less-than and greater-than signs (< and >).</p>
+ <p>Programming the Enano sidebar requires the use of two tags: {slider} and {if}. The {slider} tag is used to create a new heading
+ on the sidebar, and all text enclosed in that tag will be collapsed when the heading is clicked. To specify the text on the heading,
+ use an equals sign (=) after the "slider" text. Then insert any links (they should be wiki-formatted) to internal Enano pages and
+ external sites.</p>
+ <p>So here is what the language for the default sidebar's "Navigation" heading looks like:</p>
+ <pre>{slider=Navigation}
+ [[Main Page|Home]]
+ [[Enano:Sidebar|Edit the sidebar]]
+{/slider}</pre>
+ <p>Pretty simple, huh? Good, now we're going to learn another common aspect of Enano programming: conditionals. The {if} tag allows you
+ to decide whether a portion of the sidebar will be displayed based on a template variable. Currently the only available conditions are
+ "user_logged_in" and "auth_admin", but more will be added soon. To use a conditional, enter {if conditional_name}, and then the
+ wiki-formatted text that you want to be under that condition, and then close the tag with {/if}. In the same way, you can reverse the
+ effect with {!if}. With {!if}, the closing tag is still {/if}, so keep that in mind. An {else} tag will be supported soon.</p>
+ <p>Now it's time for some real fun: variables. All template variables can be accessed from the sidebar. A variable is simply the
+ variable name, prefixed by a dollar sign ($). Some of the most common variables are $USERNAME, $SITE_NAME, $SITE_DESC, and $PAGE_NAME.
+ The sidebar also has some special variables that it uses for some of its links. The logout link can be added with $LOGOUT_LINK, and
+ the "change theme" button can be added with $STYLE_LINK.</p>
+ <p>So here is the Enano markup for the portion of the sidebar that contains the user tools:</p>
+ <pre>{slider=$USERNAME}
+ [[User:$USERNAME|User page]]
+ [[Special:Contributions?user=$USERNAME|My Contributions]]
+ {if user_logged_in}
+ [[Special:Preferences|Preferences]]
+ $THEME_LINK
+ {/if}
+ {if auth_admin}
+ [[Special:Administration|Administration]]
+ {/if}
+ {if user_logged_in}
+ $LOGOUT_LINK
+ {/if}
+ {!if user_logged_in}
+ Create an account
+ Log in
+ {/if}
+{/slider}</pre>
+ <?php
+}
+
+function page_Admin_UserManager() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ if(isset($_POST['go'])) {
+ // We need the user ID before we can do anything
+ $q = $db->sql_query('SELECT user_id,username,email,real_name,style,user_level FROM '.table_prefix.'users WHERE username=\'' . $db->escape($_POST['username']) . '\'');
+ if(!$q) die('Error selecting user ID: '.mysql_error());
+ if($db->numrows() < 1) { echo('User does not exist, please enter another username.'); return; }
+ $r = $db->fetchrow();
+ $db->free_result();
+ if(isset($_POST['save']))
+ {
+ $_POST['level'] = intval($_POST['level']);
+
+ $new_level = $_POST['level'];
+ $old_level = intval($r['user_level']);
+
+ $re = $session->update_user((int)$r['user_id'], $_POST['new_username'], false, $_POST['new_pass'], $_POST['email'], $_POST['real_name'], false, $_POST['level']);
+
+ if($re == 'success')
+ {
+
+ if ( $new_level != $old_level )
+ {
+ $user_id = intval($r['user_id']);
+ // We need to update group memberships
+ if ( $old_level == USER_LEVEL_ADMIN )
+ {
+ $session->remove_user_from_group($user_id, GROUP_ID_ADMIN);
+ }
+ else if ( $old_level == USER_LEVEL_MOD )
+ {
+ $session->remove_user_from_group($user_id, GROUP_ID_MOD);
+ }
+
+ if ( $new_level == USER_LEVEL_ADMIN )
+ {
+ $session->add_user_to_group($user_id, GROUP_ID_ADMIN, false);
+ }
+ else if ( $new_level == USER_LEVEL_MOD )
+ {
+ $session->add_user_to_group($user_id, GROUP_ID_MOD, false);
+ }
+ }
+
+ echo('<div class="info-box">Your changes have been saved.</div>');
+ }
+ else
+ {
+ echo('<div class="error-box">Error saving changes: '.implode('<br />', $re).'</div>');
+ }
+ $q = $db->sql_query('SELECT user_id,username,email,real_name,style,user_level FROM '.table_prefix.'users WHERE username=\''.$db->escape($_POST['username']).'\'');
+ if ( !$q )
+ {
+ die('Error selecting user ID: '.mysql_error());
+ }
+ if($db->numrows($q) < 1)
+ {
+ die('User does not exist, please enter another username.');
+ }
+ $r = mysql_fetch_object($q);
+ $db->free_result();
+ }
+ elseif(isset($_POST['deleteme']) && isset($_POST['delete_conf']))
+ {
+ $q = $db->sql_query('DELETE FROM users WHERE user_id='.$r['user_id'].';');
+ if($q)
+ {
+ echo '<div class="error-box">The user account "'.$r['username'].'" was deleted.</div>';
+ }
+ else
+ {
+ echo '<div class="error-box">The user account "'.$r['username'].'" could not be deleted due to a database error.<br /><br />'.$db->get_error().'</div>';
+ }
+ }
+ else
+ {
+ echo('
+ <h3>Edit User Info</h3>
+ <form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post">
+ <table border="0" style="margin-left: 0.2in;">
+ <tr><td>Username:</td><td><input type="text" name="new_username" value="'.$r['username'].'" /></td></tr>
+ <tr><td>New Password:</td><td><input type="password" name="new_pass" /></td></tr>
+ <tr><td>E-mail:</td><td><input type="text" name="email" value="'.$r['email'].'" /></td></tr>
+ <tr><td>Real Name:</td><td><input type="text" name="real_name" value="'.$r['real_name'].'" /></td></tr>
+ <tr><td>User level:</td><td><select name="level"><option '); if($r['user_level']==USER_LEVEL_CHPREF) echo('SELECTED'); echo(' value="'.USER_LEVEL_CHPREF.'">Regular User</option><option '); if($r['user_level']==USER_LEVEL_MOD) echo('SELECTED'); echo(' value="'.USER_LEVEL_MOD.'">Moderator</option><option '); if($r['user_level']==USER_LEVEL_ADMIN) echo('SELECTED'); echo(' value="'.USER_LEVEL_ADMIN.'">Administrator</option></select></td></tr>
+ <tr><td>Delete user:</td><td><input type="hidden" name="go" /><input type="hidden" name="username" value="'.$r['username'].'" /><input onclick="return confirm(\'This is your last warning.\n\nAre you sure you want to delete this user account? Even if you delete this user account, the username will be shown in page edit history, comments, and other areas of the site.\n\nDeleting a user account CANNOT BE UNDONE and should only be done in extreme circumstances.\n\nIf the user has violated the site policy, deleting the account will not prevent him from using the site, for that you need to add a new ban rule.\n\nContinue deleting this user account?\')" type="submit" name="deleteme" value="Delete this user" style="color: red;" /> <label><input type="checkbox" name="delete_conf" /> I\'m absolutely sure</label>
+ <tr><td align="center" colspan="2">
+ <input type="submit" name="save" value="Save Changes" /></td></tr>
+ </table>
+ </form>
+ ');
+ }
+ } elseif(isset($_POST['clearsessions'])) {
+ // Get the current session information so the user doesn't get logged out
+ $aes = new AESCrypt();
+ $sk = md5($session->sid_super);
+ $qb = $db->sql_query('SELECT session_key,salt,auth_level,source_ip,time FROM '.table_prefix.'session_keys WHERE session_key=\''.$sk.'\' AND user_id='.$session->user_id.' AND auth_level='.USER_LEVEL_ADMIN);
+ if(!$qb) die('Error selecting session key info block B: '.$db->get_error());
+ if($db->numrows($qb) < 1) die('Error: cannot read admin session info block B, aborting table clear process');
+ $qa = $db->sql_query('SELECT session_key,salt,auth_level,source_ip,time FROM '.table_prefix.'session_keys WHERE session_key=\''.md5($session->sid).'\' AND user_id='.$session->user_id.' AND auth_level='.USER_LEVEL_MEMBER);
+ if(!$qa) die('Error selecting session key info block A: '.$db->get_error());
+ if($db->numrows($qa) < 1) die('Error: cannot read user session info block A, aborting table clear process');
+ $ra = mysql_fetch_object($qa);
+ $rb = mysql_fetch_object($qb);
+ $db->free_result($qa);
+ $db->free_result($qb);
+ $db->sql_query('DELETE FROM '.table_prefix.'session_keys;');
+ $db->sql_query('INSERT INTO '.table_prefix.'session_keys( session_key,salt,user_id,auth_level,source_ip,time ) VALUES( \''.$ra->session_key.'\', \''.$ra->salt.'\', \''.$session->user_id.'\', \''.$ra->auth_level.'\', \''.$ra->source_ip.'\', '.$ra->time.' ),( \''.$rb->session_key.'\', \''.$rb->salt.'\', \''.$session->user_id.'\', \''.$rb->auth_level.'\', \''.$rb->source_ip.'\', '.$rb->time.' )');
+ echo('
+ <div class="info-box">The session key table has been cleared. Your database should be a little bit smaller now.</div>
+ ');
+ }
+ echo('
+ <h3>User Management</h3>
+ <form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;">
+ <p>Username: '.$template->username_field('username').' <input type="submit" name="go" value="Go" /></p>
+ <h3>Clear session keys table</h3>
+ <p>It\'s a good idea to clean out your session keys table every once in a while, since this helps to reduce database size. During this process you will be logged off and (hopefully) logged back on automatically. The side effects of this include all users except you being logged off.</p>
+ <p><input type="submit" name="clearsessions" value="Clear session keys table" /></p>
+ </form>
+ ');
+ if(isset($_GET['action']) && isset($_GET['user']))
+ {
+ switch($_GET['action'])
+ {
+ case "activate":
+ $e = $db->sql_query('SELECT activation_key FROM '.table_prefix.'users WHERE username=\'' . $db->escape($_GET['user']) . '\'');
+ if($e)
+ {
+ $row = $db->fetchrow();
+ $db->free_result();
+ if($session->activate_account($_GET['user'], $row['activation_key'])) { echo '<div class="info-box">The user account "'.$_GET['user'].'" has been activated.</div>'; $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE time_id=' . $db->escape($_GET['logid'])); }
+ else echo '<div class="warning-box">The user account "'.$_GET['user'].'" has NOT been activated, possibly because the account is already active.</div>';
+ } else echo '<div class="error-box">Error activating account: '.mysql_error().'</div>';
+ break;
+ case "sendemail":
+ if($session->send_activation_mail($_GET['user'])) { echo '<div class="info-box">The user "'.$_GET['user'].'" has been sent an e-mail with an activation link.</div>'; $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE time_id=' . $db->escape($_GET['logid'])); }
+ else echo '<div class="error-box">The user account "'.$_GET['user'].'" has not been activated, probably because of a bad SMTP configuration.</div>';
+ break;
+ case "deny":
+ $e = $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE log_type=\'admin\' AND action=\'activ_req\' AND edit_summary=\'' . $db->escape($_GET['user']) . '\';');
+ if(!$e) echo '<div class="error-box">Error during row deletion: '.mysql_error().'</div>';
+ else echo '<div class="info-box">All activation requests for the user "'.$_GET['user'].'" have been deleted.</div>';
+ break;
+ }
+ }
+ $q = $db->sql_query('SELECT log_type, action, time_id, date_string, author, edit_summary FROM '.table_prefix.'logs WHERE log_type=\'admin\' AND action=\'activ_req\' ORDER BY time_id DESC;');
+ if($q)
+ {
+ if($db->numrows() > 0)
+ {
+ $n = $db->numrows();
+ if($n == 1) $s = $n . ' user is';
+ else $s = $n . ' users are';
+ echo '<h3>'.$s . ' awaiting account activation</h3>';
+ echo '<div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4" width="100%">
+ <tr><th>Date of request</th><th>Requested by</th><th>Requested for</th><th colspan="3">Actions</th></tr>';
+ $cls = 'row2';
+ while($row = $db->fetchrow())
+ {
+ if($cls == 'row2') $cls = 'row1';
+ else $cls = 'row2';
+ echo '<tr><td class="'.$cls.'">'.date('F d, Y h:i a', $row['time_id']).'</td><td class="'.$cls.'">'.$row['author'].'</td><td class="'.$cls.'">'.$row['edit_summary'].'</td><td class="'.$cls.'" style="text-align: center;"><a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'UserManager&action=activate&user='.$row['edit_summary'].'&logid='.$row['time_id']).'">Activate now</a></td><td class="'.$cls.'" style="text-align: center;"><a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'UserManager&action=sendemail&user='.$row['edit_summary'].'&logid='.$row['time_id']).'">Send activation e-mail</a></td><td class="'.$cls.'" style="text-align: center;"><a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'UserManager&action=deny&user='.$row['edit_summary'].'&logid='.$row['time_id']).'">Deny request</a></td></tr>';
+ }
+ echo '</table>';
+ }
+ $db->free_result();
+ }
+}
+
+function page_Admin_GroupManager()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ if(isset($_POST['do_create_stage1']))
+ {
+ if(!preg_match('/^([A-z0-9 -]+)$/', $_POST['create_group_name']))
+ {
+ echo '<p>The group name you chose is invalid.</p>';
+ return;
+ }
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;" enctype="multipart/form-data">';
+ echo '<div class="tblholder">
+ <table border="0" style="width:100%;" cellspacing="1" cellpadding="4">
+ <tr><th colspan="2">Creating group: '.$_POST['create_group_name'].'</th></tr>
+ <tr>
+ <td class="row1">Group moderator</td><td class="row1">' . $template->username_field('group_mod') . '</td>
+ </tr>
+ <tr><td class="row2">Group status</td><td class="row2">
+ <label><input type="radio" name="group_status" value="'.GROUP_CLOSED.'" checked="checked" /> Closed to new members</label><br />
+ <label><input type="radio" name="group_status" value="'.GROUP_REQUEST.'" /> Members can ask to be added</label><br />
+ <label><input type="radio" name="group_status" value="'.GROUP_OPEN.'" /> Members can join freely</label><br />
+ <label><input type="radio" name="group_status" value="'.GROUP_HIDDEN.'" /> Group is hidden</label>
+ </td></tr>
+ <tr>
+ <th class="subhead" colspan="2">
+ <input type="hidden" name="create_group_name" value="'.$_POST['create_group_name'].'" />
+ <input type="submit" name="do_create_stage2" value="Create group" />
+ </th>
+ </tr>
+ </table>
+ </div>';
+ echo '</form>';
+ return;
+ }
+ elseif(isset($_POST['do_create_stage2']))
+ {
+ if(!preg_match('/^([A-z0-9 -]+)$/', $_POST['create_group_name']))
+ {
+ echo '<p>The group name you chose is invalid.</p>';
+ return;
+ }
+ if(!in_array(intval($_POST['group_status']), Array(GROUP_CLOSED, GROUP_OPEN, GROUP_HIDDEN, GROUP_REQUEST)))
+ {
+ echo '<p>Hacking attempt</p>';
+ return;
+ }
+ $e = $db->sql_query('SELECT group_id FROM '.table_prefix.'groups WHERE group_name=\''.$db->escape($_POST['create_group_name']).'\';');
+ if(!$e)
+ {
+ echo $db->get_error();
+ return;
+ }
+ if($db->numrows() > 0)
+ {
+ echo '<p>The group name you entered already exists.</p>';
+ return;
+ }
+ $db->free_result();
+ $q = $db->sql_query('INSERT INTO '.table_prefix.'groups(group_name,group_type) VALUES( \''.$db->escape($_POST['create_group_name']).'\', ' . intval($_POST['group_status']) . ' )');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ $e = $db->sql_query('SELECT user_id FROM '.table_prefix.'users WHERE username=\''.$db->escape($_POST['group_mod']).'\';');
+ if(!$e)
+ {
+ echo $db->get_error();
+ return;
+ }
+ if($db->numrows() < 1)
+ {
+ echo '<p>The username you entered could not be found.</p>';
+ return;
+ }
+ $row = $db->fetchrow();
+ $id = $row['user_id'];
+ $db->free_result();
+ $e = $db->sql_query('SELECT group_id FROM '.table_prefix.'groups WHERE group_name=\''.$db->escape($_POST['create_group_name']).'\';');
+ if(!$e)
+ {
+ echo $db->get_error();
+ return;
+ }
+ if($db->numrows() < 1)
+ {
+ echo '<p>The group ID could not be looked up.</p>';
+ return;
+ }
+ $row = $db->fetchrow();
+ $gid = $row['group_id'];
+ $db->free_result();
+ $e = $db->sql_query('INSERT INTO '.table_prefix.'group_members(group_id,user_id,is_mod) VALUES('.$gid.', '.$id.', 1);');
+ if(!$e)
+ {
+ echo $db->get_error();
+ return;
+ }
+ echo "<div class='info-box'>
+ <b>Information</b><br />
+ The group {$_POST['create_group_name']} has been created successfully.
+ </div>";
+ }
+ if(isset($_POST['do_edit']) || isset($_POST['edit_do']))
+ {
+ // Fetch the group name
+ $q = $db->sql_query('SELECT group_name,system_group FROM '.table_prefix.'groups WHERE group_id='.intval($_POST['group_edit_id']).';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ if($db->numrows() < 1)
+ {
+ echo '<p>Error: couldn\'t look up group name</p>';
+ }
+ $row = $db->fetchrow();
+ $name = $row['group_name'];
+ $db->free_result();
+ if(isset($_POST['edit_do']))
+ {
+ if(isset($_POST['edit_do']['del_group']))
+ {
+ if ( $row['system_group'] == 1 )
+ {
+ echo '<div class="error-box">The group "' . $name . '" could not be deleted because it is a system group required for site functionality.</div>';
+ }
+ else
+ {
+ $q = $db->sql_query('DELETE FROM '.table_prefix.'group_members WHERE group_id='.intval($_POST['group_edit_id']).';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ $q = $db->sql_query('DELETE FROM '.table_prefix.'groups WHERE group_id='.intval($_POST['group_edit_id']).';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ echo '<div class="info-box">The group "'.$name.'" has been deleted. Return to the <a href="javascript:ajaxPage(\'Admin:GroupManager\');">group manager</a>.</div>';
+ return;
+ }
+ }
+ if(isset($_POST['edit_do']['save_name']))
+ {
+ if(!preg_match('/^([A-z0-9 -]+)$/', $_POST['group_name']))
+ {
+ echo '<p>The group name you chose is invalid.</p>';
+ return;
+ }
+ $q = $db->sql_query('UPDATE '.table_prefix.'groups SET group_name=\''.$db->escape($_POST['group_name']).'\'
+ WHERE group_id='.intval($_POST['group_edit_id']).';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ else
+ {
+ echo '<div class="info-box" style="margin: 0 0 10px 0;"">
+ The group name has been updated.
+ </div>';
+ }
+ $name = $_POST['group_name'];
+
+ }
+ $q = $db->sql_query('SELECT member_id FROM '.table_prefix.'group_members
+ WHERE group_id='.intval($_POST['group_edit_id']).';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ if($db->numrows() > 0)
+ {
+ while($row = $db->fetchrow($q))
+ {
+ if(isset($_POST['edit_do']['del_' . $row['member_id']]))
+ {
+ $e = $db->sql_query('DELETE FROM '.table_prefix.'group_members WHERE member_id='.$row['member_id']);
+ if(!$e)
+ {
+ echo $db->get_error();
+ return;
+ }
+ }
+ }
+ }
+ $db->free_result();
+ if(isset($_POST['edit_do']['add_member']))
+ {
+ $q = $db->sql_query('SELECT user_id FROM '.table_prefix.'users WHERE username=\''.$db->escape($_POST['edit_add_username']).'\';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ if($db->numrows() > 0)
+ {
+ $row = $db->fetchrow();
+ $user_id = $row['user_id'];
+ $is_mod = ( isset( $_POST['add_mod'] ) ) ? '1' : '0';
+ $q = $db->sql_query('INSERT INTO '.table_prefix.'group_members(group_id,user_id,is_mod) VALUES('.intval($_POST['group_edit_id']).','.$user_id.','.$is_mod.');');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ else
+ {
+ echo '<div class="info-box" style="margin: 0 0 10px 0;"">
+ The user "'.$_POST['edit_add_username'].'" has been added to this usergroup.
+ </div>';
+ }
+ }
+ else
+ echo '<div class="warning-box"><b>The user "'.$_POST['edit_add_username'].'" could not be added.</b><br />This username does not exist.</div>';
+ }
+ }
+ $sg_disabled = ( $row['system_group'] == 1 ) ? ' value="Can\'t delete system group" disabled="disabled" style="color: #FF9773" ' : ' value="Delete this group" style="color: #FF3713" ';
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;" enctype="multipart/form-data">';
+ echo '<div class="tblholder">
+ <table border="0" style="width:100%;" cellspacing="1" cellpadding="4">
+ <tr><th>Edit group name</th></tr>
+ <tr>
+ <td class="row1">
+ Group name: <input type="text" name="group_name" value="'.$name.'" />
+ </td>
+ </tr>
+ <tr>
+ <th class="subhead">
+ <input type="submit" name="edit_do[save_name]" value="Save name" />
+ <input type="submit" name="edit_do[del_group]" '.$sg_disabled.' />
+ </th>
+ </tr>
+ </table>
+ </div>
+ <input type="hidden" name="group_edit_id" value="'.$_POST['group_edit_id'].'" />';
+ echo '</form>';
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;" enctype="multipart/form-data">';
+ echo '<div class="tblholder">
+ <table border="0" style="width:100%;" cellspacing="1" cellpadding="4">
+ <tr><th colspan="3">Edit group members</th></tr>';
+ $q = $db->sql_query('SELECT m.member_id,m.is_mod,u.username FROM '.table_prefix.'group_members AS m
+ LEFT JOIN '.table_prefix.'users AS u
+ ON u.user_id=m.user_id
+ WHERE m.group_id='.intval($_POST['group_edit_id']).'
+ ORDER BY m.is_mod DESC, u.username ASC;');
+ if(!$q)
+ {
+ echo $db->get_error();
+ return;
+ }
+ if($db->numrows() < 1)
+ {
+ echo '<tr><td colspan="3" class="row1">This group has no members.</td></tr>';
+ }
+ else
+ {
+ $cls = 'row2';
+ while($row = $db->fetchrow())
+ {
+ $cls = ( $cls == 'row1' ) ? 'row2' : 'row1';
+ $mod = ( $row['is_mod'] == 1 ) ? 'Mod' : '';
+ echo '<tr>
+ <td class="'.$cls.'" style="width: 100%;">
+ ' . $row['username'] . '
+ </td>
+ <td class="'.$cls.'">
+ '.$mod.'
+ </td>
+ <td class="'.$cls.'">
+ <input type="submit" name="edit_do[del_'.$row['member_id'].']" value="Remove member" />
+ </td>
+ </tr>';
+ }
+ }
+ $db->free_result();
+ echo '</table>
+ </div>
+ <input type="hidden" name="group_edit_id" value="'.$_POST['group_edit_id'].'" />';
+ echo '</form>';
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;" enctype="multipart/form-data">';
+ echo '<div class="tblholder">
+ <table border="0" style="width:100%;" cellspacing="1" cellpadding="4">
+ <tr>
+ <th>Add a new member</th>
+ </tr>
+ <tr>
+ <td class="row1">
+ Username: ' . $template->username_field('edit_add_username') . '
+ </td>
+ </tr>
+ <tr>
+ <td class="row2">
+ <label><input type="checkbox" name="add_mod" /> Is a group moderator</label> (can add and delete other members)
+ </td>
+ </tr>
+ <tr>
+ <th class="subhead">
+ <input type="submit" name="edit_do[add_member]" value="Add user to group" />
+ </th>
+ </tr>
+ </table>
+ </div>
+ <input type="hidden" name="group_edit_id" value="'.$_POST['group_edit_id'].'" />';
+ echo '</form>';
+ return;
+ }
+ echo '<h3>Manage Usergroups</h3>';
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;" enctype="multipart/form-data">';
+ $q = $db->sql_query('SELECT group_id,group_name FROM '.table_prefix.'groups ORDER BY group_name ASC;');
+ if(!$q)
+ {
+ echo $db->get_error();
+ }
+ else
+ {
+ echo '<div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4" style="width: 100%;">
+ <tr>
+ <th>Edit an existing group</th>
+ </tr>';
+ echo '<tr><td class="row2"><select name="group_edit_id">';
+ while ( $row = $db->fetchrow() )
+ {
+ if ( $row['group_name'] != 'Everyone' )
+ {
+ echo '<option value="' . $row['group_id'] . '">' . htmlspecialchars( $row['group_name'] ) . '</option>';
+ }
+ }
+ $db->free_result();
+ echo '</select></td></tr>';
+ echo '<tr><td class="row1" style="text-align: center;"><input type="submit" name="do_edit" value="Edit group" /></td></tr>
+ </table>
+ </div>
+ </form><br />';
+ }
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;" enctype="multipart/form-data">';
+ echo '<div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4" style="width: 100%;">
+ <tr>
+ <th colspan="2">Create a new group</th>
+ </tr>';
+ echo '<tr><td class="row2">Group name:</td><td class="row2"><input type="text" name="create_group_name" /></td></tr>';
+ echo '<tr><td colspan="2" class="row1" style="text-align: center;"><input type="submit" name="do_create_stage1" value="Continue >" /></td></tr>
+ </table>
+ </div>';
+ echo '</form>';
+}
+
+function page_Admin_PageManager()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+
+ echo '<h2>Page management</h2>';
+
+ if(isset($_POST['search']) || isset($_POST['select']) || ( isset($_GET['source']) && $_GET['source'] == 'ajax' )) {
+ // The object of the game: using only the text a user entered, guess the page ID and namespace. *sigh* I HATE writing search algorithms...
+ $source = ( isset($_GET['source']) ) ? $_GET['source'] : false;
+ if ( $source == 'ajax' )
+ {
+ $_POST['search'] = true;
+ $_POST['page_url'] = $_GET['page_id'];
+ }
+ if(isset($_POST['search'])) $pid = $_POST['page_url'];
+ elseif(isset($_POST['select'])) $pid = $_POST['page_force_url'];
+ else { echo 'Internal error selecting page search terms'; return false; }
+ // Look for a namespace prefix in the urlname, and assign a different namespace, if necessary
+ $k = array_keys($paths->nslist);
+ for($i=0;$i<sizeof($paths->nslist);$i++)
+ {
+ $ln = strlen($paths->nslist[$k[$i]]);
+ if(substr($pid, 0, $ln) == $paths->nslist[$k[$i]])
+ {
+ $ns = $k[$i];
+ $page_id = substr($pid, $ln, strlen($pid));
+ }
+ }
+ // The namespace is in $ns and the page name or ID (we don't know which yet) is in $page_id
+ // Now, iterate through $paths->pages searching for a page with this name or ID
+ for($i=0;$i<sizeof($paths->pages)/2;$i++)
+ {
+ if(!isset($final_pid))
+ {
+ if ($paths->pages[$i]['urlname_nons'] == str_replace(' ', '_', $page_id)) $final_pid = str_replace(' ', '_', $page_id);
+ elseif($paths->pages[$i]['name'] == $page_id) $final_pid = $paths->pages[$i]['urlname_nons'];
+ elseif(strtolower($paths->pages[$i]['urlname_nons']) == strtolower(str_replace(' ', '_', $page_id))) $final_pid = $paths->pages[$i]['urlname_nons'];
+ elseif(strtolower($paths->pages[$i]['name']) == strtolower(str_replace('_', ' ', $page_id))) $final_pid = $paths->pages[$i]['urlname_nons'];
+ if(isset($final_pid)) { $_POST['name'] = $paths->pages[$i]['name']; $_POST['urlname'] = $paths->pages[$i]['urlname_nons']; }
+ }
+ }
+ if(!isset($final_pid)) { echo 'The page you searched for cannot be found. <a href="#" onclick="ajaxPage(\''.$paths->nslist['Admin'].'PageManager\'); return false;">Back</a>'; return false; }
+ $_POST['namespace'] = $ns;
+ $_POST['old_namespace'] = $ns;
+ $_POST['page_id'] = $final_pid;
+ $_POST['old_page_id'] = $final_pid;
+ if(!isset($paths->pages[$paths->nslist[$_POST['namespace']].$_POST['urlname']])) { echo 'The page you searched for cannot be found. <a href="#" onclick="ajaxPage(\''.$paths->nslist['Admin'].'PageManager\'); return false;">Back</a>'; return false; }
+ }
+
+ if(isset($_POST['page_id']) && isset($_POST['namespace']) && !isset($_POST['cancel']))
+ {
+ $cpage = $paths->pages[$paths->nslist[$_POST['namespace']].$_POST['old_page_id']];
+ if(isset($_POST['submit']))
+ {
+ // Create a list of things to update
+ $page_info = Array(
+ 'name'=>$_POST['name'],
+ 'urlname'=>$_POST['page_id'],
+ 'namespace'=>$_POST['namespace'],
+ 'special'=>isset($_POST['special']) ? '1' : '0',
+ 'visible'=>isset($_POST['visible']) ? '1' : '0',
+ 'comments_on'=>isset($_POST['comments_on']) ? '1' : '0',
+ 'protected'=>isset($_POST['protected']) ? '1' : '0'
+ );
+ // Build the query
+ $q = 'UPDATE '.table_prefix.'pages SET ';
+ $k = array_keys($page_info);
+ foreach($k as $c)
+ {
+ $q .= $c.'=\''.$db->escape($page_info[$c]).'\',';
+ }
+ $q = substr($q, 0, strlen($q)-1);
+ // Build the WHERE statements
+ $q .= ' WHERE ';
+ $k = array_keys($cpage);
+ foreach($k as $c)
+ {
+ if($c != 'urlname_nons' && $c != 'urlname' && $c != 'really_protected') $q .= $c.'=\''.$cpage[$c].'\' AND ';
+ elseif($c == 'urlname') $q .= $c.'=\''.$cpage['urlname_nons'].'\' AND ';
+ }
+ $q = substr($q, 0, strlen($q)-5) . ';';
+ // Send the completed query to MySQL
+ $e = $db->sql_query($q);
+ if(!$e) $db->_die('The page data could not be updated.');
+ // Update any additional tables
+ $q = Array(
+ 'UPDATE '.table_prefix.'categories SET page_id=\''.$page_info['urlname'].'\',namespace=\''.$page_info['namespace'].'\' WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';',
+ 'UPDATE '.table_prefix.'comments SET page_id=\''.$page_info['urlname'].'\',namespace=\''.$page_info['namespace'].'\' WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';',
+ 'UPDATE '.table_prefix.'logs SET page_id=\''.$page_info['urlname'].'\',namespace=\''.$page_info['namespace'].'\' WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';',
+ 'UPDATE '.table_prefix.'page_text SET page_id=\''.$page_info['urlname'].'\',namespace=\''.$page_info['namespace'].'\' WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';',
+ );
+ foreach($q as $cq)
+ {
+ $e = $db->sql_query($cq);
+ if(!$e) $db->_die('Some of the additional tables containing page information could not be updated.');
+ }
+ // Update $cpage
+ $cpage = $page_info;
+ $cpage['urlname_nons'] = $cpage['urlname'];
+ $cpage['urlname'] = $paths->nslist[$cpage['namespace']].$cpage['urlname'];
+ $_POST['old_page_id'] = $page_info['urlname'];
+ $_POST['old_namespace'] = $page_info['namespace'];
+ echo '<div class="info-box">Your changes have been saved.</div>';
+ } elseif(isset($_POST['delete'])) {
+ $q = Array(
+ 'DELETE FROM '.table_prefix.'categories WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';',
+ 'DELETE FROM '.table_prefix.'comments WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';',
+ 'DELETE FROM '.table_prefix.'logs WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';',
+ 'DELETE FROM '.table_prefix.'page_text WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';',
+ );
+ foreach($q as $cq)
+ {
+ $e = $db->sql_query($cq);
+ if(!$e) $db->_die('Some of the additional tables containing page information could not be updated.');
+ }
+
+ if(!$db->sql_query(
+ 'DELETE FROM '.table_prefix.'pages WHERE urlname="'.$db->escape($_POST['old_page_id']).'" AND namespace="'.$db->escape($_POST['old_namespace']).'";'
+ )) $db->_die('The page could not be deleted.');
+ echo '<div class="info-box">This page has been deleted.</p><p><a href="javascript:ajaxPage(\''.$paths->nslist['Admin'].'PageManager\');">Return to Page manager</a><br /><a href="javascript:ajaxPage(\''.$paths->nslist['Admin'].'Home\');">Admin home</a></div>';
+ return;
+ }
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration'.htmlspecialchars(urlSeparator).(( isset($_GET['sqldbg']) ) ? 'sqldbg&' : '') .'module='.$paths->cpage['module']).'" method="post">';
+ ?>
+ <h3>Modify page: <?php echo $_POST['name']; ?></h3>
+ <table border="0">
+ <tr><td>Namespace:</td><td><select name="namespace"><?php $nm = array_keys($paths->nslist); foreach($nm as $ns) { if($ns != 'Special' && $ns != 'Admin') { echo '<option '; if($_POST['namespace']==$ns) echo 'selected="selected" '; echo 'value="'.$ns.'">'; if($paths->nslist[$ns] == '') echo '[No prefix]'; else echo $paths->nslist[$ns]; echo '</option>'; } } ?></select></td></tr>
+ <tr><td>Page title:</td><td><input type="text" name="name" value="<?php echo $cpage['name']; ?>" /></td></tr>
+ <tr><td>Page URL string:<br /><small>No spaces, and don't enter the namespace prefix (e.g. User:).<br />Changing this value is usually not a good idea, especially for templates and project pages.</small></td><td><input type="text" name="page_id" value="<?php echo $cpage['urlname_nons']; ?>" /></td></tr>
+ <tr><td></td><td><input <?php if($cpage['comments_on']) echo 'checked="checked"'; ?> name="comments_on" type="checkbox" id="cmt" /> <label for="cmt">Enable comments for this page</label></td></tr>
+ <tr><td></td><td><input <?php if($cpage['special']) echo 'checked="checked"'; ?> name="special" type="checkbox" id="spc" /> <label for="spc">Bypass the template engine for this page</label><br /><small>This option enables you to use your own HTML headers and other code. It is recommended that only advanced users enable this feature. As with other Enano pages, you may use PHP code in your pages, meaning you can use Enano's API on the page.</small></td></tr>
+ <tr><td></td><td><input <?php if($cpage['visible']) echo 'checked="checked"'; ?> name="visible" type="checkbox" id="vis" /> <label for="vis">Allow this page to be shown in page lists</label><br /><small>Unchecking this checkbox prevents the page for being indexed for searching. The index is rebuilt each time a page is saved, and you can force an index rebuild by going to the page <?php echo $paths->nslist['Special']; ?>SearchRebuild.</small></td></tr>
+ <tr><td></td><td><input <?php if($cpage['protected']) echo 'checked="checked"'; ?> name="protected" type="checkbox" id="prt" /> <label for="prt">Prevent non-administrators from editing this page</label><br /><small>This option only has an effect when Wiki Mode is enabled.</small></td></tr>
+ <tr><td></td><td><input type="submit" name="delete" value="Delete page" style="color: red" onclick="return confirm('Do you REALLY want to delete this page?')" /></td></tr>
+ <tr><td colspan="2" style="text-align: center;"><hr /></td></tr>
+ <tr><td colspan="2" style="text-align: right;">
+ <input type="hidden" name="old_page_id" value="<?php echo $_POST['old_page_id']; ?>" />
+ <input type="hidden" name="old_namespace" value="<?php echo $_POST['old_namespace']; ?>" />
+ <input type="Submit" name="submit" value="Save changes" style="font-weight: bold;" /> <input type="submit" name="cancel" value="Cancel changes" /></td></tr>
+ </table>
+ <?php
+ echo '</form>';
+ } else {
+ echo '<h3>Please select a page</h3>';
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;" enctype="multipart/form-data">';
+ ?>
+ <p>Search for page title (remember prefixes like User: and File:) <?php echo $template->pagename_field('page_url'); ?> <input type="submit" style="font-weight: bold;" name="search" value="Search" /></p>
+ <p>Select page title from a list: <select name="page_force_url">
+ <?php
+ for($i=0;$i<sizeof($paths->pages)/2;$i++)
+ {
+ if($paths->pages[$i]['namespace'] != 'Admin' && $paths->pages[$i]['namespace'] != 'Special') echo '<option value="'.$paths->nslist[$paths->pages[$i]['namespace']].$paths->pages[$i]['urlname_nons'].'">'.$paths->nslist[$paths->pages[$i]['namespace']].$paths->pages[$i]['name'].'</option>'."\n";
+ }
+ ?>
+ </select> <input type="submit" name="select" value="Select" /></p>
+ <?php
+ echo '</form>';
+
+ }
+}
+
+function page_Admin_PageEditor()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+
+ echo '<h2>Edit page content</h2>';
+
+ if(isset($_POST['search']) || isset($_POST['select'])) {
+ // The object of the game: using only the text a user entered, guess the page ID and namespace. *sigh* I HATE writing search algorithms...
+ if(isset($_POST['search'])) $pid = $_POST['page_url'];
+ elseif(isset($_POST['select'])) $pid = $_POST['page_force_url'];
+ else { echo 'Internal error selecting page search terms'; return false; }
+ // Look for a namespace prefix in the urlname, and assign a different namespace, if necessary
+ $k = array_keys($paths->nslist);
+ for($i=0;$i<sizeof($paths->nslist);$i++)
+ {
+ $ln = strlen($paths->nslist[$k[$i]]);
+ if(substr($pid, 0, $ln) == $paths->nslist[$k[$i]])
+ {
+ $ns = $k[$i];
+ $page_id = substr($pid, $ln, strlen($pid));
+ }
+ }
+ // The namespace is in $ns and the page name or ID (we don't know which yet) is in $page_id
+ // Now, iterate through $paths->pages searching for a page with this name or ID
+ for($i=0;$i<sizeof($paths->pages)/2;$i++)
+ {
+ if(!isset($final_pid))
+ {
+ if ($paths->pages[$i]['urlname_nons'] == str_replace(' ', '_', $page_id)) $final_pid = str_replace(' ', '_', $page_id);
+ elseif($paths->pages[$i]['name'] == $page_id) $final_pid = $paths->pages[$i]['urlname_nons'];
+ elseif(strtolower($paths->pages[$i]['urlname_nons']) == strtolower(str_replace(' ', '_', $page_id))) $final_pid = $paths->pages[$i]['urlname_nons'];
+ elseif(strtolower($paths->pages[$i]['name']) == strtolower(str_replace('_', ' ', $page_id))) $final_pid = $paths->pages[$i]['urlname_nons'];
+ if(isset($final_pid)) { $_POST['name'] = $paths->pages[$i]['name']; $_POST['urlname'] = $paths->pages[$i]['urlname_nons']; }
+ }
+ }
+ if(!isset($final_pid)) { echo 'The page you searched for cannot be found. <a href="#" onclick="ajaxPage(\''.$paths->nslist['Admin'].'PageManager\'); return false;">Back</a>'; return false; }
+ $_POST['namespace'] = $ns;
+ $_POST['page_id'] = $final_pid;
+ if(!isset($paths->pages[$paths->nslist[$_POST['namespace']].$_POST['urlname']])) { echo 'The page you searched for cannot be found. <a href="#" onclick="ajaxPage(\''.$paths->nslist['Admin'].'PageManager\'); return false;">Back</a>'; return false; }
+ }
+
+ if(isset($_POST['page_id']) && !isset($_POST['cancel']))
+ {
+ echo '<form name="main" action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post">';
+ if(!isset($_POST['content']) || isset($_POST['revert'])) $content = RenderMan::getPage($_POST['page_id'], $_POST['namespace'], 0, false, false, false, false);
+ else $content = $_POST['content'];
+ if(isset($_POST['save']))
+ {
+ $data = $content;
+ $id = md5( microtime() . mt_rand() );
+
+ $minor = isset($_POST['minor']) ? 'true' : 'false';
+ $q='INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,page_id,namespace,page_text,char_tag,author,edit_summary,minor_edit) VALUES(\'page\', \'edit\', '.time().', \''.date('d M Y h:i a').'\', \'' . $db->escape($_POST['page_id']) . '\', \'' . $db->escape($_POST['namespace']) . '\', \''.$data.'\', \''.$id.'\', \''.$session->username.'\', \''.$db->escape(htmlspecialchars($_POST['summary'])).'\', '.$minor.');';
+ if(!$db->sql_query($q)) $db->_die('The history (log) entry could not be inserted into the logs table.');
+
+ $query = 'UPDATE '.table_prefix.'page_text SET page_text=\''.$db->escape($data).'\',char_tag=\''.$id.'\' WHERE page_id=\'' . $db->escape($_POST['page_id']) . '\' AND namespace=\'' . $db->escape($_POST['namespace']) . '\';';
+ $e = $db->sql_query($query);
+ if(!$e) echo '<div class="warning-box">The page data could not be saved. MySQL said: '.mysql_error().'<br /><br />Query:<br /><pre>'.$query.'</pre></div>';
+ else echo '<div class="info-box">Your page has been saved. <a href="'.makeUrlNS($_POST['namespace'], $_POST['page_id']).'">View page...</a></div>';
+ } elseif(isset($_POST['preview'])) {
+ echo '<h3>Preview</h3><p><b>Reminder:</b> This is only a preview; your changes to this page have not yet been saved.</p><div style="margin: 1em; padding: 10px; border: 1px dashed #606060; background-color: #F8F8F8; max-height: 200px; overflow: auto;">'.RenderMan::render($content).'</div>';
+ }
+ ?>
+ <p>
+ <textarea name="content" rows="20" cols="60" style="width: 100%;"><?php echo htmlspecialchars($content); ?></textarea><br />
+ Edit summary: <input name="summary" value="<?php if(isset($_POST['summary'])) echo $_POST['summary']; ?>" size="40" /><br />
+ <label><input type="checkbox" name="minor" <?php if(isset($_POST['minor'])) echo 'checked="checked" '; ?>/> This is a minor edit</label>
+ </p>
+ <p>
+ <input type="hidden" name="page_id" value="<?php echo $_POST['page_id']; ?>" />
+ <input type="hidden" name="namespace" value="<?php echo $_POST['namespace']; ?>" />
+ <input type="submit" name="save" value="Save changes" style="font-weight: bold;" /> <input type="submit" name="preview" value="Show preview" /> <input type="submit" name="revert" value="Revert changes" onclick="return confirm('Do you really want to revert your changes?');" /> <input type="submit" name="cancel" value="Cancel" onclick="return confirm('Do you really want to cancel your changes?');" />
+ </p>
+ <?php
+ echo '</form>';
+ } else {
+ echo '<h3>Please select a page</h3>';
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post" onsubmit="if(!submitAuthorized) return false;" enctype="multipart/form-data">';
+ ?>
+ <p>Search for page title (remember prefixes like User: and File:) <?php echo $template->pagename_field('page_url'); ?> <input type="submit" style="font-weight: bold;" name="search" value="Search" /></p>
+ <p>Select page title from a list: <select name="page_force_url">
+ <?php
+ for($i=0;$i<sizeof($paths->pages)/2;$i++)
+ {
+ if($paths->pages[$i]['namespace'] != 'Admin' && $paths->pages[$i]['namespace'] != 'Special') echo '<option value="'.$paths->nslist[$paths->pages[$i]['namespace']].$paths->pages[$i]['urlname_nons'].'">'.$paths->nslist[$paths->pages[$i]['namespace']].$paths->pages[$i]['name'].'</option>'."\n";
+ }
+ ?>
+ </select> <input type="submit" name="select" value="Select" /></p>
+ <?php
+ echo '</form>';
+ }
+}
+
+function page_Admin_ThemeManager()
+{
+
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+
+ // Get the list of styles in the themes/ dir
+ $h = opendir('./themes');
+ $l = Array();
+ if(!$h) die('Error opening directory "./themes" for reading.');
+ while(false !== ($n = readdir($h))) {
+ if($n != '.' && $n != '..' && is_dir('./themes/'.$n))
+ $l[] = $n;
+ }
+ closedir($h);
+ echo('
+ <h3>Theme Management</h3>
+ <p>Install, uninstall, and manage Enano themes.</p>
+ ');
+ if(isset($_POST['disenable'])) {
+ $q = 'SELECT enabled FROM '.table_prefix.'themes WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\'';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error selecting enabled/disabled state value: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $r = $db->fetchrow_num($s);
+ $db->free_result();
+ if($r[0] == 1) $e = 0;
+ else $e = 1;
+ $s=true;
+ if($e==0)
+ {
+ $c = $db->sql_query('SELECT * FROM '.table_prefix.'themes WHERE enabled=1');
+ if(!$c) $db->_die('The backup check for having at least on theme enabled failed.');
+ if($db->numrows() <= 1) { echo '<div class="warning-box">You cannot disable the last remaining theme.</div>'; $s=false; }
+ }
+ $db->free_result();
+ if($s) {
+ $q = 'UPDATE '.table_prefix.'themes SET enabled='.$e.' WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\'';
+ $a = $db->sql_query($q);
+ if(!$a) die('Error updating enabled/disabled state value: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ else echo('<div class="info-box">The theme "'.$_POST['theme_id'].'" has been '. ( ( $e == '1' ) ? 'enabled' : 'disabled' ).'.</div>');
+ }
+ }
+ elseif(isset($_POST['edit'])) {
+
+ $dir = './themes/'.$_POST['theme_id'].'/css/';
+ $list = Array();
+ // Open a known directory, and proceed to read its contents
+ if (is_dir($dir)) {
+ if ($dh = opendir($dir)) {
+ while (($file = readdir($dh)) !== false) {
+ if(preg_match('#^(.*?)\.css$#is', $file) && $file != '_printable.css') {
+ $list[$file] = capitalize_first_letter(substr($file, 0, strlen($file)-4));
+ }
+ }
+ closedir($dh);
+ }
+ }
+ $lk = array_keys($list);
+
+ $q = 'SELECT theme_name,default_style FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\'';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error selecting name value: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $r = $db->fetchrow_num($s);
+ $db->free_result();
+ echo('<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post">');
+ echo('<div class="question-box">
+ Theme name displayed to users: <input type="text" name="name" value="'.$r[0].'" /><br /><br />
+ Default stylesheet: <select name="defaultcss">');
+ foreach ($lk as $l)
+ {
+ if($r[1] == $l) $v = ' selected="selected"';
+ else $v = '';
+ echo "<option value='{$l}'$v>{$list[$l]}</option>";
+ }
+ echo('</select><br /><br />
+ <input type="submit" name="editsave" value="OK" /><input type="hidden" name="theme_id" value="'.$_POST['theme_id'].'" />
+ </div>');
+ echo('</form>');
+ }
+ elseif(isset($_POST['editsave'])) {
+ $q = 'UPDATE '.table_prefix.'themes SET theme_name=\'' . $db->escape($_POST['name']) . '\',default_style=\''.$db->escape($_POST['defaultcss']).'\' WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\'';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error updating name value: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ else echo('<div class="info-box">Theme data updated.</div>');
+ }
+ elseif(isset($_POST['up'])) {
+ // If there is only one theme or if the selected theme is already at the top, do nothing
+ $q = 'SELECT theme_order FROM '.table_prefix.'themes ORDER BY theme_order;';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error selecting order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $q = 'SELECT theme_order FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\'';
+ $sn = $db->sql_query($q);
+ if(!$sn) die('Error selecting order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $r = $db->fetchrow_num($sn);
+ if( /* check for only one theme... */ $db->numrows($s) < 2 || $r[0] == 1 /* ...and check if this theme is already at the top */ ) { echo('<div class="warning-box">This theme is already at the top of the list, or there is only one theme installed.</div>'); } else {
+ // Get the order IDs of the selected theme and the theme before it
+ $q = 'SELECT theme_order FROM '.table_prefix.'themes WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\'';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error selecting order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $r = $db->fetchrow_num($s);
+ $r = $r[0];
+ $rb = $r - 1;
+ // Thank God for jEdit's rectangular selection and the ablity to edit multiple lines at the same time ;)
+ $q = 'UPDATE '.table_prefix.'themes SET theme_order=0 WHERE theme_order='.$rb.''; /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$rb.' WHERE theme_order='.$r.''; /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$r.' WHERE theme_order=0'; /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ echo('<div class="info-box">Theme moved up.</div>');
+ }
+ $db->free_result($s);
+ $db->free_result($sn);
+ }
+ elseif(isset($_POST['down'])) {
+ // If there is only one theme or if the selected theme is already at the top, do nothing
+ $q = 'SELECT theme_order FROM '.table_prefix.'themes ORDER BY theme_order;';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error selecting order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $r = $db->fetchrow_num($s);
+ if( /* check for only one theme... */ $db->numrows($s) < 2 || $r[0] == $db->numrows($s) /* ...and check if this theme is already at the bottom */ ) { echo('<div class="warning-box">This theme is already at the bottom of the list, or there is only one theme installed.</div>'); } else {
+ // Get the order IDs of the selected theme and the theme before it
+ $q = 'SELECT theme_order FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\'';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error selecting order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $r = $db->fetchrow_num($s);
+ $r = $r[0];
+ $rb = $r + 1;
+ // Thank God for jEdit's rectangular selection and the ablity to edit multiple lines at the same time ;)
+ $q = 'UPDATE '.table_prefix.'themes SET theme_order=0 WHERE theme_order='.$rb.''; /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$rb.' WHERE theme_order='.$r.''; /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$r.' WHERE theme_order=0'; /* Check for errors... <sigh> */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ echo('<div class="info-box">Theme moved down.</div>');
+ }
+ }
+ else if(isset($_POST['uninstall']))
+ {
+ $q = 'SELECT * FROM '.table_prefix.'themes;';
+ $s = $db->sql_query($q);
+ if ( !$s )
+ {
+ die('Error getting theme count: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ }
+ $n = $db->numrows($s);
+ $db->free_result();
+
+ if ( $_POST['theme_id'] == 'oxygen' )
+ {
+ echo '<div class="error-box">The Oxygen theme is used by Enano for installation, upgrades, and error messages, and cannot be uninstalled.</div>';
+ }
+ else
+ {
+ if($n < 2)
+ {
+ echo '<div class="error-box">The theme could not be uninstalled because it is the only theme left.</div>';
+ }
+ else
+ {
+ $q = 'DELETE FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\' LIMIT 1;';
+ $s = $db->sql_query($q);
+ if ( !$s )
+ {
+ die('Error deleting theme data: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ }
+ else
+ {
+ echo('<div class="info-box">Theme uninstalled.</div>');
+ }
+ }
+ }
+ }
+ elseif(isset($_POST['install'])) {
+ $q = 'SELECT * FROM '.table_prefix.'themes;';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error getting theme count: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ $n = $db->numrows($s);
+ $n++;
+ $theme_id = $_POST['theme_id'];
+ $theme = Array();
+ include('./themes/'.$theme_id.'/theme.cfg');
+ $q = 'INSERT INTO '.table_prefix.'themes(theme_id,theme_name,theme_order,enabled) VALUES(\''.$theme['theme_id'].'\', \''.$theme['theme_name'].'\', '.$n.', 1)';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error inserting theme data: '.mysql_error().'<br /><u>SQL:</u><br />'.$q);
+ else echo('<div class="info-box">Theme "'.$theme['theme_name'].'" installed.</div>');
+ }
+ echo('
+ <h3>Currently installed themes</h3>
+ <form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post">
+ <p>
+ <select name="theme_id">
+ ');
+ $q = 'SELECT theme_id,theme_name,enabled FROM '.table_prefix.'themes ORDER BY theme_order';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error selecting theme data: '.mysql_error().'<br /><u>Attempted SQL:</u><br />'.$q);
+ while ( $r = $db->fetchrow_num($s) ) {
+ if($r[2] < 1) $r[1] .= ' (disabled)';
+ echo('<option value="'.$r[0].'">'.$r[1].'</option>');
+ }
+ $db->free_result();
+ echo('
+ </select> <input type="submit" name="disenable" value="Enable/Disable" /> <input type="submit" name="edit" value="Change settings" /> <input type="submit" name="up" value="Move up" /> <input type="submit" name="down" value="Move down" /> <input type="submit" name="uninstall" value="Uninstall" style="color: #DD3300; font-weight: bold;" />
+ </p>
+ </form>
+ <h3>Install a new theme</h3>
+ ');
+ $theme = Array();
+ $obb = '';
+ for($i=0;$i<sizeof($l);$i++) {
+ if(is_file('./themes/'.$l[$i].'/theme.cfg') && file_exists('./themes/'.$l[$i].'/theme.cfg')) {
+ include('./themes/'.$l[$i].'/theme.cfg');
+ $q = 'SELECT * FROM '.table_prefix.'themes WHERE theme_id=\''.$theme['theme_id'].'\'';
+ $s = $db->sql_query($q);
+ if(!$s) die('Error selecting list of currently installed themes: '.mysql_error().'<br /><u>Attempted SQL:</u><br />'.$q);
+ if($db->numrows($s) < 1) {
+ $obb .= '<option value="'.$theme['theme_id'].'">'.$theme['theme_name'].'</option>';
+ }
+ $db->free_result();
+ }
+ }
+ if($obb != '') {
+ echo('<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post"><p>');
+ echo('<select name="theme_id">');
+ echo($obb);
+ echo('</select>');
+ echo('
+ <input type="submit" name="install" value="Install this theme" />
+ </p></form>');
+ } else echo('<p>All themes are currently installed.</p>');
+}
+
+function page_Admin_BanControl()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ if(isset($_GET['action']) && $_GET['action'] == 'delete' && isset($_GET['id']) && $_GET['id'] != '')
+ {
+ $e = $db->sql_query('DELETE FROM '.table_prefix.'banlist WHERE ban_id=' . $db->escape($_GET['id']) . '');
+ if(!$e) $db->_die('The ban list entry was not deleted.');
+ }
+ if(isset($_POST['create']))
+ {
+ $q = 'INSERT INTO '.table_prefix.'banlist(ban_type,ban_value,reason,is_regex) VALUES( ' . $db->escape($_POST['type']) . ', \'' . $db->escape($_POST['value']) . '\', \''.$db->escape($_POST['reason']).'\'';
+ if(isset($_POST['regex'])) $q .= ', 1';
+ else $q .= ', 0';
+ $q .= ');';
+ $e = $db->sql_query($q);
+ if(!$e) $db->_die('The banlist could not be updated.');
+ }
+ $q = $db->sql_query('SELECT ban_id,ban_type,ban_value,is_regex FROM '.table_prefix.'banlist ORDER BY ban_type;');
+ if(!$q) $db->_die('The banlist data could not be selected.');
+ echo '<table border="0" cellspacing="1" cellpadding="4">';
+ echo '<tr><th>Type</th><th>Value</th><th>Regular Expression</th><th></th></tr>';
+ if($db->numrows() < 1) echo '<td colspan="4">No ban rules yet.</td>';
+ while($r = $db->fetchrow())
+ {
+ if($r['ban_type']==BAN_IP) $t = 'IP address';
+ elseif($r['ban_type']==BAN_USER) $t = 'Username';
+ elseif($r['ban_type']==BAN_EMAIL) $t = 'E-mail address';
+ if($r['is_regex']) $g = 'Yes'; else $g = 'No';
+ echo '<tr><td>'.$t.'</td><td>'.$r['ban_value'].'</td><td>'.$g.'</td><td><a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'BanControl&action=delete&id='.$r['ban_id']).'">Delete</a></td></tr>';
+ }
+ $db->free_result();
+ echo '</table>';
+ echo '<h3>Create new ban rule</h3>';
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post">';
+ ?>
+ Type: <select name="type"><option value="<?php echo BAN_IP; ?>">IP address</option><option value="<?php echo BAN_USER; ?>">Username</option><option value="<?php echo BAN_EMAIL; ?>">E-mail address</option></select><br />
+ Rule: <input type="text" name="value" size="30" /><br />
+ Reason to show to the banned user: <textarea name="reason" rows="7" cols="20"></textarea><br />
+ <input type="checkbox" name="regex" id="regex" /> <label for="regex">This rule is a regular expression</label> (advanced users only)<br />
+ <input type="submit" style="font-weight: bold;" name="create" value="Create new ban rule" />
+ <?php
+ echo '</form>';
+}
+
+function page_Admin_MassEmail()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ global $enano_config;
+ if ( isset($_POST['do_send']) )
+ {
+ $use_smtp = getConfig('smtp_enabled') == '1';
+
+ //
+ // Let's do some checking to make sure that mass mail functions
+ // are working in win32 versions of php. (copied from phpBB)
+ //
+ if ( preg_match('/[c-z]:\\\.*/i', getenv('PATH')) && !$use_smtp)
+ {
+ $ini_val = ( @phpversion() >= '4.0.0' ) ? 'ini_get' : 'get_cfg_var';
+
+ // We are running on windows, force delivery to use our smtp functions
+ // since php's are broken by default
+ $use_smtp = true;
+ $enano_config['smtp_server'] = @$ini_val('SMTP');
+ }
+
+ $mail = new emailer( !empty($use_smtp) );
+
+ // Validate subject/message body
+ $subject = stripslashes(trim($_POST['subject']));
+ $message = stripslashes(trim($_POST['message']));
+
+ if ( empty($subject) )
+ $errors[] = 'Please enter a subject.';
+ if ( empty($message) )
+ $errors[] = 'Please enter a message.';
+
+ // Get list of members
+ if ( !empty($_POST['userlist']) )
+ {
+ $userlist = str_replace(', ', ',', $_POST['userlist']);
+ $userlist = explode(',', $userlist);
+ foreach ( $userlist as $k => $u )
+ {
+ if ( $u == $session->username )
+ {
+ // Message is automatically sent to the sender
+ unset($userlist[$k]);
+ }
+ else
+ {
+ $userlist[$k] = $db->escape($u);
+ }
+ }
+ $userlist = 'WHERE username=\'' . implode('\' OR username=\'', $userlist) . '\'';
+
+ $q = $db->sql_query('SELECT email FROM '.table_prefix.'users ' . $userlist . ';');
+ if ( !$q )
+ $db->_die();
+
+ if ( $row = $db->fetchrow() )
+ {
+ do {
+ $mail->cc($row['email']);
+ } while ( $row = $db->fetchrow() );
+ }
+
+ $db->free_result();
+
+ }
+ else
+ {
+ // Sending to a usergroup
+
+ $group_id = intval($_POST['group_id']);
+ if ( $group_id < 1 )
+ {
+ $errors[] = 'Invalid group ID';
+ }
+ else
+ {
+ $q = $db->sql_query('SELECT u.email FROM '.table_prefix.'group_members AS g
+ LEFT JOIN '.table_prefix.'users AS u
+ ON (u.user_id=g.user_id)
+ WHERE g.group_id=' . $group_id . ';');
+ if ( !$q )
+ $db->_die();
+
+ if ( $row = $db->fetchrow() )
+ {
+ do {
+ $mail->cc($row['email']);
+ } while ( $row = $db->fetchrow() );
+ }
+
+ $db->free_result();
+ }
+ }
+
+ if ( sizeof($errors) < 1 )
+ {
+
+ $mail->from(getConfig('contact_email'));
+ $mail->replyto(getConfig('contact_email'));
+ $mail->set_subject($subject);
+ $mail->email_address(getConfig('contact_email'));
+
+ // Copied/modified from phpBB
+ $email_headers = 'X-AntiAbuse: Website server name - ' . $_SERVER['SERVER_NAME'] . "\n";
+ $email_headers .= 'X-AntiAbuse: User_id - ' . $session->user_id . "\n";
+ $email_headers .= 'X-AntiAbuse: Username - ' . $session->username . "\n";
+ $email_headers .= 'X-AntiAbuse: User IP - ' . $_SERVER['REMOTE_ADDR'] . "\n";
+
+ $mail->extra_headers($email_headers);
+
+ $tpl = 'The following message was mass-mailed by {SENDER}, one of the administrators from {SITE_NAME}. If this message contains spam or any comments which you find abusive or offensive, please contact the administration team at:
+
+{CONTACT_EMAIL}
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+{MESSAGE}
+';
+
+ $mail->use_template($tpl);
+
+ $mail->assign_vars(array(
+ 'SENDER' => $session->username,
+ 'SITE_NAME' => getConfig('site_name'),
+ 'CONTACT_EMAIL' => getConfig('contact_email'),
+ 'MESSAGE' => $message
+ ));
+
+ //echo '<pre>'.print_r($mail,true).'</pre>';
+
+ // All done
+ $mail->send();
+ $mail->reset();
+
+ echo '<div class="info-box">Your message has been sent.</div>';
+
+ }
+ else
+ {
+ echo '<div class="warning-box">Could not send message for the following reason(s):<ul><li>' . implode('</li><li>', $errors) . '</li></ul></div>';
+ }
+
+ }
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Administration', 'module='.$paths->cpage['module']).'" method="post">';
+ ?>
+ <div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2">Send mass e-mail</th>
+ </tr>
+ <tr>
+ <td class="row2" rowspan="2" style="width: 30%; min-width: 200px;">
+ Send message to:<br />
+ <small>
+ By default, this message will be sent to the group selected here. You may instead send the message to a specific
+ list of users by entering them in the second row, with usernames separated by a single comma (no space).
+ </small>
+ </td>
+ <td class="row1">
+ <select name="group_id">
+ <?php
+ $q = $db->sql_query('SELECT group_name,group_id FROM '.table_prefix.'groups ORDER BY group_name ASC;');
+ if ( !$q )
+ $db->_die();
+ while ( $row = $db->fetchrow() )
+ {
+ echo '<option value="' . $row['group_id'] . '">' . $row['group_name'] . '</option>';
+ }
+ ?>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td class="row1">
+ Usernames: <input type="text" name="userlist" size="50" />
+ </td>
+ </tr>
+ <tr>
+ <td class="row2" style="width: 30%; min-width: 200px;">
+ Subject:
+ </td>
+ <td class="row1">
+ <input name="subject" type="text" size="50" />
+ </td>
+ </tr>
+ <tr>
+ <td class="row2" style="width: 30%; min-width: 200px;">
+ Message:
+ </td>
+ <td class="row1">
+ <textarea name="message" rows="30" cols="60" style="width: 100%;"></textarea>
+ </td>
+ </tr>
+ <tr>
+ <th class="subhead" colspan="2" style="text-align: left;" valign="middle">
+ <div style="float: right;"><input type="submit" name="do_send" value="Send message" /></div>
+ <small style="font-weight: normal;">Please be warned: it may take a LONG time to send this message. <b>Please do not stop the script until the process is finished.</b></small>
+ </th>
+ </tr>
+
+ </table>
+ </div>
+ <?php
+ echo '</form>';
+}
+
+function page_Admin_DBBackup()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ global $system_table_list;
+ if(isset($_GET['submitting']) && $_GET['submitting'] == 'yes')
+ {
+
+ if(defined('SQL_BACKUP_CRYPT'))
+ // Try to increase our time limit
+ @set_time_limit(300); // five minutes
+ // Do the actual export
+ $aesext = ( defined('SQL_BACKUP_CRYPT') ) ? '.tea' : '';
+ $filename = 'enano_backup_' . date('dmy') . '.sql' . $aesext;
+ ob_start();
+ header('Content-disposition: attachment, filename="'.$filename.'";');
+ header('Content-type: application/transact-sql');
+ // Spew some headers
+ $headdate = date('F d, Y \a\t h:i a');
+ echo <<<HEADER
+-- Enano CMS SQL backup
+-- Generated on {$headdate} by {$session->username}
+
+HEADER;
+ // build the table list
+ $base = ( isset($_POST['do_system_tables']) ) ? $system_table_list : Array();
+ $add = ( isset($_POST['additional_tables'])) ? $_POST['additional_tables'] : Array();
+ $tables = array_merge($base, $add);
+
+ // Log it!
+ $e = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'db_backup\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($session->username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', \'' . $db->escape(implode(', ', $tables)) . '\')');
+ if ( !$e )
+ $db->_die();
+
+ foreach($tables as $i => $t)
+ {
+ if(!preg_match('#^([a-z0-9_]+)$#i', $t))
+ die('Hacking attempt');
+ // if($t == table_prefix.'files' && isset($_POST['do_data']))
+ // unset($tables[$i]);
+ }
+ foreach($tables as $t)
+ {
+ // Sorry folks - this script CAN'T backup enano_files, enano_search_index, and enano_search_cache due to the sheer size of the tables.
+ // If encryption is enabled the log data will be excluded too.
+ echo export_table(
+ $t,
+ isset($_POST['do_struct']),
+ ( isset($_POST['do_data']) /* && $t != table_prefix.'files' && $t != table_prefix.'search_index' && $t != table_prefix.'search_cache' && ( !defined('SQL_BACKUP_CRYPT') || ( defined('SQL_BACKUP_CRYPT') && $t != table_prefix.'logs' ) ) */ ),
+ false
+ ) . "\n";
+ }
+ $data = ob_get_contents();
+ ob_end_clean();
+ if(defined('SQL_BACKUP_CRYPT'))
+ {
+ // Free some memory, we don't need this stuff any more
+ $db->close();
+ unset($paths, $db, $template, $plugins);
+ $tea = new TEACrypt();
+ $data = $tea->encrypt($data, $session->private_key);
+ }
+ header('Content-length: '.strlen($data));
+ echo $data;
+ exit;
+ }
+ else
+ {
+ // Show the UI
+ echo '<form action="'.makeUrlNS('Admin', 'DBBackup', 'submitting=yes', true).'" method="post" enctype="multipart/form-data">';
+ ?>
+ <p>This page allows you to back up your Enano database should something go miserably wrong.</p>
+ <p><label><input type="checkbox" name="do_system_tables" checked="checked" /> Export tables that are part of the Enano core</label><p>
+ <p>Additional tables to export:</p>
+ <p><select name="additional_tables[]" multiple="multiple">
+ <?php
+ $q = $db->sql_query('SHOW TABLES;') or $db->_die('Somehow we were denied the request to get the list of tables.');
+ while($row = $db->fetchrow_num())
+ {
+ if(!in_array($row[0], $system_table_list)) echo '<option value="'.$row[0].'">'.$row[0].'</option>';
+ }
+ ?>
+ </select>
+ </p>
+ <p><label><input type="checkbox" name="do_struct" checked="checked" /> Include table structure</label><br />
+ <label><input type="checkbox" name="do_data" checked="checked" /> Include table data</label>
+ </p>
+ <p><input type="submit" value="Create backup" /></p>
+ <?php
+ echo '</form>';
+ }
+}
+
+function page_Admin_AdminLogout()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+ {
+ echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
+ return;
+ }
+
+ $session->logout(USER_LEVEL_ADMIN);
+ echo '<h3>You have now been logged out of the administration panel.</h3><p>You will continue to be logged into the website, but you will need to re-authenticate before you can access the administration panel again.</p><p>Return to the <a href="'.makeUrl(getConfig('main_page')).'">Main Page</a>.</p>';
+}
+
+function page_Special_Administration()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ if($session->auth_level < USER_LEVEL_ADMIN) {
+ redirect(makeUrlNS('Special', 'Login/'.$paths->page, 'level='.USER_LEVEL_ADMIN), 'Not authorized', 'You need an authorization level of '.USER_LEVEL_ADMIN.' to use this page, your auth level is: ' . $session->auth_level, 0);
+ exit;
+ }
+ else
+ {
+ $template->load_theme('admin', 'default');
+ $template->init_vars();
+ if( !isset( $_GET['noheaders'] ) )
+ {
+ $template->header();
+ }
+ echo 'Administer your Enano website.';
+ ?>
+ <script type="text/javascript">
+ function ajaxPage(t)
+ {
+ if ( t == namespace_list.Admin + 'AdminLogout' )
+ {
+ var mb = new messagebox(MB_YESNO|MB_ICONQUESTION, 'Are you sure you want to de-authenticate?', 'If you de-authenticate, you will no longer be able to use the administration panel until you re-authenticate again. You may do so at any time using the Administration button on the sidebar.');
+ mb.onclick['Yes'] = function() {
+ var tigraentry = document.getElementById('i_div0_0').parentNode;
+ var tigraobj = $(tigraentry);
+ var div = document.createElement('div');
+ div.style.backgroundColor = '#FFFFFF';
+ domObjChangeOpac(70, div);
+ div.style.position = 'absolute';
+ var top = tigraobj.Top();
+ var left = tigraobj.Left();
+ var width = tigraobj.Width();
+ var height = tigraobj.Height();
+ div.style.top = top + 'px';
+ div.style.left = left + 'px';
+ div.style.width = width + 'px';
+ div.style.height = height + 'px';
+ var body = document.getElementsByTagName('body')[0];
+ enlighten(true);
+ body.appendChild(div);
+ ajaxPageBin(namespace_list.Admin + 'AdminLogout');
+ }
+ return;
+ }
+ ajaxPageBin(t);
+ }
+ function ajaxPageBin(t)
+ {
+ document.getElementById('ajaxPageContainer').innerHTML = '<div class="wait-box">Loading page...</div>';
+ ajaxGet('<?php echo scriptPath; ?>/ajax.php?title='+t+'&_mode=getpage&noheaders&auth=<?php echo $session->sid_super; ?>', function() {
+ if(ajax.readyState == 4) {
+ document.getElementById('ajaxPageContainer').innerHTML = ajax.responseText;
+ fadeInfoBoxes();
+ }
+ });
+ }
+ function _enanoAdminOnload() { ajaxPage('<?php echo $paths->nslist['Admin']; ?>Home'); }
+ var TREE_TPL = {
+ 'target' : '_self', // name of the frame links will be opened in
+ // other possible values are: _blank, _parent, _search, _self and _top
+
+ 'icon_e' : '<?php echo scriptPath; ?>/images/icons/empty.gif', // empty image
+ 'icon_l' : '<?php echo scriptPath; ?>/images/icons/line.gif', // vertical line
+ 'icon_32' : '<?php echo scriptPath; ?>/images/icons/base.gif', // root leaf icon normal
+ 'icon_36' : '<?php echo scriptPath; ?>/images/icons/base.gif', // root leaf icon selected
+ 'icon_48' : '<?php echo scriptPath; ?>/images/icons/base.gif', // root icon normal
+ 'icon_52' : '<?php echo scriptPath; ?>/images/icons/base.gif', // root icon selected
+ 'icon_56' : '<?php echo scriptPath; ?>/images/icons/base.gif', // root icon opened
+ 'icon_60' : '<?php echo scriptPath; ?>/images/icons/base.gif', // root icon selected
+ 'icon_16' : '<?php echo scriptPath; ?>/images/icons/folder.gif', // node icon normal
+ 'icon_20' : '<?php echo scriptPath; ?>/images/icons/folderopen.gif', // node icon selected
+ 'icon_24' : '<?php echo scriptPath; ?>/images/icons/folder.gif', // node icon opened
+ 'icon_28' : '<?php echo scriptPath; ?>/images/icons/folderopen.gif', // node icon selected opened
+ 'icon_0' : '<?php echo scriptPath; ?>/images/icons/page.gif', // leaf icon normal
+ 'icon_4' : '<?php echo scriptPath; ?>/images/icons/page.gif', // leaf icon selected
+ 'icon_8' : '<?php echo scriptPath; ?>/images/icons/page.gif', // leaf icon opened
+ 'icon_12' : '<?php echo scriptPath; ?>/images/icons/page.gif', // leaf icon selected
+ 'icon_2' : '<?php echo scriptPath; ?>/images/icons/joinbottom.gif', // junction for leaf
+ 'icon_3' : '<?php echo scriptPath; ?>/images/icons/join.gif', // junction for last leaf
+ 'icon_18' : '<?php echo scriptPath; ?>/images/icons/plusbottom.gif', // junction for closed node
+ 'icon_19' : '<?php echo scriptPath; ?>/images/icons/plus.gif', // junction for last closed node
+ 'icon_26' : '<?php echo scriptPath; ?>/images/icons/minusbottom.gif',// junction for opened node
+ 'icon_27' : '<?php echo scriptPath; ?>/images/icons/minus.gif' // junction for last opended node
+ };
+ <?php
+ echo $paths->parseAdminTree(); // Make a Javascript array that defines the tree
+ if(!isset($_GET['module'])) { echo 'addOnloadHook(_enanoAdminOnload);'; } ?>
+ </script>
+ <table border="0" width="100%">
+ <tr>
+ <td class="holder" valign="top">
+ <div class="pad" style="padding-right: 20px;">
+ <script type="text/javascript">
+ new tree(TREE_ITEMS, TREE_TPL);
+ </script>
+ </div>
+ </td>
+ <td width="100%" valign="top">
+ <div class="pad" id="ajaxPageContainer">
+ <?php
+ if(isset($_GET['module']))
+ {
+ // Look for a namespace prefix in the urlname, and assign a different namespace, if necessary
+ $k = array_keys($paths->nslist);
+ for ( $i = 0; $i < sizeof($paths->nslist); $i++ )
+ {
+ $ln = strlen( $paths->nslist[ $k[ $i ] ] );
+ if ( substr($_GET['module'], 0, $ln) == $paths->nslist[$k[$i]] )
+ {
+ $ns = $k[$i];
+ $nm = substr($_GET['module'], $ln, strlen($_GET['module']));
+ }
+ }
+ $fname = 'page_'.$ns.'_'.$nm;
+ $s = strpos($fname, '?noheaders');
+ if($s) $fname = substr($fname, 0, $s);
+ $paths->cpage['module'] = $_GET['module'];
+ if ( function_exists($fname) && $_GET['module'] != $paths->nslist['Special'] . 'Administration' )
+ {
+ eval($fname.'();');
+ }
+ }
+ else
+ {
+ echo '<div class="wait-box">Please wait while the administration panel loads. You need to be using a recent browser with AJAX support in order to use Runt.</div>';
+ }
+ ?>
+ </div>
+ </td>
+ </tr>
+ </table>
+
+ <?php
+ }
+ if(!isset($_GET['noheaders']))
+ {
+ $template->footer();
+ }
+}
+
+function page_Special_EditSidebar()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ if($session->auth_level < USER_LEVEL_ADMIN)
+ {
+ redirect(makeUrlNS('Special', 'Login/'.$paths->page, 'level='.USER_LEVEL_ADMIN), '', '', false);
+ exit;
+ }
+ else
+ {
+
+ $template->add_header('<script type="text/javascript" src="'.scriptPath.'/includes/clientside/dbx.js"></script>');
+ $template->add_header('<script type="text/javascript" src="'.scriptPath.'/includes/clientside/dbx-key.js"></script>');
+ $template->add_header('<script type="text/javascript" src="'.scriptPath.'/includes/clientside/sbedit.js"></script>');
+ $template->add_header('<link rel="stylesheet" type="text/css" href="'.scriptPath.'/includes/clientside/dbx.css" />');
+
+ // Knock the sidebars dead to keep javascript in plugins from interfering
+ $template->tpl_strings['SIDEBAR_LEFT'] = '';
+ $template->tpl_strings['SIDEBAR_RIGHT'] = '';
+
+ $template->load_theme('oxygen', 'bleu');
+ $template->init_vars();
+
+ $template->header();
+
+ if(isset($_POST['save']))
+ {
+ // Write the new block order to the database
+ // The only way to do this is with tons of queries (one per block + one select query at the start to count everything) but afaik its safe...
+ // Anyone know a better way to do this?
+ $q = $db->sql_query('SELECT item_order,item_id,sidebar_id FROM '.table_prefix.'sidebar ORDER BY sidebar_id ASC, item_order ASC;');
+ if ( !$q )
+ {
+ $db->_die('The sidebar order data could not be selected.');
+ }
+ $orders = Array();
+ while($row = $db->fetchrow())
+ {
+ $orders[] = Array(
+ count($orders),
+ $row['item_id'],
+ $row['sidebar_id'],
+ );
+ }
+ $db->free_result();
+
+ // We now have an array with each sidebar ID in its respective order. Explode the order string in $_POST['order_(left|right)'] and use it to build a set of queries.
+ $ol = explode(',', $_POST['order_left']);
+ $odr = explode(',', $_POST['order_right']);
+ $om = array_merge($ol, $odr);
+ unset($ol, $odr);
+ $queries = Array();
+ foreach($orders as $k => $v)
+ {
+ $queries[] = 'UPDATE '.table_prefix.'sidebar SET item_order='.$om[$k].' WHERE item_id='.$v[1].';';
+ }
+ foreach($queries as $sql)
+ {
+ $q = $db->sql_query($sql);
+ if(!$q)
+ {
+ $t = $db->get_error();
+ echo $t;
+ $template->footer();
+ exit;
+ }
+ }
+ echo '<div class="info-box" style="margin: 10px 0;">The sidebar order information was updated successfully.</div>';
+ }
+ elseif(isset($_POST['create']))
+ {
+ switch((int)$_POST['type'])
+ {
+ case BLOCK_WIKIFORMAT:
+ $content = $_POST['wikiformat_content'];
+ break;
+ case BLOCK_TEMPLATEFORMAT:
+ $content = $_POST['templateformat_content'];
+ break;
+ case BLOCK_HTML:
+ $content = $_POST['html_content'];
+ break;
+ case BLOCK_PHP:
+ $content = $_POST['php_content'];
+ break;
+ case BLOCK_PLUGIN:
+ $content = $_POST['plugin_id'];
+ break;
+ }
+ // Get the value of item_order
+
+ $q = $db->sql_query('SELECT * FROM '.table_prefix.'sidebar WHERE sidebar_id='.$db->escape($_POST['sidebar_id']).';');
+ if(!$q) $db->_die('The order number could not be selected');
+ $io = $db->numrows();
+
+ $db->free_result();
+
+ $q = 'INSERT INTO '.table_prefix.'sidebar(block_name, block_type, sidebar_id, block_content, item_order) VALUES ( \''.$db->escape($_POST['title']).'\', \''.$db->escape($_POST['type']).'\', \''.$db->escape($_POST['sidebar_id']).'\', \''.$db->escape($content).'\', '.$io.' );';
+ $result = $db->sql_query($q);
+ if(!$result)
+ {
+ echo $db->get_error();
+ $template->footer();
+ exit;
+ }
+
+ echo '<div class="info-box" style="margin: 10px 0;">The item was added.</div>';
+
+ }
+
+ if(isset($_GET['action']) && isset($_GET['id']))
+ {
+ if(preg_match('#^([0-9]*)$#', $_GET['id']))
+ {
+ } else {
+ echo '<div class="warning-box">Error with action: $_GET["id"] was not an integer, aborting to prevent SQL injection</div>';
+ }
+ switch($_GET['action'])
+ {
+ case 'new':
+ ?>
+ <script type="text/javascript">
+ function setType(input)
+ {
+ val = input.value;
+ if(!val)
+ {
+ return false;
+ }
+ var divs = getElementsByClassName(document, 'div', 'sbadd_block');
+ for(var i in divs)
+ {
+ if(divs[i].id == 'blocktype_'+val) divs[i].style.display = 'block';
+ else divs[i].style.display = 'none';
+ }
+ }
+ </script>
+
+ <form action="<?php echo makeUrl($paths->page); ?>" method="post">
+
+ <p>
+ What type of block should this be?
+ </p>
+ <p>
+ <select name="type" onchange="setType(this)"> <?php /* (NOT WORKING, at least in firefox 2) onload="var thingy = this; setTimeout('setType(thingy)', 500);" */ ?>
+ <option value="<?php echo BLOCK_WIKIFORMAT; ?>">Wiki-formatted block</option>
+ <option value="<?php echo BLOCK_TEMPLATEFORMAT; ?>">Template-formatted block (old pre-beta 3 behavior)</option>
+ <option value="<?php echo BLOCK_HTML; ?>">Raw HTML block</option>
+ <option value="<?php echo BLOCK_PHP; ?>">PHP code block (danger, Will Robinson!)</option>
+ <option value="<?php echo BLOCK_PLUGIN; ?>">Use code from a plugin</option>
+ </select>
+ </p>
+
+ <p>
+
+ Block title: <input name="title" type="text" size="40" /><br />
+ Which sidebar: <select name="sidebar_id"><option value="<?php echo SIDEBAR_LEFT; ?>">Left</option><option value="<?php echo SIDEBAR_RIGHT; ?>">Right</option></select>
+
+ </p>
+
+ <div class="sbadd_block" id="blocktype_<?php echo BLOCK_WIKIFORMAT; ?>">
+ <p>
+ Wikitext:
+ </p>
+ <p>
+ <textarea style="width: 98%;" name="wikiformat_content" rows="15" cols="50"></textarea>
+ </p>
+ </div>
+
+ <div class="sbadd_block" id="blocktype_<?php echo BLOCK_TEMPLATEFORMAT; ?>">
+ <p>
+ Template code:
+ </p>
+ <p>
+ <textarea style="width: 98%;" name="templateformat_content" rows="15" cols="50"></textarea>
+ </p>
+ </div>
+
+ <div class="sbadd_block" id="blocktype_<?php echo BLOCK_HTML; ?>">
+ <p>
+ HTML to place inside the sidebar:
+ </p>
+ <p>
+ <textarea style="width: 98%;" name="html_content" rows="15" cols="50"></textarea>
+ </p>
+ </div>
+
+ <div class="sbadd_block" id="blocktype_<?php echo BLOCK_PHP; ?>">
+ <p>
+ <b>WARNING:</b> If you don't know what you're doing, or if you are not fluent in PHP, stop now and choose a different block type. You will brick your Enano installation if you are not careful here.
+ ALWAYS remember to write secure code! The Enano team is not responsible if someone drops all your tables because of an SQL injection vulnerability in your sidebar code. You are probably better off using the template-formatted block type.
+ </p>
+ <p>
+ <span style="color: red;">
+ It is especially important to note that this code is NOT checked for errors! If there is a syntax error in your code here, it will prevent any pages from loading AT ALL. So you need to use an external PHP editor (like <a href="http://www.jedit.org">jEdit</a>) to check your syntax before you hit save.
+ </span> You have been warned.
+ </p>
+ <p>
+ Also, you should avoid using output buffering functions (ob_[start|end|get_contents|clean]) here, because Enano uses those to track output from this script.
+ </p>
+ <p>
+ The standard <?php and ?> tags work here. Don't use an initial "<?php" or it will cause a parse error.
+ </p>
+ <p>
+ PHP code:
+ </p>
+ <p>
+ <textarea style="width: 98%;" name="php_content" rows="15" cols="50"></textarea>
+ </p>
+ </div>
+
+ <div class="sbadd_block" id="blocktype_<?php echo BLOCK_PLUGIN; ?>">
+ <p>
+ Plugin:
+ </p>
+ <p>
+ <select name="plugin_id">
+ <?php
+ foreach($template->plugin_blocks as $k => $c)
+ {
+ echo '<option value="'.$k.'">'.$k.'</option>';
+ }
+ ?>
+ </select>
+ </p>
+ </div>
+
+ <p>
+
+ <input type="submit" name="create" value="Create new block" style="font-weight: bold;" />
+ <input type="submit" name="cancel" value="Cancel" />
+
+ </p>
+
+ </form>
+
+ <script type="text/javascript">
+ var divs = getElementsByClassName(document, 'div', 'sbadd_block');
+ for(var i in divs)
+ {
+ if(divs[i].id != 'blocktype_<?php echo BLOCK_WIKIFORMAT; ?>') setTimeout("document.getElementById('"+divs[i].id+"').style.display = 'none';", 500);
+ }
+ </script>
+
+ <?php
+ $template->footer();
+ return;
+ break;
+ case 'move':
+ if( !isset($_GET['side']) || ( isset($_GET['side']) && !preg_match('#^([0-9]+)$#', $_GET['side']) ) )
+ {
+ echo '<div class="warning-box" style="margin: 10px 0;">$_GET[\'side\'] contained an SQL injection attempt</div>';
+ break;
+ }
+ $query = $db->sql_query('UPDATE '.table_prefix.'sidebar SET sidebar_id=' . $db->escape($_GET['side']) . ' WHERE item_id=' . $db->escape($_GET['id']) . ';');
+ if(!$query)
+ {
+ echo $db->get_error();
+ $template->footer();
+ exit;
+ }
+ echo '<div class="info-box" style="margin: 10px 0;">Item moved.</div>';
+ break;
+ case 'delete':
+ $query = $db->sql_query('DELETE FROM '.table_prefix.'sidebar WHERE item_id=' . $db->escape($_GET['id']) . ';'); // Already checked for injection attempts ;-)
+ if(!$query)
+ {
+ echo $db->get_error();
+ $template->footer();
+ exit;
+ }
+ if(isset($_GET['ajax']))
+ {
+ ob_end_clean();
+ die('GOOD');
+ }
+ echo '<div class="error-box" style="margin: 10px 0;">Item deleted.</div>';
+ break;
+ case 'disenable';
+ $q = $db->sql_query('SELECT item_enabled FROM '.table_prefix.'sidebar WHERE item_id=' . $db->escape($_GET['id']) . ';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ $template->footer();
+ exit;
+ }
+ $r = $db->fetchrow();
+ $db->free_result();
+ $e = ( $r['item_enabled'] == 1 ) ? '0' : '1';
+ $q = $db->sql_query('UPDATE '.table_prefix.'sidebar SET item_enabled='.$e.' WHERE item_id=' . $db->escape($_GET['id']) . ';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ $template->footer();
+ exit;
+ }
+ if(isset($_GET['ajax']))
+ {
+ ob_end_clean();
+ die('GOOD');
+ }
+ break;
+ case 'getsource':
+ $q = $db->sql_query('SELECT block_content,block_type FROM '.table_prefix.'sidebar WHERE item_id=' . $db->escape($_GET['id']) . ';');
+ if(!$q)
+ {
+ echo $db->get_error();
+ $template->footer();
+ exit;
+ }
+ ob_end_clean();
+ $r = $db->fetchrow();
+ $db->free_result();
+ if($r['block_type'] == BLOCK_PLUGIN) die('HOUSTON_WE_HAVE_A_PLUGIN');
+ die($r['block_content']);
+ break;
+ case 'save':
+ $q = $db->sql_query('UPDATE '.table_prefix.'sidebar SET block_content=\''.$db->escape(rawurldecode($_POST['content'])).'\' WHERE item_id=' . $db->escape($_GET['id']) . ';');
+ if(!$q)
+ {
+ echo 'var status=unescape(\''.hexencode($db->get_error()).'\');';
+ exit;
+ }
+ $q = $db->sql_query('SELECT block_type,block_content FROM '.table_prefix.'sidebar WHERE item_id=' . $db->escape($_GET['id']) . ';');
+ if(!$q)
+ {
+ echo 'var status=unescape(\''.hexencode($db->get_error()).'\');';
+ exit;
+ }
+ $row = $db->fetchrow();
+ $db->free_result();
+ switch($row['block_type'])
+ {
+ case BLOCK_WIKIFORMAT:
+ default:
+ $c = RenderMan::render($row['block_content']);
+ break;
+ case BLOCK_TEMPLATEFORMAT:
+ $c = $template->tplWikiFormat($row['block_content'], false, 'sidebar-editor.tpl');
+ $c = preg_replace('#<a (.*?)>(.*?)</a>#is', '<a href="#" onclick="return false;">\\2</a>', $c);
+ break;
+ case BLOCK_HTML:
+ $c = $row['block_content'];
+ $c = preg_replace('#<a (.*?)>(.*?)</a>#is', '<a href="#" onclick="return false;">\\2</a>', $c);
+ break;
+ case BLOCK_PHP:
+ ob_start();
+ eval($row['block_content']);
+ $c = ob_get_contents();
+ ob_end_clean();
+ $c = preg_replace('#<a (.*?)>(.*?)</a>#is', '<a href="#" onclick="return false;">\\2</a>', $c);
+ break;
+ case BLOCK_PLUGIN:
+ $c = ($template->fetch_block($row['block_content'])) ? $template->fetch_block($row['block_content']) : 'Can\'t find plugin block';
+ break;
+ }
+ die('var status = \'GOOD\'; var content = unescape(\''.hexencode($c).'\');');
+ break;
+ }
+ }
+
+ $q = $db->sql_query('SELECT item_id,sidebar_id,item_enabled,block_name,block_type,block_content FROM '.table_prefix.'sidebar ORDER BY sidebar_id ASC, item_order ASC;');
+ if(!$q) $db->_die('The sidebar text data could not be selected.');
+
+ $vars = $template->extract_vars('sidebar-editor.tpl');
+
+ $parser = $template->makeParserText($vars['sidebar_button']);
+ $parser->assign_vars(Array(
+ 'HREF'=>'#',
+ 'FLAGS'=>'onclick="return false;"',
+ 'TEXT'=>'Change theme'
+ ));
+ $template->tpl_strings['THEME_LINK'] = $parser->run();
+ $parser->assign_vars(Array(
+ 'TEXT'=>'Log out',
+ ));
+ $template->tpl_strings['LOGOUT_LINK'] = $parser->run();
+
+ $n1 = Array();
+ $n2 = Array();
+ $n =& $n1;
+
+ echo '<table border="0"><tr><td valign="top"><div class="dbx-group" id="sbedit_left">';
+ //if(isset($vars['sidebar_top'])) echo $template->parse($vars['sidebar_top']);
+
+ // Time for the loop
+ // what this loop does is fetch the row data, then send it out to the appropriate parser for formatting,
+ // then puts the result into $c, which is then sent to the template compiler for insertion into the TPL code.
+ while($row = $db->fetchrow())
+ {
+ if(isset($current_side))
+ {
+ if($current_side != $row['sidebar_id'])
+ {
+ // Time to switch!
+ //if(isset($vars['sidebar_top'])) echo $template->parse($vars['sidebar_bottom']);
+ echo '</div></td><td valign="top"><div class="dbx-group" id="sbedit_right">';
+ //echo '</td><td valign="top">';
+ //if(isset($vars['sidebar_top'])) echo $template->parse($vars['sidebar_top']);
+ $n =& $n2;
+ }
+ }
+ $n[] = count($n);
+ $current_side = $row['sidebar_id'];
+ switch($row['block_type'])
+ {
+ case BLOCK_WIKIFORMAT:
+ default:
+ $parser = $template->makeParserText($vars['sidebar_section']);
+ $c = RenderMan::render($row['block_content']);
+ break;
+ case BLOCK_TEMPLATEFORMAT:
+ $parser = $template->makeParserText($vars['sidebar_section']);
+ $c = $template->tplWikiFormat($row['block_content'], false, 'sidebar-editor.tpl');
+ $c = preg_replace('#<a (.*?)>(.*?)</a>#is', '<a href="#" onclick="return false;">\\2</a>', $c);
+ break;
+ case BLOCK_HTML:
+ $parser = $template->makeParserText($vars['sidebar_section_raw']);
+ $c = $row['block_content'];
+ $c = preg_replace('#<a (.*?)>(.*?)</a>#is', '<a href="#" onclick="return false;">\\2</a>', $c);
+ break;
+ case BLOCK_PHP:
+ $parser = $template->makeParserText($vars['sidebar_section_raw']);
+ ob_start();
+ eval($row['block_content']);
+ $c = ob_get_contents();
+ ob_end_clean();
+ $c = preg_replace('#<a (.*?)>(.*?)</a>#is', '<a href="#" onclick="return false;">\\2</a>', $c);
+ break;
+ case BLOCK_PLUGIN:
+ $parser = $template->makeParserText($vars['sidebar_section_raw']);
+ $c = ($template->fetch_block($row['block_content'])) ? $template->fetch_block($row['block_content']) : 'Can\'t find plugin block';
+ break;
+ }
+ $t = $template->tplWikiFormat($row['block_name']);
+ if($row['item_enabled'] == 0) $t .= ' <span id="disabled_'.$row['item_id'].'" style="color: red;">(disabled)</span>';
+ else $t .= ' <span id="disabled_'.$row['item_id'].'" style="color: red; display: none;">(disabled)</span>';
+ $side = ( $row['sidebar_id'] == SIDEBAR_LEFT ) ? SIDEBAR_RIGHT : SIDEBAR_LEFT;
+ $tb = '<a title="Enable or disable this block" href="'.makeUrl($paths->page, 'action=disenable&id='.$row['item_id'].'' , true).'" onclick="ajaxDisenableBlock(\''.$row['item_id'].'\'); return false;" ><img alt="Enable/disable this block" style="border-width: 0;" src="'.scriptPath.'/images/disenable.png" /></a>
+ <a title="Edit the contents of this block" href="'.makeUrl($paths->page, 'action=edit&id='.$row['item_id'].'' , true).'" onclick="ajaxEditBlock(\''.$row['item_id'].'\', this); return false;"><img alt="Edit this block" style="border-width: 0;" src="'.scriptPath.'/images/edit.png" /></a>
+ <a title="Permanently delete this block" href="'.makeUrl($paths->page, 'action=delete&id='.$row['item_id'].'' , true).'" onclick="if(confirm(\'Do you really want to delete this block?\')) { ajaxDeleteBlock(\''.$row['item_id'].'\', this); } return false;"><img alt="Delete this block" style="border-width: 0;" src="'.scriptPath.'/images/delete.png" /></a>
+ <a title="Move this block to the other sidebar" href="'.makeUrl($paths->page, 'action=move&id='.$row['item_id'].'&side='.$side, true).'"><img alt="Move this block" style="border-width: 0;" src="'.scriptPath.'/images/move.png" /></a>';
+ $as = '';
+ $ae = ' '.$tb;
+ $parser->assign_vars(Array('CONTENT'=>$c,'TITLE'=>$t,'ADMIN_START'=>$as,'ADMIN_END'=>$ae));
+ echo $parser->run();
+ unset($parser);
+
+ }
+ $db->free_result();
+ //if(isset($vars['sidebar_top'])) echo $template->parse($vars['sidebar_bottom']);
+ echo '</div></td></tr></table>';
+ echo '<form action="'.makeUrl($paths->page).'" method="post">';
+ $order = implode(',', $n1);
+ echo "<input type='hidden' id='divOrder_Left' name='order_left' value='{$order}' />";
+ $order = implode(',', $n2);
+ echo "<input type='hidden' id='divOrder_Right' name='order_right' value='{$order}' />";
+ echo '
+ <div style="margin: 0 auto 0 auto; text-align: center;">
+ <input type="submit" name="save" style="font-weight: bold;" value="Save changes" />
+ <input type="submit" name="revert" style="font-weight: normal;" value="Revert" onclick="return confirm(\'Do you really want to revert your changes?\nNote: this does not revert edits or deletions, those are saved as soon as you confirm the action.\')" />
+ <br />
+ <a href="'.makeUrl($paths->page, 'action=new&id=0', true).'">Create new block</a> | <a href="'.makeUrl(getConfig('main_page'), false, true).'">Main Page</a>
+ </div>
+ </form>
+ ';
+ }
+
+ $template->footer();
+}
+
+?>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/SpecialCSS.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,47 @@
+<?php
+/*
+Plugin Name: CSS Backend
+Plugin URI: http://enano.homelinux.org/
+Description: Provides the page Special:CSS, which is used in template files to reference the style sheet. Disabling or deleting this plugin will result in site instability.
+Author: Dan Fuhry
+Version: 1.0
+Author URI: http://enano.homelinux.org/
+*/
+
+/*
+ * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
+ * Version 1.0 release candidate 2
+ * Copyright (C) 2006-2007 Dan Fuhry
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+global $db, $session, $paths, $template, $plugins; // Common objects
+
+$plugins->attachHook('base_classes_initted', '
+ global $paths;
+ $paths->add_page(Array(
+ \'name\'=>\'CSS\',
+ \'urlname\'=>\'CSS\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ ');
+
+// function names are IMPORTANT!!! The name pattern is: page_<namespace ID>_<page URLname, without namespace>
+
+function page_Special_CSS() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ header('Content-type: text/css');
+ if(isset($_GET['printable']) || $paths->getParam(0) == 'printable') {
+ echo $template->get_css('_printable.css');
+ } else {
+ echo $template->get_css();
+ }
+}
+
+?>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/SpecialGroups.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,540 @@
+<?php
+/*
+Plugin Name: Group control panel
+Plugin URI: http://www.enanocms.org/
+Description: Provides group moderators and site administrators with the ability to control who is part of their groups.
+Author: Dan Fuhry
+Version: 1.0RC1
+Author URI: http://www.enanocms.org/
+*/
+
+/*
+ * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
+ * Version 1.0 release candidate 2
+ * Copyright (C) 2007 Dan Fuhry
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+$plugins->attachHook('base_classes_initted', '
+ global $paths;
+ $paths->add_page(Array(
+ \'name\'=>\'Group Membership\',
+ \'urlname\'=>\'Usergroups\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ ');
+
+function page_Special_Usergroups()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $email; // Import e-mail encryption functions
+
+ if ( !$session->user_logged_in )
+ {
+ header('Location: ' . makeUrlComplete('Special', 'Login/' . $paths->page));
+ $db->close();
+ exit;
+ }
+
+ $template->header();
+ if ( isset($_POST['do_view']) || isset($_POST['do_view_n']) || ( isset($_GET['act']) && isset($_POST['group_id']) ) )
+ {
+ $gid = ( isset ( $_POST['do_view_n'] ) ) ? intval($_POST['group_id_n']) : intval($_POST['group_id']);
+ if ( empty($gid) || $gid < 1 )
+ {
+ die_friendly('Error', '<p>Hacking attempt</p>');
+ }
+ $q = $db->sql_query('SELECT group_name,group_type FROM '.table_prefix.'groups WHERE group_id=' . $gid . ';');
+ if ( !$q )
+ {
+ $db->_die();
+ }
+ $row = $db->fetchrow();
+ $db->free_result();
+ $members = array();
+ $pending = array();
+ $q = $db->sql_query('SELECT u.username,u.email,u.reg_time,m.member_id,m.user_id,m.is_mod,m.pending,COUNT(c.comment_id)
+ FROM '.table_prefix.'users AS u
+ LEFT JOIN '.table_prefix.'group_members AS m
+ ON ( m.user_id = u.user_id )
+ LEFT JOIN '.table_prefix.'comments AS c
+ ON ( c.name = u.username )
+ WHERE m.group_id=' . $gid . '
+ GROUP BY u.user_id
+ ORDER BY m.is_mod DESC,u.username ASC;');
+ if ( !$q )
+ {
+ $db->_die();
+ }
+
+ $is_member = false;
+ $is_mod = false;
+ $is_pending = false;
+
+ while ( $mr = $db->fetchrow() )
+ {
+ if ( $mr['pending'] == 1 )
+ {
+ $pending[] = $mr;
+ if ( $mr['user_id'] == $session->user_id )
+ {
+ $is_pending = true;
+ }
+ }
+ else
+ {
+ $members[] = $mr;
+ if ( $mr['user_id'] == $session->user_id )
+ {
+ $is_member = true;
+ if ( $mr['is_mod'] == 1 )
+ {
+ $is_mod = true;
+ }
+ }
+ }
+ }
+
+ $status = ( $is_member && $is_mod )
+ ? 'You are a moderator of this group.'
+ : ( ( $is_member && !$is_mod )
+ ? 'You are a member of this group.'
+ : 'You are not a member of this group.'
+ );
+
+ $can_do_admin_stuff = ( $is_mod || $session->user_level >= USER_LEVEL_ADMIN );
+
+ switch ( $row['group_type'] )
+ {
+ case GROUP_HIDDEN: $g_state = 'Hidden group'; break;
+ case GROUP_CLOSED: $g_state = 'Closed group'; break;
+ case GROUP_REQUEST: $g_state = 'Members can request to join'; break;
+ case GROUP_OPEN: $g_state = 'Anyone can join'; break;
+ }
+
+ if ( isset($_GET['act']) && $can_do_admin_stuff )
+ {
+ switch($_GET['act'])
+ {
+ case 'update':
+ if(!in_array(intval($_POST['group_state']), Array(GROUP_CLOSED, GROUP_OPEN, GROUP_HIDDEN, GROUP_REQUEST)))
+ {
+ die_friendly('ERROR', '<p>Hacking attempt</p>');
+ }
+ $q = $db->sql_query('UPDATE '.table_prefix.'groups SET group_type=' . intval($_POST['group_state']) . ' WHERE group_id=' . intval( $_POST['group_id']) . ';');
+ if (!$q)
+ $db->_die();
+ $row['group_type'] = $_POST['group_state'];
+ echo '<div class="info-box" style="margin-left: 0;">The group state was updated.</div>';
+ break;
+ case 'adduser':
+ $username = $_POST['add_username'];
+ $mod = ( isset($_POST['add_mod']) ) ? '1' : '0';
+
+ $q = $db->sql_query('SELECT user_id FROM '.table_prefix.'users WHERE username=\'' . $db->escape($username) . '\';');
+ if (!$q)
+ $db->_die();
+ if ($db->numrows() < 1)
+ {
+ echo '<div class="error-box">The username you entered could not be found.</div>';
+ break;
+ }
+ $r = $db->fetchrow();
+ $db->free_result();
+ $uid = intval($r['user_id']);
+
+ // Check if the user is already in the group, and if so, only update modship
+ $q = $db->sql_query('SELECT member_id,is_mod FROM '.table_prefix.'group_members WHERE user_id=' . $uid . ' AND group_id=' . intval($_POST['group_id']) . ';');
+ if ( !$q )
+ $db->_die();
+ if ( $db->numrows() > 0 )
+ {
+ $r = $db->fetchrow();
+ if ( (string) $r['is_mod'] != $mod )
+ {
+ $q = $db->sql_query('UPDATE '.table_prefix.'group_members SET is_mod=' . $mod . ' WHERE member_id=' . $r['member_id'] . ';');
+ if ( !$q )
+ $db->_die();
+ foreach ( $members as $i => $member )
+ {
+ if ( $member['member_id'] == $r['member_id'] )
+ $members[$i]['is_mod'] = (int)$mod;
+ }
+ echo '<div class="info-box">The user "' . $username . '" is already in this group, so their moderator status was updated.</div>';
+ }
+ else
+ {
+ echo '<div class="info-box">The user "' . $username . '" is already in this group.</div>';
+ }
+ break;
+ }
+
+ $db->free_result();
+
+ $q = $db->sql_query('INSERT INTO '.table_prefix.'group_members(group_id,user_id,is_mod) VALUES(' . intval($_POST['group_id']) . ', ' . $uid . ', ' . $mod . ');');
+ if (!$q)
+ $db->_die();
+ echo '<div class="info-box">The user "' . $username . '" has been added to this usergroup.</div>';
+
+ $q = $db->sql_query('SELECT u.username,u.email,u.reg_time,m.member_id,m.user_id,m.is_mod,COUNT(c.comment_id)
+ FROM '.table_prefix.'users AS u
+ LEFT JOIN '.table_prefix.'group_members AS m
+ ON ( m.user_id = u.user_id )
+ LEFT JOIN '.table_prefix.'comments AS c
+ ON ( c.name = u.username )
+ WHERE m.group_id=' . $gid . '
+ AND m.pending!=1
+ AND u.user_id=' . $uid . '
+ GROUP BY u.user_id
+ ORDER BY m.is_mod DESC,u.username ASC
+ LIMIT 1;');
+ if ( !$q )
+ $db->_die();
+
+ $r = $db->fetchrow();
+ $members[] = $r;
+ $db->free_result();
+
+ break;
+ case 'del_users':
+ foreach ( $members as $i => $member )
+ {
+ if ( isset($_POST['del_user'][$member['member_id']]) )
+ {
+ $q = $db->sql_query('DELETE FROM '.table_prefix.'group_members WHERE member_id=' . $member['member_id'] . ';');
+ if (!$q)
+ $db->_die();
+ unset($members[$i]);
+ }
+ }
+ break;
+ case 'pending':
+ foreach ( $pending as $i => $member )
+ {
+ if ( isset( $_POST['with_user'][$member['member_id']]) )
+ {
+ if ( isset ( $_POST['do_appr_pending'] ) )
+ {
+ $q = $db->sql_query('UPDATE '.table_prefix.'group_members SET pending=0 WHERE member_id=' . $member['member_id'] . ';');
+ if (!$q)
+ $db->_die();
+ $members[] = $member;
+ unset($pending[$i]);
+ continue;
+ }
+ elseif ( isset ( $_POST['do_reject_pending'] ) )
+ {
+ $q = $db->sql_query('DELETE FROM '.table_prefix.'group_members WHERE member_id=' . $member['member_id'] . ';');
+ if (!$q)
+ $db->_die();
+ unset($pending[$i]);
+ }
+ }
+ }
+ echo '<div class="info-box">Pending members status updated successfully.</div>';
+ break;
+ }
+ }
+
+ if ( isset($_GET['act']) && $_GET['act'] == 'update' && !$is_member && $row['group_type'] == GROUP_OPEN )
+ {
+ $q = $db->sql_query('INSERT INTO '.table_prefix.'group_members(group_id,user_id) VALUES(' . $gid . ', ' . $session->user_id . ');');
+ if (!$q)
+ $db->_die();
+ echo '<div class="info-box">You have been added to this group.</div>';
+
+ $q = $db->sql_query('SELECT u.username,u.email,u.reg_time,m.member_id,m.user_id,m.is_mod,COUNT(c.comment_id)
+ FROM '.table_prefix.'users AS u
+ LEFT JOIN '.table_prefix.'group_members AS m
+ ON ( m.user_id = u.user_id )
+ LEFT JOIN '.table_prefix.'comments AS c
+ ON ( c.name = u.username )
+ WHERE m.group_id=' . $gid . '
+ AND m.pending!=1
+ AND u.user_id=' . $session->user_id . '
+ GROUP BY u.user_id
+ ORDER BY m.is_mod DESC,u.username ASC
+ LIMIT 1;');
+ if ( !$q )
+ $db->_die();
+
+ $r = $db->fetchrow();
+ $members[] = $r;
+ $db->free_result();
+
+ }
+
+ if ( isset($_GET['act']) && $_GET['act'] == 'update' && !$is_member && $row['group_type'] == GROUP_REQUEST && !$is_pending )
+ {
+ $q = $db->sql_query('INSERT INTO '.table_prefix.'group_members(group_id,user_id,pending) VALUES(' . $gid . ', ' . $session->user_id . ', 1);');
+ if (!$q)
+ $db->_die();
+ echo '<div class="info-box">A request has been sent to the moderator(s) of this group to add you.</div>';
+ }
+
+ $state_btns = ( $can_do_admin_stuff ) ?
+ '<label><input type="radio" name="group_state" value="' . GROUP_HIDDEN . '" ' . (( $row['group_type'] == GROUP_HIDDEN ) ? 'checked="checked"' : '' ) . ' /> Hidden group</label>
+ <label><input type="radio" name="group_state" value="' . GROUP_CLOSED . '" ' . (( $row['group_type'] == GROUP_CLOSED ) ? 'checked="checked"' : '' ) . ' /> Closed group</label>
+ <label><input type="radio" name="group_state" value="' . GROUP_REQUEST. '" ' . (( $row['group_type'] == GROUP_REQUEST) ? 'checked="checked"' : '' ) . ' /> Members can request to join</label>
+ <label><input type="radio" name="group_state" value="' . GROUP_OPEN . '" ' . (( $row['group_type'] == GROUP_OPEN ) ? 'checked="checked"' : '' ) . ' /> Anybody can join</label>'
+ : $g_state;
+ if ( !$can_do_admin_stuff && $row['group_type'] == GROUP_REQUEST && !$is_member )
+ {
+ if ( $is_pending )
+ $state_btns .= ' (Your request to join is awaiting approval)';
+ else
+ $state_btns .= ' <input type="submit" value="Request membership" />';
+ }
+
+ if ( !$can_do_admin_stuff && $row['group_type'] == GROUP_OPEN && !$is_member )
+ {
+ $state_btns .= ' <input type="submit" value="Join this group" />';
+ }
+
+ echo '<form action="' . makeUrl($paths->page, 'act=update') . '" method="post" enctype="multipart/form-data">
+ <div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2">Group information</th>
+ </tr>
+ <tr>
+ <td class="row2">Group name:</td>
+ <td class="row1">' . $row['group_name'] . '</td>
+ </tr>
+ <tr>
+ <td class="row2">Membership status:</td>
+ <td class="row1">' . $status . '</td>
+ </tr>
+ <tr>
+ <td class="row2">Group state:</td>
+ <td class="row1">' . $state_btns . '</td>
+ </tr>
+ ' . ( ( $is_mod || $session->user_level >= USER_LEVEL_ADMIN ) ? '
+ <tr>
+ <th class="subhead" colspan="2">
+ <input type="submit" value="Save changes" />
+ </th>
+ </tr>
+ ' : '' ) . '
+ </table>
+ </div>
+ <input name="group_id" value="' . $gid . '" type="hidden" />
+ </form>';
+ if ( sizeof ( $pending ) > 0 && $can_do_admin_stuff )
+ {
+ echo '<form action="' . makeUrl($paths->page, 'act=pending') . '" method="post" enctype="multipart/form-data">
+ <input name="group_id" value="' . $gid . '" type="hidden" />
+ <h2>Pending memberships</h2>
+ <div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr>
+ <th>Username</th>
+ <th>E-mail</th>
+ <th>Registered</th>
+ <th>Total comments</th>
+ <th>Select</th>
+ </tr>';
+ $cls = 'row2';
+ foreach ( $pending as $member )
+ {
+
+ $date = date('F d, Y', $member['reg_time']);
+ $cls = ( $cls == 'row2' ) ? 'row1' : 'row2';
+ $addy = $email->encryptEmail($member['email']);
+
+ echo "<tr>
+ <td class='{$cls}'>{$member['username']}</td>
+ <td class='{$cls}'>{$addy}</td>
+ <td class='{$cls}'>{$date}</td>
+ <td class='{$cls}'>{$member['COUNT(c.comment_id)']}</td>
+ <td class='{$cls}' style='text-align: center;'><input type='checkbox' name='with_user[{$member['member_id']}]' /></td>
+ </tr>";
+ }
+ echo '</table>
+ </div>
+ <div style="margin: 10px 0 0 auto;">
+ With selected:
+ <input type="submit" name="do_appr_pending" value="Approve membership" />
+ <input type="submit" name="do_reject_pending" value="Reject membership" />
+ </div>
+ </form>';
+ }
+ echo '<form action="' . makeUrl($paths->page, 'act=del_users') . '" method="post" enctype="multipart/form-data">
+ <h2>Group members</h2>
+ <div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr>
+ <th>Username</th>
+ <th>E-mail</th>
+ <th>Registered</th>
+ <th>Total comments</th>
+ ' . ( ( $can_do_admin_stuff ) ? "
+ <th>Remove?</th>
+ " : '' ) . '
+ </tr>
+ <tr>
+ <th colspan="5" class="subhead">Group moderators</th>
+ </tr>';
+ $mod_printed = false;
+ $mem_printed = false;
+ $cls = 'row2';
+
+ foreach ( $members as $member )
+ {
+ if ( $member['is_mod'] != 1 )
+ break;
+
+ $date = date('F d, Y', $member['reg_time']);
+ $cls = ( $cls == 'row2' ) ? 'row1' : 'row2';
+ $addy = $email->encryptEmail($member['email']);
+
+ $mod_printed = true;
+
+ echo "<tr>
+ <td class='{$cls}'>{$member['username']}</td>
+ <td class='{$cls}'>{$addy}</td>
+ <td class='{$cls}'>{$date}</td>
+ <td class='{$cls}'>{$member['COUNT(c.comment_id)']}</td>
+ " . ( ( $can_do_admin_stuff ) ? "
+ <td class='{$cls}' style='text-align: center;'><input type='checkbox' name='del_user[{$member['member_id']}]' /></td>
+ " : '' ) . "
+ </tr>";
+ }
+ if (!$mod_printed)
+ echo '<tr><td class="' . $cls . '" colspan="5">This group has no moderators.</td></th>';
+ echo '<tr><th class="subhead" colspan="5">Group members</th></tr>';
+ foreach ( $members as $member )
+ {
+ if ( $member['is_mod'] == 1 )
+ continue;
+
+ $date = date('F d, Y', $member['reg_time']);
+ $cls = ( $cls == 'row2' ) ? 'row1' : 'row2';
+ $addy = $email->encryptEmail($member['email']);
+
+ $mem_printed = true;
+
+ echo "<tr>
+ <td class='{$cls}'>{$member['username']}</td>
+ <td class='{$cls}'>{$addy}</td>
+ <td class='{$cls}'>{$date}</td>
+ <td class='{$cls}'>{$member['COUNT(c.comment_id)']}</td>
+ " . ( ( $can_do_admin_stuff ) ? "
+ <td class='{$cls}' style='text-align: center;'><input type='checkbox' name='del_user[{$member['member_id']}]' /></td>
+ " : '' ) . "
+ </tr>";
+ }
+ if (!$mem_printed)
+ echo '<tr><td class="' . $cls . '" colspan="5">This group has no members.</td></th>';
+ echo ' </table>
+ </div>';
+ if ( $can_do_admin_stuff )
+ {
+ echo "<div style='margin: 10px 0 0 auto;'><input type='submit' name='do_del_user' value='Remove selected users' /></div>";
+ }
+ echo '<input name="group_id" value="' . $gid . '" type="hidden" />
+ </form>';
+ if ( $can_do_admin_stuff )
+ {
+ echo '<form action="' . makeUrl($paths->page, 'act=adduser') . '" method="post" enctype="multipart/form-data" onsubmit="if(!submitAuthorized) return false;">
+ <div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2">Add a new member to this group</th>
+ </tr>
+ <tr>
+ <td class="row2">Username:</td><td class="row1">' . $template->username_field('add_username') . '</td>
+ </tr>
+ <tr>
+ <td class="row2">Group moderator:</td><td class="row1"><label><input type="checkbox" name="add_mod" /> User is a group moderator</label></td>
+ </tr>
+ <tr>
+ <th class="subhead" colspan="2">
+ <input type="submit" value="Add member" />
+ </th>
+ </tr>
+ </table>
+ </div>
+ <input name="group_id" value="' . $gid . '" type="hidden" />
+ </form>';
+ }
+ }
+ else
+ {
+ echo '<form action="'.makeUrlNS('Special', 'Usergroups').'" method="post" onsubmit="if(!submitAuthorized) return false;" enctype="multipart/form-data">';
+ echo '<div class="tblholder">
+ <table border="0" style="width: 100%;" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2">Group membership details</th>
+ </tr>
+ <tr>
+ <td class="row2" style="text-align: right;">
+ Current group memberships:
+ </td>
+ <td class="row1">';
+ $taboo = Array('Everyone');
+ if ( sizeof ( $session->groups ) > 0 )
+ {
+ echo '<select name="group_id">';
+ foreach ( $session->groups as $id => $group )
+ {
+ $taboo[] = $group;
+ if ( $group != 'Everyone' )
+ {
+ echo '<option value="' . $id . '">' . $group . '</option>';
+ }
+ }
+ echo '</select>
+ <input type="submit" name="do_view" value="View information" />';
+ }
+ else
+ {
+ echo 'None';
+ }
+
+ echo '</td>
+ </tr>';
+ $taboo = 'WHERE group_name != \'' . implode('\' AND group_name != \'', $taboo) . '\'';
+ $q = $db->sql_query('SELECT group_id,group_name FROM '.table_prefix.'groups '.$taboo.' AND group_type != ' . GROUP_HIDDEN . ' ORDER BY group_name ASC;');
+ if(!$q)
+ {
+ echo $db->get_error();
+ $template->footer();
+ return;
+ }
+ if($db->numrows() > 0)
+ {
+ echo '<tr>
+ <td class="row2" style="text-align: right;">
+ Non-memberships:
+ </td>
+ <td class="row1">
+ <select name="group_id_n">';
+ while ( $row = $db->fetchrow() )
+ {
+ if ( $row['group_name'] != 'Everyone' )
+ {
+ echo '<option value="' . $row['group_id'] . '">' . $row['group_name'] . '</option>';
+ }
+ }
+ echo '</select>
+ <input type="submit" name="do_view_n" value="View information" />
+ </td>
+ </tr>
+ ';
+ }
+ $db->free_result();
+ echo '</table>
+ </div>
+ </form>';
+ }
+ $template->footer();
+}
+
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/SpecialPageFuncs.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,365 @@
+<?php
+/*
+Plugin Name: Special page-related pages
+Plugin URI: http://enanocms.org/
+Description: Provides the page Special:CreatePage, which can be used to create new pages. Also adds the About Enano and GNU General Public License pages.
+Author: Dan Fuhry
+Version: 1.0
+Author URI: http://enanocms.org/
+*/
+
+/*
+ * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
+ * Version 1.0 release candidate 2
+ * Copyright (C) 2006-2007 Dan Fuhry
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+global $db, $session, $paths, $template, $plugins; // Common objects
+
+$plugins->attachHook('base_classes_initted', '
+ global $paths;
+ $paths->add_page(Array(
+ \'name\'=>\'Create page\',
+ \'urlname\'=>\'CreatePage\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'All pages\',
+ \'urlname\'=>\'AllPages\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'List of special pages\',
+ \'urlname\'=>\'SpecialPages\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'About Enano\',
+ \'urlname\'=>\'About_Enano\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'GNU General Public License\',
+ \'urlname\'=>\'GNU_General_Public_License\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ ');
+
+// function names are IMPORTANT!!! The name pattern is: page_<namespace ID>_<page URLname, without namespace>
+
+function page_Special_CreatePage() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if ( isset($_POST['do']) )
+ {
+ $p = $_POST['pagename'];
+ $k = array_keys($paths->nslist);
+ for ( $i = 0; $i < sizeof( $paths->nslist ); $i++ )
+ {
+ $ln = strlen( $paths->nslist[$k[$i]] );
+ if ( substr($p, 0, $ln) == $paths->nslist[$k[$i]] )
+ {
+ $namespace = $k[$i];
+ }
+ }
+ if ( $namespace == 'Special' || ( $namespace == 'System' && $session->user_level < USER_LEVEL_ADMIN ) || $namespace == 'Admin')
+ {
+ $template->header();
+
+ echo '<h3>The page could not be created.</h3><p>The name "'.$p.'" is invalid.</p>';
+
+ $template->footer();
+ $db->close();
+
+ exit;
+ }
+ $name = $db->escape(str_replace('_', ' ', $p));
+ $urlname = $db->escape(str_replace(' ', '_', $p));
+ $namespace = $_POST['namespace'];
+ if ( $namespace == 'Special' || ( $namespace == 'System' && $session->user_level < USER_LEVEL_ADMIN ) || $namespace == 'Admin')
+ {
+ $template->header();
+
+ echo '<h3>The page could not be created.</h3><p>The name "'.$paths->nslist[$namespace].$p.'" is invalid.</p>';
+
+ $template->footer();
+ $db->close();
+
+ exit;
+ }
+
+ $tn = $paths->nslist[$_POST['namespace']] . $urlname;
+ if ( isset($paths->pages[$tn]) )
+ {
+ die_friendly('Error creating page', '<p>The page already exists.</p>');
+ }
+
+ if ( $paths->nslist[$namespace] == substr($urlname, 0, strlen($paths->nslist[$namespace]) ) )
+ {
+ $urlname = substr($urlname, strlen($paths->nslist[$namespace]), strlen($urlname));
+ }
+
+ $k = array_keys( $paths->nslist );
+ if(!in_array($_POST['namespace'], $k))
+ {
+ $db->_die('An SQL injection attempt was caught at '.dirname(__FILE__).':'.__LINE__.'.');
+ }
+
+ $perms = $session->fetch_page_acl($urlname, $namespace);
+ if ( !$perms->get_permissions('create_page') )
+ die_friendly('Error creating page', '<p>An access control rule is preventing you from creating pages.</p>');
+
+ $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,author,page_id,namespace) VALUES('.time().', \''.date('d M Y h:i a').'\', \'page\', \'create\', \''.$session->username.'\', \''.$urlname.'\', \''.$_POST['namespace'].'\');');
+ if ( !$q )
+ {
+ $db->_die('The page log could not be updated.');
+ }
+
+ $q = $db->sql_query('INSERT INTO '.table_prefix.'pages(name,urlname,namespace) VALUES(\''.$name.'\', \''.$urlname.'\', \''.$_POST['namespace'].'\');');
+ if ( !$q )
+ {
+ $db->_die('The page entry could not be inserted.');
+ }
+ $q = $db->sql_query('INSERT INTO '.table_prefix.'page_text(page_id,namespace,page_text) VALUES(\''.$urlname.'\', \''.$_POST['namespace'].'\', \''.$db->escape('Please edit this page! <nowiki><script type="text/javascript">ajaxEditor();</script></nowiki>').'\');');
+ if ( !$q )
+ {
+ $db->_die('The page text entry could not be inserted.');
+ }
+
+ header('Location: '.makeUrl($paths->nslist[$_POST['namespace']].$p));
+ exit;
+ }
+ $template->header();
+ if ( !$session->get_permissions('create_page') )
+ {
+ echo 'Wiki mode is disabled, only admins can create pages.';
+
+ $template->footer();
+ $db->close();
+
+ exit;
+ }
+ echo RenderMan::render('Using the form below you can create a page.');
+ ?>
+ <form action="" method="post">
+ <p>
+ <select name="namespace">
+ <?php
+ $k = array_keys($paths->nslist);
+ for ( $i = 0; $i < sizeof($k); $i++ )
+ {
+ if ( $paths->nslist[$k[$i]] == '' )
+ {
+ $s = '[No prefix]';
+ }
+ else
+ {
+ $s = $paths->nslist[$k[$i]];
+ }
+ if ( ( $k[$i] != 'System' || $session->user_level >= USER_LEVEL_ADMIN ) && $k[$i] != 'Admin' && $k[$i] != 'Special')
+ {
+ echo '<option value="'.$k[$i].'">'.$s.'</option>';
+ }
+ }
+ ?>
+ </select> <input type="text" name="pagename" /></p>
+ <p><input type="submit" name="do" value="Create Page" /></p>
+ </form>
+ <?php
+ $template->footer();
+}
+
+function page_Special_AllPages()
+{
+ // This should be an easy one
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $template->header();
+ $sz = sizeof( $paths->pages ) / 2;
+ echo '<p>Below is a list of all of the pages on this website.</p><div class="tblholder"><table border="0" width="100%" cellspacing="1" cellpadding="4">';
+ $cclass = 'row1';
+ for ( $i = 0; $i < $sz; $i = $i )
+ {
+ if ( $cclass == 'row1')
+ {
+ $cclass='row3';
+ }
+ else if ( $cclass == 'row3')
+ {
+ $cclass='row1';
+ }
+ echo '<tr>';
+ for ( $j = 0; $j < 2; $j = $j )
+ {
+ if ( $i < $sz && $paths->pages[$i]['namespace'] != 'Special' && $paths->pages[$i]['namespace'] != 'Admin' && $paths->pages[$i]['visible'] == 1)
+ {
+ echo '<td style="width: 50%" class="'.$cclass.'"><a href="'.makeUrl($paths->pages[$i]['urlname']).'">';
+ if ( $paths->pages[$i]['namespace'] != 'Article' )
+ {
+ echo '('.$paths->pages[$i]['namespace'].') ';
+ }
+ echo $paths->pages[$i]['name'].'</a></td>';
+ $j++;
+ }
+ else if ( $i >= $sz )
+ {
+ echo '<td style="width: 50%" class="row2"></td>';
+ $j++;
+ }
+ $i++;
+ }
+ echo '</tr>';
+ }
+ echo '</table></div>';
+ $template->footer();
+}
+
+function page_Special_SpecialPages()
+{
+ // This should be an easy one
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $template->header();
+ $sz = sizeof($paths->pages) / 2;
+ echo '<p>Below is a list of all of the special pages on this website.</p><div class="tblholder"><table border="0" width="100%" cellspacing="1" cellpadding="4">';
+ $cclass='row1';
+ for ( $i = 0; $i < $sz; $i = $i)
+ {
+ if ( $cclass == 'row1' )
+ {
+ $cclass = 'row3';
+ }
+ else if ( $cclass == 'row3')
+ {
+ $cclass='row1';
+ }
+ echo '<tr>';
+ for ( $j = 0; $j < 2; $j = $j )
+ {
+ if ( $i < $sz && $paths->pages[$i]['namespace'] == 'Special' && $paths->pages[$i]['visible'] == 1)
+ {
+ echo '<td style="width: 50%" class="'.$cclass.'"><a href="'.makeUrl($paths->pages[$i]['urlname']).'">';
+ echo $paths->pages[$i]['name'].'</a></td>';
+ $j++;
+ }
+ else if ( $i >= $sz )
+ {
+ echo '<td style="width: 50%" class="row2"></td>';
+ $j++;
+ }
+ $i++;
+ }
+ echo '</tr>';
+ }
+ echo '</table></div>';
+ $template->footer();
+}
+
+function page_Special_About_Enano()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $platform = 'Unknown';
+ $uname = @file_get_contents('/proc/sys/kernel/ostype');
+ if($uname == "Linux\n")
+ $platform = 'Linux';
+ else if(file_exists('/hurd/pfinet')) // I have a little experience with GNU/Hurd :-) http://hurdvm.enanocms.org/
+ $platform = 'GNU/Hurd';
+ else if(file_exists('C:\Windows\system32\ntoskrnl.exe'))
+ $platform = 'Windows NT';
+ else if(file_exists('C:\Windows\system\krnl386.exe'))
+ $platform = 'Windows 9x/DOS';
+ else if(file_exists('/bin/bash'))
+ $platform = 'Other GNU/Mac OS X';
+ else if(is_dir('/bin'))
+ $platform = 'Other POSIX';
+ $template->header();
+ ?>
+ <br />
+ <div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr><th colspan="2" style="text-align: left;">About the Enano Content Management System</th></tr>
+ <tr><td colspan="2" class="row3"><p>This website is powered by <a href="http://enano.homelinux.org/">Enano</a>, the lightweight and open source
+ CMS that everyone can use. Enano is copyright © 2006 Dan Fuhry. For legal information, along with a list of libraries that Enano
+ uses, please see <a href="http://enano.homelinux.org/Legal_information">Legal Information</a>.</p>
+ <p>The developers and maintainers of Enano strongly believe that software should not only be free to use, but free to be modified,
+ distributed, and used to create derivative works. For more information about Free Software, check out the
+ <a href="http://en.wikipedia.org/wiki/Free_Software" onclick="window.open(this.href); return false;">Wikipedia page</a> or
+ the <a href="http://www.fsf.org/" onclick="window.open(this.href); return false;">Free Software Foundation's</a> homepage.</p>
+ <p>This program is Free Software; you can redistribute it and/or modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.</p>
+ <p>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.</p>
+ <p>You should have received <a href="<?php echo makeUrlNS('Special', 'GNU_General_Public_License'); ?>">a copy of
+ the GNU General Public License</a> along with this program; if not, write to:</p>
+ <p style="margin-left 2em;">Free Software Foundation, Inc.,<br />
+ 51 Franklin Street, Fifth Floor<br />
+ Boston, MA 02110-1301, USA</p>
+ <p>Alternatively, you can <a href="http://www.gnu.org/copyleft/gpl.html">read it online</a>.</p>
+ </td></tr>
+ <tr>
+ <td class="row2" colspan="2">
+ <table border="0" style="margin: 0 auto; background: none; width: 100%;" cellpadding="5">
+ <tr>
+ <td style="text-align: center;">
+ <a href="http://www.enanocms.org/" onclick="window.open(this.href); return false;" style="background: none; padding: 0;">
+ <img alt="Powered by Enano"
+ src="<?php echo scriptPath; ?>/images/about-powered-enano.png"
+ onmouseover="this.src='<?php echo scriptPath; ?>/images/about-powered-enano-hover.png';"
+ onmouseout="this.src='<?php echo scriptPath; ?>/images/about-powered-enano.png';"
+ style="border-width: 0px;" width="88" height="31" />
+ </a>
+ </td>
+ <td style="text-align: center;">
+ <a href="http://www.php.net/" onclick="window.open(this.href); return false;" style="background: none; padding: 0;">
+ <img alt="Written in PHP" src="<?php echo scriptPath; ?>/images/about-powered-php.png" style="border-width: 0px;" width="88" height="31" />
+ </a>
+ </td>
+ <td style="text-align: center;">
+ <a href="http://www.mysql.com/" onclick="window.open(this.href); return false;" style="background: none; padding: 0;">
+ <img alt="Database engine powered by MySQL" src="<?php echo scriptPath; ?>/images/about-powered-mysql.png" style="border-width: 0px;" width="88" height="31" />
+ </a>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr><td style="width: 100px;" class="row1"><a href="http://www.enanocms.org">Enano</a> version:</td><td class="row1"><?php echo enano_version(true); ?></td></tr>
+ <tr><td style="width: 100px;" class="row2">Web server:</td><td class="row2"><?php if(isset($_SERVER['SERVER_SOFTWARE'])) echo $_SERVER['SERVER_SOFTWARE']; else echo 'Unable to determine web server software.'; ?></td></tr>
+ <tr><td style="width: 100px;" class="row1">Server platform:</td><td class="row1"><?php echo $platform; ?></td></tr>
+ <tr><td style="width: 100px;" class="row2"><a href="http://www.php.net/">PHP</a> version:</td><td class="row2"><?php echo PHP_VERSION; ?></td></tr>
+ <tr><td style="width: 100px;" class="row1"><a href="http://www.mysql.com/">MySQL</a> version:</td><td class="row1"><?php echo mysql_get_server_info($db->_conn); ?></td></tr>
+ </table>
+ </div>
+ <?php
+ $template->footer();
+}
+
+function page_Special_GNU_General_Public_License()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $template->header();
+ if(file_exists(ENANO_ROOT.'/GPL'))
+ {
+ echo '<p>The following text represents the license that the <a href="'.makeUrlNS('Special', 'About_Enano').'">Enano</a> content management system is under. To make it easier to read, the text has been wiki-formatted; in no other way has it been changed.</p>';
+ echo RenderMan::render( htmlspecialchars ( file_get_contents ( ENANO_ROOT . '/GPL' ) ) );
+ }
+ else
+ {
+ echo '<p>It appears that the file "GPL" is missing from your Enano installation. You may find a wiki-formatted copy of the GPL at: <a href="http://www.enanocms.org/GPL">http://www.enanocms.org/GPL</a>.</p>';
+ }
+ $template->footer();
+}
+
+?>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/SpecialSearch.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,511 @@
+<?php
+/*
+Plugin Name: Search UI/frontend
+Plugin URI: http://www.enanocms.org/
+Description: Provides the page Special:Search, which is a frontend to the Enano search engine.
+Author: Dan Fuhry
+Version: 1.0
+Author URI: http://www.enanocms.org/
+*/
+
+/*
+ * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
+ * Version 1.0 release candidate 2
+ * Copyright (C) 2006-2007 Dan Fuhry
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+$plugins->attachHook('base_classes_initted', '
+ global $paths;
+ $paths->add_page(Array(
+ \'name\'=>\'Rebuild search index\',
+ \'urlname\'=>\'SearchRebuild\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'Search\',
+ \'urlname\'=>\'Search\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ ');
+
+function page_Special_SearchRebuild()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if(!$session->get_permissions('mod_misc')) die_friendly('Unauthorized', '<p>You need to be an administrator to rebuild the search index</p>');
+ $template->header();
+ if($paths->rebuild_search_index())
+ echo '<p>Index rebuilt!</p>';
+ else
+ echo '<p>Index was not rebuilt due to an error.';
+ $template->footer();
+}
+
+function page_Special_Search()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if(!$q = $paths->getParam(0)) $q = ( isset($_GET['q']) ) ? $_GET['q'] : false;
+ if(isset($_GET['words_any']))
+ {
+ $q = '';
+ if(!empty($_GET['words_any']))
+ {
+ $q .= $_GET['words_any'] . ' ';
+ }
+ if(!empty($_GET['exact_phrase']))
+ {
+ $q .= '"' . $_GET['exact_phrase'] . '" ';
+ }
+ if(!empty($_GET['exclude_words']))
+ {
+ $not = explode(' ', $_GET['exclude_words']);
+ foreach ( $not as $i => $foo )
+ {
+ $not[$i] = '-' . $not[$i];
+ }
+ $q .= implode(' ', $not);
+ }
+ if(!empty($_GET['require_words']))
+ {
+ $req = explode(' ', $_GET['require_words']);
+ foreach ( $req as $i => $foo )
+ {
+ $req[$i] = '+' . $req[$i];
+ }
+ $q .= implode(' ', $req);
+ }
+ }
+ $template->header();
+ if(!empty($q))
+ {
+ switch(SEARCH_MODE)
+ {
+
+ case "FULLTEXT":
+ if ( isset($_GET['offset']) )
+ {
+ $offset = intval($_GET['offset']);
+ }
+ else
+ {
+ $offset = 0;
+ }
+ $sql = $db->sql_query('SELECT search_id FROM '.table_prefix.'search_cache WHERE query=\''.$db->escape($q).'\';');
+ if(!$sql)
+ {
+ $db->_die('Error scanning search query cache');
+ }
+ if($db->numrows() > 0)
+ {
+ $row = $db->fetchrow();
+ $db->free_result();
+ search_fetch_fulltext_results(intval($row['search_id']), $offset);
+ }
+ else
+ {
+ // Perform search
+
+ $search = new MySQL_Fulltext_Search();
+
+ // Parse the query
+ $parse = new Searcher();
+ $query = $parse->parseQuery($q);
+ unset($parse);
+
+ // Send query to MySQL
+ $sql = $search->search($q);
+ $results = Array();
+ if ( $row = $db->fetchrow($sql) )
+ {
+ do {
+ $results[] = $row;
+ } while ( $row = $db->fetchrow($sql) );
+ }
+ else
+ {
+ // echo '<div class="warning-box">No pages that matched your search criteria could be found.</div>';
+ }
+ $texts = Array();
+ foreach ( $results as $result )
+ {
+ $texts[] = render_fulltext_result($result, $query);
+ }
+
+ // Store the result in the search cache...if someone makes the same query later we can skip searching and rendering
+ // This cache is cleared when an affected page is saved.
+
+ $results = serialize($texts);
+
+ $sql = $db->sql_query('INSERT INTO '.table_prefix.'search_cache(search_time,query,results) VALUES('.time().', \''.$db->escape($q).'\', \''.$db->escape($results).'\');');
+ if($sql)
+ {
+ search_render_fulltext_results(unserialize($results), $offset, $q);
+ }
+ else
+ {
+ $db->_die('Error inserting search into cache');
+ }
+
+ }
+ break;
+
+ case "BUILTIN":
+ $titles = $paths->makeTitleSearcher(isset($_GET['match_case']));
+ if ( isset($_GET['offset']) )
+ {
+ $offset = intval($_GET['offset']);
+ }
+ else
+ {
+ $offset = 0;
+ }
+ $sql = $db->sql_query('SELECT search_id FROM '.table_prefix.'search_cache WHERE query=\''.$db->escape($q).'\';');
+ if(!$sql)
+ {
+ $db->_die('Error scanning search query cache');
+ }
+ if($db->numrows() > 0)
+ {
+ $row = $db->fetchrow();
+ $db->free_result();
+ search_show_results(intval($row['search_id']), $offset);
+ }
+ else
+ {
+ $titles->search($q, $paths->get_page_titles());
+ $search = $paths->makeSearcher(isset($_GET['match_case']));
+ $texts = $paths->fetch_page_search_resource();
+ $search->searchMySQL($q, $texts);
+
+ $results = Array();
+ $results['text'] = $search->results;
+ $results['page'] = $titles->results;
+ $results['warn'] = $search->warnings;
+
+ $results = serialize($results);
+
+ $sql = $db->sql_query('INSERT INTO '.table_prefix.'search_cache(search_time,query,results) VALUES('.time().', \''.$db->escape($q).'\', \''.$db->escape($results).'\');');
+ if($sql)
+ {
+ search_render_results(unserialize($results), $offset, $q);
+ }
+ else
+ {
+ $db->_die('Error inserting search into cache');
+ }
+ }
+ break;
+ }
+ $code = $plugins->setHook('search_results'); // , Array('query'=>$q));
+ foreach ( $code as $cmd )
+ {
+ eval($cmd);
+ }
+ ?>
+ <form action="<?php echo makeUrl($paths->page); ?>" method="get">
+ <p>
+ <input type="text" name="q" size="40" value="<?php echo htmlspecialchars( $q ); ?>" /> <input type="submit" value="Search" /> <small><a href="<?php echo makeUrlNS('Special', 'Search'); ?>">Advanced Search</a></small>
+ </p>
+ </form>
+ <?php
+ }
+ else
+ {
+ ?>
+ <br />
+ <form action="<?php echo makeUrl($paths->page); ?>" method="get">
+ <div class="tblholder">
+ <table border="0" style="width: 100%;" cellspacing="1" cellpadding="4">
+ <tr><th colspan="2">Advanced Search</th></tr>
+ <tr>
+ <td class="row1">Search for pages with <b>any of these words</b>:</td>
+ <td class="row1"><input type="text" name="words_any" size="40" /></td>
+ </tr>
+ <tr>
+ <td class="row2">with <b>this exact phrase</b>:</td>
+ <td class="row2"><input type="text" name="exact_phrase" size="40" /></td>
+ </tr>
+ <tr>
+ <td class="row1">with <b>none of these words</b>:</td>
+ <td class="row1"><input type="text" name="exclude_words" size="40" /></td>
+ </tr>
+ <tr>
+ <td class="row2">with <b>all of these words</b>:</td>
+ <td class="row2"><input type="text" name="require_words" size="40" /></td>
+ </tr>
+ <tr>
+ <td class="row1">
+ <label for="chk_case">Case-sensitive search:</label>
+ </td>
+ <td class="row1">
+ <input type="checkbox" name="match_case" id="chk_case" />
+ </td>
+ </tr>
+ <tr>
+ <th colspan="2" class="subhead">
+ <input type="submit" name="do_search" value="Search" />
+ </td>
+ </tr>
+ </table>
+ </div>
+ </form>
+ <?php
+ }
+ $template->footer();
+}
+
+function search_show_results($search_id, $start = 0)
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $q = $db->sql_query('SELECT query,results,search_time FROM '.table_prefix.'search_cache WHERE search_id='.intval($search_id).';');
+ if(!$q)
+ return $db->get_error('Error selecting cached search results');
+ $row = $db->fetchrow();
+ $db->free_result();
+ $results = unserialize($row['results']);
+ search_render_results($results, $start, $row['query']);
+}
+
+function search_render_results($results, $start = 0, $q = '')
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $nr1 = sizeof($results['page']);
+ $nr2 = sizeof($results['text']);
+ $nr = ( $nr1 > $nr2 ) ? $nr1 : $nr2;
+ $results['page'] = array_slice($results['page'], $start, SEARCH_RESULTS_PER_PAGE);
+ $results['text'] = array_slice($results['text'], $start, SEARCH_RESULTS_PER_PAGE);
+
+ // Pagination
+ $pagination = '';
+ if ( $nr1 > SEARCH_RESULTS_PER_PAGE || $nr2 > SEARCH_RESULTS_PER_PAGE )
+ {
+ $pagination .= '<div class="tblholder" style="padding: 0; display: table; margin: 0 0 0 auto; float: right;">
+ <table border="0" style="width: 100%;" cellspacing="1" cellpadding="4">
+ <tr>
+ <th>Page:</th>';
+ $num_pages = ceil($nr / SEARCH_RESULTS_PER_PAGE);
+ $j = 0;
+ for ( $i = 1; $i <= $num_pages; $i++ )
+ {
+ if ($j == $start)
+ $pagination .= '<td class="row1"><b>' . $i . '</b></td>';
+ else
+ $pagination .= '<td class="row1"><a href="' . makeUrlNS('Special', 'Search', 'q=' . urlencode($q) . '&offset=' . $j, true) . '">' . $i . '</a></td>';
+ $j = $j + SEARCH_RESULTS_PER_PAGE;
+ }
+ $pagination .= '</tr></table></div>';
+ }
+
+ echo $pagination;
+
+ if ( $nr1 >= $start )
+ {
+ echo '<h3>Page title matches</h3>';
+ if(count($results['page']) < 1)
+ {
+ echo '<div class="error-box">No pages with a title that matched your search criteria could be found.</div>';
+ }
+ else
+ {
+ echo '<p>';
+ foreach($results['page'] as $page => $text)
+ {
+ echo '<a href="'.makeUrl($page).'">'.$paths->pages[$page]['name'].'</a><br />';
+ }
+ echo '</p>';
+ }
+ }
+ if ( $nr2 >= $start )
+ {
+ echo '<h3>Page text matches</h3>';
+ if(count($results['text']) < 1)
+ {
+ echo '<div class="error-box">No page text that matched your search criteria could be found.</div>';
+ }
+ else
+ {
+ foreach($results['text'] as $kpage => $text)
+ {
+ preg_match('#^ns=('.implode('|', array_keys($paths->nslist)).');pid=(.*?)$#i', $kpage, $matches);
+ $page = $paths->nslist[$matches[1]] . $matches[2];
+ echo '<p><span style="font-size: larger;"><a href="'.makeUrl($page).'">'.$paths->pages[$page]['name'].'</a></span><br />'.$text.'</p>';
+ }
+ }
+ }
+ if(count($results['warn']) > 0)
+ echo '<div class="warning-box"><b>Your search may not include all results.</b><br />The following errors were encountered during the search:<br /><ul><li>'.implode('</li><li>', $results['warn']).'</li></ul></div>';
+ echo $pagination;
+}
+
+function render_fulltext_result($result, $query)
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ preg_match('#^ns=('.implode('|', array_keys($paths->nslist)).');pid=(.*?)$#i', $result['page_identifier'], $matches);
+ $page = $paths->nslist[$matches[1]] . $matches[2];
+ //$score = round($result['score'] * 100, 1);
+ $score = number_format($result['score'], 2);
+ $char_length = $result['length'];
+ $result_template = <<<TPLCODE
+ <div class="search-result">
+ <h3><a href="{HREF}">{TITLE}</a></h3>
+ <p>{TEXT}</p>
+ <p>
+ <span class="search-result-info">{NAMESPACE} - Relevance score: {SCORE} ({LENGTH} bytes)</span>
+ </p>
+ </div>
+TPLCODE;
+ $parser = $template->makeParserText($result_template);
+
+ $pt =& $result['page_text'];
+ $space_chars = Array("\t", "\n", "\r", " ");
+
+ $words = array_merge($query['any'], $query['req']);
+ $pt = htmlspecialchars($pt);
+ $words2 = array();
+
+ for ( $i = 0; $i < sizeof($words); $i++)
+ {
+ if(!empty($words[$i]))
+ $words2[] = preg_quote($words[$i]);
+ }
+
+ $regex = '/(' . implode('|', $words2) . ')/i';
+ $pt = preg_replace($regex, '<span class="search-term">\\1</span>', $pt);
+
+ $title = preg_replace($regex, '<span class="title-search-term">\\1</span>', $paths->pages[$page]['name']);
+
+ $cut_off = false;
+
+ foreach ( $words as $word )
+ {
+ // Boldface searched words
+ $ptlen = strlen($pt);
+ for ( $i = 0; $i < $ptlen; $i++ )
+ {
+ $len = strlen($word);
+ if ( strtolower(substr($pt, $i, $len)) == strtolower($word) )
+ {
+ $chunk1 = substr($pt, 0, $i);
+ $chunk2 = substr($pt, $i, $len);
+ $chunk3 = substr($pt, ( $i + $len ));
+ $pt = $chunk1 . $chunk2 . $chunk3;
+ $ptlen = strlen($pt);
+ // Cut off text to 150 chars or so
+ if ( !$cut_off )
+ {
+ $cut_off = true;
+ if ( $i - 75 > 0 )
+ {
+ // Navigate backwards until a space character is found
+ $chunk = substr($pt, 0, ( $i - 75 ));
+ $final_chunk = $chunk;
+ for ( $j = strlen($chunk); $j > 0; $j = $j - 1 )
+ {
+ if ( in_array($chunk{$j}, $space_chars) )
+ {
+ $final_chunk = substr($chunk, $j + 1);
+ break;
+ }
+ }
+ $mid_chunk = substr($pt, ( $i - 75 ), 75);
+
+ $clipped = '...' . $final_chunk . $mid_chunk . $chunk2;
+
+ $chunk = substr($pt, ( $i + strlen($chunk2) + 75 ));
+ $final_chunk = $chunk;
+ for ( $j = 0; $j < strlen($chunk); $j++ )
+ {
+ if ( in_array($chunk{$j}, $space_chars) )
+ {
+ $final_chunk = substr($chunk, 0, $j);
+ break;
+ }
+ }
+
+ $end_chunk = substr($pt, ( $i + strlen($chunk2) ), 75 );
+
+ $clipped .= $end_chunk . $final_chunk . '...';
+
+ $pt = $clipped;
+ }
+ else if ( strlen($pt) > 200 )
+ {
+ $mid_chunk = substr($pt, ( $i - 75 ), 75);
+
+ $clipped = $chunk1 . $chunk2;
+
+ $chunk = substr($pt, ( $i + strlen($chunk2) + 75 ));
+ $final_chunk = $chunk;
+ for ( $j = 0; $j < strlen($chunk); $j++ )
+ {
+ if ( in_array($chunk{$j}, $space_chars) )
+ {
+ $final_chunk = substr($chunk, 0, $j);
+ break;
+ }
+ }
+
+ $end_chunk = substr($pt, ( $i + strlen($chunk2) ), 75 );
+
+ $clipped .= $end_chunk . $final_chunk . '...';
+
+ $pt = $clipped;
+
+ }
+ break 2;
+ }
+ }
+ }
+ $cut_off = false;
+ }
+
+ $parser->assign_vars(Array(
+ 'TITLE' => $title,
+ 'TEXT' => $pt,
+ 'NAMESPACE' => $matches[1],
+ 'SCORE' => $score,
+ 'LENGTH' => $char_length,
+ 'HREF' => makeUrl($page)
+ ));
+
+ return $parser->run();
+
+}
+
+function search_fetch_fulltext_results($search_id, $offset = 0)
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $q = $db->sql_query('SELECT query,results,search_time FROM '.table_prefix.'search_cache WHERE search_id='.intval($search_id).';');
+ if(!$q)
+ return $db->get_error('Error selecting cached search results');
+ $row = $db->fetchrow();
+ $db->free_result();
+ $results = unserialize($row['results']);
+ search_render_fulltext_results($results, $offset, $row['query']);
+}
+
+function search_render_fulltext_results($results, $offset = 0, $query)
+{
+ $num_results = sizeof($results);
+ $slice = array_slice($results, $offset, SEARCH_RESULTS_PER_PAGE);
+
+ if ( $num_results < 1 )
+ {
+ echo '<div class="warning-box">No pages that matched your search criteria could be found.</div>';
+ return null;
+ }
+
+ $html = paginate_array($results, sizeof($results), makeUrlNS('Special', 'Search', 'q=' . urlencode($query) . '&offset=%s'), $offset, 10);
+ echo $html . '<br />';
+
+}
+
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/SpecialUpdownload.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,300 @@
+<?php
+/*
+Plugin Name: Upload/download frontend
+Plugin URI: http://enano.homelinux.org/
+Description: Provides the pages Special:UploadFile and Special:DownloadFile. UploadFile is used to upload files to the site, and DownloadFile fetches the file from the database, creates thumbnails if necessary, and sends the file to the user.
+Author: Dan Fuhry
+Version: 1.0
+Author URI: http://enano.homelinux.org/
+*/
+
+/*
+ * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
+ * Version 1.0 release candidate 2
+ * Copyright (C) 2006-2007 Dan Fuhry
+ * SpecialUpdownload.php - handles uploading and downloading of user-uploaded files - possibly the most rigorously security-enforcing script in all of Enano, although sessions.php comes in a close second
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+global $db, $session, $paths, $template, $plugins; // Common objects
+
+$plugins->attachHook('base_classes_initted', '
+ global $paths;
+ $paths->add_page(Array(
+ \'name\'=>\'Upload file\',
+ \'urlname\'=>\'UploadFile\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'Download file\',
+ \'urlname\'=>\'DownloadFile\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ ');
+
+function page_Special_UploadFile()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $mime_types;
+ if(getConfig('enable_uploads')!='1') { die_friendly('Access denied', '<p>File uploads are disabled this website.</p>'); }
+ if ( !$session->get_permissions('upload_files') )
+ {
+ die_friendly('Access denied', '<p>File uploads are disabled for your user account or group.<p>');
+ }
+ if(isset($_POST['doit']))
+ {
+ if(isset($_FILES['data']))
+ {
+ $file =& $_FILES['data'];
+ }
+ else
+ {
+ $file = false;
+ }
+ if(!is_array($file)) die_friendly('Upload failed', '<p>The server could not retrieve the array $_FILES[\'data\'].</p>');
+ if($file['size'] == 0 || $file['size'] > (int)getConfig('max_file_size')) die_friendly('Upload failed', '<p>The file you uploaded is either too large or 0 bytes in length.</p>');
+ /*
+ $allowed_mime_types = Array(
+ 'text/plain',
+ 'image/png',
+ 'image/jpeg',
+ 'image/tiff',
+ 'image/gif',
+ 'text/html', // Safe because the file is stashed in the database
+ 'application/x-bzip2',
+ 'application/x-gzip',
+ 'text/x-c++'
+ );
+ if(function_exists('finfo_open') && $fi = finfo_open(FILEINFO_MIME, ENANO_ROOT.'/includes/magic')) // First try to use the fileinfo extension, this is the best way to determine the mimetype
+ {
+ if(!$fi) die_friendly('Upload failed', '<p>Enano was unable to determine the format of the uploaded file.</p><p>'.@finfo_file($fi, $file['tmp_name']).'</p>');
+ $type = @finfo_file($fi, $file['tmp_name']);
+ @finfo_close($fi);
+ }
+ elseif(function_exists('mime_content_type'))
+ $type = mime_content_type($file['tmp_name']); // OK, no fileinfo function. Use a (usually) built-in PHP function
+ elseif(isset($file['type']))
+ $type = $file['type']; // LAST RESORT: use the mimetype the browser sent us, though this is likely to be spoofed
+ else // DANG! Not even the browser told us. Bail out.
+ die_friendly('Upload failed', '<p>Enano was unable to determine the format of the uploaded file.</p>');
+ */
+ $types = fetch_allowed_extensions();
+ $ext = substr($file['name'], strrpos($file['name'], '.')+1, strlen($file['name']));
+ if(!isset($types[$ext]) || ( isset($types[$ext]) && !$types[$ext] ) )
+ {
+ die_friendly('Upload failed', '<p>The file type ".'.$ext.'" is not allowed.</p>');
+ }
+ $type = $mime_types[$ext];
+ //$type = explode(';', $type); $type = $type[0];
+ //if(!in_array($type, $allowed_mime_types)) die_friendly('Upload failed', '<p>The file type "'.$type.'" is not allowed.</p>');
+ if($_POST['rename'] != '')
+ {
+ $filename = $_POST['rename'];
+ }
+ else
+ {
+ $filename = $file['name'];
+ }
+ $bad_chars = Array(':', '\\', '/', '<', '>', '|', '*', '?', '"', '#', '+');
+ foreach($bad_chars as $ch)
+ {
+ if(strstr($filename, $ch) || preg_match('/^([ ]+)$/is', $filename)) die_friendly('Upload failed', '<p>The filename contains invalid characters.</p>');
+ }
+
+ if ( isset ( $paths->pages[ $paths->nslist['File'] . $filename ] ) && !isset ( $_POST['update'] ) )
+ {
+ die_friendly('Upload failed', '<p>The file already exists. You can <a href="'.makeUrlNS('Special', 'UploadFile/'.$filename).'">upload a new version of this file</a>.</p>');
+ }
+ else if ( isset($_POST['update']) &&
+ ( !isset($paths->pages[$paths->nslist['File'].$filename]) ||
+ (isset($paths->pages[$paths->nslist['File'].$filename]) &&
+ $paths->pages[$paths->nslist['File'].$filename]['protected'] == 1 )
+ )
+ )
+ {
+ die_friendly('Upload failed', '<p>Either the file does not exist (and therefore cannot be updated) or the file is protected.</p>');
+ }
+
+ $utime = time();
+
+ $filename = $db->escape($filename);
+ $ext = substr($filename, strrpos($filename, '.'), strlen($filename));
+ $flen = filesize($file['tmp_name']);
+
+ $comments = $db->escape(RenderMan::strip_php($_POST['comments']));
+ $chartag = sha1(microtime());
+ $urln = str_replace(' ', '_', $filename);
+
+ $key = md5($filename . '_' . file_get_contents($file['tmp_name']));
+ $targetname = ENANO_ROOT . '/files/' . $key . '_' . $utime . $ext;
+
+ if(!@move_uploaded_file($file['tmp_name'], $targetname))
+ {
+ die_friendly('Upload failed', '<p>Could not move uploaded file to the new location.</p>');
+ }
+
+ if(getConfig('file_history') != '1')
+ {
+ if(!$db->sql_query('DELETE FROM '.table_prefix.'files WHERE filename=\''.$filename.'\' LIMIT 1;')) $db->_die('The old file data could not be deleted.');
+ }
+ if(!$db->sql_query('INSERT INTO '.table_prefix.'files(time_id,page_id,filename,size,mimetype,file_extension,file_key) VALUES('.$utime.', \''.$urln.'\', \''.$filename.'\', '.$flen.', \''.$type.'\', \''.$ext.'\', \''.$key.'\')')) $db->_die('The file data entry could not be inserted.');
+ if(!isset($_POST['update']))
+ {
+ if(!$db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,author,page_id,namespace) VALUES('.$utime.', \''.date('d M Y h:i a').'\', \'page\', \'create\', \''.$session->username.'\', \''.$filename.'\', \''.'File'.'\');')) $db->_die('The page log could not be updated.');
+ if(!$db->sql_query('INSERT INTO '.table_prefix.'pages(name,urlname,namespace,protected,delvotes,delvote_ips) VALUES(\''.$filename.'\', \''.$urln.'\', \'File\', 0, 0, \'\')')) $db->_die('The page listing entry could not be inserted.');
+ if(!$db->sql_query('INSERT INTO '.table_prefix.'page_text(page_id,namespace,page_text,char_tag) VALUES(\''.$urln.'\', \'File\', \''.$comments.'\', \''.$chartag.'\')')) $db->_die('The page text entry could not be inserted.');
+ }
+ else
+ {
+ if(!$db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,author,page_id,namespace,edit_summary) VALUES('.$utime.', \''.date('d M Y h:i a').'\', \'page\', \'reupload\', \''.$session->username.'\', \''.$filename.'\', \''.'File'.'\', \''.$comments.'\');')) $db->_die('The page log could not be updated.');
+ }
+ die_friendly('Upload complete', '<p>Your file has been uploaded successfully. View the <a href="'.makeUrlNS('File', $filename).'">file\'s page</a>.</p>');
+ }
+ else
+ {
+ $template->header();
+ $fn = $paths->getParam(0);
+ if ( $fn && !$session->get_permissions('upload_new_version') )
+ {
+ die_friendly('Access denied', '<p>Uploading new versions of files has been disabled for your user account or group.<p>');
+ }
+ ?>
+ <p>Using this form you can upload a file to the <?php echo getConfig('site_name'); ?> site.</p>
+ <p>The maximum file size is <?php
+ // Get the max file size, and format it in a way that is user-friendly
+ $fs = getConfig('max_file_size');
+ echo commatize($fs).' bytes';
+ $fs = (int)$fs;
+ if($fs >= 1048576)
+ {
+ $fs = round($fs / 1048576, 1);
+ echo ' ('.$fs.' MB)';
+ }
+ elseif($fs >= 1024)
+ {
+ $fs = round($fs / 1024, 1);
+ echo ' ('.$fs.' KB)';
+ }
+ ?>.</p>
+ <form action="<?php echo makeUrl($paths->page); ?>" method="post" enctype="multipart/form-data">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr><td>File:</td><td><input name="data" type="file" size="40" /></td></tr>
+ <tr><td>Rename to:</td><td><input name="rename" type="text" size="40"<?php if($fn) echo ' value="'.$fn.'" readonly="readonly"'; ?> /></td></tr>
+ <?php
+ if(!$fn) echo '<tr><td>Comments:<br />(can be wiki-formatted)</td><td><textarea name="comments" rows="20" cols="60"></textarea></td></tr>';
+ else echo '<tr><td>Reason for uploading the new version: </td><td><input name="comments" size="50" /></td></tr>';
+ ?>
+ <tr><td colspan="2" style="text-align: center">
+ <?php
+ if($fn)
+ echo '<input type="hidden" name="update" value="true" />';
+ ?>
+ <input type="submit" name="doit" value="Upload file" />
+ </td></tr>
+ </table>
+ </form>
+ <?php
+ $template->footer();
+ }
+}
+
+function page_Special_DownloadFile()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $do_gzip;
+ $filename = rawurldecode($paths->getParam(0));
+ $timeid = $paths->getParam(1);
+ if($timeid && preg_match('#^([0-9]+)$#', (string)$timeid)) $tid = ' AND time_id='.$timeid;
+ else $tid = '';
+ $filename = $db->escape($filename);
+ $q = $db->sql_query('SELECT page_id,size,mimetype,time_id,file_extension,file_key FROM '.table_prefix.'files WHERE filename=\''.$filename.'\''.$tid.' ORDER BY time_id DESC;');
+ if(!$q) $db->_die('The file data could not be selected.');
+ if($db->numrows() < 1) { header('HTTP/1.1 404 Not Found'); die_friendly('File not found', '<p>The file "'.$filename.'" cannot be found.</p>'); }
+ $row = $db->fetchrow();
+ $db->free_result();
+
+ // Check permissions
+ $perms = $session->fetch_page_acl($row['page_id'], 'File');
+ if ( !$perms->get_permissions('read') )
+ {
+ die_friendly('Access denied', '<p>Access to the specified file is denied.</p>');
+ }
+
+ $fname = ENANO_ROOT . '/files/' . $row['file_key'] . '_' . $row['time_id'] . $row['file_extension'];
+ $data = file_get_contents($fname);
+ if(isset($_GET['preview']) && getConfig('enable_imagemagick')=='1' && file_exists(getConfig('imagemagick_path')) && substr($row['mimetype'], 0, 6) == 'image/')
+ {
+ $nam = tempnam('/tmp', $filename);
+ $h = @fopen($nam, 'w');
+ if(!$h) die('Error opening '.$nam.' for writing');
+ fwrite($h, $data);
+ fclose($h);
+ /* Make sure the request doesn't contain commandline injection - yow! */
+ if(!isset($_GET['width' ]) || (isset($_GET['width'] ) && !preg_match('#^([0-9]+)$#', $_GET['width'] ))) $width = '320'; else $width = $_GET['width' ];
+ if(!isset($_GET['height']) || (isset($_GET['height']) && !preg_match('#^([0-9]+)$#', $_GET['height'] ))) $height = '240'; else $height = $_GET['height'];
+ $cache_filename=ENANO_ROOT.'/cache/'.$filename.'-'.$row['time_id'].'-'.$width.'x'.$height.$row['file_extension'];
+ if(getConfig('cache_thumbs')=='1' && file_exists($cache_filename) && is_writable(ENANO_ROOT.'/cache')) {
+ $data = file_get_contents($cache_filename);
+ } elseif(getConfig('enable_imagemagick')=='1' && file_exists(getConfig('imagemagick_path'))) {
+ // Use ImageMagick to convert the image
+ //unlink($nam);
+ error_reporting(E_ALL);
+ $cmd = ''.getConfig('imagemagick_path').' "'.$nam.'" -resize "'.$width.'x'.$height.'>" "'.$nam.'.scaled'.$row['file_extension'].'"';
+ system($cmd, $stat);
+ if(!file_exists($nam.'.scaled'.$row['file_extension'])) die('Failed to call ImageMagick (return value '.$stat.'), command line was:<br />'.$cmd);
+ $data = file_get_contents($nam.'.scaled'.$row['file_extension']);
+ // Be stingy about it - better to re-generate the image hundreds of times than to fail completely
+ if(getConfig('cache_thumbs')=='1' && !file_exists($cache_filename)) {
+ // Write the generated thumbnail to the cache directory
+ $h = @fopen($cache_filename, 'w');
+ if(!$h) die('Error opening cache file "'.$cache_filename.'" for writing.');
+ fwrite($h, $data);
+ fclose($h);
+ }
+ }
+ unlink($nam);
+ }
+ $len = strlen($data);
+ header('Content-type: '.$row['mimetype']);
+ if(isset($_GET['download'])) header('Content-disposition: attachment, filename="'.$filename.'";');
+ header('Content-length: '.$len);
+ header('Last-Modified: '.date('r', $row['time_id']));
+ echo($data);
+
+ //
+ // Compress buffered output if required and send to browser
+ //
+ if ( $do_gzip )
+ {
+ //
+ // Copied from phpBB, which was in turn borrowed from php.net
+ //
+ $gzip_contents = ob_get_contents();
+ ob_end_clean();
+
+ $gzip_size = strlen($gzip_contents);
+ $gzip_crc = crc32($gzip_contents);
+
+ $gzip_contents = gzcompress($gzip_contents, 9);
+ $gzip_contents = substr($gzip_contents, 0, strlen($gzip_contents) - 4);
+
+ header('Content-encoding: gzip');
+ echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
+ echo $gzip_contents;
+ echo pack('V', $gzip_crc);
+ echo pack('V', $gzip_size);
+ }
+
+ exit;
+
+}
+
+?>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/SpecialUpdownload.php~ Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,285 @@
+<?php
+/*
+Plugin Name: Upload/download frontend
+Plugin URI: http://enano.homelinux.org/
+Description: Provides the pages Special:UploadFile and Special:DownloadFile. UploadFile is used to upload files to the site, and DownloadFile fetches the file from the database, creates thumbnails if necessary, and sends the file to the user.
+Author: Dan Fuhry
+Version: 1.0
+Author URI: http://enano.homelinux.org/
+*/
+
+/*
+ * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
+ * Version 1.0 release candidate 2
+ * Copyright (C) 2006-2007 Dan Fuhry
+ * SpecialUpdownload.php - handles uploading and downloading of user-uploaded files - possibly the most rigorously security-enforcing script in all of Enano, although sessions.php comes in a close second
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+global $db, $session, $paths, $template, $plugins; // Common objects
+
+$plugins->attachHook('base_classes_initted', '
+ global $paths;
+ $paths->add_page(Array(
+ \'name\'=>\'Upload file\',
+ \'urlname\'=>\'UploadFile\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'Download file\',
+ \'urlname\'=>\'DownloadFile\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ ');
+
+function page_Special_UploadFile()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $mime_types;
+ if(getConfig('enable_uploads')!='1') { die_friendly('Access denied', '<p>File uploads are disabled this website.</p>'); }
+ if ( !$session->get_permissions('upload_files') )
+ {
+ die_friendly('Access denied', '<p>File uploads are disabled for your user account or group.<p>');
+ }
+ if(isset($_POST['doit']))
+ {
+ if(isset($_FILES['data']))
+ {
+ $file =& $_FILES['data'];
+ }
+ else
+ {
+ $file = false;
+ }
+ if(!is_array($file)) die_friendly('Upload failed', '<p>The server could not retrieve the array $_FILES[\'data\'].</p>');
+ if($file['size'] == 0 || $file['size'] > (int)getConfig('max_file_size')) die_friendly('Upload failed', '<p>The file you uploaded is either too large or 0 bytes in length.</p>');
+ /*
+ $allowed_mime_types = Array(
+ 'text/plain',
+ 'image/png',
+ 'image/jpeg',
+ 'image/tiff',
+ 'image/gif',
+ 'text/html', // Safe because the file is stashed in the database
+ 'application/x-bzip2',
+ 'application/x-gzip',
+ 'text/x-c++'
+ );
+ if(function_exists('finfo_open') && $fi = finfo_open(FILEINFO_MIME, ENANO_ROOT.'/includes/magic')) // First try to use the fileinfo extension, this is the best way to determine the mimetype
+ {
+ if(!$fi) die_friendly('Upload failed', '<p>Enano was unable to determine the format of the uploaded file.</p><p>'.@finfo_file($fi, $file['tmp_name']).'</p>');
+ $type = @finfo_file($fi, $file['tmp_name']);
+ @finfo_close($fi);
+ }
+ elseif(function_exists('mime_content_type'))
+ $type = mime_content_type($file['tmp_name']); // OK, no fileinfo function. Use a (usually) built-in PHP function
+ elseif(isset($file['type']))
+ $type = $file['type']; // LAST RESORT: use the mimetype the browser sent us, though this is likely to be spoofed
+ else // DANG! Not even the browser told us. Bail out.
+ die_friendly('Upload failed', '<p>Enano was unable to determine the format of the uploaded file.</p>');
+ */
+ $types = fetch_allowed_extensions();
+ $ext = substr($file['name'], strrpos($file['name'], '.')+1, strlen($file['name']));
+ if(!isset($types[$ext]) || ( isset($types[$ext]) && !$types[$ext] ) )
+ {
+ die_friendly('Upload failed', '<p>The file type ".'.$ext.'" is not allowed.</p>');
+ }
+ $type = $mime_types[$ext];
+ //$type = explode(';', $type); $type = $type[0];
+ //if(!in_array($type, $allowed_mime_types)) die_friendly('Upload failed', '<p>The file type "'.$type.'" is not allowed.</p>');
+ if($_POST['rename'] != '')
+ {
+ $filename = $_POST['rename'];
+ } else {
+ $filename = $file['name'];
+ }
+ $bad_chars = Array(':', '\\', '/', '<', '>', '|', '*', '?', '"', '#', '+');
+ foreach($bad_chars as $ch)
+ {
+ if(strstr($filename, $ch) || preg_match('/^([ ]+)$/is', $filename)) die_friendly('Upload failed', '<p>The filename contains invalid characters.</p>');
+ }
+
+ if(isset($paths->pages[$paths->nslist['File'].$filename]) && !isset($_POST['update'])) die_friendly('Upload failed', '<p>The file already exists. You can <a href="'.makeUrlNS('Special', 'UploadFile/'.$filename).'">upload a new version of this file</a>.</p>');
+ elseif( isset($_POST['update']) &&
+ (!isset($paths->pages[$paths->nslist['File'].$filename]) ||
+ (isset($paths->pages[$paths->nslist['File'].$filename]) &&
+ $paths->pages[$paths->nslist['File'].$filename]['protected']==1)
+ )
+ )
+ die_friendly('Upload failed', '<p>Either the file does not exist (and therefore cannot be updated) or the file is protected.</p>');
+
+ $utime = time();
+
+ $filename = $db->escape($filename);
+ $ext = substr($filename, strrpos($filename, '.'), strlen($filename));
+ $flen = filesize($file['tmp_name']);
+
+ $comments = $db->escape(RenderMan::strip_php($_POST['comments']));
+ $chartag = sha1(microtime());
+ $urln = str_replace(' ', '_', $filename);
+
+ $key = md5($filename . '_' . file_get_contents($file['tmp_name']));
+ $targetname = ENANO_ROOT . '/files/' . $key . '_' . $utime . $ext;
+
+ if(!@move_uploaded_file($file['tmp_name'], $targetname))
+ {
+ die_friendly('Upload failed', '<p>Could not move uploaded file to the new location.</p>');
+ }
+
+ if(getConfig('file_history') != '1')
+ if(!$db->sql_query('DELETE FROM '.table_prefix.'files WHERE filename=\''.$filename.'\' LIMIT 1;')) $db->_die('The old file data could not be deleted.');
+ if(!$db->sql_query('INSERT INTO '.table_prefix.'files(time_id,page_id,filename,size,mimetype,file_extension,file_key) VALUES('.$utime.', \''.$urln.'\', \''.$filename.'\', '.$flen.', \''.$type.'\', \''.$ext.'\', \''.$key.'\')')) $db->_die('The file data entry could not be inserted.');
+ if(!isset($_POST['update']))
+ {
+ if(!$db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,author,page_id,namespace) VALUES('.$utime.', \''.date('d M Y h:i a').'\', \'page\', \'create\', \''.$session->username.'\', \''.$filename.'\', \''.'File'.'\');')) $db->_die('The page log could not be updated.');
+ if(!$db->sql_query('INSERT INTO '.table_prefix.'pages(name,urlname,namespace,protected,delvotes,delvote_ips) VALUES(\''.$filename.'\', \''.$urln.'\', \'File\', 0, 0, \'\')')) $db->_die('The page listing entry could not be inserted.');
+ if(!$db->sql_query('INSERT INTO '.table_prefix.'page_text(page_id,namespace,page_text,char_tag) VALUES(\''.$urln.'\', \'File\', \''.$comments.'\', \''.$chartag.'\')')) $db->_die('The page text entry could not be inserted.');
+ } else {
+ if(!$db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,author,page_id,namespace,edit_summary) VALUES('.$utime.', \''.date('d M Y h:i a').'\', \'page\', \'reupload\', \''.$session->username.'\', \''.$filename.'\', \''.'File'.'\', \''.$comments.'\');')) $db->_die('The page log could not be updated.');
+ }
+ die_friendly('Upload complete', '<p>Your file has been uploaded successfully. View the <a href="'.makeUrlNS('File', $filename).'">file\'s page</a>.</p>');
+ } else {
+ $template->header();
+ $fn = $paths->getParam(0);
+ if ( $fn && !$session->get_permissions('upload_new_version') )
+ {
+ die_friendly('Access denied', '<p>Uploading new versions of files has been disabled for your user account or group.<p>');
+ }
+ ?>
+ <p>Using this form you can upload a file to the <?php echo getConfig('site_name'); ?> site.</p>
+ <p>The maximum file size is <?php
+ // Get the max file size, and format it in a way that is user-friendly
+ $fs = getConfig('max_file_size');
+ echo $fs.' bytes';
+ $fs = (int)$fs;
+ if($fs >= 1048576)
+ {
+ $fs = round($fs / 1048576, 1);
+ echo ' ('.$fs.' MB)';
+ } elseif($fs >= 1024) {
+ $fs = round($fs / 1024, 1);
+ echo ' ('.$fs.' KB)';
+ }
+ ?>.</p>
+ <form action="<?php echo makeUrl($paths->page); ?>" method="post" enctype="multipart/form-data">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr><td>File:</td><td><input name="data" type="file" size="40" /></td></tr>
+ <tr><td>Rename to:</td><td><input name="rename" type="text" size="40"<?php if($fn) echo ' value="'.$fn.'" readonly="readonly"'; ?> /></td></tr>
+ <?php
+ if(!$fn) echo '<tr><td>Comments:<br />(can be wiki-formatted)</td><td><textarea name="comments" rows="20" cols="60"></textarea></td></tr>';
+ else echo '<tr><td>Reason for uploading the new version: </td><td><input name="comments" size="50" /></td></tr>';
+ ?>
+ <tr><td colspan="2" style="text-align: center">
+ <?php
+ if($fn)
+ echo '<input type="hidden" name="update" value="true" />';
+ ?>
+ <input type="submit" name="doit" value="Upload file" />
+ </td></tr>
+ </table>
+ </form>
+ <?php
+ $template->footer();
+ }
+}
+
+function page_Special_DownloadFile()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $do_gzip;
+ $filename = rawurldecode($paths->getParam(0));
+ $timeid = $paths->getParam(1);
+ if($timeid && preg_match('#^([0-9]+)$#', (string)$timeid)) $tid = ' AND time_id='.$timeid;
+ else $tid = '';
+ $filename = $db->escape($filename);
+ $q = $db->sql_query('SELECT page_id,size,mimetype,time_id,file_extension,file_key FROM '.table_prefix.'files WHERE filename=\''.$filename.'\''.$tid.' ORDER BY time_id DESC;');
+ if(!$q) $db->_die('The file data could not be selected.');
+ if($db->numrows() < 1) { header('HTTP/1.1 404 Not Found'); die_friendly('File not found', '<p>The file "'.$filename.'" cannot be found.</p>'); }
+ $row = $db->fetchrow();
+ $db->free_result();
+
+ // Check permissions
+ $perms = $session->fetch_page_acl($row['page_id'], 'File');
+ if ( !$perms->get_permissions('read') )
+ {
+ die_friendly('Access denied', '<p>Access to the specified file is denied.</p>');
+ }
+
+ $fname = ENANO_ROOT . '/files/' . $row['file_key'] . '_' . $row['time_id'] . $row['file_extension'];
+ $data = file_get_contents($fname);
+ if(isset($_GET['preview']) && getConfig('enable_imagemagick')=='1' && file_exists(getConfig('imagemagick_path')) && substr($row['mimetype'], 0, 6) == 'image/')
+ {
+ $nam = tempnam('/tmp', $filename);
+ $h = @fopen($nam, 'w');
+ if(!$h) die('Error opening '.$nam.' for writing');
+ fwrite($h, $data);
+ fclose($h);
+ /* Make sure the request doesn't contain commandline injection - yow! */
+ if(!isset($_GET['width' ]) || (isset($_GET['width'] ) && !preg_match('#^([0-9]+)$#', $_GET['width'] ))) $width = '320'; else $width = $_GET['width' ];
+ if(!isset($_GET['height']) || (isset($_GET['height']) && !preg_match('#^([0-9]+)$#', $_GET['height'] ))) $height = '240'; else $height = $_GET['height'];
+ $cache_filename=ENANO_ROOT.'/cache/'.$filename.'-'.$row['time_id'].'-'.$width.'x'.$height.$row['file_extension'];
+ if(getConfig('cache_thumbs')=='1' && file_exists($cache_filename) && is_writable(ENANO_ROOT.'/cache')) {
+ $data = file_get_contents($cache_filename);
+ } elseif(getConfig('enable_imagemagick')=='1' && file_exists(getConfig('imagemagick_path'))) {
+ // Use ImageMagick to convert the image
+ //unlink($nam);
+ error_reporting(E_ALL);
+ $cmd = ''.getConfig('imagemagick_path').' "'.$nam.'" -resize "'.$width.'x'.$height.'>" "'.$nam.'.scaled'.$row['file_extension'].'"';
+ system($cmd, $stat);
+ if(!file_exists($nam.'.scaled'.$row['file_extension'])) die('Failed to call ImageMagick (return value '.$stat.'), command line was:<br />'.$cmd);
+ $data = file_get_contents($nam.'.scaled'.$row['file_extension']);
+ // Be stingy about it - better to re-generate the image hundreds of times than to fail completely
+ if(getConfig('cache_thumbs')=='1' && !file_exists($cache_filename)) {
+ // Write the generated thumbnail to the cache directory
+ $h = @fopen($cache_filename, 'w');
+ if(!$h) die('Error opening cache file "'.$cache_filename.'" for writing.');
+ fwrite($h, $data);
+ fclose($h);
+ }
+ }
+ unlink($nam);
+ }
+ $len = strlen($data);
+ header('Content-type: '.$row['mimetype']);
+ if(isset($_GET['download'])) header('Content-disposition: attachment, filename="'.$filename.'";');
+ header('Content-length: '.$len);
+ header('Last-Modified: '.date('r', $row['time_id']));
+ echo($data);
+
+ //
+ // Compress buffered output if required and send to browser
+ //
+ if ( $do_gzip )
+ {
+ //
+ // Copied from phpBB, which was in turn borrowed from php.net
+ //
+ $gzip_contents = ob_get_contents();
+ ob_end_clean();
+
+ $gzip_size = strlen($gzip_contents);
+ $gzip_crc = crc32($gzip_contents);
+
+ $gzip_contents = gzcompress($gzip_contents, 9);
+ $gzip_contents = substr($gzip_contents, 0, strlen($gzip_contents) - 4);
+
+ header('Content-encoding: gzip');
+ echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
+ echo $gzip_contents;
+ echo pack('V', $gzip_crc);
+ echo pack('V', $gzip_size);
+ }
+
+ exit;
+
+}
+
+?>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/SpecialUserFuncs.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,875 @@
+<?php
+/*
+Plugin Name: Special user/login-related pages
+Plugin URI: http://enano.homelinux.org/
+Description: Provides the pages Special:Login, Special:Logout, Special:Register, and Special:Preferences.
+Author: Dan Fuhry
+Version: 1.0
+Author URI: http://enano.homelinux.org/
+*/
+
+/*
+ * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
+ * Version 1.0 release candidate 2
+ * Copyright (C) 2006-2007 Dan Fuhry
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+global $db, $session, $paths, $template, $plugins; // Common objects
+
+$plugins->attachHook('base_classes_initted', '
+ global $paths;
+ $paths->add_page(Array(
+ \'name\'=>\'Log in\',
+ \'urlname\'=>\'Login\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ $paths->add_page(Array(
+ \'name\'=>\'Log out\',
+ \'urlname\'=>\'Logout\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ $paths->add_page(Array(
+ \'name\'=>\'Register\',
+ \'urlname\'=>\'Register\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ $paths->add_page(Array(
+ \'name\'=>\'Edit Profile\',
+ \'urlname\'=>\'Preferences\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'Contributions\',
+ \'urlname\'=>\'Contributions\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'Change style\',
+ \'urlname\'=>\'ChangeStyle\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'Activate user account\',
+ \'urlname\'=>\'ActivateAccount\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'Captcha\',
+ \'urlname\'=>\'Captcha\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'Forgot password\',
+ \'urlname\'=>\'PasswordReset\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ ');
+
+// function names are IMPORTANT!!! The name pattern is: page_<namespace ID>_<page URLname, without namespace>
+
+$__login_status = '';
+
+function page_Special_Login()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $__login_status;
+
+ $pubkey = $session->rijndael_genkey();
+ $challenge = $session->dss_rand();
+
+ if ( isset($_GET['act']) && $_GET['act'] == 'getkey' )
+ {
+ $response = Array(
+ 'key' => $pubkey,
+ 'challenge' => $challenge
+ );
+ $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
+ $response = $json->encode($response);
+ echo $response;
+ return null;
+ }
+
+ $level = ( isset($_GET['level']) && in_array($_GET['level'], array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') ) ) ? intval($_GET['level']) : USER_LEVEL_MEMBER;
+ if ( isset($_POST['login']) )
+ {
+ if ( in_array($_POST['auth_level'], array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') ) )
+ {
+ $level = intval($_POST['auth_level']);
+ }
+ }
+
+ if ( $level > USER_LEVEL_MEMBER && !$session->user_logged_in )
+ {
+ $level = USER_LEVEL_MEMBER;
+ }
+ $template->header();
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Login').'" method="post" name="loginform" onsubmit="runEncryption();">';
+ $header = ( $level > USER_LEVEL_MEMBER ) ? 'Please re-enter your login details' : 'Please enter your username and password to log in.';
+ if ( isset($_POST['login']) )
+ {
+ echo '<p>'.$__login_status.'</p>';
+ }
+ if ( $p = $paths->getAllParams() )
+ {
+ echo '<input type="hidden" name="return_to" value="'.$p.'" />';
+ }
+ else if ( isset($_POST['login']) && isset($_POST['return_to']) )
+ {
+ echo '<input type="hidden" name="return_to" value="'.htmlspecialchars($_POST['return_to']).'" />';
+ }
+ ?>
+ <div class="tblholder">
+ <table border="0" style="width: 100%;" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="3"><?php echo $header; ?></th>
+ </tr>
+ <tr>
+ <td colspan="3" class="row1">
+ <?php
+ if ( $level <= USER_LEVEL_MEMBER )
+ {
+ echo '<p>Logging in enables you to use your preferences and access member information. If you don\'t have a username and password here, you can <a href="'.makeUrl($paths->nslist['Special'].'Register').'">create an account</a>.</p>';
+ }
+ else
+ {
+ echo '<p>You are requesting that a sensitive operation be performed. To continue, please re-enter your password to confirm your identity.</p>';
+ }
+ ?>
+ </td>
+ </tr>
+ <tr>
+ <td class="row2">
+ Username:
+ </td>
+ <td class="row1">
+ <input name="username" size="25" type="text" <?php
+ if ( $level <= USER_LEVEL_MEMBER )
+ {
+ echo 'tabindex="1" ';
+ }
+ if ( $session->user_logged_in )
+ {
+ echo 'value="' . $session->username . '"';
+ }
+ ?> />
+ </td>
+ <?php if ( $level <= USER_LEVEL_MEMBER ) { ?>
+ <td rowspan="2" class="row3">
+ <small>Forgot your password? <a href="<?php echo makeUrlNS('Special', 'PasswordReset'); ?>">No problem.</a><br />
+ Maybe you need to <a href="<?php echo makeUrlNS('Special', 'Register'); ?>">create an account</a>.</small>
+ </td>
+ <?php } ?>
+ </tr>
+ <tr>
+ <td class="row2">Password:<br /></td><td class="row1"><input name="pass" size="25" type="password" tabindex="<?php echo ( $level <= USER_LEVEL_MEMBER ) ? '2' : '1'; ?>" /></td>
+ </tr>
+ <?php if ( $level <= USER_LEVEL_MEMBER ) { ?>
+ <tr>
+ <td class="row3" colspan="3">
+ <p><b>Important note regarding cryptography:</b> Some countries do not allow the import or use of cryptographic technology. If you live in one of the countries listed below, you should <a href="<?php if($p=$paths->getParam(0))$u='/'.$p;else $u='';echo makeUrl($paths->page.$u, 'level='.$level.'&use_crypt=0', true); ?>">log in without using encryption</a>.</p>
+ <p>This restriction applies to the following countries: Belarus, China, India, Israel, Kazakhstan, Mongolia, Pakistan, Russia, Saudi Arabia, Singapore, Tunisia, Venezuela, and Vietnam.</p>
+ </td>
+ </tr>
+ <?php } ?>
+ <tr>
+ <th colspan="3" style="text-align: center" class="subhead"><input type="submit" name="login" value="Log in" tabindex="3" /></th>
+ </tr>
+ </table>
+ </div>
+ <input type="hidden" name="challenge_data" value="<?php echo $challenge; ?>" />
+ <input type="hidden" name="use_crypt" value="no" />
+ <input type="hidden" name="crypt_key" value="<?php echo $pubkey; ?>" />
+ <input type="hidden" name="crypt_data" value="" />
+ <input type="hidden" name="auth_level" value="<?php echo (string)$level; ?>" />
+ </form>
+ <?php
+ echo $session->aes_javascript('loginform', 'pass', 'use_crypt', 'crypt_key', 'crypt_data', 'challenge_data');
+ ?>
+ <?php
+ $template->footer();
+}
+
+function page_Special_Login_preloader() // adding _preloader to the end of the function name calls the function before $session and $paths setup routines are called
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $__login_status;
+ if ( isset($_GET['act']) && $_GET['act'] == 'ajaxlogin' )
+ {
+ $plugins->attachHook('login_password_reset', 'SpecialLogin_SendResponse_PasswordReset($row[\'user_id\'], $row[\'temp_password\']);');
+ $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
+ $data = $json->decode($_POST['params']);
+ $level = ( isset($data['level']) ) ? intval($data['level']) : USER_LEVEL_MEMBER;
+ $result = $session->login_with_crypto($data['username'], $data['crypt_data'], $data['crypt_key'], $data['challenge'], $level);
+ $session->start();
+ //echo "$result\n$session->sid_super";
+ //exit;
+ if ( $result == 'success' )
+ {
+ $response = Array(
+ 'result' => 'success',
+ 'key' => $session->sid_super // ( ( $session->sid_super ) ? $session->sid_super : $session->sid )
+ );
+ }
+ else
+ {
+ $response = Array(
+ 'result' => 'error',
+ 'error' => $result
+ );
+ }
+ $response = $json->encode($response);
+ echo $response;
+ $db->close();
+ exit;
+ }
+ if(isset($_POST['login'])) {
+ if($_POST['use_crypt'] == 'yes')
+ {
+ $result = $session->login_with_crypto($_POST['username'], $_POST['crypt_data'], $_POST['crypt_key'], $_POST['challenge_data'], intval($_POST['auth_level']));
+ }
+ else
+ {
+ $result = $session->login_without_crypto($_POST['username'], $_POST['pass'], false, intval($_POST['auth_level']));
+ }
+ $session->start();
+ $paths->init();
+ if($result == 'success')
+ {
+ $template->load_theme($session->theme, $session->style);
+ if(isset($_POST['return_to']))
+ {
+ $name = ( isset($paths->pages[$_POST['return_to']]['name']) ) ? $paths->pages[$_POST['return_to']]['name'] : $_POST['return_to'];
+ redirect( makeUrl($_POST['return_to']), 'Login successful', 'You have successfully logged into the '.getConfig('site_name').' site as "'.$session->username.'". Redirecting to ' . $name . '...' );
+ }
+ else
+ {
+ $paths->main_page();
+ }
+ }
+ else
+ {
+ $GLOBALS['__login_status'] = $result;
+ }
+ }
+}
+
+function SpecialLogin_SendResponse_PasswordReset($user_id, $passkey)
+{
+ $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
+
+ $response = Array(
+ 'result' => 'success_reset',
+ 'user_id' => $user_id,
+ 'temppass' => $passkey
+ );
+
+ $response = $json->encode($response);
+ echo $response;
+
+ $db->close();
+
+ exit;
+}
+
+function page_Special_Logout() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $l = $session->logout();
+ if($l == 'success') $paths->main_page();
+ $template->header();
+ echo '<h3>An error occurred during the logout process.</h3><p>'.$l.'</p>';
+ $template->footer();
+}
+
+function page_Special_Register() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if(getConfig('account_activation') == 'disable' && ( ( $session->user_level >= USER_LEVEL_ADMIN && !isset($_GET['IWannaPlayToo']) ) || $session->user_level < USER_LEVEL_ADMIN || !$session->user_logged_in ))
+ {
+ $s = ($session->user_level >= USER_LEVEL_ADMIN) ? '<p>Oops...it seems that you <em>are</em> the administrator...hehe...you can also <a href="'.makeUrl($paths->page, 'IWannaPlayToo', true).'">force account registration to work</a>.</p>' : '';
+ die_friendly('Registration disabled', '<p>The administrator has disabled new user registration on this site.</p>' . $s);
+ }
+ if(isset($_POST['submit'])) {
+ $captcharesult = $session->get_captcha($_POST['captchahash']);
+ if($captcharesult != $_POST['captchacode'])
+ $s = 'The confirmation code you entered was incorrect.';
+ else
+ // CAPTCHA code was correct, create the account
+ $s = $session->create_user($_POST['username'], $_POST['password'], $_POST['email'], $_POST['real_name']);
+ if($s == 'success')
+ {
+ switch(getConfig('account_activation'))
+ {
+ case "none":
+ default:
+ $str = 'You may now <a href="'.makeUrlNS('Special', 'Login').'">log in</a> with the username and password that you created.';
+ break;
+ case "user":
+ $str = 'Because this site requires account activation, you have been sent an e-mail with further instructions. Please follow the instructions in that e-mail to continue your registration.';
+ break;
+ case "admin":
+ $str = 'Because this site requires administrative account activation, you cannot use your account at the moment. A notice has been sent to the site administration team that will alert them that your account has been created.';
+ break;
+ }
+ die_friendly('Registration successful', '<p>Thank you for registering, your user account has been created. '.$str.'</p>');
+ }
+ }
+ $template->header();
+ echo 'A user account enables you to have greater control over your browsing experience.';
+ $session->kill_captcha();
+ $captchacode = $session->make_captcha();
+ ?>
+ <h3>Create a user account</h3>
+ <form name="regform" action="<?php echo makeUrl($paths->page); ?>" method="post">
+ <div class="tblholder">
+ <table border="0" width="100%" cellspacing="1" cellpadding="4">
+ <tr><th class="subhead" colspan="3">Please tell us a little bit about yourself.</th></tr>
+ <?php if(isset($_POST['submit'])) echo '<tr><td colspan="3" class="row2" style="color: red;">'.$s.'</td></tr>'; ?>
+ <tr><td class="row1" style="width: 50%;">Preferred username:<span id="e_username"></span></td><td class="row1" style="width: 50%;"><input type="text" name="username" size="30" onkeyup="namegood = false; validateForm();" onblur="checkUsername();" /></td><td class="row1" style="max-width: 24px;"><img alt="Good/bad icon" src="<?php echo scriptPath; ?>/images/bad.gif" id="s_username" /></td></tr>
+ <tr><td class="row3" style="width: 50%;" rowspan="2">Password:<span id="e_password"></span></td><td class="row3" style="width: 50%;"><input type="password" name="password" size="30" onkeyup="validateForm();" /></td><td rowspan="2" class="row3" style="max-width: 24px;"><img alt="Good/bad icon" src="<?php echo scriptPath; ?>/images/bad.gif" id="s_password" /></td></tr>
+ <tr><td class="row3" style="width: 50%;"><input type="password" name="password_confirm" size="30" onkeyup="validateForm();" /> <small>Enter your password again to confirm.</small></td></tr>
+ <tr><td class="row1" style="width: 50%;">E-mail address:<?php if(getConfig('account_activation')=='user') echo '<br /><small>An e-mail with an account activation key will be sent to this address, so please ensure that it is correct.</small></td>'; ?><td class="row1" style="width: 50%;"><input type="text" name="email" size="30" onkeyup="validateForm();" /></td><td class="row1" style="max-width: 24px;"><img alt="Good/bad icon" src="<?php echo scriptPath; ?>/images/bad.gif" id="s_email" /></td></tr>
+ <tr><td class="row3" style="width: 50%;">Real name:<br /><small>Giving your real name is totally optional. If you choose to provide your real name, it will be used to provide attribution for any edits or contributions you may make to this site.</small><td class="row3" style="width: 50%;"><input type="text" name="real_name" size="30" /></td><td class="row3" style="max-width: 24px;"></td></tr>
+ <tr><td class="row1" style="width: 50%;" rowspan="2">Visual confirmation<br /><small>Please enter the code shown in the image to the right into the text box. This process helps to ensure that this registration is not being performed by an automated bot. If the image to the right is illegible, you can <a href="#" onclick="regenCaptcha(); return false;">generate a new image</a>.<br /><br />If you are visually impaired or otherwise cannot read the text shown to the right, please contact the site management and they will create an account for you.</small></td><td colspan="2" class="row1"><img id="captchaimg" alt="CAPTCHA image" src="<?php echo makeUrlNS('Special', 'Captcha/'.$captchacode); ?>" /><span id="b_username"></span></td></tr>
+ <tr><td class="row1" colspan="2">Code: <input name="captchacode" type="text" size="10" /><input type="hidden" name="captchahash" value="<?php echo $captchacode; ?>" /></td></tr>
+ <tr><td class="row2" colspan="3" style="text-align: center;"><input type="submit" name="submit" value="Create my account" /></td></tr>
+ </table>
+ </div>
+ </form>
+ <script type="text/javascript">
+ // <![CDATA[
+ var namegood = false;
+ function validateForm()
+ {
+ var frm = document.forms.regform;
+ failed = false;
+
+ // Username
+ if(!namegood)
+ {
+ if(frm.username.value.match(/^([A-z0-9 \!@\-\(\)]+){2,}$/ig))
+ {
+ document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/unknown.gif';
+ document.getElementById('e_username').innerHTML = ''; // '<br /><small><b>Checking availability...</b></small>';
+ } else {
+ failed = true;
+ document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/bad.gif';
+ document.getElementById('e_username').innerHTML = '<br /><small>Your username must be at least two characters in length and may contain only alphanumeric characters (A-Z and 0-9), spaces, and the following characters: :, !, @, #, *.</small>';
+ }
+ }
+ document.getElementById('b_username').innerHTML = '';
+ if(hex_md5(frm.real_name.value) == 'fa8e397ae0f6cd5b0f90a3f48178cd7e')
+ {
+ document.getElementById('b_username').innerHTML = '<br /><br />Hey...I know you!<br /><img alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Bill_Gates_2004_cr.jpg/220px-Bill_Gates_2004_cr.jpg" />';
+ }
+
+ // Password
+ if(frm.password.value.match(/^(.+){6,}$/ig) && frm.password_confirm.value.match(/^(.+){6,}$/ig) && frm.password.value == frm.password_confirm.value)
+ {
+ document.getElementById('s_password').src='<?php echo scriptPath; ?>/images/good.gif';
+ document.getElementById('e_password').innerHTML = '<br /><small>The password you entered is valid.</small>';
+ } else {
+ failed = true;
+ if(frm.password.value.length < 6)
+ document.getElementById('e_password').innerHTML = '<br /><small>Your password must be at least six characters in length.</small>';
+ else if(frm.password.value != frm.password_confirm.value)
+ document.getElementById('e_password').innerHTML = '<br /><small>The passwords you entered do not match.</small>';
+ else
+ document.getElementById('e_password').innerHTML = '';
+ document.getElementById('s_password').src='<?php echo scriptPath; ?>/images/bad.gif';
+ }
+
+ // E-mail address
+ if(frm.email.value.match(/^(?:[\w\d]+\.?)+@(?:(?:[\w\d]\-?)+\.)+\w{2,4}$/))
+ {
+ document.getElementById('s_email').src='<?php echo scriptPath; ?>/images/good.gif';
+ } else {
+ failed = true;
+ document.getElementById('s_email').src='<?php echo scriptPath; ?>/images/bad.gif';
+ }
+ if(failed)
+ {
+ frm.submit.disabled = 'disabled';
+ } else {
+ frm.submit.disabled = false;
+ }
+ }
+ function checkUsername()
+ {
+ var frm = document.forms.regform;
+
+ if(!namegood)
+ {
+ if(frm.username.value.match(/^([A-z0-9 \.:\!@\#\*]+){2,}$/ig))
+ {
+ document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/unknown.gif';
+ document.getElementById('e_username').innerHTML = '';
+ } else {
+ document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/bad.gif';
+ document.getElementById('e_username').innerHTML = '<br /><small>Your username must be at least two characters in length and may contain only alphanumeric characters (A-Z and 0-9), spaces, and the following characters: :, !, @, #, *.</small>';
+ return false;
+ }
+ }
+
+ document.getElementById('e_username').innerHTML = '<br /><small><b>Checking availability...</b></small>';
+ ajaxGet('<?php echo scriptPath; ?>/ajax.php?title=null&_mode=checkusername&name='+escape(frm.username.value), function() {
+ if(ajax.readyState == 4)
+ if(ajax.responseText == 'good')
+ {
+ document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/good.gif';
+ document.getElementById('e_username').innerHTML = '<br /><small><b>This username is available.</b></small>';
+ namegood = true;
+ } else if(ajax.responseText == 'bad') {
+ document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/bad.gif';
+ document.getElementById('e_username').innerHTML = '<br /><small><b>Error: that username is already taken.</b></small>';
+ namegood = false;
+ } else {
+ document.getElementById('e_username').innerHTML = ajax.responseText;
+ }
+ });
+ }
+ function regenCaptcha()
+ {
+ var frm = document.forms.regform;
+ document.getElementById('captchaimg').src = '<?php echo makeUrlNS("Special", "Captcha/"); ?>'+frm.captchahash.value+'/'+Math.floor(Math.random() * 100000);
+ return false;
+ }
+ validateForm();
+ setTimeout('checkUsername();', 1000);
+ // ]]>
+ </script>
+ <?php
+ $template->footer();
+}
+
+/*
+If you want the old preferences page back, be my guest.
+function page_Special_Preferences() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $template->header();
+ if(isset($_POST['submit'])) {
+ $data = $session->update_user($session->user_id, $_POST['username'], $_POST['current_pass'], $_POST['new_pass'], $_POST['email'], $_POST['real_name'], $_POST['sig']);
+ if($data == 'success') echo '<h3>Information</h3><p>Your profile has been updated. <a href="'.scriptPath.'/">Return to the index page</a>.</p>';
+ else echo $data;
+ } else {
+ echo '
+ <h3>Edit your profile</h3>
+ <form action="'.makeUrl($paths->nslist['Special'].'Preferences').'" method="post">
+ <table border="0" style="margin-left: 0.2in;">
+ <tr><td>Username:</td><td><input type="text" name="username" value="'.$session->username.'" /></td></tr>
+ <tr><td>Current Password:</td><td><input type="password" name="current_pass" /></td></tr>
+ <tr><td colspan="2"><small>You only need to enter your current password if you are changing your e-mail address or changing your password.</small></td></tr>
+ <tr><td>New Password:</td><td><input type="password" name="new_pass" /></td></tr>
+ <tr><td>E-mail:</td><td><input type="text" name="email" value="'.$session->email.'" /></td></tr>
+ <tr><td>Real Name:</td><td><input type="text" name="real_name" value="'.$session->real_name.'" /></td></tr>
+ <tr><td>Signature:<br /><small>Your signature appears<br />below your comment posts.</small></td><td><textarea rows="10" cols="40" name="sig">'.$session->signature.'</textarea></td></tr>
+ <tr><td colspan="2">
+ <input type="submit" name="submit" value="Save Changes" /></td></tr>
+ </table>
+ </form>
+ ';
+ }
+ $template->footer();
+}
+*/
+
+function page_Special_Contributions() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $template->header();
+ $user = $paths->getParam();
+ if(!$user && isset($_GET['user']))
+ {
+ $user = $_GET['user'];
+ }
+ elseif(!$user && !isset($_GET['user']))
+ {
+ echo 'No user selected!';
+ $template->footer();
+ $db->close();
+ exit;
+ }
+
+ $user = $db->escape($user);
+
+ $q = 'SELECT time_id,date_string,page_id,namespace,author,edit_summary,minor_edit,page_id,namespace FROM '.table_prefix.'logs WHERE author=\''.$user.'\' AND action=\'edit\' ORDER BY time_id DESC;';
+ if(!$db->sql_query($q)) $db->_die('The history data for the page "'.$paths->cpage['name'].'" could not be selected.');
+ echo 'History of edits and actions<h3>Edits:</h3>';
+ if($db->numrows() < 1) echo 'No history entries in this category.';
+ while($r = $db->fetchrow()) {
+ echo '<a href="#" onclick="ajaxHistView(\''.$r['time_id'].'\', \''.$paths->nslist[$r['namespace']].$r['page_id'].'\'); return false;"><i>'.$r['date_string'].'</i></a> (<a href="#" onclick="ajaxRollback(\''.$r['time_id'].'\'); return false;">revert</a>) <a href="'.makeUrl($paths->nslist[$r['namespace']].$r['page_id']).'">'.$paths->nslist[$r['namespace']].$r['page_id'].'</a>: '.$r['edit_summary'];
+ if($r['minor_edit']) echo '<b> - minor edit</b>';
+ echo '<br />';
+ }
+ $db->free_result();
+ echo '<h3>Other changes:</h3>';
+ $q = 'SELECT log_type,time_id,action,date_string,page_id,namespace,author,edit_summary,minor_edit,page_id,namespace FROM '.table_prefix.'logs WHERE author=\''.$user.'\' AND action!=\'edit\' ORDER BY time_id DESC;';
+ if(!$db->sql_query($q)) $db->_die('The history data for the page "'.$paths->cpage['name'].'" could not be selected.');
+ if($db->numrows() < 1) echo 'No history entries in this category.';
+ while($r = $db->fetchrow()) {
+ if($r['log_type']=='page') {
+ echo '(<a href="#" onclick="ajaxRollback(\''.$r['time_id'].'\'); return false;">rollback</a>) <i>'.$r['date_string'].'</i> <a href="'.makeUrl($paths->nslist[$r['namespace']].$r['page_id']).'">'.$paths->nslist[$r['namespace']].$r['page_id'].'</a>: ';
+ if($r['action']=='prot') echo 'Protected page; reason: '.$r['edit_summary'];
+ elseif($r['action']=='unprot') echo 'Unprotected page; reason: '.$r['edit_summary'];
+ elseif($r['action']=='rename') echo 'Renamed page; old title was: '.$r['edit_summary'];
+ elseif($r['action']=='create') echo 'Created page';
+ elseif($r['action']=='delete') echo 'Deleted page';
+ if($r['minor_edit']) echo '<b> - minor edit</b>';
+ echo '<br />';
+ } elseif($r['log_type']=='security') {
+ // Not implemented, and when it is, it won't be public
+ }
+ }
+ $db->free_result();
+ $template->footer();
+}
+
+function page_Special_ChangeStyle()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if(!$session->user_logged_in) die_friendly('Access denied', '<p>You must be logged in to change your style. Spoofer.</p>');
+ if(isset($_POST['theme']) && isset($_POST['style']) && isset($_POST['return_to']))
+ {
+ $d = ENANO_ROOT . '/themes/' . $_POST['theme'];
+ $f = ENANO_ROOT . '/themes/' . $_POST['theme'] . '/css/' . $_POST['style'] . '.css';
+ if(!file_exists($d) || !is_dir($d)) die('The directory "'.$d.'" does not exist.');
+ if(!file_exists($f)) die('The file "'.$f.'" does not exist.');
+ $d = $db->escape($_POST['theme']);
+ $f = $db->escape($_POST['style']);
+ $q = 'UPDATE '.table_prefix.'users SET theme=\''.$d.'\',style=\''.$f.'\' WHERE username=\''.$session->username.'\'';
+ if(!$db->sql_query($q))
+ {
+ $db->_die('Your theme/style preferences were not updated.');
+ }
+ else
+ {
+ redirect(makeUrl($_POST['return_to']), '', '', 0);
+ }
+ }
+ else
+ {
+ $template->header();
+ $ret = ( isset($_POST['return_to']) ) ? $_POST['return_to'] : $paths->getParam(0);
+ if(!$ret) $ret = getConfig('main_page');
+ ?>
+ <form action="<?php echo makeUrl($paths->page); ?>" method="post">
+ <?php if(!isset($_POST['themeselected'])) { ?>
+ <h3>Please select a new theme:</h3>
+ <p>
+ <select name="theme">
+ <?php
+ foreach($template->theme_list as $t) {
+ if($t['enabled'])
+ {
+ echo '<option value="'.$t['theme_id'].'"';
+ if($t['theme_id'] == $session->theme) echo ' selected="selected"';
+ echo '>'.$t['theme_name'].'</option>';
+ }
+ }
+ ?>
+ </select>
+ </p>
+ <p><input type="hidden" name="return_to" value="<?php echo $ret; ?>" />
+ <input type="submit" name="themeselected" value="Continue" /></p>
+ <?php } else {
+ $theme = $_POST['theme'];
+ if ( !preg_match('/^([0-9A-z_-]+)$/i', $theme ) )
+ die('Hacking attempt');
+ ?>
+ <h3>Please select a stylesheet:</h3>
+ <p>
+ <select name="style">
+ <?php
+ $dir = './themes/'.$theme.'/css/';
+ $list = Array();
+ // Open a known directory, and proceed to read its contents
+ if (is_dir($dir)) {
+ if ($dh = opendir($dir)) {
+ while (($file = readdir($dh)) !== false) {
+ if(preg_match('#^(.*?)\.css$#is', $file) && $file != '_printable.css') {
+ $list[] = substr($file, 0, strlen($file)-4);
+ }
+ }
+ closedir($dh);
+ }
+ } else die($dir.' is not a dir');
+ foreach ( $list as $l )
+ {
+ echo '<option value="'.$l.'">'.capitalize_first_letter($l).'</option>';
+ }
+ ?>
+ </select>
+ </p>
+ <p><input type="hidden" name="return_to" value="<?php echo $ret; ?>" />
+ <input type="hidden" name="theme" value="<?php echo $theme; ?>" />
+ <input type="submit" name="allclear" value="Change style" /></p>
+ <?php } ?>
+ </form>
+ <?php
+ $template->footer();
+ }
+}
+
+function page_Special_ActivateAccount()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $user = $paths->getParam(0);
+ if(!$user) die_friendly('Account activation error', '<p>The URL was incorrect.</p>');
+ $key = $paths->getParam(1);
+ if(!$key) die_friendly('Account activation error', '<p>The URL was incorrect.</p>');
+ $s = $session->activate_account(str_replace('_', ' ', $user), $key);
+ if($s > 0) die_friendly('Activation successful', '<p>Your account is now active. Thank you for registering.</p>');
+ else die_friendly('Activation failed', '<p>The activation key was probably incorrect.</p>');
+}
+
+function page_Special_Captcha()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if($paths->getParam(0) == 'make')
+ {
+ $session->kill_captcha();
+ echo $session->make_captcha();
+ return;
+ }
+ $hash = $paths->getParam(0);
+ if(!$hash || !preg_match('#^([0-9a-f]*){32,32}$#i', $hash)) $paths->main_page();
+ $code = $session->get_captcha($hash);
+ if(!$code) die('Invalid hash or IP address incorrect.');
+ require(ENANO_ROOT.'/includes/captcha.php');
+ $captcha = new captcha($code);
+ //header('Content-disposition: attachment; filename=autocaptcha.png');
+ $captcha->make_image();
+ exit;
+}
+
+function page_Special_PasswordReset()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $template->header();
+ if($paths->getParam(0) == 'stage2')
+ {
+ $user_id = intval($paths->getParam(1));
+ $encpass = $paths->getParam(2);
+ if ( $user_id < 2 )
+ {
+ echo '<p>Hacking attempt</p>';
+ $template->footer();
+ return false;
+ }
+ if(!preg_match('#^([a-f0-9]+)$#i', $encpass))
+ {
+ echo '<p>Hacking attempt</p>';
+ $template->footer();
+ return false;
+ }
+
+ $q = $db->sql_query('SELECT username,temp_password_time FROM '.table_prefix.'users WHERE user_id='.$user_id.' AND temp_password=\'' . $encpass . '\';');
+ if($db->numrows() < 1)
+ {
+ echo '<p>Invalid credentials</p>';
+ $template->footer();
+ return false;
+ }
+ $row = $db->fetchrow();
+ $db->free_result();
+
+ if ( ( intval($row['temp_password_time']) + 3600 * 24 ) < time() )
+ {
+ echo '<p>Password has expired</p>';
+ $template->footer();
+ return false;
+ }
+
+ if ( isset($_POST['do_stage2']) )
+ {
+ $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE);
+ if($_POST['use_crypt'] == 'yes')
+ {
+ $crypt_key = $session->fetch_public_key($_POST['crypt_key']);
+ if(!$crypt_key)
+ {
+ echo 'ERROR: Couldn\'t look up public key for decryption.';
+ $template->footer();
+ return false;
+ }
+ $crypt_key = hexdecode($crypt_key);
+ $data = $aes->decrypt($_POST['crypt_data'], $crypt_key, ENC_HEX);
+ if(strlen($data) < 6)
+ {
+ echo 'ERROR: Your password must be six characters or greater in length.';
+ $template->footer();
+ return false;
+ }
+ }
+ else
+ {
+ $data = $_POST['pass'];
+ $conf = $_POST['pass_confirm'];
+ if($data != $conf)
+ {
+ echo 'ERROR: The passwords you entered do not match.';
+ $template->footer();
+ return false;
+ }
+ if(strlen($data) < 6)
+ {
+ echo 'ERROR: Your password must be six characters or greater in length.';
+ $template->footer();
+ return false;
+ }
+ }
+ if(empty($data))
+ {
+ echo 'ERROR: Sanity check failed!';
+ $template->footer();
+ return false;
+ }
+ $encpass = $aes->encrypt($data, $session->private_key, ENC_HEX);
+ $q = $db->sql_query('UPDATE '.table_prefix.'users SET password=\'' . $encpass . '\',temp_password=\'\',temp_password_time=0 WHERE user_id='.$user_id.';');
+
+ if($q)
+ {
+ $session->login_without_crypto($row['username'], $data);
+ echo '<p>Your password has been reset. Return to the <a href="' . makeUrl(getConfig('main_page')) . '">main page</a>.</p>';
+ }
+ else
+ {
+ echo $db->get_error();
+ }
+
+ $template->footer();
+ return false;
+ }
+
+ // Password reset form
+ $pubkey = $session->rijndael_genkey();
+
+ ?>
+ <form action="<?php echo makeUrl($paths->fullpage); ?>" method="post" name="resetform" onsubmit="return runEncryption();">
+ <br />
+ <div class="tblholder">
+ <table border="0" style="width: 100%;" cellspacing="1" cellpadding="4">
+ <tr><th colspan="2">Reset password</th></tr>
+ <tr><td class="row1">Password:</td><td class="row1"><input name="pass" type="password" /></td></tr>
+ <tr><td class="row2">Confirm: </td><td class="row2"><input name="pass_confirm" type="password" /></td></tr>
+ <tr>
+ <td colspan="2" class="row1" style="text-align: center;">
+ <input type="hidden" name="use_crypt" value="no" />
+ <input type="hidden" name="crypt_key" value="<?php echo $pubkey; ?>" />
+ <input type="hidden" name="crypt_data" value="" />
+ <input type="submit" name="do_stage2" value="Reset password" />
+ </td>
+ </tr>
+ </table>
+ </div>
+ </form>
+ <script type="text/javascript">
+ disableJSONExts();
+ str = '';
+ for(i=0;i<keySizeInBits/4;i++) str+='0';
+ var key = hexToByteArray(str);
+ var pt = hexToByteArray(str);
+ var ct = rijndaelEncrypt(pt, key, "ECB");
+ var ct = byteArrayToHex(ct);
+ switch(keySizeInBits)
+ {
+ case 128:
+ v = '66e94bd4ef8a2c3b884cfa59ca342b2e';
+ break;
+ case 192:
+ v = 'aae06992acbf52a3e8f4a96ec9300bd7aae06992acbf52a3e8f4a96ec9300bd7';
+ break;
+ case 256:
+ v = 'dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a21492842087';
+ break;
+ }
+ var testpassed = ( ct == v && md5_vm_test() );
+ var frm = document.forms.resetform;
+ if(testpassed)
+ {
+ frm.use_crypt.value = 'yes';
+ var cryptkey = frm.crypt_key.value;
+ frm.crypt_key.value = hex_md5(cryptkey);
+ cryptkey = hexToByteArray(cryptkey);
+ if(!cryptkey || ( ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ) && cryptkey.length != keySizeInBits / 8 )
+ {
+ frm._login.disabled = true;
+ len = ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ? '\nLen: '+cryptkey.length : '';
+ alert('The key is messed up\nType: '+typeof(cryptkey)+len);
+ }
+ }
+ function runEncryption()
+ {
+ pass1 = frm.pass.value;
+ pass2 = frm.pass_confirm.value;
+ if ( pass1 != pass2 )
+ {
+ alert('The passwords you entered do not match.');
+ return false;
+ }
+ if ( pass1.length < 6 )
+ {
+ alert('The new password must be 6 characters or greater in length.');
+ return false;
+ }
+ if(testpassed)
+ {
+ pass = frm.pass.value;
+ pass = stringToByteArray(pass);
+ cryptstring = rijndaelEncrypt(pass, cryptkey, 'ECB');
+ if(!cryptstring)
+ {
+ return false;
+ }
+ cryptstring = byteArrayToHex(cryptstring);
+ frm.crypt_data.value = cryptstring;
+ frm.pass.value = "";
+ frm.pass_confirm.value = "";
+ }
+ return true;
+ }
+ </script>
+ <?php
+ $template->footer();
+ return true;
+ }
+ if(isset($_POST['do_reset']))
+ {
+ if($session->mail_password_reset($_POST['username']))
+ {
+ echo '<p>An e-mail has been sent to the e-mail address on file for your username with a new password in it. Please check your e-mail for further instructions.</p>';
+ }
+ else
+ {
+ echo '<p>Error occured, your new password was not sent.</p>';
+ }
+ $template->footer();
+ return true;
+ }
+ echo '<p>Don\'t worry, it happens to the best of us.</p>
+ <p>To reset your password, just enter your username below, and a new password will be e-mailed to you.</p>
+ <form action="'.makeUrl($paths->page).'" method="post" onsubmit="if(!submitAuthorized) return false;">
+ <p>Username: '.$template->username_field('username').'</p>
+ <p><input type="submit" name="do_reset" value="Mail new password" /></p>
+ </form>';
+ $template->footer();
+}
+
+?>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/SpecialUserFuncs.php~ Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,856 @@
+<?php
+/*
+Plugin Name: Special user/login-related pages
+Plugin URI: http://enano.homelinux.org/
+Description: Provides the pages Special:Login, Special:Logout, Special:Register, and Special:Preferences.
+Author: Dan Fuhry
+Version: 1.0
+Author URI: http://enano.homelinux.org/
+*/
+
+/*
+ * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
+ * Version 1.0 release candidate 2
+ * Copyright (C) 2006-2007 Dan Fuhry
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+global $db, $session, $paths, $template, $plugins; // Common objects
+
+$plugins->attachHook('base_classes_initted', '
+ global $paths;
+ $paths->add_page(Array(
+ \'name\'=>\'Log in\',
+ \'urlname\'=>\'Login\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ $paths->add_page(Array(
+ \'name\'=>\'Log out\',
+ \'urlname\'=>\'Logout\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ $paths->add_page(Array(
+ \'name\'=>\'Register\',
+ \'urlname\'=>\'Register\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ $paths->add_page(Array(
+ \'name\'=>\'Edit Profile\',
+ \'urlname\'=>\'Preferences\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'Contributions\',
+ \'urlname\'=>\'Contributions\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'Change style\',
+ \'urlname\'=>\'ChangeStyle\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'Activate user account\',
+ \'urlname\'=>\'ActivateAccount\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'Captcha\',
+ \'urlname\'=>\'Captcha\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+
+ $paths->add_page(Array(
+ \'name\'=>\'Forgot password\',
+ \'urlname\'=>\'PasswordReset\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
+ ');
+
+// function names are IMPORTANT!!! The name pattern is: page_<namespace ID>_<page URLname, without namespace>
+
+$__login_status = '';
+
+function page_Special_Login()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $__login_status;
+
+ $pubkey = $session->rijndael_genkey();
+ $challenge = $session->dss_rand();
+
+ if ( isset($_GET['act']) && $_GET['act'] == 'getkey' )
+ {
+ $response = Array(
+ 'key' => $pubkey,
+ 'challenge' => $challenge
+ );
+ $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
+ $response = $json->encode($response);
+ echo $response;
+ return null;
+ }
+
+ $level = ( isset($_GET['level']) && in_array($_GET['level'], array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') ) ) ? intval($_GET['level']) : USER_LEVEL_MEMBER;
+ if ( isset($_POST['login']) )
+ {
+ if ( in_array($_POST['auth_level'], array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') ) )
+ {
+ $level = intval($_POST['auth_level']);
+ }
+ }
+
+ if ( $level > USER_LEVEL_MEMBER && !$session->user_logged_in )
+ {
+ $level = USER_LEVEL_MEMBER;
+ }
+ $template->header();
+ echo '<form action="'.makeUrl($paths->nslist['Special'].'Login').'" method="post" name="loginform" onsubmit="runEncryption();">';
+ $header = ( $level > USER_LEVEL_MEMBER ) ? 'Please re-enter your login details' : 'Please enter your username and password to log in.';
+ if ( isset($_POST['login']) )
+ {
+ echo '<p>'.$__login_status.'</p>';
+ }
+ if ( $p = $paths->getAllParams() )
+ {
+ echo '<input type="hidden" name="return_to" value="'.$p.'" />';
+ }
+ else if ( isset($_POST['login']) && isset($_POST['return_to']) )
+ {
+ echo '<input type="hidden" name="return_to" value="'.htmlspecialchars($_POST['return_to']).'" />';
+ }
+ ?>
+ <div class="tblholder">
+ <table border="0" style="width: 100%;" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="3"><?php echo $header; ?></th>
+ </tr>
+ <tr>
+ <td colspan="3" class="row1">
+ <?php
+ if ( $level <= USER_LEVEL_MEMBER )
+ {
+ echo '<p>Logging in enables you to use your preferences and access member information. If you don\'t have a username and password here, you can <a href="'.makeUrl($paths->nslist['Special'].'Register').'">create an account</a>.</p>';
+ }
+ else
+ {
+ echo '<p>You are requesting that a sensitive operation be performed. To continue, please re-enter your password to confirm your identity.</p>';
+ }
+ ?>
+ </td>
+ </tr>
+ <tr>
+ <td class="row2">
+ Username:
+ </td>
+ <td class="row1">
+ <input name="username" size="25" type="text" <?php
+ if ( $level <= USER_LEVEL_MEMBER )
+ {
+ echo 'tabindex="1" ';
+ }
+ if ( $session->user_logged_in )
+ {
+ echo 'value="' . $session->username . '"';
+ }
+ ?> />
+ </td>
+ <?php if ( $level <= USER_LEVEL_MEMBER ) { ?>
+ <td rowspan="2" class="row3">
+ <small>Forgot your password? <a href="<?php echo makeUrlNS('Special', 'PasswordReset'); ?>">No problem.</a><br />
+ Maybe you need to <a href="<?php echo makeUrlNS('Special', 'Register'); ?>">create an account</a>.</small>
+ </td>
+ <?php } ?>
+ </tr>
+ <tr>
+ <td class="row2">Password:<br /></td><td class="row1"><input name="pass" size="25" type="password" tabindex="<?php echo ( $level <= USER_LEVEL_MEMBER ) ? '2' : '1'; ?>" /></td>
+ </tr>
+ <?php if ( $level <= USER_LEVEL_MEMBER ) { ?>
+ <tr>
+ <td class="row3" colspan="3">
+ <p><b>Important note regarding cryptography:</b> Some countries do not allow the import or use of cryptographic technology. If you live in one of the countries listed below, you should <a href="<?php if($p=$paths->getParam(0))$u='/'.$p;else $u='';echo makeUrl($paths->page.$u, 'level='.$level.'&use_crypt=0', true); ?>">log in without using encryption</a>.</p>
+ <p>This restriction applies to the following countries: Belarus, China, India, Israel, Kazakhstan, Mongolia, Pakistan, Russia, Saudi Arabia, Singapore, Tunisia, Venezuela, and Vietnam.</p>
+ </td>
+ </tr>
+ <?php } ?>
+ <tr>
+ <th colspan="3" style="text-align: center" class="subhead"><input type="submit" name="login" value="Log in" tabindex="3" /></th>
+ </tr>
+ </table>
+ </div>
+ <input type="hidden" name="challenge_data" value="<?php echo $challenge; ?>" />
+ <input type="hidden" name="use_crypt" value="no" />
+ <input type="hidden" name="crypt_key" value="<?php echo $pubkey; ?>" />
+ <input type="hidden" name="crypt_data" value="" />
+ <input type="hidden" name="auth_level" value="<?php echo (string)$level; ?>" />
+ </form>
+ <?php
+ echo $session->aes_javascript('loginform', 'pass', 'use_crypt', 'crypt_key', 'crypt_data', 'challenge_data');
+ ?>
+ <?php
+ $template->footer();
+}
+
+function page_Special_Login_preloader() // adding _preloader to the end of the function name calls the function before $session and $paths setup routines are called
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $__login_status;
+ if ( isset($_GET['act']) && $_GET['act'] == 'ajaxlogin' )
+ {
+ $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
+ $data = $json->decode($_POST['params']);
+ $level = ( isset($data['level']) ) ? intval($data['level']) : USER_LEVEL_MEMBER;
+ $result = $session->login_with_crypto($data['username'], $data['crypt_data'], $data['crypt_key'], $data['challenge'], $level);
+ $session->start();
+ //echo "$result\n$session->sid_super";
+ //exit;
+ if ( $result == 'success' )
+ {
+ $response = Array(
+ 'result' => 'success',
+ 'key' => $session->sid_super // ( ( $session->sid_super ) ? $session->sid_super : $session->sid )
+ );
+ }
+ else
+ {
+ $response = Array(
+ 'result' => 'error',
+ 'error' => $result
+ );
+ }
+ $response = $json->encode($response);
+ echo $response;
+ $db->close();
+ exit;
+ }
+ if(isset($_POST['login'])) {
+ if($_POST['use_crypt'] == 'yes')
+ {
+ $result = $session->login_with_crypto($_POST['username'], $_POST['crypt_data'], $_POST['crypt_key'], $_POST['challenge_data'], intval($_POST['auth_level']));
+ }
+ else
+ {
+ $result = $session->login_without_crypto($_POST['username'], $_POST['pass'], false, intval($_POST['auth_level']));
+ }
+ $session->start();
+ $paths->init();
+ if($result == 'success')
+ {
+ $template->load_theme($session->theme, $session->style);
+ if(isset($_POST['return_to']))
+ {
+ $name = ( isset($paths->pages[$_POST['return_to']]['name']) ) ? $paths->pages[$_POST['return_to']]['name'] : $_POST['return_to'];
+ redirect( makeUrl($_POST['return_to']), 'Login successful', 'You have successfully logged into the '.getConfig('site_name').' site as "'.$session->username.'". Redirecting to ' . $name . '...' );
+ }
+ else
+ {
+ $paths->main_page();
+ }
+ }
+ else
+ {
+ $GLOBALS['__login_status'] = $result;
+ }
+ }
+}
+
+function page_Special_Logout() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $l = $session->logout();
+ if($l == 'success') $paths->main_page();
+ $template->header();
+ echo '<h3>An error occurred during the logout process.</h3><p>'.$l.'</p>';
+ $template->footer();
+}
+
+function page_Special_Register() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if(getConfig('account_activation') == 'disable' && ( ( $session->user_level >= USER_LEVEL_ADMIN && !isset($_GET['IWannaPlayToo']) ) || $session->user_level < USER_LEVEL_ADMIN || !$session->user_logged_in ))
+ {
+ $s = ($session->user_level >= USER_LEVEL_ADMIN) ? '<p>Oops...it seems that you <em>are</em> the administrator...hehe...you can also <a href="'.makeUrl($paths->page, 'IWannaPlayToo', true).'">force account registration to work</a>.</p>' : '';
+ die_friendly('Registration disabled', '<p>The administrator has disabled new user registration on this site.</p>' . $s);
+ }
+ if(isset($_POST['submit'])) {
+ $captcharesult = $session->get_captcha($_POST['captchahash']);
+ if($captcharesult != $_POST['captchacode'])
+ $s = 'The confirmation code you entered was incorrect.';
+ else
+ // CAPTCHA code was correct, create the account
+ $s = $session->create_user($_POST['username'], $_POST['password'], $_POST['email'], $_POST['real_name']);
+ if($s == 'success')
+ {
+ switch(getConfig('account_activation'))
+ {
+ case "none":
+ default:
+ $str = 'You may now <a href="'.makeUrlNS('Special', 'Login').'">log in</a> with the username and password that you created.';
+ break;
+ case "user":
+ $str = 'Because this site requires account activation, you have been sent an e-mail with further instructions. Please follow the instructions in that e-mail to continue your registration.';
+ break;
+ case "admin":
+ $str = 'Because this site requires administrative account activation, you cannot use your account at the moment. A notice has been sent to the site administration team that will alert them that your account has been created.';
+ break;
+ }
+ die_friendly('Registration successful', '<p>Thank you for registering, your user account has been created. '.$str.'</p>');
+ }
+ }
+ $template->header();
+ echo 'A user account enables you to have greater control over your browsing experience.';
+ $session->kill_captcha();
+ $captchacode = $session->make_captcha();
+ ?>
+ <h3>Create a user account</h3>
+ <form name="regform" action="<?php echo makeUrl($paths->page); ?>" method="post">
+ <div class="tblholder">
+ <table border="0" width="100%" cellspacing="1" cellpadding="4">
+ <tr><th class="subhead" colspan="3">Please tell us a little bit about yourself.</th></tr>
+ <?php if(isset($_POST['submit'])) echo '<tr><td colspan="3" class="row2" style="color: red;">'.$s.'</td></tr>'; ?>
+ <tr><td class="row1" style="width: 50%;">Preferred username:<span id="e_username"></span></td><td class="row1" style="width: 50%;"><input type="text" name="username" size="30" onkeyup="namegood = false; validateForm();" onblur="checkUsername();" /></td><td class="row1" style="max-width: 24px;"><img alt="Good/bad icon" src="<?php echo scriptPath; ?>/images/bad.gif" id="s_username" /></td></tr>
+ <tr><td class="row3" style="width: 50%;" rowspan="2">Password:<span id="e_password"></span></td><td class="row3" style="width: 50%;"><input type="password" name="password" size="30" onkeyup="validateForm();" /></td><td rowspan="2" class="row3" style="max-width: 24px;"><img alt="Good/bad icon" src="<?php echo scriptPath; ?>/images/bad.gif" id="s_password" /></td></tr>
+ <tr><td class="row3" style="width: 50%;"><input type="password" name="password_confirm" size="30" onkeyup="validateForm();" /> <small>Enter your password again to confirm.</small></td></tr>
+ <tr><td class="row1" style="width: 50%;">E-mail address:<?php if(getConfig('account_activation')=='user') echo '<br /><small>An e-mail with an account activation key will be sent to this address, so please ensure that it is correct.</small></td>'; ?><td class="row1" style="width: 50%;"><input type="text" name="email" size="30" onkeyup="validateForm();" /></td><td class="row1" style="max-width: 24px;"><img alt="Good/bad icon" src="<?php echo scriptPath; ?>/images/bad.gif" id="s_email" /></td></tr>
+ <tr><td class="row3" style="width: 50%;">Real name:<br /><small>Giving your real name is totally optional. If you choose to provide your real name, it will be used to provide attribution for any edits or contributions you may make to this site.</small><td class="row3" style="width: 50%;"><input type="text" name="real_name" size="30" /></td><td class="row3" style="max-width: 24px;"></td></tr>
+ <tr><td class="row1" style="width: 50%;" rowspan="2">Visual confirmation<br /><small>Please enter the code shown in the image to the right into the text box. This process helps to ensure that this registration is not being performed by an automated bot. If the image to the right is illegible, you can <a href="#" onclick="regenCaptcha(); return false;">generate a new image</a>.<br /><br />If you are visually impaired or otherwise cannot read the text shown to the right, please contact the site management and they will create an account for you.</small></td><td colspan="2" class="row1"><img id="captchaimg" alt="CAPTCHA image" src="<?php echo makeUrlNS('Special', 'Captcha/'.$captchacode); ?>" /><span id="b_username"></span></td></tr>
+ <tr><td class="row1" colspan="2">Code: <input name="captchacode" type="text" size="10" /><input type="hidden" name="captchahash" value="<?php echo $captchacode; ?>" /></td></tr>
+ <tr><td class="row2" colspan="3" style="text-align: center;"><input type="submit" name="submit" value="Create my account" /></td></tr>
+ </table>
+ </div>
+ </form>
+ <script type="text/javascript">
+ // <![CDATA[
+ var namegood = false;
+ function validateForm()
+ {
+ var frm = document.forms.regform;
+ failed = false;
+
+ // Username
+ if(!namegood)
+ {
+ if(frm.username.value.match(/^([A-z0-9 \!@\-\(\)]+){2,}$/ig))
+ {
+ document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/unknown.gif';
+ document.getElementById('e_username').innerHTML = ''; // '<br /><small><b>Checking availability...</b></small>';
+ } else {
+ failed = true;
+ document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/bad.gif';
+ document.getElementById('e_username').innerHTML = '<br /><small>Your username must be at least two characters in length and may contain only alphanumeric characters (A-Z and 0-9), spaces, and the following characters: :, !, @, #, *.</small>';
+ }
+ }
+ document.getElementById('b_username').innerHTML = '';
+ if(hex_md5(frm.real_name.value) == 'fa8e397ae0f6cd5b0f90a3f48178cd7e')
+ {
+ document.getElementById('b_username').innerHTML = '<br /><br />Hey...I know you!<br /><img alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Bill_Gates_2004_cr.jpg/220px-Bill_Gates_2004_cr.jpg" />';
+ }
+
+ // Password
+ if(frm.password.value.match(/^(.+){6,}$/ig) && frm.password_confirm.value.match(/^(.+){6,}$/ig) && frm.password.value == frm.password_confirm.value)
+ {
+ document.getElementById('s_password').src='<?php echo scriptPath; ?>/images/good.gif';
+ document.getElementById('e_password').innerHTML = '<br /><small>The password you entered is valid.</small>';
+ } else {
+ failed = true;
+ if(frm.password.value.length < 6)
+ document.getElementById('e_password').innerHTML = '<br /><small>Your password must be at least six characters in length.</small>';
+ else if(frm.password.value != frm.password_confirm.value)
+ document.getElementById('e_password').innerHTML = '<br /><small>The passwords you entered do not match.</small>';
+ else
+ document.getElementById('e_password').innerHTML = '';
+ document.getElementById('s_password').src='<?php echo scriptPath; ?>/images/bad.gif';
+ }
+
+ // E-mail address
+ if(frm.email.value.match(/^(?:[\w\d]+\.?)+@(?:(?:[\w\d]\-?)+\.)+\w{2,4}$/))
+ {
+ document.getElementById('s_email').src='<?php echo scriptPath; ?>/images/good.gif';
+ } else {
+ failed = true;
+ document.getElementById('s_email').src='<?php echo scriptPath; ?>/images/bad.gif';
+ }
+ if(failed)
+ {
+ frm.submit.disabled = 'disabled';
+ } else {
+ frm.submit.disabled = false;
+ }
+ }
+ function checkUsername()
+ {
+ var frm = document.forms.regform;
+
+ if(!namegood)
+ {
+ if(frm.username.value.match(/^([A-z0-9 \.:\!@\#\*]+){2,}$/ig))
+ {
+ document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/unknown.gif';
+ document.getElementById('e_username').innerHTML = '';
+ } else {
+ document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/bad.gif';
+ document.getElementById('e_username').innerHTML = '<br /><small>Your username must be at least two characters in length and may contain only alphanumeric characters (A-Z and 0-9), spaces, and the following characters: :, !, @, #, *.</small>';
+ return false;
+ }
+ }
+
+ document.getElementById('e_username').innerHTML = '<br /><small><b>Checking availability...</b></small>';
+ ajaxGet('<?php echo scriptPath; ?>/ajax.php?title=null&_mode=checkusername&name='+escape(frm.username.value), function() {
+ if(ajax.readyState == 4)
+ if(ajax.responseText == 'good')
+ {
+ document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/good.gif';
+ document.getElementById('e_username').innerHTML = '<br /><small><b>This username is available.</b></small>';
+ namegood = true;
+ } else if(ajax.responseText == 'bad') {
+ document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/bad.gif';
+ document.getElementById('e_username').innerHTML = '<br /><small><b>Error: that username is already taken.</b></small>';
+ namegood = false;
+ } else {
+ document.getElementById('e_username').innerHTML = ajax.responseText;
+ }
+ });
+ }
+ function regenCaptcha()
+ {
+ var frm = document.forms.regform;
+ document.getElementById('captchaimg').src = '<?php echo makeUrlNS("Special", "Captcha/"); ?>'+frm.captchahash.value+'/'+Math.floor(Math.random() * 100000);
+ return false;
+ }
+ validateForm();
+ setTimeout('checkUsername();', 1000);
+ // ]]>
+ </script>
+ <?php
+ $template->footer();
+}
+
+/*
+If you want the old preferences page back, be my guest.
+function page_Special_Preferences() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $template->header();
+ if(isset($_POST['submit'])) {
+ $data = $session->update_user($session->user_id, $_POST['username'], $_POST['current_pass'], $_POST['new_pass'], $_POST['email'], $_POST['real_name'], $_POST['sig']);
+ if($data == 'success') echo '<h3>Information</h3><p>Your profile has been updated. <a href="'.scriptPath.'/">Return to the index page</a>.</p>';
+ else echo $data;
+ } else {
+ echo '
+ <h3>Edit your profile</h3>
+ <form action="'.makeUrl($paths->nslist['Special'].'Preferences').'" method="post">
+ <table border="0" style="margin-left: 0.2in;">
+ <tr><td>Username:</td><td><input type="text" name="username" value="'.$session->username.'" /></td></tr>
+ <tr><td>Current Password:</td><td><input type="password" name="current_pass" /></td></tr>
+ <tr><td colspan="2"><small>You only need to enter your current password if you are changing your e-mail address or changing your password.</small></td></tr>
+ <tr><td>New Password:</td><td><input type="password" name="new_pass" /></td></tr>
+ <tr><td>E-mail:</td><td><input type="text" name="email" value="'.$session->email.'" /></td></tr>
+ <tr><td>Real Name:</td><td><input type="text" name="real_name" value="'.$session->real_name.'" /></td></tr>
+ <tr><td>Signature:<br /><small>Your signature appears<br />below your comment posts.</small></td><td><textarea rows="10" cols="40" name="sig">'.$session->signature.'</textarea></td></tr>
+ <tr><td colspan="2">
+ <input type="submit" name="submit" value="Save Changes" /></td></tr>
+ </table>
+ </form>
+ ';
+ }
+ $template->footer();
+}
+*/
+
+function page_Special_Contributions() {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $template->header();
+ $user = $paths->getParam();
+ if(!$user && isset($_GET['user']))
+ {
+ $user = $_GET['user'];
+ }
+ elseif(!$user && !isset($_GET['user']))
+ {
+ echo 'No user selected!';
+ $template->footer();
+ $db->close();
+ exit;
+ }
+
+ $user = $db->escape($user);
+
+ $q = 'SELECT time_id,date_string,page_id,namespace,author,edit_summary,minor_edit,page_id,namespace FROM '.table_prefix.'logs WHERE author=\''.$user.'\' AND action=\'edit\' ORDER BY time_id DESC;';
+ if(!$db->sql_query($q)) $db->_die('The history data for the page "'.$paths->cpage['name'].'" could not be selected.');
+ echo 'History of edits and actions<h3>Edits:</h3>';
+ if($db->numrows() < 1) echo 'No history entries in this category.';
+ while($r = $db->fetchrow()) {
+ echo '<a href="#" onclick="ajaxHistView(\''.$r['time_id'].'\', \''.$paths->nslist[$r['namespace']].$r['page_id'].'\'); return false;"><i>'.$r['date_string'].'</i></a> (<a href="#" onclick="ajaxRollback(\''.$r['time_id'].'\'); return false;">revert</a>) <a href="'.makeUrl($paths->nslist[$r['namespace']].$r['page_id']).'">'.$paths->nslist[$r['namespace']].$r['page_id'].'</a>: '.$r['edit_summary'];
+ if($r['minor_edit']) echo '<b> - minor edit</b>';
+ echo '<br />';
+ }
+ $db->free_result();
+ echo '<h3>Other changes:</h3>';
+ $q = 'SELECT log_type,time_id,action,date_string,page_id,namespace,author,edit_summary,minor_edit,page_id,namespace FROM '.table_prefix.'logs WHERE author=\''.$user.'\' AND action!=\'edit\' ORDER BY time_id DESC;';
+ if(!$db->sql_query($q)) $db->_die('The history data for the page "'.$paths->cpage['name'].'" could not be selected.');
+ if($db->numrows() < 1) echo 'No history entries in this category.';
+ while($r = $db->fetchrow()) {
+ if($r['log_type']=='page') {
+ echo '(<a href="#" onclick="ajaxRollback(\''.$r['time_id'].'\'); return false;">rollback</a>) <i>'.$r['date_string'].'</i> <a href="'.makeUrl($paths->nslist[$r['namespace']].$r['page_id']).'">'.$paths->nslist[$r['namespace']].$r['page_id'].'</a>: ';
+ if($r['action']=='prot') echo 'Protected page; reason: '.$r['edit_summary'];
+ elseif($r['action']=='unprot') echo 'Unprotected page; reason: '.$r['edit_summary'];
+ elseif($r['action']=='rename') echo 'Renamed page; old title was: '.$r['edit_summary'];
+ elseif($r['action']=='create') echo 'Created page';
+ elseif($r['action']=='delete') echo 'Deleted page';
+ if($r['minor_edit']) echo '<b> - minor edit</b>';
+ echo '<br />';
+ } elseif($r['log_type']=='security') {
+ // Not implemented, and when it is, it won't be public
+ }
+ }
+ $db->free_result();
+ $template->footer();
+}
+
+function page_Special_ChangeStyle()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if(!$session->user_logged_in) die_friendly('Access denied', '<p>You must be logged in to change your style. Spoofer.</p>');
+ if(isset($_POST['theme']) && isset($_POST['style']) && isset($_POST['return_to']))
+ {
+ $d = ENANO_ROOT . '/themes/' . $_POST['theme'];
+ $f = ENANO_ROOT . '/themes/' . $_POST['theme'] . '/css/' . $_POST['style'] . '.css';
+ if(!file_exists($d) || !is_dir($d)) die('The directory "'.$d.'" does not exist.');
+ if(!file_exists($f)) die('The file "'.$f.'" does not exist.');
+ $d = $db->escape($_POST['theme']);
+ $f = $db->escape($_POST['style']);
+ $q = 'UPDATE '.table_prefix.'users SET theme=\''.$d.'\',style=\''.$f.'\' WHERE username=\''.$session->username.'\'';
+ if(!$db->sql_query($q))
+ {
+ $db->_die('Your theme/style preferences were not updated.');
+ }
+ else
+ {
+ redirect(makeUrl($_POST['return_to']), '', '', 0);
+ }
+ }
+ else
+ {
+ $template->header();
+ $ret = ( isset($_POST['return_to']) ) ? $_POST['return_to'] : $paths->getParam(0);
+ if(!$ret) $ret = getConfig('main_page');
+ ?>
+ <form action="<?php echo makeUrl($paths->page); ?>" method="post">
+ <?php if(!isset($_POST['themeselected'])) { ?>
+ <h3>Please select a new theme:</h3>
+ <p>
+ <select name="theme">
+ <?php
+ foreach($template->theme_list as $t) {
+ if($t['enabled'])
+ {
+ echo '<option value="'.$t['theme_id'].'"';
+ if($t['theme_id'] == $session->theme) echo ' selected="selected"';
+ echo '>'.$t['theme_name'].'</option>';
+ }
+ }
+ ?>
+ </select>
+ </p>
+ <p><input type="hidden" name="return_to" value="<?php echo $ret; ?>" />
+ <input type="submit" name="themeselected" value="Continue" /></p>
+ <?php } else {
+ $theme = $_POST['theme'];
+ if ( !preg_match('/^([0-9A-z_-]+)$/i', $theme ) )
+ die('Hacking attempt');
+ ?>
+ <h3>Please select a stylesheet:</h3>
+ <p>
+ <select name="style">
+ <?php
+ $dir = './themes/'.$theme.'/css/';
+ $list = Array();
+ // Open a known directory, and proceed to read its contents
+ if (is_dir($dir)) {
+ if ($dh = opendir($dir)) {
+ while (($file = readdir($dh)) !== false) {
+ if(preg_match('#^(.*?)\.css$#is', $file) && $file != '_printable.css') {
+ $list[] = substr($file, 0, strlen($file)-4);
+ }
+ }
+ closedir($dh);
+ }
+ } else die($dir.' is not a dir');
+ foreach ( $list as $l )
+ {
+ echo '<option value="'.$l.'">'.capitalize_first_letter($l).'</option>';
+ }
+ ?>
+ </select>
+ </p>
+ <p><input type="hidden" name="return_to" value="<?php echo $ret; ?>" />
+ <input type="hidden" name="theme" value="<?php echo $theme; ?>" />
+ <input type="submit" name="allclear" value="Change style" /></p>
+ <?php } ?>
+ </form>
+ <?php
+ $template->footer();
+ }
+}
+
+function page_Special_ActivateAccount()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $user = $paths->getParam(0);
+ if(!$user) die_friendly('Account activation error', '<p>The URL was incorrect.</p>');
+ $key = $paths->getParam(1);
+ if(!$key) die_friendly('Account activation error', '<p>The URL was incorrect.</p>');
+ $s = $session->activate_account(str_replace('_', ' ', $user), $key);
+ if($s > 0) die_friendly('Activation successful', '<p>Your account is now active. Thank you for registering.</p>');
+ else die_friendly('Activation failed', '<p>The activation key was probably incorrect.</p>');
+}
+
+function page_Special_Captcha()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if($paths->getParam(0) == 'make')
+ {
+ $session->kill_captcha();
+ echo $session->make_captcha();
+ return;
+ }
+ $hash = $paths->getParam(0);
+ if(!$hash || !preg_match('#^([0-9a-f]*){32,32}$#i', $hash)) $paths->main_page();
+ $code = $session->get_captcha($hash);
+ if(!$code) die('Invalid hash or IP address incorrect.');
+ require(ENANO_ROOT.'/includes/captcha.php');
+ $captcha = new captcha($code);
+ //header('Content-disposition: attachment; filename=autocaptcha.png');
+ $captcha->make_image();
+ exit;
+}
+
+function page_Special_PasswordReset()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $template->header();
+ if($paths->getParam(0) == 'stage2')
+ {
+ $user_id = intval($paths->getParam(1));
+ $encpass = $paths->getParam(2);
+ if ( $user_id < 2 )
+ {
+ echo '<p>Hacking attempt</p>';
+ $template->footer();
+ return false;
+ }
+ if(!preg_match('#^([a-f0-9]+)$#i', $encpass))
+ {
+ echo '<p>Hacking attempt</p>';
+ $template->footer();
+ return false;
+ }
+
+ $q = $db->sql_query('SELECT username,temp_password_time FROM '.table_prefix.'users WHERE user_id='.$user_id.' AND temp_password=\'' . $encpass . '\';');
+ if($db->numrows() < 1)
+ {
+ echo '<p>Invalid credentials</p>';
+ $template->footer();
+ return false;
+ }
+ $row = $db->fetchrow();
+ $db->free_result();
+
+ if ( ( intval($row['temp_password_time']) + 3600 * 24 ) < time() )
+ {
+ echo '<p>Password has expired</p>';
+ $template->footer();
+ return false;
+ }
+
+ if ( isset($_POST['do_stage2']) )
+ {
+ $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE);
+ if($_POST['use_crypt'] == 'yes')
+ {
+ $crypt_key = $session->fetch_public_key($_POST['crypt_key']);
+ if(!$crypt_key)
+ {
+ echo 'ERROR: Couldn\'t look up public key for decryption.';
+ $template->footer();
+ return false;
+ }
+ $crypt_key = hexdecode($crypt_key);
+ $data = $aes->decrypt($_POST['crypt_data'], $crypt_key, ENC_HEX);
+ if(strlen($data) < 6)
+ {
+ echo 'ERROR: Your password must be six characters or greater in length.';
+ $template->footer();
+ return false;
+ }
+ }
+ else
+ {
+ $data = $_POST['pass'];
+ $conf = $_POST['pass_confirm'];
+ if($data != $conf)
+ {
+ echo 'ERROR: The passwords you entered do not match.';
+ $template->footer();
+ return false;
+ }
+ if(strlen($data) < 6)
+ {
+ echo 'ERROR: Your password must be six characters or greater in length.';
+ $template->footer();
+ return false;
+ }
+ }
+ if(empty($data))
+ {
+ echo 'ERROR: Sanity check failed!';
+ $template->footer();
+ return false;
+ }
+ $encpass = $aes->encrypt($data, $session->private_key, ENC_HEX);
+ $q = $db->sql_query('UPDATE '.table_prefix.'users SET password=\'' . $encpass . '\',temp_password=\'\',temp_password_time=0 WHERE user_id='.$user_id.';');
+
+ if($q)
+ {
+ $session->login_without_crypto($row['username'], $data);
+ echo '<p>Your password has been reset. Return to the <a href="' . makeUrl(getConfig('main_page')) . '">main page</a>.</p>';
+ }
+ else
+ {
+ echo $db->get_error();
+ }
+
+ $template->footer();
+ return false;
+ }
+
+ // Password reset form
+ $pubkey = $session->rijndael_genkey();
+
+ ?>
+ <form action="<?php echo makeUrl($paths->fullpage); ?>" method="post" name="resetform" onsubmit="return runEncryption();">
+ <br />
+ <div class="tblholder">
+ <table border="0" style="width: 100%;" cellspacing="1" cellpadding="4">
+ <tr><th colspan="2">Reset password</th></tr>
+ <tr><td class="row1">Password:</td><td class="row1"><input name="pass" type="password" /></td></tr>
+ <tr><td class="row2">Confirm: </td><td class="row2"><input name="pass_confirm" type="password" /></td></tr>
+ <tr>
+ <td colspan="2" class="row1" style="text-align: center;">
+ <input type="hidden" name="use_crypt" value="no" />
+ <input type="hidden" name="crypt_key" value="<?php echo $pubkey; ?>" />
+ <input type="hidden" name="crypt_data" value="" />
+ <input type="submit" name="do_stage2" value="Reset password" />
+ </td>
+ </tr>
+ </table>
+ </div>
+ </form>
+ <script type="text/javascript">
+ disableJSONExts();
+ str = '';
+ for(i=0;i<keySizeInBits/4;i++) str+='0';
+ var key = hexToByteArray(str);
+ var pt = hexToByteArray(str);
+ var ct = rijndaelEncrypt(pt, key, "ECB");
+ var ct = byteArrayToHex(ct);
+ switch(keySizeInBits)
+ {
+ case 128:
+ v = '66e94bd4ef8a2c3b884cfa59ca342b2e';
+ break;
+ case 192:
+ v = 'aae06992acbf52a3e8f4a96ec9300bd7aae06992acbf52a3e8f4a96ec9300bd7';
+ break;
+ case 256:
+ v = 'dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a21492842087';
+ break;
+ }
+ var testpassed = ( ct == v && md5_vm_test() );
+ var frm = document.forms.resetform;
+ if(testpassed)
+ {
+ frm.use_crypt.value = 'yes';
+ var cryptkey = frm.crypt_key.value;
+ frm.crypt_key.value = hex_md5(cryptkey);
+ cryptkey = hexToByteArray(cryptkey);
+ if(!cryptkey || ( ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ) && cryptkey.length != keySizeInBits / 8 )
+ {
+ frm._login.disabled = true;
+ len = ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ? '\nLen: '+cryptkey.length : '';
+ alert('The key is messed up\nType: '+typeof(cryptkey)+len);
+ }
+ }
+ function runEncryption()
+ {
+ pass1 = frm.pass.value;
+ pass2 = frm.pass_confirm.value;
+ if ( pass1 != pass2 )
+ {
+ alert('The passwords you entered do not match.');
+ return false;
+ }
+ if ( pass1.length < 6 )
+ {
+ alert('The new password must be 6 characters or greater in length.');
+ return false;
+ }
+ if(testpassed)
+ {
+ pass = frm.pass.value;
+ pass = stringToByteArray(pass);
+ cryptstring = rijndaelEncrypt(pass, cryptkey, 'ECB');
+ if(!cryptstring)
+ {
+ return false;
+ }
+ cryptstring = byteArrayToHex(cryptstring);
+ frm.crypt_data.value = cryptstring;
+ frm.pass.value = "";
+ frm.pass_confirm.value = "";
+ }
+ return true;
+ }
+ </script>
+ <?php
+ $template->footer();
+ return true;
+ }
+ if(isset($_POST['do_reset']))
+ {
+ if($session->mail_password_reset($_POST['username']))
+ {
+ echo '<p>An e-mail has been sent to the e-mail address on file for your username with a new password in it. Please check your e-mail for further instructions.</p>';
+ }
+ else
+ {
+ echo '<p>Error occured, your new password was not sent.</p>';
+ }
+ $template->footer();
+ return true;
+ }
+ echo '<p>Don\'t worry, it happens to the best of us.</p>
+ <p>To reset your password, just enter your username below, and a new password will be e-mailed to you.</p>
+ <form action="'.makeUrl($paths->page).'" method="post" onsubmit="if(!submitAuthorized) return false;">
+ <p>Username: '.$template->username_field('username').'</p>
+ <p><input type="submit" name="do_reset" value="Mail new password" /></p>
+ </form>';
+ $template->footer();
+}
+
+?>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/SpecialUserPrefs.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,462 @@
+<?php
+/*
+Plugin Name: User control panel
+Plugin URI: http://www.enanocms.org/
+Description: Provides the page Special:Preferences.
+Author: Dan Fuhry
+Version: 1.0
+Author URI: http://www.enanocms.org/
+*/
+
+/*
+ * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
+ * Version 1.0 release candidate 2
+ * Copyright (C) 2006-2007 Dan Fuhry
+ *
+ * This program is Free Software; you can redistribute it and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+$userprefs_menu = Array();
+$userprefs_menu_links = Array();
+function userprefs_menu_add($section, $text, $link)
+{
+ global $userprefs_menu;
+ if ( is_array($userprefs_menu[$section]) )
+ {
+ $userprefs_menu[$section][] = Array(
+ 'text' => $text,
+ 'link' => $link
+ );
+ }
+ else
+ {
+ $userprefs_menu[$section] = Array(Array(
+ 'text' => $text,
+ 'link' => $link
+ ));
+ }
+}
+
+function userprefs_menu_html()
+{
+ global $userprefs_menu;
+ global $userprefs_menu_links;
+
+ $html = '';
+ $quot = '"';
+
+ foreach ( $userprefs_menu as $section => $buttons )
+ {
+ $html .= ( isset($userprefs_menu_links[$section]) ) ? "<a href={$quot}{$userprefs_menu_links[$section]}{$quot}>{$section}</a>\n " : "<a>{$section}</a>\n ";
+ $html .= "<ul>\n ";
+ foreach ( $buttons as $button )
+ {
+ $html .= " <li><a href={$quot}{$button['link']}{$quot}>{$button['text']}</a></li>\n ";
+ }
+ $html .= "</ul>\n ";
+ }
+
+ return $html;
+}
+
+function userprefs_show_menu()
+{
+ echo '<div class="menu_nojs">
+ ' . userprefs_menu_html() . '
+ <span class="menuclear"></span>
+ </div>
+ <br />
+ ';
+}
+
+function userprefs_menu_init()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $userprefs_menu_links;
+
+ userprefs_menu_add('Profile/membership', 'Edit e-mail address and password', makeUrlNS('Special', 'Preferences/EmailPassword'));
+ userprefs_menu_add('Profile/membership', 'Edit signature', makeUrlNS('Special', 'Preferences/Signature'));
+ userprefs_menu_add('Profile/membership', 'Edit public profile', makeUrlNS('Special', 'Preferences/Profile'));
+ userprefs_menu_add('Private messages', 'Inbox', makeUrlNS('Special', 'PrivateMessages/Folder/Inbox'));
+ userprefs_menu_add('Private messages', 'Outbox', makeUrlNS('Special', 'PrivateMessages/Folder/Outbox'));
+ userprefs_menu_add('Private messages', 'Sent items', makeUrlNS('Special', 'PrivateMessages/Folder/Sent'));
+ userprefs_menu_add('Private messages', 'Drafts', makeUrlNS('Special', 'PrivateMessages/Folder/Drafts'));
+ userprefs_menu_add('Private messages', 'Archive', makeUrlNS('Special', 'PrivateMessages/Folder/Archive'));
+
+ $userprefs_menu_links['Profile/membership'] = makeUrlNS('Special', 'Preferences');
+ $userprefs_menu_links['Private messages'] = makeUrlNS('Special', 'PrivateMessages');
+
+ $code = $plugins->setHook('userprefs_jbox');
+ foreach ( $code as $cmd )
+ {
+ eval($cmd);
+ }
+}
+
+$plugins->attachHook('session_started', 'userprefs_menu_init();');
+
+function page_Special_Preferences()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ // We need a login to continue
+ if ( !$session->user_logged_in )
+ redirect(makeUrlNS('Special', 'Login/' . $paths->page), 'Login required', 'You need to be logged in to access this page. Please wait while you are redirected to the login page.');
+
+ // User ID - later this will be specified on the URL, but hardcoded for now
+ $uid = intval($session->user_id);
+
+ // Instanciate the AES encryptor
+ $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE);
+
+ // Basic user info
+ $q = $db->sql_query('SELECT username, password, email, real_name, signature, theme, style FROM '.table_prefix.'users WHERE user_id='.$uid.';');
+ if ( !$q )
+ $db->_die();
+
+ $row = $db->fetchrow();
+ $db->free_result();
+
+ $section = $paths->getParam(0);
+ if ( !$section )
+ {
+ $section = 'Home';
+ }
+
+ $errors = '';
+
+ switch ( $section )
+ {
+ case 'EmailPassword':
+ // Require elevated privileges (well sortof)
+ if ( $session->auth_level < USER_LEVEL_CHPREF )
+ {
+ redirect(makeUrlNS('Special', 'Login/' . $paths->fullpage, 'level=' . USER_LEVEL_CHPREF, true), 'Authentication required', 'You need to re-authenticate to access this page.', 0);
+ }
+
+ if ( isset($_POST['submit']) )
+ {
+ $email_changed = false;
+ // First do the e-mail address
+ if ( strlen($_POST['newemail']) > 0 )
+ {
+ switch('foo') // Same reason as in the password code...
+ {
+ case 'foo':
+ if ( $_POST['newemail'] != $_POST['newemail_conf'] )
+ {
+ $errors .= '<div class="error-box">The e-mail addresses you entered did not match.</div>';
+ break;
+ }
+ }
+ $q = $db->sql_query('SELECT password FROM '.table_prefix.'users WHERE user_id='.$session->user_id.';');
+ if ( !$q )
+ $db->_die();
+ $row = $db->fetchrow();
+ $db->free_result();
+ $old_pass = $aes->decrypt($row['password'], $session->private_key, ENC_HEX);
+
+ $new_email = $_POST['newemail'];
+
+ $result = $session->update_user($session->user_id, false, $old_pass, false, $new_email);
+ if ( $result != 'success' )
+ {
+ die_friendly('Error updating e-mail address', '<p>Session API returned error: ' . $result . '</p>');
+ }
+ $email_changed = true;
+ }
+ // Obtain password
+ if ( $_POST['use_crypt'] == 'yes' && !empty($_POST['crypt_data']) )
+ {
+ $key = $session->fetch_public_key($_POST['crypt_key']);
+ if ( !$key )
+ die('Can\'t lookup key');
+ $key = hexdecode($key);
+ $newpass = $aes->decrypt($_POST['crypt_data'], $key, ENC_HEX);
+ // At this point we know if we _want_ to change the password...
+
+ // We can't check the password to see if it matches the confirmation
+ // because the confirmation was destroyed during the encryption. I figured
+ // this wasn't a big deal because if the encryption worked, then either
+ // the Javascript validated it or the user hacked the form. In the latter
+ // case, if he's smart enough to hack the encryption code, he's probably
+ // smart enough to remember his password.
+
+ if ( strlen($newpass) > 0 )
+ {
+ // Perform checks
+ if ( strlen($newpass) < 6 )
+ $errors .= '<div class="error-box">Password must be at least 6 characters. You hacked my script, darn you!</div>';
+ // Encrypt new password
+ $newpass_enc = $aes->encrypt($newpass, $session->private_key, ENC_HEX);
+ // Perform the swap
+ $q = $db->sql_query('UPDATE '.table_prefix.'users SET password=\'' . $newpass_enc . '\' WHERE user_id=' . $session->user_id . ';');
+ if ( !$q )
+ $db->_die();
+ // Log out and back in
+ $username = $session->username;
+ $session->logout();
+ if ( $email_changed )
+ {
+ if ( getConfig('account_activation') == 'user' )
+ {
+ redirect(makeUrl(getConfig('main_page')), 'Profile changed', 'Your password and e-mail address have been changed. Since e-mail activation is required on this site, you will need to re-activate your account to continue. An e-mail has been sent to the new e-mail address with an activation link. You must click that link in order to log in again.', 19);
+ }
+ else if ( getConfig('account_activation') == 'admin' )
+ {
+ redirect(makeUrl(getConfig('main_page')), 'Profile changed', 'Your password and e-mail address have been changed. Since administrative activation is requires on this site, a request has been sent to the administrators to activate your account for you. You will not be able to use your account until it is activated by an administrator.', 19);
+ }
+ }
+ $session->login_without_crypto($session->username, $newpass);
+ redirect(makeUrlNS('Special', 'Preferences'), 'Password changed', 'Your password has been changed, and you will now be redirected back to the user control panel.', 4);
+ }
+ }
+ else
+ {
+ switch('foo') // allow breaking out of our section...i can't wait until PHP6 (goto support!)
+ {
+ case 'foo':
+ $pass = $_POST['newpass'];
+ if ( $pass != $_POST['newpass_conf'] )
+ {
+ $errors .= '<div class="error-box">The passwords you entered did not match</div>';
+ break;
+ }
+
+ if ( $email_changed )
+ {
+ if ( getConfig('account_activation') == 'user' )
+ {
+ redirect(makeUrl(getConfig('main_page')), 'Profile changed', 'Your e-mail address has been changed. Since e-mail activation is required on this site, you will need to re-activate your account to continue. An e-mail has been sent to the new e-mail address with an activation link. You must click that link in order to log in again.', 19);
+ }
+ else if ( getConfig('account_activation') == 'admin' )
+ {
+ redirect(makeUrl(getConfig('main_page')), 'Profile changed', 'Your e-mail address has been changed. Since administrative activation is requires on this site, a request has been sent to the administrators to activate your account for you. You will not be able to use your account until it is activated by an administrator.', 19);
+ }
+ else
+ {
+ redirect(makeUrlNS('Special', 'Preferences'), 'Password changed', 'Your e-mail address has been changed, and you will now be redirected back to the user control panel.', 4);
+ }
+ }
+
+ return;
+ }
+ }
+ }
+ $template->tpl_strings['PAGE_NAME'] = 'Change E-mail Address or Password';
+ break;
+ case 'Signature':
+ $template->tpl_strings['PAGE_NAME'] = 'Editing signature';
+ break;
+ case 'Profile':
+ $template->tpl_strings['PAGE_NAME'] = 'Editing public profile';
+ break;
+ }
+
+ $template->header();
+
+ // Output the menu
+ // This is not templatized because it conforms to the jBox menu standard.
+
+ userprefs_show_menu();
+
+ switch ( $section )
+ {
+ case 'Home':
+ global $email;
+ $user_page = '<a href="' . makeUrlNS('User', str_replace(' ', '_', $session->username)) . '">user page</a> <sup>(<a href="' . makeUrlNS('User', str_replace(' ', '_', $session->username)) . '#do:comments">comments</a>)</sup>';
+ $site_admin = $email->encryptEmail(getConfig('contact_email'), '', '', 'administrator');
+ echo "<h3 style='margin-top: 0;'>$session->username, welcome to your control panel</h3>";
+ echo "<p>Here you can make changes to your profile, view statistics on yourself on this site, and set your preferences.</p>
+ <p>If you have not already done so, you are encouraged to make a $user_page and tell the other members of this site a little about yourself.</p>
+ <p>Use the menu at the top to navigate around. If you have any questions, you may contact the $site_admin.";
+ break;
+ case 'EmailPassword':
+
+ echo '<form action="' . makeUrlNS('Special', 'Preferences/EmailPassword') . '" method="post" onsubmit="return runEncryption();" name="empwform" >';
+
+ // Password change form
+ $pubkey = $session->rijndael_genkey();
+
+ echo '<fieldset>
+ <legend>Change password</legend>
+ Type a new password:<br />
+ <input type="password" name="newpass" size="30" tabindex="1" />
+ <br />
+ <br />
+ Type the password again to confirm:<br />
+ <input type="password" name="newpass_conf" size="30" tabindex="2" />
+ </fieldset><br />
+ <fieldset>
+ <legend>Change e-mail address</legend>
+ New e-mail address:<br />
+ <input type="text" name="newemail" size="30" tabindex="3" />
+ <br />
+ <br />
+ Confirm e-mail address:<br />
+ <input type="text" name="newemail_conf" size="30" tabindex="4" />
+ </fieldset>
+ <input type="hidden" name="use_crypt" value="no" />
+ <input type="hidden" name="crypt_key" value="' . $pubkey . '" />
+ <input type="hidden" name="crypt_data" value="" />
+ <br />
+ <div style="text-align: right;"><input type="submit" name="submit" value="Save Changes" tabindex="5" /></div>';
+
+ echo '</form>';
+
+ // ENCRYPTION CODE
+ ?>
+ <script type="text/javascript">
+ disableJSONExts();
+ str = '';
+ for(i=0;i<keySizeInBits/4;i++) str+='0';
+ var key = hexToByteArray(str);
+ var pt = hexToByteArray(str);
+ var ct = rijndaelEncrypt(pt, key, "ECB");
+ var ct = byteArrayToHex(ct);
+ switch(keySizeInBits)
+ {
+ case 128:
+ v = '66e94bd4ef8a2c3b884cfa59ca342b2e';
+ break;
+ case 192:
+ v = 'aae06992acbf52a3e8f4a96ec9300bd7aae06992acbf52a3e8f4a96ec9300bd7';
+ break;
+ case 256:
+ v = 'dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a21492842087';
+ break;
+ }
+ var aes_testpassed = ( ct == v && md5_vm_test() );
+ function runEncryption()
+ {
+ var frm = document.forms.empwform;
+ if ( frm.newpass.value.length < 1 )
+ return true;
+ if(aes_testpassed)
+ {
+ frm.use_crypt.value = 'yes';
+ var cryptkey = frm.crypt_key.value;
+ frm.crypt_key.value = hex_md5(cryptkey);
+ cryptkey = hexToByteArray(cryptkey);
+ if(!cryptkey || ( ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ) && cryptkey.length != keySizeInBits / 8 )
+ {
+ frm.submit.disabled = true;
+ len = ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ? '\nLen: '+cryptkey.length : '';
+ alert('The key is messed up\nType: '+typeof(cryptkey)+len);
+ }
+ }
+ pass1 = frm.newpass.value;
+ pass2 = frm.newpass_conf.value;
+ if ( pass1 != pass2 )
+ {
+ alert('The passwords you entered do not match.');
+ return false;
+ }
+ if ( pass1.length < 6 && pass1.length > 0 )
+ {
+ alert('The new password must be 6 characters or greater in length.');
+ return false;
+ }
+ if(aes_testpassed)
+ {
+ pass = frm.newpass.value;
+ pass = stringToByteArray(pass);
+ cryptstring = rijndaelEncrypt(pass, cryptkey, 'ECB');
+ if(!cryptstring)
+ {
+ return false;
+ }
+ cryptstring = byteArrayToHex(cryptstring);
+ frm.crypt_data.value = cryptstring;
+ frm.newpass.value = "";
+ frm.newpass_conf.value = "";
+ }
+ return true;
+ }
+ </script>
+ <?php
+
+ break;
+ case 'Signature':
+ if ( isset($_POST['new_sig']) )
+ {
+ $sig = $_POST['new_sig'];
+ $sig = RenderMan::preprocess_text($sig, true, false);
+ $sql_sig = $db->escape($sig);
+ $q = $db->sql_query('UPDATE '.table_prefix.'users SET signature=\'' . $sql_sig . '\' WHERE user_id=' . $session->user_id . ';');
+ if ( !$q )
+ $db->_die();
+ $session->signature = $sig;
+ echo '<div class="info-box" style="margin: 0 0 10px 0;">Your signature has been saved.</div>';
+ }
+ echo '<form action="'.makeUrl($paths->fullpage).'" method="post">';
+ echo $template->tinymce_textarea('new_sig', $session->signature);
+ echo '<input type="submit" value="Save signature" />';
+ echo '</form>';
+ break;
+ case "Profile":
+ if ( isset($_POST['submit']) )
+ {
+ $real_name = htmlspecialchars($_POST['real_name']);
+ $real_name = $db->escape($real_name);
+ $q = $db->sql_query('UPDATE '.table_prefix."users SET real_name='$real_name' WHERE user_id=$session->user_id;");
+ if ( !$q )
+ $db->_die();
+
+ echo '<div class="info-box" style="margin: 0 0 10px 0;">Your profile has been updated.</div>';
+ }
+ echo '<form action="'.makeUrl($paths->fullpage).'" method="post">';
+ ?>
+ <div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2">Your public profile</th>
+ </tr>
+ <tr>
+ <td colspan="2" class="row3">Please note that all of the information you enter here will be <b>publicly viewable.</b> All of the fields on this page are optional and may be left blank if you so desire.</td>
+ </tr>
+ <tr>
+ <td class="row2" style="width: 50%;">Real name:</td>
+ <td class="row1" style="width: 50%;"><input type="text" name="real_name" value="<?php echo $session->real_name; ?>" size="30" /></td>
+ </tr>
+ <tr>
+ <td class="row2">Change theme:</td>
+ <td class="row1">If you don't like the look of the site, need a visual break, or are just curious, we might have some different themes for you to try out! <a href="<?php echo makeUrlNS('Special', 'ChangeStyle/' . $paths->page); ?>" onclick="ajaxChangeStyle(); return false;">Change my theme...</a></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="row3"><small>More is coming soon - planned fields include AOL, WLM, Yahoo, and XMPP messenger fields, allow public display of e-mail address, allow private messages from users not on your buddy list, homepage, occupation, and location.</small></td>
+ </tr>
+ <tr>
+ <th class="subhead" colspan="2">
+ <input type="submit" name="submit" value="Save profile" />
+ </th>
+ </tr>
+ </table>
+ </div>
+ <?php
+ echo '</form>';
+ break;
+ default:
+ $good = false;
+ $code = $plugins->setHook('userprefs_body');
+ foreach ( $code as $cmd )
+ {
+ if ( eval($code) )
+ $good = true;
+ }
+ if ( !$good )
+ {
+ echo '<h3>Invalid module</h3>
+ <p>Userprefs module "'.$section.'" not found.</p>';
+ }
+ break;
+ }
+
+ $template->footer();
+}
+
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/WhosOnline.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,145 @@
+<?php
+/*
+Plugin Name: Who's Online
+Plugin URI: javascript: // No URL yet, stay tuned!
+Description: This plugin tracks who is currently online. 3 queries per page request. This plugin works ONLY with MySQL and will likely be difficult to port because it uses unique indices and the REPLACE command.
+Author: Dan Fuhry
+Version: 0.1
+Author URI: http://www.enanocms.org/
+*/
+
+/*
+ * Who's Online plugin for Enano
+ * Version 0.1
+ * Copyright (C) 2007 Dan Fuhry
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+global $whos_online;
+$whos_online = Array('not_yet_initialized');
+
+// First things first - create the table if needed
+$ver = getConfig('whos_online_version');
+if($ver != '0.1')
+{
+ if(!
+ $db->sql_query('DROP TABLE IF EXISTS '.table_prefix.'online;')
+ ) $db->_die('Could not clean out old who\'s-online table');
+ // The key on username allows the REPLACE command later, to save queries
+ if(!$db->sql_query('CREATE TABLE '.table_prefix.'online(
+ entry_id int(12) UNSIGNED NOT NULL auto_increment,
+ user_id int(12) NOT NULL,
+ username varchar(63) NOT NULL,
+ last_load int(12) NOT NULL,
+ PRIMARY KEY ( entry_id ),
+ KEY ( username )
+ );')
+ ) $db->_die('Could not create new who\'s-online table');
+ if(!$db->sql_query('CREATE UNIQUE INDEX '.table_prefix.'onluser ON '.table_prefix.'online(username);'))
+ $db->_die('Could not create index on username column.');
+ setConfig('whos_online_version', '0.1');
+}
+
+$plugins->attachHook('session_started', '__WhosOnline_UserCount();');
+$plugins->attachHook('login_success', '__WhosOnline_logonhandler();');
+$plugins->attachHook('logout_success', '__WhosOnline_logoffhandler($ou, $oid, $level);');
+
+function __WhosOnline_UserCount()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $whos_online;
+ $whos_online = Array();
+ $whos_online['users'] = Array();
+ $whos_online['guests'] = Array();
+ $q = $db->sql_query('REPLACE INTO '.table_prefix.'online SET user_id='.$session->user_id.',username=\''.$db->escape($session->username).'\',last_load='.time().';'); if(!$q) $db->_die('');
+ $q = $db->sql_query('DELETE FROM '.table_prefix.'online WHERE last_load<'.( time() - 60*60*24 ).';'); if(!$q) $db->_die('');
+ $q = $db->sql_query('SELECT o.username,o.user_id,u.user_level FROM '.table_prefix.'online AS o
+ LEFT JOIN '.table_prefix.'users AS u
+ ON u.user_id=o.user_id
+ WHERE last_load>'.( time() - 60*5 - 1 ).' ORDER BY username ASC'); if(!$q) $db->_die('');
+ $num_guests = 0;
+ $num_users = 0;
+ $users = Array();
+ while ( $row = $db->fetchrow() )
+ {
+ ( $row['user_id'] == 1 ) ? $num_guests++ : $num_users++;
+ if($row['user_id'] > 1)
+ {
+ switch($row['user_level'])
+ {
+ case USER_LEVEL_MEMBER:
+ default:
+ $color = '303030';
+ $weight = 'normal';
+ break;
+ case USER_LEVEL_MOD:
+ $color = '00AA00';
+ $weight = 'bold';
+ break;
+ case USER_LEVEL_ADMIN:
+ $color = 'AA0000';
+ $weight = 'bold';
+ break;
+ }
+ $users[] = "<a href='".makeUrlNS('User', str_replace(' ', '_', $row['username']))."' style='color: #$color; font-weight: $weight'>{$row['username']}</a>";
+ $whos_online['users'][] = $row['username'];
+ }
+ else
+ {
+ $whos_online['guests'][] = $row['username'];
+ }
+ }
+ $total = $num_guests + $num_users;
+ $ms = ( $num_users == 1 ) ? '' : 's';
+ $gs = ( $num_guests == 1 ) ? '' : 's';
+ $ts = ( $total == 1 ) ? '' : 's';
+ $is_are = ( $total == 1 ) ? 'is' : 'are';
+ $users = implode(', ', $users);
+ $online_main = ( $num_users > 0 ) ? "<br />
+ Users online right now:
+ <div style='max-height: 100px; clip: rect(0px,auto,auto,0px); overflow: auto;'>
+ $users
+ </div>
+ Legend:<br /><span style='color: #00AA00; font-weight: bold;'>Moderators</span> :: <span style='color: #AA0000; font-weight: bold;'>Administrators</span>"
+ : '';
+ $html = "<div style='padding: 5px;'>
+ <small>
+ There $is_are <b>$total</b> user$ts online :: <b>$num_guests</b> guest$gs and <b>$num_users</b> member$ms
+ $online_main
+ </small>
+ </div>";
+ $template->sidebar_widget('Who\'s Online', $html);
+}
+
+function __WhosOnline_logonhandler()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $q = $db->sql_query('DELETE FROM '.table_prefix.'online WHERE user_id=1 AND username=\''.$db->escape($_SERVER['REMOTE_ADDR']).'\';');
+ if(!$q)
+ echo $db->get_error();
+ if(!$session->theme)
+ $session->register_guest_session();
+ $template->load_theme($session->theme, $session->style);
+ __WhosOnline_UserCount();
+}
+
+function __WhosOnline_logoffhandler($username, $user_id, $level)
+{
+ if($level <= USER_LEVEL_MEMBER)
+ {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $q = $db->sql_query('DELETE FROM '.table_prefix.'online WHERE user_id=\''.intval($user_id).'\' AND username=\''.$db->escape($username).'\';');
+ if(!$q)
+ echo $db->get_error();
+ $q = $db->sql_query('REPLACE INTO '.table_prefix.'online SET user_id=1,username=\''.$db->escape($_SERVER['REMOTE_ADDR']).'\',last_load='.time().';'); if(!$q) $db->_die('');
+ if(!$q)
+ echo $db->get_error();
+ }
+}
+
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/ajim.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,107 @@
+<?php
+/*
+Plugin Name: AjIM Enano Module
+Plugin URI: http://enanocms.org/AjIM
+Description: AjIM is an AJAX-based chatroom system which was designed to be integrated with other web apps like Enano and phpBB. It's very simple to write bindings for AjIM and it doesn't use that much code which makes it pretty fast.
+Author: Dan Fuhry
+Version: 1.0
+Author URI: http://enanocms.org/
+*/
+
+if(!defined('_AJIM_INCLUDED'))
+{
+ define('_AJIM_INCLUDED', '');
+
+ // Change this line to wherever your AjIM installation is
+
+ if(defined('scriptPath'))
+ define('ajimClientPath', scriptPath.'/ajim');
+
+ if(!defined('ENANO_ROOT'))
+ define('ENANO_ROOT', dirname(dirname(__FILE__)));
+ define('ajimServerPath', ENANO_ROOT.'/ajim');
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $__ajim_config = Array(
+ 'sb_color_background'=>'#FFF',
+ 'sb_color_foreground'=>'#000',
+ );
+ if(defined('ENANO_INSTALLED') || defined('MIDGET_INSTALLED'))
+ {
+ if(!isset($_GET['admin']))
+ {
+ $plugins->attachHook('compile_template', 'AjIM_SideBar();');
+ $plugins->attachHook('acl_rule_init', 'global $session; $session->register_acl_type(\'ajim_post\', AUTH_ALLOW, \'Submit AjIM posts\');');
+ include(ajimServerPath . '/ajim.php');
+
+ function AjIM_SideBar()
+ {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ global $__ajim_config;
+ $paths->addAdminNode('Plugin configuration', 'AjIM configuration', 'AjIM_Config');
+ $dir = getcwd();
+ chdir(ENANO_ROOT);
+ include('config.php');
+ chdir($dir);
+ unset($dir);
+ if($session->user_level >= USER_LEVEL_ADMIN)
+ {
+ $r = $db->sql_query('SELECT password FROM '.table_prefix.'users WHERE username=\''.$session->username.'\'');
+ $p = $db->fetchrow_num($r);
+ $admin = $p[0];
+ }
+ else
+ {
+ $admin = false;
+ }
+ $__ajim_config['db_connection_handle'] = $db->_conn;
+ if(!$session->user_logged_in)
+ {
+ $__ajim_config['cant_post_notice'] = 'The administrator requires that you <a href="'.makeUrlNS('Special', 'Login/'.$paths->page, null, true).'">log in</a> to post messages.';
+ }
+ else
+ {
+ $__ajim_config['cant_post_notice'] = 'The administrator has disallowed message posting for your user account.';
+ }
+ $canpost = ( $session->get_permissions('ajim_post') ) ? true : false;
+ $ajim = new ajim($__ajim_config, table_prefix, scriptPath.'/plugins/ajim.php', $admin, false, $canpost, array('RenderMan', 'render'));
+ $template->sidebar_widget('Shoutbox', $ajim->html(ajimClientPath));
+ $template->additional_headers .= '<link rel="stylesheet" type="text/css" href="'.ajimClientPath.'/ajim.php?css&id='.$ajim->id.'&pfx='.table_prefix.'&path='.scriptPath.'/plugins/ajim.php" />';
+ }
+ }
+ } elseif(isset($_GET['ajimmode'])) {
+ global $db, $session, $paths, $template, $plugins, $dbhost, $dbname, $dbuser, $dbpasswd;
+ require_once('../includes/common.php');
+ require_once(ajimServerPath . '/ajim.php');
+ header('HTTP/1.1 200 OK');
+ define('ajimClientPath', scriptPath.'/ajim');
+ if($session->user_level >= 2) {
+ $admin = $session->grab_password_hash();
+ } else $admin = false;
+ require('../config.php');
+ $canpost = (getConfig('ajim_require_login') != '1' || $session->user_logged_in) ? true : false;
+ $__ajim_config['db_connection_handle'] = $db->_conn;
+ $__ajim_config['cant_post_notice'] = 'The administrator requires that you <a href="'.makeUrlNS('Special', 'Login/'.$paths->page, null, true).'">log in</a> to post messages.';
+ $__ajim_config['allow_looping'] = true;
+ $ajim = new ajim($__ajim_config, table_prefix, scriptPath.'/plugins/ajim.php', $admin, $_GET['id'], $canpost, array('RenderMan', 'render'));
+ $db->close();
+ exit;
+ }
+
+ function page_Admin_AjIM_Config()
+ {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ if(isset($_POST['_save']))
+ {
+ setConfig('ajim_require_login', ( isset($_POST['ajim_require_login']) ) ? '1' : '0');
+ }
+ echo '<form name="main" action="'.makeUrl($paths->nslist['Special'].'Administration?module='.$paths->cpage['module']).'" method="post">';
+ ?>
+ <h3>Configure AjIM, the Asynchronous Javascript Instant Messenger</h3>
+ <p>Only one option right now...</p>
+ <p><label><input type="checkbox" name="ajim_require_login" <?php if(getConfig('ajim_require_login')=='1') echo 'checked="checked" '; ?>/>Only logged-in users can post</label></p>
+ <p><input type="submit" name="_save" value="Save changes" />
+ <?php
+ echo '</form>';
+ }
+}
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/ajim/ajim.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,825 @@
+<?php
+
+/**
+ * AjIM - the Asynchronous Javascript Instant Messenger
+ * A shoutbox/chatbox framework that uses PHP, AJAX, MySQL, and Javascript
+ * Version: 1.0 RC 1
+ * Copyright (C) 2006-2007 Dan Fuhry
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+error_reporting(E_ALL);
+class ajim {
+ var $table_prefix, $conn, $id, $admin, $iface, $prune, $formatfunc, $config, $bad_words;
+ /**
+ * Die and be friendly about it.
+ * @param string $text - should be the text to show to the user, include mysql_error() value if applicable
+ */
+ function kill($text) {
+ die('AjIM: Database error<br />'.$text);
+ }
+ /**
+ * Make a SQL query. This function contains some error correction that performs automatic database upgrades if needed.
+ * @param string $q - The query text to send to MySQL.
+ * @return resource - or, kills the connection and bails out if the query failed
+ */
+ function sql($q) {
+ $r = mysql_query($q, $this->conn);
+ if(!$r)
+ {
+ if(strstr(mysql_error(), 'Unknown column \'time_id\''))
+ {
+ $this->sql('ALTER TABLE '.$this->table_prefix.'ajim ADD COLUMN time_id int(11) NOT NULL DEFAULT 0;');
+ $r = mysql_query($q, $this->conn);
+ }
+ elseif(strstr(mysql_error(), 'Unknown column \'sid\''))
+ {
+ $this->sql('ALTER TABLE '.$this->table_prefix.'ajim ADD COLUMN sid varchar(40) NOT NULL DEFAULT \'\';');
+ $r = mysql_query($q, $this->conn);
+ }
+ elseif(strstr(mysql_error(), 'Unknown column \'ip_addr\''))
+ {
+ $this->sql('ALTER TABLE '.$this->table_prefix.'ajim ADD COLUMN ip_addr varchar(15) NOT NULL DEFAULT \'\';');
+ $r = mysql_query($q, $this->conn);
+ }
+ $this->kill('Error during query:<br /><pre>'.htmlspecialchars($q).'</pre><br />MySQL said: '.mysql_error().'<br /><br />Depending on the error, AjIM may be able to automatically repair it. Just hang tight for about ten seconds. Whatever you do, don\'t close this browser window!');
+ }
+ return $r;
+ }
+ /**
+ * Get the user's SID (unique ID used for editing authorization) or generate a new one.
+ * @return string
+ */
+ function get_sid()
+ {
+ // Tag the user with a unique ID that can be used to edit posts
+ // This is used to essentially track users, but only for the purpose of letting them edit posts
+ if(!isset($_COOKIE['ajim_sid']))
+ {
+ $hash = sha1(microtime());
+ setcookie('ajim_sid', $hash, time()+60*60*24*365); // Cookies last for one year
+ }
+ else
+ $hash = $_COOKIE['ajim_sid'];
+
+ return $hash;
+ }
+ /**
+ * Set the default value for a configuration field.
+ * @param string $key - name of the configuration key
+ * @param string $value - the default value
+ * @param array $confarray - needs to be the array passed as the first param on the constructor
+ */
+ function config_default($key, $value, &$confarray)
+ {
+ if(!isset($confarray[$key]))
+ $confarray[$key] = $value;
+ }
+ /**
+ * Set up some basic vars and a database connection
+ * @param array $config - a configuration array, with either the key db_connection_handle (a valid MySQL connection resource) or the keys dbhost, dbname, dbuser, and dbpass
+ * @param string $table_prefix - the text prepended to the "ajim" table, should match ^([A-z0-9_]+)$
+ * @param string $handler - URL to the backend script, for example in Enano this would be the plugin file plugins/ajim.php
+ * @param string $admin - string containing the MD5 hash of the user's password, IF AND ONLY IF the user should be allowed to use the moderation function. In all other cases this should be false.
+ * @param string $id - used to carry over the randomly generated instance ID between requests. Should be false if the class is being initialized for displaying the inital HTML, in all other cases should be the value of the class variable AjIM::$id
+ * @param bool $can_post - true if the user is allowed to post, false otherwise. Defaults to true.
+ * @param mixed $formatfunc - a string containing the name of a function that can be called to format text before posts are sent to the user. If you need to call a class method, this should be an array with key 0 being the class name and key 1 being the method name.
+ */
+ function __construct($config, $table_prefix, $handler, $admin = false, $id = false, $can_post = true, $formatfunc = false) {
+ // CONFIGURATION
+ // $this->prune: a limit on the number of posts in the chat box. Usually this should be set to 40 or 50. Default is 40.
+ // Set to -1 to disable pruning.
+ $this->prune = -1;
+
+ $this->get_sid();
+
+ if(!is_array($config))
+ $this->kill('$config passed to the AjIM constructor should be an associative array with either the keys dbhost, dbname, dbuser, and dbpass, or the key db_connection_handle.');
+ if(isset($config['db_connection_handle']))
+ {
+ if(!is_resource($config['db_connection_handle'])) $this->kill('$config[\'db_connection_handle\'] is not a valid resource');
+ $this->conn = $config['db_connection_handle'];
+ if(!$this->conn) $this->kill('Error verifying database connection: '.mysql_error());
+ } elseif(isset($config['dbhost']) && isset($config['dbname']) && isset($config['dbuser']) && isset($config['dbpass'])) {
+ $this->conn = mysql_connect($config['dbhost'], $config['dbuser'], $config['dbpass']);
+ if(!$this->conn) $this->kill('Error connecting to the database: '.mysql_error());
+ $this->sql('USE '.$config['dbname']);
+ }
+
+ $this->bad_words = Array('viagra', 'phentermine', 'pharma', 'rolex', 'genital', 'penis', 'ranitidine', 'prozac', 'acetaminophen', 'acyclovir', 'ionamin', 'denavir', 'nizoral', 'zoloft', 'estradiol', 'didrex', 'aciphex', 'seasonale', 'allegra', 'lexapro', 'famvir', 'propecia', 'nasacort');
+ if(isset($config['bad_words']) && is_array($config['bad_words']))
+ {
+ $this->bad_words = array_values(array_merge($this->bad_words, $config['bad_words']));
+ }
+
+ // Don't change these values here - change them by passing values to the config array in this constructor's params!
+ $this->config_default('sb_color_background', '#FFFFFF', $config);
+ $this->config_default('sb_color_foreground', '#000000', $config);
+ $this->config_default('sb_color_editlink', '#00C000', $config);
+ $this->config_default('sb_color_deletelink', '#FF0000', $config);
+ $this->config_default('sb_color_userlink', '#0000FF', $config);
+
+ $this->config = $config;
+
+ if($id) $this->id = $id;
+ else $this->id = 'ajim_'.time();
+ $this->admin = $admin;
+ $this->formatfunc = $formatfunc;
+ $this->can_post = $can_post;
+ $this->table_prefix = $table_prefix;
+ $this->sql('CREATE TABLE IF NOT EXISTS '.$this->table_prefix.'ajim(
+ post_id mediumint(8) NOT NULL auto_increment,
+ name text,
+ website text,
+ post text,
+ time_id int(11) NOT NULL DEFAULT 0,
+ PRIMARY KEY ( post_id )
+ );');
+ $this->iface = $handler;
+ if(isset($_GET['ajimmode'])) $this->handler();
+ }
+ /**
+ * A dummy function used for PHP4 compatibility.
+ * @see AjIM::__construct()
+ */
+ function ajim($config, $table_prefix, $handler, $admin = false, $id = false, $can_post = true, $formatfunc = false) {
+ $this->__construct($config, $table_prefix, $handler, $admin, $id, $can_post, $formatfunc);
+ }
+ /**
+ * Generates the initial HTML UI to be sent to the user, used internally.
+ * @access private
+ * @param string $ajimPath - path to the AjIM connector (not this file), relative to document root, with initial slash.
+ */
+ function html($ajimPath) {
+
+ $enstr = $this->can_post ? '' : ' disabled="disabled"';
+ $html = '';
+ $html .= '<script type="text/javascript" src="'.$ajimPath.'/ajim.php?js&id='.$this->id.'&path='.urlencode($this->iface).'&pfx='.$this->table_prefix.'"></script>';
+ if($this->admin) {
+ $html.= '<script type="text/javascript" src="'.$ajimPath.'/ajim.php?jsadmin&id='.$this->id.'&path='.urlencode($this->iface).'&pfx='.$this->table_prefix.'"></script>';
+ }
+ $html .= '<div id="'.$this->id.'_master" style="padding: 5%; width: 90%;">
+ <div id="'.$this->id.'_c" style="text-align: center; color: '.$this->config['sb_color_foreground'].';
+ font-family: arial, sans-serif; font-size: 7pt; background-color: '.$this->config['sb_color_background'].';
+ text-align: left; border: 1px solid #000000; border-bottom: none; margin-bottom: 0; padding: 5%; width: 90%;
+ height: 200px; clip: rect(0px,auto,200px,0px); overflow: auto;"><noscript><p>You need to have JavaScript support to use this shoutbox.</p></noscript></div>';
+ // This is the post form div
+ if($this->can_post)
+ {
+ $html .= '<div style="font-family: arial; font-size: 7pt; margin-top: 0; border: 1px solid #000000; border-top-width: 0; width: 100%;">
+ <form action="#" onsubmit="'.$this->id.'_form(); return false;" method="get">
+ <table border="0" style="margin: 0; padding: 0; width: 90%;">
+ <tr><td><span style="font-family: arial; font-size: 7pt; ">Name:</span></td> <td><input style="font-family: arial; font-size: 7pt; border: 1px solid #000; height: 15px; width: 65px; padding: 1px;" id="'.$this->id.'_name" name="name"'.$enstr.' /></td></tr>
+ <tr><td><span style="font-family: arial; font-size: 7pt; ">Website:</span></td><td><input style="font-family: arial; font-size: 7pt; border: 1px solid #000; height: 15px; width: 65px; padding: 1px;" id="'.$this->id.'_website" name="website"'.$enstr.' /></td></tr>
+ <tr><td colspan="2"><span style="font-family: arial; font-size: 7pt; ">Message:</span></td></tr>
+ <tr><td colspan="2"><textarea'.$enstr.' rows="2" cols="16" style="width: auto; margin: 0 auto;" id="'.$this->id.'_post" name="post" onkeyup="'.$this->id.'_keyhandler();"></textarea></td></tr>
+ <tr><td colspan="2" align="center"><input'.$enstr.' type="submit" value="Submit post" /><br />
+ <span style="font-family: arial; font-size: 6pt; color: #000000;">AjIM powered</span></td></tr>
+ ';
+ $html .= '</table>
+ </form>';
+ if($this->admin) {
+ $html .= '<table border="0" style="margin: 0; padding: 0; width: 90%;" align="center"><tr><td colspan="2" align="center"><span id="'.$this->id.'_admin"><a href="#" onclick="'.$this->id.'_prompt(); return false;">Administration</a></span></td></tr></table>';
+ }
+ $html.='</div></div>';
+ } else {
+ $html .= '<div style="font-family: arial; font-size: 7pt; margin: 5px; margin-top: 0; border: 1px solid #000000; border-top: none;">';
+ if(isset($this->config['cant_post_notice'])) {
+ $html .= '<div style="margin: 0; padding: 5px;">'.$this->config['cant_post_notice'].'</div>';
+ }
+ $html .= '</div></div>';
+ }
+ $html.='<script type="text/javascript">
+ document.getElementById(\''.$this->id.'_c\').innerHTML = unescape(\'%3Cdiv align="center" style="width:95%;"%3EInitializing...%3C\/div%3E\');';
+ if($this->can_post) $html .= 'if('.$this->id.'readCookie("ajim_password") && ( typeof "'.$this->id.'_login_bin" == "string" || typeof "'.$this->id.'_login_bin" == "function" )) {
+ '.$this->id.'_login_bin('.$this->id.'readCookie("ajim_password"));
+ }
+ if('.$this->id.'readCookie("ajim_name")) document.getElementById("'.$this->id.'_name").value = '.$this->id.'readCookie("ajim_name");
+ if('.$this->id.'readCookie("ajim_website")) document.getElementById("'.$this->id.'_website").value = '.$this->id.'readCookie("ajim_website");';
+ $html .= ''.$this->id.'_refresh();
+ </script>';
+
+ return $html;
+ }
+ /**
+ * Kills the database connection
+ */
+ function destroy() {
+ mysql_close($this->conn);
+ }
+ /**
+ * Strips all traces of HTML, XML, and PHP from text, and prepares it for being inserted into a MySQL database.
+ * @access private
+ * @param string $text - the text to sanitize
+ * @return string
+ */
+ function sanitize($text) {
+ $text = rawurldecode($text);
+ $text = preg_replace('#<(.*?)>#is', '<\\1>', $text);
+ $text = str_replace("\n", '<br />', $text);
+ $text = mysql_real_escape_string($text);
+ return $text;
+ }
+ /**
+ * Scrutinizes a string $text for any traces of the word $word, returns true if the text is clean.
+ * For example, if $word is "viagra" and the text contains "\/|@6r/\" this returns false, else you would get true.
+ * @access private
+ * @param string $text - the text to check
+ * @param string $word - word to look for.
+ * @return bool
+ */
+ function spamcheck($text, $word)
+ {
+ // build an array, with each key containing one letter (equiv. to str_split() in PHP 5)
+ $chars = Array();
+ for($i=0;$i<strlen($word);$i++)
+ {
+ $chars[] = substr($word, $i, 1);
+ }
+ // This is our rule list - all the known substitutions for a given letter (e.g. "\/" in place of "V", etc.), needs to be escaped for regex use
+ $subs = Array(
+ 'a'=>'a|\/\\\\|@',
+ 'b'=>'b|\|o',
+ 'c'=>'c|\(|',
+ 'd'=>'d|o\|',
+ 'e'=>'e|3',
+ 'f'=>'f',
+ 'g'=>'g|6|9',
+ 'h'=>'h|\|n',
+ 'i'=>'i|\!|1|\|',
+ 'j'=>'j|\!|1|\|',
+ 'k'=>'k|\|<|\|<',
+ 'l'=>'l|\!|1|\|',
+ 'm'=>'m|nn|rn',
+ 'n'=>'n|h|u\\|\\\\\|',
+ 'o'=>'o|\(\)|0|@',
+ 'p'=>'p',
+ 'q'=>'q',
+ 'r'=>'r|\|\^',
+ 's'=>'s',
+ 't'=>'t|\+',
+ 'u'=>'u|n',
+ 'v'=>'v|\\\\\/', // "\/"
+ 'w'=>'w|vv|\\\\\/\\\\\/', // allows for "\/\/"
+ 'x'=>'x|><|><|><|><',
+ 'y'=>'y',
+ 'z'=>'z|\|\\\\\|' // |\|
+ );
+ $regex = '#([\s]){0,1}';
+ foreach($chars as $c)
+ {
+ $lc = strtolower($c);
+ if(isset($subs[$lc]))
+ {
+ $regex .= '('.$subs[$lc].')';
+ } else {
+ die('0 $subs['.$lc.'] is not set');
+ $regex .= preg_quote($c);
+ }
+ $regex .= '(.|)';
+ }
+ $regex .= '([\s]){0,1}#is';
+ //echo($word.': '.$regex.'<br />');
+ if(preg_match($regex, $text)) return false;
+ return true;
+ }
+ /**
+ * Processes AJAX requests. Usually called if $_GET['ajimmode'] is set.
+ * @access private
+ */
+ function handler() {
+ if(isset($_GET['ajimmode'])) {
+ switch($_GET['ajimmode']) {
+ default:
+ die('');
+ break;
+ case 'getsource':
+ case 'getpost':
+ if(!preg_match('#^([0-9]+)$#', $_GET['p'])) die('SQL injection attempt');
+ $q = $this->sql('SELECT post,sid,ip_addr FROM '.$this->table_prefix.'ajim WHERE post_id='.$_GET['p']);
+ $r = mysql_fetch_assoc($q);
+ if( ( ( isset($_GET['ajim_auth']) && (!$this->admin || ($this->admin != $_GET['ajim_auth']) ) ) || !isset($_GET['ajim_auth']) ) && ( $this->get_sid() != $r['sid'] || $_SERVER['REMOTE_ADDR'] != $r['ip_addr'] ) ) die('Hacking attempt');
+ if($_GET['ajimmode']=='getpost')
+ if($this->formatfunc)
+ {
+ $p = @call_user_func($this->formatfunc, $r['post']);
+ if($p) $r['post'] = $p;
+ unset($p); // Free some memory
+ }
+ echo $r['post'];
+ break;
+ case "savepost":
+ if(!preg_match('#^([0-9]+)$#', $_POST['p'])) die('SQL injection attempt');
+ $q = $this->sql('SELECT sid,ip_addr FROM '.$this->table_prefix.'ajim WHERE post_id='.$_POST['p']);
+ $r = mysql_fetch_assoc($q);
+ if( ( ( isset($_POST['ajim_auth']) && (!$this->admin || ($this->admin != $_POST['ajim_auth']) ) ) || !isset($_POST['ajim_auth']) ) && ( $this->get_sid() != $r['sid'] || $_SERVER['REMOTE_ADDR'] != $r['ip_addr'] ) ) die('Hacking attempt');
+ $post = $this->sanitize($_POST['post']);
+ $post = $this->make_clickable($post);
+ $post = preg_replace('#_(.*?)_#is', '<i>\\1</i>', $post);
+ $post = preg_replace('#\*(.*?)\*#is', '<b>\\1</b>', $post);
+ $bad_words = Array('viagra', 'phentermine', 'pharma');
+ foreach($bad_words as $w)
+ {
+ if(!$this->spamcheck($post, $w)) die('<span style="color: red">The word "'.$w.'" has been detected in your message and as a result your post has been blocked.</span> Don\'t argue, that will only get you banned.');
+ }
+ if(!$this->can_post) die('Access to posting messages has been denied because the administrator has set that you must be logged into this website in order to post.');
+
+ $this->sql('UPDATE '.$this->table_prefix.'ajim SET post=\''.$post.'\' WHERE post_id='.$_POST['p'].';');
+
+ if($this->formatfunc)
+ {
+ $p = @call_user_func($this->formatfunc, $post);
+ if($p) $post = $p;
+ unset($p); // Free some memory
+ }
+ die($post);
+ break;
+ case 'delete':
+ if(!preg_match('#^([0-9]+)$#', $_POST['p'])) die('SQL injection attempt');
+ $q = $this->sql('SELECT sid,ip_addr FROM '.$this->table_prefix.'ajim WHERE post_id='.$_POST['p']);
+ $r = mysql_fetch_assoc($q);
+ if( ( ( isset($_POST['ajim_auth']) && (!$this->admin || ($this->admin != $_POST['ajim_auth']) ) ) || !isset($_POST['ajim_auth']) ) && ( $this->get_sid() != $r['sid'] || $_SERVER['REMOTE_ADDR'] != $r['ip_addr'] ) ) die('Hacking attempt');
+ $this->sql('DELETE FROM '.$this->table_prefix.'ajim WHERE post_id='.$_POST['p']);
+ die('good');
+ break;
+ case 'post':
+ if(!preg_match('#(^|[\n ])([\w]+?://[\w\#$%&~/.\-;:=,?@\[\]+]*)$#is', $_POST['website'])) $_POST['website']='';
+ // Now for a clever anti-spam trick: blacklist the words "viagra" and "phentermine" using one wicked regex:
+ // #([\s]){1}(v|\\\\\/)(.*){1}(i|\||l|1)(.*){1}(a|@|\/\\\\)(.*){1}(g|6)(.*){1}r(.*){1}(a|@|\/\\\\)(\s){1}#is
+ $name = $this->sanitize($_POST['name']);
+ $website = $this->sanitize($_POST['website']);
+ $post = $this->sanitize($_POST['post']);
+ foreach($this->bad_words as $w)
+ {
+ if(!$this->spamcheck($post, $w)) die('<span style="color: red">The word "'.$w.'" has been detected in your message and as a result your post has been blocked.</span> Don\'t argue, that will only get you banned.');
+ }
+ $post = $this->make_clickable($post);
+ $post = preg_replace('#_(.*?)_#is', '<i>\\1</i>', $post);
+ $post = preg_replace('#\*(.*?)\*#is', '<b>\\1</b>', $post);
+ if(!$this->can_post) die('Access to posting messages has been denied because the administrator has set that you must be logged into this website in order to post.');
+ $this->sql('INSERT INTO '.$this->table_prefix.'ajim ( name, website, post, time_id, sid, ip_addr ) VALUES(\''.$name.'\', \''.$website.'\', \''.$post.'\', '.time().', \''.mysql_real_escape_string($this->get_sid()).'\', \''.mysql_real_escape_string($_SERVER['REMOTE_ADDR']).'\');');
+ case 'view':
+ // if(isset($_GET['ajim_auth']))
+ // die('Auth: '.$_GET['ajim_auth']); // .'<br />Pw: '.$this->admin);
+ if(isset($_GET['latest']) && ( isset($this->config['allow_looping']) && $this->config['allow_looping'] == true ))
+ {
+ // Determine max execution time
+ $max_exec = intval(@ini_get('max_execution_time'));
+ if(!$max_exec) $max_exec = 30;
+ $time_left = $max_exec - 1;
+ }
+ $q = $this->sql('SELECT name, website, post, post_id, time_id, sid, ip_addr FROM '.$this->table_prefix.'ajim ORDER BY post_id;');
+ if(mysql_num_rows($q) < 1) echo '0 <span style="color: #666666">No posts.</span>';
+ else {
+ // Prune the table
+ if($this->prune > 0) {
+ $nr = mysql_num_rows($q);
+ $nr = $nr - $this->prune;
+ if($nr > 0) $this->sql('DELETE FROM '.$this->table_prefix.'ajim LIMIT '.$nr.';');
+ }
+ // Alright, what we want to do here is grab the entire table, load it into an array, and then display the posts in reverse order.
+ for($i = 1; $i<=mysql_num_rows($q); $i++) {
+ $t[$i] = mysql_fetch_object($q);
+ }
+
+ $s = sizeof($t);
+
+ if(isset($_GET['latest']) && ( isset($this->config['allow_looping']) && $this->config['allow_looping'] == true ))
+ {
+ // When I was coding this, I immediately thought "use labels and goto!" Here's hoping, PHP6 :-)
+ $latest_from_user = intval($_GET['latest']);
+ $latest_from_db = intval($t[$s]->time_id);
+ while(true)
+ {
+ if($latest_from_user == $latest_from_db && $time_left > 5)
+ {
+ $time_left = $time_left - 5;
+ sleep(5);
+ mysql_free_result($q);
+ $q = $this->sql('SELECT name, website, post, post_id, time_id, sid, ip_addr FROM '.$this->table_prefix.'ajim ORDER BY post_id;');
+ $t = Array();
+ for($i = 1; $i<=mysql_num_rows($q); $i++) {
+ $t[$i] = mysql_fetch_object($q);
+ }
+ $s = sizeof($t);
+ $latest_from_user = intval($_GET['latest']);
+ $latest_from_db = intval($t[$s]->time_id);
+ //echo (string)$latest_from_db.'<br />';
+ //flush();
+ //exit;
+ if($latest_from_user != $latest_from_db)
+ break;
+ continue;
+ }
+ elseif($latest_from_user == $latest_from_db && $time_left < 5)
+ {
+ die('[E] No new posts');
+ }
+ break;
+ }
+ }
+
+ echo $t[$s]->time_id . ' ';
+
+ // This is my favorite array trick - it baffles everyone who looks at it :-D
+ // What it does is the same as for($i=0;$i<sizeof($t);$i++), but it processes the
+ // array in reverse order.
+
+ for($i = $s; $i > 0; $i--) {
+ if($this->formatfunc)
+ {
+ $p = @call_user_func($this->formatfunc, $t[$i]->post);
+ if($p) $t[$i]->post = $p;
+ unset($p); // Free some memory
+ $good_tags = Array('b', 'i', 'u', 'br');
+ $gt = implode('|', $good_tags);
+
+ // Override any modifications that may have been made to the HTML
+ $t[$i]->post = preg_replace('#<('.$gt.')>([^.]+)</\\1>#is', '<\\1>\\2</\\1>', $t[$i]->post);
+ $t[$i]->post = preg_replace('#<('.$gt.')([ ]*?)/>#is', '<\\1 />', $t[$i]->post);
+ $t[$i]->post = preg_replace('#<('.$gt.')>#is', '<\\1 />', $t[$i]->post);
+ }
+ echo '<div style="border-bottom: 1px solid #BBB; width: 98%;"><table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td><span style="font-weight: bold">';
+ if($t[$i]->website != '') echo '<a href="'.$t[$i]->website.'" style="color: #0000FF">'.$t[$i]->name.'</a>';
+ else echo ''.$t[$i]->name.'';
+ echo '</span> ';
+ if( $this->can_post && ($t[$i]->sid == $this->get_sid() && $t[$i]->ip_addr == $_SERVER['REMOTE_ADDR'] ) || ( isset($_GET['ajim_auth']) && $_GET['ajim_auth']==$this->admin ) )
+ echo '</td><td style="text-align: right"><a href="#" onclick="void('.$this->id.'_delete_post(\''.$t[$i]->post_id.'\')); return false;" style="color: '.$this->config['sb_color_deletelink'].'">Delete</a> <a href="javascript:void('.$this->id.'_edit_post(\''.$t[$i]->post_id.'\'));" id="'.$this->id.'_editbtn_'.$t[$i]->post_id.'" style="color: '.$this->config['sb_color_editlink'].'">Edit</a>';
+ echo '</td></tr></table><span style="color: #CCC; font-style: italic;">Posted on '.date('n/j, g:ia', $t[$i]->time_id).'</span></div>';
+ echo '<div style="border-bottom: 1px solid #CCC; width: 98%;" id="'.$this->id.'_post_'.$t[$i]->post_id.'">'.$t[$i]->post.'</div>';
+ echo '<br />';
+ }
+ }
+ break;
+ case 'auth':
+ if($_POST['ajim_auth']==$this->admin) echo 'good';
+ else echo 'The password you entered is invalid.';
+ break;
+ }
+ }
+ }
+
+ /**
+ * Replace URLs within a block of text with anchors
+ * Written by Nathan Codding, copyright (C) phpBB Group
+ * @param string $text - the text to process
+ * @return string
+ */
+ function make_clickable($text)
+ {
+ $text = preg_replace('#(script|about|applet|activex|chrome):#is', "\\1:", $text);
+ $ret = ' ' . $text;
+ $ret = preg_replace('#(^|[\n ])([\w]+?://[\w\#$%&~/.\-;:=,?@\[\]+]*)#is', '\\1<a href="\\2" target="_blank">\\2</a>', $ret);
+ $ret = preg_replace("#(^|[\ n ])((www|ftp)\.[\w\#$%&~/.\-;:=,?@\[\]+]*)#is", '\\1<a href="http://\\2" target="_blank">\\2</a>', $ret);
+ $ret = preg_replace("#(^|[\n ])([a-z0-9&\-_.]+?)@([\w\-]+\.([\w\-\.]+\.)*[\w]+)#i", '\\1<a href="mailto:\\2@\\3">\\2@\\3</a>', $ret);
+ $ret = substr($ret, 1);
+ return($ret);
+ }
+}
+
+// The client-side javascript and CSS code
+
+if(isset($_GET['js']) && isset($_GET['id']) && isset($_GET['path']) && isset($_GET['pfx'])) {
+ header('Content-type: text/javascript');
+ ?>
+ // <script>
+ var <?php echo $_GET['id']; ?>id='<?php echo $_GET['id']; ?>';
+ var path='<?php echo $_GET['path']; ?>';
+ var pfx='<?php echo $_GET['pfx']; ?>';
+ var authed = false; // Don't even try to hack this var; it contains the MD5 of the password that *you* enter, setting it to true will just botch up all the requests
+ // authed is always set to false unless your password has been verified by the server, and it is sent to the server with every request.
+ var shift;
+ var <?php echo $_GET['id']; ?>editlist = new Array();
+ var <?php echo $_GET['id']; ?>_latestpost = 0;
+ var <?php echo $_GET['id']; ?>_allowrequest = true;
+
+ var <?php echo $_GET['id']; ?>_refcount = 0;
+ var <?php echo $_GET['id']; ?>_refcount_current = 0;
+
+ var <?php echo $_GET['id']; ?>interval = setInterval('<?php echo $_GET['id']; ?>_refresh();', 5000);
+ var ajim_editlevels = 0;
+
+ // Add the AjIM stylesheet to the HTML header
+ var link = document.createElement('link');
+ link.href = path+'?title=null&css&id='+<?php echo $_GET['id']; ?>id+'&path='+path+'&pfx='+pfx+'&ajimmode=';
+ link.rel = 'stylesheet';
+ link.type = 'text/css';
+ var head = document.getElementsByTagName('head');
+ head = head[0];
+ head.appendChild(link);
+
+ if(typeof window.onload == 'function')
+ var __ajim_oltemp = window.onload;
+ else
+ var __ajim_oltemp = function(e) { };
+ window.onload = function(e)
+ {
+ if(document.getElementById('<?php echo $_GET['id']; ?>_post'))
+ {
+ document.getElementById('<?php echo $_GET['id']; ?>_post').onkeyup = function(e) { <?php echo $_GET['id']; ?>_keyhandler(e); };
+ }
+ __ajim_oltemp(e);
+ }
+
+ function <?php echo $_GET['id']; ?>readCookie(name) {var nameEQ = name + "=";var ca = document.cookie.split(';');for(var i=0;i < ca.length;i++){var c = ca[i];while (c.charAt(0)==' ') c = c.substring(1,c.length);if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);}return null;}
+ function <?php echo $_GET['id']; ?>setCookie(name,value,days){if (days){var date = new Date();date.setTime(date.getTime()+(days*24*60*60*1000));var expires = "; expires="+date.toGMTString();}else var expires = "";document.cookie = name+"="+value+expires+"; path=/";}
+ function <?php echo $_GET['id']; ?>eraseCookie(name) {createCookie(name,"",-1);}
+
+ function strpos(haystack, needle)
+ {
+ if(typeof(haystack) != 'string') return false;
+ if(typeof(needle) != 'string') return false;
+ len = needle.length;
+ for(i=0;i<haystack.length;i++)
+ {
+ if ( haystack.substr(i, len) == needle )
+ return i;
+ }
+ return 0;
+ }
+
+ function <?php echo $_GET['id']; ?>_newReq(what2call) {
+ if (window.XMLHttpRequest) {
+ request = new XMLHttpRequest();
+ } else {
+ if (window.ActiveXObject) {
+ request = new ActiveXObject("Microsoft.XMLHTTP");
+ } else {
+ alert('Your browser does not support AJAX. Get Firefox 2.0!');
+ return false;
+ }
+ }
+ request.onreadystatechange = what2call;
+ return request;
+ }
+
+ function <?php echo $_GET['id']; ?>_refresh(force) {
+ <?php echo $_GET['id']; ?>_refcount++;
+ <?php echo $_GET['id']; ?>_refcount_current = <?php echo $_GET['id']; ?>_refcount;
+ if(!<?php echo $_GET['id']; ?>_allowrequest && !force)
+ return false;
+ <?php echo $_GET['id']; ?>_allowrequest = false;
+ var r = <?php echo $_GET['id']; ?>_newReq(function() {
+ if(r.readyState == 4)
+ {
+ // Prevent an old request from taking over a more recent one
+ if(<?php echo $_GET['id']; ?>_refcount > <?php echo $_GET['id']; ?>_refcount_current)
+ return;
+ if(r.responseText != '[E] No new posts')
+ {
+ time = r.responseText.substr(0, strpos(r.responseText, ' '));
+ <?php echo $_GET['id']; ?>_latestpost = parseInt(time);
+ text = r.responseText.substr(strpos(r.responseText, ' ')+1, r.responseText.length);
+ document.getElementById('<?php echo $_GET['id']; ?>_c').innerHTML = text;
+ }
+ <?php echo $_GET['id']; ?>_allowrequest = true;
+ }
+ });
+ if(force)
+ latest = '';
+ else
+ latest = '&latest='+<?php echo $_GET['id']; ?>_latestpost;
+ if(authed) r.open('GET', path+'?title=null&ajimmode=view&id='+<?php echo $_GET['id']; ?>id+'&pfx='+pfx+latest+'&ajim_auth='+authed, true);
+ else r.open('GET', path+'?title=null&ajimmode=view&id='+<?php echo $_GET['id']; ?>id+'&pfx='+pfx+latest, true);
+ r.send(null);
+ }
+
+ function <?php echo $_GET['id']; ?>_submit(name, website, post) {
+ var r = <?php echo $_GET['id']; ?>_newReq(function() {
+ if(r.readyState == 4)
+ {
+ if(r.responseText != '[E] No new posts')
+ {
+ if(parseInt(r.responseText.substr(0,1)) != 0)
+ {
+ time = r.responseText.substr(0, strpos(r.responseText, ' '));
+ <?php echo $_GET['id']; ?>_latestpost = parseInt(time);
+ text = r.responseText.substr(strpos(r.responseText, ' ')+1, r.responseText.length);
+ }
+ else
+ {
+ text = r.responseText;
+ }
+ document.getElementById('<?php echo $_GET['id']; ?>_c').innerHTML = text;
+ }
+ }
+ })
+ if(authed) var parms = 'name='+name+'&website='+website+'&post='+post+'&ajim_auth='+authed;
+ else var parms = 'name='+name+'&website='+website+'&post='+post;
+ r.open('POST', path+'?title=null&ajimmode=post&id='+<?php echo $_GET['id']; ?>id+'', true);
+ r.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+ r.setRequestHeader("Content-length", parms.length);
+ r.setRequestHeader("Connection", "close");
+ r.send(parms);
+ }
+
+ function <?php echo $_GET['id']; ?>_form() {
+ var name = document.getElementById(<?php echo $_GET['id']; ?>id+'_name').value;
+ var website = document.getElementById(<?php echo $_GET['id']; ?>id+'_website').value;
+ var post = document.getElementById(<?php echo $_GET['id']; ?>id+'_post').value;
+ if(name.length < 1) { alert('Please enter your name.'); return; }
+ if(post.length < 1) { alert('Please enter a post.'); return; }
+ <?php echo $_GET['id']; ?>setCookie('ajim_name', name, 60*60*24*365*10);
+ <?php echo $_GET['id']; ?>setCookie('ajim_website', website, 60*60*24*365*10);
+ <?php echo $_GET['id']; ?>_submit(name, website, post);
+ document.getElementById(<?php echo $_GET['id']; ?>id+'_post').value = '';
+ }
+
+
+ function <?php echo $_GET['id']; ?>_keyhandler(e)
+ {
+ if(!e) e = window.event;
+ if(e.keyCode == 13)
+ {
+ val = document.getElementById(<?php echo $_GET['id']; ?>id+'_post').value;
+ if(!shift)
+ {
+ document.getElementById(<?php echo $_GET['id']; ?>id+'_post').value = val.substr(0, val.length - 1);
+ <?php echo $_GET['id']; ?>_form();
+ }
+ }
+ }
+
+ function <?php echo $_GET['id']; ?>keysensor(event)
+ {
+ if (event.shiftKey==1)
+ {
+ shift = true;
+ }
+ else
+ {
+ shift = false;
+ }
+ }
+
+ if(window.onkeydown)
+ {
+ var kttemp = window.onkeydown;
+ window.onkeydown = function(e) { kttemp(e); <?php echo $_GET['id']; ?>keysensor(e); }
+ } else {
+ window.onkeydown = function(e) { <?php echo $_GET['id']; ?>keysensor(e); }
+ }
+
+ if(window.onkeyup)
+ {
+ var kttemp = window.onkeyup;
+ window.onkeyup = function(e) { kttemp(e); <?php echo $_GET['id']; ?>keysensor(e); }
+ } else {
+ window.onkeyup = function(e) { <?php echo $_GET['id']; ?>keysensor(e); }
+ }
+
+ function <?php echo $_GET['id']; ?>_edit_post(pid)
+ {
+ if(<?php echo $_GET['id']; ?>editlist[pid])
+ {
+ var r = <?php echo $_GET['id']; ?>_newReq(function() {
+ if(r.readyState == 4) {
+ document.getElementById('<?php echo $_GET['id']; ?>_post_'+pid).innerHTML = r.responseText;
+ document.getElementById('<?php echo $_GET['id']; ?>_editbtn_'+pid).innerHTML = 'Edit';
+ ajim_editlevels--;
+ <?php echo $_GET['id']; ?>editlist[pid] = false;
+ if(ajim_editlevels < 1)
+ {
+ <?php echo $_GET['id']; ?>interval = setInterval('<?php echo $_GET['id']; ?>_refresh();', 5000);
+ }
+ }
+ });
+ if(authed) r.open('GET', path+'?title=null&ajimmode=getpost&id='+<?php echo $_GET['id']; ?>id+'&pfx='+pfx+'&p='+pid+'&ajim_auth='+authed, true);
+ else r.open('GET', path+'?title=null&ajimmode=getpost&id='+<?php echo $_GET['id']; ?>id+'&pfx='+pfx+'&p='+pid, true);
+ r.send(null);
+ } else {
+ clearInterval(<?php echo $_GET['id']; ?>interval);
+ var r = <?php echo $_GET['id']; ?>_newReq(function() {
+ if(r.readyState == 4) {
+ document.getElementById('<?php echo $_GET['id']; ?>_post_'+pid).innerHTML = '<textarea rows="4" cols="17" id="<?php echo $_GET['id']; ?>_editor_'+pid+'">'+r.responseText+'</textarea><br /><a href="#" onclick="<?php echo $_GET['id']; ?>_save_post(\''+pid+'\'); return false;" style="font-size: 7pt; color: #00C000;">save</a>';
+ document.getElementById('<?php echo $_GET['id']; ?>_editbtn_'+pid).innerHTML = 'Cancel';
+ ajim_editlevels++;
+ <?php echo $_GET['id']; ?>editlist[pid] = true;
+ }
+ });
+ if(authed) r.open('GET', path+'?title=null&ajimmode=getsource&id='+<?php echo $_GET['id']; ?>id+'&pfx='+pfx+'&p='+pid+'&ajim_auth='+authed, true);
+ else r.open('GET', path+'?title=null&ajimmode=getsource&id='+<?php echo $_GET['id']; ?>id+'&pfx='+pfx+'&p='+pid, true);
+ r.send(null);
+ }
+ }
+
+ var ajim_global_pid;
+ function <?php echo $_GET['id']; ?>_save_post(pid) {
+ ajim_global_pid = pid;
+ if(!document.getElementById('<?php echo $_GET['id']; ?>_editor_'+pid))
+ {
+ alert('AjIM internal error: bad post ID '+pid+': editor is not open');
+ return false;
+ }
+ var r = <?php echo $_GET['id']; ?>_newReq(function() {
+ if(r.readyState == 4)
+ {
+ ajim_editlevels--;
+ <?php echo $_GET['id']; ?>editlist[pid] = false;
+ document.getElementById('<?php echo $_GET['id']; ?>_editbtn_'+ajim_global_pid).innerHTML = 'Edit';
+ document.getElementById('<?php echo $_GET['id']; ?>_post_'+ajim_global_pid).innerHTML = r.responseText;
+ if(ajim_editlevels < 1)
+ {
+ <?php echo $_GET['id']; ?>_refresh(true);
+ <?php echo $_GET['id']; ?>interval = setInterval('<?php echo $_GET['id']; ?>_refresh();', 5000);
+ }
+ }
+ });
+ var parms = 'post='+escape(document.getElementById('<?php echo $_GET['id']; ?>_editor_'+pid).value.replace('+', '%2B'))+'&ajim_auth='+authed+'&p='+pid;
+ r.open('POST', path+'?title=null&ajimmode=savepost&id='+<?php echo $_GET['id']; ?>id+'', true);
+ r.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+ r.setRequestHeader("Content-length", parms.length);
+ r.setRequestHeader("Connection", "close");
+ r.send(parms);
+ return null;
+ }
+
+ function <?php echo $_GET['id']; ?>_delete_post(pid) {
+ //document.getElementById(<?php echo $_GET['id']; ?>id+'_admin').innerHTML = '<span style="font-family: arial; font-size: 7pt; ">Loading...</span>';
+ var r = <?php echo $_GET['id']; ?>_newReq(function() {
+ if(r.readyState == 4)
+ if(r.responseText=="good") {
+ <?php echo $_GET['id']; ?>_refresh(true);
+ } else alert(r.responseText);
+ });
+ var parms = 'ajim_auth='+authed+'&p='+pid;
+ r.open('POST', path+'?title=null&ajimmode=delete&id='+<?php echo $_GET['id']; ?>id+'', true);
+ r.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+ r.setRequestHeader("Content-length", parms.length);
+ r.setRequestHeader("Connection", "close");
+ r.send(parms);
+ return null;
+ }
+
+ <?php
+} elseif(isset($_GET['jsadmin']) && isset($_GET['id']) && isset($_GET['path'])) {
+ header('Content-type: text/javascript');
+ ?>
+
+ var abuffer;
+ function <?php echo $_GET['id']; ?>_prompt() {
+ abuffer = document.getElementById(<?php echo $_GET['id']; ?>id+'_admin').innerHTML;
+ document.getElementById(<?php echo $_GET['id']; ?>id+'_admin').innerHTML = '<form action="javascript:void(0)" onsubmit="'+<?php echo $_GET['id']; ?>id+'_login()" method="get"><span style="font-family: arial; font-size: 7pt; ">Password:</span> <input style="font-family: arial; font-size: 7pt; border: 1px solid #000; height: 15px; width: 65px" id="'+<?php echo $_GET['id']; ?>id+'_passfield" name="pass" type="password" /> <input style="font-family: arial; font-size: 7pt; border: 1px solid #000; height: 15px; width: 65px" type="submit" value="OK" /></form>';
+ }
+
+ function <?php echo $_GET['id']; ?>_login() {
+ pass = document.getElementById(<?php echo $_GET['id']; ?>id+'_passfield').value;
+ pass = hex_md5(pass);
+ <?php echo $_GET['id']; ?>_login_bin(pass);
+ }
+ function <?php echo $_GET['id']; ?>_login_bin(pass) {
+ document.getElementById(<?php echo $_GET['id']; ?>id+'_admin').innerHTML = '<span style="font-family: arial; font-size: 7pt; ">Loading...</span>';
+ var r = <?php echo $_GET['id']; ?>_newReq(function() {
+ if(r.readyState == 4)
+ {
+ if(r.responseText=="good") {
+ authed = pass;
+ <?php echo $_GET['id']; ?>setCookie('ajim_password', authed, 60*60*24*365*10);
+ <?php echo $_GET['id']; ?>_latestpost = 0;
+ <?php echo $_GET['id']; ?>_refresh(true);
+ document.getElementById(<?php echo $_GET['id']; ?>id+'_admin').innerHTML = '';
+ }
+ else
+ {
+ alert(r.responseText);
+ document.getElementById(<?php echo $_GET['id']; ?>id+'_admin').innerHTML = '<span style="font-family: arial; font-size: 7pt; color: #ff0000">Invalid password!</span><br />'+abuffer;
+ }
+ }
+ })
+ var parms = 'ajim_auth='+pass;
+ r.open('POST', path+'?title=null&ajimmode=auth&id='+<?php echo $_GET['id']; ?>id+'', true);
+ r.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+ r.setRequestHeader("Content-length", parms.length);
+ r.setRequestHeader("Connection", "close");
+ r.send(parms);
+ }
+
+ var hexcase = 0; var b64pad = ""; var chrsz = 8; function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}; function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}; function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}; function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }; function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }; function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }; function md5_vm_test() { return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; }; function core_md5(x, len) { x[len >> 5] |= 0x80 << ((len) % 32); x[(((len + 64) >>> 9) << 4) + 14] = len; var a = 1732584193; var b = -271733879; var c = -1732584194; var d = 271733878; for(var i = 0; i < x.length; i += 16) { var olda = a; var oldb = b; var oldc = c; var oldd = d; a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);c = md5_ff(c, d, a, b, x[i+10], 17, -42063);b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); a = safe_add(a, olda); b = safe_add(b, oldb); c = safe_add(c, oldc); d = safe_add(d, oldd); } return Array(a, b, c, d); }; function md5_cmn(q, a, b, x, s, t) { return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); }; function md5_ff(a, b, c, d, x, s, t) { return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); }; function md5_gg(a, b, c, d, x, s, t) { return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); }; function md5_hh(a, b, c, d, x, s, t) { return md5_cmn(b ^ c ^ d, a, b, x, s, t); }; function md5_ii(a, b, c, d, x, s, t) { return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); }; function core_hmac_md5(key, data) { var bkey = str2binl(key); if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz); var ipad = Array(16), opad = Array(16); for(var i = 0; i < 16; i++) { ipad[i] = bkey[i] ^ 0x36363636; opad[i] = bkey[i] ^ 0x5C5C5C5C; } var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz); return core_md5(opad.concat(hash), 512 + 128); }; function safe_add(x, y) {var lsw = (x & 0xFFFF) + (y & 0xFFFF);var msw = (x >> 16) + (y >> 16) + (lsw >> 16);return (msw << 16) | (lsw & 0xFFFF); }; function bit_rol(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)); }; function str2binl(str) { var bin = Array(); var mask = (1 << chrsz) - 1; for(var i = 0; i < str.length * chrsz; i += chrsz) bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32); return bin; }; function binl2str(bin) { var str = ""; var mask = (1 << chrsz) - 1; for(var i = 0; i < bin.length * 32; i += chrsz) str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask); return str; }; function binl2hex(binarray) { var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; var str = ""; for(var i = 0; i < binarray.length * 4; i++) { str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) + hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF); } return str; }; function binl2b64(binarray) { var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var str = ""; for(var i = 0; i < binarray.length * 4; i += 3) { var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16) | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 ) | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF); for(var j = 0; j < 4; j++) { if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); } } return str; };
+
+ <?php
+} elseif(isset($_GET['css']) && isset($_GET['id']) && isset($_GET['path'])) {
+ header('Content-type: text/css');
+ ?>
+ div#<?php echo $_GET['id']; ?>_master {
+ margin: 0;
+ padding: 0;
+ /* background-color: #DDD; */
+ }
+ div#<?php echo $_GET['id']; ?>_master a {
+ display: inline;
+ color: #0000FF;
+ }
+ div#<?php echo $_GET['id']; ?>_master textarea {
+ font-family: arial;
+ font-size: 7pt;
+ border: 1px solid #000;
+ padding: 0;
+ }
+ <?php
+}
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/index.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,21 @@
+<?php
+/*
+Plugin Name:
+Plugin URI:
+Description:
+Author:
+Version:
+Author URI:
+*/
+
+$_GET['title'] = 'Enano:Access_denied';
+require('../includes/common.php');
+header('HTTP/1.1 403 Forbidden');
+$session->perms['edit_page'] = AUTH_DENY;
+$session->perms['view_source'] = AUTH_DENY;
+$template->tpl_strings['PAGE_NAME'] = 'Access denied';
+
+$template->header();
+echo '<p>The administrator has flagged the page "' . $_SERVER['REQUEST_URI'] . '" so that it cannot be accessed from the web. Perhaps this is because this is a cache or includes directory and only needs to be accessed by scripts.</p><p>HTTP error: 403 Forbidden</p>';
+$template->footer();
+$db->close();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/schema.sql Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,31 @@
+CREATE TABLE {{TABLE_PREFIX}}categories( page_id varchar(64), namespace varchar(64), category_id varchar(64));
+CREATE TABLE {{TABLE_PREFIX}}comments( comment_id int(12) NOT NULL auto_increment, page_id text, namespace text, subject text, comment_data text, name text, approved tinyint(1) default 1, user_id mediumint(8) NOT NULL DEFAULT -1, time int(12) NOT NULL DEFAULT 0, PRIMARY KEY ( comment_id ));
+CREATE TABLE {{TABLE_PREFIX}}config( config_name varchar(63), config_value text);
+CREATE TABLE {{TABLE_PREFIX}}logs( log_type varchar(16), action varchar(16), time_id int(12) NOT NULL default '0', date_string varchar(63), page_id text, namespace text, page_text text, char_tag varchar(40), author varchar(63), edit_summary text, minor_edit tinyint(1));
+CREATE TABLE {{TABLE_PREFIX}}page_text( page_id varchar(63), namespace varchar(16) NOT NULL default 'Article', page_text text, char_tag varchar(63));
+CREATE TABLE {{TABLE_PREFIX}}pages( page_order int(8), name varchar(127), urlname varchar(63), namespace varchar(16) NOT NULL default 'Article', special tinyint(1) default '0', visible tinyint(1) default '1', comments_on tinyint(1) default '1', protected tinyint(1) NOT NULL DEFAULT 0, wiki_mode tinyint(1) NOT NULL DEFAULT 2, delvotes int(10) NOT NULL default 0, password varchar(40) NOT NULL DEFAULT '', delvote_ips text NOT NULL);
+CREATE TABLE {{TABLE_PREFIX}}session_keys( session_key varchar(32), salt varchar(32), user_id mediumint(8), auth_level tinyint(1) NOT NULL default '0', source_ip varchar(10) default '0x7f000001', time bigint(15) default '0');
+CREATE TABLE {{TABLE_PREFIX}}themes( theme_id varchar(63), theme_name text, theme_order smallint(5) NOT NULL default '1', default_style varchar(63) NOT NULL DEFAULT '', enabled tinyint(1) NOT NULL default '1');
+CREATE TABLE {{TABLE_PREFIX}}users( user_id mediumint(8) NOT NULL auto_increment, username text, password varchar(255), email text, real_name text, user_level tinyint(1) NOT NULL default 2, theme varchar(64) NOT NULL default 'bleu.css', style varchar(64) NOT NULL default 'default', signature text, reg_time int(11) NOT NULL DEFAULT 0, account_active tinyint(1) NOT NULL DEFAULT 0, activation_key varchar(40) NOT NULL DEFAULT 0, old_encryption tinyint(1) NOT NULL DEFAULT 0, temp_password text, temp_password_time int(12) NOT NULL DEFAULT 0, PRIMARY KEY (user_id));
+CREATE TABLE {{TABLE_PREFIX}}users_extra( user_id mediumint(8) NOT NULL, user_aim varchar(63), user_yahoo varchar(63), user_msn varchar(255), user_xmpp varchar(255), user_homepage text, user_location text, user_job text, user_hobbies text, email_public tinyint(1) NOT NULL DEFAULT 0, PRIMARY KEY ( user_id ) );
+CREATE TABLE {{TABLE_PREFIX}}banlist( ban_id mediumint(8) NOT NULL auto_increment, ban_type tinyint(1), ban_value varchar(64), is_regex tinyint(1) DEFAULT 0, reason text, PRIMARY KEY ( ban_id ) );
+CREATE TABLE {{TABLE_PREFIX}}files( file_id int(12) NOT NULL auto_increment, time_id int(12) NOT NULL, page_id varchar(63) NOT NULL, filename varchar(127) default NULL, size bigint(15) NOT NULL, mimetype varchar(63) default NULL, file_extension varchar(8) default NULL, file_key varchar(32) NOT NULL, PRIMARY KEY (file_id) );
+CREATE TABLE {{TABLE_PREFIX}}buddies( buddy_id int(15) NOT NULL auto_increment, user_id mediumint(8), buddy_user_id mediumint(8), is_friend tinyint(1) NOT NULL default '1', PRIMARY KEY (buddy_id) );
+CREATE TABLE {{TABLE_PREFIX}}privmsgs( message_id int(15) NOT NULL auto_increment, message_from varchar(63), message_to varchar(255), date int(12), subject varchar(63), message_text text, folder_name varchar(63), message_read tinyint(1) NOT NULL DEFAULT 0, PRIMARY KEY (message_id) );
+CREATE TABLE {{TABLE_PREFIX}}sidebar( item_id smallint(3) NOT NULL auto_increment, item_order smallint(3) NOT NULL DEFAULT 0, item_enabled tinyint(1) NOT NULL DEFAULT 1, sidebar_id smallint(3) NOT NULL DEFAULT 1, block_name varchar(63) NOT NULL, block_type tinyint(1) NOT NULL DEFAULT 0, block_content text, PRIMARY KEY ( item_id ));
+CREATE TABLE {{TABLE_PREFIX}}hits( hit_id bigint(20) NOT NULL auto_increment, username varchar(63) NOT NULL, time int(12) NOT NULL DEFAULT 0, page_id varchar(63), namespace varchar(63), PRIMARY KEY ( hit_id ) );
+CREATE TABLE {{TABLE_PREFIX}}search_index( word varbinary(64) NOT NULL, page_names text, PRIMARY KEY ( word ) );
+CREATE TABLE {{TABLE_PREFIX}}groups( group_id mediumint(5) UNSIGNED NOT NULL auto_increment, group_name varchar(64), group_type tinyint(1) NOT NULL DEFAULT 1, PRIMARY KEY ( group_id ) );
+CREATE TABLE {{TABLE_PREFIX}}group_members( member_id int(12) UNSIGNED NOT NULL auto_increment, group_id mediumint(5) UNSIGNED NOT NULL, user_id int(12) NOT NULL, is_mod tinyint(1) NOT NULL DEFAULT 0, pending tinyint(1) NOT NULL DEFAULT 0, PRIMARY KEY ( member_id ) );
+CREATE TABLE {{TABLE_PREFIX}}acl( rule_id int(12) UNSIGNED NOT NULL auto_increment, target_type tinyint(1) UNSIGNED NOT NULL, target_id int(12) UNSIGNED NOT NULL, page_id varchar(255), namespace varchar(24), rules text, PRIMARY KEY ( rule_id ) );
+CREATE TABLE {{TABLE_PREFIX}}search_cache( search_id int(15) NOT NULL auto_increment, search_time int(11) NOT NULL, query text, results longblob, PRIMARY KEY ( search_id ));
+INSERT INTO {{TABLE_PREFIX}}config(config_name, config_value) VALUES ('site_name', '{{SITE_NAME}}'), ('main_page', 'Main_Page'), ('site_desc', '{{SITE_DESC}}'), ('wiki_mode', '{{WIKI_MODE}}'), ('wiki_edit_notice', '0'), ('sflogo_enabled', '0'), ('sflogo_groupid', ''), ('sflogo_type', '1'), ('w3c_vh32', '0'), ('w3c_vh40', '0'), ('w3c_vh401', '0'), ('w3c_vxhtml10', '0'), ('w3c_vxhtml11', '0'), ('w3c_vcss', '0'), ('approve_comments', '0'), ('enable_comments', '1'), ('plugin_SpecialAdmin.php', '1'), ('plugin_SpecialPageFuncs.php', '1'), ('plugin_SpecialUserFuncs.php', '1'), ('plugin_SpecialCSS.php', '1'), ('copyright_notice', '{{COPYRIGHT}}'), ('wiki_edit_notice_text', '== Why can I edit this page? ==\n\nEveryone can edit almost any page in this website. This concept is called a wiki. It gives everyone the opportunity to make a change for the best. While some spam and vandalism may occur, it is believed that most contributions will be legitimate and helpful.\n\nFor security purposes, a history of all page edits is kept, and administrators are able to restore vandalized or spammed pages with just a few clicks.'), ('cache_thumbs', '{{ENABLE_CACHE}}'), ('max_file_size', '256000'),('enano_version', '{{VERSION}}'),( 'allowed_mime_types', 'cbf:len=168;crc=c3dcad3f;data=0[1],1[4],0[3],1[1],0[2],1[1],0[11],1[1],0[7],1[1],0[9],1[1],0[6],1[3],0[10],1[1],0[2],1[2],0[1],1[1],0[1],1[2],0[6],1[3],0[1],1[1],0[2],1[4],0[1],1[2],0[3],1[1],0[4],1[2],0[26],1[5],0[6],1[2],0[2],1[1],0[4],1[1],0[10],1[2],0[1],1[1],0[6]|end' ), ('contact_email', '{{ADMIN_EMAIL}}');
+INSERT INTO {{TABLE_PREFIX}}page_text(page_id, namespace, page_text, char_tag) VALUES ('Main_Page', 'Article', '=== Enano has been successfully installed! ===\n\nYou have finished installing Enano on this server. Congratulations!', '');
+INSERT INTO {{TABLE_PREFIX}}pages(page_order, name, urlname, namespace, special, visible, comments_on, protected, delvotes, delvote_ips) VALUES (NULL, 'Main Page', 'Main_Page', 'Article', 0, 1, 1, 1, 0, '');
+INSERT INTO {{TABLE_PREFIX}}themes(theme_id, theme_name, theme_order, default_style, enabled) VALUES ('oxygen', 'Oxygen', 1, 'bleu.css', 1),('stpatty', 'St. Patty', 2, 'shamrock.css', 1);
+INSERT INTO {{TABLE_PREFIX}}users(user_id, username, password, email, real_name, user_level, theme, style, signature, reg_time) VALUES(1, 'Anonymous', 'invalid-pass-hash', 'anonspam@enanocms.org', 'None', 1, 'stpatty', 'shamrock', '', 0);
+INSERT INTO {{TABLE_PREFIX}}users(user_id, username, password, email, real_name, user_level, theme, style, account_active, reg_time) VALUES (2, '{{ADMIN_USER}}', '{{ADMIN_PASS}}', '{{ADMIN_EMAIL}}', '{{REAL_NAME}}', 9, 'stpatty', 'shamrock', 1, UNIX_TIMESTAMP());
+INSERT INTO {{TABLE_PREFIX}}groups(group_id,group_name,group_type) VALUES(1, 'Everyone', 3),(2,'Administrators',3),(3,'Moderators',3);
+INSERT INTO {{TABLE_PREFIX}}group_members(group_id,user_id,is_mod) VALUES(2, 2, 1);
+INSERT INTO {{TABLE_PREFIX}}acl(target_type,target_id,page_id,namespace,rules) VALUES(1,2,NULL,NULL,'read=4;post_comments=4;edit_comments=4;edit_page=4;view_source=4;mod_comments=4;history_view=4;history_rollback=4;history_rollback_extra=4;protect=4;rename=4;clear_logs=4;vote_delete=4;vote_reset=4;delete_page=4;set_wiki_mode=4;password_set=4;password_reset=4;mod_misc=4;edit_cat=4;even_when_protected=4;upload_files=4;upload_new_version=4;create_page=4;php_in_pages=4;edit_acl=4;'),(1,3,NULL,NULL,'read=4;post_comments=4;edit_comments=4;edit_page=4;view_source=4;mod_comments=4;history_view=4;history_rollback=4;history_rollback_extra=4;protect=4;rename=3;clear_logs=2;vote_delete=4;vote_reset=4;delete_page=4;set_wiki_mode=2;password_set=2;password_reset=2;mod_misc=2;edit_cat=4;even_when_protected=4;upload_files=2;upload_new_version=3;create_page=3;php_in_pages=2;edit_acl=2;');
+INSERT INTO {{TABLE_PREFIX}}sidebar(item_id, item_order, sidebar_id, block_name, block_type, block_content) VALUES (1, 1, 1, 'Navigation', 1, '[[Main Page|Home]]'),(2, 2, 1, 'Tools', 1, '[[$NS_SPECIAL$CreatePage|Create a page]]\n[[$NS_SPECIAL$UploadFile|Upload file]]\n[[$NS_SPECIAL$SpecialPages|Special pages]]\n{if auth_admin}\n[[$NS_SPECIAL$EditSidebar|Edit the sidebar]]\n[[$NS_SPECIAL$Administration|Administration]]\n{/if}'),(3, 3, 1, '$USERNAME$', 1, '[[$NS_USER$$USERNAME$|User page]]\n[[$NS_SPECIAL$Contributions/$USERNAME$|My Contributions]]\n{if user_logged_in}\n[[$NS_SPECIAL$Preferences|Preferences]]\n[[$NS_SPECIAL$PrivateMessages|Private messages]]\n[[$NS_SPECIAL$Usergroups|Group control panel]]\n$THEME_LINK$\n{/if}\n{if user_logged_in}\n$LOGOUT_LINK$\n{else}\n[[$NS_SPECIAL$Register|Create an account]]\n$LOGIN_LINK$\n[[$NS_SPECIAL$Login/$NS_SPECIAL$PrivateMessages|Private messages]]\n{/if}'),(4, 4, 1, 'Search', 1, '<div class="slideblock2" style="padding: 0px;"><form action="$SCRIPTPATH$/$NS_SPECIAL$Search" method="get" style="padding: 0; margin: 0;"><p><input name="q" alt="Search box" type="text" size="10" style="width: 70%" /> <input type="submit" value="Go" style="width: 20%" /></p></form></div>'),(5, 2, 2, 'Links', 4, 'Links')
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/admin/comment.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,51 @@
+<div class="tblholder">
+ <table border="0" width="100%" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2" style="text-align: left;">{DATETIME}</th>
+ </tr>
+ <tr>
+ <td style="width: 120px; height: 100%;" rowspan="4" valign="top" class="row1">
+ <table border="0" width="100%" style="height: 100%;" cellspacing="0" cellpadding="0">
+ <tr>
+ <td valign="top" class="row1">
+ <b>{NAME}</b><br />
+ <small>{USER_LEVEL}</small>
+ </td>
+ </tr>
+ <tr>
+ <td valign="bottom" class="row1">
+ {SEND_PM_LINK} {ADD_BUDDY_LINK}
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td class="row2">
+ <b>Subject:</b> <span id="subject_{ID}">{SUBJECT}</span>
+ </td>
+ </tr>
+ <tr>
+ <td class="row3">
+ <div id="comment_{ID}">{DATA}</div>
+ <!-- BEGIN signature -->
+ <hr style="margin-left: 1em; width: 200px;" />
+ {SIGNATURE}
+ <!-- END signature -->
+ </td>
+ </tr>
+ <!-- BEGIN can_edit -->
+ <tr>
+ <td class="row2">
+ [ {EDIT_LINK} | {DELETE_LINK} ]
+ </td>
+ </tr>
+ <!-- END can_edit -->
+ <!-- BEGIN auth_mod -->
+ <tr>
+ <td class="row1">
+ <b>Moderation options:</b> {MOD_APPROVE_LINK} {MOD_DELETE_LINK}
+ </td>
+ </tr>
+ <!-- END auth_mod -->
+ </table>
+</div>
+<br />
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/admin/css/default.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,163 @@
+/*
+ * Enano theme specifically designed to make the admin panel work better
+ */
+
+
+body { color: #000000; background-color: #456798; font-family: arial, helvetica, sans-serif; font-size: 8pt; margin: 0; padding: 0; }
+
+div#header { font-family: georgia, serif; font-size: 11pt; background-color: #254778; padding: 10px; color: #FFFFFF; line-height: 55px; }
+div#header a { color: #C0D0F0; border-bottom: 1px dotted #a0c0f0; text-decoration: none; }
+div#header div.sitename { color: #B0C8F0; font-family: georgia, serif; font-weight: normal; font-size: 22pt; margin: 0 10px 0 0; padding: 0; float: left; }
+div#header div.menulink { float: right; padding: 0 10px 0 0; }
+div#header div.menulink a { text-decoration: underline; color: #FFFFFF; border-bottom-width: 0; }
+
+div#sidebar { position: absolute; background-color: #000010; color: #FFFFFF; padding: 0px; width: 200px; display: none; }
+div#sidebar h4 { background-color: #444444; margin: 0; padding: 5px; }
+div#sidebar ul { margin: 0; padding: 0; list-style: none; }
+div#sidebar ul li a { display: block; padding: 5px 8px; text-decoration: none; color: #FFFFFF; }
+div#sidebar ul li a:hover { background-color: #303030; }
+
+div.footer { margin: 10px 0 0 0; padding: 7px; text-align: center; border: 1px solid #A0A0A0; background-color: #e0e0e0; color: #666; }
+div.footer a { color: #777; text-decoration: underline; }
+
+table#wrapper { width: 100%; margin: 10px 0 0 0; }
+table#wrapper td.top-left { width: 37px; height: 28px; background-image: url(../images/window-topcorners.png); background-repeat: no-repeat; }
+table#wrapper td.top { height: 28px; background-image: url(../images/window-top.png); background-repeat: repeat-x; }
+table#wrapper td.top-right { width: 37px; height: 28px; background-image: url(../images/window-topcorners.png); background-repeat: no-repeat; background-position: -37px 0px; }
+table#wrapper td.left { width: 37px; background-image: url(../images/window-left.png); background-repeat: repeat-y; }
+table#wrapper td.main { background-color: #FFFFFF; }
+table#wrapper td.right { width: 37px; background-image: url(../images/window-right.png); background-repeat: repeat-y; }
+table#wrapper td.bottom-left { width: 37px; height: 44px; background-image: url(../images/window-bottomcorners.png); background-repeat: no-repeat; }
+table#wrapper td.bottom { height: 44px; background-image: url(../images/window-bottom.png); background-repeat: repeat-x; }
+table#wrapper td.bottom-right { width: 37px; height: 44px; background-image: url(../images/window-bottomcorners.png); background-repeat: no-repeat; background-position: -37px 0px; }
+
+/* Content area */
+table#wrapper td.main h2.pagename {
+ border-bottom: 1px solid #456798;
+ margin-bottom: 0;
+}
+
+table#wrapper td.main a {
+ color: #294F75;
+}
+table#wrapper td.main a:hover {
+ color: #597FA5;
+}
+
+/*
+ * jBox menu system
+ */
+
+div.menu {
+ background-color: #B0D0F0;
+ font-size: 7pt;
+ border-width: 0;
+}
+div.menu a, div.menu div.label {
+ padding: 2.5pt 5px;
+ margin-right: 3px;
+ text-decoration: none;
+ display: block;
+ float: left;
+ color: #406080;
+}
+div.menu div.label {
+ color: #001020;
+ cursor: default;
+}
+div.menu span.sep {
+ display: block;
+ float: left;
+ width: 5px;
+}
+div.menu div.multopts {
+ line-height: 17pt;
+}
+div.menu div.multopts a, div.menu div.multopts div.label {
+ float: none;
+ display: inline;
+}
+div.menu a.liteselected, div.menu a.liteselected:hover, div.menu a:hover {
+ color: #406080;
+ background-color: #D0F0FF;
+}
+div.menu input[type ^="text"], div.menu input[type ^="password"] {
+ border-width: 0;
+ font-size: 9pt;
+ padding: 4px 5px;
+ max-width: 70px;
+ background-color: #D0F0FF;
+}
+div.menu input[type ^="text"]:hover, div.menu input[type ^="password"]:hover {
+ background-color: #E0F0FF;
+}
+div.menu input[type ^="text"]:focus, div.menu input[type ^="password"]:focus {
+ background-color: #F0F0FF;
+}
+div.menu input[type ^="button"], div.menu input[type ^="submit"] {
+ border-width: 0;
+ font-size: 9pt;
+ padding: 3px 5px;
+ max-width: 70px;
+}
+div.menu a.current, div.menu a.current:hover, div.menu a.selected, div.menu a.selected:hover {
+ color: #000040;
+ background-color: #FFFFFF;
+}
+div.menu ul {
+ display: none;
+ position: absolute;
+ padding: 0;
+ margin: 0;
+ background-color: #B0D0F0;
+ border-width: 0;
+ min-width: 120px;
+}
+div.menu ul li {
+ list-style: none;
+}
+div.menu ul a {
+ float: none;
+ margin: 0;
+}
+span.menuclear {
+ font-size: 1px;
+ height: 0px;
+ width: 0px;
+ clear: left;
+ line-height: 0px;
+ display: block;
+}
+
+/* Buttons - this is CSS3 */
+input[type ^="button"], input[type ^="submit"] {
+ border-width: 1px;
+ border-color: #666;
+ border-style: solid;
+ background-color: #DDD;
+ color: #101010;
+ cursor: pointer;
+ font-size: 8pt;
+ font-family: arial, helvetica, sans-serif;
+ padding: 5px 3px;
+ background-image: url(../images/buttonbg.gif);
+ background-repeat: repeat-x;
+}
+
+input[type ^="button"]:hover, input[type ^="submit"]:hover {
+ border-color: #999;
+}
+
+input[type ^="button"]:active, input[type ^="submit"]:active {
+ padding: 6px 2px 4px 4px;
+ border-color: #333;
+}
+
+input[type ^="text"], input[type ^="password"] {
+ background-color: #F8FBFF;
+ border: 1px solid #254778;
+ font-size: 8pt;
+ font-family: arial, helvetica, sans-serif;
+ padding: 3px;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/admin/elements.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,40 @@
+<!-- VAR toolbar_button --><a href="{HREF}" {PARENTFLAGS} {FLAGS}>{TEXT}</a>
+<!-- ENDVAR toolbar_button -->
+<!-- VAR toolbar_label --><div class="label">{TEXT}</div>
+<!-- ENDVAR toolbar_label -->
+<!-- VAR toolbar_button_selected --><a href="{HREF}" class="current" {PARENTFLAGS} {FLAGS}>{TEXT}</a>
+<!-- ENDVAR toolbar_button_selected -->
+<!-- VAR toolbar_menu_button --><li><a href="{HREF}" {FLAGS}>{TEXT}</a></li>
+<!-- ENDVAR toolbar_menu_button -->
+<!-- VAR toolbar_menu_block --><li>{HTML}</li>
+<!-- ENDVAR toolbar_menu_block -->
+<!-- VAR sidebar_button --><li><a href="{HREF}" {FLAGS}>{TEXT}</a></li>
+<!-- ENDVAR sidebar_button -->
+<!-- VAR sidebar_raw -->{HTML}
+<!-- ENDVAR sidebar_raw -->
+<!-- VAR sidebar_heading --><h4>{TEXT}</h4>
+<!-- ENDVAR sidebar_heading -->
+<!-- VAR sidebar_top -->
+<!-- ENDVAR sidebar_top -->
+<!-- VAR sidebar_section -->
+ <h4>
+ <!-- BEGIN in_sidebar_admin -->{ADMIN_START}<!-- END in_sidebar_admin -->
+ {TITLE}
+ <!-- BEGIN in_sidebar_admin -->{ADMIN_END}<!-- END in_sidebar_admin -->
+ </h4>
+ <ul>
+ {CONTENT}
+ </ul>
+<!-- ENDVAR sidebar_section -->
+<!-- VAR sidebar_section_raw -->
+ <h4>
+ <!-- BEGIN in_sidebar_admin -->{ADMIN_START}<!-- END in_sidebar_admin -->
+ {TITLE}
+ <!-- BEGIN in_sidebar_admin -->{ADMIN_END}<!-- END in_sidebar_admin -->
+ </h4>
+ <div>
+ {CONTENT}
+ </div>
+<!-- ENDVAR sidebar_section_raw -->
+<!-- VAR sidebar_bottom -->
+<!-- ENDVAR sidebar_bottom -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/admin/footer.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,41 @@
+ </div>
+ <div class="footer">
+ {COPYRIGHT}<br />Powered by <a href="{CONTENTPATH}{NS_SPECIAL}About_Enano{ADMIN_SID_AUTO}">Enano</a> • Copyright © 2007 Dan Fuhry
+ </div>
+ </td>
+ <td class="right"></td>
+ </tr>
+ <tr>
+ <td class="bottom-left"></td><td class="bottom"></td><td class="bottom-right"></td>
+ </tr>
+ </table>
+ <div style="display: none;">
+ <h2>Your browser does not support CSS.</h2>
+ <p>If you can see this text, it means that your browser does not support Cascading Style Sheets (CSS). CSS is a fundemental aspect of XHTML, and as a result it is becoming very widely adopted by websites, including this one. You should consider switching to a more modern web browser, such as Mozilla Firefox or Opera 9.</p>
+ <p>Because of this, there are a few minor issues that you may experience while browsing this site, not the least of which is some visual elements below that would normally be hidden in most browsers. Please excuse these minor inconveniences.</p>
+ </div>
+ <div id="root1" class="jswindow" style="display: none;">
+ <div id="tb1" class="titlebar">Confirm Logout</div>
+ <div class="content" id="cn1">
+ <form action="{CONTENTPATH}Special:Logout" method="get">
+ <div style="text-align: center">
+ <h3>Are you sure you want to log out?</h3>
+ <input type="submit" value="Log out" style="font-weight: bold;" /> <input type="button" onclick="jws.closeWin('root1');" value="Cancel" />
+ </div>
+ </form>
+ </div>
+ </div>
+ <div id="root2" class="jswindow" style="display: none;">
+ <div id="tb2" class="titlebar">Change style</div>
+ <div class="content" id="cn2">
+
+ </div>
+ </div>
+ <div id="root3" class="jswindow" style="display: none;">
+ <div id="tb3" class="titlebar">Wiki formatting help</div>
+ <div class="content" id="cn3">
+ Loading...
+ </div>
+ </div>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/admin/header.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,42 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html>
+ <head>
+ <title>{PAGE_NAME} • {SITE_NAME}</title>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <link rel="stylesheet" type="text/css" href="{SCRIPTPATH}/includes/clientside/css/enano-shared.css" />
+ <link id="mdgCss" rel="stylesheet" type="text/css" href="{SCRIPTPATH}/themes/{THEME_ID}/css/{STYLE_ID}.css" />
+ {JS_DYNAMIC_VARS}
+ <script type="text/javascript" src="{SCRIPTPATH}/themes/admin/js/menu.js"></script>
+ <script type="text/javascript" src="{SCRIPTPATH}/includes/clientside/static/enano-lib-basic.js"></script>
+ {ADDITIONAL_HEADERS}
+ </head>
+ <body>
+ <div id="header">
+ <div class="sitename">{SITE_NAME}</div>
+ <div class="menulink"><a href="#" onclick="adminOpenMenu('sidebar', this); return false;">expand menu</a></div>
+ [ <a href="{SCRIPTPATH}/{ADMIN_SID_AUTO}">Main page »</a> ]
+ </div>
+ <div class="menu_nojs" id="pagebar_main">
+ <div class="label">Page tools</div>
+ {TOOLBAR}
+ <ul>
+ {TOOLBAR_EXTRAS}
+ </ul>
+ <span class="menuclear"> </span>
+ </div>
+ <div id="sidebar">
+ {SIDEBAR_LEFT}
+ {SIDEBAR_RIGHT}
+ </div>
+ <table border="0" cellspacing="0" cellpadding="0" id="wrapper">
+ <tr>
+ <td class="top-left"></td><td class="top"> </td><td class="top-right"></td>
+ </tr>
+ <tr>
+ <td class="left"></td>
+ <td class="main">
+ <div style="float: right;">
+ <image alt=" " src="{SCRIPTPATH}/images/spacer.gif" id="ajaxloadicon" />
+ </div>
+ <h2 class="pagename">{PAGE_NAME}</h2>
+ <div id="ajaxEditContainer">
Binary file themes/admin/images/buttonbg.gif has changed
Binary file themes/admin/images/window-bottom.png has changed
Binary file themes/admin/images/window-bottomcorners.png has changed
Binary file themes/admin/images/window-left.png has changed
Binary file themes/admin/images/window-right.png has changed
Binary file themes/admin/images/window-top.png has changed
Binary file themes/admin/images/window-topcorners.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/admin/js/menu.js Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,52 @@
+var menuClicked = false;
+var menuID = false;
+var menuParent = false;
+function adminOpenMenu(menu, parent)
+{
+ menuParent = parent;
+ if ( typeof(menu) == 'string' )
+ {
+ menu = document.getElementById(menu);
+ }
+ if(!menu)
+ {
+ alert('Menu object is invalid');
+ return false;
+ }
+ var off = fetch_offset(parent);
+ var dim = fetch_dimensions(parent);
+ var w = 200;
+ var top = off['top'] + dim['h'];
+ var left = off['left'] + dim['w'] - w;
+ menu.style.top = top + 'px';
+ menu.style.left = left + 'px';
+ menu.style.display = 'block';
+ menuID = menu.id;
+ setTimeout('setMenuoffEvents();', 500);
+ //if(!IE)
+ // parent.onclick = eval('(function() { this.onclick = function() { adminOpenMenu(\'' + menu.id + '\', this); return false; }; return false; } )');
+}
+
+function adminMenuOff()
+{
+ if ( menuID )
+ {
+ menu = document.getElementById(menuID);
+ menu.style.display = 'none';
+ menu.onmousedown = false;
+ menu.onmouseup = false;
+ menuID = false;
+ document.onclick = false;
+ //menuParent.onclick();
+ //menuParent = false;
+ }
+}
+
+function setMenuoffEvents()
+{
+ menu = document.getElementById(menuID);
+ menu.onmousedown = function() { menuClicked = true; }
+ menu.onmouseup = function() { setTimeout('menuClicked = false;', 100); }
+ document.onclick = function() { if ( menuClicked ) return false; adminMenuOff(); }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/admin/sidebar-editor.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,58 @@
+<!-- VAR sidebar_button --><li><a href="javascript:void(0)" {FLAGS}>{TEXT}</a></li>
+<!-- ENDVAR sidebar_button -->
+<!-- VAR sidebar_raw --><li><span style="text-align: center;">{HTML}</span></li>
+<!-- ENDVAR sidebar_raw -->
+<!-- VAR sidebar_top -->
+ <div class="recttop">
+ <table border="0" width="100%" cellspacing="0" cellpadding="0" style="font-size: 1px;">
+ <tr>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-menu-l.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;" class="recttoptop"></td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-menu-r.gif" width="12" height="12" /> </td>
+ </tr>
+ </table>
+ </div>
+<!-- ENDVAR sidebar_top -->
+<!-- VAR sidebar_section -->
+ <div class="dbx-box">
+ <div class="dbx-handle">
+ {ADMIN_START}
+
+ {TITLE}
+ {ADMIN_END}
+
+ </div>
+ <div class="dbx-content">
+ <ul>
+ {CONTENT}
+ </ul>
+ </div>
+ </div>
+<!-- ENDVAR sidebar_section -->
+<!-- VAR sidebar_section_raw -->
+ <div class="dbx-box">
+ <div class="dbx-handle">
+ {ADMIN_START}
+
+ {TITLE}
+ {ADMIN_END}
+
+ </div>
+ <div class="dbx-content dbx-content2">
+ <ul><li>
+ {CONTENT}
+ </li></ul>
+ </div>
+ </div>
+<!-- ENDVAR sidebar_section_raw -->
+<!-- VAR sidebar_bottom -->
+ <div class="rectbot">
+ <table border="0" width="100%" cellspacing="0" cellpadding="0" style="font-size: 1px;">
+ <tr>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-bl.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;" class="rectbottop"></td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-br.gif" width="12" height="12" /> </td>
+ </tr>
+ </table>
+ </div>
+<!-- ENDVAR sidebar_bottom -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/admin/simple-footer.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,41 @@
+ </div>
+ <div class="footer">
+ {COPYRIGHT}<br />Powered by <a href="{CONTENTPATH}{NS_SPECIAL}About_Enano{ADMIN_SID_AUTO}">Enano</a> • Copyright © 2007 Dan Fuhry
+ </div>
+ </td>
+ <td class="right"></td>
+ </tr>
+ <tr>
+ <td class="bottom-left"></td><td class="bottom"></td><td class="bottom-right"></td>
+ </tr>
+ </table>
+ <div style="display: none;">
+ <h2>Your browser does not support CSS.</h2>
+ <p>If you can see this text, it means that your browser does not support Cascading Style Sheets (CSS). CSS is a fundemental aspect of XHTML, and as a result it is becoming very widely adopted by websites, including this one. You should consider switching to a more modern web browser, such as Mozilla Firefox or Opera 9.</p>
+ <p>Because of this, there are a few minor issues that you may experience while browsing this site, not the least of which is some visual elements below that would normally be hidden in most browsers. Please excuse these minor inconveniences.</p>
+ </div>
+ <div id="root1" class="jswindow" style="display: none;">
+ <div id="tb1" class="titlebar">Confirm Logout</div>
+ <div class="content" id="cn1">
+ <form action="{CONTENTPATH}Special:Logout" method="get">
+ <div style="text-align: center">
+ <h3>Are you sure you want to log out?</h3>
+ <input type="submit" value="Log out" style="font-weight: bold;" /> <input type="button" onclick="jws.closeWin('root1');" value="Cancel" />
+ </div>
+ </form>
+ </div>
+ </div>
+ <div id="root2" class="jswindow" style="display: none;">
+ <div id="tb2" class="titlebar">Change style</div>
+ <div class="content" id="cn2">
+
+ </div>
+ </div>
+ <div id="root3" class="jswindow" style="display: none;">
+ <div id="tb3" class="titlebar">Wiki formatting help</div>
+ <div class="content" id="cn3">
+ Loading...
+ </div>
+ </div>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/admin/simple-header.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,42 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html>
+ <head>
+ <title>{PAGE_NAME} • {SITE_NAME}</title>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <link rel="stylesheet" type="text/css" href="{SCRIPTPATH}/includes/clientside/css/enano-shared.css" />
+ <link id="mdgCss" rel="stylesheet" type="text/css" href="{SCRIPTPATH}/themes/{THEME_ID}/css/{STYLE_ID}.css" />
+ {JS_DYNAMIC_VARS}
+ <script type="text/javascript" src="{SCRIPTPATH}/themes/admin/js/menu.js"></script>
+ <script type="text/javascript" src="{SCRIPTPATH}/includes/clientside/static/enano-lib-basic.js"></script>
+ {ADDITIONAL_HEADERS}
+ </head>
+ <body>
+ <div id="header">
+ <div class="sitename">{SITE_NAME}</div>
+ <div class="menulink"><a href="#" onclick="adminOpenMenu('sidebar', this); return false;">expand menu</a></div>
+ [ <a href="{SCRIPTPATH}/{ADMIN_SID_AUTO}">Main page »</a> ]
+ </div>
+ <div class="menu_nojs" id="pagebar_main">
+ <div class="label">Page tools</div>
+ {TOOLBAR}
+ <ul>
+ {TOOLBAR_EXTRAS}
+ </ul>
+ <span class="menuclear"> </span>
+ </div>
+ <div id="sidebar">
+ {SIDEBAR_LEFT}
+ {SIDEBAR_RIGHT}
+ </div>
+ <table border="0" cellspacing="0" cellpadding="0" id="wrapper">
+ <tr>
+ <td class="top-left"></td><td class="top"> </td><td class="top-right"></td>
+ </tr>
+ <tr>
+ <td class="left"></td>
+ <td class="main">
+ <div style="float: right;">
+ <image alt=" " src="{SCRIPTPATH}/images/spacer.gif" id="ajaxloadicon" />
+ </div>
+ <h2 class="pagename">{PAGE_NAME}</h2>
+ <div id="ajaxEditContainer">
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/admin/theme.cfg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,18 @@
+<?php
+/*
+ * Admin theme for Enano
+ * Created by dandaman32 - (C) 2007
+ * License: GPL
+ *
+ * This theme is free software; you can redistribute and/or modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This theme is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+global $theme;
+$theme['theme_id'] = 'admin';
+$theme['theme_name'] = 'Admin';
+
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/boxart/acledit.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,36 @@
+<!-- VAR acl_field_begin -->
+<div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4" style="width: 100%;">
+ <tr>
+ <th></th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('1');">Deny</th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('2');">Disallow</th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('3');">Wiki mode</th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('4');">Allow</th>
+ </tr>
+<!-- ENDVAR acl_field_begin -->
+<!-- VAR acl_field_item -->
+ <tr>
+ <td class="{ROW_CLASS}">{FIELD_DESC}</td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="1" name="{FIELD_NAME}" {FIELD_DENY_CHECKED} /></td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="2" name="{FIELD_NAME}" {FIELD_DISALLOW_CHECKED} /></td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="3" name="{FIELD_NAME}" {FIELD_WIKIMODE_CHECKED} /></td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="4" name="{FIELD_NAME}" {FIELD_ALLOW_CHECKED} /></td>
+ </tr>
+<!-- ENDVAR acl_field_item -->
+<!-- VAR acl_field_end -->
+ <tr>
+ <td colspan="5" class="row3">
+ <p><b>Permission types:</b></p>
+ <ul>
+ <li><b>Allow</b> means that the user is allowed to access the item</li>
+ <li><b>Wiki mode</b> means the user can access the item if wiki mode is active (per-page wiki mode is taken into account)</li>
+ <li><b>Disallow</b> means the user is denied access unless something allows it.</li>
+ <li><b>Deny</b> means that the user is denied access to the item. This setting overrides all other permissions.</li>
+ </ul>
+ </td>
+ </tr>
+ </table>
+</div>
+<!-- ENDVAR acl_field_end -->
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/boxart/comment.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,51 @@
+<div class="mdg-comment" style="padding: 0px;">
+ <table border="0" width="100%" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2" style="text-align: left;">{DATETIME}</th>
+ </tr>
+ <tr>
+ <td style="width: 120px; height: 100%;" rowspan="4" valign="top" class="row1">
+ <table border="0" width="100%" style="height: 100%;" cellspacing="0" cellpadding="0">
+ <tr>
+ <td valign="top" class="row1">
+ <b>{NAME}</b><br />
+ <small>{USER_LEVEL}</small>
+ </td>
+ </tr>
+ <tr>
+ <td valign="bottom" class="row1">
+ {SEND_PM_LINK} {ADD_BUDDY_LINK}
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td class="row2">
+ <b>Subject:</b> <span id="subject_{ID}">{SUBJECT}</span>
+ </td>
+ </tr>
+ <tr>
+ <td class="row3">
+ <div id="comment_{ID}">{DATA}</div>
+ <!-- BEGIN signature -->
+ <hr style="margin-left: 1em; width: 200px;" />
+ {SIGNATURE}
+ <!-- END signature -->
+ </td>
+ </tr>
+ <!-- BEGIN can_edit -->
+ <tr>
+ <td class="row2">
+ [ {EDIT_LINK} | {DELETE_LINK} ]
+ </td>
+ </tr>
+ <!-- END can_edit -->
+ <!-- BEGIN auth_mod -->
+ <tr>
+ <td class="row1">
+ <b>Moderation options:</b> {MOD_APPROVE_LINK} {MOD_DELETE_LINK}
+ </td>
+ </tr>
+ <!-- END auth_mod -->
+ </table>
+</div>
+<br />
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/boxart/css-simple/blackjack.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,4 @@
+div#credits { text-align: center; background-color: #78837D; }
+table#enano-main { margin: 0 auto; }
+td#header-banner { background-color: #78837D; }
+td#header-banner h1 { color: #C8D3CD; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/boxart/css-simple/blueberry.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,4 @@
+div#credits { text-align: center; background-color: #355788; }
+table#enano-main { margin: 0 auto; }
+td#header-banner { background-color: #355788; }
+td#header-banner h1 { color: #C5E7FF; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/boxart/css/#Untitled-2# Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,29 @@
+<nowiki><script type='text/javascript' src='/email.js'></script><h2>Welcome to my homepage.</h2></nowiki>
+
+Please add more content here, including an introductory "Hi, my name is Debbie Fuhry", etc etc.
+{| border="0"
+|-
+| [[:File:debbie1.jpg]]
+<nowiki><span style="font-size: 66%"><i>Photo by Becky</i></span></nowiki>
+| style="padding-left: 10px;"
+===I am...===
+
+A homeschool mom: I have two kids, Tim, age 13 and Becky, age 11. I've been homeschooling them since Tim was 5 years old.
+An aspiring author: See the descriptions of [[Onesimus books|my books]], Free Indeed, hopefully to get published this year, and Faithful unto Death, which I'm still writing.
+
+===Contact me===
+
+You can either <nowiki><a href='javascript:dive("2286 815 1143 1143 538 815 2435 2286 815 1143 1143 538 815 2295 314 2406 1656 893 670 295 818 1916",2567,343)' onMouseOver="self.status=''; return true;" onMouseOut="self.status=' '; return true;">e-mail me</a></nowiki>, or visit my [http://blogs.fuhrykitchentable.no-ip.org/debbie/ blog].
+Note: if your web browser is very old, the e-mail link may appear as a bunch of jumbled numbers or it may not work at all. This is because I use an encrypted e-mail link on this page in an effort to avoid spam.
+|}
+
+===Verse of the month===
+
+'''Proverbs 3:11-12'''
+''"My son, do not despise the Lord's discipline and do not resent his rebuke, because the Lord disciplines those he loves, as a father the son he delights in."''
+
+===Quote of the month===
+
+''"Then from the dawn it seem'd there came, but faint As from beyond the limit of the world, Like the last echo born of a great cry Sounds, as if some fair city were one voice Around a king returning from his wars."''
+
+Tennyson, __Idylls of the King__ on the death of Arthur
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/boxart/css/_printable.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,75 @@
+html,body { height: 100%; }
+body { margin: 0; padding: 0; background: #FFFFFF font-family: trebuchet ms, verdana, arial, helvetica, sans-serif; font-size: 9pt; }
+.holder { border: 1px solid #CCCCCC; padding: 1px; background-color: #FFFFFF; color: #444444 }
+div.pad { padding: 10px; }
+table#title { margin: 0; padding: 0; height: 100px; background-color: #FFFFFF; text-align: center; border: 1px solid #000000; border-bottom: 0px solid #000000; }
+td.mdgSidebarHolder { width: 0px; }
+div.sidebar { display: none; width: 0px; background-color: #F8F8F8; border-left: 1px solid #CCC; border-right: 1px solid #CCC; padding: 1px 0px 0px 0px; }
+div.sidebar .head { background-color: #F0F0F0; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #111; padding: 5px; font-weight: bold; }
+div.sidebar .head:hover { background-color: #F4F4F4; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #111; padding: 5px; font-weight: bold; }
+div.sidebar div.slideblock a { background-color: #DDD; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #666; padding: 5px 5px 5px 9px; }
+div.sidebar div.slideblock a:hover { background-color: #EEE; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #666; padding: 5px 5px 5px 9px; }
+div.recttop { display: none; width: 0px; height: 12px; margin: 0; padding: 0; }
+td.recttoptop { width: 100%; height: 12px; background-image: url({SCRIPTPATH}/themes/oxygen/images/border-menu-t.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+div.rectbot { display: none; width: 0px; height: 12px; margin: 0; padding: 0; }
+td.rectbottop { width: 100%; height: 12px; background-image: url({SCRIPTPATH}/themes/oxygen/images/border-btm.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+div.slideblock { overflow: hidden; }
+div.slideblock2 { overflow: hidden; background-color: #DDD; margin: 0px 1px 0px 1px; }
+div#credits { margin: 0; padding: 10px; background-color: #FFFFFF; border: 1px solid #AAA; color: #AAA; font-size: 7pt; }
+div#credits a { color: #888888; text-decoration: underline; }
+div#credits a:hover { color: #888888; text-decoration: underline; }
+
+div#content h2 { border-bottom: 1px solid #666666; margin-bottom: 0; }
+div#content h3 { font-size: 11pt; font-weight: bold; }
+div#content p { margin-left: 1.0em; }
+div#content { font-size: 9pt; }
+div#content a { color: #000000; text-decoration: underline; }
+div#content a:hover { color: #000000; text-decoration: underline; }
+td#mainhead a { text-decoration: none; color: #000000; }
+td#mainhead a:hover { text-decoration: none; color: #000000; border-bottom: 1px dotted #606060; }
+
+div#content a.wikilink-nonexistent { color: #B05020; }
+div#content a.wikilink-nonexistent:hover { color: #D06030; }
+
+.mdg-comment { margin-left: 1em; padding: 7px; border: 1px solid #AAAAAA; background-color: #E8E8E8; }
+
+div.pagebar { background-color: #FFFFFF; margin-top: 0px; padding: 3px; font-size: 7pt; border: 1px solid #000000; }
+div.pagebar a { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #606060; }
+div.pagebar a:hover { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #606060; background-color: #E0E0E0; }
+div.pagebar#pagebarpopup { display: none; position: absolute; width: 150px; padding: 0; }
+div.pagebar#pagebarpopup a { display: block; margin: 0; }
+
+/* Rounded corners on nearly everything */
+td#mdg-tl { width: 0px; height: 0px; }
+td#mdg-tr { width: 0px; height: 0px; }
+td#mdg-top { width: 0px; height: 0px; }
+td#mdg-l { width: 0px; height: 0px; }
+td#mdg-r { width: 0px; height: 0px; }
+td#mdg-bl { width: 0px; height: 0px; }
+td#mdg-br { width: 0px; height: 0px; }
+td#mdg-ml { width: 0px; height: 0px; }
+td#mdg-mr { width: 0px; height: 0px; }
+td#mdg-brl { width: 0px; height: 0px; }
+td#mdg-brr { width: 0px; height: 0px; }
+td#mdg-btl { width: 0px; height: 0px; }
+td#mdg-btr { width: 0px; height: 0px; }
+td#mdg-btcl { width: 0px; height: 0px; }
+td#mdg-btcr { width: 0px; height: 0px; }
+td#mdg-btm { width: 0px; height: 0px; }
+td#mdg-menu-tl { width: 0px; height: 0px; }
+td#mdg-menu-tr { width: 0px; height: 0px; }
+td#mdg-menu-bl { width: 0px; height: 0px; }
+td#mdg-menu-br { width: 0px; height: 0px; }
+td#mdg-menu-top { width: 0px; height: 0px; }
+td#mdg-menu-btm { width: 0px; height: 0px; }
+
+input, textarea, select { border: 1px solid #606060; background-color: #FFFFFF; padding: 3px; }
+input:hover, textarea:hover, select:hover { border: 1px solid #606060; background-color: #FFFFFF; padding: 3px; }
+input:focus, textarea:focus, select:focus { border: 1px solid #606060; background-color: #FFFFFF; padding: 3px; }
+
+div.jswindow { border: 2px solid #7090B0; border-top: 5px solid #7090B0; padding: 0px; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; display: none; position: absolute; background-color: #FFFFFF; }
+div.titlebar { background-color: #7090B0; color: #FFFFFF; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; padding-bottom: 4px; cursor: default; }
+div.titlebar div.closebtn { width: 16px; height: 16px; border: 1px solid #B0D0F0; background-color: #90B0D0; display: block; }
+div.titlebar div.closebtn:hover { width: 16px; height: 16px; border: 1px solid #FFFFFF; background-color: #B0D0F0; display: block; }
+div.titlebar table, div.titlebar td { margin: 0; padding: 0; }
+div.jswindow div.content { padding: 10px; margin: 0; background-color: #FFFFFF; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/boxart/css/blackjack.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,259 @@
+/**
+ * Box Art for Enano - make your website look like the old Enano, er, Midget, er, AdvancedArticles?
+ * Designed by Dan Fuhry, (C) 2006
+ * This theme is Free Software; see the file "GPL" included with this package for details.
+ */
+
+/* The basics */
+html,body { height: 100%; }
+body { margin: 0; padding: 0; background: #88938D; font-family: arial, helvetica, sans-serif; font-size: 9pt; }
+.holder { border: 1px solid #CCCCCC; padding: 1px; background-color: #FFFFFF; color: #444444; }
+div.pad { padding: 10px; }
+table#enano-master { height: 100%; }
+
+/* Sidebar */
+td.mdgSidebarHolder { width: 156px; }
+div.sidebar, .dbx-group { width: 154px; background-color: #88938D; padding: 1px 0px 0px 0px; }
+div.sidebar .head, .dbx-handle { font-family: Arial, helvetica, sans-serif; font-size: 9pt; cursor: pointer; border: 1px solid #000000;background-color: #A7AFA7;color: #000000; margin: 0px 3px 2px 3px; padding: 3px 3px 5px 3px; text-decoration: none; display: block; }
+div.sidebar .head:hover, .dbx-handle:hover { font-family: Arial, helvetica, sans-serif; font-size: 9pt; cursor: pointer; border: 1px solid #000000;background-color: #A8B3AD;color: #000000; margin: 0px 3px 2px 3px; padding: 3px 3px 5px 3px; text-decoration: none; display: block; }
+div.sidebar div.slideblock a , .dbx-content a { font-family: Arial, helvetica, sans-serif; font-size: 9pt; cursor: pointer; border: 1px solid #575F57;background-color: #B8BDB8;color: #575F57; margin: 0px 3px 2px 7px; padding: 7px 3px 7px 5px; text-decoration: none; display: block; text-align: right; }
+div.sidebar div.slideblock a:hover, .dbx-content a:hover { font-family: Arial, helvetica, sans-serif; font-size: 9pt; cursor: pointer; border: 1px solid #272F27;background-color: #989D98;color: #000000; margin: 0px 3px 2px 7px; padding: 7px 3px 7px 5px; text-decoration: none; display: block; text-align: right; }
+div.recttop { width: 156px; height: 12px; margin: 0; padding: 0; }
+td.recttoptop { width: 100%; height: 12px; background-image: url({SCRIPTPATH}/themes/boxart/images/border-menu-t.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+td.recttoptop:hover { width: 100%; height: 12px; background-image: url({SCRIPTPATH}/themes/boxart/images/border-menu-t-h.gif); background-repeat: repeat-x; margin: 0; padding: 0; cursor: pointer; }
+div.rectbot { width: 156px; height: 12px; margin: 0; padding: 0; }
+td.rectbottop { width: 100%; height: 12px; background-image: url({SCRIPTPATH}/themes/boxart/images/border-btm.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+div.slideblock, .dbx-content { overflow: hidden; }
+div.slideblock2, .dbx-content2 { overflow: hidden; background-color: #88938D; margin: 0px 1px 0px 1px; }
+.dbx-handle { cursor: move; }
+
+/* The credits thingy at the bottom */
+div#credits { margin: 0; background-color: #88938D; color: #FFF; font-size: 7pt; text-align: right; padding: 3px; }
+div#credits a { color: #A8B3AD; text-decoration: none; }
+div#credits a:hover { color: #C8D3CD; text-decoration: underline; }
+
+/* The link hidden in plain "site" at the top of the page */
+td#mainhead a { text-decoration: none; color: #000000; }
+td#mainhead a:hover { text-decoration: none; color: #000000; border-bottom: 1px dotted #406080; }
+
+#enanomain { background-color: #C8CDC8; color: #272F27; }
+
+/* Text, headings, and links inside the main div (usually #ajaxEditContainer but used some other places as well) */
+div.contentDiv h2 { border-bottom: 1px solid #8E9B80; margin-bottom: 0; }
+div.contentDiv h3 { font-size: 11pt; font-weight: bold; }
+div.contentDiv li { list-style: url({SCRIPTPATH}/themes/boxart/images/bullet.gif); }
+div.contentDiv p { margin-left: 1.0em; }
+div.contentDiv blockquote { background-color: #F4F4F4; border: 1px dotted #406080; margin: 1em; padding: 10px; max-height: 250px; overflow: auto; }
+div.contentDiv { font-size: 9pt; padding: 0px 10px 10px 10px; }
+div.contentDiv a { color: #2E3B20; text-decoration: none; border-bottom: 1px dotted #666; border-top: 1px dotted #666; }
+div.contentDiv a:hover { color: #8E9B80; text-decoration: none; border-bottom: 1px dotted #AAA; border-top: 1px dotted #AAA; }
+div.contentDiv a[href ^="http://"] { color: #4E5B40; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/external.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="https://"]{ color: #4E5B40; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/https.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="irc://"] { color: #4E5B40; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/irc.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="mailto:"] { color: #4E5B40; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/email.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="http://"]:hover { color: #6E7B60; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/external.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="https://"]:hover { color: #6E7B60; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/https.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="mailto:"]:hover { color: #6E7B60; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/email.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="irc://"]:hover { color: #6E7B60; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/irc.gif) center right no-repeat; padding-right: 16px; }
+
+/* Wikilinks to pages that don't exist */
+div.contentDiv a.wikilink-nonexistent { color: #B05020; }
+div.contentDiv a.wikilink-nonexistent:hover { color: #D06030; }
+
+/* Well, not Midget and not comments (usually), but that's what the class is called ;-). Basically an informational window or used as a wrapper for tables. */
+.mdg-comment { margin-left: 1em; padding: 7px; border: 1px solid #AAAAAA; background-color: #D8DCDD; }
+.tblholder { margin-left: 1em; padding: 0px; border: 1px solid #AAAAAA; background-color: #D8DCDD; }
+
+/* The beautiful tables inside what may not obviously be mdg-comment divs */
+.tblholder td.row1 { padding: 4px; background-color: #D8DDD8 !important; }
+.tblholder td.row2 { padding: 4px; background-color: #E8EDE8 !important; }
+.tblholder td.row3 { padding: 4px; background-color: #E0E6E0 !important; }
+.tblholder th { padding: 4px; background-color: #68736D !important; font-weight: bold; text-align: center; color: #FFFFFF; }
+.tblholder th.subhead { padding: 4px; background-color: #88938D !important; font-weight: bold; text-align: center; color: #FFFFFF; }
+.tblholder table { background-color: #FFFFFF; }
+
+/* Same as mdg-comment, but without the cute comment icon. Mostly unused. */
+.mdg-infobox { margin-left: 1em; padding: 7px; border: 1px solid #AAAAAA; background-color: #D8DCDD; }
+
+/* The "page tools" bar below the site logo but above the page content * /
+div.pagebar { background-color: #A8B3AD; margin-top: 0px; padding: 3px; font-size: 7pt; }
+div.pagebar a { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #48534D; }
+div.pagebar a:hover { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #48534D; background-color: #C8D3CD; }
+div.pagebar input { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #E0F0FF; }
+div.pagebar input:hover { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #D0F0FF; }
+div.pagebar input:focus { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #F0F0FF; }
+
+/* Tweaks for the popup menu version of the same thing * /
+div.pagebar#pagebarpopup { display: none; position: absolute; width: 150px; padding: 0; }
+div.pagebar#pagebarpopup a { display: block; margin: 0; }
+
+/*
+ * jBox menu system
+ */
+
+div.menu {
+ background-color: #A8B3AD;
+ font-size: 7pt;
+ border-width: 0;
+}
+div.menu a, div.menu div.label {
+ padding: 2.5pt 5px;
+ margin-right: 3px;
+ text-decoration: none;
+ display: block;
+ float: left;
+ color: #48534D;
+ border-top-width: 0px !important;
+ border-bottom-width: 0px !important;
+}
+div.menu div.label {
+ color: #201000;
+ cursor: default;
+}
+div.menu span.sep {
+ display: block;
+ float: left;
+ width: 5px;
+}
+div.menu div.multopts {
+ line-height: 17pt;
+}
+div.menu div.multopts a, div.menu div.multopts div.label {
+ float: none;
+ display: inline;
+}
+div.menu a.liteselected, div.menu a.liteselected:hover, div.menu a:hover {
+ color: #281700;
+ background-color: #C8D3CD;
+}
+div.menu input[type ^="text"], div.menu input[type ^="password"] {
+ border-width: 0;
+ font-size: 9pt;
+ padding: 4px 5px;
+ max-width: 70px;
+ background-color: #C8CDC8;
+}
+div.menu input[type ^="text"]:hover, div.menu input[type ^="password"]:hover {
+ background-color: #D8DDD8;
+}
+div.menu input[type ^="text"]:focus, div.menu input[type ^="password"]:focus {
+ background-color: #E8EDE8;
+}
+div.menu input[type ^="button"], div.menu input[type ^="submit"] {
+ border-width: 0;
+ font-size: 9pt;
+ padding: 3px 5px;
+ max-width: 70px;
+}
+div.menu a.current, div.menu a.current:hover, div.menu a.selected, div.menu a.selected:hover {
+ color: #402000;
+ background-color: #C8CDC8;
+}
+div.menu ul {
+ display: none;
+ position: absolute;
+ padding: 0;
+ margin: 0;
+ background-color: #A8B3AD;
+ border-width: 0;
+ min-width: 120px;
+}
+div.menu ul li {
+ list-style: none;
+}
+div.menu ul a {
+ float: none;
+ margin: 0;
+}
+span.menuclear {
+ font-size: 1px;
+ height: 0px;
+ width: 0px;
+ clear: left;
+ line-height: 0px;
+ display: block;
+}
+
+/* Buttons and textboxes - these settings are used almost everywhere */
+input, textarea, select { border: 1px solid #48534D; background-color: #98A39D; padding: 3px; }
+input:hover, textarea:hover, select:hover { border: 1px solid #68736D; background-color: #A8B3AD; padding: 3px; }
+input:focus, textarea:focus, select:focus { border: 1px solid #98A39D; background-color: #C8D3CD; padding: 3px; }
+label { padding: 3px; cursor: pointer; }
+label:hover { padding: 3px; cursor: pointer; background-color: #F0F0F0; }
+
+/* JWS window theming */
+div.jswindow { border: 2px solid #98A39D; border-top: 5px solid #98A39D; padding: 0px; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; display: none; position: absolute; background-color: #D8DCDD; }
+div.titlebar { background-color: #98A39D; color: #272F27; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; padding-bottom: 4px; cursor: default; }
+div.titlebar div.closebtn { width: 16px; height: 16px; border: 1px solid #272F27; background-color: #98A39D; display: block; }
+div.titlebar div.closebtn:hover { width: 16px; height: 16px; border: 1px solid #474F47; background-color: #A8B3AD; display: block; }
+div.titlebar table, div.titlebar td { margin: 0; padding: 0; }
+div.jswindow div.content { padding: 10px; margin: 0; background-color: #D8DCDD; }
+
+/* The Wordpress-like fills behind checkboxes and their labels */
+.catCheck { padding: 3px; }
+.catCheck:hover { padding: 3px; background-color: #F0F0F0; }
+
+/* Information, warning, question, error, and wait boxes */
+div.error-box { background-image: url({SCRIPTPATH}/images/error.png); background-repeat: no-repeat; background-color: #FFF4F4; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.info-box { background-image: url({SCRIPTPATH}/images/info.png); background-repeat: no-repeat; background-color: #F4F4FF; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.warning-box { background-image: url({SCRIPTPATH}/images/warning.png); background-repeat: no-repeat; background-color: #FFFFF4; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.question-box { background-image: url({SCRIPTPATH}/images/question.png); background-repeat: no-repeat; background-color: #F4FFF4; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.wait-box { background-image: url({SCRIPTPATH}/images/wait.png); background-repeat: no-repeat; background-color: #FFF4FF; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+
+/* This stuff is mostly unused, left in for compatibility */
+div#ajaxEditContainer table { border: 0px solid #FFFFFF; }
+div#ajaxEditContainer td { margin: 1px; }
+/* div#ajaxEditContainer { overflow: auto; } /* Makes ajaxEditContainer scroll horizontally in firefox if the content is too wide - prevents that ugly clipping effect */
+div#ajaxEditContainer pre { margin-left: 1em; background-color: #F8F8F8; border: 1px dashed #90B0D0; padding: 10px; overflow: auto; max-height: 150px; }
+
+/*
+ * Docking Boxes code (for the sidebar editor)
+ */
+
+/* group container(s) */
+#sbedit {
+ margin: 0;
+ padding: 0;
+ /* position:relative; /* additional outer containers must also have position:relative */
+}
+/* keyboard navigation tooltip */
+.dbx-tooltip {
+ display:block;
+ position:absolute;
+ margin:36px 0 0 125px;
+ width:185px;
+ border:1px solid #000;
+ background:#ffd;
+ color:#000;
+ font:normal normal normal 0.85em tahoma, arial, sans-serif;
+ padding:2px 4px 3px 5px;
+ text-align:left;
+ }
+* html .dbx-tooltip { width:195px; }
+
+/* use CSS2 system colors in CSS2 browsers
+ but not safari, which doesn't support them */
+*[class="dbx-tooltip"]:lang(en) {
+ border-color:InfoText;
+ background:InfoBackground;
+ color:InfoText;
+ font:small-caption;
+ font-weight:normal;
+ }
+/* additional clone styles */
+.dbx-clone {
+ opacity: 0.8;
+}
+.dbx-content ul {
+ margin: 0; padding: 0; list-style-type: none;
+}
+.dbx-content li a, .dbx-content li a:hover {
+ text-decoration: none; color: #666;
+}
+.dbx-content li, .dbx-content2 li {
+ list-style-type: none;
+}
+.dbx-content2 {
+ background-color: #DDD; margin: 0px 1px 0px 1px;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/boxart/css/blueberry.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,255 @@
+/**
+ * Box Art for Enano - make your website look like the old Enano, er, Midget, er, AdvancedArticles?
+ * Designed by Dan Fuhry, (C) 2006
+ * This theme is Free Software; see the file "GPL" included with this package for details.
+ */
+
+/* The basics */
+html,body { height: 100%; }
+body { margin: 0; padding: 0; background: #456798; font-family: trebuchet ms, verdana, arial, helvetica, sans-serif; font-size: 9pt; }
+.holder { border: 1px solid #CCCCCC; padding: 1px; background-color: #FFFFFF; color: #444444; }
+div.pad { padding: 10px; }
+table#enano-master { height: 100%; }
+
+/* Sidebar */
+td.mdgSidebarHolder { width: 156px; }
+div.sidebar, .dbx-group { width: 154px; background-color: #456798; padding: 1px 0px 0px 0px; }
+div.sidebar .head, .dbx-handle { font-family: trebuchet ms, verdana, Arial, helvetica, sans-serif; font-size: 9pt; cursor: pointer; border-right: 1px solid #95B7E8;border-bottom: 1px solid #95B7E8;border-left: 1px solid #254778;border-top: 1px solid #254778;background-color: #85A7D8;color: #000000; margin: 0px 3px 2px 3px; padding: 3px 3px 5px 3px; text-decoration: none; display: block; }
+div.sidebar .head:hover, .dbx-handle:hover { font-family: trebuchet ms, verdana, Arial, helvetica, sans-serif; font-size: 9pt; cursor: pointer; border-right: 1px solid #95B7E8;border-bottom: 1px solid #95B7E8;border-left: 1px solid #254778;border-top: 1px solid #254778;background-color: #B5D7FF;color: #000000; margin: 0px 3px 2px 3px; padding: 3px 3px 5px 3px; text-decoration: none; display: block; }
+div.sidebar div.slideblock a , .dbx-content a { font-family: trebuchet ms, verdana, Arial, helvetica, sans-serif; font-size: 9pt; cursor: pointer; border: 1px solid #254778;background-color: #7597C8;color: #000000; margin: 0px 3px 2px 7px; padding: 7px 3px 7px 5px; text-decoration: none; display: block; text-align: right; }
+div.sidebar div.slideblock a:hover, .dbx-content a:hover { font-family: trebuchet ms, verdana, Arial, helvetica, sans-serif; font-size: 9pt; cursor: pointer; border: 1px solid #254778;background-color: #A5C7F8;color: #000000; margin: 0px 3px 2px 7px; padding: 7px 3px 7px 5px; text-decoration: none; display: block; text-align: right; }
+div.recttop { width: 156px; height: 12px; margin: 0; padding: 0; }
+td.recttoptop { width: 100%; height: 12px; background-image: url({SCRIPTPATH}/themes/boxart/images/border-menu-t.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+td.recttoptop:hover { width: 100%; height: 12px; background-image: url({SCRIPTPATH}/themes/boxart/images/border-menu-t-h.gif); background-repeat: repeat-x; margin: 0; padding: 0; cursor: pointer; }
+div.rectbot { width: 156px; height: 12px; margin: 0; padding: 0; }
+td.rectbottop { width: 100%; height: 12px; background-image: url({SCRIPTPATH}/themes/boxart/images/border-btm.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+div.slideblock, .dbx-content { overflow: hidden; }
+div.slideblock2, .dbx-content2 { overflow: hidden; background-color: #456798; margin: 0px 1px 0px 1px; }
+.dbx-handle { cursor: move; }
+/* The credits thingy at the bottom */
+div#credits { margin: 0; background-color: #456798; color: #FFF; font-size: 7pt; text-align: right; padding: 3px; }
+div#credits a { color: #B5D7F8; text-decoration: none; }
+div#credits a:hover { color: #D5F7FF; text-decoration: underline; }
+
+/* The link hidden in plain "site" at the top of the page */
+td#mainhead a { text-decoration: none; color: #000000; }
+td#mainhead a:hover { text-decoration: none; color: #000000; border-bottom: 1px dotted #406080; }
+
+#enanomain { background-color: #FFFFFF; color: #000000; }
+
+/* Text, headings, and links inside the main div (usually #ajaxEditContainer but used some other places as well) */
+div.contentDiv h2 { border-bottom: 1px solid #8E9B80; margin-bottom: 0; }
+div.contentDiv h3 { font-size: 11pt; font-weight: bold; }
+div.contentDiv li { list-style: url({SCRIPTPATH}/themes/boxart/images/bullet.gif); }
+div.contentDiv p { margin-left: 1.0em; }
+div.contentDiv blockquote { background-color: #F4F4F4; border: 1px dotted #406080; margin: 1em; padding: 10px; max-height: 250px; overflow: auto; }
+div.contentDiv { font-size: 9pt; padding: 0px 10px 10px 10px; }
+div.contentDiv a { color: #254778; text-decoration: none; }
+div.contentDiv a:hover { color: #7597C8; text-decoration: none; }
+div.contentDiv a[href ^="http://"] { color: #355788; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/external.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="https://"]{ color: #355788; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/https.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="irc://"] { color: #355788; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/irc.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="mailto:"] { color: #355788; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/email.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="http://"]:hover { color: #85A7D8; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/external.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="https://"]:hover { color: #85A7D8; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/https.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="mailto:"]:hover { color: #85A7D8; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/email.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="irc://"]:hover { color: #85A7D8; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/irc.gif) center right no-repeat; padding-right: 16px; }
+
+/* Wikilinks to pages that don't exist */
+div.contentDiv a.wikilink-nonexistent { color: #B05020; }
+div.contentDiv a.wikilink-nonexistent:hover { color: #D06030; }
+
+/* Well, not Midget and not comments (usually), but that's what the class is called ;-). Basically an informational window or used as a wrapper for tables. */
+.mdg-comment { margin-left: 1em; padding: 7px; border: 1px solid #AAAAAA; background-color: #E0E0E0; }
+
+/* The beautiful tables inside what may not obviously be mdg-comment divs */
+.mdg-comment td.row1 { padding: 4px; background-color: #E0E0E0; }
+.mdg-comment td.row2 { padding: 4px; background-color: #F0F0F0; }
+.mdg-comment td.row3 { padding: 4px; background-color: #E8E8E8; }
+.mdg-comment th { padding: 4px; background-color: #7080A0; font-weight: bold; text-align: center; color: #FFFFFF; }
+.mdg-comment th.subhead { padding: 4px; background-color: #90A0B0; font-weight: bold; text-align: center; color: #FFFFFF; }
+.mdg-comment table { background-color: #FFFFFF; }
+
+/* Same as mdg-comment, but without the cute comment icon. Mostly unused. */
+.mdg-infobox { margin-left: 1em; padding: 7px; border: 1px solid #AAAAAA; background-color: #D8DCDD; }
+
+/* The "page tools" bar below the site logo but above the page content * /
+div.pagebar { background-color: #85A7D8; margin-top: 0px; padding: 3px; font-size: 7pt; }
+div.pagebar a { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #254778; }
+div.pagebar a:hover { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #001748; background-color: #A5C7F8; }
+div.pagebar input { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #E0F0FF; }
+div.pagebar input:hover { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #D0F0FF; }
+div.pagebar input:focus { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #F0F0FF; }
+
+/* Tweaks for the popup menu version of the same thing * /
+div.pagebar#pagebarpopup { display: none; position: absolute; width: 150px; padding: 0; }
+div.pagebar#pagebarpopup a { display: block; margin: 0; }
+
+/*
+ * jBox menu system
+ */
+
+div.menu {
+ background-color: #85A7D8;
+ font-size: 7pt;
+ border-width: 0;
+}
+div.menu a, div.menu div.label {
+ padding: 2.5pt 5px;
+ margin-right: 3px;
+ text-decoration: none;
+ display: block;
+ float: left;
+ color: #254778;
+}
+div.menu div.label {
+ color: #001020;
+ cursor: default;
+}
+div.menu span.sep {
+ display: block;
+ float: left;
+ width: 5px;
+}
+div.menu div.multopts {
+ line-height: 17pt;
+}
+div.menu div.multopts a, div.menu div.multopts div.label {
+ float: none;
+ display: inline;
+}
+div.menu a.liteselected, div.menu a.liteselected:hover, div.menu a:hover {
+ color: #001748;
+ background-color: #A5C7F8;
+}
+div.menu input[type ^="text"], div.menu input[type ^="password"] {
+ border-width: 0;
+ font-size: 9pt;
+ padding: 4px 5px;
+ max-width: 70px;
+ background-color: #D0F0FF;
+}
+div.menu input[type ^="text"]:hover, div.menu input[type ^="password"]:hover {
+ background-color: #E0F0FF;
+}
+div.menu input[type ^="text"]:focus, div.menu input[type ^="password"]:focus {
+ background-color: #F0F0FF;
+}
+div.menu input[type ^="button"], div.menu input[type ^="submit"] {
+ border-width: 0;
+ font-size: 9pt;
+ padding: 3px 5px;
+ max-width: 70px;
+}
+div.menu a.current, div.menu a.current:hover, div.menu a.selected, div.menu a.selected:hover {
+ color: #000040;
+ background-color: #FFFFFF;
+}
+div.menu ul {
+ display: none;
+ position: absolute;
+ padding: 0;
+ margin: 0;
+ background-color: #85A7D8;
+ border-width: 0;
+ min-width: 120px;
+}
+div.menu ul li {
+ list-style: none;
+}
+div.menu ul a {
+ float: none;
+ margin: 0;
+}
+span.menuclear {
+ font-size: 1px;
+ height: 0px;
+ width: 0px;
+ clear: left;
+ line-height: 0px;
+ display: block;
+}
+
+/* Buttons and textboxes - these settings are used almost everywhere */
+input, textarea, select { border: 1px solid #406080; background-color: #F2F2F2; padding: 3px; }
+input:hover, textarea:hover, select:hover { border: 1px solid #6080A0; background-color: #F8F8F8; padding: 3px; }
+input:focus, textarea:focus, select:focus { border: 1px solid #90B0D0; background-color: #FFFFFF; padding: 3px; }
+label { padding: 3px; cursor: pointer; }
+label:hover { padding: 3px; cursor: pointer; background-color: #F0F0F0; }
+
+/* JWS window theming */
+div.jswindow { border: 2px solid #7090B0; border-top: 5px solid #7090B0; padding: 0px; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; display: none; position: absolute; background-color: #FFFFFF; }
+div.titlebar { background-color: #7090B0; color: #FFFFFF; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; padding-bottom: 4px; cursor: default; }
+div.titlebar div.closebtn { width: 16px; height: 16px; border: 1px solid #B0D0F0; background-color: #90B0D0; display: block; }
+div.titlebar div.closebtn:hover { width: 16px; height: 16px; border: 1px solid #FFFFFF; background-color: #B0D0F0; display: block; }
+div.titlebar table, div.titlebar td { margin: 0; padding: 0; }
+div.jswindow div.content { padding: 10px; margin: 0; background-color: #FFFFFF; }
+
+/* The Wordpress-like fills behind checkboxes and their labels */
+.catCheck { padding: 3px; }
+.catCheck:hover { padding: 3px; background-color: #F0F0F0; }
+
+/* Information, warning, question, error, and wait boxes */
+div.error-box { background-image: url({SCRIPTPATH}/images/error.png); background-repeat: no-repeat; background-color: #FFF4F4; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.info-box { background-image: url({SCRIPTPATH}/images/info.png); background-repeat: no-repeat; background-color: #F4F4FF; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.warning-box { background-image: url({SCRIPTPATH}/images/warning.png); background-repeat: no-repeat; background-color: #FFFFF4; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.question-box { background-image: url({SCRIPTPATH}/images/question.png); background-repeat: no-repeat; background-color: #F4FFF4; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.wait-box { background-image: url({SCRIPTPATH}/images/wait.png); background-repeat: no-repeat; background-color: #FFF4FF; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+
+/* This stuff is mostly unused, left in for compatibility */
+div#ajaxEditContainer table { border: 0px solid #FFFFFF; }
+div#ajaxEditContainer td { margin: 1px; }
+/* div#ajaxEditContainer { overflow: auto; } /* Makes ajaxEditContainer scroll horizontally in firefox if the content is too wide - prevents that ugly clipping effect */
+div#ajaxEditContainer pre { margin-left: 1em; background-color: #F8F8F8; border: 1px dashed #90B0D0; padding: 10px; overflow: auto; max-height: 150px; }
+
+/*
+ * Docking Boxes code (for the sidebar editor)
+ */
+
+/* group container(s) */
+#sbedit {
+ margin: 0;
+ padding: 0;
+ /* position:relative; /* additional outer containers must also have position:relative */
+}
+/* keyboard navigation tooltip */
+.dbx-tooltip {
+ display:block;
+ position:absolute;
+ margin:36px 0 0 125px;
+ width:185px;
+ border:1px solid #000;
+ background:#ffd;
+ color:#000;
+ font:normal normal normal 0.85em tahoma, arial, sans-serif;
+ padding:2px 4px 3px 5px;
+ text-align:left;
+ }
+* html .dbx-tooltip { width:195px; }
+
+/* use CSS2 system colors in CSS2 browsers
+ but not safari, which doesn't support them */
+*[class="dbx-tooltip"]:lang(en) {
+ border-color:InfoText;
+ background:InfoBackground;
+ color:InfoText;
+ font:small-caption;
+ font-weight:normal;
+ }
+/* additional clone styles */
+.dbx-clone {
+ opacity: 0.8;
+}
+.dbx-content ul {
+ margin: 0; padding: 0; list-style-type: none;
+}
+.dbx-content li a, .dbx-content li a:hover {
+ text-decoration: none; color: #666;
+}
+.dbx-content li, .dbx-content2 li {
+ list-style-type: none;
+}
+.dbx-content2 {
+ background-color: #DDD; margin: 0px 1px 0px 1px;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/boxart/css/mint.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,170 @@
+/**
+ * Box Art for Enano - make your website look like the old Enano, er, Midget, er, AdvancedArticles?
+ * Designed by Dan Fuhry, (C) 2006
+ * This theme is Free Software; see the file "GPL" included with this package for details.
+ */
+
+/* The basics */
+html,body { height: 100%; }
+body { margin: 0; padding: 0; background: #459867; font-family: trebuchet ms, verdana, arial, helvetica, sans-serif; font-size: 9pt; }
+.holder { border: 1px solid #CCCCCC; padding: 1px; background-color: #FFFFFF; color: #444444; }
+div.pad { padding: 10px; }
+table#enano-master { height: 100%; }
+
+/* Sidebar */
+td.mdgSidebarHolder { width: 156px; }
+div.sidebar, .dbx-group { width: 154px; background-color: #459867; padding: 1px 0px 0px 0px; }
+div.sidebar .head, .dbx-handle { font-family: trebuchet ms, verdana, Arial, helvetica, sans-serif; font-size: 9pt; cursor: pointer; border-right: 1px solid #95E8B7;border-bottom: 1px solid #95E8B7;border-left: 1px solid #257847;border-top: 1px solid #257847;background-color: #85D8A7;color: #000000; margin: 0px 3px 2px 3px; padding: 3px 3px 5px 3px; text-decoration: none; display: block; }
+div.sidebar .head:hover, .dbx-handle:hover { font-family: trebuchet ms, verdana, Arial, helvetica, sans-serif; font-size: 9pt; cursor: pointer; border-right: 1px solid #95E8B7;border-bottom: 1px solid #95E8B7;border-left: 1px solid #257847;border-top: 1px solid #257847;background-color: #B5FFD7;color: #000000; margin: 0px 3px 2px 3px; padding: 3px 3px 5px 3px; text-decoration: none; display: block; }
+div.sidebar div.slideblock a , .dbx-content a { font-family: trebuchet ms, verdana, Arial, helvetica, sans-serif; font-size: 9pt; cursor: pointer; border: 1px solid #257847;background-color: #75C897;color: #000000; margin: 0px 3px 2px 7px; padding: 7px 3px 7px 5px; text-decoration: none; display: block; text-align: right; }
+div.sidebar div.slideblock a:hover, .dbx-content a:hover { font-family: trebuchet ms, verdana, Arial, helvetica, sans-serif; font-size: 9pt; cursor: pointer; border: 1px solid #257847;background-color: #A5F8C7;color: #000000; margin: 0px 3px 2px 7px; padding: 7px 3px 7px 5px; text-decoration: none; display: block; text-align: right; }
+div.recttop { width: 156px; height: 12px; margin: 0; padding: 0; }
+td.recttoptop { width: 100%; height: 12px; background-image: url({SCRIPTPATH}/themes/boxart/images/border-menu-t.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+td.recttoptop:hover { width: 100%; height: 12px; background-image: url({SCRIPTPATH}/themes/boxart/images/border-menu-t-h.gif); background-repeat: repeat-x; margin: 0; padding: 0; cursor: pointer; }
+div.rectbot { width: 156px; height: 12px; margin: 0; padding: 0; }
+td.rectbottop { width: 100%; height: 12px; background-image: url({SCRIPTPATH}/themes/boxart/images/border-btm.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+div.slideblock, .dbx-content { overflow: hidden; }
+div.slideblock2, .dbx-content2 { overflow: hidden; background-color: #459867; margin: 0px 1px 0px 1px; }
+.dbx-handle { cursor: move; }
+/* The credits thingy at the bottom */
+div#credits { margin: 0; background-color: #459867; color: #FFF; font-size: 7pt; text-align: right; padding: 3px; }
+div#credits a { color: #B5F8D7; text-decoration: none; }
+div#credits a:hover { color: #D5FFF7; text-decoration: underline; }
+
+/* The link hidden in plain "site" at the top of the page */
+td#mainhead a { text-decoration: none; color: #000000; }
+td#mainhead a:hover { text-decoration: none; color: #000000; border-bottom: 1px dotted #408060; }
+
+#enanomain { background-color: #FFFFFF; color: #000000; }
+
+/* Text, headings, and links inside the main div (usually #ajaxEditContainer but used some other places as well) */
+div.contentDiv h2 { border-bottom: 1px solid #8E809B; margin-bottom: 0; }
+div.contentDiv h3 { font-size: 11pt; font-weight: bold; }
+div.contentDiv li { list-style: url({SCRIPTPATH}/themes/boxart/images/bullet.gif); }
+div.contentDiv p { margin-left: 1.0em; }
+div.contentDiv blockquote { background-color: #F4F4F4; border: 1px dotted #408060; margin: 1em; padding: 10px; max-height: 250px; overflow: auto; }
+div.contentDiv { font-size: 9pt; padding: 0px 10px 10px 10px; }
+div.contentDiv a { color: #257847; text-decoration: none; }
+div.contentDiv a:hover { color: #75C897; text-decoration: none; }
+div.contentDiv a[href ^="http://"] { color: #358857; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/external.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="https://"]{ color: #358857; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/https.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="irc://"] { color: #358857; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/irc.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="mailto:"] { color: #358857; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/email.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="http://"]:hover { color: #85D8A7; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/external.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="https://"]:hover { color: #85D8A7; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/https.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="mailto:"]:hover { color: #85D8A7; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/email.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="irc://"]:hover { color: #85D8A7; background: url({SCRIPTPATH}/themes/boxart/images/{STYLE_ID}/irc.gif) center right no-repeat; padding-right: 16px; }
+
+/* Wikilinks to pages that don't exist */
+div.contentDiv a.wikilink-nonexistent { color: #B02050; }
+div.contentDiv a.wikilink-nonexistent:hover { color: #D03060; }
+
+/* Well, not Midget and not comments (usually), but that's what the class is called ;-). Basically an informational window or used as a wrapper for tables. */
+.mdg-comment { margin-left: 1em; padding: 7px; border: 1px solid #AAAAAA; background-color: #E0E0E0; }
+
+/* The beautiful tables inside what may not obviously be mdg-comment divs */
+.mdg-comment td.row1 { padding: 4px; background-color: #E0E0E0; }
+.mdg-comment td.row2 { padding: 4px; background-color: #F0F0F0; }
+.mdg-comment td.row3 { padding: 4px; background-color: #E8E8E8; }
+.mdg-comment th { padding: 4px; background-color: #70A080; font-weight: bold; text-align: center; color: #FFFFFF; }
+.mdg-comment th.subhead { padding: 4px; background-color: #90B0A0; font-weight: bold; text-align: center; color: #FFFFFF; }
+.mdg-comment table { background-color: #FFFFFF; }
+
+/* Same as mdg-comment, but without the cute comment icon. Mostly unused. */
+.mdg-infobox { margin-left: 1em; padding: 7px; border: 1px solid #AAAAAA; background-color: #D8DDDC; }
+
+/* The "page tools" bar below the site logo but above the page content */
+div.pagebar { background-color: #85D8A7; margin-top: 0px; padding: 3px; font-size: 7pt; }
+div.pagebar a { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #257847; }
+div.pagebar a:hover { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #004817; background-color: #A5F8C7; }
+div.pagebar input { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #408060; background-color: #E0FFF0; }
+div.pagebar input:hover { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #408060; background-color: #D0FFF0; }
+div.pagebar input:focus { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #408060; background-color: #F0FFF0; }
+
+/* Tweaks for the popup menu version of the same thing */
+div.pagebar#pagebarpopup { display: none; position: absolute; width: 150px; padding: 0; }
+div.pagebar#pagebarpopup a { display: block; margin: 0; }
+
+/* Buttons and textboxes - these settings are used almost everywhere */
+input, textarea, select { border: 1px solid #408060; background-color: #F2F2F2; padding: 3px; }
+input:hover, textarea:hover, select:hover { border: 1px solid #60A080; background-color: #F8F8F8; padding: 3px; }
+input:focus, textarea:focus, select:focus { border: 1px solid #90D0B0; background-color: #FFFFFF; padding: 3px; }
+label { padding: 3px; cursor: pointer; }
+label:hover { padding: 3px; cursor: pointer; background-color: #F0F0F0; }
+
+/* JWS window theming */
+div.jswindow { border: 2px solid #70B090; border-top: 5px solid #70B090; padding: 0px; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; display: none; position: absolute; background-color: #FFFFFF; }
+div.titlebar { background-color: #70B090; color: #FFFFFF; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; padding-bottom: 4px; cursor: default; }
+div.titlebar div.closebtn { width: 16px; height: 16px; border: 1px solid #B0F0D0; background-color: #90D0B0; display: block; }
+div.titlebar div.closebtn:hover { width: 16px; height: 16px; border: 1px solid #FFFFFF; background-color: #B0F0D0; display: block; }
+div.titlebar table, div.titlebar td { margin: 0; padding: 0; }
+div.jswindow div.content { padding: 10px; margin: 0; background-color: #FFFFFF; }
+
+/* The Wordpress-like fills behind checkboxes and their labels */
+.catCheck { padding: 3px; }
+.catCheck:hover { padding: 3px; background-color: #F0F0F0; }
+
+/* Information, warning, question, error, and wait boxes */
+div.error-box { background-image: url({SCRIPTPATH}/images/error.png); background-repeat: no-repeat; background-color: #FFF4F4; border: 1px dashed #408060; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.info-box { background-image: url({SCRIPTPATH}/images/info.png); background-repeat: no-repeat; background-color: #F4FFF4; border: 1px dashed #408060; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.warning-box { background-image: url({SCRIPTPATH}/images/warning.png); background-repeat: no-repeat; background-color: #FFF4FF; border: 1px dashed #408060; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.question-box { background-image: url({SCRIPTPATH}/images/question.png); background-repeat: no-repeat; background-color: #F4F4FF; border: 1px dashed #408060; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.wait-box { background-image: url({SCRIPTPATH}/images/wait.png); background-repeat: no-repeat; background-color: #FFFFF4; border: 1px dashed #408060; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+
+/* This stuff is mostly unused, left in for compatibility */
+div#ajaxEditContainer table { border: 0px solid #FFFFFF; }
+div#ajaxEditContainer td { margin: 1px; }
+/* div#ajaxEditContainer { overflow: auto; } /* Makes ajaxEditContainer scroll horizontally in firefox if the content is too wide - prevents that ugly clipping effect */
+div#ajaxEditContainer pre { margin-left: 1em; background-color: #F8F8F8; border: 1px dashed #90D0B0; padding: 10px; overflow: auto; max-height: 150px; }
+
+/*
+ * Docking Boxes code (for the sidebar editor)
+ */
+
+/* group container(s) */
+#sbedit {
+ margin: 0;
+ padding: 0;
+ /* position:relative; /* additional outer containers must also have position:relative */
+}
+/* keyboard navigation tooltip */
+.dbx-tooltip {
+ display:block;
+ position:absolute;
+ margin:36px 0 0 125px;
+ width:185px;
+ border:1px solid #000;
+ background:#ffd;
+ color:#000;
+ font:normal normal normal 0.85em tahoma, arial, sans-serif;
+ padding:2px 4px 3px 5px;
+ text-align:left;
+ }
+* html .dbx-tooltip { width:195px; }
+
+/* use CSS2 system colors in CSS2 browsers
+ but not safari, which doesn't support them */
+*[class="dbx-tooltip"]:lang(en) {
+ border-color:InfoText;
+ background:InfoBackground;
+ color:InfoText;
+ font:small-caption;
+ font-weight:normal;
+ }
+/* additional clone styles */
+.dbx-clone {
+ opacity: 0.8;
+}
+.dbx-content ul {
+ margin: 0; padding: 0; list-style-type: none;
+}
+.dbx-content li a, .dbx-content li a:hover {
+ text-decoration: none; color: #666;
+}
+.dbx-content li, .dbx-content2 li {
+ list-style-type: none;
+}
+.dbx-content2 {
+ background-color: #DDD; margin: 0px 1px 0px 1px;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/boxart/elements.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,36 @@
+<!-- VAR sidebar_button --><a href="{HREF}" {FLAGS}>{TEXT}</a><br style="display: none;" />
+<!-- ENDVAR sidebar_button -->
+<!-- VAR sidebar_raw --><span style="text-align: center;">{HTML}</span><br style="display: none;" />
+<!-- ENDVAR sidebar_raw -->
+<!-- VAR sidebar_heading --><div class="heading">{TEXT}</div>
+<!-- ENDVAR sidebar_heading -->
+
+<!-- VAR toolbar_button --><a href="{HREF}" {PARENTFLAGS} {FLAGS}>{TEXT}</a>
+<!-- ENDVAR toolbar_button -->
+<!-- VAR toolbar_label --><div class="label">{TEXT}</div>
+<!-- ENDVAR toolbar_label -->
+<!-- VAR toolbar_button_selected --><a href="{HREF}" class="current" {PARENTFLAGS} {FLAGS}>{TEXT}</a>
+<!-- ENDVAR toolbar_button_selected -->
+<!-- VAR toolbar_menu_button --><li><a href="{HREF}" {FLAGS}>{TEXT}</a></li>
+<!-- ENDVAR toolbar_menu_button -->
+<!-- VAR toolbar_menu_block --><li>{HTML}</li>
+<!-- ENDVAR toolbar_menu_block -->
+
+<!-- VAR sidebar_section -->
+ <div class="slider">
+ <div class="heading">
+ <br style="display: none;" /><br style="display: none;" />
+ <a class="head" onclick="toggle(this); return false" href="#">{TITLE}</a><br style="display: none;" /><br style="display: none;" />
+ </div>
+ <div class="slideblock">{CONTENT}</div>
+ </div>
+<!-- ENDVAR sidebar_section -->
+<!-- VAR sidebar_section_raw -->
+ <div class="slider">
+ <div class="heading">
+ <br style="display: none;" /><br style="display: none;" />
+ <a class="head" onclick="toggle(this); return false" href="#">{TITLE}</a><br style="display: none;" /><br style="display: none;" />
+ </div>
+ <div class="slideblock2">{CONTENT}</div>
+ </div>
+<!-- ENDVAR sidebar_section_raw -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/boxart/footer.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,23 @@
+ </div>
+ <div id="mdgCommentContainer">
+ </div>
+ </div>
+ </td></tr>
+ </table>
+
+ </td>
+
+ </tr>
+ <tr><td colspan="2">
+ <!-- We strongly request that you leave the notice below in its place; it helps to attract users to Enano in exchange for providing you
+ with your CMS. Enano is still new; therefore we are looking to attract users, and we feel that this notice will help. If you refuse
+ to include even this tiny little notice, support on the Enano forums may be affected.
+ -->
+ <div id="credits">
+ {COPYRIGHT} • Powered by <a href="http://enano.homelinux.org">Enano</a> | <a href="http://validator.w3.org/check?uri=referer">Valid XHTML 1.1</a> | <a href="http://jigsaw.w3.org/css-validator/validator?profile=css2&warning=2&uri={REQUEST_URI}">Valid CSS</a> | [[Stats]]
+ </div>
+
+ </td></tr>
+ </table>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/boxart/header.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,96 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html>
+ <head>
+ <title>{PAGE_NAME} • {SITE_NAME}</title>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <link rel="stylesheet" type="text/css" href="{SCRIPTPATH}/includes/clientside/css/enano-shared.css" />
+ <link rel="stylesheet" href="{STYLE_LINK}" type="text/css" id="mdgCss" />
+ {JS_DYNAMIC_VARS}
+ <!-- This script automatically loads the other 15 JS files -->
+ <script type="text/javascript" src="{SCRIPTPATH}/includes/clientside/static/enano-lib-basic.js"></script>
+ <script type="text/javascript">
+
+ function collapseSidebar(side)
+ {
+ elem = document.getElementById(side+'-sidebar');
+ counter = document.getElementById(side+'-sidebar-showbutton');
+ if(elem.style.display=='none')
+ {
+ elem.style.display = 'block';
+ counter.style.display = 'none';
+ elem.parentNode.style.width = '156px';
+ createCookie(side+'_sidebar', 'open', 365);
+ } else {
+ elem.style.display = 'none';
+ counter.style.display = 'block';
+ elem.parentNode.style.width = '25px';
+ createCookie(side+'_sidebar', 'collapsed', 365);
+ }
+ }
+
+ window.onload = function() {
+ if(readCookie('left_sidebar') =='collapsed') collapseSidebar('left');
+ if(readCookie('right_sidebar')=='collapsed') collapseSidebar('right');
+ mdgInnerLoader();
+ }
+ </script>
+ {ADDITIONAL_HEADERS}
+ </head>
+ <body>
+ <div id="root1" class="jswindow">
+ <div id="tb1" class="titlebar">Confirm Logout</div>
+ <div class="content" id="cn1">
+ <form action="{CONTENTPATH}Special:Logout" method="get">
+ <div style="text-align: center">
+ <h3>Are you sure you want to log out?</h3>
+ <input type="submit" value="Log out" style="font-weight: bold;" /> <input type="button" onclick="jws.closeWin('root1');" value="Cancel" />
+ </div>
+ </form>
+ </div>
+ </div>
+ <div id="root2" class="jswindow">
+ <div id="tb2" class="titlebar">Change style</div>
+ <div class="content" id="cn2">
+ If you can see this text, it means that your browser does not support Cascading Style Sheets (CSS). CSS is a fundemental aspect of XHTML, and as a result it is becoming very widely adopted by websites, including this one. You should consider switching to a more modern web browser, such as Mozilla Firefox or Opera 9.
+ </div>
+ </div>
+ <div id="root3" class="jswindow">
+ <div id="tb3" class="titlebar">Wiki formatting help</div>
+ <div class="content" id="cn3">
+ Loading...
+ </div>
+ </div>
+ <table border="0" cellspacing="0" cellpadding="0" id="enano-master" width="100%">
+ <tr><td colspan="2" style="height: 96px;"><a href="{SCRIPTPATH}/{ADMIN_SID_QUES}"><img alt="{SITE_NAME}" src="{SCRIPTPATH}/themes/boxart/images/logo-{STYLE_ID}.png" style="border: 0px;" /></a></td></tr>
+ <tr>
+ <td class="mdgSidebarHolder" valign="top">
+ <div id="left-sidebar">
+
+ <div class="sidebar">
+ {SIDEBAR_LEFT}
+ {SIDEBAR_RIGHT}
+ </div>
+
+ </div>
+ <div id="left-sidebar-showbutton" style="display: none; position: fixed; top: 3px; left: 3px;">
+ <input type="button" onclick="collapseSidebar('left');" value=">>" />
+ </div>
+ </td>
+ <td valign="top" id="enanomain">
+ <table border="0" width="100%" cellspacing="0" cellpadding="0">
+
+ <td>
+ <div class="menu_nojs" id="pagebar_main">
+ <div class="label">Page tools</div>
+ {TOOLBAR}
+ <ul>
+ {TOOLBAR_EXTRAS}
+ </ul>
+ <span class="menuclear"> </span>
+ </div>
+ </td>
+ <tr>
+ <td>
+ <div class="contentDiv">
+ <h2>{PAGE_NAME}</h2>
+ <div id="ajaxEditContainer">
Binary file themes/boxart/images/blackjack/email.gif has changed
Binary file themes/boxart/images/blackjack/external.gif has changed
Binary file themes/boxart/images/blackjack/https.gif has changed
Binary file themes/boxart/images/blackjack/irc.gif has changed
Binary file themes/boxart/images/blueberry/email.gif has changed
Binary file themes/boxart/images/blueberry/external.gif has changed
Binary file themes/boxart/images/blueberry/https.gif has changed
Binary file themes/boxart/images/blueberry/irc.gif has changed
Binary file themes/boxart/images/logo-blackjack.png has changed
Binary file themes/boxart/images/logo-blueberry.png has changed
Binary file themes/boxart/images/logo-mint.png has changed
Binary file themes/boxart/images/mint/email.gif has changed
Binary file themes/boxart/images/mint/external.gif has changed
Binary file themes/boxart/images/mint/https.gif has changed
Binary file themes/boxart/images/mint/irc.gif has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/boxart/sidebar-editor.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,36 @@
+<!-- VAR sidebar_button --><li><a href="javascript:void(0)" {FLAGS}>{TEXT}</a></li>
+<!-- ENDVAR sidebar_button -->
+<!-- VAR sidebar_raw --><li><span style="text-align: center;">{HTML}</span></li>
+<!-- ENDVAR sidebar_raw -->
+<!-- VAR sidebar_section -->
+ <div class="dbx-box">
+ <div class="dbx-handle">
+ {ADMIN_START}
+
+ {TITLE}
+ {ADMIN_END}
+
+ </div>
+ <div class="dbx-content">
+ <ul>
+ {CONTENT}
+ </ul>
+ </div>
+ </div>
+<!-- ENDVAR sidebar_section -->
+<!-- VAR sidebar_section_raw -->
+ <div class="dbx-box">
+ <div class="dbx-handle">
+ {ADMIN_START}
+
+ {TITLE}
+ {ADMIN_END}
+
+ </div>
+ <div class="dbx-content dbx-content2">
+ <ul><li>
+ {CONTENT}
+ </li></ul>
+ </div>
+ </div>
+<!-- ENDVAR sidebar_section_raw -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/boxart/simple-footer.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,49 @@
+ </div>
+ <div id="mdgCommentContainer">
+ </div>
+ </div>
+ </td>
+
+ </tr>
+ <tr><td style="background-color: #355788;">
+ <!-- We strongly request that you leave the notice below in its place; it helps to attract users to Enano in exchange for providing you
+ with your CMS. Enano is still new; therefore we are looking to attract users, and we feel that this notice will help. If you refuse
+ to include even this tiny little notice, support on the Enano forums may be affected.
+ -->
+ <div id="credits">
+ Powered by Enano, © 2007 | [[Stats]]
+ </div>
+
+ </td></tr>
+ </table>
+
+ </td>
+ <td style="width: 10%;"></td>
+ </tr>
+ </table>
+
+ <div id="root1" class="jswindow">
+ <div id="tb1" class="titlebar">Confirm Logout</div>
+ <div class="content" id="cn1">
+ <form action="{CONTENTPATH}Special:Logout" method="get">
+ <div style="text-align: center">
+ <h3>Are you sure you want to log out?</h3>
+ <input type="submit" value="Log out" style="font-weight: bold;" /> <input type="button" onclick="jws.closeWin('root1');" value="Cancel" />
+ </div>
+ </form>
+ </div>
+ </div>
+ <div id="root2" class="jswindow">
+ <div id="tb2" class="titlebar">Change style</div>
+ <div class="content" id="cn2">
+ If you can see this text, it means that your browser does not support Cascading Style Sheets (CSS). CSS is a fundemental aspect of XHTML, and as a result it is becoming very widely adopted by websites, including this one. You should consider switching to a more modern web browser, such as Mozilla Firefox or Opera 9.
+ </div>
+ </div>
+ <div id="root3" class="jswindow">
+ <div id="tb3" class="titlebar">Wiki formatting help</div>
+ <div class="content" id="cn3">
+ Loading...
+ </div>
+ </div>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/boxart/simple-header.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,56 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html>
+ <head>
+ <title>{PAGE_NAME} • {SITE_NAME}</title>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <link rel="stylesheet" type="text/css" href="{SCRIPTPATH}/includes/clientside/css/enano-shared.css" />
+ <link rel="stylesheet" href="{STYLE_LINK}" type="text/css" id="mdgCss" />
+ <link rel="stylesheet" type="text/css" href="{SCRIPTPATH}/themes/{THEME_ID}/css-simple/{STYLE_ID}.css" />
+ {JS_DYNAMIC_VARS}
+ <!-- This script automatically loads the other 15 JS files -->
+ <script type="text/javascript" src="{SCRIPTPATH}/includes/clientside/static/enano-lib-basic.js"></script>
+ <script type="text/javascript">
+
+ function collapseSidebar(side)
+ {
+ elem = document.getElementById(side+'-sidebar');
+ counter = document.getElementById(side+'-sidebar-showbutton');
+ if(elem.style.display=='none')
+ {
+ elem.style.display = 'block';
+ counter.style.display = 'none';
+ elem.parentNode.style.width = '156px';
+ createCookie(side+'_sidebar', 'open', 365);
+ } else {
+ elem.style.display = 'none';
+ counter.style.display = 'block';
+ elem.parentNode.style.width = '25px';
+ createCookie(side+'_sidebar', 'collapsed', 365);
+ }
+ }
+
+ window.onload = function() {
+ if(readCookie('left_sidebar') =='collapsed') collapseSidebar('left');
+ if(readCookie('right_sidebar')=='collapsed') collapseSidebar('right');
+ mdgInnerLoader();
+ }
+ </script>
+ {ADDITIONAL_HEADERS}
+ </head>
+ <body>
+
+ <table border="0" style="width: 100%; height: 100%;">
+ <tr>
+ <td style="width: 10%;"></td>
+ <td valign="middle">
+
+ <table border="0" cellspacing="0" cellpadding="0" id="enano-master" width="100%" style="height: 200px;">
+ <tr>
+ <td colspan="2" style="height: 96px; padding: 10px;" id="header-banner">
+ <h1>{PAGE_NAME}</h1>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" id="enanomain">
+ <div class="contentDiv">
+ <div id="ajaxEditContainer">
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/boxart/theme.cfg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,18 @@
+<?php
+/*
+ * Box Art theme for Enano
+ * Created by dandaman32 - (C) 2006
+ * License: GPL
+ *
+ * This theme is free software; you can redistribute and/or modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This theme is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+global $theme;
+$theme['theme_id'] = 'boxart';
+$theme['theme_name'] = 'Box Art';
+
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/connections/acledit.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,36 @@
+<!-- VAR acl_field_begin -->
+<div class="mdg-comment" style="padding: 0px;">
+ <table border="0" cellspacing="1" cellpadding="4" style="width: 100%;">
+ <tr>
+ <th></th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('1');">Deny</th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('2');">Disallow</th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('3');">Wiki mode</th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('4');">Allow</th>
+ </tr>
+<!-- ENDVAR acl_field_begin -->
+<!-- VAR acl_field_item -->
+ <tr>
+ <td class="{ROW_CLASS}">{FIELD_DESC}</td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="1" name="{FIELD_NAME}" {FIELD_DENY_CHECKED} /></td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="2" name="{FIELD_NAME}" {FIELD_DISALLOW_CHECKED} /></td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="3" name="{FIELD_NAME}" {FIELD_WIKIMODE_CHECKED} /></td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="4" name="{FIELD_NAME}" {FIELD_ALLOW_CHECKED} /></td>
+ </tr>
+<!-- ENDVAR acl_field_item -->
+<!-- VAR acl_field_end -->
+ <tr>
+ <td colspan="5" class="row3">
+ <p><b>Permission types:</b></p>
+ <ul>
+ <li><b>Allow</b> means that the user is allowed to access the item</li>
+ <li><b>Wiki mode</b> means the user can access the item if wiki mode is active (per-page wiki mode is taken into account)</li>
+ <li><b>Disallow</b> means the user is denied access unless something allows it.</li>
+ <li><b>Deny</b> means that the user is denied access to the item. This setting overrides all other permissions.</li>
+ </ul>
+ </td>
+ </tr>
+ </table>
+</div>
+<!-- ENDVAR acl_field_end -->
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/connections/blogpost.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,13 @@
+<!-- Template file for blog posts (EnanoPress) -->
+ <p class="post-date">{D} {j} {M} {Y}</p>
+ <div class="post-info">
+ <h2 class="post-title">
+ <a href="{PERMALINK}" rel="bookmark" title="Permanent link to this post">{TITLE}</a>
+ </h2>
+ Posted by <a href="{AUTHOR_LINK}" {AUTHOR_USERPAGE_CLASS}="">{AUTHOR}</a><br />
+ <a href="{COMMENT_LINK}">{COMMENT_LINK_TEXT}</a><!-- BEGIN can_edit --> | <a href="{EDIT_LINK}">edit this post</a><!-- END can_edit -->
+ </div>
+ <div class="post-content">
+ {CONTENT}
+ </div>
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/connections/blogseparator.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,4 @@
+<div class="post-footer"> </div>
+<div class="post-info">
+
+</div>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/connections/comment.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,51 @@
+<div class="mdg-comment" style="padding: 0px;">
+ <table border="0" width="100%" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2" style="text-align: left;">{DATETIME}</th>
+ </tr>
+ <tr>
+ <td style="width: 120px; height: 100%;" rowspan="4" valign="top" class="row1">
+ <table border="0" width="100%" style="height: 100%;" cellspacing="0" cellpadding="0">
+ <tr>
+ <td valign="top" class="row1">
+ <b>{NAME}</b><br />
+ <small>{USER_LEVEL}</small>
+ </td>
+ </tr>
+ <tr>
+ <td valign="bottom" class="row1">
+ {SEND_PM_LINK} {ADD_BUDDY_LINK}
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td class="row2">
+ <b>Subject:</b> <span id="subject_{ID}">{SUBJECT}</span>
+ </td>
+ </tr>
+ <tr>
+ <td class="row3">
+ <div id="comment_{ID}">{DATA}</div>
+ <!-- BEGIN signature -->
+ <hr style="margin-left: 1em; width: 200px;" />
+ {SIGNATURE}
+ <!-- END signature -->
+ </td>
+ </tr>
+ <!-- BEGIN can_edit -->
+ <tr>
+ <td class="row2">
+ [ {EDIT_LINK} | {DELETE_LINK} ]
+ </td>
+ </tr>
+ <!-- END can_edit -->
+ <!-- BEGIN auth_mod -->
+ <tr>
+ <td class="row1">
+ <b>Moderation options:</b> {MOD_APPROVE_LINK} {MOD_DELETE_LINK}
+ </td>
+ </tr>
+ <!-- END auth_mod -->
+ </table>
+</div>
+<br />
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/connections/css/_printable.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,426 @@
+/*
+Theme Name: Connections
+Theme URI: http://www.patriciamuller.com/
+Version: 1.0
+Description: A Theme from wpthemes.Info
+Author: Patricia Muller
+Author URI: http://www.vanillamist.com/blog/
+
+Port information:
+Ported from: WordPress
+Ported by: Dan Fuhry - http://midget.rgw-net.com/
+*/
+html,body { height: 100%; }
+body {
+ margin:0;
+ padding:0;
+ font-family: 'Trebuchet MS',Georgia, Times, Times New Roman, sans-serif;
+ font-size: 0.9em;
+ text-align:center;
+ color:#333333;
+ line-height:1.3em;
+ background: #FFFFFF;
+}
+a {
+ color: #000000;
+ text-decoration:underline;
+}
+a:visited {
+ color: #000000;
+}
+a:hover {
+ color: #000000;
+ background-color: #EEE;
+ text-decoration:underline;
+}
+input, textarea
+{
+ background: #FFFFFF;
+ border: #000000 1px solid;
+}
+#rap
+{
+ background:#fff;
+ width:760px;
+ margin:0 auto;
+ padding:0px 8px;
+ text-align:left;
+ font-family: Trebuchet MS,Georgia, Arial, serif;
+ font-size: 0.9em;
+}
+#header {
+ background:#FFF;
+ height: 183px;
+ margin: 0 auto;
+ width:740px;
+ padding:0;
+ border:#000 1px solid;
+ border-bottom 0px solid #FFFFFF;
+}
+#main
+{
+ margin:0 auto;
+ padding:0;
+ background:#FFF;
+ width:740px;
+}
+#content {
+ width:510px;
+ float:left;
+ padding:5px;
+ margin:0;
+ overflow:auto;
+ display:inline;
+ text-align: left;
+}
+#sidebar {
+ width:186px;
+ float:right;
+ padding:0px 8px 10px 8px;
+ margin:0;
+ font-size:1em;
+ color:#333;
+ display:inline;
+}
+a img {
+ border: none;
+}
+acronym, abbr {
+ border-bottom: 1px dotted #000000;
+}
+acronym, abbr, span.caps {
+ cursor: help;
+ letter-spacing: .07em;
+}
+code {
+ font-size: 1em;
+ font-style: italic;
+}
+blockquote {
+ margin: 15px 30px 0 45px;
+ padding: 0 0 0 45px;
+ background: #FFF;
+ border: 1px solid #000;
+ font-style:italic;
+}
+
+cite {
+ font-size: 0.9em;
+ font-style: normal;
+}
+h3 {
+ margin: 0;
+ padding: 0;
+ font-size:1.3em;
+}
+p {
+ margin: 0 0 1em;
+ padding: 0;
+ line-height: 1.5em;
+}
+h1, h2, h3, h4 {
+ font-family: Georgia, "Lucida Sans Unicode", lucida, Verdana, serif;
+ font-weight: normal;
+ letter-spacing: 1px;
+}
+#header h1
+{
+ margin: 0;
+ font-size: 1.6em;
+ padding:10px 20px 0 0;
+ text-align:right;
+}
+#header h1 a
+{
+ color:#606060;
+ text-decoration:none;
+}
+#header h1 a:hover
+{
+ color:#606060;
+ text-decoration: underline;
+}
+#header #desc
+{
+ font-weight:normal;
+ font-size:1em;
+ color:#606060;
+ text-align:right;
+ margin:0;
+ padding:0 20px 0 0;
+}
+#sidebar div.heading {
+ margin: 0 0 0 0;
+ padding:2px;
+ font-size: 1em;
+ color: #000000;
+ text-align:center;
+ background:#DDDDDD;
+ border:#ccc 0px solid;
+ height:22px;
+ font-weight:bold;
+}
+#sidebar div.slider {
+ list-style-type: none;
+ margin: 0;
+ margin-top: 7px;
+ font-size: 0.9em;
+}
+#sidebar div.slideblock {
+ padding: 5px;
+ overflow: hidden;
+ background:#FFFFFF;
+ border: 1px solid #000000;
+ border-top 0px solid #FFFFFF;
+}
+#sidebar div.slideblock a {
+ display: block;
+ color: #333333;
+ padding: 4px;
+ text-decoration: none;
+}
+#sidebar div.slideblock a:hover {
+ display: block;
+ color: #333333;
+ background-color: #EEE;
+ padding: 4px;
+ text-decoration: none;
+}
+#pagenav
+{
+ list-style:none;
+}
+#sidebar ul li {
+ margin: 0.1em 0 0 0;
+ padding: 0;
+}
+#sidebar ul li a {
+ text-decoration: none;
+ border:none;
+}
+#sidebar ul li a:link {
+ color: #909D73;
+}
+#sidebar ul li a:visited {
+ color: #999999;
+}
+#sidebar ul li a:hover, #sidebar ul li a:active {
+ color: #990000;
+}
+#sidebar ul ul {
+ list-style-type: none;
+ padding: 5px;
+ margin: 0;
+ font-size: 1em;
+ background:none;
+ border:none;
+}
+#sidebar ul ul li
+{
+ margin:0;
+ padding:0;
+ padding-left:10px;
+ margin-left:10px;
+ background:url({TEMPLATE_DIR}/img/subcat_bullet.gif) no-repeat left;
+}
+#content ul {
+ margin-left: 0;
+ padding-left: 45px;
+ list-style-type: none;
+}
+#content ul li {
+ background: url({TEMPLATE_DIR}/img/bullet.gif) no-repeat 0 7px;
+ padding-left: 1.5em;
+}
+.post , .page
+{
+ margin:0 0 30px 0;
+}
+.page
+{
+ margin:25px -5px 0 27px;
+}
+.post-info, .page-info
+{
+ font-size:0.85em;
+ font-family: Verdana, Arial, Sans-Serif;
+ margin:0;
+ padding:0;
+ color:#333;
+}
+.page-info
+{
+ text-align:center;
+}
+.post-info a
+{
+ color:#990000;
+}
+.post-info a:hover
+{
+ color:#000;
+}
+.post-content, .page-content {
+ padding:10px 0;
+ margin:3px 0;
+ border-top:#CCCCCC 1px solid;
+ font-family: Georgia, Verdana, Arial, serif;
+ font-size:12px;
+}
+.page-content {
+
+}
+.post-title, .page-title {
+ font-family:Georgia, Arial, Serif;
+ font-size:1.3em;
+ margin:0;
+ font-weight:bold;
+}
+.page-title
+{
+ font-size:1.6em;
+ font-weight:normal;
+}
+#content .page-title a, .post-title a:link, .post-title a:visited, .post-title a:hover, .post-title a:active
+{
+ text-decoration:none;
+ color:#666666;
+}
+.post-date {
+ float: left;
+ color: #BBC4A3;
+ font-family: Georgia,'Lucida sans ms', Verdana, Arial, Helvetica, sans-serif;
+ font-size: 0.9em;
+ text-align: center;
+ font-weight: bold;
+ margin: 3px 10px 0 0;
+ padding: 8px 3px;
+ width: 55px;
+ background: #E7EBDE;
+ line-height:1em;
+}
+.post-footer
+{
+ padding-top:20px;
+ background:url({TEMPLATE_DIR}/img/divider.gif) no-repeat center;
+}
+#footer {
+ margin:0 auto;
+ padding: 7px 0;
+ border-top:#CCCCCC 1px solid;
+ clear: both;
+ font-size: 0.8em;
+ color: #999;
+ text-align:center;
+ width:740px;
+}
+#footer a {
+border:none;
+color:#777777;
+}
+
+.commentlist {
+ font-size:1em;
+ font-weight:normal;
+}
+#commentform
+{
+ margin:0 0 0 40px;
+}
+#commentform textarea {
+ width: 80%;
+}
+#commentform p {
+ margin: 0 0 1em;
+}
+#comments,#respond {
+ text-transform: uppercase;
+ margin: 3em 0 1em 40px;
+ color: #666666;
+ font: 0.9em verdana, helvetica, sans-serif;
+}
+.commentlist li
+{
+ margin:5px 0;
+ padding:10px 10px 20px 10px;
+ background:#FFFFFF;
+ border:#DDDDDD 1px solid;
+}
+.commentlist .alt
+{
+
+}
+#topnav
+{
+ list-style:none;
+ font-size:0.9em;
+ margin:0;
+ padding:11px 20px 0 0;
+ text-align:right;
+ font-family:Verdana, Arial, Sans-Serif;
+}
+#topnav li
+{
+ list-style:none;
+ display:inline;
+ padding:0;
+ margin:0;
+ font-weight:bold;
+}
+
+#topnav li a:link, #topnav li a:visited
+{
+ text-decoration:none;
+ color:#BBBBBB;
+ border-left: 1px solid #777777;
+ border-right: 1px solid #777777;
+ background-color: #777777;
+ padding: 3px;
+ margin: 0;
+}
+#topnav li a:hover, #topnav li a:focus
+{
+ color:#F0F0F0;
+ border-left: 1px solid #F0F0F0;
+ border-right: 1px solid #F0F0F0;
+ background-color: #A0A0A0;
+ padding-left: 3px;
+ padding-right: 3px;
+ padding-top: 3px;
+ padding-bottom: 5px;
+ margin: 0;
+}
+
+div.jswindow { font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; display: none; position: absolute; list-style-type: none;
+ padding: 2px;
+ margin: 0;
+ margin-top: 7px;
+ font-size: 0.9em;
+ border:#E1D6c6 1px solid;
+ background:#F3F6ED;
+ }
+div.titlebar { font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; cursor: default; margin: 0 0 0 0;
+ padding:2px;
+ margin: 2px;
+
+ font-size: 1em;
+ color: #676E04;
+ text-align:center;
+ background: #e2ebda;
+ border:0px solid #ccc;
+ height:22px;
+ font-weight:bold; }
+div.titlebar div.closebtn { width: 16px; height: 16px; background-color: #e2ebda; display: block; }
+div.titlebar div.closebtn:hover { width: 16px; height: 16px; background-color: #F3F6ED; display: block; }
+
+div.titlebar table, div.titlebar td { margin: 0; padding: 0; }
+div.jswindow div.content { padding: 5px;
+ overflow: hidden;
+ }
+
+div.pagebar { background-color: #FFFFFF; padding: 1px; font-size: 7pt; border: 1px solid #000000; }
+div.pagebar a { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #606060; }
+div.pagebar a:hover { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #606060; background-color: #E0E0E0; }
+div.pagebar#pagebarpopup { display: none; position: absolute; width: 150px; padding: 0; }
+div.pagebar#pagebarpopup a { display: block; margin: 0; }
+.mdg-comment { margin: 0; margin-left: 0.2in; padding: 10px; padding-left: 35px; border: 1px #000000 solid; margin-bottom: 10px; background: #FFFFFF; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/connections/css/default.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,568 @@
+/*
+Theme Name: Connections
+Theme URI: http://www.patriciamuller.com/
+Version: 1.0
+Description: A Theme from wpthemes.Info
+Author: Patricia Muller
+Author URI: http://www.vanillamist.com/blog/
+
+Port information:
+Ported from: WordPress
+Ported by: Dan Fuhry - http://enano.homelinux.org/
+*/
+html,body { height: 100%; }
+body {
+ margin:0;
+ padding:0;
+ font-family: 'Trebuchet MS',Georgia, Times, Times New Roman, sans-serif;
+ font-size: 0.9em;
+ /* text-align:center; */
+ color:#29303B;
+ line-height:1.3em;
+ background: #F3F6ED;
+}
+a {
+ color: #909D73;
+ text-decoration:none;
+}
+a:visited {
+ color: #8a3207;
+}
+a:hover {
+ color: #753206;
+ text-decoration:underline;
+}
+input, textarea
+{
+ background: #F3F6ED;
+ border: #E1D6C6 1px solid;
+}
+#rap
+{
+ background:#fff url(../img/rap.jpg) center repeat-y;
+ width:760px;
+ margin:0 auto;
+ padding:0px 8px;
+ text-align:left;
+ font-family: Trebuchet MS,Georgia, Arial, serif;
+ font-size: 0.9em;
+}
+#header {
+ background:#fff url(../img/top.jpg) no-repeat bottom;
+ height: 183px;
+ margin: 0 auto;
+ width:760px;
+ padding:0;
+ border:#fc9 0px solid;
+}
+#main
+{
+ margin:0 auto;
+ padding:0;
+ background:url(../img/content_bg.gif) repeat;
+ width:740px;
+}
+#content {
+ width:510px;
+ float:left;
+ padding:5px;
+ margin:0;
+ overflow:auto;
+ display:inline;
+ text-align: left;
+}
+#sidebar {
+ width:186px;
+ float:right;
+ padding:0px 8px 10px 8px;
+ margin:0;
+ font-size:1em;
+ color:#333;
+ display:inline;
+}
+a img {
+ border: none;
+}
+acronym, abbr {
+ border-bottom: 1px dotted #0c6bf0;
+}
+acronym, abbr, span.caps {
+ cursor: help;
+ letter-spacing: .07em;
+}
+code {
+ font-size: 1em;
+ font-style: italic;
+}
+blockquote {
+ margin: 15px 30px 0 45px;
+ padding: 0 0 0 45px;
+ background: url(../img/blockquote.gif) no-repeat left top;
+ font-style:italic;
+}
+
+cite {
+ font-size: 0.9em;
+ font-style: normal;
+}
+h3 {
+ margin: 0;
+ padding: 0;
+ font-size:1.3em;
+}
+p {
+ margin: 0 0 1em;
+ padding: 0;
+ line-height: 1.5em;
+}
+h1, h2, h3, h4 {
+ font-family: Georgia, "Lucida Sans Unicode", lucida, Verdana, serif;
+ font-weight: normal;
+ letter-spacing: 1px;
+}
+#header h1
+{
+ margin: 0;
+ font-size: 1.6em;
+ padding:10px 20px 0 0;
+ text-align:right;
+}
+#header h1 a
+{
+ color:#B5C09D;
+ text-decoration:none;
+}
+#header h1 a:hover
+{
+ color:#F7F3ED;
+}
+#header #desc
+{
+ font-weight:normal;
+ font-size:1em;
+ color:#B5C09D;
+ text-align:right;
+ margin:0;
+ padding:0 20px 0 0;
+}
+#sidebar div.heading {
+ margin: 0 0 0 0;
+ padding:2px;
+ font-size: 1em;
+ color: #676E04;
+ text-align:center;
+ background:url(../img/sidenav_top.jpg) no-repeat center;
+ border:#ccc 0px solid;
+ height:22px;
+ font-weight:bold;
+}
+#sidebar div.slider {
+ list-style-type: none;
+ padding: 0 2px 0 2px;
+ margin: 0;
+ margin-top: 7px;
+ font-size: 0.9em;
+ border:#E1D6c6 1px solid;
+ border-top:#f3f6ed 1px solid;
+}
+#sidebar div.slideblock {
+ padding: 5px;
+ padding-bottom: 3em;
+ overflow: hidden;
+ background:#F3F6ED url(../img/sidenav_bottom.jpg) no-repeat bottom;
+}
+#sidebar div.slideblock2 {
+ padding: 5px;
+ padding-bottom: 3em;
+ overflow: hidden;
+ background:#F3F6ED url(../img/sidenav_bottom.jpg) no-repeat bottom;
+}
+#sidebar div.slideblock a {
+ display: block;
+ color: #909D73;
+ padding: 4px;
+ text-decoration: none;
+}
+#sidebar div.slideblock a:hover {
+ display: block;
+ color: #909D73;
+ background-color: #e2ebda;
+ padding: 4px;
+ text-decoration: none;
+}
+#pagenav
+{
+ list-style:none;
+}
+#sidebar ul li {
+ margin: 0.1em 0 0 0;
+ padding: 0;
+}
+#sidebar ul li a {
+ text-decoration: none;
+ border:none;
+}
+#sidebar ul li a:link {
+ color: #909D73;
+}
+#sidebar ul li a:visited {
+ color: #999999;
+}
+#sidebar ul li a:hover, #sidebar ul li a:active {
+ color: #990000;
+}
+#sidebar ul ul {
+ list-style-type: none;
+ padding: 5px;
+ margin: 0;
+ font-size: 1em;
+ background:none;
+ border:none;
+}
+#sidebar ul ul li
+{
+ margin:0;
+ padding:0;
+ padding-left:10px;
+ margin-left:10px;
+ background:url(../img/subcat_bullet.gif) no-repeat left;
+}
+#content ul {
+ margin-left: 0;
+ padding-left: 1em;
+ list-style-type: none;
+}
+#content ul li {
+ background: url(../img/bullet.gif) no-repeat 0 7px;
+ padding-left: 1.5em;
+}
+#content p {
+ margin-left: 1em;
+}
+.post , .page
+{
+ margin:0 0 30px 0;
+}
+.page
+{
+ margin:25px -5px 0 27px;
+}
+.post-info, .page-info
+{
+ font-size:0.85em;
+ font-family: Verdana, Arial, Sans-Serif;
+ margin:0;
+ padding:0;
+ color:#333;
+}
+.page-info
+{
+ text-align:center;
+}
+.post-info a
+{
+ color:#990000;
+}
+.post-info a:hover
+{
+ color:#000;
+}
+.post-content, .page-content {
+ padding:10px 0;
+ margin:3px 0;
+ border-top:#BBC4A3 1px solid;
+ font-family: Georgia, Verdana, Arial, serif;
+ font-size:12px;
+}
+.page-content {
+
+}
+.post-title, .page-title {
+ font-family:Georgia, Arial, Serif;
+ font-size:1.3em;
+ margin:0;
+ font-weight:bold;
+}
+.page-title
+{
+ font-size:1.6em;
+ font-weight:normal;
+}
+#content .page-title a, .post-title a:link, .post-title a:visited, .post-title a:hover, .post-title a:active
+{
+ text-decoration:none;
+ color:#676E04;
+}
+.post-date {
+ float: left;
+ color: #BBC4A3;
+ font-family: Georgia,'Lucida sans ms', Verdana, Arial, Helvetica, sans-serif;
+ font-size: 0.9em;
+ text-align: center;
+ font-weight: bold;
+ margin: 3px 10px 0 0;
+ padding: 8px 3px;
+ width: 55px;
+ background: #E7EBDE;
+ line-height:1em;
+}
+.post-footer
+{
+ padding-top:20px;
+ background:url(../img/divider.gif) no-repeat center;
+}
+#footer {
+ margin:0 auto;
+ padding: 7px 0;
+ border-top:#BBC4A3 1px solid;
+ clear: both;
+ font-size: 0.8em;
+ color: #999;
+ text-align:center;
+ width:740px;
+}
+#footer a {
+border:none;
+color:#7A7636;
+}
+
+.commentlist {
+ font-size:1em;
+ font-weight:normal;
+}
+#commentform
+{
+ margin:0 0 0 40px;
+}
+#commentform textarea {
+ width: 80%;
+}
+#commentform p {
+ margin: 0 0 1em;
+}
+#comments,#respond {
+ text-transform: uppercase;
+ margin: 3em 0 1em 40px;
+ color: #676E04;
+ font: 0.9em verdana, helvetica, sans-serif;
+}
+.commentlist li
+{
+ margin:5px 0;
+ padding:10px 10px 20px 10px;
+ background:#F3F6ED url(../img/comments_bottom.jpg) repeat-x bottom;
+ border:#E1D6C6 1px solid;
+}
+.commentlist .alt
+{
+
+}
+#topnav
+{
+ list-style:none;
+ font-size:0.9em;
+ margin:0;
+ padding:11px 20px 0 0;
+ text-align:right;
+ font-family:Verdana, Arial, Sans-Serif;
+}
+#topnav li
+{
+ list-style:none;
+ display:inline;
+ padding:0;
+ margin:0;
+ font-weight:bold;
+}
+
+#topnav li.sep
+{
+ margin-left: 3px;
+ margin-right: 3px;
+ margin-top: 1px;
+ margin-bottom: 1px;
+ padding: 0;
+ padding-bottom: 2px;
+ border-left: 1px solid #3B4423;
+ border-right: 1px solid #F7F3ED;
+}
+
+#topnav li a:link, #topnav li a:visited
+{
+ text-decoration:none;
+ color:#BBC4A3;
+ border-left: 1px solid #7D8B5A;
+ border-right: 1px solid #7D8B5A;
+ background-color: #7D8B5A;
+ padding: 3px;
+ margin: 0;
+}
+#topnav li a:hover, #topnav li a:focus
+{
+ color:#F7F3ED;
+ border-left: 1px solid #F7F3ED;
+ border-right: 1px solid #F7F3ED;
+ background-color: #BBC4A3;
+ padding-left: 3px;
+ padding-right: 3px;
+ padding-top: 3px;
+ padding-bottom: 5px;
+ margin: 0;
+}
+
+div.jswindow { font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; display: none; position: absolute; list-style-type: none;
+ padding: 2px;
+ margin: 0;
+ margin-top: 7px;
+ font-size: 0.9em;
+ border:#E1D6c6 1px solid;
+ background:#F3F6ED;
+ }
+div.titlebar { font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; cursor: default; margin: 0 0 0 0;
+ padding:2px;
+ margin: 2px;
+
+ font-size: 1em;
+ color: #676E04;
+ text-align:center;
+ background: #e2ebda;
+ border:0px solid #ccc;
+ height:22px;
+ font-weight:bold; }
+div.titlebar div.closebtn { width: 16px; height: 16px; background-color: #e2ebda; display: block; }
+div.titlebar div.closebtn:hover { width: 16px; height: 16px; background-color: #F3F6ED; display: block; }
+
+div.titlebar table, div.titlebar td { margin: 0; padding: 0; }
+div.jswindow div.content { padding: 5px;
+ overflow: hidden;
+ }
+
+div.pagebar { background-color: #F3F6ED; margin-top: 0px; padding: 3px; font-size: 7pt; text-align: left; font-family: arial, helvetica, sans-serif; }
+div.pagebar a { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #909D73; }
+div.pagebar a:hover { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #990000; background-color: #BBC4A3; }
+div.pagebar#pagebarpopup { display: none; position: absolute; width: 150px; padding: 0; }
+div.pagebar#pagebarpopup a { display: block; margin: 0; }
+
+/*
+ * jBox menu system
+ */
+
+/* Exception for Connections theme */
+div#pagebar_main {
+ margin: 0px 7px 0px 8px;
+}
+
+div.menu {
+ background-color: #F3F6ED;
+ font-size: 7pt;
+ border-width: 0;
+}
+div.menu a, div.menu div.label {
+ padding: 2.5pt 5px;
+ margin-right: 3px;
+ text-decoration: none;
+ display: block;
+ float: left;
+ color: #909D73;
+}
+div.menu div.label {
+ color: #201000;
+ cursor: default;
+}
+div.menu span.sep {
+ display: block;
+ float: left;
+ width: 5px;
+}
+div.menu div.multopts {
+ line-height: 17pt;
+}
+div.menu div.multopts a, div.menu div.multopts div.label {
+ float: none;
+ display: inline;
+}
+div.menu a.liteselected, div.menu a.liteselected:hover, div.menu a:hover {
+ color: #990000;
+ background-color: #BBC4A3;
+}
+div.menu input[type ^="text"], div.menu input[type ^="password"] {
+ border-width: 0;
+ font-size: 9pt;
+ padding: 4px 5px;
+ max-width: 70px;
+ background-color: #E3E6DD;
+}
+div.menu input[type ^="text"]:hover, div.menu input[type ^="password"]:hover {
+ background-color: #ECEFF6;
+}
+div.menu input[type ^="text"]:focus, div.menu input[type ^="password"]:focus {
+ background-color: #FAFDF6;
+}
+div.menu input[type ^="button"], div.menu input[type ^="submit"] {
+ border-width: 0;
+ font-size: 9pt;
+ padding: 3px 5px;
+ max-width: 70px;
+}
+div.menu a.current, div.menu a.current:hover, div.menu a.selected, div.menu a.selected:hover {
+ color: #400000;
+ background-color: transparent;
+ background-image: url(../img/content_bg.gif);
+}
+div.menu ul {
+ display: none;
+ position: absolute;
+ padding: 0;
+ margin: 0;
+ background-color: #F3F6ED;
+ border-width: 0;
+ min-width: 120px;
+}
+div.menu ul li {
+ list-style: none;
+}
+div.menu ul a {
+ float: none;
+ margin: 0;
+}
+span.menuclear {
+ font-size: 1px;
+ height: 0px;
+ width: 0px;
+ clear: left;
+ line-height: 0px;
+ display: block;
+}
+
+.mdg-comment { margin: 0; margin-left: 0.2in; padding: 10px; border: 1px #E1D6C6 solid; margin-bottom: 10px; }
+.tblholder { margin: 0; margin-left: 0.2in; padding: 0px; border: 1px #E1D6C6 solid; margin-bottom: 10px; }
+
+.tblholder th { padding: 4px; background-color: #C8D6A3 !important; color: #696E5B !important; }
+.tblholder td.row1 { padding: 4px; background-color: #E3E6DD !important; }
+.tblholder td.row2 { padding: 4px; background-color: #F3F6ED !important; }
+.tblholder td.row3 { padding: 4px; background-color: #EBEDE6 !important; }
+.tblholder table { background-color: #FFFFFF; }
+.tblholder th.subhead { padding: 4px; background-color: #D0D4C7 !important; color: #696E5B !important; }
+
+.catCheck { padding: 3px; }
+.catCheck:hover { padding: 3px; background-color: #F3F6ED; }
+
+/* Information, warning, question, and error boxes */
+div.error-box { background-image: url(../../../images/error.png); background-repeat: no-repeat; background-color: #FFF4F4; border: 1px dashed #8a3207; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.info-box { background-image: url(../../../images/info.png); background-repeat: no-repeat; background-color: #F4F4FF; border: 1px dashed #8a3207; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.warning-box { background-image: url(../../../images/warning.png); background-repeat: no-repeat; background-color: #FFFFF4; border: 1px dashed #8a3207; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.question-box { background-image: url(../../../images/question.png); background-repeat: no-repeat; background-color: #F4FFF4; border: 1px dashed #8a3207; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+
+table#stretcher {
+ width: 100%;
+ height: 100%;
+}
+
+a.wikilink-nonexistent, a.wikilink-nonexistent:hover {
+ color: #B05020;
+ text-decoration: underline;
+ border-bottom: 1px dotted;
+}
+a.wikilink-nonexistent:hover {
+ color: #D06030;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/connections/elements.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,38 @@
+<!-- VAR toolbar_button --><a href="{HREF}" {PARENTFLAGS} {FLAGS}>{TEXT}</a>
+<!-- ENDVAR toolbar_button -->
+<!-- VAR toolbar_label --><div class="label">{TEXT}</div>
+<!-- ENDVAR toolbar_label -->
+<!-- VAR toolbar_button_selected --><a href="{HREF}" class="current" {PARENTFLAGS} {FLAGS}>{TEXT}</a>
+<!-- ENDVAR toolbar_button_selected -->
+<!-- VAR toolbar_menu_button --><li><a href="{HREF}" {FLAGS}>{TEXT}</a></li>
+<!-- ENDVAR toolbar_menu_button -->
+<!-- VAR toolbar_menu_block --><li>{HTML}</li>
+<!-- ENDVAR toolbar_menu_block -->
+<!-- VAR sidebar_button --><a href="{HREF}" {FLAGS}>{TEXT}</a><br style="display: none;" />
+<!-- ENDVAR sidebar_button -->
+<!-- VAR sidebar_raw --><span style="text-align: center;">{HTML}</span><br style="display: none;" />
+<!-- ENDVAR sidebar_raw -->
+<!-- VAR sidebar_heading --><div class="heading">{TEXT}</div>
+<!-- ENDVAR sidebar_heading -->
+<!-- VAR sidebar_top -->
+<!-- ENDVAR sidebar_top -->
+<!-- VAR sidebar_section -->
+ <div class="slider">
+ <div class="heading">
+ <br style="display: none;" /><br style="display: none;" />
+ <a class="head" onclick="toggle(this); return false" href="#">{TITLE}</a><br style="display: none;" /><br style="display: none;" />
+ </div>
+ <div class="slideblock">{CONTENT}</div>
+ </div>
+<!-- ENDVAR sidebar_section -->
+<!-- VAR sidebar_section_raw -->
+ <div class="slider">
+ <div class="heading">
+ <br style="display: none;" /><br style="display: none;" />
+ <a class="head" onclick="toggle(this); return false" href="#">{TITLE}</a><br style="display: none;" /><br style="display: none;" />
+ </div>
+ <div class="slideblock2">{CONTENT}</div>
+ </div>
+<!-- ENDVAR sidebar_section_raw -->
+<!-- VAR sidebar_bottom -->
+<!-- ENDVAR sidebar_bottom -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/connections/footer.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,30 @@
+
+ <!-- FINISH CONTENT -->
+ </div>
+
+ <div class="post-info"></div>
+ <div class="post-footer"> </div>
+
+ </div>
+
+ </div> <!-- div.post -->
+
+ </div> <!-- div#content -->
+
+ <!-- BEGINNOT in_admin -->
+ <div id="sidebar">
+
+ {SIDEBAR_LEFT}
+ {SIDEBAR_RIGHT}
+
+ </div> <!-- div sidebar -->
+ <!-- END in_admin -->
+
+ <p id="footer">
+ {COPYRIGHT}<br />
+ Powered by <a href="http://enano.homelinux.org">Enano</a> | Theme by <a href="http://www.vanillamist.com/">Patricia Muller</a> | <a href="http://validator.w3.org/check?uri=referer">Valid XHTML 1.1</a> | <a href="http://jigsaw.w3.org/css-validator/validator?profile=css2&warning=2&uri={REQUEST_URI}">Valid CSS</a> | [[Stats]]
+ </p>
+ </div>
+ </div> <!-- div rap -->
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/connections/header.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,61 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html>
+ <head>
+ <title>{PAGE_NAME} • {SITE_NAME}</title>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <link rel="stylesheet" type="text/css" href="{SCRIPTPATH}/includes/clientside/css/enano-shared.css" />
+ <link id="mdgCss" rel="stylesheet" type="text/css" href="{SCRIPTPATH}/themes/{THEME_ID}/css/{STYLE_ID}.css" />
+ {JS_DYNAMIC_VARS}
+ <!-- This script automatically loads the other 15 JS files -->
+ <script type="text/javascript" src="{SCRIPTPATH}/includes/clientside/static/enano-lib-basic.js"></script>
+ {ADDITIONAL_HEADERS}
+ </head>
+ <body>
+
+ <div id="root1" class="jswindow">
+ <div id="tb1" class="titlebar">Confirm Logout</div>
+ <div class="content" id="cn1">
+ <form action="{CONTENTPATH}Special:Logout" method="get">
+ <div style="text-align: center">
+ <h3>Are you sure you want to log out?</h3>
+ <input type="submit" value="Log out" style="font-weight: bold;" /> <input type="button" onclick="jws.closeWin('root1');" value="Cancel" />
+ </div>
+ </form>
+ </div>
+ </div>
+ <div id="root2" class="jswindow">
+ <div id="tb2" class="titlebar">Change style</div>
+ <div class="content" id="cn2">
+ If you can see this text, it means that your browser does not support Cascading Style Sheets (CSS). CSS is a fundemental aspect of XHTML, and as a result it is becoming very widely adopted by websites, including this one. You should consider switching to a more modern web browser, such as Mozilla Firefox or Opera 9.
+ </div>
+ </div>
+
+ <div id="rap">
+ <div id="header">
+ <ul id="topnav">
+ <li> </li>
+ </ul>
+ <h1><a href="{CONTENTPATH}" title="{SITE_NAME}">{SITE_NAME}</a></h1>
+ <div id="desc">{PAGE_NAME}</div>
+ </div>
+ <div class="menu_nojs" id="pagebar_main">
+ <div class="label">Page tools</div>
+ {TOOLBAR}
+ <ul>
+ {TOOLBAR_EXTRAS}
+ </ul>
+ <span class="menuclear"> </span>
+ </div>
+ <div id="main">
+ <div id="content">
+ <div class="post">
+ <div class="post-info">
+ <div style="float: right;">
+ <image alt=" " src="{SCRIPTPATH}/images/spacer.gif" id="ajaxloadicon" />
+ </div>
+ <h2 class="post-title">{PAGE_NAME}</h2>
+ </div>
+ <div class="post-content">
+
+ <div id="ajaxEditContainer">
+ <!-- START CONTENT -->
Binary file themes/connections/img/blockquote.gif has changed
Binary file themes/connections/img/bullet.gif has changed
Binary file themes/connections/img/comment.png has changed
Binary file themes/connections/img/comments_bottom.jpg has changed
Binary file themes/connections/img/content_bg.gif has changed
Binary file themes/connections/img/contentbg.jpg has changed
Binary file themes/connections/img/divider.gif has changed
Binary file themes/connections/img/rap.jpg has changed
Binary file themes/connections/img/sidenav_bottom.jpg has changed
Binary file themes/connections/img/sidenav_top.jpg has changed
Binary file themes/connections/img/sub-bullet.gif has changed
Binary file themes/connections/img/subcat_bullet.gif has changed
Binary file themes/connections/img/top.jpg has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/connections/sidebar-editor.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,58 @@
+<!-- VAR sidebar_button --><li><a href="javascript:void(0)" {FLAGS}>{TEXT}</a></li>
+<!-- ENDVAR sidebar_button -->
+<!-- VAR sidebar_raw --><li><span style="text-align: center;">{HTML}</span></li>
+<!-- ENDVAR sidebar_raw -->
+<!-- VAR sidebar_top -->
+ <div class="recttop">
+ <table border="0" width="100%" cellspacing="0" cellpadding="0" style="font-size: 1px;">
+ <tr>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-menu-l.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;" class="recttoptop"></td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-menu-r.gif" width="12" height="12" /> </td>
+ </tr>
+ </table>
+ </div>
+<!-- ENDVAR sidebar_top -->
+<!-- VAR sidebar_section -->
+ <div class="dbx-box">
+ <div class="dbx-handle">
+ {ADMIN_START}
+
+ {TITLE}
+ {ADMIN_END}
+
+ </div>
+ <div class="dbx-content">
+ <ul>
+ {CONTENT}
+ </ul>
+ </div>
+ </div>
+<!-- ENDVAR sidebar_section -->
+<!-- VAR sidebar_section_raw -->
+ <div class="dbx-box">
+ <div class="dbx-handle">
+ {ADMIN_START}
+
+ {TITLE}
+ {ADMIN_END}
+
+ </div>
+ <div class="dbx-content dbx-content2">
+ <ul><li>
+ {CONTENT}
+ </li></ul>
+ </div>
+ </div>
+<!-- ENDVAR sidebar_section_raw -->
+<!-- VAR sidebar_bottom -->
+ <div class="rectbot">
+ <table border="0" width="100%" cellspacing="0" cellpadding="0" style="font-size: 1px;">
+ <tr>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-bl.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;" class="rectbottop"></td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-br.gif" width="12" height="12" /> </td>
+ </tr>
+ </table>
+ </div>
+<!-- ENDVAR sidebar_bottom -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/connections/simple-footer.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,21 @@
+
+ <!-- FINISH CONTENT -->
+ </div>
+
+ <div class="post-info"></div>
+ <div class="post-footer"> </div>
+
+ </div>
+
+ </div> <!-- div.post -->
+
+ </div> <!-- div#content -->
+
+ <p id="footer">
+ Powered by <a href="{CONTENTPATH}{NS_SPECIAL}About_Enano{ADMIN_SID_AUTO}">Enano</a>, copyright © 2006-2007 Dan Fuhry.
+ </p>
+ </div>
+ </div> <!-- div rap -->
+ </td></tr></table>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/connections/simple-header.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,25 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html>
+ <head>
+ <title>{PAGE_NAME} • {SITE_NAME}</title>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <link rel="stylesheet" type="text/css" href="{SCRIPTPATH}/includes/clientside/css/enano-shared.css" />
+ <link id="mdgCss" rel="stylesheet" type="text/css" href="{SCRIPTPATH}/themes/{THEME_ID}/css/{STYLE_ID}.css" />
+ {JS_DYNAMIC_VARS}
+ <!-- This script automatically loads the other 15 JS files -->
+ <script type="text/javascript" src="{SCRIPTPATH}/includes/clientside/static/enano-lib-basic.js"></script>
+ {ADDITIONAL_HEADERS}
+ </head>
+ <body>
+ <table border="0" id="stretcher" cellspacing="0" cellpadding="0"><tr><td valign="middle" id="stretcher-main">
+ <div id="rap">
+ <div id="main">
+ <div id="content">
+ <div class="post">
+ <div class="post-info">
+ <h2 class="post-title">{PAGE_NAME}</h2>
+ </div>
+ <div class="post-content">
+
+ <div id="ajaxEditContainer">
+ <!-- START CONTENT -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/connections/theme.cfg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,19 @@
+<?php
+/*
+ * Connections theme for Midget
+ * Created by dandaman32 - (C) 2006
+ * Based on the WordPress theme ;)
+ * License: GPL
+ *
+ * This theme is free software; you can redistribute and/or modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This theme is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+global $theme;
+$theme['theme_id'] = 'connections';
+$theme['theme_name'] = 'Connections';
+
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/index.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,13 @@
+<?php
+
+$_GET['title'] = 'Enano:Access_denied';
+require('../includes/common.php');
+header('HTTP/1.1 403 Forbidden');
+$session->perms['edit_page'] = AUTH_DENY;
+$session->perms['view_source'] = AUTH_DENY;
+$template->tpl_strings['PAGE_NAME'] = 'Access denied';
+
+$template->header();
+echo '<p>The administrator has flagged the page "' . $_SERVER['REQUEST_URI'] . '" so that it cannot be accessed from the web. Perhaps this is because this is a cache or includes directory and only needs to be accessed by scripts.</p><p>HTTP error: 403 Forbidden</p>';
+$template->footer();
+$db->close();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/oxygen/acledit.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,36 @@
+<!-- VAR acl_field_begin -->
+<div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4" style="width: 100%;">
+ <tr>
+ <th></th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('1');">Deny</th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('2');">Disallow</th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('3');">Wiki mode</th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('4');">Allow</th>
+ </tr>
+<!-- ENDVAR acl_field_begin -->
+<!-- VAR acl_field_item -->
+ <tr>
+ <td class="{ROW_CLASS}">{FIELD_DESC}</td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="1" name="{FIELD_NAME}" {FIELD_DENY_CHECKED} /></td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="2" name="{FIELD_NAME}" {FIELD_DISALLOW_CHECKED} /></td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="3" name="{FIELD_NAME}" {FIELD_WIKIMODE_CHECKED} /></td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="4" name="{FIELD_NAME}" {FIELD_ALLOW_CHECKED} /></td>
+ </tr>
+<!-- ENDVAR acl_field_item -->
+<!-- VAR acl_field_end -->
+ <tr>
+ <td colspan="5" class="row3">
+ <p><b>Permission types:</b></p>
+ <ul>
+ <li><b>Allow</b> means that the user is allowed to access the item</li>
+ <li><b>Wiki mode</b> means the user can access the item if wiki mode is active (per-page wiki mode is taken into account)</li>
+ <li><b>Disallow</b> means the user is denied access unless something allows it.</li>
+ <li><b>Deny</b> means that the user is denied access to the item. This setting overrides all other permissions.</li>
+ </ul>
+ </td>
+ </tr>
+ </table>
+</div>
+<!-- ENDVAR acl_field_end -->
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/oxygen/comment.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,51 @@
+<div class="tblholder">
+ <table border="0" width="100%" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2" style="text-align: left;">{DATETIME}</th>
+ </tr>
+ <tr>
+ <td style="width: 120px; height: 100%;" rowspan="4" valign="top" class="row1">
+ <table border="0" width="100%" style="height: 100%;" cellspacing="0" cellpadding="0">
+ <tr>
+ <td valign="top" class="row1">
+ <b>{NAME}</b><br />
+ <small>{USER_LEVEL}</small>
+ </td>
+ </tr>
+ <tr>
+ <td valign="bottom" class="row1">
+ {SEND_PM_LINK} {ADD_BUDDY_LINK}
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td class="row2">
+ <b>Subject:</b> <span id="subject_{ID}">{SUBJECT}</span>
+ </td>
+ </tr>
+ <tr>
+ <td class="row3">
+ <div id="comment_{ID}">{DATA}</div>
+ <!-- BEGIN signature -->
+ <hr style="margin-left: 1em; width: 200px;" />
+ {SIGNATURE}
+ <!-- END signature -->
+ </td>
+ </tr>
+ <!-- BEGIN can_edit -->
+ <tr>
+ <td class="row2">
+ [ {EDIT_LINK} | {DELETE_LINK} ]
+ </td>
+ </tr>
+ <!-- END can_edit -->
+ <!-- BEGIN auth_mod -->
+ <tr>
+ <td class="row1">
+ <b>Moderation options:</b> {MOD_APPROVE_LINK} {MOD_DELETE_LINK}
+ </td>
+ </tr>
+ <!-- END auth_mod -->
+ </table>
+</div>
+<br />
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/oxygen/css-simple/bleu.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,136 @@
+/*
+ * Oxygen, but slightly more lightweight - used on minimalist pages
+ */
+
+/* Basic definitions */
+
+html, body {
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ background-image: url(../images/bleu/bg.png);
+ font-family: trebuchet ms, verdana, arial, helvetica, sans-serif;
+ font-size: 9pt;
+}
+
+/* Dummy cells and backgrounds */
+
+/* table#enano-main td { margin: 0; padding: 0; } */
+table#enano-main td#head-up-left { width: 12px; height: 12px; background-image: url(../images/bleu/border-tl.gif); }
+table#enano-main td#head-up { height: 12px; background-image: url(../images/bleu/border-top.gif); }
+table#enano-main td#head-up-right { width: 12px; height: 12px; background-image: url(../images/bleu/border-tr.gif); }
+table#enano-main td#head-left { width: 12px; background-image: url(../images/bleu/border-l.gif); padding-bottom: 12px; }
+table#enano-main td#head-main { background-color: #90B0D0; }
+table#enano-main td#head-right { width: 12px; background-image: url(../images/bleu/border-r.gif); }
+table#enano-main td#toolbar-left { width: 12px; background-image: url(../images/bleu/border-tb-l.gif); }
+table#enano-main td#toolbar-right { width: 12px; background-image: url(../images/bleu/border-tb-r.gif); }
+table#enano-main td#main-left { width: 12px; background-image: url(../images/bleu/border-m-l.gif); }
+table#enano-main td#main-main { background-color: #FFFFFF; }
+table#enano-main td#main-right { width: 12px; background-image: url(../images/bleu/border-m-r.gif); }
+table#enano-main td#foot-left { width: 12px; background-image: url(../images/bleu/border-btm-l.gif); }
+table#enano-main td#foot-main { background-color: #E8E8E8; padding-top: 12px; }
+table#enano-main td#foot-right { width: 12px; background-image: url(../images/bleu/border-btm-r.gif); }
+table#enano-main td#foot-btm-left { width: 12px; height: 12px; background-image: url(../images/bleu/border-bl.gif); }
+table#enano-main td#foot-btm { height: 12px; background-image: url(../images/bleu/border-btm.gif); }
+table#enano-main td#foot-btm-right { width: 12px; height: 12px; background-image: url(../images/bleu/border-br.gif); }
+
+/* Sidebar */
+
+td.mdgSidebarHolder { width: 156px; }
+div.sidebar, .dbx-group { width: 154px; background-color: #F8F8F8; border-left: 1px solid #CCC; border-right: 1px solid #CCC; padding: 1px 0px 0px 0px; }
+div.sidebar .head, .dbx-handle { background-color: #F0F0F0; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #111; padding: 5px; font-weight: bold; }
+div.sidebar .head:hover, .dbx-handle:hover { background-color: #F4F4F4; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #111; padding: 5px; font-weight: bold; }
+div.sidebar div.slideblock a, .dbx-content li { background-color: #DDD; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #666; padding: 5px 5px 5px 9px; list-style-type: none; }
+div.sidebar div.slideblock a:hover, .dbx-content li:hover { background-color: #EEE; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #666; padding: 5px 5px 5px 9px; }
+div.recttop { width: 156px; height: 12px; margin: 0; padding: 0; }
+td.recttoptop { width: 100%; height: 12px; background-image: url(../images/bleu/border-menu-t.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+td.recttoptop:hover { width: 100%; height: 12px; background-image: url(../images/bleu/border-menu-t-h.gif); background-repeat: repeat-x; margin: 0; padding: 0; cursor: pointer; }
+div.rectbot { width: 156px; height: 12px; margin: 0; padding: 0; }
+td.rectbottop { width: 100%; height: 12px; background-image: url(../images/bleu/border-btm.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+div.slideblock, .dbx-content { overflow: hidden; background-color: #FFF; }
+div.slideblock2 { overflow: hidden; background-color: #DDD; margin: 0px 1px 0px 1px; }
+.dbx-handle { cursor: move !important; }
+
+/*
+ * Docking Boxes code (for the sidebar editor)
+ */
+
+/* group container(s) */#sbedit {margin: 0;padding: 0;/* position:relative; /* additional outer containers must also have position:relative */}/* keyboard navigation tooltip */.dbx-tooltip {display:block;position:absolute;margin:36px 0 0 125px;width:185px;border:1px solid #000;background:#ffd;color:#000;font:normal normal normal 0.85em tahoma, arial, sans-serif;padding:2px 4px 3px 5px;text-align:left;}* html .dbx-tooltip { width:195px; }/* use CSS2 system colors in CSS2 browsersbut not safari, which doesn't support them */*[class="dbx-tooltip"]:lang(en) {border-color:InfoText;background:InfoBackground;color:InfoText;font:small-caption;font-weight:normal;}/* additional clone styles */.dbx-clone {opacity: 0.8;}.dbx-content ul {margin: 0; padding: 0;}.dbx-content li a, .dbx-content li a:hover {text-decoration: none; color: #666;}.dbx-content2 {background-color: #DDD; margin: 0px 1px 0px 1px;}/* toolbar */div.toolbar {border-bottom: 1px solid #909090;background-color: #D0D0D0;padding: 2px 0;height: 22px;font-family: arial, sans-serif;font-size: 8pt;}div.toolbar ul {margin: 0;padding: 0;}div.toolbar ul li {list-style: none;margin: 0;float: left;}div.toolbar a img {opacity: 0.6;/*filter: alpha(opacity=60);*/}div.toolbar a:hover img {opacity: 1;/*filter: alpha(opacity=100);*/}div.toolbar a {display: block;padding: 2px;border: 1px solid transparent;cursor: default;width: auto;color: #000000;margin: 0 2px;max-height: 16px;text-decoration: none;}div.toolbar a:hover {border: 1px solid #202090;background-color: #ceceed;color: #000000;text-decoration: none;}div.toolbar a:active {border: 1px solid #A0A0A0;background-color: #E0E0E0;}div.toolbar img {margin: 0;padding: 0;display: inline;border-width: 0px;}div.toolbar a span {position: relative;top: -4px;}div.toolbar li span {padding-left: 2px;padding-right: 5px;}/* vertical toolbar */div.toolbar_vert {border: 1px solid #909090;background-color: #D0D0D0;padding: 2px 0;}div.toolbar_vert ul {margin: 0;padding: 0;}div.toolbar_vert ul li {list-style: none;margin: 0;}div.toolbar_vert a img {opacity: 0.6;/*filter: alpha(opacity=60);*/}div.toolbar_vert a:hover img {opacity: 1;/*filter: alpha(opacity=100);*/}div.toolbar_vert a {display: block;padding: 2px;border: 1px solid transparent;cursor: default;width: auto;color: #000000;margin: 0 2px;max-height: 16px;text-decoration: none;}div.toolbar_vert a:hover {border: 1px solid #202090;background-color: #ceceed;color: #000000;text-decoration: none;}div.toolbar_vert a:active {border: 1px solid #A0A0A0;background-color: #E0E0E0;}div.toolbar_vert img {margin: 0;padding: 0;display: inline;border-width: 0px;}div.toolbar_vert a span {position: relative;top: -4px;}div.toolbar_vert li span {padding-left: 2px;padding-right: 5px;}
+
+/* Header */
+
+table#enano-main td#head-main {
+ text-align: center;
+}
+
+table#enano-main td#head-main h1 {
+ font-size: 14pt;
+}
+
+/* The "page tools" bar below the site logo but above the page content */
+div.pagebar { background-color: #B0D0F0; margin-top: 0px; padding: 3px; font-size: 7pt; }
+div.pagebar a { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #406080; }
+div.pagebar a.selected { background-color: #FFFFFF; color: #000040; font-weight: bold; }
+div.pagebar a:hover { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #406080; background-color: #D0F0FF; }
+div.pagebar input { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #E0F0FF; }
+div.pagebar input:hover { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #D0F0FF; }
+div.pagebar input:focus { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #F0F0FF; }
+
+/* Tweaks for the popup menu version of the same thing */
+div.pagebar#pagebarpopup { display: none; position: absolute; width: 150px; padding: 0; overflow: hidden; }
+div.pagebar#pagebarpopup a, div#pagebarpopup2 a { display: block; margin: 0; }
+
+/* Content area */
+table#enano-main td#main-main {
+ padding: 10px 0;
+}
+
+/* Text, headings, and links inside the main div (usually #ajaxEditContainer but used some other places as well) * /
+table#enano-main td#main-main h2 { border-bottom: 1px solid #90B0D0; margin-bottom: 0; }
+table#enano-main td#main-main h3 { font-size: 11pt; font-weight: bold; }
+table#enano-main td#main-main li { list-style: url(../images/bullet.gif); }
+table#enano-main td#main-main blockquote { background-color: #F4F4F4; border: 1px dotted #406080; margin: 1em; padding: 10px; max-height: 250px; overflow: auto; }
+table#enano-main td#main-main a { color: #7090B0; }
+table#enano-main td#main-main a:hover { color: #90B0D0; }
+table#enano-main td#main-main a[href ^="http://"] { color: #80A0C0; background: url(../images/bleu/external.gif) center right no-repeat; padding-right: 16px; }
+table#enano-main td#main-main a[href ^="https://"] { color: #80A0C0; background: url(../images/bleu/https.gif) center right no-repeat; padding-right: 16px; }
+table#enano-main td#main-main a[href ^="mailto:"] { color: #80A0C0; background: url(../images/bleu/email.gif) center right no-repeat; padding-right: 16px; }
+table#enano-main td#main-main a[href ^="irc://"] { color: #80A0C0; background: url(../images/bleu/irc.gif) center right no-repeat; padding-right: 16px; }
+table#enano-main td#main-main a[href ^="http://"]:hover { color: #A0C0E0; background: url(../images/bleu/external.gif) center right no-repeat; padding-right: 16px; }
+table#enano-main td#main-main a[href ^="https://"]:hover { color: #A0C0E0; background: url(../images/bleu/https.gif) center right no-repeat; padding-right: 16px; }
+table#enano-main td#main-main a[href ^="mailto:"]:hover { color: #A0C0E0; background: url(../images/bleu/email.gif) center right no-repeat; padding-right: 16px; }
+table#enano-main td#main-main a[href ^="irc://"]:hover { color: #A0C0E0; background: url(../images/bleu/irc.gif) center right no-repeat; padding-right: 16px; }
+
+/* Footer */
+
+table#enano-main td#foot-main {
+ color: #AAA;
+ font-size: 7pt;
+}
+
+/* Styled boxes */
+
+.mdg-comment, .mdg-infobox { margin-left: 1em; padding: 7px; border: 1px solid #AAAAAA; background-color: #E8E8E8; }
+
+/* Tables */
+
+.tblholder { margin: 10px 0 0 0; padding: 0; border: 1px solid #AAAAAA; background-color: #E8E8E8; }
+div.tblholder td.row1 { padding: 4px; background-color: #E0E0E0; }
+div.tblholder td.row2 { padding: 4px; background-color: #F0F0F0; }
+div.tblholder td.row3 { padding: 4px; background-color: #E8E8E8; }
+div.tblholder th { padding: 4px; background-color: #7080A0; font-weight: bold; text-align: center; color: #FFFFFF; }
+div.tblholder th.subhead { padding: 4px; background-color: #90A0B0; font-weight: bold; text-align: center; color: #FFFFFF; }
+div.tblholder table { background-color: #FFFFFF; width: 100%; }
+
+/* Buttons and textboxes - these settings are used almost everywhere */
+
+input, textarea, select { border: 1px solid #406080; background-color: #F2F2F2; padding: 3px; font-family: arial, helvetica, sans-serif; font-size: 9pt; }
+input:hover, textarea:hover, select:hover { border: 1px solid #6080A0; background-color: #F8F8F8; padding: 3px; }
+input:focus, textarea:focus, select:focus { border: 1px solid #90B0D0; background-color: #FFFFFF; padding: 3px; }
+label { padding: 3px; cursor: pointer; }
+label:hover { padding: 3px; cursor: pointer; background-color: #F0F0F0; }
+input#pageheading { font-size: 14pt; border-bottom: 1px solid #90B0D0; margin-bottom: 0; }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/oxygen/css/_printable.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,131 @@
+/**
+ * The original Oxygen theme for Enano
+ * Designed by Dan Fuhry, (C) 2006
+ * This theme is Free Software; see the file "GPL" included with this package for details.
+ */
+
+/* The basics */
+html,body { height: 100%; }
+body { margin: 0; padding: 0; background-color: #FFFFFF; font-family: trebuchet ms, verdana, arial, helvetica, sans-serif; font-size: 9pt; }
+.holder { border: 1px solid #CCCCCC; padding: 1px; background-color: #FFFFFF; color: #444444 }
+div.pad { padding: 10px; }
+table#title { margin: 0; padding: 0; height: 100px; background-color: #FFFFFF; text-align: center; border: 1px solid #000000; }
+
+/* Sidebar */
+td.mdgSidebarHolder { width: 0px; }
+div.sidebar { display: none; }
+div.recttop, div.rectbot { display: none; }
+
+/* The credits thingy at the bottom */
+div#credits { margin: 0; padding: 10px; background-color: #FFFFFF; color: #AAA; font-size: 7pt; border: 1px solid #000000; }
+div#credits a { color: #B0B0B0; text-decoration: underline; }
+div#credits a:hover { color: #A0A0A0; text-decoration: underline; }
+
+/* The link hidden in plain "site" at the top of the page */
+td#mainhead a { text-decoration: none; color: #000000; }
+td#mainhead a:hover { text-decoration: none; color: #000000; border-bottom: 1px dotted #406080; }
+
+/* Text, headings, and links inside the main div (usually #ajaxEditContainer but used some other places as well) */
+div.contentDiv h2 { border-bottom: 1px solid #AAAAAA; margin-bottom: 0; }
+div.contentDiv h3 { font-size: 11pt; font-weight: bold; }
+div.contentDiv li { list-style: square; }
+div.contentDiv p { margin-left: 1.0em; }
+div.contentDiv blockquote { background-color: #F4F4F4; border: 1px dotted #406080; margin: 1em; padding: 10px; max-height: 250px; overflow: auto; }
+div.contentDiv { font-size: 9pt; }
+div.contentDiv a { color: #909090; }
+div.contentDiv a:hover { color: #B0B0B0; }
+div.contentDiv a[href ^="http://"] { color: #A0A0A0; }
+div.contentDiv a[href ^="https://"] { color: #A0A0A0; }
+div.contentDiv a[href ^="irc://"] { color: #A0A0A0; }
+div.contentDiv a[href ^="mailto:"] { color: #A0A0A0; }
+div.contentDiv a[href ^="http://"]:hover { color: #C0C0C0; }
+div.contentDiv a[href ^="https://"]:hover { color: #C0C0C0; }
+div.contentDiv a[href ^="mailto:"]:hover { color: #C0C0C0; }
+div.contentDiv a[href ^="irc://"]:hover { color: #C0C0C0; }
+
+/* Wikilinks to pages that don't exist
+div.contentDiv a.wikilink-nonexistent { color: #B05020; }
+div.contentDiv a.wikilink-nonexistent:hover { color: #D06030; } */
+
+/* Well, not Midget and not comments (usually), but that's what the class is called ;-). Basically an informational window or used as a wrapper for tables. */
+.mdg-comment { margin-left: 1em; padding: 7px; border: 1px solid #AAAAAA; background-color: #E8E8E8; }
+
+/* The beautiful tables inside what may not obviously be mdg-comment divs */
+.mdg-comment td.row1 { padding: 4px; background-color: #FFFFFF; margin: 1px; border: 1px solid #CCCCCC; }
+.mdg-comment td.row2 { padding: 4px; background-color: #FFFFFF; margin: 1px; border: 1px solid #CCCCCC; }
+.mdg-comment td.row3 { padding: 4px; background-color: #FFFFFF; margin: 1px; border: 1px solid #CCCCCC; }
+.mdg-comment th { padding: 4px; background-color: #FFFFFF; margin: 1px; border: 1px solid #CCCCCC; font-weight: bold; text-align: center; }
+.mdg-comment th.subhead { padding: 4px; background-color: #FFFFFF; margin: 1px; border: 1px solid #CCCCCC; font-weight: bold; text-align: center; }
+.mdg-comment table { background-color: #FFFFFF; }
+
+/* Same as mdg-comment, but without the cute comment icon. Mostly unused. */
+.mdg-infobox { margin-left: 1em; padding: 7px; border: 1px solid #AAAAAA; background-color: #E8E8E8; }
+
+/* The "page tools" bar below the site logo but above the page content */
+div.pagebar { background-color: #FFFFFF; margin-top: 0px; padding: 3px; font-size: 7pt; border: 1px solid #000000; border-top: none; }
+div.pagebar a { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #606060; }
+div.pagebar a:hover { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #606060; background-color: #F0F0F0; }
+div.pagebar input { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #E8E8E8; }
+div.pagebar input:hover { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #F0F0F0; }
+div.pagebar input:focus { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #F8F8F8; }
+
+/* Tweaks for the popup menu version of the same thing */
+div.pagebar#pagebarpopup { display: none; position: absolute; width: 150px; padding: 0; }
+div.pagebar#pagebarpopup a, div#pagebarpopup2 a { display: block; margin: 0; }
+
+/* Rounded corners on nearly everything */
+td#mdg-tl { margin: 0; padding: 0; width: 0; height: 0; }
+td#mdg-tr { margin: 0; padding: 0; width: 0; height: 0; }
+td#mdg-top { margin: 0; padding: 0; width: 0; height: 0; }
+td#mdg-l { margin: 0; padding: 0; width: 0; height: 0; }
+td#mdg-r { margin: 0; padding: 0; width: 0; height: 0; }
+td#mdg-bl { margin: 0; padding: 0; width: 0; height: 0; }
+td#mdg-br { margin: 0; padding: 0; width: 0; height: 0; }
+td#mdg-ml { margin: 0; padding: 0; width: 0; height: 0; }
+td#mdg-mr { margin: 0; padding: 0; width: 0; height: 0; }
+td#mdg-brl { margin: 0; padding: 0; width: 0; height: 0; }
+td#mdg-brr { margin: 0; padding: 0; width: 0; height: 0; }
+td#mdg-btl { margin: 0; padding: 0; width: 0; height: 0; }
+td#mdg-btr { margin: 0; padding: 0; width: 0; height: 0; }
+td#mdg-btcl { margin: 0; padding: 0; width: 0; height: 0; }
+td#mdg-btcr { margin: 0; padding: 0; width: 0; height: 0; }
+td#mdg-btm { margin: 0; padding: 0; width: 0; height: 0; }
+td.mdg-menu-top { margin: 0; padding: 0; width: 0; height: 0; }
+td.mdg-menu-tl { margin: 0; padding: 0; width: 0; height: 0; }
+td.mdg-menu-tr { margin: 0; padding: 0; width: 0; height: 0; }
+td.mdg-menu-bl { margin: 0; padding: 0; width: 0; height: 0; }
+td.mdg-menu-br { margin: 0; padding: 0; width: 0; height: 0; }
+td.mdg-menu-btm { margin: 0; padding: 0; width: 0; height: 0; }
+
+/* Buttons and textboxes - these settings are used almost everywhere */
+input, textarea, select { border: 1px solid #406080; background-color: #F2F2F2; padding: 3px; }
+input:hover, textarea:hover, select:hover { border: 1px solid #6080A0; background-color: #F8F8F8; padding: 3px; }
+input:focus, textarea:focus, select:focus { border: 1px solid #90B0D0; background-color: #FFFFFF; padding: 3px; }
+label { padding: 3px; cursor: pointer; }
+label:hover { padding: 3px; cursor: pointer; background-color: #F0F0F0; }
+
+/* JWS window theming */
+div.jswindow { border: 2px solid #7090B0; border-top: 5px solid #7090B0; padding: 0px; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; display: none; position: absolute; background-color: #FFFFFF; }
+div.titlebar { background-color: #7090B0; color: #FFFFFF; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; padding-bottom: 4px; cursor: default; }
+div.titlebar div.closebtn { width: 16px; height: 16px; border: 1px solid #B0D0F0; background-color: #90B0D0; display: block; }
+div.titlebar div.closebtn:hover { width: 16px; height: 16px; border: 1px solid #FFFFFF; background-color: #B0D0F0; display: block; }
+div.titlebar table, div.titlebar td { margin: 0; padding: 0; }
+div.jswindow div.content { padding: 10px; margin: 0; background-color: #FFFFFF; }
+
+/* The Wordpress-like fills behind checkboxes and their labels */
+.catCheck { padding: 3px; }
+.catCheck:hover { padding: 3px; background-color: #F0F0F0; }
+
+/* Information, warning, question, error, and wait boxes */
+div.error-box { background-color: #F0F0F0; border: 1px dashed #606060; padding: 10px; margin: 1em 0 0 1em; min-height: 25px; }
+div.info-box { background-color: #F0F0F0; border: 1px dashed #606060; padding: 10px; margin: 1em 0 0 1em; min-height: 25px; }
+div.warning-box { background-color: #F0F0F0; border: 1px dashed #606060; padding: 10px; margin: 1em 0 0 1em; min-height: 25px; }
+div.question-box { background-color: #F0F0F0; border: 1px dashed #606060; padding: 10px; margin: 1em 0 0 1em; min-height: 25px; }
+div.wait-box { background-color: #F0F0F0; border: 1px dashed #606060; padding: 10px; margin: 1em 0 0 1em; min-height: 25px; }
+
+/* This stuff is mostly unused, left in for compatibility */
+div#ajaxEditContainer table { border: 0px solid #FFFFFF; }
+div#ajaxEditContainer td { margin: 1px; }
+/* div#ajaxEditContainer { overflow: auto; } /* Makes ajaxEditContainer scroll horizontally in firefox if the content is too wide - prevents that ugly clipping effect */
+div#ajaxEditContainer pre { margin-left: 1em; background-color: #F8F8F8; border: 1px dashed #90B0D0; padding: 10px; overflow: auto; max-height: 150px; }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/oxygen/css/bleu.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,372 @@
+/**
+ * The original Oxygen theme for Enano
+ * Designed by Dan Fuhry, (C) 2006
+ * This theme is Free Software; see the file "GPL" included with this package for details.
+ */
+
+/* The basics */
+html,body { height: 100%; }
+body { margin: 0; padding: 0; background: url(../images/bleu/bg.png); font-family: trebuchet ms, verdana, arial, helvetica, sans-serif; font-size: 9pt; }
+.holder { border: 1px solid #CCCCCC; padding: 1px; background-color: #FFFFFF; color: #444444 }
+div.pad { padding: 10px; }
+table#title { margin: 0; padding: 0; height: 100px; background-color: #90B0D0; text-align: center; }
+
+/* Sidebar */
+td.mdgSidebarHolder { width: 140px; }
+div.sidebar, .dbx-group { width: 138px; background-color: #F8F8F8; border-left: 1px solid #CCC; border-right: 1px solid #CCC; padding: 1px 0px 0px 0px; }
+div.sidebar .head, .dbx-handle { background-color: #F0F0F0; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #111; padding: 5px; font-weight: bold; }
+div.sidebar .head:hover, .dbx-handle:hover { background-color: #F4F4F4; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #111; padding: 5px; font-weight: bold; }
+div.sidebar div.slideblock a, .dbx-content li { background-color: #DDD; display: block; margin: 0px 1px; border-bottom: 1px solid #FFF; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #666; padding: 5px 5px 5px 9px; list-style-type: none; }
+div.sidebar div.slideblock a:hover, .dbx-content li:hover { background-color: #EEE; display: block; margin: 0px 1px; border-bottom: 1px solid #FFF; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #666; padding: 5px 5px 5px 9px; }
+div.recttop { width: 140px; height: 12px; margin: 0; padding: 0; }
+td.recttoptop { width: 100%; height: 12px; background-image: url(../images/bleu/border-menu-t.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+td.recttoptop:hover { width: 100%; height: 12px; background-image: url(../images/bleu/border-menu-t-h.gif); background-repeat: repeat-x; margin: 0; padding: 0; cursor: pointer; }
+div.rectbot { width: 140px; height: 12px; margin: 0; padding: 0; }
+td.rectbottop { width: 100%; height: 12px; background-image: url(../images/bleu/border-btm.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+div.slideblock, .dbx-content { overflow: hidden; background-color: #DDD; }
+div.slideblock2 { overflow: hidden; background-color: #DDD; margin: 0px 1px 0px 1px; }
+.dbx-handle { cursor: move !important; }
+
+/* The credits thingy at the bottom */
+div#credits { margin: 0; padding: 10px; padding-bottom: 0px; padding-top: 12px; background-color: #E8E8E8; color: #AAA; font-size: 7pt; }
+div#credits a { color: #90B0D0; text-decoration: none; }
+div#credits a:hover { color: #80A0C0; text-decoration: underline; }
+
+/* The link hidden in plain "site" at the top of the page */
+td#mainhead a { text-decoration: none; color: #000000; }
+td#mainhead a:hover { text-decoration: none; color: #000000; border-bottom: 1px dotted #406080; }
+
+/* Text, headings, and links inside the main div (usually #ajaxEditContainer but used some other places as well) */
+div.contentDiv h2 { border-bottom: 1px solid #90B0D0; margin-bottom: 0; }
+div.contentDiv h3 { font-size: 11pt; font-weight: bold; }
+div.contentDiv li , div#messageBox li { list-style: url(../images/bullet.gif); }
+div.contentDiv p , div#messageBox p { margin-left: 1.0em; }
+div.contentDiv blockquote , div#messageBox blockquote { background-color: #F4F4F4; border: 1px dotted #406080; margin: 1em; padding: 10px; max-height: 250px; overflow: auto; }
+div.contentDiv , div#messageBox { font-size: 9pt; }
+div.contentDiv a , div#messageBox a { color: #7090B0; }
+div.contentDiv a:hover , div#messageBox a:hover { color: #90B0D0; }
+div.contentDiv a[href ^="http://"] , div#messageBox a[href ^="http://"] { color: #80A0C0; background: url(../images/bleu/external.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="https://"] , div#messageBox a[href ^="https://"] { color: #80A0C0; background: url(../images/bleu/https.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="mailto:"] , div#messageBox a[href ^="mailto:"] { color: #80A0C0; background: url(../images/bleu/email.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="irc://"] , div#messageBox a[href ^="irc://"] { color: #80A0C0; background: url(../images/bleu/irc.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="http://"]:hover , div#messageBox a[href ^="http://"]:hover { color: #A0C0E0; background: url(../images/bleu/external.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="https://"]:hover, div#messageBox a[href ^="https://"]:hover { color: #A0C0E0; background: url(../images/bleu/https.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="mailto:"]:hover , div#messageBox a[href ^="mailto:"]:hover { color: #A0C0E0; background: url(../images/bleu/email.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="irc://"]:hover , div#messageBox a[href ^="irc://"]:hover { color: #A0C0E0; background: url(../images/bleu/irc.gif) center right no-repeat; padding-right: 16px; }
+
+/* Wikilinks to pages that don't exist */
+div.contentDiv a.wikilink-nonexistent { color: #B05020; }
+div.contentDiv a.wikilink-nonexistent:hover { color: #D06030; }
+
+/* Well, not Midget and not comments (usually), but that's what the class is called ;-). Basically an informational window or used as a wrapper for tables. */
+.mdg-comment, .mdg-infobox { margin-left: 1em; padding: 7px; border: 1px solid #AAAAAA; background-color: #E8E8E8; }
+
+.tblholder { margin: 10px 0 0 0; padding: 0; border: 1px solid #AAAAAA; background-color: #E8E8E8; }
+
+/* The beautiful tables inside what may not obviously be mdg-comment divs */
+div.tblholder td.row1 { padding: 4px; background-color: #E0E0E0; }
+div.tblholder td.row2 { padding: 4px; background-color: #F0F0F0; }
+div.tblholder td.row3 { padding: 4px; background-color: #E8E8E8; }
+div.tblholder th { padding: 4px; background-color: #7080A0; font-weight: bold; text-align: center; color: #FFFFFF; }
+div.tblholder th.subhead { padding: 4px; background-color: #90A0B0; font-weight: bold; text-align: center; color: #FFFFFF; }
+div.tblholder table { background-color: #FFFFFF; width: 100%; }
+
+/* The "page tools" bar below the site logo but above the page content
+div.pagebar { background-color: #B0D0F0; margin-top: 0px; padding: 3px; font-size: 7pt; }
+div.pagebar a { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #406080; }
+div.pagebar a.selected { background-color: #FFFFFF; color: #000040; font-weight: bold; }
+div.pagebar a:hover { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #406080; background-color: #D0F0FF; }
+div.pagebar input { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #E0F0FF; }
+div.pagebar input:hover { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #D0F0FF; }
+div.pagebar input:focus { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #F0F0FF; }
+*/
+
+/*
+ * jBox menu system
+ */
+
+div.menu, div.menu_nojs {
+ background-color: #B0D0F0;
+ font-size: 7pt;
+ border-width: 0;
+}
+div.menu a, div.menu div.label {
+ padding: 2.5pt 5px;
+ margin-right: 3px;
+ text-decoration: none;
+ display: block;
+ float: left;
+ color: #406080;
+}
+div.menu_nojs a, div.menu_nojs div.label {
+ padding: 2.5pt 5px;
+ margin-right: 3px;
+ text-decoration: none;
+ display: block;
+ color: #406080;
+}
+div.menu div.label, div.menu_nojs div.label {
+ color: #001020;
+ cursor: default;
+}
+div.menu span.sep, div.menu_nojs span.sep {
+ display: block;
+ float: left;
+ width: 5px;
+}
+div.menu div.multopts, div.menu_nojs div.multopts {
+ line-height: 17pt;
+}
+div.menu div.multopts a, div.menu div.multopts div.label, div.menu_nojs div.multopts a, div.menu_nojs div.multopts div.label {
+ float: none;
+ display: inline;
+}
+div.menu a.liteselected, div.menu a.liteselected:hover, div.menu a:hover, div.menu_nojs a.liteselected, div.menu_nojs a.liteselected:hover, div.menu_nojs a:hover {
+ color: #406080;
+ background-color: #D0F0FF;
+}
+div.menu input[type ^="text"], div.menu input[type ^="password"], div.menu_nojs input[type ^="text"], div.menu_nojs input[type ^="password"] {
+ border-width: 0;
+ font-size: 9pt;
+ padding: 2px 5px 3px 5px;
+ max-width: 70px;
+ background-color: #D0F0FF;
+}
+div.menu input[type ^="text"]:hover, div.menu input[type ^="password"]:hover, div.menu_nojs input[type ^="text"]:hover, div.menu_nojs input[type ^="password"]:hover {
+ background-color: #E0F0FF;
+}
+div.menu input[type ^="text"]:focus, div.menu input[type ^="password"]:focus, div.menu_nojs input[type ^="text"]:focus, div.menu_nojs input[type ^="password"]:focus {
+ background-color: #F0F0FF;
+}
+div.menu input[type ^="button"], div.menu input[type ^="submit"], div.menu_nojs input[type ^="button"], div.menu_nojs input[type ^="submit"] {
+ border-width: 0;
+ font-size: 9pt;
+ padding: 3px 5px;
+ max-width: 70px;
+}
+div.menu a.current, div.menu a.current:hover, div.menu a.selected, div.menu a.selected:hover, div.menu_nojs a.current, div.menu_nojs a.current:hover, div.menu_nojs a.selected, div.menu_nojs a.selected:hover {
+ color: #000040;
+ background-color: #FFFFFF;
+}
+div.menu ul {
+ display: none;
+ position: absolute;
+ padding: 0;
+ margin: 0 !important;
+ background-color: #B0D0F0;
+ border-width: 0;
+ min-width: 120px;
+}
+div.menu_nojs ul {
+ display: block;
+ padding: 0;
+ margin: 0 0 0 1em;
+ background-color: #B0D0F0;
+ border-width: 0;
+ min-width: 120px;
+}
+div.menu ul li, div.menu_nojs ul li {
+ list-style: none;
+}
+div.menu ul a, div.menu_nojs ul a {
+ float: none;
+ margin: 0;
+}
+span.menuclear {
+ font-size: 1px;
+ height: 0px;
+ width: 0px;
+ clear: left;
+ line-height: 0px;
+ display: block;
+}
+
+/* Rounded corners on nearly everything */
+td#mdg-tl { width: 12px; height: 12px; background: url(../images/bleu/border-tl.gif); }
+td#mdg-tr { width: 12px; height: 12px; background: url(../images/bleu/border-tr.gif); }
+td#mdg-top { background: url(../images/bleu/border-top.gif); }
+td#mdg-l { width: 12px; height: 12px; background: url(../images/bleu/border-l.gif); }
+td#mdg-r { width: 12px; height: 12px; background: url(../images/bleu/border-r.gif); }
+td#mdg-bl { width: 12px; height: 12px; background: url(../images/bleu/border-tb-l.gif); }
+td#mdg-br { width: 12px; height: 12px; background: url(../images/bleu/border-tb-r.gif); }
+td#mdg-ml { width: 12px; height: 12px; background: url(../images/bleu/border-m-l.gif); }
+td#mdg-mr { width: 12px; height: 12px; background: url(../images/bleu/border-m-r.gif); }
+td#mdg-brl { width: 12px; height: 1px; background: url(../images/bleu/border-m-l.gif); }
+td#mdg-brr { width: 12px; height: 1px; background: url(../images/bleu/border-m-r.gif); }
+td#mdg-btl { width: 12px; height: 1px; background: url(../images/bleu/border-btm-l.gif); }
+td#mdg-btr { width: 12px; height: 1px; background: url(../images/bleu/border-btm-r.gif); }
+td#mdg-btcl { width: 12px; height: 12px; background: url(../images/bleu/border-bl.gif); }
+td#mdg-btcr { width: 12px; height: 12px; background: url(../images/bleu/border-br.gif); }
+td#mdg-btm { height: 12px; background: url(../images/bleu/border-btm.gif); }
+td.mdg-menu-top { width: 84%; height: 12px; background: url(../images/bleu/border-menu-t.gif); margin: 0; padding: 0; background-repeat: repeat-x; font-size: 2px; }
+td.mdg-menu-tl { width: 12px; height: 12px; background: url(../images/bleu/border-menu-l.gif); background-position: left top; background-repeat: no-repeat; }
+td.mdg-menu-tr { width: 12px; height: 12px; background: url(../images/bleu/border-menu-r.gif); background-position: right top; background-repeat: no-repeat; }
+td.mdg-menu-bl { width: 12px; height: 12px; background: url(../images/bleu/border-bl.gif); }
+td.mdg-menu-br { width: 12px; height: 12px; background: url(../images/bleu/border-br.gif); }
+td.mdg-menu-btm { height: 12px; background: url(../images/bleu/border-btm.gif); }
+
+/* Buttons and textboxes - these settings are used almost everywhere */
+input, textarea, select { border: 1px solid #406080; background-color: #F2F2F2; padding: 3px; font-family: arial, helvetica, sans-serif; font-size: 8pt; }
+input:hover, textarea:hover, select:hover { border: 1px solid #6080A0; background-color: #F8F8F8; padding: 3px; }
+input:focus, textarea:focus, select:focus { border: 1px solid #90B0D0; background-color: #FFFFFF; padding: 3px; }
+label { padding: 3px; cursor: pointer; font-family: arial, helvetica, sans-serif; font-size: 8pt; }
+label:hover { padding: 3px; cursor: pointer; background-color: #F0F0F0; }
+input#pageheading { font-size: 14pt; border-bottom: 1px solid #90B0D0; margin-bottom: 0; }
+
+input[type ^="button"], input[type ^="submit"] {
+ background-image: url(../images/buttonbg.gif);
+ background-repeat: repeat-x;
+}
+
+/* JWS window theming */
+div.jswindow { border: 2px solid #7090B0; border-top: 5px solid #7090B0; padding: 0px; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; display: none; position: absolute; background-color: #FFFFFF; }
+div.titlebar { background-color: #7090B0; color: #FFFFFF; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; padding-bottom: 4px; cursor: default; }
+div.titlebar div.closebtn { width: 16px; height: 16px; border: 1px solid #B0D0F0; background-color: #90B0D0; display: block; }
+div.titlebar div.closebtn:hover { width: 16px; height: 16px; border: 1px solid #FFFFFF; background-color: #B0D0F0; display: block; }
+div.titlebar table, div.titlebar td { margin: 0; padding: 0; }
+div.jswindow div.content { padding: 10px; margin: 0; background-color: #FFFFFF; }
+
+/* The Wordpress-like fills behind checkboxes and their labels */
+.catCheck { padding: 3px; }
+.catCheck:hover { padding: 3px; background-color: #F0F0F0; }
+
+/* Information, warning, question, error, and wait boxes */
+div.error-box { background-image: url(../../../images/error.png); background-repeat: no-repeat; background-color: #FFF4F4; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.info-box { background-image: url(../../../images/info.png); background-repeat: no-repeat; background-color: #F4F4FF; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.warning-box { background-image: url(../../../images/warning.png); background-repeat: no-repeat; background-color: #FFFFF4; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.question-box { background-image: url(../../../images/question.png); background-repeat: no-repeat; background-color: #F4FFF4; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.wait-box { background-image: url(../../../images/wait.png); background-repeat: no-repeat; background-color: #FFF4FF; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+
+/* This stuff is mostly unused, left in for compatibility */
+div#ajaxEditContainer table { border: 0px solid #FFFFFF; }
+div#ajaxEditContainer td { margin: 1px; }
+/* div#ajaxEditContainer { overflow: auto; } /* Makes ajaxEditContainer scroll horizontally in firefox if the content is too wide - prevents that ugly clipping effect */
+div#ajaxEditContainer pre { margin-left: 1em; background-color: #F8F8F8; border: 1px dashed #90B0D0; padding: 10px; overflow: auto; max-height: 150px; }
+
+/* Tables where diffs are shown */
+table.diff, td.diff-otitle, td.diff-ntitle { background-color: white; }
+td.diff-addedline { background: #cfc; font-size: smaller; }
+td.diff-deletedline { background: #ffa; font-size: smaller; }
+td.diff-context { background: #eee; font-size: smaller; }
+span.diffchange { color: red; font-weight: bold; }
+
+/* toolbar */
+div.toolbar {
+ border-bottom: 1px solid #909090;
+ background-color: #D0D0D0;
+ padding: 2px 0;
+ height: 22px;
+ font-family: arial, sans-serif;
+ font-size: 8pt;
+}
+div.toolbar ul {
+ margin: 0;
+ padding: 0;
+}
+div.toolbar ul li {
+ list-style: none;
+ margin: 0;
+ float: left;
+}
+div.toolbar a img {
+ opacity: 0.6;
+ /*filter: alpha(opacity=60);*/
+}
+div.toolbar a:hover img {
+ opacity: 1;
+ /*filter: alpha(opacity=100);*/
+}
+div.toolbar a {
+ display: block;
+ padding: 2px;
+ border: 1px solid transparent;
+ cursor: default;
+ width: auto;
+ color: #000000;
+ margin: 0 2px;
+ max-height: 16px;
+ text-decoration: none;
+}
+div.toolbar a:hover {
+ border: 1px solid #202090;
+ background-color: #ceceed;
+ color: #000000;
+ text-decoration: none;
+}
+div.toolbar a:active {
+ border: 1px solid #A0A0A0;
+ background-color: #E0E0E0;
+}
+div.toolbar img {
+ margin: 0;
+ padding: 0;
+ display: inline;
+ border-width: 0px;
+}
+div.toolbar a span {
+ position: relative;
+ top: -4px;
+}
+div.toolbar li span {
+ padding-left: 2px;
+ padding-right: 5px;
+}
+
+/* vertical toolbar */
+div.toolbar_vert {
+ border: 1px solid #909090;
+ background-color: #D0D0D0;
+ padding: 2px 0;
+}
+div.toolbar_vert ul {
+ margin: 0;
+ padding: 0;
+}
+div.toolbar_vert ul li {
+ list-style: none;
+ margin: 0;
+}
+div.toolbar_vert a img {
+ opacity: 0.6;
+ /*filter: alpha(opacity=60);*/
+}
+div.toolbar_vert a:hover img {
+ opacity: 1;
+ /*filter: alpha(opacity=100);*/
+}
+div.toolbar_vert a {
+ display: block;
+ padding: 2px;
+ border: 1px solid transparent;
+ cursor: default;
+ width: auto;
+ color: #000000;
+ margin: 0 2px;
+ max-height: 16px;
+ text-decoration: none;
+}
+div.toolbar_vert a:hover {
+ border: 1px solid #202090;
+ background-color: #ceceed;
+ color: #000000;
+ text-decoration: none;
+}
+div.toolbar_vert a:active {
+ border: 1px solid #A0A0A0;
+ background-color: #E0E0E0;
+}
+div.toolbar_vert img {
+ margin: 0;
+ padding: 0;
+ display: inline;
+ border-width: 0px;
+}
+div.toolbar_vert a span {
+ position: relative;
+ top: -4px;
+}
+div.toolbar_vert li span {
+ padding-left: 2px;
+ padding-right: 5px;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/oxygen/css/mint.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,372 @@
+/**
+ * The original Oxygen theme for Enano
+ * Designed by Dan Fuhry, (C) 2006
+ * This theme is Free Software; see the file "GPL" included with this package for details.
+ */
+
+/* The basics */
+html,body { height: 100%; }
+body { margin: 0; padding: 0; background: url(../images/mint/bg.png); font-family: trebuchet ms, verdana, arial, helvetica, sans-serif; font-size: 9pt; }
+.holder { border: 1px solid #CCCCCC; padding: 1px; background-color: #FFFFFF; color: #444444 }
+div.pad { padding: 10px; }
+table#title { margin: 0; padding: 0; height: 100px; background-color: #90D0B0; text-align: center; }
+
+/* Sidebar */
+td.mdgSidebarHolder { width: 140px; }
+div.sidebar, .dbx-group { width: 138px; background-color: #F8F8F8; border-left: 1px solid #CCC; border-right: 1px solid #CCC; padding: 1px 0px 0px 0px; }
+div.sidebar .head, .dbx-handle { background-color: #F0F0F0; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #111; padding: 5px; font-weight: bold; }
+div.sidebar .head:hover, .dbx-handle:hover { background-color: #F4F4F4; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #111; padding: 5px; font-weight: bold; }
+div.sidebar div.slideblock a, .dbx-content li { background-color: #DDD; display: block; margin: 0px 1px; border-bottom: 1px solid #FFF; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #666; padding: 5px 5px 5px 9px; list-style-type: none; }
+div.sidebar div.slideblock a:hover, .dbx-content li:hover { background-color: #EEE; display: block; margin: 0px 1px; border-bottom: 1px solid #FFF; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #666; padding: 5px 5px 5px 9px; }
+div.recttop { width: 140px; height: 12px; margin: 0; padding: 0; }
+td.recttoptop { width: 100%; height: 12px; background-image: url(../images/mint/border-menu-t.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+td.recttoptop:hover { width: 100%; height: 12px; background-image: url(../images/mint/border-menu-t-h.gif); background-repeat: repeat-x; margin: 0; padding: 0; cursor: pointer; }
+div.rectbot { width: 140px; height: 12px; margin: 0; padding: 0; }
+td.rectbottop { width: 100%; height: 12px; background-image: url(../images/mint/border-btm.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+div.slideblock, .dbx-content { overflow: hidden; background-color: #DDD; }
+div.slideblock2 { overflow: hidden; background-color: #DDD; margin: 0px 1px 0px 1px; }
+.dbx-handle { cursor: move !important; }
+
+/* The credits thingy at the bottom */
+div#credits { margin: 0; padding: 10px; padding-bottom: 0px; padding-top: 12px; background-color: #E8E8E8; color: #AAA; font-size: 7pt; }
+div#credits a { color: #90D0B0; text-decoration: none; }
+div#credits a:hover { color: #80C0A0; text-decoration: underline; }
+
+/* The link hidden in plain "site" at the top of the page */
+td#mainhead a { text-decoration: none; color: #000000; }
+td#mainhead a:hover { text-decoration: none; color: #000000; border-bottom: 1px dotted #408060; }
+
+/* Text, headings, and links inside the main div (usually #ajaxEditContainer but used some other places as well) */
+div.contentDiv h2 { border-bottom: 1px solid #90D0B0; margin-bottom: 0; }
+div.contentDiv h3 { font-size: 11pt; font-weight: bold; }
+div.contentDiv li , div#messageBox li { list-style: url(../images/bullet.gif); }
+div.contentDiv p , div#messageBox p { margin-left: 1.0em; }
+div.contentDiv blockquote , div#messageBox blockquote { background-color: #F4F4F4; border: 1px dotted #408060; margin: 1em; padding: 10px; max-height: 250px; overflow: auto; }
+div.contentDiv , div#messageBox { font-size: 9pt; }
+div.contentDiv a , div#messageBox a { color: #70B090; }
+div.contentDiv a:hover , div#messageBox a:hover { color: #90D0B0; }
+div.contentDiv a[href ^="http://"] , div#messageBox a[href ^="http://"] { color: #80C0A0; background: url(../images/mint/external.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="https://"] , div#messageBox a[href ^="https://"] { color: #80C0A0; background: url(../images/mint/https.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="mailto:"] , div#messageBox a[href ^="mailto:"] { color: #80C0A0; background: url(../images/mint/email.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="irc://"] , div#messageBox a[href ^="irc://"] { color: #80C0A0; background: url(../images/mint/irc.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="http://"]:hover , div#messageBox a[href ^="http://"]:hover { color: #A0E0C0; background: url(../images/mint/external.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="https://"]:hover, div#messageBox a[href ^="https://"]:hover { color: #A0E0C0; background: url(../images/mint/https.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="mailto:"]:hover , div#messageBox a[href ^="mailto:"]:hover { color: #A0E0C0; background: url(../images/mint/email.gif) center right no-repeat; padding-right: 16px; }
+div.contentDiv a[href ^="irc://"]:hover , div#messageBox a[href ^="irc://"]:hover { color: #A0E0C0; background: url(../images/mint/irc.gif) center right no-repeat; padding-right: 16px; }
+
+/* Wikilinks to pages that don't exist */
+div.contentDiv a.wikilink-nonexistent { color: #B02050; }
+div.contentDiv a.wikilink-nonexistent:hover { color: #D03060; }
+
+/* Well, not Midget and not comments (usually), but that's what the class is called ;-). Basically an informational window or used as a wrapper for tables. */
+.mdg-comment, .mdg-infobox { margin-left: 1em; padding: 7px; border: 1px solid #AAAAAA; background-color: #E8E8E8; }
+
+.tblholder { margin: 10px 0 0 0; padding: 0; border: 1px solid #AAAAAA; background-color: #E8E8E8; }
+
+/* The beautiful tables inside what may not obviously be mdg-comment divs */
+div.tblholder td.row1 { padding: 4px; background-color: #E0E0E0; }
+div.tblholder td.row2 { padding: 4px; background-color: #F0F0F0; }
+div.tblholder td.row3 { padding: 4px; background-color: #E8E8E8; }
+div.tblholder th { padding: 4px; background-color: #70A080; font-weight: bold; text-align: center; color: #FFFFFF; }
+div.tblholder th.subhead { padding: 4px; background-color: #90B0A0; font-weight: bold; text-align: center; color: #FFFFFF; }
+div.tblholder table { background-color: #FFFFFF; width: 100%; }
+
+/* The "page tools" bar below the site logo but above the page content
+div.pagebar { background-color: #B0F0D0; margin-top: 0px; padding: 3px; font-size: 7pt; }
+div.pagebar a { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #408060; }
+div.pagebar a.selected { background-color: #FFFFFF; color: #004000; font-weight: bold; }
+div.pagebar a:hover { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #408060; background-color: #D0FFF0; }
+div.pagebar input { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #408060; background-color: #E0FFF0; }
+div.pagebar input:hover { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #408060; background-color: #D0FFF0; }
+div.pagebar input:focus { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #408060; background-color: #F0FFF0; }
+*/
+
+/*
+ * jBox menu system
+ */
+
+div.menu, div.menu_nojs {
+ background-color: #B0F0D0;
+ font-size: 7pt;
+ border-width: 0;
+}
+div.menu a, div.menu div.label {
+ padding: 2.5pt 5px;
+ margin-right: 3px;
+ text-decoration: none;
+ display: block;
+ float: left;
+ color: #408060;
+}
+div.menu_nojs a, div.menu_nojs div.label {
+ padding: 2.5pt 5px;
+ margin-right: 3px;
+ text-decoration: none;
+ display: block;
+ color: #408060;
+}
+div.menu div.label, div.menu_nojs div.label {
+ color: #002010;
+ cursor: default;
+}
+div.menu span.sep, div.menu_nojs span.sep {
+ display: block;
+ float: left;
+ width: 5px;
+}
+div.menu div.multopts, div.menu_nojs div.multopts {
+ line-height: 17pt;
+}
+div.menu div.multopts a, div.menu div.multopts div.label, div.menu_nojs div.multopts a, div.menu_nojs div.multopts div.label {
+ float: none;
+ display: inline;
+}
+div.menu a.liteselected, div.menu a.liteselected:hover, div.menu a:hover, div.menu_nojs a.liteselected, div.menu_nojs a.liteselected:hover, div.menu_nojs a:hover {
+ color: #408060;
+ background-color: #D0FFF0;
+}
+div.menu input[type ^="text"], div.menu input[type ^="password"], div.menu_nojs input[type ^="text"], div.menu_nojs input[type ^="password"] {
+ border-width: 0;
+ font-size: 9pt;
+ padding: 4px 5px;
+ max-width: 70px;
+ background-color: #D0FFF0;
+}
+div.menu input[type ^="text"]:hover, div.menu input[type ^="password"]:hover, div.menu_nojs input[type ^="text"]:hover, div.menu_nojs input[type ^="password"]:hover {
+ background-color: #E0FFF0;
+}
+div.menu input[type ^="text"]:focus, div.menu input[type ^="password"]:focus, div.menu_nojs input[type ^="text"]:focus, div.menu_nojs input[type ^="password"]:focus {
+ background-color: #F0FFF0;
+}
+div.menu input[type ^="button"], div.menu input[type ^="submit"], div.menu_nojs input[type ^="button"], div.menu_nojs input[type ^="submit"] {
+ border-width: 0;
+ font-size: 9pt;
+ padding: 3px 5px;
+ max-width: 70px;
+}
+div.menu a.current, div.menu a.current:hover, div.menu a.selected, div.menu a.selected:hover, div.menu_nojs a.current, div.menu_nojs a.current:hover, div.menu_nojs a.selected, div.menu_nojs a.selected:hover {
+ color: #004000;
+ background-color: #FFFFFF;
+}
+div.menu ul {
+ display: none;
+ position: absolute;
+ padding: 0;
+ margin: 0 !important;
+ background-color: #B0F0D0;
+ border-width: 0;
+ min-width: 120px;
+}
+div.menu_nojs ul {
+ display: block;
+ padding: 0;
+ margin: 0 0 0 1em;
+ background-color: #B0F0D0;
+ border-width: 0;
+ min-width: 120px;
+}
+div.menu ul li, div.menu_nojs ul li {
+ list-style: none;
+}
+div.menu ul a, div.menu_nojs ul a {
+ float: none;
+ margin: 0;
+}
+span.menuclear {
+ font-size: 1px;
+ height: 0px;
+ width: 0px;
+ clear: left;
+ line-height: 0px;
+ display: block;
+}
+
+/* Rounded corners on nearly everything */
+td#mdg-tl { width: 12px; height: 12px; background: url(../images/mint/border-tl.gif); }
+td#mdg-tr { width: 12px; height: 12px; background: url(../images/mint/border-tr.gif); }
+td#mdg-top { background: url(../images/mint/border-top.gif); }
+td#mdg-l { width: 12px; height: 12px; background: url(../images/mint/border-l.gif); }
+td#mdg-r { width: 12px; height: 12px; background: url(../images/mint/border-r.gif); }
+td#mdg-bl { width: 12px; height: 12px; background: url(../images/mint/border-tb-l.gif); }
+td#mdg-br { width: 12px; height: 12px; background: url(../images/mint/border-tb-r.gif); }
+td#mdg-ml { width: 12px; height: 12px; background: url(../images/mint/border-m-l.gif); }
+td#mdg-mr { width: 12px; height: 12px; background: url(../images/mint/border-m-r.gif); }
+td#mdg-brl { width: 12px; height: 1px; background: url(../images/mint/border-m-l.gif); }
+td#mdg-brr { width: 12px; height: 1px; background: url(../images/mint/border-m-r.gif); }
+td#mdg-btl { width: 12px; height: 1px; background: url(../images/mint/border-btm-l.gif); }
+td#mdg-btr { width: 12px; height: 1px; background: url(../images/mint/border-btm-r.gif); }
+td#mdg-btcl { width: 12px; height: 12px; background: url(../images/mint/border-bl.gif); }
+td#mdg-btcr { width: 12px; height: 12px; background: url(../images/mint/border-br.gif); }
+td#mdg-btm { height: 12px; background: url(../images/mint/border-btm.gif); }
+td.mdg-menu-top { width: 84%; height: 12px; background: url(../images/mint/border-menu-t.gif); margin: 0; padding: 0; background-repeat: repeat-x; font-size: 2px; }
+td.mdg-menu-tl { width: 12px; height: 12px; background: url(../images/mint/border-menu-l.gif); background-position: left top; background-repeat: no-repeat; }
+td.mdg-menu-tr { width: 12px; height: 12px; background: url(../images/mint/border-menu-r.gif); background-position: right top; background-repeat: no-repeat; }
+td.mdg-menu-bl { width: 12px; height: 12px; background: url(../images/mint/border-bl.gif); }
+td.mdg-menu-br { width: 12px; height: 12px; background: url(../images/mint/border-br.gif); }
+td.mdg-menu-btm { height: 12px; background: url(../images/mint/border-btm.gif); }
+
+/* Buttons and textboxes - these settings are used almost everywhere */
+input, textarea, select { border: 1px solid #408060; background-color: #F2F2F2; padding: 3px; font-family: arial, helvetica, sans-serif; font-size: 8pt; }
+input:hover, textarea:hover, select:hover { border: 1px solid #60A080; background-color: #F8F8F8; padding: 3px; }
+input:focus, textarea:focus, select:focus { border: 1px solid #90D0B0; background-color: #FFFFFF; padding: 3px; }
+label { padding: 3px; cursor: pointer; font-family: arial, helvetica, sans-serif; font-size: 8pt; }
+label:hover { padding: 3px; cursor: pointer; background-color: #F0F0F0; }
+input#pageheading { font-size: 14pt; border-bottom: 1px solid #90D0B0; margin-bottom: 0; }
+
+input[type ^="button"], input[type ^="submit"] {
+ background-image: url(../images/buttonbg.gif);
+ background-repeat: repeat-x;
+}
+
+/* JWS window theming */
+div.jswindow { border: 2px solid #70B090; border-top: 5px solid #70B090; padding: 0px; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; display: none; position: absolute; background-color: #FFFFFF; }
+div.titlebar { background-color: #70B090; color: #FFFFFF; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; padding-bottom: 4px; cursor: default; }
+div.titlebar div.closebtn { width: 16px; height: 16px; border: 1px solid #B0F0D0; background-color: #90D0B0; display: block; }
+div.titlebar div.closebtn:hover { width: 16px; height: 16px; border: 1px solid #FFFFFF; background-color: #B0F0D0; display: block; }
+div.titlebar table, div.titlebar td { margin: 0; padding: 0; }
+div.jswindow div.content { padding: 10px; margin: 0; background-color: #FFFFFF; }
+
+/* The Wordpress-like fills behind checkboxes and their labels */
+.catCheck { padding: 3px; }
+.catCheck:hover { padding: 3px; background-color: #F0F0F0; }
+
+/* Information, warning, question, error, and wait boxes */
+div.error-box { background-image: url(../../../images/error.png); background-repeat: no-repeat; background-color: #FFF4F4; border: 1px dashed #408060; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.info-box { background-image: url(../../../images/info.png); background-repeat: no-repeat; background-color: #F4FFF4; border: 1px dashed #408060; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.warning-box { background-image: url(../../../images/warning.png); background-repeat: no-repeat; background-color: #FFF4FF; border: 1px dashed #408060; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.question-box { background-image: url(../../../images/question.png); background-repeat: no-repeat; background-color: #F4F4FF; border: 1px dashed #408060; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.wait-box { background-image: url(../../../images/wait.png); background-repeat: no-repeat; background-color: #FFFFF4; border: 1px dashed #408060; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+
+/* This stuff is mostly unused, left in for compatibility */
+div#ajaxEditContainer table { border: 0px solid #FFFFFF; }
+div#ajaxEditContainer td { margin: 1px; }
+/* div#ajaxEditContainer { overflow: auto; } /* Makes ajaxEditContainer scroll horizontally in firefox if the content is too wide - prevents that ugly clipping effect */
+div#ajaxEditContainer pre { margin-left: 1em; background-color: #F8F8F8; border: 1px dashed #90D0B0; padding: 10px; overflow: auto; max-height: 150px; }
+
+/* Tables where diffs are shown */
+table.diff, td.diff-otitle, td.diff-ntitle { background-color: white; }
+td.diff-addedline { background: #cfc; font-size: smaller; }
+td.diff-deletedline { background: #ffa; font-size: smaller; }
+td.diff-context { background: #eee; font-size: smaller; }
+span.diffchange { color: red; font-weight: bold; }
+
+/* toolbar */
+div.toolbar {
+ border-bottom: 1px solid #909090;
+ background-color: #D0D0D0;
+ padding: 2px 0;
+ height: 22px;
+ font-family: arial, sans-serif;
+ font-size: 8pt;
+}
+div.toolbar ul {
+ margin: 0;
+ padding: 0;
+}
+div.toolbar ul li {
+ list-style: none;
+ margin: 0;
+ float: left;
+}
+div.toolbar a img {
+ opacity: 0.6;
+ /*filter: alpha(opacity=60);*/
+}
+div.toolbar a:hover img {
+ opacity: 1;
+ /*filter: alpha(opacity=100);*/
+}
+div.toolbar a {
+ display: block;
+ padding: 2px;
+ border: 1px solid transparent;
+ cursor: default;
+ width: auto;
+ color: #000000;
+ margin: 0 2px;
+ max-height: 16px;
+ text-decoration: none;
+}
+div.toolbar a:hover {
+ border: 1px solid #209020;
+ background-color: #ceedce;
+ color: #000000;
+ text-decoration: none;
+}
+div.toolbar a:active {
+ border: 1px solid #A0A0A0;
+ background-color: #E0E0E0;
+}
+div.toolbar img {
+ margin: 0;
+ padding: 0;
+ display: inline;
+ border-width: 0px;
+}
+div.toolbar a span {
+ position: relative;
+ top: -4px;
+}
+div.toolbar li span {
+ padding-left: 2px;
+ padding-right: 5px;
+}
+
+/* vertical toolbar */
+div.toolbar_vert {
+ border: 1px solid #909090;
+ background-color: #D0D0D0;
+ padding: 2px 0;
+}
+div.toolbar_vert ul {
+ margin: 0;
+ padding: 0;
+}
+div.toolbar_vert ul li {
+ list-style: none;
+ margin: 0;
+}
+div.toolbar_vert a img {
+ opacity: 0.6;
+ /*filter: alpha(opacity=60);*/
+}
+div.toolbar_vert a:hover img {
+ opacity: 1;
+ /*filter: alpha(opacity=100);*/
+}
+div.toolbar_vert a {
+ display: block;
+ padding: 2px;
+ border: 1px solid transparent;
+ cursor: default;
+ width: auto;
+ color: #000000;
+ margin: 0 2px;
+ max-height: 16px;
+ text-decoration: none;
+}
+div.toolbar_vert a:hover {
+ border: 1px solid #209020;
+ background-color: #ceedce;
+ color: #000000;
+ text-decoration: none;
+}
+div.toolbar_vert a:active {
+ border: 1px solid #A0A0A0;
+ background-color: #E0E0E0;
+}
+div.toolbar_vert img {
+ margin: 0;
+ padding: 0;
+ display: inline;
+ border-width: 0px;
+}
+div.toolbar_vert a span {
+ position: relative;
+ top: -4px;
+}
+div.toolbar_vert li span {
+ padding-left: 2px;
+ padding-right: 5px;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/oxygen/elements.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,64 @@
+<!-- VAR toolbar_button --><a href="{HREF}" {PARENTFLAGS} {FLAGS}>{TEXT}</a>
+<!-- ENDVAR toolbar_button -->
+<!-- VAR toolbar_label --><div class="label">{TEXT}</div>
+<!-- ENDVAR toolbar_label -->
+<!-- VAR toolbar_button_selected --><a href="{HREF}" class="current" {PARENTFLAGS} {FLAGS}>{TEXT}</a>
+<!-- ENDVAR toolbar_button_selected -->
+<!-- VAR toolbar_menu_button --><li><a href="{HREF}" {FLAGS}>{TEXT}</a></li>
+<!-- ENDVAR toolbar_menu_button -->
+<!-- VAR toolbar_menu_block --><li>{HTML}</li>
+<!-- ENDVAR toolbar_menu_block -->
+<!-- VAR sidebar_button --><a href="{HREF}" {FLAGS}>{TEXT}</a><br style="display: none;" />
+<!-- ENDVAR sidebar_button -->
+<!-- VAR sidebar_raw --><span style="text-align: center;">{HTML}</span><br style="display: none;" />
+<!-- ENDVAR sidebar_raw -->
+<!-- VAR sidebar_heading --><div class="heading">{TEXT}</div>
+<!-- ENDVAR sidebar_heading -->
+<!-- VAR sidebar_top -->
+ <div class="recttop">
+ <table border="0" width="100%" cellspacing="0" cellpadding="0" style="font-size: 1px;">
+ <tr>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-menu-l.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;" class="recttoptop"></td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-menu-r.gif" width="12" height="12" /> </td>
+ </tr>
+ </table>
+ </div>
+ <div class="sidebar">
+<!-- ENDVAR sidebar_top -->
+<!-- VAR sidebar_section -->
+ <div class="slider">
+ <div class="heading">
+ <!-- BEGIN in_sidebar_admin -->{ADMIN_START}<!-- END in_sidebar_admin -->
+ <br style="display: none;" /><br style="display: none;" />
+ <a class="head" onclick="toggle(this); return false" href="#">{TITLE}</a>
+ <!-- BEGIN in_sidebar_admin -->{ADMIN_END}<!-- END in_sidebar_admin -->
+ <br style="display: none;" /><br style="display: none;" />
+ </div>
+ <div class="slideblock">{CONTENT}</div>
+ </div>
+<!-- ENDVAR sidebar_section -->
+<!-- VAR sidebar_section_raw -->
+ <div class="slider">
+ <div class="heading">
+ <!-- BEGIN in_sidebar_admin -->{ADMIN_START}<!-- END in_sidebar_admin -->
+ <br style="display: none;" /><br style="display: none;" />
+ <a class="head" onclick="toggle(this); return false" href="#">{TITLE}</a>
+ <!-- BEGIN in_sidebar_admin -->{ADMIN_END}<!-- END in_sidebar_admin -->
+ <br style="display: none;" /><br style="display: none;" />
+ </div>
+ <div class="slideblock2">{CONTENT}</div>
+ </div>
+<!-- ENDVAR sidebar_section_raw -->
+<!-- VAR sidebar_bottom -->
+ </div>
+ <div class="rectbot">
+ <table border="0" width="100%" cellspacing="0" cellpadding="0" style="font-size: 1px;">
+ <tr>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-bl.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;" class="rectbottop"></td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-br.gif" width="12" height="12" /> </td>
+ </tr>
+ </table>
+ </div>
+<!-- ENDVAR sidebar_bottom -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/oxygen/footer.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,80 @@
+ </div>
+ <div id="mdgCommentContainer">
+ </div>
+ </div></div>
+ </td><td id="mdg-mr"></td></tr>
+ <tr><td id="mdg-btl"></td><td>
+ <!-- We strongly request that you leave the notice below in its place; it helps to attract users to Enano in exchange for providing you
+ with your CMS. Enano is still new; therefore we are looking to attract users, and we feel that this notice will help. If you refuse
+ to include even this tiny little notice, support on the Enano forums may be affected. Thanks guys.
+
+ -Dan
+ -->
+ <div id="credits">
+ {COPYRIGHT}<br />
+ Powered by <a href="http://www.enanocms.org">Enano</a> | <a href="http://validator.w3.org/check?uri=referer">Valid XHTML 1.1</a> | <a href="http://jigsaw.w3.org/css-validator/validator?uri=referer">Valid CSS</a> | [[Stats]]
+ </div>
+
+ </td><td id="mdg-btr"></td></tr>
+ <tr><td id="mdg-btcl"></td><td id="mdg-btm"></td><td id="mdg-btcr"></td></tr>
+ </table>
+
+ </td>
+
+ <!-- BEGIN sidebar_right -->
+ <!-- BEGINNOT in_admin -->
+ <td class="mdgSidebarHolder" valign="top">
+ <div id="right-sidebar">
+
+ {SIDEBAR_RIGHT}
+
+ </div>
+ <div id="right-sidebar-showbutton" style="display: none; position: fixed; top: 3px; right: 3px;">
+ <input type="button" onclick="collapseSidebar('right');" value="<<" />
+ </div>
+ </td>
+ <!-- END in_admin -->
+ <!-- END sidebar_right -->
+
+ </tr>
+ </table>
+ <div style="display: none;">
+ <h2>Your browser does not support CSS.</h2>
+ <p>If you can see this text, it means that your browser does not support Cascading Style Sheets (CSS). CSS is a fundemental aspect of XHTML, and as a result it is becoming very widely adopted by websites, including this one. You should consider switching to a more modern web browser, such as Mozilla Firefox or Opera 9.</p>
+ <p>Because of this, there are a few minor issues that you may experience while browsing this site, not the least of which is some visual elements below that would normally be hidden in most browsers. Please excuse these minor inconveniences.</p>
+ </div>
+ <div id="root1" class="jswindow" style="display: none;">
+ <div id="tb1" class="titlebar">Confirm Logout</div>
+ <div class="content" id="cn1">
+ <form action="{CONTENTPATH}Special:Logout" method="get">
+ <div style="text-align: center">
+ <h3>Are you sure you want to log out?</h3>
+ <input type="submit" value="Log out" style="font-weight: bold;" /> <input type="button" onclick="jws.closeWin('root1');" value="Cancel" />
+ </div>
+ </form>
+ </div>
+ </div>
+ <div id="root2" class="jswindow" style="display: none;">
+ <div id="tb2" class="titlebar">Change style</div>
+ <div class="content" id="cn2">
+
+ </div>
+ </div>
+ <div id="root3" class="jswindow" style="display: none;">
+ <div id="tb3" class="titlebar">Wiki formatting help</div>
+ <div class="content" id="cn3">
+ Loading...
+ </div>
+ </div>
+ <script type="text/javascript">
+ // This initializes the Javascript runtime when the DOM is ready - not when the page is
+ // done loading, because enano-lib-basic still has to load some 15 other script files
+ // check for the init function - this is a KHTML fix
+ if ( typeof ( enano_init ) == 'function' )
+ {
+ enano_init();
+ window.onload = function(e) { };
+ }
+ </script>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/oxygen/header.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,141 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html>
+ <head>
+ <title>{PAGE_NAME} • {SITE_NAME}</title>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <link rel="stylesheet" type="text/css" href="{SCRIPTPATH}/includes/clientside/css/enano-shared.css" />
+ <link id="mdgCss" rel="stylesheet" href="{SCRIPTPATH}/themes/{THEME_ID}/css/{STYLE_ID}.css" type="text/css" />
+ {JS_DYNAMIC_VARS}
+ <!-- This script automatically loads the other 15 JS files -->
+ <script type="text/javascript" src="{SCRIPTPATH}/includes/clientside/static/enano-lib-basic.js"></script>
+ {ADDITIONAL_HEADERS}
+
+ <script type="text/javascript">
+
+ function collapseSidebar(side)
+ {
+ elem = document.getElementById(side+'-sidebar');
+ if(!elem) return;
+ counter = document.getElementById(side+'-sidebar-showbutton');
+ if(elem.style.display=='none')
+ {
+ elem.style.display = 'block';
+ counter.style.display = 'none';
+ elem.parentNode.style.width = '156px';
+ createCookie(side+'_sidebar', 'open', 365);
+ } else {
+ elem.style.display = 'none';
+ counter.style.display = 'block';
+ elem.parentNode.style.width = '25px';
+ createCookie(side+'_sidebar', 'collapsed', 365);
+ }
+ }
+
+ /*
+ window.onload = function() {
+ if(typeof readCookie == 'function')
+ {
+ if(readCookie('left_sidebar') =='collapsed') collapseSidebar('left');
+ if(readCookie('right_sidebar')=='collapsed') collapseSidebar('right');
+ }
+ if(typeof mdgInnerLoader == 'function')
+ mdgInnerLoader();
+ }
+ */
+
+ function ajaxRenameInline()
+ {
+ // This trick is _so_ vBulletin...
+ elem = document.getElementById('h2PageName');
+ if(!elem) return;
+ elem.style.display = 'none';
+ name = elem.innerHTML;
+ textbox = document.createElement('input');
+ textbox.type = 'text';
+ textbox.value = name;
+ textbox.id = 'pageheading';
+ textbox.size = name.length + 7;
+ textbox.onkeyup = function(e) { if(!e) return; if(e.keyCode == 13) ajaxRenameInlineSave(); if(e.keyCode == 27) ajaxRenameInlineCancel(); };
+ elem.parentNode.insertBefore(textbox, elem);
+ document.onclick = ajaxRenameInlineCancel;
+ }
+ function ajaxRenameInlineSave()
+ {
+ elem1 = document.getElementById('h2PageName');
+ elem2 = document.getElementById('pageheading');
+ if(!elem1 || !elem2) return;
+ value = elem2.value;
+ elem2.parentNode.removeChild(elem2); // just destroy the thing
+ elem1.innerHTML = value;
+ elem1.style.display = 'block';
+ if(!value || value=='') return;
+ ajaxPost(stdAjaxPrefix+'&_mode=rename', 'newtitle='+escape(value), function() {
+ if(ajax.readyState == 4) {
+ alert(ajax.responseText);
+ }
+ });
+ }
+ function ajaxRenameInlineCancel(e)
+ {
+ elem1 = document.getElementById('h2PageName');
+ elem2 = document.getElementById('pageheading');
+ if(!elem1 || !elem2) return;
+ if ( e.target )
+ {
+ if(e.target == elem2)
+ return;
+ }
+ //value = elem2.value;
+ elem2.parentNode.removeChild(elem2); // just destroy the thing
+ //elem1.innerHTML = value;
+ elem1.style.display = 'block';
+ document.onclick = null;
+ }
+ </script>
+
+ </head>
+ <body>
+ <table border="0" cellspacing="0" cellpadding="3" id="enano-master" width="100%">
+ <tr>
+ <!-- BEGIN sidebar_left -->
+ <td class="mdgSidebarHolder" valign="top">
+ <div id="left-sidebar">
+ {SIDEBAR_LEFT}
+ </div>
+ <div id="left-sidebar-showbutton" style="display: none; position: fixed; top: 3px; left: 3px;">
+ <input type="button" onclick="collapseSidebar('left');" value=">>" />
+ </div>
+ </td>
+ <!-- END sidebar_left -->
+ <td valign="top">
+ <table border="0" width="100%" cellspacing="0" cellpadding="0">
+
+ <tr><td id="mdg-tl"></td><td id="mdg-top"></td><td id="mdg-tr"></td></tr>
+
+ <tr><td id="mdg-l"></td><td>
+ <table border="0" width="100%" id="title" cellspacing="0" cellpadding="0">
+ <tr>
+ <td id="mainhead"><h2><a href="{SCRIPTPATH}/{ADMIN_SID_QUES}">{SITE_NAME}</a></h2><h4>{SITE_DESC}</h4></td>
+ </tr>
+ </table>
+ </td><td id="mdg-r"></td></tr>
+
+ <tr><td id="mdg-brl"></td><td style="background-color: #FFFFFF;"></td><td id="mdg-brr"></td></tr>
+
+ <tr><td id="mdg-bl"></td><td>
+ <div class="menu_nojs" id="pagebar_main">
+ <div class="label">Page tools</div>
+ {TOOLBAR}
+ <ul>
+ {TOOLBAR_EXTRAS}
+ </ul>
+ <span class="menuclear"> </span>
+ </div>
+ </td><td id="mdg-br"></td></tr>
+ <tr><td id="mdg-ml"></td><td style="background-color: #FFFFFF;">
+ <div class="pad"><div class="contentDiv">
+ <div style="float: right;">
+ <image alt=" " src="{SCRIPTPATH}/images/spacer.gif" id="ajaxloadicon" />
+ </div>
+ <h2 <!-- BEGIN auth_rename --> ondblclick="ajaxRenameInline();" title="Double-click to rename this page" <!-- END auth_rename --> id="h2PageName">{PAGE_NAME}</h2>
+ <div id="ajaxEditContainer">
Binary file themes/oxygen/images/bleu/bg.png has changed
Binary file themes/oxygen/images/bleu/border-bl.gif has changed
Binary file themes/oxygen/images/bleu/border-br.gif has changed
Binary file themes/oxygen/images/bleu/border-btm-l.gif has changed
Binary file themes/oxygen/images/bleu/border-btm-r.gif has changed
Binary file themes/oxygen/images/bleu/border-btm.gif has changed
Binary file themes/oxygen/images/bleu/border-l.gif has changed
Binary file themes/oxygen/images/bleu/border-m-l.gif has changed
Binary file themes/oxygen/images/bleu/border-m-r.gif has changed
Binary file themes/oxygen/images/bleu/border-menu-l.gif has changed
Binary file themes/oxygen/images/bleu/border-menu-r.gif has changed
Binary file themes/oxygen/images/bleu/border-menu-t-h.gif has changed
Binary file themes/oxygen/images/bleu/border-menu-t.gif has changed
Binary file themes/oxygen/images/bleu/border-r.gif has changed
Binary file themes/oxygen/images/bleu/border-tb-l.gif has changed
Binary file themes/oxygen/images/bleu/border-tb-r.gif has changed
Binary file themes/oxygen/images/bleu/border-tl.gif has changed
Binary file themes/oxygen/images/bleu/border-top.gif has changed
Binary file themes/oxygen/images/bleu/border-tr.gif has changed
Binary file themes/oxygen/images/bleu/bullet.gif has changed
Binary file themes/oxygen/images/bleu/email.gif has changed
Binary file themes/oxygen/images/bleu/external.gif has changed
Binary file themes/oxygen/images/bleu/https.gif has changed
Binary file themes/oxygen/images/bleu/irc.gif has changed
Binary file themes/oxygen/images/buttonbg.gif has changed
Binary file themes/oxygen/images/mint/bg.png has changed
Binary file themes/oxygen/images/mint/border-bl.gif has changed
Binary file themes/oxygen/images/mint/border-br.gif has changed
Binary file themes/oxygen/images/mint/border-btm-l.gif has changed
Binary file themes/oxygen/images/mint/border-btm-r.gif has changed
Binary file themes/oxygen/images/mint/border-btm.gif has changed
Binary file themes/oxygen/images/mint/border-l.gif has changed
Binary file themes/oxygen/images/mint/border-m-l.gif has changed
Binary file themes/oxygen/images/mint/border-m-r.gif has changed
Binary file themes/oxygen/images/mint/border-menu-l.gif has changed
Binary file themes/oxygen/images/mint/border-menu-r.gif has changed
Binary file themes/oxygen/images/mint/border-menu-t-h.gif has changed
Binary file themes/oxygen/images/mint/border-menu-t.gif has changed
Binary file themes/oxygen/images/mint/border-r.gif has changed
Binary file themes/oxygen/images/mint/border-tb-l.gif has changed
Binary file themes/oxygen/images/mint/border-tb-r.gif has changed
Binary file themes/oxygen/images/mint/border-tl.gif has changed
Binary file themes/oxygen/images/mint/border-top.gif has changed
Binary file themes/oxygen/images/mint/border-tr.gif has changed
Binary file themes/oxygen/images/mint/bullet.gif has changed
Binary file themes/oxygen/images/mint/email.gif has changed
Binary file themes/oxygen/images/mint/external.gif has changed
Binary file themes/oxygen/images/mint/https.gif has changed
Binary file themes/oxygen/images/mint/irc.gif has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/oxygen/sidebar-editor.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,58 @@
+<!-- VAR sidebar_button --><li><a href="javascript:void(0)" {FLAGS}>{TEXT}</a></li>
+<!-- ENDVAR sidebar_button -->
+<!-- VAR sidebar_raw --><li><span style="text-align: center;">{HTML}</span></li>
+<!-- ENDVAR sidebar_raw -->
+<!-- VAR sidebar_top -->
+ <div class="recttop">
+ <table border="0" width="100%" cellspacing="0" cellpadding="0" style="font-size: 1px;">
+ <tr>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-menu-l.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;" class="recttoptop"></td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-menu-r.gif" width="12" height="12" /> </td>
+ </tr>
+ </table>
+ </div>
+<!-- ENDVAR sidebar_top -->
+<!-- VAR sidebar_section -->
+ <div class="dbx-box">
+ <div class="dbx-handle">
+ {ADMIN_START}
+
+ {TITLE}
+ {ADMIN_END}
+
+ </div>
+ <div class="dbx-content">
+ <ul>
+ {CONTENT}
+ </ul>
+ </div>
+ </div>
+<!-- ENDVAR sidebar_section -->
+<!-- VAR sidebar_section_raw -->
+ <div class="dbx-box">
+ <div class="dbx-handle">
+ {ADMIN_START}
+
+ {TITLE}
+ {ADMIN_END}
+
+ </div>
+ <div class="dbx-content dbx-content2">
+ <ul><li>
+ {CONTENT}
+ </li></ul>
+ </div>
+ </div>
+<!-- ENDVAR sidebar_section_raw -->
+<!-- VAR sidebar_bottom -->
+ <div class="rectbot">
+ <table border="0" width="100%" cellspacing="0" cellpadding="0" style="font-size: 1px;">
+ <tr>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-bl.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;" class="rectbottop"></td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-br.gif" width="12" height="12" /> </td>
+ </tr>
+ </table>
+ </div>
+<!-- ENDVAR sidebar_bottom -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/oxygen/simple-footer.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,25 @@
+
+ </div>
+ </td>
+ <td id="main-right"></td>
+ </tr>
+ <tr>
+ <td id="foot-left"></td>
+ <td id="foot-main">
+ {COPYRIGHT}
+ </td>
+ <td id="foot-right"></td>
+ </tr>
+ <tr>
+ <td id="foot-btm-left"></td>
+ <td id="foot-btm"></td>
+ <td id="foot-btm-right"></td>
+ </tr>
+ </table>
+ </td>
+ <td style="width: 10%;"></td>
+ </tr>
+ </table>
+ </body>
+</html>
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/oxygen/simple-header.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,33 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html>
+ <head>
+ <title>{PAGE_NAME} • {SITE_NAME}</title>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <link rel="stylesheet" href="{SCRIPTPATH}/themes/{THEME_ID}/css-simple/{STYLE_ID}.css" type="text/css" id="mdgCss" />
+ {JS_DYNAMIC_VARS}
+ <!-- This script automatically loads the other 15 JS files -->
+ <script type="text/javascript" src="{SCRIPTPATH}/includes/clientside/static/enano-lib-basic.js"></script>
+ {ADDITIONAL_HEADERS}
+ </head>
+ <body>
+ <table border="0" style="width: 100%; height: 100%;">
+ <tr>
+ <td style="width: 10%;"></td>
+ <td valign="middle">
+ <table id="enano-main" border="0" cellspacing="0" cellpadding="0" style="margin: 0 auto;">
+ <tr>
+ <td id="head-up-left"></td>
+ <td id="head-up"></td>
+ <td id="head-up-right"></td>
+ </tr>
+ <tr>
+ <td id="head-left"></td>
+ <td id="head-main">
+ <h1>{PAGE_NAME}</h1>
+ </td>
+ <td id="head-right"></td>
+ </tr>
+ <tr>
+ <td id="main-left"></td>
+ <td id="main-main">
+ <div id="ajaxEditContainer">
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/oxygen/theme.cfg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,18 @@
+<?php
+/*
+ * Box Art theme for Enano
+ * Created by dandaman32 - (C) 2006
+ * License: GPL
+ *
+ * This theme is free software; you can redistribute and/or modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This theme is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+global $theme;
+$theme['theme_id'] = 'oxygen';
+$theme['theme_name'] = 'Oxygen Bleu';
+
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/oxygen/toolbar.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,49 @@
+<!-- Stuff related to toolbars and clickable buttons.
+ Used mostly in the page toolbar on most pages.
+ -->
+
+<!-- VAR toolbar_start -->
+ <div class="toolbar">
+ <ul>
+<!-- ENDVAR toolbar_start -->
+<!-- VAR toolbar_button -->
+ <li>
+ <a title="{TITLE}" {FLAGS}>
+ <img alt="{TITLE}" src="{IMAGE}" />
+ <!-- BEGIN show_title -->
+ <span>{TITLE}</span>
+ <!-- END show_title -->
+ </a>
+ </li>
+<!-- ENDVAR toolbar_button -->
+<!-- VAR toolbar_label -->
+ <li>
+ <span>{TITLE}</span>
+ </li>
+<!-- ENDVAR toolbar_label -->
+<!-- VAR toolbar_end -->
+ </ul>
+ </div>
+<!-- ENDVAR toolbar_end -->
+
+<!-- VAR toolbar_vert_start -->
+ <div class="toolbar_vert">
+ <ul>
+<!-- ENDVAR toolbar_vert_start -->
+<!-- VAR toolbar_vert_button -->
+ <li>
+ <a title="{TITLE}" {FLAGS}>
+ <img alt="{TITLE}" src="{IMAGE}" />
+ <span>{TITLE}</span>
+ </a>
+ </li>
+<!-- ENDVAR toolbar_vert_button -->
+<!-- VAR toolbar_vert_label -->
+ <li>
+ <span>{TITLE}</span>
+ </li>
+<!-- ENDVAR toolbar_vert_label -->
+<!-- VAR toolbar_vert_end -->
+ </ul>
+ </div>
+<!-- ENDVAR toolbar_vert_end -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/printable/acledit.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,36 @@
+<!-- VAR acl_field_begin -->
+<div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4" style="width: 100%;">
+ <tr>
+ <th></th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('1');">Deny</th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('2');">Disallow</th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('3');">Wiki mode</th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('4');">Allow</th>
+ </tr>
+<!-- ENDVAR acl_field_begin -->
+<!-- VAR acl_field_item -->
+ <tr>
+ <td class="{ROW_CLASS}">{FIELD_DESC}</td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="1" name="{FIELD_NAME}" {FIELD_DENY_CHECKED} /></td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="2" name="{FIELD_NAME}" {FIELD_DISALLOW_CHECKED} /></td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="3" name="{FIELD_NAME}" {FIELD_WIKIMODE_CHECKED} /></td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="4" name="{FIELD_NAME}" {FIELD_ALLOW_CHECKED} /></td>
+ </tr>
+<!-- ENDVAR acl_field_item -->
+<!-- VAR acl_field_end -->
+ <tr>
+ <td colspan="5" class="row3">
+ <p><b>Permission types:</b></p>
+ <ul>
+ <li><b>Allow</b> means that the user is allowed to access the item</li>
+ <li><b>Wiki mode</b> means the user can access the item if wiki mode is active (per-page wiki mode is taken into account)</li>
+ <li><b>Disallow</b> means the user is denied access unless something allows it.</li>
+ <li><b>Deny</b> means that the user is denied access to the item. This setting overrides all other permissions.</li>
+ </ul>
+ </td>
+ </tr>
+ </table>
+</div>
+<!-- ENDVAR acl_field_end -->
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/printable/comment.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,51 @@
+<div class="tblholder">
+ <table border="0" width="100%" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2" style="text-align: left;">{DATETIME}</th>
+ </tr>
+ <tr>
+ <td style="width: 120px; height: 100%;" rowspan="4" valign="top" class="row1">
+ <table border="0" width="100%" style="height: 100%;" cellspacing="0" cellpadding="0">
+ <tr>
+ <td valign="top" class="row1">
+ <b>{NAME}</b><br />
+ <small>{USER_LEVEL}</small>
+ </td>
+ </tr>
+ <tr>
+ <td valign="bottom" class="row1">
+ {SEND_PM_LINK} {ADD_BUDDY_LINK}
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td class="row2">
+ <b>Subject:</b> <span id="subject_{ID}">{SUBJECT}</span>
+ </td>
+ </tr>
+ <tr>
+ <td class="row3">
+ <div id="comment_{ID}">{DATA}</div>
+ <!-- BEGIN signature -->
+ <hr style="margin-left: 1em; width: 200px;" />
+ {SIGNATURE}
+ <!-- END signature -->
+ </td>
+ </tr>
+ <!-- BEGIN can_edit -->
+ <tr>
+ <td class="row2">
+ [ {EDIT_LINK} | {DELETE_LINK} ]
+ </td>
+ </tr>
+ <!-- END can_edit -->
+ <!-- BEGIN auth_mod -->
+ <tr>
+ <td class="row1">
+ <b>Moderation options:</b> {MOD_APPROVE_LINK} {MOD_DELETE_LINK}
+ </td>
+ </tr>
+ <!-- END auth_mod -->
+ </table>
+</div>
+<br />
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/printable/css-simple/bleu.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,136 @@
+/*
+ * Oxygen, but slightly more lightweight - used on minimalist pages
+ */
+
+/* Basic definitions */
+
+html, body {
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ background-image: url(../images/bleu/bg.png);
+ font-family: trebuchet ms, verdana, arial, helvetica, sans-serif;
+ font-size: 9pt;
+}
+
+/* Dummy cells and backgrounds */
+
+/* table#enano-main td { margin: 0; padding: 0; } */
+table#enano-main td#head-up-left { width: 12px; height: 12px; background-image: url(../images/bleu/border-tl.gif); }
+table#enano-main td#head-up { height: 12px; background-image: url(../images/bleu/border-top.gif); }
+table#enano-main td#head-up-right { width: 12px; height: 12px; background-image: url(../images/bleu/border-tr.gif); }
+table#enano-main td#head-left { width: 12px; background-image: url(../images/bleu/border-l.gif); padding-bottom: 12px; }
+table#enano-main td#head-main { background-color: #90B0D0; }
+table#enano-main td#head-right { width: 12px; background-image: url(../images/bleu/border-r.gif); }
+table#enano-main td#toolbar-left { width: 12px; background-image: url(../images/bleu/border-tb-l.gif); }
+table#enano-main td#toolbar-right { width: 12px; background-image: url(../images/bleu/border-tb-r.gif); }
+table#enano-main td#main-left { width: 12px; background-image: url(../images/bleu/border-m-l.gif); }
+table#enano-main td#main-main { background-color: #FFFFFF; }
+table#enano-main td#main-right { width: 12px; background-image: url(../images/bleu/border-m-r.gif); }
+table#enano-main td#foot-left { width: 12px; background-image: url(../images/bleu/border-btm-l.gif); }
+table#enano-main td#foot-main { background-color: #E8E8E8; padding-top: 12px; }
+table#enano-main td#foot-right { width: 12px; background-image: url(../images/bleu/border-btm-r.gif); }
+table#enano-main td#foot-btm-left { width: 12px; height: 12px; background-image: url(../images/bleu/border-bl.gif); }
+table#enano-main td#foot-btm { height: 12px; background-image: url(../images/bleu/border-btm.gif); }
+table#enano-main td#foot-btm-right { width: 12px; height: 12px; background-image: url(../images/bleu/border-br.gif); }
+
+/* Sidebar */
+
+td.mdgSidebarHolder { width: 156px; }
+div.sidebar, .dbx-group { width: 154px; background-color: #F8F8F8; border-left: 1px solid #CCC; border-right: 1px solid #CCC; padding: 1px 0px 0px 0px; }
+div.sidebar .head, .dbx-handle { background-color: #F0F0F0; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #111; padding: 5px; font-weight: bold; }
+div.sidebar .head:hover, .dbx-handle:hover { background-color: #F4F4F4; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #111; padding: 5px; font-weight: bold; }
+div.sidebar div.slideblock a, .dbx-content li { background-color: #DDD; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #666; padding: 5px 5px 5px 9px; list-style-type: none; }
+div.sidebar div.slideblock a:hover, .dbx-content li:hover { background-color: #EEE; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #666; padding: 5px 5px 5px 9px; }
+div.recttop { width: 156px; height: 12px; margin: 0; padding: 0; }
+td.recttoptop { width: 100%; height: 12px; background-image: url(../images/bleu/border-menu-t.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+td.recttoptop:hover { width: 100%; height: 12px; background-image: url(../images/bleu/border-menu-t-h.gif); background-repeat: repeat-x; margin: 0; padding: 0; cursor: pointer; }
+div.rectbot { width: 156px; height: 12px; margin: 0; padding: 0; }
+td.rectbottop { width: 100%; height: 12px; background-image: url(../images/bleu/border-btm.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+div.slideblock, .dbx-content { overflow: hidden; background-color: #FFF; }
+div.slideblock2 { overflow: hidden; background-color: #DDD; margin: 0px 1px 0px 1px; }
+.dbx-handle { cursor: move !important; }
+
+/*
+ * Docking Boxes code (for the sidebar editor)
+ */
+
+/* group container(s) */#sbedit {margin: 0;padding: 0;/* position:relative; /* additional outer containers must also have position:relative */}/* keyboard navigation tooltip */.dbx-tooltip {display:block;position:absolute;margin:36px 0 0 125px;width:185px;border:1px solid #000;background:#ffd;color:#000;font:normal normal normal 0.85em tahoma, arial, sans-serif;padding:2px 4px 3px 5px;text-align:left;}* html .dbx-tooltip { width:195px; }/* use CSS2 system colors in CSS2 browsersbut not safari, which doesn't support them */*[class="dbx-tooltip"]:lang(en) {border-color:InfoText;background:InfoBackground;color:InfoText;font:small-caption;font-weight:normal;}/* additional clone styles */.dbx-clone {opacity: 0.8;}.dbx-content ul {margin: 0; padding: 0;}.dbx-content li a, .dbx-content li a:hover {text-decoration: none; color: #666;}.dbx-content2 {background-color: #DDD; margin: 0px 1px 0px 1px;}/* toolbar */div.toolbar {border-bottom: 1px solid #909090;background-color: #D0D0D0;padding: 2px 0;height: 22px;font-family: arial, sans-serif;font-size: 8pt;}div.toolbar ul {margin: 0;padding: 0;}div.toolbar ul li {list-style: none;margin: 0;float: left;}div.toolbar a img {opacity: 0.6;/*filter: alpha(opacity=60);*/}div.toolbar a:hover img {opacity: 1;/*filter: alpha(opacity=100);*/}div.toolbar a {display: block;padding: 2px;border: 1px solid transparent;cursor: default;width: auto;color: #000000;margin: 0 2px;max-height: 16px;text-decoration: none;}div.toolbar a:hover {border: 1px solid #202090;background-color: #ceceed;color: #000000;text-decoration: none;}div.toolbar a:active {border: 1px solid #A0A0A0;background-color: #E0E0E0;}div.toolbar img {margin: 0;padding: 0;display: inline;border-width: 0px;}div.toolbar a span {position: relative;top: -4px;}div.toolbar li span {padding-left: 2px;padding-right: 5px;}/* vertical toolbar */div.toolbar_vert {border: 1px solid #909090;background-color: #D0D0D0;padding: 2px 0;}div.toolbar_vert ul {margin: 0;padding: 0;}div.toolbar_vert ul li {list-style: none;margin: 0;}div.toolbar_vert a img {opacity: 0.6;/*filter: alpha(opacity=60);*/}div.toolbar_vert a:hover img {opacity: 1;/*filter: alpha(opacity=100);*/}div.toolbar_vert a {display: block;padding: 2px;border: 1px solid transparent;cursor: default;width: auto;color: #000000;margin: 0 2px;max-height: 16px;text-decoration: none;}div.toolbar_vert a:hover {border: 1px solid #202090;background-color: #ceceed;color: #000000;text-decoration: none;}div.toolbar_vert a:active {border: 1px solid #A0A0A0;background-color: #E0E0E0;}div.toolbar_vert img {margin: 0;padding: 0;display: inline;border-width: 0px;}div.toolbar_vert a span {position: relative;top: -4px;}div.toolbar_vert li span {padding-left: 2px;padding-right: 5px;}
+
+/* Header */
+
+table#enano-main td#head-main {
+ text-align: center;
+}
+
+table#enano-main td#head-main h1 {
+ font-size: 14pt;
+}
+
+/* The "page tools" bar below the site logo but above the page content */
+div.pagebar { background-color: #B0D0F0; margin-top: 0px; padding: 3px; font-size: 7pt; }
+div.pagebar a { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #406080; }
+div.pagebar a.selected { background-color: #FFFFFF; color: #000040; font-weight: bold; }
+div.pagebar a:hover { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #406080; background-color: #D0F0FF; }
+div.pagebar input { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #E0F0FF; }
+div.pagebar input:hover { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #D0F0FF; }
+div.pagebar input:focus { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #F0F0FF; }
+
+/* Tweaks for the popup menu version of the same thing */
+div.pagebar#pagebarpopup { display: none; position: absolute; width: 150px; padding: 0; overflow: hidden; }
+div.pagebar#pagebarpopup a, div#pagebarpopup2 a { display: block; margin: 0; }
+
+/* Content area */
+table#enano-main td#main-main {
+ padding: 10px 0;
+}
+
+/* Text, headings, and links inside the main div (usually #ajaxEditContainer but used some other places as well) * /
+table#enano-main td#main-main h2 { border-bottom: 1px solid #90B0D0; margin-bottom: 0; }
+table#enano-main td#main-main h3 { font-size: 11pt; font-weight: bold; }
+table#enano-main td#main-main li { list-style: url(../images/bullet.gif); }
+table#enano-main td#main-main blockquote { background-color: #F4F4F4; border: 1px dotted #406080; margin: 1em; padding: 10px; max-height: 250px; overflow: auto; }
+table#enano-main td#main-main a { color: #7090B0; }
+table#enano-main td#main-main a:hover { color: #90B0D0; }
+table#enano-main td#main-main a[href ^="http://"] { color: #80A0C0; background: url(../images/bleu/external.gif) center right no-repeat; padding-right: 16px; }
+table#enano-main td#main-main a[href ^="https://"] { color: #80A0C0; background: url(../images/bleu/https.gif) center right no-repeat; padding-right: 16px; }
+table#enano-main td#main-main a[href ^="mailto:"] { color: #80A0C0; background: url(../images/bleu/email.gif) center right no-repeat; padding-right: 16px; }
+table#enano-main td#main-main a[href ^="irc://"] { color: #80A0C0; background: url(../images/bleu/irc.gif) center right no-repeat; padding-right: 16px; }
+table#enano-main td#main-main a[href ^="http://"]:hover { color: #A0C0E0; background: url(../images/bleu/external.gif) center right no-repeat; padding-right: 16px; }
+table#enano-main td#main-main a[href ^="https://"]:hover { color: #A0C0E0; background: url(../images/bleu/https.gif) center right no-repeat; padding-right: 16px; }
+table#enano-main td#main-main a[href ^="mailto:"]:hover { color: #A0C0E0; background: url(../images/bleu/email.gif) center right no-repeat; padding-right: 16px; }
+table#enano-main td#main-main a[href ^="irc://"]:hover { color: #A0C0E0; background: url(../images/bleu/irc.gif) center right no-repeat; padding-right: 16px; }
+
+/* Footer */
+
+table#enano-main td#foot-main {
+ color: #AAA;
+ font-size: 7pt;
+}
+
+/* Styled boxes */
+
+.mdg-comment, .mdg-infobox { margin-left: 1em; padding: 7px; border: 1px solid #AAAAAA; background-color: #E8E8E8; }
+
+/* Tables */
+
+.tblholder { margin: 10px 0 0 0; padding: 0; border: 1px solid #AAAAAA; background-color: #E8E8E8; }
+div.tblholder td.row1 { padding: 4px; background-color: #E0E0E0; }
+div.tblholder td.row2 { padding: 4px; background-color: #F0F0F0; }
+div.tblholder td.row3 { padding: 4px; background-color: #E8E8E8; }
+div.tblholder th { padding: 4px; background-color: #7080A0; font-weight: bold; text-align: center; color: #FFFFFF; }
+div.tblholder th.subhead { padding: 4px; background-color: #90A0B0; font-weight: bold; text-align: center; color: #FFFFFF; }
+div.tblholder table { background-color: #FFFFFF; width: 100%; }
+
+/* Buttons and textboxes - these settings are used almost everywhere */
+
+input, textarea, select { border: 1px solid #406080; background-color: #F2F2F2; padding: 3px; font-family: arial, helvetica, sans-serif; font-size: 9pt; }
+input:hover, textarea:hover, select:hover { border: 1px solid #6080A0; background-color: #F8F8F8; padding: 3px; }
+input:focus, textarea:focus, select:focus { border: 1px solid #90B0D0; background-color: #FFFFFF; padding: 3px; }
+label { padding: 3px; cursor: pointer; }
+label:hover { padding: 3px; cursor: pointer; background-color: #F0F0F0; }
+input#pageheading { font-size: 14pt; border-bottom: 1px solid #90B0D0; margin-bottom: 0; }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/printable/css-simple/printbits.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,7 @@
+span.normallink {
+ display: none;
+}
+div.mdg-comment {
+ display: none;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/printable/css/default.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,352 @@
+/**
+ * Printable page theme for Enano
+ * Designed by Dan Fuhry, (C) 2006
+ * This theme is Free Software; see the file "GPL" included with this package for details.
+ */
+
+/* The basics */
+html,body { height: 100%; }
+body { margin: 0; padding: 0; background-color: #FFFFFF; font-family: trebuchet ms, verdana, arial, helvetica, sans-serif; font-size: 9pt; }
+.holder { border: 1px solid #CCCCCC; padding: 1px; background-color: #FFFFFF; color: #444444 }
+div.pad { padding: 10px; }
+table#title { margin: 0; padding: 0; height: 100px; background-color: #90B0D0; text-align: center; }
+
+/* Sidebar */
+td.mdgSidebarHolder { width: 140px; }
+div.sidebar, .dbx-group { width: 138px; background-color: #F8F8F8; border-left: 1px solid #CCC; border-right: 1px solid #CCC; padding: 1px 0px 0px 0px; }
+div.sidebar .head, .dbx-handle { background-color: #F0F0F0; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #111; padding: 5px; font-weight: bold; }
+div.sidebar .head:hover, .dbx-handle:hover { background-color: #F4F4F4; display: block; margin: 0px 1px 1px 1px; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #111; padding: 5px; font-weight: bold; }
+div.sidebar div.slideblock a, .dbx-content li { background-color: #DDD; display: block; margin: 0px 1px; border-bottom: 1px solid #FFF; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #666; padding: 5px 5px 5px 9px; list-style-type: none; }
+div.sidebar div.slideblock a:hover, .dbx-content li:hover { background-color: #EEE; display: block; margin: 0px 1px; border-bottom: 1px solid #FFF; font-family: Trebuchet MS, Arial, helvetica, sans-serif; font-size: 7pt; cursor: pointer; text-decoration: none; color: #666; padding: 5px 5px 5px 9px; }
+div.recttop { width: 140px; height: 12px; margin: 0; padding: 0; }
+td.recttoptop { width: 100%; height: 12px; background-image: url(../images/bleu/border-menu-t.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+td.recttoptop:hover { width: 100%; height: 12px; background-image: url(../images/bleu/border-menu-t-h.gif); background-repeat: repeat-x; margin: 0; padding: 0; cursor: pointer; }
+div.rectbot { width: 140px; height: 12px; margin: 0; padding: 0; }
+td.rectbottop { width: 100%; height: 12px; background-image: url(../images/bleu/border-btm.gif); background-repeat: repeat-x; margin: 0; padding: 0; }
+div.slideblock, .dbx-content { overflow: hidden; background-color: #DDD; }
+div.slideblock2 { overflow: hidden; background-color: #DDD; margin: 0px 1px 0px 1px; }
+.dbx-handle { cursor: move !important; }
+
+/* The credits thingy at the bottom */
+div#credits { margin: 10px; border-top: 1px solid #C0C0C0; padding: 10px 0; color: #AAA; font-size: 7pt; }
+div#credits a { color: #B0B0B0; text-decoration: underline; }
+div#credits a:hover { color: #B0B0B0; text-decoration: underline; }
+
+/* The link hidden in plain "site" at the top of the page */
+td#mainhead a { text-decoration: none; color: #000000; }
+td#mainhead a:hover { text-decoration: none; color: #000000; border-bottom: 1px dotted #406080; }
+
+/* Text, headings, and links inside the main div (usually #ajaxEditContainer but used some other places as well) */
+div.contentDiv h2 { border-bottom: 1px solid #B0B0B0; margin-bottom: 0; }
+div.contentDiv h3 { font-size: 11pt; font-weight: bold; }
+div.contentDiv li , div#messageBox li { list-style: url(../images/bullet.gif); }
+div.contentDiv p , div#messageBox p { margin-left: 1.0em; }
+div.contentDiv blockquote , div#messageBox blockquote { background-color: #F4F4F4; border: 1px dotted #406080; margin: 1em; padding: 10px; max-height: 250px; overflow: auto; }
+div.contentDiv , div#messageBox { font-size: 9pt; }
+div.contentDiv a , div#messageBox a { color: #909090; }
+div.contentDiv a:hover , div#messageBox a:hover { color: #B0B0B0; }
+div.contentDiv a[href ^="http://"] , div#messageBox a[href ^="http://"] { color: #A0A0A0; }
+div.contentDiv a[href ^="https://"] , div#messageBox a[href ^="https://"] { color: #A0A0A0; }
+div.contentDiv a[href ^="mailto:"] , div#messageBox a[href ^="mailto:"] { color: #A0A0A0; }
+div.contentDiv a[href ^="irc://"] , div#messageBox a[href ^="irc://"] { color: #A0A0A0; }
+div.contentDiv a[href ^="http://"]:hover , div#messageBox a[href ^="http://"]:hover { color: #C0C0C0; }
+div.contentDiv a[href ^="https://"]:hover, div#messageBox a[href ^="https://"]:hover { color: #C0C0C0; }
+div.contentDiv a[href ^="mailto:"]:hover , div#messageBox a[href ^="mailto:"]:hover { color: #C0C0C0; }
+div.contentDiv a[href ^="irc://"]:hover , div#messageBox a[href ^="irc://"]:hover { color: #C0C0C0; }
+
+/* Wikilinks to pages that don't exist */
+div.contentDiv a.wikilink-nonexistent { color: #707070; border-bottom: 1px dotted #B05020; text-decoration: none; }
+div.contentDiv a.wikilink-nonexistent:hover { color: #707070; border-bottom: 1px dotted #B05020; text-decoration: none; }
+
+/* Well, not Midget and not comments (usually), but that's what the class is called ;-). Basically an informational window or used as a wrapper for tables. */
+.mdg-comment, .mdg-infobox { margin-left: 1em; padding: 7px; border: 1px solid #AAAAAA; background-color: #E8E8E8; }
+
+.tblholder { margin: 10px 0 0 0; padding: 0; border: 1px solid #AAAAAA; background-color: #E8E8E8; }
+
+/* The beautiful tables inside what may not obviously be mdg-comment divs */
+div.tblholder td.row1 { padding: 4px; border-color: #E0E0E0; border-width: 1px 1px 0 0; border-style: solid; background-color: #FFFFFF; }
+div.tblholder td.row2 { padding: 4px; border-color: #F0F0F0; border-width: 1px 1px 0 0; border-style: solid; background-color: #FFFFFF; }
+div.tblholder td.row3 { padding: 4px; border-color: #E8E8E8; border-width: 1px 1px 0 0; border-style: solid; background-color: #FFFFFF; }
+div.tblholder th { padding: 4px; border-color: #7080A0; border-width: 1px 1px 0 0; border-style: solid; background-color: #FFFFFF; font-weight: bold; text-align: center; color: #000000; }
+div.tblholder th.subhead { padding: 4px; border-color: #90A0B0; border-width: 1px 1px 0 0; border-style: solid; background-color: #FFFFFF; font-weight: bold; text-align: center; color: #000000; }
+div.tblholder table { background-color: #FFFFFF; width: 100%; }
+
+/* The "page tools" bar below the site logo but above the page content
+div.pagebar { background-color: #B0D0F0; margin-top: 0px; padding: 3px; font-size: 7pt; }
+div.pagebar a { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #406080; }
+div.pagebar a.selected { background-color: #FFFFFF; color: #000040; font-weight: bold; }
+div.pagebar a:hover { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #406080; background-color: #D0F0FF; }
+div.pagebar input { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #E0F0FF; }
+div.pagebar input:hover { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #D0F0FF; }
+div.pagebar input:focus { font-family: Bon Apetit, sans-serif; font-size: 7pt; border: 0; margin: 0px 0px 0px 0px; text-decoration: none; color: #406080; background-color: #F0F0FF; }
+*/
+
+/*
+ * jBox menu system
+ */
+
+div.menu {
+ background-color: #B0D0F0;
+ font-size: 7pt;
+ border-width: 0;
+}
+div.menu a, div.menu div.label {
+ padding: 2.5pt 5px;
+ margin-right: 3px;
+ text-decoration: none;
+ display: block;
+ float: left;
+ color: #406080;
+}
+div.menu div.label {
+ color: #001020;
+ cursor: default;
+}
+div.menu span.sep {
+ display: block;
+ float: left;
+ width: 5px;
+}
+div.menu div.multopts {
+ line-height: 17pt;
+}
+div.menu div.multopts a, div.menu div.multopts div.label {
+ float: none;
+ display: inline;
+}
+div.menu a.liteselected, div.menu a.liteselected:hover, div.menu a:hover {
+ color: #406080;
+ background-color: #D0F0FF;
+}
+div.menu input[type ^="text"], div.menu input[type ^="password"] {
+ border-width: 0;
+ font-size: 9pt;
+ padding: 4px 5px;
+ max-width: 70px;
+ background-color: #D0F0FF;
+}
+div.menu input[type ^="text"]:hover, div.menu input[type ^="password"]:hover {
+ background-color: #E0F0FF;
+}
+div.menu input[type ^="text"]:focus, div.menu input[type ^="password"]:focus {
+ background-color: #F0F0FF;
+}
+div.menu input[type ^="button"], div.menu input[type ^="submit"] {
+ border-width: 0;
+ font-size: 9pt;
+ padding: 3px 5px;
+ max-width: 70px;
+}
+div.menu a.current, div.menu a.current:hover, div.menu a.selected, div.menu a.selected:hover {
+ color: #000040;
+ background-color: #FFFFFF;
+}
+div.menu ul {
+ display: none;
+ position: absolute;
+ padding: 0;
+ margin: 0;
+ background-color: #B0D0F0;
+ border-width: 0;
+ min-width: 120px;
+}
+div.menu ul li {
+ list-style: none;
+}
+div.menu ul a {
+ float: none;
+ margin: 0;
+}
+span.menuclear {
+ font-size: 1px;
+ height: 0px;
+ width: 0px;
+ clear: left;
+ line-height: 0px;
+ display: block;
+}
+
+/* Rounded corners on nearly everything */
+td#mdg-tl { width: 12px; height: 12px; background: url(../images/bleu/border-tl.gif); }
+td#mdg-tr { width: 12px; height: 12px; background: url(../images/bleu/border-tr.gif); }
+td#mdg-top { background: url(../images/bleu/border-top.gif); }
+td#mdg-l { width: 12px; height: 12px; background: url(../images/bleu/border-l.gif); }
+td#mdg-r { width: 12px; height: 12px; background: url(../images/bleu/border-r.gif); }
+td#mdg-bl { width: 12px; height: 12px; background: url(../images/bleu/border-tb-l.gif); }
+td#mdg-br { width: 12px; height: 12px; background: url(../images/bleu/border-tb-r.gif); }
+td#mdg-ml { width: 12px; height: 12px; background: url(../images/bleu/border-m-l.gif); }
+td#mdg-mr { width: 12px; height: 12px; background: url(../images/bleu/border-m-r.gif); }
+td#mdg-brl { width: 12px; height: 1px; background: url(../images/bleu/border-m-l.gif); }
+td#mdg-brr { width: 12px; height: 1px; background: url(../images/bleu/border-m-r.gif); }
+td#mdg-btl { width: 12px; height: 1px; background: url(../images/bleu/border-btm-l.gif); }
+td#mdg-btr { width: 12px; height: 1px; background: url(../images/bleu/border-btm-r.gif); }
+td#mdg-btcl { width: 12px; height: 12px; background: url(../images/bleu/border-bl.gif); }
+td#mdg-btcr { width: 12px; height: 12px; background: url(../images/bleu/border-br.gif); }
+td#mdg-btm { height: 12px; background: url(../images/bleu/border-btm.gif); }
+td.mdg-menu-top { width: 84%; height: 12px; background: url(../images/bleu/border-menu-t.gif); margin: 0; padding: 0; background-repeat: repeat-x; font-size: 2px; }
+td.mdg-menu-tl { width: 12px; height: 12px; background: url(../images/bleu/border-menu-l.gif); background-position: left top; background-repeat: no-repeat; }
+td.mdg-menu-tr { width: 12px; height: 12px; background: url(../images/bleu/border-menu-r.gif); background-position: right top; background-repeat: no-repeat; }
+td.mdg-menu-bl { width: 12px; height: 12px; background: url(../images/bleu/border-bl.gif); }
+td.mdg-menu-br { width: 12px; height: 12px; background: url(../images/bleu/border-br.gif); }
+td.mdg-menu-btm { height: 12px; background: url(../images/bleu/border-btm.gif); }
+
+/* Buttons and textboxes - these settings are used almost everywhere */
+input, textarea, select { border: 1px solid #406080; background-color: #F2F2F2; padding: 3px; font-family: arial, helvetica, sans-serif; font-size: 9pt; }
+input:hover, textarea:hover, select:hover { border: 1px solid #6080A0; background-color: #F8F8F8; padding: 3px; }
+input:focus, textarea:focus, select:focus { border: 1px solid #90B0D0; background-color: #FFFFFF; padding: 3px; }
+label { padding: 3px; cursor: pointer; }
+label:hover { padding: 3px; cursor: pointer; background-color: #F0F0F0; }
+input#pageheading { font-size: 14pt; border-bottom: 1px solid #90B0D0; margin-bottom: 0; }
+
+/* JWS window theming */
+div.jswindow { border: 2px solid #7090B0; border-top: 5px solid #7090B0; padding: 0px; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; display: none; position: absolute; background-color: #FFFFFF; }
+div.titlebar { background-color: #7090B0; color: #FFFFFF; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; padding-bottom: 4px; cursor: default; }
+div.titlebar div.closebtn { width: 16px; height: 16px; border: 1px solid #B0D0F0; background-color: #90B0D0; display: block; }
+div.titlebar div.closebtn:hover { width: 16px; height: 16px; border: 1px solid #FFFFFF; background-color: #B0D0F0; display: block; }
+div.titlebar table, div.titlebar td { margin: 0; padding: 0; }
+div.jswindow div.content { padding: 10px; margin: 0; background-color: #FFFFFF; }
+
+/* The Wordpress-like fills behind checkboxes and their labels */
+.catCheck { padding: 3px; }
+.catCheck:hover { padding: 3px; background-color: #F0F0F0; }
+
+/* Information, warning, question, error, and wait boxes */
+div.error-box { background-image: url(../../../images/error.png); background-repeat: no-repeat; background-color: #FFF4F4; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.info-box { background-image: url(../../../images/info.png); background-repeat: no-repeat; background-color: #F4F4FF; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.warning-box { background-image: url(../../../images/warning.png); background-repeat: no-repeat; background-color: #FFFFF4; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.question-box { background-image: url(../../../images/question.png); background-repeat: no-repeat; background-color: #F4FFF4; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.wait-box { background-image: url(../../../images/wait.png); background-repeat: no-repeat; background-color: #FFF4FF; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+
+/* This stuff is mostly unused, left in for compatibility */
+div#ajaxEditContainer table { border: 0px solid #FFFFFF; }
+div#ajaxEditContainer td { margin: 1px; }
+/* div#ajaxEditContainer { overflow: auto; } /* Makes ajaxEditContainer scroll horizontally in firefox if the content is too wide - prevents that ugly clipping effect */
+div#ajaxEditContainer pre { margin-left: 1em; background-color: #F8F8F8; border: 1px dashed #90B0D0; padding: 10px; overflow: auto; max-height: 150px; }
+
+/* Tables where diffs are shown */
+table.diff, td.diff-otitle, td.diff-ntitle { background-color: white; }
+td.diff-addedline { background: #cfc; font-size: smaller; }
+td.diff-deletedline { background: #ffa; font-size: smaller; }
+td.diff-context { background: #eee; font-size: smaller; }
+span.diffchange { color: red; font-weight: bold; }
+
+/* toolbar */
+div.toolbar {
+ border-bottom: 1px solid #909090;
+ background-color: #D0D0D0;
+ padding: 2px 0;
+ height: 22px;
+ font-family: arial, sans-serif;
+ font-size: 8pt;
+}
+div.toolbar ul {
+ margin: 0;
+ padding: 0;
+}
+div.toolbar ul li {
+ list-style: none;
+ margin: 0;
+ float: left;
+}
+div.toolbar a img {
+ opacity: 0.6;
+ /*filter: alpha(opacity=60);*/
+}
+div.toolbar a:hover img {
+ opacity: 1;
+ /*filter: alpha(opacity=100);*/
+}
+div.toolbar a {
+ display: block;
+ padding: 2px;
+ border: 1px solid transparent;
+ cursor: default;
+ width: auto;
+ color: #000000;
+ margin: 0 2px;
+ max-height: 16px;
+ text-decoration: none;
+}
+div.toolbar a:hover {
+ border: 1px solid #202090;
+ background-color: #ceceed;
+ color: #000000;
+ text-decoration: none;
+}
+div.toolbar a:active {
+ border: 1px solid #A0A0A0;
+ background-color: #E0E0E0;
+}
+div.toolbar img {
+ margin: 0;
+ padding: 0;
+ display: inline;
+ border-width: 0px;
+}
+div.toolbar a span {
+ position: relative;
+ top: -4px;
+}
+div.toolbar li span {
+ padding-left: 2px;
+ padding-right: 5px;
+}
+
+/* vertical toolbar */
+div.toolbar_vert {
+ border: 1px solid #909090;
+ background-color: #D0D0D0;
+ padding: 2px 0;
+}
+div.toolbar_vert ul {
+ margin: 0;
+ padding: 0;
+}
+div.toolbar_vert ul li {
+ list-style: none;
+ margin: 0;
+}
+div.toolbar_vert a img {
+ opacity: 0.6;
+ /*filter: alpha(opacity=60);*/
+}
+div.toolbar_vert a:hover img {
+ opacity: 1;
+ /*filter: alpha(opacity=100);*/
+}
+div.toolbar_vert a {
+ display: block;
+ padding: 2px;
+ border: 1px solid transparent;
+ cursor: default;
+ width: auto;
+ color: #000000;
+ margin: 0 2px;
+ max-height: 16px;
+ text-decoration: none;
+}
+div.toolbar_vert a:hover {
+ border: 1px solid #202090;
+ background-color: #ceceed;
+ color: #000000;
+ text-decoration: none;
+}
+div.toolbar_vert a:active {
+ border: 1px solid #A0A0A0;
+ background-color: #E0E0E0;
+}
+div.toolbar_vert img {
+ margin: 0;
+ padding: 0;
+ display: inline;
+ border-width: 0px;
+}
+div.toolbar_vert a span {
+ position: relative;
+ top: -4px;
+}
+div.toolbar_vert li span {
+ padding-left: 2px;
+ padding-right: 5px;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/printable/elements.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,64 @@
+<!-- VAR toolbar_button --><a href="{HREF}" {PARENTFLAGS} {FLAGS}>{TEXT}</a>
+<!-- ENDVAR toolbar_button -->
+<!-- VAR toolbar_label --><div class="label">{TEXT}</div>
+<!-- ENDVAR toolbar_label -->
+<!-- VAR toolbar_button_selected --><a href="{HREF}" class="current" {PARENTFLAGS} {FLAGS}>{TEXT}</a>
+<!-- ENDVAR toolbar_button_selected -->
+<!-- VAR toolbar_menu_button --><li><a href="{HREF}" {FLAGS}>{TEXT}</a></li>
+<!-- ENDVAR toolbar_menu_button -->
+<!-- VAR toolbar_menu_block --><li>{HTML}</li>
+<!-- ENDVAR toolbar_menu_block -->
+<!-- VAR sidebar_button --><a href="{HREF}" {FLAGS}>{TEXT}</a><br style="display: none;" />
+<!-- ENDVAR sidebar_button -->
+<!-- VAR sidebar_raw --><span style="text-align: center;">{HTML}</span><br style="display: none;" />
+<!-- ENDVAR sidebar_raw -->
+<!-- VAR sidebar_heading --><div class="heading">{TEXT}</div>
+<!-- ENDVAR sidebar_heading -->
+<!-- VAR sidebar_top -->
+ <div class="recttop">
+ <table border="0" width="100%" cellspacing="0" cellpadding="0" style="font-size: 1px;">
+ <tr>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-menu-l.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;" class="recttoptop"></td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-menu-r.gif" width="12" height="12" /> </td>
+ </tr>
+ </table>
+ </div>
+ <div class="sidebar">
+<!-- ENDVAR sidebar_top -->
+<!-- VAR sidebar_section -->
+ <div class="slider">
+ <div class="heading">
+ <!-- BEGIN in_sidebar_admin -->{ADMIN_START}<!-- END in_sidebar_admin -->
+ <br style="display: none;" /><br style="display: none;" />
+ <a class="head" onclick="toggle(this); return false" href="#">{TITLE}</a>
+ <!-- BEGIN in_sidebar_admin -->{ADMIN_END}<!-- END in_sidebar_admin -->
+ <br style="display: none;" /><br style="display: none;" />
+ </div>
+ <div class="slideblock">{CONTENT}</div>
+ </div>
+<!-- ENDVAR sidebar_section -->
+<!-- VAR sidebar_section_raw -->
+ <div class="slider">
+ <div class="heading">
+ <!-- BEGIN in_sidebar_admin -->{ADMIN_START}<!-- END in_sidebar_admin -->
+ <br style="display: none;" /><br style="display: none;" />
+ <a class="head" onclick="toggle(this); return false" href="#">{TITLE}</a>
+ <!-- BEGIN in_sidebar_admin -->{ADMIN_END}<!-- END in_sidebar_admin -->
+ <br style="display: none;" /><br style="display: none;" />
+ </div>
+ <div class="slideblock2">{CONTENT}</div>
+ </div>
+<!-- ENDVAR sidebar_section_raw -->
+<!-- VAR sidebar_bottom -->
+ </div>
+ <div class="rectbot">
+ <table border="0" width="100%" cellspacing="0" cellpadding="0" style="font-size: 1px;">
+ <tr>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-bl.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;" class="rectbottop"></td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-br.gif" width="12" height="12" /> </td>
+ </tr>
+ </table>
+ </div>
+<!-- ENDVAR sidebar_bottom -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/printable/footer.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,26 @@
+ </div>
+ </div></div>
+
+ <!-- We strongly request that you leave the notice below in its place; it helps to attract users to Enano in exchange for providing you
+ with your CMS. Enano is still new; therefore we are looking to attract users, and we feel that this notice will help. If you refuse
+ to include even this tiny little notice, support on the Enano forums may be affected. Thanks guys.
+
+ -Dan
+ -->
+ <div id="credits">
+ {COPYRIGHT}<br />
+ Powered by <a href="http://www.enanocms.org">Enano</a> | <a href="http://validator.w3.org/check?uri=referer">Valid XHTML 1.1</a> | <a href="http://jigsaw.w3.org/css-validator/validator?uri=referer">Valid CSS</a> | [[Stats]]
+ </div>
+
+ <script type="text/javascript">
+ // This initializes the Javascript runtime when the DOM is ready - not when the page is
+ // done loading, because enano-lib-basic still has to load some 15 other script files
+ // check for the init function - this is a KHTML fix
+ if ( typeof ( enano_init ) == 'function' )
+ {
+ enano_init();
+ window.onload = function(e) { };
+ }
+ </script>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/printable/header.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,21 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html>
+ <head>
+ <title>{PAGE_NAME} • {SITE_NAME}</title>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <link rel="stylesheet" type="text/css" href="{SCRIPTPATH}/includes/clientside/css/enano-shared.css" />
+ <link id="mdgCss" rel="stylesheet" href="{SCRIPTPATH}/themes/{THEME_ID}/css/{STYLE_ID}.css" type="text/css" />
+ <link rel="stylesheet" media="print" href="{SCRIPTPATH}/themes/{THEME_ID}/css-simple/printbits.css" type="text/css" />
+ {JS_DYNAMIC_VARS}
+ <!-- This script automatically loads the other 15 JS files -->
+ <script type="text/javascript" src="{SCRIPTPATH}/includes/clientside/static/enano-lib-basic.js"></script>
+ {ADDITIONAL_HEADERS}
+
+ </head>
+ <body>
+ <div class="pad"><div class="contentDiv">
+ <div style="float: right;">
+ <span class="normallink"><a href="#" onclick="window.print(); return false;">print page</a> | <a href="{CONTENTPATH}{PAGE_URLNAME}{ADMIN_SID_AUTO}">view normal version</a></span> <image alt=" " src="{SCRIPTPATH}/images/spacer.gif" id="ajaxloadicon" />
+ </div>
+ <h2>{PAGE_NAME}</h2>
+ <div id="ajaxEditContainer">
Binary file themes/printable/images/bleu/bg.png has changed
Binary file themes/printable/images/bleu/border-bl.gif has changed
Binary file themes/printable/images/bleu/border-br.gif has changed
Binary file themes/printable/images/bleu/border-btm-l.gif has changed
Binary file themes/printable/images/bleu/border-btm-r.gif has changed
Binary file themes/printable/images/bleu/border-btm.gif has changed
Binary file themes/printable/images/bleu/border-l.gif has changed
Binary file themes/printable/images/bleu/border-m-l.gif has changed
Binary file themes/printable/images/bleu/border-m-r.gif has changed
Binary file themes/printable/images/bleu/border-menu-l.gif has changed
Binary file themes/printable/images/bleu/border-menu-r.gif has changed
Binary file themes/printable/images/bleu/border-menu-t-h.gif has changed
Binary file themes/printable/images/bleu/border-menu-t.gif has changed
Binary file themes/printable/images/bleu/border-r.gif has changed
Binary file themes/printable/images/bleu/border-tb-l.gif has changed
Binary file themes/printable/images/bleu/border-tb-r.gif has changed
Binary file themes/printable/images/bleu/border-tl.gif has changed
Binary file themes/printable/images/bleu/border-top.gif has changed
Binary file themes/printable/images/bleu/border-tr.gif has changed
Binary file themes/printable/images/bleu/bullet.gif has changed
Binary file themes/printable/images/bleu/email.gif has changed
Binary file themes/printable/images/bleu/external.gif has changed
Binary file themes/printable/images/bleu/https.gif has changed
Binary file themes/printable/images/bleu/irc.gif has changed
Binary file themes/printable/images/mint/bg.png has changed
Binary file themes/printable/images/mint/border-bl.gif has changed
Binary file themes/printable/images/mint/border-br.gif has changed
Binary file themes/printable/images/mint/border-btm-l.gif has changed
Binary file themes/printable/images/mint/border-btm-r.gif has changed
Binary file themes/printable/images/mint/border-btm.gif has changed
Binary file themes/printable/images/mint/border-l.gif has changed
Binary file themes/printable/images/mint/border-m-l.gif has changed
Binary file themes/printable/images/mint/border-m-r.gif has changed
Binary file themes/printable/images/mint/border-menu-l.gif has changed
Binary file themes/printable/images/mint/border-menu-r.gif has changed
Binary file themes/printable/images/mint/border-menu-t-h.gif has changed
Binary file themes/printable/images/mint/border-menu-t.gif has changed
Binary file themes/printable/images/mint/border-r.gif has changed
Binary file themes/printable/images/mint/border-tb-l.gif has changed
Binary file themes/printable/images/mint/border-tb-r.gif has changed
Binary file themes/printable/images/mint/border-tl.gif has changed
Binary file themes/printable/images/mint/border-top.gif has changed
Binary file themes/printable/images/mint/border-tr.gif has changed
Binary file themes/printable/images/mint/bullet.gif has changed
Binary file themes/printable/images/mint/email.gif has changed
Binary file themes/printable/images/mint/external.gif has changed
Binary file themes/printable/images/mint/https.gif has changed
Binary file themes/printable/images/mint/irc.gif has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/printable/punbb/bleu.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,111 @@
+/****************************************************************/
+/* 1. BACKGROUND AND TEXT COLOURS */
+/****************************************************************/
+
+/* 1.1 Default background colour and text colour */
+
+BODY {BACKGROUND-COLOR: #FFF}
+
+.pun {COLOR: #333}
+
+DIV.box, .pun BLOCKQUOTE, DIV.codebox, #adminconsole FIELDSET TH, .rowodd, .roweven {BACKGROUND-COLOR: #F1F1F1}
+#adminconsole TD, #adminconsole TH {BORDER-COLOR: #F1F1F1}
+
+/* 1. 2 Darker background colours */
+
+TD.tc2, TD.tc3, TD.tcmod, #postpreview, #viewprofile DD, DIV.forminfo,
+#adminconsole FIELDSET TD, DIV.blockmenu DIV.box, #adstats DD {BACKGROUND-COLOR: #DEDFDF}
+
+/* 1.3 Main headers and navigation bar background and text colour */
+
+.pun H2, #brdmenu {BACKGROUND-COLOR: #7090B0; COLOR: #FFF}
+
+/* 1.4 Table header rows */
+
+.pun TH {BACKGROUND-COLOR: #D1D1D1}
+
+/* 1.5 Fieldset legend text colour */
+
+.pun LEGEND {COLOR: #005CB1}
+
+/* 1.6 Highlighted text for various items */
+
+.pun DIV.blockmenu LI.isactive A, #posterror LI STRONG {COLOR: #333}
+
+/****************************************************************/
+/* 2. POST BACKGROUNDS AND TEXT */
+/****************************************************************/
+
+/* 2.1 This is the setup for posts. */
+
+DIV.blockpost DIV.box, DIV.postright, DIV.postfootright {BACKGROUND-COLOR: #DEDFDF}
+DIV.postright, DIV.postfootright {BORDER-LEFT-COLOR: #f1f1f1}
+DIV.postleft, DIV.postfootleft, DIV.blockpost LABEL {BACKGROUND-COLOR: #F1F1F1}
+
+/* 2.2 Background for post headers and text colour for post numbers in viewtopic */
+
+DIV.blockpost H2 {BACKGROUND-COLOR: #7090B0}
+DIV.blockpost H2 SPAN.conr {COLOR: #AABDCD}
+
+/* 2.3 This is the line above the signature in posts. Colour and background should be the same */
+
+.pun HR {BACKGROUND-COLOR: #333; COLOR: #333}
+
+/****************************************************************/
+/* 3. BORDER COLOURS */
+/****************************************************************/
+
+/* 3.1 All external borders */
+
+DIV.box {BORDER-COLOR: #7090B0}
+
+/* 3.2 Makes the top border of posts match the colour used for post headers */
+
+DIV.blockpost DIV.box {BORDER-COLOR: #7090B0 #7090B0 #7090B0}
+
+/* 3.3 Table internal borders. By default TH is same as background so border is invisible */
+
+.pun TD {BORDER-COLOR: #BBCEDE}
+.pun TH {BORDER-COLOR: #D1D1D1}
+
+/* 3.4 Creates the inset border for quote boxes, code boxes and form info boxes */
+
+.pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {BORDER-COLOR: #ACA899 #FFF #FFF #ACA899}
+
+/* 3.5 Gecko's default fieldset borders are really nasty so this gives them a colour
+without interferring with IE's rather nice default */
+
+.pun DIV>FIELDSET {BORDER-COLOR: #ACA899}
+
+/****************************************************************/
+/* 4. LINK COLOURS */
+/****************************************************************/
+
+/* 4.1 This is the default for all links */
+
+.pun A:link, .pun A:visited {COLOR: #7090B0}
+.pun A:hover {COLOR: #90B0D0}
+
+/* 4.2 This is the colour for links in header rows and the navigation bar */
+
+.pun H2 A:link, .pun H2 A:visited, #brdmenu A:link, #brdmenu A:visited {COLOR: #FFF}
+.pun H2 A:hover, #brdmenu A:hover {COLOR: #FFF}
+
+/* 4.3 This is for closed topics and "hot" links */
+
+LI.postreport A:link, LI.postreport A:visited, TR.iclosed TD.tcl A:link, TR.iclosed TD.tcl A:visited {COLOR: #888}
+LI.postreport A:hover, TR.iclosed TD.tcl A:hover {COLOR: #AAA}
+LI.maintenancelink A:link, LI.maintenancelink A:visited {COLOR: #B42000}
+LI.maintenancelink A:hover {COLOR: #B42000}
+
+/****************************************************************/
+/* 5. POST STATUS INDICATORS */
+/****************************************************************/
+
+/* These are the post status indicators which appear at the left of some tables.
+.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and
+.isticky = sticky topics. The default is "icon". By default only .inew is different.*/
+
+DIV.icon {BORDER-COLOR: #E6E6E6 #DEDEDE #DADADA #E2E2E2}
+TR.iredirect DIV.icon {BORDER-COLOR: #76B696 #6EAE8E #5A9A7A #72B292}
+DIV.inew {BORDER-COLOR: #7696B6 #6E8EAE #5A7A9A #7292B2}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/printable/punbb/mint.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,111 @@
+/****************************************************************/
+/* 1. BACKGROUND AND TEXT COLOURS */
+/****************************************************************/
+
+/* 1.1 Default background colour and text colour */
+
+BODY {BACKGROUND-COLOR: #FFF}
+
+.pun {COLOR: #333}
+
+DIV.box, .pun BLOCKQUOTE, DIV.codebox, #adminconsole FIELDSET TH, .rowodd, .roweven {BACKGROUND-COLOR: #F1F1F1}
+#adminconsole TD, #adminconsole TH {BORDER-COLOR: #F1F1F1}
+
+/* 1. 2 Darker background colours */
+
+TD.tc2, TD.tc3, TD.tcmod, #postpreview, #viewprofile DD, DIV.forminfo,
+#adminconsole FIELDSET TD, DIV.blockmenu DIV.box, #adstats DD {BACKGROUND-COLOR: #DEDFDF}
+
+/* 1.3 Main headers and navigation bar background and text colour */
+
+.pun H2, #brdmenu {BACKGROUND-COLOR: #70B090; COLOR: #FFF}
+
+/* 1.4 Table header rows */
+
+.pun TH {BACKGROUND-COLOR: #D1D1D1}
+
+/* 1.5 Fieldset legend text colour */
+
+.pun LEGEND {COLOR: #00B15C}
+
+/* 1.6 Highlighted text for various items */
+
+.pun DIV.blockmenu LI.isactive A, #posterror LI STRONG {COLOR: #333}
+
+/****************************************************************/
+/* 2. POST BACKGROUNDS AND TEXT */
+/****************************************************************/
+
+/* 2.1 This is the setup for posts. */
+
+DIV.blockpost DIV.box, DIV.postright, DIV.postfootright {BACKGROUND-COLOR: #DEDFDF}
+DIV.postright, DIV.postfootright {BORDER-LEFT-COLOR: #f1f1f1}
+DIV.postleft, DIV.postfootleft, DIV.blockpost LABEL {BACKGROUND-COLOR: #F1F1F1}
+
+/* 2.2 Background for post headers and text colour for post numbers in viewtopic */
+
+DIV.blockpost H2 {BACKGROUND-COLOR: #70B090}
+DIV.blockpost H2 SPAN.conr {COLOR: #AACDBD}
+
+/* 2.3 This is the line above the signature in posts. Colour and background should be the same */
+
+.pun HR {BACKGROUND-COLOR: #333; COLOR: #333}
+
+/****************************************************************/
+/* 3. BORDER COLOURS */
+/****************************************************************/
+
+/* 3.1 All external borders */
+
+DIV.box {BORDER-COLOR: #70B090}
+
+/* 3.2 Makes the top border of posts match the colour used for post headers */
+
+DIV.blockpost DIV.box {BORDER-COLOR: #70B090 #70B090 #70B090}
+
+/* 3.3 Table internal borders. By default TH is same as background so border is invisible */
+
+.pun TD {BORDER-COLOR: #BBDECE}
+.pun TH {BORDER-COLOR: #D1D1D1}
+
+/* 3.4 Creates the inset border for quote boxes, code boxes and form info boxes */
+
+.pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {BORDER-COLOR: #AC99A8 #FFF #FFF #AC99A8}
+
+/* 3.5 Gecko's default fieldset borders are really nasty so this gives them a colour
+without interferring with IE's rather nice default */
+
+.pun DIV>FIELDSET {BORDER-COLOR: #AC99A8}
+
+/****************************************************************/
+/* 4. LINK COLOURS */
+/****************************************************************/
+
+/* 4.1 This is the default for all links */
+
+.pun A:link, .pun A:visited {COLOR: #70B090}
+.pun A:hover {COLOR: #90D0B0}
+
+/* 4.2 This is the colour for links in header rows and the navigation bar */
+
+.pun H2 A:link, .pun H2 A:visited, #brdmenu A:link, #brdmenu A:visited {COLOR: #FFF}
+.pun H2 A:hover, #brdmenu A:hover {COLOR: #FFF}
+
+/* 4.3 This is for closed topics and "hot" links */
+
+LI.postreport A:link, LI.postreport A:visited, TR.iclosed TD.tcl A:link, TR.iclosed TD.tcl A:visited {COLOR: #888}
+LI.postreport A:hover, TR.iclosed TD.tcl A:hover {COLOR: #AAA}
+LI.maintenancelink A:link, LI.maintenancelink A:visited {COLOR: #B40020}
+LI.maintenancelink A:hover {COLOR: #B40020}
+
+/****************************************************************/
+/* 5. POST STATUS INDICATORS */
+/****************************************************************/
+
+/* These are the post status indicators which appear at the left of some tables.
+.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and
+.isticky = sticky topics. The default is "icon". By default only .inew is different.*/
+
+DIV.icon {BORDER-COLOR: #E6E6E6 #DEDEDE #DADADA #E2E2E2}
+TR.iredirect DIV.icon {BORDER-COLOR: #7696B6 #6E8EAE #5A7A9A #7292B2}
+DIV.inew {BORDER-COLOR: #76B696 #6EAE8E #5A9A7A #72B292}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/printable/sidebar-editor.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,58 @@
+<!-- VAR sidebar_button --><li><a href="javascript:void(0)" {FLAGS}>{TEXT}</a></li>
+<!-- ENDVAR sidebar_button -->
+<!-- VAR sidebar_raw --><li><span style="text-align: center;">{HTML}</span></li>
+<!-- ENDVAR sidebar_raw -->
+<!-- VAR sidebar_top -->
+ <div class="recttop">
+ <table border="0" width="100%" cellspacing="0" cellpadding="0" style="font-size: 1px;">
+ <tr>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-menu-l.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;" class="recttoptop"></td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-menu-r.gif" width="12" height="12" /> </td>
+ </tr>
+ </table>
+ </div>
+<!-- ENDVAR sidebar_top -->
+<!-- VAR sidebar_section -->
+ <div class="dbx-box">
+ <div class="dbx-handle">
+ {ADMIN_START}
+
+ {TITLE}
+ {ADMIN_END}
+
+ </div>
+ <div class="dbx-content">
+ <ul>
+ {CONTENT}
+ </ul>
+ </div>
+ </div>
+<!-- ENDVAR sidebar_section -->
+<!-- VAR sidebar_section_raw -->
+ <div class="dbx-box">
+ <div class="dbx-handle">
+ {ADMIN_START}
+
+ {TITLE}
+ {ADMIN_END}
+
+ </div>
+ <div class="dbx-content dbx-content2">
+ <ul><li>
+ {CONTENT}
+ </li></ul>
+ </div>
+ </div>
+<!-- ENDVAR sidebar_section_raw -->
+<!-- VAR sidebar_bottom -->
+ <div class="rectbot">
+ <table border="0" width="100%" cellspacing="0" cellpadding="0" style="font-size: 1px;">
+ <tr>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-bl.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;" class="rectbottop"></td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-br.gif" width="12" height="12" /> </td>
+ </tr>
+ </table>
+ </div>
+<!-- ENDVAR sidebar_bottom -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/printable/simple-footer.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,25 @@
+
+ </div>
+ </td>
+ <td id="main-right"></td>
+ </tr>
+ <tr>
+ <td id="foot-left"></td>
+ <td id="foot-main">
+ {COPYRIGHT}
+ </td>
+ <td id="foot-right"></td>
+ </tr>
+ <tr>
+ <td id="foot-btm-left"></td>
+ <td id="foot-btm"></td>
+ <td id="foot-btm-right"></td>
+ </tr>
+ </table>
+ </td>
+ <td style="width: 10%;"></td>
+ </tr>
+ </table>
+ </body>
+</html>
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/printable/simple-header.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,33 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html>
+ <head>
+ <title>{PAGE_NAME} • {SITE_NAME}</title>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <link rel="stylesheet" href="{SCRIPTPATH}/themes/{THEME_ID}/css-simple/{STYLE_ID}.css" type="text/css" id="mdgCss" />
+ {JS_DYNAMIC_VARS}
+ <!-- This script automatically loads the other 15 JS files -->
+ <script type="text/javascript" src="{SCRIPTPATH}/includes/clientside/static/enano-lib-basic.js"></script>
+ {ADDITIONAL_HEADERS}
+ </head>
+ <body>
+ <table border="0" style="width: 100%; height: 100%;">
+ <tr>
+ <td style="width: 10%;"></td>
+ <td valign="middle">
+ <table id="enano-main" border="0" cellspacing="0" cellpadding="0" style="margin: 0 auto;">
+ <tr>
+ <td id="head-up-left"></td>
+ <td id="head-up"></td>
+ <td id="head-up-right"></td>
+ </tr>
+ <tr>
+ <td id="head-left"></td>
+ <td id="head-main">
+ <h1>{PAGE_NAME}</h1>
+ </td>
+ <td id="head-right"></td>
+ </tr>
+ <tr>
+ <td id="main-left"></td>
+ <td id="main-main">
+ <div id="ajaxEditContainer">
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/printable/theme.cfg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,18 @@
+<?php
+/*
+ * Box Art theme for Enano
+ * Created by dandaman32 - (C) 2006
+ * License: GPL
+ *
+ * This theme is free software; you can redistribute and/or modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This theme is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+global $theme;
+$theme['theme_id'] = 'oxygen';
+$theme['theme_name'] = 'Oxygen Bleu';
+
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/printable/toolbar.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,49 @@
+<!-- Stuff related to toolbars and clickable buttons.
+ Used mostly in the page toolbar on most pages.
+ -->
+
+<!-- VAR toolbar_start -->
+ <div class="toolbar">
+ <ul>
+<!-- ENDVAR toolbar_start -->
+<!-- VAR toolbar_button -->
+ <li>
+ <a title="{TITLE}" {FLAGS}>
+ <img alt="{TITLE}" src="{IMAGE}" />
+ <!-- BEGIN show_title -->
+ <span>{TITLE}</span>
+ <!-- END show_title -->
+ </a>
+ </li>
+<!-- ENDVAR toolbar_button -->
+<!-- VAR toolbar_label -->
+ <li>
+ <span>{TITLE}</span>
+ </li>
+<!-- ENDVAR toolbar_label -->
+<!-- VAR toolbar_end -->
+ </ul>
+ </div>
+<!-- ENDVAR toolbar_end -->
+
+<!-- VAR toolbar_vert_start -->
+ <div class="toolbar_vert">
+ <ul>
+<!-- ENDVAR toolbar_vert_start -->
+<!-- VAR toolbar_vert_button -->
+ <li>
+ <a title="{TITLE}" {FLAGS}>
+ <img alt="{TITLE}" src="{IMAGE}" />
+ <span>{TITLE}</span>
+ </a>
+ </li>
+<!-- ENDVAR toolbar_vert_button -->
+<!-- VAR toolbar_vert_label -->
+ <li>
+ <span>{TITLE}</span>
+ </li>
+<!-- ENDVAR toolbar_vert_label -->
+<!-- VAR toolbar_vert_end -->
+ </ul>
+ </div>
+<!-- ENDVAR toolbar_vert_end -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/stpatty/acledit.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,36 @@
+<!-- VAR acl_field_begin -->
+<div class="tblholder">
+ <table border="0" cellspacing="1" cellpadding="4" style="width: 100%;">
+ <tr>
+ <th></th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('1');">Deny</th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('2');">Disallow</th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('3');">Wiki mode</th>
+ <th style='cursor: pointer;' title="Click to change all columns" onclick="__aclSetAllRadios('4');">Allow</th>
+ </tr>
+<!-- ENDVAR acl_field_begin -->
+<!-- VAR acl_field_item -->
+ <tr>
+ <td class="{ROW_CLASS}">{FIELD_DESC}</td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="1" name="{FIELD_NAME}" {FIELD_DENY_CHECKED} /></td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="2" name="{FIELD_NAME}" {FIELD_DISALLOW_CHECKED} /></td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="3" name="{FIELD_NAME}" {FIELD_WIKIMODE_CHECKED} /></td>
+ <td class="{ROW_CLASS}" style="text-align: center;"><input type="radio" value="4" name="{FIELD_NAME}" {FIELD_ALLOW_CHECKED} /></td>
+ </tr>
+<!-- ENDVAR acl_field_item -->
+<!-- VAR acl_field_end -->
+ <tr>
+ <td colspan="5" class="row3">
+ <p><b>Permission types:</b></p>
+ <ul>
+ <li><b>Allow</b> means that the user is allowed to access the item</li>
+ <li><b>Wiki mode</b> means the user can access the item if wiki mode is active (per-page wiki mode is taken into account)</li>
+ <li><b>Disallow</b> means the user is denied access unless something allows it.</li>
+ <li><b>Deny</b> means that the user is denied access to the item. This setting overrides all other permissions.</li>
+ </ul>
+ </td>
+ </tr>
+ </table>
+</div>
+<!-- ENDVAR acl_field_end -->
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/stpatty/comment.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,51 @@
+<div class="tblholder">
+ <table border="0" width="100%" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2" style="text-align: left;">{DATETIME}</th>
+ </tr>
+ <tr>
+ <td style="width: 120px; height: 100%;" rowspan="4" valign="top" class="row1">
+ <table border="0" width="100%" style="height: 100%;" cellspacing="0" cellpadding="0">
+ <tr>
+ <td valign="top" class="row1">
+ <b>{NAME}</b><br />
+ <small>{USER_LEVEL}</small>
+ </td>
+ </tr>
+ <tr>
+ <td valign="bottom" class="row1">
+ {SEND_PM_LINK} {ADD_BUDDY_LINK}
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td class="row2">
+ <b>Subject:</b> <span id="subject_{ID}">{SUBJECT}</span>
+ </td>
+ </tr>
+ <tr>
+ <td class="row3">
+ <div id="comment_{ID}">{DATA}</div>
+ <!-- BEGIN signature -->
+ <hr style="margin-left: 1em; width: 200px;" />
+ {SIGNATURE}
+ <!-- END signature -->
+ </td>
+ </tr>
+ <!-- BEGIN can_edit -->
+ <tr>
+ <td class="row2">
+ [ {EDIT_LINK} | {DELETE_LINK} ]
+ </td>
+ </tr>
+ <!-- END can_edit -->
+ <!-- BEGIN auth_mod -->
+ <tr>
+ <td class="row1">
+ <b>Moderation options:</b> {MOD_APPROVE_LINK} {MOD_DELETE_LINK}
+ </td>
+ </tr>
+ <!-- END auth_mod -->
+ </table>
+</div>
+<br />
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/stpatty/css-extra/ie-fixes.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,23 @@
+/*
+ * St. Patty theme for Enano
+ * Copyright (C) 2007 Dan Fuhry
+ *
+ * This theme is Free Software, available under the terms of the GNU General Public License. See the file "GPL" included with this
+ * package for details.
+ */
+
+div#bg {
+ background-image: none;
+}
+div#title {
+ background-image: none;
+}
+div#rap {
+ background-image: url(../images/rap-ie.gif);
+}
+div#sidebar ul li a {
+ margin-bottom: -14px;
+}
+div#pagetools a {
+ padding: 4px 3px;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/stpatty/css-simple/shamrock.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,40 @@
+/*
+ * St. Patty theme for Enano
+ * Copyright (C) 2007 Dan Fuhry
+ *
+ * This theme is Free Software, available under the terms of the GNU General Public License. See the file "GPL" included with this
+ * package for details.
+ *
+ * Some ideas - most notably the hatching patterns and floating divs, were taken from Bittersweet <http://templates.arcsin.se/>
+ * No code or graphics were copied.
+ */
+
+div#title h1 {
+ font-size: 16pt;
+ text-align: left;
+ font-weight: normal;
+ margin: 0 10px;
+ padding: 10px;
+}
+
+div#maincontent h2#pagetitle {
+ font-size: 12pt;
+}
+div.footer {
+ min-height: 10px;
+}
+
+table#stretcher {
+ width: 100%;
+ height: 100%;
+}
+
+div#bg {
+ height: 100%;
+}
+
+div#rap {
+ border-top: 1px solid #237000;
+ border-bottom: 1px solid #237000;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/stpatty/css/shamrock.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,426 @@
+/*
+ * St. Patty theme for Enano
+ * Copyright (C) 2007 Dan Fuhry
+ *
+ * This theme is Free Software, available under the terms of the GNU General Public License. See the file "GPL" included with this
+ * package for details.
+ *
+ * Some ideas - most notably the hatching patterns and floating divs, were taken from Bittersweet <http://templates.arcsin.se/>
+ * No code or graphics were copied.
+ */
+
+html,body {
+ margin: 0;
+ padding: 0;
+ height: 100%;
+}
+body {
+ background-color: #101d14;
+ background-image: url(../images/bghatching.gif);
+ background-repeat: repeat;
+ font-family: "Lucida Sans Unicode", sans-serif;
+ font-size: 75%;
+}
+div#bg {
+ min-height: 500px;
+ width: 100%;
+ background-image: url(../images/bgfade.png);
+ background-repeat: repeat-x;
+}
+div#rap {
+ width: 760px;
+ padding: 0 10px;
+ margin: 0 auto;
+ background-image: url(../images/rap.png);
+}
+div#title {
+ margin: 0px;
+ padding: 0px;
+ background-color: #6abd2b;
+ background-image: url(../images/header.gif);
+ background-repeat: repeat-x;
+ border-bottom: 1px solid #237000;
+ vertical-align: middle;
+}
+div#title h1 {
+ margin: 0px 10px 10px 10px;
+ padding-top: 30px;
+ text-align: left;
+}
+div#title h2 {
+ margin: 0px 10px 0px 10px;
+ padding-bottom: 40px;
+ text-align: left;
+}
+div#title img#clover {
+ float: right;
+ margin-right: 10px;
+ margin-top: 10px;
+
+ display: none;
+}
+div.straightaway {
+ clear: both;
+}
+/* Footer */
+div.footer {
+ min-height: 40px;
+ padding: 10px;
+ background-image: url(../images/footer.gif);
+ background-repeat: repeat-x;
+ background-color: #6fba38;
+ color: #FFF;
+}
+div.footer a {
+ color: #B3FF78;
+}
+
+/* Content area */
+div#maincontent {
+ padding: 10px;
+ padding-right: 150px;
+}
+img#ajaxloadicon {
+ margin-top: 10px;
+}
+div#maincontent h2 {
+ color: #53a018;
+ margin: 10px 0;
+ padding: 0;
+ font-size: 16pt;
+}
+div#maincontent p {
+ margin-left: 1em;
+}
+div#maincontent h2#pagetitle {
+ margin: 0;
+ border-bottom: 1px solid #73c038;
+ font-size: 18pt;
+ color: #000000;
+}
+div#maincontent a:link, div#maincontent a:visited {
+ color: #237000;
+ text-decoration: none;
+}
+div#maincontent a:hover {
+ color: #033000;
+ border-bottom: 1px dotted #033000;
+}
+div#maincontent a.wikilink-nonexistent {
+ color: #AA0000;
+}
+div#maincontent a.wikilink-nonexistent:hover {
+ color: #BA2000;
+}
+div#maincontent ul {
+ list-style: square;
+}
+/* Sidebar */
+div#sidebar, div.dbx-box {
+ float: right;
+ width: 135px;
+}
+div#sidebar h4, div.dbx-handle {
+ margin: 0;
+ padding: 0 5px;
+ line-height: 25px;
+ color: #FFF;
+ background-color: #104715;
+ border-bottom: 1px solid #93e058;
+ font-weight: normal;
+ text-align: right;
+ text-transform: lowercase;
+}
+div.dbx-handle {
+ text-align: left;
+ cursor: move;
+}
+div#sidebar ul, .dbx-content ul {
+ margin: 0;
+ padding: 0;
+ list-style: none !important;
+}
+div#sidebar ul li, div.dbx-content ul li {
+ padding: 0;
+}
+div#sidebar ul li a, div.dbx-content ul li a {
+ line-height: 25px;
+ padding: 0 7px;
+ text-decoration: none;
+ color: #000;
+ background-color: #60A745;
+ display: block;
+ border-bottom: 1px solid #93e058;
+}
+div#sidebar ul li a:hover, div.dbx-content ul li a:hover {
+ background-color: #70B755;
+}
+div#sidebar div, div.dbx-content2 {
+ background-color: #60A745;
+ border-bottom: 1px solid #93e058;
+ width: 135px;
+ /* padding: 3px; */
+}
+div#sidebar div ul {
+ margin-left: 2em;
+ list-style: square;
+}
+div#sidebar div ul a {
+ background-color: transparent;
+ display: inline;
+ border-bottom-width: 0px;
+ padding: 0;
+ color: #134000;
+}
+div#sidebar div ul a:hover {
+ background-color: transparent;
+ display: inline;
+ color: #033000;
+ border-bottom: 1px dotted #033000;
+}
+div#maincontent div.dbx-box a {
+ color: #000000;
+}
+div#sidebar div div {
+ background: transparent;
+ border-bottom-width: 0;
+ padding: 0;
+}
+/* Page toolbar */
+/*
+div.pagetools {
+ background-color: #93e058;
+ line-height: 20px;
+ font-size: 75%;
+ padding: 0 5px;
+}
+div.pagetools a {
+ text-decoration: none;
+ padding: 3px;
+ color: #235000;
+}
+div.pagetools a:hover {
+ background-color: #A3F068;
+ height: 20px;
+}
+div.pagetools a.selected {
+ font-weight: bold;
+ background-color: #f4fff7;
+}
+div.pagetools#pagebarpopup {
+ display: none;
+ position: absolute;
+ width: 150px;
+ padding: 0;
+ overflow: hidden;
+}
+div.pagetools#pagebarpopup a {
+ display: block;
+}
+*/
+
+/*
+ * jBox menu system
+ */
+
+div.menu {
+ background-color: #93e058;
+ font-size: 7pt;
+ border-width: 0;
+}
+div.menu a, div.menu div.label {
+ padding: 2.5pt 5px;
+ margin-right: 3px;
+ text-decoration: none;
+ display: block;
+ float: left;
+ color: #235000;
+ border-bottom-width: 0 !important;
+}
+div.menu div.label {
+ color: #002010;
+ cursor: default;
+}
+div.menu span.sep {
+ display: block;
+ float: left;
+ width: 5px;
+}
+div.menu div.multopts {
+ line-height: 17pt;
+}
+div.menu div.multopts a, div.menu div.multopts div.label {
+ float: none;
+ display: inline;
+}
+div.menu a.liteselected, div.menu a.liteselected:hover, div.menu a:hover {
+ color: #235000;
+ background-color: #A3F068;
+}
+div.menu input[type ^="text"], div.menu input[type ^="password"] {
+ border-width: 0;
+ font-size: 9pt;
+ padding: 4px 5px;
+ max-width: 70px;
+ background-color: #A3F068;
+}
+div.menu input[type ^="text"]:hover, div.menu input[type ^="password"]:hover {
+ background-color: #AAF870;
+}
+div.menu input[type ^="text"]:focus, div.menu input[type ^="password"]:focus {
+ background-color: #B3FF78;
+}
+div.menu input[type ^="button"], div.menu input[type ^="submit"] {
+ border-width: 0;
+ font-size: 9pt;
+ padding: 3px 5px;
+ max-width: 70px;
+}
+div.menu a.current, div.menu a.current:hover, div.menu a.selected, div.menu a.selected:hover {
+ color: #000040;
+ background-color: #f4fff7;
+ font-weight: bold;
+}
+div.menu ul {
+ display: none;
+ position: absolute;
+ padding: 0;
+ margin: 0;
+ background-color: #93e058;
+ border-width: 0;
+ min-width: 120px;
+}
+div.menu ul li {
+ list-style: none;
+}
+div.menu ul a {
+ float: none;
+ margin: 0;
+}
+span.menuclear {
+ font-size: 1px;
+ height: 0px;
+ width: 0px;
+ clear: left;
+ line-height: 0px;
+ display: block;
+}
+
+/* Other Enano-related stuff */
+
+/* Tables */
+.tblholder { margin: 10px 0 0 0; padding: 0; border: 1px solid #AAAAAA; background-color: #E8E8E8; }
+div.tblholder td.row1 { padding: 4px; background-color: #E0E0E0; }
+div.tblholder td.row2 { padding: 4px; background-color: #F0F0F0; }
+div.tblholder td.row3 { padding: 4px; background-color: #E8E8E8; }
+div.tblholder th { padding: 4px; background-color: #73c038; font-weight: bold; text-align: center; color: #FFFFFF; }
+div.tblholder th.subhead { padding: 4px; background-color: #93e058; font-weight: bold; text-align: center; color: #FFFFFF; }
+div.tblholder table { background-color: #FFFFFF; width: 100%; }
+
+/* JWS window theming */
+div.jswindow { border: 2px solid #7090B0; border-top: 5px solid #7090B0; padding: 0px; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; display: none; position: absolute; background-color: #FFFFFF; }
+div.titlebar { background-color: #7090B0; color: #FFFFFF; font-family: Trebuchet MS, tahoma, verdana, arial, sans-serif; font-size: 9pt; padding-bottom: 4px; cursor: default; }
+div.titlebar div.closebtn { width: 16px; height: 16px; border: 1px solid #B0D0F0; background-color: #90B0D0; display: block; }
+div.titlebar div.closebtn:hover { width: 16px; height: 16px; border: 1px solid #FFFFFF; background-color: #B0D0F0; display: block; }
+div.titlebar table, div.titlebar td { margin: 0; padding: 0; }
+div.jswindow div.content { padding: 10px; margin: 0; background-color: #FFFFFF; }
+
+/* The Wordpress-like fills behind checkboxes and their labels */
+.catCheck { padding: 3px; }
+.catCheck:hover { padding: 3px; background-color: #F0F0F0; }
+
+/* Information, warning, question, error, and wait boxes */
+div.error-box { background-image: url(../../../images/error.png); background-repeat: no-repeat; background-color: #FFF4F4; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.info-box { background-image: url(../../../images/info.png); background-repeat: no-repeat; background-color: #F4F4FF; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.warning-box { background-image: url(../../../images/warning.png); background-repeat: no-repeat; background-color: #FFFFF4; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.question-box { background-image: url(../../../images/question.png); background-repeat: no-repeat; background-color: #F4FFF4; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+div.wait-box { background-image: url(../../../images/wait.png); background-repeat: no-repeat; background-color: #FFF4FF; border: 1px dashed #406080; padding: 10px 10px 10px 50px; margin: 1em 0 0 1em; min-height: 25px; }
+
+/* Tables where diffs are shown */
+table.diff, td.diff-otitle, td.diff-ntitle { background-color: white; }
+td.diff-addedline { background: #cfc; font-size: smaller; }
+td.diff-deletedline { background: #ffa; font-size: smaller; }
+td.diff-context { background: #eee; font-size: smaller; }
+span.diffchange { color: red; font-weight: bold; }
+
+/* Bordered boxes */
+blockquote, .mdg-comment, .mdg-infobox {
+ background: #FFF;
+ border-bottom: 1px solid #EEE;
+ border-top: 1px solid #EEE;
+ color: #333;
+ display: block;
+ margin-bottom: 1.2em;
+ padding: 6px 12px;
+}
+
+/*
+ * Docking Boxes code (for the sidebar editor)
+ */
+
+/* group container(s) */
+#sbedit {
+ margin: 0;
+ padding: 0;
+ /* position:relative; /* additional outer containers must also have position:relative */
+}
+/* keyboard navigation tooltip */
+.dbx-tooltip {
+ display:block;
+ position:absolute;
+ margin:36px 0 0 125px;
+ width:185px;
+ border:1px solid #000;
+ background:#ffd;
+ color:#000;
+ font:normal normal normal 0.85em tahoma, arial, sans-serif;
+ padding:2px 4px 3px 5px;
+ text-align:left;
+ }
+* html .dbx-tooltip { width:195px; }
+
+/* use CSS2 system colors in CSS2 browsers
+ but not safari, which doesn't support them */
+*[class="dbx-tooltip"]:lang(en) {
+ border-color:InfoText;
+ background:InfoBackground;
+ color:InfoText;
+ font:small-caption;
+ font-weight:normal;
+ }
+/* additional clone styles */
+.dbx-clone {
+ opacity: 0.8;
+}
+.dbx-content ul {
+ margin: 0; padding: 0;
+ list-style: none;
+}
+.dbx-content li a, .dbx-content li a:hover {
+ text-decoration: none;
+}
+.dbx-content2 {
+ margin: 0px 1px 0px 1px;
+}
+
+/* inputs */
+input {
+ color: #555;
+ font: normal 1.1em "Lucida Sans Unicode",sans-serif;
+}
+
+input, select, textarea {
+ background-color: #539018;
+ color: #FFF;
+ padding: 2px;
+ border: 1px solid #EEE;
+}
+
+input:hover {
+ background-color: #73b038;
+}
+
+input:active {
+ background-color: #83c048;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/stpatty/elements.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,40 @@
+<!-- VAR toolbar_button --><a href="{HREF}" {PARENTFLAGS} {FLAGS}>{TEXT}</a>
+<!-- ENDVAR toolbar_button -->
+<!-- VAR toolbar_label --><div class="label">{TEXT}</div>
+<!-- ENDVAR toolbar_label -->
+<!-- VAR toolbar_button_selected --><a href="{HREF}" class="current" {PARENTFLAGS} {FLAGS}>{TEXT}</a>
+<!-- ENDVAR toolbar_button_selected -->
+<!-- VAR toolbar_menu_button --><li><a href="{HREF}" {FLAGS}>{TEXT}</a></li>
+<!-- ENDVAR toolbar_menu_button -->
+<!-- VAR toolbar_menu_block --><li>{HTML}</li>
+<!-- ENDVAR toolbar_menu_block -->
+<!-- VAR sidebar_button --><li><a href="{HREF}" {FLAGS}>{TEXT}</a></li>
+<!-- ENDVAR sidebar_button -->
+<!-- VAR sidebar_raw -->{HTML}
+<!-- ENDVAR sidebar_raw -->
+<!-- VAR sidebar_heading --><h4>{TEXT}</h4>
+<!-- ENDVAR sidebar_heading -->
+<!-- VAR sidebar_top -->
+<!-- ENDVAR sidebar_top -->
+<!-- VAR sidebar_section -->
+ <h4>
+ <!-- BEGIN in_sidebar_admin -->{ADMIN_START}<!-- END in_sidebar_admin -->
+ {TITLE}
+ <!-- BEGIN in_sidebar_admin -->{ADMIN_END}<!-- END in_sidebar_admin -->
+ </h4>
+ <ul>
+ {CONTENT}
+ </ul>
+<!-- ENDVAR sidebar_section -->
+<!-- VAR sidebar_section_raw -->
+ <h4>
+ <!-- BEGIN in_sidebar_admin -->{ADMIN_START}<!-- END in_sidebar_admin -->
+ {TITLE}
+ <!-- BEGIN in_sidebar_admin -->{ADMIN_END}<!-- END in_sidebar_admin -->
+ </h4>
+ <div>
+ {CONTENT}
+ </div>
+<!-- ENDVAR sidebar_section_raw -->
+<!-- VAR sidebar_bottom -->
+<!-- ENDVAR sidebar_bottom -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/stpatty/footer.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,41 @@
+ </div>
+ </div>
+
+ <div class="straightaway"></div>
+ <div class="footer">
+ <!-- We strongly request that you leave the notice below in its place; it helps to attract users to Enano in exchange for providing you
+ with your CMS. Enano is still new; therefore we are looking to attract users, and we feel that this notice will help. If you refuse
+ to include even this tiny little notice, support on the Enano forums may be affected. Thanks guys.
+
+ -Dan
+ -->
+ {COPYRIGHT} • Powered by <a href="<!-- BEGIN stupid_mode -->http://www.enanocms.org/<!-- BEGINELSE stupid_mode -->{CONTENTPATH}{NS_SPECIAL}About_Enano{ADMIN_SID_AUTO}<!-- END stupid_mode -->">Enano</a> | <a href="http://validator.w3.org/check?uri=referer">Valid XHTML 1.1</a> | <a href="http://jigsaw.w3.org/css-validator/validator?uri=referer">Valid CSS</a> | [[Stats]]
+ </div>
+ </div>
+ </div>
+ <div style="display: none;">
+ <h2>Your browser does not support CSS.</h2>
+ <p>If you can see this text, it means that your browser does not support Cascading Style Sheets (CSS). CSS is a fundemental aspect of XHTML, and as a result it is becoming very widely adopted by websites, including this one. You should consider switching to a more modern web browser, such as Mozilla Firefox or Opera 9.</p>
+ <p>Because of this, there are a few minor issues that you may experience while browsing this site, not the least of which is some visual elements below that would normally be hidden in most browsers. Please excuse these minor inconveniences.</p>
+ </div>
+ <div id="root2" class="jswindow" style="display: none;">
+ <div id="tb2" class="titlebar">Change style</div>
+ <div class="content" id="cn2">
+
+ </div>
+ </div>
+ <div id="root3" class="jswindow" style="display: none;">
+ <div id="tb3" class="titlebar">Wiki formatting help</div>
+ <div class="content" id="cn3">
+ Loading...
+ </div>
+ </div>
+ <script type="text/javascript">
+ // This initializes the Javascript runtime when the DOM is ready - not when the page is
+ // done loading, because enano-lib-basic still has to load some 15 other script files
+ enano_init();
+ window.onload = function(e) { };
+ </script>
+ </body>
+</html>
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/stpatty/header.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,102 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html>
+ <head>
+ <title>{PAGE_NAME} • {SITE_NAME}</title>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ {JS_DYNAMIC_VARS}
+ <link rel="stylesheet" type="text/css" href="{SCRIPTPATH}/includes/clientside/css/enano-shared.css" />
+ <link id="mdgCss" rel="stylesheet" type="text/css" href="{SCRIPTPATH}/themes/{THEME_ID}/css/{STYLE_ID}.css" />
+ <!-- This script automatically loads the other 15 JS files -->
+ <script type="text/javascript" src="{SCRIPTPATH}/includes/clientside/static/enano-lib-basic.js"></script>
+ <!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="{SCRIPTPATH}/themes/{THEME_ID}/css-extra/ie-fixes.css" />
+ <![endif]-->
+ <script type="text/javascript">
+ // <![CDATA[
+ function ajaxRenameInline()
+ {
+ // This trick is _so_ vBulletin...
+ elem = document.getElementById('pagetitle');
+ if(!elem) return;
+ elem.style.display = 'none';
+ name = elem.innerHTML;
+ textbox = document.createElement('input');
+ textbox.type = 'text';
+ textbox.value = name;
+ textbox.id = 'pageheading';
+ textbox.size = name.length + 7;
+ textbox.onkeyup = function(e) { if(!e) return; if(e.keyCode == 13) ajaxRenameInlineSave(); if(e.keyCode == 27) ajaxRenameInlineCancel(); };
+ elem.parentNode.insertBefore(textbox, elem);
+ document.onclick = ajaxRenameInlineCancel;
+ }
+ function ajaxRenameInlineSave()
+ {
+ elem1 = document.getElementById('pagetitle');
+ elem2 = document.getElementById('pageheading');
+ if(!elem1 || !elem2) return;
+ value = elem2.value;
+ elem2.parentNode.removeChild(elem2); // just destroy the thing
+ elem1.innerHTML = value;
+ elem1.style.display = 'block';
+ if(!value || value=='') return;
+ ajaxPost(stdAjaxPrefix+'&_mode=rename', 'newtitle='+escape(value), function() {
+ if(ajax.readyState == 4) {
+ alert(ajax.responseText);
+ }
+ });
+ }
+ function ajaxRenameInlineCancel(e)
+ {
+ if ( !e )
+ e = window.event;
+ elem1 = document.getElementById('pagetitle');
+ elem2 = document.getElementById('pageheading');
+ if(!elem1 || !elem2) return;
+ if ( e && e.target )
+ {
+ if(e.target == elem2)
+ return;
+ }
+ //value = elem2.value;
+ elem2.parentNode.removeChild(elem2); // just destroy the thing
+ //elem1.innerHTML = value;
+ elem1.style.display = 'block';
+ document.onclick = null;
+ }
+ // ]]>
+ </script>
+ {ADDITIONAL_HEADERS}
+ </head>
+ <body>
+ <div id="bg">
+ <div id="rap">
+ <div id="title">
+ <img id="clover" src="{SCRIPTPATH}/themes/{THEME_ID}/images/clover.png" alt=" " />
+ <h1>{SITE_NAME}</h1>
+ <h2>{SITE_DESC}</h2>
+ </div>
+ <div class="menu_nojs" id="pagebar_main">
+ <div class="label">Page tools</div>
+ {TOOLBAR}
+ <ul>
+ {TOOLBAR_EXTRAS}
+ </ul>
+ <span class="menuclear"> </span>
+ </div>
+ <div id="sidebar">
+ <!-- BEGIN sidebar_left -->
+ {SIDEBAR_LEFT}
+ <!-- END sidebar_left -->
+ <!-- BEGIN sidebar_right -->
+ <!-- BEGINNOT in_admin -->
+ {SIDEBAR_RIGHT}
+ <!-- END in_admin -->
+ <!-- END sidebar_right -->
+ </div>
+ <div id="maincontent">
+ <div style="float: right;">
+ <img alt=" " src="{SCRIPTPATH}/images/spacer.gif" id="ajaxloadicon" />
+ </div>
+ <h2 id="pagetitle" <!-- BEGIN auth_rename --> ondblclick="ajaxRenameInline();" title="Double-click to rename this page" <!-- END auth_rename -->>{PAGE_NAME}</h2>
+ <div id="ajaxEditContainer">
+
Binary file themes/stpatty/images/bgfade.png has changed
Binary file themes/stpatty/images/bghatching.gif has changed
Binary file themes/stpatty/images/bghatching.png has changed
Binary file themes/stpatty/images/clover.png has changed
Binary file themes/stpatty/images/footer.gif has changed
Binary file themes/stpatty/images/header-hilite.png has changed
Binary file themes/stpatty/images/header.gif has changed
Binary file themes/stpatty/images/rap-ie.gif has changed
Binary file themes/stpatty/images/rap.png has changed
Binary file themes/stpatty/img-sources/bgfade.xcf has changed
Binary file themes/stpatty/img-sources/footer.xcf has changed
Binary file themes/stpatty/img-sources/header.xcf has changed
Binary file themes/stpatty/img-sources/hilite.xcf has changed
Binary file themes/stpatty/img-sources/main-hatching.xcf has changed
Binary file themes/stpatty/img-sources/rap.xcf has changed
Binary file themes/stpatty/img-sources/sidebar-hatching.xcf has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/stpatty/punbb/shamrock.css Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,111 @@
+/****************************************************************/
+/* 1. BACKGROUND AND TEXT COLOURS */
+/****************************************************************/
+
+/* 1.1 Default background colour and text colour */
+
+BODY {BACKGROUND-COLOR: #FFF}
+
+.pun {COLOR: #333}
+
+DIV.box, .pun BLOCKQUOTE, DIV.codebox, #adminconsole FIELDSET TH, .rowodd, .roweven {BACKGROUND-COLOR: #F1F1F1}
+#adminconsole TD, #adminconsole TH {BORDER-COLOR: #F1F1F1}
+
+/* 1. 2 Darker background colours */
+
+TD.tc2, TD.tc3, TD.tcmod, #postpreview, #viewprofile DD, DIV.forminfo,
+#adminconsole FIELDSET TD, DIV.blockmenu DIV.box, #adstats DD {BACKGROUND-COLOR: #DEDFDF}
+
+/* 1.3 Main headers and navigation bar background and text colour */
+
+.pun H2, #brdmenu {BACKGROUND-COLOR: #7090B0; COLOR: #FFF}
+
+/* 1.4 Table header rows */
+
+.pun TH {BACKGROUND-COLOR: #D1D1D1}
+
+/* 1.5 Fieldset legend text colour */
+
+.pun LEGEND {COLOR: #005CB1}
+
+/* 1.6 Highlighted text for various items */
+
+.pun DIV.blockmenu LI.isactive A, #posterror LI STRONG {COLOR: #333}
+
+/****************************************************************/
+/* 2. POST BACKGROUNDS AND TEXT */
+/****************************************************************/
+
+/* 2.1 This is the setup for posts. */
+
+DIV.blockpost DIV.box, DIV.postright, DIV.postfootright {BACKGROUND-COLOR: #DEDFDF}
+DIV.postright, DIV.postfootright {BORDER-LEFT-COLOR: #f1f1f1}
+DIV.postleft, DIV.postfootleft, DIV.blockpost LABEL {BACKGROUND-COLOR: #F1F1F1}
+
+/* 2.2 Background for post headers and text colour for post numbers in viewtopic */
+
+DIV.blockpost H2 {BACKGROUND-COLOR: #7090B0}
+DIV.blockpost H2 SPAN.conr {COLOR: #AABDCD}
+
+/* 2.3 This is the line above the signature in posts. Colour and background should be the same */
+
+.pun HR {BACKGROUND-COLOR: #333; COLOR: #333}
+
+/****************************************************************/
+/* 3. BORDER COLOURS */
+/****************************************************************/
+
+/* 3.1 All external borders */
+
+DIV.box {BORDER-COLOR: #7090B0}
+
+/* 3.2 Makes the top border of posts match the colour used for post headers */
+
+DIV.blockpost DIV.box {BORDER-COLOR: #7090B0 #7090B0 #7090B0}
+
+/* 3.3 Table internal borders. By default TH is same as background so border is invisible */
+
+.pun TD {BORDER-COLOR: #BBCEDE}
+.pun TH {BORDER-COLOR: #D1D1D1}
+
+/* 3.4 Creates the inset border for quote boxes, code boxes and form info boxes */
+
+.pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {BORDER-COLOR: #ACA899 #FFF #FFF #ACA899}
+
+/* 3.5 Gecko's default fieldset borders are really nasty so this gives them a colour
+without interferring with IE's rather nice default */
+
+.pun DIV>FIELDSET {BORDER-COLOR: #ACA899}
+
+/****************************************************************/
+/* 4. LINK COLOURS */
+/****************************************************************/
+
+/* 4.1 This is the default for all links */
+
+.pun A:link, .pun A:visited {COLOR: #7090B0}
+.pun A:hover {COLOR: #90B0D0}
+
+/* 4.2 This is the colour for links in header rows and the navigation bar */
+
+.pun H2 A:link, .pun H2 A:visited, #brdmenu A:link, #brdmenu A:visited {COLOR: #FFF}
+.pun H2 A:hover, #brdmenu A:hover {COLOR: #FFF}
+
+/* 4.3 This is for closed topics and "hot" links */
+
+LI.postreport A:link, LI.postreport A:visited, TR.iclosed TD.tcl A:link, TR.iclosed TD.tcl A:visited {COLOR: #888}
+LI.postreport A:hover, TR.iclosed TD.tcl A:hover {COLOR: #AAA}
+LI.maintenancelink A:link, LI.maintenancelink A:visited {COLOR: #B42000}
+LI.maintenancelink A:hover {COLOR: #B42000}
+
+/****************************************************************/
+/* 5. POST STATUS INDICATORS */
+/****************************************************************/
+
+/* These are the post status indicators which appear at the left of some tables.
+.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and
+.isticky = sticky topics. The default is "icon". By default only .inew is different.*/
+
+DIV.icon {BORDER-COLOR: #E6E6E6 #DEDEDE #DADADA #E2E2E2}
+TR.iredirect DIV.icon {BORDER-COLOR: #76B696 #6EAE8E #5A9A7A #72B292}
+DIV.inew {BORDER-COLOR: #7696B6 #6E8EAE #5A7A9A #7292B2}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/stpatty/sidebar-editor.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,58 @@
+<!-- VAR sidebar_button --><li><a href="javascript:void(0)" {FLAGS}>{TEXT}</a></li>
+<!-- ENDVAR sidebar_button -->
+<!-- VAR sidebar_raw --><li><span style="text-align: center;">{HTML}</span></li>
+<!-- ENDVAR sidebar_raw -->
+<!-- VAR sidebar_top -->
+ <div class="recttop">
+ <table border="0" width="100%" cellspacing="0" cellpadding="0" style="font-size: 1px;">
+ <tr>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-menu-l.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;" class="recttoptop"></td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-menu-r.gif" width="12" height="12" /> </td>
+ </tr>
+ </table>
+ </div>
+<!-- ENDVAR sidebar_top -->
+<!-- VAR sidebar_section -->
+ <div class="dbx-box">
+ <div class="dbx-handle">
+ {ADMIN_START}
+
+ {TITLE}
+ {ADMIN_END}
+
+ </div>
+ <div class="dbx-content">
+ <ul>
+ {CONTENT}
+ </ul>
+ </div>
+ </div>
+<!-- ENDVAR sidebar_section -->
+<!-- VAR sidebar_section_raw -->
+ <div class="dbx-box">
+ <div class="dbx-handle">
+ {ADMIN_START}
+
+ {TITLE}
+ {ADMIN_END}
+
+ </div>
+ <div class="dbx-content dbx-content2">
+ <ul><li>
+ {CONTENT}
+ </li></ul>
+ </div>
+ </div>
+<!-- ENDVAR sidebar_section_raw -->
+<!-- VAR sidebar_bottom -->
+ <div class="rectbot">
+ <table border="0" width="100%" cellspacing="0" cellpadding="0" style="font-size: 1px;">
+ <tr>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-bl.gif" width="12" height="12" /> </td>
+ <td style="margin: 0; padding: 0; height: 12px;" class="rectbottop"></td>
+ <td style="margin: 0; padding: 0; height: 12px;"> <img alt=" " src="{SCRIPTPATH}/themes/oxygen/images/{STYLE_ID}/border-br.gif" width="12" height="12" /> </td>
+ </tr>
+ </table>
+ </div>
+<!-- ENDVAR sidebar_bottom -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/stpatty/simple-footer.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,36 @@
+ </div>
+ </div>
+
+ <div class="straightaway"></div>
+ <div class="footer">
+ <!-- We strongly request that you leave the notice below in its place; it helps to attract users to Enano in exchange for providing you
+ with your CMS. Enano is still new; therefore we are looking to attract users, and we feel that this notice will help. If you refuse
+ to include even this tiny little notice, support on the Enano forums may be affected. Thanks guys.
+
+ -Dan
+ -->
+ Powered by <a href="{CONTENTPATH}{NS_SPECIAL}About_Enano{ADMIN_SID_AUTO}">Enano</a>, copyright © 2006-2007 Dan Fuhry.
+ </div>
+ </div>
+ </td></tr></table>
+ </div>
+ <div style="display: none;">
+ <h2>Your browser does not support CSS.</h2>
+ <p>If you can see this text, it means that your browser does not support Cascading Style Sheets (CSS). CSS is a fundemental aspect of XHTML, and as a result it is becoming very widely adopted by websites, including this one. You should consider switching to a more modern web browser, such as Mozilla Firefox or Opera 9.</p>
+ <p>Because of this, there are a few minor issues that you may experience while browsing this site, not the least of which is some visual elements below that would normally be hidden in most browsers. Please excuse these minor inconveniences.</p>
+ </div>
+ <div id="root2" class="jswindow" style="display: none;">
+ <div id="tb2" class="titlebar">Change style</div>
+ <div class="content" id="cn2">
+
+ </div>
+ </div>
+ <div id="root3" class="jswindow" style="display: none;">
+ <div id="tb3" class="titlebar">Wiki formatting help</div>
+ <div class="content" id="cn3">
+ Loading...
+ </div>
+ </div>
+ </body>
+</html>
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/stpatty/simple-header.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,78 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html>
+ <head>
+ <title>{PAGE_NAME} • {SITE_NAME}</title>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ {JS_DYNAMIC_VARS}
+ <link id="mdgCss" rel="stylesheet" type="text/css" href="{SCRIPTPATH}/themes/{THEME_ID}/css/{STYLE_ID}.css" />
+ <link id="mdgCss" rel="stylesheet" type="text/css" href="{SCRIPTPATH}/themes/{THEME_ID}/css-simple/{STYLE_ID}.css" />
+ <!-- This script automatically loads the other 15 JS files -->
+ <script type="text/javascript" src="{SCRIPTPATH}/includes/clientside/static/enano-lib-basic.js"></script>
+ <!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="{SCRIPTPATH}/themes/{THEME_ID}/css-extra/ie-fixes.css" />
+ <![endif]-->
+ <script type="text/javascript">
+ // <![CDATA[
+ function ajaxRenameInline()
+ {
+ // This trick is _so_ vBulletin...
+ elem = document.getElementById('pagetitle');
+ if(!elem) return;
+ elem.style.display = 'none';
+ name = elem.innerHTML;
+ textbox = document.createElement('input');
+ textbox.type = 'text';
+ textbox.value = name;
+ textbox.id = 'pageheading';
+ textbox.size = name.length + 7;
+ textbox.onkeyup = function(e) { if(!e) return; if(e.keyCode == 13) ajaxRenameInlineSave(); if(e.keyCode == 27) ajaxRenameInlineCancel(); };
+ elem.parentNode.insertBefore(textbox, elem);
+ }
+ function ajaxRenameInlineSave()
+ {
+ elem1 = document.getElementById('pagetitle');
+ elem2 = document.getElementById('pageheading');
+ if(!elem1 || !elem2) return;
+ value = elem2.value;
+ elem2.parentNode.removeChild(elem2); // just destroy the thing
+ elem1.innerHTML = value;
+ elem1.style.display = 'block';
+ if(!value || value=='') return;
+ ajaxPost(stdAjaxPrefix+'&_mode=rename', 'newtitle='+escape(value), function() {
+ if(ajax.readyState == 4) {
+ alert(ajax.responseText);
+ }
+ });
+ }
+ function ajaxRenameInlineCancel()
+ {
+ elem1 = document.getElementById('pagetitle');
+ elem2 = document.getElementById('pageheading');
+ if(!elem1 || !elem2) return;
+ //value = elem2.value;
+ elem2.parentNode.removeChild(elem2); // just destroy the thing
+ //elem1.innerHTML = value;
+ elem1.style.display = 'block';
+ if(!value || value=='') return;
+ }
+ // ]]>
+ </script>
+ {ADDITIONAL_HEADERS}
+ </head>
+ <body>
+ <div id="bg">
+ <table border="0" id="stretcher" cellspacing="0" cellpadding="0"><tr><td valign="middle" id="stretcher-main">
+ <div id="rap">
+ <div id="title">
+ <img id="clover" src="{SCRIPTPATH}/themes/{THEME_ID}/images/clover.png" alt=" " />
+ <h1>{PAGE_NAME}</h1>
+ </div>
+ <div id="sidebar">
+
+ </div>
+ <div id="maincontent">
+ <div style="float: right;">
+ <img alt=" " src="{SCRIPTPATH}/images/spacer.gif" id="ajaxloadicon" />
+ </div>
+ <div id="ajaxEditContainer">
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/stpatty/theme.cfg Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,18 @@
+<?php
+/*
+ * Saint Patty theme for Enano
+ * Created by dandaman32 - (C) 2007
+ * License: GPL
+ *
+ * This theme is free software; you can redistribute and/or modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This theme is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+global $theme;
+$theme['theme_id'] = 'stpatty';
+$theme['theme_name'] = 'St. Patty';
+
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/themes/stpatty/toolbar.tpl Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,49 @@
+<!-- Stuff related to toolbars and clickable buttons.
+ Used mostly in the page toolbar on most pages.
+ -->
+
+<!-- VAR toolbar_start -->
+ <div class="toolbar">
+ <ul>
+<!-- ENDVAR toolbar_start -->
+<!-- VAR toolbar_button -->
+ <li>
+ <a title="{TITLE}" {FLAGS}>
+ <img alt="{TITLE}" src="{IMAGE}" />
+ <!-- BEGIN show_title -->
+ <span>{TITLE}</span>
+ <!-- END show_title -->
+ </a>
+ </li>
+<!-- ENDVAR toolbar_button -->
+<!-- VAR toolbar_label -->
+ <li>
+ <span>{TITLE}</span>
+ </li>
+<!-- ENDVAR toolbar_label -->
+<!-- VAR toolbar_end -->
+ </ul>
+ </div>
+<!-- ENDVAR toolbar_end -->
+
+<!-- VAR toolbar_vert_start -->
+ <div class="toolbar_vert">
+ <ul>
+<!-- ENDVAR toolbar_vert_start -->
+<!-- VAR toolbar_vert_button -->
+ <li>
+ <a title="{TITLE}" {FLAGS}>
+ <img alt="{TITLE}" src="{IMAGE}" />
+ <span>{TITLE}</span>
+ </a>
+ </li>
+<!-- ENDVAR toolbar_vert_button -->
+<!-- VAR toolbar_vert_label -->
+ <li>
+ <span>{TITLE}</span>
+ </li>
+<!-- ENDVAR toolbar_vert_label -->
+<!-- VAR toolbar_vert_end -->
+ </ul>
+ </div>
+<!-- ENDVAR toolbar_vert_end -->
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/upgrade.php Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,671 @@
+<?php
+
+/*
+ * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
+ * Version 1.0 (Banshee)
+ * upgrade.php - upgrade script
+ * Copyright (C) 2006-2007 Dan Fuhry
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+define('IN_ENANO_INSTALL', 'true');
+
+if(!defined('scriptPath')) {
+ $sp = dirname($_SERVER['REQUEST_URI']);
+ if($sp == '/' || $sp == '\\') $sp = '';
+ define('scriptPath', $sp);
+}
+
+if(!defined('contentPath')) {
+ $sp = dirname($_SERVER['REQUEST_URI']);
+ if($sp == '/' || $sp == '\\') $sp = '';
+ define('contentPath', $sp);
+}
+
+global $_starttime, $this_page, $sideinfo;
+$_starttime = microtime(true);
+
+define('ENANO_ROOT', dirname(__FILE__));
+require(ENANO_ROOT.'/includes/constants.php');
+
+if(defined('ENANO_DEBUG'))
+{
+ require_once(ENANO_ROOT.'/includes/debugger/debugConsole.php');
+}
+else
+{
+ function dc_here($m) { return false; }
+ function dc_dump($a, $g) { return false; }
+ function dc_watch($n) { return false; }
+ function dc_start_timer($u) { return false; }
+ function dc_stop_timer($m) { return false; }
+}
+
+// SCRIPT CONFIGURATION
+// Everything related to versions goes here!
+
+// Valid versions to upgrade from
+$valid_versions = Array('1.0b1', '1.0b2', '1.0b3', '1.0b4', '1.0RC1', '1.0RC2');
+
+// Basically a list of dependencies, which should be resolved automatically
+// If, for example, if upgrading from 1.0b1 to 1.0RC1 requires one extra query that would not
+// normally be required (for whatever reason) then you would add a custom version number to the array under key '1.0b1'.
+$deps_list = Array(
+ '1.0b1' => Array('1.0b2'),
+ '1.0b2' => Array('1.0b3'),
+ '1.0b3' => Array('1.0b4'),
+ '1.0b4' => Array('1.0RC1'),
+ '1.0RC1' => Array('1.0RC2')
+ );
+$this_version = '1.0';
+$func_list = Array(
+ '1.0b4' => Array('u_1_0_RC1_update_user_ids', 'u_1_0_RC1_add_admins_to_group', 'u_1_0_RC1_alter_files_table', 'u_1_0_RC1_destroy_session_cookie', 'u_1_0_RC1_set_contact_email', 'u_1_0_RC1_update_page_text'),
+ '1.0RC2' => Array('u_1_0_populate_userpage_comments')
+ );
+
+if(!isset($_GET['mode']))
+{
+ $_GET['mode'] = 'login';
+}
+
+function err($t)
+{
+ global $template;
+ echo $t;
+ $template->footer();
+ exit;
+}
+
+require(ENANO_ROOT.'/includes/template.php');
+
+// Initialize the session manager
+require(ENANO_ROOT.'/includes/functions.php');
+require(ENANO_ROOT.'/includes/dbal.php');
+require(ENANO_ROOT.'/includes/paths.php');
+require(ENANO_ROOT.'/includes/sessions.php');
+require(ENANO_ROOT.'/includes/plugins.php');
+require(ENANO_ROOT.'/includes/rijndael.php');
+require(ENANO_ROOT.'/includes/render.php');
+$db = new mysql();
+$db->connect();
+
+$plugins = new pluginLoader();
+
+if(!defined('ENANO_CONFIG_FETCHED'))
+{
+ // Select and fetch the site configuration
+ $e = $db->sql_query('SELECT config_name, config_value FROM '.table_prefix.'config;');
+ if ( !$e )
+ {
+ $db->_die('Some critical configuration information could not be selected.');
+ }
+ else
+ {
+ define('ENANO_CONFIG_FETCHED', ''); // Used in die_semicritical to figure out whether to call getConfig() or not
+ }
+
+ $enano_config = Array();
+ while($r = $db->fetchrow())
+ {
+ $enano_config[$r['config_name']] = $r['config_value'];
+ }
+ $db->free_result();
+}
+
+$v = enano_version();
+if(in_array($v, Array(false, '', '1.0b3', '1.0b4')))
+{
+ $ul_admin = 2;
+ $ul_mod = 1;
+ $ul_member = 0;
+ $ul_guest = -1;
+}
+else
+{
+ $ul_admin = USER_LEVEL_ADMIN;
+ $ul_mod = USER_LEVEL_MOD;
+ $ul_member = USER_LEVEL_MEMBER;
+ $ul_guest = USER_LEVEL_GUEST;
+}
+
+$_GET['title'] = 'unset';
+
+$session = new sessionManager();
+$paths = new pathManager();
+$session->start();
+
+$template = new template_nodb();
+$template->load_theme('oxygen', 'bleu', false);
+
+$modestrings = Array(
+ 'login' => 'Administrative login',
+ 'welcome' => 'Welcome',
+ 'setversion' => 'Select Enano version',
+ 'confirm' => 'Confirm upgrade',
+ 'upgrade' => 'Database installation',
+ 'finish' => 'Upgrade complete'
+ );
+
+$sideinfo = '';
+$vars = $template->extract_vars('elements.tpl');
+$p = $template->makeParserText($vars['sidebar_button']);
+foreach ( $modestrings as $id => $str )
+{
+ if ( $_GET['mode'] == $id )
+ {
+ $flags = 'style="font-weight: bold; text-decoration: underline;"';
+ $this_page = $str;
+ }
+ else
+ {
+ $flags = '';
+ }
+ $p->assign_vars(Array(
+ 'HREF' => '#',
+ 'FLAGS' => $flags . ' onclick="return false;"',
+ 'TEXT' => $str
+ ));
+ $sideinfo .= $p->run();
+}
+
+$template->init_vars();
+
+function upg_assign_vars($schema)
+{
+ $schema = str_replace('{{SITE_NAME}}', mysql_real_escape_string(getConfig('site_name')), $schema);
+ $schema = str_replace('{{SITE_DESC}}', mysql_real_escape_string(getConfig('site_desc')), $schema);
+ $schema = str_replace('{{COPYRIGHT}}', mysql_real_escape_string(getConfig('copyright_notice')), $schema);
+ $schema = str_replace('{{TABLE_PREFIX}}', table_prefix, $schema);
+ if(getConfig('wiki_mode')=='1') $schema = str_replace('{{WIKI_MODE}}', '1', $schema);
+ else $schema = str_replace('{{WIKI_MODE}}', '0', $schema);
+ return $schema;
+}
+
+/* Version-specific functions */
+
+function u_1_0_RC1_update_user_ids()
+{
+ global $db;
+ // First, make sure this hasn't already been done
+ $q = $db->sql_query('SELECT username FROM '.table_prefix.'users WHERE user_id=1;');
+ if ( !$q )
+ $db->_die();
+ $row = $db->fetchrow();
+ if ( $row['username'] == 'Anonymous' )
+ return true;
+ // Find the first unused user ID
+ $used = Array();
+ $q = $db->sql_query('SELECT user_id FROM '.table_prefix.'users');
+ if ( !$q )
+ $db->_die();
+ $c = false;
+ while ( $row = $db->fetchrow() )
+ {
+ $i = intval($row['user_id']);
+ $used[$i] = true;
+ if ( !isset($used[$i - 1]) && $c )
+ {
+ $id = $i - 1;
+ break;
+ }
+ $c = true;
+ }
+ if ( !isset($id) )
+ $id = $i + 1;
+ $db->free_result();
+
+ $q = $db->sql_query('UPDATE '.table_prefix.'users SET user_id=' . $id . ' WHERE user_id=1;');
+ if(!$q)
+ $db->_die();
+ $q = $db->sql_query('UPDATE '.table_prefix.'users SET user_id=1 WHERE user_id=-1 AND username=\'Anonymous\';');
+ if(!$q)
+ $db->_die();
+
+}
+
+function u_1_0_RC1_add_admins_to_group()
+{
+ global $db;
+ $q = $db->sql_query('SELECT user_id FROM '.table_prefix.'users WHERE user_level=' . USER_LEVEL_ADMIN . ';');
+ if ( !$q )
+ $db->_die();
+ $base = 'INSERT INTO '.table_prefix.'group_members(group_id,user_id) VALUES';
+ $blocks = Array();
+ while ( $row = $db->fetchrow($q) )
+ {
+ $blocks[] = '(2,' . $row['user_id'] . ')';
+ }
+ $blocks = implode(',', $blocks);
+ $sql = $base . $blocks . ';';
+ if(!$db->sql_query($sql))
+ $db->_die();
+}
+
+function u_1_0_RC1_alter_files_table()
+{
+ global $db;
+ if(!is_dir(ENANO_ROOT.'/files'))
+ @mkdir(ENANO_ROOT . '/files');
+ if(!is_dir(ENANO_ROOT.'/files'))
+ die('ERROR: Couldn\'t create files directory');
+ $q = $db->sql_unbuffered_query('SELECT * FROM '.table_prefix.'files;', $db->_conn);
+ if(!$q) $db->_die();
+ while ( $row = $db->fetchrow() )
+ {
+ $file_data = base64_decode($row['data']);
+ $path = ENANO_ROOT . '/files/' . md5( $row['filename'] . '_' . $file_data ) . '_' . $row['time_id'] . $row['file_extension'];
+ @unlink($path);
+ $handle = @fopen($path, 'w');
+ if(!$handle)
+ die('fopen failed');
+ fwrite($handle, $file_data);
+ fclose($handle);
+
+ }
+
+ $q = $db->sql_query('ALTER TABLE '.table_prefix.'files DROP PRIMARY KEY, ADD COLUMN file_id int(12) NOT NULL auto_increment FIRST, ADD PRIMARY KEY (file_id), ADD COLUMN file_key varchar(32) NOT NULL;');
+ if(!$q) $db->_die();
+
+ $list = Array();
+ $q = $db->sql_unbuffered_query('SELECT * FROM '.table_prefix.'files;', $db->_conn);
+ if(!$q) $db->_die();
+ while ( $row = $db->fetchrow($q) )
+ {
+ $file_data = base64_decode($row['data']);
+ $key = md5( $row['filename'] . '_' . $file_data );
+ $list[] = 'UPDATE '.table_prefix.'files SET file_key=\'' . $key . '\' WHERE file_id=' . $row['file_id'] . ';';
+ }
+
+ foreach ( $list as $sql )
+ {
+ if(!$db->sql_query($sql)) $db->_die();
+ }
+
+ if(!$db->sql_query('ALTER TABLE '.table_prefix.'files DROP data')) $db->_die();
+
+}
+
+function u_1_0_RC1_destroy_session_cookie()
+{
+ unset($_COOKIE['sid']);
+ setcookie('sid', '', time()-3600*24, scriptPath);
+ setcookie('sid', '', time()-3600*24, scriptPath.'/');
+}
+
+function u_1_0_RC1_set_contact_email()
+{
+ global $db;
+ $q = $db->sql_query('SELECT email FROM '.table_prefix.'users WHERE user_level='.USER_LEVEL_ADMIN.' ORDER BY user_level ASC LIMIT 1;');
+ if(!$q)
+ $db->_die();
+ $row = $db->fetchrow();
+ setConfig('contact_email', $row['email']);
+}
+
+function u_1_0_RC1_update_page_text()
+{
+ global $db;
+ $q = $db->sql_unbuffered_query('SELECT page_id,namespace,page_text,char_tag FROM '.table_prefix.'page_text');
+ if (!$q)
+ $db->_die();
+
+ $qs = array();
+
+ while ( $row = $db->fetchrow($q) )
+ {
+ $row['page_text'] = str_replace(Array(
+ "{QUOT:{$row['char_tag']}}",
+ "{APOS:{$row['char_tag']}}",
+ "{SLASH:{$row['char_tag']}}"
+ ), Array(
+ '"', "'", '\\'
+ ), $row['page_text']);
+ $qs[] = 'UPDATE '.table_prefix.'page_text SET page_text=\'' . mysql_real_escape_string($row['page_text']) . '\'
+ WHERE page_id=\'' . mysql_real_escape_string($row['page_id']) . '\' AND
+ namespace=\'' . mysql_real_escape_string($row['namespace']) . '\';';
+ }
+
+ foreach($qs as $query)
+ {
+ if(!$db->sql_query($query))
+ $db->_die();
+ }
+}
+
+function u_1_0_populate_userpage_comments()
+{
+ global $db;
+ $q = $db->sql_query('SELECT COUNT(c.comment_id) AS num_comments...');
+ if ( !$q )
+ $db->_die();
+
+ while ( $row = $db->fetchrow() )
+ {
+
+ }
+}
+
+switch($_GET['mode'])
+{
+ case "login":
+ if($session->user_logged_in && $session->user_level >= $ul_admin)
+ {
+ if(isset($_POST['login']))
+ {
+ $session->login_without_crypto($_POST['username'], $_POST['password'], false, $ul_admin);
+ if($session->sid_super)
+ {
+ header('Location: upgrade.php?mode=welcome&auth='.$session->sid_super);
+ exit;
+ }
+ }
+ $template->header();
+ ?>
+ <form action="upgrade.php?mode=login" method="post">
+ <table border="0" style="margin-left: auto; margin-right: auto; margin-top: 5px;" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2">You must re-authenticate to perform this upgrade.</th>
+ </tr>
+ <?php
+ if(isset($_POST['login']))
+ {
+ echo '<tr><td colspan="2"><p style="color: red;">Login failed. Bad password?</p></td></tr>';
+ }
+ ?>
+ <tr>
+ <td>Username:</td><td><input type="text" name="username" size="30" /></td>
+ </tr>
+ <tr>
+ <td>Password:</td><td><input type="password" name="password" size="30" /></td>
+ </tr>
+ <tr>
+ <td colspan="2" style="text-align: center;"><input type="submit" name="login" value="Log in" />
+ </tr>
+ </table>
+ </form>
+ <?php
+ }
+ else
+ {
+ if(isset($_POST['login']))
+ {
+ $result = $session->login_without_crypto($_POST['username'], $_POST['password'], false, $ul_member);
+ if($result == 'success')
+ {
+ header('Location: upgrade.php');
+ exit;
+ }
+ }
+ $template->header();
+ ?>
+ <form action="upgrade.php?mode=login" method="post">
+ <table border="0" style="margin-left: auto; margin-right: auto; margin-top: 5px;" cellspacing="1" cellpadding="4">
+ <tr>
+ <th colspan="2">Please log in to continue with this upgrade.</th>
+ </tr>
+ <?php
+ if(isset($_POST['login']))
+ {
+ echo '<tr><td colspan="2"><p style="color: red;">Login failed. Bad password?</p></td></tr>';
+ }
+ ?>
+ <tr>
+ <td>Username:</td><td><input type="text" name="username" size="30" /></td>
+ </tr>
+ <tr>
+ <td>Password:</td><td><input type="password" name="password" size="30" /></td>
+ </tr>
+ <tr>
+ <td colspan="2" style="text-align: center;"><input type="submit" name="login" value="Log in" />
+ </tr>
+ </table>
+ </form>
+ <?php
+ }
+ break;
+ case "welcome":
+ if(!$session->sid_super) { $template->header(); echo '<p>No admin session found! Please <a href="upgrade.php">restart the upgrade</a>.</p>'; $template->footer(); exit; }
+
+ // Just show a simple welcome page to display version information
+ $template->header();
+ require('config.php');
+
+ ?>
+
+ <div style="text-align: center; margin-top: 10px;">
+ <img alt="[ Enano CMS Project logo ]" src="images/enano-artwork/installer-greeting-blue.png" style="display: block; margin: 0 auto; padding-left: 134px;" />
+ <h2>Welcome to the Enano upgrade wizard</h2>
+ <?php
+ if ( file_exists('./_nightly.php') )
+ {
+ echo '<div class="warning-box" style="text-align: left; margin: 10px auto; display: table; width: 60%;"><b>You are about to upgrade to a NIGHTLY BUILD of Enano.</b><br />Nightly builds CANNOT be re-upgraded to the final release. They may also contain serious flaws, security problems, or extraneous debugging information. Continuing this process on a production site is NOT recommended.</div>';
+ }
+ ?>
+ </div>
+ <div style="display: table; margin: 0 auto;">
+ <p>You are about to upgrade Enano to version <b><?php echo $this_version; ?></b>. Before you continue, please ensure that:</p>
+ <ul>
+ <li>You have completely backed up your database (<b><?php echo "$dbhost:$dbname"; ?></b>)</li>
+ <li>You have backed up the entire Enano directory (<b><?php echo ENANO_ROOT; ?></b>)</li>
+ <li>You have reviewed the release notes for this version, and you<br />are comfortable with any known bugs or issues</li>
+ </ul>
+ </div>
+ <div style="text-align: center; margin-top: 10px;">
+ <form action="upgrade.php?mode=setversion&auth=<?php echo $session->sid_super; ?>" method="post">
+ <input type="submit" value="Continue with upgrade" />
+ </form>
+ </div>
+
+ <?php
+
+ break;
+ case "setversion":
+ if(!$session->sid_super) { $template->header(); echo '<p>No admin session found! Please <a href="upgrade.php">restart the upgrade</a>.</p>'; $template->footer(); exit; }
+ $v = ( function_exists('enano_version') ) ? enano_version() : '';
+ if(!in_array($v, $valid_versions) && $v != '')
+ {
+ $template->header();
+ ?>
+ <p>Your version of Enano (<?php echo $v; ?>) can't be upgraded to this version (<?php echo $this_version; ?>).</p>
+ <?php
+ break;
+ } elseif($v == '') {
+ // OK, we don't know which version he's running. So we'll cheat ;-)
+ $template->header();
+ echo "<form action='upgrade.php?mode=confirm&auth={$session->sid_super}' method='post'>";
+ ?>
+ <p>Sorry, we couldn't detect which version of Enano you're running on your server. Please select which version of Enano you have below, and make absolutely sure that you're correct.</p>
+ <p><select name="version"><?php
+ foreach($valid_versions as $c)
+ {
+ echo "<option value='{$c}'>{$c}</option>";
+ }
+ ?></select></p>
+ <p>
+ <input type="submit" value="Continue" />
+ </p>
+ <?php
+ echo `</form>`;
+ break;
+ } else {
+ header('Location: upgrade.php?mode=confirm&auth='.$session->sid_super);
+ }
+ break;
+ case "confirm":
+ $enano_version = ( isset($_POST['version']) ) ? $_POST['version'] : enano_version();
+
+ $template->header();
+ if(!$session->sid_super) { echo '<p>No admin session found! Please <a href="upgrade.php">restart the upgrade</a>.</p>'; $template->footer(); exit; }
+ ?>
+ <form action="upgrade.php?mode=upgrade&auth=<?php echo $session->sid_super; ?>" method="post">
+ <table border="0" style="margin-left: auto; margin-right: auto; margin-top: 5px;" cellspacing="1" cellpadding="4">
+ <tr>
+ <td colspan="2"><p><b>Are you sure you want to perform this upgrade?</b></p><p>You can still cancel the upgrade process now. If<br />the upgrade fails, you will need to roll back<br />any actions made using manual SQL queries.</p><p><b>Please clear your browser cache or<br />shift-reload after the upgrade.</b><br />If you fail to do so, some page elements may<br />be broken.</td>
+ </tr>
+ <tr>
+ <td colspan="2" style="text-align: center;">
+ <input type="hidden" name="enano_version" value="<?php echo $enano_version; ?>" />
+ <input type="submit" name="doit" value="Upgrade Enano!" />
+ </td>
+ </tr>
+ </table>
+ </form>
+ <?php
+ break;
+ case "upgrade":
+ $template->header();
+ if(!$session->sid_super) { echo '<p>No admin session found! Please <a href="upgrade.php">restart the upgrade</a>.</p>'; $template->footer(); exit; }
+ if(!isset($_POST['enano_version'])) { echo '<p>Can\'t find the version information on the POST query, are you trying to do this upgrade directly? Please <a href="upgrade.php">restart the upgrade</a>.</p>'; break; }
+ $enano_version = $_POST['enano_version'];
+ echo '<p>Preparing for schema execution...';
+ // Build an array of queries
+ $schema = file_get_contents('upgrade.sql');
+
+ // Strip out and process version blocks
+ preg_match_all('#---BEGIN ([0-9A-z\.\-]*?)---'."\n".'(.*?)'."\n".'---END \\1---#is', $schema, $matches);
+
+ $from_list =& $matches[1];
+ $query_list =& $matches[2];
+
+ foreach($matches[0] as $m)
+ {
+ $schema = str_replace($m, '', $schema);
+ }
+ $schema = explode("\n", $schema);
+ foreach($schema as $k => $q)
+ {
+ if(substr($q, 0, 2) == '--' || $q == '')
+ {
+ unset($schema[$k]);
+ //die('<pre>'.htmlspecialchars(print_r($schema, true)).'</pre>');
+ }
+ else
+ {
+ $schema[$k] = upg_assign_vars($schema[$k]);
+ }
+ }
+
+ foreach($query_list as $k => $q)
+ {
+ $query_list[$k] = explode("\n", $query_list[$k]);
+ foreach($query_list[$k] as $i => $s)
+ {
+ $tq =& $query_list[$k][$i];
+ if(substr($s, 0, 2) == '--' || $s == '')
+ {
+ unset($query_list[$k][$i]);
+ //die('<pre>'.htmlspecialchars(print_r($schema, true)).'</pre>');
+ }
+ else
+ {
+ $query_list[$k][$i] = upg_assign_vars($query_list[$k][$i]);
+ }
+ }
+ $query_list[$k] = array_values($query_list[$k]);
+ }
+
+ $assoc_list = Array();
+
+ foreach($from_list as $i => $v)
+ {
+ $assoc_list[$v] = $query_list[$i];
+ }
+
+ $schema = array_values($schema);
+
+ $deps_resolved = false;
+ $installing_versions = Array($enano_version);
+
+ while(true)
+ {
+ $v = array_keys($deps_list);
+ foreach($v as $i => $ver)
+ {
+ if(in_array($ver, $installing_versions))
+ {
+ // $ver is on the list of versions to be installed. Add its dependencies to the list of versions to install.
+ foreach($deps_list[$ver] as $dep)
+ {
+ if(!in_array($dep, $installing_versions))
+ {
+ $installing_versions[] = $dep;
+ }
+ }
+ }
+ if($i == count($deps_list) - 1)
+ {
+ break 2;
+ }
+ }
+ }
+
+ foreach($installing_versions as $this_ver)
+ {
+ $schema = array_merge($schema, $assoc_list[$this_ver]);
+ }
+
+ // Time for some proper SQL syntax!
+ // Also check queries for so-called injection attempts to make
+ // sure that it doesn't fail during the upgrade process and
+ // leave the user with a half-upgraded database
+ foreach($schema as $s => $q)
+ {
+ if(substr($q, strlen($q)-1, 1) != ';')
+ {
+ $schema[$s] .= ';';
+ }
+ if ( !$db->check_query($schema[$s]) )
+ {
+ // Uh-oh, the check failed, bail out
+ // The DBAL runs sanity checks on all queries for safety,
+ // so if the check fails in mid-upgrade we are in deep
+ // dodo doo-doo.
+ echo 'Query failed sanity check, this should never happen and is a bug.</p><p>Query was:</p><pre>'.$schema[$s].'</pre>';
+ break 2;
+ }
+ }
+
+ $schema = array_values($schema);
+
+ // Used extensively for debugging
+ // echo '<pre>'.htmlspecialchars(print_r($schema, true)).'</pre>';
+ // break;
+
+ echo 'done!<br />Executing upgrade schema...';
+
+ // OK, do the loop, baby!!!
+ foreach($schema as $q)
+ {
+ $r = $db->sql_query($q);
+ if(!$r)
+ {
+ echo $db->get_error();
+ break 2;
+ }
+ }
+
+ // Call any custom functions
+ foreach ( $installing_versions as $ver )
+ {
+ if ( isset($func_list[$ver]) )
+ {
+ foreach($func_list[$ver] as $function)
+ {
+ @call_user_func($function);
+ }
+ }
+ }
+
+ echo 'done!</p>';
+ echo '<p>You will be redirected shortly. If you aren\'t redirected, <a href="index.php">click here</a>.</p>
+ <script type="text/javascript">setTimeout("window.location=\'index.php\'", 2000)</script>';
+ break;
+}
+$template->footer();
+
+?>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/upgrade.sql Wed Jun 13 16:03:00 2007 -0400
@@ -0,0 +1,84 @@
+-- Enano CMS - upgrade SQL
+-- Variables are in the format {{VAR_NAME}}
+-- ALL NON-SQL LINES, even otherwise blank lines, must start with "--" or they will get sent to MySQL!
+-- Common tasks (version numbers)
+DELETE FROM {{TABLE_PREFIX}}config WHERE config_name='enano_version' OR config_name='enano_beta_version' OR config_name='enano_alpha_version' OR config_name='enano_rc_version';
+INSERT INTO {{TABLE_PREFIX}}config (config_name, config_value) VALUES( 'enano_version', '1.0' );
+---BEGIN 1.0RC2---
+-- Add the "Moderators" group
+UPDATE {{TABLE_PREFIX}}groups SET group_id=9999 WHERE group_id=3;
+UPDATE {{TABLE_PREFIX}}group_members SET group_id=9999 WHERE group_id=3;
+ALTER TABLE {{TABLE_PREFIX}}groups ADD COLUMN system_group tinyint(1) NOT NULL DEFAULT 0;
+UPDATE {{TABLE_PREFIX}}groups SET system_group=1 WHERE group_id=1 OR group_id=2;
+INSERT INTO {{TABLE_PREFIX}}groups(group_id,group_name,group_type,system_group) VALUES(3, 'Moderators', 3, 1);
+-- ...and add the associated ACL rule
+INSERT INTO {{TABLE_PREFIX}}acl(target_type,target_id,page_id,namespace,rules) VALUES(1,3,NULL,NULL,'read=4;post_comments=4;edit_comments=4;edit_page=4;view_source=4;mod_comments=4;history_view=4;history_rollback=4;history_rollback_extra=4;protect=4;rename=3;clear_logs=2;vote_delete=4;vote_reset=4;delete_page=4;set_wiki_mode=2;password_set=2;password_reset=2;mod_misc=2;edit_cat=4;even_when_protected=4;upload_files=2;upload_new_version=3;create_page=3;php_in_pages=2;edit_acl=2;');
+-- Create table with extra user information
+CREATE TABLE users_extra( user_id mediumint(8) NOT NULL, user_aim varchar(63) default NULL, user_yahoo varchar(63) default NULL, user_msn varchar(255) default NULL, user_xmpp varchar(255) default NULL, user_homepage text, user_location text, user_job text, user_hobbies text, email_public tinyint(1) NOT NULL default '0', userpage_comments smallint(5) NOT NULL default '0', PRIMARY KEY ( user_id ) );
+---END 1.0RC2---
+---BEGIN 1.0RC1---
+-- Not too many DB changes in this release - that's a good sign ;-)
+ALTER TABLE {{TABLE_PREFIX}}search_index MODIFY COLUMN word varbinary(64) NOT NULL;
+CREATE FULLTEXT INDEX {{TABLE_PREFIX}}page_search_idx ON {{TABLE_PREFIX}}page_text(page_id,namespace,page_text);
+UPDATE {{TABLE_PREFIX}}users SET user_level=3 WHERE user_level=2;
+UPDATE {{TABLE_PREFIX}}sidebar SET block_content='[[$NS_USER$$USERNAME$|User page]]\n[[$NS_SPECIAL$Contributions/$USERNAME$|My Contributions]]\n{if user_logged_in}\n[[$NS_SPECIAL$Preferences|Preferences]]\n[[$NS_SPECIAL$PrivateMessages|Private messages]]\n[[$NS_SPECIAL$Usergroups|Group control panel]]\n$THEME_LINK$\n{/if}\n{if user_logged_in}\n$LOGOUT_LINK$\n{else}\n[[$NS_SPECIAL$Register|Create an account]]\n$LOGIN_LINK$\n[[$NS_SPECIAL$Login/$NS_SPECIAL$PrivateMessages|Private messages]]\n{/if}',block_name='$USERNAME$' WHERE block_name='$USERNAME' AND item_id=3;
+---END 1.0RC1---
+---BEGIN 1.0b4---
+CREATE TABLE {{TABLE_PREFIX}}hits( hit_id bigint(20) NOT NULL auto_increment, username varchar(63) NOT NULL, time int(12) NOT NULL DEFAULT 0, page_id varchar(63), namespace varchar(63), PRIMARY KEY ( hit_id ) );
+CREATE TABLE {{TABLE_PREFIX}}search_index( word binary(32) NOT NULL, page_names text, PRIMARY KEY ( word ) );
+CREATE TABLE {{TABLE_PREFIX}}search_cache( search_id int(15) NOT NULL auto_increment, search_time int(11) NOT NULL, query text, results longblob, PRIMARY KEY ( search_id ));
+CREATE TABLE {{TABLE_PREFIX}}acl( rule_id int(12) UNSIGNED NOT NULL auto_increment, target_type tinyint(1) UNSIGNED NOT NULL, target_id int(12) UNSIGNED NOT NULL, page_id varchar(255), namespace varchar(24), rules text, PRIMARY KEY ( rule_id ) );
+ALTER TABLE {{TABLE_PREFIX}}users ADD COLUMN old_encryption tinyint(1) NOT NULL DEFAULT 0;
+ALTER TABLE {{TABLE_PREFIX}}users MODIFY COLUMN password text;
+ALTER TABLE {{TABLE_PREFIX}}users ADD COLUMN temp_password text, ADD COLUMN temp_password_time int(12) NOT NULL DEFAULT 0;
+UPDATE {{TABLE_PREFIX}}users SET old_encryption=1;
+UPDATE {{TABLE_PREFIX}}users SET user_level=9 WHERE user_level=2;
+UPDATE {{TABLE_PREFIX}}users SET user_level=5 WHERE user_level=1;
+UPDATE {{TABLE_PREFIX}}users SET user_level=2 WHERE user_level=0;
+UPDATE {{TABLE_PREFIX}}users SET user_level=1 WHERE user_level=-1;
+-- Group system
+CREATE TABLE {{TABLE_PREFIX}}groups( group_id mediumint(5) UNSIGNED NOT NULL auto_increment, group_name varchar(64), group_type tinyint(1) NOT NULL DEFAULT 1, PRIMARY KEY ( group_id ) );
+CREATE TABLE {{TABLE_PREFIX}}group_members( member_id int(12) UNSIGNED NOT NULL auto_increment, group_id mediumint(5) UNSIGNED NOT NULL, user_id int(12) NOT NULL, is_mod tinyint(1) NOT NULL DEFAULT 0, pending tinyint(1) NOT NULL DEFAULT 0, PRIMARY KEY ( member_id ) );
+INSERT INTO {{TABLE_PREFIX}}groups(group_id,group_name,group_type) VALUES(1, 'Everyone', 3),(2,'Administrators',3);
+-- Sidebar updates
+DELETE FROM {{TABLE_PREFIX}}sidebar WHERE item_id=5 AND block_name='Links';
+INSERT INTO {{TABLE_PREFIX}}sidebar(item_order, sidebar_id, block_name, block_type, block_content) VALUES(2, 2, 'Links', 4, 'Links');
+UPDATE {{TABLE_PREFIX}}sidebar SET block_content='[[$NS_USER$$USERNAME$|User page]]\n[[$NS_SPECIAL$Contributions/$USERNAME$|My Contributions]]\n{if user_logged_in}\n[[$NS_SPECIAL$Preferences|Preferences]]\n[[$NS_SPECIAL$PrivateMessages|Private messages]]\n[[$NS_SPECIAL$Usergroups|Group control panel]]\n$THEME_LINK$\n{/if}\n{if user_logged_in}\n$LOGOUT_LINK$\n{else}\n[[$NS_SPECIAL$Register|Create an account]]\n[[$NS_SPECIAL$Login/$PAGE_URLNAME$|Log in]]\n[[$NS_SPECIAL$Login/$NS_SPECIAL$PrivateMessages|Private messages]]\n{/if}' WHERE block_name='$USERNAME$' AND item_id=3;
+UPDATE {{TABLE_PREFIX}}sidebar SET block_name='$USERNAME$' WHERE block_name='$USERNAME';
+-- Set the default theme
+INSERT INTO {{TABLE_PREFIX}}themes(theme_id,theme_name,theme_order,default_style,enabled) VALUES('stpatty', 'St. Patty', 1, 'shamrock.css', 1);
+UPDATE {{TABLE_PREFIX}}themes SET theme_order=2 WHERE theme_id='oxygen';
+UPDATE {{TABLE_PREFIX}}users SET theme='stpatty',style='shamrock';
+---END 1.0b4---
+---BEGIN 1.0b3---
+INSERT INTO {{TABLE_PREFIX}}config(config_name, config_value) VALUES( 'allowed_mime_types', 'cbf:len=168;crc=c3dcad3f;data=0[1],1[4],0[3],1[1],0[2],1[1],0[11],1[1],0[7],1[1],0[9],1[1],0[6],1[3],0[10],1[1],0[2],1[2],0[1],1[1],0[1],1[2],0[6],1[3],0[1],1[1],0[2],1[4],0[1],1[2],0[3],1[1],0[4],1[2],0[26],1[5],0[6],1[2],0[2],1[1],0[4],1[1],0[10],1[2],0[1],1[1],0[6]|end' );
+---END 1.0b3---
+---BEGIN 1.0b2---
+-- 10/1: Removed alterations to users table, moved to upgrade.php, to allow the session manager to work
+CREATE TABLE {{TABLE_PREFIX}}privmsgs( message_id int(15) NOT NULL auto_increment, message_from varchar(63), message_to varchar(255), date int(12), subject varchar(63), message_text text, folder_name varchar(63), PRIMARY KEY (message_id) );
+CREATE TABLE {{TABLE_PREFIX}}buddies( buddy_id int(15) NOT NULL auto_increment, user_id mediumint(8), buddy_user_id mediumint(8), is_friend tinyint(1) NOT NULL DEFAULT 1, PRIMARY KEY (buddy_id) );
+-- Fill 'em up with a basic sidebar - sometime there will be a migration script that will convert the old sidebar format to the new
+CREATE TABLE {{TABLE_PREFIX}}sidebar( item_id smallint(3) NOT NULL auto_increment, item_order smallint(3) NOT NULL DEFAULT 0, sidebar_id smallint(3) NOT NULL DEFAULT 1, block_name varchar(63) NOT NULL, block_type tinyint(1) NOT NULL DEFAULT 0, item_enabled tinyint(1) NOT NULL DEFAULT 1, block_content text, PRIMARY KEY ( item_id ));
+INSERT INTO {{TABLE_PREFIX}}sidebar(item_id, item_order, sidebar_id, block_name, block_type, block_content) VALUES (1, 1, 1, 'Navigation', 1, '[[Main Page|Home]]'),(2, 2, 1, 'Tools', 1, '[[Special:CreatePage|Create a page]]\n[[Special:UploadFile|Upload file]]\n[[Special:SpecialPages|Special pages]]\n{if auth_admin}\n[[Special:EditSidebar|Edit the sidebar]]\n[[Special:Administration|Administration]]\n{/if}'),(3, 3, 1, '$USERNAME$', 1, '[[User:$USERNAME$|User page]]\n[[Special:Contributions/$USERNAME$|My Contributions]]\n{if user_logged_in}\n[[Special:Preferences|Preferences]]\n[[Special:PrivateMessages|Private messages]]\n$THEME_LINK$\n{/if}\n{if user_logged_in}\n$LOGOUT_LINK$\n{else}\n[[Special:Register|Create an account]]\n[[Special:Login/$PAGE_URLNAME$|Log in]]\n[[Special:Login/Special:PrivateMessages|Private messages]]\n{/if}'),(4, 4, 1, 'Search', 1, '<div class="slideblock2" style="padding: 3px;"><form action="$SCRIPTPATH$/Special:Search" method="get" style="padding: 0; margin: 0;"><p><input name="q" alt="Search box" type="text" size="10" style="width: 70%" /> <input type="submit" value="Go" style="width: 20%" /></p></form></div>'),(5, 2, 2, 'Links', 3, '$ob = Array();\nif(getConfig(''sflogo_enabled'')==''1'')\n{\n $ob[] = ''<a style="text-align: center;" href="http://sourceforge.net/" onclick="window.open(this.href);return false;"><img border="0" alt="SourceForge.net Logo" src="http://sflogo.sourceforge.net/sflogo.php?group_id=''.getConfig(''sflogo_groupid'').''&type=''.getConfig(''sflogo_type'').''" /></a>'';\n}\nif(getConfig(''w3c_v32'') ==''1'') $ob[] = ''<a style="text-align: center;" href="http://validator.w3.org/check?uri=referer" onclick="window.open(this.href);return false;"><img style="border: 0px solid #FFFFFF;" alt="Valid HTML 3.2" src="http://validator.w3.org/images/v32" /></a>'';\nif(getConfig(''w3c_v40'') ==''1'') $ob[] = ''<a style="text-align: center;" href="http://validator.w3.org/check?uri=referer" onclick="window.open(this.href);return false;"><img style="border: 0px solid #FFFFFF;" alt="Valid HTML 4.0" src="http://validator.w3.org/images/v40" /></a>'';\nif(getConfig(''w3c_v401'') ==''1'') $ob[] = ''<a style="text-align: center;" href="http://validator.w3.org/check?uri=referer" onclick="window.open(this.href);return false;"><img style="border: 0px solid #FFFFFF;" alt="Valid HTML 4.01" src="http://validator.w3.org/images/v401" /></a>'';\nif(getConfig(''w3c_vxhtml10'')==''1'') $ob[] = ''<a style="text-align: center;" href="http://validator.w3.org/check?uri=referer" onclick="window.open(this.href);return false;"><img style="border: 0px solid #FFFFFF;" alt="Valid XHTML 1.0" src="http://validator.w3.org/images/vxhtml10" /></a>'';\nif(getConfig(''w3c_vxhtml11'')==''1'') $ob[] = ''<a style="text-align: center;" href="http://validator.w3.org/check?uri=referer" onclick="window.open(this.href);return false;"><img style="border: 0px solid #FFFFFF;" alt="Valid XHTML 1.1" src="http://validator.w3.org/images/vxhtml11" /></a>'';\nif(getConfig(''w3c_vcss'') ==''1'') $ob[] = ''<a style="text-align: center;" href="http://validator.w3.org/check?uri=referer" onclick="window.open(this.href);return false;"><img style="border: 0px solid #FFFFFF;" alt="Valid CSS" src="http://validator.w3.org/images/vcss" /></a>'';\nif(getConfig(''dbd_button'') ==''1'') $ob[] = ''<a style="text-align: center;" href="http://www.defectivebydesign.org/join/button" onclick="window.open(this.href);return false;"><img style="border: 0px solid #FFFFFF;" alt="DRM technology restricts what you can do with your computer" src="http://defectivebydesign.org/sites/nodrm.civicactions.net/files/images/dbd_sm_btn.gif" /><br /><small>Protect your freedom >></small></a>'';\nif(count($ob) > 0) echo ''<div style="text-align: center; padding: 5px;">''.implode(''<br />'', $ob).''</div>'';');
+ALTER TABLE {{TABLE_PREFIX}}banlist ADD COLUMN reason text;
+-- Here's a tricky one for ya :-/ what we're trying to do is add an auto-increment primary key to a table, this was a first for me but it seemed to work, tested on MySQL 4.1.20
+ALTER TABLE {{TABLE_PREFIX}}comments ADD COLUMN comment_id int(12) NOT NULL auto_increment FIRST, ADD PRIMARY KEY ( comment_id );
+-- Session manager stuff
+ALTER TABLE {{TABLE_PREFIX}}themes ADD COLUMN default_style varchar(63) NOT NULL DEFAULT '';
+ALTER TABLE {{TABLE_PREFIX}}users ADD COLUMN signature text;
+ALTER TABLE {{TABLE_PREFIX}}users ADD COLUMN reg_time int(11) NOT NULL DEFAULT 0;
+ALTER TABLE {{TABLE_PREFIX}}users ADD COLUMN account_active tinyint(1) NOT NULL DEFAULT 0;
+ALTER TABLE {{TABLE_PREFIX}}users ADD COLUMN activation_key varchar(40) NOT NULL DEFAULT 0;
+UPDATE {{TABLE_PREFIX}}users SET account_active=1;
+UPDATE {{TABLE_PREFIX}}themes SET default_style='bleu.css' WHERE theme_id='oxygen';
+---END 1.0b2---
+---BEGIN 1.0b1---
+CREATE TABLE {{TABLE_PREFIX}}files( time_id int(12) NOT NULL, page_id varchar(63) NOT NULL, filename varchar(127), size bigint(15) NOT NULL, mimetype varchar(63), file_extension varchar(8), data longblob, PRIMARY KEY (time_id) );
+ALTER TABLE {{TABLE_PREFIX}}pages MODIFY COLUMN protected tinyint(1) NOT NULL DEFAULT 0;
+ALTER TABLE {{TABLE_PREFIX}}pages ADD COLUMN wiki_mode tinyint(1) NOT NULL DEFAULT 2 AFTER protected;
+ALTER TABLE {{TABLE_PREFIX}}pages ADD COLUMN password varchar(40) NOT NULL DEFAULT '' AFTER wiki_mode;
+ALTER TABLE {{TABLE_PREFIX}}comments ADD COLUMN user_id mediumint(8) NOT NULL DEFAULT -1;
+ALTER TABLE {{TABLE_PREFIX}}comments ADD COLUMN time int(12) NOT NULL default 0;
+UPDATE {{TABLE_PREFIX}}pages SET wiki_mode=2;
+UPDATE {{TABLE_PREFIX}}comments SET user_id=-1;
+---END 1.0b1---