-Evergreen doesn't keep a GNU-style ChangeLog except in release tarballs.
-Those seeking a change log are encouraged to run 'git log -v', or read
-it online at: http://git.evergreen-ils.org/?p=Evergreen.git;a=log
+commit 647c0f45ab6b8b2cbd55226fb92345a8e19f2879
+Author: Jason Boyer <JBoyer@equinoxOLI.org>
+Date: Fri May 20 09:03:48 2022 -0400
+
+ Update Server Upgrade Doc
+
+ Signed-off-by: Jason Boyer <JBoyer@equinoxOLI.org>
+
+16 16 docs/modules/installation/pages/server_upgrade.adoc
+
+commit e79e34035a17cf2d72c57e3b2a99b24f6fba5b6e
+Author: Jason Boyer <JBoyer@equinoxOLI.org>
+Date: Fri May 20 08:58:31 2022 -0400
+
+ bumping Perl version string for 3.7.3
+
+ Signed-off-by: Jason Boyer <JBoyer@equinoxOLI.org>
+
+1 1 Open-ILS/src/perlmods/lib/OpenILS.pm
+
+commit f86068866fb2778e0074d2504ae356c16064940e
+Author: Jason Boyer <JBoyer@equinoxOLI.org>
+Date: Fri May 20 08:55:32 2022 -0400
+
+ Translation updates - po files
+
+ Signed-off-by: Jason Boyer <JBoyer@equinoxOLI.org>
+
+4 4 build/i18n/po/actor/ar-JO.po
+4 4 build/i18n/po/actor/cs-CZ.po
+4 4 build/i18n/po/actor/de-DE.po
+4 4 build/i18n/po/actor/en-GB.po
+4 4 build/i18n/po/actor/es-ES.po
+4 4 build/i18n/po/actor/hy-AM.po
+619 319 build/i18n/po/bootstrap-opac/cs-CZ.po
+614 310 build/i18n/po/bootstrap-opac/en-CA.po
+1889 1435 build/i18n/po/bootstrap-opac/es-ES.po
+991 642 build/i18n/po/bootstrap-opac/fr-CA.po
+7 5 build/i18n/po/cat.properties/en-CA.po
+31 22 build/i18n/po/circ.properties/en-CA.po
+3753 3266 build/i18n/po/db.seed/ar-JO.po
+3823 3280 build/i18n/po/db.seed/cs-CZ.po
+3651 3214 build/i18n/po/db.seed/de-DE.po
+3684 3238 build/i18n/po/db.seed/en-CA.po
+3658 3221 build/i18n/po/db.seed/en-GB.po
+3758 3271 build/i18n/po/db.seed/es-ES.po
+3671 3234 build/i18n/po/db.seed/fi-FI.po
+3659 3222 build/i18n/po/db.seed/fr-CA.po
+3646 3209 build/i18n/po/db.seed/he-IL.po
+3646 3209 build/i18n/po/db.seed/hu-HU.po
+3767 3280 build/i18n/po/db.seed/hy-AM.po
+3652 3215 build/i18n/po/db.seed/oc-FR.po
+3662 3225 build/i18n/po/db.seed/pt-BR.po
+3657 3220 build/i18n/po/db.seed/ru-RU.po
+3646 3209 build/i18n/po/db.seed/sv-SE.po
+3647 3210 build/i18n/po/db.seed/tr-TR.po
+3571 3210 build/i18n/po/fm_IDL.dtd/ar-JO.po
+3584 3220 build/i18n/po/fm_IDL.dtd/cs-CZ.po
+3525 3182 build/i18n/po/fm_IDL.dtd/de-DE.po
+3569 3208 build/i18n/po/fm_IDL.dtd/en-CA.po
+3568 3207 build/i18n/po/fm_IDL.dtd/en-GB.po
+3571 3210 build/i18n/po/fm_IDL.dtd/es-ES.po
+3571 3210 build/i18n/po/fm_IDL.dtd/fi-FI.po
+3520 3177 build/i18n/po/fm_IDL.dtd/fr-CA.po
+3519 3176 build/i18n/po/fm_IDL.dtd/he-IL.po
+3519 3176 build/i18n/po/fm_IDL.dtd/hu-HU.po
+3574 3213 build/i18n/po/fm_IDL.dtd/hy-AM.po
+3519 3176 build/i18n/po/fm_IDL.dtd/oc-FR.po
+3562 3204 build/i18n/po/fm_IDL.dtd/pt-BR.po
+3561 3203 build/i18n/po/fm_IDL.dtd/ru-RU.po
+3519 3176 build/i18n/po/fm_IDL.dtd/sv-SE.po
+3519 3176 build/i18n/po/fm_IDL.dtd/tr-TR.po
+274 257 build/i18n/po/ils_events.xml/ar-JO.po
+278 259 build/i18n/po/ils_events.xml/cs-CZ.po
+271 257 build/i18n/po/ils_events.xml/de-DE.po
+275 258 build/i18n/po/ils_events.xml/en-CA.po
+281 262 build/i18n/po/ils_events.xml/en-GB.po
+274 257 build/i18n/po/ils_events.xml/es-ES.po
+274 257 build/i18n/po/ils_events.xml/fi-FI.po
+275 258 build/i18n/po/ils_events.xml/fr-CA.po
+271 257 build/i18n/po/ils_events.xml/he-IL.po
+271 257 build/i18n/po/ils_events.xml/hu-HU.po
+274 257 build/i18n/po/ils_events.xml/hy-AM.po
+271 257 build/i18n/po/ils_events.xml/oc-FR.po
+275 258 build/i18n/po/ils_events.xml/pt-BR.po
+274 257 build/i18n/po/ils_events.xml/ru-RU.po
+271 257 build/i18n/po/ils_events.xml/sv-SE.po
+271 257 build/i18n/po/ils_events.xml/tr-TR.po
+26 18 build/i18n/po/kpac/ar-JO.po
+27 19 build/i18n/po/kpac/cs-CZ.po
+26 18 build/i18n/po/kpac/de-DE.po
+31 23 build/i18n/po/kpac/en-GB.po
+26 18 build/i18n/po/kpac/es-ES.po
+26 18 build/i18n/po/kpac/hy-AM.po
+5 5 build/i18n/po/lang.dtd/en-CA.po
+16 12 build/i18n/po/multiclass_search_help.html/en-GB.po
+23 19 build/i18n/po/patron.properties/en-CA.po
+5 5 build/i18n/po/register.js/en-CA.po
+13 13 build/i18n/po/selfcheck.js/en-CA.po
+439 274 build/i18n/po/tpac/ar-JO.po
+450 282 build/i18n/po/tpac/cs-CZ.po
+424 267 build/i18n/po/tpac/de-DE.po
+424 270 build/i18n/po/tpac/en-CA.po
+440 275 build/i18n/po/tpac/en-GB.po
+442 277 build/i18n/po/tpac/es-ES.po
+441 276 build/i18n/po/tpac/fi-FI.po
+565 400 build/i18n/po/tpac/fr-CA.po
+424 267 build/i18n/po/tpac/he-IL.po
+424 267 build/i18n/po/tpac/hu-HU.po
+440 275 build/i18n/po/tpac/hy-AM.po
+424 267 build/i18n/po/tpac/oc-FR.po
+424 270 build/i18n/po/tpac/pt-BR.po
+424 267 build/i18n/po/tpac/ru-RU.po
+424 267 build/i18n/po/tpac/sv-SE.po
+424 267 build/i18n/po/tpac/tr-TR.po
+634 0 build/i18n/po/vandelay/en-CA.po
+890 600 build/i18n/po/webstaff/ar-JO.po
+1177 861 build/i18n/po/webstaff/cs-CZ.po
+816 591 build/i18n/po/webstaff/de-DE.po
+822 595 build/i18n/po/webstaff/en-CA.po
+842 593 build/i18n/po/webstaff/en-GB.po
+890 600 build/i18n/po/webstaff/es-ES.po
+847 595 build/i18n/po/webstaff/hy-AM.po
+816 591 build/i18n/po/webstaff/ru-RU.po
+ create mode 100644 build/i18n/po/vandelay/en-CA.po
+
+commit 9ff76946eb7d1c5cd05b84cb169b43beda65f5cb
+Author: Jason Boyer <JBoyer@equinoxOLI.org>
+Date: Fri May 20 15:54:51 2022 -0400
+
+ Update 3.7 Point Release Notes
+
+ Signed-off-by: Jason Boyer <JBoyer@equinoxOLI.org>
+
+4 4 docs/RELEASE_NOTES_3_7.adoc
+
+commit a3bc6094a84cb6cbf8d31379812e8f4512b71d8c
+Author: Andrea Buntz Neiman <abneiman@equinoxinitiative.org>
+Date: Fri May 20 14:46:55 2022 -0400
+
+ Docs: 3.7.3 Release Notes
+
+ Signed-off-by: Andrea Buntz Neiman <abneiman@equinoxinitiative.org>
+
+159 0 docs/RELEASE_NOTES_3_7.adoc
+
+commit 997407f8d89b0bc9951cf8009d0263ad6a561e14
+Author: Jason Boyer <JBoyer@equinoxOLI.org>
+Date: Fri May 20 08:39:14 2022 -0400
+
+ Translation updates - newpot
+
+ Signed-off-by: Jason Boyer <JBoyer@equinoxOLI.org>
+
+531 507 build/i18n/po/bootstrap-opac/bootstrap-opac.pot
+1 1 build/i18n/po/conify/conify.pot
+5 9 build/i18n/po/fm_IDL.dtd/fm_IDL.dtd.pot
+14 14 build/i18n/po/kpac/kpac.pot
+441 441 build/i18n/po/tpac/tpac.pot
+2 2 build/i18n/po/urlverify/urlverify.pot
+121 121 build/i18n/po/webstaff/webstaff.pot
+
+commit 5105bfe1306276229b56c8207ab66e9cc6a37d18
+Author: Galen Charlton <gmc@equinoxOLI.org>
+Date: Thu May 19 17:25:52 2022 -0400
+
+ LP#1946531: (follow-up) show progress bar when adding users to bucket
+
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+ Signed-off-by: Jane Sandberg <js7389@princeton.edu>
+
+6 3 Open-ILS/web/js/ui/default/staff/circ/patron/bucket/app.js
+
+commit e3e0673e3d3e4495f1ea6c70f6eefdc1ec9e8628
+Author: Jeff Davis <jeff.davis@bc.libraries.coop>
+Date: Wed May 11 15:55:21 2022 -0700
+
+ LP#1946531: use batch method to add users to bucket via User Buckets UI
+
+ Signed-off-by: Jeff Davis <jeff.davis@bc.libraries.coop>
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+ Signed-off-by: Jane Sandberg <js7389@princeton.edu>
+
+20 19 Open-ILS/web/js/ui/default/staff/circ/patron/bucket/app.js
+
+commit cc8c8b549bc306873c76acf2ada14fe7ed56a51e
+Author: Kyle Huckins <khuckins@catalyte.io>
+Date: Wed Dec 15 17:43:42 2021 +0000
+
+ lp1950507 Providers Admin Screenreader form fix
+
+ - Move Search and Reset Form buttons to bottom of form when expanded.
+
+ Signed-off-by: Kyle Huckins <khuckins@catalyte.io>
+ Signed-off-by: Tiffany Little <tlittle@georgialibraries.org>
+ Signed-off-by: Jane Sandberg <js7389@princeton.edu>
+
+8 2 Open-ILS/src/eg2/src/app/staff/acq/provider/acq-provider-search-form.component.html
+
+commit 80f4dede70e311720da4318501edc315271f5a1c
+Author: Galen Charlton <gmc@equinoxOLI.org>
+Date: Thu May 19 14:12:20 2022 -0400
+
+ LP#1968082: (follow-up) show progress bar when adding/removing items from bucket
+
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+
+12 4 Open-ILS/web/js/ui/default/staff/cat/bucket/copy/app.js
+
+commit 9491523be07d5d4836131ad2da8ce211ec1bdc6e
+Author: Galen Charlton <gmc@equinoxOLI.org>
+Date: Thu May 19 13:52:14 2022 -0400
+
+ LP#1968082: (follow-up) tidy up whitespace
+
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+
+22 24 Open-ILS/web/js/ui/default/staff/cat/bucket/copy/app.js
+
+commit 7bc64a213a2defa573a043c2c597e3777d1bf961
+Author: Jessica Woolford <jwoolford@biblio.org>
+Date: Thu Apr 7 15:15:55 2022 -0400
+
+ LP#1968082: Use the batch API call to add and remove items from item buckets.
+
+ In particular, when adding/removing items while on the item
+ bucket interface itself.
+
+ Signed-off-by: Jessica Woolford <jwoolford@biblio.org>
+ Signed-off-by: Jane Sandberg <js7389@princeton.edu>
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+
+42 34 Open-ILS/web/js/ui/default/staff/cat/bucket/copy/app.js
+
+commit 3c34ec4196293575838954e31bf538a9f21b44e1
+Author: Bill Erickson <berickxx@gmail.com>
+Date: Thu Jun 3 11:09:25 2021 -0400
+
+ LP1930740 EDI order writer attribute check repair
+
+ Repairs mistaken references to $self->{compiled}->{edi_attr}... The
+ hash key we need is {edi_attrs}.
+
+ This issue prevented these attribute types from getting applied:
+
+ LINEITEM_IDENT_VENDOR_NUMBER
+ COPY_SPEC_CODES
+ INCLUDE_EMPTY_LI_NOTE
+
+ Signed-off-by: Bill Erickson <berickxx@gmail.com>
+ Signed-off-by: Jessica Woolford <jwoolford@biblio.org>
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+3 3 Open-ILS/src/perlmods/lib/OpenILS/Utils/EDIWriter.pm
+
+commit 0647d3bdc9c7945bdda4e80735247df631d382b3
+Author: Galen Charlton <gmc@equinoxOLI.org>
+Date: Tue Apr 26 17:33:18 2022 -0400
+
+ LP#1970486: fix SuperCat crash on serial units with stat cats
+
+ This patch fixes a bug where retrieving a title via SuperCat (in
+ particular, with holdings XML) can crash of the title has a serial
+ unit (i.e., barcoded serial item) attached that also has a statistical
+ category.
+
+ To test
+ -------
+ [1] Create a title with a barcoded serial item.
+ [2] Attempt to fetch the title via SuperCat:
+
+ https://EGSERVER/opac/extras/supercat/retrieve/marcxml-full/record/BIBID
+
+ [3] Note that an internal server error is returned.
+ [4] Apply the patch and repeat step 2. This time, an XML
+ document should be returned that includes the serial item
+ and its stat cat.
+
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+ Signed-off-by: Mike Rylander <mrylander@gmail.com>
+
+1 0 Open-ILS/src/perlmods/lib/OpenILS/Application/SuperCat.pm
+
+commit 59a3000be00e3c7392efd9a907ba26cc6fa7eede
+Author: Garry Collum <gcollum@gmail.com>
+Date: Thu Apr 15 15:50:55 2021 -0400
+
+ LP1907863 Bootstrap Opac: My Lists formatting
+
+ This patch moves the buttons for each list row underneath the title and descriptions fields.
+ It makes the create list form collapsible using a button.
+ If there are lists, the create form is collapsed.
+ The create form is expanded on load, if the user selects move bucket to new list, or add rec to new list from a menu or button from another page.
+ The "Move contents of basket to this list?" in the creation form now defaults to 'yes' if an option to move a basket to a new list is chosen from a menu.
+ It adds localization functions to the button texts and removes a dangling </div> in anon-list.tt2
+ It moves the create form from a <table> design and uses Bootstrap elements instead.
+
+ To Test.
+
+ 1. After applying the patch view the list page and notice that the form is expanded.
+ 2. Create a list. The form is now collapse.
+ 3. Perform a search and add some of the titles to a basket.
+ 4. From one of the result rows drop-down the Add to My List menu and select 'Add to New List'.
+ The form is expanded and the "Move contents of basket to this list" should be 'yes'.
+ 5. From the basket screen or from the lists screen click on the 'Add to New List' button. The results should be the same as step 4.
+ 6. After creating a few lists, notice that the buttons for each list are now displayed under the list title and description and
+ each row is distinguished by a bottom border.
+
+ Signed-off-by: Garry Collum <gcollum@gmail.com>
+ Signed-off-by: Ruth Frasur <rfrasur@library.in.gov>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+
+110 114 Open-ILS/src/templates-bootstrap/opac/myopac/lists.tt2
+6 7 Open-ILS/src/templates-bootstrap/opac/parts/anon_list.tt2
+1 1 Open-ILS/src/templates-bootstrap/opac/parts/bookbag_actions.tt2
+
+commit 6c89e2ffe9f9ac4efe3f51a59af35c1cdc731a1b
+Author: Dan Briem <dbriem@wlsmail.org>
+Date: Thu Mar 17 16:38:10 2022 -0400
+
+ LP#1965317 Barcode Completion on Traditional Cat Staff Holds
+
+ This allows the completed barcode to populate in the barcode
+ input when the hold group interface isn't rendered.
+
+ Signed-off-by: Dan Briem <dbriem@wlsmail.org>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+1 1 Open-ILS/web/js/ui/default/opac/staff.js
+
+commit 74662562d5f436588f3887d57f3b87e3779b44c2
+Author: Jane Sandberg <js7389@princeton.edu>
+Date: Thu Apr 7 15:40:47 2022 -0700
+
+ Stamp upgrade script for MADS update
+
+ Signed-off-by: Jane Sandberg <js7389@princeton.edu>
+
+1 1 Open-ILS/src/sql/Pg/002.schema.config.sql
+1 1 Open-ILS/src/sql/Pg/upgrade/{XXXX.data.MADS21-xsl.sql => 1325.data.MADS21-xsl.sql}
+ rename Open-ILS/src/sql/Pg/upgrade/{XXXX.data.MADS21-xsl.sql => 1325.data.MADS21-xsl.sql} (99%)
+
+commit afe551c8cec1d43cde4c6ce189388a420b1c5dff
+Author: Jane Sandberg <sandbej@linnbenton.edu>
+Date: Tue Jan 5 13:27:05 2021 -0800
+
+ LP1800871: small correction to upgrade script
+
+ Signed-off-by: Jane Sandberg <sandbej@linnbenton.edu>
+ Signed-off-by: Jason Boyer <JBoyer@equinoxOLI.org>
+
+2 2 Open-ILS/src/sql/Pg/upgrade/XXXX.data.MADS21-xsl.sql
+
+commit 2e80011b2ff838f17709b60686c2f4b5898ad862
+Author: Josh Stompro <stompro@stompro.org>
+Date: Thu Feb 28 08:39:54 2019 -0600
+
+ LP#1800871 - MARC21slim2MADS 2.15 update
+
+ This update fixes an error when trying to process a 755 tag in
+ and authority record that has a source set.
+
+ See the discussion on the listserv at:
+ https://georgialibraries.markmail.org/thread/rmwcxkwjzv2qczmu
+
+ To test, try to import the sample authority record provided
+ by Linda Jansova (https://markmail.org/thread/2ay3j4wg7fecymhz)
+ in evergreen, and see the log files for the import errors.
+
+ It is also possible to test from the command line.
+
+ In /openils/var/xsl, copy the example autority marc xml file to
+ that directory, name it americ.xml, then run the command
+ xsltproc ./MARC21slim2MADS.xsl ./americ.xml
+
+ This will error out.
+
+ After patch has been applied, try importing the sample authority
+ record and see that it imports successfully.
+
+ Signed-off-by: Josh Stompro <stompro@stompro.org>
+ Signed-off-by: Jane Sandberg <sandbej@linnbenton.edu>
+ Signed-off-by: Jason Boyer <JBoyer@equinoxOLI.org>
+
+2 1 Open-ILS/src/sql/Pg/955.data.MADS21-xsl.sql
+1631 0 Open-ILS/src/sql/Pg/upgrade/XXXX.data.MADS21-xsl.sql
+3 2 Open-ILS/xsl/MARC21slim2MADS.xsl
+ create mode 100644 Open-ILS/src/sql/Pg/upgrade/XXXX.data.MADS21-xsl.sql
+
+commit 20774cdf0dcce81cc944d3185a9fb1edf0df8830
+Author: Garry Collum <gcollum@gmail.com>
+Date: Thu Sep 23 14:31:24 2021 -0400
+
+ LP#1942240 Insufficient color contrast in boostrap forms
+
+ Overrides the bootstrap form-control border color. Also changes the
+ border_standard color in colors.tt2 which is used for the border
+ around some form elements.
+
+ After this patch is applied the color ratio is 3.54:1
+
+ Signed-off-by: Garry Collum <gcollum@gmail.com>
+ Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org>
+ Signed-off-by: Jane Sandberg <js7389@princeton.edu>
+
+5 1 Open-ILS/src/templates-bootstrap/opac/css/style.css.tt2
+1 1 Open-ILS/src/templates-bootstrap/opac/parts/css/colors.tt2
+
+commit 38504ee71419d93b5016799198a4566228012461
+Author: blake <blake@mobiusconsortium.org>
+Date: Mon Sep 20 12:32:26 2021 -0500
+
+ LP1944205 Advanced Authority Documentation
+
+ Added a new document authorities_advanced.adoc
+
+ Integrated to the nav
+
+ Signed-off-by: blake <blake@mobiusconsortium.org>
+ Signed-off-by: Lynn Floyd <alynn2671@gmail.com>
+ Signed-off-by: Jane Sandberg <js7389@princeton.edu>
+
+1 0 docs/modules/cataloging/nav.adoc
+397 0 docs/modules/cataloging/pages/authorities_advanced.adoc
+ create mode 100644 docs/modules/cataloging/pages/authorities_advanced.adoc
+
+commit a9e3431fd21221f93791104bb376b5250b1209c2
+Author: Jason Stephenson <jason@sigio.com>
+Date: Fri Feb 11 09:44:55 2022 -0500
+
+ LP1959904: Fix Angular Profile Select Component
+
+ The Angular profile select component has a bug when permission group
+ tree display entries are used. It will loop forever if the grp and
+ parent have the same value in permission.grp_tree_display_entry
+ because it is comparing permission group tree entries to permission
+ group tree display entries in the groups filter of the grpLabel
+ function.
+
+ This patch adds a ternary operator to compare display entries to
+ display entries and group tree entries to group tree entries in a
+ manner identical to how the parent value is determined a few lines
+ above.
+
+ See the bug description for more information:
+
+ https://bugs.launchpad.net/evergreen/+bug/1959904
+
+ Signed-off-by: Jason Stephenson <jason@sigio.com>
+ Signed-off-by: John Amundson <jamundson@cwmars.org>
+ Signed-off-by: Mike Rylander <mrylander@gmail.com>
+
+1 1 Open-ILS/src/eg2/src/app/staff/share/patron/profile-select.component.ts
+
+commit 93915e867613c49fc9dc0071c04b8094eb8fa7ca
+Author: Bill Erickson <berickxx@gmail.com>
+Date: Wed Mar 16 14:22:13 2022 -0400
+
+ LP1950826 Return error result on contact invalidation
+
+ If penalty creation fails, return the error/event response to the caller
+ instead of the editor's last event.
+
+ Signed-off-by: Bill Erickson <berickxx@gmail.com>
+ Signed-off-by: Christine Burns <christine.burns@bc.libraries.coop>
+
+4 1 Open-ILS/src/perlmods/lib/OpenILS/Utils/BadContact.pm
+
+commit c502f686ab18da72522a806b340dbb81df2aff0f
+Author: Jason Etheridge <jason@EquinoxOLI.org>
+Date: Mon Nov 15 17:30:17 2021 -0500
+
+ LP1950826 fix invalidate email action
+
+ and other invalidate contact actions
+
+ Signed-off-by: Jason Etheridge <jason@EquinoxOLI.org>
+ Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org>
+ Signed-off-by: Bill Erickson <berickxx@gmail.com>
+
+8 3 Open-ILS/src/perlmods/lib/OpenILS/Utils/BadContact.pm
+
+commit df24ff42034d87cc6c0a109b613487bd231665dd
+Author: Kyle Huckins <khuckins@catalyte.io>
+Date: Sun Mar 13 00:27:16 2022 +0000
+
+ lp1913340 - List All Courses in OPAC
+
+ - Removed handling preventing an empty query from providing results
+ - Strip * from query to ensure expected behavior
+
+ Signed-off-by: Kyle Huckins <khuckins@catalyte.io>
+ Signed-off-by: Christine Burns <christine.burns@bc.libraries.coop>
+ Signed-off-by: Jane Sandberg <js7389@princeton.edu>
+
+3 2 Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Course.pm
+
+commit 58fcafc2970fd5a1d793ecea3a97ce88f95c1306
+Author: Chris Sharp <csharp@georgialibraries.org>
+Date: Wed Dec 15 08:49:28 2021 -0500
+
+ LP#1954923: Fix current date issue in Boostrap OPAC Circ History CSV export
+
+ Signed-off-by: Chris Sharp <csharp@georgialibraries.org>
+ Signed-off-by: Garry Collum <gcollum@gmail.com>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+
+1 1 Open-ILS/src/templates-bootstrap/opac/myopac/circ_history/export.tt2
+
+commit ec32f4c330c4a3067a5276a38987a366ff606631
+Author: Garry Collum <gcollum@gmail.com>
+Date: Thu Jan 13 15:02:34 2022 -0500
+
+ LP1920039-Bootstrap Opac: More Details button doesn't change on use.
+
+ The 'More Details' button in a bib record in the Bootstrap Opac should change
+ to say 'Less Details' when pressed. This patch fixes that behavior.
+
+ To Test.
+ 1. Go to a bib record in the boostrap opac.
+ 2. Press "More Details"
+ 3. Notice the button still displays "More Details"
+ 4. Apply the patch and repeat.
+ 5. The button should now toggle between "More Details" and "Less Details"
+
+ Signed-off-by: Garry Collum <gcollum@gmail.com>
+ Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org>
+ Signed-off-by: John Amundson <jamundson@cwmars.org>
+ Signed-off-by: Jason Stephenson <jason@sigio.com>
+
+9 6 Open-ILS/src/templates-bootstrap/opac/parts/record/summary.tt2
+
+commit 9b8597a1886e20b51ea9a7ec660e754b695c3b95
+Author: Jason Boyer <JBoyer@equinoxOLI.org>
+Date: Thu Sep 23 15:49:16 2021 -0400
+
+ LP1930747: Add MARC_NAMESPACE to Const.pm
+
+ Now that we have 3 separate $MARC_NAMESPACE definitions it's time
+ to just move it into Const.pm and call it done.
+
+ Signed-off-by: Jason Boyer <JBoyer@equinoxOLI.org>
+ Signed-off-by: Jason Stephenson <jason@sigio.com>
+
+2 3 Open-ILS/src/perlmods/lib/OpenILS/Application/AppUtils.pm
+2 3 Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/AuthCommon.pm
+5 6 Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/BibCommon.pm
+5 0 Open-ILS/src/perlmods/lib/OpenILS/Const.pm
+
+commit 6301bfdac77da0404fa7e7f31f7fb1895ba47f84
+Author: Jason Boyer <JBoyer@equinoxinitiative.org>
+Date: Thu Oct 15 13:50:18 2020 -0400
+
+ LP1900005: Don't require a specific 'opensrf' user
+
+ There's no technical reason to require a specific user beyond our
+ instructions stating that it's the default. One thing that we should
+ do is not allow our network services to be run as root.
+ Additionally, autogen.sh is excluded from running as root because while
+ that would work, it may then have to *always* be run by root or
+ require you to change the file owner between runs.
+
+ NOTE: We check for the user by id rather than name, as there's no rule
+ saying user 0 must be called "root" on Linux.
+
+ NOTE: This also cleans up and unifies the the coding style and removes
+ some dead code in autogen.sh.
+
+ To test:
+ Pre-patch:
+ Use oils_ctl.sh to start SIP or z3950 as opensrf, Success.
+ Use oils_ctl.sh to start SIP or z3950 as yourself, Failure.
+ Use oils_ctl.sh to start SIP or z3950 as root, Failure.
+ Run autogen.sh as opensrf, Success.
+ Run autogen.sh as yourself, Failure.
+ Run autogen.sh as root, Failure.
+
+ Post patch:
+ Use oils_ctl.sh to start SIP or z3950 as opensrf, Success.
+ Use oils_ctl.sh to start SIP or z3950 as your normal user, Success.
+ Use oils_ctl.sh to start SIP or z3950 as root, Failure.
+ Run autogen.sh as opensrf, Success.
+ Run autogen.sh as yourself, potential Success - IF you're able to write to the correct directory / files.
+ Run autogen.sh as root, Failure.
+
+ Signed-off-by: Jason Boyer <JBoyer@equinoxinitiative.org>
+ Signed-off-by: Mike Rylander <mrylander@gmail.com>
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+2 2 Open-ILS/examples/oils_ctl.sh
+82 49 Open-ILS/src/extras/autogen.sh
+
+commit eb99c4a5bf0e3d1ee05d8f85aa123037b83ad2f7
+Author: Dan Briem <dbriem@wlsmail.org>
+Date: Wed Mar 16 16:45:37 2022 -0400
+
+ LP#1746800 Exclude empty records on filtered staff searches
+
+ Excludes empty bibs on staff searches when filtering on location
+ or location group or when using the availability modifier.
+
+ Signed-off-by: Dan Briem <dbriem@wlsmail.org>
+ Signed-off-by: Mike Rylander <mrylander@gmail.com>
+
+1 1 Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm
+
+commit 007d4fe599c435e862ec1a858547967c424ca095
+Author: Terran McCanna <tmccanna@georgialibraries.org>
+Date: Thu Mar 24 14:48:14 2022 -0400
+
+ LP1909681 Open hold grid links in new tab (for 3.7)
+
+ Followup to lp1909681_open_hold_grid_links_in_new_tabs which
+ resolved the same issue on 3.8 and 3.9.
+
+ Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org>
+ Signed-off-by: Mike Rylander <mrylander@gmail.com>
+
+2 2 Open-ILS/src/eg2/src/app/staff/share/holds/grid.component.html
+
+commit 65e2870540b1a388649122becadddf66b3e6d174
+Author: Garry Collum <gcollum@gmail.com>
+Date: Thu Feb 3 17:57:45 2022 -0500
+
+ LP#1959405: hold status not looking for shelf delay status
+
+ This patch fixes the blank status display in the opac by treating that
+ status as a 'Waiting for Copy' status. This commit covers both the TPAC
+ and the Bootstrap OPAC.
+
+ To Test:
+ As stated by Erica in LP1959405
+ 1. Administration->Local Administration->Library Settins Editor
+ set Hold Shelf Status Delay to 1 minute.
+ 2. Place a hold for a patron
+ 3. Capture the hold.
+ The opac will change from "Waiting for Copy" to a blank column.
+ 4. Allow the delay interval to expire
+ The opac will change from a blank status to "Available"
+
+ 5. Apply the patch
+ 6. Repeat 2-3.
+ The opac will continue to display "Waiting for Copy"
+ 7. Allow the delay interval to expire
+ The opac will change from "Waiting for Copy" to "Available"
+
+ Signed-off-by: Garry Collum <gcollum@gmail.com>
+ Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org>
+ Signed-off-by: Mike Rylander <mrylander@gmail.com>
+
+2 2 Open-ILS/src/templates-bootstrap/opac/parts/hold_status.tt2
+2 2 Open-ILS/src/templates/opac/parts/hold_status.tt2
+
+commit 209f99883dd8f43082b61a603e908a88bb9618b7
+Author: Michele Morgan <mmorgan@noblenet.org>
+Date: Tue Mar 2 11:46:42 2021 -0500
+
+ LP1907123 Angular Catalog View Holds missing columns
+
+ Teaches the t_holds.tt2 TPAC file to save columns with the same names as
+ the Angular Catalog.
+
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+ Signed-off-by: Elaine Hardy <ehardy@georgialibraries.org>
+ Signed-off-by: Mike Rylander <mrylander@gmail.com>
+
+134 134 Open-ILS/src/templates/staff/cat/catalog/t_holds.tt2
+
+commit 3ae18863abe7ac7490e599df24d7c9f2e78b5a4e
+Author: Galen Charlton <gmc@equinoxOLI.org>
+Date: Fri Feb 11 10:45:51 2022 -0500
+
+ LP#1939338: fix IDL mistake that could prevent admin of carousels
+
+ This patch fixes a typo found in the IDL definition of the
+ classes for bib, call number, item, and user buckets. One effect
+ of the typo is that the admin interface for carousels could not
+ flesh out the record buckets unless the staff user was either
+ a global administrator or was the one who had created the carousel
+ and bucket originally.
+
+ This patch likely fixes other cases where one would expect to be
+ able to access buckets created by another user.
+
+ This patch is effectively a subset of a patch in the Simple Reporter
+ branch (bug 1945836 and working repository commit 36369719067) that
+ addresses several more errors in the IDL. However, I'm submitting this one
+ now in the hopes of resolving a long-standing bug with carousels sooner
+ rather than later.
+
+ To test
+ -------
+ [1] As a local admin, create a carousel definition.
+ [2] As a different local admin at the same OU, open the carousels
+ admin interface. Note that attempting to retrieve carousel defs
+ created in step 1 will result in a console error and the interface
+ not being completely rendered.
+ [3] Apply the patch and repeat step 2. This time, the carousel definitions
+ should all display.
+
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+ Signed-off-by: Andrea Buntz Neiman <abneiman@equinoxOLI.org>
+ Signed-off-by: Mike Rylander <mrylander@gmail.com>
+
+16 16 Open-ILS/examples/fm_IDL.xml
+
+commit 385c7af5f4f9f46f2beed8a1b60912750ca8517f
+Author: Tiffany Little <tlittle@georgialibraries.org>
+Date: Fri Jun 18 14:33:50 2021 -0400
+
+ LP1928003 Protect real copies from auto-deletion by cancelling acq line items
+
+ Signed-off-by: Tiffany Little <tlittle@georgialibraries.org>
+ Signed-off-by: Mike Rylander <mrylander@gmail.com>
+
+1 1 Open-ILS/src/perlmods/lib/OpenILS/Application/Acq/Order.pm
+
+commit ea6ebb9333c0f246c7443ce6242c7bebadcf03a3
+Author: Garry Collum <gcollum@gmail.com>
+Date: Sun Jan 23 21:05:16 2022 -0500
+
+ LP1010494 - More Details button is not translatable.
+
+ Surrounds the text in the More Details and Less Details button in the
+ bootstrap opac bib record screen and changes 'Less Details' to
+ 'Fewer Details'.
+
+ Signed-off-by: Garry Collum <gcollum@gmail.com>
+ Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+
+3 3 Open-ILS/src/templates-bootstrap/opac/parts/record/summary.tt2
+
+commit f32e39bd76f85938c76869f9ee8a27736790af1c
+Author: Lynn Floyd <alynn2671@gmail.com>
+Date: Thu Dec 30 15:56:29 2021 -0500
+
+ Added Author to Pending view in Item Buckets
+
+ Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+
+2 1 Open-ILS/src/templates/staff/cat/bucket/copy/t_pending.tt2
+
+commit 6e752c8d8cd1818b0eac51df59ac2c8850e20116
+Author: Lynn Floyd <alynn2671@gmail.com>
+Date: Thu Dec 30 12:22:17 2021 -0500
+
+ Add Author field to Item buckets.
+
+ Signed-off-by: Lynn Floyd <alynn2671@gmail.com>
+ Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+
+2 0 Open-ILS/src/templates/staff/cat/bucket/copy/t_view.tt2
+
+commit f06a162b27ba3e0859ae18f74fadace3d6dbaae5
+Author: Jason Stephenson <jason@sigio.com>
+Date: Wed Mar 16 13:29:09 2022 -0400
+
+ LP1965161: Sort Monograph Parts in Holds Metadata
+
+ When placing a hold in the Angular Staff Catalog, parts are not sorted
+ in the proper order. This patch corrects the sort order.
+
+ To verify the bug:
+
+ 1. Find a record with parts in your catalog.
+ 2. Place a hold on a specific part using the Angular Staff Catalog.
+ 3. Notice that the entries int he parts drop down are likely not
+ sorted in the correct order. (If they are you lucked out and
+ should try again with a different record.)
+
+ To verify the fix after applying the patch and re-installing
+ Evergreen, repeat the above steps. The parts should display in the
+ proper sort order by label.
+
+ Signed-off-by: Jason Stephenson <jason@sigio.com>
+ Signed-off-by: Bill Erickson <berickxx@gmail.com>
+
+5 1 Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm
+
+commit 179c78b3f443465e27d0668ad25cd5af3f5c0ed1
+Author: Galen Charlton <gmc@equinoxOLI.org>
+Date: Tue Nov 9 18:22:07 2021 -0500
+
+ LP#1950394: isolate attribute extraction of metarecord
+
+ This patch ensures that calling the Template Toolkit block
+ get_marc_attrs() on the metarecord's lead record's MARCXML
+ does not interfere with attributes already parsed from the
+ current bib's MARCXML on the record summary page in the Bootstrap
+ OPAC.
+
+ This fixes an issue where electronic resource links could fail to
+ be displayed under the following conditions:
+
+ - the MARC record has an 856 field with ind1 = 4 and ind2 = 0 or 1
+ and is NOT a located URI
+ - the bib is part of a metarecord set with at least one other member
+ - the master record in the metarecord set does not have 856 fields
+
+ To test
+ -------
+ [1] Create a setup where two bibs are in the same metarecord set, one
+ with 856 fields and one without. Arrange that the one without
+ 856 fields is the lead record in the metarecord.
+ [2] View the one that has 856 fields in the Bootstrap OPAC's record
+ summary page. Note that the electronic resource links do not
+ appear.
+ [3] Apply the patch and repeat step 2. This time, the links should
+ appear.
+
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+ Signed-off-by: Jason Stephenson <jason@sigio.com>
+
+4 0 Open-ILS/src/templates-bootstrap/opac/parts/record/summary.tt2
+
+commit d2fd2441a841b1fa1d29bc4f55ebefc0f89f126a
+Author: Dan Briem <dbriem@wlsmail.org>
+Date: Sat Nov 20 15:14:36 2021 -0500
+
+ LP#1939426 Traditional Catalog Holds: Patron Info Not Populating
+
+ When no hold groups exist, its interface isn't present. When
+ placing volume holds, the advanced link isn't present.
+
+ This checks that those elements exist before accessing their
+ attributes and adds a missing name attribute to the Bootstrap
+ catalog to display the email address.
+
+ Signed-off-by: Dan Briem <dbriem@wlsmail.org>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+ Signed-off-by: Mike Rylander <mrylander@gmail.com>
+
+1 1 Open-ILS/src/templates-bootstrap/opac/parts/place_hold.tt2
+12 7 Open-ILS/web/js/ui/default/opac/staff.js
+
+commit 0b3dddad68d056a0c867055942cc1df090ed0913
+Author: Jason Boyer <JBoyer@equinoxOLI.org>
+Date: Fri Mar 11 09:03:02 2022 -0500
+
+ LP1964019: Change span tag to div to work around a Chrome bug
+
+ For some reason the span tag wrapping the contents of the Holdable? column
+ began to cause problems with Chrome 99 on Windows. Changing the spans to divs
+ works everywhere without turning off tooltips.
+
+ Signed-off-by: Jason Boyer <JBoyer@equinoxOLI.org>
+ Signed-off-by: Mike Rylander <mrylander@gmail.com>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+
+3 3 Open-ILS/src/eg2/src/app/staff/catalog/record/copies.component.html
+
+commit 6440259b9354ba517ab700190e73c9b79b81b830
+Author: gmontimantis <86423994+gmontimantis@users.noreply.github.com>
+Date: Wed Jan 26 12:20:40 2022 -0500
+
+ Revising 'Using the Public Access Catalog' page
+
+ Updating screenshots and information in this doc to match Bootstrap. Some areas need updating still.
+
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+- - docs/modules/opac/assets/images/opac/advanced_search_ex.jpg
+- - docs/modules/opac/assets/images/opac/advanced_search_filters.jpg
+- - docs/modules/opac/assets/images/opac/back_to_results.jpg
+- - docs/modules/opac/assets/images/opac/branch_search.jpg
+- - docs/modules/opac/assets/images/opac/did_you_mean_no_results.jpg
+- - docs/modules/opac/assets/images/opac/email_records_screen.jpg
+- - docs/modules/opac/assets/images/opac/highlighting.jpg
+- - docs/modules/opac/assets/images/opac/more_details_record.jpg
+- - docs/modules/opac/assets/images/opac/permalink.jpg
+- - docs/modules/opac/assets/images/opac/placing_holds.jpg
+- - docs/modules/opac/assets/images/opac/print_email_records.jpg
+- - docs/modules/opac/assets/images/opac/print_records_screen.jpg
+- - docs/modules/opac/assets/images/opac/record_details.jpg
+- - docs/modules/opac/assets/images/opac/search_facets.JPG
+- - docs/modules/opac/assets/images/opac/search_results.jpg
+- - docs/modules/opac/assets/images/opac/search_results_quantity.JPG
+- - docs/modules/opac/assets/images/opac/viewing_record.jpg
+45 56 docs/modules/opac/pages/using_the_public_access_catalog.adoc
+ create mode 100644 docs/modules/opac/assets/images/opac/advanced_search_ex.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac/advanced_search_filters.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac/back_to_results.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac/branch_search.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac/did_you_mean_no_results.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac/email_records_screen.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac/highlighting.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac/more_details_record.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac/permalink.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac/placing_holds.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac/print_email_records.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac/print_records_screen.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac/record_details.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac/search_facets.JPG
+ create mode 100644 docs/modules/opac/assets/images/opac/search_results.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac/search_results_quantity.JPG
+ create mode 100644 docs/modules/opac/assets/images/opac/viewing_record.jpg
+
+commit 54544786f2d46e964fac032a969f2404dee1b95d
+Author: Jason Boyer <JBoyer@equinoxOLI.org>
+Date: Tue Mar 1 07:55:16 2022 -0500
+
+ Update Test for LP1722827 After LP1482757
+
+ The 4th part of the old test is incorrect as not deleting these is
+ the point of 1482757. Test has been updated to reflect that.
+
+ Signed-off-by: Jason Boyer <JBoyer@equinoxOLI.org>
+
+3 3 Open-ILS/src/sql/Pg/t/lp1722827_trim_spaces_from_located_uris.pg
+
+commit 4551f3b913c5d8567535c30d4449dd277179976f
+Author: Michele Morgan <mmorgan@noblenet.org>
+Date: Fri Feb 25 16:30:12 2022 -0500
+
+ LP#1482757: stamp upgrade script
+
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+
+1 1 Open-ILS/src/sql/Pg/002.schema.config.sql
+2 0 Open-ILS/src/sql/Pg/upgrade/{XXXX.function.biblio.extract_located_uris.sql => 1311.function.biblio.extract_located_uris.sql}
+ rename Open-ILS/src/sql/Pg/upgrade/{XXXX.function.biblio.extract_located_uris.sql => 1311.function.biblio.extract_located_uris.sql} (99%)
+
+commit 160690af7091d38db88eecdfb9df2cbf8092ca88
+Author: Jason Stephenson <jason@sigio.com>
+Date: Thu Sep 24 12:31:23 2020 -0400
+
+ LP#1482757: Speed Up the Delete of Orphaned URIs in upgrade script
+
+ Modify the code that deletes orphaned asset.uri table entries in the
+ upgrade script to use IN logic on the subquery, because IN is much
+ faster than NOT IN. Also take into account the link between
+ serial.item and asset.uri so that we don't accidentally delete URIs
+ used by serial items.
+
+ Signed-off-by: Jason Stephenson <jason@sigio.com>
+ Signed-off-by: Jessica Woolford <jwoolford@biblio.org>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+
+9 3 Open-ILS/src/sql/Pg/upgrade/XXXX.function.biblio.extract_located_uris.sql
+
+commit 6d621d264fab6aa3e49ecad1a11eb1858400810f
+Author: Michele Morgan <mmorgan@noblenet.org>
+Date: Wed Jul 29 16:40:06 2020 -0400
+
+ LP#1482757: Delete URIs and call numbers when all 856 fields are removed
+
+ This patch assures that URIs and call numbers are deleted as appropriate
+ when all 856 fields are removed from the MARC.
+
+ Also provides for tracking editor and edit_date when call numbers are
+ deleted.
+
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+ Signed-off-by: Jason Stephenson <jason@sigio.com>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+
+9 5 Open-ILS/src/sql/Pg/030.schema.metabib.sql
+10 6 Open-ILS/src/sql/Pg/upgrade/XXXX.function.biblio.extract_located_uris.sql
+
+commit 452665b7ad155f673acc786a278db141c6b9510c
+Author: Michele Morgan <mmorgan@noblenet.org>
+Date: Fri Apr 24 13:03:23 2020 -0400
+
+ LP#1482757: Amend upgrade script to remove existing orphaned URIs
+
+ Remove orphaned URIs from the database that have accumulated from past
+ additions, updates and deletions of records with located URIs.
+
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+ Signed-off-by: Jason Stephenson <jason@sigio.com>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+
+8 0 Open-ILS/src/sql/Pg/upgrade/XXXX.function.biblio.extract_located_uris.sql
+
+commit 75535fd1ce953180f1d260d06e0032053c86d5bc
+Author: Michele Morgan <mmorgan@noblenet.org>
+Date: Fri Apr 24 12:43:39 2020 -0400
+
+ LP#1482757: Remove 'orphaned_uri_list' and 'NOT cn.deleted' criteria
+
+ Per Dan Wells' suggestions.
+
+ 1) One possible "crack" I see for data to fall through is the dead map
+ selector. The "AND cn.label = '##URI##' AND NOT cn.deleted" seems overly
+ restrictive. Now, I realize we *shouldn't* have mappings to deleted or
+ non-##URI## call numbers, but it isn't impossible, and I don't think we'd
+ have harm in leaving those restrictions out. If a map isn't used, let's
+ get rid of it regardless, I think.
+
+ 2) (side note) orphaned_uri_list doesn't seems to be used any more, so
+ should be removed.
+
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+ Signed-off-by: Jason Stephenson <jason@sigio.com>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+
+1 2 Open-ILS/src/sql/Pg/030.schema.metabib.sql
+1 2 Open-ILS/src/sql/Pg/upgrade/XXXX.function.biblio.extract_located_uris.sql
+
+commit 68359b62f2facc1dc853369ba20a14b75bb6c100
+Author: Mike Rylander <mrylander@gmail.com>
+Date: Fri May 19 15:33:03 2017 -0400
+
+ LP#1482757: Be sure to remove all orphaned URI
+
+ As reported by Michele Morgan, URIs can be orphaned in some cases, such
+ as when a location drops one of several 856 entries. This commit tracks
+ objects at the mapping level, to identify disused URIs even where the
+ call number level is not changed.
+
+ Signed-off-by: Mike Rylander <mrylander@gmail.com>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+ Signed-off-by: Jason Stephenson <jason@sigio.com>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+
+25 19 Open-ILS/src/sql/Pg/030.schema.metabib.sql
+26 20 Open-ILS/src/sql/Pg/upgrade/XXXX.function.biblio.extract_located_uris.sql
+
+commit 4dfa5ff6681358958fa609d2729ab099dab96e68
+Author: Mike Rylander <mrylander@gmail.com>
+Date: Fri Aug 5 08:56:05 2016 -0400
+
+ LP#1482757: More careful Located URI remapping
+
+ Instead of recreating all Located URI mappings, we will add any new
+ ones and remember all those (existing and new) that are in use. Any
+ existing maps that we don't see in this record, and whose URI is only
+ used once previously and therefore about to be orphaned, we remove.
+
+ Signed-off-by: Mike Rylander <mrylander@gmail.com>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+ Signed-off-by: Jason Stephenson <jason@sigio.com>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+
+33 8 Open-ILS/src/sql/Pg/030.schema.metabib.sql
+140 0 Open-ILS/src/sql/Pg/upgrade/XXXX.function.biblio.extract_located_uris.sql
+ create mode 100644 Open-ILS/src/sql/Pg/upgrade/XXXX.function.biblio.extract_located_uris.sql
+
+commit 594687ef2c4562ea3e79c17376c1785cf9a84262
+Author: gmontimantis <86423994+gmontimantis@users.noreply.github.com>
+Date: Thu Feb 17 09:55:10 2022 -0500
+
+ Update to Batch Search page
+
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+- - docs/modules/opac/assets/images/opac_basket/add_to_basket.jpg
+- - docs/modules/opac/assets/images/opac_basket/basket_icon.jpg
+- - docs/modules/opac/assets/images/opac_basket/drop_down_actions.jpg
+- - docs/modules/opac/assets/images/opac_basket/select_checkboxes.jpg
+- - docs/modules/opac/assets/images/opac_basket/view_basket.jpg
+1 1 docs/modules/opac/nav.adoc
+78 0 docs/modules/opac/pages/baskets.adoc
+0 108 docs/modules/opac/pages/batch_actions_from_search.adoc
+ create mode 100644 docs/modules/opac/assets/images/opac_basket/add_to_basket.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac_basket/basket_icon.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac_basket/drop_down_actions.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac_basket/select_checkboxes.jpg
+ create mode 100644 docs/modules/opac/assets/images/opac_basket/view_basket.jpg
+ create mode 100644 docs/modules/opac/pages/baskets.adoc
+ delete mode 100644 docs/modules/opac/pages/batch_actions_from_search.adoc
+
+commit 8c1e4bfb580b74d83b397d892b8a7c844e5d6c76
+Author: Jeff Godin <jgodin@tadl.org>
+Date: Fri Jan 28 17:54:38 2022 -0500
+
+ Avoid fleshing standing penalty org unit children
+
+ When fleshing the org unit on standing penalties, exclude child org
+ units. We don't need them, and they can cause issues when your
+ standing penalty has a Depth of "Everywhere": you end up with a full
+ copy of the org unit tree, and you will include this when editing
+ and saving the user.
+
+ Signed-off-by: Jeff Godin <jgodin@tadl.org>
+ Signed-off-by: Chris Sharp <csharp@georgialibraries.org>
+
+4 1 Open-ILS/web/js/ui/default/staff/services/patron_search.js
+
+commit a4e6ed0f70e296dada640a3361312160b6770a1e
+Author: Terran McCanna <tmccanna@georgialibraries.org>
+Date: Mon Jun 21 12:55:57 2021 -0400
+
+ LP1927990 Bootstrap OPAC: Patron messages lose line breaks
+
+ Fixes problem where messages added to the Patron Message Center
+ lose their line breaks in the Bootstrap OPAC and makes them
+ difficult to read.
+
+ Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+
+1 1 Open-ILS/src/templates-bootstrap/opac/myopac/messages/single_message.tt2
+
+commit bc51765f250e371b5b434ebbb341eece0033912f
+Author: Galen Charlton <gmc@equinoxOLI.org>
+Date: Mon Nov 1 12:36:31 2021 -0400
+
+ LP#1949389: reduce number of PCRUD requests by subscription manager
+
+ This patch changes how the AngularJS subscription manager fetches
+ serial item templates. In particular, rather than issuing a PCRUD
+ request for every org unit in the system, it fetches them in one
+ fell swoop. This fixes an issue where loading the subscription manager
+ in a large Evergreen consortium could lead to so many requests that
+ it drives PCRUD into backlog mode, resulting in higher request
+ latency across the board.
+
+ To test
+ -------
+ [1] Apply the patch.
+ [2] Verify that the subscription manager lets you set the receiving
+ template for each distribution and that the drop-down's contents
+ changes if the distribution library is changed.
+ [3] Verify that the Apply Binding Template action works and that
+ the binding template drop-down(s) include the relevant copy templates.
+
+ Note that if a binding template has been set already, the current
+ binding template is _not_ displayed as the selected value in the drop-down.
+ This is existing behavior that this patch does not aim to fix.
+
+ Sponsored-by: BC Libraries Cooperative
+
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+ Signed-off-by: Mike Rylander <mrylander@gmail.com>
+ Signed-off-by: Jeff Davis <jdavis@sitka.bclibraries.ca>
+
+7 8 Open-ILS/web/js/ui/default/staff/serials/directives/subscription_manager.js
+34 4 Open-ILS/web/js/ui/default/staff/serials/services/core.js
+
+commit 35286d4359dd21f6fe874f857d0df0d8399b02f8
+Author: Steven Callender <stevecallender@esilibrary.com>
+Date: Mon Oct 4 13:20:56 2021 -0400
+
+ LP#1946019: copyloc.js change to clear locations on new branch select.
+
+ Signed-off-by: Steven Callender <stevecallender@esilibrary.com>
+ Signed-off-by: Garry Collum <gcollum@gmail.com>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+
+1 0 Open-ILS/web/js/ui/default/opac/copyloc.js
+
+commit 6cd54975990d20304657ca9e2d22583036146b6d
+Author: Garry Collum <gcollum@gmail.com>
+Date: Wed Dec 29 14:29:41 2021 -0500
+
+ LP1955927_Barcode_search_fails_in_patron_search_modal
+
+ Fixes the barcode search in the patron search modal in the holds screen.
+
+ To test:
+ 1. Navigate to the 'place a hold' screen in a bib record and open
+ the patron search modal.
+ 2. Enter a patron barcode.
+ 3. The search for the patron fails.
+ 4. Apply the patch and repeat.
+
+ Signed-off-by: Garry Collum <gcollum@gmail.com>
+ Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org>
+ Signed-off-by: Jason Stephenson <jason@sigio.com>
+
+1 1 Open-ILS/src/eg2/src/app/staff/share/patron/search.component.html
+
+commit bda143573b8ac7ff4aaecddfe1fb1110f91d2bbd
+Author: Terran McCanna <tmccanna@georgialibraries.org>
+Date: Thu Jan 13 17:10:32 2022 -0500
+
+ LP1957840 Typo fix in mcrp class in fm_IDL.xml
+
+ Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org>
+ Signed-off-by: Garry Collum <gcollum@gmail.com>
+ Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
+
+1 1 Open-ILS/examples/fm_IDL.xml
+
+commit 60029bc2b5ba4b35a48b8b41351918356ae8d1db
+Author: Galen Charlton <gmc@equinoxOLI.org>
+Date: Fri Jan 7 18:50:04 2022 -0500
+
+ LP#1951021: account for change in OverDrive checkout response
+
+ The OverDrive circulation API soon will stop providing a direct
+ download link in favor of displaying a separate fulfillment page
+ (either as an iframe or a redirect). This patch implements this
+ change with the redirect option.
+
+ Additional information on the API change can be found at
+
+ http://developer.overdrive.com/overdrive-api-notices/01-sep-2021-coming-soon-changes-to-overdrive-checkouts-api
+
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+ Signed-off-by: Jeff Davis <jdavis@sitka.bclibraries.ca>
+ Signed-off-by: Garry Collum <gcollum@gmail.com>
+
+6 2 Open-ILS/src/perlmods/lib/OpenILS/Application/EbookAPI.pm
+31 3 Open-ILS/src/perlmods/lib/OpenILS/Application/EbookAPI/OverDrive.pm
+4 1 Open-ILS/src/perlmods/lib/OpenILS/Utils/HTTPClient.pm
+8 1 Open-ILS/web/js/ui/default/opac/ebook_api/loggedin.js
+
+commit 6febd96f44049fbb574bce2efb92d641c8b55e25
+Author: Lynn Floyd <alynn2671@gmail.com>
+Date: Mon Sep 6 12:13:13 2021 -0400
+
+ Adding videos from Conferences
+
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+3 0 docs/modules/circulation/pages/basic_holds.adoc
+8 0 docs/modules/reports/pages/introduction.adoc
+2 0 docs/modules/shared/pages/how_to_contribute_docs.adoc
+
+commit c364e0da0a998ec1fb8ee53c13c873917927efac
+Author: gmontimantis <86423994+gmontimantis@users.noreply.github.com>
+Date: Wed Feb 2 11:54:44 2022 -0500
+
+ Docs: Updating Opac Lists doc
+
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+- - docs/modules/opac/assets/images/lists_opac/add_to_basket.jpg
+- - docs/modules/opac/assets/images/lists_opac/add_to_list_basket.jpg
+- - docs/modules/opac/assets/images/lists_opac/basket_checkbox.jpg
+- - docs/modules/opac/assets/images/lists_opac/call_number.jpg
+- - docs/modules/opac/assets/images/lists_opac/home_list_link.jpg
+- - docs/modules/opac/assets/images/lists_opac/list_notes.jpg
+- - docs/modules/opac/assets/images/lists_opac/list_options.jpg
+- - docs/modules/opac/assets/images/lists_opac/list_preferences.jpg
+- - docs/modules/opac/assets/images/lists_opac/move_selected_to_list.jpg
+- - docs/modules/opac/assets/images/lists_opac/my_account_list_options.jpg
+- - docs/modules/opac/assets/images/lists_opac/search_results_list_button.jpg
+37 17 docs/modules/opac/pages/my_lists.adoc
+ create mode 100644 docs/modules/opac/assets/images/lists_opac/add_to_basket.jpg
+ create mode 100644 docs/modules/opac/assets/images/lists_opac/add_to_list_basket.jpg
+ create mode 100644 docs/modules/opac/assets/images/lists_opac/basket_checkbox.jpg
+ create mode 100644 docs/modules/opac/assets/images/lists_opac/call_number.jpg
+ create mode 100644 docs/modules/opac/assets/images/lists_opac/home_list_link.jpg
+ create mode 100644 docs/modules/opac/assets/images/lists_opac/list_notes.jpg
+ create mode 100644 docs/modules/opac/assets/images/lists_opac/list_options.jpg
+ create mode 100644 docs/modules/opac/assets/images/lists_opac/list_preferences.jpg
+ create mode 100644 docs/modules/opac/assets/images/lists_opac/move_selected_to_list.jpg
+ create mode 100644 docs/modules/opac/assets/images/lists_opac/my_account_list_options.jpg
+ create mode 100644 docs/modules/opac/assets/images/lists_opac/search_results_list_button.jpg
+
+commit fe3f6dbd0f3a37ccc8573bd20d32312ecb4d9a31
+Author: Jane Sandberg <sandbergja@gmail.com>
+Date: Tue Jan 25 09:50:47 2022 -0800
+
+ Docs: use asciidoc ordered list rather than adding numbers manually
+
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+23 38 docs/modules/cataloging/pages/overlay_record_3950_import.adoc
+
+commit 25161711beca3ed6a083e94214b4599ccb8a3f8e
+Author: gmontimantis <86423994+gmontimantis@users.noreply.github.com>
+Date: Wed Nov 10 14:37:40 2021 -0500
+
+ Docs: updating z39.50 overlay doc and images
+
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+- - docs/modules/cataloging/assets/images/overlay/mark_local_overlay.jpg
+- - docs/modules/cataloging/assets/images/overlay/overlay.jpg
+- - docs/modules/cataloging/assets/images/overlay/overlay_confirmation.jpg
+- - docs/modules/cataloging/assets/images/overlay/search.png
+- - docs/modules/cataloging/assets/images/overlay/view_marc.jpg
+14 19 docs/modules/cataloging/pages/overlay_record_3950_import.adoc
+ create mode 100644 docs/modules/cataloging/assets/images/overlay/mark_local_overlay.jpg
+ create mode 100644 docs/modules/cataloging/assets/images/overlay/overlay.jpg
+ create mode 100644 docs/modules/cataloging/assets/images/overlay/overlay_confirmation.jpg
+ create mode 100644 docs/modules/cataloging/assets/images/overlay/search.png
+ create mode 100644 docs/modules/cataloging/assets/images/overlay/view_marc.jpg
+
+commit ed50ac40338cbe755ec3f74ba33b8de48ed170bd
+Author: gmontimantis <86423994+gmontimantis@users.noreply.github.com>
+Date: Mon Jan 24 14:04:16 2022 -0500
+
+ Docs: Update barcode_completion_grid.jpg
+
+ Updated barcode grid screenshot; other one was too blurry
+
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+- - docs/modules/admin/assets/images/barcode_completion/barcode_completion_grid.jpg
+
+commit 3bb007277374dce161e1338e356f1b68188acbf7
+Author: gmontimantis <86423994+gmontimantis@users.noreply.github.com>
+Date: Fri Jul 30 10:15:46 2021 -0400
+
+ Docs: Update basic_holds.adoc
+
+ removing Print full pull list alternative reference
+
+ https://bugs.launchpad.net/evergreen/+bug/1775402
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+0 2 docs/modules/circulation/pages/basic_holds.adoc
+
+commit 96c793974e62503fa9088bec04722b90a8511756
+Author: gmontimantis <86423994+gmontimantis@users.noreply.github.com>
+Date: Fri Jul 30 10:14:01 2021 -0400
+
+ Docs: Update basic_holds.adoc to include updated screenshot
+
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+- - docs/modules/circulation/assets/images/media/holds-managing-16.png
+- - docs/modules/circulation/assets/images/media/queue_positions.jpg
+2 2 docs/modules/circulation/pages/basic_holds.adoc
+ delete mode 100644 docs/modules/circulation/assets/images/media/holds-managing-16.png
+ create mode 100644 docs/modules/circulation/assets/images/media/queue_positions.jpg
+
+commit 6e32ee20e85d2e379283e70b5fbe72a53ee7d52d
+Author: Jane Sandberg <sandbergja@gmail.com>
+Date: Fri Jan 14 15:58:02 2022 -0800
+
+ Docs: add a chapter about the course materials module
+
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+1 0 docs/antora.yml
+4 0 docs/modules/course_materials/_attributes.adoc
+3 0 docs/modules/course_materials/nav.adoc
+2 0 docs/modules/course_materials/pages/_attributes.adoc
+74 0 docs/modules/course_materials/pages/administration.adoc
+4 0 docs/modules/course_materials/pages/introduction.adoc
+66 0 docs/modules/course_materials/pages/materials.adoc
+ create mode 100644 docs/modules/course_materials/_attributes.adoc
+ create mode 100644 docs/modules/course_materials/nav.adoc
+ create mode 100644 docs/modules/course_materials/pages/_attributes.adoc
+ create mode 100644 docs/modules/course_materials/pages/administration.adoc
+ create mode 100644 docs/modules/course_materials/pages/introduction.adoc
+ create mode 100644 docs/modules/course_materials/pages/materials.adoc
+
+commit a9716efeed659a63ed4993261741760ed9790315
+Author: Jane Sandberg <sandbergja@gmail.com>
+Date: Tue Dec 14 13:02:15 2021 -0800
+
+ LP 1942645: stamp upgrade script
+
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+1 1 Open-ILS/src/sql/Pg/002.schema.config.sql
+1 1 Open-ILS/src/sql/Pg/upgrade/{XXXX.schema.update_course_module_term_constraints.sql => 1309.schema.update_course_module_term_constraints.sql}
+ rename Open-ILS/src/sql/Pg/upgrade/{XXXX.schema.update_course_module_term_constraints.sql => 1309.schema.update_course_module_term_constraints.sql} (74%)
+
+commit 90833952b2e590564c52c55232825059b00fd11b
+Author: malexander <malexander@catalyte.io>
+Date: Wed Dec 8 19:12:23 2021 +0000
+
+ lp-1942645 term name uniqueness
+
+ dropped name uniqueness between orgs, added constraint to owning lib and name
+
+ Includes syntax corrections from Martha Driscoll -- thank you, Martha!
+
+ Signed-off-by: malexander <malexander@catalyte.io>
+ Signed-off-by: Beth Willis <willis@noblenet.org>
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+3 2 Open-ILS/src/sql/Pg/040.schema.asset.sql
+11 0 Open-ILS/src/sql/Pg/upgrade/XXXX.schema.update_course_module_term_constraints.sql
+ create mode 100644 Open-ILS/src/sql/Pg/upgrade/XXXX.schema.update_course_module_term_constraints.sql
+
+commit 560ad20dcb7a2d156a3901573773c729b70726dc
+Author: Jason Stephenson <jason@sigio.com>
+Date: Mon Feb 10 11:09:37 2020 -0500
+
+ Lp 1862652: pingest.pl reingest record attributes fix
+
+ Use the rdeleted parameter when reingesting record attributes in
+ pingest.pl support script so that passing argument values to the
+ --attr option makes sense.
+
+ Prior to this patch, arguments of the --attr option would be ignored,
+ and all record attribute fields were reingested for all records,
+ deleted and not deleted alike.
+
+ With this patch, the arguments of the --attr option are respected for
+ not deleted records. Deleted records still have all attributes
+ reingested.
+
+ Signed-off-by: Jason Stephenson <jason@sigio.com>
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+1 1 Open-ILS/src/support-scripts/pingest.pl
+
+commit 52a3dd19b4115f800fd862177ec855a471e6a827
+Author: Bill Erickson <berickxx@gmail.com>
+Date: Thu Jul 8 10:19:43 2021 -0400
+
+ LP1933275 Staff catalog holdings view shows correct counts
+
+ teaches the Holdings view to determine the number of copies and call
+ numbers attached to each org unit based on the full data set (via new
+ API) instead of copies in hand, since we may only have copies in hand
+ for a subset of child org units.
+
+ Signed-off-by: Bill Erickson <berickxx@gmail.com>
+ Signed-off-by: Mary Llewellyn <mllewell@biblio.org>
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+32 24 Open-ILS/src/eg2/src/app/staff/catalog/record/holdings.component.ts
+72 0 Open-ILS/src/perlmods/lib/OpenILS/Application/Search/Biblio.pm
+
+commit de798db2fd4ae9bd112ef6e3bfbbb47d64c646cc
+Author: Jane Sandberg <sandbergja@gmail.com>
+Date: Wed Dec 1 16:08:52 2021 -0800
+
+ Docs: remove outdated screenshots
+
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+- - docs/modules/admin/assets/images/media/lsa-barcode_completion_admin.png
+- - docs/modules/admin/assets/images/media/lsa-barcode_completion_fields.png
+ delete mode 100644 docs/modules/admin/assets/images/media/lsa-barcode_completion_admin.png
+ delete mode 100644 docs/modules/admin/assets/images/media/lsa-barcode_completion_fields.png
+
+commit 054d2c2402b679121d40e4d493c77146c72b62d7
+Author: gmontimantis <86423994+gmontimantis@users.noreply.github.com>
+Date: Thu Nov 18 08:57:26 2021 -0500
+
+ Docs: update lsa-barcode-completion
+
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+- - docs/modules/admin/assets/images/barcode_completion/barcode_completion_grid.jpg
+- - docs/modules/admin/assets/images/barcode_completion/barcode_record_editor.jpg
+2 2 docs/modules/admin/pages/lsa-barcode_completion.adoc
+ create mode 100644 docs/modules/admin/assets/images/barcode_completion/barcode_completion_grid.jpg
+ create mode 100644 docs/modules/admin/assets/images/barcode_completion/barcode_record_editor.jpg
+
+commit 7fed99cb0ef2a57b15067e352e6ba9ab76e423ba
+Author: Galen Charlton <gmc@equinoxOLI.org>
+Date: Thu Nov 11 11:21:11 2021 -0500
+
+ LP#1949910: serialize deleting items from item bucket
+
+ This patch serializes the fetching and fleshing of items to delete
+ when the delete-from-item-bucket action is invoked, thereby
+ avoiding possible drone starvation from open-ils.search. It
+ also throws up the progress dialog for good measure while
+ the deletion occurs.
+
+ To test
+ -------
+ [1] Set up an item bucket with 25-50 items.
+ [2] From the item bucket intervace, invoke the action to delete
+ all of the items.
+ [3] Note that the open-ils.search.asset.copy.fleshed2.retrieve calls,
+ one for each item, are all made simultaneously. Assuming stock
+ max_children settings, this will cause open-ils.search to log
+ that some requests are hitting the backlog.
+ [4] Apply the patch and refresh the item bucket page, then repeat
+ step 2 (it doesn't matter for this purpose that the items have
+ already been deleted). This time, the open-ils.search API calls
+ are made serially and a progress bar is displayed while the
+ deletion takes place. Verify that no requests hit the backlog.
+
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+ Signed-off-by: Jeff Davis <jdavis@sitka.bclibraries.ca>
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+12 8 Open-ILS/web/js/ui/default/staff/cat/bucket/copy/app.js
+
+commit c4582addfea354c297622f1008a7a9ab15ff91cb
+Author: Jason Boyer <JBoyer@equinoxOLI.org>
+Date: Thu Nov 18 08:52:09 2021 -0500
+
+ Forward Port 3.6.3 Upgrade Script
+
+105 0 Open-ILS/src/sql/Pg/version-upgrade/3.6.2-3.6.3-upgrade-db.sql
+ create mode 100644 Open-ILS/src/sql/Pg/version-upgrade/3.6.2-3.6.3-upgrade-db.sql
+
+commit 6287faaa0a51a7b9a4e35ea1c4896253f834d500
+Author: gmontimantis <86423994+gmontimantis@users.noreply.github.com>
+Date: Wed Nov 17 13:40:16 2021 -0500
+
+ docs: updating batch_importing_MARC.adoc
+
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+- - docs/modules/cataloging/assets/images/batch_importing_MARC/import_item_attribute_def.jpg
+- - docs/modules/cataloging/assets/images/batch_importing_MARC/import_record.jpg
+- - docs/modules/cataloging/assets/images/batch_importing_MARC/marc_tag_and_subfield.jpg
+- - docs/modules/cataloging/assets/images/batch_importing_MARC/match_set_quality.jpg
+- - docs/modules/cataloging/assets/images/batch_importing_MARC/new_record_match.jpg
+- - docs/modules/cataloging/assets/images/batch_importing_MARC/operator.jpg
+- - docs/modules/cataloging/assets/images/batch_importing_MARC/record_attribute.jpg
+- - docs/modules/cataloging/assets/images/batch_importing_MARC/replace_node.jpg
+58 64 docs/modules/cataloging/pages/batch_importing_MARC.adoc
+ create mode 100644 docs/modules/cataloging/assets/images/batch_importing_MARC/import_item_attribute_def.jpg
+ create mode 100644 docs/modules/cataloging/assets/images/batch_importing_MARC/import_record.jpg
+ create mode 100644 docs/modules/cataloging/assets/images/batch_importing_MARC/marc_tag_and_subfield.jpg
+ create mode 100644 docs/modules/cataloging/assets/images/batch_importing_MARC/match_set_quality.jpg
+ create mode 100644 docs/modules/cataloging/assets/images/batch_importing_MARC/new_record_match.jpg
+ create mode 100644 docs/modules/cataloging/assets/images/batch_importing_MARC/operator.jpg
+ create mode 100644 docs/modules/cataloging/assets/images/batch_importing_MARC/record_attribute.jpg
+ create mode 100644 docs/modules/cataloging/assets/images/batch_importing_MARC/replace_node.jpg
+
+commit 69b220019728ebb254ff778de05424467798a65a
+Author: Kyle Huckins <khuckins@catalyte.io>
+Date: Wed Jul 31 16:42:35 2019 +0000
+
+ Docs: lp1739277 Release Notes for Org Selector Styling
+
+ - Add release notes for new Org Selector Styling functionality.
+
+ Signed-off-by: Kyle Huckins <khuckins@catalyte.io>
+
+ Changes to be committed:
+ new file: docs/RELEASE_NOTES_NEXT/Client/org-select-styling.adoc
+
+ Signed-off-by: Jennifer Bruch <jbruch@sparkpa.org>
+ Signed-off-by: Jane Sandberg <sandbej@linnbenton.edu>
+
+4 0 docs/RELEASE_NOTES_NEXT/Client/org-select-styling.adoc
+ create mode 100644 docs/RELEASE_NOTES_NEXT/Client/org-select-styling.adoc
+
+commit 5aef704200d7c6cbfaddc56e3b0c5d44f7dd2a6d
+Author: Kyle Huckins <khuckins@catalyte.io>
+Date: Tue Jul 30 19:00:14 2019 +0000
+
+ lp1739277 OrgSelect Class Callback Holdings Implementation
+
+ - Implement OrgSelectClassCallback in Angular Catalog Holdings UI
+
+ Signed-off-by: Kyle Huckins <khuckins@catalyte.io>
+
+ Changes to be committed:
+ modified: Open-ILS/src/eg2/src/app/staff/catalog/record/holdings.component.html
+ modified: Open-ILS/src/eg2/src/app/staff/catalog/record/holdings.component.ts
+
+ Signed-off-by: Jennifer Bruch <jbruch@sparkpa.org>
+ Signed-off-by: Jane Sandberg <sandbej@linnbenton.edu>
+
+4 2 Open-ILS/src/eg2/src/app/staff/catalog/record/holdings.component.html
+21 0 Open-ILS/src/eg2/src/app/staff/catalog/record/holdings.component.ts
+
+commit 1b97e2f633d912d3c3eec29e86d309b960d3ad47
+Author: Bill Erickson <berickxx@gmail.com>
+Date: Tue Jul 30 12:12:12 2019 -0400
+
+ LP1739277 Angular org selector style callback
+
+ Allow the caller of an <eg-org-select> to pass a function which is
+ called against each org unit in the list to determine what CSS class(es)
+ should be applied to the org unit label in the list.
+
+ Includes sandbox example.
+
+ Signed-off-by: Bill Erickson <berickxx@gmail.com>
+ Signed-off-by: Jennifer Bruch <jbruch@sparkpa.org>
+ Signed-off-by: Jane Sandberg <sandbej@linnbenton.edu>
+
+1 1 Open-ILS/src/eg2/src/app/share/org-select/org-select.component.html
+8 1 Open-ILS/src/eg2/src/app/share/org-select/org-select.component.ts
+6 0 Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html
+6 1 Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts
+
+commit 72a75c6e6a1560732a817cef6052646e542f3756
+Author: Jennifer Pringle <jennifer.pringle@bc.libraries.coop>
+Date: Thu Oct 7 11:46:13 2021 -0700
+
+ Docs: Adding latency test and disable sounds to workstation admin.
+
+ Signed-off-by: Jennifer Pringle <jennifer.pringle@bc.libraries.coop>
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+- - docs/modules/admin/assets/images/workstation/latency-test.png
+34 0 docs/modules/admin/pages/latency.adoc
+1 0 docs/modules/admin/pages/workstation_admin.adoc
+ create mode 100644 docs/modules/admin/assets/images/workstation/latency-test.png
+ create mode 100644 docs/modules/admin/pages/latency.adoc
+
+commit b6e43c82c359c86b1144210698444e473de1216e
+Author: Lynn Floyd <alynn2671@gmail.com>
+Date: Fri Jun 4 15:41:31 2021 -0400
+
+ Docs: Transit List
+
+ Documentation on Transit List.
+
+ Signed-off-by: Lynn Floyd <alynn2671@gmail.com>
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+- - docs/modules/local_admin/assets/images/transit_list/transit_list_from.png
+- - docs/modules/local_admin/assets/images/transit_list/transit_list_to.png
+1 0 docs/modules/local_admin/nav.adoc
+35 0 docs/modules/local_admin/pages/transit_list.adoc
+ create mode 100644 docs/modules/local_admin/assets/images/transit_list/transit_list_from.png
+ create mode 100644 docs/modules/local_admin/assets/images/transit_list/transit_list_to.png
+ create mode 100644 docs/modules/local_admin/pages/transit_list.adoc
+
+commit 06198b7bec47aebca66524ac243404c3df7e77d1
+Author: gmontimantis <86423994+gmontimantis@users.noreply.github.com>
+Date: Mon Jun 28 12:22:57 2021 -0400
+
+ Docs: Update receipt_template_editor.adoc
+
+ Fixes https://bugs.launchpad.net/evergreen/+bug/1929592
+
+ Signed-off-by: Jane Sandberg <sandbergja@gmail.com>
+
+3 1 docs/modules/admin/pages/receipt_template_editor.adoc
+
+commit 767bfeeb7fbc8f73f595a189895db34372d420ad
+Author: Terran McCanna <tmccanna@georgialibraries.org>
+Date: Tue Sep 21 16:48:50 2021 -0400
+
+ LP1766726 Clarify Field Hints on Print Templates
+
+ Adds 'patron.' to beginning of patron field hints in Checkout and Items Out
+ templates to make it easier for users to understand.
+
+ Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org>
+ Signed-off-by: Jennifer Weston <jennifer.weston@equinoxOLI.org>
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+
+18 18 Open-ILS/src/templates/staff/share/print_templates/t_checkout.tt2
+13 13 Open-ILS/src/templates/staff/share/print_templates/t_items_out.tt2
+
+commit 137f42f13f6dd0aa6813a077d81bd975529d6047
+Author: Mike Risher <mrisher@catalyte.io>
+Date: Wed May 20 23:27:20 2020 +0000
+
+ LP#1819233 improve AngularJS eg-basic-combo-box filtering
+
+ Adjust the eg-basic-combo-box so that it doesn’t give console errors
+ when typing characters such as [. Fix the bug that causes it to
+ sometimes show no results when there are valid results that match.
+
+ To test
+ -------
+ [1] Apply the patch, then create a new report template, add a
+ display field, then open the Change Transform modal.
+ [2] Verify that the selection box will accept characters like '['
+ as input without browser console noise, that the filtering
+ is case-insensitive, and that filtering continues to work
+ after clicking on the selector.
+ [3] Instances of this combo box can also be found in the AngularJS
+ volume/copy editor.
+
+ Signed-off-by: Mike Risher <mrisher@catalyte.io>
+ Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org>
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+
+13 3 Open-ILS/web/js/ui/default/staff/services/ui.js
+
+commit ba8e057a2797860268b6a962133fb2120c9a1c5b
+Author: Steven Callender <stevecallender@esilibrary.com>
+Date: Fri Dec 4 09:59:25 2020 -0500
+
+ LP1906842 PLACE_UNFILLABLE_HOLD permission not working if no titles exist
+
+ This fix will correct an issue where the screen just keeps looping to
+ the override screen when trying to place a hold that has no titles
+ available for it.
+
+ Patch courtesy of Mike Rylander.
+
+ Signed-off-by: Steven Callender <stevecallender@esilibrary.com>
+ Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org>
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+
+1 1 Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm
+
+commit a9821ca3b6b4fa508fc11e97740459b23c970641
+Author: Jeff Davis <jeff.davis@bc.libraries.coop>
+Date: Thu Jun 6 14:30:34 2019 -0700
+
+ LP#1830089: close transaction and update copy status on payment or adjust to zero
+
+ When you make a payment that sets the balance owed to zero, Evergreen
+ closes the transaction and sets the item status to Lost & Paid (if
+ appropriate). Adjust to Zero should do the same thing, but hitherto it
+ would not update the item status. This commit refactors some code to
+ ensure that Evergreen gives the same result whether you make a payment
+ or adjust to zero.
+
+ Signed-off-by: Jeff Davis <jeff.davis@bc.libraries.coop>
+ Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org>
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+
+54 0 Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/CircCommon.pm
+10 56 Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Money.pm
+
+commit b04ecabb9346b113d37809a31a7ee39e9111421c
+Author: Galen Charlton <gmc@equinoxOLI.org>
+Date: Fri Nov 5 12:07:52 2021 -0400
+
+ LP#1947173: stamp schema update
+
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+
+1 1 Open-ILS/src/sql/Pg/002.schema.config.sql
+1 1 Open-ILS/src/sql/Pg/upgrade/{XXXX.schema.symspell-speed-ingest.sql => 1306.schema.symspell-speed-ingest.sql}
+ rename Open-ILS/src/sql/Pg/upgrade/{XXXX.schema.symspell-speed-ingest.sql => 1306.schema.symspell-speed-ingest.sql} (99%)
+
+commit ca64d81c00fd2ec98e2b81d9bad17cab245c903e
+Author: Mike Rylander <mrylander@gmail.com>
+Date: Wed Oct 20 16:22:37 2021 -0400
+
+ LP#1947173: Clean up bad cataloging pot hole
+
+ If a MARC record has effectively empty fields (all space or punctuation)
+ then it's possible to stumble over a NULL text array when parsing
+ content for the symspell dictionary. This commit checks for that
+ condition and returns early to avoid the problem.
+
+ Signed-off-by: Mike Rylander <mrylander@gmail.com>
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+
+3 0 Open-ILS/src/sql/Pg/300.schema.staged_search.sql
+3 0 Open-ILS/src/sql/Pg/upgrade/XXXX.schema.symspell-speed-ingest.sql
+
+commit 1ed9223c2d63ef9dd4a142c42386c1cb729ad599
+Author: Mike Rylander <mrylander@gmail.com>
+Date: Thu Oct 14 09:57:24 2021 -0400
+
+ LP#1947173: Speed up the symspell part of ingest
+
+ For certain data, and certain data set sizes, merging the suggestion
+ arrays used by the symspell algorithm is noticably expensive. This is
+ the case for suggestion arrays containing many thousands of entries.
+ These suggestion sets are not only slow, but generally not useful. We
+ avoid the creation of such overly long suggestion sets using several
+ word filters that take advantage of our knowledge of the incoming data
+ to optimize for what is useful in a bibliographic context. The
+ mechanisms employed by this patch are:
+
+ - Omit suggestions whose length is longer than the max prefix key length
+ when the prefix key length is less than or equal to the maximum prefix
+ key length minus the maximum edit distance.
+ - Omit words that contain a run of 5 or more digits. This will drop most
+ identifiers from the dictionary while still allowing suggestions to
+ happen for year values.
+ - Omit empty keys from the dictionary. This should have been the case
+ already but is now enforced directly.
+ - Add a small speedup to evergreen.text_array_merge_unique() by making
+ it assume that arrays passed to it do not have null values, which we
+ intentionally avoid, and against which we protect in other ways in the
+ commit.
+
+ Besides improving reingest speed, the patches will also make the
+ search.symspell_dictionary table significantly smaller.
+
+ Signed-off-by: Mike Rylander <mrylander@gmail.com>
+ Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
+
+18 4 Open-ILS/src/sql/Pg/300.schema.staged_search.sql
+420 0 Open-ILS/src/sql/Pg/upgrade/XXXX.schema.symspell-speed-ingest.sql
+6 1 Open-ILS/src/support-scripts/symspell-sideload.pl
+ create mode 100644 Open-ILS/src/sql/Pg/upgrade/XXXX.schema.symspell-speed-ingest.sql
+
+commit f2081ba7fcf2b8c228ded32129b002accb70017d
+Author: Jason Stephenson <jason@sigio.com>
+Date: Fri Oct 29 11:17:36 2021 -0400
+
+ Forward-port 3.7.2 version upgrade script
+
+ Signed-off-by: Jason Stephenson <jason@sigio.com>
+
+781 0 Open-ILS/src/sql/Pg/version-upgrade/3.7.1-3.7.2-upgrade-db.sql
+ create mode 100644 Open-ILS/src/sql/Pg/version-upgrade/3.7.1-3.7.2-upgrade-db.sql
sub ils_version {
# version format is "x-y-z", for example "2-0-0" for Evergreen 2.0.0
# For branches, format is "x-y"
- return "HEAD";
+ return "3-7-3";
}
__PACKAGE__->register_method(
FOR EACH ROW EXECUTE PROCEDURE evergreen.array_overlap_check ('deprecates');
INSERT INTO config.upgrade_log (version, applied_to) VALUES ('1325', :eg_version); -- stompro/sandbergja/JBoyer
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.7.3', :eg_version);
CREATE TABLE config.bib_source (
id SERIAL PRIMARY KEY,
--- /dev/null
+--Upgrade Script for 3.7.2 to 3.7.3
+\set eg_version '''3.7.3'''
+BEGIN;
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('3.7.3', :eg_version);
+
+SELECT evergreen.upgrade_deps_block_check('1306', :eg_version);
+
+-- We don't pass this function arrays with nulls, so we save 5% not testing for that
+CREATE OR REPLACE FUNCTION evergreen.text_array_merge_unique (
+ TEXT[], TEXT[]
+) RETURNS TEXT[] AS $F$
+ SELECT NULLIF(ARRAY(
+ SELECT * FROM UNNEST($1) x
+ UNION
+ SELECT * FROM UNNEST($2) y
+ ),'{}');
+$F$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION search.symspell_build_raw_entry (
+ raw_input TEXT,
+ source_class TEXT,
+ no_limit BOOL DEFAULT FALSE,
+ prefix_length INT DEFAULT 6,
+ maxED INT DEFAULT 3
+) RETURNS SETOF search.symspell_dictionary AS $F$
+DECLARE
+ key TEXT;
+ del_key TEXT;
+ key_list TEXT[];
+ entry search.symspell_dictionary%ROWTYPE;
+BEGIN
+ key := raw_input;
+
+ IF NOT no_limit AND CHARACTER_LENGTH(raw_input) > prefix_length THEN
+ key := SUBSTRING(key FROM 1 FOR prefix_length);
+ key_list := ARRAY[raw_input, key];
+ ELSE
+ key_list := ARRAY[key];
+ END IF;
+
+ FOREACH del_key IN ARRAY key_list LOOP
+ -- skip empty keys
+ CONTINUE WHEN del_key IS NULL OR CHARACTER_LENGTH(del_key) = 0;
+
+ entry.prefix_key := del_key;
+
+ entry.keyword_count := 0;
+ entry.title_count := 0;
+ entry.author_count := 0;
+ entry.subject_count := 0;
+ entry.series_count := 0;
+ entry.identifier_count := 0;
+
+ entry.keyword_suggestions := '{}';
+ entry.title_suggestions := '{}';
+ entry.author_suggestions := '{}';
+ entry.subject_suggestions := '{}';
+ entry.series_suggestions := '{}';
+ entry.identifier_suggestions := '{}';
+
+ IF source_class = 'keyword' THEN entry.keyword_suggestions := ARRAY[raw_input]; END IF;
+ IF source_class = 'title' THEN entry.title_suggestions := ARRAY[raw_input]; END IF;
+ IF source_class = 'author' THEN entry.author_suggestions := ARRAY[raw_input]; END IF;
+ IF source_class = 'subject' THEN entry.subject_suggestions := ARRAY[raw_input]; END IF;
+ IF source_class = 'series' THEN entry.series_suggestions := ARRAY[raw_input]; END IF;
+ IF source_class = 'identifier' THEN entry.identifier_suggestions := ARRAY[raw_input]; END IF;
+ IF source_class = 'keyword' THEN entry.keyword_suggestions := ARRAY[raw_input]; END IF;
+
+ IF del_key = raw_input THEN
+ IF source_class = 'keyword' THEN entry.keyword_count := 1; END IF;
+ IF source_class = 'title' THEN entry.title_count := 1; END IF;
+ IF source_class = 'author' THEN entry.author_count := 1; END IF;
+ IF source_class = 'subject' THEN entry.subject_count := 1; END IF;
+ IF source_class = 'series' THEN entry.series_count := 1; END IF;
+ IF source_class = 'identifier' THEN entry.identifier_count := 1; END IF;
+ END IF;
+
+ RETURN NEXT entry;
+ END LOOP;
+
+ FOR del_key IN SELECT x FROM UNNEST(search.symspell_generate_edits(key, 1, maxED)) x LOOP
+
+ -- skip empty keys
+ CONTINUE WHEN del_key IS NULL OR CHARACTER_LENGTH(del_key) = 0;
+ -- skip suggestions that are already too long for the prefix key
+ CONTINUE WHEN CHARACTER_LENGTH(del_key) <= (prefix_length - maxED) AND CHARACTER_LENGTH(raw_input) > prefix_length;
+
+ entry.keyword_suggestions := '{}';
+ entry.title_suggestions := '{}';
+ entry.author_suggestions := '{}';
+ entry.subject_suggestions := '{}';
+ entry.series_suggestions := '{}';
+ entry.identifier_suggestions := '{}';
+
+ IF source_class = 'keyword' THEN entry.keyword_count := 0; END IF;
+ IF source_class = 'title' THEN entry.title_count := 0; END IF;
+ IF source_class = 'author' THEN entry.author_count := 0; END IF;
+ IF source_class = 'subject' THEN entry.subject_count := 0; END IF;
+ IF source_class = 'series' THEN entry.series_count := 0; END IF;
+ IF source_class = 'identifier' THEN entry.identifier_count := 0; END IF;
+
+ entry.prefix_key := del_key;
+
+ IF source_class = 'keyword' THEN entry.keyword_suggestions := ARRAY[raw_input]; END IF;
+ IF source_class = 'title' THEN entry.title_suggestions := ARRAY[raw_input]; END IF;
+ IF source_class = 'author' THEN entry.author_suggestions := ARRAY[raw_input]; END IF;
+ IF source_class = 'subject' THEN entry.subject_suggestions := ARRAY[raw_input]; END IF;
+ IF source_class = 'series' THEN entry.series_suggestions := ARRAY[raw_input]; END IF;
+ IF source_class = 'identifier' THEN entry.identifier_suggestions := ARRAY[raw_input]; END IF;
+ IF source_class = 'keyword' THEN entry.keyword_suggestions := ARRAY[raw_input]; END IF;
+
+ RETURN NEXT entry;
+ END LOOP;
+
+END;
+$F$ LANGUAGE PLPGSQL STRICT IMMUTABLE;
+
+CREATE OR REPLACE FUNCTION search.symspell_build_entries (
+ full_input TEXT,
+ source_class TEXT,
+ old_input TEXT DEFAULT NULL,
+ include_phrases BOOL DEFAULT FALSE
+) RETURNS SETOF search.symspell_dictionary AS $F$
+DECLARE
+ prefix_length INT;
+ maxED INT;
+ word_list TEXT[];
+ input TEXT;
+ word TEXT;
+ entry search.symspell_dictionary;
+BEGIN
+ IF full_input IS NOT NULL THEN
+ SELECT value::INT INTO prefix_length FROM config.internal_flag WHERE name = 'symspell.prefix_length' AND enabled;
+ prefix_length := COALESCE(prefix_length, 6);
+
+ SELECT value::INT INTO maxED FROM config.internal_flag WHERE name = 'symspell.max_edit_distance' AND enabled;
+ maxED := COALESCE(maxED, 3);
+
+ input := evergreen.lowercase(full_input);
+ word_list := ARRAY_AGG(x) FROM search.symspell_parse_words_distinct(input) x;
+ IF word_list IS NULL THEN
+ RETURN;
+ END IF;
+
+ IF CARDINALITY(word_list) > 1 AND include_phrases THEN
+ RETURN QUERY SELECT * FROM search.symspell_build_raw_entry(input, source_class, TRUE, prefix_length, maxED);
+ END IF;
+
+ FOREACH word IN ARRAY word_list LOOP
+ -- Skip words that have runs of 5 or more digits (I'm looking at you, ISxNs)
+ CONTINUE WHEN CHARACTER_LENGTH(word) > 4 AND word ~ '\d{5,}';
+ RETURN QUERY SELECT * FROM search.symspell_build_raw_entry(word, source_class, FALSE, prefix_length, maxED);
+ END LOOP;
+ END IF;
+
+ IF old_input IS NOT NULL THEN
+ input := evergreen.lowercase(old_input);
+
+ FOR word IN SELECT x FROM search.symspell_parse_words_distinct(input) x LOOP
+ -- similarly skip words that have 5 or more digits here to
+ -- avoid adding erroneous prefix deletion entries to the dictionary
+ CONTINUE WHEN CHARACTER_LENGTH(word) > 4 AND word ~ '\d{5,}';
+ entry.prefix_key := word;
+
+ entry.keyword_count := 0;
+ entry.title_count := 0;
+ entry.author_count := 0;
+ entry.subject_count := 0;
+ entry.series_count := 0;
+ entry.identifier_count := 0;
+
+ entry.keyword_suggestions := '{}';
+ entry.title_suggestions := '{}';
+ entry.author_suggestions := '{}';
+ entry.subject_suggestions := '{}';
+ entry.series_suggestions := '{}';
+ entry.identifier_suggestions := '{}';
+
+ IF source_class = 'keyword' THEN entry.keyword_count := -1; END IF;
+ IF source_class = 'title' THEN entry.title_count := -1; END IF;
+ IF source_class = 'author' THEN entry.author_count := -1; END IF;
+ IF source_class = 'subject' THEN entry.subject_count := -1; END IF;
+ IF source_class = 'series' THEN entry.series_count := -1; END IF;
+ IF source_class = 'identifier' THEN entry.identifier_count := -1; END IF;
+
+ RETURN NEXT entry;
+ END LOOP;
+ END IF;
+END;
+$F$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION search.symspell_build_and_merge_entries (
+ full_input TEXT,
+ source_class TEXT,
+ old_input TEXT DEFAULT NULL,
+ include_phrases BOOL DEFAULT FALSE
+) RETURNS SETOF search.symspell_dictionary AS $F$
+DECLARE
+ new_entry RECORD;
+ conflict_entry RECORD;
+BEGIN
+
+ IF full_input = old_input THEN -- neither NULL, and are the same
+ RETURN;
+ END IF;
+
+ FOR new_entry IN EXECUTE $q$
+ SELECT count,
+ prefix_key,
+ s AS suggestions
+ FROM (SELECT prefix_key,
+ ARRAY_AGG(DISTINCT $q$ || source_class || $q$_suggestions[1]) s,
+ SUM($q$ || source_class || $q$_count) count
+ FROM search.symspell_build_entries($1, $2, $3, $4)
+ GROUP BY 1) x
+ $q$ USING full_input, source_class, old_input, include_phrases
+ LOOP
+ EXECUTE $q$
+ SELECT prefix_key,
+ $q$ || source_class || $q$_suggestions suggestions,
+ $q$ || source_class || $q$_count count
+ FROM search.symspell_dictionary
+ WHERE prefix_key = $1 $q$
+ INTO conflict_entry
+ USING new_entry.prefix_key;
+
+ IF new_entry.count <> 0 THEN -- Real word, and count changed
+ IF conflict_entry.prefix_key IS NOT NULL THEN -- we'll be updating
+ IF conflict_entry.count > 0 THEN -- it's a real word
+ RETURN QUERY EXECUTE $q$
+ UPDATE search.symspell_dictionary
+ SET $q$ || source_class || $q$_count = $2
+ WHERE prefix_key = $1
+ RETURNING * $q$
+ USING new_entry.prefix_key, GREATEST(0, new_entry.count + conflict_entry.count);
+ ELSE -- it was a prefix key or delete-emptied word before
+ IF conflict_entry.suggestions @> new_entry.suggestions THEN -- already have all suggestions here...
+ RETURN QUERY EXECUTE $q$
+ UPDATE search.symspell_dictionary
+ SET $q$ || source_class || $q$_count = $2
+ WHERE prefix_key = $1
+ RETURNING * $q$
+ USING new_entry.prefix_key, GREATEST(0, new_entry.count);
+ ELSE -- new suggestion!
+ RETURN QUERY EXECUTE $q$
+ UPDATE search.symspell_dictionary
+ SET $q$ || source_class || $q$_count = $2,
+ $q$ || source_class || $q$_suggestions = $3
+ WHERE prefix_key = $1
+ RETURNING * $q$
+ USING new_entry.prefix_key, GREATEST(0, new_entry.count), evergreen.text_array_merge_unique(conflict_entry.suggestions,new_entry.suggestions);
+ END IF;
+ END IF;
+ ELSE
+ -- We keep the on-conflict clause just in case...
+ RETURN QUERY EXECUTE $q$
+ INSERT INTO search.symspell_dictionary AS d (
+ $q$ || source_class || $q$_count,
+ prefix_key,
+ $q$ || source_class || $q$_suggestions
+ ) VALUES ( $1, $2, $3 ) ON CONFLICT (prefix_key) DO
+ UPDATE SET $q$ || source_class || $q$_count = d.$q$ || source_class || $q$_count + EXCLUDED.$q$ || source_class || $q$_count,
+ $q$ || source_class || $q$_suggestions = evergreen.text_array_merge_unique(d.$q$ || source_class || $q$_suggestions, EXCLUDED.$q$ || source_class || $q$_suggestions)
+ RETURNING * $q$
+ USING new_entry.count, new_entry.prefix_key, new_entry.suggestions;
+ END IF;
+ ELSE -- key only, or no change
+ IF conflict_entry.prefix_key IS NOT NULL THEN -- we'll be updating
+ IF NOT conflict_entry.suggestions @> new_entry.suggestions THEN -- There are new suggestions
+ RETURN QUERY EXECUTE $q$
+ UPDATE search.symspell_dictionary
+ SET $q$ || source_class || $q$_suggestions = $2
+ WHERE prefix_key = $1
+ RETURNING * $q$
+ USING new_entry.prefix_key, evergreen.text_array_merge_unique(conflict_entry.suggestions,new_entry.suggestions);
+ END IF;
+ ELSE
+ RETURN QUERY EXECUTE $q$
+ INSERT INTO search.symspell_dictionary AS d (
+ $q$ || source_class || $q$_count,
+ prefix_key,
+ $q$ || source_class || $q$_suggestions
+ ) VALUES ( $1, $2, $3 ) ON CONFLICT (prefix_key) DO -- key exists, suggestions may be added due to this entry
+ UPDATE SET $q$ || source_class || $q$_suggestions = evergreen.text_array_merge_unique(d.$q$ || source_class || $q$_suggestions, EXCLUDED.$q$ || source_class || $q$_suggestions)
+ RETURNING * $q$
+ USING new_entry.count, new_entry.prefix_key, new_entry.suggestions;
+ END IF;
+ END IF;
+ END LOOP;
+END;
+$F$ LANGUAGE PLPGSQL;
+
+
+\qecho ''
+\qecho 'The following should be run at the end of the upgrade before any'
+\qecho 'reingest occurs. Because new triggers are installed already,'
+\qecho 'updates to indexed strings will cause zero-count dictionary entries'
+\qecho 'to be recorded which will require updating every row again (or'
+\qecho 'starting from scratch) so best to do this before other batch'
+\qecho 'changes. A later reingest that does not significantly change'
+\qecho 'indexed strings will /not/ cause table bloat here, and will be'
+\qecho 'as fast as normal. A copy of the SQL in a ready-to-use, non-escaped'
+\qecho 'form is available inside a comment at the end of this upgrade sub-'
+\qecho 'script so you do not need to copy this comment from the psql ouptut.'
+\qecho ''
+\qecho '\\a'
+\qecho '\\t'
+\qecho ''
+\qecho '\\o title'
+\qecho 'select value from metabib.title_field_entry where source in (select id from biblio.record_entry where not deleted);'
+\qecho '\\o author'
+\qecho 'select value from metabib.author_field_entry where source in (select id from biblio.record_entry where not deleted);'
+\qecho '\\o subject'
+\qecho 'select value from metabib.subject_field_entry where source in (select id from biblio.record_entry where not deleted);'
+\qecho '\\o series'
+\qecho 'select value from metabib.series_field_entry where source in (select id from biblio.record_entry where not deleted);'
+\qecho '\\o identifier'
+\qecho 'select value from metabib.identifier_field_entry where source in (select id from biblio.record_entry where not deleted);'
+\qecho '\\o keyword'
+\qecho 'select value from metabib.keyword_field_entry where source in (select id from biblio.record_entry where not deleted);'
+\qecho ''
+\qecho '\\o'
+\qecho '\\a'
+\qecho '\\t'
+\qecho ''
+\qecho '// Then, at the command line:'
+\qecho ''
+\qecho '$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl title > title.sql'
+\qecho '$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl author > author.sql'
+\qecho '$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl subject > subject.sql'
+\qecho '$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl series > series.sql'
+\qecho '$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl identifier > identifier.sql'
+\qecho '$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl keyword > keyword.sql'
+\qecho ''
+\qecho '// And, back in psql'
+\qecho ''
+\qecho 'ALTER TABLE search.symspell_dictionary SET UNLOGGED;'
+\qecho 'TRUNCATE search.symspell_dictionary;'
+\qecho ''
+\qecho '\\i identifier.sql'
+\qecho '\\i author.sql'
+\qecho '\\i title.sql'
+\qecho '\\i subject.sql'
+\qecho '\\i series.sql'
+\qecho '\\i keyword.sql'
+\qecho ''
+\qecho 'CLUSTER search.symspell_dictionary USING symspell_dictionary_pkey;'
+\qecho 'REINDEX TABLE search.symspell_dictionary;'
+\qecho 'ALTER TABLE search.symspell_dictionary SET LOGGED;'
+\qecho 'VACUUM ANALYZE search.symspell_dictionary;'
+\qecho ''
+\qecho 'DROP TABLE search.symspell_dictionary_partial_title;'
+\qecho 'DROP TABLE search.symspell_dictionary_partial_author;'
+\qecho 'DROP TABLE search.symspell_dictionary_partial_subject;'
+\qecho 'DROP TABLE search.symspell_dictionary_partial_series;'
+\qecho 'DROP TABLE search.symspell_dictionary_partial_identifier;'
+\qecho 'DROP TABLE search.symspell_dictionary_partial_keyword;'
+
+/* To run by hand:
+
+\a
+\t
+
+\o title
+select value from metabib.title_field_entry where source in (select id from biblio.record_entry where not deleted);
+
+\o author
+select value from metabib.author_field_entry where source in (select id from biblio.record_entry where not deleted);
+
+\o subject
+select value from metabib.subject_field_entry where source in (select id from biblio.record_entry where not deleted);
+
+\o series
+select value from metabib.series_field_entry where source in (select id from biblio.record_entry where not deleted);
+
+\o identifier
+select value from metabib.identifier_field_entry where source in (select id from biblio.record_entry where not deleted);
+
+\o keyword
+select value from metabib.keyword_field_entry where source in (select id from biblio.record_entry where not deleted);
+
+\o
+\a
+\t
+
+// Then, at the command line:
+
+$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl title > title.sql
+$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl author > author.sql
+$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl subject > subject.sql
+$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl series > series.sql
+$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl identifier > identifier.sql
+$ ~/EG-src-path/Open-ILS/src/support-scripts/symspell-sideload.pl keyword > keyword.sql
+
+// To the extent your hardware allows, the above commands can be run in
+// in parallel, in different shells. Each will use a full CPU, and RAM
+// may be a limiting resource, so keep an eye on that with `top`.
+
+
+// And, back in psql
+
+ALTER TABLE search.symspell_dictionary SET UNLOGGED;
+TRUNCATE search.symspell_dictionary;
+
+\i identifier.sql
+\i author.sql
+\i title.sql
+\i subject.sql
+\i series.sql
+\i keyword.sql
+
+CLUSTER search.symspell_dictionary USING symspell_dictionary_pkey;
+REINDEX TABLE search.symspell_dictionary;
+ALTER TABLE search.symspell_dictionary SET LOGGED;
+VACUUM ANALYZE search.symspell_dictionary;
+
+DROP TABLE search.symspell_dictionary_partial_title;
+DROP TABLE search.symspell_dictionary_partial_author;
+DROP TABLE search.symspell_dictionary_partial_subject;
+DROP TABLE search.symspell_dictionary_partial_series;
+DROP TABLE search.symspell_dictionary_partial_identifier;
+DROP TABLE search.symspell_dictionary_partial_keyword;
+
+*/
+
+
+SELECT evergreen.upgrade_deps_block_check('1309', :eg_version);
+
+ALTER TABLE asset.course_module_term
+ DROP CONSTRAINT course_module_term_name_key;
+
+ALTER TABLE asset.course_module_term
+ ADD CONSTRAINT cmt_once_per_owning_lib UNIQUE (owning_lib, name);
+
+
+SELECT evergreen.upgrade_deps_block_check('1311', :eg_version);
+
+CREATE OR REPLACE FUNCTION biblio.extract_located_uris( bib_id BIGINT, marcxml TEXT, editor_id INT ) RETURNS VOID AS $func$
+DECLARE
+ uris TEXT[];
+ uri_xml TEXT;
+ uri_label TEXT;
+ uri_href TEXT;
+ uri_use TEXT;
+ uri_owner_list TEXT[];
+ uri_owner TEXT;
+ uri_owner_id INT;
+ uri_id INT;
+ uri_cn_id INT;
+ uri_map_id INT;
+ current_uri INT;
+ current_map INT;
+ uri_map_count INT;
+ current_uri_map_list INT[];
+ current_map_owner_list INT[];
+
+BEGIN
+
+ uris := oils_xpath('//*[@tag="856" and (@ind1="4" or @ind1="1") and (@ind2="0" or @ind2="1")]',marcxml);
+ IF ARRAY_UPPER(uris,1) > 0 THEN
+ FOR i IN 1 .. ARRAY_UPPER(uris, 1) LOOP
+ -- First we pull info out of the 856
+ uri_xml := uris[i];
+
+ uri_href := (oils_xpath('//*[@code="u"]/text()',uri_xml))[1];
+ uri_label := (oils_xpath('//*[@code="y"]/text()|//*[@code="3"]/text()',uri_xml))[1];
+ uri_use := (oils_xpath('//*[@code="z"]/text()|//*[@code="2"]/text()|//*[@code="n"]/text()',uri_xml))[1];
+
+ IF uri_label IS NULL THEN
+ uri_label := uri_href;
+ END IF;
+ CONTINUE WHEN uri_href IS NULL;
+
+ -- Get the distinct list of libraries wanting to use
+ SELECT ARRAY_AGG(
+ DISTINCT REGEXP_REPLACE(
+ x,
+ $re$^.*?\((\w+)\).*$$re$,
+ E'\\1'
+ )
+ ) INTO uri_owner_list
+ FROM UNNEST(
+ oils_xpath(
+ '//*[@code="9"]/text()|//*[@code="w"]/text()|//*[@code="n"]/text()',
+ uri_xml
+ )
+ )x;
+
+ IF ARRAY_UPPER(uri_owner_list,1) > 0 THEN
+
+ -- look for a matching uri
+ IF uri_use IS NULL THEN
+ SELECT id INTO uri_id
+ FROM asset.uri
+ WHERE label = uri_label AND href = uri_href AND use_restriction IS NULL AND active
+ ORDER BY id LIMIT 1;
+ IF NOT FOUND THEN -- create one
+ INSERT INTO asset.uri (label, href, use_restriction) VALUES (uri_label, uri_href, uri_use);
+ SELECT id INTO uri_id
+ FROM asset.uri
+ WHERE label = uri_label AND href = uri_href AND use_restriction IS NULL AND active;
+ END IF;
+ ELSE
+ SELECT id INTO uri_id
+ FROM asset.uri
+ WHERE label = uri_label AND href = uri_href AND use_restriction = uri_use AND active
+ ORDER BY id LIMIT 1;
+ IF NOT FOUND THEN -- create one
+ INSERT INTO asset.uri (label, href, use_restriction) VALUES (uri_label, uri_href, uri_use);
+ SELECT id INTO uri_id
+ FROM asset.uri
+ WHERE label = uri_label AND href = uri_href AND use_restriction = uri_use AND active;
+ END IF;
+ END IF;
+
+ FOR j IN 1 .. ARRAY_UPPER(uri_owner_list, 1) LOOP
+ uri_owner := uri_owner_list[j];
+
+ SELECT id INTO uri_owner_id FROM actor.org_unit WHERE shortname = BTRIM(REPLACE(uri_owner,chr(160),''));
+ CONTINUE WHEN NOT FOUND;
+
+ -- we need a call number to link through
+ SELECT id INTO uri_cn_id FROM asset.call_number WHERE owning_lib = uri_owner_id AND record = bib_id AND label = '##URI##' AND NOT deleted;
+ IF NOT FOUND THEN
+ INSERT INTO asset.call_number (owning_lib, record, create_date, edit_date, creator, editor, label)
+ VALUES (uri_owner_id, bib_id, 'now', 'now', editor_id, editor_id, '##URI##');
+ SELECT id INTO uri_cn_id FROM asset.call_number WHERE owning_lib = uri_owner_id AND record = bib_id AND label = '##URI##' AND NOT deleted;
+ END IF;
+
+ -- now, link them if they're not already
+ SELECT id INTO uri_map_id FROM asset.uri_call_number_map WHERE call_number = uri_cn_id AND uri = uri_id;
+ IF NOT FOUND THEN
+ INSERT INTO asset.uri_call_number_map (call_number, uri) VALUES (uri_cn_id, uri_id);
+ SELECT id INTO uri_map_id FROM asset.uri_call_number_map WHERE call_number = uri_cn_id AND uri = uri_id;
+ END IF;
+
+ current_uri_map_list := current_uri_map_list || uri_map_id;
+ current_map_owner_list := current_map_owner_list || uri_cn_id;
+
+ END LOOP;
+
+ END IF;
+
+ END LOOP;
+ END IF;
+
+ -- Clear any orphaned URIs, URI mappings and call
+ -- numbers for this bib that weren't mapped above.
+ FOR current_map IN
+ SELECT m.id
+ FROM asset.uri_call_number_map m
+ LEFT JOIN asset.call_number cn ON (cn.id = m.call_number)
+ WHERE cn.record = bib_id
+ AND cn.label = '##URI##'
+ AND (NOT (m.id = ANY (current_uri_map_list))
+ OR current_uri_map_list is NULL)
+ LOOP
+ SELECT uri INTO current_uri FROM asset.uri_call_number_map WHERE id = current_map;
+ DELETE FROM asset.uri_call_number_map WHERE id = current_map;
+
+ SELECT COUNT(*) INTO uri_map_count FROM asset.uri_call_number_map WHERE uri = current_uri;
+ IF uri_map_count = 0 THEN
+ DELETE FROM asset.uri WHERE id = current_uri;
+ END IF;
+ END LOOP;
+
+ UPDATE asset.call_number
+ SET deleted = TRUE, edit_date = now(), editor = editor_id
+ WHERE id IN (
+ SELECT id
+ FROM asset.call_number
+ WHERE record = bib_id
+ AND label = '##URI##'
+ AND NOT deleted
+ AND (NOT (id = ANY (current_map_owner_list))
+ OR current_map_owner_list is NULL)
+ );
+
+ RETURN;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+-- Remove existing orphaned URIs from the database.
+DELETE FROM asset.uri
+WHERE id IN
+(
+SELECT uri.id
+FROM asset.uri
+LEFT JOIN asset.uri_call_number_map
+ON uri_call_number_map.uri = uri.id
+LEFT JOIN serial.item
+ON item.uri = uri.id
+WHERE uri_call_number_map IS NULL
+AND item IS NULL
+);
+
+
+
+SELECT evergreen.upgrade_deps_block_check('1325', :eg_version);
+
+UPDATE config.xml_transform SET xslt=$XSLT$<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:mads="http://www.loc.gov/mads/v2"
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:marc="http://www.loc.gov/MARC21/slim"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="marc">
+ <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
+ <xsl:strip-space elements="*"/>
+
+ <xsl:variable name="ascii">
+ <xsl:text> !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~</xsl:text>
+ </xsl:variable>
+
+ <xsl:variable name="latin1">
+ <xsl:text> ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ</xsl:text>
+ </xsl:variable>
+ <!-- Characters that usually don't need to be escaped -->
+ <xsl:variable name="safe">
+ <xsl:text>!'()*-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~</xsl:text>
+ </xsl:variable>
+
+ <xsl:variable name="hex">0123456789ABCDEF</xsl:variable>
+
+
+ <xsl:template name="datafield">
+ <xsl:param name="tag"/>
+ <xsl:param name="ind1">
+ <xsl:text> </xsl:text>
+ </xsl:param>
+ <xsl:param name="ind2">
+ <xsl:text> </xsl:text>
+ </xsl:param>
+ <xsl:param name="subfields"/>
+ <xsl:element name="marc:datafield">
+ <xsl:attribute name="tag">
+ <xsl:value-of select="$tag"/>
+ </xsl:attribute>
+ <xsl:attribute name="ind1">
+ <xsl:value-of select="$ind1"/>
+ </xsl:attribute>
+ <xsl:attribute name="ind2">
+ <xsl:value-of select="$ind2"/>
+ </xsl:attribute>
+ <xsl:copy-of select="$subfields"/>
+ </xsl:element>
+ </xsl:template>
+
+ <xsl:template name="subfieldSelect">
+ <xsl:param name="codes">abcdefghijklmnopqrstuvwxyz</xsl:param>
+ <xsl:param name="delimeter">
+ <xsl:text> </xsl:text>
+ </xsl:param>
+ <xsl:variable name="str">
+ <xsl:for-each select="marc:subfield">
+ <xsl:if test="contains($codes, @code)">
+ <xsl:value-of select="text()"/>
+ <xsl:value-of select="$delimeter"/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:value-of select="substring($str,1,string-length($str)-string-length($delimeter))"/>
+ </xsl:template>
+
+ <xsl:template name="buildSpaces">
+ <xsl:param name="spaces"/>
+ <xsl:param name="char">
+ <xsl:text> </xsl:text>
+ </xsl:param>
+ <xsl:if test="$spaces>0">
+ <xsl:value-of select="$char"/>
+ <xsl:call-template name="buildSpaces">
+ <xsl:with-param name="spaces" select="$spaces - 1"/>
+ <xsl:with-param name="char" select="$char"/>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="chopPunctuation">
+ <xsl:param name="chopString"/>
+ <xsl:param name="punctuation">
+ <xsl:text>.:,;/ </xsl:text>
+ </xsl:param>
+ <xsl:variable name="length" select="string-length($chopString)"/>
+ <xsl:choose>
+ <xsl:when test="$length=0"/>
+ <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
+ <xsl:with-param name="punctuation" select="$punctuation"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="not($chopString)"/>
+ <xsl:otherwise>
+ <xsl:value-of select="$chopString"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="chopPunctuationFront">
+ <xsl:param name="chopString"/>
+ <xsl:variable name="length" select="string-length($chopString)"/>
+ <xsl:choose>
+ <xsl:when test="$length=0"/>
+ <xsl:when test="contains('.:,;/[ ', substring($chopString,1,1))">
+ <xsl:call-template name="chopPunctuationFront">
+ <xsl:with-param name="chopString" select="substring($chopString,2,$length - 1)"
+ />
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="not($chopString)"/>
+ <xsl:otherwise>
+ <xsl:value-of select="$chopString"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="chopPunctuationBack">
+ <xsl:param name="chopString"/>
+ <xsl:param name="punctuation">
+ <xsl:text>.:,;/] </xsl:text>
+ </xsl:param>
+ <xsl:variable name="length" select="string-length($chopString)"/>
+ <xsl:choose>
+ <xsl:when test="$length=0"/>
+ <xsl:when test="contains($punctuation, substring($chopString,$length,1))">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="substring($chopString,1,$length - 1)"/>
+ <xsl:with-param name="punctuation" select="$punctuation"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="not($chopString)"/>
+ <xsl:otherwise>
+ <xsl:value-of select="$chopString"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- nate added 12/14/2007 for lccn.loc.gov: url encode ampersand, etc. -->
+ <xsl:template name="url-encode">
+
+ <xsl:param name="str"/>
+
+ <xsl:if test="$str">
+ <xsl:variable name="first-char" select="substring($str,1,1)"/>
+ <xsl:choose>
+ <xsl:when test="contains($safe,$first-char)">
+ <xsl:value-of select="$first-char"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="codepoint">
+ <xsl:choose>
+ <xsl:when test="contains($ascii,$first-char)">
+ <xsl:value-of
+ select="string-length(substring-before($ascii,$first-char)) + 32"
+ />
+ </xsl:when>
+ <xsl:when test="contains($latin1,$first-char)">
+ <xsl:value-of
+ select="string-length(substring-before($latin1,$first-char)) + 160"/>
+ <!-- was 160 -->
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:message terminate="no">Warning: string contains a character
+ that is out of range! Substituting "?".</xsl:message>
+ <xsl:text>63</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="hex-digit1"
+ select="substring($hex,floor($codepoint div 16) + 1,1)"/>
+ <xsl:variable name="hex-digit2" select="substring($hex,$codepoint mod 16 + 1,1)"/>
+ <!-- <xsl:value-of select="concat('%',$hex-digit2)"/> -->
+ <xsl:value-of select="concat('%',$hex-digit1,$hex-digit2)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:if test="string-length($str) > 1">
+ <xsl:call-template name="url-encode">
+ <xsl:with-param name="str" select="substring($str,2)"/>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:if>
+ </xsl:template>
+
+
+<!--
+2.15 reversed genre and setAuthority template order under relatedTypeAttribute tmee 11/13/2018
+2.14 Fixed bug in mads:geographic attributes syntax ws 05/04/2016
+2.13 fixed repeating <geographic> tmee 01/31/2014
+2.12 added $2 authority for <classification> tmee 09/18/2012
+2.11 added delimiters between <classification> subfields tmee 09/18/2012
+2.10 fixed type="other" and type="otherType" for mads:related tmee 09/16/2011
+2.09 fixed professionTerm and genreTerm empty tag error tmee 09/16/2011
+2.08 fixed marc:subfield @code='i' matching error tmee 09/16/2011
+2.07 fixed 555 duplication error tmee 08/10/2011
+2.06 fixed topic subfield error tmee 08/10/2011
+2.05 fixed title subfield error tmee 06/20/2011
+2.04 fixed geographicSubdivision mapping for authority element tmee 06/16/2011
+2.03 added classification for 053, 055, 060, 065, 070, 080, 082, 083, 086, 087 tmee 06/03/2011
+2.02 added descriptionStandard for 008/10 tmee 04/27/2011
+2.01 added extensions for 046, 336, 370, 374, 375, 376 tmee 04/08/2011
+2.00 redefined imported MODS elements in version 1.0 to MADS elements in version 2.0 tmee 02/08/2011
+1.08 added 372 subfields $a $s $t for <fieldOfActivity> tmee 06/24/2010
+1.07 removed role/roleTerm 100, 110, 111, 400, 410, 411, 500, 510, 511, 700, 710, 711 tmee 06/24/2010
+1.06 added strip-space tmee 06/24/2010
+1.05 added subfield $a for 130, 430, 530 tmee 06/21/2010
+1.04 fixed 550 z omission ntra 08/11/2008
+1.03 removed duplication of 550 $a text tmee 11/01/2006
+1.02 fixed namespace references between mads and mods ntra 10/06/2006
+1.01 revised rgue/jrad 11/29/05
+1.00 adapted from MARC21Slim2MODS3.xsl ntra 07/06/05
+-->
+
+ <!-- authority attribute defaults to 'naf' if not set using this authority parameter, for <authority> descriptors: name, titleInfo, geographic -->
+ <xsl:param name="authority"/>
+ <xsl:variable name="auth">
+ <xsl:choose>
+ <xsl:when test="$authority">
+ <xsl:value-of select="$authority"/>
+ </xsl:when>
+ <xsl:otherwise>naf</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="controlField008" select="marc:controlfield[@tag='008']"/>
+ <xsl:variable name="controlField008-06"
+ select="substring(descendant-or-self::marc:controlfield[@tag=008],7,1)"/>
+ <xsl:variable name="controlField008-11"
+ select="substring(descendant-or-self::marc:controlfield[@tag=008],12,1)"/>
+ <xsl:variable name="controlField008-14"
+ select="substring(descendant-or-self::marc:controlfield[@tag=008],15,1)"/>
+ <xsl:template match="/">
+ <xsl:choose>
+ <xsl:when test="descendant-or-self::marc:collection">
+ <mads:madsCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.loc.gov/mads/v2 http://www.loc.gov/standards/mads/v2/mads-2-0.xsd">
+ <xsl:for-each select="descendant-or-self::marc:collection/marc:record">
+ <mads:mads version="2.0">
+ <xsl:call-template name="marcRecord"/>
+ </mads:mads>
+ </xsl:for-each>
+ </mads:madsCollection>
+ </xsl:when>
+ <xsl:otherwise>
+ <mads:mads version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.loc.gov/mads/v2 http://www.loc.gov/standards/mads/mads-2-0.xsd">
+ <xsl:for-each select="descendant-or-self::marc:record">
+ <xsl:call-template name="marcRecord"/>
+ </xsl:for-each>
+ </mads:mads>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="marcRecord">
+ <mads:authority>
+ <!-- 2.04 -->
+ <xsl:choose>
+ <xsl:when test="$controlField008-06='d'">
+ <xsl:attribute name="geographicSubdivision">
+ <xsl:text>direct</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when test="$controlField008-06='i'">
+ <xsl:attribute name="geographicSubdivision">
+ <xsl:text>indirect</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when test="$controlField008-06='n'">
+ <xsl:attribute name="geographicSubdivision">
+ <xsl:text>not applicable</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:apply-templates select="marc:datafield[100 <= @tag and @tag < 200]"/>
+ </mads:authority>
+
+ <!-- related -->
+ <xsl:apply-templates
+ select="marc:datafield[500 <= @tag and @tag <= 585]|marc:datafield[700 <= @tag and @tag <= 785]"/>
+
+ <!-- variant -->
+ <xsl:apply-templates select="marc:datafield[400 <= @tag and @tag <= 485]"/>
+
+ <!-- notes -->
+ <xsl:apply-templates select="marc:datafield[667 <= @tag and @tag <= 688]"/>
+
+ <!-- url -->
+ <xsl:apply-templates select="marc:datafield[@tag=856]"/>
+ <xsl:apply-templates select="marc:datafield[@tag=010]"/>
+ <xsl:apply-templates select="marc:datafield[@tag=024]"/>
+ <xsl:apply-templates select="marc:datafield[@tag=372]"/>
+
+ <!-- classification -->
+ <xsl:apply-templates select="marc:datafield[@tag=053]"/>
+ <xsl:apply-templates select="marc:datafield[@tag=055]"/>
+ <xsl:apply-templates select="marc:datafield[@tag=060]"/>
+ <xsl:apply-templates select="marc:datafield[@tag=065]"/>
+ <xsl:apply-templates select="marc:datafield[@tag=070]"/>
+ <xsl:apply-templates select="marc:datafield[@tag=080]"/>
+ <xsl:apply-templates select="marc:datafield[@tag=082]"/>
+ <xsl:apply-templates select="marc:datafield[@tag=083]"/>
+ <xsl:apply-templates select="marc:datafield[@tag=086]"/>
+ <xsl:apply-templates select="marc:datafield[@tag=087]"/>
+
+ <!-- affiliation-->
+ <xsl:for-each select="marc:datafield[@tag=373]">
+ <mads:affiliation>
+ <mads:position>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </mads:position>
+ <mads:dateValid point="start">
+ <xsl:value-of select="marc:subfield[@code='s']"/>
+ </mads:dateValid>
+ <mads:dateValid point="end">
+ <xsl:value-of select="marc:subfield[@code='t']"/>
+ </mads:dateValid>
+ </mads:affiliation>
+ </xsl:for-each>
+ <xsl:for-each select="marc:datafield[@tag=371]">
+ <mads:affiliation>
+ <mads:address>
+ <mads:street>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </mads:street>
+ <mads:city>
+ <xsl:value-of select="marc:subfield[@code='b']"/>
+ </mads:city>
+ <mads:state>
+ <xsl:value-of select="marc:subfield[@code='c']"/>
+ </mads:state>
+ <mads:country>
+ <xsl:value-of select="marc:subfield[@code='d']"/>
+ </mads:country>
+ <mads:postcode>
+ <xsl:value-of select="marc:subfield[@code='e']"/>
+ </mads:postcode>
+ </mads:address>
+ <mads:email>
+ <xsl:value-of select="marc:subfield[@code='m']"/>
+ </mads:email>
+ </mads:affiliation>
+ </xsl:for-each>
+
+ <!-- extension-->
+ <xsl:for-each select="marc:datafield[@tag=336]">
+ <mads:extension>
+ <mads:contentType>
+ <mads:contentType type="text">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </mads:contentType>
+ <mads:contentType type="code">
+ <xsl:value-of select="marc:subfield[@code='b']"/>
+ </mads:contentType>
+ </mads:contentType>
+ </mads:extension>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=374]">
+ <mads:extension>
+ <mads:profession>
+ <xsl:choose>
+ <xsl:when test="marc:subfield[@code='a']">
+ <mads:professionTerm>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </mads:professionTerm>
+ </xsl:when>
+ <xsl:when test="marc:subfield[@code='s']">
+ <mads:dateValid point="start">
+ <xsl:value-of select="marc:subfield[@code='s']"/>
+ </mads:dateValid>
+ </xsl:when>
+ <xsl:when test="marc:subfield[@code='t']">
+ <mads:dateValid point="end">
+ <xsl:value-of select="marc:subfield[@code='t']"/>
+ </mads:dateValid>
+ </xsl:when>
+ </xsl:choose>
+ </mads:profession>
+ </mads:extension>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=375]">
+ <mads:extension>
+ <mads:gender>
+ <xsl:choose>
+ <xsl:when test="marc:subfield[@code='a']">
+ <mads:genderTerm>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </mads:genderTerm>
+ </xsl:when>
+ <xsl:when test="marc:subfield[@code='s']">
+ <mads:dateValid point="start">
+ <xsl:value-of select="marc:subfield[@code='s']"/>
+ </mads:dateValid>
+ </xsl:when>
+ <xsl:when test="marc:subfield[@code='t']">
+ <mads:dateValid point="end">
+ <xsl:value-of select="marc:subfield[@code='t']"/>
+ </mads:dateValid>
+ </xsl:when>
+ </xsl:choose>
+ </mads:gender>
+ </mads:extension>
+ </xsl:for-each>
+
+ <xsl:for-each select="marc:datafield[@tag=376]">
+ <mads:extension>
+ <mads:familyInformation>
+ <mads:typeOfFamily>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </mads:typeOfFamily>
+ <mads:nameOfProminentMember>
+ <xsl:value-of select="marc:subfield[@code='b']"/>
+ </mads:nameOfProminentMember>
+ <mads:hereditaryTitle>
+ <xsl:value-of select="marc:subfield[@code='c']"/>
+ </mads:hereditaryTitle>
+ <mads:dateValid point="start">
+ <xsl:value-of select="marc:subfield[@code='s']"/>
+ </mads:dateValid>
+ <mads:dateValid point="end">
+ <xsl:value-of select="marc:subfield[@code='t']"/>
+ </mads:dateValid>
+ </mads:familyInformation>
+ </mads:extension>
+ </xsl:for-each>
+
+ <mads:recordInfo>
+ <mads:recordOrigin>Converted from MARCXML to MADS version 2.0 (Revision 2.13)</mads:recordOrigin>
+ <!-- <xsl:apply-templates select="marc:datafield[@tag=024]"/> -->
+
+ <xsl:apply-templates select="marc:datafield[@tag=040]/marc:subfield[@code='a']"/>
+ <xsl:apply-templates select="marc:controlfield[@tag=005]"/>
+ <xsl:apply-templates select="marc:controlfield[@tag=001]"/>
+ <xsl:apply-templates select="marc:datafield[@tag=040]/marc:subfield[@code='b']"/>
+ <xsl:apply-templates select="marc:datafield[@tag=040]/marc:subfield[@code='e']"/>
+ <xsl:for-each select="marc:controlfield[@tag=008]">
+ <xsl:if test="substring(.,11,1)='a'">
+ <mads:descriptionStandard>
+ <xsl:text>earlier rules</xsl:text>
+ </mads:descriptionStandard>
+ </xsl:if>
+ <xsl:if test="substring(.,11,1)='b'">
+ <mads:descriptionStandard>
+ <xsl:text>aacr1</xsl:text>
+ </mads:descriptionStandard>
+ </xsl:if>
+ <xsl:if test="substring(.,11,1)='c'">
+ <mads:descriptionStandard>
+ <xsl:text>aacr2</xsl:text>
+ </mads:descriptionStandard>
+ </xsl:if>
+ <xsl:if test="substring(.,11,1)='d'">
+ <mads:descriptionStandard>
+ <xsl:text>aacr2 compatible</xsl:text>
+ </mads:descriptionStandard>
+ </xsl:if>
+ <xsl:if test="substring(.,11,1)='z'">
+ <mads:descriptionStandard>
+ <xsl:text>other rules</xsl:text>
+ </mads:descriptionStandard>
+ </xsl:if>
+ </xsl:for-each>
+ </mads:recordInfo>
+ </xsl:template>
+
+ <!-- start of secondary templates -->
+
+ <!-- ======== xlink ======== -->
+
+ <!-- <xsl:template name="uri">
+ <xsl:for-each select="marc:subfield[@code='0']">
+ <xsl:attribute name="xlink:href">
+ <xsl:value-of select="."/>
+ </xsl:attribute>
+ </xsl:for-each>
+ </xsl:template>
+ -->
+ <xsl:template match="marc:subfield[@code='i']">
+ <xsl:attribute name="otherType">
+ <xsl:value-of select="."/>
+ </xsl:attribute>
+ </xsl:template>
+
+ <!-- No role/roleTerm mapped in MADS 06/24/2010
+ <xsl:template name="role">
+ <xsl:for-each select="marc:subfield[@code='e']">
+ <mads:role>
+ <mads:roleTerm type="text">
+ <xsl:value-of select="."/>
+ </mads:roleTerm>
+ </mads:role>
+ </xsl:for-each>
+ </xsl:template>
+-->
+
+ <xsl:template name="part">
+ <xsl:variable name="partNumber">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="axis">n</xsl:with-param>
+ <xsl:with-param name="anyCodes">n</xsl:with-param>
+ <xsl:with-param name="afterCodes">fghkdlmor</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="partName">
+ <xsl:call-template name="specialSubfieldSelect">
+ <xsl:with-param name="axis">p</xsl:with-param>
+ <xsl:with-param name="anyCodes">p</xsl:with-param>
+ <xsl:with-param name="afterCodes">fghkdlmor</xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:if test="string-length(normalize-space($partNumber))">
+ <mads:partNumber>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="$partNumber"/>
+ </xsl:call-template>
+ </mads:partNumber>
+ </xsl:if>
+ <xsl:if test="string-length(normalize-space($partName))">
+ <mads:partName>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="$partName"/>
+ </xsl:call-template>
+ </mads:partName>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="nameABCDN">
+ <xsl:for-each select="marc:subfield[@code='a']">
+ <mads:namePart>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </mads:namePart>
+ </xsl:for-each>
+ <xsl:for-each select="marc:subfield[@code='b']">
+ <mads:namePart>
+ <xsl:value-of select="."/>
+ </mads:namePart>
+ </xsl:for-each>
+ <xsl:if
+ test="marc:subfield[@code='c'] or marc:subfield[@code='d'] or marc:subfield[@code='n']">
+ <mads:namePart>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">cdn</xsl:with-param>
+ </xsl:call-template>
+ </mads:namePart>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="nameABCDQ">
+ <mads:namePart>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">aq</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </mads:namePart>
+ <xsl:call-template name="termsOfAddress"/>
+ <xsl:call-template name="nameDate"/>
+ </xsl:template>
+
+ <xsl:template name="nameACDENQ">
+ <mads:namePart>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">acdenq</xsl:with-param>
+ </xsl:call-template>
+ </mads:namePart>
+ </xsl:template>
+
+ <xsl:template name="nameDate">
+ <xsl:for-each select="marc:subfield[@code='d']">
+ <mads:namePart type="date">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString" select="."/>
+ </xsl:call-template>
+ </mads:namePart>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="specialSubfieldSelect">
+ <xsl:param name="anyCodes"/>
+ <xsl:param name="axis"/>
+ <xsl:param name="beforeCodes"/>
+ <xsl:param name="afterCodes"/>
+ <xsl:variable name="str">
+ <xsl:for-each select="marc:subfield">
+ <xsl:if
+ test="contains($anyCodes, @code) or (contains($beforeCodes,@code) and following-sibling::marc:subfield[@code=$axis]) or (contains($afterCodes,@code) and preceding-sibling::marc:subfield[@code=$axis])">
+ <xsl:value-of select="text()"/>
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+ </xsl:template>
+
+ <xsl:template name="termsOfAddress">
+ <xsl:if test="marc:subfield[@code='b' or @code='c']">
+ <mads:namePart type="termsOfAddress">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">bc</xsl:with-param>
+ </xsl:call-template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </mads:namePart>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="displayLabel">
+ <xsl:if test="marc:subfield[@code='z']">
+ <xsl:attribute name="displayLabel">
+ <xsl:value-of select="marc:subfield[@code='z']"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:if test="marc:subfield[@code='3']">
+ <xsl:attribute name="displayLabel">
+ <xsl:value-of select="marc:subfield[@code='3']"/>
+ </xsl:attribute>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="isInvalid">
+ <xsl:if test="@code='z'">
+ <xsl:attribute name="invalid">yes</xsl:attribute>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="sub2Attribute">
+ <!-- 024 -->
+ <xsl:if test="../marc:subfield[@code='2']">
+ <xsl:attribute name="type">
+ <xsl:value-of select="../marc:subfield[@code='2']"/>
+ </xsl:attribute>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="marc:controlfield[@tag=001]">
+ <mads:recordIdentifier>
+ <xsl:if test="../marc:controlfield[@tag=003]">
+ <xsl:attribute name="source">
+ <xsl:value-of select="../marc:controlfield[@tag=003]"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="."/>
+ </mads:recordIdentifier>
+ </xsl:template>
+
+ <xsl:template match="marc:controlfield[@tag=005]">
+ <mads:recordChangeDate encoding="iso8601">
+ <xsl:value-of select="."/>
+ </mads:recordChangeDate>
+ </xsl:template>
+
+ <xsl:template match="marc:controlfield[@tag=008]">
+ <mads:recordCreationDate encoding="marc">
+ <xsl:value-of select="substring(.,1,6)"/>
+ </mads:recordCreationDate>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=010]">
+ <xsl:for-each select="marc:subfield">
+ <mads:identifier type="lccn">
+ <xsl:call-template name="isInvalid"/>
+ <xsl:value-of select="."/>
+ </mads:identifier>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=024]">
+ <xsl:for-each select="marc:subfield[not(@code=2)]">
+ <mads:identifier>
+ <xsl:call-template name="isInvalid"/>
+ <xsl:call-template name="sub2Attribute"/>
+ <xsl:value-of select="."/>
+ </mads:identifier>
+ </xsl:for-each>
+ </xsl:template>
+
+ <!-- ========== 372 ========== -->
+ <xsl:template match="marc:datafield[@tag=372]">
+ <mads:fieldOfActivity>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">a</xsl:with-param>
+ </xsl:call-template>
+ <xsl:text>-</xsl:text>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">st</xsl:with-param>
+ </xsl:call-template>
+ </mads:fieldOfActivity>
+ </xsl:template>
+
+
+ <!-- ========== 040 ========== -->
+ <xsl:template match="marc:datafield[@tag=040]/marc:subfield[@code='a']">
+ <mads:recordContentSource authority="marcorg">
+ <xsl:value-of select="."/>
+ </mads:recordContentSource>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=040]/marc:subfield[@code='b']">
+ <mads:languageOfCataloging>
+ <mads:languageTerm authority="iso639-2b" type="code">
+ <xsl:value-of select="."/>
+ </mads:languageTerm>
+ </mads:languageOfCataloging>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=040]/marc:subfield[@code='e']">
+ <mads:descriptionStandard>
+ <xsl:value-of select="."/>
+ </mads:descriptionStandard>
+ </xsl:template>
+
+ <!-- ========== classification 2.03 ========== -->
+
+ <xsl:template match="marc:datafield[@tag=053]">
+ <mads:classification>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcdxyz</xsl:with-param>
+ <xsl:with-param name="delimeter">-</xsl:with-param>
+ </xsl:call-template>
+ </mads:classification>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=055]">
+ <mads:classification>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcdxyz</xsl:with-param>
+ <xsl:with-param name="delimeter">-</xsl:with-param>
+ </xsl:call-template>
+ </mads:classification>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=060]">
+ <mads:classification>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcdxyz</xsl:with-param>
+ <xsl:with-param name="delimeter">-</xsl:with-param>
+ </xsl:call-template>
+ </mads:classification>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=065]">
+ <mads:classification>
+ <xsl:attribute name="authority">
+ <xsl:value-of select="marc:subfield[@code='2']"/>
+ </xsl:attribute>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcdxyz</xsl:with-param>
+ <xsl:with-param name="delimeter">-</xsl:with-param>
+ </xsl:call-template>
+ </mads:classification>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=070]">
+ <mads:classification>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
+ <xsl:with-param name="delimeter">-</xsl:with-param>
+ </xsl:call-template>
+ </mads:classification>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=080]">
+ <mads:classification>
+ <xsl:attribute name="authority">
+ <xsl:value-of select="marc:subfield[@code='2']"/>
+ </xsl:attribute>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
+ <xsl:with-param name="delimeter">-</xsl:with-param>
+ </xsl:call-template>
+ </mads:classification>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=082]">
+ <mads:classification>
+ <xsl:attribute name="authority">
+ <xsl:value-of select="marc:subfield[@code='2']"/>
+ </xsl:attribute>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
+ <xsl:with-param name="delimeter">-</xsl:with-param>
+ </xsl:call-template>
+ </mads:classification>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=083]">
+ <mads:classification>
+ <xsl:attribute name="authority">
+ <xsl:value-of select="marc:subfield[@code='2']"/>
+ </xsl:attribute>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
+ <xsl:with-param name="delimeter">-</xsl:with-param>
+ </xsl:call-template>
+ </mads:classification>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=086]">
+ <mads:classification>
+ <xsl:attribute name="authority">
+ <xsl:value-of select="marc:subfield[@code='2']"/>
+ </xsl:attribute>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
+ <xsl:with-param name="delimeter">-</xsl:with-param>
+ </xsl:call-template>
+ </mads:classification>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=087]">
+ <mads:classification>
+ <xsl:attribute name="authority">
+ <xsl:value-of select="marc:subfield[@code='2']"/>
+ </xsl:attribute>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">abcdxyz5</xsl:with-param>
+ <xsl:with-param name="delimeter">-</xsl:with-param>
+ </xsl:call-template>
+ </mads:classification>
+ </xsl:template>
+
+
+ <!-- ========== names ========== -->
+ <xsl:template match="marc:datafield[@tag=100]">
+ <mads:name type="personal">
+ <xsl:call-template name="setAuthority"/>
+ <xsl:call-template name="nameABCDQ"/>
+ </mads:name>
+ <xsl:apply-templates select="*[marc:subfield[not(contains('abcdeq',@code))]]"/>
+ <xsl:call-template name="title"/>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=110]">
+ <mads:name type="corporate">
+ <xsl:call-template name="setAuthority"/>
+ <xsl:call-template name="nameABCDN"/>
+ </mads:name>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=111]">
+ <mads:name type="conference">
+ <xsl:call-template name="setAuthority"/>
+ <xsl:call-template name="nameACDENQ"/>
+ </mads:name>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=400]">
+ <mads:variant>
+ <xsl:call-template name="variantTypeAttribute"/>
+ <mads:name type="personal">
+ <xsl:call-template name="nameABCDQ"/>
+ </mads:name>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ <xsl:call-template name="title"/>
+ </mads:variant>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=410]">
+ <mads:variant>
+ <xsl:call-template name="variantTypeAttribute"/>
+ <mads:name type="corporate">
+ <xsl:call-template name="nameABCDN"/>
+ </mads:name>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </mads:variant>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=411]">
+ <mads:variant>
+ <xsl:call-template name="variantTypeAttribute"/>
+ <mads:name type="conference">
+ <xsl:call-template name="nameACDENQ"/>
+ </mads:name>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </mads:variant>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=500]|marc:datafield[@tag=700]">
+ <mads:related>
+ <xsl:call-template name="relatedTypeAttribute"/>
+ <!-- <xsl:call-template name="uri"/> -->
+ <mads:name type="personal">
+ <xsl:call-template name="setAuthority"/>
+ <xsl:call-template name="nameABCDQ"/>
+ </mads:name>
+ <xsl:call-template name="title"/>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </mads:related>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=510]|marc:datafield[@tag=710]">
+ <mads:related>
+ <xsl:call-template name="relatedTypeAttribute"/>
+ <!-- <xsl:call-template name="uri"/> -->
+ <mads:name type="corporate">
+ <xsl:call-template name="setAuthority"/>
+ <xsl:call-template name="nameABCDN"/>
+ </mads:name>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </mads:related>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=511]|marc:datafield[@tag=711]">
+ <mads:related>
+ <xsl:call-template name="relatedTypeAttribute"/>
+ <!-- <xsl:call-template name="uri"/> -->
+ <mads:name type="conference">
+ <xsl:call-template name="setAuthority"/>
+ <xsl:call-template name="nameACDENQ"/>
+ </mads:name>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </mads:related>
+ </xsl:template>
+
+ <!-- ========== titles ========== -->
+ <xsl:template match="marc:datafield[@tag=130]">
+ <xsl:call-template name="uniform-title"/>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=430]">
+ <mads:variant>
+ <xsl:call-template name="variantTypeAttribute"/>
+ <xsl:call-template name="uniform-title"/>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </mads:variant>
+ </xsl:template>
+
+ <xsl:template match="marc:datafield[@tag=530]|marc:datafield[@tag=730]">
+ <mads:related>
+ <xsl:call-template name="relatedTypeAttribute"/>
+ <xsl:call-template name="uniform-title"/>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </mads:related>
+ </xsl:template>
+
+ <xsl:template name="title">
+ <xsl:variable name="hasTitle">
+ <xsl:for-each select="marc:subfield">
+ <xsl:if test="(contains('tfghklmors',@code) )">
+ <xsl:value-of select="@code"/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:if test="string-length($hasTitle) > 0 ">
+ <mads:titleInfo>
+ <xsl:call-template name="setAuthority"/>
+ <mads:title>
+ <xsl:variable name="str">
+ <xsl:for-each select="marc:subfield">
+ <xsl:if test="(contains('atfghklmors',@code) )">
+ <xsl:value-of select="text()"/>
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </mads:title>
+ <xsl:call-template name="part"/>
+ <!-- <xsl:call-template name="uri"/> -->
+ </mads:titleInfo>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="uniform-title">
+ <xsl:variable name="hasTitle">
+ <xsl:for-each select="marc:subfield">
+ <xsl:if test="(contains('atfghklmors',@code) )">
+ <xsl:value-of select="@code"/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:if test="string-length($hasTitle) > 0 ">
+ <mads:titleInfo>
+ <xsl:call-template name="setAuthority"/>
+ <mads:title>
+ <xsl:variable name="str">
+ <xsl:for-each select="marc:subfield">
+ <xsl:if test="(contains('adfghklmors',@code) )">
+ <xsl:value-of select="text()"/>
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="substring($str,1,string-length($str)-1)"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </mads:title>
+ <xsl:call-template name="part"/>
+ <!-- <xsl:call-template name="uri"/> -->
+ </mads:titleInfo>
+ </xsl:if>
+ </xsl:template>
+
+
+ <!-- ========== topics ========== -->
+ <xsl:template match="marc:subfield[@code='x']">
+ <mads:topic>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="."/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </mads:topic>
+ </xsl:template>
+
+ <!-- 2.06 fix -->
+ <xsl:template
+ match="marc:datafield[@tag=150][marc:subfield[@code='a' or @code='b']]|marc:datafield[@tag=180][marc:subfield[@code='x']]">
+ <xsl:call-template name="topic"/>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </xsl:template>
+ <xsl:template
+ match="marc:datafield[@tag=450][marc:subfield[@code='a' or @code='b']]|marc:datafield[@tag=480][marc:subfield[@code='x']]">
+ <mads:variant>
+ <xsl:call-template name="variantTypeAttribute"/>
+ <xsl:call-template name="topic"/>
+ </mads:variant>
+ </xsl:template>
+ <xsl:template
+ match="marc:datafield[@tag=550 or @tag=750][marc:subfield[@code='a' or @code='b']]">
+ <mads:related>
+ <xsl:call-template name="relatedTypeAttribute"/>
+ <!-- <xsl:call-template name="uri"/> -->
+ <xsl:call-template name="topic"/>
+ <xsl:apply-templates select="marc:subfield[@code='z']"/>
+ </mads:related>
+ </xsl:template>
+ <xsl:template name="topic">
+ <mads:topic>
+ <xsl:call-template name="setAuthority"/>
+ <!-- tmee2006 dedupe 550a
+ <xsl:if test="@tag=550 or @tag=750">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ -->
+ <xsl:choose>
+ <xsl:when test="@tag=180 or @tag=480 or @tag=580 or @tag=780">
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:apply-templates select="marc:subfield[@code='x']"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ </xsl:choose>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:choose>
+ <xsl:when test="@tag=180 or @tag=480 or @tag=580 or @tag=780">
+ <xsl:apply-templates select="marc:subfield[@code='x']"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:with-param>
+ </xsl:call-template>
+ </mads:topic>
+ </xsl:template>
+
+ <!-- ========= temporals ========== -->
+ <xsl:template match="marc:subfield[@code='y']">
+ <mads:temporal>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="."/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </mads:temporal>
+ </xsl:template>
+ <xsl:template
+ match="marc:datafield[@tag=148][marc:subfield[@code='a']]|marc:datafield[@tag=182 ][marc:subfield[@code='y']]">
+ <xsl:call-template name="temporal"/>
+ </xsl:template>
+ <xsl:template
+ match="marc:datafield[@tag=448][marc:subfield[@code='a']]|marc:datafield[@tag=482][marc:subfield[@code='y']]">
+ <mads:variant>
+ <xsl:call-template name="variantTypeAttribute"/>
+ <xsl:call-template name="temporal"/>
+ </mads:variant>
+ </xsl:template>
+ <xsl:template
+ match="marc:datafield[@tag=548 or @tag=748][marc:subfield[@code='a']]|marc:datafield[@tag=582 or @tag=782][marc:subfield[@code='y']]">
+ <mads:related>
+ <xsl:call-template name="relatedTypeAttribute"/>
+ <!-- <xsl:call-template name="uri"/> -->
+ <xsl:call-template name="temporal"/>
+ </mads:related>
+ </xsl:template>
+ <xsl:template name="temporal">
+ <mads:temporal>
+ <xsl:call-template name="setAuthority"/>
+ <xsl:if test="@tag=548 or @tag=748">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </xsl:if>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:choose>
+ <xsl:when test="@tag=182 or @tag=482 or @tag=582 or @tag=782">
+ <xsl:apply-templates select="marc:subfield[@code='y']"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:with-param>
+ </xsl:call-template>
+ </mads:temporal>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </xsl:template>
+
+ <!-- ========== genre ========== -->
+ <xsl:template match="marc:subfield[@code='v']">
+ <mads:genre>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="."/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </mads:genre>
+ </xsl:template>
+ <xsl:template
+ match="marc:datafield[@tag=155][marc:subfield[@code='a']]|marc:datafield[@tag=185][marc:subfield[@code='v']]">
+ <xsl:call-template name="genre"/>
+ </xsl:template>
+ <xsl:template
+ match="marc:datafield[@tag=455][marc:subfield[@code='a']]|marc:datafield[@tag=485 ][marc:subfield[@code='v']]">
+ <mads:variant>
+ <xsl:call-template name="variantTypeAttribute"/>
+ <xsl:call-template name="genre"/>
+ </mads:variant>
+ </xsl:template>
+ <!--
+ <xsl:template match="marc:datafield[@tag=555]">
+ <mads:related>
+ <xsl:call-template name="relatedTypeAttribute"/>
+ <xsl:call-template name="uri"/>
+ <xsl:call-template name="genre"/>
+ </mads:related>
+ </xsl:template>
+ -->
+ <xsl:template
+ match="marc:datafield[@tag=555 or @tag=755][marc:subfield[@code='a']]|marc:datafield[@tag=585][marc:subfield[@code='v']]">
+ <mads:related>
+ <xsl:call-template name="relatedTypeAttribute"/>
+ <xsl:call-template name="genre"/>
+ </mads:related>
+ </xsl:template>
+ <xsl:template name="genre">
+ <mads:genre>
+ <xsl:if test="@tag=555">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </xsl:if>
+ <xsl:call-template name="setAuthority"/>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:choose>
+ <!-- 2.07 fix -->
+ <xsl:when test="@tag='555'"/>
+ <xsl:when test="@tag=185 or @tag=485 or @tag=585">
+ <xsl:apply-templates select="marc:subfield[@code='v']"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:with-param>
+ </xsl:call-template>
+ </mads:genre>
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <!-- ========= geographic ========== -->
+ <xsl:template match="marc:subfield[@code='z']">
+ <mads:geographic>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:value-of select="."/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </mads:geographic>
+ </xsl:template>
+ <xsl:template name="geographic">
+ <mads:geographic>
+ <!-- 2.14 -->
+ <xsl:call-template name="setAuthority"/>
+ <!-- 2.13 -->
+ <xsl:if test="@tag=151 or @tag=551">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </xsl:if>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:if test="@tag=181 or @tag=481 or @tag=581">
+ <xsl:apply-templates select="marc:subfield[@code='z']"/>
+ </xsl:if>
+ <!-- 2.13
+ <xsl:choose>
+ <xsl:when test="@tag=181 or @tag=481 or @tag=581">
+ <xsl:apply-templates select="marc:subfield[@code='z']"/>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ -->
+ </xsl:with-param>
+ </xsl:call-template>
+ </mads:geographic>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </xsl:template>
+ <xsl:template
+ match="marc:datafield[@tag=151][marc:subfield[@code='a']]|marc:datafield[@tag=181][marc:subfield[@code='z']]">
+ <xsl:call-template name="geographic"/>
+ </xsl:template>
+ <xsl:template
+ match="marc:datafield[@tag=451][marc:subfield[@code='a']]|marc:datafield[@tag=481][marc:subfield[@code='z']]">
+ <mads:variant>
+ <xsl:call-template name="variantTypeAttribute"/>
+ <xsl:call-template name="geographic"/>
+ </mads:variant>
+ </xsl:template>
+ <xsl:template
+ match="marc:datafield[@tag=551]|marc:datafield[@tag=581][marc:subfield[@code='z']]">
+ <mads:related>
+ <xsl:call-template name="relatedTypeAttribute"/>
+ <!-- <xsl:call-template name="uri"/> -->
+ <xsl:call-template name="geographic"/>
+ </mads:related>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=580]">
+ <mads:related>
+ <xsl:call-template name="relatedTypeAttribute"/>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </mads:related>
+ </xsl:template>
+ <xsl:template
+ match="marc:datafield[@tag=751][marc:subfield[@code='z']]|marc:datafield[@tag=781][marc:subfield[@code='z']]">
+ <mads:related>
+ <xsl:call-template name="relatedTypeAttribute"/>
+ <xsl:call-template name="geographic"/>
+ </mads:related>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=755]">
+ <mads:related>
+ <xsl:call-template name="relatedTypeAttribute"/>
+ <xsl:call-template name="setAuthority"/>
+ <xsl:call-template name="genre"/>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </mads:related>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=780]">
+ <mads:related>
+ <xsl:call-template name="relatedTypeAttribute"/>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </mads:related>
+ </xsl:template>
+ <xsl:template match="marc:datafield[@tag=785]">
+ <mads:related>
+ <xsl:call-template name="relatedTypeAttribute"/>
+ <xsl:apply-templates select="marc:subfield[@code!='i']"/>
+ </mads:related>
+ </xsl:template>
+
+ <!-- ========== notes ========== -->
+ <xsl:template match="marc:datafield[667 <= @tag and @tag <= 688]">
+ <mads:note>
+ <xsl:choose>
+ <xsl:when test="@tag=667">
+ <xsl:attribute name="type">nonpublic</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@tag=670">
+ <xsl:attribute name="type">source</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@tag=675">
+ <xsl:attribute name="type">notFound</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@tag=678">
+ <xsl:attribute name="type">history</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@tag=681">
+ <xsl:attribute name="type">subject example</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@tag=682">
+ <xsl:attribute name="type">deleted heading information</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="@tag=688">
+ <xsl:attribute name="type">application history</xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+ <xsl:call-template name="chopPunctuation">
+ <xsl:with-param name="chopString">
+ <xsl:choose>
+ <xsl:when test="@tag=667 or @tag=675">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </xsl:when>
+ <xsl:when test="@tag=670 or @tag=678">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ab</xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="680 <= @tag and @tag <=688">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">ai</xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:with-param>
+ </xsl:call-template>
+ </mads:note>
+ </xsl:template>
+
+ <!-- ========== url ========== -->
+ <xsl:template match="marc:datafield[@tag=856][marc:subfield[@code='u']]">
+ <mads:url>
+ <xsl:if test="marc:subfield[@code='z' or @code='3']">
+ <xsl:attribute name="displayLabel">
+ <xsl:call-template name="subfieldSelect">
+ <xsl:with-param name="codes">z3</xsl:with-param>
+ </xsl:call-template>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="marc:subfield[@code='u']"/>
+ </mads:url>
+ </xsl:template>
+
+ <xsl:template name="relatedTypeAttribute">
+ <xsl:choose>
+ <xsl:when
+ test="@tag=500 or @tag=510 or @tag=511 or @tag=548 or @tag=550 or @tag=551 or @tag=555 or @tag=580 or @tag=581 or @tag=582 or @tag=585">
+ <xsl:if test="substring(marc:subfield[@code='w'],1,1)='a'">
+ <xsl:attribute name="type">earlier</xsl:attribute>
+ </xsl:if>
+ <xsl:if test="substring(marc:subfield[@code='w'],1,1)='b'">
+ <xsl:attribute name="type">later</xsl:attribute>
+ </xsl:if>
+ <xsl:if test="substring(marc:subfield[@code='w'],1,1)='t'">
+ <xsl:attribute name="type">parentOrg</xsl:attribute>
+ </xsl:if>
+ <xsl:if test="substring(marc:subfield[@code='w'],1,1)='g'">
+ <xsl:attribute name="type">broader</xsl:attribute>
+ </xsl:if>
+ <xsl:if test="substring(marc:subfield[@code='w'],1,1)='h'">
+ <xsl:attribute name="type">narrower</xsl:attribute>
+ </xsl:if>
+ <xsl:if test="substring(marc:subfield[@code='w'],1,1)='r'">
+ <xsl:attribute name="type">other</xsl:attribute>
+ </xsl:if>
+ <xsl:if test="contains('fin|', substring(marc:subfield[@code='w'],1,1))">
+ <xsl:attribute name="type">other</xsl:attribute>
+ </xsl:if>
+ </xsl:when>
+ <xsl:when test="@tag=530 or @tag=730">
+ <xsl:attribute name="type">other</xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- 7xx -->
+ <xsl:attribute name="type">equivalent</xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:apply-templates select="marc:subfield[@code='i']"/>
+ </xsl:template>
+
+
+
+ <xsl:template name="variantTypeAttribute">
+ <xsl:choose>
+ <xsl:when
+ test="@tag=400 or @tag=410 or @tag=411 or @tag=451 or @tag=455 or @tag=480 or @tag=481 or @tag=482 or @tag=485">
+ <xsl:if test="substring(marc:subfield[@code='w'],1,1)='d'">
+ <xsl:attribute name="type">acronym</xsl:attribute>
+ </xsl:if>
+ <xsl:if test="substring(marc:subfield[@code='w'],1,1)='n'">
+ <xsl:attribute name="type">other</xsl:attribute>
+ </xsl:if>
+ <xsl:if test="contains('fit', substring(marc:subfield[@code='w'],1,1))">
+ <xsl:attribute name="type">other</xsl:attribute>
+ </xsl:if>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- 430 -->
+ <xsl:attribute name="type">other</xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:apply-templates select="marc:subfield[@code='i']"/>
+ </xsl:template>
+
+ <xsl:template name="setAuthority">
+ <xsl:choose>
+ <!-- can be called from the datafield or subfield level, so "..//@tag" means
+ the tag can be at the subfield's parent level or at the datafields own level -->
+
+ <xsl:when
+ test="ancestor-or-self::marc:datafield/@tag=100 and (@ind1=0 or @ind1=1) and $controlField008-11='a' and $controlField008-14='a'">
+ <xsl:attribute name="authority">
+ <xsl:text>naf</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="ancestor-or-self::marc:datafield/@tag=100 and (@ind1=0 or @ind1=1) and $controlField008-11='a' and $controlField008-14='b'">
+ <xsl:attribute name="authority">
+ <xsl:text>lcsh</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="ancestor-or-self::marc:datafield/@tag=100 and (@ind1=0 or @ind1=1) and $controlField008-11='k'">
+ <xsl:attribute name="authority">
+ <xsl:text>lacnaf</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="ancestor-or-self::marc:datafield/@tag=100 and @ind1=3 and $controlField008-11='a' and $controlField008-14='b'">
+ <xsl:attribute name="authority">
+ <xsl:text>lcsh</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="ancestor-or-self::marc:datafield/@tag=100 and @ind1=3 and $controlField008-11='k' and $controlField008-14='b'">
+ <xsl:attribute name="authority">cash</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='a' and $controlField008-14='a'">
+ <xsl:attribute name="authority">naf</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='a' and $controlField008-14='b'">
+ <xsl:attribute name="authority">lcsh</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='k' and $controlField008-14='a'">
+ <xsl:attribute name="authority">
+ <xsl:text>lacnaf</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="ancestor-or-self::marc:datafield/@tag=110 and $controlField008-11='k' and $controlField008-14='b'">
+ <xsl:attribute name="authority">
+ <xsl:text>cash</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="100 <= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag <= 155 and $controlField008-11='b'">
+ <xsl:attribute name="authority">
+ <xsl:text>lcshcl</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=100 or ancestor-or-self::marc:datafield/@tag=110 or ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130 or ancestor-or-self::marc:datafield/@tag=151) and $controlField008-11='c'">
+ <xsl:attribute name="authority">
+ <xsl:text>nlmnaf</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=100 or ancestor-or-self::marc:datafield/@tag=110 or ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130 or ancestor-or-self::marc:datafield/@tag=151) and $controlField008-11='d'">
+ <xsl:attribute name="authority">
+ <xsl:text>nalnaf</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="100 <= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag <= 155 and $controlField008-11='r'">
+ <xsl:attribute name="authority">
+ <xsl:text>aat</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="100 <= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag <= 155 and $controlField008-11='s'">
+ <xsl:attribute name="authority">sears</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="100 <= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag <= 155 and $controlField008-11='v'">
+ <xsl:attribute name="authority">rvm</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="100 <= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag <= 155 and $controlField008-11='z'">
+ <xsl:attribute name="authority">
+ <xsl:value-of
+ select="../marc:datafield[ancestor-or-self::marc:datafield/@tag=040]/marc:subfield[@code='f']"
+ />
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130) and $controlField008-11='a' and $controlField008-14='a'">
+ <xsl:attribute name="authority">
+ <xsl:text>naf</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130) and $controlField008-11='a' and $controlField008-14='b'">
+ <xsl:attribute name="authority">
+ <xsl:text>lcsh</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=111 or ancestor-or-self::marc:datafield/@tag=130) and $controlField008-11='k' ">
+ <xsl:attribute name="authority">
+ <xsl:text>lacnaf</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150 or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='a' ">
+ <xsl:attribute name="authority">
+ <xsl:text>lcsh</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150 or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='a' ">
+ <xsl:attribute name="authority">
+ <xsl:text>lcsh</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150 or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='c' ">
+ <xsl:attribute name="authority">
+ <xsl:text>mesh</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150 or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='d' ">
+ <xsl:attribute name="authority">
+ <xsl:text>nal</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=148 or ancestor-or-self::marc:datafield/@tag=150 or ancestor-or-self::marc:datafield/@tag=155) and $controlField008-11='k' ">
+ <xsl:attribute name="authority">
+ <xsl:text>cash</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='a' and $controlField008-14='a'">
+ <xsl:attribute name="authority">
+ <xsl:text>naf</xsl:text>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='a' and $controlField008-14='b'">
+ <xsl:attribute name="authority">lcsh</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='k' and $controlField008-14='a'">
+ <xsl:attribute name="authority">lacnaf</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="ancestor-or-self::marc:datafield/@tag=151 and $controlField008-11='k' and $controlField008-14='b'">
+ <xsl:attribute name="authority">cash</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(..//ancestor-or-self::marc:datafield/@tag=180 or ..//ancestor-or-self::marc:datafield/@tag=181 or ..//ancestor-or-self::marc:datafield/@tag=182 or ..//ancestor-or-self::marc:datafield/@tag=185) and $controlField008-11='a'">
+ <xsl:attribute name="authority">lcsh</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="ancestor-or-self::marc:datafield/@tag=700 and (@ind1='0' or @ind1='1') and @ind2='0'">
+ <xsl:attribute name="authority">naf</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="ancestor-or-self::marc:datafield/@tag=700 and (@ind1='0' or @ind1='1') and @ind2='5'">
+ <xsl:attribute name="authority">lacnaf</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="ancestor-or-self::marc:datafield/@tag=700 and @ind1='3' and @ind2='0'">
+ <xsl:attribute name="authority">lcsh</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="ancestor-or-self::marc:datafield/@tag=700 and @ind1='3' and @ind2='5'">
+ <xsl:attribute name="authority">cash</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(700 <= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag <= 755 ) and @ind2='1'">
+ <xsl:attribute name="authority">lcshcl</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=700 or ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751) and @ind2='2'">
+ <xsl:attribute name="authority">nlmnaf</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=700 or ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751) and @ind2='3'">
+ <xsl:attribute name="authority">nalnaf</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(700 <= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag <= 755 ) and @ind2='6'">
+ <xsl:attribute name="authority">rvm</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(700 <= ancestor-or-self::marc:datafield/@tag and ancestor-or-self::marc:datafield/@tag <= 755 ) and @ind2='7'">
+ <xsl:attribute name="authority">
+ <xsl:value-of select="marc:subfield[@code='2']"/>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751) and @ind2='5'">
+ <xsl:attribute name="authority">lacnaf</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=710 or ancestor-or-self::marc:datafield/@tag=711 or ancestor-or-self::marc:datafield/@tag=730 or ancestor-or-self::marc:datafield/@tag=751) and @ind2='0'">
+ <xsl:attribute name="authority">naf</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755) and @ind2='0'">
+ <xsl:attribute name="authority">lcsh</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755) and @ind2='2'">
+ <xsl:attribute name="authority">mesh</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755) and @ind2='3'">
+ <xsl:attribute name="authority">nal</xsl:attribute>
+ </xsl:when>
+ <xsl:when
+ test="(ancestor-or-self::marc:datafield/@tag=748 or ancestor-or-self::marc:datafield/@tag=750 or ancestor-or-self::marc:datafield/@tag=755) and @ind2='5'">
+ <xsl:attribute name="authority">cash</xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:template>
+ <xsl:template match="*"/>
+</xsl:stylesheet>$XSLT$ WHERE name = 'mads21';
+
+COMMIT;
+
+-- Update auditor tables to catch changes to source tables.
+-- Can be removed/skipped if there were no schema changes.
+SELECT auditor.update_auditors();
<html><head><script></script></head><body onload="var x = document.getElementById('version'); var version ='/xul/server/'.split(/\//)[2]; if (version == 'server') { version = 'versionless debug build'; } x.appendChild(document.createTextNode(version));">
<h1 style="text-decoration: underline">Evergreen</h1>
<p>Target Server ID: <span id="version"></span></p>
-<p>$HeadURL$</p>
+<p>http://git.evergreen-ils.org/?p=Evergreen.git;a=shortlog;h=refs/heads/tags/rel_3_7_3</p>
<h2>What is Evergreen?</h2>
<blockquote>
<p>
pref("open-ils.enable_join_tabs", true);
// We'll use this one to help brand some build information into the client, and rely on subversion keywords
-pref("open-ils.repository.headURL","$HeadURL$");
+pref("open-ils.repository.headURL","http://git.evergreen-ils.org/?p=Evergreen.git;a=shortlog;h=refs/heads/tags/rel_3_7_3");
pref("open-ils.repository.author","$Author$");
pref("open-ils.repository.revision","$Revision$");
pref("open-ils.repository.date","$Date$");
; HM NIS Edit Wizard helper defines
; Old versions of makensis don't like this, moved to Makefile
;!define /file PRODUCT_VERSION "client/VERSION"
-!define PRODUCT_TAG "Master"
+!define PRODUCT_TAG "3.7"
!define PRODUCT_INSTALL_TAG "${PRODUCT_TAG}"
!define UI_IMAGESET "beta"
;!define UI_IMAGESET "release"
+++ /dev/null
-docs/modules/installation/pages/server_installation.adoc
\ No newline at end of file
--- /dev/null
+= Installing the Evergreen server =
+:toc:
+
+== Preamble: referenced user accounts ==
+
+In subsequent sections, we will refer to a number of different accounts, as
+follows:
+
+ * Linux user accounts:
+ ** The *user* Linux account is the account that you use to log onto the
+ Linux system as a regular user.
+ ** The *root* Linux account is an account that has system administrator
+ privileges. On Debian you can switch to this account from
+ your *user* account by issuing the `su -` command and entering the
+ password for the *root* account when prompted. On Ubuntu you can switch
+ to this account from your *user* account using the `sudo su -` command
+ and entering the password for your *user* account when prompted.
+ ** The *opensrf* Linux account is an account that you create when installing
+ OpenSRF. You can switch to this account from the *root* account by
+ issuing the `su - opensrf` command.
+ ** The *postgres* Linux account is created automatically when you install
+ the PostgreSQL database server. You can switch to this account from the
+ *root* account by issuing the `su - postgres` command.
+ * PostgreSQL user accounts:
+ ** The *evergreen* PostgreSQL account is a superuser account that you will
+ create to connect to the PostgreSQL database server.
+ * Evergreen administrator account:
+ ** The *egadmin* Evergreen account is an administrator account for
+ Evergreen that you will use to test connectivity and configure your
+ Evergreen instance.
+
+== Preamble: developer instructions ==
+
+[NOTE]
+Skip this section if you are using an official release tarball downloaded
+from http://evergreen-ils.org/egdownloads
+
+Developers working directly with the source code from the Git repository,
+rather than an official release tarball, must perform one step before they
+can proceed with the `./configure` step.
+
+As the *user* Linux account, issue the following command in the Evergreen
+source directory to generate the configure script and Makefiles:
+
+[source, bash]
+------------------------------------------------------------------------------
+autoreconf -i
+------------------------------------------------------------------------------
+
+== Installing prerequisites ==
+
+ * **PostgreSQL**: The minimum supported version is 9.6.
+ * **Linux**: Evergreen has been tested on
+ Debian Buster (10),
+ Debian Stretch (9),
+ Debian Jessie (8),
+ Ubuntu Focal Fossa (20.04),
+ and Ubuntu Bionic Beaver (18.04).
+ If you are running an older version of these distributions, you may want
+ to upgrade before upgrading Evergreen. For instructions on upgrading these
+ distributions, visit the Debian or Ubuntu websites.
+ * **OpenSRF**: The minimum supported version of OpenSRF is 3.2.0.
+
+
+Evergreen has a number of prerequisite packages that must be installed
+before you can successfully configure, compile, and install Evergreen.
+
+1. Begin by installing the most recent version of OpenSRF (3.2.0 or later).
+ You can download OpenSRF releases from http://evergreen-ils.org/opensrf-downloads/
++
+2. Issue the following commands as the *root* Linux account to install
+ prerequisites using the `Makefile.install` prerequisite installer,
+ substituting `debian-buster`,`debian-stretch`,`debian-jessie`,`ubuntu-focal`,
+ or `ubuntu-bionic` for <osname> below:
++
+[source, bash]
+------------------------------------------------------------------------------
+make -f Open-ILS/src/extras/Makefile.install <osname>
+------------------------------------------------------------------------------
++
+[[optional_developer_additions]]
+3. OPTIONAL: Developer additions
++
+To perform certain developer tasks from a Git source code checkout,
+including the testing of the Angular web client components,
+additional packages may be required. As the *root* Linux account:
++
+ * To install packages needed for retrieving and managing web dependencies,
+ use the <osname>-developer Makefile.install target. Currently,
+ this is only needed for building and installing the web
+ staff client.
++
+[source, bash]
+------------------------------------------------------------------------------
+make -f Open-ILS/src/extras/Makefile.install <osname>-developer
+------------------------------------------------------------------------------
++
+ * To install packages required for building Evergreen translations, use
+ the <osname>-translator Makefile.install target.
++
+[source, bash]
+------------------------------------------------------------------------------
+make -f Open-ILS/src/extras/Makefile.install <osname>-translator
+------------------------------------------------------------------------------
++
+ * To install packages required for building Evergreen release bundles, use
+ the <osname>-packager Makefile.install target.
++
+[source, bash]
+------------------------------------------------------------------------------
+make -f Open-ILS/src/extras/Makefile.install <osname>-packager
+------------------------------------------------------------------------------
+
+== Extra steps for web staff client ==
+
+[NOTE]
+Skip this entire section if you are using an official release tarball downloaded
+from http://evergreen-ils.org/downloads. Otherwise, ensure you have installed the
+xref:#optional_developer_additions[optional developer additions] before proceeding.
+
+[[install_files_for_web_staff_client]]
+=== Install AngularJS files for web staff client ===
+
+1. Building, Testing, Minification: The remaining steps all take place within
+ the staff JS web root:
++
+[source,sh]
+------------------------------------------------------------------------------
+cd $EVERGREEN_ROOT/Open-ILS/web/js/ui/default/staff/
+------------------------------------------------------------------------------
++
+2. Install Project-local Dependencies. npm inspects the 'package.json' file
+ for dependencies and fetches them from the Node package network.
++
+[source,sh]
+------------------------------------------------------------------------------
+npm install # fetch JS dependencies
+------------------------------------------------------------------------------
++
+3. Run the build script.
++
+[source,sh]
+------------------------------------------------------------------------------
+# build, concat+minify
+npm run build-prod
+------------------------------------------------------------------------------
++
+4. OPTIONAL: Test web client code if the <osname>-developer packages were installed.
+ CHROME_BIN should be set to the path to chrome or chromimum, e.g.,
+ `/usr/bin/chromium`:
++
+[source,sh]
+------------------------------------------------------------------------------
+CHROME_BIN=/path/to/chrome npm run test
+------------------------------------------------------------------------------
+
+[[install_files_for_angular_web_staff_client]]
+=== Install Angular files for web staff client ===
+
+1. Building, Testing, Minification: The remaining steps all take place within
+ the Angular staff root:
++
+[source,sh]
+------------------------------------------------------------------------------
+cd $EVERGREEN_ROOT/Open-ILS/src/eg2/
+------------------------------------------------------------------------------
++
+2. Install Project-local Dependencies. npm inspects the 'package.json' file
+ for dependencies and fetches them from the Node package network.
++
+[source,sh]
+------------------------------------------------------------------------------
+npm install # fetch JS dependencies
+------------------------------------------------------------------------------
++
+3. Run the build script.
++
+[source,sh]
+------------------------------------------------------------------------------
+# build and run tests
+ng build --prod
+------------------------------------------------------------------------------
++
+4. OPTIONAL: Test eg2 web client code if the <osname>-developer packages were installed:
+ CHROME_BIN should be set to the path to chrome or chromimum, e.g.,
+ `/usr/bin/chromium`:
++
+[source,sh]
+------------------------------------------------------------------------------
+CHROME_BIN=/path/to/chrome npm run test
+------------------------------------------------------------------------------
+
+[[install_opac_deps]]
+=== Install OPAC skin dependencies ===
+
+1. The following steps take place within the OPAC dependencies root:
++
+[source,sh]
+------------------------------------------------------------------------------
+cd $EVERGREEN_ROOT/Open-ILS/web/opac/deps
+------------------------------------------------------------------------------
++
+2. Install Project-local Dependencies. npm inspects the 'package.json' file
+ for dependencies and fetches them from the Node package network.
++
+[source,sh]
+------------------------------------------------------------------------------
+npm install # fetch JS and CSS dependencies
+------------------------------------------------------------------------------
++
+Note that there is no build step.
+
+== Configuration and compilation instructions ==
+
+For the time being, we are still installing everything in the `/openils/`
+directory. From the Evergreen source directory, issue the following commands as
+the *user* Linux account to configure and build Evergreen:
+
+[source, bash]
+------------------------------------------------------------------------------
+PATH=/openils/bin:$PATH ./configure --prefix=/openils --sysconfdir=/openils/conf
+make
+------------------------------------------------------------------------------
+
+These instructions assume that you have also installed OpenSRF under `/openils/`.
+If not, please adjust PATH as needed so that the Evergreen `configure` script
+can find `osrf_config`.
+
+== Installation instructions ==
+
+1. Once you have configured and compiled Evergreen, issue the following
+ command as the *root* Linux account to install Evergreen and copy
+ example configuration files to `/openils/conf`.
++
+[source, bash]
+------------------------------------------------------------------------------
+make install
+------------------------------------------------------------------------------
+
+== Change ownership of the Evergreen files ==
+
+All files in the `/openils/` directory and subdirectories must be owned by the
+`opensrf` user. Issue the following command as the *root* Linux account to
+change the ownership on the files:
+
+[source, bash]
+------------------------------------------------------------------------------
+chown -R opensrf:opensrf /openils
+------------------------------------------------------------------------------
+
+== Run ldconfig ==
+
+On Ubuntu 18.04 / 20.04 or Debian Stretch / Buster, run the following command as the root user:
+
+[source, bash]
+------------------------------------------------------------------------------
+ldconfig
+------------------------------------------------------------------------------
+
+== Additional Instructions for Developers ==
+
+[NOTE]
+Skip this section if you are using an official release tarball downloaded
+from http://evergreen-ils.org/egdownloads
+
+Developers working directly with the source code from the Git repository,
+rather than an official release tarball, need to install the Dojo Toolkit
+set of JavaScript libraries. The appropriate version of Dojo is included in
+Evergreen release tarballs. Developers should install the Dojo 1.3.3 version
+of Dojo by issuing the following commands as the *opensrf* Linux account:
+
+[source, bash]
+------------------------------------------------------------------------------
+wget http://download.dojotoolkit.org/release-1.3.3/dojo-release-1.3.3.tar.gz
+tar -C /openils/var/web/js -xzf dojo-release-1.3.3.tar.gz
+cp -r /openils/var/web/js/dojo-release-1.3.3/* /openils/var/web/js/dojo/.
+------------------------------------------------------------------------------
+
+
+== Configure the Apache Web server ==
+
+. Use the example configuration files to configure your Web server for
+the Evergreen catalog, web staff client, Web services, and administration
+interfaces. Issue the following commands as the *root* Linux account:
++
+[source,bash]
+------------------------------------------------------------------------------------
+cp Open-ILS/examples/apache_24/eg_24.conf /etc/apache2/sites-available/eg.conf
+cp Open-ILS/examples/apache_24/eg_vhost_24.conf /etc/apache2/eg_vhost.conf
+cp Open-ILS/examples/apache_24/eg_startup /etc/apache2/
+# Now set up SSL
+mkdir /etc/apache2/ssl
+cd /etc/apache2/ssl
+------------------------------------------------------------------------------------
++
+. The `openssl` command cuts a new SSL key for your Apache server. For a
+production server, you should purchase a signed SSL certificate, but you can
+just use a self-signed certificate and accept the warnings in the
+and browser during testing and development. Create an SSL key for the Apache
+server by issuing the following command as the *root* Linux account:
++
+[source,bash]
+------------------------------------------------------------------------------
+openssl req -new -x509 -days 365 -nodes -out server.crt -keyout server.key
+------------------------------------------------------------------------------
++
+. As the *root* Linux account, edit the `eg.conf` file that you copied into
+place.
+ a. To enable access to the offline upload / execute interface from any
+ workstation on any network, make the following change (and note that
+ you *must* secure this for a production instance):
+ * Replace `Require host 10.0.0.0/8` with `Require all granted`
+. Change the user for the Apache server.
+ * As the *root* Linux account, edit
+ `/etc/apache2/envvars`. Change `export APACHE_RUN_USER=www-data` to
+ `export APACHE_RUN_USER=opensrf`.
+. As the *root* Linux account, configure Apache with KeepAlive settings
+ appropriate for Evergreen. Higher values can improve the performance of a
+ single client by allowing multiple requests to be sent over the same TCP
+ connection, but increase the risk of using up all available Apache child
+ processes and memory.
+ * Edit `/etc/apache2/apache2.conf`.
+ a. Change `KeepAliveTimeout` to `1`.
+ b. Change `MaxKeepAliveRequests` to `100`.
+. As the *root* Linux account, configure the prefork module to start and keep
+ enough Apache servers available to provide quick responses to clients without
+ running out of memory. The following settings are a good starting point for a
+ site that exposes the default Evergreen catalog to the web:
++
+.`/etc/apache2/mods-available/mpm_prefork.conf`
+[source,bash]
+------------------------------------------------------------------------------
+<IfModule mpm_prefork_module>
+ StartServers 15
+ MinSpareServers 5
+ MaxSpareServers 15
+ MaxRequestWorkers 75
+ MaxConnectionsPerChild 500
+</IfModule>
+------------------------------------------------------------------------------
++
+. As the *root* user, enable the mpm_prefork module:
++
+[source,bash]
+------------------------------------------------------------------------------
+a2dismod mpm_event
+a2enmod mpm_prefork
+------------------------------------------------------------------------------
++
+. As the *root* Linux account, enable the Evergreen site:
++
+[source,bash]
+------------------------------------------------------------------------------
+a2dissite 000-default # OPTIONAL: disable the default site (the "It Works" page)
+a2ensite eg.conf
+------------------------------------------------------------------------------
++
+. As the *root* Linux account, enable Apache to write
+ to the lock directory; this is currently necessary because Apache
+ is running as the `opensrf` user:
++
+[source,bash]
+------------------------------------------------------------------------------
+chown opensrf /var/lock/apache2
+------------------------------------------------------------------------------
+
+Learn more about additional Apache options in the following sections:
+
+ * xref:admin:apache_rewrite_tricks.adoc#apache_rewrite_tricks[Apache Rewrite Tricks]
+ * xref:admin:apache_access_handler.adoc#apache_access_handler_perl_module[Apache Access Handler Perl Module]
+
+== Configure OpenSRF for the Evergreen application ==
+
+There are a number of example OpenSRF configuration files in `/openils/conf/`
+that you can use as a template for your Evergreen installation. Issue the
+following commands as the *opensrf* Linux account:
+
+[source, bash]
+------------------------------------------------------------------------------
+cp -b /openils/conf/opensrf_core.xml.example /openils/conf/opensrf_core.xml
+cp -b /openils/conf/opensrf.xml.example /openils/conf/opensrf.xml
+------------------------------------------------------------------------------
+
+When you installed OpenSRF, you created four Jabber users on two
+separate domains and edited the `opensrf_core.xml` file accordingly. Please
+refer back to the OpenSRF README and, as the *opensrf* Linux account, edit the
+Evergreen version of the `opensrf_core.xml` file using the same Jabber users
+and domains as you used while installing and testing OpenSRF.
+
+[NOTE]
+The `-b` flag tells the `cp` command to create a backup version of the
+destination file. The backup version of the destination file has a tilde (`~`)
+appended to the file name, so if you have forgotten the Jabber users and
+domains, you can retrieve the settings from the backup version of the files.
+
+`eg_db_config`, described in xref:#creating_the_evergreen_database[Creating the Evergreen database], sets the database connection information in `opensrf.xml` for you.
+
+=== Configure action triggers for the Evergreen application ===
+_Action Triggers_ provide hooks for the system to perform actions when a given
+event occurs; for example, to generate reminder or overdue notices, the
+`checkout.due` hook is processed and events are triggered for potential actions
+if there is no checkin time.
+
+To enable the default set of hooks, issue the following command as the
+*opensrf* Linux account:
+
+[source, bash]
+------------------------------------------------------------------------------
+cp -b /openils/conf/action_trigger_filters.json.example /openils/conf/action_trigger_filters.json
+------------------------------------------------------------------------------
+
+For more information about configuring and running action triggers, see
+xref:admin:actiontriggers_process.adoc#processing_action_triggers[Notifications / Action Triggers].
+
+[[creating_the_evergreen_database]]
+== Creating the Evergreen database ==
+
+=== Setting up the PostgreSQL server ===
+
+For production use, most libraries install the PostgreSQL database server on a
+dedicated machine. Therefore, by default, the `Makefile.install` prerequisite
+installer does *not* install the PostgreSQL 9 database server that is required
+by every Evergreen system. You can install the packages required by Debian or
+Ubuntu on the machine of your choice using the following commands as the
+*root* Linux account:
+
+. Installing PostgreSQL server packages
+
+Each OS build target provides the postgres server installation packages
+required for each operating system. To install Postgres server packages,
+use the make target 'postgres-server-<OSTYPE>'. Choose the most appropriate
+command below based on your operating system. This will install PostgreSQL 9.6,
+the minimum supported version.
+
+[source, bash]
+------------------------------------------------------------------------------
+make -f Open-ILS/src/extras/Makefile.install postgres-server-debian-buster
+make -f Open-ILS/src/extras/Makefile.install postgres-server-debian-stretch
+make -f Open-ILS/src/extras/Makefile.install postgres-server-debian-jessie
+make -f Open-ILS/src/extras/Makefile.install postgres-server-ubuntu-bionic
+make -f Open-ILS/src/extras/Makefile.install postgres-server-ubuntu-focal
+------------------------------------------------------------------------------
+
+To install PostgreSQL version 10, use the following command for your operating
+system:
+
+[source, bash]
+------------------------------------------------------------------------------
+make -f Open-ILS/src/extras/Makefile.install postgres-server-debian-buster-10
+make -f Open-ILS/src/extras/Makefile.install postgres-server-debian-stretch-10
+make -f Open-ILS/src/extras/Makefile.install postgres-server-debian-jessie-10
+make -f Open-ILS/src/extras/Makefile.install postgres-server-ubuntu-bionic-10
+make -f Open-ILS/src/extras/Makefile.install postgres-server-ubuntu-focal-10
+------------------------------------------------------------------------------
+
+For a standalone PostgreSQL server, install the following Perl modules for your
+distribution as the *root* Linux account:
+
+.(Debian and Ubuntu)
+No extra modules required for these distributions.
+
+You need to create a PostgreSQL superuser to create and access the database.
+Issue the following command as the *postgres* Linux account to create a new
+PostgreSQL superuser named `evergreen`. When prompted, enter the new user's
+password:
+
+[source, bash]
+------------------------------------------------------------------------------
+createuser -s -P evergreen
+------------------------------------------------------------------------------
+
+.Enabling connections to the PostgreSQL database
+
+Your PostgreSQL database may be configured by default to prevent connections,
+for example, it might reject attempts to connect via TCP/IP or from other
+servers. To enable TCP/IP connections from localhost, check your `pg_hba.conf`
+file, found in the `/etc/postgresql/` directory on Debian and Ubuntu.
+A simple way to enable TCP/IP
+connections from localhost to all databases with password authentication, which
+would be suitable for a test install of Evergreen on a single server, is to
+ensure the file contains the following entries _before_ any "host ... ident"
+entries:
+
+------------------------------------------------------------------------------
+host all all ::1/128 md5
+host all all 127.0.0.1/32 md5
+------------------------------------------------------------------------------
+
+When you change the `pg_hba.conf` file, you will need to reload PostgreSQL to
+make the changes take effect. For more information on configuring connectivity
+to PostgreSQL, see
+http://www.postgresql.org/docs/devel/static/auth-pg-hba-conf.html
+
+=== Creating the Evergreen database and schema ===
+
+Once you have created the *evergreen* PostgreSQL account, you also need to
+create the database and schema, and configure your configuration files to point
+at the database server. Issue the following command as the *root* Linux account
+from inside the Evergreen source directory, replacing <user>, <password>,
+<hostname>, <port>, and <dbname> with the appropriate values for your
+PostgreSQL database (where <user> and <password> are for the *evergreen*
+PostgreSQL account you just created), and replace <admin-user> and <admin-pass>
+with the values you want for the *egadmin* Evergreen administrator account:
+
+[source, bash]
+------------------------------------------------------------------------------
+perl Open-ILS/src/support-scripts/eg_db_config --update-config \
+ --service all --create-database --create-schema --create-offline \
+ --user <user> --password <password> --hostname <hostname> --port <port> \
+ --database <dbname> --admin-user <admin-user> --admin-pass <admin-pass>
+------------------------------------------------------------------------------
+
+This creates the database and schema and configures all of the services in
+your `/openils/conf/opensrf.xml` configuration file to point to that database.
+It also creates the configuration files required by the Evergreen `cgi-bin`
+administration scripts, and sets the user name and password for the *egadmin*
+Evergreen administrator account to your requested values.
+
+You can get a complete set of options for `eg_db_config` by passing the
+`--help` parameter.
+
+=== Loading sample data ===
+
+If you add the `--load-all-sample` parameter to the `eg_db_config` command,
+a set of authority and bibliographic records, call numbers, copies, staff
+and regular users, and transactions will be loaded into your target
+database. This sample dataset is commonly referred to as the _concerto_
+sample data, and can be useful for testing out Evergreen functionality and
+for creating problem reports that developers can easily recreate with their
+own copy of the _concerto_ sample data.
+
+=== Creating the database on a remote server ===
+
+In a production instance of Evergreen, your PostgreSQL server should be
+installed on a dedicated server.
+
+==== PostgreSQL 9.6 and later ====
+
+To create the database instance on a remote database server running PostgreSQL
+9.6 or later, simply use the `--create-database` flag on `eg_db_config`.
+
+== Starting Evergreen ==
+
+1. As the *root* Linux account, start the `memcached` and `ejabberd` services
+(if they aren't already running):
++
+[source, bash]
+------------------------------------------------------------------------------
+/etc/init.d/ejabberd start
+/etc/init.d/memcached start
+------------------------------------------------------------------------------
++
+2. As the *opensrf* Linux account, start Evergreen. The `-l` flag in the
+following command is only necessary if you want to force Evergreen to treat the
+hostname as `localhost`; if you configured `opensrf.xml` using the real
+hostname of your machine as returned by `perl -ENet::Domain 'print
+Net::Domain::hostfqdn() . "\n";'`, you should not use the `-l` flag.
++
+[source, bash]
+------------------------------------------------------------------------------
+osrf_control -l --start-all
+------------------------------------------------------------------------------
++
+ ** If you receive the error message `bash: osrf_control: command not found`,
+ then your environment variable `PATH` does not include the `/openils/bin`
+ directory; this should have been set in the *opensrf* Linux account's
+ `.bashrc` configuration file. To manually set the `PATH` variable, edit the
+ configuration file `~/.bashrc` as the *opensrf* Linux account and add the
+ following line:
++
+[source, bash]
+------------------------------------------------------------------------------
+export PATH=$PATH:/openils/bin
+------------------------------------------------------------------------------
++
+3. As the *opensrf* Linux account, generate the Web files needed by the web staff
+ client and catalog and update the organization unit proximity (you need to do
+ this the first time you start Evergreen, and after that each time you change the library org unit configuration.
+):
++
+[source, bash]
+------------------------------------------------------------------------------
+autogen.sh
+------------------------------------------------------------------------------
++
+4. As the *root* Linux account, restart the Apache Web server:
++
+[source, bash]
+------------------------------------------------------------------------------
+/etc/init.d/apache2 restart
+------------------------------------------------------------------------------
++
+If the Apache Web server was running when you started the OpenSRF services, you
+might not be able to successfully log in to the OPAC or web staff client until the
+Apache Web server is restarted.
+
+== Testing connections to Evergreen ==
+
+Once you have installed and started Evergreen, test your connection to
+Evergreen via `srfsh`. As the *opensrf* Linux account, issue the following
+commands to start `srfsh` and try to log onto the Evergreen server using the
+*egadmin* Evergreen administrator user name and password that you set using the
+`eg_db_config` command:
+
+[source, bash]
+------------------------------------------------------------------------------
+/openils/bin/srfsh
+srfsh% login <admin-user> <admin-pass>
+------------------------------------------------------------------------------
+
+You should see a result like:
+
+ Received Data: "250bf1518c7527a03249858687714376"
+ ------------------------------------
+ Request Completed Successfully
+ Request Time in seconds: 0.045286
+ ------------------------------------
+
+ Received Data: {
+ "ilsevent":0,
+ "textcode":"SUCCESS",
+ "desc":" ",
+ "pid":21616,
+ "stacktrace":"oils_auth.c:304",
+ "payload":{
+ "authtoken":"e5f9827cc0f93b503a1cc66bee6bdd1a",
+ "authtime":420
+ }
+
+ }
+
+ ------------------------------------
+ Request Completed Successfully
+ Request Time in seconds: 1.336568
+ ------------------------------------
+[[install-troubleshooting-1]]
+If this does not work, it's time to do some troubleshooting.
+
+ * As the *opensrf* Linux account, run the `settings-tester.pl` script to see
+ if it finds any system configuration problems. The script is found at
+ `Open-ILS/src/support-scripts/settings-tester.pl` in the Evergreen source
+ tree.
+ * Follow the steps in the http://evergreen-ils.org/dokuwiki/doku.php?id=troubleshooting:checking_for_errors[troubleshooting guide].
+ * If you have faithfully followed the entire set of installation steps
+ listed here, you are probably extremely close to a working system.
+ Gather your configuration files and log files and contact the
+ http://evergreen-ils.org/communicate/mailing-lists/[Evergreen development
+mailing list] for assistance before making any drastic changes to your system
+ configuration.
+
+== Getting help ==
+
+Need help installing or using Evergreen? Join the mailing lists at
+http://evergreen-ils.org/communicate/mailing-lists/ or contact us on the Freenode
+IRC network on the #evergreen channel.
+
+== License ==
+
+This work is licensed under the Creative Commons Attribution-ShareAlike 3.0
+Unported License. To view a copy of this license, visit
+http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative
+Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.
export PATH=${PATH}:/usr/sbin
AC_PREREQ(2.61)
-AC_INIT(Open-ILS, trunk, open-ils-dev@list.georgialibraries.org)
+AC_INIT(Open-ILS, 3.7.3, open-ils-dev@list.georgialibraries.org)
AC_CONFIG_SRCDIR([configure.ac])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE