New version 0.4.0 of the reports plugin 39/head
authorLars Vogdt <lrupp@users.noreply.github.com>
Sun, 11 Aug 2019 09:51:58 +0000 (11:51 +0200)
committerLars Vogdt <lrupp@users.noreply.github.com>
Sun, 11 Aug 2019 09:51:58 +0000 (11:51 +0200)
17 files changed:
reports/LICENSE [new file with mode: 0644]
reports/README.md [new file with mode: 0644]
reports/reports/README.md [new file with mode: 0644]
reports/reports/css/style.css [new file with mode: 0755]
reports/reports/custom-report.php [new file with mode: 0644]
reports/reports/js/jquery-latest.js [new file with mode: 0644]
reports/reports/js/jquery.tablesorter.js [new file with mode: 0644]
reports/reports/js/picnet.table.filter.min.js [new file with mode: 0644]
reports/reports/js/saveFormValues.js [new file with mode: 0644]
reports/reports/pix/asc.gif [new file with mode: 0644]
reports/reports/pix/bg.gif [new file with mode: 0644]
reports/reports/pix/desc.gif [new file with mode: 0644]
reports/reports/pix/network.png [new file with mode: 0644]
reports/reports/pix/server.png [new file with mode: 0644]
reports/reports/pix/vm.png [new file with mode: 0644]
reports/reports/plugin.php [new file with mode: 0644]
reports/reports/reportExtensionLib.php [new file with mode: 0644]

