angular flat marc edit
authorBill Erickson <berickxx@gmail.com>
Thu, 27 Jun 2019 20:09:15 +0000 (16:09 -0400)
committerBill Erickson <berickxx@gmail.com>
Thu, 27 Jun 2019 20:09:15 +0000 (16:09 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/staff/catalog/record/record.component.html
Open-ILS/src/eg2/src/app/staff/catalog/record/record.component.ts
Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor.component.html
Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor.component.ts
Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor.service.ts [deleted file]
Open-ILS/src/eg2/src/app/staff/share/marc-edit/flat-editor.component.html
Open-ILS/src/eg2/src/app/staff/share/marc-edit/flat-editor.component.ts
Open-ILS/src/eg2/src/app/staff/share/marc-edit/marc-edit.module.ts
Open-ILS/src/eg2/src/app/staff/share/marc-edit/marcrecord.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/index.html
Open-ILS/web/js/marc/marcrecord.js

index 8aa483f..077fdd1 100644 (file)
       <!-- NOTE some tabs send the user over to the AngJS app -->
       <ngb-tab title="MARC Edit" i18n-title id="marc_edit">
         <ng-template ngbTabContent>
-          <div class="alert alert-info mt-3" i18n>
-            MARC Edit not yet implemented.  See the
-            <a target="_blank"
-              href="/eg/staff/cat/catalog/record/{{recordId}}/marc_edit">
-              AngularJS MARC Edit Tab.
-            </a>
-          </div>
           <div class="mt-3">
-            <eg-marc-editor [recordId]="recordId"></eg-marc-editor>
+            <eg-marc-editor (recordSaved)="handleMarcRecordSaved()" 
+              [recordId]="recordId"></eg-marc-editor>
           </div>
         </ng-template>
       </ngb-tab>
index c70b565..e397444 100644 (file)
@@ -110,6 +110,11 @@ export class RecordComponent implements OnInit {
         }
         return null;
     }
+
+    handleMarcRecordSaved() {
+        this.staffCat.currentDetailRecordSummary = null;
+        this.loadRecord();
+    }
 }
 
 
index 16cb53d..4b1171a 100644 (file)
@@ -1,15 +1,44 @@
 
-<!-- TODO: migrate to Angular / Typescript?
-      Or move to common location under /js/
--->
-<!--
-<script src="/js/ui/default/staff/marcrecord.js"></script>
--->
+
+<div class="row d-flex p-2 m-2">
+  <div class="flex-1"></div>
+  <button class="btn btn-success" (click)="saveRecord()" i18n>
+    Save Changes</button>
+</div>
 
 <div class="row">
-  <div>HEADER STUFF</div>
+  <div class="col-lg-12">
+    <ngb-tabset [activeId]="editorTab">
+      <ngb-tab title="Enhanced MARC Editor" i18n-title id="rich">
+        <ng-template ngbTabContent>
+          <div class="alert alert-info mt-3" i18n>
+          Enhanced MARC Editor is not yet implemented.  See the
+          <ng-container *ngIf="record && record.id">
+            <a target="_blank"
+              href="/eg/staff/cat/catalog/record/{{record.id}}/marc_edit">
+              AngularJS MARC Editor.
+            </a>
+          </ng-container>
+          <ng-container *ngIf="!record || !record.id">
+            <a target="_blank" href="/eg/staff/cat/catalog/new_bib">
+              AngularJS MARC Editor.
+            </a>
+          </ng-container>
+          </div>
+        </ng-template>
+      </ngb-tab>
+      <ngb-tab title="Flat Text Editor" i18n-title id="flat">
+        <ng-template ngbTabContent>
+          <eg-marc-flat-editor></eg-marc-flat-editor>
+        </ng-template>
+      </ngb-tab>
+    </ngb-tabset>
+  </div>
+</div>
+
+<div class="row d-flex p-2 m-2 flex-row-reverse">
+  <button class="btn btn-success" (click)="saveRecord()" i18n>
+    Save Changes</button>
 </div>
 
-<eg-marc-flat-editor [record]="record">
-</eg-marc-flat-editor>
 
index f62d69e..f0ec986 100644 (file)
@@ -1,17 +1,16 @@
-import {Component, Input, Output, OnInit, AfterViewInit, EventEmitter,
-    OnDestroy} from '@angular/core';
+import {Component, Input, Output, OnInit, EventEmitter} from '@angular/core';
 import {IdlService} from '@eg/core/idl.service';
+import {EventService} from '@eg/core/event.service';
+import {NetService} from '@eg/core/net.service';
+import {AuthService} from '@eg/core/auth.service';
 import {OrgService} from '@eg/core/org.service';
 import {PcrudService} from '@eg/core/pcrud.service';
-//import {MarcEditorService, MARC21} from './editor.service';
-import {MarcEditorService} from './editor.service';
+import {MarcRecord} from './marcrecord';
 
 /**
  * MARC Record editor main interface.
  */
 
