Merge branch 'master' of git+ssh://yeti.esilibrary.com/home/evergreen/evergreen-equin...
authorberick <berick@esilibrary.com>
Thu, 3 Mar 2011 15:01:45 +0000 (10:01 -0500)
committerberick <berick@esilibrary.com>
Thu, 3 Mar 2011 15:01:45 +0000 (10:01 -0500)
238 files changed:
Open-ILS/examples/apache/eg_vhost.conf
Open-ILS/examples/oils_web.xml.example
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb/I18NFilter.pm [new file with mode: 0644]
Open-ILS/web/css/skin/default/opac/contentslider.css [new file with mode: 0644]
Open-ILS/web/css/skin/default/opac/semiauto.css [new file with mode: 0644]
Open-ILS/web/css/skin/default/opac/style.css [new file with mode: 0644]
Open-ILS/web/images/KCLS_logo_horiz.gif [new file with mode: 0644]
Open-ILS/web/images/acct-btn-hover.png [new file with mode: 0644]
Open-ILS/web/images/acct-btn.png [new file with mode: 0644]
Open-ILS/web/images/acct_checked_out_off.gif [new file with mode: 0644]
Open-ILS/web/images/acct_checked_out_on.gif [new file with mode: 0644]
Open-ILS/web/images/acct_favs_off.gif [new file with mode: 0644]
Open-ILS/web/images/acct_favs_on.gif [new file with mode: 0644]
Open-ILS/web/images/acct_fines_off.jpg [new file with mode: 0644]
Open-ILS/web/images/acct_fines_on.jpg [new file with mode: 0644]
Open-ILS/web/images/acct_holds_off.gif [new file with mode: 0644]
Open-ILS/web/images/acct_holds_on.gif [new file with mode: 0644]
Open-ILS/web/images/acct_lists_off.gif [new file with mode: 0644]
Open-ILS/web/images/acct_lists_on.gif [new file with mode: 0644]
Open-ILS/web/images/acct_payments_off.jpg [new file with mode: 0644]
Open-ILS/web/images/acct_payments_on.jpg [new file with mode: 0644]
Open-ILS/web/images/acct_prefs_off.gif [new file with mode: 0644]
Open-ILS/web/images/acct_prefs_on.gif [new file with mode: 0644]
Open-ILS/web/images/acct_sum_fines_bl.png [new file with mode: 0644]
Open-ILS/web/images/acct_sum_fines_br.png [new file with mode: 0644]
Open-ILS/web/images/acct_sum_fines_tl.png [new file with mode: 0644]
Open-ILS/web/images/acct_sum_fines_tr.png [new file with mode: 0644]
Open-ILS/web/images/acct_summary_off.gif [new file with mode: 0644]
Open-ILS/web/images/acct_summary_on.gif [new file with mode: 0644]
Open-ILS/web/images/add_mylist.gif [new file with mode: 0644]
Open-ILS/web/images/add_mylist_sel.gif [new file with mode: 0644]
Open-ILS/web/images/add_mylist_sel.kcls.gif [new file with mode: 0644]
Open-ILS/web/images/add_search_row_btn.gif [new file with mode: 0644]
Open-ILS/web/images/adv_row_close_btn.png [new file with mode: 0644]
Open-ILS/web/images/adv_search.png [new file with mode: 0644]
Open-ILS/web/images/adv_search_hover.png [new file with mode: 0644]
Open-ILS/web/images/adv_search_off.gif [new file with mode: 0644]
Open-ILS/web/images/adv_search_on.gif [new file with mode: 0644]
Open-ILS/web/images/another_search.png [new file with mode: 0644]
Open-ILS/web/images/another_search_hover.png [new file with mode: 0644]
Open-ILS/web/images/arrow-down.gif [new file with mode: 0644]
Open-ILS/web/images/arrow-right.gif [new file with mode: 0644]
Open-ILS/web/images/arrow-right.png [new file with mode: 0644]
Open-ILS/web/images/asknow_available.gif [new file with mode: 0644]
Open-ILS/web/images/banner-bg.png [new file with mode: 0644]
Open-ILS/web/images/banner1.jpg [new file with mode: 0644]
Open-ILS/web/images/btnCancel.png [new file with mode: 0644]
Open-ILS/web/images/btnSubmit.png [new file with mode: 0644]
Open-ILS/web/images/button-bg.png [new file with mode: 0644]
Open-ILS/web/images/cancel_btn.gif [new file with mode: 0644]
Open-ILS/web/images/cd-small.png [new file with mode: 0644]
Open-ILS/web/images/clipboard.png [new file with mode: 0644]
Open-ILS/web/images/dash-corner-left1.png [new file with mode: 0644]
Open-ILS/web/images/dash-corner-left2.png [new file with mode: 0644]
Open-ILS/web/images/dash-corner-mid1.png [new file with mode: 0644]
Open-ILS/web/images/dash-corner-mid2.png [new file with mode: 0644]
Open-ILS/web/images/dash-corner-right1.png [new file with mode: 0644]
Open-ILS/web/images/dash-corner-right2.png [new file with mode: 0644]
Open-ILS/web/images/dash-divider.jpg [new file with mode: 0644]
Open-ILS/web/images/dropdown-hover.gif [new file with mode: 0644]
Open-ILS/web/images/dropdown.gif [new file with mode: 0644]
Open-ILS/web/images/expert_search_off.gif [new file with mode: 0644]
Open-ILS/web/images/expert_search_on.gif [new file with mode: 0644]
Open-ILS/web/images/faqs-btn.png [new file with mode: 0644]
Open-ILS/web/images/go-btn-hover.png [new file with mode: 0644]
Open-ILS/web/images/go-btn.png [new file with mode: 0644]
Open-ILS/web/images/go_but_long.gif [new file with mode: 0644]
Open-ILS/web/images/golive.jpg [new file with mode: 0644]
Open-ILS/web/images/gray-arrow.png [new file with mode: 0644]
Open-ILS/web/images/green_check.png [new file with mode: 0644]
Open-ILS/web/images/header_left.gif [new file with mode: 0644]
Open-ILS/web/images/header_right.gif [new file with mode: 0644]
Open-ILS/web/images/hp-links-left.jpg [new file with mode: 0644]
Open-ILS/web/images/hp-links-mid.jpg [new file with mode: 0644]
Open-ILS/web/images/hp-links-right.jpg [new file with mode: 0644]
Open-ILS/web/images/locations.jpg [new file with mode: 0644]
Open-ILS/web/images/login-bg.jpg [new file with mode: 0644]
Open-ILS/web/images/login-bg2.jpg [new file with mode: 0644]
Open-ILS/web/images/login-box-bg.jpg [new file with mode: 0644]
Open-ILS/web/images/login-btn-hover.png [new file with mode: 0644]
Open-ILS/web/images/login-btn.gif [new file with mode: 0644]
Open-ILS/web/images/login-btn.png [new file with mode: 0644]
Open-ILS/web/images/login-btn2.png [new file with mode: 0644]
Open-ILS/web/images/logout-btn-hover.png [new file with mode: 0644]
Open-ILS/web/images/logout-btn.png [new file with mode: 0644]
Open-ILS/web/images/media_3dobject.jpg [new file with mode: 0644]
Open-ILS/web/images/media_book.jpg [new file with mode: 0644]
Open-ILS/web/images/media_bookoncassette.jpg [new file with mode: 0644]
Open-ILS/web/images/media_bookoncassettecd.jpg [new file with mode: 0644]
Open-ILS/web/images/media_bookoncd.jpg [new file with mode: 0644]
Open-ILS/web/images/media_cassettewithbook.jpg [new file with mode: 0644]
Open-ILS/web/images/media_cdrom.jpg [new file with mode: 0644]
Open-ILS/web/images/media_cdwithbook.jpg [new file with mode: 0644]
Open-ILS/web/images/media_downloadebook.jpg [new file with mode: 0644]
Open-ILS/web/images/media_downloadmusic.jpg [new file with mode: 0644]
Open-ILS/web/images/media_downloadvideo.jpg [new file with mode: 0644]
Open-ILS/web/images/media_dvd.jpg [new file with mode: 0644]
Open-ILS/web/images/media_eaudio.jpg [new file with mode: 0644]
Open-ILS/web/images/media_ebooktext.jpg [new file with mode: 0644]
Open-ILS/web/images/media_equipment.jpg [new file with mode: 0644]
Open-ILS/web/images/media_films.jpg [new file with mode: 0644]
Open-ILS/web/images/media_games.jpg [new file with mode: 0644]
Open-ILS/web/images/media_kit.jpg [new file with mode: 0644]
Open-ILS/web/images/media_language.jpg [new file with mode: 0644]
Open-ILS/web/images/media_largeprint.jpg [new file with mode: 0644]
Open-ILS/web/images/media_magazines.jpg [new file with mode: 0644]
Open-ILS/web/images/media_map.jpg [new file with mode: 0644]
Open-ILS/web/images/media_microform.jpg [new file with mode: 0644]
Open-ILS/web/images/media_musiccassete.jpg [new file with mode: 0644]
Open-ILS/web/images/media_musiccassette.jpg [new file with mode: 0644]
Open-ILS/web/images/media_musiccd.jpg [new file with mode: 0644]
Open-ILS/web/images/media_musicrecord.jpg [new file with mode: 0644]
Open-ILS/web/images/media_newspaper.jpg [new file with mode: 0644]
Open-ILS/web/images/media_online.jpg [new file with mode: 0644]
Open-ILS/web/images/media_onlinejournal.jpg [new file with mode: 0644]
Open-ILS/web/images/media_podcasts.jpg [new file with mode: 0644]
Open-ILS/web/images/media_printedmusic.jpg [new file with mode: 0644]
Open-ILS/web/images/media_projectedmedia.jpg [new file with mode: 0644]
Open-ILS/web/images/media_sheetmusic.jpg [new file with mode: 0644]
Open-ILS/web/images/media_slide.jpg [new file with mode: 0644]
Open-ILS/web/images/media_software.jpg [new file with mode: 0644]
Open-ILS/web/images/media_streamingaudio.jpg [new file with mode: 0644]
Open-ILS/web/images/media_streamingvideo.jpg [new file with mode: 0644]
Open-ILS/web/images/media_vhs.jpg [new file with mode: 0644]
Open-ILS/web/images/num_search_off.gif [new file with mode: 0644]
Open-ILS/web/images/num_search_on.gif [new file with mode: 0644]
Open-ILS/web/images/one_land.gif [new file with mode: 0644]
Open-ILS/web/images/pay-fines-btn-hover.png [new file with mode: 0644]
Open-ILS/web/images/pay-fines-btn.png [new file with mode: 0644]
Open-ILS/web/images/pay_fines_btn.gif [new file with mode: 0644]
Open-ILS/web/images/place_hold.gif [new file with mode: 0644]
Open-ILS/web/images/plus_sign.png [new file with mode: 0644]
Open-ILS/web/images/projectedmedia.jpg [new file with mode: 0644]
Open-ILS/web/images/question-mark.png [new file with mode: 0644]
Open-ILS/web/images/questions.png [new file with mode: 0644]
Open-ILS/web/images/rdetail_arrow.png [new file with mode: 0644]
Open-ILS/web/images/reset_form_btn.gif [new file with mode: 0644]
Open-ILS/web/images/reviews.gif [new file with mode: 0644]
Open-ILS/web/images/save-btn.png [new file with mode: 0644]
Open-ILS/web/images/save_btn.gif [new file with mode: 0644]
Open-ILS/web/images/search_btn.gif [new file with mode: 0644]
Open-ILS/web/images/starz.png [new file with mode: 0644]
Open-ILS/web/images/sub_checked_hist_off.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_checked_hist_on.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_checked_out_off.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_checked_out_on.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_holds_hist_off.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_holds_hist_on.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_holds_off.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_holds_on.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_prefs_info_off.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_prefs_info_on.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_prefs_notify_off.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_prefs_notify_on.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_prefs_search_off.jpg [new file with mode: 0644]
Open-ILS/web/images/sub_prefs_search_on.jpg [new file with mode: 0644]
Open-ILS/web/images/submit_btn.gif [new file with mode: 0644]
Open-ILS/web/images/tool_back.gif [new file with mode: 0644]
Open-ILS/web/images/tool_back.png [new file with mode: 0644]
Open-ILS/web/images/tool_font.gif [new file with mode: 0644]
Open-ILS/web/images/tool_forward.gif [new file with mode: 0644]
Open-ILS/web/images/tool_forward.png [new file with mode: 0644]
Open-ILS/web/images/tool_help.gif [new file with mode: 0644]
Open-ILS/web/images/tool_help.png [new file with mode: 0644]
Open-ILS/web/images/tool_home.gif [new file with mode: 0644]
Open-ILS/web/images/tool_home.png [new file with mode: 0644]
Open-ILS/web/images/tool_mail.gif [new file with mode: 0644]
Open-ILS/web/images/tool_print.gif [new file with mode: 0644]
Open-ILS/web/images/tool_print.png [new file with mode: 0644]
Open-ILS/web/images/utils-corner-left.png [new file with mode: 0644]
Open-ILS/web/images/utils-corner-mid.png [new file with mode: 0644]
Open-ILS/web/images/utils-corner-right.jpg [new file with mode: 0644]
Open-ILS/web/images/utils-corner-right.png [new file with mode: 0644]
Open-ILS/web/images/utils-corner.jpg [new file with mode: 0644]
Open-ILS/web/images/view_my_list.png [new file with mode: 0644]
Open-ILS/web/images/view_my_list_hover.png [new file with mode: 0644]
Open-ILS/web/js/ui/default/opac/simple.js [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/base.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/common.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/home.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/login.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/marc_attrs.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/myopac/_links.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/myopac/bookbags.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/myopac/circs.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/myopac/fines.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/myopac/holds.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/myopac/main.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/myopac/prefs.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/myopac/update_email.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/place_hold.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/record.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac-poc/results.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/advanced.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/home.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/login.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/myopac/circs.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/myopac/holds.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/myopac/lists.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/myopac/main.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/myopac/prefs.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/advanced/global_row.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/advanced/search.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/audience_selector.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/base.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/cn_browse.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/filtersort.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/format_selector.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/header.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/homesearch.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/language_selector.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/login/form.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/marc_misc.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/myopac/base.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/org_selector.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/place_hold.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/qtype_selector.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/record/body.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/record/cn_details.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/record/copyinfo.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/record/extras.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/record/summary.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/result/lowhits.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/result/table.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/searchbar.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/tips.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/topnav.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/utils.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/place_hold.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/record.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/results.tt2 [new file with mode: 0644]

index 7fea97c..7fb1354 100644 (file)
@@ -169,26 +169,6 @@ RewriteRule . - [E=locale:%1]
 
 </Location>
 
-<Location /js/>
-    # ----------------------------------------------------------------------------------
-    # Some mod_deflate fun
-    # ----------------------------------------------------------------------------------
-    <IfModule mod_deflate.c>
-        SetOutputFilter DEFLATE
-
-        BrowserMatch ^Mozilla/4 gzip-only-text/html
-        BrowserMatch ^Mozilla/4\.0[678] no-gzip
-        BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
-
-        SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
-
-        <IfModule mod_headers.c>
-            Header append Vary User-Agent env=!dont-vary
-        </IfModule>
-    </IfModule>
-
-</Location>
-
 # ----------------------------------------------------------------------------------
 # Force SSL on the OPAC's "My Account" page
 # ----------------------------------------------------------------------------------
@@ -554,7 +534,40 @@ RewriteRule ^/openurl$ ${openurl:%1} [NE,PT]
     Options +ExecCGI
     PerlSendHeader On
     allow from all
+    <IfModule mod_deflate.c>
+        SetOutputFilter DEFLATE
+        BrowserMatch ^Mozilla/4 gzip-only-text/html
+        BrowserMatch ^Mozilla/4\.0[678] no-gzip
+        BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
+        SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
+        <IfModule mod_headers.c>
+            Header append Cache-Control "public"
+            Header append Vary User-Agent env=!dont-vary
+        </IfModule>
+    </IfModule>
 </Location>
+<LocationMatch ^/(images|css|js)/>
+    # should pick up the default expire time from eg.conf...
+    <IfModule mod_deflate.c>
+        SetOutputFilter DEFLATE
+        BrowserMatch ^Mozilla/4 gzip-only-text/html
+        BrowserMatch ^Mozilla/4\.0[678] no-gzip
+        BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
+        SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
+        <IfModule mod_headers.c>
+            Header append Cache-Control "public"
+            Header append Vary User-Agent env=!dont-vary
+        </IfModule>
+    </IfModule>
+</LocationMatch>
+<Location /eg/opac>
+    PerlSetVar OILSWebContextLoader "OpenILS::WWW::EGCatLoader"
+    # Expire the HTML quickly since we're loading dynamic data for each page
+    ExpiresActive On
+    ExpiresByType text/html "access plus 5 seconds"
+</Location>
+
+
 # Note: the template processor will decline handling anything it does not
 # have an explicit configuration for, which means it will fall back to 
 # Apache to serve the file.  However, in the interest of speed, go ahead 
index 60f1573..0728082 100644 (file)
@@ -9,8 +9,24 @@
         files have the following filename extension -->
     <default_template_extension>tt2</default_template_extension>
 
-    <!-- media_prefix can be a remote server.  
-         E.g. <media_prefix>http://static.example.com/media</media_prefix> -->
+    <!-- Media Prefix.  Allows static files to be served from an alternate domain/server
+
+            Examples:
+
+                # local URL path
+                <media_prefix>/media</media_prefix> 
+
+                # server w/ path.  
+                <media_prefix>static.example.com/media</media_prefix> 
+
+                ===
+                In the first 2 examples, the request protocol (http vs https) will
+                match the protocol of the current page
+                ===
+
+                # full-qualified with static protocol
+                <media_prefix>http://static.example.com/media</media_prefix> 
+     -->
     <media_prefix/>
 
     <!-- If set to true, all output will be parsed as XML before delivery to the client.  
         XML parsing adds overhead, so this should only be used for debugging -->
     <force_valid_xml>false</force_valid_xml>
 
+    <!-- Turn on template-toolkit debugging, which reports on undefined blocks, macros, etc. -->
+    <debug_template>false</debug_template>
+
+    <!-- 
+        Supported locales.  Locales with no message catalog will use the native template strings.
+        All locales will fall back to native strings when a given string is not in the catalog
+    -->
+    <locales>
+        <en_US/>
+        <en_CA>/openils/var/data/locale/messages.en_CA.po</en_CA>
+        <fr_CA>/openils/var/data/locale/messages.fr_CA.po</fr_CA>
+    </locales>
+
     <!-- Where templates can be found.  Paths will be checked in the order entered here.
          It's possible to override individual or sets of templates by putting them into
          a path in front of the default template path -->
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm
new file mode 100644 (file)
index 0000000..40d867b
--- /dev/null
@@ -0,0 +1,293 @@
+package OpenILS::WWW::EGCatLoader;
+use strict; use warnings;
+use CGI;
+use XML::LibXML;
+use URI::Escape;
+use Digest::MD5 qw(md5_hex);
+use Apache2::Const -compile => qw(OK DECLINED FORBIDDEN HTTP_INTERNAL_SERVER_ERROR REDIRECT HTTP_BAD_REQUEST);
+use OpenSRF::AppSession;
+use OpenSRF::EX qw/:try/;
+use OpenSRF::Utils qw/:datetime/;
+use OpenSRF::Utils::JSON;
+use OpenSRF::Utils::Logger qw/$logger/;
+use OpenILS::Application::AppUtils;
+use OpenILS::Utils::CStoreEditor qw/:funcs/;
+use OpenILS::Utils::Fieldmapper;
+use DateTime::Format::ISO8601;
+
+# EGCatLoader sub-modules 
+use OpenILS::WWW::EGCatLoader::Util;
+use OpenILS::WWW::EGCatLoader::Account;
+use OpenILS::WWW::EGCatLoader::Search;
+use OpenILS::WWW::EGCatLoader::Record;
+use OpenILS::WWW::EGCatLoader::Container;
+
+my $U = 'OpenILS::Application::AppUtils';
+
+use constant COOKIE_SES => 'ses';
+
+sub new {
+    my($class, $apache, $ctx) = @_;
+
+    my $self = bless({}, ref($class) || $class);
+
+    $self->apache($apache);
+    $self->ctx($ctx);
+    $self->cgi(CGI->new);
+
+    OpenILS::Utils::CStoreEditor->init; # just in case
+    $self->editor(new_editor());
+
+    return $self;
+}
+
+
+# current Apache2::RequestRec;
+sub apache {
+    my($self, $apache) = @_;
+    $self->{apache} = $apache if $apache;
+    return $self->{apache};
+}
+
+# runtime / template context
+sub ctx {
+    my($self, $ctx) = @_;
+    $self->{ctx} = $ctx if $ctx;
+    return $self->{ctx};
+}
+
+# cstore editor
+sub editor {
+    my($self, $editor) = @_;
+    $self->{editor} = $editor if $editor;
+    return $self->{editor};
+}
+
+# CGI handle
+sub cgi {
+    my($self, $cgi) = @_;
+    $self->{cgi} = $cgi if $cgi;
+    return $self->{cgi};
+}
+
+
+# -----------------------------------------------------------------------------
+# Perform initial setup, load common data, then load page data
+# -----------------------------------------------------------------------------
+sub load {
+    my $self = shift;
+
+    $self->init_ro_object_cache;
+
+    my $stat = $self->load_common;
+    return $stat unless $stat == Apache2::Const::OK;
+
+    my $path = $self->apache->path_info;
+
+    return $self->load_simple("home") if $path =~ /opac\/home/;
+    return $self->load_simple("advanced") if $path =~ /opac\/advanced/;
+    return $self->load_rresults if $path =~ /opac\/results/;
+    return $self->load_record if $path =~ /opac\/record/;
+    return $self->load_mylist_add if $path =~ /opac\/mylist\/add/;
+    return $self->load_mylist_del if $path =~ /opac\/mylist\/del/;
+    return $self->load_cache_clear if $path =~ /opac\/cache\/clear/;
+
+    # ----------------------------------------------------------------
+    # Logout and login require SSL
+    # ----------------------------------------------------------------
+    if($path =~ /opac\/login/) {
+        return $self->redirect_ssl unless $self->cgi->https;
+        return $self->load_login;
+    }
+
+    if($path =~ /opac\/logout/) {
+        #return Apache2::Const::FORBIDDEN unless $self->cgi->https; 
+        $self->apache->log->warn("catloader: logout called in non-secure context from " . 
+            ($self->ctx->{referer} || '<no referer>')) unless $self->cgi->https;
+        return $self->load_logout;
+    }
+
+    # ----------------------------------------------------------------
+    #  Everything below here requires SSL + authentication
+    # ----------------------------------------------------------------
+    return $self->redirect_auth
+        unless $self->cgi->https and $self->editor->requestor;
+
+    return $self->load_place_hold if $path =~ /opac\/place_hold/;
+    return $self->load_myopac_holds if $path =~ /opac\/myopac\/holds/;
+    return $self->load_myopac_circs if $path =~ /opac\/myopac\/circs/;
+    return $self->load_myopac_fines if $path =~ /opac\/myopac\/main/;
+    return $self->load_myopac_update_email if $path =~ /opac\/myopac\/update_email/;
+    return $self->load_myopac_bookbags if $path =~ /opac\/myopac\/bookbags/;
+    return $self->load_myopac if $path =~ /opac\/myopac/;
+
+    return Apache2::Const::OK;
+}
+
+
+# -----------------------------------------------------------------------------
+# Redirect to SSL equivalent of a given page
+# -----------------------------------------------------------------------------
+sub redirect_ssl {
+    my $self = shift;
+    my $new_page = sprintf('https://%s%s', $self->apache->hostname, $self->apache->unparsed_uri);
+    $self->apache->print($self->cgi->redirect(-url => $new_page));
+    return Apache2::Const::REDIRECT;
+}
+
+# -----------------------------------------------------------------------------
+# If an authnticated resource is requested w/o auth, redirect to the login page,
+# then return to the originally requrested resource upon successful login.
+# -----------------------------------------------------------------------------
+sub redirect_auth {
+    my $self = shift;
+    my $login_page = sprintf('https://%s%s/login', $self->apache->hostname, $self->ctx->{opac_root});
+    my $redirect_to = uri_escape($self->apache->unparsed_uri);
+    $self->apache->print($self->cgi->redirect(-url => "$login_page?redirect_to=$redirect_to"));
+    return Apache2::Const::REDIRECT;
+}
+
+# -----------------------------------------------------------------------------
+# Fall-through for loading a basic page
+# -----------------------------------------------------------------------------
+sub load_simple {
+    my ($self, $page) = @_;
+    $self->ctx->{page} = $page;
+    return Apache2::Const::OK;
+}
+
+# -----------------------------------------------------------------------------
+# Tests to see if the user is authenticated and sets some common context values
+# -----------------------------------------------------------------------------
+sub load_common {
+    my $self = shift;
+
+    my $e = $self->editor;
+    my $ctx = $self->ctx;
+
+    $ctx->{referer} = $self->cgi->referer;
+    $ctx->{path_info} = $self->cgi->path_info;
+    $ctx->{opac_root} = $ctx->{base_path} . "/opac"; # absolute base url
+    $ctx->{is_staff} = ($self->apache->headers_in->get('User-Agent') =~ 'oils_xulrunner');
+
+    # capture some commonly accessed pages
+    $ctx->{home_page} = 'http://' . $self->apache->hostname . $self->ctx->{opac_root} . "/home";
+    $ctx->{logout_page} = 'https://' . $self->apache->hostname . $self->ctx->{opac_root} . "/logout";
+
+    if($e->authtoken($self->cgi->cookie(COOKIE_SES))) {
+
+        if($e->checkauth) {
+
+            $ctx->{authtoken} = $e->authtoken;
+            $ctx->{authtime} = $e->authtime;
+            $ctx->{user} = $e->requestor;
+
+            $ctx->{user_stats} = $U->simplereq(
+                'open-ils.actor', 
+                'open-ils.actor.user.opac.vital_stats', 
+                $e->authtoken, $e->requestor->id);
+
+        } else {
+
+            # For now, keep an eye out for any pages being unceremoniously redirected to logout...
+            $self->apache->log->info("catloader: loading " . $ctx->{path_info} . 
+                "; auth session " .  $e->authtoken . " no longer valid; redirecting to logout");
+
+            return $self->load_logout;
+        }
+    }
+
+    return Apache2::Const::OK;
+}
+
+
+# -----------------------------------------------------------------------------
+# Log in and redirect to the redirect_to URL (or home)
+# -----------------------------------------------------------------------------
+sub load_login {
+    my $self = shift;
+    my $cgi = $self->cgi;
+    my $ctx = $self->ctx;
+
+    $ctx->{page} = 'login';
+
+    my $username = $cgi->param('username');
+    my $password = $cgi->param('password');
+    my $org_unit = $cgi->param('loc') || $ctx->{aou_tree}->()->id;
+    my $persist = $cgi->param('persist');
+
+    # initial log form only
+    return Apache2::Const::OK unless $username and $password;
+
+       my $seed = $U->simplereq(
+        'open-ils.auth', 
+               'open-ils.auth.authenticate.init', $username);
+
+    my $args = {       
+        username => $username, 
+        password => md5_hex($seed . md5_hex($password)), 
+        type => ($persist) ? 'persist' : 'opac' 
+    };
+
+    my $bc_regex = $ctx->{get_org_setting}->($org_unit, 'opac.barcode_regex');
+
+    $args->{barcode} = delete $args->{username} 
+        if $bc_regex and $username =~ /$bc_regex/;
+
+       my $response = $U->simplereq(
+        'open-ils.auth', 'open-ils.auth.authenticate.complete', $args);
+
+    if($U->event_code($response)) { 
+        # login failed, report the reason to the template
+        $ctx->{login_failed_event} = $response;
+        return Apache2::Const::OK;
+    }
+
+    # login succeeded, redirect as necessary
+
+    my $acct = $self->apache->unparsed_uri;
+    $acct =~ s#/login#/myopac/main#;
+
+    $self->apache->print(
+        $cgi->redirect(
+            -url => $cgi->param('redirect_to') || $acct,
+            -cookie => $cgi->cookie(
+                -name => COOKIE_SES,
+                -path => '/',
+                -secure => 1,
+                -value => $response->{payload}->{authtoken},
+                -expires => ($persist) ? CORE::time + $response->{payload}->{authtime} : undef
+            )
+        )
+    );
+
+    return Apache2::Const::REDIRECT;
+}
+
+# -----------------------------------------------------------------------------
+# Log out and redirect to the home page
+# -----------------------------------------------------------------------------
+sub load_logout {
+    my $self = shift;
+
+    # If the user was adding anyting to an anonymous cache 
+    # while logged in, go ahead and clear it out.
+    $self->clear_anon_cache;
+
+    $self->apache->print(
+        $self->cgi->redirect(
+            -url => $self->ctx->{home_page},
+            -cookie => $self->cgi->cookie(
+                -name => COOKIE_SES,
+                -path => '/',
+                -value => '',
+                -expires => '-1h'
+            )
+        )
+    );
+
+    return Apache2::Const::REDIRECT;
+}
+
+1;
+
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm
new file mode 100644 (file)
index 0000000..5042641
--- /dev/null
@@ -0,0 +1,510 @@
+package OpenILS::WWW::EGCatLoader;
+use strict; use warnings;
+use Apache2::Const -compile => qw(OK DECLINED FORBIDDEN HTTP_INTERNAL_SERVER_ERROR REDIRECT HTTP_BAD_REQUEST);
+use OpenSRF::Utils::Logger qw/$logger/;
+use OpenILS::Utils::CStoreEditor qw/:funcs/;
+use OpenILS::Utils::Fieldmapper;
+use OpenILS::Application::AppUtils;
+my $U = 'OpenILS::Application::AppUtils';
+
+
+# context additions: 
+#   user : au object, fleshed
+sub load_myopac {
+    my $self = shift;
+    $self->ctx->{page} = 'myopac';
+
+    $self->ctx->{user} = $self->editor->retrieve_actor_user([
+        $self->ctx->{user}->id,
+        {
+            flesh => 1,
+            flesh_fields => {
+                au => ['card']
+                # ...
+            }
+        }
+    ]);
+
+    return Apache2::Const::OK;
+}
+
+
+sub fetch_user_holds {
+    my $self = shift;
+    my $hold_ids = shift;
+    my $ids_only = shift;
+    my $flesh = shift;
+    my $available = shift;
+    my $limit = shift;
+    my $offset = shift;
+
+    my $e = $self->editor;
+
+    my $circ = OpenSRF::AppSession->create('open-ils.circ');
+
+    if(!$hold_ids) {
+
+        $hold_ids = $circ->request(
+            'open-ils.circ.holds.id_list.retrieve.authoritative', 
+            $e->authtoken, 
+            $e->requestor->id
+        )->gather(1);
+    
+        $hold_ids = [ grep { defined $_ } @$hold_ids[$offset..($offset + $limit - 1)] ] if $limit or $offset;
+    }
+
+
+    return $hold_ids if $ids_only or @$hold_ids == 0;
+
+    my $args = {
+        suppress_notices => 1,
+        suppress_transits => 1,
+        suppress_mvr => 1,
+        suppress_patron_details => 1,
+        include_bre => $flesh ? 1 : 0
+    };
+
+    # ----------------------------------------------------------------
+    # Collect holds in batches of $batch_size for faster retrieval
+
+    my $batch_size = 8;
+    my $batch_idx = 0;
+    my $mk_req_batch = sub {
+        my @ses;
+        my $top_idx = $batch_idx + $batch_size;
+        while($batch_idx < $top_idx) {
+            my $hold_id = $hold_ids->[$batch_idx++];
+            last unless $hold_id;
+            my $ses = OpenSRF::AppSession->create('open-ils.circ');
+            my $req = $ses->request(
+                'open-ils.circ.hold.details.retrieve', 
+                $e->authtoken, $hold_id, $args);
+            push(@ses, {ses => $ses, req => $req});
+        }
+        return @ses;
+    };
+
+    my $first = 1;
+    my(@collected, @holds, @ses);
+
+    while(1) {
+        @ses = $mk_req_batch->() if $first;
+        last if $first and not @ses;
+
+        if(@collected) {
+            # If desired by the caller, filter any holds that are not available.
+            if ($available) {
+                @collected = grep { $_->{hold}->{status} == 4 } @collected;
+            }
+            while(my $blob = pop(@collected)) {
+                $blob->{marc_xml} = XML::LibXML->new->parse_string($blob->{hold}->{bre}->marc) if $flesh;
+                push(@holds, $blob);
+            }
+        }
+
+        for my $req_data (@ses) {
+            push(@collected, {hold => $req_data->{req}->gather(1)});
+            $req_data->{ses}->kill_me;
+        }
+
+        @ses = $mk_req_batch->();
+        last unless @collected or @ses;
+        $first = 0;
+    }
+
+    # put the holds back into the original server sort order
+    my @sorted;
+    for my $id (@$hold_ids) {
+        push @sorted, grep { $_->{hold}->{hold}->id == $id } @holds;
+    }
+
+    return \@sorted;
+}
+
+sub handle_hold_update {
+    my $self = shift;
+    my $action = shift;
+    my $e = $self->editor;
+
+
+    my @hold_ids = $self->cgi->param('hold_id'); # for non-_all actions
+    @hold_ids = @{$self->fetch_user_holds(undef, 1)} if $action =~ /_all/;
+
+    my $circ = OpenSRF::AppSession->create('open-ils.circ');
+
+    if($action =~ /cancel/) {
+
+        for my $hold_id (@hold_ids) {
+            my $resp = $circ->request(
+                'open-ils.circ.hold.cancel', $e->authtoken, $hold_id, 6 )->gather(1); # 6 == patron-cancelled-via-opac
+        }
+
+    } else {
+        
+        my $vlist = [];
+        for my $hold_id (@hold_ids) {
+            my $vals = {id => $hold_id};
+
+            if($action =~ /activate/) {
+                $vals->{frozen} = 'f';
+                $vals->{thaw_date} = undef;
+
+            } elsif($action =~ /suspend/) {
+                $vals->{frozen} = 't';
+                # $vals->{thaw_date} = TODO;
+            }
+            push(@$vlist, $vals);
+        }
+
+        $circ->request('open-ils.circ.hold.update.batch.atomic', $e->authtoken, undef, $vlist)->gather(1);
+    }
+
+    $circ->kill_me;
+    return undef;
+}
+
+sub load_myopac_holds {
+    my $self = shift;
+    my $e = $self->editor;
+    my $ctx = $self->ctx;
+    
+
+    my $limit = $self->cgi->param('limit') || 0;
+    my $offset = $self->cgi->param('offset') || 0;
+    my $action = $self->cgi->param('action') || '';
+    my $available = int($self->cgi->param('available') || 0);
+
+    $self->handle_hold_update($action) if $action;
+
+    $ctx->{holds} = $self->fetch_user_holds(undef, 0, 1, $available, $limit, $offset);
+
+    return Apache2::Const::OK;
+}
+
+sub load_place_hold {
+    my $self = shift;
+    my $ctx = $self->ctx;
+    my $e = $self->editor;
+    my $cgi = $self->cgi;
+    $self->ctx->{page} = 'place_hold';
+
+    $ctx->{hold_target} = $cgi->param('hold_target');
+    $ctx->{hold_type} = $cgi->param('hold_type');
+    $ctx->{default_pickup_lib} = $e->requestor->home_ou; # XXX staff
+
+    if($ctx->{hold_type} eq 'T') {
+        $ctx->{record} = $e->retrieve_biblio_record_entry($ctx->{hold_target});
+    }
+    # ...
+
+    $ctx->{marc_xml} = XML::LibXML->new->parse_string($ctx->{record}->marc);
+
+    if(my $pickup_lib = $cgi->param('pickup_lib')) {
+
+        my $args = {
+            patronid => $e->requestor->id,
+            titleid => $ctx->{hold_target}, # XXX
+            pickup_lib => $pickup_lib,
+            depth => 0, # XXX
+        };
+
+        my $allowed = $U->simplereq(
+            'open-ils.circ',
+            'open-ils.circ.title_hold.is_possible',
+            $e->authtoken, $args
+        );
+
+        if($allowed->{success} == 1) {
+            my $hold = Fieldmapper::action::hold_request->new;
+
+            $hold->pickup_lib($pickup_lib);
+            $hold->requestor($e->requestor->id);
+            $hold->usr($e->requestor->id); # XXX staff
+            $hold->target($ctx->{hold_target});
+            $hold->hold_type($ctx->{hold_type});
+            # frozen, expired, etc..
+
+            my $stat = $U->simplereq(
+                'open-ils.circ',
+                'open-ils.circ.holds.create',
+                $e->authtoken, $hold
+            );
+
+            if($stat and $stat > 0) {
+                # if successful, return the user to the requesting page
+                $self->apache->log->info("Redirecting back to " . $cgi->param('redirect_to'));
+                $self->apache->print($cgi->redirect(-url => $cgi->param('redirect_to')));
+                return Apache2::Const::REDIRECT;
+
+            } else {
+                $ctx->{hold_failed} = 1;
+            }
+        } else { # hold *check* failed
+            $ctx->{hold_failed} = 1; # XXX process the events, etc
+            $ctx->{hold_failed_event} = $allowed->{last_event};
+        }
+
+        # hold permit failed
+        $logger->info('hold permit result ' . OpenSRF::Utils::JSON->perl2JSON($allowed));
+    }
+
+    return Apache2::Const::OK;
+}
+
+
+sub fetch_user_circs {
+    my $self = shift;
+    my $flesh = shift; # flesh bib data, etc.
+    my $circ_ids = shift;
+    my $limit = shift;
+    my $offset = shift;
+
+    my $e = $self->editor;
+
+    my @circ_ids;
+
+    if($circ_ids) {
+        @circ_ids = @$circ_ids;
+
+    } else {
+
+        my $circ_data = $U->simplereq(
+            'open-ils.actor', 
+            'open-ils.actor.user.checked_out',
+            $e->authtoken, 
+            $e->requestor->id
+        );
+
+        @circ_ids =  ( @{$circ_data->{overdue}}, @{$circ_data->{out}} );
+
+        if($limit or $offset) {
+            @circ_ids = grep { defined $_ } @circ_ids[0..($offset + $limit - 1)];
+        }
+    }
+
+    return [] unless @circ_ids;
+
+    my $cstore = OpenSRF::AppSession->create('open-ils.cstore');
+
+    my $qflesh = {
+        flesh => 3,
+        flesh_fields => {
+            circ => ['target_copy'],
+            acp => ['call_number'],
+            acn => ['record']
+        }
+    };
+
+    $e->xact_begin;
+    my $circs = $e->search_action_circulation(
+        [{id => \@circ_ids}, ($flesh) ? $qflesh : {}], {substream => 1});
+
+    my @circs;
+    for my $circ (@$circs) {
+        push(@circs, {
+            circ => $circ, 
+            marc_xml => ($flesh and $circ->target_copy->call_number->id != -1) ? 
+                XML::LibXML->new->parse_string($circ->target_copy->call_number->record->marc) : 
+                undef  # pre-cat copy, use the dummy title/author instead
+        });
+    }
+    $e->xact_rollback;
+
+    # make sure the final list is in the correct order
+    my @sorted_circs;
+    for my $id (@circ_ids) {
+        push(
+            @sorted_circs,
+            (grep { $_->{circ}->id == $id } @circs)
+        );
+    }
+
+    return \@sorted_circs;
+}
+
+
+sub handle_circ_renew {
+    my $self = shift;
+    my $action = shift;
+    my $ctx = $self->ctx;
+
+    my @renew_ids = $self->cgi->param('circ');
+
+    my $circs = $self->fetch_user_circs(0, ($action eq 'renew') ? [@renew_ids] : undef);
+
+    # TODO: fire off renewal calls in batches to speed things up
+    my @responses;
+    for my $circ (@$circs) {
+
+        my $evt = $U->simplereq(
+            'open-ils.circ', 
+            'open-ils.circ.renew',
+            $self->editor->authtoken,
+            {
+                patron_id => $self->editor->requestor->id,
+                copy_id => $circ->{circ}->target_copy,
+                opac_renewal => 1
+            }
+        );
+
+        # TODO return these, then insert them into the circ data 
+        # blob that is shoved into the template for each circ
+        # so the template won't have to match them
+        push(@responses, {copy => $circ->{circ}->target_copy, evt => $evt});
+    }
+
+    return @responses;
+}
+
+
+sub load_myopac_circs {
+    my $self = shift;
+    my $e = $self->editor;
+    my $ctx = $self->ctx;
+
+    $ctx->{circs} = [];
+    my $limit = $self->cgi->param('limit') || 0; # 0 == unlimited
+    my $offset = $self->cgi->param('offset') || 0;
+    my $action = $self->cgi->param('action') || '';
+
+    # perform the renewal first if necessary
+    my @results = $self->handle_circ_renew($action) if $action =~ /renew/;
+
+    $ctx->{circs} = $self->fetch_user_circs(1, undef, $limit, $offset);
+
+    my $success_renewals = 0;
+    my $failed_renewals = 0;
+    for my $data (@{$ctx->{circs}}) {
+        my ($resp) = grep { $_->{copy} == $data->{circ}->target_copy->id } @results;
+
+        if($resp) {
+            my $evt = ref($resp->{evt}) eq 'ARRAY' ? $resp->{evt}->[0] : $resp->{evt};
+            $data->{renewal_response} = $evt;
+            $success_renewals++ if $evt->{textcode} eq 'SUCCESS';
+            $failed_renewals++ if $evt->{textcode} ne 'SUCCESS';
+        }
+    }
+
+    $ctx->{success_renewals} = $success_renewals;
+    $ctx->{failed_renewals} = $failed_renewals;
+
+    return Apache2::Const::OK;
+}
+
+sub load_myopac_fines {
+    my $self = shift;
+    my $e = $self->editor;
+    my $ctx = $self->ctx;
+    $ctx->{"fines"} = {
+        "circulation" => [],
+        "grocery" => [],
+        "total_paid" => 0,
+        "total_owed" => 0,
+        "balance_owed" => 0
+    };
+
+    my $limit = $self->cgi->param('limit') || 0;
+    my $offset = $self->cgi->param('offset') || 0;
+
+    my $cstore = OpenSRF::AppSession->create('open-ils.cstore');
+
+    # TODO: This should really be a ML call, but the existing calls 
+    # return an excessive amount of data and don't offer streaming
+
+    my %paging = ($limit or $offset) ? (limit => $limit, offset => $offset) : ();
+
+    my $req = $cstore->request(
+        'open-ils.cstore.direct.money.open_billable_transaction_summary.search',
+        {
+            usr => $e->requestor->id,
+            balance_owed => {'!=' => 0}
+        },
+        {
+            flesh => 4,
+            flesh_fields => {
+                mobts => ['circulation', 'grocery'],
+                mg => ['billings'],
+                mb => ['btype'],
+                circ => ['target_copy'],
+                acp => ['call_number'],
+                acn => ['record']
+            },
+            order_by => { mobts => 'xact_start' },
+            %paging
+        }
+    );
+
+    while(my $resp = $req->recv) {
+        my $mobts = $resp->content;
+        my $circ = $mobts->circulation;
+
+        my $last_billing;
+        if($mobts->grocery) {
+            my @billings = sort { $a->billing_ts cmp $b->billing_ts } @{$mobts->grocery->billings};
+            $last_billing = pop(@billings);
+        }
+
+        # XXX TODO switch to some money-safe non-fp library for math
+        $ctx->{"fines"}->{$_} += $mobts->$_ for (
+            qw/total_paid total_owed balance_owed/
+        );
+
+        push(
+            @{$ctx->{"fines"}->{$mobts->grocery ? "grocery" : "circulation"}},
+            {
+                xact => $mobts,
+                last_grocery_billing => $last_billing,
+                marc_xml => ($mobts->xact_type ne 'circulation' or $circ->target_copy->call_number->id == -1) ?
+                    undef :
+                    XML::LibXML->new->parse_string($circ->target_copy->call_number->record->marc),
+            } 
+        );
+    }
+
+     return Apache2::Const::OK;
+}       
+
+sub load_myopac_update_email {
+    my $self = shift;
+    my $e = $self->editor;
+    my $ctx = $self->ctx;
+    my $email = $self->cgi->param('email') || '';
+
+    unless($email =~ /.+\@.+\..+/) { # TODO better regex?
+        $ctx->{invalid_email} = $email;
+        return Apache2::Const::OK;
+    }
+
+    my $stat = $U->simplereq(
+        'open-ils.actor', 
+        'open-ils.actor.user.email.update', 
+        $e->authtoken, $email);
+
+    my $url = $self->apache->unparsed_uri;
+    $url =~ s/update_email/main/;
+    $self->apache->print($self->cgi->redirect(-url => $url));
+
+    return Apache2::Const::REDIRECT;
+}
+
+sub load_myopac_bookbags {
+    my $self = shift;
+    my $e = $self->editor;
+    my $ctx = $self->ctx;
+    my $limit = $self->cgi->param('limit') || 0;
+    my $offset = $self->cgi->param('offset') || 0;
+
+    my $args = {order_by => {cbreb => 'name'}};
+    $args->{limit} = $limit if $limit;
+    $args->{offset} = $limit if $limit;
+
+    $ctx->{bookbags} = $e->search_container_biblio_record_entry_bucket([
+        {owner => $self->editor->requestor->id, btype => 'bookbag'},
+        $args
+    ]);
+
+    return Apache2::Const::OK;
+}
+
+
+1
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm
new file mode 100644 (file)
index 0000000..934714a
--- /dev/null
@@ -0,0 +1,115 @@
+package OpenILS::WWW::EGCatLoader;
+use strict; use warnings;
+use Apache2::Const -compile => qw(OK DECLINED FORBIDDEN HTTP_INTERNAL_SERVER_ERROR REDIRECT HTTP_BAD_REQUEST);
+use OpenSRF::Utils::Logger qw/$logger/;
+use OpenILS::Utils::CStoreEditor qw/:funcs/;
+use OpenILS::Utils::Fieldmapper;
+use OpenILS::Application::AppUtils;
+my $U = 'OpenILS::Application::AppUtils';
+
+use constant COOKIE_ANON_CACHE => 'anoncache';
+use constant ANON_CACHE_MYLIST => 'mylist';
+
+# Retrieve the users cached records AKA 'My List'
+# Returns an empty list if there are no cached records
+sub fetch_mylist {
+    my $self = shift;
+
+    my $list = [];
+    my $cache_key = $self->cgi->cookie(COOKIE_ANON_CACHE);
+
+    if($cache_key) {
+
+        $list = $U->simplereq(
+            'open-ils.actor',
+            'open-ils.actor.anon_cache.get_value', 
+            $cache_key, ANON_CACHE_MYLIST);
+
+        if(!$list) {
+            $cache_key = undef;
+            $list = [];
+        }
+    }
+
+    $self->apache->log->info("Found anon-cache list [@$list]");
+
+    return ($cache_key, $list);
+}
+
+
+# Adds a record (by id) to My List, creating a new anon cache + list if necessary.
+sub load_mylist_add {
+    my $self = shift;
+    my $rec_id = $self->cgi->param('record');
+
+    my ($cache_key, $list) = $self->fetch_mylist;
+    push(@$list, $rec_id);
+
+    $cache_key = $U->simplereq(
+        'open-ils.actor',
+        'open-ils.actor.anon_cache.set_value', 
+        $cache_key, ANON_CACHE_MYLIST, $list);
+
+    return $self->mylist_action_redirect($cache_key);
+}
+
+# Removes a record ID from My List
+sub load_mylist_del {
+    my $self = shift;
+    my $rec_id = $self->cgi->param('record');
+
+    my ($cache_key, $list) = $self->fetch_mylist;
+    return $self->mylist_action_redirect unless $cache_key;
+
+    $list = [ grep { $_ ne $rec_id } @$list ];
+
+    $cache_key = $U->simplereq(
+        'open-ils.actor',
+        'open-ils.actor.anon_cache.set_value', 
+        $cache_key, ANON_CACHE_MYLIST, $list);
+
+    return $self->mylist_action_redirect($cache_key);
+}
+
+sub load_cache_clear {
+    my $self = shift;
+    $self->clear_anon_cache;
+    return $self->mylist_action_redirect;
+}
+
+# Wipes the entire anonymous cache, including My List
+sub clear_anon_cache {
+    my $self = shift;
+    my $field = shift;
+
+    my $cache_key = $self->cgi->cookie(COOKIE_ANON_CACHE) or return;
+
+    $U->simplereq(
+        'open-ils.actor',
+        'open-ils.actor.anon_cache.delete_session', $cache_key)
+        if $cache_key;
+
+}
+
+# Called after an anon-cache / My List action occurs.  Redirect
+# to the redirect_url (cgi param) or referrer or home.
+sub mylist_action_redirect {
+    my $self = shift;
+    my $cache_key = shift;
+
+    $self->apache->print(
+        $self->cgi->redirect(
+            -url => $self->cgi->param('redirect_to') || $self->ctx->{referer} || $self->ctx->{home_page},
+            -cookie => $self->cgi->cookie(
+                -name => COOKIE_ANON_CACHE,
+                -path => '/',
+                -value => ($cache_key) ? $cache_key : '',
+                -expires => ($cache_key) ? undef : '-1h'
+            )
+        )
+    );
+
+    return Apache2::Const::REDIRECT;
+}
+
+1;
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm
new file mode 100644 (file)
index 0000000..c3716d5
--- /dev/null
@@ -0,0 +1,128 @@
+package OpenILS::WWW::EGCatLoader;
+use strict; use warnings;
+use Apache2::Const -compile => qw(OK DECLINED FORBIDDEN HTTP_INTERNAL_SERVER_ERROR REDIRECT HTTP_BAD_REQUEST);
+use OpenSRF::Utils::Logger qw/$logger/;
+use OpenILS::Utils::CStoreEditor qw/:funcs/;
+use OpenILS::Utils::Fieldmapper;
+use OpenILS::Application::AppUtils;
+my $U = 'OpenILS::Application::AppUtils';
+
+# context additions: 
+#   record : bre object
+sub load_record {
+    my $self = shift;
+    $self->ctx->{page} = 'record';
+
+    my $org = $self->cgi->param('loc') || $self->ctx->{aou_tree}->()->id;
+    my $depth = $self->cgi->param('depth') || 0;
+    my $copy_limit = int($self->cgi->param('copy_limit') || 20);
+    my $copy_offset = int($self->cgi->param('copy_offset') || 0);
+
+    my $rec_id = $self->ctx->{page_args}->[0]
+        or return Apache2::Const::HTTP_BAD_REQUEST;
+
+    # run copy retrieval in parallel to bib retrieval
+    my $copy_rec = OpenSRF::AppSession->create('open-ils.cstore')->request(
+        'open-ils.cstore.json_query.atomic', 
+        $self->mk_copy_query($rec_id, $org, $depth, $copy_limit, $copy_offset));
+
+    $self->ctx->{record} = $self->editor->retrieve_biblio_record_entry($rec_id);
+    $self->ctx->{marc_xml} = XML::LibXML->new->parse_string($self->ctx->{record}->marc);
+
+    $self->ctx->{copies} = $copy_rec->gather(1);
+    $self->ctx->{copy_limit} = $copy_limit;
+    $self->ctx->{copy_offset} = $copy_offset;
+
+    return Apache2::Const::OK;
+}
+
+sub mk_copy_query {
+    my $self = shift;
+    my $rec_id = shift;
+    my $org = shift;
+    my $depth = shift;
+    my $copy_limit = shift;
+    my $copy_offset = shift;
+
+    my $query = {
+        select => {
+            acp => ['id', 'barcode', 'circ_lib', 'create_date', 'age_protect', 'holdable'],
+            acpl => [
+                {column => 'name', alias => 'copy_location'},
+                {column => 'holdable', alias => 'location_holdable'}
+            ],
+            ccs => [
+                {column => 'name', alias => 'copy_status'},
+                {column => 'holdable', alias => 'status_holdable'}
+            ],
+            acn => [
+                {column => 'label', alias => 'call_number_label'},
+                {column => 'id', alias => 'call_number'}
+            ],
+            circ => ['due_date'],
+        },
+        from => {
+            acp => {
+                acn => {},
+                acpl => {},
+                ccs => {},
+                circ => {type => 'left'},
+                aou => {}
+            }
+        },
+        where => {
+            '+acp' => {
+                deleted => 'f',
+                call_number => {
+                    in => {
+                        select => {acn => ['id']},
+                        from => 'acn',
+                        where => {record => $rec_id}
+                    }
+                },
+                circ_lib => {
+                    in => {
+                        select => {aou => [{
+                            column => 'id', 
+                            transform => 'actor.org_unit_descendants', 
+                            result_field => 'id', 
+                            params => [$depth]
+                        }]},
+                        from => 'aou',
+                        where => {id => $org}
+                    }
+                }
+            },
+            '+acn' => {deleted => 'f'},
+            '+circ' => {checkin_time => undef}
+        },
+
+        # Order is: copies with circ_lib=org, followed by circ_lib name, followed by call_number label
+        order_by => [
+            {class => 'aou', field => 'name'}, 
+            {class => 'acn', field => 'label'}
+        ],
+
+        limit => $copy_limit,
+        offset => $copy_offset
+    };
+
+    # Filter hidden items if this is the public catalog
+    unless($self->ctx->{is_staff}) { 
+        $query->{where}->{'+acp'}->{opac_visible} = 't';
+        $query->{where}->{'+acpl'}->{opac_visible} = 't';
+        $query->{where}->{'+ccs'}->{opac_visible} = 't';
+    }
+
+    return $query;
+    #return $self->editor->json_query($query);
+}
+
+sub mk_marc_html {
+    my($self, $rec_id) = @_;
+
+    $self->ctx->{marc_html} = $U->simplereq(
+        'open-ils.search', 'open-ils.search.biblio.record.html', $rec_id);
+}
+
+1;
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm
new file mode 100644 (file)
index 0000000..e2ea613
--- /dev/null
@@ -0,0 +1,183 @@
+package OpenILS::WWW::EGCatLoader;
+use strict; use warnings;
+use Apache2::Const -compile => qw(OK DECLINED FORBIDDEN HTTP_INTERNAL_SERVER_ERROR REDIRECT HTTP_BAD_REQUEST);
+use OpenSRF::Utils::Logger qw/$logger/;
+use OpenILS::Utils::CStoreEditor qw/:funcs/;
+use OpenILS::Utils::Fieldmapper;
+use OpenILS::Application::AppUtils;
+my $U = 'OpenILS::Application::AppUtils';
+
+
+sub _prepare_biblio_search_basics {
+    my ($cgi) = @_;
+
+    return $cgi->param('query') unless $cgi->param('qtype');
+
+    my %parts;
+    my @part_names = qw/qtype contains query/;
+    $parts{$_} = [ $cgi->param($_) ] for (@part_names);
+
+    my @chunks = ();
+    for (my $i = 0; $i < scalar @{$parts{'qtype'}}; $i++) {
+        my ($qtype, $contains, $query) = map { $parts{$_}->[$i] } @part_names;
+
+        next unless $query =~ /\S/;
+        push(@chunks, $qtype . ':') unless $qtype eq 'keyword' and $i == 0;
+
+        # This stuff probably will need refined or rethought to better handle
+        # the weird things Real Users will surely type in.
+        if ($contains eq 'nocontains') {
+            $query =~ s/"//g;
+            $query = ('"' . $query . '"') if index $query, ' ';
+            $query = '-' . $query;
+        } elsif ($contains eq 'phrase') {
+            $query =~ s/"//g;
+            $query = ('"' . $query . '"') if index $query, ' ';
+        } elsif ($contains eq 'exact') {
+            $query =~ s/[\^\$]//g;
+            $query = '^' . $query . '$';
+        }
+        push @chunks, $query;
+    }
+
+    return join(' ', @chunks);
+}
+
+sub _prepare_biblio_search {
+    my ($cgi, $ctx) = @_;
+
+    my $query = _prepare_biblio_search_basics($cgi);
+
+    $query = ('#' . $_ . ' ' . $query) foreach ($cgi->param('modifier'));
+
+    foreach (grep /^fi:/, $cgi->param) {
+        /:(\w+)$/ or next;
+        my $term = join(",", $cgi->param($_));
+        $query .= " $1($term)" if length $term;
+    }
+
+    if ($cgi->param('sort')) {
+        my ($axis, $desc) = split /\./, $cgi->param('sort');
+        $query .= " sort($axis)";
+        $query .= '#descending' if $desc;
+    }
+
+    if ($cgi->param('pubdate') && $cgi->param('date1')) {
+        if ($cgi->param('pubdate') eq 'between') {
+            $query .= ' between(' . $cgi->param('date1');
+            $query .= ',' .  $cgi->param('date2') if $cgi->param('date2');
+            $query .= ')';
+        } elsif ($cgi->param('pubdate') eq 'is') {
+            $query .= ' between(' . $cgi->param('date1') .
+                ',' .  $cgi->param('date1') . ')';  # sic, date1 twice
+        } else {
+            $query .= ' ' . $cgi->param('pubdate') .
+                '(' . $cgi->param('date1') . ')';
+        }
+    }
+
+    my $site = $cgi->param('loc') || $ctx->{aou_tree}->()->id;
+    if (defined($cgi->param('loc')) or not $query =~ /site\(\d+\)/) {
+        $query .= " site($site)";
+    }
+    if (defined($cgi->param('depth')) or not $query =~ /depth\(\d+\)/) {
+        my $depth = defined $cgi->param('depth') ?
+            $cgi->param('depth') : $ctx->{find_aou}->($site)->ou_type->depth;
+        $query .= " depth($depth)";
+    }
+
+    return $query;
+}
+
+# context additions: 
+#   page_size
+#   hit_count
+#   records : list of bre's and copy-count objects
+sub load_rresults {
+    my $self = shift;
+    my $cgi = $self->cgi;
+    my $ctx = $self->ctx;
+    my $e = $self->editor;
+
+    $ctx->{page} = 'rresult';
+    my $page = $cgi->param('page') || 0;
+    my $facet = $cgi->param('facet');
+    my $limit = $cgi->param('limit') || 10; # TODO user settings
+    my $offset = $page * $limit;
+
+    my $query = _prepare_biblio_search($cgi, $ctx);
+    # Limit and offset will stay here. Everything else should be part of
+    # the query string, not special args.
+    my $args = {'limit' => $limit, 'offset' => $offset};
+
+    # Stuff these into the TT context so that templates can use them in redrawing forms
+    $ctx->{processed_search_query} = $query;
+
+    $query = "$query $facet" if $facet; # TODO
+
+    my $results;
+
+    try {
+
+        my $method = 'open-ils.search.biblio.multiclass.query';
+        $method .= '.staff' if $ctx->{is_staff};
+        $results = $U->simplereq('open-ils.search', $method, $args, $query, 1);
+
+    } catch Error with {
+        my $err = shift;
+        $logger->error("multiclass search error: $err");
+        $results = {count => 0, ids => []};
+    };
+
+    my $rec_ids = [map { $_->[0] } @{$results->{ids}}];
+
+    $ctx->{records} = [];
+    $ctx->{search_facets} = {};
+    $ctx->{page_size} = $limit;
+    $ctx->{hit_count} = $results->{count};
+
+    return Apache2::Const::OK if @$rec_ids == 0;
+
+    my $cstore1 = OpenSRF::AppSession->create('open-ils.cstore');
+    my $bre_req = $cstore1->request(
+        'open-ils.cstore.direct.biblio.record_entry.search', {id => $rec_ids});
+
+    my $search = OpenSRF::AppSession->create('open-ils.search');
+    my $facet_req = $search->request('open-ils.search.facet_cache.retrieve', $results->{facet_key}, 10);
+
+    my @data;
+    while(my $resp = $bre_req->recv) {
+        my $bre = $resp->content; 
+
+        # XXX farm out to multiple cstore sessions before loop, then collect after
+        my $copy_counts = $e->json_query(
+            {from => ['asset.record_copy_count', 1, $bre->id, 0]})->[0];
+
+        push(@data,
+            {
+                bre => $bre,
+                marc_xml => XML::LibXML->new->parse_string($bre->marc),
+                copy_counts => $copy_counts
+            }
+        );
+    }
+
+    $cstore1->kill_me;
+
+    # shove recs into context in search results order
+    for my $rec_id (@$rec_ids) { 
+        push(
+            @{$ctx->{records}},
+            grep { $_->{bre}->id == $rec_id } @data
+        );
+    }
+
+    my $facets = $facet_req->gather(1);
+
+    $facets->{$_} = {cmf => $ctx->{find_cmf}->($_), data => $facets->{$_}} for keys %$facets;  # quick-n-dirty
+    $ctx->{search_facets} = $facets;
+
+    return Apache2::Const::OK;
+}
+
+1;
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm
new file mode 100644 (file)
index 0000000..50495a8
--- /dev/null
@@ -0,0 +1,122 @@
+package OpenILS::WWW::EGCatLoader;
+use strict; use warnings;
+use Apache2::Const -compile => qw(OK DECLINED FORBIDDEN HTTP_INTERNAL_SERVER_ERROR REDIRECT HTTP_BAD_REQUEST);
+use OpenSRF::Utils::Logger qw/$logger/;
+use OpenILS::Utils::CStoreEditor qw/:funcs/;
+use OpenILS::Utils::Fieldmapper;
+use OpenILS::Application::AppUtils;
+my $U = 'OpenILS::Application::AppUtils';
+
+our %cache = (
+    map => {aou => {}}, # others added dynamically as needed
+    list => {},
+    org_settings => {}
+);
+
+sub init_ro_object_cache {
+    my $self = shift;
+    my $e = $self->editor;
+    my $ctx = $self->ctx;
+
+    # fetch-on-demand-and-cache subs for commonly used public data
+    my @public_classes = qw/ccs aout cifm citm clm cmf crahp/;
+
+    for my $hint (@public_classes) {
+
+        my ($class) = grep {
+            $Fieldmapper::fieldmap->{$_}->{hint} eq $hint
+        } keys %{ $Fieldmapper::fieldmap };
+
+        my $ident_field =  $Fieldmapper::fieldmap->{$class}->{identity};
+
+           $class =~ s/Fieldmapper:://o;
+           $class =~ s/::/_/g;
+
+        # copy statuses
+        my $list_key = $hint . '_list';
+        my $find_key = "find_$hint";
+
+        $ctx->{$list_key} = sub {
+            my $method = "retrieve_all_$class";
+            $cache{list}{$hint} = $e->$method() unless $cache{list}{$hint};
+            return $cache{list}{$hint};
+        };
+    
+        $cache{map}{$hint} = {} unless $cache{map}{$hint};
+
+        $ctx->{$find_key} = sub {
+            my $id = shift;
+            return $cache{map}{$hint}{$id} if $cache{map}{$hint}{$id}; 
+            ($cache{map}{$hint}{$id}) = grep { $_->$ident_field eq $id } @{$ctx->{$list_key}->()};
+            return $cache{map}{$hint}{$id};
+        };
+
+    }
+
+    $ctx->{aou_tree} = sub {
+
+        # fetch the org unit tree
+        unless($cache{aou_tree}) {
+            my $tree = $e->search_actor_org_unit([
+                           {   parent_ou => undef},
+                           {   flesh            => -1,
+                                   flesh_fields    => {aou =>  ['children']},
+                                   order_by        => {aou => 'name'}
+                           }
+                   ])->[0];
+
+            # flesh the org unit type for each org unit
+            # and simultaneously set the id => aou map cache
+            sub flesh_aout {
+                my $node = shift;
+                my $ctx = shift;
+                $node->ou_type( $ctx->{find_aout}->($node->ou_type) );
+                $cache{map}{aou}{$node->id} = $node;
+                flesh_aout($_, $ctx) foreach @{$node->children};
+            };
+            flesh_aout($tree, $ctx);
+
+            $cache{aou_tree} = $tree;
+        }
+
+        return $cache{aou_tree};
+    };
+
+    # Add a special handler for the tree-shaped org unit cache
+    $ctx->{find_aou} = sub {
+        my $org_id = shift;
+        $ctx->{aou_tree}->(); # force the org tree to load
+        return $cache{map}{aou}{$org_id};
+    };
+
+    # turns an ISO date into something TT can understand
+    $ctx->{parse_datetime} = sub {
+        my $date = shift;
+        $date = DateTime::Format::ISO8601->new->parse_datetime(cleanse_ISO8601($date));
+        return sprintf(
+            "%0.2d:%0.2d:%0.2d %0.2d-%0.2d-%0.4d",
+            $date->hour,
+            $date->minute,
+            $date->second,
+            $date->day,
+            $date->month,
+            $date->year
+        );
+    };
+
+    # retrieve and cache org unit setting values
+    $ctx->{get_org_setting} = sub {
+        my($org_id, $setting) = @_;
+
+        $cache{org_settings}{$org_id} = {} 
+            unless $cache{org_settings}{$org_id};
+
+        $cache{org_settings}{$org_id}{$setting} = 
+            $U->ou_ancestor_setting_value($org_id, $setting)
+                unless exists $cache{org_settings}{$org_id}{$setting};
+
+        return $cache{org_settings}{$org_id}{$setting};
+    };
+}
+
+1;
index ec765af..4064ec2 100644 (file)
@@ -7,6 +7,7 @@ use File::stat;
 use Apache2::Const -compile => qw(OK DECLINED HTTP_INTERNAL_SERVER_ERROR);
 use Apache2::Log;
 use OpenSRF::EX qw(:try);
+use OpenILS::Utils::CStoreEditor;
 
 use constant OILS_HTTP_COOKIE_SKIN => 'oils:skin';
 use constant OILS_HTTP_COOKIE_THEME => 'oils:theme';
@@ -15,12 +16,13 @@ use constant OILS_HTTP_COOKIE_LOCALE => 'oils:locale';
 my $web_config;
 my $web_config_file;
 my $web_config_edit_time;
+my %lh_cache; # locale handlers
 
 sub import {
     my $self = shift;
     $web_config_file = shift || '';
     unless(-r $web_config_file) {
-        warn "Invalid web config $web_config_file";
+        warn "Invalid web config $web_config_file\n";
         return;
     }
     check_web_config();
@@ -32,26 +34,77 @@ sub handler {
     check_web_config($r); # option to disable this
     my $ctx = load_context($r);
     my $base = $ctx->{base_path};
+
+    $r->content_type('text/html; encoding=utf8');
+
     my($template, $page_args, $as_xml) = find_template($r, $base, $ctx);
+    $ctx->{page_args} = $page_args;
+
+    my $stat = run_context_loader($r, $ctx);
+
+    return $stat unless $stat == Apache2::Const::OK;
     return Apache2::Const::DECLINED unless $template;
 
     $template = $ctx->{skin} . "/$template";
-    $ctx->{page_args} = $page_args;
-    $r->content_type('text/html; encoding=utf8');
 
     my $tt = Template->new({
         OUTPUT => ($as_xml) ?  sub { parse_as_xml($r, $ctx, @_); } : $r,
         INCLUDE_PATH => $ctx->{template_paths},
+        DEBUG => $ctx->{debug_template},
+        PLUGINS => {EGI18N => 'OpenILS::WWW::EGWeb::I18NFilter'}
     });
 
-    unless($tt->process($template, {ctx => $ctx})) {
-        $r->log->warn('Template error: ' . $tt->error);
+    unless($tt->process($template, {ctx => $ctx, l => set_text_handler($ctx, $r)})) {
+        $r->log->warn('egweb: template error: ' . $tt->error);
         return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR;
     }
 
     return Apache2::Const::OK;
 }
 
+sub set_text_handler {
+    my $ctx = shift;
+    my $r = shift;
+
+    my $locale = $ctx->{locale};
+    $locale =~ s/-/_/g;
+
+    $r->log->debug("egweb: messages locale = $locale");
+
+    unless($lh_cache{$locale}) {
+        $r->log->info("egweb: Unsupported locale: $locale");
+        $lh_cache{$locale} = $lh_cache{'en_US'};
+    }
+
+    return $OpenILS::WWW::EGWeb::I18NFilter::maketext = 
+        sub { return $lh_cache{$locale}->maketext(@_); };
+}
+
+
+
+sub run_context_loader {
+    my $r = shift;
+    my $ctx = shift;
+
+    my $stat = Apache2::Const::OK;
+
+    my $loader = $r->dir_config('OILSWebContextLoader');
+    return $stat unless $loader;
+
+    eval {
+        $loader->use;
+        $stat = $loader->new($r, $ctx)->load;
+    };
+
+    if($@) {
+        $r->log->error("egweb: Context Loader error: $@");
+        return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR;
+    }
+
+    $r->log->debug("egweb: context loader resulted in status $stat");
+    return $stat;
+}
+
 sub parse_as_xml {
     my $r = shift;
     my $ctx = shift;
@@ -65,9 +118,9 @@ sub parse_as_xml {
         $data = $ctx->{final_dtd} . "\n" . $data;
         $success = 1;
     } otherwise {
-       my $e = shift;
+           my $e = shift;
         my $err = "Invalid XML: $e";
-        $r->log->error($err);
+        $r->log->error("egweb: $err");
         $r->content_type('text/plain; encoding=utf8');
         $r->print("\n$err\n\n$data");
     };
@@ -79,16 +132,23 @@ sub parse_as_xml {
 sub load_context {
     my $r = shift;
     my $cgi = CGI->new;
-    my $ctx = $web_config->{ctx};
+    my $ctx = {}; # new context for each page load
+    $ctx->{$_} = $web_config->{base_ctx}->{$_} for keys %{$web_config->{base_ctx}};
     $ctx->{hostname} = $r->hostname;
     $ctx->{base_url} = $cgi->url(-base => 1);
     $ctx->{skin} = $cgi->cookie(OILS_HTTP_COOKIE_SKIN) || 'default';
     $ctx->{theme} = $cgi->cookie(OILS_HTTP_COOKIE_THEME) || 'default';
+
     $ctx->{locale} = 
         $cgi->cookie(OILS_HTTP_COOKIE_LOCALE) || 
         parse_accept_lang($r->headers_in->get('Accept-Language')) || 'en-US';
-    $r->log->debug('skin = ' . $ctx->{skin} . ' : theme = ' . 
-        $ctx->{theme} . ' : locale = ' . $ctx->{locale});
+
+    my $mprefix = $ctx->{media_prefix};
+    if($mprefix and $mprefix !~ /^http/ and $mprefix !~ /^\//) {
+        # if a hostname is provided /w no protocol, match the protocol to the current page
+        $ctx->{media_prefix} = ($cgi->https) ? "https://$mprefix" : "http://$mprefix";
+    }
+
     return $ctx;
 }
 
@@ -146,7 +206,7 @@ sub find_template {
             last unless $localpath;
             for my $tpath (@{$ctx->{template_paths}}) {
                 my $fpath = "$tpath/$skin/$localpath.$ext";
-                $r->log->debug("looking at possible template $fpath");
+                $r->log->debug("egweb: looking at possible template $fpath");
                 if(-r $fpath) {
                     $template = "$localpath.$ext";
                     last;
@@ -161,12 +221,12 @@ sub find_template {
 
         # no template configured or found
         unless($template) {
-            $r->log->warn("No template configured for path $path");
+            $r->log->debug("egweb: No template configured for path $path");
             return ();
         }
     }
 
-    $r->log->debug("template = $template : page args = @$page_args");
+    $r->log->debug("egweb: template = $template : page args = @$page_args");
     return ($template, $page_args, $as_xml);
 }
 
@@ -176,12 +236,46 @@ sub check_web_config {
     my $r = shift;
     my $epoch = stat($web_config_file)->mtime;
     unless($web_config_edit_time and $web_config_edit_time == $epoch) {
-        $r->log->debug("Reloading web config after edit...") if $r;
+        $r->log->debug("egweb: Reloading web config after edit...") if $r;
         $web_config_edit_time = $epoch;
         $web_config = parse_config($web_config_file);
     }
 }
 
+# Create an I18N sub-module for each supported locale
+# Each module creates its own MakeText lexicon by parsing .po/.mo files
+sub load_locale_handlers {
+    my $ctx = shift;
+    my $locales = $ctx->{locales};
+
+    $locales->{en_US} = {} unless exists $locales->{en_US};
+
+    for my $lang (keys %$locales) {
+        my $messages = $locales->{$lang};
+        $messages = '' if ref $messages; # empty {}
+
+        # TODO Can we do this without eval?
+        my $eval = <<EVAL;
+            package OpenILS::WWW::EGWeb::I18N::$lang;
+            use base 'OpenILS::WWW::EGWeb::I18N';
+            if(\$messages) {
+                use Locale::Maketext::Lexicon::Gettext;
+                if(open F, '$messages') {
+                    our %Lexicon = (%Lexicon, %{ Locale::Maketext::Lexicon::Gettext->parse(<F>) });
+                    close F;
+                } else {
+                    warn "unable to open messages file: $messages"; 
+                }
+            }
+EVAL
+        eval $eval;
+        warn "$@\n" if $@; # TODO better logging
+        $lh_cache{$lang} = "OpenILS::WWW::EGWeb::I18N::$lang"->new;
+    }
+}
+
+
+
 sub parse_config {
     my $cfg_file = shift;
     my $data = XML::Simple->new->XMLin($cfg_file);
@@ -191,9 +285,12 @@ sub parse_config {
     $ctx->{media_prefix} = (ref $data->{media_prefix}) ? '' : $data->{media_prefix};
     $ctx->{base_path} = (ref $data->{base_path}) ? '' : $data->{base_path};
     $ctx->{template_paths} = [];
-    $ctx->{force_valid_xml} = ($data->{force_valid_xml} =~ /true/io) ? 1 : 0;
+    $ctx->{force_valid_xml} = ( ($data->{force_valid_xml}||'') =~ /true/io) ? 1 : 0;
+    $ctx->{debug_template} = ( ($data->{debug_template}||'')  =~ /true/io) ? 1 : 0;
     $ctx->{default_template_extension} = $data->{default_template_extension} || 'tt2';
     $ctx->{web_dir} = $data->{web_dir};
+    $ctx->{locales} = $data->{locales};
+    load_locale_handlers($ctx);
 
     my $tpaths = $data->{template_paths}->{path};
     $tpaths = [$tpaths] unless ref $tpaths;
@@ -217,7 +314,7 @@ sub parse_config {
         }
     }
 
-    return {ctx => $ctx, handlers => $handlers};
+    return {base_ctx => $ctx, handlers => $handlers};
 }
 
 package PathConfig;
@@ -226,5 +323,9 @@ sub new {
     return bless(\%args, $class);
 }
 
+# base class for all supported locales
+package OpenILS::WWW::EGWeb::I18N;
+use base 'Locale::Maketext';
+our %Lexicon = (_AUTO => 1);
 
 1;
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb/I18NFilter.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb/I18NFilter.pm
new file mode 100644 (file)
index 0000000..cc931fa
--- /dev/null
@@ -0,0 +1,19 @@
+package OpenILS::WWW::EGWeb::I18NFilter;
+use Template::Plugin::Filter;
+use base qw(Template::Plugin::Filter);
+our $DYNAMIC = 1;
+our $maketext;
+
+sub filter {
+    my ($self, $text, $args) = @_;
+    return $maketext->($text, @$args);
+}
+
+sub init {
+    my $self = shift;
+    $self->install_filter('l');
+    return $self;
+}
+
+1;
+
diff --git a/Open-ILS/web/css/skin/default/opac/contentslider.css b/Open-ILS/web/css/skin/default/opac/contentslider.css
new file mode 100644 (file)
index 0000000..64a6d25
--- /dev/null
@@ -0,0 +1,39 @@
+.sliderwrapper{
+position: relative; /*leave as is*/
+overflow: hidden; /*leave as is*/
+width: 675px; /*width of featured content slider*/
+height: 213px;
+}
+
+
+
+.sliderwrapper .contentdiv{
+visibility: hidden; /*leave as is*/
+position: absolute; /*leave as is*/ 
+left: 0;  /*leave as is*/
+top: 0;  /*leave as is*/
+width: 675px; /*width of content DIVs within slider. Total width should equal slider's inner width (390+5+5=400) */
+height: 100%;
+filter:progid:DXImageTransform.Microsoft.alpha(opacity=100);
+-moz-opacity: 1;
+opacity: 1;
+}
+
+.pagination{
+width: 400px; /*Width of pagination DIV. Total width should equal slider's outer width (400+10+10=420)*/
+text-align: right;
+background-color: navy;
+padding: 5px 10px;
+}
+
+.pagination a{
+padding: 0 5px;
+text-decoration: none; 
+color: #00007D;
+background: white;
+}
+
+.pagination a:hover, .pagination a.selected{
+color: #000;
+background-color: #FEE496;
+}
\ No newline at end of file
diff --git a/Open-ILS/web/css/skin/default/opac/semiauto.css b/Open-ILS/web/css/skin/default/opac/semiauto.css
new file mode 100644 (file)
index 0000000..f652eaa
--- /dev/null
@@ -0,0 +1,181 @@
+/* once done renaming and everything, combine with style.css */
+
+/* Verfied in-use classes --------------------------- */
+.opac-auto-004 { background: #E0F0E0; }
+.opac-auto-009 { border: 3px solid #E0E0E0; }
+.opac-auto-010 { border-bottom: 1px dotted #ccc; padding-top: 10px; }
+.opac-auto-011 { border-bottom: 1px dotted #ccc; padding-top: 6px; }
+.opac-auto-012 { border-bottom: none; }
+.opac-auto-013 { border-bottom: none; *height: 0px; }
+.opac-auto-015 { border-left: 1px solid #e9ebf3; padding-right: 27px; }
+.opac-auto-017 { border: none; width: 100%; }
+.opac-auto-018 { border-top: 1px dotted #ccc; padding-top: 17px; }
+.clear-both { clear: both; }
+.common-no-pad { clear: both; height: 0px; margin: 0px; padding: 0px; }
+.common-full-pad { clear: both; height: 15px; }
+.opac-auto-029 { color: #333; font-weight: bold; font-size: 13px; }
+.opac-auto-030 { color: #545454; }
+.opac-auto-031 { color: #9999FF; padding-left: 10px; font-size: 7pt; font-weight: 300; }
+.red { color: red; }
+.bold-red { color: red; font-weight: bold }
+.pointer { cursor: pointer; }
+/* ------------------------------------------- */
+
+
+#lib_selector_span { display: none }
+.float-left { float: left; }
+.opac-auto-039 { float: left; font-weight: bold; padding-top: 5px; }
+.opac-auto-040 { float: left; padding: 5px 0px 0px 10px; }
+.left-corner { float: left; width: 163px; height: 30px; background: url('/images/utils-corner-mid.png') repeat-x top; }
+.float-right { float: right; }
+.opac-auto-045 { float: right; margin-right: 17px; }
+.opac-auto-046 { float: right; width: 214px; }
+.opac-auto-047 { float: right; width: 353px; background: #ccc; padding: 10px; margin-top: 7px; }
+.opac-auto-048 { float: right; width: 65px; }
+#they_said_dont_touch { float: right; width: 675px; height: 213px; color: green; overflow: hidden; }
+.opac-auto-050 { float: right; width: 85px; }
+.ten-px { font-size: 10px; }
+.eleven-px { font-size: 11px; }
+.eight-pt { font-size: 8pt; }
+.opac-auto-054 { font-size: 8pt; padding-left: 20px; }
+.bold { font-weight: bold; }
+.opac-auto-057 { font-weight: bold; padding: 5px; margin: 5px; width: 100%; }
+.opac-auto-058 { font-weight: bold; padding-left: 10px; }
+.opac-auto-059 { font-weight: bold; padding-right: 10px; }
+.opac-auto-060 { font-weight: normal; }
+.opac-auto-061 { height: 0px; border-top: 1px solid #b7b7b7; border-bottom: 1px solid #d4d4d4; margin: 15px 0px; }
+.small-height { height: 10px; }
+.normal-height { height: 15px; }
+.big-height { height: 20px; }
+.very-big-height { height: 30px; }
+#gold-links-holder { height: 24px; background: #252525; }
+.opac-auto-067 { margin: 3px; width: 100%; }
+.big-block { margin: auto; width: 974px; height: 0px; }
+.opac-auto-069 { margin-bottom: 10px; }
+.opac-auto-070 { margin-bottom: 20px; }
+.opac-auto-071 { margin-bottom: 5px; }
+.opac-auto-072 { margin-left: 20px; }
+.opac-auto-073 { margin-left: 5px; margin-top: 5px; }
+#cn_browse_where { margin-left: 6px; }
+.opac-auto-075 { margin-right: 20px; }
+.opac-auto-076 { margin-right: 3px; }
+.opac-auto-077 { margin-right: 4px; position: relative; top: -10px; }
+.opac-auto-078 { margin-right: 7px; }
+.opac-auto-079 { margin-top: 10px; }
+.opac-auto-080 { margin-top: 10px; margin-bottom: 10px; }
+.opac-auto-081 { margin-top: 13px; }
+.opac-auto-082 { margin-top: 29px; }
+.opac-auto-083 { margin-top: 2px; }
+.opac-auto-084 { margin-top: 5px; }
+.opac-auto-085 { margin-top: 6px; margin-left: 20px; width: 250px; padding: 5px; }
+.opac-auto-086 { margin-top: 8px; }
+.opac-auto-087 { max-width: 11em; }
+.opac-auto-088 { padding: 0px; }
+.opac-auto-089 { padding: 0px 10px; }
+.opac-auto-090 { padding: 10px; }
+.opac-auto-091 { padding: 10px 0px; }
+.opac-auto-092 { padding: 4px; text-align: center; }
+.pad-bottom-five { padding: 5px; }
+.opac-auto-094 { padding: 5px 7px 0px 0px; }
+.opac-auto-095 { padding: 5px 7px 0px 0px; white-space: nowrap; }
+.opac-auto-096 { padding: 6px }
+.opac-auto-097 { padding: 8px 0px 6px 0px; width: 100%; border: 0; }
+.opac-auto-097b { padding: 8px 0px 6px 0px; border: 0; }
+.opac-auto-098 { padding-bottom: 10px; }
+.opac-auto-099 { padding-bottom: 12px; color: #666; }
+.opac-auto-100 { padding-bottom: 16px; }
+.opac-auto-101 { padding-bottom: 1px; }
+.opac-auto-102 { padding-bottom: 7px; }
+.opac-auto-103 { padding-left: 10px; }
+.opac-auto-104 { padding-left: 11px; padding-right: 11px; }
+.opac-auto-105 { padding-left: 11px; padding-right: 13px; }
+.opac-auto-106 { padding-left: 15px; }
+.opac-auto-107 { padding-left: 15px; padding-bottom: 10px; }
+.opac-auto-108 { padding-left: 5px; }
+.opac-auto-109 { padding-left: 5px; padding-bottom: 10px; }
+.opac-auto-110 { padding-left: 6px; }
+.opac-auto-111 { padding-left: 8px; }
+.opac-auto-112 { padding-left: 9px; }
+.opac-auto-113 { padding-right: 10px; }
+.opac-auto-114 { padding-right: 15px; padding-left: 15px; }
+.opac-auto-115 { padding-right: 20px; }
+.opac-auto-116 { padding-right: 5px; }
+.opac-auto-117 { padding-right: 7px; }
+.pad-top-ten { padding-top: 10px; }
+.opac-auto-119 { padding-top: 14px; }
+.opac-auto-120 { padding-top: 5px; }
+.opac-auto-121 { padding-top: 6px; }
+.opac-auto-122 { padding-top: 7px; }
+.opac-auto-123 { padding-top: 8px; }
+.pos-abs { position: absolute; }
+#new_cat_link_holder { position: absolute; z-index: 101; }
+#new_cat_link_holder a { display: block; width: 675px; height: 213px; }
+.pos-rel { position: relative; }
+#search-box table { position: relative; left: -10px; }
+.opac-auto-129 { position: relative; left: -19px; }
+.opac-auto-130 { position: relative; left: 80px; }
+.opac-auto-131 { position: relative; top: 0px; left: 55px; }
+.opac-auto-132 { position: relative; top: 13px; }
+.opac-auto-133 { position: relative; top: -13px; left: 2px; font-size: 10px; }
+.opac-auto-134 { position: relative; top: -15px; left: 172px; }
+.opac-auto-135 { position: relative; top: -15px; left: -23px; }
+.opac-auto-136 { position: relative; top: 161px; left: 172px; }
+.opac-auto-137 { position: relative; top: 161px; left: -23px; }
+#home_adv_search_link { position: relative; top: -1px; left: 10px; }
+#util_back_btn { position: relative; top: 1px; left: 10px; }
+.opac-auto-140 { position: relative; top: -2px; }
+#util_help_btn { position: relative; top: 2px; left: 40px; }
+#util_forw_btn { position: relative; top: 2px; left: 50px; }
+.opac-auto-143 { position: relative; top: -3px; }
+#util_home_btn { position: relative; top: 3px; left: 20px; }
+.opac-auto-145 { position: relative; top: -3px; left: 3px; }
+.opac-auto-146 { position: relative; top: -3px; left: -5px; }
+.opac-auto-147 { position: relative; top: -5px; }
+#learn_more { position: relative; top: 5px; }
+.opac-auto-149 { position: relative; top: 5px; left: 25px; }
+#util_print_btn { position: relative; top: 5px; left: 30px; }
+.opac-auto-151 { position: relative; top: 75px; }
+#adv_reset { position: relative; top: -9px; }
+.opac-auto-153 { position: relative; z-index: 100; }
+.text-center { text-align: center; }
+.opac-auto-156 { text-align: center; font-weight: bold; }
+#adv_quick_search_sidebar { text-align: center; margin-top: 20px; width: 400px; }
+.opac-auto-158 { text-align: center; margin-top: 6px; margin-bottom: 6px }
+.opac-auto-159 { text-align: center; padding: 20px; width: 100% }
+.opac-auto-160 { text-align: center; padding-bottom: 8px; }
+.opac-auto-161 { text-align: right; padding-right: 7px; }
+.opac-auto-162 { vertical-align: top; }
+.nowrap { white-space: nowrap; }
+.opac-auto-164 { white-space: nowrap; padding-left: 5px; }
+.full-width { width: 100%; }
+.opac-auto-167 { width: 100%; border: 1px solid black; padding: 6px; margin-top: 5px; }
+.opac-auto-168 { width: 100%; border: 2px solid #E0F0E0; margin-bottom: 20px; }
+.opac-auto-169 { width: 100%; height: 100%; }
+.opac-auto-170 { width: 100%; margin-top: 20px; border-top: 1px dotted #ccc; padding-top: 8px; }
+.opac-auto-171 { width: 100%; text-align: center; font-weight: 700; margin-top: 10px; }
+.opac-auto-172 { width: 100%; text-align: center; padding-bottom: 5px; }
+.opac-auto-173 { width: 10px; }
+.opac-auto-174 { width: 111px; height: 25px; }
+.opac-auto-175 { width: 125px; height: 21px; }
+.opac-auto-176 { width: 129px; }
+#search_box { width: 162px; }
+.opac-auto-178 { width: 174px; }
+.opac-auto-179 { width: 175px; margin-right: 11px; }
+.opac-auto-180 { width: 182px; color: black; padding: 5px 25px; }
+.opac-auto-181 { width: 195px; }
+.opac-auto-182 { width: 230px; text-align: left; margin-top: 3px; }
+.opac-auto-183 { width: 250px; text-align: left; }
+.opac-auto-184 { width: 26px; height: 23px; margin-top: 6px; margin-bottom: 6px; }
+.opac-auto-185 { width: 324px; }
+.opac-auto-186 { width: 400px; margin-top: 20px; }
+.opac-auto-187 { width: 662px; }
+.opac-auto-188 { width: 700px; height: 30px; border: 1px solid red; }
+.opac-auto-189 { width: 742px; float: left; }
+.opac-auto-190 { width: 88px; }
+.opac-auto-191 { width: 90px; }
+#cn_browse_div > div { width: 90%; text-align: center; margin: 10px; }
+.opac-auto-193 { width: 91px; }
+#cn_browse { width: 95%; text-align: center; padding: 15px; }
+.opac-auto-195 { width: 99%; text-align: center }
+#homesearch_thing { width: 664px; height: 117px; background: #bda964; }
+#mystery_thing { width: 664px; height: 35px; background: #ffffff; }
diff --git a/Open-ILS/web/css/skin/default/opac/style.css b/Open-ILS/web/css/skin/default/opac/style.css
new file mode 100644 (file)
index 0000000..6780de3
--- /dev/null
@@ -0,0 +1,942 @@
+body {
+       margin:0;
+       font-family: Arial, Helvetica, sans-serif;
+       font-size: 12px;
+       background:#333;
+}
+
+img {
+       border: none;
+}
+
+a {
+       color: #003399;
+       text-decoration: none;
+}
+
+a:hover {
+       text-decoration: underline;
+}
+
+#search-wrapper input[type=text] {
+       border:none;
+       margin:0;
+       padding:0;
+}
+
+#search-wrapper select {
+       border:1px solid #e9ebf3;
+       margin:0;
+       padding:0;
+       width:168px;
+}
+
+/*
+#search-wrapper select {
+       border:0px solid black;
+       filter:alpha(opacity=0);
+       -moz-opacity:0;
+       -khtml-opacity:0;
+       opacity:0;
+       padding:0;
+       margin:0;
+       height:18px;
+       font-size: 12px;
+}
+*/
+h1 {
+       margin:0;
+       margin-bottom: 5px;
+       font-size: 20px;
+       font-weight:normal;
+}
+
+h2 {
+       margin:0;
+       margin-bottom: 5px;
+       font-size: 14px;
+       font-weight:bold;
+}
+
+.hide_me, .hidden {
+       display: none;
+       visibility: hidden;
+}
+
+div.select-box-wrapper {
+       position:absolute;
+       padding-top:2px;
+       padding-left:3px;
+       overflow:hidden;
+       text-align:left;
+}
+
+div.select-wrapper {
+       border:1px solid #4C8AB0;
+       display:inline-block;
+       position:relative;
+       z-index:2;
+       background:url('/images/dropdown.gif') no-repeat right center;
+}
+
+div.select-wrapper:hover {
+       background:url('/images/dropdown-hover.gif') no-repeat right center;
+}
+
+#dash_wrapper {
+       width:500px;
+       position:relative;
+       top:-26px;
+}
+
+#dashboard {
+       clear:both;
+       float:right;
+       width:384px;
+}
+
+#dashboard span {
+       font-weight:bold;
+       position:relative;
+       left:-1px;
+}
+
+#dash_user {
+       font-weight: bold;
+       text-transform: capitalize;
+    position: relative;
+    top: 10px;
+}
+
+#dash_corner_mid1a {
+    vertical-align: top;
+    background: url('/images/dash-corner-mid1.png') repeat-x;
+    padding-left: 8px;
+}
+#dash_corner_mid1b {
+    background: url('/images/dash-corner-mid1.png') repeat-x;
+    padding: 0px 8px 0px 10px;
+}
+#dash_corner_mid1b img { position: relative; top: -1px; }
+#dash_corner_mid1c {
+    background: url('/images/dash-corner-mid1.png') repeat-x;
+    vertical-align: top;
+}
+#dash_corner_mid2a {
+    vertical-align: top;
+    width: 372px;
+    background: url('/images/dash-corner-mid2.png') repeat-x;
+}
+.dash-pos-out { position: relative; left: 3px; }
+.dash-pos-holds { position: relative; left: 100px; }
+.dash-align-out { text-align: right; width: 86px; }
+.dash-align-holds { text-align: right; width: 62px; }
+.dash-pos-pickup { position: relative; left: 170px; }
+.dash-align-pickup { text-align: right; width: 111px; }
+.dash-pos-fines { position: relative; left: 284px; }
+.dash-align-fines { text-align: right; width: 76px; }
+.pos-rel-top4 { position: relative; top: 4px; }
+#dash_number_row { position: relative; top: 6px; }
+#logout_link { left: 1px; }
+
+#dash_checked { color: #ffcc33; }
+#dash_holds { color: #ffcc33; }
+#dash_pickup { color: #1dd93c; }
+#dash_fines { color: #f41d36; }
+#header {
+       color: #fff;
+       padding: 26px 0px 26px 0px;
+       width: 974px;
+       margin: auto;
+       font-size:11px;
+}
+
+#header a {
+       color: #fff;
+}
+
+#header a:hover {
+       color: white;
+       text-decoration: none;
+}
+
+#header-links {
+       color: #afafaf;
+       font-size: 11px;
+       font-weight: bold;
+       position: relative;
+       top:4px;
+       
+}
+
+#header-links a {
+       color: #afafaf;
+       display: block;
+       float:left;
+       margin-right:22px;
+}
+
+#header-links a:hover {
+       color: white;
+       text-decoration: none;
+}
+
+#header #header-links2 {
+       position:relative;
+       top:-8px;
+       color: white;
+       padding-bottom: 15px;
+}
+
+#header #header-links2 a {
+       color: white;
+}
+
+#header #header-links2 a:hover {
+       text-decoration: underline;
+}
+
+#header #your-acct-login {
+       padding-top:10px;
+}
+
+#gold-links {
+       margin:auto;
+       width:974px;
+       padding-left:0px;
+}
+
+#gold-links-home {
+       margin:auto;
+       width:694px;
+       padding-left:0px;
+}
+
+#util-bar {
+       margin:auto;
+       width:974px;
+       padding-left:0px;
+       height:0px;
+}
+
+#search-wrapper {
+       border-bottom: 1px solid #e9ebf3;
+       padding-bottom: 5px;
+       background: white;
+}
+
+#search_box_wrapper {
+       border:1px solid #e9ebf3;
+       padding: 1px;
+    padding-left: 3px;
+}
+
+#search-wrapper #breadcrumb {
+       margin-top:0px;
+       font-size: 10px;
+       float:left;
+}
+
+#search-wrapper #search-within {
+       margin-top:10px;
+       float:right;
+       position:relative;
+       left:-173px;
+}
+
+#search-wrapper #breadcrumb a {
+       color: black;
+}
+
+#search-wrapper #search_frm label {
+       font-size: 10px;
+}
+
+#search-wrapper #search-box {
+       width:974px;
+       margin:auto;
+       padding-left: 0px;
+}
+
+#utils {
+       float:right;
+       z-index:1;
+       width:150px;
+       height:30px;
+       background:url('/images/utils-corner-left.png') no-repeat left top;
+       padding-left: 3px;
+       color: white;
+       position:relative;
+}
+
+#utils a {
+       color: white;
+       font-size: 10px;
+}
+#adv_search_tabs {
+       height:33px;
+       width:974px;
+       margin:auto;
+}
+
+#adv_search_tabs a {
+       float: left;
+       display: block;
+       height:33px;
+       margin-right:7px;
+}
+
+#adv_search {
+       width:156px;
+       background:url('/images/adv_search_on.gif') no-repeat bottom;
+}
+
+#num_search {
+       width:156px;
+       background:url('/images/num_search_off.gif') no-repeat bottom;
+}
+
+#expert_search {
+       width:156px;
+       background:url('/images/expert_search_off.gif') no-repeat bottom;
+}
+
+#acct_tabs {
+       height:33px;
+       width:974px;
+       margin:auto;
+}
+
+#acct_tabs a {
+       float: left;
+       display: block;
+       height:33px;
+       margin-right:7px;
+}
+
+.acct-tab {
+    background-repeat: no-repeat;
+    background-position: bottom;
+    width:156px;
+}
+
+.acct-main-off {
+       background-image:url('/images/acct_summary_off.gif');
+}
+.acct-main-on {
+       background-image:url('/images/acct_summary_on.gif');
+}
+
+.acct-circs-off {
+       background-image:url('/images/acct_checked_out_off.gif');
+}
+.acct-circs-on {
+       background-image:url('/images/acct_checked_out_on.gif');
+}
+
+.acct-holds-off {
+       background-image:url('/images/acct_holds_off.gif');
+}
+.acct-holds-on {
+       background-image:url('/images/acct_holds_on.gif');
+}
+
+.acct-prefs-off {
+       background-image:url('/images/acct_prefs_off.gif');
+}
+.acct-prefs-on {
+       background-image:url('/images/acct_prefs_on.gif');
+}
+
+.acct-lists-off {
+       background-image:url('/images/acct_lists_off.gif');
+}
+.acct-lists-on {
+       background-image:url('/images/acct_lists_on.gif');
+}
+
+#rdetail_header {
+       font-size:14px;
+       font-weight:bold;
+       color:#074079;
+       padding: 5px 7px 6px 0px;
+       border-bottom: 1px dotted #ccc;
+}
+
+#rdetail_result_count {
+       color: black;
+       font-size: 11px;
+       font-weight: normal;
+}
+
+#rdetail_result_nav {
+       float:right;
+       font-size: 11px;
+       font-weight:normal;
+}
+
+#rdetail_details_table {
+       margin-top: 15px;
+}
+
+#rdetail_title {
+       font-size: 18px;
+}
+
+#rdetail_image { border: none; }
+#rdetail_image_cell {
+       padding-top: 3px;
+       padding-right: 10px;
+}
+
+.rdetail_aux_utils {
+       border-left:1px dotted #ccc;
+       padding-left: 17px;
+       padding-bottom: 6px;
+       padding-right: 70px;
+}
+
+.results_aux_utils {
+       border-left:1px dotted #ccc;
+       padding-left: 17px;
+       padding-bottom: 6px;
+       padding-right: 50px;
+}
+
+#rdetails_status td, #rdetails_status2 td {
+       white-space:nowrap !important;
+       padding: 7px 0px 3px 13px;
+}
+
+#rdetails_status thead td {
+       background-color: #d8d8d8;
+       padding: 13px 0px 13px 13px;
+       font-size: 10px;
+       text-transform: uppercase;
+       font-weight: bold;
+}
+
+#rdetails_status tbody td {
+       padding-left: 13px;;
+}
+
+.rdetail_extras {
+       height: 29px;
+       background: #9ad0f1;
+       padding-top:1px;
+       margin-bottom: 10px;
+       margin-top: 10px;
+       clear:both;
+}
+
+.rdetail_extras_hr {
+       height: 1px;
+       background: #b7def5;
+       margin-left: 1px;
+       margin-right: 1px;
+}
+
+.rdetail_extras_link {
+       padding-top: 4px;
+       padding-left: 12px;
+       font-size: 10px;
+       text-transform: uppercase;
+       font-weight: bold;
+}
+
+.rdetail_extras_lbl {
+       position: relative;
+       top: -4px;
+       left: 7px;
+}
+
+#paginate-homebanner a.toc {
+       display:block;
+       width:20px;
+       height:20px;
+       background:gray;
+       float:left;
+       margin-left:2px;
+       margin-right:2px;
+       margin-top:2px;
+}
+
+#rdetail_extras_expand, #rdetail_extras_collapse, #rdetail_locs_collapse {
+       margin-left: 13px;
+}
+
+#rdetail_locs_expand, #rdetail_locs_collapse {
+       padding-bottom:3px;
+       margin-top:15px;
+       margin-left:13px;
+}
+
+#rdetail_anotes_div .biography {
+       margin:0;
+}
+
+#paginate-homebanner a.selected {
+       border: 2px solid black;
+       margin-top:0px;
+       margin-left:0px;
+       margin-right:0px;
+}
+
+#hp-buttons {
+       margin: auto;
+       margin-top: 6px;
+       width: 694px; /* 974px; */
+}
+
+#hp-welcome {
+       position:absolute;
+       width:295px;
+       height:192px;
+       background: url('/images/banner-bg.png') no-repeat;
+       color: #fff;
+       padding-left: 33px;
+       padding-top: 21px;
+       z-index:9999999999;
+}
+
+#hp-welcome h1 {
+       font-size: 25px;
+       margin-bottom:15px;
+}
+
+#hp-welcome a {
+       color: #fff;
+       text-decoration: underline;
+}
+
+#hp-banner {
+       margin: auto;
+       width: 694px; /* formerly 974px */
+       height: 213px;
+}
+
+#hp-ql-table {
+       margin-left: 2px;
+       padding-top: 3px;
+}
+
+#hp-ql-table a {
+       color: #333;
+       font-weight: bold;
+       font-size: 13px;
+       text-transform: uppercase;
+       text-decoration: none;
+       display: block;
+       width: 144px;
+       height: 25px;
+       padding-top: 9px;
+       padding-left: 15px;
+       background: url('/images/button-bg.png') no-repeat;
+}
+
+#hp-ql-bottom {
+       width: 640px;
+       height: 31px;
+       padding-left: 24px;
+       padding-top: 13px;
+       background: url('/images/hp-links-mid.jpg') repeat-x;
+}
+
+#hp-ql-bottom a {
+       display: inline-block;
+       text-decoration: none;
+       color: white;
+       font-size: 15px;
+       font-weight: bold;
+}
+
+#hp-ql-bottom img {
+    position:relative;
+    top:-1px;
+    left:2px;
+}
+
+#content-wrapper {
+       background: white;
+       min-height: 260px;
+       border-bottom: 1px solid black;
+}
+
+#main-content-home { width: 694px; margin: auto; padding-left: 17px; }
+#main-content { width: 974px; margin:auto; padding-left: 0px; }
+
+#main-content .login_boxes {
+       border: 1px solid #dedede;
+       background:url('/images/login-bg.jpg') top repeat-x;
+       color: #333;
+}
+
+#main-content .login_boxes h1 {
+       font-weight: normal;
+       font-size: 25px;
+       margin:0;
+}
+
+#main-content .left_brain {
+       padding-left:28px;
+       padding-top:25px;
+}
+
+#main-content .left_brain input[type=text], #main-content .left_brain input[type=password] {
+       width:167px;
+       height:18px;
+       margin:0;
+       padding:0;
+       border:none;
+       background: none;
+       font-size: 15px;
+       color: #666;
+}
+
+#main-content .left_brain .input_bg {
+       padding:10px 10px 0px 13px;
+       background: url('/images/login-box-bg.jpg') no-repeat;
+       width:167px;
+       height:29px;
+}
+
+#home-buttons-inner {
+       width:664px;
+       height:117px;
+       background:#bda964;
+}
+
+#holds_temp_parent td {
+       border-bottom:1px solid #dcdbdb;
+}
+
+#holds_temp_parent input, #holds_temp_parent select {
+       margin:0;
+}
+
+
+
+
+#results_header_bar {
+       background: #929292;
+       border-top:1px solid #8b8b8b;
+}
+
+#results_header_inner {
+       height:32px;
+       width:974px;
+       margin:auto;
+       padding-top:6px;
+}
+
+.results_header_btns {
+       float:left;
+       margin-right: 6px;
+}
+
+.cached_list_div { width: 111px; height: 25px; }
+
+.results_header_div {
+       float: left;
+       width: 0px;
+       height: 25px;
+       border-left: 1px solid #7c7c7c;
+       border-right: 1px solid #9c9c9c;
+       margin: 0px 13px;
+}
+
+.results_header_lbl {
+       font-weight: bold;
+       float: left;
+       font-size: 11px;
+       color: #191919;
+       position: relative;
+       top: 5px;
+       margin-right: 6px;
+}
+
+.results_header_sel {
+    /* width: 88px; */
+       float:left;
+       position: relative;
+       top: 2px;
+       margin:0;
+}
+
+.results_header_nav1 {
+       padding: 5px 7px 6px 0px;
+       border-bottom: 1px dotted #ccc;
+}
+
+.results_header_nav1 .h1 {
+       font-size:14px;
+       font-weight:bold;
+       color:#074079;
+}
+
+.start_end_links_span {
+       font-size: 11px;
+}
+
+.nav_arrow_fix {
+       font-size:8px;
+       position:relative;
+       top:-1px;
+}
+
+#result_table_div {
+       margin-top: 20px;
+}
+
+.result_numbers {
+       font-size: 11px; padding-left:15px; white-space: nowrap; width: 320px;
+}
+
+.result_table_subtable { width: 100%; border-collapse: collapse; border: 0; }
+
+
+
+
+.icon_text {
+       text-transform:capitalize;
+}
+
+.result_table_title_cell {
+       padding-left: 7px;
+}
+
+#myopac_summary_div p {
+       margin:0;
+       margin-bottom: 10px;
+}
+
+#acct_sum_checked_table td {
+       padding-bottom:5px;
+}
+
+#zero_search_hits div { float:left;width:300px;margin-top:20px; }
+
+#zero_search_hits p {
+       margin-top:0;
+}
+
+#zero_hits_term {
+       text-transform: uppercase;
+    font-weight: bold;
+}
+
+#zero_search_hits #spell_check_link {
+       text-transform: uppercase;
+}
+
+#zero_search_hits #zero_hits_suggestions {
+       text-transform: uppercase;
+}
+
+.results_info_table td {
+       padding-right: 10px;
+}
+
+#myopac_holds_main_table {
+       border-collapse: collapse;
+}
+
+#myopac_holds_main_table td {
+       border: 1px solid black;
+       
+}
+
+#myopac_prefs_div .data_grid {
+       border-collapse:collapse;
+}
+
+#myopac_prefs_div .data_grid td {
+       background:#f0f0f0;
+       border-bottom:3px solid white;
+       padding:6px 0px 7px 17px;
+}
+
+.header_middle {
+       height:22px;
+       font-size:14px;
+       font-weight:bold;
+       color:#074079;
+       padding: 0px 7px 0px 0px;
+       border-bottom: 1px dotted #ccc;
+}
+
+.header_middle a {
+       font-size: 12px;
+       font-weight: normal;
+}
+
+.acct_sum_row {
+       padding: 7px 15px;
+       width: 712px;
+       background: #f0f0f0;
+       margin-bottom: 2px;
+       font-size: 10px;
+       font-weight: bold;
+       text-transform: uppercase;
+}
+
+.acct_sum_row a {
+       text-transform: none;
+       font-size: 12px;
+       position:relative;
+       top:-1px;
+}
+
+.acct_sum_row .view_link {
+       font-weight: normal;
+       font-size:12px;
+}
+
+#myopac_sum_fines {
+       float:right;
+       padding: 15px 0px 0px 23px;
+       background: #f0f0f0;
+       width: 177px;
+       height: 166px;
+}
+
+.acct_holds_temp td {
+       text-align: left;
+}
+
+#acct_checked_tabs .align, #acct_holds_tabs .align, #acct_prefs_tabs .align {
+       float:left;
+       /*padding-left:10px;*/
+}
+
+#acct_checked_tabs .selected, #acct_holds_tabs .selected, #acct_prefs_tabs .selected {
+       /*background:url('/images/gray-arrow.png') left 3px no-repeat;*/
+}
+
+#acct_checked_main_header, #acct_holds_main_header, #acct_checked_hist_header, #acct_list_header, #acct_list_header_anon, #temp_list_holds {
+       font-weight:bold;
+       text-transform:uppercase;
+       font-size: 10px;
+}
+
+#acct_checked_main_header td, #acct_holds_main_header td, #acct_checked_hist_header td, #acct_list_header td, #acct_list_header_anon td, #temp_list_holds td {
+       background: #d8d8d8;
+       padding: 8px 0px 7px 0px;
+}
+
+#acct_list_header select, #acct_list_header_anon select {
+       font-weight:normal;
+       text-transform:none;
+}
+
+#acct_holds_activates_table label {
+       font-weight: bold;
+       font-size: 11px;
+       text-transform:uppercase;
+       padding-right: 5px;
+}
+
+.adv_search_font {
+       font-size: 10px;
+}
+
+.search_catalog_lbl {
+       font-size: 14px;
+}
+
+.lbl1 {
+       font-size:14px;
+       font-weight:bold;
+}
+
+.lbl2 {
+       font-size:10px;
+       font-weight:normal;
+       position:relative;
+       top:3px;
+}
+
+#myopac_tabs, #adv_search_parent {
+       background: #929292;
+       border-top:1px solid #8b8b8b;
+       padding-top:5px;
+       margin-bottom:20px;
+}
+
+#adv_search_parent {
+       margin-bottom:0px;
+}
+
+#myopac_loading {
+       width:100%;
+       text-align:center;
+       padding-top:20px;
+       font-size:16px;
+       font-weight:bold;
+}
+
+.chili_link {
+       width:100px !important;
+       text-align: center !important;
+}
+
+.chili_review div.chili_link div {
+       margin: auto;
+}
+
+/* some facet styling */
+.facetClassContainer { margin: 2px; border: 1px solid #CCC; }
+.facetClassLabelContainer { border: 1px solid #CCC; }
+.facetClassLabel { font-weight: bold; text-align: center; }
+.facetFieldContainer {  }
+.facetFieldLabel { padding-left: 2px; margin-top: 5px; margin-bottom: 5px; font-weight: bold; text-align: left; }
+.extraFacetFieldsWrapper { }
+.toggleExtraFacetFieldsButton { float: right; margin: 0px; padding: 0px; }
+.facetFieldLineCount { display: inline-block; border-right: 1px solid #CCC; color: gray; width: 3em; margin-right: 3px }
+.facetField { border-top: 1px solid #CCC; }
+.facetFields { padding-left: 5px; }
+.facetFieldLineValue { overflow: hidden; text-overflow: ellipsis; }
+
+#footer {
+       padding-top:5px;
+       padding-bottom: 10px;
+       color: white;
+       margin: auto;
+       width: 974px;
+       color: #afafaf;
+       font-size: 11px;
+}
+
+#footer a {
+       color: white;
+       color: #afafaf;
+}
+
+.color_4 {
+       text-transform: uppercase;
+       font-weight: bold;
+       font-size: 10px;
+}
+
+.advanced_div { padding-top: 15px; }
+#adv_global_search select { width: 13em; }
+#adv_global_input_table select { width: 7em; }
+.adv_adv_link { font-size: 8pt; color: red; }
+#acct_prefs_header { float: left; }
+#limit_to_available {
+    float: left; position: relative; top: 2px;
+    left: -2px; margin-right: 4px;
+}
+#rdetail_copy_info_table { font-size: 8pt; }
+#rdetail_copy_info_table td { padding: 3px; }
+.search_page_nav_link { cursor: pointer; }
+#opac.result.sort { width: 160px; }
+.renew-summary { font-size: 125%; font-style: italic; margin: 0.5ex 0; }
+.failure-text { margin-left: 4em; font-style: italic; color: #ff0000; }
+.refine-controls { font-size: 125%; padding: 0.5ex 0; }
+#adv_search_refine input[type=text] { border: 1px inset #ccc !important; }
+#adv_search_refine select { border: 1px inset #ccc !important; }
+#adv_search_refine {
+    padding-left: 5em; background-color: #d7d7d7; margin: 2ex 0;
+}
+.row-remover { position: relative; top: 1px; vertical-align: middle; }
diff --git a/Open-ILS/web/images/KCLS_logo_horiz.gif b/Open-ILS/web/images/KCLS_logo_horiz.gif
new file mode 100644 (file)
index 0000000..8e1d56e
Binary files /dev/null and b/Open-ILS/web/images/KCLS_logo_horiz.gif differ
diff --git a/Open-ILS/web/images/acct-btn-hover.png b/Open-ILS/web/images/acct-btn-hover.png
new file mode 100644 (file)
index 0000000..1e6e20a
Binary files /dev/null and b/Open-ILS/web/images/acct-btn-hover.png differ
diff --git a/Open-ILS/web/images/acct-btn.png b/Open-ILS/web/images/acct-btn.png
new file mode 100644 (file)
index 0000000..c9b92cd
Binary files /dev/null and b/Open-ILS/web/images/acct-btn.png differ
diff --git a/Open-ILS/web/images/acct_checked_out_off.gif b/Open-ILS/web/images/acct_checked_out_off.gif
new file mode 100644 (file)
index 0000000..dcfcfcb
Binary files /dev/null and b/Open-ILS/web/images/acct_checked_out_off.gif differ
diff --git a/Open-ILS/web/images/acct_checked_out_on.gif b/Open-ILS/web/images/acct_checked_out_on.gif
new file mode 100644 (file)
index 0000000..f364d38
Binary files /dev/null and b/Open-ILS/web/images/acct_checked_out_on.gif differ
diff --git a/Open-ILS/web/images/acct_favs_off.gif b/Open-ILS/web/images/acct_favs_off.gif
new file mode 100644 (file)
index 0000000..5ffc024
Binary files /dev/null and b/Open-ILS/web/images/acct_favs_off.gif differ
diff --git a/Open-ILS/web/images/acct_favs_on.gif b/Open-ILS/web/images/acct_favs_on.gif
new file mode 100644 (file)
index 0000000..f96342a
Binary files /dev/null and b/Open-ILS/web/images/acct_favs_on.gif differ
diff --git a/Open-ILS/web/images/acct_fines_off.jpg b/Open-ILS/web/images/acct_fines_off.jpg
new file mode 100644 (file)
index 0000000..b73b61d
Binary files /dev/null and b/Open-ILS/web/images/acct_fines_off.jpg differ
diff --git a/Open-ILS/web/images/acct_fines_on.jpg b/Open-ILS/web/images/acct_fines_on.jpg
new file mode 100644 (file)
index 0000000..4ea7e89
Binary files /dev/null and b/Open-ILS/web/images/acct_fines_on.jpg differ
diff --git a/Open-ILS/web/images/acct_holds_off.gif b/Open-ILS/web/images/acct_holds_off.gif
new file mode 100644 (file)
index 0000000..6179396
Binary files /dev/null and b/Open-ILS/web/images/acct_holds_off.gif differ
diff --git a/Open-ILS/web/images/acct_holds_on.gif b/Open-ILS/web/images/acct_holds_on.gif
new file mode 100644 (file)
index 0000000..d1c75bb
Binary files /dev/null and b/Open-ILS/web/images/acct_holds_on.gif differ
diff --git a/Open-ILS/web/images/acct_lists_off.gif b/Open-ILS/web/images/acct_lists_off.gif
new file mode 100644 (file)
index 0000000..9a5b2a2
Binary files /dev/null and b/Open-ILS/web/images/acct_lists_off.gif differ
diff --git a/Open-ILS/web/images/acct_lists_on.gif b/Open-ILS/web/images/acct_lists_on.gif
new file mode 100644 (file)
index 0000000..668b0c9
Binary files /dev/null and b/Open-ILS/web/images/acct_lists_on.gif differ
diff --git a/Open-ILS/web/images/acct_payments_off.jpg b/Open-ILS/web/images/acct_payments_off.jpg
new file mode 100644 (file)
index 0000000..c8a50f5
Binary files /dev/null and b/Open-ILS/web/images/acct_payments_off.jpg differ
diff --git a/Open-ILS/web/images/acct_payments_on.jpg b/Open-ILS/web/images/acct_payments_on.jpg
new file mode 100644 (file)
index 0000000..c571398
Binary files /dev/null and b/Open-ILS/web/images/acct_payments_on.jpg differ
diff --git a/Open-ILS/web/images/acct_prefs_off.gif b/Open-ILS/web/images/acct_prefs_off.gif
new file mode 100644 (file)
index 0000000..c357add
Binary files /dev/null and b/Open-ILS/web/images/acct_prefs_off.gif differ
diff --git a/Open-ILS/web/images/acct_prefs_on.gif b/Open-ILS/web/images/acct_prefs_on.gif
new file mode 100644 (file)
index 0000000..67d1f47
Binary files /dev/null and b/Open-ILS/web/images/acct_prefs_on.gif differ
diff --git a/Open-ILS/web/images/acct_sum_fines_bl.png b/Open-ILS/web/images/acct_sum_fines_bl.png
new file mode 100644 (file)
index 0000000..d750579
Binary files /dev/null and b/Open-ILS/web/images/acct_sum_fines_bl.png differ
diff --git a/Open-ILS/web/images/acct_sum_fines_br.png b/Open-ILS/web/images/acct_sum_fines_br.png
new file mode 100644 (file)
index 0000000..8aa81f0
Binary files /dev/null and b/Open-ILS/web/images/acct_sum_fines_br.png differ
diff --git a/Open-ILS/web/images/acct_sum_fines_tl.png b/Open-ILS/web/images/acct_sum_fines_tl.png
new file mode 100644 (file)
index 0000000..17051c9
Binary files /dev/null and b/Open-ILS/web/images/acct_sum_fines_tl.png differ
diff --git a/Open-ILS/web/images/acct_sum_fines_tr.png b/Open-ILS/web/images/acct_sum_fines_tr.png
new file mode 100644 (file)
index 0000000..fb9dac3
Binary files /dev/null and b/Open-ILS/web/images/acct_sum_fines_tr.png differ
diff --git a/Open-ILS/web/images/acct_summary_off.gif b/Open-ILS/web/images/acct_summary_off.gif
new file mode 100644 (file)
index 0000000..63456c1
Binary files /dev/null and b/Open-ILS/web/images/acct_summary_off.gif differ
diff --git a/Open-ILS/web/images/acct_summary_on.gif b/Open-ILS/web/images/acct_summary_on.gif
new file mode 100644 (file)
index 0000000..99d4990
Binary files /dev/null and b/Open-ILS/web/images/acct_summary_on.gif differ
diff --git a/Open-ILS/web/images/add_mylist.gif b/Open-ILS/web/images/add_mylist.gif
new file mode 100644 (file)
index 0000000..a30b32d
Binary files /dev/null and b/Open-ILS/web/images/add_mylist.gif differ
diff --git a/Open-ILS/web/images/add_mylist_sel.gif b/Open-ILS/web/images/add_mylist_sel.gif
new file mode 100644 (file)
index 0000000..0448d21
Binary files /dev/null and b/Open-ILS/web/images/add_mylist_sel.gif differ
diff --git a/Open-ILS/web/images/add_mylist_sel.kcls.gif b/Open-ILS/web/images/add_mylist_sel.kcls.gif
new file mode 100644 (file)
index 0000000..45bd8b6
Binary files /dev/null and b/Open-ILS/web/images/add_mylist_sel.kcls.gif differ
diff --git a/Open-ILS/web/images/add_search_row_btn.gif b/Open-ILS/web/images/add_search_row_btn.gif
new file mode 100644 (file)
index 0000000..a48e68c
Binary files /dev/null and b/Open-ILS/web/images/add_search_row_btn.gif differ
diff --git a/Open-ILS/web/images/adv_row_close_btn.png b/Open-ILS/web/images/adv_row_close_btn.png
new file mode 100644 (file)
index 0000000..edccf37
Binary files /dev/null and b/Open-ILS/web/images/adv_row_close_btn.png differ
diff --git a/Open-ILS/web/images/adv_search.png b/Open-ILS/web/images/adv_search.png
new file mode 100644 (file)
index 0000000..79fb08a
Binary files /dev/null and b/Open-ILS/web/images/adv_search.png differ
diff --git a/Open-ILS/web/images/adv_search_hover.png b/Open-ILS/web/images/adv_search_hover.png
new file mode 100644 (file)
index 0000000..0cb3fe1
Binary files /dev/null and b/Open-ILS/web/images/adv_search_hover.png differ
diff --git a/Open-ILS/web/images/adv_search_off.gif b/Open-ILS/web/images/adv_search_off.gif
new file mode 100644 (file)
index 0000000..a129b93
Binary files /dev/null and b/Open-ILS/web/images/adv_search_off.gif differ
diff --git a/Open-ILS/web/images/adv_search_on.gif b/Open-ILS/web/images/adv_search_on.gif
new file mode 100644 (file)
index 0000000..d0faa4f
Binary files /dev/null and b/Open-ILS/web/images/adv_search_on.gif differ
diff --git a/Open-ILS/web/images/another_search.png b/Open-ILS/web/images/another_search.png
new file mode 100644 (file)
index 0000000..4bcd214
Binary files /dev/null and b/Open-ILS/web/images/another_search.png differ
diff --git a/Open-ILS/web/images/another_search_hover.png b/Open-ILS/web/images/another_search_hover.png
new file mode 100644 (file)
index 0000000..08efaf5
Binary files /dev/null and b/Open-ILS/web/images/another_search_hover.png differ
diff --git a/Open-ILS/web/images/arrow-down.gif b/Open-ILS/web/images/arrow-down.gif
new file mode 100644 (file)
index 0000000..ebf64c4
Binary files /dev/null and b/Open-ILS/web/images/arrow-down.gif differ
diff --git a/Open-ILS/web/images/arrow-right.gif b/Open-ILS/web/images/arrow-right.gif
new file mode 100644 (file)
index 0000000..6c82655
Binary files /dev/null and b/Open-ILS/web/images/arrow-right.gif differ
diff --git a/Open-ILS/web/images/arrow-right.png b/Open-ILS/web/images/arrow-right.png
new file mode 100644 (file)
index 0000000..232a5e4
Binary files /dev/null and b/Open-ILS/web/images/arrow-right.png differ
diff --git a/Open-ILS/web/images/asknow_available.gif b/Open-ILS/web/images/asknow_available.gif
new file mode 100644 (file)
index 0000000..326c8d1
Binary files /dev/null and b/Open-ILS/web/images/asknow_available.gif differ
diff --git a/Open-ILS/web/images/banner-bg.png b/Open-ILS/web/images/banner-bg.png
new file mode 100644 (file)
index 0000000..6d990c5
Binary files /dev/null and b/Open-ILS/web/images/banner-bg.png differ
diff --git a/Open-ILS/web/images/banner1.jpg b/Open-ILS/web/images/banner1.jpg
new file mode 100644 (file)
index 0000000..28eaafc
Binary files /dev/null and b/Open-ILS/web/images/banner1.jpg differ
diff --git a/Open-ILS/web/images/btnCancel.png b/Open-ILS/web/images/btnCancel.png
new file mode 100644 (file)
index 0000000..4cfacaf
Binary files /dev/null and b/Open-ILS/web/images/btnCancel.png differ
diff --git a/Open-ILS/web/images/btnSubmit.png b/Open-ILS/web/images/btnSubmit.png
new file mode 100644 (file)
index 0000000..7a67408
Binary files /dev/null and b/Open-ILS/web/images/btnSubmit.png differ
diff --git a/Open-ILS/web/images/button-bg.png b/Open-ILS/web/images/button-bg.png
new file mode 100644 (file)
index 0000000..38390aa
Binary files /dev/null and b/Open-ILS/web/images/button-bg.png differ
diff --git a/Open-ILS/web/images/cancel_btn.gif b/Open-ILS/web/images/cancel_btn.gif
new file mode 100644 (file)
index 0000000..1cebf59
Binary files /dev/null and b/Open-ILS/web/images/cancel_btn.gif differ
diff --git a/Open-ILS/web/images/cd-small.png b/Open-ILS/web/images/cd-small.png
new file mode 100644 (file)
index 0000000..d2f8fb4
Binary files /dev/null and b/Open-ILS/web/images/cd-small.png differ
diff --git a/Open-ILS/web/images/clipboard.png b/Open-ILS/web/images/clipboard.png
new file mode 100644 (file)
index 0000000..b4bf071
Binary files /dev/null and b/Open-ILS/web/images/clipboard.png differ
diff --git a/Open-ILS/web/images/dash-corner-left1.png b/Open-ILS/web/images/dash-corner-left1.png
new file mode 100644 (file)
index 0000000..9559e8b
Binary files /dev/null and b/Open-ILS/web/images/dash-corner-left1.png differ
diff --git a/Open-ILS/web/images/dash-corner-left2.png b/Open-ILS/web/images/dash-corner-left2.png
new file mode 100644 (file)
index 0000000..5bc8112
Binary files /dev/null and b/Open-ILS/web/images/dash-corner-left2.png differ
diff --git a/Open-ILS/web/images/dash-corner-mid1.png b/Open-ILS/web/images/dash-corner-mid1.png
new file mode 100644 (file)
index 0000000..546b8a8
Binary files /dev/null and b/Open-ILS/web/images/dash-corner-mid1.png differ
diff --git a/Open-ILS/web/images/dash-corner-mid2.png b/Open-ILS/web/images/dash-corner-mid2.png
new file mode 100644 (file)
index 0000000..15af112
Binary files /dev/null and b/Open-ILS/web/images/dash-corner-mid2.png differ
diff --git a/Open-ILS/web/images/dash-corner-right1.png b/Open-ILS/web/images/dash-corner-right1.png
new file mode 100644 (file)
index 0000000..061afc9
Binary files /dev/null and b/Open-ILS/web/images/dash-corner-right1.png differ
diff --git a/Open-ILS/web/images/dash-corner-right2.png b/Open-ILS/web/images/dash-corner-right2.png
new file mode 100644 (file)
index 0000000..8663e0c
Binary files /dev/null and b/Open-ILS/web/images/dash-corner-right2.png differ
diff --git a/Open-ILS/web/images/dash-divider.jpg b/Open-ILS/web/images/dash-divider.jpg
new file mode 100644 (file)
index 0000000..19dda7d
Binary files /dev/null and b/Open-ILS/web/images/dash-divider.jpg differ
diff --git a/Open-ILS/web/images/dropdown-hover.gif b/Open-ILS/web/images/dropdown-hover.gif
new file mode 100644 (file)
index 0000000..1ac62ae
Binary files /dev/null and b/Open-ILS/web/images/dropdown-hover.gif differ
diff --git a/Open-ILS/web/images/dropdown.gif b/Open-ILS/web/images/dropdown.gif
new file mode 100644 (file)
index 0000000..3aab6fe
Binary files /dev/null and b/Open-ILS/web/images/dropdown.gif differ
diff --git a/Open-ILS/web/images/expert_search_off.gif b/Open-ILS/web/images/expert_search_off.gif
new file mode 100644 (file)
index 0000000..96b4f51
Binary files /dev/null and b/Open-ILS/web/images/expert_search_off.gif differ
diff --git a/Open-ILS/web/images/expert_search_on.gif b/Open-ILS/web/images/expert_search_on.gif
new file mode 100644 (file)
index 0000000..6a41861
Binary files /dev/null and b/Open-ILS/web/images/expert_search_on.gif differ
diff --git a/Open-ILS/web/images/faqs-btn.png b/Open-ILS/web/images/faqs-btn.png
new file mode 100644 (file)
index 0000000..38134ec
Binary files /dev/null and b/Open-ILS/web/images/faqs-btn.png differ
diff --git a/Open-ILS/web/images/go-btn-hover.png b/Open-ILS/web/images/go-btn-hover.png
new file mode 100644 (file)
index 0000000..9b878b2
Binary files /dev/null and b/Open-ILS/web/images/go-btn-hover.png differ
diff --git a/Open-ILS/web/images/go-btn.png b/Open-ILS/web/images/go-btn.png
new file mode 100644 (file)
index 0000000..24091c9
Binary files /dev/null and b/Open-ILS/web/images/go-btn.png differ
diff --git a/Open-ILS/web/images/go_but_long.gif b/Open-ILS/web/images/go_but_long.gif
new file mode 100644 (file)
index 0000000..79d2f9a
Binary files /dev/null and b/Open-ILS/web/images/go_but_long.gif differ
diff --git a/Open-ILS/web/images/golive.jpg b/Open-ILS/web/images/golive.jpg
new file mode 100644 (file)
index 0000000..8b34912
Binary files /dev/null and b/Open-ILS/web/images/golive.jpg differ
diff --git a/Open-ILS/web/images/gray-arrow.png b/Open-ILS/web/images/gray-arrow.png
new file mode 100644 (file)
index 0000000..bf56b6e
Binary files /dev/null and b/Open-ILS/web/images/gray-arrow.png differ
diff --git a/Open-ILS/web/images/green_check.png b/Open-ILS/web/images/green_check.png
new file mode 100644 (file)
index 0000000..9738bd8
Binary files /dev/null and b/Open-ILS/web/images/green_check.png differ
diff --git a/Open-ILS/web/images/header_left.gif b/Open-ILS/web/images/header_left.gif
new file mode 100644 (file)
index 0000000..9543795
Binary files /dev/null and b/Open-ILS/web/images/header_left.gif differ
diff --git a/Open-ILS/web/images/header_right.gif b/Open-ILS/web/images/header_right.gif
new file mode 100644 (file)
index 0000000..f00ff76
Binary files /dev/null and b/Open-ILS/web/images/header_right.gif differ
diff --git a/Open-ILS/web/images/hp-links-left.jpg b/Open-ILS/web/images/hp-links-left.jpg
new file mode 100644 (file)
index 0000000..0b8c9cf
Binary files /dev/null and b/Open-ILS/web/images/hp-links-left.jpg differ
diff --git a/Open-ILS/web/images/hp-links-mid.jpg b/Open-ILS/web/images/hp-links-mid.jpg
new file mode 100644 (file)
index 0000000..c9cdabf
Binary files /dev/null and b/Open-ILS/web/images/hp-links-mid.jpg differ
diff --git a/Open-ILS/web/images/hp-links-right.jpg b/Open-ILS/web/images/hp-links-right.jpg
new file mode 100644 (file)
index 0000000..63812f9
Binary files /dev/null and b/Open-ILS/web/images/hp-links-right.jpg differ
diff --git a/Open-ILS/web/images/locations.jpg b/Open-ILS/web/images/locations.jpg
new file mode 100644 (file)
index 0000000..56e7785
Binary files /dev/null and b/Open-ILS/web/images/locations.jpg differ
diff --git a/Open-ILS/web/images/login-bg.jpg b/Open-ILS/web/images/login-bg.jpg
new file mode 100644 (file)
index 0000000..46fc85f
Binary files /dev/null and b/Open-ILS/web/images/login-bg.jpg differ
diff --git a/Open-ILS/web/images/login-bg2.jpg b/Open-ILS/web/images/login-bg2.jpg
new file mode 100644 (file)
index 0000000..2c38853
Binary files /dev/null and b/Open-ILS/web/images/login-bg2.jpg differ
diff --git a/Open-ILS/web/images/login-box-bg.jpg b/Open-ILS/web/images/login-box-bg.jpg
new file mode 100644 (file)
index 0000000..caf036d
Binary files /dev/null and b/Open-ILS/web/images/login-box-bg.jpg differ
diff --git a/Open-ILS/web/images/login-btn-hover.png b/Open-ILS/web/images/login-btn-hover.png
new file mode 100644 (file)
index 0000000..442f33f
Binary files /dev/null and b/Open-ILS/web/images/login-btn-hover.png differ
diff --git a/Open-ILS/web/images/login-btn.gif b/Open-ILS/web/images/login-btn.gif
new file mode 100644 (file)
index 0000000..69d6a56
Binary files /dev/null and b/Open-ILS/web/images/login-btn.gif differ
diff --git a/Open-ILS/web/images/login-btn.png b/Open-ILS/web/images/login-btn.png
new file mode 100644 (file)
index 0000000..5548b99
Binary files /dev/null and b/Open-ILS/web/images/login-btn.png differ
diff --git a/Open-ILS/web/images/login-btn2.png b/Open-ILS/web/images/login-btn2.png
new file mode 100644 (file)
index 0000000..ff4af14
Binary files /dev/null and b/Open-ILS/web/images/login-btn2.png differ
diff --git a/Open-ILS/web/images/logout-btn-hover.png b/Open-ILS/web/images/logout-btn-hover.png
new file mode 100644 (file)
index 0000000..411fc01
Binary files /dev/null and b/Open-ILS/web/images/logout-btn-hover.png differ
diff --git a/Open-ILS/web/images/logout-btn.png b/Open-ILS/web/images/logout-btn.png
new file mode 100644 (file)
index 0000000..bd31a47
Binary files /dev/null and b/Open-ILS/web/images/logout-btn.png differ
diff --git a/Open-ILS/web/images/media_3dobject.jpg b/Open-ILS/web/images/media_3dobject.jpg
new file mode 100644 (file)
index 0000000..21ee11d
Binary files /dev/null and b/Open-ILS/web/images/media_3dobject.jpg differ
diff --git a/Open-ILS/web/images/media_book.jpg b/Open-ILS/web/images/media_book.jpg
new file mode 100644 (file)
index 0000000..d928e6e
Binary files /dev/null and b/Open-ILS/web/images/media_book.jpg differ
diff --git a/Open-ILS/web/images/media_bookoncassette.jpg b/Open-ILS/web/images/media_bookoncassette.jpg
new file mode 100644 (file)
index 0000000..acc469e
Binary files /dev/null and b/Open-ILS/web/images/media_bookoncassette.jpg differ
diff --git a/Open-ILS/web/images/media_bookoncassettecd.jpg b/Open-ILS/web/images/media_bookoncassettecd.jpg
new file mode 100644 (file)
index 0000000..e288689
Binary files /dev/null and b/Open-ILS/web/images/media_bookoncassettecd.jpg differ
diff --git a/Open-ILS/web/images/media_bookoncd.jpg b/Open-ILS/web/images/media_bookoncd.jpg
new file mode 100644 (file)
index 0000000..9e49aed
Binary files /dev/null and b/Open-ILS/web/images/media_bookoncd.jpg differ
diff --git a/Open-ILS/web/images/media_cassettewithbook.jpg b/Open-ILS/web/images/media_cassettewithbook.jpg
new file mode 100644 (file)
index 0000000..c434af6
Binary files /dev/null and b/Open-ILS/web/images/media_cassettewithbook.jpg differ
diff --git a/Open-ILS/web/images/media_cdrom.jpg b/Open-ILS/web/images/media_cdrom.jpg
new file mode 100644 (file)
index 0000000..59f9702
Binary files /dev/null and b/Open-ILS/web/images/media_cdrom.jpg differ
diff --git a/Open-ILS/web/images/media_cdwithbook.jpg b/Open-ILS/web/images/media_cdwithbook.jpg
new file mode 100644 (file)
index 0000000..b1828d8
Binary files /dev/null and b/Open-ILS/web/images/media_cdwithbook.jpg differ
diff --git a/Open-ILS/web/images/media_downloadebook.jpg b/Open-ILS/web/images/media_downloadebook.jpg
new file mode 100644 (file)
index 0000000..ce97463
Binary files /dev/null and b/Open-ILS/web/images/media_downloadebook.jpg differ
diff --git a/Open-ILS/web/images/media_downloadmusic.jpg b/Open-ILS/web/images/media_downloadmusic.jpg
new file mode 100644 (file)
index 0000000..953b7e7
Binary files /dev/null and b/Open-ILS/web/images/media_downloadmusic.jpg differ
diff --git a/Open-ILS/web/images/media_downloadvideo.jpg b/Open-ILS/web/images/media_downloadvideo.jpg
new file mode 100644 (file)
index 0000000..e3abfc3
Binary files /dev/null and b/Open-ILS/web/images/media_downloadvideo.jpg differ
diff --git a/Open-ILS/web/images/media_dvd.jpg b/Open-ILS/web/images/media_dvd.jpg
new file mode 100644 (file)
index 0000000..905f623
Binary files /dev/null and b/Open-ILS/web/images/media_dvd.jpg differ
diff --git a/Open-ILS/web/images/media_eaudio.jpg b/Open-ILS/web/images/media_eaudio.jpg
new file mode 100644 (file)
index 0000000..0d810ba
Binary files /dev/null and b/Open-ILS/web/images/media_eaudio.jpg differ
diff --git a/Open-ILS/web/images/media_ebooktext.jpg b/Open-ILS/web/images/media_ebooktext.jpg
new file mode 100644 (file)
index 0000000..c45f944
Binary files /dev/null and b/Open-ILS/web/images/media_ebooktext.jpg differ
diff --git a/Open-ILS/web/images/media_equipment.jpg b/Open-ILS/web/images/media_equipment.jpg
new file mode 100644 (file)
index 0000000..47b8377
Binary files /dev/null and b/Open-ILS/web/images/media_equipment.jpg differ
diff --git a/Open-ILS/web/images/media_films.jpg b/Open-ILS/web/images/media_films.jpg
new file mode 100644 (file)
index 0000000..99b74a0
Binary files /dev/null and b/Open-ILS/web/images/media_films.jpg differ
diff --git a/Open-ILS/web/images/media_games.jpg b/Open-ILS/web/images/media_games.jpg
new file mode 100644 (file)
index 0000000..24d50ae
Binary files /dev/null and b/Open-ILS/web/images/media_games.jpg differ
diff --git a/Open-ILS/web/images/media_kit.jpg b/Open-ILS/web/images/media_kit.jpg
new file mode 100644 (file)
index 0000000..ea50e56
Binary files /dev/null and b/Open-ILS/web/images/media_kit.jpg differ
diff --git a/Open-ILS/web/images/media_language.jpg b/Open-ILS/web/images/media_language.jpg
new file mode 100644 (file)
index 0000000..0d86b5b
Binary files /dev/null and b/Open-ILS/web/images/media_language.jpg differ
diff --git a/Open-ILS/web/images/media_largeprint.jpg b/Open-ILS/web/images/media_largeprint.jpg
new file mode 100644 (file)
index 0000000..bd8b0a4
Binary files /dev/null and b/Open-ILS/web/images/media_largeprint.jpg differ
diff --git a/Open-ILS/web/images/media_magazines.jpg b/Open-ILS/web/images/media_magazines.jpg
new file mode 100644 (file)
index 0000000..e8bb737
Binary files /dev/null and b/Open-ILS/web/images/media_magazines.jpg differ
diff --git a/Open-ILS/web/images/media_map.jpg b/Open-ILS/web/images/media_map.jpg
new file mode 100644 (file)
index 0000000..9236724
Binary files /dev/null and b/Open-ILS/web/images/media_map.jpg differ
diff --git a/Open-ILS/web/images/media_microform.jpg b/Open-ILS/web/images/media_microform.jpg
new file mode 100644 (file)
index 0000000..7e7e0dc
Binary files /dev/null and b/Open-ILS/web/images/media_microform.jpg differ
diff --git a/Open-ILS/web/images/media_musiccassete.jpg b/Open-ILS/web/images/media_musiccassete.jpg
new file mode 100644 (file)
index 0000000..7d9a779
Binary files /dev/null and b/Open-ILS/web/images/media_musiccassete.jpg differ
diff --git a/Open-ILS/web/images/media_musiccassette.jpg b/Open-ILS/web/images/media_musiccassette.jpg
new file mode 100644 (file)
index 0000000..c4a673f
Binary files /dev/null and b/Open-ILS/web/images/media_musiccassette.jpg differ
diff --git a/Open-ILS/web/images/media_musiccd.jpg b/Open-ILS/web/images/media_musiccd.jpg
new file mode 100644 (file)
index 0000000..f82eaed
Binary files /dev/null and b/Open-ILS/web/images/media_musiccd.jpg differ
diff --git a/Open-ILS/web/images/media_musicrecord.jpg b/Open-ILS/web/images/media_musicrecord.jpg
new file mode 100644 (file)
index 0000000..4731692
Binary files /dev/null and b/Open-ILS/web/images/media_musicrecord.jpg differ
diff --git a/Open-ILS/web/images/media_newspaper.jpg b/Open-ILS/web/images/media_newspaper.jpg
new file mode 100644 (file)
index 0000000..8a7b769
Binary files /dev/null and b/Open-ILS/web/images/media_newspaper.jpg differ
diff --git a/Open-ILS/web/images/media_online.jpg b/Open-ILS/web/images/media_online.jpg
new file mode 100644 (file)
index 0000000..2f9cfcc
Binary files /dev/null and b/Open-ILS/web/images/media_online.jpg differ
diff --git a/Open-ILS/web/images/media_onlinejournal.jpg b/Open-ILS/web/images/media_onlinejournal.jpg
new file mode 100644 (file)
index 0000000..3528f1c
Binary files /dev/null and b/Open-ILS/web/images/media_onlinejournal.jpg differ
diff --git a/Open-ILS/web/images/media_podcasts.jpg b/Open-ILS/web/images/media_podcasts.jpg
new file mode 100644 (file)
index 0000000..c65727c
Binary files /dev/null and b/Open-ILS/web/images/media_podcasts.jpg differ
diff --git a/Open-ILS/web/images/media_printedmusic.jpg b/Open-ILS/web/images/media_printedmusic.jpg
new file mode 100644 (file)
index 0000000..2379dbd
Binary files /dev/null and b/Open-ILS/web/images/media_printedmusic.jpg differ
diff --git a/Open-ILS/web/images/media_projectedmedia.jpg b/Open-ILS/web/images/media_projectedmedia.jpg
new file mode 100644 (file)
index 0000000..99b74a0
Binary files /dev/null and b/Open-ILS/web/images/media_projectedmedia.jpg differ
diff --git a/Open-ILS/web/images/media_sheetmusic.jpg b/Open-ILS/web/images/media_sheetmusic.jpg
new file mode 100644 (file)
index 0000000..9207268
Binary files /dev/null and b/Open-ILS/web/images/media_sheetmusic.jpg differ
diff --git a/Open-ILS/web/images/media_slide.jpg b/Open-ILS/web/images/media_slide.jpg
new file mode 100644 (file)
index 0000000..62aca57
Binary files /dev/null and b/Open-ILS/web/images/media_slide.jpg differ
diff --git a/Open-ILS/web/images/media_software.jpg b/Open-ILS/web/images/media_software.jpg
new file mode 100644 (file)
index 0000000..090cee2
Binary files /dev/null and b/Open-ILS/web/images/media_software.jpg differ
diff --git a/Open-ILS/web/images/media_streamingaudio.jpg b/Open-ILS/web/images/media_streamingaudio.jpg
new file mode 100644 (file)
index 0000000..3efafe8
Binary files /dev/null and b/Open-ILS/web/images/media_streamingaudio.jpg differ
diff --git a/Open-ILS/web/images/media_streamingvideo.jpg b/Open-ILS/web/images/media_streamingvideo.jpg
new file mode 100644 (file)
index 0000000..ab9bf9c
Binary files /dev/null and b/Open-ILS/web/images/media_streamingvideo.jpg differ
diff --git a/Open-ILS/web/images/media_vhs.jpg b/Open-ILS/web/images/media_vhs.jpg
new file mode 100644 (file)
index 0000000..228d156
Binary files /dev/null and b/Open-ILS/web/images/media_vhs.jpg differ
diff --git a/Open-ILS/web/images/num_search_off.gif b/Open-ILS/web/images/num_search_off.gif
new file mode 100644 (file)
index 0000000..1062802
Binary files /dev/null and b/Open-ILS/web/images/num_search_off.gif differ
diff --git a/Open-ILS/web/images/num_search_on.gif b/Open-ILS/web/images/num_search_on.gif
new file mode 100644 (file)
index 0000000..f7d7829
Binary files /dev/null and b/Open-ILS/web/images/num_search_on.gif differ
diff --git a/Open-ILS/web/images/one_land.gif b/Open-ILS/web/images/one_land.gif
new file mode 100644 (file)
index 0000000..082b996
Binary files /dev/null and b/Open-ILS/web/images/one_land.gif differ
diff --git a/Open-ILS/web/images/pay-fines-btn-hover.png b/Open-ILS/web/images/pay-fines-btn-hover.png
new file mode 100644 (file)
index 0000000..b7708da
Binary files /dev/null and b/Open-ILS/web/images/pay-fines-btn-hover.png differ
diff --git a/Open-ILS/web/images/pay-fines-btn.png b/Open-ILS/web/images/pay-fines-btn.png
new file mode 100644 (file)
index 0000000..356433b
Binary files /dev/null and b/Open-ILS/web/images/pay-fines-btn.png differ
diff --git a/Open-ILS/web/images/pay_fines_btn.gif b/Open-ILS/web/images/pay_fines_btn.gif
new file mode 100644 (file)
index 0000000..eb4816f
Binary files /dev/null and b/Open-ILS/web/images/pay_fines_btn.gif differ
diff --git a/Open-ILS/web/images/place_hold.gif b/Open-ILS/web/images/place_hold.gif
new file mode 100644 (file)
index 0000000..3f72215
Binary files /dev/null and b/Open-ILS/web/images/place_hold.gif differ
diff --git a/Open-ILS/web/images/plus_sign.png b/Open-ILS/web/images/plus_sign.png
new file mode 100644 (file)
index 0000000..a17d58a
Binary files /dev/null and b/Open-ILS/web/images/plus_sign.png differ
diff --git a/Open-ILS/web/images/projectedmedia.jpg b/Open-ILS/web/images/projectedmedia.jpg
new file mode 100644 (file)
index 0000000..ba0e6d2
Binary files /dev/null and b/Open-ILS/web/images/projectedmedia.jpg differ
diff --git a/Open-ILS/web/images/question-mark.png b/Open-ILS/web/images/question-mark.png
new file mode 100644 (file)
index 0000000..b5f0f87
Binary files /dev/null and b/Open-ILS/web/images/question-mark.png differ
diff --git a/Open-ILS/web/images/questions.png b/Open-ILS/web/images/questions.png
new file mode 100644 (file)
index 0000000..9be69b2
Binary files /dev/null and b/Open-ILS/web/images/questions.png differ
diff --git a/Open-ILS/web/images/rdetail_arrow.png b/Open-ILS/web/images/rdetail_arrow.png
new file mode 100644 (file)
index 0000000..e464bf2
Binary files /dev/null and b/Open-ILS/web/images/rdetail_arrow.png differ
diff --git a/Open-ILS/web/images/reset_form_btn.gif b/Open-ILS/web/images/reset_form_btn.gif
new file mode 100644 (file)
index 0000000..6b70964
Binary files /dev/null and b/Open-ILS/web/images/reset_form_btn.gif differ
diff --git a/Open-ILS/web/images/reviews.gif b/Open-ILS/web/images/reviews.gif
new file mode 100644 (file)
index 0000000..b78fa25
Binary files /dev/null and b/Open-ILS/web/images/reviews.gif differ
diff --git a/Open-ILS/web/images/save-btn.png b/Open-ILS/web/images/save-btn.png
new file mode 100644 (file)
index 0000000..4565850
Binary files /dev/null and b/Open-ILS/web/images/save-btn.png differ
diff --git a/Open-ILS/web/images/save_btn.gif b/Open-ILS/web/images/save_btn.gif
new file mode 100644 (file)
index 0000000..f87282a
Binary files /dev/null and b/Open-ILS/web/images/save_btn.gif differ
diff --git a/Open-ILS/web/images/search_btn.gif b/Open-ILS/web/images/search_btn.gif
new file mode 100644 (file)
index 0000000..f2fdc9b
Binary files /dev/null and b/Open-ILS/web/images/search_btn.gif differ
diff --git a/Open-ILS/web/images/starz.png b/Open-ILS/web/images/starz.png
new file mode 100644 (file)
index 0000000..4a79dd4
Binary files /dev/null and b/Open-ILS/web/images/starz.png differ
diff --git a/Open-ILS/web/images/sub_checked_hist_off.jpg b/Open-ILS/web/images/sub_checked_hist_off.jpg
new file mode 100644 (file)
index 0000000..7fda1c3
Binary files /dev/null and b/Open-ILS/web/images/sub_checked_hist_off.jpg differ
diff --git a/Open-ILS/web/images/sub_checked_hist_on.jpg b/Open-ILS/web/images/sub_checked_hist_on.jpg
new file mode 100644 (file)
index 0000000..703aac1
Binary files /dev/null and b/Open-ILS/web/images/sub_checked_hist_on.jpg differ
diff --git a/Open-ILS/web/images/sub_checked_out_off.jpg b/Open-ILS/web/images/sub_checked_out_off.jpg
new file mode 100644 (file)
index 0000000..0573fbd
Binary files /dev/null and b/Open-ILS/web/images/sub_checked_out_off.jpg differ
diff --git a/Open-ILS/web/images/sub_checked_out_on.jpg b/Open-ILS/web/images/sub_checked_out_on.jpg
new file mode 100644 (file)
index 0000000..97bb178
Binary files /dev/null and b/Open-ILS/web/images/sub_checked_out_on.jpg differ
diff --git a/Open-ILS/web/images/sub_holds_hist_off.jpg b/Open-ILS/web/images/sub_holds_hist_off.jpg
new file mode 100644 (file)
index 0000000..020abe9
Binary files /dev/null and b/Open-ILS/web/images/sub_holds_hist_off.jpg differ
diff --git a/Open-ILS/web/images/sub_holds_hist_on.jpg b/Open-ILS/web/images/sub_holds_hist_on.jpg
new file mode 100644 (file)
index 0000000..020abe9
Binary files /dev/null and b/Open-ILS/web/images/sub_holds_hist_on.jpg differ
diff --git a/Open-ILS/web/images/sub_holds_off.jpg b/Open-ILS/web/images/sub_holds_off.jpg
new file mode 100644 (file)
index 0000000..b888359
Binary files /dev/null and b/Open-ILS/web/images/sub_holds_off.jpg differ
diff --git a/Open-ILS/web/images/sub_holds_on.jpg b/Open-ILS/web/images/sub_holds_on.jpg
new file mode 100644 (file)
index 0000000..9505638
Binary files /dev/null and b/Open-ILS/web/images/sub_holds_on.jpg differ
diff --git a/Open-ILS/web/images/sub_prefs_info_off.jpg b/Open-ILS/web/images/sub_prefs_info_off.jpg
new file mode 100644 (file)
index 0000000..896e227
Binary files /dev/null and b/Open-ILS/web/images/sub_prefs_info_off.jpg differ
diff --git a/Open-ILS/web/images/sub_prefs_info_on.jpg b/Open-ILS/web/images/sub_prefs_info_on.jpg
new file mode 100644 (file)
index 0000000..0895969
Binary files /dev/null and b/Open-ILS/web/images/sub_prefs_info_on.jpg differ
diff --git a/Open-ILS/web/images/sub_prefs_notify_off.jpg b/Open-ILS/web/images/sub_prefs_notify_off.jpg
new file mode 100644 (file)
index 0000000..55df9da
Binary files /dev/null and b/Open-ILS/web/images/sub_prefs_notify_off.jpg differ
diff --git a/Open-ILS/web/images/sub_prefs_notify_on.jpg b/Open-ILS/web/images/sub_prefs_notify_on.jpg
new file mode 100644 (file)
index 0000000..fd536a8
Binary files /dev/null and b/Open-ILS/web/images/sub_prefs_notify_on.jpg differ
diff --git a/Open-ILS/web/images/sub_prefs_search_off.jpg b/Open-ILS/web/images/sub_prefs_search_off.jpg
new file mode 100644 (file)
index 0000000..89115f6
Binary files /dev/null and b/Open-ILS/web/images/sub_prefs_search_off.jpg differ
diff --git a/Open-ILS/web/images/sub_prefs_search_on.jpg b/Open-ILS/web/images/sub_prefs_search_on.jpg
new file mode 100644 (file)
index 0000000..3eab9fa
Binary files /dev/null and b/Open-ILS/web/images/sub_prefs_search_on.jpg differ
diff --git a/Open-ILS/web/images/submit_btn.gif b/Open-ILS/web/images/submit_btn.gif
new file mode 100644 (file)
index 0000000..5286943
Binary files /dev/null and b/Open-ILS/web/images/submit_btn.gif differ
diff --git a/Open-ILS/web/images/tool_back.gif b/Open-ILS/web/images/tool_back.gif
new file mode 100644 (file)
index 0000000..37d1278
Binary files /dev/null and b/Open-ILS/web/images/tool_back.gif differ
diff --git a/Open-ILS/web/images/tool_back.png b/Open-ILS/web/images/tool_back.png
new file mode 100644 (file)
index 0000000..41a13e2
Binary files /dev/null and b/Open-ILS/web/images/tool_back.png differ
diff --git a/Open-ILS/web/images/tool_font.gif b/Open-ILS/web/images/tool_font.gif
new file mode 100644 (file)
index 0000000..9dc10a9
Binary files /dev/null and b/Open-ILS/web/images/tool_font.gif differ
diff --git a/Open-ILS/web/images/tool_forward.gif b/Open-ILS/web/images/tool_forward.gif
new file mode 100644 (file)
index 0000000..db0d800
Binary files /dev/null and b/Open-ILS/web/images/tool_forward.gif differ
diff --git a/Open-ILS/web/images/tool_forward.png b/Open-ILS/web/images/tool_forward.png
new file mode 100644 (file)
index 0000000..582a6b9
Binary files /dev/null and b/Open-ILS/web/images/tool_forward.png differ
diff --git a/Open-ILS/web/images/tool_help.gif b/Open-ILS/web/images/tool_help.gif
new file mode 100644 (file)
index 0000000..2a3de86
Binary files /dev/null and b/Open-ILS/web/images/tool_help.gif differ
diff --git a/Open-ILS/web/images/tool_help.png b/Open-ILS/web/images/tool_help.png
new file mode 100644 (file)
index 0000000..3007c20
Binary files /dev/null and b/Open-ILS/web/images/tool_help.png differ
diff --git a/Open-ILS/web/images/tool_home.gif b/Open-ILS/web/images/tool_home.gif
new file mode 100644 (file)
index 0000000..9b83ccf
Binary files /dev/null and b/Open-ILS/web/images/tool_home.gif differ
diff --git a/Open-ILS/web/images/tool_home.png b/Open-ILS/web/images/tool_home.png
new file mode 100644 (file)
index 0000000..0620200
Binary files /dev/null and b/Open-ILS/web/images/tool_home.png differ
diff --git a/Open-ILS/web/images/tool_mail.gif b/Open-ILS/web/images/tool_mail.gif
new file mode 100644 (file)
index 0000000..83c3573
Binary files /dev/null and b/Open-ILS/web/images/tool_mail.gif differ
diff --git a/Open-ILS/web/images/tool_print.gif b/Open-ILS/web/images/tool_print.gif
new file mode 100644 (file)
index 0000000..d3d7ee3
Binary files /dev/null and b/Open-ILS/web/images/tool_print.gif differ
diff --git a/Open-ILS/web/images/tool_print.png b/Open-ILS/web/images/tool_print.png
new file mode 100644 (file)
index 0000000..2c0dc0b
Binary files /dev/null and b/Open-ILS/web/images/tool_print.png differ
diff --git a/Open-ILS/web/images/utils-corner-left.png b/Open-ILS/web/images/utils-corner-left.png
new file mode 100644 (file)
index 0000000..db70a75
Binary files /dev/null and b/Open-ILS/web/images/utils-corner-left.png differ
diff --git a/Open-ILS/web/images/utils-corner-mid.png b/Open-ILS/web/images/utils-corner-mid.png
new file mode 100644 (file)
index 0000000..80d4857
Binary files /dev/null and b/Open-ILS/web/images/utils-corner-mid.png differ
diff --git a/Open-ILS/web/images/utils-corner-right.jpg b/Open-ILS/web/images/utils-corner-right.jpg
new file mode 100644 (file)
index 0000000..1559897
Binary files /dev/null and b/Open-ILS/web/images/utils-corner-right.jpg differ
diff --git a/Open-ILS/web/images/utils-corner-right.png b/Open-ILS/web/images/utils-corner-right.png
new file mode 100644 (file)
index 0000000..303ab75
Binary files /dev/null and b/Open-ILS/web/images/utils-corner-right.png differ
diff --git a/Open-ILS/web/images/utils-corner.jpg b/Open-ILS/web/images/utils-corner.jpg
new file mode 100644 (file)
index 0000000..4932a28
Binary files /dev/null and b/Open-ILS/web/images/utils-corner.jpg differ
diff --git a/Open-ILS/web/images/view_my_list.png b/Open-ILS/web/images/view_my_list.png
new file mode 100644 (file)
index 0000000..d5f1b83
Binary files /dev/null and b/Open-ILS/web/images/view_my_list.png differ
diff --git a/Open-ILS/web/images/view_my_list_hover.png b/Open-ILS/web/images/view_my_list_hover.png
new file mode 100644 (file)
index 0000000..369cb1a
Binary files /dev/null and b/Open-ILS/web/images/view_my_list_hover.png differ
diff --git a/Open-ILS/web/js/ui/default/opac/simple.js b/Open-ILS/web/js/ui/default/opac/simple.js
new file mode 100644 (file)
index 0000000..7124d03
--- /dev/null
@@ -0,0 +1,29 @@
+/* Keep this dead simple. No dojo. Call nothing via onload. */
+function $(s) { return document.getElementById(s); }
+function removeClass(node, cls) {
+    if (!node || !node.className) return;
+    node.className =
+        node.className.replace(new RegExp("\\b" + cls + "\\b", "g"), "");
+}
+function addClass(node, cls) {
+    if (!node) return;
+    removeClass(node, cls);
+    if (!node.className) node.className = cls;
+    else node.className += ' ' + cls;
+}
+function unHideMe(node) { removeClass(node, "hide_me"); }
+function hideMe(node) { addClass(node, "hide_me"); }
+
+var _search_row_template;
+function addSearchRow() {
+    if (!_search_row_template) {
+        t = $("adv_global_row").cloneNode(true);
+        t.id = null;
+        _search_row_template = t;
+    }
+
+    $("adv_global_tbody").insertBefore(
+        _search_row_template.cloneNode(true),
+        $("adv_global_addrow")
+    );
+}
diff --git a/Open-ILS/web/templates/default/opac-poc/base.tt2 b/Open-ILS/web/templates/default/opac-poc/base.tt2
new file mode 100644 (file)
index 0000000..6d54607
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns='http://www.w3.org/1999/xhtml' lang='[% ctx.locale %]' xml:lang='[% ctx.locale %]'>
+    <head>
+        <title>[% ctx.page_title %]</title>
+        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+        [% BLOCK html_head; END; # provide a default that can be overridden %]
+        [% PROCESS html_head %]
+    </head>
+    <body>
+        [% content %] 
+    </body>
+</html>
diff --git a/Open-ILS/web/templates/default/opac-poc/common.tt2 b/Open-ILS/web/templates/default/opac-poc/common.tt2
new file mode 100644 (file)
index 0000000..c4caa0e
--- /dev/null
@@ -0,0 +1,58 @@
+[% 
+    # Org Unit Selector Widget : 
+    #   PROCESS build_org_selector id='selector-id' name='selector-name'
+    BLOCK build_org_selector;
+        first_run = 0;
+        IF !org_unit;
+            org_unit = ctx.aou_tree;
+            first_run = 1;
+%]
+    <select id='[% id %]' name='[% name %]'>
+    [% END %]
+        <option value='[% org_unit.id %]' [% IF org_unit.id == value %] selected='selected' [% END %]>
+            [% 
+                pad = org_unit.ou_type.depth * 2;
+                FOR idx IN [0..pad]; '&nbsp;'; END;
+                org_unit.name;
+            %]
+        </option>
+        [% FOR child IN org_unit.children; PROCESS build_org_selector org_unit = child; END %]
+    [% IF first_run %]
+    </select>
+    [% END %]
+[% END %]
+
+[% PROCESS 'default/opac/marc_attrs.tt2' %]
+[%  USE date;
+    USE money = format('$%.2f');
+    icon_by_mattype = {     # XXX KCLS-specific
+        "a" => "media_book.jpg",
+        "b" => "media_magazines.jpg",
+        "c" => "media_printedmusic.jpg",
+        "d" => "media_microform.jpg",
+        "e" => "media_equipment.jpg",
+        "f" => "media_films.jpg",
+        "g" => "",
+        "h" => "media_dvd.jpg",
+        "i" => "media_bookoncassette.jpg",
+        "j" => "media_musiccd.jpg",
+        "k" => "media_musiccassette.jpg",
+        "l" => "media_musicrecord.jpg",
+        "m" => "media_software.jpg",
+        "n" => "media_bookoncd.jpg",
+        "o" => "media_kit.jpg",
+        "p" => "media_newspaper.jpg",
+        "q" => "media_largeprint.jpg",
+        "r" => "media_3dobject.jpg",
+        "s" => "media_slide.jpg",
+        "t" => "media_online.jpg",
+        "u" => "media_eaudio.jpg",
+        "v" => "media_ebooktext.jpg",
+        "w" => "media_eaudio.jpg",
+        "x" => "media_downloadmusic.jpg",
+        "y" => "media_downloadvideo.jpg",
+        "z" => "media_map.jpg",
+        "2" => "media_cassettewithbook.jpg",
+        "5" => "media_cdwithbook.jpg"
+    };
+%]
diff --git a/Open-ILS/web/templates/default/opac-poc/home.tt2 b/Open-ILS/web/templates/default/opac-poc/home.tt2
new file mode 100644 (file)
index 0000000..03b2ad1
--- /dev/null
@@ -0,0 +1,24 @@
+[% ctx.page_title = "Home" %]
+
+[% BLOCK html_head %]
+<style>
+    #home_div { text-align: center; width: 100%; margin-top: 30px;}
+</style>
+[% END %]
+
+[% WRAPPER "default/opac/base.tt2" %]
+[% PROCESS "default/opac/common.tt2" %]
+
+<div id='home_div'>
+    <img src='/images/eg_logo.jpg'/>
+    <br/><br/>
+    <form action='./results' method='GET'>
+        <input type='text' name='query' size='50' value='[% query %]'/>
+        [% PROCESS build_org_selector name='loc' %]
+        <input type='submit' value='[% l('Go!') %]'/>
+        <input type='hidden' name='page' value='0'/>
+    </form>
+</div>
+
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/login.tt2 b/Open-ILS/web/templates/default/opac-poc/login.tt2
new file mode 100644 (file)
index 0000000..1bae958
--- /dev/null
@@ -0,0 +1,32 @@
+[% BLOCK html_head %]
+<style>
+</style>
+[% END %]
+
+[% 
+    USE CGI;
+    WRAPPER "default/opac/base.tt2"; 
+    ctx.page_title = "Login";
+%]
+
+<div style='width:400px; text-align:center; border: 1px solid #888'>
+    <form method='POST'>
+        <table>
+            <tr>
+                <td>Username or Barcode</td>
+                <td><input name='username' type='text'/></td>
+            </tr>
+            <tr>
+                <td>Password</td>
+                <td><input name='password' type='password'/></td>
+            </tr>
+            <tr>
+                <td colspan='2' style='text-align:center'>
+                    <input type='submit'/>
+                </td>
+            </tr>
+        </table>
+        <input type='hidden' name='redirect_to' value='[% CGI.param('redirect_to') || ctx.referer | replace('^http:', 'https:') %]'/>
+    </form>
+</div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/marc_attrs.tt2 b/Open-ILS/web/templates/default/opac-poc/marc_attrs.tt2
new file mode 100644 (file)
index 0000000..73f12c3
--- /dev/null
@@ -0,0 +1,18 @@
+[% 
+    # Extract MARC fields from XML
+    #   get_marc_attrs( { marc_xml => doc } )
+    BLOCK get_marc_attrs;
+        xml = args.marc_xml;
+        args.isbn = xml.findnodes('//*[@tag="020"]/*[@code="a"]').textContent;
+        args.upc = xml.findnodes('//*[@tag="024"]/*[@code="a"]').textContent;
+        args.issn = xml.findnodes('//*[@tag="022"]/*[@code="a"]').textContent;
+        args.title = xml.findnodes('//*[@tag="245"]/*[@code="a"]').textContent;
+        args.author = xml.findnodes('//*[@tag="100"]/*[@code="a"]').textContent;
+        args.publisher = xml.findnodes('//*[@tag="260"]/*[@code="b"]').textContent;
+        args.pubdate = xml.findnodes('//*[@tag="260"]/*[@code="c"]').textContent;
+        args.mattype = xml.findnodes('//*[@tag="998"]/*[@code="d"]').textContent; # XXX this is KCLS-specific and will need to change
+
+        # clean up the ISBN
+        args.isbn_clean = args.isbn.replace('\ .*', '');
+    END;
+%]
diff --git a/Open-ILS/web/templates/default/opac-poc/myopac/_links.tt2 b/Open-ILS/web/templates/default/opac-poc/myopac/_links.tt2
new file mode 100644 (file)
index 0000000..b034198
--- /dev/null
@@ -0,0 +1,20 @@
+<div>[%
+pages = [
+    {url => "main", name => "My Account"},
+    {url => "circs", name => "Items Out"},
+    {url => "holds", name => "Items on Hold"},
+    {url => "fines", name => "Fines"},
+    {url => "prefs", name => "Account Preferences"},
+    {url => "bookbags", name => "My Bookbags"}
+];
+FOREACH page IN pages %]
+    <span style="margin: 0 0.5em;">
+    [% IF page.url != myopac_page %]<a href="[% page.url %]">[% END;
+        page.name;
+        IF page.url != myopac_page %]</a>
+    [% ELSE; ctx.page_title = page.name; END %]</span>
+[% END %]</div>
+<ul>
+    <li><a href="../home">Home</a></li>
+    <li><a href="../logout">Logout</a></li>
+</ul>
diff --git a/Open-ILS/web/templates/default/opac-poc/myopac/bookbags.tt2 b/Open-ILS/web/templates/default/opac-poc/myopac/bookbags.tt2
new file mode 100644 (file)
index 0000000..0ac2dc0
--- /dev/null
@@ -0,0 +1,52 @@
+[% BLOCK html_head %]
+<style>
+    table { width: 100%; text-align: center; padding: 20px; margin-top: 30px; }
+    table { border-collapse: collapse; }
+    table { padding: 3px; border-bottom: 1px solid #ddd; text-align: left;}
+    table tr:nth-child(odd) { background-color:#ded; }
+    #action_div { width: 95%; }
+    #action-buttons { float:right; }
+</style>
+[% END %]
+
+[% WRAPPER "default/opac/base.tt2" %]
+[% INCLUDE "default/opac/myopac/_links.tt2" myopac_page = "bookbags" %]
+
+[% IF ctx.bookbags.size == 0 %]
+<b>No Bookbags</b>
+[% STOP; END %]
+
+<form method='POST' id='bbag-form'>
+    <div id='action_div'>
+        <div id='action-buttons'>
+            <select name='action'>
+                <option value='delete'>Delete Selected</option>
+                <option value='delete_all'>Delete All</option>
+            </select>
+            <input type='submit' value='Go'/>
+        </div>
+    </div>
+    <table>
+        <thead>
+            <tr>
+                <th>Name</th>
+                <th>Public</th>
+                <th>Created On</th>
+                <th>Items</th>
+            </tr>
+        </thead>
+        <tbody>
+            [% FOR bbag IN ctx.bookbags %]
+                <tr [% IF loop.count % 2 == 1 %] class='bbag-table-odd' [% END %]>
+                    <td>[% bbag.name %]</td>
+                    <td>[% bbag.pub == 't' ? 'Yes' : 'No' %]</td>
+                    <td>[% date.format(ctx.parse_datetime(bbag.create_time),'%Y-%m-%d') %]</td>
+                    <td>XXX</td>
+                </tr>
+            [% END %]
+        </tbody>
+    </table>
+</form>
+
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/myopac/circs.tt2 b/Open-ILS/web/templates/default/opac-poc/myopac/circs.tt2
new file mode 100644 (file)
index 0000000..5f08d2e
--- /dev/null
@@ -0,0 +1,77 @@
+[% BLOCK html_head %]
+<style>
+    table { width: 100%; text-align: center; padding: 20px; margin-top: 30px; }
+    table { border-collapse: collapse; }
+    table { padding: 3px; border-bottom: 1px solid #ddd; text-align: left;}
+    #action_div { width: 95%; }
+    .renew-summary { float:left; padding-right: 10px;}
+    #action-buttons { float:right; }
+    .circ-table-odd { background-color:#ded; }
+    .failure-text { font-weight: bold; color: red; }
+    #circ-form { margin-top: 20px; }
+</style>
+[% END %]
+
+[% PROCESS "default/opac/common.tt2" %]
+[% WRAPPER "default/opac/base.tt2" %]
+[% INCLUDE "default/opac/myopac/_links.tt2" myopac_page = "circs" %]
+
+[% IF ctx.circs.size == 0 %]
+<b>No Items Checked Out</b>
+[% STOP; END %]
+
+<form method='POST' id='circ-form'>
+    <div id='action_div'>
+        [% IF ctx.success_renewals > 0 %]
+            <div class='renew-summary'><b>Successfully renewed [% ctx.success_renewals %] items.</b></div>
+        [% END %]
+        [% IF ctx.failed_renewals > 0 %]
+            <div class='renew-summary'><b>Failed to renew [% ctx.failed_renewals %] items.</b></div>
+        [% END %]
+        <div id='action-buttons'>
+            <button type='submit' value='renew' name='action'>Renew Selected</button>
+            <button type='submit' value='renew_all' name='action'>Renew All</button>
+        </div>
+    </div>
+    <table>
+        <thead>
+            <tr>
+                <th>Title</th>
+                <th>Author</th>
+                <th>Due Date</th>
+                <th>Renewals Remaining</th>
+                <th>Select</th>
+            </tr>
+        </thead>
+        <tbody>
+            [% FOR circ IN ctx.circs %]
+                [% attrs = {marc_xml => circ.marc_xml}; %]
+                [% PROCESS get_marc_attrs args=attrs; %]
+
+                <tr [% IF loop.count % 2 == 1 %] class='circ-table-odd' [% END %]>
+                    <td><a href='../record/[% circ.circ.target_copy.call_number.record.id %]'>[% attrs.title %]</a></td>
+                    <td><a href='../results?query=au:[% attrs.author | url %]'>[% attrs.author %]</a></td>
+                    <td>[% date.format(ctx.parse_datetime(circ.circ.due_date),'%Y-%m-%d') %]</td>
+                    <td><em>[% circ.circ.renewal_remaining %]</em></td>
+                    <td><input name='circ' value='[% circ.circ.id %]' type='checkbox' 
+                        [% IF circ.circ.renewal_remaining < 1 %] disabled='disabled' [% END %]/></td>
+                </tr>
+
+                [% IF circ.renewal_response and circ.renewal_response.textcode != 'SUCCESS' %]
+                <tr [% IF loop.count % 2 == 1 %] class='circ-table-odd' [% END %]>
+                    <td colspan='0'>
+                        <div class='failure-text'>
+                            [% circ.renewal_response.textcode %] 
+                            [% IF circ.renewal_response.payload.fail_part and circ.renewal_response.payload.fail_part != circ.renewal_response.textcode %]
+                                [% circ.renewal_response.payload.fail_part %]
+                            [% END %]
+                        </div>
+                    </td>
+                </tr>
+                [% END %]
+            [% END %]
+        </tbody>
+    </table>
+</form>
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/myopac/fines.tt2 b/Open-ILS/web/templates/default/opac-poc/myopac/fines.tt2
new file mode 100644 (file)
index 0000000..727322f
--- /dev/null
@@ -0,0 +1,107 @@
+[% BLOCK html_head %]
+<style>
+    table { width: 100%; text-align: center; padding: 20px; margin-top: 30px; }
+    table { border-collapse: collapse; }
+    table { padding: 3px; border-bottom: 1px solid #ddd; text-align: left;}
+    table tr:nth-child(odd) { background-color:#ded; }
+    h2 { margin-bottom: 0; }
+</style>
+[% END %]
+
+[% PROCESS "default/opac/common.tt2" %]
+[% WRAPPER "default/opac/base.tt2" %]
+[% INCLUDE "default/opac/myopac/_links.tt2" myopac_page = "fines" %]
+<h2>Summary</h2>
+<table>
+    <thead>
+        <tr>
+            <th>Total Owed</th>
+            <th>Total Paid</th>
+            <th>Balance Owed</th>
+        </tr>
+    </thead>
+    <tbody>
+        <tr>
+            <td>[% money(ctx.fines.total_owed) %]</td>
+            <td>[% money(ctx.fines.total_paid) %]</td>
+            <td>[% money(ctx.fines.balance_owed) %]</td>
+        </tr>
+    </tbody>
+</table>
+
+[% IF ctx.fines.circulation.size > 0 %]
+<h2>Overdue materials</h2>
+<table>
+    <thead>
+        <tr>
+            <th>Title</th>
+            <th>Author</th>
+            <th>Checkout Date</th>
+            <th>Due Date</th>
+            <th>Date Returned</th>
+            <th>Balance Owed</th>
+        </tr>
+    </thead>
+    <tbody>
+    [% FOR f IN ctx.fines.circulation %]
+        [% attrs = {marc_xml => f.marc_xml}; %]
+        [% PROCESS get_marc_attrs args=attrs; %]
+        <tr>
+            <td>[% attrs.title %]</td>
+            <td>[% attrs.author %]</td>
+            <td>[% date.format(
+                ctx.parse_datetime(f.xact.circulation.xact_start), "%Y-%m-%d"
+            ) %]</td>
+            <td>[% date.format(
+                ctx.parse_datetime(f.xact.circulation.due_date), "%Y-%m-%d"
+            ) %]</td>
+            <td>[%
+                IF f.xact.circulation.checkin_time;
+                    date.format(
+                        ctx.parse_datetime(f.xact.circulation.checkin_time),
+                        "%Y-%m-%d"
+                    );
+                END %]</td><!-- XXX TODO display stop_fines_time if set? Display something instead of blank like "fines accruing" ? -->
+            <td>[% money(f.xact.balance_owed) %]</td>
+        </tr>
+    [% END %]
+    </tbody>
+</table>
+[% END %]
+
+[% IF ctx.fines.grocery.size > 0 %]
+<h2>Other Fees</h2>
+<table>
+    <thead>
+        <tr>
+            <th>Transaction Start Time</th>
+            <th>Last Payment Time</th>
+            <th>Initial Amount Owed</th>
+            <th>Total Amount Paid</th>
+            <th>Balance Owed</th>
+            <th>Billing Type</th>
+        </tr>
+    </thead>
+    <tbody>
+    [% FOR f IN ctx.fines.grocery %]
+        <tr>
+            <td>[%
+                date.format(
+                    ctx.parse_datetime(f.xact.xact_start), "%Y-%m-%d"
+                ) %]</td>
+            <td>[% IF f.xact.last_payment_ts;
+                    date.format(
+                        ctx.parse_datetime(f.xact.last_payment_ts), "%Y-%m-%d"
+                        );
+                    END %]</td>
+            <td>[% money(f.xact.total_owed) %]</td>
+            <td>[% money(f.xact.total_paid) %]</td>
+            <td>[% money(f.xact.balance_owed) %]</td>
+            <td>[% f.xact.last_billing_type %]</td>
+        </tr>
+    [% END %]
+    </tbody>
+</table>
+[% END %]
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/myopac/holds.tt2 b/Open-ILS/web/templates/default/opac-poc/myopac/holds.tt2
new file mode 100644 (file)
index 0000000..ce09725
--- /dev/null
@@ -0,0 +1,94 @@
+[% BLOCK html_head %]
+<style>
+    table { width: 100%; text-align: center; padding: 20px; margin-top: 30px; }
+    table { border-collapse: collapse; }
+    table { padding: 3px; border-bottom: 1px solid #ddd; text-align: left;}
+    table tr:nth-child(odd) { background-color:#ded; }
+    #action_div { width: 95%; }
+    #action-buttons { float:right; }
+</style>
+[% END %]
+
+[%  PROCESS "default/opac/common.tt2";
+    WRAPPER "default/opac/base.tt2";
+    INCLUDE "default/opac/myopac/_links.tt2" myopac_page = "holds" %]
+
+[% IF ctx.holds.size == 0 %]
+<b>No Items On Hold</b>
+[% STOP; END %]
+
+<form method='POST'>
+
+    <div id='action_div'>
+        <div id='action-buttons'>
+            <select name='action'>
+                <option value='cancel'>Cancel Selected</option>
+                <option value='cancel_all'>Cancel All</option>
+                <option value='suspend'>Suspend Selected</option>
+                <option value='suspend_all'>Suspend All</option>
+                <option value='activate'>Activate Selected</option>
+                <option value='activate_all'>Activate All</option>
+            </select>
+            <input type='Submit' value='Go'/>
+        </div>
+    </div>
+    <table>
+        <thead>
+            <tr>
+                <th>Title</th>
+                <th>Author</th>
+                <th>Formats</th>
+                <th>Pickup Location</th>
+                <th>Status</th>
+                <th>Active</th>
+                <th>Activate on...</th>
+                <th>Expiration Date</th>
+                <th>Select</th>
+            </tr>
+        </thead>
+        <tbody>
+            [% FOR hold IN ctx.holds %]
+                [% attrs = {marc_xml => hold.marc_xml}; %]
+                [% PROCESS get_marc_attrs args=attrs; %]
+            <tr>
+                <td><a href='../record/[% hold.hold.bre.id %]'>[% attrs.title %]</a></td>
+                <td><a href='../results?query=au:[% attrs.author | url %]'>[% attrs.author %]</a></td>
+                <td>
+                    [%
+                        key = attrs.mattype;
+                        format_desc = ctx.find_citm(key).value;
+                        icon_filename = icon_by_mattype.$key;
+                        IF icon_filename;
+                    %]<!-- XXX in situations where we might show M-type holds, this won't be good enough -->
+                    <img alt="[% format_desc %]" title="[% format_desc %]"
+                        src="/images/mattype/[% icon_filename %]" />
+                    [%  END %]
+                </td>
+                <td>[% ctx.find_aou(hold.hold.hold.pickup_lib).name %]</td>
+                <td>[%
+                    IF hold.hold.status == 4;
+                        "Available";
+                    ELSIF hold.hold.estimated_wait;
+                        "Estimated wait (days): "; hold.hold.estimated_wait;
+                    ELSIF hold.hold.status == 3;
+                        "In Transit";
+                    ELSIF hold.hold.status < 3;
+                        "Waiting for copy";
+                    END;
+                %]</td>
+                <td>[% IF hold.hold.hold.frozen == 't' %] No [% ELSE %] Yes [% END %]</td>
+                <td>[% 
+                    IF hold.hold.hold.frozen == 't' AND hold.hold.hold.thaw_date;
+                        date.format(ctx.parse_datetime(hold.hold.hold.thaw_date),'%Y-%m-%d'); 
+                    ELSE;
+                        '-';
+                    END 
+                %]</td>
+                <td>[% hold.hold.hold.expire_time ? hold.hold.hold.expire_time : '-' %]</td>
+                <td><input type='checkbox' name='hold_id' value='[% hold.hold.hold.id %]'/></td>
+            </tr>
+            [% END %]
+        </tbody>
+    </table>
+</form> 
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/myopac/main.tt2 b/Open-ILS/web/templates/default/opac-poc/myopac/main.tt2
new file mode 100644 (file)
index 0000000..33a533e
--- /dev/null
@@ -0,0 +1,39 @@
+[% BLOCK html_head %]
+<style>
+    table { text-align: center; padding: 20px; margin-top: 30px; border-collapse: collapse; }
+    table td { padding: 5px 15px 5px 15px; border-bottom: 1px solid #ddd; text-align: left;}
+    table tr:nth-child(odd) { background-color:#ded; }
+</style>
+[% END %]
+
+[% WRAPPER "default/opac/base.tt2" %]
+[% INCLUDE "default/opac/myopac/_links.tt2" myopac_page = "main" %]
+<table>
+    <tr>
+        <td>First Name</td>
+        <td>[% ctx.user.first_given_name %]</td>
+    </tr>
+    <tr>
+        <td>Middle Name</td>
+        <td>[% ctx.user.second_given_name %]</td>
+    </tr>
+    <tr>
+        <td>Last Name</td>
+        <td>[% ctx.user.family_name %]</td>
+    </tr>
+    <tr>
+        <td>Library Card</td>
+        <td>[% ctx.user.card.barcode %]</td>
+    </tr>
+    <tr>
+        <td>Email Address</td>
+        <td>[% ctx.user.email %]</td>
+        <td><a href='update_email'>Change</a></td>
+    </tr>
+    <tr>
+        <td>Phone</td>
+        <td>[% ctx.user.day_phone %]</td>
+    </tr>
+</table>
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/myopac/prefs.tt2 b/Open-ILS/web/templates/default/opac-poc/myopac/prefs.tt2
new file mode 100644 (file)
index 0000000..d9a60ba
--- /dev/null
@@ -0,0 +1,15 @@
+[% BLOCK html_head %]
+<style>
+    table { width: 100%; text-align: center; padding: 20px; margin-top: 30px; }
+    table { border-collapse: collapse; }
+    table { padding: 3px; border-bottom: 1px solid #ddd; text-align: left;}
+    table tr:nth-child(odd) { background-color:#ded; }
+</style>
+[% END %]
+
+[% WRAPPER "default/opac/base.tt2" %]
+[% INCLUDE "default/opac/myopac/_links.tt2" myopac_page = "prefs" %]
+<p><em>XXX TODO Need to find out whether the list of pref fields can/should be generated
+    from db entries or something.</em></p>
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/myopac/update_email.tt2 b/Open-ILS/web/templates/default/opac-poc/myopac/update_email.tt2
new file mode 100644 (file)
index 0000000..7666c8f
--- /dev/null
@@ -0,0 +1,20 @@
+[% BLOCK html_head %]
+<style>
+    table { text-align: center; padding: 20px; margin-top: 30px; border-collapse: collapse; }
+    table td { padding: 5px 15px 5px 15px; border-bottom: 1px solid #ddd; text-align: left;}
+    table tr:nth-child(odd) { background-color:#ded; }
+</style>
+[% END %]
+
+[% WRAPPER "default/opac/base.tt2" %]
+[% INCLUDE "default/opac/myopac/_links.tt2" %]
+
+<form method='POST'>
+    <table> 
+        <tr><td>Current Email</td><td>[% ctx.user.email %]</td></tr>
+        <tr><td>New Email</td><td><input type='text' name='email'/></td></tr>
+    </table>
+    <input type='submit'/>
+</form>
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/place_hold.tt2 b/Open-ILS/web/templates/default/opac-poc/place_hold.tt2
new file mode 100644 (file)
index 0000000..bfbee07
--- /dev/null
@@ -0,0 +1,33 @@
+[% BLOCK html_head %]
+<style>
+</style>
+[% END %]
+
+[% 
+    USE CGI;
+    PROCESS "default/opac/common.tt2";
+    WRAPPER "default/opac/base.tt2"; 
+    ctx.page_title = "Place Hold";
+    attrs = {marc_xml => ctx.marc_xml};
+    PROCESS get_marc_attrs args=attrs;
+%]
+
+
+<div>
+    <div>Placing hold on [% attrs.title %], by [% attrs.author %]</div>
+    [% IF ctx.hold_success %] 
+        <div>Succeeded</div>
+    [% ELSIF ctx.hold_failed %]
+        <div>Failed...</div>
+    [% ELSE %]
+    <form action='place_hold' method='POST'>
+        Choose a pickup Library [% PROCESS build_org_selector name='pickup_lib' value=ctx.default_pickup_lib %]
+        <input type='Submit'/>
+        <input type='hidden' name='hold_target' value='[% CGI.param('hold_target') | html %]'/>
+        <input type='hidden' name='hold_type' value='[% CGI.param('hold_type') | html %]'/>
+        <input type='hidden' name='redirect_to' value='[% ctx.referer | html %]'/>
+    </form>
+    [% END %]
+</div>
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/record.tt2 b/Open-ILS/web/templates/default/opac-poc/record.tt2
new file mode 100644 (file)
index 0000000..24f1203
--- /dev/null
@@ -0,0 +1,82 @@
+[% BLOCK html_head %]
+<style>
+    table { width: 100%; padding: 20px; margin-top: 30px; }
+    table { border-collapse: collapse; }
+    table td { padding: 3px; border-bottom: 1px solid #ddd; text-align: left;}
+    table th { padding: 3px; border-bottom: 1px solid #ddd; text-align: left;}
+    table tr:nth-child(even) { background-color:#ded; }
+    #record_table td { padding-left: 15px; padding-right: 15px; }
+</style>
+[% END %]
+
+[% 
+    WRAPPER "default/opac/base.tt2"; 
+    PROCESS "default/opac/common.tt2";
+    ctx.page_title = "Details";
+    record = ctx.record;
+    attrs = {marc_xml => ctx.marc_xml};
+    PROCESS get_marc_attrs args=attrs;
+%]
+
+<div id='detail_div'>
+    <table id='record_table' style='width:auto'>
+        <tr>
+            <td rowspan='10' style='width:55px; vertical-align:top; padding-right:4px;'>
+                [% IF attrs.isbn_clean || attrs.upc %]
+                <img width='50' height='70' src='[% ctx.media_prefix %]/opac/extras/ac/jacket/small/[% attrs.isbn_clean || attrs.upc %]'/>
+                [% END %]
+            </td>
+        </tr>
+        [% IF attrs.title %]<tr><td>Title</td><td>[% attrs.title %]</td></tr>[% END %]
+        [% IF attrs.author %]<tr><td>Author</td><td><a href='../results?query=au:[% attrs.author | uri %]'>[% attrs.author %]</a></td></tr>[% END %]
+        [% IF attrs.isbn %]<tr><td>ISBN</td><td>[% attrs.isbn %]</td></tr>[% END %]
+        [% IF attrs.issn %]<tr><td>ISSN</td><td>[% attrs.issn %]</td></tr>[% END %]
+        [% IF attrs.upc %]<tr><td>UPC</td><td>[% attrs.upc %]</td></tr>[% END %]
+        [% IF attrs.pubdate %]<tr><td>Publication Date</td><td>[% attrs.pubdate %]</td></tr>[% END %]
+        [% IF attrs.publisher %]<tr><td>Publishere</td><td>[% attrs.publisher %]</td></tr>[% END %]
+        <tr>
+            <td>Subjects</td>
+            <td>
+            [% FOR node IN ctx.marc_xml.findnodes('//*[@tag="650"]') %]
+                [% 
+                    s0 = node.childNodes.0.textContent;
+                    s1 = node.childNodes.1.textContent;
+                %]
+                [% IF s0 %]
+                    <a href='../results?query=su:[% s0 | url %]'>[% s0 %]</a>
+                    [% IF s1 %]
+                    <span>--</span>
+                    <a href='../results?query=su:[% s1 | url %]'>[% s1 %]</a>
+                    [% END %]
+                    <br/>
+                [% END %]
+            [% END %]
+            </td>
+        </tr>
+    </table>
+    <table id='copy_table'>
+        <thead>
+            <tr>
+                <th>Owning Lib</th>
+                <th>Call Number</th>
+                <th>Barcode</th>
+                <th>Status</th>
+            </tr>
+        </thead>
+        <tbody>
+        [% FOR acn IN record.call_numbers %]
+            [% FOR acp IN acn.copies %]
+                <tr>
+                    <td>[% ctx.find_aou(acn.owning_lib).shortname %]</td>
+                    <td>[% acn.label %]</td>
+                    <td>[% acp.barcode %]</td>
+                    <td>[% ctx.find_ccs(acp.status).name %]</td>
+                </tr>
+            [% END %]
+        [% END %]
+        </tbody>
+    </table>
+</div>
+
+
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac-poc/results.tt2 b/Open-ILS/web/templates/default/opac-poc/results.tt2
new file mode 100644 (file)
index 0000000..9ecead4
--- /dev/null
@@ -0,0 +1,117 @@
+[% BLOCK html_head %]
+<style>
+    #body_table { width: 100%; margin-top: 20px; }
+    #left_block { width: 15%; vertical-align: top; }
+    #right_block { width: auto; vertical-align: top;}
+    #record_table { border-collapse: collapse; width:100%; }
+    #record_table td { padding: 3px; border-bottom: 1px solid #ddd; }
+    #record_table tr:nth-child(odd) { background-color:#ded; }
+    .record-table-odd { background-color:#ded; }
+    #form_div { text-align: center; width: 100%; margin-top: 10px;}
+    #links_div { margin-bottom: 10px; padding: 5px;}
+</style>
+[% END %]
+
+[% 
+    USE CGI;
+    USE POSIX;
+    WRAPPER "default/opac/base.tt2"; 
+    PROCESS "default/opac/common.tt2";
+    ctx.page_title = "Results";
+    page = CGI.param('page') || 0; 
+    query = CGI.param('query');
+    page_count = POSIX.ceil(ctx.hit_count / ctx.page_size);
+    loc = CGI.param('loc');
+%]
+
+<div id='form_div'>
+    <form action='./results' method='GET'>
+        <input type='text' name='query' size='50' value='[% query %]'/>
+        [% PROCESS build_org_selector name='loc' value=loc %]
+        <input type='submit'/>
+        <input type='hidden' name='page' value='0'/>
+    </form>
+</div>
+
+<table id='body_table'>
+    <tr>
+        <td id='left_block'>
+                [% IF ctx.user; %]
+                    <div id='links_div'>
+                        <div><a href='home'>Home</a></div>
+                        <div><a href='myopac/main'>Account</a></div>
+                        <div><a href='logout'>Logout</a></div>
+                    </div>
+                    <hr/>
+                    <table>
+                        <tr><td colspan='2' style='border-bottom:1px solid #9A9'>Signed in as [% ctx.user.usrname %]</td></tr>
+                        <tr><td>Total Holds</td><td>[% ctx.user_stats.holds.total %]</td></tr>
+                        <tr><td>Ready Holds</td><td>[% ctx.user_stats.holds.ready %]</td></tr>
+                        <tr><td>Items Out</td><td>[% ctx.user_stats.checkouts.out %]</td></tr>
+                        <tr><td>Fines</td><td>$[% ctx.user_stats.fines.balance_owed %]</td></tr>
+                    </table>
+                [% ELSE %]
+                    [% 
+                        login = CGI.url("-path" => 1).replace('^http:', 'https:').replace('/results','/login');
+                    %]
+                    <a href='[% login %]'>Login</a>
+                [% END %]
+            </div>
+            <div>
+                [% FOR facet_type IN ctx.search_facets.keys %]
+                    [% cmf = ctx.search_facets.$facet_type.cmf %]
+                    <b>[% cmf.label %]</b>
+                    <ul>
+                        [% FOR facet IN ctx.search_facets.$facet_type.data.keys %]
+                            [% facet_count = ctx.search_facets.$facet_type.data.$facet %]
+                            <li><a href='results?query=[% query | url %]&facet=[% cmf.field_class %]|[% cmf.name %][[% facet | url %]]'>[% facet_count %] / [% facet %]</a></li>
+                        [% END %]
+                    </ul>
+                [% END %]
+            </div>
+        </td>
+        <td id='right_block'>
+            <div>
+                <span>[% l('Hits: [_1] / Page [_2] of [_3]', ctx.hit_count, page + 1, page_count) %]</span>
+                [% 
+                    q = query | url;
+                    np_link = '?query=' _ q;
+                    IF loc; np_link = np_link _ "&loc=" _ loc; END;
+                    IF depth or depth == 0; np_link = np_link _ "&depth=" _ depth; END;
+                %]
+                <a [% IF page > 0 %] href='[% np_link %]&page=[% page - 1 %]' [% END %]>Prev</a>  
+                <a [% IF (page + 1) < page_count %] href='[% np_link %]&page=[% page + 1 %]' [% END %]>Next</a>
+            </div>
+            <table id='record_table'>
+                [%
+                FOR rec IN ctx.records;
+                    attrs = {marc_xml => rec.marc_xml};
+                    PROCESS get_marc_attrs args=attrs;
+                %]
+                <tr [% IF loop.count % 2 == 1 %] class='record-table-odd' [% END %]>
+                    <td style='width:52px;height:72px'>
+                        [% IF attrs.isbn %]
+                        <img width='50' height='70' src='[% ctx.media_prefix %]/opac/extras/ac/jacket/small/[% attrs.isbn_clean || attrs.upc %]'/>
+                        [% END %]
+                    </td>
+                    <td width='auto'>
+                        <div width='99%'>
+                            <div style='float:left'>
+                                <a href='record/[% rec.bre.id %]'>[% attrs.title %]</a>
+                            </div>
+                            <div style='float:right'>
+                                <span>[% rec.copy_counts.available %] / [% rec.copy_counts.visible %]</span>
+                                <span style='padding-left:10px;'><a href='place_hold?hold_target=[% rec.bre.id %]&hold_type=T'>Hold</a></span>
+                            </div>
+                        </div><br/>
+                        <div>[% attrs.author %]</div>
+                        <div>[% attrs.isbn || attrs.issn || attrs.upc %] [% attrs.publisher %] [% attrs.pubdate %]</div>
+                    </td>
+                </tr>
+                [% END %]
+            </table>
+        </td>
+    </tr>
+
+</table>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/advanced.tt2 b/Open-ILS/web/templates/default/opac/advanced.tt2
new file mode 100644 (file)
index 0000000..adb1807
--- /dev/null
@@ -0,0 +1,23 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    WRAPPER "default/opac/parts/base.tt2";
+    INCLUDE "default/opac/parts/topnav.tt2";
+    ctx.page_title = l("Advanced Search") %]
+    <div id="search-wrapper">
+        [% INCLUDE "default/opac/parts/utils.tt2" %]
+        <div id="adv_search_parent">
+            <div id="adv_search_tabs">
+                <a href="#" alt="[% l('Advanced Search') %]" id="adv_search"></a>
+                <a href="#" alt="[% l('Numeric Search') %]" id="num_search"></a>
+                <a href="#" alt="[% l('Expert Search') %]" id="expert_search"></a>
+            </div>
+        </div>
+    </div>
+    <div id="content-wrapper">
+        <div id="main-content">
+            <div class="advanced_div">
+            [% INCLUDE "default/opac/parts/advanced/search.tt2" %]
+            </div>
+            <div class="common-full-pad"></div>        
+        </div>
+    </div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/home.tt2 b/Open-ILS/web/templates/default/opac/home.tt2
new file mode 100644 (file)
index 0000000..3436a46
--- /dev/null
@@ -0,0 +1,16 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    WRAPPER "default/opac/parts/base.tt2";
+    INCLUDE "default/opac/parts/topnav.tt2";
+    ctx.page_title = l("Home") %]
+    <div id="search-wrapper">
+        [% INCLUDE "default/opac/parts/utils.tt2" %]
+        [% INCLUDE "default/opac/parts/searchbar.tt2" %]
+    </div>
+    <div id="content-wrapper">
+        <div id="main-content-home">
+            <div class="common-full-pad"></div>
+            [% INCLUDE "default/opac/parts/homesearch.tt2" %]
+            <div class="common-full-pad"></div>        
+        </div>
+    </div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/login.tt2 b/Open-ILS/web/templates/default/opac/login.tt2
new file mode 100644 (file)
index 0000000..675a40d
--- /dev/null
@@ -0,0 +1,27 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    WRAPPER "default/opac/parts/base.tt2";
+    INCLUDE "default/opac/parts/topnav.tt2";
+    ctx.page_title = l("Account Login") %]
+    <div id="search-wrapper">
+        [% INCLUDE "default/opac/parts/utils.tt2" %]
+        [% INCLUDE "default/opac/parts/searchbar.tt2" %]
+    </div>
+    <div id="content-wrapper">
+        <div id="main-content">
+            [% INCLUDE "default/opac/parts/login/form.tt2" %]
+            <div class="clear-both very-big-height"></div>     
+            <script type="text/javascript">
+                /* Note: when common browsers suppor HTML5 "autofocus", we can remove this */
+                var _onload = window.onload;
+                window.onload = function() {
+                    try {
+                        document.getElementById("username_field").focus();
+                        if (_onload) _onload();
+                    } catch (E) {
+                        void(0);
+                    }
+                };
+            </script>
+        </div>
+    </div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/myopac/circs.tt2 b/Open-ILS/web/templates/default/opac/myopac/circs.tt2
new file mode 100644 (file)
index 0000000..d5602be
--- /dev/null
@@ -0,0 +1,217 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    PROCESS "default/opac/parts/marc_misc.tt2";
+    WRAPPER "default/opac/parts/base.tt2" +
+        "default/opac/parts/myopac/base.tt2";
+    myopac_page = "circs"  %]
+<div id='myopac_checked_div' style="padding:0px;">
+    <div id="acct_checked_tabs" style="padding-bottom: 12px;color:#666;" class="hide_me">
+        <div class="align selected" id="checked_label">
+            <img src="[% ctx.media_prefix %]/images/sub_checked_out_on.jpg" />
+        </div>
+        <div class="align" id="checked_hist_link">
+            <a class="" href="#"><img
+                src="[% ctx.media_prefix %]/images/sub_checked_hist_off.jpg" /></a>
+        </div>
+        <div class="align hide_me" id="checked_link">
+            <a href="#">
+                <img src="[% ctx.media_prefix %]/images/sub_checked_out_off.jpg" />
+            </a>
+        </div>
+        <div class="align selected hide_me" id="checked_hist_label">
+            <img src="[% ctx.media_prefix %]/images/sub_checked_hist_on.jpg" />
+        </div>    
+        <div class="clear-both"></div>
+    </div>
+    
+    <div class="header_middle">
+        <span class="float-left">[% l('Current Items Checked Out') %]</span>
+        <span class="float-right">
+            <a class="hide_me" href="#">[% l('Export List') %]</a>
+        </span>
+    </div>
+    <div class="clear-both"></div>
+    [% IF ctx.circs.size < 1 %]
+    <div class="opac-auto-079">
+        <big><strong>[% l('You have no items checked out.') %]</strong></big>
+    </div>
+    [% ELSE %]
+    [% IF ctx.success_renewals %]
+    <div class="renew-summary">
+        [% l("Successfully renewed [_1] item(s)", ctx.success_renewals) %]
+    </div>
+    [% END %]
+    [% IF ctx.failed_renewals %]
+    <div class="renew-summary red">
+        [% l("Failed to renew [_1] item(s)", ctx.failed_renewals) %]
+    </div>
+    [% END %]
+    <div id='checked_main'>
+        <form method="POST" id="circ-form"
+            onsubmit="return confirm('[% l("Are you sure you wish to renew the selected item(s)?") %]');">
+        <table cellpadding='0' cellspacing='0' class="opac-auto-097b">
+            <tr>
+                <td>
+                    <select name="action">
+                        <option value="renew">[% l('Renew Selected Titles') %]</option>
+                    </select>
+                </td>
+                <td style="padding-left:9px;">
+                    <input type="image"
+                        alt="[% l('Go') %]" title="[% l('Go') %]"
+                        src="[% ctx.media_prefix %]/images/go-btn.png" /></a>
+                </td>
+                <td style="padding-left:5px;">
+                    <a href="#"><img alt="Renewing Help"
+                        src="[% ctx.media_prefix %]/images/question-mark.png" /></a>
+                </td>
+            </tr>
+        </table>
+        <table id="acct_checked_main_header" cellpadding='0' cellspacing='0'
+            border='0'>
+            <tr>
+                <td width="1%" style="padding-left:10px;">
+                    <input type="checkbox" id="check_all_checked"
+                        onclick="var inputs=document.getElementsByTagName('input'); for (i = 0; i < inputs.length; i++) { if (inputs[i].name == 'circ' && !inputs[i].disabled) inputs[i].checked = this.checked;}"
+                    />
+                </td>
+                <td width="40%" style="padding-left:5px;">
+                    <span title="Click to sort" class='pointer'>
+                        Title
+                    </span> /
+                    <span title="Click to sort" class='pointer'>
+                        Author
+                    </span>
+                </td>
+                <td width="8%" style="padding-right:5px;" align="center">
+                    <span title="Click to sort" class='pointer'>Renews<br />Left
+                    </span>
+                </td>
+                <td width="13%" style="padding-left:5px;">
+                    <span title="Click to sort" class='pointer'>Due Date</span>
+                </td>
+                <td width="16%">
+                    <span title="Click to sort" class='pointer'>barcode</span>
+                </td>
+                <td width="22%">
+                    <span title="Click to sort" class='pointer'>call number</span>
+                </td>
+            </tr>
+        </table>
+   
+        <div id="checked_temp_parent">
+            <div id="acct_checked_temp">
+                <table cellpadding='0' cellspacing='0' border='0'
+                    style="margin-top:5px;">
+                    [% FOR circ IN ctx.circs;
+                        attrs = {marc_xml => circ.marc_xml};
+                        PROCESS get_marc_attrs args=attrs; %]
+                    <tr>
+                        <td width="1%" style="padding-left:10px;" valign="top">
+                            <input type="checkbox" name="circ"
+                                [% IF circ.circ.renewal_remaining < 1; l('disabled="disabled"'); END %]
+                                value="[% circ.circ.id %]" />
+                        </td>
+                        <td width="40%"
+                            style="padding-left:5px;padding-bottom:10px;"
+                            name="author">
+                            <a href="[% ctx.opac_root %]/record/[% circ.circ.target_copy.call_number.record.id %]" name="[% l('Catalog record') %]">[% attrs.title %]</a>
+                            [% IF attrs.author %] /
+                            <a href="[% ctx.opac_root %]/results?query=au:[% attrs.author | replace('[,\.:;]', '') | url %]">[% attrs.author %]</a>
+                            [% END %]
+                        </td>
+                        <td width="8%" name="renewals" align="center">
+                            [% circ.circ.renewal_remaining %]
+                        </td>
+                        <td width="13%" style="padding-left:5px;"
+                            name="due_date">
+                            [% date.format(ctx.parse_datetime(circ.circ.due_date),DATE_FORMAT) %]
+                        </td>
+                        <td width="16%" name="barcode">
+                            [% circ.circ.target_copy.barcode %]
+                        </td>
+                        <td width="22%" name="call_number">
+                            [% circ.circ.target_copy.call_number.label %]
+                        </td>
+                    </tr>
+                    [%  IF circ.renewal_response AND
+                            circ.renewal_response.textcode != 'SUCCESS' %]
+                    <tr>
+                        <td colspan="6">[%# XXX colspan="0" does not work in IE %]
+                            <span class="failure-text" title="[% circ.renewal_response.textcode %] / [% circ.renewal_response.payload.fail_part %]">
+                                [% circ.renewal_response.desc || circ.renewal_response.payload.fail_part || circ.renewal_response.textcode %]
+                            </span>
+                        </td>
+                    </tr>
+                    [%  END;
+                    END %]
+                </table>
+            </div>
+        </div>
+        </form>
+    </div>
+    [% END %]
+    <div id='checked_hist' class="hide_me" style="padding-top:8px;">
+        <table id="acct_checked_hist_header" cellpadding='0' cellspacing='0'
+            border='0' width='100%'>
+            <tr>
+                <td width="45%" style="padding-left:15px;">
+                    <span title="Click to sort" class='pointer'>Title</span> /
+                    <span title="Click to sort" class='pointer'>Author</span>
+                </td>
+                <td width="22%"
+                    style="white-space:nowrap;padding-left:5px;">
+                    <span title="Click to sort" class='pointer'>Call Number</span>
+                </td>
+                <td width="11%">
+                    <span title="Click to sort" class='pointer'>Checkout</span>
+                </td>
+                <td width="11%">
+                    <span title="Click to sort" class='pointer'>Due Date</span>
+                </td>
+                <td width="11%">
+                    <span title="Click to sort" class='pointer'>Returned</span>
+                </td>
+            </tr>
+        </table>
+        <table cellpadding='0' cellspacing='0' border='0'
+            style="margin-top:5px;" width="100%">
+            <tbody id="acct_checked_hist_parent">
+                <tr id="acct_checked_hist_temp">
+                    <td width="45%"
+                        style="padding-left:15px;padding-bottom:10px;">
+                        <a href="#" name="title"></a> /
+                        <span name="author"></span>
+                    </td>
+                    <td width="22%" style="padding-left:5px;"
+                        name="call_number"></td>
+                    <td width="11%" name="checkout"></td>
+                    <td width="11%" name="due_date"></td>
+                    <td width="11%" name="returned"
+                        nowrap="nowrap" style="white-space:nowrap;"></td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+    <div id='non_cat_circs_div' class='hide_me'>
+        <br/>
+        <div style='text-align: center'><b>[% l("Other Circulations") %]</b></div>
+        <table class='data_grid' width='100%'>
+            <thead>
+                <tr>
+                    <td>[% l("Circulating Library") %]</td>
+                    <td>[% l("Circulation Type") %]</td>
+                    <td>[% l("Please return by ...") %]</td>
+                </tr>
+            </thead>
+            <tbody id='non_cat_circs_tbody'>
+                <tr id='non_cat_circs_row'>
+                    <td name='circ_lib'/>
+                    <td name='item_type'/>
+                    <td name='circ_time'/>
+                </tr>
+            </tbody>
+        </table>
+    <span class='hide_me' id='myopac_renew_fail'>[% l("The system is unable to renew the selected item at this time.  This usually means the item is needed to fulfill a hold.  Please see a librarian for further help.") %]</span>
+   <span class='hide_me' id='myopac_renew_fail2'>[% l("Library policy prevents the renewal of this item at this time.  Please see a librarian for further details.") %]</span>
+</div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/myopac/holds.tt2 b/Open-ILS/web/templates/default/opac/myopac/holds.tt2
new file mode 100644 (file)
index 0000000..8babf82
--- /dev/null
@@ -0,0 +1,250 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    PROCESS "default/opac/parts/marc_misc.tt2";
+    WRAPPER "default/opac/parts/base.tt2" +
+        "default/opac/parts/myopac/base.tt2";
+    myopac_page = "holds"  %]
+<div id='myopac_holds_div'>
+    <div id="acct_holds_tabs" style="padding-bottom: 12px;color:#666;" class="hide_me">
+        <div class="align selected" id="holds_label">
+            <img src="[% ctx.media_prefix %]/images/sub_holds_on.jpg" />
+        </div>
+        <div class="align hide_me" id="holds_hist_link">
+            <a href="#"><img
+                src="[% ctx.media_prefix %]/images/sub_holds_hist_off.jpg" /></a>
+        </div>
+        <div class="align hide_me" id="holds_link">
+            <a href="#"><img
+                src="[% ctx.media_prefix %]/images/sub_holds_off.jpg" /></a>
+        </div>
+        <div class="align selected hide_me" id="holds_hist_label">
+            <img src="[% ctx.media_prefix %]/images/sub_holds_hist_on.jpg" />
+        </div> 
+        <div class="clear-both"></div>
+    </div>
+    <div class="header_middle">
+        <span id="acct_holds_header" style="float:left;">
+            [%  IF CGI.param("available");
+                    l("Items Ready for Pickup");
+                ELSE;
+                    l("Current Items on Hold");
+                END
+            %]
+        </span>
+        <span style="float:right;">
+            <a class="hide_me" href="#">Export List</a>
+        </span>
+    </div>
+    <div class="clear-both"></div>
+    <div id='holds_main'>
+        <form method="POST">
+        <table cellpadding='0' cellspacing='0' class="opac-auto-097">
+            <tr>
+                <td width="1">
+                    <select name="action" id="acct_holds_actions">
+                        <option id='myopac_holds_actions_none' value=''>
+                        -- [% l("Actions for selected holds") %] --
+                        </option>
+                        <option value='suspend'>
+                            [% l("Suspend") %]
+                        </option>
+                        <option value='activate'>
+                            [% l("Activate") %]
+                        </option>
+                        <!-- XXX maybe later <option value='thaw_date'>
+                            [% l("Set Active Date") %]
+                        </option> -->
+                        <option value='cancel'>
+                            [% l("Cancel") %]
+                        </option>
+                    </select>
+                </td>
+                <td width="1" style="padding-left:9px;">
+                    <input type="image"
+                        alt="[% l('Go') %]" title="[% l('Go') %]"
+                        src="[% ctx.media_prefix %]/images/go-btn.png" />
+                </td>
+                <td width="1" style="padding-left:5px;">
+                    <a href="#"><img
+                        alt="Holds Help"
+                        src="[% ctx.media_prefix %]/images/question-mark.png" /></a>
+                </td>
+                <td align="right">
+                    [% l("Show") %] &nbsp; &nbsp;
+                    [% IF CGI.param("available") %]
+                    <a href="holds">[% l('all') %]</a> |
+                    <strong>[% l("only available") %]</strong>
+                    [% ELSE %]
+                    <strong>[% l("all") %]</strong> |
+                    <a href="holds?available=1">[% l("only available") %]</a>
+                    [% END %] &nbsp; &nbsp;
+                    [% l("holds") %]
+                    <select class="hide_me" id="holds_sort">
+                        <option value="">-- Sort By --</option>
+                        <option value="title">Title</option>
+                        <option value="pickup">PickUp Location</option>
+                        <option value="status">Status</option>
+                    </select>
+                </td>
+            </tr>
+        </table>
+        [% IF ctx.holds.size < 1 %]
+        <div class="opac-auto-079">
+            <big><strong>[% l('No holds found.') %]</strong></big>
+        </div>
+        [% ELSE %]
+        <table id="acct_holds_main_header" cellpadding='0' cellspacing='0'
+            border='0' width="100%">
+            <tr>
+                <td width="36" align="center">
+                    <input type="checkbox" id="check_all_holds" />
+                </td>
+                <td width="138">
+                    <span title="Click to sort"
+                        style="cursor:pointer;">
+                        Title
+                    </span>
+                </td>
+                <td width="123">
+                    <span title="Click to sort" style="cursor:pointer;">Author</span>
+                </td>
+                <td width="64">
+                    <span title="Click to sort"
+                        style="cursor:pointer;">Format</span>
+                </td>
+                <td width="136">
+                    <span title="Click to sort"
+                        style="cursor:pointer;">Pickup Location</span>
+                </td>
+                <td width="104">Activate</td>
+                <td width="106">Cancel if not<br />filled by</td>
+                <td width="95">Active</td>
+                <td width="172">
+                    <span title="Click to sort"
+                        style="cursor:pointer;">Status</span>
+                </td>
+            </tr>
+        </table>
+        <div class="hide_me">
+            <select id="hold_pickup_lib_temp" name="hold_pickup_lib_sel"
+                class="hide_me" style="width:125px;height:21px;"></select>
+        </div>
+
+        <table cellpadding='0' cellspacing='0' border='0' width="100%">
+            <tbody id="holds_temp_parent">
+                [% FOR hold IN ctx.holds;
+                    attrs = {marc_xml => hold.marc_xml};
+                    PROCESS get_marc_attrs args=attrs %]
+                <tr id="acct_holds_temp" name="acct_holds_temp"
+                    class="acct_holds_temp">
+                    <td width="36" align="center" style="text-align:center;">
+                        <input type="checkbox" name="hold_id" value="[% hold.hold.hold.id %]" />
+                    </td>
+                    <td width="138">
+                        <div style="margin-top:10px;margin-bottom:10px;">
+                            <a href="[% ctx.opac_root %]/record/[% hold.hold.bre.id %]">[% attrs.title | html %]</a>
+                        </div>
+                    </td>
+                    <td width="123">
+                        <div style="margin-top:10px;margin-bottom:10px;">
+                            <a href="[% ctx.opac_root %]/results?query=au:[% attrs.author | replace('[,\.:;]', '') | url %]">[% attrs.author | html %]</a>
+                        </div>
+                    </td>
+                    <td width="64">
+                        <div style="width:26px;height:23px;margin-top:6px;margin-bottom:6px;">
+                            [% IF attrs.format_icon %]
+                            <img src="[% ctx.media_prefix %]/images/[% attrs.form_icon %]"
+                                title="[% attrs.format %]" alt="[% attrs.format %]" />
+                            [% ELSE;
+                                attrs.format;
+                               END %]
+                        </div>
+                    </td>
+                    <td width="136">
+                        [% ctx.find_aou(hold.hold.hold.pickup_lib).name %]
+                    </td>
+                    <td width="104">
+                        <!-- <input
+                            title="Enter a date (e.g. 10/21/2010)"
+                            class="hide_me" style="width:91px;"
+                            name="activate_box" type="text" /> -->
+                        [% IF hold.hold.hold.frozen == 't' AND
+                                hold.hold.hold.thaw_date;
+                            date.format(ctx.parse_datetime(hold.hold.hold.thaw_date), DATE_FORMAT);
+                        END %]
+                    </td>
+                    <td width="106">
+                        <!-- <input title="[% l('Enter a date (e.g. 10/21/2010)') %]"
+                            class="hide_me" style="width:91px;"
+                            name="hold_expires_box" type="text" />-->
+                        [% IF hold.hold.hold.expire_time;
+                            date.format(ctx.parse_datetime(hold.hold.hold.expire_time), DATE_FORMAT);
+                        END %]
+                    </td>
+                    <td width="95">
+                        <!-- <select name="hold_active_sel"
+                            style="width:90px;" class="hide_me">
+                            <option value="f">Active</option>
+                            <option value="t">Suspended</option>
+                        </select> -->
+                        [% l(hold.hold.hold.frozen == 'f' ? 'Active' : 'Suspended') %]
+                    </td>
+                    <td width="110">
+                        <div name="acct_holds_status"
+                            style="margin-top:10px;margin-bottom:10px;">
+                            [%
+                                IF hold.hold.status == 4;
+                                    l("Available");
+                                ELSIF hold.hold.estimated_wait;
+                                    l("Estimated wait (days): ");
+                                    hold.hold.estimated_wait;
+                                ELSIF hold.hold.status == 3;
+                                    l("In Transit");
+                                ELSIF hold.hold.status < 3;
+                                    l("Waiting for copy");
+                                END;
+                            %]
+                        </div>
+                    </td>
+                    <td width="62" align="right"
+                        style="text-align:right;padding-right:7px;">
+                        <a name="hold_edit_link" href="#">Edit</a>
+                        <a href="#" name="hold_save_link"
+                            class="hide_me">Save</a>
+                        <a href="#" name="hold_cancel_link"
+                            class="hide_me">Back</a>
+                    </td>
+                </tr>
+                [% END %]
+            </tbody>
+        </table>
+        [% END %]
+        </form>
+    </div>
+
+    <span id='myopac.holds.cancel.confirm' class='hide_me'>[% l("Are you sure you wish to cancel the selected holds?") %]</span>
+    <span id='myopac.holds.freeze.confirm' class='hide_me'>[% l("Are you sure you wish to suspend the selected holds?  If an item has already been selected to fulfill the hold, it will not be suspended") %]</span>
+    <span id='myopac.holds.thaw.confirm' class='hide_me'>[% l("Are you sure you wish to activate the selected holds?") %]</span>
+    <span id='myopac.holds.thaw_date.confirm' class='hide_me'>[% l("Are you sure you wish to change the activate date for the selected holds?") %]</span>
+    <span id='myopac.holds.freeze.select_thaw' class='hide_me'>[% l("Select an automatic activation date.  If no date is chosen, the holds will remain suspended until they are manually activated.") %]</span>
+
+    <table width='100%' id='myopac_holds_processing' class='hide_me'>
+        <tr><td>[% l("Processing holds... This may take a moment.") %]</td></tr>
+    </table>
+   
+    <span class='hide_me' id='myopac_holds_cancel_verify'>
+       [% l("If you wish to cancel the selected hold, click OK, otherwise click Cancel.") %]
+    </span>
+</div>
+<div id='myopac_holds_thaw_date_form' class='hide_me'>
+    <div id='myopac_holds_freeze_select_thaw'>
+        [% l("Select an automatic activation date.  If no date is chosen, the holds will remain suspended until they are manually activated.") %]
+    </div>
+    <p>
+        <input size='10' maxlength='10'
+            type='text' id='myopac_holds_thaw_date_input' />
+    </p>
+    <p>
+        <button>[% l("Submit") %]</button>
+    </p>
+</div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/myopac/lists.tt2 b/Open-ILS/web/templates/default/opac/myopac/lists.tt2
new file mode 100644 (file)
index 0000000..c93fac5
--- /dev/null
@@ -0,0 +1,281 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    WRAPPER "default/opac/parts/base.tt2" +
+        "default/opac/parts/myopac/base.tt2";
+    myopac_page = "lists"  %]
+<div
+    style="margin-top: 6px;margin-left:20px;width:250px;padding:5px;"
+    id="mylist_div">
+    <div style="padding-bottom: 7px;">
+        <h2 style="font-weight:normal;">Create new list</h2>
+        Enter the name of the new list:<br />
+        <input type="text" id="mylist_new" />
+    </div>
+    <table cellpadding="0" cellspacing="10" border="0">
+        <tr>
+            <td>
+                Share this list?
+                <a href="#"><img
+                    alt="Sharing Help"
+                    src="[% ctx.media_prefix %]/images/question-mark.png" /></a>
+            </td>
+            <td>
+                <input type="radio" value="0" name="shareList"
+                    id="shareListNo" checked="checked" />
+                <label for="shareListNo">No</label>
+                <br />
+                <input type="radio" value="1" name="shareList"
+                    id="shareListYes" />
+                    <label for="shareListYes">Yes</label>
+            </td>
+        </tr>
+    </table>
+    <a href="#"><img
+        alt="Submit" src="[% ctx.media_prefix %]/images/btnSubmit.png" /></a>
+    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+    <a href="#"><img
+        alt="Cancel" src="[% ctx.media_prefix %]/images/btnCancel.png" /></a>
+</div>
+<div id='myopac_bookbag_div' style="padding:5px;">
+    <div class="header_middle">
+        <span id="acct_holds_header" style="float:left;">My Lists</span>
+        <span style="float:right;">
+            <a class="hide_me" href="#">Export List</a>
+        </span>
+    </div>
+    <div style="float:right;width:85px;">
+        <div style="position:absolute">
+            <div style="position:relative;top:13px;">
+                <a href="#"
+                    style="position:relative;top:-3px;left:-5px;"><img
+                    alt="Saving Help"
+                    src="[% ctx.media_prefix %]/images/question-mark.png" /></a>
+                <a id='acct_lists_save' href="#"><img alt="Save"
+                    src="[% ctx.media_prefix %]/images/save-btn.png" /></a>
+            </div>
+        </div>
+    </div>
+    <div class="clear-both pad-top-ten">
+        <a href="#">+ Add new list</a>
+    </div>
+    <div id="temp_wrapper">
+        <div id='acct_list_template2' class="hide_me">
+            <div style="width:100%">
+                <table cellpadding="0" cellspacing="0" border="0">
+                    <tr>
+                        <td style="font-weight:bold;padding-right:10px;" id='anon_list_name'>
+                            Temporary List
+                        </td>
+                        <td>
+                            <a href="#"><img
+                                alt="Anonymous List Help"
+                                src="[% ctx.media_prefix %]/images/question-mark.png" /></a>
+                        </td>
+                    </tr>
+                </table>
+                <div class="float-right"></div>
+                <div class="clear-both pad-bottom-five"></div>
+            </div>
+    
+            <table id="acct_list_header_anon" cellpadding='0' cellspacing='0' border='0'>
+                <tr>
+                    <td width="1%" style="padding-left:10px;">
+                        <input type="checkbox" id="check_all_list_anon" />
+                    </td>
+                    <td width="98%" style="padding-left:5px;">Title</td>
+                    <td width="1%">
+                        <select style='width:175px;margin-right:11px;'
+                            name="list_actions" id="sel_all_list_anon">
+                            <option value="0">-- Actions for this list --</option>
+                            <option value="hold">Place Hold</option>
+                            <option value="remove">Remove Items</option>
+                        </select>
+                    </td>
+                </tr>
+            </table>
+            <table cellpadding='0' cellspacing='5' border='0'
+                width='91%' style='margin-left:5px;margin-top:5px;'>
+                <tbody id='anon_list_tbody'></tbody>
+            </table>
+            <br /><br />
+        </div>
+        <div id='acct_lists_prime'>
+            <div id='acct_list_template'>
+                <div style="width:100%">
+                    <div style="float:left;font-weight:bold;padding-top:5px;"
+                        name='list_name'></div>
+                    <div style="float:left;padding:5px 0px 0px 10px;">
+                        <a target='_blank' name='share_list_rss'
+                            class='hide_me'><img alt="RSS Feed" border="0"
+                            src="/opac[% ctx.media_prefix %]/images/small-rss.png"
+                            title="You are sharing this list"/></a>
+                    </div>
+                    <div style="float:left;padding:5px 0px 0px 10px;">
+                        <a href="#" name="share_list_link">Share</a>
+                    </div>
+                    <div style="float:left;padding:5px 0px 0px 10px;">
+                        <a href="#" name="remove_list">Remove</a>
+                    </div>
+                    <div class="clear-both pad-bottom-five"></div>
+                </div>
+                <table id="acct_list_header" cellpadding='0' cellspacing='0'
+                    border='0'>
+                    <tr>
+                        <td width="1%" style="padding-left:10px;">
+                            <input type="checkbox" id="check_all_list" />
+                        </td>
+                        <td width="98%" style="padding-left:5px;">Title</td>
+                        <td width="1%">
+                            <select style='width:175px;margin-right:11px;' name="list_actions">
+                                <option value="0">-- Actions for this list --</option>
+                                <option value="hold">Place Hold</option>
+                                <option value="remove">Remove Items</option>
+                            </select>
+                        </td>
+                    </tr>
+                </table>
+                <table cellpadding='0' cellspacing='5' border='0'
+                    width='91%' style='margin-left:5px;margin-top:5px;'>
+                    <tbody name='list_tbody'></tbody>
+                </table>
+                <br /><br />
+            </div>
+        </div>
+    </div>
+    <div id='myopac_delete_bookbag_warn' class='hide_me'>
+        [% l("This will remove the selected bookbag and all items contained within the bookbag.  Are you sure you wish to continue?") %]
+    </div>
+    <div style='text-align: center; font-weight: bold;' 
+        class='hide_me' id='myopac_bookbags_none'>[% l("You have not created any bookbags") %]</div>
+    <table width='100%' class='data_grid data_grid_center hide_me'
+        id='myopac_bookbag_table'>
+        <thead>
+            <tr>
+                <td>[% l("Name") %]</td>
+                <td>[% l("# Items") %]</td>
+                <td>[% l("Shared") %]</td>
+                <td>[% l("Share / Hide") %]</td>
+                <td>[% l("Delete this bookbag?") %]</td>
+            </tr>
+        </thead>
+        <tbody id='myopac_bookbag_tbody'>
+            <tr id='myopac_bookbag_tr'>
+                <td>
+                    <a href='#' class='classic_link'
+                        name='myopac_expand_bookbag'> </a>
+                </td>
+                <td>
+                    <span name='myopac_bookbag_item_count'> </span>
+                    <span> [% l("Items") %]</span>
+                </td>
+                <td>
+                    <span name='myopac_bb_published_no' class='hide_me'>
+                        [% l("No") %]
+                    </span>
+                    <span name='myopac_bb_published_yes' class='hide_me'>
+                        [% l("Yes") %]
+                    </span>
+                    <a name='myopac_bb_published_view'
+                        class='classic_link hide_me'>[% l("(View)") %]</a>
+                    <a name='myopac_bb_published_atom'
+                        class='unadorned_link hide_me'>
+                        <img alt="RSS Feed" border="0"
+                        src="/opac[% ctx.media_prefix %]/images/small-rss.png"
+                        title="[% l("ATOM Feed") %]" />
+                    </a>
+                </td>
+                <td>
+                    <a name='myopac_bb_make_unpublished'
+                        class='classic_link hide_me'>[% l("Hide") %]</a>
+                    <a name='myopac_bb_make_published'
+                        class='classic_link hide_me'>[% l("Share this Bookbag") %]</a>
+                </td>
+                <td>
+                    <a class='classic_link' href='#'
+                        name='myopac_container_delete'>[% l("Delete") %]</a>
+                </td>
+            </tr>
+        </tbody>
+    </table>
+    <table width='100%' class='data_grid data_grid_center hide_me' style='margin-top: 10px;'>
+        <thead>
+            <tr><td>[% l("Create a new Bookbag") %]</td></tr>
+        </thead>
+        <tbody>
+            <tr>
+                <td> 
+                    <span style='padding-right: 5px;'>
+                        [% l("Enter the name of the new Bookbag: ") %]
+                    </span>
+                    <input id='myopac_bookbag_new_name' type='text' /> 
+                </td>
+            </tr>
+            <tr>
+                <td>
+                    <span style='padding: 5px;'>[% l("Share this Bookbag") %]</span>
+                    <a class='classic_link'
+                        href='#'><b>[% l("(Help)") %]</b></a>
+                    <span>[% l("Yes") %]</span>
+                    <input type='radio' name='bb_public' id='bb_public_yes'/>
+                    <span>[% l("No") %]</span>
+                    <input type='radio' name='bb_public' id='bb_public_no' checked='checked'/>
+                    <input style='padding-left: 10px;' type='submit'
+                        value='[% l("Submit") %]' />
+                </td>
+            </tr>
+        </tbody>
+    </table>
+    <div style='width: 99%; text-align: center'>
+        <b id='myopac_bookbag_items_name'> </b>
+    </div>
+    <div class='hide_me'
+        style='width:100%; text-align:center; font-weight:700; margin-top:10px;'
+        id='myopac_bookbag_no_items'>
+        [% l("The selected bookbag contains no items...") %]
+    </div>
+    <table width='100%' class='hide_me data_grid data_grid_center'
+        id='myopac_bookbag_items_table'>
+        <thead> 
+            <tr>
+                <td>[% l("Title") %]</td>
+                <td>[% l("Authors") %]</td>
+                <td>[% l("Remove this item?") %]</td>
+            </tr> 
+        </thead>
+        <tbody id='myopac_bookbag_items_tbody'>
+            <tr id='myopac_bookbag_items_row'>
+                <td>
+                    <a name='myopac_bookbag_items_title'
+                        class='classic_link'> </a>
+                </td>
+                <td name='myopac_bookbag_items_author'></td>
+                <td>
+                    <a name='myopac_bookbag_items_remove'
+                        class='classic_link'>[% l("remove") %]</a>
+                </td>    
+            </tr>
+        </tbody>
+    </table>
+    <span id='bb_publish_text' class='hide_me'>[% l("Sharing a Bookbag means that the contents of the Bookbag will be visible to others.  To see the public view of a shared Bookbag, click the \"View\" link in the \"Shared\" column of the Bookbag list at the top of this page.") %]</span>
+    <span id='myopac_remove_bb_item_confirm' class='hide_me'>
+        [% l("Are you sure you wish to remove this bookbag item?") %]
+    </span>
+    <span id='myopac_make_published_confirm' class='hide_me'>
+        [% l("Sharing this bookbag will allow the contents of the bookbag to be seen by others.  Are you sure you wish to share this bookbag?") %]
+    </span>
+    <span id='myopac_make_unpublished_confirm' class='hide_me'>
+        [% l("Are you sure you wish to hide this bookbag?") %]
+    </span>
+    <span id='myopac_bb_update_success' class='hide_me'>
+        [% l("The Bookbag was successfully updated.") %]
+    </span>
+    <span id='bb_create_warning' class='hide_me'>
+        [% l("Warning: Adding items to a bookbag creates a link between you and the items in the database.  The contents of the bookbag are NOT publicly viewable unless the bookbag is shared. However, if you prefer not to have any link between your patron record and a particular item or items, we suggest that you do not place said items in a bookbag or that you avoid using bookbags all together.  Thank you.") %]
+    </span>
+    <span id='myopac_bb_what_are' class='hide_me'>
+        [% l("Bookbags are...") %]
+    </span>
+    <span class='hide_me' id='bb_update_success'>
+        [% l("Bookbag successfully updated") %]
+    </span>
+</div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/myopac/main.tt2 b/Open-ILS/web/templates/default/opac/myopac/main.tt2
new file mode 100644 (file)
index 0000000..0c307f0
--- /dev/null
@@ -0,0 +1,468 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    PROCESS "default/opac/parts/marc_misc.tt2";
+    WRAPPER "default/opac/parts/base.tt2" +
+        "default/opac/parts/myopac/base.tt2";
+    myopac_page = "main"  %]
+<div id='myopac_summary_div' style="padding:0px;">
+    <div id="acct_sum">
+        <div style="width:742px;float:left;">
+            <div class="header_middle">Account Summary</div>
+        </div>
+        <div id="myopac_sum_fines">
+            <div style="position:absolute;">
+                <div style="position:relative;top:-15px;left:-23px;">
+                    <img src="[% ctx.media_prefix %]/images/acct_sum_fines_tl.png" />
+                </div>
+            </div>
+            <div style="position:absolute;">
+                <div style="position:relative;top:-15px;left:172px;">
+                    <img src="[% ctx.media_prefix %]/images/acct_sum_fines_tr.png" />
+                </div>
+            </div>
+            <div style="position:absolute;">
+                <div style="position:relative;top:161px;left:-23px;">
+                    <img src="[% ctx.media_prefix %]/images/acct_sum_fines_bl.png" />
+                </div>
+            </div>
+            <div style="position:absolute;">
+                <div style="position:relative;top:161px;left:172px;">
+                    <img src="[% ctx.media_prefix %]/images/acct_sum_fines_br.png" />
+                </div>
+            </div>
+            [% l('Fines:') %]
+            <span id="myopac_sum_fines_bal" class='[% ctx.fines.balance_owed ? "red" : ""%]'>
+                [% money(ctx.fines.balance_owed) %]
+            </span><br />
+            <a class="hide_me" href="#" id="pay_fines_btn1"><img
+                alt="[% l('Pay Fines') %]"
+                onmouseover="this.src='[% ctx.media_prefix %]/images/pay-fines-btn-hover.png';"
+                onmouseout="this.src='[% ctx.media_prefix %]/images/pay-fines-btn.png';"
+                src="[% ctx.media_prefix %]/images/pay-fines-btn.png"
+                style="position:relative;top:5px;" /></a>
+        </div>
+        <div style="width:662px;">
+            <div style="float:left;">
+                <div style="padding:10px 0px;" id="myopac_sum_name"></div>
+                <div class="acct_sum_row">
+                    <table width="100%" cellspacing="0" cellpadding="0">
+                        <tr>
+                            <td>
+                                [% l("Items Currently Checked out") %]
+                                <span id="myopac_sum_checked" class="view_link">
+                                    ([% ctx.user_stats.checkouts.total_out %])
+                                </span>
+                            </td>
+                            <td align="right" class="view_link">
+                                <a href="[% ctx.opac_root %]/myopac/circs">[% l("View All") %]</a>
+                            </td>
+                        </tr>
+                    </table>
+                </div>
+                <div class="acct_sum_row">
+                    <table width="100%" cellspacing="0" cellpadding="0">
+                        <tr>
+                            <td>
+                                Items Currently on Hold
+                                <span id="myopac_sum_holds" class="view_link">
+                                    ([% ctx.user_stats.holds.total %])
+                                </span>
+                            </td>
+                            <td align="right" class="view_link">
+                                <a href="[% ctx.opac_root %]/myopac/holds">View All</a>
+                            </td>
+                        </tr>
+                    </table>
+                </div>
+                <div class="acct_sum_row">
+                    <table width="100%" cellspacing="0" cellpadding="0">
+                        <tr>
+                            <td>
+                                Items ready for pickup
+                                <span id="myopac_sum_pickup" class="view_link">
+                                    ([% ctx.user_stats.holds.ready %])
+                                </span>
+                            </td>
+                            <td align="right" class="view_link">
+                                <a href="[% ctx.opac_root %]/myopac/holds?available=1">View All</a>
+                            </td>
+                        </tr>
+                    </table>
+                </div>
+                <div class="acct_sum_row" id="myopac_sum_fines_slim">
+                    <table width="100%" cellspacing="0" cellpadding="0">
+                        <tr>
+                            <td>Fees &amp; Fines</td>
+                            <td align="right" class="view_link">
+                                <a class="hide_me"
+                                    id="show_fines_link"
+                                    href="#">Show Overdue Materials</a>
+                            </td>
+                        </tr>
+                    </table>
+                </div>
+            </div>
+        </div>
+        <div class="clear-both"></div>
+        <div id='myopac_fines_div'>
+            <table width='100%' class='data_grid data_grid_center'>
+                <thead class='color_3'>
+                    <tr>
+                        <td colspan='3' style='padding: 6px'>
+                            <b>[% l("Summary") %]</b>
+                        </td>
+                    </tr>
+                    <tr>
+                        <td width='33%'>[% l("Total Owed") %]</td>
+                        <td width='33%'>[% l("Total Paid") %]</td>
+                        <td width='33%'>[% l("Balance Owed") %]</td>
+                    </tr>
+                </thead>
+                <tbody id='myopac_fines_summary_tbody'>
+                    <tr id='myopac_fines_summary_row'>
+                        <td id='myopac_fines_summary_total'>[% money(ctx.fines.total_owed) %]</td>
+                        <td id='myopac_fines_summary_paid'>[% money(ctx.fines.total_paid) %]</td>
+                        <td id='myopac_fines_summary_balance' class='bold-red'>[% money(ctx.fines.balance_owed) %]</td>
+                    </tr>
+                </tbody>
+            </table>
+        <!--
+        <div id='accrue_explanation' class='hide_me'>
+            <span>Transactions whose balances are marked with a</span>
+            <span class='bold-red'>*</span>
+            <span>will continue to accrue fines until the checked out item is returned.</span>
+        </div>
+        -->
+        [% IF ctx.fines.circulation.size > 0 %]
+            <div id='myopac_circ_trans_div'>
+                <br/><hr/><br/>
+                <table width='100%' class='data_grid data_grid_center'
+                    id='myopac_circ_trans_table'>
+                    <thead>
+                        <tr>
+                            <td colspan='10' style='padding: 6px'>
+                                <strong>[% l("Fines") %]</strong>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td>[% l("Title") %]</td>
+                            <td>[% l("Author") %]</td>
+                            <td>[% l("Checkout Date") %]</td>
+                            <td>[% l("Due Date") %]</td>
+                            <td>[% l("Date Returned") %]</td>
+                            <td>[% l("Balance Owed") %]</td>
+                            <!-- TODO: hidden until pay-fines is implemented
+                            <td nowrap="nowrap" style="white-space:nowrap;">
+                                <input id="pay_fines_box1" checked="checked"
+                                    type="checkbox" title="[% l('Click to (un)select all fines') %]" />
+                                <label for="pay_fines_box1">[% l('Pay Fines') %]</label>
+                            </td>
+                            -->
+                        </tr>
+                    </thead>
+                    <tbody id='myopac_circ_trans_tbody'>
+                        [% FOR f IN ctx.fines.circulation;
+                            attrs = {marc_xml => f.marc_xml};
+                            PROCESS get_marc_attrs args=attrs %]
+                        <tr id='myopac_circ_trans_row'>
+                            <td>
+                                <a class='classic_link'
+                                    href="[% ctx.opac_root %]/record/[% f.xact.circulation.target_copy.call_number.record.id %]">[% attrs.title %]</a>
+                            </td>
+                            <td>
+                                <a class="classic_link"
+                                    href="[% ctx.opac_root %]/results?query=au:[% attrs.author | replace('[,\.:;]', '') | url %]">[% attrs.author %]</a>
+                            </td>
+                            <td name='myopac_circ_trans_start'>
+                                [% date.format(
+                                    ctx.parse_datetime(
+                                        f.xact.circulation.xact_start
+                                    ), DATE_FORMAT
+                                ) %]
+                            </td>
+                            <td name='myopac_circ_trans_due'>
+                                [% date.format(
+                                    ctx.parse_datetime(
+                                        f.xact.circulation.due_date
+                                    ), DATE_FORMAT
+                                ) %]
+                            </td>
+                            <td name='myopac_circ_trans_finished'>
+                                [%  IF f.xact.circulation.checkin_time;
+                                        date.format(
+                                            ctx.parse_datetime(
+                                                f.xact.circulation.checkin_time
+                                            ), DATE_FORMAT
+                                        );
+                                    ELSE %]
+                                    <!-- XXX TODO fines aren't really accruing
+                                        if circ has hit maxfines. more clarity
+                                        here? -->
+                                    <span class="red">[% l('(fines accruing)') %]</span>
+                                [%  END %]
+                            </td>
+                            <td>
+                                <strong class="red">
+                                    [% money(f.xact.balance_owed) %]
+                                </strong>
+                            </td>
+                            <!-- TODO: hidden until pay-fines is implemented
+                            <td>
+                                <input type="checkbox" name="selector" title="[% l('Pay this fine') %]" />
+                            </td>
+                            -->
+                        </tr>
+                        [% END %]
+                    </tbody>
+                </table>
+            </div>
+        [% END %]
+
+        [% IF ctx.fines.grocery.size > 0 %]
+            <!-- Table for all non-circulation transactions -->
+            <div id='myopac_trans_div'>
+                <br/>
+                <hr class='opac-auto-013'  color="#dcdbdb" />
+                <br/>
+                <table width='100%' class='data_grid data_grid_center'
+                    id='myopac_trans_table'>
+                    <thead>
+                        <tr>
+                            <td colspan='8' style='padding: 6px'>
+                                <b>[% l("Other Fees") %]</b>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td width='16%'>[% l("Transaction Start Time") %]</td>
+                            <td width='16%'>[% l("Last Payment Time") %]</td>
+                            <td width='16%'>[% l("Initial Amount Owed") %]</td>
+                            <td width='16%'>[% l("Total Amount Paid") %]</td>
+                            <td width='16%'>[% l("Balance Owed") %]</td>
+                            <td width='16%'>[% l("Billing Type") %]</td>
+                            <!-- TODO: hidden until pay-fines is implemented
+                            <td width='4%' align="center" nowrap="nowrap"
+                                style="white-space:nowrap;">
+                                <input id="pay_fines_box2" checked="checked"
+                                    type="checkbox"
+                                    title="[% l('Click to (un)select all fines') %]" />
+                                <label for="pay_fines_box2">[% l("Pay Fines") %]</label>
+                            </td>
+                            -->
+                        </tr>
+                    </thead>
+                    <tbody id='myopac_trans_tbody'>
+                        [% FOR f IN ctx.fines.grocery %]
+                        <tr id='myopac_trans_row'>
+                            <td>[% date.format(
+                                    ctx.parse_datetime(f.xact.xact_start),
+                                    DATE_FORMAT
+                            ) %]</td>
+                            <td>
+                                [%  IF f.xact.last_payment_ts;
+                                        date.format(
+                                            ctx.parse_datetime(
+                                                f.xact.last_payment_ts
+                                            ), DATE_FORMAT
+                                        );
+                                    END %]
+                            </td>
+                            <td>[% money(f.xact.total_owed) %]</td>
+                            <td>[% money(f.xact.total_paid) %]</td>
+                            <td class="red">
+                                <strong>
+                                    [% money(f.xact.balance_owed) %]
+                                </strong>
+                            </td>
+                            <td>[% f.xact.last_billing_type %]</td>
+                            <!-- TODO: hidden until pay-fines is implemented
+                            <td>
+                                <input type="checkbox" name='selector' title='[% l("Pay this fine") %]'/>
+                            </td>
+                            -->
+                        </tr>
+                        [% END %]
+                    </tbody>
+                </table>
+            </div>
+            [% END %]
+            <!-- TODO: hidden until pay-fines is implemented
+            <a href="#"><img alt="[% l('Pay Fines') %]"
+                onmouseover="this.src='[% ctx.media_prefix %]/images/pay-fines-btn-hover.png';"
+                src="[% ctx.media_prefix %]/images/pay-fines-btn.png"
+                style="position:relative;top:5px;" /></a>
+            <br/>
+            -->
+        </div>
+    </div>
+    <div id="pay_fines_now" class="hide_me">
+        <table id='oils-selfck-cc-payment-table'>
+            <tbody>
+                <tr>
+                    <td><div style="width:129px;"></div></td>
+                    <td><div style="width:195px;"></div></td>
+                    <td><div style="width:324px;"></div></td>
+                </tr>
+                <tr>
+                    <td colspan='2'><strong>Billing Information</strong></td>
+                    <td rowspan='13' valign='top'>
+                        Selected fines you are paying for:
+                        <table cellpadding="0" cellspacing="5" border="0">
+                            <thead>
+                                <tr>
+                                    <td>
+                                        <strong>Name</strong>
+                                    </td>
+                                    <td>
+                                        <strong>Amount</strong>
+                                    </td>
+                                </tr>
+                            </thead>
+                            <tbody id="selectedFines">
+                            </tbody>
+                        </table>
+                        <br />
+                        <div id='oils-selfck-cc-payment-summary'>
+                            Total amount to pay:
+                            <strong>$<span></span></strong>
+                        </div>
+                        <br />
+                        Click <strong>Cancel</strong> to go back and (un)select
+                        other fines.
+                    </td>
+                </tr>
+                <tr>
+                    <td>First Name</td>
+                    <td><input jsId='oilsSelfckCCFName' /></td>
+                </tr>
+                <tr>
+                    <td>Last Name</td>
+                    <td><input jsId='oilsSelfckCCLName' /></td>
+                </tr>
+                <tr>
+                    <td>Street Address</td>
+                    <td><input jsId='oilsSelfckCCStreet' /></td>
+                </tr>
+                <tr>
+                    <td>City</td>
+                    <td><input jsId='oilsSelfckCCCity' /></td>
+                </tr>
+                <tr>
+                    <td>State or Province</td>
+                    <td><input jsId='oilsSelfckCCState' /></td>
+                </tr>
+                <tr>
+                    <td>ZIP or Postal Code</td>
+                    <td><input jsId='oilsSelfckCCZip' /></td>
+                </tr>
+                <tr>
+                  <td colspan='2'><strong>Credit Card Information</strong></td>
+                </tr>
+                <!-- Technically not needed since card type is derived from the CC number
+                <tr>
+                    <td>Type of Card</td>
+                    <td>
+                        <select jsId='oilsSelfckCCType' required='true'>
+                            <option value='VISA'>VISA</option>
+                            <option value='MasterCard'>MasterCard</option>
+                            <option value='American Express'>American Express</option>
+                        </select>
+                    </td>
+                </tr>
+                -->
+                <tr>
+                    <td>Credit Card #</td>
+                    <td><input jsId='oilsSelfckCCNumber' /></td>
+                </tr>
+                <tr>
+                    <td>
+                        <div style="position:absolute;">
+                            <div style="position:relative;left:80px;">
+                                <a href="#"><img
+                                    src="[% ctx.media_prefix %]/images/question-mark.png" /></a>
+                            </div>
+                        </div>
+                        Security Code
+                    </td>
+                    <td>
+                        <input jsId='oilsSelfckCCCVV' />
+                    </td>
+                </tr>
+                <tr>
+                    <td>Exipration Month</td>
+                    <td>
+                        <select jsId='oilsSelfckCCMonth'>
+                            <option value='01' selected='selected'>January</option>
+                            <option value='02'>February</option>
+                            <option value='03'>March</option>
+                            <option value='04'>April</option>
+                            <option value='05'>May</option>
+                            <option value='06'>June</option>
+                            <option value='07'>July</option>
+                            <option value='08'>August</option>
+                            <option value='09'>September</option>
+                            <option value='10'>October</option>
+                            <option value='11'>November</option>
+                            <option value='12'>December</option>
+                        </select>
+                    </td>
+                </tr>
+                <tr>
+                    <td>Expiration Year</td>
+                    <td>
+                      <select jsId='oilsSelfckCCYear'>
+                        <option value='2011'>2011</option>
+                        <option value='2012'>2012</option>
+                        <option value='2013'>2013</option>
+                        <option value='2014'>2014</option>
+                        <option value='2015'>2015</option>
+                        <option value='2016'>2016</option>
+                        <option value='2017'>2017</option>
+                        <option value='2018'>2018</option>
+                        <option value='2019'>2019</option>
+                      </select>
+                    </td>
+                </tr>
+                <tr class="hide_me">
+                    <td>Edit Billing Address</td>
+                    <td>
+                        <input jsId='oilsSelfckEditDetails'/>
+                    </td>
+                </tr>
+                <tr>
+                    <td colspan='2' align="center">
+                        <button jsId='oilsSelfckCCSubmit'>
+                            Submit Payment
+                        </button>
+                        <button>
+                            Cancel
+                        </button>
+                    </td>
+                </tr>
+                <tr>
+                    <td colspan="3">
+                        <br />
+                        Important! You must have a printed receipt to be
+                        eligible for a refund on lost items (regulations allow
+                        for no exceptions).
+                        <br />
+                        <strong>
+                            To ensure your necessary receipt information is
+                            not lost, enter your email address above and a
+                            receipt will be emailed to you. Otherwise, make
+                            certain you have a printed receipt in hand before
+                            closing the payment receipt screen.
+                        </strong>
+                        <br />
+                        Refunds are not available for parts and pieces, overdue
+                        fines, or items that do not display a specific title in
+                        My Account. For a full list of refundable and
+                        non-refundable items, visit
+                        <a href="http://www.kcls.org/usingthelibrary/borrowing/refundable.cfm">http://www.kcls.org/usingthelibrary/borrowing/refundable.cfm</a><br /><br />
+                        This site uses VeriSign SSL encryption to ensure your
+                        privacy.
+                    </td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+</div>
+[% END %]
diff --git a/Open-ILS/web/templates/default/opac/myopac/prefs.tt2 b/Open-ILS/web/templates/default/opac/myopac/prefs.tt2
new file mode 100644 (file)
index 0000000..9f6177a
--- /dev/null
@@ -0,0 +1,779 @@
+[%  PROCESS "default/opac/parts/header.tt2";
+    WRAPPER "default/opac/parts/base.tt2" +
+        "default/opac/parts/myopac/base.tt2";
+    myopac_page = "prefs"  %]
+    <div id='myopac_prefs_div'>
+        <div id="acct_prefs_tabs"
+             style="padding-bottom: 12px;color:#666;">
+            <div style="float:left;">
+                <div class="align selected"
+                     id="prefs_info_lbl"><img src=
+                     "[% ctx.media_prefix %]/images/sub_prefs_info_on.jpg" /></div>
+
+                <div class="align hide_me"
+                     id="prefs_info_link">
+                    <a href="#"><img src=
+                         "[% ctx.media_prefix %]/images/sub_prefs_info_off.jpg" /></a>
+                </div>
+
+                <div class="align"
+                     id="prefs_notify_link">
+                    <a href="#"><img src=
+                         "[% ctx.media_prefix %]/images/sub_prefs_notify_off.jpg" /></a>
+                </div>
+
+                <div class="align selected hide_me"
+                     id="prefs_notify_lbl"><img src=
+                     "[% ctx.media_prefix %]/images/sub_prefs_notify_on.jpg" /></div>
+
+                <div class="align"
+                     id="prefs_search_link">
+                    <a href="#"><img src=
+                         "[% ctx.media_prefix %]/images/sub_prefs_search_off.jpg" /></a>
+                </div>
+
+                <div class="align selected hide_me"
+                     id="prefs_search_lbl"><img src=
+                     "[% ctx.media_prefix %]/images/sub_prefs_search_on.jpg" /></div>
+            </div>
+
+            <div style="float:right;width:65px;">
+                <div style="position:absolute">
+                    <div style="position:relative;top:75px;">
+                        <a id='acct_prefs_save'
+                             class='hide_me'
+                             href="#"><img alt="Save"
+                             src="[% ctx.media_prefix %]/images/save-btn.png" /></a>
+                    </div>
+                </div>
+            </div>
+
+            <div class="clear-both"></div>
+        </div>
+
+        <div class="header_middle">
+            <span id="acct_prefs_header">
+                Account Information and Preferences
+            </span>
+            <span class="float-right">
+                <a class="hide_me"
+                    href="#">Export List</a>
+            </span>
+        </div>
+
+        <div class="clear-both normal-height"></div>
+
+        <table class="hide_me full-width" id="acct_search_main">
+            <tbody id='myopac_prefs_tbody'>
+                <tr id='myopac_prefs_loading'>
+                    <td colspan='3'><b>[% l("Loading...") %]</b></td>
+                </tr>
+
+                <tr id='myopac_prefs_row'>
+                    <td width='20%'>[% l("Search hits per page") %]</td>
+
+                    <td>
+                        <div style="position:absolute">
+                            <div style="position:relative;top:0px;left:55px;">
+                                <a href="#">
+                                <img alt="Search Hits Help"
+                                     src=
+                                     "[% ctx.media_prefix %]/images/question-mark.png" /></a>
+                            </div>
+                        </div><select id='prefs_hits_per'
+                            style="position:relative;z-index:100;">
+                            <option value='5'>
+                                5
+                            </option>
+
+                            <option value='8'>
+                                8
+                            </option>
+
+                            <option value='10'>
+                                10
+                            </option>
+
+                            <option value='15'>
+                                15
+                            </option>
+
+                            <option value='20'>
+                                20
+                            </option>
+
+                            <option value='25'>
+                                25
+                            </option>
+
+                            <option value='50'>
+                                50
+                            </option>
+                        </select>
+                    </td>
+                </tr>
+
+                <tr>
+                    <td colspan="2"><label for="circHistStart">Keep history of
+                    checked out items?</label> <input type="checkbox"
+                           id="circHistStart" /></td>
+                </tr><!-- FONT size preference -->
+
+                <tr class="hide_me">
+                    <td>[% l("Default Font Size") %]</td>
+
+                    <td><select id='prefs_def_font'>
+                        <option value='regular'>
+                            [% l("Regular Font") %]
+                        </option>
+
+                        <option value='large'>
+                            [% l("Large Font") %]
+                        </option>
+                    </select></td>
+                </tr>
+
+                <tr class="hide_me">
+                    <td>[% l("Default Search Location") %]</td>
+                    <td>
+                        <div style='margin-bottom: 5px;'>
+                            <input type='checkbox' id='myopac_pref_home_lib' />
+                                 [% l("Always search my home library by default.") %]
+                        </div>
+                        <select id='prefs_def_location'></select>
+                    </td>
+                </tr>
+
+                <tr class="hide_me">
+                    <td>[% l("Default Search Range") %]</td>
+
+                    <td><select id='prefs_def_range'>
+                        </select></td>
+                </tr>
+            </tbody>
+        </table><a href=
+        "http://www.kcls.org/usingthelibrary/catalog_help/library_elf.cfm"><u>Try
+        Library Elf-to manage library materials!</u></a>
+
+        <table class="hide_me"
+               id="acct_notify_main">
+            <tbody>
+                <tr class="hide_me">
+                    <td><span>[% l("Default Hold Notification Method") %]</span> <a class=
+                    'classic_link'
+                       href='#'>[% l("(Help)") %]</a></td>
+
+                    <td style="padding-left:15px;"><select id=
+                    'prefs_hold_notify'>
+                        <option value='phone:email'
+                                selected='selected'>
+                            [% l("Use Phone and Email") %]
+                        </option>
+
+                        <option value='phone'>
+                            [% l("Use Phone Only") %]
+                        </option>
+
+                        <option value='email'>
+                            [% l("Use Email Only") %]
+                        </option>
+                    </select></td>
+                </tr>
+
+                <tr>
+                    <td style="padding-top:10px;"><strong>Pick Up Notice for
+                    Holds</strong><br />
+                    <input type="checkbox"
+                           id="opac.hold_notify.email"
+                           name="opac.hold_notify.email" /> <label for=
+                           "opac.hold_notify.email">Email</label><br />
+                    <input type="checkbox"
+                           id="opac.hold_notify.phone"
+                           name="opac.hold_notify.phone" /> <label for=
+                           "opac.hold_notify.phone">Phone</label>
+                           <b>(Temporarily phone notification will generate a
+                           mailed paper notice.)</b></td>
+                </tr>
+
+                <tr>
+                    <td style="padding-top:10px;"><strong>Expire Notice for
+                    Holds</strong><br />
+                    <input type="checkbox"
+                           id="notification.hold.expire.email"
+                           name="notification.hold.expire.email" /> <label for=
+                           "notification.hold.expire.email">Email</label></td>
+                </tr>
+
+                <tr>
+                    <td style="padding-top:10px;"><strong>Cancel Notice for
+                    Holds</strong><br />
+                    <input type="checkbox"
+                           id="notification.hold.cancel.email"
+                           name="notification.hold.cancel.email" /> <label for=
+                           "notification.hold.cancel.email">Email</label></td>
+                </tr>
+
+                <tr>
+                    <td style="padding-top:10px;"><strong>Overdue First
+                    Notice</strong><br />
+                    <input type="checkbox"
+                           id="notification.overdue.first.email"
+                           name="notification.overdue.first.email" />
+                           <label for=
+                           "notification.overdue.first.email">Email</label><br />
+                    <input type="checkbox"
+                           id="notification.overdue.first.phone"
+                           name="notification.overdue.first.phone" />
+                           <label for=
+                           "notification.overdue.first.phone">Phone</label>
+                           <b>(Temporarily phone notification will generate a
+                           mailed paper notice.)</b></td>
+                </tr>
+
+                <tr>
+                    <td style="padding-top:10px;"><strong>Courtesy
+                    Notice</strong><br />
+                    <input type="checkbox"
+                           id="notification.predue.email"
+                           name="notification.predue.email" /> <label for=
+                           "notification.predue.email">Email</label><br /></td>
+                </tr>
+            </tbody>
+        </table>
+
+        <div id="acct_info_main">
+            <div id='myopac.expired.alert'
+                 class='hide_me'
+                 style='margin-bottom: 20px;'>
+                <table class='data_grid'
+                       width='100%'>
+                    <tbody>
+                        <tr>
+                            <td width='100%' class='red'>
+                                [% l("Your account expired on") %]
+                                <span id='myopac.expired.date'></span>!
+                                [% l("Please see a librarian to renew your account.") %]</td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+
+            <div id='myopac.notes.div'
+                 class='hide_me'>
+                <table class='data_grid'
+                       width='100%'>
+                    <thead>
+                        <tr>
+                            <td colspan='2'>
+                            <b>[% l("* Staff Notes *") %]</b></td>
+                        </tr>
+                    </thead>
+
+                    <tbody id='myopac.notes.tbody'>
+                        <tr id='myopac.notes.tr'>
+                            <td><b name='title'></b> : <span name=
+                            'value'></span></td>
+                        </tr>
+                    </tbody>
+                </table><br />
+            </div>
+
+            <table width='70%'
+                   class='light_border data_grid'>
+                <tbody id='myopac_summary_tbody'>
+                    <tr>
+                        <td width='30%'
+                            class='color_4 light_border'>[% l("Name") %]</td>
+
+                        <td class='light_border'><span id=
+                        'myopac_summary_prefix'
+                              style='padding-right: 5px;'></span> <span id=
+                              'myopac_summary_first'
+                              style='padding-right: 5px;'></span> <span id=
+                              'myopac_summary_middle'
+                              style='padding-right: 5px;'></span> <span id=
+                              'myopac_summary_last'
+                              style='padding-right: 5px;'></span> <span id=
+                              'myopac_summary_suffix'></span></td>
+
+                        <td></td>
+                    </tr>
+
+                    <tr>
+                        <td class='color_4 light_border'>
+                        [% l("Day Phone") %]</td>
+
+                        <td class='light_border'
+                            id='myopac_summary_dayphone'></td>
+
+                        <td class='light_border'><a href='#'
+                           class="hide_me"
+                           id='myopac_summary_phone1_change'
+                           style=
+                           'text-decoration: underline;'>[% l("Change") %]</a></td>
+                    </tr>
+
+                    <tr id='myopac_update_phone1_row'
+                        class='hide_me'>
+                        <td class='myopac_update_cell'
+                            colspan='3'>
+                            <span class='myopac_update_span'>
+                                Enter New [% l("Day Phone") %]:
+                            </span>
+
+                            <input type='text' size='24' id='myopac_new_phone1' />
+                            <span class='myopac_update_span'>
+                                <button>
+                                    <span class='myopac_update_span'>
+                                        [% l("Submit") %]</span>
+                                </button>
+                            </span>
+                            <span class='myopac_update_span'>
+                                <button>
+                                    <span class='myopac_update_span'>
+                                        [% l("Cancel") %]</span>
+                                </button>
+                            </span>
+                        </td>
+                    </tr>
+
+                    <tr>
+                        <td class='color_4 light_border'>
+                        [% l("Evening Phone") %]</td>
+
+                        <td class='light_border'
+                            id='myopac_summary_eveningphone'></td>
+
+                        <td class='light_border'><a href='#'
+                           class="hide_me"
+                           id='myopac_summary_phone2_change'
+                           style=
+                           'text-decoration: underline;'>[% l("Change") %]</a></td>
+                    </tr>
+
+                    <tr id='myopac_update_phone2_row'
+                        class='hide_me'>
+                        <td class='myopac_update_cell'
+                            colspan='3'><span class='myopac_update_span'>New
+                            [% l("Evening Phone") %]:</span>
+                            <input type='text' size='24' id='myopac_new_phone2' />
+                            <span class='myopac_update_span'><button><span class=
+                                'myopac_update_span'>[% l("Submit") %]</span></button></span>
+                            <span class='myopac_update_span'><button><span class=
+                                'myopac_update_span'>[% l("Cancel") %]</span></button></span>
+                        </td>
+                    </tr>
+
+                    <tr>
+                        <td class='color_4 light_border'>
+                        [% l("Other Phone") %]</td>
+
+                        <td class='light_border'
+                            id='myopac_summary_otherphone'></td>
+
+                        <td class='light_border'><a href='#'
+                           class="hide_me"
+                           id='myopac_summary_phone3_change'
+                           style=
+                           'text-decoration: underline;'>[% l("Change") %]</a></td>
+                    </tr>
+
+                    <tr id='myopac_update_phone3_row'
+                        class='hide_me'>
+                        <td class='myopac_update_cell'
+                            colspan='3'><span class='myopac_update_span'>Enter
+                            New [% l("Other Phone") %]:</span>
+                            <input type='text' size='24' id='myopac_new_phone3' />
+                            <span class='myopac_update_span'><button><span class=
+                                'myopac_update_span'>[% l("Submit") %]</span></button></span>
+                            <span class='myopac_update_span'><button><span class=
+                                'myopac_update_span'>[% l("Cancel") %]</span></button></span>
+                        </td>
+                    </tr>
+
+                    <tr>
+                        <td class='color_4 light_border'>
+                            <div style="position:absolute">
+                                <div style=
+                                "position:relative;left:70px;top:-3px;">
+                                    <a href="#">
+                                    <img alt="Username Help"
+                                         src=
+                                         "[% ctx.media_prefix %]/images/question-mark.png" /></a>
+                                </div>
+                            </div>[% l("Username") %]
+                        </td>
+
+                        <td class='light_border'
+                            id='myopac_summary_username'></td>
+
+                        <td class='light_border'><a href='#'
+                           class="hide_me"
+                           id='myopac_summary_username_change'
+                           style=
+                           'text-decoration: underline;'>[% l("Change") %]</a></td>
+                    </tr>
+
+                    <tr id='myopac_update_username_row'
+                        class='hide_me'>
+                        <td class='myopac_update_cell'
+                            colspan='3'><span class=
+                            'myopac_update_span'>[% l("Enter new username:") %]</span>
+                            <input type='text' size='24' id='myopac_new_username' />
+                            <span class='myopac_update_span'><button><span class=
+                                'myopac_update_span'>[% l("Submit") %]</span></button></span>
+                            <span class='myopac_update_span'><button><span class=
+                                'myopac_update_span'>[% l("Cancel") %]</span></button></span>
+                        </td>
+                    </tr>
+                    <tr>
+                        <td class='color_4 light_border'>
+                        [% l("Password") %]</td>
+                        <td class='light_border'
+                            id='myopac_summary_password'>
+                            [% l("(not shown)") %]</td>
+                        <td class='light_border'><a href='#'
+                           class="hide_me"
+                           id='myopac_summary_password_change'
+                           style=
+                           'text-decoration: underline;'>[% l("Change") %]</a></td>
+                    </tr>
+                    <tr id='myopac_update_password_row'
+                        class='hide_me'>
+                        <td class='myopac_update_cell'
+                            colspan='3'>
+                            <table>
+                                <tbody>
+                                    <tr>
+                                        <td>
+                                            <span class= 'myopac_update_span'>
+                                                [% l("Enter current password:") %]
+                                            </span>
+                                        </td>
+
+                                        <td>
+                                            <input type='password'
+                                               size='24'
+                                               id='myopac_current_password' />
+                                           </td>