diff --git a/reports/LICENSE b/reports/LICENSE
new file mode 100644 (file)
index 0000000..d159169
--- /dev/null
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       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.
+
+                    GNU GENERAL PUBLIC LICENSE
+   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:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) 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.
+
+    c) 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:
+
+    a) 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,
+
+    b) 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,
+
+    c) 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.
diff --git a/reports/README.md b/reports/README.md
new file mode 100644 (file)
index 0000000..466bf57
--- /dev/null
@@ -0,0 +1,55 @@
+# racktables-reports
+
+This is an additional plugin for RackTables, that creates Custom Reports Tabs right in the Reports page. It's based on the work of  
+
+Sebastian Mogilowski <sebastian@mogilowski.net> (Website and HowTo: http://www.mogilowski.net/projects/racktables )
+
+The original plugin was rewritten to follow the new [plugin standards](https://wiki.racktables.org/index.php/Plugins) for RackTables.
+
+## Other changes for version 0.4.0:
+* Unify Server, Switch and Virtual Machine Reports (maintaining only one function for all)
+* allow users to customize the path to the CSS and JS files via config variables ('Configuration' => 'User interface')
+* always show: Name, MAC(s), IPv4 and IPv6 addresses, comment and contact information
+* additionally show:
+  * Type, asset no., location, OEM S/N, HW expire date and OS for servers
+  * Type, asset no., location, OEM S/N, HW expire date and OS version for switches
+  * OS and Hypervisor (container) for virtual machines
+* show MAC addresses also for switches (configurable via config variable 'REPORTS_SHOW_MAC_FOR_SWITCHES')
+* enhance CSV filename with the short form of the export (server,switches,vm or custom => export_server_$date.csv)
+* create 'mailto' links, if the contact is an Email address
+
+## INSTALL
+
+1) Copy the files in the /reports/ folder to your RackTables plugins installation ( _/path/to/racktables/plugins/_ ).
+
+2) Copy the CSS and JS and image files to the corresponding folders:
+```
+   mkdir -p '/path/to/racktables/wwwroot/{css,js,pix}/report/'
+   cp -v 'css/style.css' '/path/to/racktables/wwwroot/css/report/style.css'
+   cp -v "js/*" '/path/to/racktables/wwwroot/js/report/'
+   cp -v "pix/*" '/path/to/racktables/wwwroot/pix/report/'
+```
+
+3) Activate the plugin via the _Configuration_ => _Plugins_ menu.
+
+4) Depending on where you copied the CSS and JS files in step 2, you might want to adjust the configuration variables in _'Configuration'_ => _'User interface'_:
+```
+   REPORTS_CSS_PATH => defaults to 'css/report' (NO trailing slashes)
+   REPORTS_JS_PATH  => defaults to 'js/report'  (NO trailing slashes)
+```
+
+5) You might also want to enable/disable the MAC(s) column for your switch report via _'Configuration'_ => _'User interface'_:
+```
+   REPORTS_SHOW_MAC_FOR_SWITCHES => defaults to 'yes'
+```
+
+## USAGE
+
+Login into RackTables and go to "Reports".
+
+Now you find "Custom", "Server", "Switches" and "Virtual machines" in the report menu.
+
+Sort multiple columns simultaneously by holding down the shift key and clicking a second, third or even fourth column header! 
+
+Save your custom report by supplying a name in the "Save:" field and click on the "Ok" button. Restoring your custom report criteria: simply click on the link in the form with the name you provided. 
+
diff --git a/reports/reports/README.md b/reports/reports/README.md
new file mode 100644 (file)
index 0000000..1356e43
--- /dev/null
@@ -0,0 +1,43 @@
+# Racktables custom report plugin                                                                                                                                          
+This is an additional plugin for RackTables, based on the work of 
+Mogilowski Sebastian <sebastian@mogilowski.net>
+
+
+## Installation
+
+1) Copy the files in the /reports/ folder to your RackTables plugins installation ( _/path/to/racktables/plugins/_ ).
+
+2) Copy the CSS and JS and image files to the corresponding folders:
+```
+   mkdir -p '/path/to/racktables/wwwroot/{css,js,pix}/report/'
+   cp -v 'css/style.css' '/path/to/racktables/wwwroot/css/report/style.css'
+   cp -v "js/*" '/path/to/racktables/wwwroot/js/report/'
+   cp -v "pix/*" '/path/to/racktables/wwwroot/pix/report/'
+```
+
+3) Activate the plugin via the _Configuration_ => _Plugins_ menu.
+
+4) Depending on where you copied the CSS and JS files in step 2, you might want to adjust the configuration variables in _'Configuration'_ => _'User interface'_:
+```
+   REPORTS_CSS_PATH => defaults to 'css/report' (NO trailing slashes)
+   REPORTS_JS_PATH  => defaults to 'js/report'  (NO trailing slashes)
+```
+
+5) You might also want to enable/disable the MAC(s) column for your switch report via _'Configuration'_ => _'User interface'_:
+```
+   REPORTS_SHOW_MAC_FOR_SWITCHES => defaults to 'yes'
+```
+
+----
+
+## FAQ
+
+Q: How to find the right typeid of my devices?
+
+A: Visit 
+
+   Main page -> Configuration -> Dictionary -> Chapter 'ObjectType'
+and note down the value in the "Key" column.
+
+
diff --git a/reports/reports/css/style.css b/reports/reports/css/style.css
new file mode 100755 (executable)
index 0000000..2a74049
--- /dev/null
@@ -0,0 +1,111 @@
+/* tables */
+table.tablesorter {
+       font-family:arial;
+       background-color: #CDCDCD;
+       margin:10px 0pt 15px;
+       font-size: 8pt;
+       width: 100%;
+       text-align: left;
+       width:95%;
+}
+table.tablesorter thead tr th, table.tablesorter tfoot tr th {
+       background-color: #3C78B5;
+       /*border: 1px solid #FFF;*/
+       font-size: 11pt;
+    font-weight:bold;
+       padding: 4px;
+    color:white;
+    border:1px solid #3C78B5;
+}
+table.tablesorter thead tr .header {
+       background-image: url(?module=chrome&uri=pix/report/bg.gif);
+       background-repeat: no-repeat;
+       background-position: center right;
+       cursor: pointer;
+}
+table.tablesorter tbody td {
+       color: #3D3D3D;
+       padding: 2px;
+       background-color: #E8E8E8;
+       vertical-align: top;
+    font-weight:bold;
+    
+}
+table.tablesorter tbody tr.odd td {
+       background-color:#D0D0D0;
+}
+table.tablesorter thead tr .headerSortUp {
+       background-image: url(?module=chrome&uri=pix/report/asc.gif);
+}
+table.tablesorter thead tr .headerSortDown {
+       background-image: url(?module=chrome&uri=pix/report/desc.gif);
+}
+table.tablesorter thead tr .headerSortDown, table.tablesorter thead tr .headerSortUp {
+    background-color: #468DD5;
+}
+
+/* Custom Report */
+table.searchTable {
+       font-size: 8pt;
+       text-align: left;
+       border-collapse:collapse;
+       border-spacing:0px;
+       width:180px;
+       border:1px solid #3C78B5;
+}
+
+table.searchTable tr.odd {
+       background-color: #D0D0D0;
+}
+
+table.searchTable th {
+       font-size: 8pt;
+    padding : 2px;
+    text-decoration: underline;
+}
+
+table.searchTable td {
+       padding : 0px; 
+       height:20px;
+}
+
+table.searchTable td table {
+   border:none;
+}
+
+.searchForm {
+
+}
+.show_hide {
+   /* display:none; */
+}
+
+/* Images from http://openiconlibrary.sourceforge.net */
+
+/* Server */
+table.tablesorter tbody tr span.object_typeid_4 { 
+       background-image: url(?module=chrome&uri=pix/report/server.png);
+       background-repeat: no-repeat;
+       padding-left:20px;
+}
+/* Example set text color of object type */
+/*
+table.tablesorter tbody tr span.object_typeid_4 a {
+    color:red; 
+}
+*/
+
+/* Switches */
+table.tablesorter tbody tr span.object_typeid_8 { 
+    background-image: url(?module=chrome&uri=pix/report/network.png);
+    background-repeat: no-repeat;
+    padding-left:20px;
+}
+
+/* VMs */
+table.tablesorter tbody tr span.object_typeid_1504 { 
+    background-image: url(?module=chrome&uri=pix/report/vm.png);
+    background-repeat: no-repeat;
+    padding-left:20px;
+}
diff --git a/reports/reports/custom-report.php b/reports/reports/custom-report.php
new file mode 100644 (file)
index 0000000..df0d9c9
--- /dev/null
@@ -0,0 +1,786 @@
+<?php
+// Custom Racktables Report v.0.4.0
+// List a type of objects in a table and allow to export them via CSV
+
+// 2016-02-04 - Mogilowski Sebastian <sebastian@mogilowski.net>
+// 2018-09-10 - Lars Vogdt <lars@linux-schulserver.de>
+
+
+function renderCustomReport()
+{
+    # Get object list
+    $phys_typelist = readChapter (CHAP_OBJTYPE, 'o');
+    $attibutes     = getAttrMap();
+    $aTagList      = getTagList();
+    $report_type   = 'custom';
+
+    if ( ( $_SERVER['REQUEST_METHOD'] == 'POST' ) && ( isset( $_POST['csv'] ) ) ) {
+
+        header('Content-type: text/csv');
+        header('Content-Disposition: attachment; filename=export_'.$report_type.'_'.date("Ymdhis").'.csv');
+        header('Pragma: no-cache');
+        header('Expires: 0');
+
+        $outstream = fopen("php://output", "w");
+
+        $aResult = getResult($_POST); // Get Result
+        $_POST['name'] = validateColums($_POST); // Fix empty colums
+
+        $csvDelimiter = (isset( $_POST['csvDelimiter'] )) ? $_POST['csvDelimiter'] : ',';
+
+        /* Create Header */
+        $aCSVRow = array();
+
+        if ( isset( $_POST['sName'] ) && $_POST['sName'] )
+            array_push($aCSVRow, "Name");
+
+        if ( isset( $_POST['label'] ) )
+            array_push($aCSVRow, "Label");
+
+        if ( isset( $_POST['type'] ) )
+               array_push($aCSVRow, "Type");
+
+        if ( isset( $_POST['asset_no'] ) )
+            array_push($aCSVRow, "Asset Tag");
+
+        if ( isset( $_POST['has_problems'] ) )
+            array_push($aCSVRow, "Has Problems");
+
+        if ( isset( $_POST['comment'] ) )
+            array_push($aCSVRow, "Comment");
+
+        if ( isset( $_POST['runs8021Q'] ) )
+            array_push($aCSVRow, "Runs 8021Q");
+
+        if ( isset( $_POST['location'] ) )
+            array_push($aCSVRow, "Location");
+
+        if ( isset( $_POST['MACs'] ) )
+            array_push($aCSVRow, "MACs");
+
+        if ( isset( $_POST['IPs'] ) )
+            array_push($aCSVRow, "IPs");
+
+        if ( isset( $_POST['attributeIDs'] ) ) {
+            foreach ( $_POST['attributeIDs'] as $attributeID )
+                array_push($aCSVRow, $attibutes[$attributeID]['name']);
+        }
+
+        if ( isset( $_POST['Tags'] ) )
+            array_push($aCSVRow, "Tags");
+
+        if ( isset( $_POST['Ports'] ) )
+            array_push($aCSVRow, "Ports");
+
+        if ( isset( $_POST['Containers'] ) )
+                   array_push($aCSVRow, "Containers");
+
+        if ( isset( $_POST['Childs'] ) )
+            array_push($aCSVRow, "Child objects");
+
+        fputcsv( $outstream, $aCSVRow, $csvDelimiter );
+
+        /* Create data rows */
+        foreach ( $aResult as $Result ) {
+            $aCSVRow = array();
+
+            if ( isset( $_POST['sName'] ) )
+                array_push($aCSVRow, $Result['name']);
+
+            if ( isset( $_POST['label'] ) )
+                array_push($aCSVRow, $Result['label']);
+
+            if ( isset( $_POST['type'] ) )
+               array_push($aCSVRow, $phys_typelist[$Result['objtype_id']]);
+
+            if ( isset( $_POST['asset_no'] ) )
+                array_push($aCSVRow, $Result['asset_no']);
+
+            if ( isset( $_POST['has_problems'] ) )
+                array_push($aCSVRow, $Result['has_problems']);
+
+            if ( isset( $_POST['comment'] ) )
+                array_push($aCSVRow, str_replace('&quot;',"'",$Result['comment']));
+
+            if ( isset( $_POST['runs8021Q'] ) )
+                array_push($aCSVRow, $Result['runs8021Q']);
+
+            if ( isset( $_POST['location'] ) )
+                array_push($aCSVRow, preg_replace('/<a[^>]*>(.*)<\/a>/iU', '$1', getLocation($Result)));
+
+            if ( isset( $_POST['MACs'] ) ) {
+                $sTemp = '';
+                foreach ( getObjectPortsAndLinks($Result['id']) as $portNumber => $aPortDetails ) {
+                    if ( trim($aPortDetails['l2address']) != '')
+                        $sTemp .= $aPortDetails['l2address'].' ';
+                }
+                array_push($aCSVRow, $sTemp);
+            }
+
+            if ( isset( $_POST['IPs'] ) ) {
+                $sTemp = '';
+                foreach ( getObjectIPv4AllocationList($Result['id']) as $key => $aDetails ) {
+                    if ( function_exists('ip4_format') )
+                        $key = ip4_format($key);
+                    if ( trim($key) != '')
+                        $sTemp .= $key.' ';
+
+                }
+                foreach ( getObjectIPv6AllocationList($Result['id']) as $key => $aDetails ) {
+                    if ( function_exists('ip6_format') )
+                        $key = ip6_format($key);
+                    else
+                      $key = new IPv6Address($key);
+                    if ( trim($key) != '')
+                        $sTemp .= $key.' ';
+                }
+                array_push($aCSVRow, $sTemp);
+            }
+
+            if ( isset( $_POST['attributeIDs'] ) ) {
+                $attributes = getAttrValues ($Result['id']);
+                foreach ( $_POST['attributeIDs'] as $attributeID ) {
+                    if ( isset( $attributes[$attributeID]['a_value'] ) )
+                        array_push($aCSVRow,$attributes[$attributeID]['a_value']);
+                    elseif ( ($attributes[$attributeID]['value'] != '') && ( $attributes[$attributeID]['type'] == 'date' )   )
+                        array_push($aCSVRow,date("Y-m-d",$attributes[$attributeID]['value']));
+                    else
+                     array_push($aCSVRow,'');
+                }
+            }
+
+            if ( isset( $_POST['Tags'] ) ) {
+                $sTemp = '';
+                foreach ( $Result['tags'] as $aTag ) {
+                    $sTemp .= $aTag['tag'].' ';
+                }
+                if ( count($Result['itags']) > 0 ) {
+                    $sTemp .=  '(';
+                    foreach ( $Result['itags'] as $aTag ) {
+                        $sTemp .= $aTag['tag'].' ';
+                    }
+                    $sTemp .=  ')';
+                }
+                array_push($aCSVRow, $sTemp);
+            }
+
+            if ( isset( $_POST['Ports'] ) ) {
+                $sTemp = '';
+
+                foreach ( $Result['portsLinks'] as $port ) {
+                    $sTemp .= $port['name'].': '.$port['remote_object_name'];
+                    if ( trim($port['cableid']) != '')
+                        $sTemp .= ' Cable ID: '.$port['cableid'];
+                    $sTemp .= ' ';
+                }
+                $sTemp = trim($sTemp);
+
+                array_push($aCSVRow, $sTemp);
+            }
+
+            if ( isset( $_POST['Containers'] ) ) {
+               $sTemp = '';
+
+               foreach ( getObjectContainerList($Result['id']) as $key => $aDetails ) {
+                   $sTemp .= trim($aDetails['container_name']).' ';
+               }
+               $sTemp = trim($sTemp);
+
+               array_push($aCSVRow, $sTemp);
+            }
+
+            if ( isset( $_POST['Childs'] ) ) {
+               $sTemp = '';
+
+               foreach ( getObjectChildObjectList($Result['id']) as $key => $aDetails ) {
+                   $sTemp .= trim($aDetails['object_name']).' ';
+               }
+               $sTemp = trim($sTemp);
+
+               array_push($aCSVRow, $sTemp);
+            }
+
+            fputcsv( $outstream, $aCSVRow, $csvDelimiter );
+        }
+
+        fclose($outstream);
+
+        exit(0); # Exit normally after send CSV to browser
+
+    }
+
+    echo '<h2> Custom report</h2><ul>';
+
+    // Load stylesheet and jquery scripts
+    $css_path=getConfigVar('REPORTS_CSS_PATH');
+    $js_path=getConfigVar('REPORTS_JS_PATH');
+    addCSS ("$css_path/style.css");
+    addJS ("$js_path/saveFormValues.js");
+    addJS ("$js_path/jquery-latest.js");
+    addJS ("$js_path/jquery.tablesorter.js");
+    addJS ("$js_path/picnet.table.filter.min.js");
+
+    if ( $_SERVER['REQUEST_METHOD'] == 'POST' )
+        echo '<a href="#" class="show_hide">Show/hide search form</a><br/><br/>';
+
+    echo '<div class="searchForm">';
+
+    echo '<form method="post" name="searchForm">';
+
+    echo '<table class="searchTable">
+            <tr>
+              <th>Object Type</th>
+              <th>Common Values</th>
+              <th>Attributes</th>
+              <th>Tags</th>
+              <th>Misc</th>
+            </tr>
+            <tr>';
+
+    echo '<td valign="top">
+             <table class="searchTable">';
+    $i=0;
+    foreach ( $phys_typelist as $objectTypeID => $sName ) {
+        if( $i % 2 )
+          echo '<tr class="odd">';
+        else
+         echo '<tr>';
+        echo '  <td>
+                   <input type="checkbox" name="objectIDs[]" value="'.$objectTypeID.'"';
+                    if (isset($_POST['objectIDs']) && in_array($objectTypeID, $_POST['objectIDs']) )
+                      echo ' checked="checked"';
+        echo '     > '.$sName.'
+                 </td>
+               </tr>';
+        $i++;
+    }
+    echo '  </table>
+           </td>';
+
+    echo '<td valign="top">
+           <table class="searchTable">
+             <tr><td><input type="checkbox" name="sName" value="1" ';if (isset($_POST['sName'])) echo ' checked="checked"'; echo '> Name</td></tr>
+             <tr class="odd"><td><input type="checkbox" name="label" value="1" ';if (isset($_POST['label'])) echo ' checked="checked"'; echo '> Label</td></tr>
+             <tr><td><input type="checkbox" name="type" value="1" ';if (isset($_POST['type'])) echo ' checked="checked"'; echo '> Type</td></tr>
+             <tr class="odd"><td><input type="checkbox" name="asset_no" value="1" ';if (isset($_POST['asset_no'])) echo ' checked="checked"'; echo '> Asset Tag</td></tr>
+             <tr><td><input type="checkbox" name="location" value="1" ';if (isset($_POST['location'])) echo ' checked="checked"'; echo '> Location</td></tr>
+             <tr class="odd"><td><input type="checkbox" name="has_problems" value="1" ';if (isset($_POST['has_problems'])) echo ' checked="checked"'; echo '> Has Problems</td></tr>
+             <tr><td><input type="checkbox" name="comment" value="1" ';if (isset($_POST['comment'])) echo ' checked="checked"'; echo '> Comment</td></tr>
+             <tr class="odd"><td><input type="checkbox" name="runs8021Q" value="1" ';if (isset($_POST['runs8021Q'])) echo ' checked="checked"'; echo '> Runs 8021Q</td></tr>
+             <tr><td><input type="checkbox" name="MACs" value="1" ';if (isset($_POST['MACs'])) echo ' checked="checked"'; echo '> MACs</td></tr>
+             <tr class="odd"><td><input type="checkbox" name="IPs" value="1" ';if (isset($_POST['IPs'])) echo ' checked="checked"'; echo '> IPs</td></tr>
+             <tr><td><input type="checkbox" name="Tags" value="1" ';if (isset($_POST['Tags'])) echo ' checked="checked"'; echo '> Tags</td></tr>
+             <tr class="odd"><td><input type="checkbox" name="Ports" value="1" ';if (isset($_POST['Ports'])) echo ' checked="checked"'; echo '> Ports</td></tr>
+             <tr><td><input type="checkbox" name="Containers" value="1" ';if (isset($_POST['Containers'])) echo ' checked="checked"'; echo '> Containers</td></tr>
+             <tr class="odd"><td><input type="checkbox" name="Childs" value="1" ';if (isset($_POST['Childs'])) echo ' checked="checked"'; echo '> Child objects</td></tr>
+           </table>
+         </td>';
+
+    echo '<td valign="top">
+             <table class="searchTable">';
+    $i=0;
+    foreach ( $attibutes as $attributeID => $aRow ) {
+      if( $i % 2 )
+          echo '<tr class="odd">';
+        else
+         echo '<tr>';
+      echo ' <td>
+                <input type="checkbox" name="attributeIDs[]" value="'.$attributeID.'"';
+                 if (isset($_POST['attributeIDs']) && in_array($attributeID, $_POST['attributeIDs']) )
+                 echo ' checked="checked"';
+      echo '> '.$aRow['name'].'
+              </td>
+             </tr>';
+      $i++;
+    }
+    echo '  </table>
+           </td>';
+
+    echo '<td valign="top">
+            <table class="searchTable">';
+
+    $i = 0;
+    foreach ( $aTagList as $aTag ) {
+        echo '<tr '.($i%2 ? 'class="odd"' : '').'>
+                <td>
+                  <input type="checkbox" name="tag['.$aTag['id'].']" value="1" '.( isset($_POST['tag'][$aTag['id']]) ? 'checked="checked" ' : '').'> '.
+                  $aTag['tag'].'
+                </td>
+              </tr>';
+        $i++;
+    }
+    if ( count($aTagList) < 1 )
+     echo '<tr><td><i>No Tags available</i></td></tr>';
+
+    echo '  </table>
+          </td>';
+
+    echo '<td valign="top">
+            <table class="searchTable">
+              <tr class="odd"><td><input type="checkbox" name="csv" value="1"> CSV Export</td></tr>
+              <tr><td><input type="text" name="csvDelimiter" value="," size="1"> CSV Delimiter</td></tr>
+              <tr class="odd"><td>Name Filter: <i>(Regular Expression)</i></td></tr>
+              <tr><td><input type="text" name="name_preg" value="'; if (isset($_POST['name_preg'])) echo $_POST['name_preg']; echo '" style="height: 11pt;"></td></tr>
+              <tr class="odd"><td>Asset Tag Filter: <i>(Regular Expression)</i></td></tr>
+              <tr><td><input type="text" name="tag_preg" value="'; if (isset($_POST['tag_preg'])) echo $_POST['tag_preg']; echo '" style="height: 11pt;"></td></tr>
+              <tr class="odd"><td>Comment Filter: <i>(Regular Expression)</i></td></tr>
+              <tr><td><input type="text" name="comment_preg" value="'; if (isset($_POST['comment_preg'])) echo $_POST['comment_preg']; echo '" style="height: 11pt;"></td></tr>
+              <tr class="odd"><td>&nbsp;</td></tr>
+              <tr>
+                <td>
+                  Save:
+                  <input id="nameQuery" type="text" name="nameQuery" value="" style="height: 11pt; width:150px"/> <input type="button" value=" Ok " onclick="saveQuery();">
+               </td>
+              </tr>
+              <tr class="odd">
+                <td>
+                  Load:<br/>
+                   <span id="loadButtons"></span>
+                   <script type="text/javascript">
+                     loadButtons();
+                   </script>
+                </td>
+              </tr>
+              <tr><td>&nbsp;</td></tr>
+              <tr><td align="right"><input type="submit" value=" Search "></td></tr>
+            </table>
+          </td>
+        </tr>
+      </table>';
+
+    echo '</form>';
+
+    echo '</div>';
+
+    if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
+
+     $aResult = getResult($_POST); // Get Result
+     $_POST['sName'] = validateColums($_POST); // Fix empty colums
+
+     if ( count($aResult) > 0) {
+
+        echo '<table  id="customTable" class="tablesorter">
+               <thead>
+                 <tr>';
+
+        if ( isset( $_POST['sName'] )  && $_POST['sName'] )
+            echo '<th>Name</th>';
+
+        if ( isset( $_POST['label'] ) )
+            echo '<th>Label</th>';
+
+        if ( isset( $_POST['type'] ) )
+               echo '<th>Type</th>';
+
+        if ( isset( $_POST['asset_no'] ) )
+            echo '<th>Asset Tag</th>';
+
+        if ( isset( $_POST['has_problems'] ) )
+            echo '<th>Has Problems</th>';
+
+        if ( isset( $_POST['comment'] ) )
+            echo '<th>Comment</th>';
+
+        if ( isset( $_POST['runs8021Q'] ) )
+            echo '<th>Runs 8021Q</th>';
+
+        if ( isset( $_POST['location'] ) )
+            echo '<th>Location</th>';
+
+        if ( isset( $_POST['MACs'] ) )
+            echo '<th>MAC(s)</th>';
+
+        if ( isset( $_POST['IPs'] ) )
+            echo '<th>IP(s)</th>';
+
+        if ( isset( $_POST['attributeIDs'] ) ) {
+            foreach ( $_POST['attributeIDs'] as $attributeID )
+                echo '<th>'.$attibutes[$attributeID]['name'].'</th>';
+        }
+
+        if ( isset( $_POST['Tags'] ) ) {
+            echo '<th>Tags</th>';
+        }
+
+        if ( isset ($_POST['Ports']) ) {
+            echo '<th>Ports</th>';
+        }
+
+        if ( isset( $_POST['Containers'] ) ) {
+               echo '<th>Containers</th>';
+        }
+
+        if ( isset( $_POST['Childs'] ) ) {
+               echo '<th>Child objects</th>';
+        }
+
+        echo '  </tr>
+              </thead>
+              <tbody>';
+
+        foreach ( $aResult as $Result ) {
+
+            echo '<tr>';
+
+            if ( isset( $_POST['sName'] ) ) {
+                echo '<td>
+                        <span class="object_'.str_replace('$','',$Result['atags'][1]['tag']).'">';
+                if ( isset( $Result['name'] ) )
+                    echo '<a href="'. makeHref ( array( 'page' => 'object', 'object_id' => $Result['id']) )  .'">'.$Result['name'].'</a>';
+                else
+                 echo '&nbsp;';
+                echo '  </span>
+                       </td>';
+            }
+
+            if ( isset( $_POST['label'] ) ) {
+                echo '<td>';
+                if ( isset( $Result['label'] ) )
+                  echo $Result['label'];
+                else
+                 echo '&nbsp;';
+                echo '</td>';
+            }
+
+            if ( isset( $_POST['type'] ) ) {
+               echo '<td>';
+               if ( isset( $Result['objtype_id'] ) )
+                       echo $phys_typelist[$Result['objtype_id']];
+               else
+                       echo '&nbsp;';
+               echo '</td>';
+            }
+
+            if ( isset( $_POST['asset_no'] ) ) {
+               echo '<td>';
+               if ( isset( $Result['asset_no'] ) )
+                 echo $Result['asset_no'];
+               else
+                echo '&nbsp;';
+               echo '</td>';
+            }
+
+            if ( isset( $_POST['has_problems'] ) ) {
+               echo '<td>';
+               if ( isset( $Result['has_problems'] ) )
+                 echo $Result['has_problems'];
+               else
+                echo '&nbsp;';
+               echo '</td>';
+            }
+
+            if ( isset( $_POST['comment'] ) ) {
+               echo '<td>';
+               if ( isset( $Result['comment'] ) )
+                 echo makeLinksInText($Result['comment']);
+               else
+                echo '&nbsp;';
+               echo '</td>';
+            }
+
+            if ( isset( $_POST['runs8021Q'] ) ) {
+               echo '<td>';
+               if ( isset( $Result['runs8021Q'] ) )
+                 echo $Result['runs8021Q'];
+               else
+                echo '&nbsp;';
+               echo '</td>';
+            }
+
+            if ( isset( $_POST['location'] ) ) {
+                echo '<td>';
+                echo getLocation($Result);
+                echo '</td>';
+            }
+
+            if ( isset( $_POST['MACs'] ) ) {
+                echo '<td>';
+                foreach ( getObjectPortsAndLinks($Result['id']) as $portNumber => $aPortDetails ) {
+                    if ( trim($aPortDetails['l2address']) != '')
+                       echo $aPortDetails['l2address'].'<br/>';
+                }
+                echo '</td>';
+            }
+
+            if ( isset( $_POST['IPs'] ) ) {
+                echo '<td>';
+                foreach ( getObjectIPv4AllocationList($Result['id']) as $key => $aDetails ) {
+                    if ( function_exists('ip4_format') )
+                           $key = ip4_format($key);
+                    if ( trim($key) != '')
+                        echo $key . '<br/>';
+                }
+                foreach ( getObjectIPv6AllocationList($Result['id']) as $key => $aDetails ) {
+                    if ( function_exists('ip6_format') )
+                        $key = ip6_format($key);
+                    else
+                     $key = new IPv6Address($key);
+                    if ( trim($key) != '')
+                        echo $key . '<br/>';
+                }
+                echo '</td>';
+            }
+
+            if ( isset( $_POST['attributeIDs'] ) ) {
+             $attributes = getAttrValues ($Result['id']);
+                foreach ( $_POST['attributeIDs'] as $attributeID ) {
+                    echo '<td>';
+                    if ( isset( $attributes[$attributeID]['a_value'] ) && ($attributes[$attributeID]['a_value'] != '') )
+                        echo $attributes[$attributeID]['a_value'];
+                    elseif ( ($attributes[$attributeID]['value'] != '') && ( $attributes[$attributeID]['type'] == 'date' )   )
+                        echo date("Y-m-d",$attributes[$attributeID]['value']);
+                    else
+                     echo '&nbsp;';
+
+                }
+            }
+
+            if ( isset( $_POST['Tags'] ) ) {
+                echo '<td>';
+                foreach ( $Result['tags'] as $aTag )
+                    echo '<a href="'. makeHref ( array( 'page' => 'depot', 'tab' => 'default', 'andor' => 'and', 'cft[]' => $aTag['id']) ) .'">'.$aTag['tag'].'</a> ';
+
+                if ( count($Result['itags']) > 0 ) {
+                    echo '(';
+                    foreach ( $Result['itags'] as $aTag )
+                        echo '<a href="'. makeHref ( array( 'page' => 'depot', 'tab' => 'default', 'andor' => 'and', 'cft[]' => $aTag['id']) ) .'">'.$aTag['tag'].'</a> ';
+
+                    echo ')';
+                }
+                echo '</td>';
+            }
+
+            if ( isset ($_POST['Ports']) ) {
+                echo '<td>';
+
+                foreach ( $Result['portsLinks'] as $port ) {
+                   echo $port['name'].': ';
+                   if ( $port['remote_object_name'] != 'unknown' )
+                       echo formatPortLink ($port['remote_object_id'], $port['remote_object_name'], $port['remote_id'], NULL);
+                   else
+                    echo $port['remote_object_name'];
+                   if ( trim($port['cableid']) != '')
+                       echo ' Cable ID: '.$port['cableid'];
+                   echo '<br/>';
+                }
+
+                echo '</td>';
+            }
+
+            if ( isset ($_POST['Containers']) ) {
+               echo '<td>';
+
+               foreach ( getObjectContainerList($Result['id']) as $key => $aDetails ) {
+                   echo '<a href="'. makeHref ( array( 'page' => 'object', 'object_id' => $key) )  .'">'.$aDetails['container_name'].'</a><br/>';
+               }
+
+               echo '</td>';
+            }
+
+            if ( isset ($_POST['Childs']) ) {
+               echo '<td>';
+
+               foreach ( getObjectChildObjectList($Result['id']) as $key => $aDetails ) {
+                   echo '<a href="'. makeHref ( array( 'page' => 'object', 'object_id' => $key) )  .'">'.$aDetails['object_name'].'</a><br/>';
+               }
+
+               echo '</td>';
+            }
+
+            echo '</tr>';
+
+        }
+
+        echo '  </tbody>
+              </table>
+              <script type="text/javascript">$(".searchForm").hide();</script>';
+     }
+     else {
+        echo '<br/><br/><div align="center" style="font-size:10pt;"><i>No items found !!!</i></div><br/>';
+     }
+
+     echo '<script type="text/javascript">
+               $(document).ready(function()
+                 {
+                   $.tablesorter.defaults.widgets = ["zebra"];
+                   $("#customTable").tablesorter(
+                     { headers: {
+                     }, sortList: [[0,0]] }
+                   );
+                   $("#customTable").tableFilter();
+
+                   $(".show_hide").show();
+
+                   $(".show_hide").click(function(){
+                     $(".searchForm").slideToggle(\'slow\');
+                   });
+
+                 }
+                 );
+            </script>';
+    }
+
+}
+
+/**
+ * getResult Function
+ *
+ * Call Racktables API to get Objects and filter the result if required
+ *
+ * @param array $post
+ * @return array Result
+ */
+function getResult ( $post ) {
+
+       #Get available objects
+       $phys_typelist = readChapter (CHAP_OBJTYPE, 'o');
+
+       $rackObjectTypeID     = array_search('Rack', $phys_typelist);
+       $rowObjectTypeID      = array_search('Row', $phys_typelist);
+       $locationObjectTypeID = array_search('Location', $phys_typelist);
+
+       $rackRealm     = false;
+       $rowRealm      = false;
+       $locationRealm = false;
+
+    $sFilter = '';
+    if ( isset ($post['objectIDs']) ) {
+        foreach ( $post['objectIDs'] as $sFilterValue ) {
+            $sFilter.='{$typeid_'.$sFilterValue.'} or ';
+
+            if (($rackObjectTypeID) && ($sFilterValue == $rackObjectTypeID))
+               $rackRealm = true;
+            if (($rowObjectTypeID) && ($sFilterValue == $rowObjectTypeID))
+                       $rowRealm = true;
+            if (($locationObjectTypeID) && ($sFilterValue == $locationObjectTypeID))
+               $locationRealm = true;
+
+        }
+        $sFilter=substr($sFilter, 0, -4);
+        $sFilter = '('.$sFilter.')';
+    }
+
+    $aResult = scanRealmByText ( 'object', $sFilter );
+
+    # Get other realms than objects if user selected them
+    if ($rackRealm)
+       $aResult = array_merge($aResult, scanRealmByText ( 'rack') );
+    if ($rowRealm)
+       $aResult = array_merge($aResult, scanRealmByText ( 'row') );
+    if ($locationRealm)
+       $aResult = array_merge($aResult, scanRealmByText ( 'location') );
+
+    // Add tags
+    $aTemp = array();
+    foreach ( $aResult as $Result) {
+        $Result['tags']  = loadEntityTags( 'object', $Result['id'] );
+        $Result['itags'] = getImplicitTags( $Result['tags'] );
+
+        array_push($aTemp, $Result);
+    }
+    $aResult = $aTemp;
+
+    // Search / Filter by name
+    if ( isset ($post['name_preg']) && ($post['name_preg'] != '') ) {
+        $aTemp = array();
+        foreach ( $aResult as $Result ) {
+             if ( preg_match ( '/'.$post['name_preg'].'/' , $Result['name']) )
+                array_push($aTemp, $Result);
+        }
+        $aResult = $aTemp;
+    }
+
+    // Search / Filter by tag
+    if ( isset ($post['tag_preg']) && ($post['tag_preg'] != '') ) {
+        $aTemp = array();
+        foreach ( $aResult as $Result ) {
+            if ( preg_match ( '/'.$post['tag_preg'].'/' , $Result['asset_no']) )
+                array_push($aTemp, $Result);
+        }
+        $aResult = $aTemp;
+    }
+
+    // Search / Filter by comment
+    if ( isset ($post['comment_preg']) && ($post['comment_preg'] != '') ) {
+        $aTemp = array();
+        foreach ( $aResult as $Result ) {
+            if ( preg_match ( '/'.$post['comment_preg'].'/' , $Result['comment']) )
+                array_push($aTemp, $Result);
+        }
+        $aResult = $aTemp;
+    }
+
+    // Tags
+    if ( (isset ($post['tag'])) && ( count($post['tag']) >0 ) ) {
+        $aTemp = array();
+        $aSearchTags = array_keys($post['tag']);
+
+        foreach ( $aResult as $Result ) {
+
+            foreach ( $Result['tags'] as $aTag ) {
+               if ( in_array($aTag['id'], $aSearchTags) )
+                   array_push($aTemp, $Result);
+            }
+
+            foreach ( $Result['itags'] as $aTag ) {
+                if ( in_array($aTag['id'], $aSearchTags) )
+                    array_push($aTemp, $Result);
+            }
+
+        }
+
+        $aResult = $aTemp;
+    }
+
+    // Ports - Load port data if necessary
+    if ( isset ($post['Ports']) ) {
+        $aTemp = array();
+
+        foreach ( $aResult as $Result ) {
+
+            $Result['portsLinks'] = getObjectPortsAndLinks ($Result['id']);
+
+            foreach ( $Result['portsLinks'] as $i => $port) {
+
+                $Result['portsLinks'][$i]['remote_object_name'] = 'unknown';
+                if (!is_null( $port['remote_object_id'] )){
+                    $remote_object = spotEntity ('object', intval($port['remote_object_id']));
+                    $Result['portsLinks'][$i]['remote_object_name'] = $remote_object['name'];
+                }
+            }
+
+            array_push($aTemp, $Result);
+        }
+
+       $aResult = $aTemp;
+    }
+
+    return $aResult;
+}
+
+/**
+ * validateColums Function
+ *
+ * If user doesn't select any colum to display this function preselect the name colum
+ * to display the results
+ *
+ * @param array $_POST
+ * @return bool display
+ */
+function validateColums($POST) {
+    if (isset( $POST['sName'] ) )
+        return true;
+
+    if ( (!isset($POST['label'])) &&
+         (!isset($POST['asset_no'])) &&
+         (!isset($POST['has_problems'])) &&
+         (!isset($POST['comment'])) &&
+         (!isset($POST['runs8021Q'])) &&
+         (!isset($POST['location'])) &&
+         (!isset($POST['MACs'])) &&
+         (!isset($POST['label'])) &&
+      (!isset($POST['attributeIDs'])) ) {
+     return true;
+    }
+
+}
diff --git a/reports/reports/js/jquery-latest.js b/reports/reports/js/jquery-latest.js
new file mode 100644 (file)
index 0000000..98f4b87
--- /dev/null
@@ -0,0 +1,4 @@
+/*! jQuery v1.7.2 jquery.com | jquery.org/license */\r
+(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"<!doctype html>":"")+"<html><body>"),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a)?d(a,e):b_(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&f.type(b)==="object")for(var e in b)b_(a+"["+e+"]",b[e],c,d);else d(a,b)}function b$(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bZ(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bS,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bZ(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bZ(a,c,d,e,"*",g));return l}function bY(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bO),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bB(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?1:0,g=4;if(d>0){if(c!=="border")for(;e<g;e+=2)c||(d-=parseFloat(f.css(a,"padding"+bx[e]))||0),c==="margin"?d+=parseFloat(f.css(a,c+bx[e]))||0:d-=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0;return d+"px"}d=by(a,b);if(d<0||d==null)d=a.style[b];if(bt.test(d))return d;d=parseFloat(d)||0;if(c)for(;e<g;e+=2)d+=parseFloat(f.css(a,"padding"+bx[e]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+bx[e]))||0);return d+"px"}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;b.nodeType===1&&(b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?b.outerHTML=a.outerHTML:c!=="input"||a.type!=="checkbox"&&a.type!=="radio"?c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text):(a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value)),b.removeAttribute(f.expando),b.removeAttribute("_submit_attached"),b.removeAttribute("_change_attached"))}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c,i[c][d])}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h,i){var j,k=d==null,l=0,m=a.length;if(d&&typeof d=="object"){for(l in d)e.access(a,c,l,d[l],1,h,f);g=1}else if(f!==b){j=i===b&&e.isFunction(f),k&&(j?(j=c,c=function(a,b,c){return j.call(e(a),c)}):(c.call(a,f),c=null));if(c)for(;l<m;l++)c(a[l],d,j?f.call(a[l],l,c(a[l],d)):f,i);g=1}return g?a:k?c.call(a):m?c(a[0],d):h},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m,n=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?n(g):h==="function"&&(!a.unique||!p.has(g))&&c.push(g)},o=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,j=!0,m=k||0,k=0,l=c.length;for(;c&&m<l;m++)if(c[m].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}j=!1,c&&(a.once?e===!0?p.disable():c=[]:d&&d.length&&(e=d.shift(),p.fireWith(e[0],e[1])))},p={add:function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){j&&f<=l&&(l--,f<=m&&m--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&p.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(j?a.once||d.push([b,c]):(!a.once||!e)&&o(b,c));return this},fire:function(){p.fireWith(this,arguments);return this},fired:function(){return!!i}};return p};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p=c.createElement("div"),q=c.documentElement;p.setAttribute("className","t"),p.innerHTML="   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="<div "+n+"display:block;'><div style='"+t+"0;display:block;overflow:hidden;'></div></div>"+"<table "+n+"' cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="<table><tr><td style='"+t+"0;display:none'></td><td>t</td></tr></table>",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="<div style='width:5px;'></div>",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h,i,j=this[0],k=0,m=null;if(a===b){if(this.length){m=f.data(j);if(j.nodeType===1&&!f._data(j,"parsedAttrs")){g=j.attributes;for(i=g.length;k<i;k++)h=g[k].name,h.indexOf("data-")===0&&(h=f.camelCase(h.substring(5)),l(j,h,m[h]));f._data(j,"parsedAttrs",!0)}}return m}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!";return f.access(this,function(c){if(c===b){m=this.triggerHandler("getData"+e,[d[0]]),m===b&&j&&(m=f.data(j,a),m=l(j,a,m));return m===b&&d[1]?this.data(d[0]):m}d[1]=c,this.each(function(){var b=f(this);b.triggerHandler("setData"+e,d),f.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length<d)return f.queue(this[0],a);return c===b?this:this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise(c)}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,f.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i<g;i++)e=d[i],e&&(c=f.propFix[e]||e,h=u.test(e),h||f.attr(a,e,""),a.removeAttribute(v?e:c),h&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0,coords:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(\r
+a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:g&&G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=f.event.special[c.type]||{},j=[],k,l,m,n,o,p,q,r,s,t,u;g[0]=c,c.delegateTarget=this;if(!i.preDispatch||i.preDispatch.call(this,c)!==!1){if(e&&(!c.button||c.type!=="click")){n=f(this),n.context=this.ownerDocument||this;for(m=c.target;m!=this;m=m.parentNode||this)if(m.disabled!==!0){p={},r=[],n[0]=m;for(k=0;k<e;k++)s=d[k],t=s.selector,p[t]===b&&(p[t]=s.quick?H(m,s.quick):n.is(t)),p[t]&&r.push(s);r.length&&j.push({elem:m,matches:r})}}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k<j.length&&!c.isPropagationStopped();k++){q=j[k],c.currentTarget=q.elem;for(l=0;l<q.matches.length&&!c.isImmediatePropagationStopped();l++){s=q.matches[l];if(h||!c.namespace&&!s.namespace||c.namespace_re&&c.namespace_re.test(s.namespace))c.data=s.data,c.handleObj=s,o=((f.event.special[s.origType]||{}).handle||s.handler).apply(q.elem,g),o!==b&&(c.result=o,o===!1&&(c.preventDefault(),c.stopPropagation()))}}i.postDispatch&&i.postDispatch.call(this,c);return c.result}},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),d._submit_attached=!0)})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9||d===11){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.globalPOS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")[\\s/>]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f\r
+.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(f.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(g){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,function(a,b){b.src?f.ajax({type:"GET",global:!1,url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1></$2>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]==="<table>"&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i<u;i++)bn(l[i]);else bn(l);l.nodeType?j.push(l):j=f.merge(j,l)}if(d){g=function(a){return!a.type||be.test(a.type)};for(k=0;j[k];k++){h=j[k];if(e&&f.nodeName(h,"script")&&(!h.type||be.test(h.type)))e.push(h.parentNode?h.parentNode.removeChild(h):h);else{if(h.nodeType===1){var v=f.grep(h.getElementsByTagName("script"),g);j.splice.apply(j,[k+1,0].concat(v))}d.appendChild(h)}}}return j},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bp=/alpha\([^)]*\)/i,bq=/opacity=([^)]*)/,br=/([A-Z]|^ms)/g,bs=/^[\-+]?(?:\d*\.)?\d+$/i,bt=/^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,bu=/^([\-+])=([\-+.\de]+)/,bv=/^margin/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Top","Right","Bottom","Left"],by,bz,bA;f.fn.css=function(a,c){return f.access(this,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)},a,c,arguments.length>1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),(e===""&&f.css(d,"display")==="none"||!f.contains(d.ownerDocument.documentElement,d))&&f._data(d,"olddisplay",cu(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(ct("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(ct("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o,p,q;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]);if((k=f.cssHooks[g])&&"expand"in k){l=k.expand(a[g]),delete a[g];for(i in l)i in a||(a[i]=l[i])}}for(g in a){h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cu(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cm.test(h)?(q=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),q?(f._data(this,"toggle"+i,q==="show"?"hide":"show"),j[q]()):j[h]()):(m=cn.exec(h),n=j.cur(),m?(o=parseFloat(m[2]),p=m[3]||(f.cssNumber[i]?"":"px"),p!=="px"&&(f.style(this,i,(o||1)+p),n=(o||1)/j.cur()*n,f.style(this,i,n+p)),m[1]&&(o=(m[1]==="-="?-1:1)*o+n),j.custom(n,o,p)):j.custom(n,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:ct("show",1),slideUp:ct("hide",1),slideToggle:ct("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a){return a},swing:function(a){return-Math.cos(a*Math.PI)/2+.5}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cq||cr(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){f._data(e.elem,"fxshow"+e.prop)===b&&(e.options.hide?f._data(e.elem,"fxshow"+e.prop,e.start):e.options.show&&f._data(e.elem,"fxshow"+e.prop,e.end))},h()&&f.timers.push(h)&&!co&&(co=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cq||cr(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(co),co=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(cp.concat.apply([],cp),function(a,b){b.indexOf("margin")&&(f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)})}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cv,cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?cv=function(a,b,c,d){try{d=a.getBoundingClientRect()}catch(e){}if(!d||!f.contains(c,a))return d?{top:d.top,left:d.left}:{top:0,left:0};var g=b.body,h=cy(b),i=c.clientTop||g.clientTop||0,j=c.clientLeft||g.clientLeft||0,k=h.pageYOffset||f.support.boxModel&&c.scrollTop||g.scrollTop,l=h.pageXOffset||f.support.boxModel&&c.scrollLeft||g.scrollLeft,m=d.top+k-i,n=d.left+l-j;return{top:m,left:n}}:cv=function(a,b,c){var d,e=a.offsetParent,g=a,h=b.body,i=b.defaultView,j=i?i.getComputedStyle(a,null):a.currentStyle,k=a.offsetTop,l=a.offsetLeft;while((a=a.parentNode)&&a!==h&&a!==c){if(f.support.fixedPosition&&j.position==="fixed")break;d=i?i.getComputedStyle(a,null):a.currentStyle,k-=a.scrollTop,l-=a.scrollLeft,a===e&&(k+=a.offsetTop,l+=a.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(a.nodeName))&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),g=e,e=a.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),j=d}if(j.position==="relative"||j.position==="static")k+=h.offsetTop,l+=h.offsetLeft;f.support.fixedPosition&&j.position==="fixed"&&(k+=Math.max(c.scrollTop,h.scrollTop),l+=Math.max(c.scrollLeft,h.scrollLeft));return{top:k,left:l}},f.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){f.offset.setOffset(this,a,b)});var c=this[0],d=c&&c.ownerDocument;if(!d)return null;if(c===d.body)return f.offset.bodyOffset(c);return cv(c,d,d.documentElement)},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);\r
diff --git a/reports/reports/js/jquery.tablesorter.js b/reports/reports/js/jquery.tablesorter.js
new file mode 100644 (file)
index 0000000..9b58731
--- /dev/null
@@ -0,0 +1,1031 @@
+/*\r
+ * \r
+ * TableSorter 2.0 - Client-side table sorting with ease!\r
+ * Version 2.0.5b\r
+ * @requires jQuery v1.2.3\r
+ * \r
+ * Copyright (c) 2007 Christian Bach\r
+ * Examples and docs at: http://tablesorter.com\r
+ * Dual licensed under the MIT and GPL licenses:\r
+ * http://www.opensource.org/licenses/mit-license.php\r
+ * http://www.gnu.org/licenses/gpl.html\r
+ * \r
+ */\r
+/**\r
+ * \r
+ * @description Create a sortable table with multi-column sorting capabilitys\r
+ * \r
+ * @example $('table').tablesorter();\r
+ * @desc Create a simple tablesorter interface.\r
+ * \r
+ * @example $('table').tablesorter({ sortList:[[0,0],[1,0]] });\r
+ * @desc Create a tablesorter interface and sort on the first and secound column column headers.\r
+ * \r
+ * @example $('table').tablesorter({ headers: { 0: { sorter: false}, 1: {sorter: false} } });\r
+ *          \r
+ * @desc Create a tablesorter interface and disableing the first and second  column headers.\r
+ *      \r
+ * \r
+ * @example $('table').tablesorter({ headers: { 0: {sorter:"integer"}, 1: {sorter:"currency"} } });\r
+ * \r
+ * @desc Create a tablesorter interface and set a column parser for the first\r
+ *       and second column.\r
+ * \r
+ * \r
+ * @param Object\r
+ *            settings An object literal containing key/value pairs to provide\r
+ *            optional settings.\r
+ * \r
+ * \r
+ * @option String cssHeader (optional) A string of the class name to be appended\r
+ *         to sortable tr elements in the thead of the table. Default value:\r
+ *         "header"\r
+ * \r
+ * @option String cssAsc (optional) A string of the class name to be appended to\r
+ *         sortable tr elements in the thead on a ascending sort. Default value:\r
+ *         "headerSortUp"\r
+ * \r
+ * @option String cssDesc (optional) A string of the class name to be appended\r
+ *         to sortable tr elements in the thead on a descending sort. Default\r
+ *         value: "headerSortDown"\r
+ * \r
+ * @option String sortInitialOrder (optional) A string of the inital sorting\r
+ *         order can be asc or desc. Default value: "asc"\r
+ * \r
+ * @option String sortMultisortKey (optional) A string of the multi-column sort\r
+ *         key. Default value: "shiftKey"\r
+ * \r
+ * @option String textExtraction (optional) A string of the text-extraction\r
+ *         method to use. For complex html structures inside td cell set this\r
+ *         option to "complex", on large tables the complex option can be slow.\r
+ *         Default value: "simple"\r
+ * \r
+ * @option Object headers (optional) An array containing the forces sorting\r
+ *         rules. This option let's you specify a default sorting rule. Default\r
+ *         value: null\r
+ * \r
+ * @option Array sortList (optional) An array containing the forces sorting\r
+ *         rules. This option let's you specify a default sorting rule. Default\r
+ *         value: null\r
+ * \r
+ * @option Array sortForce (optional) An array containing forced sorting rules.\r
+ *         This option let's you specify a default sorting rule, which is\r
+ *         prepended to user-selected rules. Default value: null\r
+ * \r
+ * @option Boolean sortLocaleCompare (optional) Boolean flag indicating whatever\r
+ *         to use String.localeCampare method or not. Default set to true.\r
+ * \r
+ * \r
+ * @option Array sortAppend (optional) An array containing forced sorting rules.\r
+ *         This option let's you specify a default sorting rule, which is\r
+ *         appended to user-selected rules. Default value: null\r
+ * \r
+ * @option Boolean widthFixed (optional) Boolean flag indicating if tablesorter\r
+ *         should apply fixed widths to the table columns. This is usefull when\r
+ *         using the pager companion plugin. This options requires the dimension\r
+ *         jquery plugin. Default value: false\r
+ * \r
+ * @option Boolean cancelSelection (optional) Boolean flag indicating if\r
+ *         tablesorter should cancel selection of the table headers text.\r
+ *         Default value: true\r
+ * \r
+ * @option Boolean debug (optional) Boolean flag indicating if tablesorter\r
+ *         should display debuging information usefull for development.\r
+ * \r
+ * @type jQuery\r
+ * \r
+ * @name tablesorter\r
+ * \r
+ * @cat Plugins/Tablesorter\r
+ * \r
+ * @author Christian Bach/christian.bach@polyester.se\r
+ */\r
+\r
+(function ($) {\r
+    $.extend({\r
+        tablesorter: new\r
+        function () {\r
+\r
+            var parsers = [],\r
+                widgets = [];\r
+\r
+            this.defaults = {\r
+                cssHeader: "header",\r
+                cssAsc: "headerSortUp",\r
+                cssDesc: "headerSortDown",\r
+                cssChildRow: "expand-child",\r
+                sortInitialOrder: "asc",\r
+                sortMultiSortKey: "shiftKey",\r
+                sortForce: null,\r
+                sortAppend: null,\r
+                sortLocaleCompare: true,\r
+                textExtraction: "simple",\r
+                parsers: {}, widgets: [],\r
+                widgetZebra: {\r
+                    css: ["even", "odd"]\r
+                }, headers: {}, widthFixed: false,\r
+                cancelSelection: true,\r
+                sortList: [],\r
+                headerList: [],\r
+                dateFormat: "us",\r
+                decimal: '/\.|\,/g',\r
+                onRenderHeader: null,\r
+                selectorHeaders: 'thead th',\r
+                debug: false\r
+            };\r
+\r
+            /* debuging utils */\r
+\r
+            function benchmark(s, d) {\r
+                log(s + "," + (new Date().getTime() - d.getTime()) + "ms");\r
+            }\r
+\r
+            this.benchmark = benchmark;\r
+\r
+            function log(s) {\r
+                if (typeof console != "undefined" && typeof console.debug != "undefined") {\r
+                    console.log(s);\r
+                } else {\r
+                    alert(s);\r
+                }\r
+            }\r
+\r
+            /* parsers utils */\r
+\r
+            function buildParserCache(table, $headers) {\r
+\r
+                if (table.config.debug) {\r
+                    var parsersDebug = "";\r
+                }\r
+\r
+                if (table.tBodies.length == 0) return; // In the case of empty tables\r
+                var rows = table.tBodies[0].rows;\r
+\r
+                if (rows[0]) {\r
+\r
+                    var list = [],\r
+                        cells = rows[0].cells,\r
+                        l = cells.length;\r
+\r
+                    for (var i = 0; i < l; i++) {\r
+\r
+                        var p = false;\r
+\r
+                        if ($.metadata && ($($headers[i]).metadata() && $($headers[i]).metadata().sorter)) {\r
+\r
+                            p = getParserById($($headers[i]).metadata().sorter);\r
+\r
+                        } else if ((table.config.headers[i] && table.config.headers[i].sorter)) {\r
+\r
+                            p = getParserById(table.config.headers[i].sorter);\r
+                        }\r
+                        if (!p) {\r
+\r
+                            p = detectParserForColumn(table, rows, -1, i);\r
+                        }\r
+\r
+                        if (table.config.debug) {\r
+                            parsersDebug += "column:" + i + " parser:" + p.id + "\n";\r
+                        }\r
+\r
+                        list.push(p);\r
+                    }\r
+                }\r
+\r
+                if (table.config.debug) {\r
+                    log(parsersDebug);\r
+                }\r
+\r
+                return list;\r
+            };\r
+\r
+            function detectParserForColumn(table, rows, rowIndex, cellIndex) {\r
+                var l = parsers.length,\r
+                    node = false,\r
+                    nodeValue = false,\r
+                    keepLooking = true;\r
+                while (nodeValue == '' && keepLooking) {\r
+                    rowIndex++;\r
+                    if (rows[rowIndex]) {\r
+                        node = getNodeFromRowAndCellIndex(rows, rowIndex, cellIndex);\r
+                        nodeValue = trimAndGetNodeText(table.config, node);\r
+                        if (table.config.debug) {\r
+                            log('Checking if value was empty on row:' + rowIndex);\r
+                        }\r
+                    } else {\r
+                        keepLooking = false;\r
+                    }\r
+                }\r
+                for (var i = 1; i < l; i++) {\r
+                    if (parsers[i].is(nodeValue, table, node)) {\r
+                        return parsers[i];\r
+                    }\r
+                }\r
+                // 0 is always the generic parser (text)\r
+                return parsers[0];\r
+            }\r
+\r
+            function getNodeFromRowAndCellIndex(rows, rowIndex, cellIndex) {\r
+                return rows[rowIndex].cells[cellIndex];\r
+            }\r
+\r
+            function trimAndGetNodeText(config, node) {\r
+                return $.trim(getElementText(config, node));\r
+            }\r
+\r
+            function getParserById(name) {\r
+                var l = parsers.length;\r
+                for (var i = 0; i < l; i++) {\r
+                    if (parsers[i].id.toLowerCase() == name.toLowerCase()) {\r
+                        return parsers[i];\r
+                    }\r
+                }\r
+                return false;\r
+            }\r
+\r
+            /* utils */\r
+\r
+            function buildCache(table) {\r
+\r
+                if (table.config.debug) {\r
+                    var cacheTime = new Date();\r
+                }\r
+\r
+                var totalRows = (table.tBodies[0] && table.tBodies[0].rows.length) || 0,\r
+                    totalCells = (table.tBodies[0].rows[0] && table.tBodies[0].rows[0].cells.length) || 0,\r
+                    parsers = table.config.parsers,\r
+                    cache = {\r
+                        row: [],\r
+                        normalized: []\r
+                    };\r
+\r
+                for (var i = 0; i < totalRows; ++i) {\r
+\r
+                    /** Add the table data to main data array */\r
+                    var c = $(table.tBodies[0].rows[i]),\r
+                        cols = [];\r
+\r
+                    // if this is a child row, add it to the last row's children and\r
+                    // continue to the next row\r
+                    if (c.hasClass(table.config.cssChildRow)) {\r
+                        cache.row[cache.row.length - 1] = cache.row[cache.row.length - 1].add(c);\r
+                        // go to the next for loop\r
+                        continue;\r
+                    }\r
+\r
+                    cache.row.push(c);\r
+\r
+                    for (var j = 0; j < totalCells; ++j) {\r
+                        cols.push(parsers[j].format(getElementText(table.config, c[0].cells[j]), table, c[0].cells[j]));\r
+                    }\r
+\r
+                    cols.push(cache.normalized.length); // add position for rowCache\r
+                    cache.normalized.push(cols);\r
+                    cols = null;\r
+                };\r
+\r
+                if (table.config.debug) {\r
+                    benchmark("Building cache for " + totalRows + " rows:", cacheTime);\r
+                }\r
+\r
+                return cache;\r
+            };\r
+\r
+            function getElementText(config, node) {\r
+\r
+                var text = "";\r
+\r
+                if (!node) return "";\r
+\r
+                if (!config.supportsTextContent) config.supportsTextContent = node.textContent || false;\r
+\r
+                if (config.textExtraction == "simple") {\r
+                    if (config.supportsTextContent) {\r
+                        text = node.textContent;\r
+                    } else {\r
+                        if (node.childNodes[0] && node.childNodes[0].hasChildNodes()) {\r
+                            text = node.childNodes[0].innerHTML;\r
+                        } else {\r
+                            text = node.innerHTML;\r
+                        }\r
+                    }\r
+                } else {\r
+                    if (typeof(config.textExtraction) == "function") {\r
+                        text = config.textExtraction(node);\r
+                    } else {\r
+                        text = $(node).text();\r
+                    }\r
+                }\r
+                return text;\r
+            }\r
+\r
+            function appendToTable(table, cache) {\r
+\r
+                if (table.config.debug) {\r
+                    var appendTime = new Date()\r
+                }\r
+\r
+                var c = cache,\r
+                    r = c.row,\r
+                    n = c.normalized,\r
+                    totalRows = n.length,\r
+                    checkCell = (n[0].length - 1),\r
+                    tableBody = $(table.tBodies[0]),\r
+                    rows = [];\r
+\r
+\r
+                for (var i = 0; i < totalRows; i++) {\r
+                    var pos = n[i][checkCell];\r
+\r
+                    rows.push(r[pos]);\r
+\r
+                    if (!table.config.appender) {\r
+\r
+                        //var o = ;\r
+                        var l = r[pos].length;\r
+                        for (var j = 0; j < l; j++) {\r
+                            tableBody[0].appendChild(r[pos][j]);\r
+                        }\r
+\r
+                        // \r
+                    }\r
+                }\r
+\r
+\r
+\r
+                if (table.config.appender) {\r
+\r
+                    table.config.appender(table, rows);\r
+                }\r
+\r
+                rows = null;\r
+\r
+                if (table.config.debug) {\r
+                    benchmark("Rebuilt table:", appendTime);\r
+                }\r
+\r
+                // apply table widgets\r
+                applyWidget(table);\r
+\r
+                // trigger sortend\r
+                setTimeout(function () {\r
+                    $(table).trigger("sortEnd");\r
+                }, 0);\r
+\r
+            };\r
+\r
+            function buildHeaders(table) {\r
+\r
+                if (table.config.debug) {\r
+                    var time = new Date();\r
+                }\r
+\r
+                var meta = ($.metadata) ? true : false;\r
+                \r
+                var header_index = computeTableHeaderCellIndexes(table);\r
+\r
+                $tableHeaders = $(table.config.selectorHeaders, table).each(function (index) {\r
+\r
+                    this.column = header_index[this.parentNode.rowIndex + "-" + this.cellIndex];\r
+                    // this.column = index;\r
+                    this.order = formatSortingOrder(table.config.sortInitialOrder);\r
+                    \r
+                                       \r
+                                       this.count = this.order;\r
+\r
+                    if (checkHeaderMetadata(this) || checkHeaderOptions(table, index)) this.sortDisabled = true;\r
+                                       if (checkHeaderOptionsSortingLocked(table, index)) this.order = this.lockedOrder = checkHeaderOptionsSortingLocked(table, index);\r
+\r
+                    if (!this.sortDisabled) {\r
+                        var $th = $(this).addClass(table.config.cssHeader);\r
+                        if (table.config.onRenderHeader) table.config.onRenderHeader.apply($th);\r
+                    }\r
+\r
+                    // add cell to headerList\r
+                    table.config.headerList[index] = this;\r
+                });\r
+\r
+                if (table.config.debug) {\r
+                    benchmark("Built headers:", time);\r
+                    log($tableHeaders);\r
+                }\r
+\r
+                return $tableHeaders;\r
+\r
+            };\r
+\r
+            // from:\r
+            // http://www.javascripttoolbox.com/lib/table/examples.php\r
+            // http://www.javascripttoolbox.com/temp/table_cellindex.html\r
+\r
+\r
+            function computeTableHeaderCellIndexes(t) {\r
+                var matrix = [];\r
+                var lookup = {};\r
+                var thead = t.getElementsByTagName('THEAD')[0];\r
+                var trs = thead.getElementsByTagName('TR');\r
+\r
+                for (var i = 0; i < trs.length; i++) {\r
+                    var cells = trs[i].cells;\r
+                    for (var j = 0; j < cells.length; j++) {\r
+                        var c = cells[j];\r
+\r
+                        var rowIndex = c.parentNode.rowIndex;\r
+                        var cellId = rowIndex + "-" + c.cellIndex;\r
+                        var rowSpan = c.rowSpan || 1;\r
+                        var colSpan = c.colSpan || 1\r
+                        var firstAvailCol;\r
+                        if (typeof(matrix[rowIndex]) == "undefined") {\r
+                            matrix[rowIndex] = [];\r
+                        }\r
+                        // Find first available column in the first row\r
+                        for (var k = 0; k < matrix[rowIndex].length + 1; k++) {\r
+                            if (typeof(matrix[rowIndex][k]) == "undefined") {\r
+                                firstAvailCol = k;\r
+                                break;\r
+                            }\r
+                        }\r
+                        lookup[cellId] = firstAvailCol;\r
+                        for (var k = rowIndex; k < rowIndex + rowSpan; k++) {\r
+                            if (typeof(matrix[k]) == "undefined") {\r
+                                matrix[k] = [];\r
+                            }\r
+                            var matrixrow = matrix[k];\r
+                            for (var l = firstAvailCol; l < firstAvailCol + colSpan; l++) {\r
+                                matrixrow[l] = "x";\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+                return lookup;\r
+            }\r
+\r
+            function checkCellColSpan(table, rows, row) {\r
+                var arr = [],\r
+                    r = table.tHead.rows,\r
+                    c = r[row].cells;\r
+\r
+                for (var i = 0; i < c.length; i++) {\r
+                    var cell = c[i];\r
+\r
+                    if (cell.colSpan > 1) {\r
+                        arr = arr.concat(checkCellColSpan(table, headerArr, row++));\r
+                    } else {\r
+                        if (table.tHead.length == 1 || (cell.rowSpan > 1 || !r[row + 1])) {\r
+                            arr.push(cell);\r
+                        }\r
+                        // headerArr[row] = (i+row);\r
+                    }\r
+                }\r
+                return arr;\r
+            };\r
+\r
+            function checkHeaderMetadata(cell) {\r
+                if (($.metadata) && ($(cell).metadata().sorter === false)) {\r
+                    return true;\r
+                };\r
+                return false;\r
+            }\r
+\r
+            function checkHeaderOptions(table, i) {\r
+                if ((table.config.headers[i]) && (table.config.headers[i].sorter === false)) {\r
+                    return true;\r
+                };\r
+                return false;\r
+            }\r
+                       \r
+                        function checkHeaderOptionsSortingLocked(table, i) {\r
+                if ((table.config.headers[i]) && (table.config.headers[i].lockedOrder)) return table.config.headers[i].lockedOrder;\r
+                return false;\r
+            }\r
+                       \r
+            function applyWidget(table) {\r
+                var c = table.config.widgets;\r
+                var l = c.length;\r
+                for (var i = 0; i < l; i++) {\r
+\r
+                    getWidgetById(c[i]).format(table);\r
+                }\r
+\r
+            }\r
+\r
+            function getWidgetById(name) {\r
+                var l = widgets.length;\r
+                for (var i = 0; i < l; i++) {\r
+                    if (widgets[i].id.toLowerCase() == name.toLowerCase()) {\r
+                        return widgets[i];\r
+                    }\r
+                }\r
+            };\r
+\r
+            function formatSortingOrder(v) {\r
+                if (typeof(v) != "Number") {\r
+                    return (v.toLowerCase() == "desc") ? 1 : 0;\r
+                } else {\r
+                    return (v == 1) ? 1 : 0;\r
+                }\r
+            }\r
+\r
+            function isValueInArray(v, a) {\r
+                var l = a.length;\r
+                for (var i = 0; i < l; i++) {\r
+                    if (a[i][0] == v) {\r
+                        return true;\r
+                    }\r
+                }\r
+                return false;\r
+            }\r
+\r
+            function setHeadersCss(table, $headers, list, css) {\r
+                // remove all header information\r
+                $headers.removeClass(css[0]).removeClass(css[1]);\r
+\r
+                var h = [];\r
+                $headers.each(function (offset) {\r
+                    if (!this.sortDisabled) {\r
+                        h[this.column] = $(this);\r
+                    }\r
+                });\r
+\r
+                var l = list.length;\r
+                for (var i = 0; i < l; i++) {\r
+                    h[list[i][0]].addClass(css[list[i][1]]);\r
+                }\r
+            }\r
+\r
+            function fixColumnWidth(table, $headers) {\r
+                var c = table.config;\r
+                if (c.widthFixed) {\r
+                    var colgroup = $('<colgroup>');\r
+                    $("tr:first td", table.tBodies[0]).each(function () {\r
+                        colgroup.append($('<col>').css('width', $(this).width()));\r
+                    });\r
+                    $(table).prepend(colgroup);\r
+                };\r
+            }\r
+\r
+            function updateHeaderSortCount(table, sortList) {\r
+                var c = table.config,\r
+                    l = sortList.length;\r
+                for (var i = 0; i < l; i++) {\r
+                    var s = sortList[i],\r
+                        o = c.headerList[s[0]];\r
+                    o.count = s[1];\r
+                    o.count++;\r
+                }\r
+            }\r
+\r
+            /* sorting methods */\r
+\r
+            function multisort(table, sortList, cache) {\r
+\r
+                if (table.config.debug) {\r
+                    var sortTime = new Date();\r
+                }\r
+\r
+                var dynamicExp = "var sortWrapper = function(a,b) {",\r
+                    l = sortList.length;\r
+\r
+                // TODO: inline functions.\r
+                for (var i = 0; i < l; i++) {\r
+\r
+                    var c = sortList[i][0];\r
+                    var order = sortList[i][1];\r
+                    // var s = (getCachedSortType(table.config.parsers,c) == "text") ?\r
+                    // ((order == 0) ? "sortText" : "sortTextDesc") : ((order == 0) ?\r
+                    // "sortNumeric" : "sortNumericDesc");\r
+                    // var s = (table.config.parsers[c].type == "text") ? ((order == 0)\r
+                    // ? makeSortText(c) : makeSortTextDesc(c)) : ((order == 0) ?\r
+                    // makeSortNumeric(c) : makeSortNumericDesc(c));\r
+                    var s = (table.config.parsers[c].type == "text") ? ((order == 0) ? makeSortFunction("text", "asc", c) : makeSortFunction("text", "desc", c)) : ((order == 0) ? makeSortFunction("numeric", "asc", c) : makeSortFunction("numeric", "desc", c));\r
+                    var e = "e" + i;\r
+\r
+                    dynamicExp += "var " + e + " = " + s; // + "(a[" + c + "],b[" + c\r
+                    // + "]); ";\r
+                    dynamicExp += "if(" + e + ") { return " + e + "; } ";\r
+                    dynamicExp += "else { ";\r
+\r
+                }\r
+\r
+                // if value is the same keep orignal order\r
+                var orgOrderCol = cache.normalized[0].length - 1;\r
+                dynamicExp += "return a[" + orgOrderCol + "]-b[" + orgOrderCol + "];";\r
+\r
+                for (var i = 0; i < l; i++) {\r
+                    dynamicExp += "}; ";\r
+                }\r
+\r
+                dynamicExp += "return 0; ";\r
+                dynamicExp += "}; ";\r
+\r
+                if (table.config.debug) {\r
+                    benchmark("Evaling expression:" + dynamicExp, new Date());\r
+                }\r
+\r
+                eval(dynamicExp);\r
+\r
+                cache.normalized.sort(sortWrapper);\r
+\r
+                if (table.config.debug) {\r
+                    benchmark("Sorting on " + sortList.toString() + " and dir " + order + " time:", sortTime);\r
+                }\r
+\r
+                return cache;\r
+            };\r
+\r
+            function makeSortFunction(type, direction, index) {\r
+                var a = "a[" + index + "]",\r
+                    b = "b[" + index + "]";\r
+                if (type == 'text' && direction == 'asc') {\r
+                    return "(" + a + " == " + b + " ? 0 : (" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : (" + a + " < " + b + ") ? -1 : 1 )));";\r
+                } else if (type == 'text' && direction == 'desc') {\r
+                    return "(" + a + " == " + b + " ? 0 : (" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : (" + b + " < " + a + ") ? -1 : 1 )));";\r
+                } else if (type == 'numeric' && direction == 'asc') {\r
+                    return "(" + a + " === null && " + b + " === null) ? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : " + a + " - " + b + "));";\r
+                } else if (type == 'numeric' && direction == 'desc') {\r
+                    return "(" + a + " === null && " + b + " === null) ? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : " + b + " - " + a + "));";\r
+                }\r
+            };\r
+\r
+            function makeSortText(i) {\r
+                return "((a[" + i + "] < b[" + i + "]) ? -1 : ((a[" + i + "] > b[" + i + "]) ? 1 : 0));";\r
+            };\r
+\r
+            function makeSortTextDesc(i) {\r
+                return "((b[" + i + "] < a[" + i + "]) ? -1 : ((b[" + i + "] > a[" + i + "]) ? 1 : 0));";\r
+            };\r
+\r
+            function makeSortNumeric(i) {\r
+                return "a[" + i + "]-b[" + i + "];";\r
+            };\r
+\r
+            function makeSortNumericDesc(i) {\r
+                return "b[" + i + "]-a[" + i + "];";\r
+            };\r
+\r
+            function sortText(a, b) {\r
+                if (table.config.sortLocaleCompare) return a.localeCompare(b);\r
+                return ((a < b) ? -1 : ((a > b) ? 1 : 0));\r
+            };\r
+\r
+            function sortTextDesc(a, b) {\r
+                if (table.config.sortLocaleCompare) return b.localeCompare(a);\r
+                return ((b < a) ? -1 : ((b > a) ? 1 : 0));\r
+            };\r
+\r
+            function sortNumeric(a, b) {\r
+                return a - b;\r
+            };\r
+\r
+            function sortNumericDesc(a, b) {\r
+                return b - a;\r
+            };\r
+\r
+            function getCachedSortType(parsers, i) {\r
+                return parsers[i].type;\r
+            }; /* public methods */\r
+            this.construct = function (settings) {\r
+                return this.each(function () {\r
+                    // if no thead or tbody quit.\r
+                    if (!this.tHead || !this.tBodies) return;\r
+                    // declare\r
+                    var $this, $document, $headers, cache, config, shiftDown = 0,\r
+                        sortOrder;\r
+                    // new blank config object\r
+                    this.config = {};\r
+                    // merge and extend.\r
+                    config = $.extend(this.config, $.tablesorter.defaults, settings);\r
+                    // store common expression for speed\r
+                    $this = $(this);\r
+                    // save the settings where they read\r
+                    $.data(this, "tablesorter", config);\r
+                    // build headers\r
+                    $headers = buildHeaders(this);\r
+                    // try to auto detect column type, and store in tables config\r
+                    this.config.parsers = buildParserCache(this, $headers);\r
+                    // build the cache for the tbody cells\r
+                    cache = buildCache(this);\r
+                    // get the css class names, could be done else where.\r
+                    var sortCSS = [config.cssDesc, config.cssAsc];\r
+                    // fixate columns if the users supplies the fixedWidth option\r
+                    fixColumnWidth(this);\r
+                    // apply event handling to headers\r
+                    // this is to big, perhaps break it out?\r
+                    $headers.click(\r
+\r
+                    function (e) {\r
+                        var totalRows = ($this[0].tBodies[0] && $this[0].tBodies[0].rows.length) || 0;\r
+                        if (!this.sortDisabled && totalRows > 0) {\r
+                            // Only call sortStart if sorting is\r
+                            // enabled.\r
+                            $this.trigger("sortStart");\r
+                            // store exp, for speed\r
+                            var $cell = $(this);\r
+                            // get current column index\r
+                            var i = this.column;\r
+                            // get current column sort order\r
+                            this.order = this.count++ % 2;\r
+                                                       // always sort on the locked order.\r
+                                                       if(this.lockedOrder) this.order = this.lockedOrder;\r
+                                                       \r
+                                                       // user only whants to sort on one\r
+                            // column\r
+                            if (!e[config.sortMultiSortKey]) {\r
+                                // flush the sort list\r
+                                config.sortList = [];\r
+                                if (config.sortForce != null) {\r
+                                    var a = config.sortForce;\r
+                                    for (var j = 0; j < a.length; j++) {\r
+                                        if (a[j][0] != i) {\r
+                                            config.sortList.push(a[j]);\r
+                                        }\r
+                                    }\r
+                                }\r
+                                // add column to sort list\r
+                                config.sortList.push([i, this.order]);\r
+                                // multi column sorting\r
+                            } else {\r
+                                // the user has clicked on an all\r
+                                // ready sortet column.\r
+                                if (isValueInArray(i, config.sortList)) {\r
+                                    // revers the sorting direction\r
+                                    // for all tables.\r
+                                    for (var j = 0; j < config.sortList.length; j++) {\r
+                                        var s = config.sortList[j],\r
+                                            o = config.headerList[s[0]];\r
+                                        if (s[0] == i) {\r
+                                            o.count = s[1];\r
+                                            o.count++;\r
+                                            s[1] = o.count % 2;\r
+                                        }\r
+                                    }\r
+                                } else {\r
+                                    // add column to sort list array\r
+                                    config.sortList.push([i, this.order]);\r
+                                }\r
+                            };\r
+                            setTimeout(function () {\r
+                                // set css for headers\r
+                                setHeadersCss($this[0], $headers, config.sortList, sortCSS);\r
+                                appendToTable(\r
+                                       $this[0], multisort(\r
+                                       $this[0], config.sortList, cache)\r
+                                                               );\r
+                            }, 1);\r
+                            // stop normal event by returning false\r
+                            return false;\r
+                        }\r
+                        // cancel selection\r
+                    }).mousedown(function () {\r
+                        if (config.cancelSelection) {\r
+                            this.onselectstart = function () {\r
+                                return false\r
+                            };\r
+                            return false;\r
+                        }\r
+                    });\r
+                    // apply easy methods that trigger binded events\r
+                    $this.bind("update", function () {\r
+                        var me = this;\r
+                        setTimeout(function () {\r
+                            // rebuild parsers.\r
+                            me.config.parsers = buildParserCache(\r
+                            me, $headers);\r
+                            // rebuild the cache map\r
+                            cache = buildCache(me);\r
+                        }, 1);\r
+                    }).bind("updateCell", function (e, cell) {\r
+                        var config = this.config;\r
+                        // get position from the dom.\r
+                        var pos = [(cell.parentNode.rowIndex - 1), cell.cellIndex];\r
+                        // update cache\r
+                        cache.normalized[pos[0]][pos[1]] = config.parsers[pos[1]].format(\r
+                        getElementText(config, cell), cell);\r
+                    }).bind("sorton", function (e, list) {\r
+                        $(this).trigger("sortStart");\r
+                        config.sortList = list;\r
+                        // update and store the sortlist\r
+                        var sortList = config.sortList;\r
+                        // update header count index\r
+                        updateHeaderSortCount(this, sortList);\r
+                        // set css for headers\r
+                        setHeadersCss(this, $headers, sortList, sortCSS);\r
+                        // sort the table and append it to the dom\r
+                        appendToTable(this, multisort(this, sortList, cache));\r
+                    }).bind("appendCache", function () {\r
+                        appendToTable(this, cache);\r
+                    }).bind("applyWidgetId", function (e, id) {\r
+                        getWidgetById(id).format(this);\r
+                    }).bind("applyWidgets", function () {\r
+                        // apply widgets\r
+                        applyWidget(this);\r
+                    });\r
+                    if ($.metadata && ($(this).metadata() && $(this).metadata().sortlist)) {\r
+                        config.sortList = $(this).metadata().sortlist;\r
+                    }\r
+                    // if user has supplied a sort list to constructor.\r
+                    if (config.sortList.length > 0) {\r
+                        $this.trigger("sorton", [config.sortList]);\r
+                    }\r
+                    // apply widgets\r
+                    applyWidget(this);\r
+                });\r
+            };\r
+            this.addParser = function (parser) {\r
+                var l = parsers.length,\r
+                    a = true;\r
+                for (var i = 0; i < l; i++) {\r
+                    if (parsers[i].id.toLowerCase() == parser.id.toLowerCase()) {\r
+                        a = false;\r
+                    }\r
+                }\r
+                if (a) {\r
+                    parsers.push(parser);\r
+                };\r
+            };\r
+            this.addWidget = function (widget) {\r
+                widgets.push(widget);\r
+            };\r
+            this.formatFloat = function (s) {\r
+                var i = parseFloat(s);\r
+                return (isNaN(i)) ? 0 : i;\r
+            };\r
+            this.formatInt = function (s) {\r
+                var i = parseInt(s);\r
+                return (isNaN(i)) ? 0 : i;\r
+            };\r
+            this.isDigit = function (s, config) {\r
+                // replace all an wanted chars and match.\r
+                return /^[-+]?\d*$/.test($.trim(s.replace(/[,.']/g, '')));\r
+            };\r
+            this.clearTableBody = function (table) {\r
+                if ($.browser.msie) {\r
+                    function empty() {\r
+                        while (this.firstChild)\r
+                        this.removeChild(this.firstChild);\r
+                    }\r
+                    empty.apply(table.tBodies[0]);\r
+                } else {\r
+                    table.tBodies[0].innerHTML = "";\r
+                }\r
+            };\r
+        }\r
+    });\r
+\r
+    // extend plugin scope\r
+    $.fn.extend({\r
+        tablesorter: $.tablesorter.construct\r
+    });\r
+\r
+    // make shortcut\r
+    var ts = $.tablesorter;\r
+\r
+    // add default parsers\r
+    ts.addParser({\r
+        id: "text",\r
+        is: function (s) {\r
+            return true;\r
+        }, format: function (s) {\r
+            return $.trim(s.toLocaleLowerCase());\r
+        }, type: "text"\r
+    });\r
+\r
+    ts.addParser({\r
+        id: "digit",\r
+        is: function (s, table) {\r
+            var c = table.config;\r
+            return $.tablesorter.isDigit(s, c);\r
+        }, format: function (s) {\r
+            return $.tablesorter.formatFloat(s);\r
+        }, type: "numeric"\r
+    });\r
+\r
+    ts.addParser({\r
+        id: "currency",\r
+        is: function (s) {\r
+            return /^[£$€?.]/.test(s);\r
+        }, format: function (s) {\r
+            return $.tablesorter.formatFloat(s.replace(new RegExp(/[£$€]/g), ""));\r
+        }, type: "numeric"\r
+    });\r
+\r
+    ts.addParser({\r
+        id: "ipAddress",\r
+        is: function (s) {\r
+            return /^\d{2,3}[\.]\d{2,3}[\.]\d{2,3}[\.]\d{2,3}$/.test(s);\r
+        }, format: function (s) {\r
+            var a = s.split("."),\r
+                r = "",\r
+                l = a.length;\r
+            for (var i = 0; i < l; i++) {\r
+                var item = a[i];\r
+                if (item.length == 2) {\r
+                    r += "0" + item;\r
+                } else {\r
+                    r += item;\r
+                }\r
+            }\r
+            return $.tablesorter.formatFloat(r);\r
+        }, type: "numeric"\r
+    });\r
+\r
+    ts.addParser({\r
+        id: "url",\r
+        is: function (s) {\r
+            return /^(https?|ftp|file):\/\/$/.test(s);\r
+        }, format: function (s) {\r
+            return jQuery.trim(s.replace(new RegExp(/(https?|ftp|file):\/\//), ''));\r
+        }, type: "text"\r
+    });\r
+\r
+    ts.addParser({\r
+        id: "isoDate",\r
+        is: function (s) {\r
+            return /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(s);\r
+        }, format: function (s) {\r
+            return $.tablesorter.formatFloat((s != "") ? new Date(s.replace(\r
+            new RegExp(/-/g), "/")).getTime() : "0");\r
+        }, type: "numeric"\r
+    });\r
+\r
+    ts.addParser({\r
+        id: "percent",\r
+        is: function (s) {\r
+            return /\%$/.test($.trim(s));\r
+        }, format: function (s) {\r
+            return $.tablesorter.formatFloat(s.replace(new RegExp(/%/g), ""));\r
+        }, type: "numeric"\r
+    });\r
+\r
+    ts.addParser({\r
+        id: "usLongDate",\r
+        is: function (s) {\r
+            return s.match(new RegExp(/^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/));\r
+        }, format: function (s) {\r
+            return $.tablesorter.formatFloat(new Date(s).getTime());\r
+        }, type: "numeric"\r
+    });\r
+\r
+    ts.addParser({\r
+        id: "shortDate",\r
+        is: function (s) {\r
+            return /\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2,4}/.test(s);\r
+        }, format: function (s, table) {\r
+            var c = table.config;\r
+            s = s.replace(/\-/g, "/");\r
+            if (c.dateFormat == "us") {\r
+                // reformat the string in ISO format\r
+                s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3/$1/$2");\r
+            } else if (c.dateFormat == "uk") {\r
+                // reformat the string in ISO format\r
+                s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3/$2/$1");\r
+            } else if (c.dateFormat == "dd/mm/yy" || c.dateFormat == "dd-mm-yy") {\r
+                s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2})/, "$1/$2/$3");\r
+            }\r
+            return $.tablesorter.formatFloat(new Date(s).getTime());\r
+        }, type: "numeric"\r
+    });\r
+    ts.addParser({\r
+        id: "time",\r
+        is: function (s) {\r
+            return /^(([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/.test(s);\r
+        }, format: function (s) {\r
+            return $.tablesorter.formatFloat(new Date("2000/01/01 " + s).getTime());\r
+        }, type: "numeric"\r
+    });\r
+    ts.addParser({\r
+        id: "metadata",\r
+        is: function (s) {\r
+            return false;\r
+        }, format: function (s, table, cell) {\r
+            var c = table.config,\r
+                p = (!c.parserMetadataName) ? 'sortValue' : c.parserMetadataName;\r
+            return $(cell).metadata()[p];\r
+        }, type: "numeric"\r
+    });\r
+    // add default widgets\r
+    ts.addWidget({\r
+        id: "zebra",\r
+        format: function (table) {\r
+            if (table.config.debug) {\r
+                var time = new Date();\r
+            }\r
+            var $tr, row = -1,\r
+                odd;\r
+            // loop through the visible rows\r
+            $("tr:visible", table.tBodies[0]).each(function (i) {\r
+                $tr = $(this);\r
+                // style children rows the same way the parent\r
+                // row was styled\r
+                if (!$tr.hasClass(table.config.cssChildRow)) row++;\r
+                odd = (row % 2 == 0);\r
+                $tr.removeClass(\r
+                table.config.widgetZebra.css[odd ? 0 : 1]).addClass(\r
+                table.config.widgetZebra.css[odd ? 1 : 0])\r
+            });\r
+            if (table.config.debug) {\r
+                $.tablesorter.benchmark("Applying Zebra widget", time);\r
+            }\r
+        }\r
+    });\r
+})(jQuery);
\ No newline at end of file
diff --git a/reports/reports/js/picnet.table.filter.min.js b/reports/reports/js/picnet.table.filter.min.js
new file mode 100644 (file)
index 0000000..444342c
--- /dev/null
@@ -0,0 +1,178 @@
+function $JSCompiler_alias_THROW$$($jscomp_throw_param$$){throw $jscomp_throw_param$$;}var $JSCompiler_alias_VOID$$=void 0,$JSCompiler_alias_TRUE$$=!0,$JSCompiler_alias_NULL$$=null,$JSCompiler_alias_FALSE$$=!1,$JSCompiler_prototypeAlias$$,$goog$global$$=this;\r
+function $goog$typeOf$$($value$$38$$){var $s$$2$$=typeof $value$$38$$;if("object"==$s$$2$$)if($value$$38$$){if($value$$38$$ instanceof Array)return"array";if($value$$38$$ instanceof Object)return $s$$2$$;var $className$$1$$=Object.prototype.toString.call($value$$38$$);if("[object Window]"==$className$$1$$)return"object";if("[object Array]"==$className$$1$$||"number"==typeof $value$$38$$.length&&"undefined"!=typeof $value$$38$$.splice&&"undefined"!=typeof $value$$38$$.propertyIsEnumerable&&!$value$$38$$.propertyIsEnumerable("splice"))return"array";\r
+if("[object Function]"==$className$$1$$||"undefined"!=typeof $value$$38$$.call&&"undefined"!=typeof $value$$38$$.propertyIsEnumerable&&!$value$$38$$.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"==$s$$2$$&&"undefined"==typeof $value$$38$$.call)return"object";return $s$$2$$}function $goog$isArrayLike$$($val$$4$$){var $type$$46$$=$goog$typeOf$$($val$$4$$);return"array"==$type$$46$$||"object"==$type$$46$$&&"number"==typeof $val$$4$$.length}\r
+function $goog$isString$$($val$$6$$){return"string"==typeof $val$$6$$}function $goog$isFunction$$($val$$9$$){return"function"==$goog$typeOf$$($val$$9$$)}function $goog$isObject$$($type$$47_val$$10$$){$type$$47_val$$10$$=$goog$typeOf$$($type$$47_val$$10$$);return"object"==$type$$47_val$$10$$||"array"==$type$$47_val$$10$$||"function"==$type$$47_val$$10$$}var $goog$UID_PROPERTY_$$="closure_uid_"+Math.floor(2147483648*Math.random()).toString(36),$goog$uidCounter_$$=0;\r
+function $goog$bindNative_$$($fn$$,$selfObj$$1$$,$var_args$$17$$){return $fn$$.call.apply($fn$$.bind,arguments)}\r
+function $goog$bindJs_$$($fn$$1$$,$selfObj$$2$$,$var_args$$18$$){$fn$$1$$||$JSCompiler_alias_THROW$$(Error());if(2<arguments.length){var $boundArgs$$=Array.prototype.slice.call(arguments,2);return function(){var $newArgs$$=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply($newArgs$$,$boundArgs$$);return $fn$$1$$.apply($selfObj$$2$$,$newArgs$$)}}return function(){return $fn$$1$$.apply($selfObj$$2$$,arguments)}}\r
+function $goog$bind$$($fn$$2$$,$selfObj$$3$$,$var_args$$19$$){$goog$bind$$=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?$goog$bindNative_$$:$goog$bindJs_$$;return $goog$bind$$.apply($JSCompiler_alias_NULL$$,arguments)}\r
+function $goog$partial$$($fn$$3$$,$var_args$$20$$){var $args$$=Array.prototype.slice.call(arguments,1);return function(){var $newArgs$$1$$=Array.prototype.slice.call(arguments);$newArgs$$1$$.unshift.apply($newArgs$$1$$,$args$$);return $fn$$3$$.apply(this,$newArgs$$1$$)}}var $goog$now$$=Date.now||function(){return+new Date};\r
+function $goog$inherits$$($childCtor$$,$parentCtor$$){function $tempCtor$$(){}$tempCtor$$.prototype=$parentCtor$$.prototype;$childCtor$$.$superClass_$=$parentCtor$$.prototype;$childCtor$$.prototype=new $tempCtor$$};function $goog$string$subs$$($str$$12$$,$var_args$$22$$){for(var $i$$5$$=1;$i$$5$$<arguments.length;$i$$5$$++)var $replacement$$=(""+arguments[$i$$5$$]).replace(/\$/g,"$$$$"),$str$$12$$=$str$$12$$.replace(/\%s/,$replacement$$);return $str$$12$$}function $goog$string$trim$$($str$$25$$){return $str$$25$$.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")}\r
+function $goog$string$htmlEscape$$($str$$31$$){if(!$goog$string$allRe_$$.test($str$$31$$))return $str$$31$$;-1!=$str$$31$$.indexOf("&")&&($str$$31$$=$str$$31$$.replace($goog$string$amperRe_$$,"&amp;"));-1!=$str$$31$$.indexOf("<")&&($str$$31$$=$str$$31$$.replace($goog$string$ltRe_$$,"&lt;"));-1!=$str$$31$$.indexOf(">")&&($str$$31$$=$str$$31$$.replace($goog$string$gtRe_$$,"&gt;"));-1!=$str$$31$$.indexOf('"')&&($str$$31$$=$str$$31$$.replace($goog$string$quotRe_$$,"&quot;"));return $str$$31$$}\r
+var $goog$string$amperRe_$$=/&/g,$goog$string$ltRe_$$=/</g,$goog$string$gtRe_$$=/>/g,$goog$string$quotRe_$$=/\"/g,$goog$string$allRe_$$=/[&<>\"]/,$goog$string$toCamelCaseCache_$$={};function $goog$string$toCamelCase$$($str$$42$$){return $goog$string$toCamelCaseCache_$$[$str$$42$$]||($goog$string$toCamelCaseCache_$$[$str$$42$$]=(""+$str$$42$$).replace(/\-([a-z])/g,function($all$$,$match$$){return $match$$.toUpperCase()}))};var $goog$userAgent$detectedOpera_$$,$goog$userAgent$detectedIe_$$,$goog$userAgent$detectedWebkit_$$,$goog$userAgent$detectedGecko_$$;function $goog$userAgent$getUserAgentString$$(){return $goog$global$$.navigator?$goog$global$$.navigator.userAgent:$JSCompiler_alias_NULL$$}$goog$userAgent$detectedGecko_$$=$goog$userAgent$detectedWebkit_$$=$goog$userAgent$detectedIe_$$=$goog$userAgent$detectedOpera_$$=$JSCompiler_alias_FALSE$$;var $ua$$inline_9$$;\r
+if($ua$$inline_9$$=$goog$userAgent$getUserAgentString$$()){var $navigator$$inline_10$$=$goog$global$$.navigator;$goog$userAgent$detectedOpera_$$=0==$ua$$inline_9$$.indexOf("Opera");$goog$userAgent$detectedIe_$$=!$goog$userAgent$detectedOpera_$$&&-1!=$ua$$inline_9$$.indexOf("MSIE");$goog$userAgent$detectedWebkit_$$=!$goog$userAgent$detectedOpera_$$&&-1!=$ua$$inline_9$$.indexOf("WebKit");$goog$userAgent$detectedGecko_$$=!$goog$userAgent$detectedOpera_$$&&!$goog$userAgent$detectedWebkit_$$&&"Gecko"==\r
+$navigator$$inline_10$$.product}var $goog$userAgent$OPERA$$=$goog$userAgent$detectedOpera_$$,$goog$userAgent$IE$$=$goog$userAgent$detectedIe_$$,$goog$userAgent$GECKO$$=$goog$userAgent$detectedGecko_$$,$goog$userAgent$WEBKIT$$=$goog$userAgent$detectedWebkit_$$,$navigator$$inline_12$$=$goog$global$$.navigator,$goog$userAgent$MAC$$=-1!=($navigator$$inline_12$$&&$navigator$$inline_12$$.platform||"").indexOf("Mac"),$goog$userAgent$VERSION$$;\r
+a:{var $version$$inline_15$$="",$re$$inline_16$$;if($goog$userAgent$OPERA$$&&$goog$global$$.opera)var $operaVersion$$inline_17$$=$goog$global$$.opera.version,$version$$inline_15$$="function"==typeof $operaVersion$$inline_17$$?$operaVersion$$inline_17$$():$operaVersion$$inline_17$$;else if($goog$userAgent$GECKO$$?$re$$inline_16$$=/rv\:([^\);]+)(\)|;)/:$goog$userAgent$IE$$?$re$$inline_16$$=/MSIE\s+([^\);]+)(\)|;)/:$goog$userAgent$WEBKIT$$&&($re$$inline_16$$=/WebKit\/(\S+)/),$re$$inline_16$$)var $arr$$inline_18$$=\r
+$re$$inline_16$$.exec($goog$userAgent$getUserAgentString$$()),$version$$inline_15$$=$arr$$inline_18$$?$arr$$inline_18$$[1]:"";if($goog$userAgent$IE$$){var $docMode$$inline_19$$,$doc$$inline_137$$=$goog$global$$.document;$docMode$$inline_19$$=$doc$$inline_137$$?$doc$$inline_137$$.documentMode:$JSCompiler_alias_VOID$$;if($docMode$$inline_19$$>parseFloat($version$$inline_15$$)){$goog$userAgent$VERSION$$=""+$docMode$$inline_19$$;break a}}$goog$userAgent$VERSION$$=$version$$inline_15$$}\r
+var $goog$userAgent$isVersionCache_$$={};\r
+function $goog$userAgent$isVersion$$($version$$8$$){var $JSCompiler_temp$$5_order$$inline_23$$;if(!($JSCompiler_temp$$5_order$$inline_23$$=$goog$userAgent$isVersionCache_$$[$version$$8$$])){$JSCompiler_temp$$5_order$$inline_23$$=0;for(var $v1Subs$$inline_24$$=$goog$string$trim$$(""+$goog$userAgent$VERSION$$).split("."),$v2Subs$$inline_25$$=$goog$string$trim$$(""+$version$$8$$).split("."),$subCount$$inline_26$$=Math.max($v1Subs$$inline_24$$.length,$v2Subs$$inline_25$$.length),$subIdx$$inline_27$$=\r
+0;0==$JSCompiler_temp$$5_order$$inline_23$$&&$subIdx$$inline_27$$<$subCount$$inline_26$$;$subIdx$$inline_27$$++){var $v1Sub$$inline_28$$=$v1Subs$$inline_24$$[$subIdx$$inline_27$$]||"",$v2Sub$$inline_29$$=$v2Subs$$inline_25$$[$subIdx$$inline_27$$]||"",$v1CompParser$$inline_30$$=RegExp("(\\d*)(\\D*)","g"),$v2CompParser$$inline_31$$=RegExp("(\\d*)(\\D*)","g");do{var $v1Comp$$inline_32$$=$v1CompParser$$inline_30$$.exec($v1Sub$$inline_28$$)||["","",""],$v2Comp$$inline_33$$=$v2CompParser$$inline_31$$.exec($v2Sub$$inline_29$$)||\r
+["","",""];if(0==$v1Comp$$inline_32$$[0].length&&0==$v2Comp$$inline_33$$[0].length)break;$JSCompiler_temp$$5_order$$inline_23$$=((0==$v1Comp$$inline_32$$[1].length?0:parseInt($v1Comp$$inline_32$$[1],10))<(0==$v2Comp$$inline_33$$[1].length?0:parseInt($v2Comp$$inline_33$$[1],10))?-1:(0==$v1Comp$$inline_32$$[1].length?0:parseInt($v1Comp$$inline_32$$[1],10))>(0==$v2Comp$$inline_33$$[1].length?0:parseInt($v2Comp$$inline_33$$[1],10))?1:0)||((0==$v1Comp$$inline_32$$[2].length)<(0==$v2Comp$$inline_33$$[2].length)?\r
+-1:(0==$v1Comp$$inline_32$$[2].length)>(0==$v2Comp$$inline_33$$[2].length)?1:0)||($v1Comp$$inline_32$$[2]<$v2Comp$$inline_33$$[2]?-1:$v1Comp$$inline_32$$[2]>$v2Comp$$inline_33$$[2]?1:0)}while(0==$JSCompiler_temp$$5_order$$inline_23$$)}$JSCompiler_temp$$5_order$$inline_23$$=$goog$userAgent$isVersionCache_$$[$version$$8$$]=0<=$JSCompiler_temp$$5_order$$inline_23$$}return $JSCompiler_temp$$5_order$$inline_23$$}var $goog$userAgent$isDocumentModeCache_$$={};\r
+function $goog$userAgent$isDocumentMode$$(){return $goog$userAgent$isDocumentModeCache_$$[9]||($goog$userAgent$isDocumentModeCache_$$[9]=$goog$userAgent$IE$$&&document.documentMode&&9<=document.documentMode)};function $goog$object$forEach$$($obj$$21$$,$f$$){for(var $key$$16$$ in $obj$$21$$)$f$$.call($JSCompiler_alias_VOID$$,$obj$$21$$[$key$$16$$],$key$$16$$,$obj$$21$$)}var $goog$object$PROTOTYPE_FIELDS_$$="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",");\r
+function $goog$object$extend$$($target$$35$$,$var_args$$25$$){for(var $key$$39$$,$source$$2$$,$i$$16$$=1;$i$$16$$<arguments.length;$i$$16$$++){$source$$2$$=arguments[$i$$16$$];for($key$$39$$ in $source$$2$$)$target$$35$$[$key$$39$$]=$source$$2$$[$key$$39$$];for(var $j$$1$$=0;$j$$1$$<$goog$object$PROTOTYPE_FIELDS_$$.length;$j$$1$$++)$key$$39$$=$goog$object$PROTOTYPE_FIELDS_$$[$j$$1$$],Object.prototype.hasOwnProperty.call($source$$2$$,$key$$39$$)&&($target$$35$$[$key$$39$$]=$source$$2$$[$key$$39$$])}}\r
+;function $goog$debug$Error$$($opt_msg$$){this.stack=Error().stack||"";if($opt_msg$$)this.message=""+$opt_msg$$}$goog$inherits$$($goog$debug$Error$$,Error);$goog$debug$Error$$.prototype.name="CustomError";function $goog$asserts$AssertionError$$($messagePattern$$,$messageArgs$$){$messageArgs$$.unshift($messagePattern$$);$goog$debug$Error$$.call(this,$goog$string$subs$$.apply($JSCompiler_alias_NULL$$,$messageArgs$$));$messageArgs$$.shift();this.$messagePattern$=$messagePattern$$}$goog$inherits$$($goog$asserts$AssertionError$$,$goog$debug$Error$$);$goog$asserts$AssertionError$$.prototype.name="AssertionError";\r
+function $goog$asserts$assert$$($condition$$,$opt_message$$8$$,$var_args$$29$$){if(!$condition$$){var $givenArgs$$inline_36$$=Array.prototype.slice.call(arguments,2),$message$$inline_37$$="Assertion failed";if($opt_message$$8$$)var $message$$inline_37$$=$message$$inline_37$$+(": "+$opt_message$$8$$),$args$$inline_38$$=$givenArgs$$inline_36$$;$JSCompiler_alias_THROW$$(new $goog$asserts$AssertionError$$(""+$message$$inline_37$$,$args$$inline_38$$||[]))}};var $goog$array$ARRAY_PROTOTYPE_$$=Array.prototype;function $goog$array$indexOf$$($arr$$12$$,$obj$$48$$){if($goog$isString$$($arr$$12$$))return!$goog$isString$$($obj$$48$$)||1!=$obj$$48$$.length?-1:$arr$$12$$.indexOf($obj$$48$$,0);for(var $i$$20$$=0;$i$$20$$<$arr$$12$$.length;$i$$20$$++)if($i$$20$$ in $arr$$12$$&&$arr$$12$$[$i$$20$$]===$obj$$48$$)return $i$$20$$;return-1}\r
+function $goog$array$forEach$$($arr$$16$$,$f$$8$$,$opt_obj$$7$$){for(var $l$$2$$=$arr$$16$$.length,$arr2$$=$goog$isString$$($arr$$16$$)?$arr$$16$$.split(""):$arr$$16$$,$i$$22$$=0;$i$$22$$<$l$$2$$;$i$$22$$++)$i$$22$$ in $arr2$$&&$f$$8$$.call($opt_obj$$7$$,$arr2$$[$i$$22$$],$i$$22$$,$arr$$16$$)}\r
+function $goog$array$map$$($arr$$21$$,$f$$13$$,$opt_obj$$12$$){for(var $l$$5$$=$arr$$21$$.length,$res$$6$$=Array($l$$5$$),$arr2$$3$$=$goog$isString$$($arr$$21$$)?$arr$$21$$.split(""):$arr$$21$$,$i$$25$$=0;$i$$25$$<$l$$5$$;$i$$25$$++)$i$$25$$ in $arr2$$3$$&&($res$$6$$[$i$$25$$]=$f$$13$$.call($opt_obj$$12$$,$arr2$$3$$[$i$$25$$],$i$$25$$,$arr$$21$$));return $res$$6$$}\r
+function $goog$array$concat$$($var_args$$38$$){return $goog$array$ARRAY_PROTOTYPE_$$.concat.apply($goog$array$ARRAY_PROTOTYPE_$$,arguments)}function $goog$array$clone$$($arr$$42$$){if("array"==$goog$typeOf$$($arr$$42$$))return $goog$array$concat$$($arr$$42$$);for(var $rv$$7$$=[],$i$$37$$=0,$len$$=$arr$$42$$.length;$i$$37$$<$len$$;$i$$37$$++)$rv$$7$$[$i$$37$$]=$arr$$42$$[$i$$37$$];return $rv$$7$$}\r
+function $goog$array$slice$$($arr$$44$$,$start$$5$$,$opt_end$$5$$){$goog$asserts$assert$$($arr$$44$$.length!=$JSCompiler_alias_NULL$$);return 2>=arguments.length?$goog$array$ARRAY_PROTOTYPE_$$.slice.call($arr$$44$$,$start$$5$$):$goog$array$ARRAY_PROTOTYPE_$$.slice.call($arr$$44$$,$start$$5$$,$opt_end$$5$$)};function $goog$dom$classes$add$$($element$$10$$,$var_args$$43$$){var $className$$inline_140_classes$$;$className$$inline_140_classes$$=($className$$inline_140_classes$$=$element$$10$$.className)&&"function"==typeof $className$$inline_140_classes$$.split?$className$$inline_140_classes$$.split(/\s+/):[];var $args$$3_args$$inline_41$$=$goog$array$slice$$(arguments,1),$b$$18_classes$$inline_40$$;$b$$18_classes$$inline_40$$=$className$$inline_140_classes$$;for(var $rv$$inline_42$$=0,$i$$inline_43$$=0;$i$$inline_43$$<\r
+$args$$3_args$$inline_41$$.length;$i$$inline_43$$++)0<=$goog$array$indexOf$$($b$$18_classes$$inline_40$$,$args$$3_args$$inline_41$$[$i$$inline_43$$])||($b$$18_classes$$inline_40$$.push($args$$3_args$$inline_41$$[$i$$inline_43$$]),$rv$$inline_42$$++);$b$$18_classes$$inline_40$$=$rv$$inline_42$$==$args$$3_args$$inline_41$$.length;$element$$10$$.className=$className$$inline_140_classes$$.join(" ");return $b$$18_classes$$inline_40$$};var $goog$dom$BrowserFeature$CAN_ADD_NAME_OR_TYPE_ATTRIBUTES$$=!$goog$userAgent$IE$$||$goog$userAgent$isDocumentMode$$();!$goog$userAgent$GECKO$$&&!$goog$userAgent$IE$$||$goog$userAgent$IE$$&&$goog$userAgent$isDocumentMode$$()||$goog$userAgent$GECKO$$&&$goog$userAgent$isVersion$$("1.9.1");var $goog$dom$BrowserFeature$CAN_USE_INNER_TEXT$$=$goog$userAgent$IE$$&&!$goog$userAgent$isVersion$$("9");function $goog$dom$getElementsByTagNameAndClass_$$($className$$10_opt_tag$$1_tagName$$1$$,$opt_class$$1$$,$els_opt_el$$3_parent$$5$$){$els_opt_el$$3_parent$$5$$=$els_opt_el$$3_parent$$5$$||document;$className$$10_opt_tag$$1_tagName$$1$$=$className$$10_opt_tag$$1_tagName$$1$$&&"*"!=$className$$10_opt_tag$$1_tagName$$1$$?$className$$10_opt_tag$$1_tagName$$1$$.toUpperCase():"";if($els_opt_el$$3_parent$$5$$.querySelectorAll&&$els_opt_el$$3_parent$$5$$.querySelector&&(!$goog$userAgent$WEBKIT$$||"CSS1Compat"==\r
+document.compatMode||$goog$userAgent$isVersion$$("528"))&&($className$$10_opt_tag$$1_tagName$$1$$||$opt_class$$1$$))return $els_opt_el$$3_parent$$5$$.querySelectorAll($className$$10_opt_tag$$1_tagName$$1$$+($opt_class$$1$$?"."+$opt_class$$1$$:""));if($opt_class$$1$$&&$els_opt_el$$3_parent$$5$$.getElementsByClassName){$els_opt_el$$3_parent$$5$$=$els_opt_el$$3_parent$$5$$.getElementsByClassName($opt_class$$1$$);if($className$$10_opt_tag$$1_tagName$$1$$){for(var $arrayLike$$={},$len$$1$$=0,$i$$51$$=\r
+0,$el$$1$$;$el$$1$$=$els_opt_el$$3_parent$$5$$[$i$$51$$];$i$$51$$++)$className$$10_opt_tag$$1_tagName$$1$$==$el$$1$$.nodeName&&($arrayLike$$[$len$$1$$++]=$el$$1$$);$arrayLike$$.length=$len$$1$$;return $arrayLike$$}return $els_opt_el$$3_parent$$5$$}$els_opt_el$$3_parent$$5$$=$els_opt_el$$3_parent$$5$$.getElementsByTagName($className$$10_opt_tag$$1_tagName$$1$$||"*");if($opt_class$$1$$){$arrayLike$$={};for($i$$51$$=$len$$1$$=0;$el$$1$$=$els_opt_el$$3_parent$$5$$[$i$$51$$];$i$$51$$++)$className$$10_opt_tag$$1_tagName$$1$$=\r
+$el$$1$$.className,"function"==typeof $className$$10_opt_tag$$1_tagName$$1$$.split&&0<=$goog$array$indexOf$$($className$$10_opt_tag$$1_tagName$$1$$.split(/\s+/),$opt_class$$1$$)&&($arrayLike$$[$len$$1$$++]=$el$$1$$);$arrayLike$$.length=$len$$1$$;return $arrayLike$$}return $els_opt_el$$3_parent$$5$$}\r
+function $goog$dom$setProperties$$($element$$18$$,$properties$$){$goog$object$forEach$$($properties$$,function($val$$19$$,$key$$43$$){"style"==$key$$43$$?$element$$18$$.style.cssText=$val$$19$$:"class"==$key$$43$$?$element$$18$$.className=$val$$19$$:"for"==$key$$43$$?$element$$18$$.htmlFor=$val$$19$$:$key$$43$$ in $goog$dom$DIRECT_ATTRIBUTE_MAP_$$?$element$$18$$.setAttribute($goog$dom$DIRECT_ATTRIBUTE_MAP_$$[$key$$43$$],$val$$19$$):0==$key$$43$$.lastIndexOf("aria-",0)?$element$$18$$.setAttribute($key$$43$$,\r
+$val$$19$$):$element$$18$$[$key$$43$$]=$val$$19$$})}var $goog$dom$DIRECT_ATTRIBUTE_MAP_$$={cellpadding:"cellPadding",cellspacing:"cellSpacing",colspan:"colSpan",rowspan:"rowSpan",valign:"vAlign",height:"height",width:"width",usemap:"useMap",frameborder:"frameBorder",maxlength:"maxLength",type:"type"};\r
+function $goog$dom$createDom$$($tagName$$2$$,$opt_attributes$$,$var_args$$45$$){var $args$$inline_46$$=arguments,$doc$$inline_47$$=document,$element$$inline_52_tagName$$inline_48_tagNameArr$$inline_50$$=$args$$inline_46$$[0],$attributes$$inline_49$$=$args$$inline_46$$[1];if(!$goog$dom$BrowserFeature$CAN_ADD_NAME_OR_TYPE_ATTRIBUTES$$&&$attributes$$inline_49$$&&($attributes$$inline_49$$.name||$attributes$$inline_49$$.type)){$element$$inline_52_tagName$$inline_48_tagNameArr$$inline_50$$=["<",$element$$inline_52_tagName$$inline_48_tagNameArr$$inline_50$$];\r
+$attributes$$inline_49$$.name&&$element$$inline_52_tagName$$inline_48_tagNameArr$$inline_50$$.push(' name="',$goog$string$htmlEscape$$($attributes$$inline_49$$.name),'"');if($attributes$$inline_49$$.type){$element$$inline_52_tagName$$inline_48_tagNameArr$$inline_50$$.push(' type="',$goog$string$htmlEscape$$($attributes$$inline_49$$.type),'"');var $clone$$inline_51$$={};$goog$object$extend$$($clone$$inline_51$$,$attributes$$inline_49$$);$attributes$$inline_49$$=$clone$$inline_51$$;delete $attributes$$inline_49$$.type}$element$$inline_52_tagName$$inline_48_tagNameArr$$inline_50$$.push(">");\r
+$element$$inline_52_tagName$$inline_48_tagNameArr$$inline_50$$=$element$$inline_52_tagName$$inline_48_tagNameArr$$inline_50$$.join("")}$element$$inline_52_tagName$$inline_48_tagNameArr$$inline_50$$=$doc$$inline_47$$.createElement($element$$inline_52_tagName$$inline_48_tagNameArr$$inline_50$$);if($attributes$$inline_49$$)$goog$isString$$($attributes$$inline_49$$)?$element$$inline_52_tagName$$inline_48_tagNameArr$$inline_50$$.className=$attributes$$inline_49$$:"array"==$goog$typeOf$$($attributes$$inline_49$$)?\r
+$goog$dom$classes$add$$.apply($JSCompiler_alias_NULL$$,[$element$$inline_52_tagName$$inline_48_tagNameArr$$inline_50$$].concat($attributes$$inline_49$$)):$goog$dom$setProperties$$($element$$inline_52_tagName$$inline_48_tagNameArr$$inline_50$$,$attributes$$inline_49$$);2<$args$$inline_46$$.length&&$goog$dom$append_$$($doc$$inline_47$$,$element$$inline_52_tagName$$inline_48_tagNameArr$$inline_50$$,$args$$inline_46$$);return $element$$inline_52_tagName$$inline_48_tagNameArr$$inline_50$$}\r
+function $goog$dom$append_$$($doc$$12$$,$parent$$6$$,$args$$8$$){function $childHandler$$($child$$1$$){$child$$1$$&&$parent$$6$$.appendChild($goog$isString$$($child$$1$$)?$doc$$12$$.createTextNode($child$$1$$):$child$$1$$)}for(var $i$$52$$=2;$i$$52$$<$args$$8$$.length;$i$$52$$++){var $arg$$5$$=$args$$8$$[$i$$52$$];if($goog$isArrayLike$$($arg$$5$$)&&!($goog$isObject$$($arg$$5$$)&&0<$arg$$5$$.nodeType)){var $JSCompiler_inline_result$$54$$;a:{if($arg$$5$$&&"number"==typeof $arg$$5$$.length){if($goog$isObject$$($arg$$5$$)){$JSCompiler_inline_result$$54$$=\r
+"function"==typeof $arg$$5$$.item||"string"==typeof $arg$$5$$.item;break a}if($goog$isFunction$$($arg$$5$$)){$JSCompiler_inline_result$$54$$="function"==typeof $arg$$5$$.item;break a}}$JSCompiler_inline_result$$54$$=$JSCompiler_alias_FALSE$$}$goog$array$forEach$$($JSCompiler_inline_result$$54$$?$goog$array$clone$$($arg$$5$$):$arg$$5$$,$childHandler$$)}else $childHandler$$($arg$$5$$)}}\r
+var $goog$dom$TAGS_TO_IGNORE_$$={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1},$goog$dom$PREDEFINED_TAG_VALUES_$$={IMG:" ",BR:"\n"};\r
+function $goog$dom$getTextContent$$($node$$16_textContent$$){if($goog$dom$BrowserFeature$CAN_USE_INNER_TEXT$$&&"innerText"in $node$$16_textContent$$)$node$$16_textContent$$=$node$$16_textContent$$.innerText.replace(/(\r\n|\r|\n)/g,"\n");else{var $buf$$=[];$goog$dom$getTextContent_$$($node$$16_textContent$$,$buf$$,$JSCompiler_alias_TRUE$$);$node$$16_textContent$$=$buf$$.join("")}$node$$16_textContent$$=$node$$16_textContent$$.replace(/ \xAD /g," ").replace(/\xAD/g,"");$node$$16_textContent$$=$node$$16_textContent$$.replace(/\u200B/g,\r
+"");$goog$dom$BrowserFeature$CAN_USE_INNER_TEXT$$||($node$$16_textContent$$=$node$$16_textContent$$.replace(/ +/g," "));" "!=$node$$16_textContent$$&&($node$$16_textContent$$=$node$$16_textContent$$.replace(/^\s*/,""));return $node$$16_textContent$$}\r
+function $goog$dom$getTextContent_$$($child$$7_node$$18$$,$buf$$2$$,$normalizeWhitespace$$){if(!($child$$7_node$$18$$.nodeName in $goog$dom$TAGS_TO_IGNORE_$$))if(3==$child$$7_node$$18$$.nodeType)$normalizeWhitespace$$?$buf$$2$$.push((""+$child$$7_node$$18$$.nodeValue).replace(/(\r\n|\r|\n)/g,"")):$buf$$2$$.push($child$$7_node$$18$$.nodeValue);else if($child$$7_node$$18$$.nodeName in $goog$dom$PREDEFINED_TAG_VALUES_$$)$buf$$2$$.push($goog$dom$PREDEFINED_TAG_VALUES_$$[$child$$7_node$$18$$.nodeName]);\r
+else for($child$$7_node$$18$$=$child$$7_node$$18$$.firstChild;$child$$7_node$$18$$;)$goog$dom$getTextContent_$$($child$$7_node$$18$$,$buf$$2$$,$normalizeWhitespace$$),$child$$7_node$$18$$=$child$$7_node$$18$$.nextSibling}\r
+function $goog$dom$getAncestorByTagNameAndClass$$($element$$27$$,$opt_tag$$2$$){var $tagName$$4$$=$opt_tag$$2$$?$opt_tag$$2$$.toUpperCase():$JSCompiler_alias_NULL$$;return $goog$dom$getAncestor$$($element$$27$$,function($node$$21$$){return(!$tagName$$4$$||$node$$21$$.nodeName==$tagName$$4$$)&&$JSCompiler_alias_TRUE$$})}\r
+function $goog$dom$getAncestor$$($element$$29$$,$matcher$$){for(var $steps$$=0;$element$$29$$;){if($matcher$$($element$$29$$))return $element$$29$$;$element$$29$$=$element$$29$$.parentNode;$steps$$++}return $JSCompiler_alias_NULL$$};function $goog$style$setStyle_$$($element$$32$$,$value$$55$$,$style$$1$$){$element$$32$$.style[$goog$string$toCamelCase$$($style$$1$$)]=$value$$55$$};function $goog$Disposable$$(){}$goog$Disposable$$.prototype.$disposed_$=$JSCompiler_alias_FALSE$$;$goog$Disposable$$.prototype.$dispose$=function $$goog$Disposable$$$$$dispose$$(){if(!this.$disposed_$)this.$disposed_$=$JSCompiler_alias_TRUE$$,this.$disposeInternal$()};$goog$Disposable$$.prototype.$disposeInternal$=function $$goog$Disposable$$$$$disposeInternal$$(){this.$dependentDisposables_$&&$goog$disposeAll$$.apply($JSCompiler_alias_NULL$$,this.$dependentDisposables_$)};\r
+function $goog$dispose$$($obj$$60$$){$obj$$60$$&&"function"==typeof $obj$$60$$.$dispose$&&$obj$$60$$.$dispose$()}function $goog$disposeAll$$($var_args$$49$$){for(var $i$$57$$=0,$len$$2$$=arguments.length;$i$$57$$<$len$$2$$;++$i$$57$$){var $disposable$$1$$=arguments[$i$$57$$];$goog$isArrayLike$$($disposable$$1$$)?$goog$disposeAll$$.apply($JSCompiler_alias_NULL$$,$disposable$$1$$):$goog$dispose$$($disposable$$1$$)}};function $goog$events$Listener$$(){}var $goog$events$Listener$counter_$$=0;$JSCompiler_prototypeAlias$$=$goog$events$Listener$$.prototype;$JSCompiler_prototypeAlias$$.key=0;$JSCompiler_prototypeAlias$$.$removed$=$JSCompiler_alias_FALSE$$;$JSCompiler_prototypeAlias$$.$callOnce$=$JSCompiler_alias_FALSE$$;\r
+$JSCompiler_prototypeAlias$$.$init$=function $$JSCompiler_prototypeAlias$$$$init$$($listener$$26$$,$proxy$$,$src$$5$$,$type$$51$$,$capture$$,$opt_handler$$){$goog$isFunction$$($listener$$26$$)?this.$isFunctionListener_$=$JSCompiler_alias_TRUE$$:$listener$$26$$&&$listener$$26$$.handleEvent&&$goog$isFunction$$($listener$$26$$.handleEvent)?this.$isFunctionListener_$=$JSCompiler_alias_FALSE$$:$JSCompiler_alias_THROW$$(Error("Invalid listener argument"));this.$listener$=$listener$$26$$;this.$proxy$=$proxy$$;\r
+this.src=$src$$5$$;this.type=$type$$51$$;this.capture=!!$capture$$;this.$handler$=$opt_handler$$;this.$callOnce$=$JSCompiler_alias_FALSE$$;this.key=++$goog$events$Listener$counter_$$;this.$removed$=$JSCompiler_alias_FALSE$$};$JSCompiler_prototypeAlias$$.handleEvent=function $$JSCompiler_prototypeAlias$$$handleEvent$($eventObject$$){return this.$isFunctionListener_$?this.$listener$.call(this.$handler$||this.src,$eventObject$$):this.$listener$.handleEvent.call(this.$listener$,$eventObject$$)};!$goog$userAgent$IE$$||$goog$userAgent$isDocumentMode$$();var $goog$events$BrowserFeature$HAS_W3C_EVENT_SUPPORT$$=!$goog$userAgent$IE$$||$goog$userAgent$isDocumentMode$$();$goog$userAgent$IE$$&&$goog$userAgent$isVersion$$("8");!$goog$userAgent$WEBKIT$$||$goog$userAgent$isVersion$$("528");$goog$userAgent$GECKO$$&&$goog$userAgent$isVersion$$("1.9b")||$goog$userAgent$IE$$&&$goog$userAgent$isVersion$$("8")||$goog$userAgent$OPERA$$&&$goog$userAgent$isVersion$$("9.5")||$goog$userAgent$WEBKIT$$&&$goog$userAgent$isVersion$$("528");\r
+!$goog$userAgent$GECKO$$||$goog$userAgent$isVersion$$("8");function $goog$events$Event$$($type$$52$$,$opt_target$$1$$){this.type=$type$$52$$;this.currentTarget=this.target=$opt_target$$1$$}$goog$inherits$$($goog$events$Event$$,$goog$Disposable$$);$goog$events$Event$$.prototype.$disposeInternal$=function $$goog$events$Event$$$$$disposeInternal$$(){delete this.type;delete this.target;delete this.currentTarget};$goog$events$Event$$.prototype.$propagationStopped_$=$JSCompiler_alias_FALSE$$;$goog$events$Event$$.prototype.$returnValue_$=$JSCompiler_alias_TRUE$$;function $goog$reflect$sinkValue$$($x$$54$$){$goog$reflect$sinkValue$$[" "]($x$$54$$);return $x$$54$$}$goog$reflect$sinkValue$$[" "]=function $$goog$reflect$sinkValue$$$__0$(){};function $goog$events$BrowserEvent$$($opt_e$$,$opt_currentTarget$$){$opt_e$$&&this.$init$($opt_e$$,$opt_currentTarget$$)}$goog$inherits$$($goog$events$BrowserEvent$$,$goog$events$Event$$);$JSCompiler_prototypeAlias$$=$goog$events$BrowserEvent$$.prototype;$JSCompiler_prototypeAlias$$.target=$JSCompiler_alias_NULL$$;$JSCompiler_prototypeAlias$$.relatedTarget=$JSCompiler_alias_NULL$$;$JSCompiler_prototypeAlias$$.offsetX=0;$JSCompiler_prototypeAlias$$.offsetY=0;$JSCompiler_prototypeAlias$$.clientX=0;\r
+$JSCompiler_prototypeAlias$$.clientY=0;$JSCompiler_prototypeAlias$$.screenX=0;$JSCompiler_prototypeAlias$$.screenY=0;$JSCompiler_prototypeAlias$$.button=0;$JSCompiler_prototypeAlias$$.keyCode=0;$JSCompiler_prototypeAlias$$.charCode=0;$JSCompiler_prototypeAlias$$.ctrlKey=$JSCompiler_alias_FALSE$$;$JSCompiler_prototypeAlias$$.altKey=$JSCompiler_alias_FALSE$$;$JSCompiler_prototypeAlias$$.shiftKey=$JSCompiler_alias_FALSE$$;$JSCompiler_prototypeAlias$$.metaKey=$JSCompiler_alias_FALSE$$;\r
+$JSCompiler_prototypeAlias$$.$platformModifierKey$=$JSCompiler_alias_FALSE$$;$JSCompiler_prototypeAlias$$.$event_$=$JSCompiler_alias_NULL$$;\r
+$JSCompiler_prototypeAlias$$.$init$=function $$JSCompiler_prototypeAlias$$$$init$$($e$$10$$,$opt_currentTarget$$1$$){var $type$$54$$=this.type=$e$$10$$.type;$goog$events$Event$$.call(this,$type$$54$$);this.target=$e$$10$$.target||$e$$10$$.srcElement;this.currentTarget=$opt_currentTarget$$1$$;var $relatedTarget$$=$e$$10$$.relatedTarget;if($relatedTarget$$){if($goog$userAgent$GECKO$$){var $JSCompiler_inline_result$$57$$;a:{try{$goog$reflect$sinkValue$$($relatedTarget$$.nodeName);$JSCompiler_inline_result$$57$$=\r
+$JSCompiler_alias_TRUE$$;break a}catch($e$$inline_59$$){}$JSCompiler_inline_result$$57$$=$JSCompiler_alias_FALSE$$}$JSCompiler_inline_result$$57$$||($relatedTarget$$=$JSCompiler_alias_NULL$$)}}else if("mouseover"==$type$$54$$)$relatedTarget$$=$e$$10$$.fromElement;else if("mouseout"==$type$$54$$)$relatedTarget$$=$e$$10$$.toElement;this.relatedTarget=$relatedTarget$$;this.offsetX=$goog$userAgent$WEBKIT$$||$e$$10$$.offsetX!==$JSCompiler_alias_VOID$$?$e$$10$$.offsetX:$e$$10$$.layerX;this.offsetY=$goog$userAgent$WEBKIT$$||\r
+$e$$10$$.offsetY!==$JSCompiler_alias_VOID$$?$e$$10$$.offsetY:$e$$10$$.layerY;this.clientX=$e$$10$$.clientX!==$JSCompiler_alias_VOID$$?$e$$10$$.clientX:$e$$10$$.pageX;this.clientY=$e$$10$$.clientY!==$JSCompiler_alias_VOID$$?$e$$10$$.clientY:$e$$10$$.pageY;this.screenX=$e$$10$$.screenX||0;this.screenY=$e$$10$$.screenY||0;this.button=$e$$10$$.button;this.keyCode=$e$$10$$.keyCode||0;this.charCode=$e$$10$$.charCode||("keypress"==$type$$54$$?$e$$10$$.keyCode:0);this.ctrlKey=$e$$10$$.ctrlKey;this.altKey=\r
+$e$$10$$.altKey;this.shiftKey=$e$$10$$.shiftKey;this.metaKey=$e$$10$$.metaKey;this.$platformModifierKey$=$goog$userAgent$MAC$$?$e$$10$$.metaKey:$e$$10$$.ctrlKey;this.state=$e$$10$$.state;this.$event_$=$e$$10$$;delete this.$returnValue_$;delete this.$propagationStopped_$};\r
+$JSCompiler_prototypeAlias$$.$disposeInternal$=function $$JSCompiler_prototypeAlias$$$$disposeInternal$$(){$goog$events$BrowserEvent$$.$superClass_$.$disposeInternal$.call(this);this.relatedTarget=this.currentTarget=this.target=this.$event_$=$JSCompiler_alias_NULL$$};var $goog$events$listeners_$$={},$goog$events$listenerTree_$$={},$goog$events$sources_$$={},$goog$events$onStringMap_$$={};\r
+function $goog$events$listen$$($src$$8$$,$type$$55$$,$key$$45_listener$$29$$,$capture$$1_opt_capt$$2$$,$opt_handler$$1$$){if($type$$55$$){if("array"==$goog$typeOf$$($type$$55$$)){for(var $i$$61_proxy$$1$$=0;$i$$61_proxy$$1$$<$type$$55$$.length;$i$$61_proxy$$1$$++)$goog$events$listen$$($src$$8$$,$type$$55$$[$i$$61_proxy$$1$$],$key$$45_listener$$29$$,$capture$$1_opt_capt$$2$$,$opt_handler$$1$$);return $JSCompiler_alias_NULL$$}var $capture$$1_opt_capt$$2$$=!!$capture$$1_opt_capt$$2$$,$listenerObj_map$$=\r
+$goog$events$listenerTree_$$;$type$$55$$ in $listenerObj_map$$||($listenerObj_map$$[$type$$55$$]={$count_$:0,$remaining_$:0});$listenerObj_map$$=$listenerObj_map$$[$type$$55$$];$capture$$1_opt_capt$$2$$ in $listenerObj_map$$||($listenerObj_map$$[$capture$$1_opt_capt$$2$$]={$count_$:0,$remaining_$:0},$listenerObj_map$$.$count_$++);var $listenerObj_map$$=$listenerObj_map$$[$capture$$1_opt_capt$$2$$],$srcUid$$=$src$$8$$[$goog$UID_PROPERTY_$$]||($src$$8$$[$goog$UID_PROPERTY_$$]=++$goog$uidCounter_$$),\r
+$listenerArray$$;$listenerObj_map$$.$remaining_$++;if($listenerObj_map$$[$srcUid$$]){$listenerArray$$=$listenerObj_map$$[$srcUid$$];for($i$$61_proxy$$1$$=0;$i$$61_proxy$$1$$<$listenerArray$$.length;$i$$61_proxy$$1$$++)if($listenerObj_map$$=$listenerArray$$[$i$$61_proxy$$1$$],$listenerObj_map$$.$listener$==$key$$45_listener$$29$$&&$listenerObj_map$$.$handler$==$opt_handler$$1$$){if($listenerObj_map$$.$removed$)break;return $listenerArray$$[$i$$61_proxy$$1$$].key}}else $listenerArray$$=$listenerObj_map$$[$srcUid$$]=\r
+[],$listenerObj_map$$.$count_$++;$i$$61_proxy$$1$$=$goog$events$getProxy$$();$i$$61_proxy$$1$$.src=$src$$8$$;$listenerObj_map$$=new $goog$events$Listener$$;$listenerObj_map$$.$init$($key$$45_listener$$29$$,$i$$61_proxy$$1$$,$src$$8$$,$type$$55$$,$capture$$1_opt_capt$$2$$,$opt_handler$$1$$);$key$$45_listener$$29$$=$listenerObj_map$$.key;$i$$61_proxy$$1$$.key=$key$$45_listener$$29$$;$listenerArray$$.push($listenerObj_map$$);$goog$events$listeners_$$[$key$$45_listener$$29$$]=$listenerObj_map$$;$goog$events$sources_$$[$srcUid$$]||\r
+($goog$events$sources_$$[$srcUid$$]=[]);$goog$events$sources_$$[$srcUid$$].push($listenerObj_map$$);$src$$8$$.addEventListener?($src$$8$$==$goog$global$$||!$src$$8$$.$customEvent_$)&&$src$$8$$.addEventListener($type$$55$$,$i$$61_proxy$$1$$,$capture$$1_opt_capt$$2$$):$src$$8$$.attachEvent($type$$55$$ in $goog$events$onStringMap_$$?$goog$events$onStringMap_$$[$type$$55$$]:$goog$events$onStringMap_$$[$type$$55$$]="on"+$type$$55$$,$i$$61_proxy$$1$$);return $key$$45_listener$$29$$}$JSCompiler_alias_THROW$$(Error("Invalid event type"))}\r
+function $goog$events$getProxy$$(){var $proxyCallbackFunction$$=$goog$events$handleBrowserEvent_$$,$f$$25$$=$goog$events$BrowserFeature$HAS_W3C_EVENT_SUPPORT$$?function($eventObject$$1$$){return $proxyCallbackFunction$$.call($f$$25$$.src,$f$$25$$.key,$eventObject$$1$$)}:function($eventObject$$2_v$$){$eventObject$$2_v$$=$proxyCallbackFunction$$.call($f$$25$$.src,$f$$25$$.key,$eventObject$$2_v$$);if(!$eventObject$$2_v$$)return $eventObject$$2_v$$};return $f$$25$$}\r
+function $goog$events$unlistenByKey$$($key$$47$$){if(!$goog$events$listeners_$$[$key$$47$$])return $JSCompiler_alias_FALSE$$;var $listener$$33$$=$goog$events$listeners_$$[$key$$47$$];if($listener$$33$$.$removed$)return $JSCompiler_alias_FALSE$$;var $src$$12_srcUid$$1$$=$listener$$33$$.src,$type$$58$$=$listener$$33$$.type,$listenerArray$$2_proxy$$2$$=$listener$$33$$.$proxy$,$capture$$3$$=$listener$$33$$.capture;$src$$12_srcUid$$1$$.removeEventListener?($src$$12_srcUid$$1$$==$goog$global$$||!$src$$12_srcUid$$1$$.$customEvent_$)&&\r
+$src$$12_srcUid$$1$$.removeEventListener($type$$58$$,$listenerArray$$2_proxy$$2$$,$capture$$3$$):$src$$12_srcUid$$1$$.detachEvent&&$src$$12_srcUid$$1$$.detachEvent($type$$58$$ in $goog$events$onStringMap_$$?$goog$events$onStringMap_$$[$type$$58$$]:$goog$events$onStringMap_$$[$type$$58$$]="on"+$type$$58$$,$listenerArray$$2_proxy$$2$$);$src$$12_srcUid$$1$$=$src$$12_srcUid$$1$$[$goog$UID_PROPERTY_$$]||($src$$12_srcUid$$1$$[$goog$UID_PROPERTY_$$]=++$goog$uidCounter_$$);$listenerArray$$2_proxy$$2$$=$goog$events$listenerTree_$$[$type$$58$$][$capture$$3$$][$src$$12_srcUid$$1$$];\r
+if($goog$events$sources_$$[$src$$12_srcUid$$1$$]){var $sourcesArray$$=$goog$events$sources_$$[$src$$12_srcUid$$1$$],$i$$inline_63$$=$goog$array$indexOf$$($sourcesArray$$,$listener$$33$$);0<=$i$$inline_63$$&&($goog$asserts$assert$$($sourcesArray$$.length!=$JSCompiler_alias_NULL$$),$goog$array$ARRAY_PROTOTYPE_$$.splice.call($sourcesArray$$,$i$$inline_63$$,1));0==$sourcesArray$$.length&&delete $goog$events$sources_$$[$src$$12_srcUid$$1$$]}$listener$$33$$.$removed$=$JSCompiler_alias_TRUE$$;$listenerArray$$2_proxy$$2$$.$needsCleanup_$=\r
+$JSCompiler_alias_TRUE$$;$goog$events$cleanUp_$$($type$$58$$,$capture$$3$$,$src$$12_srcUid$$1$$,$listenerArray$$2_proxy$$2$$);delete $goog$events$listeners_$$[$key$$47$$];return $JSCompiler_alias_TRUE$$}\r
+function $goog$events$cleanUp_$$($type$$59$$,$capture$$4$$,$srcUid$$2$$,$listenerArray$$3$$){if(!$listenerArray$$3$$.$locked_$&&$listenerArray$$3$$.$needsCleanup_$){for(var $oldIndex$$=0,$newIndex$$=0;$oldIndex$$<$listenerArray$$3$$.length;$oldIndex$$++)$listenerArray$$3$$[$oldIndex$$].$removed$?$listenerArray$$3$$[$oldIndex$$].$proxy$.src=$JSCompiler_alias_NULL$$:($oldIndex$$!=$newIndex$$&&($listenerArray$$3$$[$newIndex$$]=$listenerArray$$3$$[$oldIndex$$]),$newIndex$$++);$listenerArray$$3$$.length=\r
+$newIndex$$;$listenerArray$$3$$.$needsCleanup_$=$JSCompiler_alias_FALSE$$;0==$newIndex$$&&(delete $goog$events$listenerTree_$$[$type$$59$$][$capture$$4$$][$srcUid$$2$$],$goog$events$listenerTree_$$[$type$$59$$][$capture$$4$$].$count_$--,0==$goog$events$listenerTree_$$[$type$$59$$][$capture$$4$$].$count_$&&(delete $goog$events$listenerTree_$$[$type$$59$$][$capture$$4$$],$goog$events$listenerTree_$$[$type$$59$$].$count_$--),0==$goog$events$listenerTree_$$[$type$$59$$].$count_$&&delete $goog$events$listenerTree_$$[$type$$59$$])}}\r
+function $goog$events$fireListeners_$$($listenerArray$$5_map$$4$$,$obj$$66_objUid$$2$$,$type$$65$$,$capture$$9$$,$eventObject$$4$$){var $retval$$=1,$obj$$66_objUid$$2$$=$obj$$66_objUid$$2$$[$goog$UID_PROPERTY_$$]||($obj$$66_objUid$$2$$[$goog$UID_PROPERTY_$$]=++$goog$uidCounter_$$);if($listenerArray$$5_map$$4$$[$obj$$66_objUid$$2$$]){$listenerArray$$5_map$$4$$.$remaining_$--;$listenerArray$$5_map$$4$$=$listenerArray$$5_map$$4$$[$obj$$66_objUid$$2$$];$listenerArray$$5_map$$4$$.$locked_$?$listenerArray$$5_map$$4$$.$locked_$++:\r
+$listenerArray$$5_map$$4$$.$locked_$=1;try{for(var $length$$16$$=$listenerArray$$5_map$$4$$.length,$i$$67$$=0;$i$$67$$<$length$$16$$;$i$$67$$++){var $listener$$39$$=$listenerArray$$5_map$$4$$[$i$$67$$];$listener$$39$$&&!$listener$$39$$.$removed$&&($retval$$&=$goog$events$fireListener$$($listener$$39$$,$eventObject$$4$$)!==$JSCompiler_alias_FALSE$$)}}finally{$listenerArray$$5_map$$4$$.$locked_$--,$goog$events$cleanUp_$$($type$$65$$,$capture$$9$$,$obj$$66_objUid$$2$$,$listenerArray$$5_map$$4$$)}}return Boolean($retval$$)}\r
+function $goog$events$fireListener$$($listener$$40$$,$eventObject$$5$$){var $rv$$13$$=$listener$$40$$.handleEvent($eventObject$$5$$);$listener$$40$$.$callOnce$&&$goog$events$unlistenByKey$$($listener$$40$$.key);return $rv$$13$$}\r
+function $goog$events$handleBrowserEvent_$$($key$$49$$,$opt_evt$$){if(!$goog$events$listeners_$$[$key$$49$$])return $JSCompiler_alias_TRUE$$;var $listener$$41$$=$goog$events$listeners_$$[$key$$49$$],$be$$1_type$$67$$=$listener$$41$$.type,$map$$6$$=$goog$events$listenerTree_$$;if(!($be$$1_type$$67$$ in $map$$6$$))return $JSCompiler_alias_TRUE$$;var $map$$6$$=$map$$6$$[$be$$1_type$$67$$],$ieEvent_part$$inline_67_retval$$1$$,$targetsMap$$1$$;if(!$goog$events$BrowserFeature$HAS_W3C_EVENT_SUPPORT$$){var $JSCompiler_temp$$8_hasCapture$$2_parts$$inline_65$$;\r
+if(!($JSCompiler_temp$$8_hasCapture$$2_parts$$inline_65$$=$opt_evt$$))a:{$JSCompiler_temp$$8_hasCapture$$2_parts$$inline_65$$="window.event".split(".");for(var $cur$$inline_66_hasBubble$$1$$=$goog$global$$;$ieEvent_part$$inline_67_retval$$1$$=$JSCompiler_temp$$8_hasCapture$$2_parts$$inline_65$$.shift();)if($cur$$inline_66_hasBubble$$1$$[$ieEvent_part$$inline_67_retval$$1$$]!=$JSCompiler_alias_NULL$$)$cur$$inline_66_hasBubble$$1$$=$cur$$inline_66_hasBubble$$1$$[$ieEvent_part$$inline_67_retval$$1$$];\r
+else{$JSCompiler_temp$$8_hasCapture$$2_parts$$inline_65$$=$JSCompiler_alias_NULL$$;break a}$JSCompiler_temp$$8_hasCapture$$2_parts$$inline_65$$=$cur$$inline_66_hasBubble$$1$$}$ieEvent_part$$inline_67_retval$$1$$=$JSCompiler_temp$$8_hasCapture$$2_parts$$inline_65$$;$JSCompiler_temp$$8_hasCapture$$2_parts$$inline_65$$=$JSCompiler_alias_TRUE$$ in $map$$6$$;$cur$$inline_66_hasBubble$$1$$=$JSCompiler_alias_FALSE$$ in $map$$6$$;if($JSCompiler_temp$$8_hasCapture$$2_parts$$inline_65$$){if(0>$ieEvent_part$$inline_67_retval$$1$$.keyCode||\r
+$ieEvent_part$$inline_67_retval$$1$$.returnValue!=$JSCompiler_alias_VOID$$)return $JSCompiler_alias_TRUE$$;a:{var $evt$$14_useReturnValue$$inline_70$$=$JSCompiler_alias_FALSE$$;if(0==$ieEvent_part$$inline_67_retval$$1$$.keyCode)try{$ieEvent_part$$inline_67_retval$$1$$.keyCode=-1;break a}catch($ex$$inline_71$$){$evt$$14_useReturnValue$$inline_70$$=$JSCompiler_alias_TRUE$$}if($evt$$14_useReturnValue$$inline_70$$||$ieEvent_part$$inline_67_retval$$1$$.returnValue==$JSCompiler_alias_VOID$$)$ieEvent_part$$inline_67_retval$$1$$.returnValue=\r
+$JSCompiler_alias_TRUE$$}}$evt$$14_useReturnValue$$inline_70$$=new $goog$events$BrowserEvent$$;$evt$$14_useReturnValue$$inline_70$$.$init$($ieEvent_part$$inline_67_retval$$1$$,this);$ieEvent_part$$inline_67_retval$$1$$=$JSCompiler_alias_TRUE$$;try{if($JSCompiler_temp$$8_hasCapture$$2_parts$$inline_65$$){for(var $ancestors$$2$$=[],$parent$$19$$=$evt$$14_useReturnValue$$inline_70$$.currentTarget;$parent$$19$$;$parent$$19$$=$parent$$19$$.parentNode)$ancestors$$2$$.push($parent$$19$$);$targetsMap$$1$$=\r
+$map$$6$$[$JSCompiler_alias_TRUE$$];$targetsMap$$1$$.$remaining_$=$targetsMap$$1$$.$count_$;for(var $i$$69$$=$ancestors$$2$$.length-1;!$evt$$14_useReturnValue$$inline_70$$.$propagationStopped_$&&0<=$i$$69$$&&$targetsMap$$1$$.$remaining_$;$i$$69$$--)$evt$$14_useReturnValue$$inline_70$$.currentTarget=$ancestors$$2$$[$i$$69$$],$ieEvent_part$$inline_67_retval$$1$$&=$goog$events$fireListeners_$$($targetsMap$$1$$,$ancestors$$2$$[$i$$69$$],$be$$1_type$$67$$,$JSCompiler_alias_TRUE$$,$evt$$14_useReturnValue$$inline_70$$);\r
+if($cur$$inline_66_hasBubble$$1$$){$targetsMap$$1$$=$map$$6$$[$JSCompiler_alias_FALSE$$];$targetsMap$$1$$.$remaining_$=$targetsMap$$1$$.$count_$;for($i$$69$$=0;!$evt$$14_useReturnValue$$inline_70$$.$propagationStopped_$&&$i$$69$$<$ancestors$$2$$.length&&$targetsMap$$1$$.$remaining_$;$i$$69$$++)$evt$$14_useReturnValue$$inline_70$$.currentTarget=$ancestors$$2$$[$i$$69$$],$ieEvent_part$$inline_67_retval$$1$$&=$goog$events$fireListeners_$$($targetsMap$$1$$,$ancestors$$2$$[$i$$69$$],$be$$1_type$$67$$,\r
+$JSCompiler_alias_FALSE$$,$evt$$14_useReturnValue$$inline_70$$)}}else $ieEvent_part$$inline_67_retval$$1$$=$goog$events$fireListener$$($listener$$41$$,$evt$$14_useReturnValue$$inline_70$$)}finally{if($ancestors$$2$$)$ancestors$$2$$.length=0;$evt$$14_useReturnValue$$inline_70$$.$dispose$()}return $ieEvent_part$$inline_67_retval$$1$$}$be$$1_type$$67$$=new $goog$events$BrowserEvent$$($opt_evt$$,this);try{$ieEvent_part$$inline_67_retval$$1$$=$goog$events$fireListener$$($listener$$41$$,$be$$1_type$$67$$)}finally{$be$$1_type$$67$$.$dispose$()}return $ieEvent_part$$inline_67_retval$$1$$}\r
+;function $goog$events$EventHandler$$($opt_handler$$7$$){this.$handler_$=$opt_handler$$7$$;this.$keys_$=[]}$goog$inherits$$($goog$events$EventHandler$$,$goog$Disposable$$);var $goog$events$EventHandler$typeArray_$$=[];\r
+function $JSCompiler_StaticMethods_listen$$($JSCompiler_StaticMethods_listen$self$$,$src$$16$$,$type$$68$$,$opt_fn$$,$opt_handler$$8$$){"array"!=$goog$typeOf$$($type$$68$$)&&($goog$events$EventHandler$typeArray_$$[0]=$type$$68$$,$type$$68$$=$goog$events$EventHandler$typeArray_$$);for(var $i$$70$$=0;$i$$70$$<$type$$68$$.length;$i$$70$$++)$JSCompiler_StaticMethods_listen$self$$.$keys_$.push($goog$events$listen$$($src$$16$$,$type$$68$$[$i$$70$$],$opt_fn$$||$JSCompiler_StaticMethods_listen$self$$,$JSCompiler_alias_FALSE$$,\r
+$opt_handler$$8$$||$JSCompiler_StaticMethods_listen$self$$.$handler_$||$JSCompiler_StaticMethods_listen$self$$))}$goog$events$EventHandler$$.prototype.$disposeInternal$=function $$goog$events$EventHandler$$$$$disposeInternal$$(){$goog$events$EventHandler$$.$superClass_$.$disposeInternal$.call(this);$goog$array$forEach$$(this.$keys_$,$goog$events$unlistenByKey$$);this.$keys_$.length=0};$goog$events$EventHandler$$.prototype.handleEvent=function $$goog$events$EventHandler$$$$handleEvent$(){$JSCompiler_alias_THROW$$(Error("EventHandler.handleEvent not implemented"))};var $goog$Timer$defaultTimerObject$$=$goog$global$$.window;\r
+function $goog$Timer$callOnce$$($listener$$45$$,$opt_delay$$,$opt_handler$$13$$){$goog$isFunction$$($listener$$45$$)?$opt_handler$$13$$&&($listener$$45$$=$goog$bind$$($listener$$45$$,$opt_handler$$13$$)):$listener$$45$$&&"function"==typeof $listener$$45$$.handleEvent?$listener$$45$$=$goog$bind$$($listener$$45$$.handleEvent,$listener$$45$$):$JSCompiler_alias_THROW$$(Error("Invalid listener argument"));return 2147483647<$opt_delay$$?-1:$goog$Timer$defaultTimerObject$$.setTimeout($listener$$45$$,$opt_delay$$||\r
+0)};function $picnet$ui$filter$FilterState$$($id$$2$$,$value$$63$$,$idx$$,$type$$73$$){this.id=$id$$2$$;this.value=$value$$63$$;this.$idx$=$idx$$;this.type=$type$$73$$}$picnet$ui$filter$FilterState$$.prototype.toString=function $$picnet$ui$filter$FilterState$$$$toString$(){return"id["+this.id+"] value["+this.value+"] idx["+this.$idx$+"] type["+this.type+"]"};function $picnet$ui$filter$GenericListFilterOptions$$(){}$picnet$ui$filter$GenericListFilterOptions$$.prototype.additionalFilterTriggers=[];$picnet$ui$filter$GenericListFilterOptions$$.prototype.clearFiltersControls=[];$picnet$ui$filter$GenericListFilterOptions$$.prototype.filterDelay=250;$picnet$ui$filter$GenericListFilterOptions$$.prototype.filterToolTipMessage='Quotes (") match phrases. (not) excludes a match from the results. (or) can be used to do Or searches. I.e. [red or blue] will match either red or blue. Numeric values support >=, >, <=, <, = and != operators.';\r
+$picnet$ui$filter$GenericListFilterOptions$$.prototype.enableCookies=$JSCompiler_alias_TRUE$$;$picnet$ui$filter$GenericListFilterOptions$$.prototype.matchingElement=$JSCompiler_alias_NULL$$;$picnet$ui$filter$GenericListFilterOptions$$.prototype.filteringElements=$JSCompiler_alias_NULL$$;$picnet$ui$filter$GenericListFilterOptions$$.prototype.additionalFilterValueCookieId=$JSCompiler_alias_NULL$$;function $picnet$ui$filter$SearchEngine$$(){this.$precedences_$={or:1,and:2,not:3}}\r
+function $JSCompiler_StaticMethods_doesTextMatchTokens$$($textToMatch$$,$postFixTokens$$,$exactMatch$$){if(!$postFixTokens$$)return $JSCompiler_alias_TRUE$$;for(var $textToMatch$$=$exactMatch$$?$textToMatch$$:$textToMatch$$.toLowerCase(),$stackResult$$=[],$stackResult1_token$$4$$,$stackResult2$$,$i$$73$$=0;$i$$73$$<$postFixTokens$$.length;$i$$73$$++)$stackResult1_token$$4$$=$postFixTokens$$[$i$$73$$],"and"!==$stackResult1_token$$4$$&&"or"!==$stackResult1_token$$4$$&&"not"!==$stackResult1_token$$4$$?\r
+0===$stackResult1_token$$4$$.indexOf(">")||0===$stackResult1_token$$4$$.indexOf("<")||0===$stackResult1_token$$4$$.indexOf("=")||0===$stackResult1_token$$4$$.indexOf("!=")?$stackResult$$.push($JSCompiler_StaticMethods_doesNumberMatchToken$$($stackResult1_token$$4$$,$textToMatch$$)):$stackResult$$.push($exactMatch$$?$textToMatch$$===$stackResult1_token$$4$$:0<=$textToMatch$$.indexOf($stackResult1_token$$4$$)):"and"===$stackResult1_token$$4$$?($stackResult1_token$$4$$=$stackResult$$.pop(),$stackResult2$$=\r
+$stackResult$$.pop(),$stackResult$$.push($stackResult1_token$$4$$&&$stackResult2$$)):"or"===$stackResult1_token$$4$$?($stackResult1_token$$4$$=$stackResult$$.pop(),$stackResult2$$=$stackResult$$.pop(),$stackResult$$.push($stackResult1_token$$4$$||$stackResult2$$)):"not"===$stackResult1_token$$4$$&&($stackResult1_token$$4$$=$stackResult$$.pop(),$stackResult$$.push(!$stackResult1_token$$4$$));return 1===$stackResult$$.length&&$stackResult$$.pop()}\r
+function $JSCompiler_StaticMethods_doesNumberMatchToken$$($token$$5$$,$text$$9$$){var $op_txt$$inline_76$$,$exp$$,$actual$$;$op_txt$$inline_76$$=$text$$9$$;"$"===$op_txt$$inline_76$$.charAt(0)&&($op_txt$$inline_76$$=$op_txt$$inline_76$$.substring(1));$actual$$=parseFloat($op_txt$$inline_76$$);if(0===$token$$5$$.indexOf("="))$op_txt$$inline_76$$="=",$exp$$=parseFloat($token$$5$$.substring(1));else if(0===$token$$5$$.indexOf("!="))$op_txt$$inline_76$$="!=",$exp$$=parseFloat($token$$5$$.substring(2));\r
+else if(0===$token$$5$$.indexOf(">="))$op_txt$$inline_76$$=">=",$exp$$=parseFloat($token$$5$$.substring(2));else if(0===$token$$5$$.indexOf(">"))$op_txt$$inline_76$$=">",$exp$$=parseFloat($token$$5$$.substring(1));else if(0===$token$$5$$.indexOf("<="))$op_txt$$inline_76$$="<=",$exp$$=parseFloat($token$$5$$.substring(2));else if(0===$token$$5$$.indexOf("<"))$op_txt$$inline_76$$="<",$exp$$=parseFloat($token$$5$$.substring(1));else return $JSCompiler_alias_TRUE$$;switch($op_txt$$inline_76$$){case "!=":return $actual$$!==\r
+$exp$$;case "=":return $actual$$===$exp$$;case ">=":return $actual$$>=$exp$$;case ">":return $actual$$>$exp$$;case "<=":return $actual$$<=$exp$$;case "<":return $actual$$<$exp$$}$JSCompiler_alias_THROW$$(Error("Could not find a number operation: "+$op_txt$$inline_76$$))}\r
+function $JSCompiler_StaticMethods_normaliseTerm$$($tokens$$,$token$$7$$,$term$$){for(var $idx$$1$$=$token$$7$$.indexOf($term$$);-1!==$idx$$1$$;)0<$idx$$1$$&&$tokens$$.push($token$$7$$.substring(0,$idx$$1$$)),$tokens$$.push($term$$),$token$$7$$=$token$$7$$.substring($idx$$1$$+1),$idx$$1$$=$token$$7$$.indexOf($term$$);return $token$$7$$};function $goog$net$Cookies$$($context$$){this.$document_$=$context$$}var $goog$net$Cookies$SPLIT_RE_$$=/\s*;\s*/;\r
+$goog$net$Cookies$$.prototype.set=function $$goog$net$Cookies$$$$set$($name$$61$$,$value$$65$$,$expiresStr_opt_maxAge$$,$opt_path_pathStr$$,$domainStr_opt_domain$$,$opt_secure_secureStr$$){/[;=\s]/.test($name$$61$$)&&$JSCompiler_alias_THROW$$(Error('Invalid cookie name "'+$name$$61$$+'"'));/[;\r\n]/.test($value$$65$$)&&$JSCompiler_alias_THROW$$(Error('Invalid cookie value "'+$value$$65$$+'"'));$expiresStr_opt_maxAge$$!==$JSCompiler_alias_VOID$$||($expiresStr_opt_maxAge$$=-1);$domainStr_opt_domain$$=\r
+$domainStr_opt_domain$$?";domain="+$domainStr_opt_domain$$:"";$opt_path_pathStr$$=$opt_path_pathStr$$?";path="+$opt_path_pathStr$$:"";$opt_secure_secureStr$$=$opt_secure_secureStr$$?";secure":"";$expiresStr_opt_maxAge$$=0>$expiresStr_opt_maxAge$$?"":0==$expiresStr_opt_maxAge$$?";expires="+(new Date(1970,1,1)).toUTCString():";expires="+(new Date($goog$now$$()+1E3*$expiresStr_opt_maxAge$$)).toUTCString();this.$document_$.cookie=$name$$61$$+"="+$value$$65$$+$domainStr_opt_domain$$+$opt_path_pathStr$$+\r
+$expiresStr_opt_maxAge$$+$opt_secure_secureStr$$};$goog$net$Cookies$$.prototype.get=function $$goog$net$Cookies$$$$get$($name$$62$$,$opt_default$$){for(var $nameEq$$=$name$$62$$+"=",$parts$$3$$=(this.$document_$.cookie||"").split($goog$net$Cookies$SPLIT_RE_$$),$i$$77$$=0,$part$$2$$;$part$$2$$=$parts$$3$$[$i$$77$$];$i$$77$$++)if(0==$part$$2$$.indexOf($nameEq$$))return $part$$2$$.substr($nameEq$$.length);return $opt_default$$};var $goog$net$cookies$$=new $goog$net$Cookies$$(document);\r
+$goog$net$cookies$$.$MAX_COOKIE_LENGTH$=3950;function $picnet$ui$filter$GenericListFilter$$($filterInput$$,$list$$,$options$$2$$){this.list=$list$$;this.options=$options$$2$$;this.$filterInput$=$filterInput$$;this.$filters$=[this.$filterInput$];this.$eventHandler$=new $goog$events$EventHandler$$(this);this.search=new $picnet$ui$filter$SearchEngine$$;this.$initialiseFilters$()}$goog$inherits$$($picnet$ui$filter$GenericListFilter$$,$goog$Disposable$$);var $picnet$ui$filter$GenericListFilter$filteridx$$=0;$JSCompiler_prototypeAlias$$=$picnet$ui$filter$GenericListFilter$$.prototype;\r
+$JSCompiler_prototypeAlias$$.$initialiseFilters$=function $$JSCompiler_prototypeAlias$$$$initialiseFilters$$(){this.$filterKey$=(this.list.getAttribute("id")||this.list.getAttribute("name")||"")+"_"+ ++$picnet$ui$filter$GenericListFilter$filteridx$$+"_filters";this.$initialiseControlCaches$();$JSCompiler_StaticMethods_registerListenersOnFilters$$(this);var $additionalFilterStates$$inline_87_filterState$$inline_82$$=this.options.enableCookies&&$goog$net$cookies$$.get(this.$filterKey$);if($additionalFilterStates$$inline_87_filterState$$inline_82$$){for(var $additionalFilterStates$$inline_87_filterState$$inline_82$$=\r
+$additionalFilterStates$$inline_87_filterState$$inline_82$$.split("|"),$additionalStates$$inline_88_states$$inline_83$$=[],$additionalFilterValueCookieId$$inline_86_i$$inline_84$$=0;$additionalFilterValueCookieId$$inline_86_i$$inline_84$$<$additionalFilterStates$$inline_87_filterState$$inline_82$$.length;$additionalFilterValueCookieId$$inline_86_i$$inline_84$$++){var $additionalState$$inline_89_state$$inline_85$$=$additionalFilterStates$$inline_87_filterState$$inline_82$$[$additionalFilterValueCookieId$$inline_86_i$$inline_84$$].split(",");\r
+$additionalStates$$inline_88_states$$inline_83$$.push(new $picnet$ui$filter$FilterState$$($additionalState$$inline_89_state$$inline_85$$[0],$additionalState$$inline_89_state$$inline_85$$[3],parseInt($additionalState$$inline_89_state$$inline_85$$[1],10),$additionalState$$inline_89_state$$inline_85$$[2]))}$JSCompiler_StaticMethods_applyFilterStates$$(this,$additionalStates$$inline_88_states$$inline_83$$,$JSCompiler_alias_TRUE$$)}if($additionalFilterValueCookieId$$inline_86_i$$inline_84$$=this.options.additionalFilterValueCookieId)if($additionalFilterStates$$inline_87_filterState$$inline_82$$=\r
+this.options.enableCookies&&$goog$net$cookies$$.get($additionalFilterValueCookieId$$inline_86_i$$inline_84$$)){$additionalFilterStates$$inline_87_filterState$$inline_82$$=$additionalFilterStates$$inline_87_filterState$$inline_82$$.split("|");$additionalStates$$inline_88_states$$inline_83$$=[];for($additionalFilterValueCookieId$$inline_86_i$$inline_84$$=0;$additionalFilterValueCookieId$$inline_86_i$$inline_84$$<$additionalFilterStates$$inline_87_filterState$$inline_82$$.length;$additionalFilterValueCookieId$$inline_86_i$$inline_84$$++)$additionalState$$inline_89_state$$inline_85$$=\r
+$additionalFilterStates$$inline_87_filterState$$inline_82$$[$additionalFilterValueCookieId$$inline_86_i$$inline_84$$].split(","),$additionalStates$$inline_88_states$$inline_83$$.push(new $picnet$ui$filter$FilterState$$($additionalState$$inline_89_state$$inline_85$$[0],$additionalState$$inline_89_state$$inline_85$$[3],parseInt($additionalState$$inline_89_state$$inline_85$$[1],10),$additionalState$$inline_89_state$$inline_85$$[2]));$JSCompiler_StaticMethods_applyFilterStates$$(this,$additionalStates$$inline_88_states$$inline_83$$,\r
+$JSCompiler_alias_TRUE$$)}};\r
+function $JSCompiler_StaticMethods_registerListenersOnFilters$$($JSCompiler_StaticMethods_registerListenersOnFilters$self$$){var a;$goog$array$forEach$$($JSCompiler_StaticMethods_registerListenersOnFilters$self$$.$filters$,function($filter$$){$JSCompiler_StaticMethods_listen$$(this.$eventHandler$,$filter$$,"text"===$filter$$.getAttribute("type")?"keyup":"change",this.$onFilterChanged$,this)},$JSCompiler_StaticMethods_registerListenersOnFilters$self$$);if($JSCompiler_StaticMethods_registerListenersOnFilters$self$$.options.clearFiltersControls)for(var $i$$81$$=0;$i$$81$$<\r
+$JSCompiler_StaticMethods_registerListenersOnFilters$self$$.options.clearFiltersControls.length;$i$$81$$++)$JSCompiler_StaticMethods_registerListenersOnFilters$self$$.options.clearFiltersControls[$i$$81$$].length&&($JSCompiler_StaticMethods_registerListenersOnFilters$self$$.options.clearFiltersControls[$i$$81$$]=$JSCompiler_StaticMethods_registerListenersOnFilters$self$$.options.clearFiltersControls[$i$$81$$][0]),$JSCompiler_StaticMethods_listen$$($JSCompiler_StaticMethods_registerListenersOnFilters$self$$.$eventHandler$,\r
+$JSCompiler_StaticMethods_registerListenersOnFilters$self$$.options.clearFiltersControls[$i$$81$$],"click",$JSCompiler_StaticMethods_registerListenersOnFilters$self$$.$clearAllFilters$,$JSCompiler_StaticMethods_registerListenersOnFilters$self$$);if($JSCompiler_StaticMethods_registerListenersOnFilters$self$$.options.additionalFilterTriggers)for($i$$81$$=0;$i$$81$$<$JSCompiler_StaticMethods_registerListenersOnFilters$self$$.options.additionalFilterTriggers.length;$i$$81$$++){var $trigger$$=$JSCompiler_StaticMethods_registerListenersOnFilters$self$$.options.additionalFilterTriggers[$i$$81$$];\r
+$trigger$$.length&&(a=$JSCompiler_StaticMethods_registerListenersOnFilters$self$$.options.additionalFilterTriggers[$i$$81$$]=$trigger$$[0],$trigger$$=a);var $type$$74$$=$trigger$$.options?"select-one":$trigger$$.getAttribute("type");switch($type$$74$$){case "select-one":$JSCompiler_StaticMethods_listen$$($JSCompiler_StaticMethods_registerListenersOnFilters$self$$.$eventHandler$,$trigger$$,"change",$JSCompiler_StaticMethods_registerListenersOnFilters$self$$.$onFilterChanged$,$JSCompiler_StaticMethods_registerListenersOnFilters$self$$);\r
+break;case "text":$trigger$$.setAttribute("title",$JSCompiler_StaticMethods_registerListenersOnFilters$self$$.options.filterToolTipMessage);$JSCompiler_StaticMethods_listen$$($JSCompiler_StaticMethods_registerListenersOnFilters$self$$.$eventHandler$,$trigger$$,"keyup",$JSCompiler_StaticMethods_registerListenersOnFilters$self$$.$onFilterChanged$,$JSCompiler_StaticMethods_registerListenersOnFilters$self$$);break;case "checkbox":$JSCompiler_StaticMethods_listen$$($JSCompiler_StaticMethods_registerListenersOnFilters$self$$.$eventHandler$,\r
+$trigger$$,"click",$JSCompiler_StaticMethods_registerListenersOnFilters$self$$.$onFilterChanged$,$JSCompiler_StaticMethods_registerListenersOnFilters$self$$);break;default:$JSCompiler_alias_THROW$$("Filter type "+$type$$74$$+" is not supported")}}}\r
+$JSCompiler_prototypeAlias$$.$clearAllFilters$=function $$JSCompiler_prototypeAlias$$$$clearAllFilters$$(){$goog$array$forEach$$(this.$filters$,this.$clearFilterValue$,this);this.options.additionalFilterTriggers&&$goog$array$forEach$$(this.options.additionalFilterTriggers,this.$clearFilterValue$,this);this.refresh()};\r
+$JSCompiler_prototypeAlias$$.$clearFilterValue$=function $$JSCompiler_prototypeAlias$$$$clearFilterValue$$($f$$26$$){var $type$$75$$=$f$$26$$.options?"select-one":$f$$26$$.getAttribute("type");switch($type$$75$$){case "select-one":$f$$26$$.selectedIndex=0;break;case "text":$f$$26$$.value="";break;case "checkbox":$f$$26$$.checked=$JSCompiler_alias_FALSE$$;break;default:$JSCompiler_alias_THROW$$("Filter type "+$type$$75$$+" is not supported")}};\r
+$JSCompiler_prototypeAlias$$.$initialiseControlCaches$=function $$JSCompiler_prototypeAlias$$$$initialiseControlCaches$$(){this.$listItems$=this.list.childNodes};$JSCompiler_prototypeAlias$$.$onFilterChanged$=function $$JSCompiler_prototypeAlias$$$$onFilterChanged$$(){this.$lastkeytime$=(new Date).getTime();this.$quickFindTimer$()};\r
+$JSCompiler_prototypeAlias$$.$quickFindTimer$=function $$JSCompiler_prototypeAlias$$$$quickFindTimer$$(){if(this.$lastTimerID$)clearTimeout(this.$lastTimerID$),this.$lastTimerID$=0;this.$cancelQuickFind$=$JSCompiler_alias_TRUE$$;var $delay$$3$$=this.options.filterDelay;(new Date).getTime()-this.$lastkeytime$>=$delay$$3$$?this.refresh():this.$lastTimerID$=$goog$Timer$callOnce$$(function(){this.$quickFindTimer$.call(this)},$delay$$3$$/3,this)};\r
+$JSCompiler_prototypeAlias$$.refresh=function $$JSCompiler_prototypeAlias$$$refresh$(){this.$cancelQuickFind$=$JSCompiler_alias_FALSE$$;clearTimeout(this.$lastTimerID$);var $filterStates$$=this.$getFilterStates$();$JSCompiler_StaticMethods_applyFilterStates$$(this,$filterStates$$,$JSCompiler_alias_FALSE$$);if(this.options.enableCookies){for(var $val$$inline_93$$=[],$additionalFilter$$inline_94$$=[],$additionalFilterValueCookieId$$inline_95$$=$JSCompiler_alias_NULL$$,$i$$inline_96$$=0;$i$$inline_96$$<\r
+$filterStates$$.length;$i$$inline_96$$++){var $state$$inline_97$$=$filterStates$$[$i$$inline_96$$],$val$$inline_93$$=$JSCompiler_StaticMethods_addFilterStateToStringArray$$($val$$inline_93$$,$state$$inline_97$$),$additionalFilterValueCookieId$$inline_95$$=this.options.additionalFilterValueCookieId;if(this.options.additionalFilterTriggers&&$additionalFilterValueCookieId$$inline_95$$)for(var $j$$inline_98$$=0;$j$$inline_98$$<this.options.additionalFilterTriggers.length;$j$$inline_98$$++)$state$$inline_97$$.id===\r
+this.options.additionalFilterTriggers[$j$$inline_98$$].getAttribute("id")&&($additionalFilter$$inline_94$$=$JSCompiler_StaticMethods_addFilterStateToStringArray$$($additionalFilter$$inline_94$$,$state$$inline_97$$))}$goog$net$cookies$$.set(this.$filterKey$,$val$$inline_93$$.join(""),999999);this.options.additionalFilterTriggers&&$additionalFilterValueCookieId$$inline_95$$&&$goog$net$cookies$$.set($additionalFilterValueCookieId$$inline_95$$,$additionalFilter$$inline_94$$.join(""),999999)}};\r
+$JSCompiler_prototypeAlias$$.$getFilterStates$=function $$JSCompiler_prototypeAlias$$$$getFilterStates$$(){var $state$$1$$=this.$getFilterStateForFilter$(this.$filterInput$);return $state$$1$$?[$state$$1$$]:[]};\r
+$JSCompiler_prototypeAlias$$.$getFilterStateForFilter$=function $$JSCompiler_prototypeAlias$$$$getFilterStateForFilter$$($filter$$1$$){var $type$$76$$=$filter$$1$$.options?"select-one":$filter$$1$$.getAttribute("type"),$value$$67$$;switch($type$$76$$){case "text":$value$$67$$=$filter$$1$$.value===$JSCompiler_alias_NULL$$?$JSCompiler_alias_NULL$$:$filter$$1$$.value.toLowerCase();break;case "select-one":$value$$67$$=0===$filter$$1$$.selectedIndex?$JSCompiler_alias_NULL$$:$filter$$1$$.options[$filter$$1$$.selectedIndex].value;\r
+break;case "checkbox":$value$$67$$=$filter$$1$$.checked;break;default:$JSCompiler_alias_THROW$$("Filter type "+$type$$76$$+" is not supported")}return $value$$67$$===$JSCompiler_alias_NULL$$||0>=$value$$67$$.length?$JSCompiler_alias_NULL$$:new $picnet$ui$filter$FilterState$$($filter$$1$$.getAttribute("id"),$value$$67$$,0,$type$$76$$)};\r
+function $JSCompiler_StaticMethods_addFilterStateToStringArray$$($cookieStringArray$$,$filterState$$1$$){0<$cookieStringArray$$.length&&$cookieStringArray$$.push("|");$cookieStringArray$$.push($filterState$$1$$.id);$cookieStringArray$$.push(",");$cookieStringArray$$.push($filterState$$1$$.$idx$);$cookieStringArray$$.push(",");$cookieStringArray$$.push($filterState$$1$$.type);$cookieStringArray$$.push(",");$cookieStringArray$$.push($filterState$$1$$.value);return $cookieStringArray$$}\r
+function $JSCompiler_StaticMethods_applyFilterStates$$($JSCompiler_StaticMethods_applyFilterStates$self$$,$filterStates$$2$$,$setValueOnFilter$$){$JSCompiler_StaticMethods_applyFilterStates$self$$.options.filteringElements&&$JSCompiler_StaticMethods_applyFilterStates$self$$.options.filteringElements($filterStates$$2$$);$JSCompiler_StaticMethods_applyFilterStatesImpl$$($JSCompiler_StaticMethods_applyFilterStates$self$$,$filterStates$$2$$,$setValueOnFilter$$);$JSCompiler_StaticMethods_applyFilterStates$self$$.options.filteredElements&&\r
+$JSCompiler_StaticMethods_applyFilterStates$self$$.options.filteredElements($filterStates$$2$$)}\r
+function $JSCompiler_StaticMethods_applyFilterStatesImpl$$($JSCompiler_StaticMethods_applyFilterStatesImpl$self$$,$filterStates$$3$$,$setValueOnFilter$$1$$){$JSCompiler_StaticMethods_clearElementFilteredStates$$($JSCompiler_StaticMethods_applyFilterStatesImpl$self$$);if(!(0===(!$filterStates$$3$$||$filterStates$$3$$.length)&&$JSCompiler_StaticMethods_applyFilterStatesImpl$self$$.options.matchingElement))if($filterStates$$3$$===$JSCompiler_alias_NULL$$||0===$filterStates$$3$$.length)$JSCompiler_StaticMethods_applyStateToElements$$($JSCompiler_StaticMethods_applyFilterStatesImpl$self$$,\r
+$JSCompiler_alias_NULL$$);else for(var $i$$84$$=0;$i$$84$$<$filterStates$$3$$.length;$i$$84$$++){var $state$$3$$=$filterStates$$3$$[$i$$84$$];if($setValueOnFilter$$1$$&&$state$$3$$.type&&$state$$3$$.id){var $filter$$2$$=$goog$isString$$($state$$3$$.id)?document.getElementById($state$$3$$.id):$state$$3$$.id;0===$filter$$2$$.length&&$JSCompiler_alias_THROW$$("Could not find the speficied filter: "+$state$$3$$.id);switch($state$$3$$.type){case "select-one":$goog$array$forEach$$($filter$$2$$.options,\r
+function($o$$1$$,$idx$$2$$){$o$$1$$.value===$state$$3$$.value?($o$$1$$.setAttribute("selected","selected"),$filter$$2$$.selectedIndex=$idx$$2$$):$o$$1$$.removeAttribute("selected")});break;case "text":$filter$$2$$.value=$state$$3$$.value;break;case "checkbox":$filter$$2$$.checked="true"===$state$$3$$.value;break;default:$JSCompiler_alias_THROW$$("Filter type "+$state$$3$$.type+" is not supported")}}$JSCompiler_StaticMethods_applyStateToElements$$($JSCompiler_StaticMethods_applyFilterStatesImpl$self$$,\r
+$state$$3$$)}$JSCompiler_StaticMethods_hideElementsThatDoNotMatchAnyFiltres$$($JSCompiler_StaticMethods_applyFilterStatesImpl$self$$)}function $JSCompiler_StaticMethods_clearElementFilteredStates$$($JSCompiler_StaticMethods_clearElementFilteredStates$self$$){$goog$array$forEach$$($JSCompiler_StaticMethods_clearElementFilteredStates$self$$.$listItems$,function($r$$){$r$$.removeAttribute("filtermatch")})}\r
+function $JSCompiler_StaticMethods_applyStateToElements$$($JSCompiler_StaticMethods_applyStateToElements$self$$,$filterState$$2$$){for(var $normalisedTokens$$3$$=$JSCompiler_StaticMethods_getNormalisedSearchTokensForState$$($JSCompiler_StaticMethods_applyStateToElements$self$$,$filterState$$2$$),$i$$85$$=0;$i$$85$$<$JSCompiler_StaticMethods_applyStateToElements$self$$.$listItems$.length&&!$JSCompiler_StaticMethods_applyStateToElements$self$$.$cancelQuickFind$;$i$$85$$++){var $item$$=$JSCompiler_StaticMethods_applyStateToElements$self$$.$listItems$[$i$$85$$];\r
+$item$$.getAttribute("filtermatch")||$JSCompiler_StaticMethods_applyStateToElements$self$$.$doesElementContainText$($filterState$$2$$,$item$$,$normalisedTokens$$3$$)||$item$$.setAttribute("filtermatch","false")}}\r
+function $JSCompiler_StaticMethods_getNormalisedSearchTokensForState$$($JSCompiler_StaticMethods_getNormalisedSearchTokensForState$self$$,$state$$4$$){if($state$$4$$===$JSCompiler_alias_NULL$$)return $JSCompiler_alias_NULL$$;switch($state$$4$$.type){case "select-one":return[$state$$4$$.value];case "text":var $JSCompiler_StaticMethods_parseSearchTokens$self$$inline_101_JSCompiler_inline_result$$100$$;$JSCompiler_StaticMethods_parseSearchTokens$self$$inline_101_JSCompiler_inline_result$$100$$=$JSCompiler_StaticMethods_getNormalisedSearchTokensForState$self$$.search;\r
+var $matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$=$state$$4$$.value;if($matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$){var $matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$=$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$.toLowerCase(),$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$;$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$=\r
+$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$.replace(">= ",">=").replace("> ",">").replace("<= ","<=").replace("< ","<").replace("!= ","!=").replace("= ","=");for(var $i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$=/([^"^\s]+)\s*|"([^"]+)"\s*/g,$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$=[],$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$=$JSCompiler_alias_NULL$$;$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$=\r
+$i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$.exec($exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$);)$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$.push($i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$[1]||$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$[2]);$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$=[];\r
+for($i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$=0;$i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$<$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$.length;$i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$++)$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$=$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$[$i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$],\r
+$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$=$JSCompiler_StaticMethods_normaliseTerm$$($exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$,$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$,"("),$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$=$JSCompiler_StaticMethods_normaliseTerm$$($exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$,$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$,\r
+")"),0<$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$.length&&$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$.push($i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$);$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$=$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$;$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$=\r
+[];for(var $lastToken$$inline_153_normalisedTokens$$inline_159$$,$i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$=0;$i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$<$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$.length;$i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$++)if(($i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$=$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$[$i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$])&&\r
+0!==$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$.length)0===$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$.indexOf("-")&&($i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$="not",$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$[$i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$]=$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$[$i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$].substring(1),\r
+$i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$--),$lastToken$$inline_153_normalisedTokens$$inline_159$$&&"("!==$lastToken$$inline_153_normalisedTokens$$inline_159$$&&"not"!==$lastToken$$inline_153_normalisedTokens$$inline_159$$&&"and"!==$lastToken$$inline_153_normalisedTokens$$inline_159$$&&"or"!==$lastToken$$inline_153_normalisedTokens$$inline_159$$&&"and"!==$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$&&"or"!==$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$&&\r
+")"!==$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$&&$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$.push("and"),$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$.push($i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$),$lastToken$$inline_153_normalisedTokens$$inline_159$$=$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$;$lastToken$$inline_153_normalisedTokens$$inline_159$$=\r
+$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$;$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$="";$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$=[];for($i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$=0;$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$<$lastToken$$inline_153_normalisedTokens$$inline_159$$.length;$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$++){var $token$$inline_164$$=\r
+$lastToken$$inline_153_normalisedTokens$$inline_159$$[$i$$inline_163_match$$inline_174_token$$inline_149_token$$inline_155$$];if(0!==$token$$inline_164$$.length)if("and"!==$token$$inline_164$$&&"or"!==$token$$inline_164$$&&"not"!==$token$$inline_164$$&&"("!==$token$$inline_164$$&&")"!==$token$$inline_164$$)$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$=$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$+"|"+$token$$inline_164$$;else if(0===\r
+$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$.length||"("===$token$$inline_164$$)$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$.push($token$$inline_164$$);else if(")"===$token$$inline_164$$)for($i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$=$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$.pop();"("!==$i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$&&\r
+0<$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$.length;)$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$=$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$+"|"+$i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$,$i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$=$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$.pop();\r
+else{if("("!==$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$[$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$.length-1])for(;0!==$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$.length&&!("("===$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$[$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$.length-\r
+1]);)if($JSCompiler_StaticMethods_parseSearchTokens$self$$inline_101_JSCompiler_inline_result$$100$$.$precedences_$[$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$[$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$.length-1]]>$JSCompiler_StaticMethods_parseSearchTokens$self$$inline_101_JSCompiler_inline_result$$100$$.$precedences_$[$token$$inline_164$$])$i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$=\r
+$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$.pop(),$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$=$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$+"|"+$i$$inline_148_i$$inline_154_regex$$inline_172_stackOperator$$inline_162$$;else break;$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$.push($token$$inline_164$$)}}for(;0<$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$.length;)$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$=\r
+$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$+"|"+$exp$$inline_171_newTokens$$inline_152_normalisedTokens$$inline_147_stackOps$$inline_161$$.pop();$JSCompiler_StaticMethods_parseSearchTokens$self$$inline_101_JSCompiler_inline_result$$100$$=$matches$$inline_173_postFix$$inline_160_text$$inline_102_tokens$$inline_151$$.substring(1).split("|")}else $JSCompiler_StaticMethods_parseSearchTokens$self$$inline_101_JSCompiler_inline_result$$100$$=$JSCompiler_alias_NULL$$;return $JSCompiler_StaticMethods_parseSearchTokens$self$$inline_101_JSCompiler_inline_result$$100$$;\r
+case "checkbox":return $JSCompiler_alias_NULL$$;default:$JSCompiler_alias_THROW$$("State type "+$state$$4$$.type+" is not supported")}}\r
+function $JSCompiler_StaticMethods_hideElementsThatDoNotMatchAnyFiltres$$($JSCompiler_StaticMethods_hideElementsThatDoNotMatchAnyFiltres$self$$){for(var $i$$86$$=0;$i$$86$$<$JSCompiler_StaticMethods_hideElementsThatDoNotMatchAnyFiltres$self$$.$listItems$.length&&!$JSCompiler_StaticMethods_hideElementsThatDoNotMatchAnyFiltres$self$$.$cancelQuickFind$;$i$$86$$++){var $item$$1$$=$JSCompiler_StaticMethods_hideElementsThatDoNotMatchAnyFiltres$self$$.$listItems$[$i$$86$$],$show$$="false"!==$item$$1$$.getAttribute("filtermatch");\r
+$item$$1$$.style.display=$show$$?"":"none"}}\r
+$JSCompiler_prototypeAlias$$.$doesElementContainText$=function $$JSCompiler_prototypeAlias$$$$doesElementContainText$$($state$$5$$,$item$$2$$,$textTokens$$1$$,$optText_text$$inline_167$$){var $JSCompiler_temp$$135_JSCompiler_temp$$2_exact_object$$inline_112$$=$state$$5$$!=$JSCompiler_alias_NULL$$&&"select-one"===$state$$5$$.type;$optText_text$$inline_167$$||($optText_text$$inline_167$$=$goog$string$trim$$($goog$dom$getTextContent$$($item$$2$$)));if($JSCompiler_temp$$135_JSCompiler_temp$$2_exact_object$$inline_112$$=$JSCompiler_StaticMethods_doesTextMatchTokens$$($optText_text$$inline_167$$,\r
+$textTokens$$1$$,$JSCompiler_temp$$135_JSCompiler_temp$$2_exact_object$$inline_112$$))this.options.matchingElement?($JSCompiler_temp$$135_JSCompiler_temp$$2_exact_object$$inline_112$$=$item$$2$$,window.jQuery&&($JSCompiler_temp$$135_JSCompiler_temp$$2_exact_object$$inline_112$$=window.jQuery($item$$2$$)),$JSCompiler_temp$$135_JSCompiler_temp$$2_exact_object$$inline_112$$=this.options.matchingElement($state$$5$$,$JSCompiler_temp$$135_JSCompiler_temp$$2_exact_object$$inline_112$$,$textTokens$$1$$)):\r
+$JSCompiler_temp$$135_JSCompiler_temp$$2_exact_object$$inline_112$$=$JSCompiler_alias_TRUE$$;return $JSCompiler_temp$$135_JSCompiler_temp$$2_exact_object$$inline_112$$};\r
+$JSCompiler_prototypeAlias$$.$disposeInternal$=function $$JSCompiler_prototypeAlias$$$$disposeInternal$$(){$picnet$ui$filter$GenericListFilter$$.$superClass_$.$disposeInternal$.call(this);$goog$dispose$$(this.options);$goog$dispose$$(this.$eventHandler$);$goog$dispose$$(this.search);delete this.list;delete this.$filterInput$;delete this.$listItems$;delete this.$filters$};function $picnet$ui$filter$TableFilterOptions$$(){}$goog$inherits$$($picnet$ui$filter$TableFilterOptions$$,$picnet$ui$filter$GenericListFilterOptions$$);function $picnet$ui$filter$TableFilter$$($grid$$,$options$$3$$){$options$$3$$.matchingRow&&($options$$3$$.matchingElement=$options$$3$$.matchingRow);$options$$3$$.filteringRows&&($options$$3$$.filteringElements=$options$$3$$.filteringRows);$options$$3$$.filteredRows&&($options$$3$$.filteredElements=$options$$3$$.filteredRows);$picnet$ui$filter$GenericListFilter$$.call(this,$JSCompiler_alias_NULL$$,$grid$$,$options$$3$$)}$goog$inherits$$($picnet$ui$filter$TableFilter$$,$picnet$ui$filter$GenericListFilter$$);\r
+$JSCompiler_prototypeAlias$$=$picnet$ui$filter$TableFilter$$.prototype;$JSCompiler_prototypeAlias$$.$initialiseFilters$=function $$JSCompiler_prototypeAlias$$$$initialiseFilters$$(){this.$thead$=$goog$dom$getElementsByTagNameAndClass_$$("thead",$JSCompiler_alias_NULL$$,this.options.frozenHeaderTable||this.list)[0];this.$tbody$=$goog$dom$getElementsByTagNameAndClass_$$("tbody",$JSCompiler_alias_NULL$$,this.list)[0];$picnet$ui$filter$TableFilter$$.$superClass_$.$initialiseFilters$.call(this)};\r
+$JSCompiler_prototypeAlias$$.$initialiseControlCaches$=function $$JSCompiler_prototypeAlias$$$$initialiseControlCaches$$(){this.headers=$goog$dom$getElementsByTagNameAndClass_$$("th",$JSCompiler_alias_NULL$$,this.$thead$);this.$listItems$=$goog$dom$getElementsByTagNameAndClass_$$("tr",$JSCompiler_alias_NULL$$,this.$tbody$);$JSCompiler_StaticMethods_buildFiltersRow$$(this);var $tHeadFilters$$=$goog$dom$getElementsByTagNameAndClass_$$("tr","filters",this.$thead$)[0];this.$filters$=$goog$array$concat$$($goog$array$map$$($goog$dom$getElementsByTagNameAndClass_$$("input",\r
+$JSCompiler_alias_NULL$$,$tHeadFilters$$),function($ctl$$){return $ctl$$}),$goog$array$map$$($goog$dom$getElementsByTagNameAndClass_$$("select",$JSCompiler_alias_NULL$$,$tHeadFilters$$),function($ctl$$1$$){return $ctl$$1$$}));this.$filterColumnIndexes$=$goog$array$map$$(this.$filters$,this.$getColumnIndexOfFilter$,this)};\r
+$JSCompiler_prototypeAlias$$.$getColumnIndexOfFilter$=function $$JSCompiler_prototypeAlias$$$$getColumnIndexOfFilter$$($f$$27_td$$){var $f$$27_td$$=$goog$dom$getAncestorByTagNameAndClass$$($f$$27_td$$,"TD"),$cells$$=$goog$dom$getAncestorByTagNameAndClass$$($f$$27_td$$,"TR").getElementsByTagName("td");return $goog$array$indexOf$$($cells$$,$f$$27_td$$)};\r
+function $JSCompiler_StaticMethods_buildFiltersRow$$($JSCompiler_StaticMethods_buildFiltersRow$self$$){for(var $tr$$1$$=$goog$dom$createDom$$("tr",{"class":"filters"}),$i$$87$$=0;$i$$87$$<$JSCompiler_StaticMethods_buildFiltersRow$self$$.headers.length;$i$$87$$++){var $element$$inline_119_filterType$$inline_117_header$$2_td$$1$$=$JSCompiler_StaticMethods_buildFiltersRow$self$$.headers[$i$$87$$],$filterClass_visible$$="none"!=$element$$inline_119_filterType$$inline_117_header$$2_td$$1$$.style.display;\r
+if($filterClass_visible$$){var $JSCompiler_StaticMethods_getFilterDom$self$$inline_114_headerText$$="false"===$element$$inline_119_filterType$$inline_117_header$$2_td$$1$$.getAttribute("filter")||!$filterClass_visible$$?"":$goog$dom$getTextContent$$($element$$inline_119_filterType$$inline_117_header$$2_td$$1$$),$filterClass_visible$$=$element$$inline_119_filterType$$inline_117_header$$2_td$$1$$.getAttribute("filter-class");if($JSCompiler_StaticMethods_getFilterDom$self$$inline_114_headerText$$&&1<\r
+$JSCompiler_StaticMethods_getFilterDom$self$$inline_114_headerText$$.length){var $filter$$3$$;a:{var $JSCompiler_StaticMethods_getFilterDom$self$$inline_114_headerText$$=$JSCompiler_StaticMethods_buildFiltersRow$self$$,$colIdx$$inline_115$$=$i$$87$$,$element$$inline_119_filterType$$inline_117_header$$2_td$$1$$=$element$$inline_119_filterType$$inline_117_header$$2_td$$1$$.getAttribute("filter-type")||"text";switch($element$$inline_119_filterType$$inline_117_header$$2_td$$1$$){case "text":$filter$$3$$=\r
+$goog$dom$createDom$$("input",{type:"text",id:"filter_"+$colIdx$$inline_115$$,"class":"filter",title:$JSCompiler_StaticMethods_getFilterDom$self$$inline_114_headerText$$.options.filterToolTipMessage});break a;case "ddl":$filter$$3$$=$JSCompiler_StaticMethods_getSelectFilter$$($JSCompiler_StaticMethods_getFilterDom$self$$inline_114_headerText$$,$colIdx$$inline_115$$);break a;default:$JSCompiler_alias_THROW$$("filter-type: "+$element$$inline_119_filterType$$inline_117_header$$2_td$$1$$+" is not supported")}}$element$$inline_119_filterType$$inline_117_header$$2_td$$1$$=\r
+$filter$$3$$;$goog$isString$$("width")?$goog$style$setStyle_$$($element$$inline_119_filterType$$inline_117_header$$2_td$$1$$,"95%","width"):$goog$object$forEach$$("width",$goog$partial$$($goog$style$setStyle_$$,$element$$inline_119_filterType$$inline_117_header$$2_td$$1$$));$element$$inline_119_filterType$$inline_117_header$$2_td$$1$$=$goog$dom$createDom$$("td",$JSCompiler_alias_NULL$$,$filter$$3$$)}else $element$$inline_119_filterType$$inline_117_header$$2_td$$1$$=$goog$dom$createDom$$("td",{},"");\r
+$filterClass_visible$$&&$goog$dom$classes$add$$($element$$inline_119_filterType$$inline_117_header$$2_td$$1$$,$filterClass_visible$$);$tr$$1$$.appendChild($element$$inline_119_filterType$$inline_117_header$$2_td$$1$$)}}$JSCompiler_StaticMethods_buildFiltersRow$self$$.$thead$.appendChild($tr$$1$$)}\r
+function $JSCompiler_StaticMethods_getSelectFilter$$($JSCompiler_StaticMethods_getSelectFilter$self$$,$colIdx$$1$$){var $select$$=$goog$dom$createDom$$("select",{id:"filter_"+$colIdx$$1$$,"class":"filter"},$goog$dom$createDom$$("option",{},$JSCompiler_StaticMethods_getSelectFilter$self$$.options.selectOptionLabel)),$cells$$1$$=$goog$array$map$$($JSCompiler_StaticMethods_getSelectFilter$self$$.$listItems$,function($r$$1$$){return $r$$1$$.cells[$colIdx$$1$$]}),$values$$7$$=[];$goog$array$forEach$$($cells$$1$$,\r
+function($td$$2_txt$$1$$){($td$$2_txt$$1$$=$goog$string$trim$$($goog$dom$getTextContent$$($td$$2_txt$$1$$)))&&!("&nbsp;"===$td$$2_txt$$1$$||0<=$goog$array$indexOf$$($values$$7$$,$td$$2_txt$$1$$))&&$values$$7$$.push($td$$2_txt$$1$$)});$values$$7$$.sort();$goog$array$forEach$$($values$$7$$,function($child$$inline_128_txt$$2$$){$child$$inline_128_txt$$2$$=$goog$dom$createDom$$("option",{value:$child$$inline_128_txt$$2$$.replace('"',"&#034;")},$child$$inline_128_txt$$2$$);$select$$.appendChild($child$$inline_128_txt$$2$$)});\r
+return $select$$}\r
+$JSCompiler_prototypeAlias$$.$getFilterStates$=function $$JSCompiler_prototypeAlias$$$$getFilterStates$$(){for(var $filterStates$$4$$=[],$i$$88$$=0;$i$$88$$<this.$filters$.length;$i$$88$$++){var $state$$7$$=this.$getFilterStateForFilter$(this.$filters$[$i$$88$$]);$state$$7$$&&$filterStates$$4$$.push($state$$7$$)}if(!this.options.additionalFilterTriggers)return $filterStates$$4$$;for($i$$88$$=0;$i$$88$$<this.options.additionalFilterTriggers.length;$i$$88$$++)($state$$7$$=this.$getFilterStateForFilter$(this.options.additionalFilterTriggers[$i$$88$$]))&&$filterStates$$4$$.push($state$$7$$);\r
+return $filterStates$$4$$};\r
+$JSCompiler_prototypeAlias$$.$getFilterStateForFilter$=function $$JSCompiler_prototypeAlias$$$$getFilterStateForFilter$$($JSCompiler_inline_result$$130_filter$$4_filterCell$$inline_132$$){var $state$$8$$=$picnet$ui$filter$TableFilter$$.$superClass_$.$getFilterStateForFilter$.call(this,$JSCompiler_inline_result$$130_filter$$4_filterCell$$inline_132$$);if($state$$8$$){$JSCompiler_inline_result$$130_filter$$4_filterCell$$inline_132$$=$goog$dom$getAncestorByTagNameAndClass$$($JSCompiler_inline_result$$130_filter$$4_filterCell$$inline_132$$,"TD");\r
+if(!$JSCompiler_inline_result$$130_filter$$4_filterCell$$inline_132$$||0>=$JSCompiler_inline_result$$130_filter$$4_filterCell$$inline_132$$.length)$JSCompiler_inline_result$$130_filter$$4_filterCell$$inline_132$$=-1;else var $filterRow$$inline_133$$=$goog$dom$getAncestorByTagNameAndClass$$($JSCompiler_inline_result$$130_filter$$4_filterCell$$inline_132$$,"TR"),$JSCompiler_inline_result$$130_filter$$4_filterCell$$inline_132$$=$goog$array$indexOf$$($filterRow$$inline_133$$.cells,$JSCompiler_inline_result$$130_filter$$4_filterCell$$inline_132$$);\r
+$state$$8$$.$idx$=$JSCompiler_inline_result$$130_filter$$4_filterCell$$inline_132$$}return $state$$8$$};\r
+$JSCompiler_prototypeAlias$$.$doesElementContainText$=function $$JSCompiler_prototypeAlias$$$$doesElementContainText$$($state$$9$$,$tr$$2$$,$textTokens$$5$$){var $cells$$2$$=$tr$$2$$.getElementsByTagName("td"),$columnIdx_txt$$3$$=$state$$9$$===$JSCompiler_alias_NULL$$?-1:$state$$9$$.$idx$;if(0>$columnIdx_txt$$3$$){for(var $columnIdx_txt$$3$$=[],$i$$89$$=0;$i$$89$$<$cells$$2$$.length;$i$$89$$++){var $header$$5$$=this.headers[$i$$89$$];"none"!=$header$$5$$.style.display&&"false"!==$header$$5$$.getAttribute("filter")&&\r
+$columnIdx_txt$$3$$.push($goog$string$trim$$($goog$dom$getTextContent$$($cells$$2$$[$i$$89$$])))}return $picnet$ui$filter$TableFilter$$.$superClass_$.$doesElementContainText$.call(this,$state$$9$$,$tr$$2$$,$textTokens$$5$$,$columnIdx_txt$$3$$.join("\t"))}return $picnet$ui$filter$TableFilter$$.$superClass_$.$doesElementContainText$.call(this,$state$$9$$,$cells$$2$$[$columnIdx_txt$$3$$],$textTokens$$5$$)};\r
+$JSCompiler_prototypeAlias$$.$disposeInternal$=function $$JSCompiler_prototypeAlias$$$$disposeInternal$$(){$picnet$ui$filter$TableFilter$$.$superClass_$.$disposeInternal$.call(this);delete this.$filterColumnIndexes$;delete this.headers;delete this.$thead$;delete this.$tbody$};var $jq$$=window.jQuery;\r
+$jq$$&&function($jq$$1$$){$jq$$1$$.$tableFilter$=function $$jq$$1$$$$tableFilter$$($element$$67$$,$opts$$){var $tf$$;this.$init$=function $this$$init$$(){var $options$$4$$=$jq$$1$$.extend({},new $picnet$ui$filter$TableFilterOptions$$,$opts$$);$tf$$=new $picnet$ui$filter$TableFilter$$($element$$67$$,$options$$4$$)};this.refresh=function $this$refresh$(){$picnet$ui$filter$TableFilter$$.$superClass_$.refresh.call($tf$$)};this.$init$()};$jq$$1$$.fn.tableFilter=function $$jq$$1$$$fn$tableFilter$($options$$5$$){return $goog$array$forEach$$(this,function($t$$){if($JSCompiler_alias_VOID$$===\r
+$jq$$1$$($t$$).data("tableFilter")||$jq$$1$$($t$$).data("tableFilter")===$JSCompiler_alias_NULL$$){var $plugin$$1$$=new $jq$$1$$.$tableFilter$($t$$,$options$$5$$);$jq$$1$$($t$$).data("tableFilter",$plugin$$1$$)}})};$jq$$1$$.fn.tableFilterRefresh=function $$jq$$1$$$fn$tableFilterRefresh$(){return $goog$array$forEach$$(this,function($t$$1$$){$JSCompiler_alias_VOID$$!==$jq$$1$$($t$$1$$).data("tableFilter")&&$jq$$1$$($t$$1$$).data("tableFilter")!==$JSCompiler_alias_NULL$$&&$jq$$1$$($t$$1$$).data("tableFilter").refresh()})}}($jq$$);\r
diff --git a/reports/reports/js/saveFormValues.js b/reports/reports/js/saveFormValues.js
new file mode 100644 (file)
index 0000000..71deef0
--- /dev/null
@@ -0,0 +1,174 @@
+/** 
+ * custom search javascript functions 
+ * 
+ * based on scripts from http://www.howtocreate.co.uk/jslibs
+ **/
+
+var FS_INCLUDE_NAMES = 0, FS_EXCLUDE_NAMES = 1, FS_INCLUDE_IDS = 2, FS_EXCLUDE_IDS = 3, FS_INCLUDE_CLASSES = 4, FS_EXCLUDE_CLASSES = 5;
+
+function getFormString( formRef, oAndPass, oTypes, oNames ) {
+       if( oNames ) {
+               oNames = new RegExp((( oTypes > 3 )?'\\b(':'^(')+oNames.replace(/([\\\/\[\]\(\)\.\+\*\{\}\?\^\$\|])/g,'\\$1').replace(/,/g,'|')+(( oTypes > 3 )?')\\b':')$'),'');
+               var oExclude = oTypes % 2;
+       }
+       for( var x = 0, oStr = '', y = false; formRef.elements[x]; x++ ) {
+               if( formRef.elements[x].type ) {
+                       if( oNames ) {
+                               var theAttr = ( oTypes > 3 ) ? formRef.elements[x].className : ( ( oTypes > 1 ) ? formRef.elements[x].id : formRef.elements[x].name );
+                               if( ( oExclude && theAttr && theAttr.match(oNames) ) || ( !oExclude && !( theAttr && theAttr.match(oNames) ) ) ) { continue; }
+                       }
+                       var oE = formRef.elements[x]; var oT = oE.type.toLowerCase();
+                       if( oT == 'text' || oT == 'textarea' || ( oT == 'password' && oAndPass ) || oT == 'datetime' || oT == 'datetime-local' || oT == 'date' || oT == 'month' || oT == 'week' || oT == 'time' || oT == 'number' || oT == 'range' || oT == 'email' || oT == 'url' ) {
+                               oStr += ( y ? ',' : '' ) + oE.value.replace(/%/g,'%p').replace(/,/g,'%c');
+                               y = true;
+                       } else if( oT == 'radio' || oT == 'checkbox' ) {
+                               oStr += ( y ? ',' : '' ) + ( oE.checked ? '1' : '' );
+                               y = true;
+                       } else if( oT == 'select-one' ) {
+                               oStr += ( y ? ',' : '' ) + oE.selectedIndex;
+                               y = true;
+                       } else if( oT == 'select-multiple' ) {
+                               for( var oO = oE.options, i = 0; oO[i]; i++ ) {
+                                       oStr += ( y ? ',' : '' ) + ( oO[i].selected ? '1' : '' );
+                                       y = true;
+                               }
+                       }
+               }
+       }
+       return oStr;
+}
+
+function recoverInputs( formRef, oStr, oAndPass, oTypes, oNames ) {
+       if( oStr ) {
+               oStr = oStr.split( ',' );
+               if( oNames ) {
+                       oNames = new RegExp((( oTypes > 3 )?'\\b(':'^(')+oNames.replace(/([\\\/\[\]\(\)\.\+\*\{\}\?\^\$\|])/g,'\\$1').replace(/,/g,'|')+(( oTypes > 3 )?')\\b':')$'),'');
+                       var oExclude = oTypes % 2;
+               }
+               for( var x = 0, y = 0; formRef.elements[x]; x++ ) {
+                       if( formRef.elements[x].type ) {
+                               if( oNames ) {
+                                       var theAttr = ( oTypes > 3 ) ? formRef.elements[x].className : ( ( oTypes > 1 ) ? formRef.elements[x].id : formRef.elements[x].name );
+                                       if( ( oExclude && theAttr && theAttr.match(oNames) ) || ( !oExclude && ( !theAttr || !theAttr.match(oNames) ) ) ) { continue; }
+                               }
+                               var oE = formRef.elements[x]; var oT = oE.type.toLowerCase();
+                               if( oT == 'text' || oT == 'textarea' || ( oT == 'password' && oAndPass ) || oT == 'datetime' || oT == 'datetime-local' || oT == 'date' || oT == 'month' || oT == 'week' || oT == 'time' || oT == 'number' || oT == 'range' || oT == 'email' || oT == 'url' ) {
+                                       oE.value = oStr[y].replace(/%c/g,',').replace(/%p/g,'%');
+                                       y++;
+                               } else if( oT == 'radio' || oT == 'checkbox' ) {
+                                       oE.checked = oStr[y] ? true : false;
+                                       y++;
+                               } else if( oT == 'select-one' ) {
+                                       oE.selectedIndex = parseInt( oStr[y] );
+                                       y++;
+                               } else if( oT == 'select-multiple' ) {
+                                       for( var oO = oE.options, i = 0; oO[i]; i++ ) {
+                                               oO[i].selected = oStr[y] ? true : false;
+                                               y++;
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+function retrieveCookie( cookieName ) {
+       /* retrieved in the format
+       cookieName4=value; cookieName3=value; cookieName2=value; cookieName1=value
+       only cookies for this domain and path will be retrieved */
+       var cookieJar = document.cookie.split( "; " );
+       for( var x = 0; x < cookieJar.length; x++ ) {
+               var oneCookie = cookieJar[x].split( "=" );
+               if( oneCookie[0] == escape( cookieName ) ) { return oneCookie[1] ? unescape( oneCookie[1] ) : ''; }
+       }
+       return null;
+}
+
+function setCookie( cookieName, cookieValue, lifeTime, path, domain, isSecure ) {
+       if( !cookieName ) { return false; }
+       if( lifeTime == "delete" ) { lifeTime = -10; } //this is in the past. Expires immediately.
+       /* This next line sets the cookie but does not overwrite other cookies.
+       syntax: cookieName=cookieValue[;expires=dataAsString[;path=pathAsString[;domain=domainAsString[;secure]]]]
+       Because of the way that document.cookie behaves, writing this here is equivalent to writing
+       document.cookie = whatIAmWritingNow + "; " + document.cookie; */
+       document.cookie = escape( cookieName ) + "=" + escape( cookieValue ) +
+               ( lifeTime ? ";expires=" + ( new Date( ( new Date() ).getTime() + ( 1000 * lifeTime ) ) ).toGMTString() : "" ) +
+               ( path ? ";path=" + path : "") + ( domain ? ";domain=" + domain : "") + 
+               ( isSecure ? ";secure" : "");
+       //check if the cookie has been set/deleted as required
+       if( lifeTime < 0 ) { if( typeof( retrieveCookie( cookieName ) ) == "string" ) { return false; } return true; }
+       if( typeof( retrieveCookie( cookieName ) ) == "string" ) { return true; } return false;
+}
+
+function get_cookies_array() {
+
+    var cookies = { };
+
+    if (document.cookie && document.cookie != '') {
+        var split = document.cookie.split(';');
+        for (var i = 0; i < split.length; i++) {
+            var name_value = split[i].split("=");
+            name_value[0] = name_value[0].replace(/^ /, '');
+            //cookies[decodeURIComponent(name_value[0])] = decodeURIComponent(name_value[1]);
+            cookies[unescape(name_value[0])] = unescape(name_value[1]);
+        }
+    }
+
+    return cookies;
+
+}
+
+/** Custom function to save and load search queries **/
+
+function saveQuery() {
+    var sName = document.getElementById("nameQuery").value;
+    sName='customReport_'+sName;
+    setCookie(sName,getFormString(document.forms.searchForm,true),3600000000); /* Looooong valid cookie */
+    loadButtons();
+ }
+
+ function loadQuery(name) {
+    recoverInputs(document.forms.searchForm,retrieveCookie('customReport_'+name),true);
+ }
+
+ function deleteQuery(name) {
+    setCookie( 'customReport_'+name, "", "delete");
+    loadButtons();
+ }
+
+ function loadButtons() {
+    var cookies = get_cookies_array();
+    var container = document.getElementById("loadButtons");
+    container.innerHTML = "";
+
+    for(var name in cookies) {
+       searchIndex = /(customReport_)/g;
+       isCustomReportCookie = searchIndex.test( name );
+       
+       if (isCustomReportCookie != false) {
+               
+               name = name.substring(13);
+               
+            var load = document.createElement("a");
+
+            load.setAttribute("href","#");
+            load.setAttribute("onclick","loadQuery(\'"+name+"\')");
+            load.innerHTML = "Load "+name;
+
+            container.appendChild(load);
+            
+            var span = document.createElement("span");
+            span.innerHTML = " | ";
+            container.appendChild(span);
+
+            var remove = document.createElement("a");
+
+            remove.setAttribute("href","#");
+            remove.setAttribute("onclick","deleteQuery(\'"+name+"\')");
+            remove.innerHTML = "Delete "+name;
+
+            container.appendChild(remove);
+            container.appendChild(document.createElement("br"));
+        }
+    }
+}
diff --git a/reports/reports/pix/asc.gif b/reports/reports/pix/asc.gif
new file mode 100644 (file)
index 0000000..7415786
Binary files /dev/null and b/reports/reports/pix/asc.gif differ
diff --git a/reports/reports/pix/bg.gif b/reports/reports/pix/bg.gif
new file mode 100644 (file)
index 0000000..fac668f
Binary files /dev/null and b/reports/reports/pix/bg.gif differ
diff --git a/reports/reports/pix/desc.gif b/reports/reports/pix/desc.gif
new file mode 100644 (file)
index 0000000..3b30b3c
Binary files /dev/null and b/reports/reports/pix/desc.gif differ
diff --git a/reports/reports/pix/network.png b/reports/reports/pix/network.png
new file mode 100644 (file)
index 0000000..72808f9
Binary files /dev/null and b/reports/reports/pix/network.png differ
diff --git a/reports/reports/pix/server.png b/reports/reports/pix/server.png
new file mode 100644 (file)
index 0000000..64df565
Binary files /dev/null and b/reports/reports/pix/server.png differ
diff --git a/reports/reports/pix/vm.png b/reports/reports/pix/vm.png
new file mode 100644 (file)
index 0000000..8b6438a
Binary files /dev/null and b/reports/reports/pix/vm.png differ
diff --git a/reports/reports/plugin.php b/reports/reports/plugin.php
new file mode 100644 (file)
index 0000000..3cb73d0
--- /dev/null
@@ -0,0 +1,381 @@
+<?php
+// Custom Racktables Report v.0.4.1
+// List a type of objects in a table and allow to export them via CSV
+
+// 2016-02-04 - Mogilowski Sebastian <sebastian@mogilowski.net>
+// 2018-09-10 - Lars Vogdt <lars@linux-schulserver.de>
+
+
+require_once "reportExtensionLib.php";
+require_once "custom-report.php";
+
+function plugin_reports_info ()
+{               
+        return array
+        (       
+                'name' => 'reports',
+                'longname' => 'Custom Reports', 
+                'version' => '0.4.1',
+                'home_url' => 'https://github.com/lrupp/racktables-reports'
+        );          
+}  
+
+function plugin_reports_init ()
+{
+       global $page, $tab;
+       $tab['reports']['custom'] = 'Custom';
+       $tab['reports']['server'] = 'Server';
+       $tab['reports']['switches'] = 'Switches';
+       $tab['reports']['vm'] = 'Virtual Machines';
+
+       $tabhandler['reports']['custom'] = 'renderCustomReport';
+       $tabhandler['reports']['server'] = 'renderServerReport';
+       $tabhandler['reports']['switches'] = 'renderSwitchReport';
+       $tabhandler['reports']['vm'] = 'renderVMReport';
+
+       registerTabHandler('reports', 'custom', 'renderCustomReport');
+        registerTabHandler('reports', 'server', 'renderServerReport');
+       registerTabHandler('reports', 'switches', 'renderSwitchReport');
+       registerTabHandler('reports', 'vm', 'renderVMReport');
+}
+
+function plugin_reports_install ()
+{
+       addConfigVar('REPORTS_CSS_PATH', 'css/report', 'string', 'yes', 'no', 'no', 'Path to the CSS files of the Custom Reports plugin');
+       addConfigVar('REPORTS_JS_PATH', 'js/report', 'string', 'yes', 'no', 'no', 'Path to the Javascript files of the Custom Reports plugin');
+       addConfigVar('REPORTS_SHOW_MAC_FOR_SWITCHES', 'yes', 'string', 'no', 'no', 'yes', 'Show MAC addresses in Custom Switch Report' );
+       return TRUE;
+}
+
+function plugin_reports_uninstall ()
+{
+       deleteConfigVar('REPORTS_CSS_PATH');
+       deleteConfigVar('REPORTS_JS_PATH');
+       deleteConfigVar('REPORTS_SHOW_MAC_FOR_SWITCHES');
+       return TRUE;
+}
+
+function plugin_reports_upgrade ()
+{
+        return TRUE;
+}
+
+function renderServerReport()
+{
+       $filter='{$typeid_4}'; # typeid_4 = Server
+       renderReport($filter);
+}
+
+function renderSwitchReport()
+{
+       $filter='{$typeid_8}'; # typeid_8 = Switches
+       renderReport($filter);
+}
+
+function renderVMReport()
+{
+       $filter='{$typeid_1504}'; # typeid_1504 = Virtual machines
+       renderReport($filter);
+}
+
+
+function renderReport($sFilter)
+{
+  $aResult = array();
+  $iTotal = 0;
+
+  foreach (scanRealmByText ('object', $sFilter) as $Result)
+  {
+
+    $aResult[$Result['id']] = array();
+    $aResult[$Result['id']]['sName'] = $Result['name'];
+
+    // Asset Number
+    $aResult[$Result['id']]['sAsset'] = $Result['asset_no'];
+
+    // Load additional attributes:
+    $attributes = getAttrValues ($Result['id']);
+
+    // Contact information
+    $aResult[$Result['id']]['sContact'] = '';
+    if ( isset( $attributes['14']['a_value'] ) )
+        $aResult[$Result['id']]['sContact'] = $attributes['14']['a_value'];
+
+    // Create active links in comment
+    $aResult[$Result['id']]['sComment'] = $Result['comment'];
+
+    // Hardware Type
+    $aResult[$Result['id']]['HWtype'] = '';
+    if ( isset( $attributes['2']['a_value'] ) )
+        $aResult[$Result['id']]['HWtype'] = $attributes['2']['a_value'];
+
+    // OEM S/N
+    $aResult[$Result['id']]['OEMSN'] = '';
+    if ( isset( $attributes['1']['a_value'] ) )
+        $aResult[$Result['id']]['OEMSN'] = $attributes['1']['a_value'];
+
+    // HW Expire Date
+    $aResult[$Result['id']]['HWExpDate'] = '';
+    if ( isset( $attributes['22']['value'] ) )
+        $aResult[$Result['id']]['HWExpDate'] = date("Y-m-d",$attributes['22']['value']);
+
+    // Operating System (OS)
+    $aResult[$Result['id']]['sOS'] = '';
+    if ( isset( $attributes['4']['a_value'] ) )
+        $aResult[$Result['id']]['sOS'] = $attributes['4']['a_value'];
+
+    // OS Version (for Switches)
+    $aResult[$Result['id']]['sOSVersion'] = '';
+    if ( isset( $attributes['5']['a_value'] ) )
+        $aResult[$Result['id']]['sOSVersion'] = $attributes['5']['a_value'];
+
+
+    $aResult[$Result['id']]['sSlotNumber'] = 'unknown';
+    if ( isset( $attributes['28']['a_value'] ) && ( $attributes['28']['a_value'] != '' ) )
+        $aResult[$Result['id']]['sSlotNumber'] = $attributes['28']['a_value'];
+
+    // Location
+    $aResult[$Result['id']]['sLocation'] = getLocation($Result);
+
+    // IP Informations
+    $aResult[$Result['id']]['ipV4List'] = getObjectIPv4AllocationList($Result['id']);
+    $aResult[$Result['id']]['ipV6List'] = getObjectIPv6AllocationList($Result['id']);
+
+    // Port (MAC) Informations
+    $aResult[$Result['id']]['ports'] = getObjectPortsAndLinks($Result['id']);
+
+    // Container
+    $aResult[$Result['id']]['container'] = getObjectContainerList($Result['id']);
+
+    $iTotal++;
+  }
+
+  // define standard fields for all filters
+  $aCSVRow = array('Name','MAC(s)','IP(s)','Comment','Contact');
+  $title = 'Unnamed report';
+  // add specific fields depending on filter value
+  switch($sFilter)
+  {
+      case '{$typeid_4}': $title = 'Server report';
+                          $report_type = 'server';
+                          array_push($aCSVRow, 'Type','Asset No.','Location','OEM S/N','HW Expire Date','OS');
+                          break;
+      case '{$typeid_8}': $title = 'Switch report';
+                          $report_type = 'switches';
+                          array_push($aCSVRow, 'Type','Asset No.','Location','OEM S/N','HW Expire Date','OS Version');
+                          break;
+      case '{$typeid_1504}': $title = 'Virtual machines report';
+                             $report_type = 'vm';
+                             array_push($aCSVRow, 'OS','Hypervisor');
+                             break;
+      default: echo '<h2>Unknown/No valid filter definition found</h2>';
+               break;
+  }
+
+  if ( isset($_GET['csv']) ) {
+
+     header('Content-type: text/csv');
+     header('Content-Disposition: attachment; filename=export_'.$report_type.'_'.date("Ymdhis").'.csv');
+     header('Pragma: no-cache');
+     header('Expires: 0');
+
+     $outstream = fopen("php://output", "w");
+
+     fputcsv( $outstream, $aCSVRow );
+
+     foreach ($aResult as $id => $aRow) 
+     {
+         //           0      1      2        3         4        5        6            7       8            9        10
+         // Server: 'Name','MAC','IP(s)','Comment','Contact', 'Type','Asset No.','Location','OEM','HW Expire Date','OS'
+         // Switch: 'Name','MAC','IP(s)','Comment','Contact', 'Type','Asset No.','Location','OEM','HW Expire Date','OS Version'
+         // VM    : 'Name','MAC','IP(s)','Comment','Contact', 'OS',  'Hypervisor'
+
+         $aCSVRow = array();
+         // Name
+         $aCSVRow[0] = $aRow['sName'];
+
+         // MAC
+         $aCSVRow[1] = '';
+         foreach ( $aRow['ports'] as $portNumber => $aPortDetails ) {
+          if (trim($aPortDetails['l2address']) != '')
+           $aCSVRow[1] .= $aPortDetails['l2address'] . ' ';
+         }
+         $aCSVRow[1] = trim($aCSVRow[1]);
+
+         // IP(s)
+         $aCSVRow[2] = '';
+         foreach ( $aRow['ipV4List'] as $key => $aDetails ) {
+          if ( function_exists('ip4_format') )
+           $key = ip4_format($key);
+          if ( trim($key) != '')
+           $aCSVRow[2] .= $key . ' ';
+         }
+         foreach ( $aRow['ipV6List'] as $key => $aDetails ) {
+          if ( function_exists('ip6_format') )
+           $key = ip6_format($key);
+          if ( trim($key) != '')
+           $aCSVRow[2] .= $key . ' ';
+         }
+         $aCSVRow[2] = trim($aCSVRow[2]);
+
+         // Comment
+         $aCSVRow[3] = str_replace('&quot;',"'",$aRow['sComment']);
+
+         // Contact
+         $aCSVRow[4] = $aRow['sContact'];
+
+         switch($sFilter)
+         {
+             case '{$typeid_4}':
+             case '{$typeid_8}':
+                                 // Type
+                                 $aCSVRow[5] = $aRow['HWtype'];
+                                 // Asset No
+                                 $aCSVRow[6] = $aRow['sAsset'];
+                                 // Location
+                                 $aCSVRow[7] = preg_replace('/<a[^>]*>(.*)<\/a>/iU', '$1', $aRow['sLocation']);
+                                 // OEM S/N
+                                 $aCSVRow[8] = $aRow['OEMSN'];
+                                 // HW Expire Date
+                                 $aCSVRow[9] = $aRow['HWExpDate'];
+                                 break;
+             case '{$typeid_1504}':
+                                 // OS
+                                 $aCSVRow[5] = $aRow['sOS'];
+                                 // Container
+                                 $aCSVRow[6] = '';
+                                 foreach ( $aRow['container'] as $key => $aDetails ) {
+                                     $aCSVRow[6] .= trim($aDetails['container_name']).' ';
+                                 }
+                                 break;
+         }
+         switch($sFilter)
+         {
+             case '{$typeid_4}': // OS
+                                 $aCSVRow[10] = $aRow['sOS'];
+                                 break;
+             case '{$typeid_8}': // OS Version
+                                 $aCSVRow[10] = $aRow['sOSVersion'];
+                                 break;
+         }
+
+         fputcsv( $outstream, $aCSVRow );
+     }
+
+     fclose($outstream);
+
+     exit(0); # Exit normally after send CSV to browser
+
+  }
+
+  // Load stylesheet and jquery sicripts
+  $css_path=getConfigVar('REPORTS_CSS_PATH');
+  $js_path=getConfigVar('REPORTS_JS_PATH');
+  addCSS ("$css_path/style.css");
+  addJS ("$js_path/jquery-latest.js");
+  addJS ("$js_path/jquery.tablesorter.js");
+  addJS ("$js_path/picnet.table.filter.min.js");
+
+  // Display the stat array
+  echo "\n<h2>$title (".$iTotal.")</h2><ul>";
+  echo "<a href='index.php?page=reports&tab=$report_type&csv'>CSV Export</a>\n";
+  echo "<table id=\"reportTable\" class=\"tablesorter\">\n  <thead>\n    <tr>\n";
+  foreach ($aCSVRow  as $row)
+  {
+    echo "      <th>$row</th>\n";
+  }
+  echo "    </tr>\n  </thead>\n<tbody>\n";
+
+  foreach ($aResult as $id => $aRow)
+  {
+      //           0      1      2        3         4        5        6            7       8            9        10
+      // Server: 'Name','MAC','IP(s)','Comment','Contact', 'Type','Asset No.','Location','OEM','HW Expire Date','OS'
+      // Switch: 'Name','MAC','IP(s)','Comment','Contact', 'Type','Asset No.','Location','OEM','HW Expire Date','OS Version'
+      // VM    : 'Name','MAC','IP(s)','Comment','Contact', 'OS',  'Hypervisor'
+      //
+      // Name
+      echo "<tr>\n  <td><a href=\"". makeHref ( array( 'page' => 'object', 'object_id' => $id) )  ."\">".$aRow['sName']."</a></td>\n  <td>";
+      // MAC
+      if (getConfigVar ('REPORTS_SHOW_MAC_FOR_SWITCHES') == 'yes')
+      {
+        foreach ( $aRow['ports'] as $portNumber => $aPortDetails ) {
+          if (trim($aPortDetails['l2address']) != '')
+              echo $aPortDetails['l2address'] . "<br/>\n";
+        }
+      }
+      echo "  </td>\n  <td>";
+
+      // IP(s)
+      foreach ( $aRow['ipV4List'] as $key => $aDetails ) {
+          if ( function_exists('ip4_format') )
+              $key = ip4_format($key);
+          if ( trim($key) != '')
+              echo $key . "<br/>\n";
+      }
+
+      foreach ( $aRow['ipV6List'] as $key => $aDetails ) {
+          if ( function_exists('ip6_format') )
+              $key = ip6_format($key);
+          if ( trim($key) != '')
+              echo $key . "<br/>\n";
+      }
+
+      // Comment & Contact
+      echo "  </td>\n  <td>".makeLinksInText($aRow['sComment'])."  </td>\n";
+      echo '  <td>'.makeLinksInText($aRow['sContact'])."  </td>\n";
+
+      switch($sFilter)
+      {
+             case '{$typeid_4}':
+             case '{$typeid_8}':
+                                 // Type
+                                 echo '  <td>'.$aRow['HWtype']."</td>\n";
+                                 // Asset No
+                                 echo '  <td>'.$aRow['sAsset']."</td>\n";
+                                 // Location
+                                 echo '  <td>'.$aRow['sLocation']."</td>\n";
+                                 // OEM S/N
+                                 echo '  <td>'.$aRow['OEMSN']."</td>\n";
+                                 // HW Expire Date
+                                 echo '  <td>'.$aRow['HWExpDate']."</td>\n";
+                                 break;
+             case '{$typeid_1504}':
+                                 // OS
+                                 echo '  <td>'.$aRow['sOS']."</td>\n";
+                                 // Container
+                                 echo '  <td>';
+                                 foreach ( $aRow['container'] as $key => $aDetails ) {
+                                     echo trim($aDetails['container_name'])."<br/>\n";
+                                 }
+                                 echo "  </td>\n";
+                                 break;
+      }
+      switch($sFilter)
+      {
+             case '{$typeid_4}': // OS
+                                 echo '  <td>'.$aRow['sOS']."</td>\n";
+                                 break;
+             case '{$typeid_8}': // OS Version
+                                 echo '  <td>'.$aRow['sOSVersion']."</td>\n";
+                                 break;
+      }
+      echo "  </tr>\n";
+  }
+
+  echo "  </tbody>\n</table>\n";
+
+  echo '<script type="text/javascript">
+          $(document).ready(function()
+          {
+            $.tablesorter.defaults.widgets = ["zebra"];
+            $("#reportTable").tablesorter(
+              { headers: {
+                2: { sorter: "ipAddress" },
+              }, sortList: [[0,0]] }
+            )
+            $("#reportTable").tableFilter();
+          });
+       </script>';
+}
+
+?>
diff --git a/reports/reports/reportExtensionLib.php b/reports/reports/reportExtensionLib.php
new file mode 100644 (file)
index 0000000..0b7a86d
--- /dev/null
@@ -0,0 +1,216 @@
+<?php
+// Custom Racktables Report v.0.3.3
+// Libary file
+
+// 2016-02-04 - Mogilowski Sebastian <sebastian@mogilowski.net>
+
+error_reporting(E_ERROR | E_PARSE);
+
+/**
+ * Get the location of an RackTables object
+ *
+ * @param array $aObject
+ * @return string
+ */
+function getLocation($aObject) {
+    $sRowName = 'unknown';
+    $sRackName = 'unknown';
+
+    # Location parsing for other realms than objects
+    if ($aObject['realm'] == 'rack') {
+       $sLocation = $aObject["location_name"] . ': '. $aObject["row_name"];
+       return $sLocation;
+    }
+
+    if ($aObject['realm'] == 'row') {
+       $sLocation = $aObject["location_name"];
+       return $sLocation;
+    }
+
+    if ($aObject['realm'] == 'location') {
+       if ($aObject["parent_name"] == null)
+               return '';
+       $sLocation = $aObject["parent_name"];
+       return $sLocation;
+    }
+
+    # Try to read the mount informations of the object
+    if ( function_exists('getMountInfo') ) {
+        $mountInfo = getMountInfo (array($aObject['id']));
+
+        if ( isset( $mountInfo[$aObject['id']][0]["rack_name"] ) )
+            $sRackName = $mountInfo[$aObject['id']][0]["rack_name"];
+
+        $sRowName = 'unknown';
+        if ( isset( $mountInfo[$aObject['id']][0]["row_name"] ) )
+            $sRowName = $mountInfo[$aObject['id']][0]["row_name"];
+    }
+    else {
+        if ( isset( $aObject["Row_name"] ) )
+            $sRowName = $aObject["Row_name"];
+
+        if ( isset( $aObject["Rack_name"] ) )
+            $sRackName = $aObject["Rack_name"];
+    }
+
+    # No mount information available - check for a container
+    if ( ( $sRowName == 'unknown' ) && ( $sRackName == 'unknown' ) && ( isset( $aObject['container_id'] ) ) ) {
+        $sContainerName = '<a href="'. makeHref ( array( 'page' => 'object', 'object_id' => $aObject['container_id']) )  .'">'.$aObject['container_name'].'</a>';
+
+       $attributes = getAttrValues ($aObject['id']);
+       if ( isset($attributes['28']['a_value']) && $attributes['28']['a_value'] != '' )
+           $sLocation = $sContainerName.': Slot '.$attributes['28']['a_value'];
+       else
+           $sLocation = $sContainerName;
+
+        # Get mount info of the container
+        $sContainerRowName = 'unknown';
+        $sContainerRackName = 'unknown';
+
+        if ( function_exists('getMountInfo') ) {
+
+            $containerMountInfo = getMountInfo (array($aObject['container_id']));
+
+            if ( isset( $containerMountInfo[$aObject['container_id']][0]["rack_name"] ) )
+                $sContainerRackName = $containerMountInfo[$aObject['container_id']][0]["rack_name"];
+
+            if ( isset( $containerMountInfo[$aObject['container_id']][0]["row_name"] ) )
+            $sContainerRowName = $containerMountInfo[$aObject['container_id']][0]["row_name"];
+
+            $sLocation .= '<br/>' . $sContainerRowName.': '.$sContainerRackName;
+        }
+    }
+    else {
+        $sLocation = $sRowName.': '.$sRackName;
+    }
+
+    return $sLocation;
+
+}
+
+ /**
+  * Create hyperlinks in text
+  *
+  * @param string $sText
+  * @return string
+  */
+ function makeLinksInText($sText)
+ {
+       # prepend http:// to www.xyz.com strings
+       $sText = preg_replace("/([^\/](www\.))(([^(\s|,)<]{4,68})[^(\s|,)<]*)/", ' http://$2$3', $sText);
+
+       # add html hyperlink to http:// and https:// strings
+       $sText = preg_replace("/(http:\/\/|https:\/\/)(([^(\s|,)<]{4,68})[^(\s|,)<]*)/", '<a href="$1$2" target="_blank">$2$4</a>', $sText);
+
+        # try to add mailto: links in text containing an '@' with a domain name
+        $sText = preg_replace("/([a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4})/", '<a href="mailto:$1" target="_blank">$1</a>', $sText);
+
+    return $sText;
+ }
+
+
+ # Need for backward compatibility - Define function from Racktables version 0.20.x
+if ( !function_exists('ip6_format') )
+{
+
+    function ip6_format ($ip_bin) {
+        // maybe this is IPv6-to-IPv4 address?
+        if (substr ($ip_bin, 0, 12) == "\0\0\0\0\0\0\0\0\0\0\xff\xff")
+            return '::ffff:' . implode ('.', unpack ('C*', substr ($ip_bin, 12, 4)));
+
+        $result = array();
+        $hole_index = NULL;
+        $max_hole_index = NULL;
+        $hole_length = 0;
+        $max_hole_length = 0;
+
+        for ($i = 0; $i < 8; $i++) {
+
+            $unpacked = unpack ('n', substr ($ip_bin, $i * 2, 2));
+            $value = array_shift ($unpacked);
+            $result[] = dechex ($value & 0xffff);
+
+            if ($value != 0) {
+
+                unset ($hole_index);
+                $hole_length = 0;
+
+            }
+            else {
+
+                if (! isset ($hole_index))
+                    $hole_index = $i;
+                if (++$hole_length >= $max_hole_length) {
+                    $max_hole_index = $hole_index;
+                    $max_hole_length = $hole_length;
+                }
+
+            }
+
+        }
+
+        if (isset ($max_hole_index)) {
+             array_splice ($result, $max_hole_index, $max_hole_length, array (''));
+
+            if ($max_hole_index == 0 && $max_hole_length == 8)
+                return '::';
+            elseif ($max_hole_index == 0)
+                return ':' . implode (':', $result);
+            elseif ($max_hole_index + $max_hole_length == 8)
+                return implode (':', $result) . ':';
+        }
+
+        return implode (':', $result);
+    }
+
+}
+
+/**
+ * Get the containers of an RackTables object
+ *
+ * @param integer $object_id
+ * @return array
+ */
+function getObjectContainerList ($object_id) {
+       $ret = array();
+
+       $result = usePreparedSelectBlade
+       (
+               'SELECT el.parent_entity_id AS container_id, ro.name as container_name '.
+               'FROM EntityLink AS el '.
+               'INNER JOIN RackObject AS ro ON ro.id = el.parent_entity_id '.
+               'WHERE el.child_entity_type = "object" AND el.parent_entity_type = "object" AND el.child_entity_id = ?',
+               array ($object_id)
+       );
+
+       while ($row = $result->fetch (PDO::FETCH_ASSOC))
+               $ret[$row['container_id']] = array ('container_name' => $row['container_name']);
+
+       return $ret;
+}
+
+/**
+ * Get list of child objects of an RackTables object
+ *
+ * @param integer $object_id
+ * @return array
+ */
+function getObjectChildObjectList ($object_id) {
+       $ret = array();
+
+       $result = usePreparedSelectBlade
+       (
+               'SELECT el.child_entity_id AS object_id, ro.name as object_name '.
+               'FROM EntityLink AS el  '.
+               'INNER JOIN RackObject AS ro ON ro.id = el.child_entity_id '.
+               'WHERE el.child_entity_type = "object" AND el.parent_entity_type = "object" AND el.parent_entity_id = ?',
+               array ($object_id)
+       );
+
+       while ($row = $result->fetch (PDO::FETCH_ASSOC))
+               $ret[$row['object_id']] = array ('object_name' => $row['object_name']);
+
+       return $ret;
+}
+
+?>