From d75634dc021fb401718e18a8f7f7f7215d4daf86 Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Tue, 5 Mar 2013 13:06:57 -0500
Subject: [PATCH] Resolving VUFIND-276 (feedback module).

---
 config/vufind/config.ini                      |   13 +-
 languages/en.ini                              | 1522 +++++++++--------
 module/VuFind/config/module.config.php        |    4 +-
 .../VuFind/Controller/FeedbackController.php  |   88 +
 .../src/VuFind/View/Helper/Root/Feedback.php  |   69 +
 themes/blueprint/css/styles.css               |   41 +
 .../images/feedbacktab/image-tab-en.png       |  Bin 0 -> 1804 bytes
 themes/blueprint/js/feedback.js               |   85 +
 .../blueprint/js/jquery.tabSlideOut.v2.0.js   |  245 +++
 .../blueprint/templates/feedback/email.phtml  |    6 +
 .../blueprint/templates/feedback/form.phtml   |   28 +
 .../blueprint/templates/feedback/home.phtml   |    7 +
 .../blueprint/templates/layout/layout.phtml   |   19 +
 themes/root/theme.config.php                  |    6 +
 14 files changed, 1373 insertions(+), 760 deletions(-)
 create mode 100644 module/VuFind/src/VuFind/Controller/FeedbackController.php
 create mode 100644 module/VuFind/src/VuFind/View/Helper/Root/Feedback.php
 create mode 100644 themes/blueprint/images/feedbacktab/image-tab-en.png
 create mode 100644 themes/blueprint/js/feedback.js
 create mode 100644 themes/blueprint/js/jquery.tabSlideOut.v2.0.js
 create mode 100644 themes/blueprint/templates/feedback/email.phtml
 create mode 100644 themes/blueprint/templates/feedback/form.phtml
 create mode 100644 themes/blueprint/templates/feedback/home.phtml

diff --git a/config/vufind/config.ini b/config/vufind/config.ini
index 4de4b6a7590..9f0516cf0e4 100644
--- a/config/vufind/config.ini
+++ b/config/vufind/config.ini
@@ -834,4 +834,15 @@ search = true
 ; a limit is recommended if you have large trees, as otherwise large numbers of
 ; results can cause performance problems.  If treeSearchLimit is -1 or not set,
 ; results will be unlimited.