-declare var MARC21;
-
 @Component({
   selector: 'eg-marc-editor',
   templateUrl: './editor.component.html'
@@ -19,38 +18,93 @@ declare var MARC21;
 
 export class MarcEditorComponent implements OnInit {
 
-    _recordId: number;
+    record: MarcRecord;
+    editorTab: 'rich' | 'flat';
+
     @Input() set recordId(id: number) {
-        this._recordId = id;
-        this.loadRecord();
+        if (!id) { return; }
+        if (this.record && this.record.id === id) { return; }
+        this.fromId(id);
     }
 
-    get recordId(): number {
-        return this._recordId;
+    @Input() set recordXml(xml: string) {
+        if (xml) { this.fromXml(xml); }
     }
 
-    //record: MARC21.Record;
-    record: any; // MARC21.Record
+    // If true, saving records to the database is assumed to
+    // happen externally.  IOW, the record editor is just an
+    // in-place MARC modification interface.
+    inPlaceMode: boolean;
+
+    // In inPlaceMode, this is emitted in lieu of saving the record
+    // in th database.  When inPlaceMode is false, this is emitted after
+    // the record is successfully saved.
+    @Output() recordSaved: EventEmitter<string>;
 
     constructor(
+        private evt: EventService,
         private idl: IdlService,
+        private net: NetService,
+        private auth: AuthService,
         private org: OrgService,
         private pcrud: PcrudService
     ) {
+        this.recordSaved = new EventEmitter<string>();
+    }
+
+
+    ngOnInit() {
+        // Default to flat for now since it's all that's supported.
+        this.editorTab = 'flat';
     }
 
-    ngOnInit() {}
+    saveRecord(): Promise<any> {
+        const xml = this.record.toXml();
 
-    loadRecord(): Promise<any> {
-        if (!this.recordId) {
+        if (this.inPlaceMode) {
+            // Let the caller have the modified XML and move on.
+            this.recordSaved.emit(xml);
             return Promise.resolve();
         }
 
-        return this.pcrud.retrieve('bre', this.recordId)
+        if (this.record.id) { // Editing an existing record
+
+            const method = 'open-ils.cat.biblio.record.marc.replace';
+
+            return this.net.request(
+                'open-ils.cat', method,
+                this.auth.token(), this.record.id,
+                xml, null /* TODO: record source */
+            ).toPromise().then(response => {
+
+                const evt = this.evt.parse(response);
+                if (evt) {
+                    console.error(evt);
+                    // TODO: toast
+                }
+
+                // TODO: toast
+                this.recordSaved.emit(xml);
+                return response;
+            });
+
+        } else {
+            // TODO: create a new record
+        }
+    }
+
+    fromId(id: number): Promise<any> {
+        return this.pcrud.retrieve('bre', id)
         .toPromise().then(bib => {
-            this.record = new MARC21.Record({marcxml: bib.marc()})
+            this.record = new MarcRecord(bib.marc());
+            this.record.id = id;
         });
     }
+
+    fromXml(xml: string) {
+        this.record = new MarcRecord(xml);
+        this.record.id = null;
+    }
 }
 
 
diff --git a/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor.service.ts b/Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor.service.ts
deleted file mode 100644 (file)
index a66e1ac..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-import {Injectable} from '@angular/core';
-
-// Tell typescript about our external MARC21 JS library.
-// We could use an 'any' instead, but this is kind of helpful.
-/*
-export module MARC21 {
-    export class Record {
-        constructor(args: any) {}
-        toBreaker(): string {
-            return '';
-        }
-    }
-}
-*/
-
-export class MarcEditorService {
-}
-
-
-
index 4450fbc..57f725b 100644 (file)
@@ -1,6 +1,7 @@
 
-<div>
+<div *ngIf="record">
   <textarea class="form-control flat-editor-content" 
-    [(ngModel)]="breakerText" rows="40" spellcheck="false">
+    (blur)="record.absorbBreakerChanges()"
+    [(ngModel)]="record.breakerText" rows="40" spellcheck="false">
   </textarea>
 </div>
index b3e957f..f51214e 100644 (file)
@@ -1,10 +1,9 @@
-import {Component, Input, Output, OnInit, AfterViewInit, EventEmitter,
-    OnDestroy} from '@angular/core';
+import {Component, Input, OnInit, Host} from '@angular/core';
 import {IdlService} from '@eg/core/idl.service';
 import {OrgService} from '@eg/core/org.service';
 import {ServerStoreService} from '@eg/core/server-store.service';
-//import {MarcEditorService, MARC21} from './editor.service';
-import {MarcEditorService} from './editor.service';
+import {MarcEditorComponent} from './editor.component';
+import {MarcRecord} from './marcrecord';
 
 /**
  * MARC Record flat text (marc-breaker) editor.
@@ -18,30 +17,15 @@ import {MarcEditorService} from './editor.service';
 
 export class MarcFlatEditorComponent implements OnInit {
 
-    // MARC21.Record
-    //_record: MARC21.Record;
-    _record: any;
-    //@Input() set record(r: MARC21.Record) {
-    @Input() set record(r: any) {
-        this._record = r;
-        if (this._record) {
-            this.breakerText = this._record.toBreaker();
-            console.log('here with record ' + this._record);
-            console.log('here with breaker ' + this.breakerText);
-        }
+    get record(): MarcRecord {
+        return this.editor.record;
     }
 
-    //get record(): MARC21.Record {
-    get record(): any {
-        return this._record;
-    }
-
-    breakerText: string;
-
     constructor(
         private idl: IdlService,
         private org: OrgService,
         private store: ServerStoreService,
+        @Host() private editor: MarcEditorComponent
     ) {
     }
 
index 3f012d4..796fb96 100644 (file)
@@ -1,6 +1,5 @@
 import {NgModule} from '@angular/core';
 import {EgCommonModule} from '@eg/common.module';
-import {MarcEditorService} from './editor.service';
 import {MarcEditorComponent} from './editor.component';
 import {MarcRichEditorComponent} from './rich-editor.component';
 import {MarcFlatEditorComponent} from './flat-editor.component';
@@ -18,7 +17,6 @@ import {MarcFlatEditorComponent} from './flat-editor.component';
         MarcEditorComponent
     ],
     providers: [
-      MarcEditorService
     ]
 })
 
diff --git a/Open-ILS/src/eg2/src/app/staff/share/marc-edit/marcrecord.ts b/Open-ILS/src/eg2/src/app/staff/share/marc-edit/marcrecord.ts
new file mode 100644 (file)
index 0000000..bb815f7
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+  * Simple wrapper class for our external MARC21.Record JS library.
+  */
+
+declare var MARC21;
+
+export class MarcRecord {
+
+    id: number; // Database ID when known.
+    record: any; // MARC21.Record object
+    breakerText: string;
+
+    constructor(xml: string) {
+        this.record = new MARC21.Record({marcxml: xml});
+        this.breakerText = this.record.toBreaker();
+    }
+
+    toXml(): string {
+        return this.record.toXmlString();
+    }
+
+    toBreaker(): string {
+        return this.record.toBreaker();
+    }
+
+    absorbBreakerChanges() {
+        this.record = new MARC21.Record({marcbreaker: this.breakerText});
+    }
+}
+
index 08d63e8..f876be4 100644 (file)
@@ -16,8 +16,7 @@
   <script src="/js/dojo/opensrf/opensrf.js"></script>
   <script src="/js/dojo/opensrf/opensrf_ws.js"></script>
 
-  <!-- TODO TESTING -->
-  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
-  <script src="/js/ui/default/staff/marcrecord.js"></script>
+  <!-- TODO: integrate w/ webpack for minify, etc.  Typescript? -->
+  <script src="/js/marc/marcrecord.js"></script>
 </body>
 </html>
index 9fe525b..3e189af 100644 (file)
  * ---------------------------------------------------------------------------
  */
 
-// !!! Head's up !!!
-// This module requires a /real/ jQuery be used with your
-// angularjs, so as to avoid using hand-rolled AJAX.
+/*
+ * Copy of file from Open-ILS/web/js/ui/default/staff/marcedit.js
+ *
+ * This copy of the the MARC21 library heavily modified by
+ * Bill Erickson <berickxx@gmail.com> 2019 circa Evergreen 3.3.
+ *
+ * 1. All jquery dependencies have been replaced with Vanilla JS.
+ * 2. Many features from the original have been removed (for now,
+ *    anyway) since they were not needed at the time and would have
+ *    required additional jquery porting work.
+ * 
+ * Code is otherwise unchanged.
+ */
 
 var MARC21 = {
 
@@ -178,66 +188,64 @@ var MARC21 = {
             return counter;
         }
 
-        // this.clone = function () { return dojo.clone(this) } // maybe implement later...
-
-        this.fromXmlURL = function (url) {
-            var me = this;
-            return $.get( // This is a Promise
-                url,
-                function (mxml) {
-                    me.fromXmlDocument($('record', mxml)[0]);
-                    if (me.onLoad) me.onLoad();
-            });
-        }
-
         this.fromXmlString = function (mxml) {
-                this.fromXmlDocument( $( $.parseXML( mxml ) ).find('record')[0] );
+            var xmlDoc = new DOMParser().parseFromString(mxml, "text/xml");
+            this.fromXmlDocument(xmlDoc.getElementsByTagName('record')[0]);
         }
 
         this.fromXmlDocument = function (mxml) {
             var me = this;
-            me.leader = $($('leader',mxml)[0]).text() || '00000cam a2200205Ka 4500';
+            var ldr =  mxml.getElementsByTagName('leader')[0];
+            me.leader = (ldr ? ldr.textContent : '') || '00000cam a2200205Ka 4500';
 
-            $('controlfield', mxml).each(function (ind) {
-                var cf=$(this);
+            var cfNodes = mxml.getElementsByTagName('controlfield');
+            for (var idx = 0; idx < cfNodes.length; idx++) {
+                var cf = cfNodes[idx];
                 me.fields.push(
                     new MARC21.Field({
                           record : me,
-                          tag    : cf.attr('tag'),
-                          data   : cf.text(),
+                          tag    : cf.getAttribute('tag'),
+                          data   : cf.textContent
                     })
-                )
-            });
+                );
+            }
+
+            var dfNodes = mxml.getElementsByTagName('datafield');
+            for (var idx = 0; idx < dfNodes.length; idx++) {
+                var df = dfNodes[idx];
+
+                var sfNodes = df.getElementsByTagName('subfield');
+                var subfields = [];
+                for (var idx2 = 0; idx2 < sfNodes.length; idx2++) {
+                    var sf = sfNodes[idx2];
+                    subfields.push(
+                        [sf.getAttribute('code'), sf.textContent, idx2]);
+                }
 
-            $('datafield', mxml).each(function (ind) {
-                var df=$(this);
                 me.fields.push(
                     new MARC21.Field({
                         record    : me,
-                        tag       : df.attr('tag'),
-                        ind1      : df.attr('ind1'),
-                        ind2      : df.attr('ind2'),
-                        subfields : $('subfield', df).map(
-                            function (i, sf) {
-                                return [[ $(sf).attr('code'), $(sf).text(), i ]];
-                            }
-                        ).get()
+                        tag       : df.getAttribute('tag'),
+                        ind1      : df.getAttribute('ind1'),
+                        ind2      : df.getAttribute('ind2'),
+                        subfields : subfields
                     })
-                )
-            });
+                );
+            }
 
             for (var j = 0; j < this.fields.length; j++) {
                 this.fields[j].position = j;
             }
 
             me.ready = true;
-
         }
 
         this.toXmlDocument = function () {
 
-            var doc = $.parseXML('<record xmlns="http://www.loc.gov/MARC21/slim"/>');
-            var rec_node = $('record', doc)[0];
+            var doc = new DOMParser().parseFromString(
+                '<record xmlns="http://www.loc.gov/MARC21/slim"/>', 'text/xml');
+
+            var rec_node = doc.getElementsByTagName('record')[0];
 
             var ldr = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'leader');
             ldr.textContent = this.leader;
@@ -397,34 +405,6 @@ var MARC21 = {
             return 'BKS'; // default
         }
         
-        this.videorecordingFormatName = function () {
-            var _7 = this.field('007').data;
-        
-            if (_7 && _7.match(/^v/)) {
-                var _v_e = _7.substr(
-                    MARC21.Record._physical_characteristics.v.subfields.e.start,
-                    MARC21.Record._physical_characteristics.v.subfields.e.len
-                );
-        
-                return MARC21.Record._physical_characteristics.v.subfields.e.values[ _v_e ];
-            }
-        
-            return null;
-        }
-        
-        this.videorecordingFormatCode = function () {
-            var _7 = this.field('007').data;
-        
-            if (_7 && _7.match(/^v/)) {
-                return _7.substr(
-                    MARC21.Record._physical_characteristics.v.subfields.e.start,
-                    MARC21.Record._physical_characteristics.v.subfields.e.len
-                );
-            }
-        
-            return null;
-        }
-        
         this.extractFixedField = function (field, dflt) {
         if (!MARC21.Record._ff_pos[field]) return null;
         
@@ -574,7 +554,7 @@ var MARC21 = {
         if (kwargs.onLoad) this.onLoad = kwargs.onLoad;
 
         if (kwargs.url) {
-            this.fromXmlURL(kwargs.url);
+            //this.fromXmlURL(kwargs.url);
         } else if (kwargs.marcxml) {
             this.fromXmlString(kwargs.marcxml);
             if (this.onLoad) this.onLoad();
@@ -589,7 +569,6 @@ var MARC21 = {
         if (kwargs.rtype == 'AUT') {
             this.setFixedField('Type','z');
         }
-
     },
 
     Field : function (kwargs) {
@@ -746,365 +725,6 @@ var MARC21 = {
         if (kwargs.subfields) this.subfields = kwargs.subfields;
         else this.subfields = [];
 
-    },
-
-    Batch : function(kwargs) {
-
-        this.parse = function () {
-            if (this.source instanceof Object ) { // assume an xml collection document
-                this.source = $('record', this.source);
-                this.type = 'xml';
-            } else if (this.source.match(/^\s*</)) { // this is xml text
-                this.source = $.parseXML( mxml ).find('record');
-                this.type = 'xml';
-            } else { // must be a marcbreaker doc. split on blank lines
-                this.source = this.source.split(/^$/);
-                this.type = 'marcbreaker';
-            }
-        }
-
-        this.fetchURL = function (u) {
-            var me = this;
-            $.get( u, function (mrc) {
-                me.source = mrc;
-                me.ready = true;
-            });
-        }
-
-        this.next = function () {
-            var chunk = this.source[this.current_record++];
-
-            if (chunk) {
-                var args = {};
-                args[this.type] = chunk;
-                if (this.delimiter) args.delimiter = this.delimiter;
-                return new MARC21.Record(args);
-            }
-
-            return null;
-        }
-
-        this.ready = false;
-        this.records = [];
-        this.source = kwargs.source;
-        this.delimiter = kwargs.delimiter
-        this.current_record = 0;
-
-        if (this.source) this.ready = true;
-        if (!this.ready && kwargs.url) this.fetchURL( kwargs.url );
-
-        if (this.ready) this.parse();
-
-    },
-
-    AuthorityControlSet : function (kwargs) {
-    
-        kwargs = kwargs || {};
-    
-        if (!MARC21.AuthorityControlSet._remote_loaded) {
-    
-            // TODO -- push the raw tree into the oils cache for later reuse
-    
-            // fetch everything up front...
-            this._preFetchWithFielder({
-                "acs": "_control_set_list",
-                "at": "_thesaurus_list",
-                "acsaf": "_authority_field_list",
-                "acsbf": "_bib_field_list",
-                "aba": "_browse_axis_list",
-                "abaafm": "_browse_field_map_list"
-            });
-    
-            MARC21.AuthorityControlSet._remote_loaded = true;
-        }
-    
-        if (MARC21.AuthorityControlSet._remote_loaded && !MARC21.AuthorityControlSet._remote_parsed) {
-    
-            MARC21.AuthorityControlSet._browse_axis_by_code = {};
-            MARC21.AuthorityControlSet._browse_axis_list.forEach(function (ba) {
-                ba.maps(
-                    MARC21.AuthorityControlSet._browse_field_map_list.filter(
-                        function (m) { return m.axis() == ba.code() }
-                    )
-                );
-                MARC21.AuthorityControlSet._browse_axis_by_code[ba.code()] = ba;
-            });
-    
-            // loop over each acs
-            MARC21.AuthorityControlSet._control_set_list.forEach(function (cs) {
-                MARC21.AuthorityControlSet._controlsets[''+cs.id()] = {
-                    id : cs.id(),
-                    name : cs.name(),
-                    description : cs.description(),
-                    authority_tag_map : {},
-                    control_map : {},
-                    bib_fields : [],
-                    raw : cs
-                };
-    
-                // grab the authority fields
-                var acsaf_list = MARC21.AuthorityControlSet._authority_field_list.filter(
-                    function (af) { return af.control_set() == cs.id() }
-                );
-    
-                var at_list = MARC21.AuthorityControlSet._thesaurus_list.filter(
-                    function (at) { return at.control_set() == cs.id() }
-                );
-    
-                MARC21.AuthorityControlSet._controlsets[''+cs.id()].raw.authority_fields( acsaf_list );
-                MARC21.AuthorityControlSet._controlsets[''+cs.id()].raw.thesauri( at_list );
-    
-                // and loop over each
-                acsaf_list.forEach(function (csaf) {
-                    csaf.axis_maps([]);
-    
-                    // link the main entry if we're subordinate
-                    if (csaf.main_entry()) {
-                        csaf.main_entry(
-                            acsaf_list.filter(function (x) {
-                                return x.id() == csaf.main_entry();
-                            })[0]
-                        );
-                    }
-    
-                    // link the sub entries if we're main
-                    csaf.sub_entries(
-                        acsaf_list.filter(function (x) {
-                            return x.main_entry() == csaf.id();
-                        })
-                    );
-    
-                    // now, bib fields
-                    var acsbf_list = MARC21.AuthorityControlSet._bib_field_list.filter(
-                        function (b) { return b.authority_field() == csaf.id() }
-                    );
-                    csaf.bib_fields( acsbf_list );
-    
-                    MARC21.AuthorityControlSet._controlsets[''+cs.id()].bib_fields = [].concat(
-                        MARC21.AuthorityControlSet._controlsets[''+cs.id()].bib_fields,
-                        acsbf_list
-                    );
-    
-                    acsbf_list.forEach(function (csbf) {
-                        // link the authority field to the bib field
-                        if (csbf.authority_field()) {
-                            csbf.authority_field(
-                                acsaf_list.filter(function (x) {
-                                    return x.id() == csbf.authority_field();
-                                })[0]
-                            );
-                        }
-    
-                    });
-    
-                    MARC21.AuthorityControlSet._browse_axis_list.forEach(
-                        function (ba) {
-                            ba.maps().filter(
-                                function (m) { return m.field() == csaf.id() }
-                            ).forEach(
-                                function (fm) { fm.field( csaf ); csaf.axis_maps().push( fm ) } // and set the field
-                            )
-                        }
-                    );
-    
-                });
-    
-                // build the authority_tag_map
-                MARC21.AuthorityControlSet._controlsets[''+cs.id()].bib_fields.forEach(function (bf) {
-    
-                    if (!MARC21.AuthorityControlSet._controlsets[''+cs.id()].control_map[bf.tag()])
-                        MARC21.AuthorityControlSet._controlsets[''+cs.id()].control_map[bf.tag()] = {};
-    
-                    bf.authority_field().sf_list().split('').forEach(function (sf_code) {
-    
-                        if (!MARC21.AuthorityControlSet._controlsets[''+cs.id()].control_map[bf.tag()][sf_code])
-                            MARC21.AuthorityControlSet._controlsets[''+cs.id()].control_map[bf.tag()][sf_code] = {};
-    
-                        MARC21.AuthorityControlSet._controlsets[''+cs.id()].control_map[bf.tag()][sf_code][bf.authority_field().tag()] = sf_code;
-                    });
-                });
-    
-            });
-    
-            if (this.controlSetList().length > 0)
-                delete MARC21.AuthorityControlSet._controlsets['-1'];
-    
-            MARC21.AuthorityControlSet._remote_parsed = true;
-        }
-    
-        this._preFetchWithFielder = function(cmap) {
-            for (var hint in cmap) {
-                var cache_key = cmap[hint];
-                var method = "open-ils.fielder." + hint + ".atomic";
-                var pkey = fieldmapper.IDL.fmclasses[hint].pkey;
-    
-                var query = {};
-                query[pkey] = {"!=": null};
-    
-                MARC21.AuthorityControlSet[cache_key] = dojo.map(
-                    fieldmapper.standardRequest(
-                        ["open-ils.fielder", method],
-                        [{"cache": 1, "query" : query}]
-                    ),
-                    function(h) { return new fieldmapper[hint]().fromHash(h); }
-                );
-            }
-        }
-    
-        this.controlSetId = function (x) {
-            if (x) this._controlset = ''+x;
-            return this._controlset;
-        }
-    
-        this.controlSet = function (x) {
-            return MARC21.AuthorityControlSet._controlsets[''+this.controlSetId(x)];
-        }
-    
-        this.controlSetByThesaurusCode = function (x) {
-            var thes = MARC21.AuthorityControlSet._thesaurus_list.filter(
-                function (at) { return at.code() == x }
-            )[0];
-    
-            return this.controlSet(thes.control_set());
-        }
-    
-        this.browseAxisByCode = function(code) {
-            return MARC21.AuthorityControlSet._browse_axis_by_code[code];
-        }
-    
-        this.bibFieldByTag = function (x) {
-            var me = this;
-            return me.controlSet().bib_fields.filter(
-                function (bf) { if (bf.tag() == x) return true }
-            )[0];
-        }
-    
-        this.bibFields = function (x) {
-            return this.controlSet(x).bib_fields;
-        }
-    
-        this.bibFieldBrowseAxes = function (t) {
-            var blist = [];
-            for (var bcode in MARC21.AuthorityControlSet._browse_axis_by_code) {
-                MARC21.AuthorityControlSet._browse_axis_by_code[bcode].maps().forEach(
-                    function (m) {
-                        if (m.field().bib_fields().filter(
-                                function (b) { return b.tag() == t }
-                            ).length > 0
-                        ) blist.push(bcode);
-                    }
-                );
-            }
-            return blist;
-        }
-    
-        this.authorityFields = function (x) {
-            return this.controlSet(x).raw.authority_fields();
-        }
-    
-        this.thesauri = function (x) {
-            return this.controlSet(x).raw.thesauri();
-        }
-    
-        this.controlSetList = function () {
-            var l = [];
-            for (var i in MARC21.AuthorityControlSet._controlsets) {
-                l.push(i);
-            }
-            return l;
-        }
-    
-        this.findControlSetsForTag = function (tag) {
-            var me = this;
-            var old_acs = this.controlSetId();
-            var acs_list = me.controlSetList().filter(
-                function(acs_id) { return (me.controlSet(acs_id).control_map[tag]) }
-            );
-            this.controlSetId(old_acs);
-            return acs_list;
-        }
-    
-        this.findControlSetsForAuthorityTag = function (tag) {
-            var me = this;
-            var old_acs = this.controlSetId();
-    
-            var acs_list = me.controlSetList().filter(
-                function(acs_id) {
-                    var a = me.controlSet(acs_id);
-                    for (var btag in a.control_map) {
-                        for (var sf in a.control_map[btag]) {
-                            if (a.control_map[btag][sf][tag]) return true;
-                        }
-                    }
-                    return false;
-                }
-            );
-            this.controlSetId(old_acs);
-            return acs_list;
-        }
-    
-        this.bibToAuthority = function (field) {
-            var b_field = this.bibFieldByTag(field.tag);
-    
-            if (b_field) { // construct an marc authority record
-                var af = b_field.authority_field();
-    
-                var sflist = [];                
-                for (var i = 0; i < field.subfields.length; i++) {
-                    if (af.sf_list().indexOf(field.subfields[i][0]) > -1) {
-                        sflist.push(field.subfields[i]);
-                    }
-                }
-    
-                var m = new MARC21.Record ({rtype:'AUT'});
-                m.appendFields(
-                    new MARC21.Field ({
-                        tag : af.tag(),
-                        ind1: field.ind1,
-                        ind2: field.ind2,
-                        subfields: sflist
-                    })
-                );
-    
-                return m.toXmlString();
-            }
-    
-            return null;
-        }
-    
-        this.bibToAuthorities = function (field) {
-            var auth_list = [];
-            var me = this;
-    
-            var old_acs = this.controlSetId();
-            me.controlSetList().forEach(
-                function (acs_id) {
-                    var acs = me.controlSet(acs_id);
-                    var x = me.bibToAuthority(field);
-                    if (x) { var foo = {}; foo[acs_id] = x; auth_list.push(foo); }
-                }
-            );
-            this.controlSetId(old_acs);
-    
-            return auth_list;
-        }
-    
-        // This should not be used in an angular world.  Instead, the call
-        // to open-ils.search.authority.simple_heading.from_xml.batch.atomic should
-        // be performed by the code that wants to find matching authorities.
-        this.findMatchingAuthorities = function (field) {
-            return fieldmapper.standardRequest(
-                [ 'open-ils.search', 'open-ils.search.authority.simple_heading.from_xml.batch.atomic' ],
-                this.bibToAuthorities(field)
-            );
-        }
-    
-        if (kwargs.controlSet) {
-            this.controlSetId( kwargs.controlSet );
-        } else {
-            this.controlSetId( this.controlSetList().sort(function(a,b){return (a - b)}) );
-        }
-    
     }
 };
 
@@ -1689,1334 +1309,3 @@ MARC21.Record._ff_pos = {
      }
 };
 
-MARC21.Record._physical_characteristics = {
-    c : {
-        label     : "Electronic Resource",
-        subfields : {
-            b : {    start : 1,
-                len   : 1,
-                label : "SMD",
-                values: {    a : "Tape Cartridge",
-                        b : "Chip cartridge",
-                        c : "Computer optical disk cartridge",
-                        f : "Tape cassette",
-                        h : "Tape reel",
-                        j : "Magnetic disk",
-                        m : "Magneto-optical disk",
-                        o : "Optical disk",
-                        r : "Remote",
-                        u : "Unspecified",
-                        z : "Other"
-                }
-            },
-            d : {    start : 3,
-                len   : 1,
-                label : "Color",
-                values: {    a : "One color",
-                        b : "Black-and-white",
-                        c : "Multicolored",
-                        g : "Gray scale",
-                        m : "Mixed",
-                        n : "Not applicable",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            e : {    start : 4,
-                len   : 1,
-                label : "Dimensions",
-                values: {    a : "3 1/2 in.",
-                        e : "12 in.",
-                        g : "4 3/4 in. or 12 cm.",
-                        i : "1 1/8 x 2 3/8 in.",
-                        j : "3 7/8 x 2 1/2 in.",
-                        n : "Not applicable",
-                        o : "5 1/4 in.",
-                        u : "Unknown",
-                        v : "8 in.",
-                        z : "Other"
-                }
-            },
-            f : {    start : 5,
-                len   : 1,
-                label : "Sound",
-                values: {    ' ' : "No sound (Silent)",
-                        a   : "Sound",
-                        u   : "Unknown"
-                }
-            },
-            g : {    start : 6,
-                len   : 3,
-                label : "Image bit depth",
-                values: {    mmm   : "Multiple",
-                        nnn   : "Not applicable",
-                        '---' : "Unknown"
-                }
-            },
-            h : {    start : 9,
-                len   : 1,
-                label : "File formats",
-                values: {    a : "One file format",
-                        m : "Multiple file formats",
-                        u : "Unknown"
-                }
-            },
-            i : {    start : 10,
-                len   : 1,
-                label : "Quality assurance target(s)",
-                values: {    a : "Absent",
-                        n : "Not applicable",
-                        p : "Present",
-                        u : "Unknown"
-                }
-            },
-            j : {    start : 11,
-                len   : 1,
-                label : "Antecedent/Source",
-                values: {    a : "File reproduced from original",
-                        b : "File reproduced from microform",
-                        c : "File reproduced from electronic resource",
-                        d : "File reproduced from an intermediate (not microform)",
-                        m : "Mixed",
-                        n : "Not applicable",
-                        u : "Unknown"
-                }
-            },
-            k : {    start : 12,
-                len   : 1,
-                label : "Level of compression",
-                values: {    a : "Uncompressed",
-                        b : "Lossless",
-                        d : "Lossy",
-                        m : "Mixed",
-                        u : "Unknown"
-                }
-            },
-            l : {    start : 13,
-                len   : 1,
-                label : "Reformatting quality",
-                values: {    a : "Access",
-                        n : "Not applicable",
-                        p : "Preservation",
-                        r : "Replacement",
-                        u : "Unknown"
-                }
-            }
-        }
-    },
-    d : {
-        label     : "Globe",
-        subfields : {
-            b : {    start : 1,
-                len   : 1,
-                label : "SMD",
-                values: {    a : "Celestial globe",
-                        b : "Planetary or lunar globe",
-                        c : "Terrestrial globe",
-                        e : "Earth moon globe",
-                        u : "Unspecified",
-                        z : "Other"
-                }
-            },
-            d : {    start : 3,
-                len   : 1,
-                label : "Color",
-                values: {    a : "One color",
-                        c : "Multicolored"
-                }
-            },
-            e : {    start : 4,
-                len   : 1,
-                label : "Physical medium",
-                values: {    a : "Paper",
-                        b : "Wood",
-                        c : "Stone",
-                        d : "Metal",
-                        e : "Synthetics",
-                        f : "Skins",
-                        g : "Textile",
-                        p : "Plaster",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            f : {    start : 5,
-                len   : 1,
-                label : "Type of reproduction",
-                values: {    f : "Facsimile",
-                        n : "Not applicable",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            }
-        }
-    },
-    a : {
-        label     : "Map",
-        subfields : {
-            b : {    start : 1,
-                len   : 1,
-                label : "SMD",
-                values: {    d : "Atlas",
-                        g : "Diagram",
-                        j : "Map",
-                        k : "Profile",
-                        q : "Model",
-                        r : "Remote-sensing image",
-                        s : "Section",
-                        u : "Unspecified",
-                        y : "View",
-                        z : "Other"
-                }
-            },
-            d : {    start : 3,
-                len   : 1,
-                label : "Color",
-                values: {    a : "One color",
-                        c : "Multicolored"
-                }
-            },
-            e : {    start : 4,
-                len   : 1,
-                label : "Physical medium",
-                values: {    a : "Paper",
-                        b : "Wood",
-                        c : "Stone",
-                        d : "Metal",
-                        e : "Synthetics",
-                        f : "Skins",
-                        g : "Textile",
-                        p : "Plaster",
-                        q : "Flexible base photographic medium, positive",
-                        r : "Flexible base photographic medium, negative",
-                        s : "Non-flexible base photographic medium, positive",
-                        t : "Non-flexible base photographic medium, negative",
-                        u : "Unknown",
-                        y : "Other photographic medium",
-                        z : "Other"
-                }
-            },
-            f : {    start : 5,
-                len   : 1,
-                label : "Type of reproduction",
-                values: {    f : "Facsimile",
-                        n : "Not applicable",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            g : {    start : 6,
-                len   : 1,
-                label : "Production/reproduction details",
-                values: {    a : "Photocopy, blueline print",
-                        b : "Photocopy",
-                        c : "Pre-production",
-                        d : "Film",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            h : {    start : 7,
-                len   : 1,
-                label : "Positive/negative",
-                values: {    a : "Positive",
-                        b : "Negative",
-                        m : "Mixed",
-                        n : "Not applicable"
-                }
-            }
-        }
-    },
-    h : {
-        label     : "Microform",
-        subfields : {
-            b : {    start : 1,
-                len   : 1,
-                label : "SMD",
-                values: {    a : "Aperture card",
-                        b : "Microfilm cartridge",
-                        c : "Microfilm cassette",
-                        d : "Microfilm reel",
-                        e : "Microfiche",
-                        f : "Microfiche cassette",
-                        g : "Microopaque",
-                        u : "Unspecified",
-                        z : "Other"
-                }
-            },
-            d : {    start : 3,
-                len   : 1,
-                label : "Positive/negative",
-                values: {    a : "Positive",
-                        b : "Negative",
-                        m : "Mixed",
-                        u : "Unknown"
-                }
-            },
-            e : {    start : 4,
-                len   : 1,
-                label : "Dimensions",
-                values: {    a : "8 mm.",
-                        e : "16 mm.",
-                        f : "35 mm.",
-                        g : "70mm.",
-                        h : "105 mm.",
-                        l : "3 x 5 in. (8 x 13 cm.)",
-                        m : "4 x 6 in. (11 x 15 cm.)",
-                        o : "6 x 9 in. (16 x 23 cm.)",
-                        p : "3 1/4 x 7 3/8 in. (9 x 19 cm.)",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            f : {    start : 5,
-                len   : 4,
-                label : "Reduction ratio range/Reduction ratio",
-                values: {    a : "Low (1-16x)",
-                        b : "Normal (16-30x)",
-                        c : "High (31-60x)",
-                        d : "Very high (61-90x)",
-                        e : "Ultra (90x-)",
-                        u : "Unknown",
-                        v : "Reduction ratio varies"
-                }
-            },
-            g : {    start : 9,
-                len   : 1,
-                label : "Color",
-                values: {    b : "Black-and-white",
-                        c : "Multicolored",
-                        m : "Mixed",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            h : {    start : 10,
-                len   : 1,
-                label : "Emulsion on film",
-                values: {    a : "Silver halide",
-                        b : "Diazo",
-                        c : "Vesicular",
-                        m : "Mixed",
-                        n : "Not applicable",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            i : {    start : 11,
-                len   : 1,
-                label : "Quality assurance target(s)",
-                values: {    a : "1st gen. master",
-                        b : "Printing master",
-                        c : "Service copy",
-                        m : "Mixed generation",
-                        u : "Unknown"
-                }
-            },
-            j : {    start : 12,
-                len   : 1,
-                label : "Base of film",
-                values: {    a : "Safety base, undetermined",
-                        c : "Safety base, acetate undetermined",
-                        d : "Safety base, diacetate",
-                        l : "Nitrate base",
-                        m : "Mixed base",
-                        n : "Not applicable",
-                        p : "Safety base, polyester",
-                        r : "Safety base, mixed",
-                        t : "Safety base, triacetate",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            }
-        }
-    },
-    m : {
-        label     : "Motion Picture",
-        subfields : {
-            b : {    start : 1,
-                len   : 1,
-                label : "SMD",
-                values: {    a : "Film cartridge",
-                        f : "Film cassette",
-                        r : "Film reel",
-                        u : "Unspecified",
-                        z : "Other"
-                }
-            },
-            d : {    start : 3,
-                len   : 1,
-                label : "Color",
-                values: {    b : "Black-and-white",
-                        c : "Multicolored",
-                        h : "Hand-colored",
-                        m : "Mixed",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            e : {    start : 4,
-                len   : 1,
-                label : "Motion picture presentation format",
-                values: {    a : "Standard sound aperture, reduced frame",
-                        b : "Nonanamorphic (wide-screen)",
-                        c : "3D",
-                        d : "Anamorphic (wide-screen)",
-                        e : "Other-wide screen format",
-                        f : "Standard. silent aperture, full frame",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            f : {    start : 5,
-                len   : 1,
-                label : "Sound on medium or separate",
-                values: {    a : "Sound on medium",
-                        b : "Sound separate from medium",
-                        u : "Unknown"
-                }
-            },
-            g : {    start : 6,
-                len   : 1,
-                label : "Medium for sound",
-                values: {    a : "Optical sound track on motion picture film",
-                        b : "Magnetic sound track on motion picture film",
-                        c : "Magnetic audio tape in cartridge",
-                        d : "Sound disc",
-                        e : "Magnetic audio tape on reel",
-                        f : "Magnetic audio tape in cassette",
-                        g : "Optical and magnetic sound track on film",
-                        h : "Videotape",
-                        i : "Videodisc",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            h : {    start : 7,
-                len   : 1,
-                label : "Dimensions",
-                values: {    a : "Standard 8 mm.",
-                        b : "Super 8 mm./single 8 mm.",
-                        c : "9.5 mm.",
-                        d : "16 mm.",
-                        e : "28 mm.",
-                        f : "35 mm.",
-                        g : "70 mm.",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            i : {    start : 8,
-                len   : 1,
-                label : "Configuration of playback channels",
-                values: {    k : "Mixed",
-                        m : "Monaural",
-                        n : "Not applicable",
-                        q : "Multichannel, surround or quadraphonic",
-                        s : "Stereophonic",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            j : {    start : 9,
-                len   : 1,
-                label : "Production elements",
-                values: {    a : "Work print",
-                        b : "Trims",
-                        c : "Outtakes",
-                        d : "Rushes",
-                        e : "Mixing tracks",
-                        f : "Title bands/inter-title rolls",
-                        g : "Production rolls",
-                        n : "Not applicable",
-                        z : "Other"
-                }
-            }
-        }
-    },
-    k : {
-        label     : "Non-projected Graphic",
-        subfields : {
-            b : {    start : 1,
-                len   : 1,
-                label : "SMD",
-                values: {    c : "Collage",
-                        d : "Drawing",
-                        e : "Painting",
-                        f : "Photo-mechanical print",
-                        g : "Photonegative",
-                        h : "Photoprint",
-                        i : "Picture",
-                        j : "Print",
-                        l : "Technical drawing",
-                        n : "Chart",
-                        o : "Flash/activity card",
-                        u : "Unspecified",
-                        z : "Other"
-                }
-            },
-            d : {    start : 3,
-                len   : 1,
-                label : "Color",
-                values: {    a : "One color",
-                        b : "Black-and-white",
-                        c : "Multicolored",
-                        h : "Hand-colored",
-                        m : "Mixed",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            e : {    start : 4,
-                len   : 1,
-                label : "Primary support material",
-                values: {    a : "Canvas",
-                        b : "Bristol board",
-                        c : "Cardboard/illustration board",
-                        d : "Glass",
-                        e : "Synthetics",
-                        f : "Skins",
-                        g : "Textile",
-                        h : "Metal",
-                        m : "Mixed collection",
-                        o : "Paper",
-                        p : "Plaster",
-                        q : "Hardboard",
-                        r : "Porcelain",
-                        s : "Stone",
-                        t : "Wood",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            f : {    start : 5,
-                len   : 1,
-                label : "Secondary support material",
-                values: {    a : "Canvas",
-                        b : "Bristol board",
-                        c : "Cardboard/illustration board",
-                        d : "Glass",
-                        e : "Synthetics",
-                        f : "Skins",
-                        g : "Textile",
-                        h : "Metal",
-                        m : "Mixed collection",
-                        o : "Paper",
-                        p : "Plaster",
-                        q : "Hardboard",
-                        r : "Porcelain",
-                        s : "Stone",
-                        t : "Wood",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            }
-        }
-    },
-    g : {
-        label     : "Projected Graphic",
-        subfields : {
-            b : {    start : 1,
-                len   : 1,
-                label : "SMD",
-                values: {    c : "Film cartridge",
-                        d : "Filmstrip",
-                        f : "Film filmstrip type",
-                        o : "Filmstrip roll",
-                        s : "Slide",
-                        t : "Transparency",
-                        z : "Other"
-                }
-            },
-            d : {    start : 3,
-                len   : 1,
-                label : "Color",
-                values: {    b : "Black-and-white",
-                        c : "Multicolored",
-                        h : "Hand-colored",
-                        m : "Mixed",
-                        n : "Not applicable",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            e : {    start : 4,
-                len   : 1,
-                label : "Base of emulsion",
-                values: {    d : "Glass",
-                        e : "Synthetics",
-                        j : "Safety film",
-                        k : "Film base, other than safety film",
-                        m : "Mixed collection",
-                        o : "Paper",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            f : {    start : 5,
-                len   : 1,
-                label : "Sound on medium or separate",
-                values: {    a : "Sound on medium",
-                        b : "Sound separate from medium",
-                        u : "Unknown"
-                }
-            },
-            g : {    start : 6,
-                len   : 1,
-                label : "Medium for sound",
-                values: {    a : "Optical sound track on motion picture film",
-                        b : "Magnetic sound track on motion picture film",
-                        c : "Magnetic audio tape in cartridge",
-                        d : "Sound disc",
-                        e : "Magnetic audio tape on reel",
-                        f : "Magnetic audio tape in cassette",
-                        g : "Optical and magnetic sound track on film",
-                        h : "Videotape",
-                        i : "Videodisc",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            h : {    start : 7,
-                len   : 1,
-                label : "Dimensions",
-                values: {    a : "Standard 8 mm.",
-                        b : "Super 8 mm./single 8 mm.",
-                        c : "9.5 mm.",
-                        d : "16 mm.",
-                        e : "28 mm.",
-                        f : "35 mm.",
-                        g : "70 mm.",
-                        j : "2 x 2 in. (5 x 5 cm.)",
-                        k : "2 1/4 x 2 1/4 in. (6 x 6 cm.)",
-                        s : "4 x 5 in. (10 x 13 cm.)",
-                        t : "5 x 7 in. (13 x 18 cm.)",
-                        v : "8 x 10 in. (21 x 26 cm.)",
-                        w : "9 x 9 in. (23 x 23 cm.)",
-                        x : "10 x 10 in. (26 x 26 cm.)",
-                        y : "7 x 7 in. (18 x 18 cm.)",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            i : {    start : 8,
-                len   : 1,
-                label : "Secondary support material",
-                values: {    c : "Cardboard",
-                        d : "Glass",
-                        e : "Synthetics",
-                        h : "metal",
-                        j : "Metal and glass",
-                        k : "Synthetics and glass",
-                        m : "Mixed collection",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            }
-        }
-    },
-    r : {
-        label     : "Remote-sensing Image",
-        subfields : {
-            b : {    start : 1,
-                len   : 1,
-                label : "SMD",
-                values: { u : "Unspecified" }
-            },
-            d : {    start : 3,
-                len   : 1,
-                label : "Altitude of sensor",
-                values: {    a : "Surface",
-                        b : "Airborne",
-                        c : "Spaceborne",
-                        n : "Not applicable",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            e : {    start : 4,
-                len   : 1,
-                label : "Attitude of sensor",
-                values: {    a : "Low oblique",
-                        b : "High oblique",
-                        c : "Vertical",
-                        n : "Not applicable",
-                        u : "Unknown"
-                }
-            },
-            f : {    start : 5,
-                len   : 1,
-                label : "Cloud cover",
-                values: {    0 : "0-09%",
-                        1 : "10-19%",
-                        2 : "20-29%",
-                        3 : "30-39%",
-                        4 : "40-49%",
-                        5 : "50-59%",
-                        6 : "60-69%",
-                        7 : "70-79%",
-                        8 : "80-89%",
-                        9 : "90-100%",
-                        n : "Not applicable",
-                        u : "Unknown"
-                }
-            },
-            g : {    start : 6,
-                len   : 1,
-                label : "Platform construction type",
-                values: {    a : "Balloon",
-                        b : "Aircraft-low altitude",
-                        c : "Aircraft-medium altitude",
-                        d : "Aircraft-high altitude",
-                        e : "Manned spacecraft",
-                        f : "Unmanned spacecraft",
-                        g : "Land-based remote-sensing device",
-                        h : "Water surface-based remote-sensing device",
-                        i : "Submersible remote-sensing device",
-                        n : "Not applicable",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            h : {    start : 7,
-                len   : 1,
-                label : "Platform use category",
-                values: {    a : "Meteorological",
-                        b : "Surface observing",
-                        c : "Space observing",
-                        m : "Mixed uses",
-                        n : "Not applicable",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            i : {    start : 8,
-                len   : 1,
-                label : "Sensor type",
-                values: {    a : "Active",
-                        b : "Passive",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            j : {    start : 9,
-                len   : 2,
-                label : "Data type",
-                values: {    nn : "Not applicable",
-                        uu : "Unknown",
-                        zz : "Other",
-                        aa : "Visible light",
-                        da : "Near infrared",
-                        db : "Middle infrared",
-                        dc : "Far infrared",
-                        dd : "Thermal infrared",
-                        de : "Shortwave infrared (SWIR)",
-                        df : "Reflective infrared",
-                        dv : "Combinations",
-                        dz : "Other infrared data",
-                        ga : "Sidelooking airborne radar (SLAR)",
-                        gb : "Synthetic aperture radar (SAR-single frequency)",
-                        gc : "SAR-multi-frequency (multichannel)",
-                        gd : "SAR-like polarization",
-                        ge : "SAR-cross polarization",
-                        gf : "Infometric SAR",
-                        gg : "Polarmetric SAR",
-                        gu : "Passive microwave mapping",
-                        gz : "Other microwave data",
-                        ja : "Far ultraviolet",
-                        jb : "Middle ultraviolet",
-                        jc : "Near ultraviolet",
-                        jv : "Ultraviolet combinations",
-                        jz : "Other ultraviolet data",
-                        ma : "Multi-spectral, multidata",
-                        mb : "Multi-temporal",
-                        mm : "Combination of various data types",
-                        pa : "Sonar-water depth",
-                        pb : "Sonar-bottom topography images, sidescan",
-                        pc : "Sonar-bottom topography, near-surface",
-                        pd : "Sonar-bottom topography, near-bottom",
-                        pe : "Seismic surveys",
-                        pz : "Other acoustical data",
-                        ra : "Gravity anomales (general)",
-                        rb : "Free-air",
-                        rc : "Bouger",
-                        rd : "Isostatic",
-                        sa : "Magnetic field",
-                        ta : "Radiometric surveys"
-                }
-            }
-        }
-    },
-    s : {
-        label     : "Sound Recording",
-        subfields : {
-            b : {    start : 1,
-                len   : 1,
-                label : "SMD",
-                values: {    d : "Sound disc",
-                        e : "Cylinder",
-                        g : "Sound cartridge",
-                        i : "Sound-track film",
-                        q : "Roll",
-                        s : "Sound cassette",
-                        t : "Sound-tape reel",
-                        u : "Unspecified",
-                        w : "Wire recording",
-                        z : "Other"
-                }
-            },
-            d : {    start : 3,
-                len   : 1,
-                label : "Speed",
-                values: {    a : "16 rpm",
-                        b : "33 1/3 rpm",
-                        c : "45 rpm",
-                        d : "78 rpm",
-                        e : "8 rpm",
-                        f : "1.4 mps",
-                        h : "120 rpm",
-                        i : "160 rpm",
-                        k : "15/16 ips",
-                        l : "1 7/8 ips",
-                        m : "3 3/4 ips",
-                        o : "7 1/2 ips",
-                        p : "15 ips",
-                        r : "30 ips",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            e : {    start : 4,
-                len   : 1,
-                label : "Configuration of playback channels",
-                values: {    m : "Monaural",
-                        q : "Quadraphonic",
-                        s : "Stereophonic",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            f : {    start : 5,
-                len   : 1,
-                label : "Groove width or pitch",
-                values: {    m : "Microgroove/fine",
-                        n : "Not applicable",
-                        s : "Coarse/standard",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            g : {    start : 6,
-                len   : 1,
-                label : "Dimensions",
-                values: {    a : "3 in.",
-                        b : "5 in.",
-                        c : "7 in.",
-                        d : "10 in.",
-                        e : "12 in.",
-                        f : "16 in.",
-                        g : "4 3/4 in. (12 cm.)",
-                        j : "3 7/8 x 2 1/2 in.",
-                        o : "5 1/4 x 3 7/8 in.",
-                        s : "2 3/4 x 4 in.",
-                        n : "Not applicable",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            h : {    start : 7,
-                len   : 1,
-                label : "Tape width",
-                values: {    l : "1/8 in.",
-                        m : "1/4in.",
-                        n : "Not applicable",
-                        o : "1/2 in.",
-                        p : "1 in.",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            i : {    start : 8,
-                len   : 1,
-                label : "Tape configuration ",
-                values: {    a : "Full (1) track",
-                        b : "Half (2) track",
-                        c : "Quarter (4) track",
-                        d : "8 track",
-                        e : "12 track",
-                        f : "16 track",
-                        n : "Not applicable",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            m : {    start : 12,
-                len   : 1,
-                label : "Special playback",
-                values: {    a : "NAB standard",
-                        b : "CCIR standard",
-                        c : "Dolby-B encoded, standard Dolby",
-                        d : "dbx encoded",
-                        e : "Digital recording",
-                        f : "Dolby-A encoded",
-                        g : "Dolby-C encoded",
-                        h : "CX encoded",
-                        n : "Not applicable",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            n : {    start : 13,
-                len   : 1,
-                label : "Capture and storage",
-                values: {    a : "Acoustical capture, direct storage",
-                        b : "Direct storage, not acoustical",
-                        d : "Digital storage",
-                        e : "Analog electrical storage",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            }
-        }
-    },
-    f : {
-        label     : "Tactile Material",
-        subfields : {
-            b : {    start : 1,
-                len   : 1,
-                label : "SMD",
-                values: {    a : "Moon",
-                        b : "Braille",
-                        c : "Combination",
-                        d : "Tactile, with no writing system",
-                        u : "Unspecified",
-                        z : "Other"
-                }
-            },
-            d : {    start : 3,
-                len   : 2,
-                label : "Class of braille writing",
-                values: {    a : "Literary braille",
-                        b : "Format code braille",
-                        c : "Mathematics and scientific braille",
-                        d : "Computer braille",
-                        e : "Music braille",
-                        m : "Multiple braille types",
-                        n : "Not applicable",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            e : {    start : 4,
-                len   : 1,
-                label : "Level of contraction",
-                values: {    a : "Uncontracted",
-                        b : "Contracted",
-                        m : "Combination",
-                        n : "Not applicable",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            f : {    start : 6,
-                len   : 3,
-                label : "Braille music format",
-                values: {    a : "Bar over bar",
-                        b : "Bar by bar",
-                        c : "Line over line",
-                        d : "Paragraph",
-                        e : "Single line",
-                        f : "Section by section",
-                        g : "Line by line",
-                        h : "Open score",
-                        i : "Spanner short form scoring",
-                        j : "Short form scoring",
-                        k : "Outline",
-                        l : "Vertical score",
-                        n : "Not applicable",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            g : {    start : 9,
-                len   : 1,
-                label : "Special physical characteristics",
-                values: {    a : "Print/braille",
-                        b : "Jumbo or enlarged braille",
-                        n : "Not applicable",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            }
-        }
-    },
-    v : {
-        label     : "Videorecording",
-        subfields : {
-            b : {    start : 1,
-                len   : 1,
-                label : "SMD",
-                values: {     c : "Videocartridge",
-                        d : "Videodisc",
-                        f : "Videocassette",
-                        r : "Videoreel",
-                        u : "Unspecified",
-                        z : "Other"
-                }
-            },
-            d : {    start : 3,
-                len   : 1,
-                label : "Color",
-                values: {    b : "Black-and-white",
-                        c : "Multicolored",
-                        m : "Mixed",
-                        n : "Not applicable",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            e : {    start : 4,
-                len   : 1,
-                label : "Videorecording format",
-                values: {    a : "Beta",
-                        b : "VHS",
-                        c : "U-matic",
-                        d : "EIAJ",
-                        e : "Type C",
-                        f : "Quadruplex",
-                        g : "Laserdisc",
-                        h : "CED",
-                        i : "Betacam",
-                        j : "Betacam SP",
-                        k : "Super-VHS",
-                        m : "M-II",
-                        o : "D-2",
-                        p : "8 mm.",
-                        q : "Hi-8 mm.",
-                        u : "Unknown",
-                        v : "DVD",
-                        z : "Other"
-                }
-            },
-            f : {    start : 5,
-                len   : 1,
-                label : "Sound on medium or separate",
-                values: {    a : "Sound on medium",
-                        b : "Sound separate from medium",
-                        u : "Unknown"
-                }
-            },
-            g : {    start : 6,
-                len   : 1,
-                label : "Medium for sound",
-                values: {    a : "Optical sound track on motion picture film",
-                        b : "Magnetic sound track on motion picture film",
-                        c : "Magnetic audio tape in cartridge",
-                        d : "Sound disc",
-                        e : "Magnetic audio tape on reel",
-                        f : "Magnetic audio tape in cassette",
-                        g : "Optical and magnetic sound track on motion picture film",
-                        h : "Videotape",
-                        i : "Videodisc",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            h : {    start : 7,
-                len   : 1,
-                label : "Dimensions",
-                values: {    a : "8 mm.",
-                        m : "1/4 in.",
-                        o : "1/2 in.",
-                        p : "1 in.",
-                        q : "2 in.",
-                        r : "3/4 in.",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            },
-            i : {    start : 8,
-                len   : 1,
-                label : "Configuration of playback channel",
-                values: {    k : "Mixed",
-                        m : "Monaural",
-                        n : "Not applicable",
-                        q : "Multichannel, surround or quadraphonic",
-                        s : "Stereophonic",
-                        u : "Unknown",
-                        z : "Other"
-                }
-            }
-        }
-    }
-};
-
-MARC21.AuthorityControlSet._remote_loaded = false;
-MARC21.AuthorityControlSet._remote_parsed = false;
-
-MARC21.AuthorityControlSet._controlsets = {
-    // static sorta-LoC setup ... to be overwritten with server data 
-    '-1' : {
-        id : -1,
-        name : 'Static LoC legacy mapping',
-        description : 'Legacy mapping provided as a default',
-        control_map : {
-            100 : {
-                'a' : { 100 : 'a' },
-                'd' : { 100 : 'd' },
-                'e' : { 100 : 'e' },
-                'q' : { 100 : 'q' }
-            },
-            110 : {
-                'a' : { 110 : 'a' },
-                'd' : { 110 : 'd' }
-            },
-            111 : {
-                'a' : { 111 : 'a' },
-                'd' : { 111 : 'd' }
-            },
-            130 : {
-                'a' : { 130 : 'a' },
-                'd' : { 130 : 'd' }
-            },
-            240 : {
-                'a' : { 130 : 'a' },
-                'd' : { 130 : 'd' }
-            },
-            400 : {
-                'a' : { 100 : 'a' },
-                'd' : { 100 : 'd' }
-            },
-            410 : {
-                'a' : { 110 : 'a' },
-                'd' : { 110 : 'd' }
-            },
-            411 : {
-                'a' : { 111 : 'a' },
-                'd' : { 111 : 'd' }
-            },
-            440 : {
-                'a' : { 130 : 'a' },
-                'n' : { 130 : 'n' },
-                'p' : { 130 : 'p' }
-            },
-            700 : {
-                'a' : { 100 : 'a' },
-                'd' : { 100 : 'd' },
-                'q' : { 100 : 'q' },
-                't' : { 100 : 't' }
-            },
-            710 : {
-                'a' : { 110 : 'a' },
-                'd' : { 110 : 'd' }
-            },
-            711 : {
-                'a' : { 111 : 'a' },
-                'c' : { 111 : 'c' },
-                'd' : { 111 : 'd' }
-            },
-            730 : {
-                'a' : { 130 : 'a' },
-                'd' : { 130 : 'd' }
-            },
-            800 : {
-                'a' : { 100 : 'a' },
-                'd' : { 100 : 'd' }
-            },
-            810 : {
-                'a' : { 110 : 'a' },
-                'd' : { 110 : 'd' }
-            },
-            811 : {
-                'a' : { 111 : 'a' },
-                'd' : { 111 : 'd' }
-            },
-            830 : {
-                'a' : { 130 : 'a' },
-                'd' : { 130 : 'd' }
-            },
-            600 : {
-                'a' : { 100 : 'a' },
-                'd' : { 100 : 'd' },
-                'q' : { 100 : 'q' },
-                't' : { 100 : 't' },
-                'v' : { 180 : 'v',
-                    100 : 'v',
-                    181 : 'v',
-                    182 : 'v',
-                    185 : 'v'
-                },
-                'x' : { 180 : 'x',
-                    100 : 'x',
-                    181 : 'x',
-                    182 : 'x',
-                    185 : 'x'
-                },
-                'y' : { 180 : 'y',
-                    100 : 'y',
-                    181 : 'y',
-                    182 : 'y',
-                    185 : 'y'
-                },
-                'z' : { 180 : 'z',
-                    100 : 'z',
-                    181 : 'z',
-                    182 : 'z',
-                    185 : 'z'
-                }
-            },
-            610 : {
-                'a' : { 110 : 'a' },
-                'd' : { 110 : 'd' },
-                't' : { 110 : 't' },
-                'v' : { 180 : 'v',
-                    110 : 'v',
-                    181 : 'v',
-                    182 : 'v',
-                    185 : 'v'
-                },
-                'x' : { 180 : 'x',
-                    110 : 'x',
-                    181 : 'x',
-                    182 : 'x',
-                    185 : 'x'
-                },
-                'y' : { 180 : 'y',
-                    110 : 'y',
-                    181 : 'y',
-                    182 : 'y',
-                    185 : 'y'
-                },
-                'z' : { 180 : 'z',
-                    110 : 'z',
-                    181 : 'z',
-                    182 : 'z',
-                    185 : 'z'
-                }
-            },
-            611 : {
-                'a' : { 111 : 'a' },
-                'd' : { 111 : 'd' },
-                't' : { 111 : 't' },
-                'v' : { 180 : 'v',
-                    111 : 'v',
-                    181 : 'v',
-                    182 : 'v',
-                    185 : 'v'
-                },
-                'x' : { 180 : 'x',
-                    111 : 'x',
-                    181 : 'x',
-                    182 : 'x',
-                    185 : 'x'
-                },
-                'y' : { 180 : 'y',
-                    111 : 'y',
-                    181 : 'y',
-                    182 : 'y',
-                    185 : 'y'
-                },
-                'z' : { 180 : 'z',
-                    111 : 'z',
-                    181 : 'z',
-                    182 : 'z',
-                    185 : 'z'
-                }
-            },
-            630 : {
-                'a' : { 130 : 'a' },
-                'd' : { 130 : 'd' }
-            },
-            648 : {
-                'a' : { 148 : 'a' },
-                'v' : { 148 : 'v' },
-                'x' : { 148 : 'x' },
-                'y' : { 148 : 'y' },
-                'z' : { 148 : 'z' }
-            },
-            650 : {
-                'a' : { 150 : 'a' },
-                'b' : { 150 : 'b' },
-                'v' : { 180 : 'v',
-                    150 : 'v',
-                    181 : 'v',
-                    182 : 'v',
-                    185 : 'v'
-                },
-                'x' : { 180 : 'x',
-                    150 : 'x',
-                    181 : 'x',
-                    182 : 'x',
-                    185 : 'x'
-                },
-                'y' : { 180 : 'y',
-                    150 : 'y',
-                    181 : 'y',
-                    182 : 'y',
-                    185 : 'y'
-                },
-                'z' : { 180 : 'z',
-                    150 : 'z',
-                    181 : 'z',
-                    182 : 'z',
-                    185 : 'z'
-                }
-            },
-            651 : {
-                'a' : { 151 : 'a' },
-                'v' : { 180 : 'v',
-                    151 : 'v',
-                    181 : 'v',
-                    182 : 'v',
-                    185 : 'v'
-                },
-                'x' : { 180 : 'x',
-                    151 : 'x',
-                    181 : 'x',
-                    182 : 'x',
-                    185 : 'x'
-                },
-                'y' : { 180 : 'y',
-                    151 : 'y',
-                    181 : 'y',
-                    182 : 'y',
-                    185 : 'y'
-                },
-                'z' : { 180 : 'z',
-                    151 : 'z',
-                    181 : 'z',
-                    182 : 'z',
-                    185 : 'z'
-                }
-            },
-            655 : {
-                'a' : { 155 : 'a' },
-                'v' : { 180 : 'v',
-                    155 : 'v',
-                    181 : 'v',
-                    182 : 'v',
-                    185 : 'v'
-                },
-                'x' : { 180 : 'x',
-                    155 : 'x',
-                    181 : 'x',
-                    182 : 'x',
-                    185 : 'x'
-                },
-                'y' : { 180 : 'y',
-                    155 : 'y',
-                    181 : 'y',
-                    182 : 'y',
-                    185 : 'y'
-                },
-                'z' : { 180 : 'z',
-                    155 : 'z',
-                    181 : 'z',
-                    182 : 'z',
-                    185 : 'z'
-                }
-            }
-        }
-    }
-};
-