-treeSearchLimit = 100
\ No newline at end of file
+treeSearchLimit = 100
+
+; This section will be used to configure the feedback module.
+; Set "tab_enabled" to true in order to enable the feedback module.
+[Feedback]
+;tab_enabled       = true
+;recipient_email   = "feedback@myuniversity.edu"
+;recipient_name    = "Your Library"
+;email_subject     = "VuFind Feedback"
+; This is the information for where feedback emails are sent from.
+;sender_email      = "noreply@vufind.org"
+;sender_name       = "VuFind Feedback"
\ No newline at end of file
diff --git a/languages/en.ini b/languages/en.ini
index 762ce142214..daff14bb63c 100644
--- a/languages/en.ini
+++ b/languages/en.ini
@@ -1,758 +1,764 @@
-; For future reference:
-;English = English
-Access = Access
-Account = Account
-Add = Add
-Add a Note = "Add a Note"
-Add Tag = "Add Tag"
-Add Tags = "Add Tags"
-Add to another list = "Add to another list"
-Add to Book Bag = "Add to Book Bag"
-Add to favorites = "Add to Favorites"
-Add your comment = "Add your comment"
-Address = Address
-add_comment_fail_blank = "Comment cannot be blank."
-add_comment_success = "Comment added."
-add_favorite_fail = "Error: Record not saved"
-add_favorite_prefix = Add
-add_favorite_suffix = "to favorites"
-add_list_fail = "Error: List not created"
-add_other_libraries = "Include articles at other libraries"
-add_search       = "Add Search Field"
-add_search_group = "Add Search Group"
-add_tag_error = "Error: Could Not Save Tags"
-add_tag_note = "Spaces will separate tags.  Use quotes for multi-word tags."
-add_tag_success = "Tags Saved"
-Advanced = Advanced
-Advanced Search = "Advanced Search"
-advSearchError_noRights    = "I'm sorry, but you don't have permission to edit that search. Perhaps your browser session has expired?"
-advSearchError_notAdvanced = "The search you have requested to edit is not an advanced search."
-advSearchError_notFound    = "The search you have requested was not found."
-adv_search_all          = "All Fields"
-adv_search_author       = Author
-adv_search_callnumber   = "Call Number"
-adv_search_filters      = "Applied Filters"
-adv_search_isn          = ISBN/ISSN
-adv_search_journaltitle = "Journal Title"
-adv_search_label = "Search for"
-adv_search_publisher    = Publisher
-adv_search_select_all   = "select all"
-adv_search_series       = Series
-adv_search_subject      = Subject
-adv_search_title        = Title
-adv_search_toc          = "Table of Contents"
-adv_search_year         = "Year of Publication"
-All Fields = "All Fields"
-All Pages Loaded = "All Pages Loaded"
-alphabrowse_matches = "Titles"
-An error has occurred = "An error has occurred"
-AND = AND
-APA Citation = "APA Citation"
-Ask a Librarian = "Ask a Librarian"
-Audience = Audience
-Audio = Audio
-authentication_error_admin = "We cannot log you in at this time.  Please contact your system administrator for assistance."
-authentication_error_blank = "Login information cannot be blank."
-authentication_error_denied = "Credentials do not match! Access denied."
-authentication_error_invalid = "Invalid login -- please try again."
-authentication_error_technical = "We cannot log you in at this time.  Please try again later."
-Author = Author
-Author Browse = "Author Browse"
-Author Notes = "Author Notes"
-Author Results for = "Author Results for"
-Author Search Results = "Author Search Results"
-Authors Related to Your Search = "Authors Related to Your Search"
-Auto configuration is currently disabled = "Auto configuration is currently disabled"
-auto_configure_description = "If this is a new installation, you may be able to fix the error using VuFind's Auto Configure tool."
-auto_configure_disabled = "Auto configuration is disabled."
-auto_configure_title = "Auto Configure"
-Available = Available
-Available Functionality = "Available Functionality"
-Awards = Awards
-Back to Record = "Back to Record"
-Back to Search Results = "Back to Search Results"
-Backtrace = Backtrace
-Bag = Bag
-Balance = Balance
-basic_search_keep_filters = "Retain my current filters"
-Be the first to leave a comment = "Be the first to leave a comment"
-Be the first to tag this record = "Be the first to tag this record"
-Bibliographic Details = "Bibliographic Details"
-Bibliography = Bibliography
-Book = Book
-Book Bag = "Book Bag"
-Book Cover = "Book Cover"
-bookbag_confirm_empty = "Are you sure you want to empty your Book Bag?"
-bookbag_delete = "Delete Selected Book Bag Items"
-bookbag_delete_selected = "Delete Selected"
-bookbag_email = "Email Selected Book Bag Items"
-bookbag_email_selected  = "Email Selected"
-bookbag_export = "Export Selected Book Bag Items"
-bookbag_export_selected  = "Export Selected"
-bookbag_full = "Full"
-bookbag_full_msg = "Your Book Bag is Full"
-bookbag_is_empty = "Your Book Bag is empty"
-bookbag_print_selected  = "Print Selected"
-bookbag_save = "Save Selected Book Bag Items"
-bookbag_save_selected  = "Save Selected"
-Bookmark = Bookmark
-Books = Books
-Braille = Braille
-Browse = Browse
-Browse Alphabetically = "Browse Alphabetically"
-Browse for Authors = "Browse for Authors"
-Browse Home = "Browse Home"
-Browse the Catalog = "Browse the Catalog"
-Browse the Collection  = "Browse the Collection"
-Browse the Collection Alphabetically = "Browse the Collection Alphabetically"
-browse_dewey = "Call Number (Dewey)"
-browse_lcc = "Call Number (LC)"
-bulk_email_success = "Your item(s) were e-mailed"
-bulk_email_title = "Library Catalog Items"
-bulk_error_missing = "Some data was missing. Your request was not successful."
-bulk_export_not_supported = "The record(s) you have selected do not support bulk export."
-bulk_fail = "Sorry, an error has occurred. Please try again."
-bulk_noitems_advice = "No items were selected. Please click on a checkbox next to an item and try again."
-bulk_save_error = "Some data was missing. Your items were not saved."
-bulk_save_success = "Your item(s) were saved successfully"
-By = By
-by = by
-By Alphabetical = "By Alphabetical"
-By Author = "By Author"
-By Call Number = "By Call Number"
-By Course = "By Course"
-By Department = "By Department"
-By Era = "By Era"
-By Genre = "By Genre"
-By Instructor = "By Instructor"
-By Popularity = "By Popularity"
-By Recent = "By Recent"
-By Region = "By Region"
-By Title = "By Title"
-By Topic = "By Topic"
-Call Number = "Call Number"
-callnumber_abbrev = "Call #"
-Cannot find record = "Cannot find record"
-Cannot find similar records = "Cannot find similar records"
-Cassette = Cassette
-Catalog Results = "Catalog Results"
-cat_establish_account = "In order to establish your account profile, please enter the following information:"
-cat_password_abbrev = "Catalog Password"
-cat_username_abbrev = "Catalog Username"
-CD = CD
-Check Hold = "Check Hold"
-Check Recall = "Check Recall"
-Checked Out = "Checked Out"
-Checked Out Items = "Checked Out Items"
-Checkedout = "Checked Out"
-Choose a Category to Begin Browsing = "Choose a Category to Begin Browsing"
-Choose a Column to Begin Browsing = "Choose a Column to Begin Browsing"
-Choose a List = "Choose a List"
-citation_issue_abbrev = "no."
-citation_multipage_abbrev = "pp."
-citation_singlepage_abbrev = "p."
-citation_volume_abbrev = "Vol."
-Cite this = "Cite this"
-close = close
-Code = Code
-Collection Browse = "Collection Browse"
-Collection Items = "Collection Items"
-Collections = Collections
-collection_disambiguation = "Found Multiple Matching Collections"
-collection_empty = "No items to display."
-collection_view_record = "View Record"
-Comments = Comments
-comment_error_load = "Error: Could Not Redraw Comment List"
-comment_error_save = "Error: Could Not Save Comment"
-Configuration = "Configuration"
-confirm_delete = "Are you sure you want to delete this?"
-confirm_delete_brief = "Delete Item?"
-confirm_delete_list_brief = "Delete List?"
-confirm_delete_list_text = "Are you sure you want to delete this list?"
-confirm_dialog_no = Cancel
-confirm_dialog_yes = Confirm
-confirm_hold_cancel_all_text = "Do you wish to cancel all your current holds?"
-confirm_hold_cancel_selected_text = "Do you wish to cancel your selected holds?"
-Contents = Contents
-Contributors = "Contributors"
-Copies = Copies
-Copy = Copy
-Corporate Author = "Corporate Author"
-Course = Course
-Course Reserves = "Course Reserves"
-course_reserves_empty_list = "No matching Course Reserves found."
-Cover Image = "Cover Image"
-Create a List = "Create a List"
-Create New Account = "Create New Account"
-Created = Created
-Date = Date
-date_day_placeholder = "D"
-date_from = "From"
-date_month_placeholder = "M"
-date_to = "To"
-date_year_placeholder = "Y"
-Days = Days
-Debug Information = "Debug Information"
-Delete = Delete
-delete_comment_failure = "Could not delete comment."
-delete_comment_success = "Comment deleted."
-delete_list = "Delete List"
-delete_selected = "Delete Selected"
-delete_selected_favorites = "Delete Selected Favorites"
-del_search       = "Remove Search Group"
-Department = Department
-Description = Description
-Desired Username = "Desired Username"
-Details = "Staff View"
-Displaying the top = "Displaying the top"
-Document Inspector = "Document Inspector"
-Due = Due
-Due Date = "Due Date"
-DVD = DVD
-eBook = eBook
-Edit = Edit
-Edit this Advanced Search = "Edit this Advanced Search"
-Edition = Edition
-edit_list = "Edit List"
-edit_list_fail = "Sorry, you are not permitted to edit this list"
-edit_list_success = "List successfully updated."
-Electronic = Electronic
-Email = Email
-Email Address = "Email Address"
-Email address is invalid = "Email address is invalid"
-Email Record = "Email Record"
-Email this = "Email this"
-Email this Search = "Email this Search"
-email_failure = "Error - Message Cannot Be Sent"
-email_link = "Link"
-email_selected = "Email Selected"
-email_selected_favorites = "Email Selected Favorites"
-email_sending = "Sending Message..."
-email_success = "Message Sent"
-Empty = Empty
-Empty Book Bag = "Empty Book Bag"
-Enable Auto Config = "Enable Auto Config"
-End Page = "End Page"
-Era = Era
-error_inconsistent_parameters = "Sorry, an error has occurred. Inconsistent parameters detected."
-error_page_parameter_list_heading = "Request Parameters"
-Exception = Exception
-Excerpt = Excerpt
-exclude_newspapers = "Exclude newspaper articles"
-Expires = Expires
-Export = Export
-Export Favorites = "Export Favorites"
-Export Items = "Export Items"
-Export Record = "Export Record"
-Export to = "Export to "
-export_choose_format = "Please choose an export format."
-export_download = "Download File"
-export_exporting = "Creating Export File"
-export_fail = "Your items were not exported"
-export_invalid_format = "The selected export format is not supported by this record."
-export_missing = "Some data was missing. Your items were not exported."
-export_no_formats = "This record does not support export."
-export_redirect = "Start export to %%service%%"
-export_refworks = "Start export to RefWorks"
-export_save = "Save File"
-export_selected = "Export Selected"
-export_selected_favorites = "Export Selected Favorites"
-export_success = "Export Complete"
-export_unsupported_format = "Unsupported Export Format"
-FAQs = "FAQs"
-Favorites = Favorites
-fav_delete = "Delete Selected Favorites"
-fav_delete_deleting = "Your favorite(s) are being deleted."
-fav_delete_fail = "Sorry, an error has occurred. Your favorite(s) were not deleted."
-fav_delete_missing = "Some data was missing. Your favorite(s) were not deleted."
-fav_delete_success = "Your favorite(s) were deleted."
-fav_delete_warn = "You are about to delete these favorites from all your lists - If you want to delete favorites from a specific list only, please select the list before clicking delete."
-fav_email_fail = "Sorry, an error has occurred. Your favorite(s) were not e-mailed."
-fav_email_missing = "Some data was missing. Your favorite(s) were not emailed."
-fav_email_success = "Your favorite(s) were emailed as requested."
-fav_export = "Export Favorites"
-fav_list_delete = "List has been deleted"
-fav_list_delete_cancel = "This list was not deleted"
-fav_list_delete_fail = "Sorry, an error has occurred. Your list was not deleted."
-Fee = Fee
-filter_wildcard = "Any"
-Find = Find
-Find More = "Find More"
-Find New Items = "Find New Items"
-Finding Aid = "Finding Aid"
-Fine = Fine
-Fines = Fines
-fine_limit_patron = "You have reached your fines limit and cannot renew items"
-First Name = "First Name"
-fix_metadata = "Yes, fix the metadata; I'll wait"
-for search = "for search"
-Format = Format
-found = found
-From = "From"
-Full description = "Full description"
-fulltext_limit = "Limit to articles with full text available"
-Genre = Genre
-Geography = Geography
-Get full text = "Get full text"
-Get RSS Feed = "Get RSS Feed"
-Globe = Globe
-Go = "Go"
-Go to Standard View = "Go to Standard View"
-google_map_cluster = "Cluster"
-google_map_cluster_points = "Cluster Points"
-Grid = Grid
-Group = Group
-group_AND  = "ALL Groups"
-group_OR   = "ANY Groups"
-Has Illustrations = "Has Illustrations"
-Help with Advanced Search = "Help with Advanced Search"
-Help with Search Operators = "Help with Search Operators"
-hierarchy_hide_tree = "Hide Full Hierarchy"
-hierarchy_show_tree = "Show Full Hierarchy"
-hierarchy_tree = "Context"
-hierarchy_tree_error = "Sorry, we were unable to load the hierarchical tree"
-hierarchy_view_context = "View Context"
-History = History
-history_delete          = Delete
-history_delete_link     = Delete
-history_empty_search    = "Anything (empty search)"
-history_limits          = Limits
-history_no_searches     = "There are currently no searches in your history."
-history_purge           = "Purge my unsaved searches"
-history_recent_searches = "Your Recent Searches"
-history_results         = Results
-history_save            = Save?
-history_saved_searches  = "Your Saved Searches"
-history_save_link       = Save
-history_search          = Search
-history_time            = Time
-Holdings = Holdings
-Holdings at Other Libraries = "Holdings at Other Libraries"
-Holdings details from = "Holdings details from"
-Holds = Holds
-Holds and Recalls = "Holds and Recalls"
-hold_available = "Available for Pickup"
-hold_cancel = "Cancel Hold"
-hold_cancel_all = "Cancel All Holds"
-hold_cancel_fail = "Your request was not canceled. Please contact the circulation desk for further assistance"
-hold_cancel_selected = "Cancel Selected Holds"
-hold_cancel_success = "Your request was successfully canceled"
-hold_cancel_success_items = "request(s) were successfully canceled"
-hold_date_invalid = "Please enter a valid date"
-hold_date_past = "Please enter a date in the future"
-hold_empty_selection = "No holds were selected"
-hold_error_blocked = "You do not have sufficient privileges to place a hold on this item"
-hold_error_fail = "Your request failed. Please contact the circulation desk for further assistance"
-hold_invalid_pickup = "An invalid pick up location was entered. Please try again"
-hold_login = "for hold and recall information" 
-hold_place = "Place Request"
-hold_place_fail_missing = "Your request failed. Some data was missing. Please contact the circulation desk for further assistance"
-hold_place_success = "Your request was successful"
-hold_profile_html = "For hold and recall information, please establish your <a href="%%url%%">Library Catalog Profile</a>."
-hold_queue_position = "Queue Position"
-hold_required_by = "No longer required after"
-hold_success = "Your request was successful"
-Home = Home
-home_browse = "Browse by"
-Identifier = "Identifier"
-Illustrated = Illustrated
-ils_offline_holdings_message = "Holdings and item availability information is currently unavailable. Please accept our apologies for any inconvenience this may cause and contact us for further assistance:"
-ils_offline_home_message = "Your account details and live item information will be unavailable during this time. Please accept our apologies for any inconvenience this may cause and contact us for further assistance:"
-ils_offline_login_message = "Your account details will be unavailable during this time. Please accept our apologies for any inconvenience this may cause and contact us for further assistance:"
-ils_offline_status = "Our Library Management System is currently under maintenance."
-ils_offline_title = "System Under Maintenance"
-Import Record = "Import Record"
-Import to = "Import to "
-in = in
-In This Collection = "In This Collection"
-information = "Information"
-Institution = Institution
-Institutional Login = "Institutional Login"
-Instructor = Instructor
-Internet = Internet
-Invalid Patron Login = "Invalid Patron Login"
-Invalid phone number. = "Invalid phone number."
-Invalid Recipient Email Address = "Invalid Recipient Email Address"
-Invalid Sender Email Address = "Invalid Sender Email Address"
-in_collection_label = "In collection:"
-ISBN = ISBN
-ISBN/ISSN = "ISBN/ISSN"
-ISSN = ISSN
-Issue = Issue
-Item Description = "Item Description"
-Item removed from favorites = "Item removed from favorites"
-Item removed from list = "Item removed from list"
-Items = "Items"
-items = items
-items_added_to_bookbag = "item(s) added to your Book Bag"
-items_already_in_bookbag = "item(s) are either already in your Book Bag or could not be added"
-Journal = Journal
-Journal Articles = "Journal Articles"
-Journal Title = "Journal Title"
-Journals = Journals
-Jump to = "Jump to"
-Keyword = Keyword
-Keyword Filter = "Keyword Filter"
-Kit = Kit
-Language = Language
-large = "Large"
-Last Modified = "Last Modified"
-Last Name = "Last Name"
-less = less
-Library = Library
-Library Catalog Password = "Library Catalog Password"
-Library Catalog Profile = "Library Catalog Profile"
-Library Catalog Record = "Library Catalog Record"
-Library Catalog Search = "Library Catalog Search"
-Library Catalog Search Result = "Library Catalog Search Result"
-Library Catalog Username = "Library Catalog Username"
-Library Web Search = "Library Web Search"
-lightbox_error = "Error: Cannot Load Popup Box"
-Limit To = "Limit To"
-List = List
-list_access_denied = "You do not have permission to view this list."
-list_edit_name_required = "List name is required."
-Loading = Loading
-load_tag_error = "Error: Could Not Load Tags"
-Located = Located
-Location = Location
-Log Out = "Log Out"
-Login = Login
-login_disabled = "Login is not available at this time."
-Logout = Logout
-Main Author = "Main Author"
-Manuscript = Manuscript
-Map = Map
-Map View = "Map View"
-Maps = Maps
-map_results_label = "At this location:"
-Media Format = "Media Format"
-medium = "Medium"
-Message = Message
-Message From Sender = "Message From Sender"
-Metadata Prefix = "Metadata Prefix"
-Microfilm = Microfilm
-MLA Citation = "MLA Citation"
-mobile_link = "You appear to be on a mobile device; switch to mobile view?"
-more = more
-More catalog results = "More catalog results"
-More options = "More options"
-More Summon results = "More Summon results"
-more_info_toggle = "Show/hide more info."
-Most Recent Received Issues = "Most Recent Received Issues"
-Multiple Call Numbers = "Multiple Call Numbers"
-Multiple Locations = "Multiple Locations"
-Musical Score = "Musical Score"
-My Favorites = "My Favorites"
-My Fines = "My Fines"
-My Holds = "My Holds"
-My Profile = "My Profile"
-MyResearch Help = "MyResearch Help"
-Narrow Search = "Narrow Search"
-navigate_back = "Back"
-Need Help? = "Need Help?"
-New Item Feed = "New Item Feed"
-New Item Search = "New Item Search"
-New Item Search Results = "New Item Search Results"
-New Items = "New Items"
-New Title = "New Title"
-Newspaper = Newspaper
-Next = Next
-No citations are available for this record = "No citations are available for this record"
-No Cover Image = "No Cover Image"
-No dependency problems found = "No dependency problems found"
-No excerpts were found for this record. = "No excerpts were found for this record."
-No library account = "No library account"
-No new item information is currently available. = "No new item information is currently available."
-No Preference = "No Preference"
-No reviews were found for this record = "No reviews were found for this record"
-No Tags = "No Tags"
-nohit_filters  = "Filters currently applied to this search:"
-nohit_heading  = "No Results!"
-nohit_no_filters = "No filters were applied to this search."
-nohit_parse_error = "There seems to be a problem with your search query.  Please check the syntax.  If you are not trying to use advanced features, putting the query inside double quotes may help."
-nohit_prefix   = "Your search"
-nohit_spelling = "Perhaps you should try some spelling variations"
-nohit_suffix   = "did not match any resources."
-nohit_suggest = "You may want to try to revise your search phrase by removing some words or check your spelling."
-NOT = NOT
-Not Illustrated = "Not Illustrated"
-Not On Reserve = "Not On Reserve"
-Note = Note
-Notes = Notes
-note_760   = "Main series"
-note_765   = "Translation of"
-note_770   = "Has supplement"
-note_772   = "Supplement to"
-note_773   = "Contained in"
-note_774   = "Constituent unit"
-note_775   = "Other edition available"
-note_777   = "Issued with"
-note_780_0 = "Continues"
-note_780_1 = "Continues in part"
-note_780_2 = "Supersedes"
-note_780_3 = "Supersedes in part"
-note_780_4 = "Formed by"
-note_780_5 = "Absorbed"
-note_780_6 = "Absorbed in part"
-note_780_7 = "Separated from"
-note_785_0 = "Continued by"
-note_785_1 = "Continued in part by"
-note_785_2 = "Superseded by"
-note_785_3 = "Superseded in part by"
-note_785_4 = "Absorbed by"
-note_785_5 = "Absorbed in part by"
-note_785_6 = "Split into"
-note_785_7 = "Merged with"
-note_785_8 = "Changed back to"
-not_applicable = "n/a"
-no_description = "Description not available."
-no_items_selected = "No Items were Selected"
-Number = Number
-OAI Server = "OAI Server"
-of = of
-On Reserve - Ask at Circulation Desk = "On Reserve - Ask at Circulation Desk"
-On Reserve = "On Reserve"
-Online Access = "Online Access"
-on_reserve = "Reserves - Ask at Circulation"
-OR = OR
-or create a new list = "or create a new list"
-original = "Original"
-Other Authors = "Other Authors"
-Other Editions = "Other Editions"
-Other Libraries = "Other Libraries"
-Password = Password
-Password Again = "Password Again"
-Password cannot be blank = "Password cannot be blank"
-Passwords do not match = "Passwords do not match"
-Past = Past
-peer_reviewed_limit = "Limit to articles from peer-reviewed journals"
-Phone Number = "Phone Number"
-Photo = Photo
-Physical Description = "Physical Description"
-Physical Object = "Physical Object"
-pick_up_location = "Pickup Library"
-Place a Hold = "Place a Hold"
-Playing Time = "Playing Time"
-Please check back soon = "Please check back soon"
-Please contact the Library Reference Department for assistance = "Please contact the Library Reference Department for assistance"
-Posted by = "Posted by"
-posted_on = "on"
-Preferred Library = "Preferred Library"
-Prev = Prev
-Preview = "Preview"
-Preview from = "Preview from"
-Previous Title = "Previous Title"
-Print = Print
-print_selected = "Print Selected"
-Private = Private
-Production Credits = "Production Credits"
-Profile = Profile
-profile_update = "Your profile was updated as requested"
-Provider = Provider
-Public = Public
-Publication = Publication
-Publication Frequency = "Publication Frequency"
-Published = Published
-Published in = "Published in"
-query time = "query time"
-Range = Range
-Range slider = "Range slider"
-Read the full review online... = "Read the full review online..."
-Recall This = "Recall This"
-Record Citations = "Record Citations"
-Record Count = "Record Count"
-Region = Region
-Related Author = "Related Author"
-Related Items = "Related Items"
-Related Subjects = "Related Subjects"
-Remove Filters = "Remove Filters"
-Remove from Book Bag = "Remove from Book Bag"
-renew_all = "Renew All Items"
-renew_determine_fail = "We were unable to determine if your item can be renewed. Please contact a member of staff."
-renew_empty_selection = "No items were selected"
-renew_error = "We were unable to renew your item(s) - Please contact a member of staff"
-renew_fail = "This item could not be renewed"
-renew_item = "Renew Item"
-renew_item_due = "Item due within the next 24 hours"
-renew_item_limit = "This item has reached its renewal limit"
-renew_item_no = "This item cannot be renewed"
-renew_item_overdue = "Item Overdue"
-renew_item_requested ="This item has been requested by another user"
-renew_selected = "Renew Selected Items"
-renew_select_box = "Renew Item"
-renew_success = "Renewal Successful"
-Requests = "Requests"
-request_place_text = "Place a Request"
-request_submit_text = "Submit Request"
-Reserves = Reserves
-Reserves Search = "Reserves Search"
-Reserves Search Results = "Reserves Search Results"
-Results for = "Results for"
-Results per page = "Results per page"
-Resumption Token = "Resumption Token"
-Review by = "Review by"
-Reviews = Reviews
-Save = Save
-Save Comment = "Save Comment"
-Saved in = "Saved in"
-save_search        = "Save Search"
-save_search_remove = "Remove Saved Search"
-scholarly_limit = "Limit to articles from scholarly journals"
-Scroll to Load More = "Scroll to Load More"
-Search = Search
-Search For = "Search For"
-Search For Items on Reserve = "Search For Items on Reserve"
-Search History = "Search History"
-Search Home = "Search Home"
-Search Options = "Search Options"
-Search Results = "Search Results"
-search results of = "search results of"
-Search Tips = "Search Tips"
-Search Tools = "Search Tools"
-Search Type = "Search Type"
-search_AND = "ALL Terms"
-search_groups    = "Search Groups"
-search_match     = Match
-search_NOT = "NO Terms"
-search_OR  = "ANY Terms"
-search_save_success = "Search saved successfully."
-search_unsave_success = "Saved search removed successfully."
-see all = "see all"
-See also = "See also"
-Select this record = "Select this record"
-Select your carrier = "Select your carrier"
-Selected = "Selected"
-select_page = "Select Page"
-Send = Send
-Sensor Image = "Sensor Image"
-Serial = Serial
-Series = Series
-Set = Set
-Showing = Showing
-Similar Items = "Similar Items"
-skip_confirm = "Are you sure you want to skip this step?"
-skip_fix_metadata = "Do not fix the metadata at this time."
-skip_step = "Skip this step"
-Slide = Slide
-sms_failure = "Error!  Could not send message."
-sms_phone_number = "10-Digit Phone Number"
-sms_sending = "Sending message..."
-sms_success = "Message sent."
-Software = Software
-Sorry, but the help you requested is unavailable in your language. = "Sorry, but the help you requested is unavailable in your language."
-Sort = Sort
-sort_author     = Author
-sort_author_author     = Alphabetical
-sort_author_relevance  = Popularity
-sort_callnumber = "Call Number"
-sort_relevance  = Relevance
-sort_title      = Title
-sort_year       = "Date Descending"
-sort_year asc   = "Date Ascending"
-spell_expand_alt = "Expand Search"
-spell_suggest    = "Search alternatives"
-Staff View = "Staff View"
-Start a new Advanced Search = "Start a new Advanced Search"
-Start a new Basic Search = "Start a new Basic Search"
-Start Page = "Start Page"
-starting from = "starting from"
-Status = Status
-status_unknown_message = "Live Status Unavailable"
-Subcollection = Subcollection
-Subject = Subject
-Subject Area = "Subject Area"
-Subject Recommendations = "Subject Recommendations"
-Subjects = "Subjects"
-Submit = Submit
-Suggested Topics = "Suggested Topics"
-Summary = Summary
-Summon Results = "Summon Results"
-summon_database_recommendations = "You may find additional resources here:"
-Supplied by Amazon = "Supplied by Amazon"
-Switch view to = "Switch view to"
-System Unavailable = "System Unavailable"
-Table of Contents = "Table of Contents"
-Table of Contents unavailable = "Table of Contents unavailable"
-Tag = Tag
-Tags = Tags
-test_fail = "Failed"
-test_fix = "Fix"
-test_ok = "OK"
-Text this = "Text this"
-That email address is already used = "That email address is already used"
-That username is already taken = "That username is already taken"
-The record you selected is not part of any of your lists. = "The record you selected is not part of any of your lists."
-The record you selected is not part of the selected list. = "The record you selected is not part of the selected list."
-The system is currently unavailable due to system maintenance = "The system is currently unavailable due to system maintenance"
-Theme = Theme
-This email was sent from = "This email was sent from"
-This field is required = "This field is required"
-This item is already part of the following list/lists = "This item is already part of the following list/lists"
-Title = Title
-Title not available = "Title not available"
-title_hold_place = "Place a Title Level Request"
-To = "To"
-too_many_favorites = "This list is too large to display all at once.  Try rearranging your favorites into more lists or limiting using tags."
-too_many_new_items = "There are too many new items to display in a single list.  Try limiting your search."
-too_many_reserves = "There are too many course reserves to display in a single list.  Try limiting your search."
-Topic = Topic
-Topics = Topics
-top_facet_additional_prefix  = "Additional "
-top_facet_suffix             = "... within your search."
-tree_search_limit_reached_html = "Your search returned too many results to display in the tree. Showing only the first <b>%%limit%%</b> items. For a full search click <a id="fullSearchLink" href="%%url%%" target="_blank">here.</a>"
-University Library = "University Library"
-Unknown = Unknown
-Upgrade VuFind = "Upgrade VuFind"
-upgrade_description = "If you are upgrading a previous VuFind version, you can load your old settings with this tool."
-Use for = "Use for"
-Use instead = "Use instead"
-User Account = "User Account"
-Username = Username
-Username cannot be blank = "Username cannot be blank"
-VHS = VHS
-Video = Video
-Video Clips = "Video Clips"
-Videos = Videos
-view already selected = "view already selected"
-View Book Bag = "View Book Bag"
-View Full Collection = "View Full Collection"
-View Full Record = "View Full Record"
-View online: Full view Book Preview from the Hathi Trust = "View online: Full view Book Preview from the Hathi Trust"
-View Record = "View Record"
-View Records = "View Records"
-Volume = Volume
-Volume Holdings = "Volume Holdings"
-vudl_tab_docs = "Docs"
-vudl_tab_pages = "Pages"
-VuFind Configuration = "VuFind Configuration"
-vufind_upgrade_fail = "We cannot upgrade VuFind at this time"
-Warning: These citations may not always be 100% accurate = "Warning: These citations may not always be 100% accurate"
-wcterms_broader = "Broader Subjects"
-wcterms_exact = "Related Subjects"
-wcterms_narrower = "Narrower Subjects"
-Web = Web
-widen_prefix = "Try widening your search to"
-wiki_link = "Provided by Wikipedia"
-with filters = "with filters"
-with_selected = "with selected"
-Year of Publication = "Year of Publication"
-Yesterday = Yesterday
-You do not have any fines = "You do not have any fines"
-You do not have any holds or recalls placed = "You do not have any holds or recalls placed"
-You do not have any items checked out = "You do not have any items checked out"
-You do not have any saved resources = "You do not have any saved resources"
-You must be logged in first = "You must be logged in first"
-Your Account = "Your Account"
-Your book bag is empty = "Your book bag is empty"
-Your Checked Out Items = "Your Checked Out Items"
-Your Comment = "Your Comment"
-Your Favorites = "Your Favorites"
-Your Fines = "Your Fines"
-Your Holds and Recalls = "Your Holds and Recalls"
-Your Lists = "Your Lists"
-Your Profile = "Your Profile"
-Your search terms = "Your search terms"
-Your Tags = "Your Tags"
-Zip = Zip
-zoom = "Zoom"
+; For future reference:
+;English = English
+Access = Access
+Account = Account
+Add = Add
+Add a Note = "Add a Note"
+Add Tag = "Add Tag"
+Add Tags = "Add Tags"
+Add to another list = "Add to another list"
+Add to Book Bag = "Add to Book Bag"
+Add to favorites = "Add to Favorites"
+Add your comment = "Add your comment"
+Address = Address
+add_comment_fail_blank = "Comment cannot be blank."
+add_comment_success = "Comment added."
+add_favorite_fail = "Error: Record not saved"
+add_favorite_prefix = Add
+add_favorite_suffix = "to favorites"
+add_list_fail = "Error: List not created"
+add_other_libraries = "Include articles at other libraries"
+add_search       = "Add Search Field"
+add_search_group = "Add Search Group"
+add_tag_error = "Error: Could Not Save Tags"
+add_tag_note = "Spaces will separate tags.  Use quotes for multi-word tags."
+add_tag_success = "Tags Saved"
+Advanced = Advanced
+Advanced Search = "Advanced Search"
+advSearchError_noRights    = "I'm sorry, but you don't have permission to edit that search. Perhaps your browser session has expired?"
+advSearchError_notAdvanced = "The search you have requested to edit is not an advanced search."
+advSearchError_notFound    = "The search you have requested was not found."
+adv_search_all          = "All Fields"
+adv_search_author       = Author
+adv_search_callnumber   = "Call Number"
+adv_search_filters      = "Applied Filters"
+adv_search_isn          = ISBN/ISSN
+adv_search_journaltitle = "Journal Title"
+adv_search_label = "Search for"
+adv_search_publisher    = Publisher
+adv_search_select_all   = "select all"
+adv_search_series       = Series
+adv_search_subject      = Subject
+adv_search_title        = Title
+adv_search_toc          = "Table of Contents"
+adv_search_year         = "Year of Publication"
+All Fields = "All Fields"
+All Pages Loaded = "All Pages Loaded"
+alphabrowse_matches = "Titles"
+An error has occurred = "An error has occurred"
+AND = AND
+APA Citation = "APA Citation"
+Ask a Librarian = "Ask a Librarian"
+Audience = Audience
+Audio = Audio
+authentication_error_admin = "We cannot log you in at this time.  Please contact your system administrator for assistance."
+authentication_error_blank = "Login information cannot be blank."
+authentication_error_denied = "Credentials do not match! Access denied."
+authentication_error_invalid = "Invalid login -- please try again."
+authentication_error_technical = "We cannot log you in at this time.  Please try again later."
+Author = Author
+Author Browse = "Author Browse"
+Author Notes = "Author Notes"
+Author Results for = "Author Results for"
+Author Search Results = "Author Search Results"
+Authors Related to Your Search = "Authors Related to Your Search"
+Auto configuration is currently disabled = "Auto configuration is currently disabled"
+auto_configure_description = "If this is a new installation, you may be able to fix the error using VuFind's Auto Configure tool."
+auto_configure_disabled = "Auto configuration is disabled."
+auto_configure_title = "Auto Configure"
+Available = Available
+Available Functionality = "Available Functionality"
+Awards = Awards
+Back to Record = "Back to Record"
+Back to Search Results = "Back to Search Results"
+Backtrace = Backtrace
+Bag = Bag
+Balance = Balance
+basic_search_keep_filters = "Retain my current filters"
+Be the first to leave a comment = "Be the first to leave a comment"
+Be the first to tag this record = "Be the first to tag this record"
+Bibliographic Details = "Bibliographic Details"
+Bibliography = Bibliography
+Book = Book
+Book Bag = "Book Bag"
+Book Cover = "Book Cover"
+bookbag_confirm_empty = "Are you sure you want to empty your Book Bag?"
+bookbag_delete = "Delete Selected Book Bag Items"
+bookbag_delete_selected = "Delete Selected"
+bookbag_email = "Email Selected Book Bag Items"
+bookbag_email_selected  = "Email Selected"
+bookbag_export = "Export Selected Book Bag Items"
+bookbag_export_selected  = "Export Selected"
+bookbag_full = "Full"
+bookbag_full_msg = "Your Book Bag is Full"
+bookbag_is_empty = "Your Book Bag is empty"
+bookbag_print_selected  = "Print Selected"
+bookbag_save = "Save Selected Book Bag Items"
+bookbag_save_selected  = "Save Selected"
+Bookmark = Bookmark
+Books = Books
+Braille = Braille
+Browse = Browse
+Browse Alphabetically = "Browse Alphabetically"
+Browse for Authors = "Browse for Authors"
+Browse Home = "Browse Home"
+Browse the Catalog = "Browse the Catalog"
+Browse the Collection  = "Browse the Collection"
+Browse the Collection Alphabetically = "Browse the Collection Alphabetically"
+browse_dewey = "Call Number (Dewey)"
+browse_lcc = "Call Number (LC)"
+bulk_email_success = "Your item(s) were e-mailed"
+bulk_email_title = "Library Catalog Items"
+bulk_error_missing = "Some data was missing. Your request was not successful."
+bulk_export_not_supported = "The record(s) you have selected do not support bulk export."
+bulk_fail = "Sorry, an error has occurred. Please try again."
+bulk_noitems_advice = "No items were selected. Please click on a checkbox next to an item and try again."
+bulk_save_error = "Some data was missing. Your items were not saved."
+bulk_save_success = "Your item(s) were saved successfully"
+By = By
+by = by
+By Alphabetical = "By Alphabetical"
+By Author = "By Author"
+By Call Number = "By Call Number"
+By Course = "By Course"
+By Department = "By Department"
+By Era = "By Era"
+By Genre = "By Genre"
+By Instructor = "By Instructor"
+By Popularity = "By Popularity"
+By Recent = "By Recent"
+By Region = "By Region"
+By Title = "By Title"
+By Topic = "By Topic"
+Call Number = "Call Number"
+callnumber_abbrev = "Call #"
+Cannot find record = "Cannot find record"
+Cannot find similar records = "Cannot find similar records"
+Cassette = Cassette
+Catalog Results = "Catalog Results"
+cat_establish_account = "In order to establish your account profile, please enter the following information:"
+cat_password_abbrev = "Catalog Password"
+cat_username_abbrev = "Catalog Username"
+CD = CD
+Check Hold = "Check Hold"
+Check Recall = "Check Recall"
+Checked Out = "Checked Out"
+Checked Out Items = "Checked Out Items"
+Checkedout = "Checked Out"
+Choose a Category to Begin Browsing = "Choose a Category to Begin Browsing"
+Choose a Column to Begin Browsing = "Choose a Column to Begin Browsing"
+Choose a List = "Choose a List"
+citation_issue_abbrev = "no."
+citation_multipage_abbrev = "pp."
+citation_singlepage_abbrev = "p."
+citation_volume_abbrev = "Vol."
+Cite this = "Cite this"
+close = close
+Code = Code
+Collection Browse = "Collection Browse"
+Collection Items = "Collection Items"
+Collections = Collections
+collection_disambiguation = "Found Multiple Matching Collections"
+collection_empty = "No items to display."
+collection_view_record = "View Record"
+Comments = Comments
+comment_error_load = "Error: Could Not Redraw Comment List"
+comment_error_save = "Error: Could Not Save Comment"
+Configuration = "Configuration"
+confirm_delete = "Are you sure you want to delete this?"
+confirm_delete_brief = "Delete Item?"
+confirm_delete_list_brief = "Delete List?"
+confirm_delete_list_text = "Are you sure you want to delete this list?"
+confirm_dialog_no = Cancel
+confirm_dialog_yes = Confirm
+confirm_hold_cancel_all_text = "Do you wish to cancel all your current holds?"
+confirm_hold_cancel_selected_text = "Do you wish to cancel your selected holds?"
+Contents = Contents
+Contributors = "Contributors"
+Copies = Copies
+Copy = Copy
+Corporate Author = "Corporate Author"
+Course = Course
+Course Reserves = "Course Reserves"
+course_reserves_empty_list = "No matching Course Reserves found."
+Cover Image = "Cover Image"
+Create a List = "Create a List"
+Create New Account = "Create New Account"
+Created = Created
+Date = Date
+date_day_placeholder = "D"
+date_from = "From"
+date_month_placeholder = "M"
+date_to = "To"
+date_year_placeholder = "Y"
+Days = Days
+Debug Information = "Debug Information"
+Delete = Delete
+delete_comment_failure = "Could not delete comment."
+delete_comment_success = "Comment deleted."
+delete_list = "Delete List"
+delete_selected = "Delete Selected"
+delete_selected_favorites = "Delete Selected Favorites"
+del_search       = "Remove Search Group"
+Department = Department
+Description = Description
+Desired Username = "Desired Username"
+Details = "Staff View"
+Displaying the top = "Displaying the top"
+Document Inspector = "Document Inspector"
+Due = Due
+Due Date = "Due Date"
+DVD = DVD
+eBook = eBook
+Edit = Edit
+Edit this Advanced Search = "Edit this Advanced Search"
+Edition = Edition
+edit_list = "Edit List"
+edit_list_fail = "Sorry, you are not permitted to edit this list"
+edit_list_success = "List successfully updated."
+Electronic = Electronic
+Email = Email
+Email Address = "Email Address"
+Email address is invalid = "Email address is invalid"
+Email Record = "Email Record"
+Email this = "Email this"
+Email this Search = "Email this Search"
+email_failure = "Error - Message Cannot Be Sent"
+email_link = "Link"
+email_selected = "Email Selected"
+email_selected_favorites = "Email Selected Favorites"
+email_sending = "Sending Message..."
+email_success = "Message Sent"
+Empty = Empty
+Empty Book Bag = "Empty Book Bag"
+Enable Auto Config = "Enable Auto Config"
+End Page = "End Page"
+Era = Era
+error_inconsistent_parameters = "Sorry, an error has occurred. Inconsistent parameters detected."
+error_page_parameter_list_heading = "Request Parameters"
+Exception = Exception
+Excerpt = Excerpt
+exclude_newspapers = "Exclude newspaper articles"
+Expires = Expires
+Export = Export
+Export Favorites = "Export Favorites"
+Export Items = "Export Items"
+Export Record = "Export Record"
+Export to = "Export to "
+export_choose_format = "Please choose an export format."
+export_download = "Download File"
+export_exporting = "Creating Export File"
+export_fail = "Your items were not exported"
+export_invalid_format = "The selected export format is not supported by this record."
+export_missing = "Some data was missing. Your items were not exported."
+export_no_formats = "This record does not support export."
+export_redirect = "Start export to %%service%%"
+export_refworks = "Start export to RefWorks"
+export_save = "Save File"
+export_selected = "Export Selected"
+export_selected_favorites = "Export Selected Favorites"
+export_success = "Export Complete"
+export_unsupported_format = "Unsupported Export Format"
+FAQs = "FAQs"
+Favorites = Favorites
+fav_delete = "Delete Selected Favorites"
+fav_delete_deleting = "Your favorite(s) are being deleted."
+fav_delete_fail = "Sorry, an error has occurred. Your favorite(s) were not deleted."
+fav_delete_missing = "Some data was missing. Your favorite(s) were not deleted."
+fav_delete_success = "Your favorite(s) were deleted."
+fav_delete_warn = "You are about to delete these favorites from all your lists - If you want to delete favorites from a specific list only, please select the list before clicking delete."
+fav_email_fail = "Sorry, an error has occurred. Your favorite(s) were not e-mailed."
+fav_email_missing = "Some data was missing. Your favorite(s) were not emailed."
+fav_email_success = "Your favorite(s) were emailed as requested."
+fav_export = "Export Favorites"
+fav_list_delete = "List has been deleted"
+fav_list_delete_cancel = "This list was not deleted"
+fav_list_delete_fail = "Sorry, an error has occurred. Your list was not deleted."
+Fee = Fee
+Feedback Email = "Feedback Email"
+feedback_name = "Name"
+filter_wildcard = "Any"
+Find = Find
+Find More = "Find More"
+Find New Items = "Find New Items"
+Finding Aid = "Finding Aid"
+Fine = Fine
+Fines = Fines
+fine_limit_patron = "You have reached your fines limit and cannot renew items"
+First Name = "First Name"
+fix_metadata = "Yes, fix the metadata; I'll wait"
+for search = "for search"
+Form Submitted! = "Form Submitted!"
+Format = Format
+found = found
+From = "From"
+Full description = "Full description"
+fulltext_limit = "Limit to articles with full text available"
+Genre = Genre
+Geography = Geography
+Get full text = "Get full text"
+Get RSS Feed = "Get RSS Feed"
+Globe = Globe
+Go = "Go"
+Go to Standard View = "Go to Standard View"
+google_map_cluster = "Cluster"
+google_map_cluster_points = "Cluster Points"
+Grid = Grid
+Group = Group
+group_AND  = "ALL Groups"
+group_OR   = "ANY Groups"
+Has Illustrations = "Has Illustrations"
+Help with Advanced Search = "Help with Advanced Search"
+Help with Search Operators = "Help with Search Operators"
+hierarchy_hide_tree = "Hide Full Hierarchy"
+hierarchy_show_tree = "Show Full Hierarchy"
+hierarchy_tree = "Context"
+hierarchy_tree_error = "Sorry, we were unable to load the hierarchical tree"
+hierarchy_view_context = "View Context"
+History = History
+history_delete          = Delete
+history_delete_link     = Delete
+history_empty_search    = "Anything (empty search)"
+history_limits          = Limits
+history_no_searches     = "There are currently no searches in your history."
+history_purge           = "Purge my unsaved searches"
+history_recent_searches = "Your Recent Searches"
+history_results         = Results
+history_save            = Save?
+history_saved_searches  = "Your Saved Searches"
+history_save_link       = Save
+history_search          = Search
+history_time            = Time
+Holdings = Holdings
+Holdings at Other Libraries = "Holdings at Other Libraries"
+Holdings details from = "Holdings details from"
+Holds = Holds
+Holds and Recalls = "Holds and Recalls"
+hold_available = "Available for Pickup"
+hold_cancel = "Cancel Hold"
+hold_cancel_all = "Cancel All Holds"
+hold_cancel_fail = "Your request was not canceled. Please contact the circulation desk for further assistance"
+hold_cancel_selected = "Cancel Selected Holds"
+hold_cancel_success = "Your request was successfully canceled"
+hold_cancel_success_items = "request(s) were successfully canceled"
+hold_date_invalid = "Please enter a valid date"
+hold_date_past = "Please enter a date in the future"
+hold_empty_selection = "No holds were selected"
+hold_error_blocked = "You do not have sufficient privileges to place a hold on this item"
+hold_error_fail = "Your request failed. Please contact the circulation desk for further assistance"
+hold_invalid_pickup = "An invalid pick up location was entered. Please try again"
+hold_login = "for hold and recall information" 
+hold_place = "Place Request"
+hold_place_fail_missing = "Your request failed. Some data was missing. Please contact the circulation desk for further assistance"
+hold_place_success = "Your request was successful"
+hold_profile_html = "For hold and recall information, please establish your <a href="%%url%%">Library Catalog Profile</a>."
+hold_queue_position = "Queue Position"
+hold_required_by = "No longer required after"
+hold_success = "Your request was successful"
+Home = Home
+home_browse = "Browse by"
+Identifier = "Identifier"
+Illustrated = Illustrated
+ils_offline_holdings_message = "Holdings and item availability information is currently unavailable. Please accept our apologies for any inconvenience this may cause and contact us for further assistance:"
+ils_offline_home_message = "Your account details and live item information will be unavailable during this time. Please accept our apologies for any inconvenience this may cause and contact us for further assistance:"
+ils_offline_login_message = "Your account details will be unavailable during this time. Please accept our apologies for any inconvenience this may cause and contact us for further assistance:"
+ils_offline_status = "Our Library Management System is currently under maintenance."
+ils_offline_title = "System Under Maintenance"
+Import Record = "Import Record"
+Import to = "Import to "
+in = in
+In This Collection = "In This Collection"
+information = "Information"
+Institution = Institution
+Institutional Login = "Institutional Login"
+Instructor = Instructor
+Internet = Internet
+Invalid Patron Login = "Invalid Patron Login"
+Invalid phone number. = "Invalid phone number."
+Invalid Recipient Email Address = "Invalid Recipient Email Address"
+Invalid Sender Email Address = "Invalid Sender Email Address"
+in_collection_label = "In collection:"
+ISBN = ISBN
+ISBN/ISSN = "ISBN/ISSN"
+ISSN = ISSN
+Issue = Issue
+Item Description = "Item Description"
+Item removed from favorites = "Item removed from favorites"
+Item removed from list = "Item removed from list"
+Items = "Items"
+items = items
+items_added_to_bookbag = "item(s) added to your Book Bag"
+items_already_in_bookbag = "item(s) are either already in your Book Bag or could not be added"
+Journal = Journal
+Journal Articles = "Journal Articles"
+Journal Title = "Journal Title"
+Journals = Journals
+Jump to = "Jump to"
+Keyword = Keyword
+Keyword Filter = "Keyword Filter"
+Kit = Kit
+Language = Language
+large = "Large"
+Last Modified = "Last Modified"
+Last Name = "Last Name"
+less = less
+Library = Library
+Library Catalog Password = "Library Catalog Password"
+Library Catalog Profile = "Library Catalog Profile"
+Library Catalog Record = "Library Catalog Record"
+Library Catalog Search = "Library Catalog Search"
+Library Catalog Search Result = "Library Catalog Search Result"
+Library Catalog Username = "Library Catalog Username"
+Library Web Search = "Library Web Search"
+lightbox_error = "Error: Cannot Load Popup Box"
+Limit To = "Limit To"
+List = List
+list_access_denied = "You do not have permission to view this list."
+list_edit_name_required = "List name is required."
+Loading = Loading
+load_tag_error = "Error: Could Not Load Tags"
+Located = Located
+Location = Location
+Log Out = "Log Out"
+Login = Login
+login_disabled = "Login is not available at this time."
+Logout = Logout
+Main Author = "Main Author"
+Manuscript = Manuscript
+Map = Map
+Map View = "Map View"
+Maps = Maps
+map_results_label = "At this location:"
+Media Format = "Media Format"
+medium = "Medium"
+Message = Message
+Message From Sender = "Message From Sender"
+Metadata Prefix = "Metadata Prefix"
+Microfilm = Microfilm
+MLA Citation = "MLA Citation"
+mobile_link = "You appear to be on a mobile device; switch to mobile view?"
+more = more
+More catalog results = "More catalog results"
+More options = "More options"
+More Summon results = "More Summon results"
+more_info_toggle = "Show/hide more info."
+Most Recent Received Issues = "Most Recent Received Issues"
+Multiple Call Numbers = "Multiple Call Numbers"
+Multiple Locations = "Multiple Locations"
+Musical Score = "Musical Score"
+My Favorites = "My Favorites"
+My Fines = "My Fines"
+My Holds = "My Holds"
+My Profile = "My Profile"
+MyResearch Help = "MyResearch Help"
+Narrow Search = "Narrow Search"
+navigate_back = "Back"
+Need Help? = "Need Help?"
+New Item Feed = "New Item Feed"
+New Item Search = "New Item Search"
+New Item Search Results = "New Item Search Results"
+New Items = "New Items"
+New Title = "New Title"
+Newspaper = Newspaper
+Next = Next
+No citations are available for this record = "No citations are available for this record"
+No Cover Image = "No Cover Image"
+No dependency problems found = "No dependency problems found"
+No excerpts were found for this record. = "No excerpts were found for this record."
+No library account = "No library account"
+No new item information is currently available. = "No new item information is currently available."
+No Preference = "No Preference"
+No reviews were found for this record = "No reviews were found for this record"
+No Tags = "No Tags"
+nohit_filters  = "Filters currently applied to this search:"
+nohit_heading  = "No Results!"
+nohit_no_filters = "No filters were applied to this search."
+nohit_parse_error = "There seems to be a problem with your search query.  Please check the syntax.  If you are not trying to use advanced features, putting the query inside double quotes may help."
+nohit_prefix   = "Your search"
+nohit_spelling = "Perhaps you should try some spelling variations"
+nohit_suffix   = "did not match any resources."
+nohit_suggest = "You may want to try to revise your search phrase by removing some words or check your spelling."
+NOT = NOT
+Not Illustrated = "Not Illustrated"
+Not On Reserve = "Not On Reserve"
+Note = Note
+Notes = Notes
+note_760   = "Main series"
+note_765   = "Translation of"
+note_770   = "Has supplement"
+note_772   = "Supplement to"
+note_773   = "Contained in"
+note_774   = "Constituent unit"
+note_775   = "Other edition available"
+note_777   = "Issued with"
+note_780_0 = "Continues"
+note_780_1 = "Continues in part"
+note_780_2 = "Supersedes"
+note_780_3 = "Supersedes in part"
+note_780_4 = "Formed by"
+note_780_5 = "Absorbed"
+note_780_6 = "Absorbed in part"
+note_780_7 = "Separated from"
+note_785_0 = "Continued by"
+note_785_1 = "Continued in part by"
+note_785_2 = "Superseded by"
+note_785_3 = "Superseded in part by"
+note_785_4 = "Absorbed by"
+note_785_5 = "Absorbed in part by"
+note_785_6 = "Split into"
+note_785_7 = "Merged with"
+note_785_8 = "Changed back to"
+not_applicable = "n/a"
+no_description = "Description not available."
+no_items_selected = "No Items were Selected"
+Number = Number
+OAI Server = "OAI Server"
+of = of
+On Reserve - Ask at Circulation Desk = "On Reserve - Ask at Circulation Desk"
+On Reserve = "On Reserve"
+Online Access = "Online Access"
+on_reserve = "Reserves - Ask at Circulation"
+OR = OR
+or create a new list = "or create a new list"
+original = "Original"
+Other Authors = "Other Authors"
+Other Editions = "Other Editions"
+Other Libraries = "Other Libraries"
+Password = Password
+Password Again = "Password Again"
+Password cannot be blank = "Password cannot be blank"
+Passwords do not match = "Passwords do not match"
+Past = Past
+peer_reviewed_limit = "Limit to articles from peer-reviewed journals"
+Phone Number = "Phone Number"
+Photo = Photo
+Physical Description = "Physical Description"
+Physical Object = "Physical Object"
+pick_up_location = "Pickup Library"
+Place a Hold = "Place a Hold"
+Playing Time = "Playing Time"
+Please check back soon = "Please check back soon"
+Please contact the Library Reference Department for assistance = "Please contact the Library Reference Department for assistance"
+Please enable JavaScript. = "Please enable JavaScript."
+Posted by = "Posted by"
+posted_on = "on"
+Preferred Library = "Preferred Library"
+Prev = Prev
+Preview = "Preview"
+Preview from = "Preview from"
+Previous Title = "Previous Title"
+Print = Print
+print_selected = "Print Selected"
+Private = Private
+Production Credits = "Production Credits"
+Profile = Profile
+profile_update = "Your profile was updated as requested"
+Provider = Provider
+Public = Public
+Publication = Publication
+Publication Frequency = "Publication Frequency"
+Published = Published
+Published in = "Published in"
+query time = "query time"
+Range = Range
+Range slider = "Range slider"
+Read the full review online... = "Read the full review online..."
+Recall This = "Recall This"
+Record Citations = "Record Citations"
+Record Count = "Record Count"
+Region = Region
+Related Author = "Related Author"
+Related Items = "Related Items"
+Related Subjects = "Related Subjects"
+Remove Filters = "Remove Filters"
+Remove from Book Bag = "Remove from Book Bag"
+renew_all = "Renew All Items"
+renew_determine_fail = "We were unable to determine if your item can be renewed. Please contact a member of staff."
+renew_empty_selection = "No items were selected"
+renew_error = "We were unable to renew your item(s) - Please contact a member of staff"
+renew_fail = "This item could not be renewed"
+renew_item = "Renew Item"
+renew_item_due = "Item due within the next 24 hours"
+renew_item_limit = "This item has reached its renewal limit"
+renew_item_no = "This item cannot be renewed"
+renew_item_overdue = "Item Overdue"
+renew_item_requested ="This item has been requested by another user"
+renew_selected = "Renew Selected Items"
+renew_select_box = "Renew Item"
+renew_success = "Renewal Successful"
+Requests = "Requests"
+request_place_text = "Place a Request"
+request_submit_text = "Submit Request"
+Reserves = Reserves
+Reserves Search = "Reserves Search"
+Reserves Search Results = "Reserves Search Results"
+Results for = "Results for"
+Results per page = "Results per page"
+Resumption Token = "Resumption Token"
+Review by = "Review by"
+Reviews = Reviews
+Save = Save
+Save Comment = "Save Comment"
+Saved in = "Saved in"
+save_search        = "Save Search"
+save_search_remove = "Remove Saved Search"
+scholarly_limit = "Limit to articles from scholarly journals"
+Scroll to Load More = "Scroll to Load More"
+Search = Search
+Search For = "Search For"
+Search For Items on Reserve = "Search For Items on Reserve"
+Search History = "Search History"
+Search Home = "Search Home"
+Search Options = "Search Options"
+Search Results = "Search Results"
+search results of = "search results of"
+Search Tips = "Search Tips"
+Search Tools = "Search Tools"
+Search Type = "Search Type"
+search_AND = "ALL Terms"
+search_groups    = "Search Groups"
+search_match     = Match
+search_NOT = "NO Terms"
+search_OR  = "ANY Terms"
+search_save_success = "Search saved successfully."
+search_unsave_success = "Saved search removed successfully."
+see all = "see all"
+See also = "See also"
+Select this record = "Select this record"
+Select your carrier = "Select your carrier"
+Selected = "Selected"
+select_page = "Select Page"
+Send = Send
+Send us your feedback! = "Send us your feedback!"
+Sensor Image = "Sensor Image"
+Serial = Serial
+Series = Series
+Set = Set
+Showing = Showing
+Similar Items = "Similar Items"
+skip_confirm = "Are you sure you want to skip this step?"
+skip_fix_metadata = "Do not fix the metadata at this time."
+skip_step = "Skip this step"
+Slide = Slide
+sms_failure = "Error!  Could not send message."
+sms_phone_number = "10-Digit Phone Number"
+sms_sending = "Sending message..."
+sms_success = "Message sent."
+Software = Software
+Sorry, but the help you requested is unavailable in your language. = "Sorry, but the help you requested is unavailable in your language."
+Sort = Sort
+sort_author     = Author
+sort_author_author     = Alphabetical
+sort_author_relevance  = Popularity
+sort_callnumber = "Call Number"
+sort_relevance  = Relevance
+sort_title      = Title
+sort_year       = "Date Descending"
+sort_year asc   = "Date Ascending"
+spell_expand_alt = "Expand Search"
+spell_suggest    = "Search alternatives"
+Staff View = "Staff View"
+Start a new Advanced Search = "Start a new Advanced Search"
+Start a new Basic Search = "Start a new Basic Search"
+Start Page = "Start Page"
+starting from = "starting from"
+Status = Status
+status_unknown_message = "Live Status Unavailable"
+Subcollection = Subcollection
+Subject = Subject
+Subject Area = "Subject Area"
+Subject Recommendations = "Subject Recommendations"
+Subjects = "Subjects"
+Submit = Submit
+Suggested Topics = "Suggested Topics"
+Summary = Summary
+Summon Results = "Summon Results"
+summon_database_recommendations = "You may find additional resources here:"
+Supplied by Amazon = "Supplied by Amazon"
+Switch view to = "Switch view to"
+System Unavailable = "System Unavailable"
+Table of Contents = "Table of Contents"
+Table of Contents unavailable = "Table of Contents unavailable"
+Tag = Tag
+Tags = Tags
+test_fail = "Failed"
+test_fix = "Fix"
+test_ok = "OK"
+Text this = "Text this"
+Thank you for your feedback. = "Thank you for your feedback."
+That email address is already used = "That email address is already used"
+That username is already taken = "That username is already taken"
+The record you selected is not part of any of your lists. = "The record you selected is not part of any of your lists."
+The record you selected is not part of the selected list. = "The record you selected is not part of the selected list."
+The system is currently unavailable due to system maintenance = "The system is currently unavailable due to system maintenance"
+Theme = Theme
+This email was sent from = "This email was sent from"
+This field is required = "This field is required"
+This item is already part of the following list/lists = "This item is already part of the following list/lists"
+Title = Title
+Title not available = "Title not available"
+title_hold_place = "Place a Title Level Request"
+To = "To"
+too_many_favorites = "This list is too large to display all at once.  Try rearranging your favorites into more lists or limiting using tags."
+too_many_new_items = "There are too many new items to display in a single list.  Try limiting your search."
+too_many_reserves = "There are too many course reserves to display in a single list.  Try limiting your search."
+Topic = Topic
+Topics = Topics
+top_facet_additional_prefix  = "Additional "
+top_facet_suffix             = "... within your search."
+tree_search_limit_reached_html = "Your search returned too many results to display in the tree. Showing only the first <b>%%limit%%</b> items. For a full search click <a id="fullSearchLink" href="%%url%%" target="_blank">here.</a>"
+University Library = "University Library"
+Unknown = Unknown
+Upgrade VuFind = "Upgrade VuFind"
+upgrade_description = "If you are upgrading a previous VuFind version, you can load your old settings with this tool."
+Use for = "Use for"
+Use instead = "Use instead"
+User Account = "User Account"
+Username = Username
+Username cannot be blank = "Username cannot be blank"
+VHS = VHS
+Video = Video
+Video Clips = "Video Clips"
+Videos = Videos
+view already selected = "view already selected"
+View Book Bag = "View Book Bag"
+View Full Collection = "View Full Collection"
+View Full Record = "View Full Record"
+View online: Full view Book Preview from the Hathi Trust = "View online: Full view Book Preview from the Hathi Trust"
+View Record = "View Record"
+View Records = "View Records"
+Volume = Volume
+Volume Holdings = "Volume Holdings"
+vudl_tab_docs = "Docs"
+vudl_tab_pages = "Pages"
+VuFind Configuration = "VuFind Configuration"
+vufind_upgrade_fail = "We cannot upgrade VuFind at this time"
+Warning: These citations may not always be 100% accurate = "Warning: These citations may not always be 100% accurate"
+wcterms_broader = "Broader Subjects"
+wcterms_exact = "Related Subjects"
+wcterms_narrower = "Narrower Subjects"
+Web = Web
+widen_prefix = "Try widening your search to"
+wiki_link = "Provided by Wikipedia"
+with filters = "with filters"
+with_selected = "with selected"
+Year of Publication = "Year of Publication"
+Yesterday = Yesterday
+You do not have any fines = "You do not have any fines"
+You do not have any holds or recalls placed = "You do not have any holds or recalls placed"
+You do not have any items checked out = "You do not have any items checked out"
+You do not have any saved resources = "You do not have any saved resources"
+You must be logged in first = "You must be logged in first"
+Your Account = "Your Account"
+Your book bag is empty = "Your book bag is empty"
+Your Checked Out Items = "Your Checked Out Items"
+Your Comment = "Your Comment"
+Your Favorites = "Your Favorites"
+Your Fines = "Your Fines"
+Your Holds and Recalls = "Your Holds and Recalls"
+Your Lists = "Your Lists"
+Your Profile = "Your Profile"
+Your search terms = "Your search terms"
+Your Tags = "Your Tags"
+Zip = Zip
+zoom = "Zoom"
diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php
index 6aff258f76b..546c01d447b 100644
--- a/module/VuFind/config/module.config.php
+++ b/module/VuFind/config/module.config.php
@@ -105,6 +105,7 @@ $config = array(
             'cart' => 'VuFind\Controller\CartController',
             'cover' => 'VuFind\Controller\CoverController',
             'error' => 'VuFind\Controller\ErrorController',
+            'feedback' => 'VuFind\Controller\FeedbackController',
             'help' => 'VuFind\Controller\HelpController',
             'hierarchy' => 'VuFind\Controller\HierarchyController',
             'index' => 'VuFind\Controller\IndexController',
@@ -848,7 +849,8 @@ $staticRoutes = array(
     'Browse/LCC', 'Browse/Region', 'Browse/Tag', 'Browse/Topic',
     'Cart/doExport', 'Cart/Email', 'Cart/Export', 'Cart/Home', 'Cart/MyResearchBulk',
     'Cart/Save', 'Collections/ByTitle', 'Collections/Home',
-    'Cover/Show', 'Cover/Unavailable', 'Error/Unavailable', 'Help/Home',
+    'Cover/Show', 'Cover/Unavailable', 'Error/Unavailable',
+    'Feedback/Email', 'Feedback/Home', 'Help/Home',
     'Install/Done', 'Install/FixBasicConfig', 'Install/FixCache',
     'Install/FixDatabase', 'Install/FixDependencies', 'Install/FixILS',
     'Install/FixSecurity', 'Install/FixSolr', 'Install/Home',
diff --git a/module/VuFind/src/VuFind/Controller/FeedbackController.php b/module/VuFind/src/VuFind/Controller/FeedbackController.php
new file mode 100644
index 00000000000..4164936a6fd
--- /dev/null
+++ b/module/VuFind/src/VuFind/Controller/FeedbackController.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Feedback Controller
+ *
+ * PHP version 5
+ *
+ * @category VuFind2
+ * @package  Controller
+ * @author   Josiah Knoll <jk1135@ship.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org   Main Site
+ */
+namespace VuFind\Controller;
+use Zend\Mail as Mail;
+
+/**
+ * Feedback Class
+ *
+ * Controls the Feedback
+ *
+ * @category VuFind2
+ * @package  Controller
+ * @author   Josiah Knoll <jk1135@ship.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org/wiki/building_a_recommendations_module Wiki
+ */
+class FeedbackController extends AbstractBase
+{
+    /**
+     * Display Feedback home form.
+     *
+     * @return \Zend\View\Model\ViewModel
+     */
+    public function homeAction()
+    {
+        // no action needed
+        return $this->createViewModel();
+    }
+
+    /**
+     * Recieves input from the user and sends an email to the recipient set in
+     * the config.ini
+     *
+     * @return void
+     */
+    public function emailAction()
+    {
+        $name = $this->params()->fromPost('name', 'No Name Given');
+        $users_email = $this->params()->fromPost('email', 'user@noemail.com');
+        $comments = $this->params()->fromPost('comments', '');
+
+        // These settings are set in the feedback settion of your config.ini
+        $config = $this->getServiceLocator()->get('VuFind\Config')->get('config');
+        $feedback = isset($config->Feedback) ? $config->Feedback : null;
+        $recipient_email = isset($feedback->recipient_email)
+            ? $feedback->recipient_email : null;
+        $recipient_name = isset($feedback->recipient_name)
+            ? $feedback->recipient_name : 'Your Library';
+        $email_subject = isset($feedback->email_subject)
+            ? $feedback->email_subject : 'Vufind Feedback';
+        $sender_email = isset($feedback->sender_email)
+            ? $feedback->sender_email : 'noreply@vufind.org';
+        $sender_name = isset($feedback->sender_name)
+            ? $feedback->sender_name : 'VuFind Feedback';
+        if ($recipient_email == null) {
+            throw new \Exception(
+                'Feedback Module Error: Recipient Email Unset (see config.ini)'
+            );
+        }
+        if ($comments == "") {
+            throw new \Exception('Feedback Module Error: Comment Post Failed');
+        }
+
+        $email_message = 'Name: '.$name."\n";
+        $email_message .= 'Email: '.$users_email."\n";
+        $email_message .= 'Comments: '.$comments."\n";
+
+        // This sets up the email to be sent
+        $mail = new Mail\Message();
+        $mail->setBody($email_message);
+        $mail->setFrom($sender_email, $sender_name);
+        $mail->addTo($recipient_email, $recipient_name);
+        $mail->setSubject($email_subject);
+
+        $this->getServiceLocator()->get('VuFind\Mailer')->getTransport()
+            ->send($mail);
+    }
+}
diff --git a/module/VuFind/src/VuFind/View/Helper/Root/Feedback.php b/module/VuFind/src/VuFind/View/Helper/Root/Feedback.php
new file mode 100644
index 00000000000..1f06fed6ec9
--- /dev/null
+++ b/module/VuFind/src/VuFind/View/Helper/Root/Feedback.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * This is a helper that lets the layout know whether or not to include the feedback
+ * tab
+ *
+ * PHP version 5
+ *
+ * Copyright (C) Villanova University 2010.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @category VuFind2
+ * @package  View_Helpers
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org/wiki/vufind2:developer_manual Wiki
+ */
+namespace VuFind\View\Helper\Root;
+
+/**
+ * This is a helper that lets the layout know whether or not to include the feedback
+ * tab
+ *
+ * @category VuFind2
+ * @package  View_Helpers
+ * @author   Josiah Knoll <jk1135@ship.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org/wiki/vufind2:developer_manual Wiki
+ */
+class Feedback extends \Zend\View\Helper\AbstractHelper
+{
+    /**
+     * Is the tab enabled?
+     *
+     * @var bool
+     */
+    protected $tab;
+
+    /**
+     * Constructor
+     *
+     * @param bool $enabled Is the tab enabled?
+     */
+    public function __construct($enabled = true)
+    {
+        $this->tab = $enabled;
+    }
+
+    /**
+     * This will retrieve the config for whether or not the tab is enabled.
+     *
+     * @return boolean
+     */
+    public function tabEnabled()
+    {
+        return $this->tab;
+    }
+}
diff --git a/themes/blueprint/css/styles.css b/themes/blueprint/css/styles.css
index e3617174e19..5658b75eca9 100644
--- a/themes/blueprint/css/styles.css
+++ b/themes/blueprint/css/styles.css
@@ -2023,3 +2023,44 @@ div#closeContextHelp:active {
 .jstree-highlight {
     font-weight: bold;
 }
+
+/*hides the div so that only people with JavaScript will see the tab*/
+div.slideOutForm {
+    display: none;
+}
+
+/*stylizes the feedback tab div*/
+.slide-out-div {
+  padding: 20px;
+  width: 270px;
+  height: 300px;
+  background: #6B8F25;
+  border: 1px solid #000000;
+  z-index: 9;
+  color: white;
+}
+
+/* larger font size for "send us your feedback" */
+p.feedbackHeader {
+    font-size: 1.4em;
+}
+
+/* this is used to change the properties of errors in the feedback tab */
+#contact_form .error {
+  padding: .1em;
+  line-height: 2.5;
+}
+
+/* changes the text on the feedback home page */
+.feedbackPageLabel {
+    color: black;
+}
+
+/* These two sections change the colors of the selected and unselected text fields */
+.feedbackSelect {
+    background: #D6FFAD;
+}
+
+.feedbackDeselect {
+    background: #FFFFFF;
+}
diff --git a/themes/blueprint/images/feedbacktab/image-tab-en.png b/themes/blueprint/images/feedbacktab/image-tab-en.png
new file mode 100644
index 0000000000000000000000000000000000000000..e2dbd7255453d661c1898361cade47c4516a0744
GIT binary patch
literal 1804
zcmV+n2lM!eP)<h;3K|Lk000e1NJLTq0015U003490ssI2S6Q+200001b5ch_0Itp)
z=>Px*#z{m$R9M69nR`%F*B!@y=iIw@AH0Nx?20J3O8{A2m;fm&Dv6+N0_v1#g6Nn@
zH8Xa`@lmFkIGvc$(WITElLlj(#7s+@7_7$eRf`WaDkw-qhgS&*5(2nTVTtRq%ig{B
zoc?hel4_J?Ib<fCoIiH=oVn+7&z$r9o!?`TTEl5IA(T>J*APNZr;}gzx(Ozs?cd2^
zn4CrknJhE_{J)}SJTm+K!8l_I1N4T1zZfIT|MN1#><tB_4A3K@Yx9bI`p_7q8}mr=
z#)7|5N*JKa&ThkqTbI8(EGQ~EGU3Jicho{qWy8l~PUIf{nf~EV4BYv$f2ec5wa65m
z_E^GGhH&$V>bFnSlstS^;{~^03Tf!5C_DR#d0JXbRPsNn-#Syb*PmIupGvB2ITEZ5
zSF3cVYTxy9$^+5!tSbu_Zog-cQkrMmL@A||Y%G}-Alf;6yU)=s`bG$m36(MCFya7!
zP?-=}l6`@%x}l?@p`!u-5W=bPi|vCq`WzhqU<jWX9hq3)afX5TmSq*M%`1tHOjNo?
zef-+IlBHS24A5zb`6J@+wYGmM-TL-3UY|QHA&&u?!@Qq^<3`&DZ*Z75PfJ(2=4t61
z=5Gz&V1TY{DC0SyD0kN!)56)Ng+;l$cuuHlEMs8keU1)|5NwW4%S?VIBWVdnxU!+_
z)9a;U8oFQBc)0SnjW^Hf!(tG?z@47<-ddK1-rig5C-M7mV18%_aRu31ZI<N%uT{bq
z0Fa5asU&%#tIo4+dLng=%QJ)!ayWbMx(5KjKG4R*8lU$1+@<AP0O07QH$OVPRVGqR
z%V7rSAWb+SvU7NVQmR#lG=FiyCwX%odw~I3BLs1nmx+WBni>%w88#gwj1b2F{nwMf
zwmaHAUT0T-V|MDAt*eg<Ds6rH83xvPYq0Hd(*c?IdT+NFB1~$P?&{~q4t~0WjWsH*
ztH1FN2UoGwH2`4DJsR_q@L(eV47vK+dunAOF+i(0b<v`ob4<A!AqW6Q#Nno!=k`_n
z#wU$T6rE?=n31&Xru|xZ%{u__ROW{Cq$OXu`i@k+F;Ru2CoL5vPic8^OIKA(S5;|w
zu_$>mW-ViLJrP-UID3`f4rec=RP>E7KsR@u=Q$zPXjQtgMk|k1Z9O%CAEP0{ln|3C
z$)elq<T%ypMXy&ke*yqD%W{l)mwPa9v?VUPV8PbWt}!D1=ks4i2q_unPapr~@yl-o
zh^}op(s8SflJ5@D36Q{7?eYw{JVTS>Wt2#jQmVL>dzvKsHt)7fC{p$MJQ`JyA;RSG
z-W|Bp4FHj0)3xdl`(Rt(s~(M1v*tWkn6u;9rQa+0%Yu|uE1ukTsp$X%UFW8)6@8x3
zyy#;6KGEmNPFc+Wt<y}QlyaQv+ks?=PR{_{(R)>`(iJY;F7R4`*B0jNP^)yE_UjBT
z)v~kO;*6;_%W|7#`PaI1>_5AWfddnL?#s;wIm}T?hVI_Fe&ghyPi!1h^8Pw7kJov)
z@^|b5GXT(O!sc3581?ZN>pzN)Of*NQ9j$uP<#9|DtyPC^S@H2y{i6WT)?K4qe*Ht8
z6<7C8R3S^Veibz(?(}ExEB?2+^Sn<QNii>CAimi%pO9p+uJt$oV1)0w2W28hO^IcI
zR`D7DD#;?H-&6x-KeFAi(LJ|Ycut5jrXYj}l`J!}1(oKDzIq1e@+*5dtje=(rj*W`
zv$81nHH^4ZpZ$rAp}%)*{fOv72+f?D>T(bM@yNO_`<vM4y1DawYj-t9Sg9=dBrm%(
z2_XasA>@<2O2my2X0U36aAtBr{@g8LK~W!`dMVbJvLI#E?nBSFc2|#Y)%O>ht>&Df
z++D-UeT2~ErUQ~J&a)PddqeK`v5Pa-i<0MP)f)hS5#MvWMJ7_L!OCE-qrzrTO8)&-
z*XWBWA!;F*0ov&vKnMqG!vTO0S*s337(1Lj4A9rw%6U$hZ(T_#4bere%-Nw<>FQcf
zFi^<JD|-^BXQn4DK?p6)DyBeMyQ?eeK45?*R4zHRCe!jvv_63XwGXsa|LYJlFC!D_
zQsdvp>%bnk*H&}x&UF`+%C*32xBueY;*9ld&>`B0upq;K3l$jaLu2%z)0mZ7Mq^av
zivneao?sgTElM6G4W*RIvNSIA7z)XsyT#>k@K^-^i8E}^KKUxf8~{j?_mc~|0z~ti
z0061+ixpps5Hf_D4B@8H0|*>l)wuu4gR4OP{L{xj#7tySn#5!L5&Z)|V~o*^*r}oy
uFh&m&nUe4-pWm7J-t#a3a2#j1+y4Vke%8so%8A?n0000<MNUMnLSTZ4FL~zx

literal 0
HcmV?d00001

diff --git a/themes/blueprint/js/feedback.js b/themes/blueprint/js/feedback.js
new file mode 100644
index 00000000000..3ef20dd169a
--- /dev/null
+++ b/themes/blueprint/js/feedback.js
@@ -0,0 +1,85 @@
+//this overrides settings in jquery.tabSlideOut.v2.0.js
+$(function(){
+  $('.slide-out-div').tabSlideOut({
+    pathToTabImage: tabImage,
+    imageHeight: '86px',
+    imageWidth: '30px',
+    handleOffset: '-1',
+    speed: '300',
+    topPos: '150px'
+  });
+});
+
+//This is the ajax for the feedback
+$(function() {
+  $('.error').hide();
+  $("div#slideOut").removeClass('slideOutForm');
+  $('input.text-input').addClass('feedbackDeselect');
+  $('input.text-input').focus(function(){
+    $(this).removeClass('feedbackDeselect').addClass('feedbackSelect');
+  });
+  $('input.text-input').blur(function(){
+    $(this).removeClass('feedbackSelect').addClass('feedbackDeselect');
+  });
+
+  $(".button").click(function() {
+    // validate and process form here
+    // first hide error messages
+    $('.submit_button').hide();
+    $('.error').hide();
+
+    var name = $("input#name").val();
+    if (name == "") {
+      $("label#name_error").show();
+      $("input#name").focus();
+      return false;
+    }
+    var email = $("input#email").val();
+    if (email == "") {
+      $("label#email_error").show();
+      $("input#email").focus();
+      return false;
+    }
+    function validateEmail(email) {
+      var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
+      return re.test(email);
+    }
+    if(!validateEmail(email)) {
+      $("label#invalid_email_error").show();
+      $("input#email").focus();
+      return false;
+    }
+    var comments = $("textarea#comments").val();
+    if (comments == "") {
+      $("label#comments_error").show();
+      return false;
+    }
+    $('input#submit_btn').hide();
+
+    var dataString = 'name='+ encodeURIComponent(name) + '&email='
+        + encodeURIComponent(email) + '&comments=' + encodeURIComponent(comments);
+    //Grabs hidden inputs
+    var formSuccess = $("input#formSuccess").val();
+    var feedbackSuccess = $("input#feedbackSuccess").val();
+    var feedbackFailure = $("input#feedbackFailure").val();
+
+    $.ajax({
+      type: "POST",
+      url: path + '/Feedback/Email',
+      data: dataString,
+      success: function() {
+        $('#contact_form').html("<div id='message'></div>");
+        $('#message').html("<p class=\"feedbackHeader\"><b>"+formSuccess+"</b></p> <br />")
+        .append("<p>"+feedbackSuccess+"</p>")
+        .hide()
+        .fadeIn(1500, function() {
+          $('#message')
+        });
+      },
+      error: function() {
+          alert(feedbackFailure);
+      }
+    });
+  return false;
+  });
+});
diff --git a/themes/blueprint/js/jquery.tabSlideOut.v2.0.js b/themes/blueprint/js/jquery.tabSlideOut.v2.0.js
new file mode 100644
index 00000000000..c8b906078d6
--- /dev/null
+++ b/themes/blueprint/js/jquery.tabSlideOut.v2.0.js
@@ -0,0 +1,245 @@
+/*
+    tabSlideOUt v2.0
+    
+    By William Paoli: http://wpaoli.building58.com
+
+    To use you must have an image ready to go as your tab
+    Make sure to pass in at minimum the path to the image and its dimensions:
+    
+    example:
+    
+        $('.slide-out-div').tabSlideOut({
+                tabHandle: '.handle',                         //class of the element that will be your tab -doesnt have to be an anchor
+                pathToTabImage: 'images/contact_tab.gif',     //relative path to the image for the tab *required*
+                imageHeight: '133px',                         //height of tab image *required*
+                imageWidth: '44px',                           //width of tab image *required*    
+        });
+
+    
+*/
+
+
+(function($){
+    $.fn.tabSlideOut = function(callerSettings) {
+        var settings = $.extend({
+            tabHandle: '.handle',
+			toggleButton: '.tab-opener',
+            speed: 300, 
+            action: 'click',
+            tabLocation: 'left',
+            topPos: '200px',
+            leftPos: '20px',
+            fixedPosition: false,
+            positioning: 'absolute',
+            pathToTabImage: null,
+            imageHeight: null,
+            imageWidth: null,
+			handleOffset: '0',
+            onLoadSlideOut: false,
+            onOpen: function(){},
+            onClose: function(){}
+        }, callerSettings||{});
+
+        settings.tabHandle = $(settings.tabHandle);
+        settings.toggleButton = $(settings.toggleButton);
+
+        var obj = this;
+        if (settings.fixedPosition === true) {
+            settings.positioning = 'fixed';
+        } else {
+            settings.positioning = 'absolute';
+        }
+        
+        //ie6 doesn't do well with the fixed option
+        if (document.all && !window.opera && !window.XMLHttpRequest) {
+            settings.positioning = 'absolute';
+        }
+        
+        //set initial tabHandle css
+        if (settings.pathToTabImage !== null) {
+            settings.tabHandle.css({
+            'background' : 'url('+settings.pathToTabImage+') no-repeat',
+            'width' : settings.imageWidth,
+            'height': settings.imageHeight
+            });
+        }
+        
+        settings.tabHandle.css({ 
+            'display': 'block',
+            'textIndent' : '-99999px',
+            'outline' : 'none',
+            'position' : 'absolute'
+        });
+        
+        obj.css({
+            'line-height' : '1',
+            'position' : settings.positioning
+        });
+
+        
+        var properties = {
+                    containerWidth: parseInt(obj.outerWidth(), 10) + 'px',
+                    containerHeight: parseInt(obj.outerHeight(), 10) + 'px',
+                    tabWidth: parseInt(settings.tabHandle.outerWidth(), 10) + 'px',
+                    tabHeight: parseInt(settings.tabHandle.outerHeight(), 10) + 'px'
+                };
+
+        //set calculated css
+        if(settings.tabLocation === 'top' || settings.tabLocation === 'bottom') {
+            obj.css({'left' : settings.leftPos});
+            settings.tabHandle.css({'right' : settings.handleOffset + 'px'});
+        }
+        
+        if(settings.tabLocation === 'top') {
+            obj.css({'top' : '-' + properties.containerHeight});
+            settings.tabHandle.css({'bottom' : '-' + properties.tabHeight});
+        }
+
+        if(settings.tabLocation === 'bottom') {
+            obj.css({'bottom' : '-' + properties.containerHeight, 'position' : 'fixed'});
+            settings.tabHandle.css({'top' : '-' + properties.tabHeight});
+            
+        }
+        
+        if(settings.tabLocation === 'left' || settings.tabLocation === 'right') {
+            obj.css({
+                'height' : properties.containerHeight,
+                'top' : settings.topPos
+            });
+            
+            settings.tabHandle.css({'top' : settings.handleOffset + 'px'});
+        }
+        
+        if(settings.tabLocation === 'left') {
+            obj.css({ 'left': '-' + properties.containerWidth});
+            settings.tabHandle.css({'right' : '-' + properties.tabWidth});
+        }
+
+        if(settings.tabLocation === 'right') {
+            obj.css({ 'right': '-' + properties.containerWidth});
+            settings.tabHandle.css({'left' : '-' + properties.tabWidth});
+            
+            $('html').css('overflow-x', 'hidden');
+        }
+
+        //functions for animation events
+        
+        settings.tabHandle.click(function(event){
+            event.preventDefault();
+        });
+        settings.toggleButton.click(function(event){
+            event.preventDefault();
+        });
+        
+        var slideIn = function() {
+            
+            if (settings.tabLocation === 'top') {
+                obj.animate({top:'-' + properties.containerHeight}, settings.speed, settings.onClose()).removeClass('open');
+            } else if (settings.tabLocation === 'left') {
+                obj.animate({left: '-' + properties.containerWidth}, settings.speed, settings.onClose()).removeClass('open');
+            } else if (settings.tabLocation === 'right') {
+                obj.animate({right: '-' + properties.containerWidth}, settings.speed, settings.onClose()).removeClass('open');
+            } else if (settings.tabLocation === 'bottom') {
+                obj.animate({bottom: '-' + properties.containerHeight}, settings.speed, settings.onClose()).removeClass('open');
+            }    
+            
+        };
+        
+        var slideOut = function() {
+            
+            if (settings.tabLocation === 'top') {
+                obj.animate({top:'-3px'},  settings.speed, settings.onOpen()).addClass('open');
+            } else if (settings.tabLocation === 'left') {
+                obj.animate({left:'-3px'},  settings.speed, settings.onOpen()).addClass('open');
+            } else if (settings.tabLocation === 'right') {
+                obj.animate({right:'-3px'},  settings.speed, settings.onOpen()).addClass('open');
+            } else if (settings.tabLocation === 'bottom') {
+                obj.animate({bottom:'-3px'},  settings.speed, settings.onOpen()).addClass('open');
+            }
+        };
+
+        var clickScreenToClose = function() {
+            obj.click(function(event){
+                event.stopPropagation();
+            });
+
+			settings.toggleButton.click(function(event){
+                event.stopPropagation();
+            });
+			
+            
+            $(document).click(function(){
+                slideIn();
+            });
+        };
+        
+        var clickAction = function(){
+            settings.tabHandle.click(function(event){
+                if (obj.hasClass('open')) {
+                    slideIn();
+                } else {
+                    slideOut();
+                }
+            });
+            settings.toggleButton.click(function(event){
+                if (obj.hasClass('open')) {
+                    slideIn();
+                } else {
+                    slideOut();
+                }
+            });
+            clickScreenToClose();
+        };
+        
+        var hoverAction = function(){
+            obj.hover(
+                function(){
+	                if (!obj.hasClass('open')) {
+	                    slideOut();
+    				}
+                },
+                
+                function(){
+	                if (obj.hasClass('open')) {
+						setTimeout(slideIn, 1000);
+    				}
+                });
+                
+                settings.tabHandle.click(function(event){
+                    if (obj.hasClass('open')) {
+                        slideIn();
+                    }
+                });
+
+	            settings.toggleButton.click(function(event){
+	                if (obj.hasClass('open')) {
+	                    slideIn();
+	                } else {
+	                    slideOut();
+	                }
+	            });
+	
+                clickScreenToClose();
+                
+        };
+        
+        var slideOutOnLoad = function(){
+            slideIn();
+            setTimeout(slideOut, 500);
+        };
+        
+        //choose which type of action to bind
+        if (settings.action === 'click') {
+            clickAction();
+        }
+        
+        if (settings.action === 'hover') {
+            hoverAction();
+        }
+        
+        if (settings.onLoadSlideOut) {
+            slideOutOnLoad();
+        }
+        
+    };
+})(jQuery);
diff --git a/themes/blueprint/templates/feedback/email.phtml b/themes/blueprint/templates/feedback/email.phtml
new file mode 100644
index 00000000000..d5c023f746e
--- /dev/null
+++ b/themes/blueprint/templates/feedback/email.phtml
@@ -0,0 +1,6 @@
+<div class="slideOutForm" id="slideOut">
+  <div class="slide-out-div">
+   <a class="handle">Content</a>
+   <?=$this->render('feedback/form.phtml');?>
+  </div>
+</div>
diff --git a/themes/blueprint/templates/feedback/form.phtml b/themes/blueprint/templates/feedback/form.phtml
new file mode 100644
index 00000000000..d1d0f007071
--- /dev/null
+++ b/themes/blueprint/templates/feedback/form.phtml
@@ -0,0 +1,28 @@
+<div id="contact_form">
+  <form method="post">
+    <p class="feedbackHeader"><b><?=$this->transEsc("Send us your feedback!")?></b></p>
+    <label for="name" style="line-height: 2.5;">
+      <?=$this->transEsc("feedback_name")?></label>
+    <label class="error" for="name">
+      <?=$this->transEsc("Please enable JavaScript.")?></label>
+    <label class="error" for="name" id="name_error">
+      <?=$this->transEsc("This field is required")?>.</label><br />
+    <input type="text" id="name" size="30" class="text-input" /><br />
+    <label for="email" style="line-height: 2.5;">
+      <?=$this->transEsc("Email")?></label>
+    <label class="error" for="email" id="email_error">
+      <?=$this->transEsc("This field is required")?>.</label>
+    <label class="error" for="email" id="invalid_email_error">
+      <?=$this->transEsc("Email address is invalid")?>.</label><br />
+    <input type="text" id="email" size="30" class="text-input" /><br />
+    <label for="comments" style="line-height: 2.5;">
+      <?=$this->transEsc("Comments")?></label>
+    <label class="error" for="comments" id="comments_error">
+      <?=$this->transEsc("This field is required")?>.</label><br />
+    <textarea id="comments" style="width:250px;height:130px"></textarea><br />
+    <input type="submit" class="button" value="<?=$this->transEsc("Send")?>" />
+    <input type="hidden" id="formSuccess" value="<?=$this->transEsc("Form Submitted!")?>"/>
+    <input type="hidden" id="feedbackSuccess" value="<?=$this->transEsc("Thank you for your feedback.")?>"/>
+    <input type="hidden" id="feedbackFailure" value="<?=$this->transEsc("An error has occurred")?>"/>
+  </form>
+</div>
diff --git a/themes/blueprint/templates/feedback/home.phtml b/themes/blueprint/templates/feedback/home.phtml
new file mode 100644
index 00000000000..42b3c6b88ec
--- /dev/null
+++ b/themes/blueprint/templates/feedback/home.phtml
@@ -0,0 +1,7 @@
+<?
+    // Set page title
+    $this->headTitle($this->translate('Feedback Email'));
+    // Get rid of the feedback tab since this uses the same variables
+    $this->layout()->feedbacktab = false;
+?>
+<?=$this->render('feedback/form.phtml');?>
diff --git a/themes/blueprint/templates/layout/layout.phtml b/themes/blueprint/templates/layout/layout.phtml
index ca70bee2252..87614915789 100644
--- a/themes/blueprint/templates/layout/layout.phtml
+++ b/themes/blueprint/templates/layout/layout.phtml
@@ -41,6 +41,16 @@
             }
             $this->headScript()->appendScript($script);
         }
+        $feedback = $this->feedback()->tabEnabled();
+        if ($feedback) {
+            $this->headScript()->appendFile("jquery.tabSlideOut.v2.0.js");
+            $this->headScript()->appendFile("feedback.js");
+            $tab = $this->imageLink("feedbacktab/image-tab-" . $this->layout()->userLang .".png");
+            if (null === $tab) {
+                $tab = $this->imageLink("feedbacktab/image-tab-en.png");
+            }
+            $this->headScript()->appendScript('var tabImage = \'' . $tab . '\';');
+        }
     ?>
     <?=$this->headScript()?>
   </head>
@@ -68,6 +78,15 @@
         <?=$this->layout()->searchbox?>
       </div>
       <? endif; ?>
+      <?
+        // Set up the feedback tab -- the same possible cases exist as the search box
+        if ($feedback && !isset($this->layout()->feedbacktab)) {
+            $this->layout()->feedbacktab = $this->render('feedback/email.phtml');
+        }
+      ?>
+      <? if (isset($this->layout()->feedbacktab)): ?>
+        <div class="feedbacktab"><?=$this->layout()->feedbacktab?></div>
+      <? endif; ?>
       <? if ($this->layout()->breadcrumbs): ?>
       <div class="breadcrumbs">
         <div class="breadcrumbinner">
diff --git a/themes/root/theme.config.php b/themes/root/theme.config.php
index 30803512ce4..1d8307ece2c 100644
--- a/themes/root/theme.config.php
+++ b/themes/root/theme.config.php
@@ -49,6 +49,12 @@ return array(
                     $sm->getServiceLocator()->get('VuFind\Export')
                 );
             },
+            'feedback' => function ($sm) {
+                $config = $sm->getServiceLocator()->get('VuFind\Config')->get('config');
+                $enabled = isset($config->Feedback->tab_enabled)
+                    ? $config->Feedback->tab_enabled : false;
+                return new \VuFind\View\Helper\Root\Feedback($enabled);
+            },
             'flashmessages' => function ($sm) {
                 $messenger = $sm->getServiceLocator()->get('ControllerPluginManager')
                     ->get('FlashMessenger');
-- 
GitLab