]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/js/ui/default/staff/marcrecord.js
LP2061136 - Stamping 1405 DB upgrade script
[Evergreen.git] / Open-ILS / web / js / ui / default / staff / marcrecord.js
1 /* ---------------------------------------------------------------------------
2  * Copyright (C) 2009-2015  Equinox Software, Inc.
3  * Mike Rylander <miker@esilibrary.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * ---------------------------------------------------------------------------
15  */
16
17 // !!! Head's up !!!
18 // This module requires a /real/ jQuery be used with your
19 // angularjs, so as to avoid using hand-rolled AJAX.
20
21 var MARC21 = {
22
23     Record : function(kwargs) {
24         if (!kwargs) kwargs = {};
25
26         this.generate008 = function () {
27             var f;
28             var s;
29             var orig008 = '                                        ';
30             var now = new Date();
31             var y = now.getUTCFullYear().toString().substr(2,2);
32             var m = now.getUTCMonth() + 1;
33             if (m < 10) m = '0' + m;
34             var d = now.getUTCDate();
35             if (d < 10) d = '0' + d;
36
37
38             if (f = this.field('008',true)[0]) {
39                 orig008 = f.data;
40             }
41         
42             /* lang code from 041a */
43             var lang = orig008.substr(35, 3);
44             
45             if (f = this.field('041',true)[0]) {
46                 if (s = f.subfield('a',true)[0]) {
47                     if(s[1]) lang = s[1];
48                 }
49             }
50         
51             /* country code from 044a */
52             var country = orig008.substr(15, 3);
53             if (f = this.field('044',true)[0]) {
54                 if (s = f.subfield('a',true)[0]) {
55                     if(s[1]) country = s[1];
56                 }
57             }
58             while (country.length < 3) country = country + ' ';
59             if (country.length > 3) country = country.substr(0,3);
60         
61             /* date1 from 260c */
62             var date1 = now.getUTCFullYear().toString();
63             if (f = this.field('260',true)[0]) {
64                 if (s = f.subfield('c',true)[0]) {
65                     if (s[1]) {
66                         var tmpd = s[1];
67                         tmpd = tmpd.replace(/[^0-9]/g, '');
68                         if (tmpd.match(/^\d\d\d\d/)) {
69                             date1 = tmpd.substr(0, 4);
70                         }
71                     }
72                 }
73             }
74         
75             var date2 = orig008.substr(11, 4);
76             var datetype = orig008.substr(6, 1);
77             var modded = orig008.substr(38, 1);
78             var catsrc = orig008.substr(39, 1);
79         
80             return '' + y + m + d + datetype + date1 + date2 + country + '                 ' + lang + modded + catsrc;
81         
82         }
83
84         this.title = function () { return this.subfield('245','a')[1] }
85
86         this.field = function (spec, wantarray) {
87             var list = this.fields.filter(function (f) {
88                 if (f.tag.match(spec)) return true;
89                 return false;
90             });
91
92             if (!wantarray && list.length == 1) return list[0];
93             return list;
94         }
95
96         this.subfield = function (spec, code) {
97             var f = this.field(spec, true)[0];
98             if (f) return f.subfield(code)
99             return null;
100         }
101
102         this.appendFields = function () {
103             var me = this;
104             Array.prototype.slice.call(arguments).forEach( function (f) { f.position = me.fields.length; me.fields.push( f ) } );
105         }
106
107         this.deleteField = function (f) { return this.deleteFields(f) },
108
109         this.insertOrderedFields = function () {
110             var me = this;
111             for (var i = 0; i < arguments.length; i++) {
112                 var f = arguments[i];
113                 var done = false;
114                 for (var j = 0; j < this.fields.length; j++) {
115                     if (f.tag < this.fields[j].tag) {
116                         this.insertFieldsBefore(this.fields[j], f);
117                         done = true;
118                         break;
119                     }
120                 }
121                 if (!done) this.appendFields(f);
122             }
123         }
124
125         this.insertFieldsBefore = function (target) {
126             var args = Array.prototype.slice.call(arguments);
127             args.splice(0,1);
128             var me = this;
129             for (var j = 0; j < this.fields.length; j++) {
130                 if (target === this.fields[j]) {
131                     args.forEach( function (f) {
132                         f.record = me;
133                         me.fields.splice(j++,0,f);
134                     });
135                     break;
136                 }
137             }
138             for (var j = 0; j < this.fields.length; j++) {
139                 this.fields[j].position = j;
140             }
141         }
142
143         this.insertFieldsAfter = function (target) {
144             var args = Array.prototype.slice.call(arguments);
145             args.splice(0,1);
146             var me = this;
147             for (var j = 0; j < this.fields.length; j++) {
148                 if (target === this.fields[j]) {
149                     args.forEach( function (f) {
150                         f.record = me;
151                         me.fields.splice(++j,0,f);
152                     });
153                     break;
154                 }
155             }
156             for (var j = 0; j < this.fields.length; j++) {
157                 this.fields[j].position = j;
158             }
159         }
160
161         this.deleteFields = function () {
162             var me = this;
163             var counter = 0;
164             for ( var i in arguments ) {
165                 var f = arguments[i];
166                 for (var j = 0; j < me.fields.length; j++) {
167                     if (f === me.fields[j]) {
168                         me.fields[j].record = null;
169                         me.fields.splice(j,1);
170                         counter++
171                         break;
172                     }
173                 }
174             }
175             for (var j = 0; j < this.fields.length; j++) {
176                 this.fields[j].position = j;
177             }
178             return counter;
179         }
180
181         // this.clone = function () { return dojo.clone(this) } // maybe implement later...
182
183         this.fromXmlURL = function (url) {
184             var me = this;
185             return $.get( // This is a Promise
186                 url,
187                 function (mxml) {
188                     me.fromXmlDocument($('record', mxml)[0]);
189                     if (me.onLoad) me.onLoad();
190             });
191         }
192
193         this.fromXmlString = function (mxml) {
194                 this.fromXmlDocument( $( $.parseXML( mxml ) ).find('record')[0] );
195         }
196
197         this.fromXmlDocument = function (mxml) {
198             var me = this;
199             me.leader = $($('leader',mxml)[0]).text() || '00000cam a2200205Ka 4500';
200
201             $('controlfield', mxml).each(function (ind) {
202                 var cf=$(this);
203                 me.fields.push(
204                     new MARC21.Field({
205                           record : me,
206                           tag    : cf.attr('tag'),
207                           data   : cf.text(),
208                     })
209                 )
210             });
211
212             $('datafield', mxml).each(function (ind) {
213                 var df=$(this);
214                 me.fields.push(
215                     new MARC21.Field({
216                         record    : me,
217                         tag       : df.attr('tag'),
218                         ind1      : df.attr('ind1'),
219                         ind2      : df.attr('ind2'),
220                         subfields : $('subfield', df).map(
221                             function (i, sf) {
222                                 return [[ $(sf).attr('code'), $(sf).text(), i ]];
223                             }
224                         ).get()
225                     })
226                 )
227             });
228
229             for (var j = 0; j < this.fields.length; j++) {
230                 this.fields[j].position = j;
231             }
232
233             me.ready = true;
234
235         }
236
237         this.toXmlDocument = function () {
238
239             var doc = $.parseXML('<record xmlns="http://www.loc.gov/MARC21/slim"/>');
240             var rec_node = $('record', doc)[0];
241
242             var ldr = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'leader');
243             ldr.textContent = this.leader;
244             rec_node.appendChild( ldr );
245
246             this.fields.forEach(function (f) {
247                 var element = f.isControlfield() ? 'controlfield' : 'datafield';
248                 var f_node = doc.createElementNS( 'http://www.loc.gov/MARC21/slim', element );
249                 f_node.setAttribute('tag', f.tag);
250                 
251                 if (f.isControlfield()) {
252                     if (f.data) f_node.textContent = f.data;
253                 } else {
254                     f_node.setAttribute('ind1', f.indicator(1));
255                     f_node.setAttribute('ind2', f.indicator(2));
256                     f.subfields.forEach( function (sf) {
257                         var sf_node = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'subfield');
258                         sf_node.setAttribute('code', sf[0]);
259                         sf_node.textContent = sf[1];
260                         f_node.appendChild(sf_node);
261                     });
262                 }
263
264                 rec_node.appendChild(f_node);
265             });
266
267             return doc;
268         }
269
270         this.toXmlString = function () {
271             return (new XMLSerializer()).serializeToString( this.toXmlDocument() );
272         }
273
274         this.fromBreaker = function (marctxt) {
275             var me = this;
276
277             function cf_line_data (l) { return l.substring(4) || '' };
278             function df_line_data (l) { return l.substring(6) || '' };
279             function line_tag (l) { return l.substring(0,3) };
280             function df_ind1 (l) { return l.substring(4,5).replace('\\',' ') };
281             function df_ind2 (l) { return l.substring(5,6).replace('\\',' ') };
282             function isControlField (l) {
283                 var x = line_tag(l);
284                 return (x == 'LDR' || x < '010') ? true : false;
285             }
286             
287             var lines = marctxt.replace(/^=/gm,'').split('\n');
288             lines.forEach(function (current_line, ind) {
289
290                 if (current_line.match(/^#/)) {
291                     // skip comment lines
292                 } else if (isControlField(current_line)) {
293                     if (line_tag(current_line) == 'LDR') {
294                         me.leader = cf_line_data(current_line) || '00000cam a2200205Ka 4500';
295                     } else {
296                         me.fields.push(
297                             new MARC21.Field({
298                                 record : me,
299                                 tag    : line_tag(current_line),
300                                 data   : cf_line_data(current_line).replace(/\\/g, ' ')
301                             })
302                         );
303                     }
304                 } else {
305                     if (current_line.substring(4,5) == me.delimiter) // add indicators if they were left out
306                         current_line = current_line.substring(0,3) + ' \\\\' + current_line.substring(4);
307
308                     var data = df_line_data(current_line);
309                     if (!(data.substring(0,1) == me.delimiter)) data = me.delimiter + 'a' + data;
310
311                     var local_delimiter = me.delimiter;
312                     if (data.indexOf('\u2021') > -1)
313                         local_delimiter = '\u2021';
314
315                     var sf_list = data.split(local_delimiter);
316                     sf_list.shift();
317
318                     me.fields.push(
319                         new MARC21.Field({
320                                 record    : me,
321                                 tag       : line_tag(current_line),
322                                 ind1      : df_ind1(current_line),
323                                 ind2      : df_ind2(current_line),
324                                 subfields : sf_list.map( function (sf, i) {
325                                                 var sf_data = sf.substring(1);
326                                                 if (local_delimiter == '$') sf_data = sf_data.replace(/\{dollar\}/g, '$');
327                                                 return [ sf.substring(0,1), sf_data, i ];
328                                             })
329                         })
330                     );
331                 }
332             });
333
334             for (var j = 0; j < this.fields.length; j++) {
335                 this.fields[j].position = j;
336             }
337
338             me.ready = true;
339             return this;
340         }
341
342         this.pruneEmptyFieldsAndSubfields = function() {
343             var me = this;
344             var fields_to_remove = [];
345             for (var i = 0; i < this.fields.length; i++) {
346                 var f = this.fields[i];
347                 if (f.isControlfield()) {
348                     if (!f.data){
349                         fields_to_remove.push(f);
350                     }
351                 } else {
352                     f.pruneEmptySubfields();
353                     if (f.isEmptyDatafield()) {
354                         fields_to_remove.push(f);
355                     }
356                 }
357             }
358             fields_to_remove.forEach(function(f) {
359                 me.deleteField(f);
360             });
361         }
362
363         this.toBreaker = function () {
364
365             var me = this;
366             var mtxt = '=LDR ' + this.leader + '\n';
367
368             mtxt += this.fields.map( function (f) {
369                 if (f.isControlfield()) {
370                     if (f.data) return '=' + f.tag + ' ' + f.data.replace(/ /g, '\\');
371                     return '=' + f.tag;
372                 } else {
373                     return '=' + f.tag + ' ' +
374                         f.indicator(1).replace(' ','\\') + 
375                         f.indicator(2).replace(' ','\\') + 
376                         f.subfields.map( function (sf) {
377                             var sf_data = sf[1];
378                             if (me.delimiter == '$') sf_data = sf_data.replace(/\$/g, '{dollar}');
379                             return me.delimiter + sf[0] + sf_data;
380                         }).join('');
381                 }
382             }).join('\n');
383
384             return mtxt;
385         }
386
387         this.recordType = function () {
388         
389             var _t = this.leader.substr(MARC21.Record._ff_pos.Type.ldr.BKS.start, MARC21.Record._ff_pos.Type.ldr.BKS.len);
390             var _b = this.leader.substr(MARC21.Record._ff_pos.BLvl.ldr.BKS.start, MARC21.Record._ff_pos.BLvl.ldr.BKS.len);
391         
392             for (var t in MARC21.Record._recType) {
393                 if (_t.match(MARC21.Record._recType[t].Type) && _b.match(MARC21.Record._recType[t].BLvl)) {
394                     return t;
395                 }
396             }
397             return 'BKS'; // default
398         }
399         
400         this.videorecordingFormatName = function () {
401             var _7 = this.field('007').data;
402         
403             if (_7 && _7.match(/^v/)) {
404                 var _v_e = _7.substr(
405                     MARC21.Record._physical_characteristics.v.subfields.e.start,
406                     MARC21.Record._physical_characteristics.v.subfields.e.len
407                 );
408         
409                 return MARC21.Record._physical_characteristics.v.subfields.e.values[ _v_e ];
410             }
411         
412             return null;
413         }
414         
415         this.videorecordingFormatCode = function () {
416             var _7 = this.field('007').data;
417         
418             if (_7 && _7.match(/^v/)) {
419                 return _7.substr(
420                     MARC21.Record._physical_characteristics.v.subfields.e.start,
421                     MARC21.Record._physical_characteristics.v.subfields.e.len
422                 );
423             }
424         
425             return null;
426         }
427         
428         this.extractFixedField = function (field, dflt) {
429         if (!MARC21.Record._ff_pos[field]) return null;
430         
431             var _l = this.leader;
432             var _8 = this.field('008').data;
433             var _6 = this.field('006').data;
434         
435             var rtype = this.recordType();
436         
437             var val;
438         
439             if (MARC21.Record._ff_pos[field].ldr && _l) {
440                 if (MARC21.Record._ff_pos[field].ldr[rtype]) {
441                     val = _l.substr(
442                         MARC21.Record._ff_pos[field].ldr[rtype].start,
443                         MARC21.Record._ff_pos[field].ldr[rtype].len
444                     );
445                 }
446             } else if (MARC21.Record._ff_pos[field]._8 && _8) {
447                 if (MARC21.Record._ff_pos[field]._8[rtype]) {
448                     val = _8.substr(
449                         MARC21.Record._ff_pos[field]._8[rtype].start,
450                         MARC21.Record._ff_pos[field]._8[rtype].len
451                     );
452                 }
453             }
454         
455             if (!val && MARC21.Record._ff_pos[field]._6 && _6) {
456                 if (MARC21.Record._ff_pos[field]._6[rtype]) {
457                     val = _6.substr(
458                         MARC21.Record._ff_pos[field]._6[rtype].start,
459                         MARC21.Record._ff_pos[field]._6[rtype].len
460                     );
461                 }
462             }
463     
464             if (!val && dflt) {
465                 val = '';
466                 var d;
467                 var p;
468                 if (MARC21.Record._ff_pos[field].ldr && MARC21.Record._ff_pos[field].ldr[rtype]) {
469                     d = MARC21.Record._ff_pos[field].ldr[rtype].def;
470                     p = 'ldr';
471                 }
472     
473                 if (MARC21.Record._ff_pos[field]._8 && MARC21.Record._ff_pos[field]._8[rtype]) {
474                     d = MARC21.Record._ff_pos[field]._8[rtype].def;
475                     p = '_8';
476                 }
477     
478                 if (!val && MARC21.Record._ff_pos[field]._6 && MARC21.Record._ff_pos[field]._6[rtype]) {
479                     d = MARC21.Record._ff_pos[field]._6[rtype].def;
480                     p = '_6';
481                 }
482     
483                 if (p) {
484                     for (var j = 0; j < MARC21.Record._ff_pos[field][p][rtype].len; j++) {
485                         val += d;
486                     }
487                 } else {
488                     val = null;
489                 }
490             }
491     
492             return val;
493         }
494     
495         this.setFixedField = function (field, value) {
496             if (!MARC21.Record._ff_pos[field]) return null;
497         
498             var _l = this.leader;
499             var _8 = this.field('008').data;
500             var _6 = this.field('006').data;
501         
502             var rtype = this.recordType();
503         
504             var done = false;
505             if (MARC21.Record._ff_pos[field].ldr && _l) {
506                 if (MARC21.Record._ff_pos[field].ldr[rtype]) { // It's in the leader
507                     if (value.length > MARC21.Record._ff_pos[field].ldr[rtype].len)
508                         value = value.substr(0, MARC21.Record._ff_pos[field].ldr[rtype].len);
509                     while (value.length < MARC21.Record._ff_pos[field].ldr[rtype].len)
510                         value += MARC21.Record._ff_pos[field].ldr[rtype].def;
511                     this.leader =
512                         _l.substring(0, MARC21.Record._ff_pos[field].ldr[rtype].start) +
513                         value +
514                         _l.substring(
515                             MARC21.Record._ff_pos[field].ldr[rtype].start
516                             + MARC21.Record._ff_pos[field].ldr[rtype].len
517                         );
518                     done = true;
519                 }
520             } else if (MARC21.Record._ff_pos[field]._8 && _8) {
521                 if (MARC21.Record._ff_pos[field]._8[rtype]) { // Nope, it's in the 008
522                     if (value.length > MARC21.Record._ff_pos[field]._8[rtype].len)
523                         value = value.substr(0, MARC21.Record._ff_pos[field]._8[rtype].len);
524                     while (value.length < MARC21.Record._ff_pos[field]._8[rtype].len)
525                         value += MARC21.Record._ff_pos[field]._8[rtype].def;
526
527                     // first ensure that 008 is padded to appropriate length
528                     var f008_length = (rtype in MARC21.Record._ff_lengths['008']) ?
529                         MARC21.Record._ff_lengths['008'][rtype] :
530                         MARC21.Record._ff_lengths['008']['default'];
531                     if (_8.length < f008_length) {
532                         for (var i = _8.length; i < f008_length; i++) {
533                             _8 += ' ';
534                         }
535                     }
536                     this.field('008').update(
537                         _8.substring(0, MARC21.Record._ff_pos[field]._8[rtype].start) +
538                         value +
539                         _8.substring(
540                             MARC21.Record._ff_pos[field]._8[rtype].start
541                             + MARC21.Record._ff_pos[field]._8[rtype].len
542                         )
543                     );
544                     done = true;
545                 }
546             }
547         
548             if (!done && MARC21.Record._ff_pos[field]._6 && _6) {
549                 if (MARC21.Record._ff_pos[field]._6[rtype]) { // ok, maybe the 006?
550                     if (value.length > MARC21.Record._ff_pos[field]._6[rtype].len)
551                         value = value.substr(0, MARC21.Record._ff_pos[field]._6[rtype].len);
552                     while (value.length < MARC21.Record._ff_pos[field]._6[rtype].len)
553                         value += MARC21.Record._ff_pos[field]._6[rtype].def;
554                     this.field('006').update(
555                         _6.substring(0, MARC21.Record._ff_pos[field]._6[rtype].start) +
556                         value +
557                         _6.substring(
558                             MARC21.Record._ff_pos[field]._6[rtype].start
559                             + MARC21.Record._ff_pos[field]._6[rtype].len
560                         )
561                     );
562                 }
563             }
564     
565             return value;
566         }
567
568         this.ready = false;
569         this.fields = [];
570         this.delimiter = MARC21.Record.delimiter ? MARC21.Record.delimiter : '\u2021';
571         this.leader = '00000cam a2200205Ka 4500';
572
573         if (kwargs.delimiter) this.delimiter = kwargs.delimiter;
574         if (kwargs.onLoad) this.onLoad = kwargs.onLoad;
575
576         if (kwargs.url) {
577             this.fromXmlURL(kwargs.url);
578         } else if (kwargs.marcxml) {
579             this.fromXmlString(kwargs.marcxml);
580             if (this.onLoad) this.onLoad();
581         } else if (kwargs.xml) {
582             this.fromXmlDocument(kwargs.xml);
583             if (this.onLoad) this.onLoad();
584         } else if (kwargs.marcbreaker) {
585             this.fromBreaker(kwargs.marcbreaker);
586             if (this.onLoad) this.onLoad();
587         }
588
589         if (kwargs.rtype == 'AUT') {
590             this.setFixedField('Type','z');
591         }
592
593     },
594
595     Field : function (kwargs) {
596         if (!kwargs) kwargs = {};
597
598         this.subfield = function (code, wantarray) {
599             var list = this.subfields.filter( function (s) {
600                 if (s[0] == code) return true; return false;
601             });
602             if (!wantarray && list.length == 1) return list[0];
603             return list;
604         }
605
606         this.addSubfields = function () {
607             for (var i = 0; i < arguments.length; i++) {
608                 var code = arguments[i];
609                 var value = arguments[++i];
610                 this.subfields.push( [ code, value ] );
611             }
612         }
613
614         this.deleteExactSubfields = function () {
615             var me = this;
616             var counter = 0;
617             var done = false;
618             for ( var i in arguments ) {
619                 var f = arguments[i];
620                 for (var j = 0; j < me.subfields.length; j++) {
621                     if (f === me.subfields[j]) {
622                         me.subfields.splice(j,1);
623                         counter++
624                         j++;
625                         done = true;
626                     }
627                     if (done && me.subfields[j])
628                         me.subfields[j][2] -= 1;
629                 }
630             }
631             return counter;
632         }
633
634
635         this.deleteSubfields = function (c) {
636             return this.deleteSubfield( { code : c } );
637         }
638
639         this.deleteSubfield = function (args) {
640             var me = this;
641             if (!Array.isArray( args.code )) {
642                 args.code = [ args.code ];
643             }
644
645             if (args.pos && !Array.isArray( args.pos )) {
646                 args.pos = [ args.pos ];
647             }
648
649             for (var i = 0; i < args.code.length; i++) {
650                 var sub_pos = {};
651                 for (var j = 0; j < me.subfields.length; j++) {
652                     if (me.subfields[j][0] == args.code[i]) {
653
654                         if (!sub_pos[args.code[i]]) sub_pos[args.code[j]] = 0;
655                         else sub_pos[args.code[i]]++;
656
657                         if (args.pos) {
658                             for (var k = 0; k < args.pos.length; k++) {
659                                 if (sub_pos[args.code[i]] == args.pos[k]) me.subfields.splice(j,1);
660                             }
661                         } else if (args.match && me.subfields[j][1].match( args.match )) {
662                             me.subfields.splice(j,1);
663                         } else {
664                             me.subfields.splice(j,1);
665                         }
666                     }
667                 }
668             }
669         }
670
671         this.update = function ( args ) {
672             if (this.isControlfield()) {
673                 this.data = args;
674             } else {
675                 if (args.ind1) this.ind1 = args.ind1;
676                 if (args.ind2) this.ind2 = args.ind2;
677                 if (args.tag) this.tag = args.tag;
678
679                 for (var i in args) {
680                     if (i == 'tag' || i == 'ind1' || i == 'ind2') continue;
681                     var done = 0;
682                     this.subfields.forEach( function (f) {
683                         if (!done && f[0] == i) {
684                             f[1] = args[i];
685                             done = 1;
686                         }
687                     });
688                 }
689             }
690         }
691
692         this.isControlfield = function () {
693             return this.tag < '010' ? true : false;
694         }
695
696         this.pruneEmptySubfields = function () {
697             if (this.isControlfield()) return;
698             var me = this;
699             var subfields_to_remove = [];
700             this.subfields.forEach( function(f) {
701                 if (f[1] == '') {
702                     subfields_to_remove.push(f);
703                 }
704             });
705             subfields_to_remove.forEach(function(f) {
706                 me.deleteExactSubfields(f);
707             });
708         }
709         this.isEmptyDatafield = function () {
710             if (this.isControlfield()) return false;
711             var isEmpty = true;
712             this.subfields.forEach( function(f) {
713                 if (isEmpty && f[1] != '') {
714                     isEmpty = false;
715                 }
716             });
717             return isEmpty;
718         }
719
720         this.indicator = function (num, value) {
721             if (value !== undefined) {
722                 if (num == 1) this.ind1 = value;
723                 else if (num == 2) this.ind2 = value;
724                 else { this.error = true; return null; }
725             }
726             if (num == 1) return this.ind1;
727             else if (num == 2) return this.ind2;
728             else { this.error = true; return null; }
729         }
730
731         this.error = false; 
732         this.record = null; // MARC record pointer
733         this.tag = ''; // MARC tag
734         this.ind1 = ' '; // MARC indicator 1
735         this.ind2 = ' '; // MARC indicator 2
736         this.data = ''; // MARC data for a controlfield element
737         this.subfields = []; // list of MARC subfields for a datafield element
738
739         this.position = kwargs.position;
740         this.record = kwargs.record;
741         this.tag = kwargs.tag;
742         this.ind1 = kwargs.ind1 || ' ';
743         this.ind2 = kwargs.ind2 || ' ';
744         this.data = kwargs.data;
745
746         if (kwargs.subfields) this.subfields = kwargs.subfields;
747         else this.subfields = [];
748
749     },
750
751     Batch : function(kwargs) {
752
753         this.parse = function () {
754             if (this.source instanceof Object ) { // assume an xml collection document
755                 this.source = $('record', this.source);
756                 this.type = 'xml';
757             } else if (this.source.match(/^\s*</)) { // this is xml text
758                 this.source = $.parseXML( mxml ).find('record');
759                 this.type = 'xml';
760             } else { // must be a marcbreaker doc. split on blank lines
761                 this.source = this.source.split(/^$/);
762                 this.type = 'marcbreaker';
763             }
764         }
765
766         this.fetchURL = function (u) {
767             var me = this;
768             $.get( u, function (mrc) {
769                 me.source = mrc;
770                 me.ready = true;
771             });
772         }
773
774         this.next = function () {
775             var chunk = this.source[this.current_record++];
776
777             if (chunk) {
778                 var args = {};
779                 args[this.type] = chunk;
780                 if (this.delimiter) args.delimiter = this.delimiter;
781                 return new MARC21.Record(args);
782             }
783
784             return null;
785         }
786
787         this.ready = false;
788         this.records = [];
789         this.source = kwargs.source;
790         this.delimiter = kwargs.delimiter
791         this.current_record = 0;
792
793         if (this.source) this.ready = true;
794         if (!this.ready && kwargs.url) this.fetchURL( kwargs.url );
795
796         if (this.ready) this.parse();
797
798     },
799
800     AuthorityControlSet : function (kwargs) {
801     
802         kwargs = kwargs || {};
803     
804         if (!MARC21.AuthorityControlSet._remote_loaded) {
805     
806             // TODO -- push the raw tree into the oils cache for later reuse
807     
808             // fetch everything up front...
809             this._preFetchWithFielder({
810                 "acs": "_control_set_list",
811                 "at": "_thesaurus_list",
812                 "acsaf": "_authority_field_list",
813                 "acsbf": "_bib_field_list",
814                 "aba": "_browse_axis_list",
815                 "abaafm": "_browse_field_map_list"
816             });
817     
818             MARC21.AuthorityControlSet._remote_loaded = true;
819         }
820     
821         if (MARC21.AuthorityControlSet._remote_loaded && !MARC21.AuthorityControlSet._remote_parsed) {
822     
823             MARC21.AuthorityControlSet._browse_axis_by_code = {};
824             MARC21.AuthorityControlSet._browse_axis_list.forEach(function (ba) {
825                 ba.maps(
826                     MARC21.AuthorityControlSet._browse_field_map_list.filter(
827                         function (m) { return m.axis() == ba.code() }
828                     )
829                 );
830                 MARC21.AuthorityControlSet._browse_axis_by_code[ba.code()] = ba;
831             });
832     
833             // loop over each acs
834             MARC21.AuthorityControlSet._control_set_list.forEach(function (cs) {
835                 MARC21.AuthorityControlSet._controlsets[''+cs.id()] = {
836                     id : cs.id(),
837                     name : cs.name(),
838                     description : cs.description(),
839                     authority_tag_map : {},
840                     control_map : {},
841                     bib_fields : [],
842                     raw : cs
843                 };
844     
845                 // grab the authority fields
846                 var acsaf_list = MARC21.AuthorityControlSet._authority_field_list.filter(
847                     function (af) { return af.control_set() == cs.id() }
848                 );
849     
850                 var at_list = MARC21.AuthorityControlSet._thesaurus_list.filter(
851                     function (at) { return at.control_set() == cs.id() }
852                 );
853     
854                 MARC21.AuthorityControlSet._controlsets[''+cs.id()].raw.authority_fields( acsaf_list );
855                 MARC21.AuthorityControlSet._controlsets[''+cs.id()].raw.thesauri( at_list );
856     
857                 // and loop over each
858                 acsaf_list.forEach(function (csaf) {
859                     csaf.axis_maps([]);
860     
861                     // link the main entry if we're subordinate
862                     if (csaf.main_entry()) {
863                         csaf.main_entry(
864                             acsaf_list.filter(function (x) {
865                                 return x.id() == csaf.main_entry();
866                             })[0]
867                         );
868                     }
869     
870                     // link the sub entries if we're main
871                     csaf.sub_entries(
872                         acsaf_list.filter(function (x) {
873                             return x.main_entry() == csaf.id();
874                         })
875                     );
876     
877                     // now, bib fields
878                     var acsbf_list = MARC21.AuthorityControlSet._bib_field_list.filter(
879                         function (b) { return b.authority_field() == csaf.id() }
880                     );
881                     csaf.bib_fields( acsbf_list );
882     
883                     MARC21.AuthorityControlSet._controlsets[''+cs.id()].bib_fields = [].concat(
884                         MARC21.AuthorityControlSet._controlsets[''+cs.id()].bib_fields,
885                         acsbf_list
886                     );
887     
888                     acsbf_list.forEach(function (csbf) {
889                         // link the authority field to the bib field
890                         if (csbf.authority_field()) {
891                             csbf.authority_field(
892                                 acsaf_list.filter(function (x) {
893                                     return x.id() == csbf.authority_field();
894                                 })[0]
895                             );
896                         }
897     
898                     });
899     
900                     MARC21.AuthorityControlSet._browse_axis_list.forEach(
901                         function (ba) {
902                             ba.maps().filter(
903                                 function (m) { return m.field() == csaf.id() }
904                             ).forEach(
905                                 function (fm) { fm.field( csaf ); csaf.axis_maps().push( fm ) } // and set the field
906                             )
907                         }
908                     );
909     
910                 });
911     
912                 // build the authority_tag_map
913                 MARC21.AuthorityControlSet._controlsets[''+cs.id()].bib_fields.forEach(function (bf) {
914     
915                     if (!MARC21.AuthorityControlSet._controlsets[''+cs.id()].control_map[bf.tag()])
916                         MARC21.AuthorityControlSet._controlsets[''+cs.id()].control_map[bf.tag()] = {};
917     
918                     bf.authority_field().sf_list().split('').forEach(function (sf_code) {
919     
920                         if (!MARC21.AuthorityControlSet._controlsets[''+cs.id()].control_map[bf.tag()][sf_code])
921                             MARC21.AuthorityControlSet._controlsets[''+cs.id()].control_map[bf.tag()][sf_code] = {};
922     
923                         MARC21.AuthorityControlSet._controlsets[''+cs.id()].control_map[bf.tag()][sf_code][bf.authority_field().tag()] = sf_code;
924                     });
925                 });
926     
927             });
928     
929             if (this.controlSetList().length > 0)
930                 delete MARC21.AuthorityControlSet._controlsets['-1'];
931     
932             MARC21.AuthorityControlSet._remote_parsed = true;
933         }
934     
935         this._preFetchWithFielder = function(cmap) {
936             for (var hint in cmap) {
937                 var cache_key = cmap[hint];
938                 var method = "open-ils.fielder." + hint + ".atomic";
939                 var pkey = fieldmapper.IDL.fmclasses[hint].pkey;
940     
941                 var query = {};
942                 query[pkey] = {"!=": null};
943     
944                 MARC21.AuthorityControlSet[cache_key] = dojo.map(
945                     fieldmapper.standardRequest(
946                         ["open-ils.fielder", method],
947                         [{"cache": 1, "query" : query}]
948                     ),
949                     function(h) { return new fieldmapper[hint]().fromHash(h); }
950                 );
951             }
952         }
953     
954         this.controlSetId = function (x) {
955             if (x) this._controlset = ''+x;
956             return this._controlset;
957         }
958     
959         this.controlSet = function (x) {
960             return MARC21.AuthorityControlSet._controlsets[''+this.controlSetId(x)];
961         }
962     
963         this.controlSetByThesaurusCode = function (x) {
964             var thes = MARC21.AuthorityControlSet._thesaurus_list.filter(
965                 function (at) { return at.code() == x }
966             )[0];
967     
968             return this.controlSet(thes.control_set());
969         }
970     
971         this.browseAxisByCode = function(code) {
972             return MARC21.AuthorityControlSet._browse_axis_by_code[code];
973         }
974     
975         this.bibFieldByTag = function (x) {
976             var me = this;
977             return me.controlSet().bib_fields.filter(
978                 function (bf) { if (bf.tag() == x) return true }
979             )[0];
980         }
981     
982         this.bibFields = function (x) {
983             return this.controlSet(x).bib_fields;
984         }
985     
986         this.bibFieldBrowseAxes = function (t) {
987             var blist = [];
988             for (var bcode in MARC21.AuthorityControlSet._browse_axis_by_code) {
989                 MARC21.AuthorityControlSet._browse_axis_by_code[bcode].maps().forEach(
990                     function (m) {
991                         if (m.field().bib_fields().filter(
992                                 function (b) { return b.tag() == t }
993                             ).length > 0
994                         ) blist.push(bcode);
995                     }
996                 );
997             }
998             return blist;
999         }
1000     
1001         this.authorityFields = function (x) {
1002             return this.controlSet(x).raw.authority_fields();
1003         }
1004     
1005         this.thesauri = function (x) {
1006             return this.controlSet(x).raw.thesauri();
1007         }
1008     
1009         this.controlSetList = function () {
1010             var l = [];
1011             for (var i in MARC21.AuthorityControlSet._controlsets) {
1012                 l.push(i);
1013             }
1014             return l;
1015         }
1016     
1017         this.findControlSetsForTag = function (tag) {
1018             var me = this;
1019             var old_acs = this.controlSetId();
1020             var acs_list = me.controlSetList().filter(
1021                 function(acs_id) { return (me.controlSet(acs_id).control_map[tag]) }
1022             );
1023             this.controlSetId(old_acs);
1024             return acs_list;
1025         }
1026     
1027         this.findControlSetsForAuthorityTag = function (tag) {
1028             var me = this;
1029             var old_acs = this.controlSetId();
1030     
1031             var acs_list = me.controlSetList().filter(
1032                 function(acs_id) {
1033                     var a = me.controlSet(acs_id);
1034                     for (var btag in a.control_map) {
1035                         for (var sf in a.control_map[btag]) {
1036                             if (a.control_map[btag][sf][tag]) return true;
1037                         }
1038                     }
1039                     return false;
1040                 }
1041             );
1042             this.controlSetId(old_acs);
1043             return acs_list;
1044         }
1045     
1046         this.bibToAuthority = function (field) {
1047             var b_field = this.bibFieldByTag(field.tag);
1048     
1049             if (b_field) { // construct an marc authority record
1050                 var af = b_field.authority_field();
1051     
1052                 var sflist = [];                
1053                 for (var i = 0; i < field.subfields.length; i++) {
1054                     if (af.sf_list().indexOf(field.subfields[i][0]) > -1) {
1055                         sflist.push(field.subfields[i]);
1056                     }
1057                 }
1058     
1059                 var m = new MARC21.Record ({rtype:'AUT'});
1060                 m.appendFields(
1061                     new MARC21.Field ({
1062                         tag : af.tag(),
1063                         ind1: field.ind1,
1064                         ind2: field.ind2,
1065                         subfields: sflist
1066                     })
1067                 );
1068     
1069                 return m.toXmlString();
1070             }
1071     
1072             return null;
1073         }
1074     
1075         this.bibToAuthorities = function (field) {
1076             var auth_list = [];
1077             var me = this;
1078     
1079             var old_acs = this.controlSetId();
1080             me.controlSetList().forEach(
1081                 function (acs_id) {
1082                     var acs = me.controlSet(acs_id);
1083                     var x = me.bibToAuthority(field);
1084                     if (x) { var foo = {}; foo[acs_id] = x; auth_list.push(foo); }
1085                 }
1086             );
1087             this.controlSetId(old_acs);
1088     
1089             return auth_list;
1090         }
1091     
1092         // This should not be used in an angular world.  Instead, the call
1093         // to open-ils.search.authority.simple_heading.from_xml.batch.atomic should
1094         // be performed by the code that wants to find matching authorities.
1095         this.findMatchingAuthorities = function (field) {
1096             return fieldmapper.standardRequest(
1097                 [ 'open-ils.search', 'open-ils.search.authority.simple_heading.from_xml.batch.atomic' ],
1098                 this.bibToAuthorities(field)
1099             );
1100         }
1101     
1102         if (kwargs.controlSet) {
1103             this.controlSetId( kwargs.controlSet );
1104         } else {
1105             this.controlSetId( this.controlSetList().sort(function(a,b){return (a - b)}) );
1106         }
1107     
1108     }
1109 };
1110
1111 MARC21.Record._recType = {
1112     BKS : { Type : /[at]{1}/,    BLvl : /[acdm]{1}/ },
1113     SER : { Type : /[a]{1}/,    BLvl : /[bsi]{1}/ },
1114     VIS : { Type : /[gkro]{1}/,    BLvl : /[abcdmsi]{1}/ },
1115     MIX : { Type : /[p]{1}/,    BLvl : /[cdi]{1}/ },
1116     MAP : { Type : /[ef]{1}/,    BLvl : /[abcdmsi]{1}/ },
1117     SCO : { Type : /[cd]{1}/,    BLvl : /[abcdmsi]{1}/ },
1118     REC : { Type : /[ij]{1}/,    BLvl : /[abcdmsi]{1}/ },
1119     COM : { Type : /[m]{1}/,    BLvl : /[abcdmsi]{1}/ },
1120     AUT : { Type : /[z]{1}/,    BLvl : /.{1}/ },
1121     MFHD : { Type : /[uvxy]{1}/,  BLvl : /.{1}/ }
1122 };
1123
1124 MARC21.Record._ff_lengths = {
1125     '008' : {
1126         default : 40,
1127         MFHD    : 32
1128     }
1129 }
1130
1131 MARC21.Record._ff_pos = {
1132     AccM : {
1133         _8 : {
1134             SCO : {start: 24, len : 6, def : ' ' },
1135             REC : {start: 24, len : 6, def : ' ' }
1136         },
1137         _6 : {
1138             SCO : {start: 7, len : 6, def : ' ' },
1139             REC : {start: 7, len : 6, def : ' ' }
1140         }
1141     },
1142     Alph : {
1143         _8 : {
1144             SER : {start : 33, len : 1, def : ' ' }
1145         },
1146         _6 : {
1147             SER : {start : 16, len : 1, def : ' ' }
1148         }
1149     },
1150     Audn : {
1151         _8 : {
1152             BKS : {start : 22, len : 1, def : ' ' },
1153             SER : {start : 22, len : 1, def : ' ' },
1154             VIS : {start : 22, len : 1, def : ' ' },
1155             SCO : {start : 22, len : 1, def : ' ' },
1156             REC : {start : 22, len : 1, def : ' ' },
1157             COM : {start : 22, len : 1, def : ' ' }
1158         },
1159         _6 : {
1160             BKS : {start : 5, len : 1, def : ' ' },
1161             SER : {start : 5, len : 1, def : ' ' },
1162             VIS : {start : 5, len : 1, def : ' ' },
1163             SCO : {start : 5, len : 1, def : ' ' },
1164             REC : {start : 5, len : 1, def : ' ' },
1165             COM : {start : 5, len : 1, def : ' ' }
1166         }
1167     },
1168     Biog : {
1169         _8 : {
1170             BKS : {start : 34, len : 1, def : ' ' }
1171         },
1172         _6 : {
1173             BKS : {start : 17, len : 1, def : ' ' }
1174         }
1175     },
1176     BLvl : {
1177         ldr : {
1178             BKS : {start : 7, len : 1, def : 'm' },
1179             SER : {start : 7, len : 1, def : 's' },
1180             VIS : {start : 7, len : 1, def : 'm' },
1181             MIX : {start : 7, len : 1, def : 'c' },
1182             MAP : {start : 7, len : 1, def : 'm' },
1183             SCO : {start : 7, len : 1, def : 'm' },
1184             REC : {start : 7, len : 1, def : 'm' },
1185             COM : {start : 7, len : 1, def : 'm' }
1186         }
1187     },
1188     Comp : {
1189         _8 : {
1190             SCO : {start : 18, len : 2, def : 'uu'},
1191             REC : {start : 18, len : 2, def : 'uu'}
1192         },
1193         _6 : {
1194             SCO : {start : 1, len : 2, def : 'uu'},
1195             REC : {start : 1, len : 2, def : 'uu'}
1196         },
1197     },
1198     Conf : {
1199         _8 : {
1200             BKS : {start : 29, len : 1, def : '0' },
1201             SER : {start : 29, len : 1, def : '0' }
1202         },
1203         _6 : {
1204             BKS : {start : 11, len : 1, def : '0' },
1205             SER : {start : 11, len : 1, def : '0' }
1206         }
1207     },
1208     Cont : {
1209         _8 : {
1210             BKS : {start : 24, len : 4, def : ' ' },
1211             SER : {start : 25, len : 3, def : ' ' }
1212         },
1213         _6 : {
1214             BKS : {start : 7, len : 4, def : ' ' },
1215             SER : {start : 8, len : 3, def : ' ' }
1216         }
1217     },
1218     CrTp : {
1219         _8 : {
1220             MAP : {start: 25, len : 1, def : 'a' }
1221         },
1222         _6 : { 
1223             MAP : {start : 8, len : 1, def : 'a' }
1224         }
1225     },
1226     Ctrl : {
1227         ldr : {
1228             BKS : {start : 8, len : 1, def : ' ' },
1229             SER : {start : 8, len : 1, def : ' ' },
1230             VIS : {start : 8, len : 1, def : ' ' },
1231             MIX : {start : 8, len : 1, def : ' ' },
1232             MAP : {start : 8, len : 1, def : ' ' },
1233             SCO : {start : 8, len : 1, def : ' ' },
1234             REC : {start : 8, len : 1, def : ' ' },
1235             COM : {start : 8, len : 1, def : ' ' }
1236         }
1237     },
1238     Ctry : {
1239             _8 : {
1240                 BKS : {start : 15, len : 3, def : ' ' },
1241                 SER : {start : 15, len : 3, def : ' ' },
1242                 VIS : {start : 15, len : 3, def : ' ' },
1243                 MIX : {start : 15, len : 3, def : ' ' },
1244                 MAP : {start : 15, len : 3, def : ' ' },
1245                 SCO : {start : 15, len : 3, def : ' ' },
1246                 REC : {start : 15, len : 3, def : ' ' },
1247                 COM : {start : 15, len : 3, def : ' ' }
1248             }
1249         },
1250     Date1 : {
1251         _8 : {
1252             BKS : {start : 7, len : 4, def : ' ' },
1253             SER : {start : 7, len : 4, def : ' ' },
1254             VIS : {start : 7, len : 4, def : ' ' },
1255             MIX : {start : 7, len : 4, def : ' ' },
1256             MAP : {start : 7, len : 4, def : ' ' },
1257             SCO : {start : 7, len : 4, def : ' ' },
1258             REC : {start : 7, len : 4, def : ' ' },
1259             COM : {start : 7, len : 4, def : ' ' }
1260         }
1261     },
1262     Date2 : {
1263         _8 : {
1264             BKS : {start : 11, len : 4, def : ' ' },
1265             SER : {start : 11, len : 4, def : '9' },
1266             VIS : {start : 11, len : 4, def : ' ' },
1267             MIX : {start : 11, len : 4, def : ' ' },
1268             MAP : {start : 11, len : 4, def : ' ' },
1269             SCO : {start : 11, len : 4, def : ' ' },
1270             REC : {start : 11, len : 4, def : ' ' },
1271             COM : {start : 11, len : 4, def : ' ' }
1272         }
1273     },
1274     Desc : {
1275         ldr : {
1276             BKS : {start : 18, len : 1, def : ' ' },
1277             SER : {start : 18, len : 1, def : ' ' },
1278             VIS : {start : 18, len : 1, def : ' ' },
1279             MIX : {start : 18, len : 1, def : ' ' },
1280             MAP : {start : 18, len : 1, def : ' ' },
1281             SCO : {start : 18, len : 1, def : ' ' },
1282             REC : {start : 18, len : 1, def : ' ' },
1283             COM : {start : 18, len : 1, def : ' ' }
1284         }
1285     },
1286     DtSt : {
1287         _8 : {
1288             BKS : {start : 6, len : 1, def : ' ' },
1289             SER : {start : 6, len : 1, def : 'c' },
1290             VIS : {start : 6, len : 1, def : ' ' },
1291             MIX : {start : 6, len : 1, def : ' ' },
1292             MAP : {start : 6, len : 1, def : ' ' },
1293             SCO : {start : 6, len : 1, def : ' ' },
1294             REC : {start : 6, len : 1, def : ' ' },
1295             COM : {start : 6, len : 1, def : ' ' }
1296         }
1297     },
1298     ELvl : {
1299         ldr : {
1300             BKS : {start : 17, len : 1, def : ' ' },
1301             SER : {start : 17, len : 1, def : ' ' },
1302             VIS : {start : 17, len : 1, def : ' ' },
1303             MIX : {start : 17, len : 1, def : ' ' },
1304             MAP : {start : 17, len : 1, def : ' ' },
1305             SCO : {start : 17, len : 1, def : ' ' },
1306             REC : {start : 17, len : 1, def : ' ' },
1307             COM : {start : 17, len : 1, def : ' ' },
1308             AUT : {start : 17, len : 1, def : 'n' },
1309             MFHD : {start : 17, len : 1, def : 'u' }
1310         }
1311     },
1312     EntW : {
1313         _8 : {
1314             SER : {start : 24, len : 1, def : ' '}
1315         },
1316         _6 : {
1317             SER : {start : 7, len : 1, def : ' '}
1318         }
1319     },
1320     Fest : {
1321         _8 : {
1322             BKS : {start : 30, len : 1, def : '0' }
1323         },
1324         _6 : {
1325             BKS : {start : 13, len : 1, def : '0' }
1326         }
1327     },
1328     File : {
1329         _8 : {
1330             COM : {start: 26, len : 1, def : 'u' }
1331         },
1332         _6 : {
1333             COM : {start: 9, len : 1, def : 'u' }
1334         }
1335     },
1336     FMus : {
1337         _8 : {
1338             SCO : {start : 20, len : 1, def : 'u'},
1339             REC : {start : 20, len : 1, def : 'n'}
1340         },
1341         _6 : {
1342             SCO : {start : 3, len : 1, def : 'u'},
1343             REC : {start : 3, len : 1, def : 'n'}
1344         },
1345     },
1346     Form : {
1347         _8 : {
1348             BKS : {start : 23, len : 1, def : ' ' },
1349             SER : {start : 23, len : 1, def : ' ' },
1350             VIS : {start : 29, len : 1, def : ' ' },
1351             MIX : {start : 23, len : 1, def : ' ' },
1352             MAP : {start : 29, len : 1, def : ' ' },
1353             SCO : {start : 23, len : 1, def : ' ' },
1354             REC : {start : 23, len : 1, def : ' ' },
1355             COM : {start : 23, len : 1, def : ' ' }
1356         },
1357         _6 : {
1358             BKS : {start : 6, len : 1, def : ' ' },
1359             SER : {start : 6, len : 1, def : ' ' },
1360             VIS : {start : 12, len : 1, def : ' ' },
1361             MIX : {start : 6, len : 1, def : ' ' },
1362             MAP : {start : 12, len : 1, def : ' ' },
1363             SCO : {start : 6, len : 1, def : ' ' },
1364             REC : {start : 6, len : 1, def : ' ' },
1365             COM : {start : 6, len : 1, def : ' ' }
1366         }
1367     },
1368     Freq : {
1369         _8 : {
1370             SER : {start : 18, len : 1, def : ' '}
1371         },
1372         _6 : {
1373             SER : {start : 1, len : 1, def : ' '}
1374         }
1375     },
1376     GPub : {
1377         _8 : {
1378             BKS : {start : 28, len : 1, def : ' ' },
1379             SER : {start : 28, len : 1, def : ' ' },
1380             VIS : {start : 28, len : 1, def : ' ' },
1381             MAP : {start : 28, len : 1, def : ' ' },
1382             COM : {start : 28, len : 1, def : ' ' }
1383         },
1384         _6 : {
1385             BKS : {start : 11, len : 1, def : ' ' },
1386             SER : {start : 11, len : 1, def : ' ' },
1387             VIS : {start : 11, len : 1, def : ' ' },
1388             MAP : {start : 11, len : 1, def : ' ' },
1389             COM : {start : 11, len : 1, def : ' ' }
1390         }
1391     },
1392     Ills : {
1393         _8 : {
1394             BKS : {start : 18, len : 4, def : ' ' }
1395         },
1396         _6 : {
1397             BKS : {start : 1, len : 4, def : ' ' }
1398         }
1399     },
1400     Indx : {
1401         _8 : {
1402             BKS : {start : 31, len : 1, def : '0' },
1403             MAP : {start : 31, len : 1, def : '0' }
1404         },
1405         _6 : {
1406             BKS : {start : 14, len : 1, def : '0' },
1407             MAP : {start : 14, len : 1, def : '0' }
1408         }
1409     },
1410     Item : {
1411         ldr : {
1412             MFHD : {start : 18, len : 1, def : 'i' }
1413         }
1414     },
1415     Lang : {
1416         _8 : {
1417             BKS : {start : 35, len : 3, def : ' ' },
1418             SER : {start : 35, len : 3, def : ' ' },
1419             VIS : {start : 35, len : 3, def : ' ' },
1420             MIX : {start : 35, len : 3, def : ' ' },
1421             MAP : {start : 35, len : 3, def : ' ' },
1422             SCO : {start : 35, len : 3, def : ' ' },
1423             REC : {start : 35, len : 3, def : ' ' },
1424             COM : {start : 35, len : 3, def : ' ' }
1425         }
1426     },
1427     LitF : {
1428         _8 : {
1429             BKS : {start : 33, len : 1, def : '0' }
1430         },
1431         _6 : {
1432             BKS : {start : 16, len : 1, def : '0' }
1433         }
1434     },
1435     LTxt : {
1436         _8 : {
1437             SCO : {start : 30, len : 2, def : 'n'},
1438             REC : {start : 30, len : 2, def : ' '}
1439         },
1440         _6 : {
1441             SCO : {start : 13, len : 2, def : 'n'},
1442             REC : {start : 13, len : 2, def : ' '}
1443         },
1444     },
1445     MRec : {
1446         _8 : {
1447             BKS : {start : 38, len : 1, def : ' ' },
1448             SER : {start : 38, len : 1, def : ' ' },
1449             VIS : {start : 38, len : 1, def : ' ' },
1450             MIX : {start : 38, len : 1, def : ' ' },
1451             MAP : {start : 38, len : 1, def : ' ' },
1452             SCO : {start : 38, len : 1, def : ' ' },
1453             REC : {start : 38, len : 1, def : ' ' },
1454             COM : {start : 38, len : 1, def : ' ' }
1455         }
1456     },
1457     Orig : {
1458         _8 : {
1459             SER : {start : 22, len : 1, def : ' '}
1460         },
1461         _6 : {
1462             SER : {start: 5, len : 1, def: ' '}
1463         }
1464     },
1465     Part : {
1466         _8 : {
1467             SCO : {start : 21, len : 1, def : ' '},
1468             REC : {start : 21, len : 1, def : 'n'}
1469         },
1470         _6 : {
1471             SCO : {start : 4, len : 1, def : ' '},
1472             REC : {start : 4, len : 1, def : 'n'}
1473         },
1474     },
1475     Proj : {
1476         _8 : {
1477             MAP : {start : 22, len : 2, def : ' ' }
1478         },
1479         _6 : {
1480             MAP: {start : 5, len : 2, def : ' ' }
1481         }
1482     },
1483     RecStat : {
1484         ldr : {
1485             BKS : {start : 5, len : 1, def : 'n' },
1486             SER : {start : 5, len : 1, def : 'n' },
1487             VIS : {start : 5, len : 1, def : 'n' },
1488             MIX : {start : 5, len : 1, def : 'n' },
1489             MAP : {start : 5, len : 1, def : 'n' },
1490             SCO : {start : 5, len : 1, def : 'n' },
1491             REC : {start : 5, len : 1, def : 'n' },
1492             COM : {start : 5, len : 1, def : 'n' },
1493             MFHD: {start : 5, len : 1, def : 'n' },
1494             AUT : {start : 5, len : 1, def : 'n' }
1495         }
1496     },
1497     Regl : {
1498         _8 : {
1499             SER : {start : 19, len : 1, def : ' '}
1500         },
1501         _6 : {
1502             SER : {start : 2, len : 1, def : ' '}
1503         }
1504     },
1505     Relf : {
1506         _8 : {
1507             MAP : {start: 18, len : 4, def : ' '}
1508         },
1509         _6 : {
1510             MAP : {start: 1, len : 4, def : ' '}
1511         }
1512     },
1513     'S/L' : {
1514         _8 : {
1515             SER : {start : 34, len : 1, def : '0' }
1516         },
1517         _6 : {
1518             SER : {start : 17, len : 1, def : '0' }
1519         }
1520     },
1521     SpFM : {
1522         _8 : {
1523             MAP : {start: 33, len : 2, def : ' ' }
1524         },
1525         _6 : {
1526             MAP : {start: 16, len : 2, def : ' '}
1527         }
1528     },
1529     Srce : {
1530         _8 : {
1531             BKS : {start : 39, len : 1, def : 'd' },
1532             SER : {start : 39, len : 1, def : 'd' },
1533             VIS : {start : 39, len : 1, def : 'd' },
1534             SCO : {start : 39, len : 1, def : 'd' },
1535             REC : {start : 39, len : 1, def : 'd' },
1536             COM : {start : 39, len : 1, def : 'd' },
1537             MFHD : {start : 39, len : 1, def : 'd' },
1538             "AUT" : {"start" : 39, "len" : 1, "def" : 'd' }
1539         }
1540     },
1541     SrTp : {
1542         _8 : {
1543             SER : {start : 21, len : 1, def : ' '}
1544         },
1545         _6 : {
1546             SER : {start : 4, len : 1, def : ' '}
1547         }
1548     },
1549     Tech : {
1550         _8 : {
1551             VIS : {start : 34, len : 1, def : ' '}
1552         },
1553         _6 : {
1554             VIS : {start : 17, len : 1, def : ' '}
1555         }
1556     },
1557     Time : {
1558         _8 : {
1559             VIS : {start : 18, len : 3, def : ' '}
1560         },
1561         _6 : {
1562             VIS : {start : 1, len : 3, def : ' '}
1563         }
1564     },
1565     TMat : {
1566         _8 : {
1567             VIS : {start : 33, len : 1, def : ' ' }
1568         },
1569         _6 : {
1570             VIS : {start : 16, len : 1, def : ' ' }
1571         }
1572     },
1573     TrAr : {
1574         _8 : {
1575             SCO : {start : 33, len : 1, def : ' ' },
1576             REC : {start : 33, len : 1, def : 'n' }
1577         },
1578         _6 : {
1579             SCO : {start : 16, len : 1, def : ' ' },
1580             REC : {start : 16, len : 1, def : 'n' }
1581         }
1582     },
1583     Type : {
1584         ldr : {
1585             BKS : {start : 6, len : 1, def : 'a' },
1586             SER : {start : 6, len : 1, def : 'a' },
1587             VIS : {start : 6, len : 1, def : 'g' },
1588             MIX : {start : 6, len : 1, def : 'p' },
1589             MAP : {start : 6, len : 1, def : 'e' },
1590             SCO : {start : 6, len : 1, def : 'c' },
1591             REC : {start : 6, len : 1, def : 'i' },
1592             COM : {start : 6, len : 1, def : 'm' },
1593             AUT : {start : 6, len : 1, def : 'z' },
1594             MFHD : {start : 6, len : 1, def : 'y' }
1595         }
1596     },
1597     "GeoDiv" : {
1598          "_8" : {
1599              "AUT" : {"start" : 6, "len" : 1, "def" : ' ' }
1600          }
1601      },
1602      "Roman" : {
1603          "_8" : {
1604              "AUT" : {"start" : 7, "len" : 1, "def" : ' ' }
1605          }
1606      },
1607      "CatLang" : {
1608          "_8" : {
1609              "AUT" : {"start" : 8, "len" : 1, "def" : ' ' }
1610          }
1611      },
1612      "Kind" : {
1613          "_8" : {
1614              "AUT" : {"start" : 9, "len" : 1, "def" : ' ' }
1615          }
1616      },
1617      "Rules" : {
1618          "_8" : {
1619              "AUT" : {"start" : 10, "len" : 1, "def" : ' ' }
1620          }
1621      },
1622      "Subj" : {
1623          "_8" : {
1624              "AUT" : {"start" : 11, "len" : 1, "def" : ' ' }
1625          }
1626      },
1627      "Series" : {
1628          "_8" : {
1629              "AUT" : {"start" : 12, "len" : 1, "def" : ' ' }
1630          }
1631      },
1632      "SerNum" : {
1633          "_8" : {
1634              "AUT" : {"start" : 13, "len" : 1, "def" : ' ' }
1635          }
1636      },
1637      "NameUse" : {
1638          "_8" : {
1639              "AUT" : {"start" : 14, "len" : 1, "def" : ' ' }
1640          }
1641      },
1642      "SubjUse" : {
1643          "_8" : {
1644              "AUT" : {"start" : 15, "len" : 1, "def" : ' ' }
1645          }
1646      },
1647      "SerUse" : {
1648          "_8" : {
1649              "AUT" : {"start" : 16, "len" : 1, "def" : ' ' }
1650          }
1651      },
1652      "TypeSubd" : {
1653          "_8" : {
1654              "AUT" : {"start" : 17, "len" : 1, "def" : ' ' }
1655          }
1656      },
1657      "GovtAgn" : {
1658          "_8" : {
1659              "AUT" : {"start" : 28, "len" : 1, "def" : ' ' }
1660          }
1661      },
1662      "RefStatus" : {
1663          "_8" : {
1664              "AUT" : {"start" : 29, "len" : 1, "def" : ' ' }
1665          }
1666      },
1667      "UpdStatus" : {
1668          "_8" : {
1669              "AUT" : {"start" : 31, "len" : 1, "def" : ' ' }
1670          }
1671      },
1672      "Name" : {
1673          "_8" : {
1674              "AUT" : {"start" : 32, "len" : 1, "def" : ' ' }
1675          }
1676      },
1677      "Status" : {
1678          "_8" : {
1679              "AUT" : {"start" : 33, "len" : 1, "def" : ' ' }
1680          }
1681      },
1682      "ModRec" : {
1683          "_8" : {
1684              "AUT" : {"start" : 38, "len" : 1, "def" : ' ' }
1685          }
1686      },
1687      "Source" : {
1688          "_8" : {
1689              "AUT" : {"start" : 39, "len" : 1, "def" : ' ' }
1690          }
1691      }
1692 };
1693
1694 MARC21.Record._physical_characteristics = {
1695     c : {
1696         label     : "Electronic Resource",
1697         subfields : {
1698             b : {    start : 1,
1699                 len   : 1,
1700                 label : "SMD",
1701                 values: {    a : "Tape Cartridge",
1702                         b : "Chip cartridge",
1703                         c : "Computer optical disk cartridge",
1704                         f : "Tape cassette",
1705                         h : "Tape reel",
1706                         j : "Magnetic disk",
1707                         m : "Magneto-optical disk",
1708                         o : "Optical disk",
1709                         r : "Remote",
1710                         u : "Unspecified",
1711                         z : "Other"
1712                 }
1713             },
1714             d : {    start : 3,
1715                 len   : 1,
1716                 label : "Color",
1717                 values: {    a : "One color",
1718                         b : "Black-and-white",
1719                         c : "Multicolored",
1720                         g : "Gray scale",
1721                         m : "Mixed",
1722                         n : "Not applicable",
1723                         u : "Unknown",
1724                         z : "Other"
1725                 }
1726             },
1727             e : {    start : 4,
1728                 len   : 1,
1729                 label : "Dimensions",
1730                 values: {    a : "3 1/2 in.",
1731                         e : "12 in.",
1732                         g : "4 3/4 in. or 12 cm.",
1733                         i : "1 1/8 x 2 3/8 in.",
1734                         j : "3 7/8 x 2 1/2 in.",
1735                         n : "Not applicable",
1736                         o : "5 1/4 in.",
1737                         u : "Unknown",
1738                         v : "8 in.",
1739                         z : "Other"
1740                 }
1741             },
1742             f : {    start : 5,
1743                 len   : 1,
1744                 label : "Sound",
1745                 values: {    ' ' : "No sound (Silent)",
1746                         a   : "Sound",
1747                         u   : "Unknown"
1748                 }
1749             },
1750             g : {    start : 6,
1751                 len   : 3,
1752                 label : "Image bit depth",
1753                 values: {    mmm   : "Multiple",
1754                         nnn   : "Not applicable",
1755                         '---' : "Unknown"
1756                 }
1757             },
1758             h : {    start : 9,
1759                 len   : 1,
1760                 label : "File formats",
1761                 values: {    a : "One file format",
1762                         m : "Multiple file formats",
1763                         u : "Unknown"
1764                 }
1765             },
1766             i : {    start : 10,
1767                 len   : 1,
1768                 label : "Quality assurance target(s)",
1769                 values: {    a : "Absent",
1770                         n : "Not applicable",
1771                         p : "Present",
1772                         u : "Unknown"
1773                 }
1774             },
1775             j : {    start : 11,
1776                 len   : 1,
1777                 label : "Antecedent/Source",
1778                 values: {    a : "File reproduced from original",
1779                         b : "File reproduced from microform",
1780                         c : "File reproduced from electronic resource",
1781                         d : "File reproduced from an intermediate (not microform)",
1782                         m : "Mixed",
1783                         n : "Not applicable",
1784                         u : "Unknown"
1785                 }
1786             },
1787             k : {    start : 12,
1788                 len   : 1,
1789                 label : "Level of compression",
1790                 values: {    a : "Uncompressed",
1791                         b : "Lossless",
1792                         d : "Lossy",
1793                         m : "Mixed",
1794                         u : "Unknown"
1795                 }
1796             },
1797             l : {    start : 13,
1798                 len   : 1,
1799                 label : "Reformatting quality",
1800                 values: {    a : "Access",
1801                         n : "Not applicable",
1802                         p : "Preservation",
1803                         r : "Replacement",
1804                         u : "Unknown"
1805                 }
1806             }
1807         }
1808     },
1809     d : {
1810         label     : "Globe",
1811         subfields : {
1812             b : {    start : 1,
1813                 len   : 1,
1814                 label : "SMD",
1815                 values: {    a : "Celestial globe",
1816                         b : "Planetary or lunar globe",
1817                         c : "Terrestrial globe",
1818                         e : "Earth moon globe",
1819                         u : "Unspecified",
1820                         z : "Other"
1821                 }
1822             },
1823             d : {    start : 3,
1824                 len   : 1,
1825                 label : "Color",
1826                 values: {    a : "One color",
1827                         c : "Multicolored"
1828                 }
1829             },
1830             e : {    start : 4,
1831                 len   : 1,
1832                 label : "Physical medium",
1833                 values: {    a : "Paper",
1834                         b : "Wood",
1835                         c : "Stone",
1836                         d : "Metal",
1837                         e : "Synthetics",
1838                         f : "Skins",
1839                         g : "Textile",
1840                         p : "Plaster",
1841                         u : "Unknown",
1842                         z : "Other"
1843                 }
1844             },
1845             f : {    start : 5,
1846                 len   : 1,
1847                 label : "Type of reproduction",
1848                 values: {    f : "Facsimile",
1849                         n : "Not applicable",
1850                         u : "Unknown",
1851                         z : "Other"
1852                 }
1853             }
1854         }
1855     },
1856     a : {
1857         label     : "Map",
1858         subfields : {
1859             b : {    start : 1,
1860                 len   : 1,
1861                 label : "SMD",
1862                 values: {    d : "Atlas",
1863                         g : "Diagram",
1864                         j : "Map",
1865                         k : "Profile",
1866                         q : "Model",
1867                         r : "Remote-sensing image",
1868                         s : "Section",
1869                         u : "Unspecified",
1870                         y : "View",
1871                         z : "Other"
1872                 }
1873             },
1874             d : {    start : 3,
1875                 len   : 1,
1876                 label : "Color",
1877                 values: {    a : "One color",
1878                         c : "Multicolored"
1879                 }
1880             },
1881             e : {    start : 4,
1882                 len   : 1,
1883                 label : "Physical medium",
1884                 values: {    a : "Paper",
1885                         b : "Wood",
1886                         c : "Stone",
1887                         d : "Metal",
1888                         e : "Synthetics",
1889                         f : "Skins",
1890                         g : "Textile",
1891                         p : "Plaster",
1892                         q : "Flexible base photographic medium, positive",
1893                         r : "Flexible base photographic medium, negative",
1894                         s : "Non-flexible base photographic medium, positive",
1895                         t : "Non-flexible base photographic medium, negative",
1896                         u : "Unknown",
1897                         y : "Other photographic medium",
1898                         z : "Other"
1899                 }
1900             },
1901             f : {    start : 5,
1902                 len   : 1,
1903                 label : "Type of reproduction",
1904                 values: {    f : "Facsimile",
1905                         n : "Not applicable",
1906                         u : "Unknown",
1907                         z : "Other"
1908                 }
1909             },
1910             g : {    start : 6,
1911                 len   : 1,
1912                 label : "Production/reproduction details",
1913                 values: {    a : "Photocopy, blueline print",
1914                         b : "Photocopy",
1915                         c : "Pre-production",
1916                         d : "Film",
1917                         u : "Unknown",
1918                         z : "Other"
1919                 }
1920             },
1921             h : {    start : 7,
1922                 len   : 1,
1923                 label : "Positive/negative",
1924                 values: {    a : "Positive",
1925                         b : "Negative",
1926                         m : "Mixed",
1927                         n : "Not applicable"
1928                 }
1929             }
1930         }
1931     },
1932     h : {
1933         label     : "Microform",
1934         subfields : {
1935             b : {    start : 1,
1936                 len   : 1,
1937                 label : "SMD",
1938                 values: {    a : "Aperture card",
1939                         b : "Microfilm cartridge",
1940                         c : "Microfilm cassette",
1941                         d : "Microfilm reel",
1942                         e : "Microfiche",
1943                         f : "Microfiche cassette",
1944                         g : "Microopaque",
1945                         u : "Unspecified",
1946                         z : "Other"
1947                 }
1948             },
1949             d : {    start : 3,
1950                 len   : 1,
1951                 label : "Positive/negative",
1952                 values: {    a : "Positive",
1953                         b : "Negative",
1954                         m : "Mixed",
1955                         u : "Unknown"
1956                 }
1957             },
1958             e : {    start : 4,
1959                 len   : 1,
1960                 label : "Dimensions",
1961                 values: {    a : "8 mm.",
1962                         e : "16 mm.",
1963                         f : "35 mm.",
1964                         g : "70mm.",
1965                         h : "105 mm.",
1966                         l : "3 x 5 in. (8 x 13 cm.)",
1967                         m : "4 x 6 in. (11 x 15 cm.)",
1968                         o : "6 x 9 in. (16 x 23 cm.)",
1969                         p : "3 1/4 x 7 3/8 in. (9 x 19 cm.)",
1970                         u : "Unknown",
1971                         z : "Other"
1972                 }
1973             },
1974             f : {    start : 5,
1975                 len   : 4,
1976                 label : "Reduction ratio range/Reduction ratio",
1977                 values: {    a : "Low (1-16x)",
1978                         b : "Normal (16-30x)",
1979                         c : "High (31-60x)",
1980                         d : "Very high (61-90x)",
1981                         e : "Ultra (90x-)",
1982                         u : "Unknown",
1983                         v : "Reduction ratio varies"
1984                 }
1985             },
1986             g : {    start : 9,
1987                 len   : 1,
1988                 label : "Color",
1989                 values: {    b : "Black-and-white",
1990                         c : "Multicolored",
1991                         m : "Mixed",
1992                         u : "Unknown",
1993                         z : "Other"
1994                 }
1995             },
1996             h : {    start : 10,
1997                 len   : 1,
1998                 label : "Emulsion on film",
1999                 values: {    a : "Silver halide",
2000                         b : "Diazo",
2001                         c : "Vesicular",
2002                         m : "Mixed",
2003                         n : "Not applicable",
2004                         u : "Unknown",
2005                         z : "Other"
2006                 }
2007             },
2008             i : {    start : 11,
2009                 len   : 1,
2010                 label : "Quality assurance target(s)",
2011                 values: {    a : "1st gen. master",
2012                         b : "Printing master",
2013                         c : "Service copy",
2014                         m : "Mixed generation",
2015                         u : "Unknown"
2016                 }
2017             },
2018             j : {    start : 12,
2019                 len   : 1,
2020                 label : "Base of film",
2021                 values: {    a : "Safety base, undetermined",
2022                         c : "Safety base, acetate undetermined",
2023                         d : "Safety base, diacetate",
2024                         l : "Nitrate base",
2025                         m : "Mixed base",
2026                         n : "Not applicable",
2027                         p : "Safety base, polyester",
2028                         r : "Safety base, mixed",
2029                         t : "Safety base, triacetate",
2030                         u : "Unknown",
2031                         z : "Other"
2032                 }
2033             }
2034         }
2035     },
2036     m : {
2037         label     : "Motion Picture",
2038         subfields : {
2039             b : {    start : 1,
2040                 len   : 1,
2041                 label : "SMD",
2042                 values: {    a : "Film cartridge",
2043                         f : "Film cassette",
2044                         r : "Film reel",
2045                         u : "Unspecified",
2046                         z : "Other"
2047                 }
2048             },
2049             d : {    start : 3,
2050                 len   : 1,
2051                 label : "Color",
2052                 values: {    b : "Black-and-white",
2053                         c : "Multicolored",
2054                         h : "Hand-colored",
2055                         m : "Mixed",
2056                         u : "Unknown",
2057                         z : "Other"
2058                 }
2059             },
2060             e : {    start : 4,
2061                 len   : 1,
2062                 label : "Motion picture presentation format",
2063                 values: {    a : "Standard sound aperture, reduced frame",
2064                         b : "Nonanamorphic (wide-screen)",
2065                         c : "3D",
2066                         d : "Anamorphic (wide-screen)",
2067                         e : "Other-wide screen format",
2068                         f : "Standard. silent aperture, full frame",
2069                         u : "Unknown",
2070                         z : "Other"
2071                 }
2072             },
2073             f : {    start : 5,
2074                 len   : 1,
2075                 label : "Sound on medium or separate",
2076                 values: {    a : "Sound on medium",
2077                         b : "Sound separate from medium",
2078                         u : "Unknown"
2079                 }
2080             },
2081             g : {    start : 6,
2082                 len   : 1,
2083                 label : "Medium for sound",
2084                 values: {    a : "Optical sound track on motion picture film",
2085                         b : "Magnetic sound track on motion picture film",
2086                         c : "Magnetic audio tape in cartridge",
2087                         d : "Sound disc",
2088                         e : "Magnetic audio tape on reel",
2089                         f : "Magnetic audio tape in cassette",
2090                         g : "Optical and magnetic sound track on film",
2091                         h : "Videotape",
2092                         i : "Videodisc",
2093                         u : "Unknown",
2094                         z : "Other"
2095                 }
2096             },
2097             h : {    start : 7,
2098                 len   : 1,
2099                 label : "Dimensions",
2100                 values: {    a : "Standard 8 mm.",
2101                         b : "Super 8 mm./single 8 mm.",
2102                         c : "9.5 mm.",
2103                         d : "16 mm.",
2104                         e : "28 mm.",
2105                         f : "35 mm.",
2106                         g : "70 mm.",
2107                         u : "Unknown",
2108                         z : "Other"
2109                 }
2110             },
2111             i : {    start : 8,
2112                 len   : 1,
2113                 label : "Configuration of playback channels",
2114                 values: {    k : "Mixed",
2115                         m : "Monaural",
2116                         n : "Not applicable",
2117                         q : "Multichannel, surround or quadraphonic",
2118                         s : "Stereophonic",
2119                         u : "Unknown",
2120                         z : "Other"
2121                 }
2122             },
2123             j : {    start : 9,
2124                 len   : 1,
2125                 label : "Production elements",
2126                 values: {    a : "Work print",
2127                         b : "Trims",
2128                         c : "Outtakes",
2129                         d : "Rushes",
2130                         e : "Mixing tracks",
2131                         f : "Title bands/inter-title rolls",
2132                         g : "Production rolls",
2133                         n : "Not applicable",
2134                         z : "Other"
2135                 }
2136             }
2137         }
2138     },
2139     k : {
2140         label     : "Non-projected Graphic",
2141         subfields : {
2142             b : {    start : 1,
2143                 len   : 1,
2144                 label : "SMD",
2145                 values: {    c : "Collage",
2146                         d : "Drawing",
2147                         e : "Painting",
2148                         f : "Photo-mechanical print",
2149                         g : "Photonegative",
2150                         h : "Photoprint",
2151                         i : "Picture",
2152                         j : "Print",
2153                         l : "Technical drawing",
2154                         n : "Chart",
2155                         o : "Flash/activity card",
2156                         u : "Unspecified",
2157                         z : "Other"
2158                 }
2159             },
2160             d : {    start : 3,
2161                 len   : 1,
2162                 label : "Color",
2163                 values: {    a : "One color",
2164                         b : "Black-and-white",
2165                         c : "Multicolored",
2166                         h : "Hand-colored",
2167                         m : "Mixed",
2168                         u : "Unknown",
2169                         z : "Other"
2170                 }
2171             },
2172             e : {    start : 4,
2173                 len   : 1,
2174                 label : "Primary support material",
2175                 values: {    a : "Canvas",
2176                         b : "Bristol board",
2177                         c : "Cardboard/illustration board",
2178                         d : "Glass",
2179                         e : "Synthetics",
2180                         f : "Skins",
2181                         g : "Textile",
2182                         h : "Metal",
2183                         m : "Mixed collection",
2184                         o : "Paper",
2185                         p : "Plaster",
2186                         q : "Hardboard",
2187                         r : "Porcelain",
2188                         s : "Stone",
2189                         t : "Wood",
2190                         u : "Unknown",
2191                         z : "Other"
2192                 }
2193             },
2194             f : {    start : 5,
2195                 len   : 1,
2196                 label : "Secondary support material",
2197                 values: {    a : "Canvas",
2198                         b : "Bristol board",
2199                         c : "Cardboard/illustration board",
2200                         d : "Glass",
2201                         e : "Synthetics",
2202                         f : "Skins",
2203                         g : "Textile",
2204                         h : "Metal",
2205                         m : "Mixed collection",
2206                         o : "Paper",
2207                         p : "Plaster",
2208                         q : "Hardboard",
2209                         r : "Porcelain",
2210                         s : "Stone",
2211                         t : "Wood",
2212                         u : "Unknown",
2213                         z : "Other"
2214                 }
2215             }
2216         }
2217     },
2218     g : {
2219         label     : "Projected Graphic",
2220         subfields : {
2221             b : {    start : 1,
2222                 len   : 1,
2223                 label : "SMD",
2224                 values: {    c : "Film cartridge",
2225                         d : "Filmstrip",
2226                         f : "Film filmstrip type",
2227                         o : "Filmstrip roll",
2228                         s : "Slide",
2229                         t : "Transparency",
2230                         z : "Other"
2231                 }
2232             },
2233             d : {    start : 3,
2234                 len   : 1,
2235                 label : "Color",
2236                 values: {    b : "Black-and-white",
2237                         c : "Multicolored",
2238                         h : "Hand-colored",
2239                         m : "Mixed",
2240                         n : "Not applicable",
2241                         u : "Unknown",
2242                         z : "Other"
2243                 }
2244             },
2245             e : {    start : 4,
2246                 len   : 1,
2247                 label : "Base of emulsion",
2248                 values: {    d : "Glass",
2249                         e : "Synthetics",
2250                         j : "Safety film",
2251                         k : "Film base, other than safety film",
2252                         m : "Mixed collection",
2253                         o : "Paper",
2254                         u : "Unknown",
2255                         z : "Other"
2256                 }
2257             },
2258             f : {    start : 5,
2259                 len   : 1,
2260                 label : "Sound on medium or separate",
2261                 values: {    a : "Sound on medium",
2262                         b : "Sound separate from medium",
2263                         u : "Unknown"
2264                 }
2265             },
2266             g : {    start : 6,
2267                 len   : 1,
2268                 label : "Medium for sound",
2269                 values: {    a : "Optical sound track on motion picture film",
2270                         b : "Magnetic sound track on motion picture film",
2271                         c : "Magnetic audio tape in cartridge",
2272                         d : "Sound disc",
2273                         e : "Magnetic audio tape on reel",
2274                         f : "Magnetic audio tape in cassette",
2275                         g : "Optical and magnetic sound track on film",
2276                         h : "Videotape",
2277                         i : "Videodisc",
2278                         u : "Unknown",
2279                         z : "Other"
2280                 }
2281             },
2282             h : {    start : 7,
2283                 len   : 1,
2284                 label : "Dimensions",
2285                 values: {    a : "Standard 8 mm.",
2286                         b : "Super 8 mm./single 8 mm.",
2287                         c : "9.5 mm.",
2288                         d : "16 mm.",
2289                         e : "28 mm.",
2290                         f : "35 mm.",
2291                         g : "70 mm.",
2292                         j : "2 x 2 in. (5 x 5 cm.)",
2293                         k : "2 1/4 x 2 1/4 in. (6 x 6 cm.)",
2294                         s : "4 x 5 in. (10 x 13 cm.)",
2295                         t : "5 x 7 in. (13 x 18 cm.)",
2296                         v : "8 x 10 in. (21 x 26 cm.)",
2297                         w : "9 x 9 in. (23 x 23 cm.)",
2298                         x : "10 x 10 in. (26 x 26 cm.)",
2299                         y : "7 x 7 in. (18 x 18 cm.)",
2300                         u : "Unknown",
2301                         z : "Other"
2302                 }
2303             },
2304             i : {    start : 8,
2305                 len   : 1,
2306                 label : "Secondary support material",
2307                 values: {    c : "Cardboard",
2308                         d : "Glass",
2309                         e : "Synthetics",
2310                         h : "metal",
2311                         j : "Metal and glass",
2312                         k : "Synthetics and glass",
2313                         m : "Mixed collection",
2314                         u : "Unknown",
2315                         z : "Other"
2316                 }
2317             }
2318         }
2319     },
2320     r : {
2321         label     : "Remote-sensing Image",
2322         subfields : {
2323             b : {    start : 1,
2324                 len   : 1,
2325                 label : "SMD",
2326                 values: { u : "Unspecified" }
2327             },
2328             d : {    start : 3,
2329                 len   : 1,
2330                 label : "Altitude of sensor",
2331                 values: {    a : "Surface",
2332                         b : "Airborne",
2333                         c : "Spaceborne",
2334                         n : "Not applicable",
2335                         u : "Unknown",
2336                         z : "Other"
2337                 }
2338             },
2339             e : {    start : 4,
2340                 len   : 1,
2341                 label : "Attitude of sensor",
2342                 values: {    a : "Low oblique",
2343                         b : "High oblique",
2344                         c : "Vertical",
2345                         n : "Not applicable",
2346                         u : "Unknown"
2347                 }
2348             },
2349             f : {    start : 5,
2350                 len   : 1,
2351                 label : "Cloud cover",
2352                 values: {    0 : "0-09%",
2353                         1 : "10-19%",
2354                         2 : "20-29%",
2355                         3 : "30-39%",
2356                         4 : "40-49%",
2357                         5 : "50-59%",
2358                         6 : "60-69%",
2359                         7 : "70-79%",
2360                         8 : "80-89%",
2361                         9 : "90-100%",
2362                         n : "Not applicable",
2363                         u : "Unknown"
2364                 }
2365             },
2366             g : {    start : 6,
2367                 len   : 1,
2368                 label : "Platform construction type",
2369                 values: {    a : "Balloon",
2370                         b : "Aircraft-low altitude",
2371                         c : "Aircraft-medium altitude",
2372                         d : "Aircraft-high altitude",
2373                         e : "Manned spacecraft",
2374                         f : "Unmanned spacecraft",
2375                         g : "Land-based remote-sensing device",
2376                         h : "Water surface-based remote-sensing device",
2377                         i : "Submersible remote-sensing device",
2378                         n : "Not applicable",
2379                         u : "Unknown",
2380                         z : "Other"
2381                 }
2382             },
2383             h : {    start : 7,
2384                 len   : 1,
2385                 label : "Platform use category",
2386                 values: {    a : "Meteorological",
2387                         b : "Surface observing",
2388                         c : "Space observing",
2389                         m : "Mixed uses",
2390                         n : "Not applicable",
2391                         u : "Unknown",
2392                         z : "Other"
2393                 }
2394             },
2395             i : {    start : 8,
2396                 len   : 1,
2397                 label : "Sensor type",
2398                 values: {    a : "Active",
2399                         b : "Passive",
2400                         u : "Unknown",
2401                         z : "Other"
2402                 }
2403             },
2404             j : {    start : 9,
2405                 len   : 2,
2406                 label : "Data type",
2407                 values: {    nn : "Not applicable",
2408                         uu : "Unknown",
2409                         zz : "Other",
2410                         aa : "Visible light",
2411                         da : "Near infrared",
2412                         db : "Middle infrared",
2413                         dc : "Far infrared",
2414                         dd : "Thermal infrared",
2415                         de : "Shortwave infrared (SWIR)",
2416                         df : "Reflective infrared",
2417                         dv : "Combinations",
2418                         dz : "Other infrared data",
2419                         ga : "Sidelooking airborne radar (SLAR)",
2420                         gb : "Synthetic aperture radar (SAR-single frequency)",
2421                         gc : "SAR-multi-frequency (multichannel)",
2422                         gd : "SAR-like polarization",
2423                         ge : "SAR-cross polarization",
2424                         gf : "Infometric SAR",
2425                         gg : "Polarmetric SAR",
2426                         gu : "Passive microwave mapping",
2427                         gz : "Other microwave data",
2428                         ja : "Far ultraviolet",
2429                         jb : "Middle ultraviolet",
2430                         jc : "Near ultraviolet",
2431                         jv : "Ultraviolet combinations",
2432                         jz : "Other ultraviolet data",
2433                         ma : "Multi-spectral, multidata",
2434                         mb : "Multi-temporal",
2435                         mm : "Combination of various data types",
2436                         pa : "Sonar-water depth",
2437                         pb : "Sonar-bottom topography images, sidescan",
2438                         pc : "Sonar-bottom topography, near-surface",
2439                         pd : "Sonar-bottom topography, near-bottom",
2440                         pe : "Seismic surveys",
2441                         pz : "Other acoustical data",
2442                         ra : "Gravity anomales (general)",
2443                         rb : "Free-air",
2444                         rc : "Bouger",
2445                         rd : "Isostatic",
2446                         sa : "Magnetic field",
2447                         ta : "Radiometric surveys"
2448                 }
2449             }
2450         }
2451     },
2452     s : {
2453         label     : "Sound Recording",
2454         subfields : {
2455             b : {    start : 1,
2456                 len   : 1,
2457                 label : "SMD",
2458                 values: {    d : "Sound disc",
2459                         e : "Cylinder",
2460                         g : "Sound cartridge",
2461                         i : "Sound-track film",
2462                         q : "Roll",
2463                         s : "Sound cassette",
2464                         t : "Sound-tape reel",
2465                         u : "Unspecified",
2466                         w : "Wire recording",
2467                         z : "Other"
2468                 }
2469             },
2470             d : {    start : 3,
2471                 len   : 1,
2472                 label : "Speed",
2473                 values: {    a : "16 rpm",
2474                         b : "33 1/3 rpm",
2475                         c : "45 rpm",
2476                         d : "78 rpm",
2477                         e : "8 rpm",
2478                         f : "1.4 mps",
2479                         h : "120 rpm",
2480                         i : "160 rpm",
2481                         k : "15/16 ips",
2482                         l : "1 7/8 ips",
2483                         m : "3 3/4 ips",
2484                         o : "7 1/2 ips",
2485                         p : "15 ips",
2486                         r : "30 ips",
2487                         u : "Unknown",
2488                         z : "Other"
2489                 }
2490             },
2491             e : {    start : 4,
2492                 len   : 1,
2493                 label : "Configuration of playback channels",
2494                 values: {    m : "Monaural",
2495                         q : "Quadraphonic",
2496                         s : "Stereophonic",
2497                         u : "Unknown",
2498                         z : "Other"
2499                 }
2500             },
2501             f : {    start : 5,
2502                 len   : 1,
2503                 label : "Groove width or pitch",
2504                 values: {    m : "Microgroove/fine",
2505                         n : "Not applicable",
2506                         s : "Coarse/standard",
2507                         u : "Unknown",
2508                         z : "Other"
2509                 }
2510             },
2511             g : {    start : 6,
2512                 len   : 1,
2513                 label : "Dimensions",
2514                 values: {    a : "3 in.",
2515                         b : "5 in.",
2516                         c : "7 in.",
2517                         d : "10 in.",
2518                         e : "12 in.",
2519                         f : "16 in.",
2520                         g : "4 3/4 in. (12 cm.)",
2521                         j : "3 7/8 x 2 1/2 in.",
2522                         o : "5 1/4 x 3 7/8 in.",
2523                         s : "2 3/4 x 4 in.",
2524                         n : "Not applicable",
2525                         u : "Unknown",
2526                         z : "Other"
2527                 }
2528             },
2529             h : {    start : 7,
2530                 len   : 1,
2531                 label : "Tape width",
2532                 values: {    l : "1/8 in.",
2533                         m : "1/4in.",
2534                         n : "Not applicable",
2535                         o : "1/2 in.",
2536                         p : "1 in.",
2537                         u : "Unknown",
2538                         z : "Other"
2539                 }
2540             },
2541             i : {    start : 8,
2542                 len   : 1,
2543                 label : "Tape configuration ",
2544                 values: {    a : "Full (1) track",
2545                         b : "Half (2) track",
2546                         c : "Quarter (4) track",
2547                         d : "8 track",
2548                         e : "12 track",
2549                         f : "16 track",
2550                         n : "Not applicable",
2551                         u : "Unknown",
2552                         z : "Other"
2553                 }
2554             },
2555             m : {    start : 12,
2556                 len   : 1,
2557                 label : "Special playback",
2558                 values: {    a : "NAB standard",
2559                         b : "CCIR standard",
2560                         c : "Dolby-B encoded, standard Dolby",
2561                         d : "dbx encoded",
2562                         e : "Digital recording",
2563                         f : "Dolby-A encoded",
2564                         g : "Dolby-C encoded",
2565                         h : "CX encoded",
2566                         n : "Not applicable",
2567                         u : "Unknown",
2568                         z : "Other"
2569                 }
2570             },
2571             n : {    start : 13,
2572                 len   : 1,
2573                 label : "Capture and storage",
2574                 values: {    a : "Acoustical capture, direct storage",
2575                         b : "Direct storage, not acoustical",
2576                         d : "Digital storage",
2577                         e : "Analog electrical storage",
2578                         u : "Unknown",
2579                         z : "Other"
2580                 }
2581             }
2582         }
2583     },
2584     f : {
2585         label     : "Tactile Material",
2586         subfields : {
2587             b : {    start : 1,
2588                 len   : 1,
2589                 label : "SMD",
2590                 values: {    a : "Moon",
2591                         b : "Braille",
2592                         c : "Combination",
2593                         d : "Tactile, with no writing system",
2594                         u : "Unspecified",
2595                         z : "Other"
2596                 }
2597             },
2598             d : {    start : 3,
2599                 len   : 2,
2600                 label : "Class of braille writing",
2601                 values: {    a : "Literary braille",
2602                         b : "Format code braille",
2603                         c : "Mathematics and scientific braille",
2604                         d : "Computer braille",
2605                         e : "Music braille",
2606                         m : "Multiple braille types",
2607                         n : "Not applicable",
2608                         u : "Unknown",
2609                         z : "Other"
2610                 }
2611             },
2612             e : {    start : 4,
2613                 len   : 1,
2614                 label : "Level of contraction",
2615                 values: {    a : "Uncontracted",
2616                         b : "Contracted",
2617                         m : "Combination",
2618                         n : "Not applicable",
2619                         u : "Unknown",
2620                         z : "Other"
2621                 }
2622             },
2623             f : {    start : 6,
2624                 len   : 3,
2625                 label : "Braille music format",
2626                 values: {    a : "Bar over bar",
2627                         b : "Bar by bar",
2628                         c : "Line over line",
2629                         d : "Paragraph",
2630                         e : "Single line",
2631                         f : "Section by section",
2632                         g : "Line by line",
2633                         h : "Open score",
2634                         i : "Spanner short form scoring",
2635                         j : "Short form scoring",
2636                         k : "Outline",
2637                         l : "Vertical score",
2638                         n : "Not applicable",
2639                         u : "Unknown",
2640                         z : "Other"
2641                 }
2642             },
2643             g : {    start : 9,
2644                 len   : 1,
2645                 label : "Special physical characteristics",
2646                 values: {    a : "Print/braille",
2647                         b : "Jumbo or enlarged braille",
2648                         n : "Not applicable",
2649                         u : "Unknown",
2650                         z : "Other"
2651                 }
2652             }
2653         }
2654     },
2655     v : {
2656         label     : "Videorecording",
2657         subfields : {
2658             b : {    start : 1,
2659                 len   : 1,
2660                 label : "SMD",
2661                 values: {     c : "Videocartridge",
2662                         d : "Videodisc",
2663                         f : "Videocassette",
2664                         r : "Videoreel",
2665                         u : "Unspecified",
2666                         z : "Other"
2667                 }
2668             },
2669             d : {    start : 3,
2670                 len   : 1,
2671                 label : "Color",
2672                 values: {    b : "Black-and-white",
2673                         c : "Multicolored",
2674                         m : "Mixed",
2675                         n : "Not applicable",
2676                         u : "Unknown",
2677                         z : "Other"
2678                 }
2679             },
2680             e : {    start : 4,
2681                 len   : 1,
2682                 label : "Videorecording format",
2683                 values: {    a : "Beta",
2684                         b : "VHS",
2685                         c : "U-matic",
2686                         d : "EIAJ",
2687                         e : "Type C",
2688                         f : "Quadruplex",
2689                         g : "Laserdisc",
2690                         h : "CED",
2691                         i : "Betacam",
2692                         j : "Betacam SP",
2693                         k : "Super-VHS",
2694                         m : "M-II",
2695                         o : "D-2",
2696                         p : "8 mm.",
2697                         q : "Hi-8 mm.",
2698                         u : "Unknown",
2699                         v : "DVD",
2700                         z : "Other"
2701                 }
2702             },
2703             f : {    start : 5,
2704                 len   : 1,
2705                 label : "Sound on medium or separate",
2706                 values: {    a : "Sound on medium",
2707                         b : "Sound separate from medium",
2708                         u : "Unknown"
2709                 }
2710             },
2711             g : {    start : 6,
2712                 len   : 1,
2713                 label : "Medium for sound",
2714                 values: {    a : "Optical sound track on motion picture film",
2715                         b : "Magnetic sound track on motion picture film",
2716                         c : "Magnetic audio tape in cartridge",
2717                         d : "Sound disc",
2718                         e : "Magnetic audio tape on reel",
2719                         f : "Magnetic audio tape in cassette",
2720                         g : "Optical and magnetic sound track on motion picture film",
2721                         h : "Videotape",
2722                         i : "Videodisc",
2723                         u : "Unknown",
2724                         z : "Other"
2725                 }
2726             },
2727             h : {    start : 7,
2728                 len   : 1,
2729                 label : "Dimensions",
2730                 values: {    a : "8 mm.",
2731                         m : "1/4 in.",
2732                         o : "1/2 in.",
2733                         p : "1 in.",
2734                         q : "2 in.",
2735                         r : "3/4 in.",
2736                         u : "Unknown",
2737                         z : "Other"
2738                 }
2739             },
2740             i : {    start : 8,
2741                 len   : 1,
2742                 label : "Configuration of playback channel",
2743                 values: {    k : "Mixed",
2744                         m : "Monaural",
2745                         n : "Not applicable",
2746                         q : "Multichannel, surround or quadraphonic",
2747                         s : "Stereophonic",
2748                         u : "Unknown",
2749                         z : "Other"
2750                 }
2751             }
2752         }
2753     }
2754 };
2755
2756 MARC21.AuthorityControlSet._remote_loaded = false;
2757 MARC21.AuthorityControlSet._remote_parsed = false;
2758
2759 MARC21.AuthorityControlSet._controlsets = {
2760     // static sorta-LoC setup ... to be overwritten with server data 
2761     '-1' : {
2762         id : -1,
2763         name : 'Static LoC legacy mapping',
2764         description : 'Legacy mapping provided as a default',
2765         control_map : {
2766             100 : {
2767                 'a' : { 100 : 'a' },
2768                 'd' : { 100 : 'd' },
2769                 'e' : { 100 : 'e' },
2770                 'q' : { 100 : 'q' }
2771             },
2772             110 : {
2773                 'a' : { 110 : 'a' },
2774                 'd' : { 110 : 'd' }
2775             },
2776             111 : {
2777                 'a' : { 111 : 'a' },
2778                 'd' : { 111 : 'd' }
2779             },
2780             130 : {
2781                 'a' : { 130 : 'a' },
2782                 'd' : { 130 : 'd' }
2783             },
2784             240 : {
2785                 'a' : { 130 : 'a' },
2786                 'd' : { 130 : 'd' }
2787             },
2788             400 : {
2789                 'a' : { 100 : 'a' },
2790                 'd' : { 100 : 'd' }
2791             },
2792             410 : {
2793                 'a' : { 110 : 'a' },
2794                 'd' : { 110 : 'd' }
2795             },
2796             411 : {
2797                 'a' : { 111 : 'a' },
2798                 'd' : { 111 : 'd' }
2799             },
2800             440 : {
2801                 'a' : { 130 : 'a' },
2802                 'n' : { 130 : 'n' },
2803                 'p' : { 130 : 'p' }
2804             },
2805             700 : {
2806                 'a' : { 100 : 'a' },
2807                 'd' : { 100 : 'd' },
2808                 'q' : { 100 : 'q' },
2809                 't' : { 100 : 't' }
2810             },
2811             710 : {
2812                 'a' : { 110 : 'a' },
2813                 'd' : { 110 : 'd' }
2814             },
2815             711 : {
2816                 'a' : { 111 : 'a' },
2817                 'c' : { 111 : 'c' },
2818                 'd' : { 111 : 'd' }
2819             },
2820             730 : {
2821                 'a' : { 130 : 'a' },
2822                 'd' : { 130 : 'd' }
2823             },
2824             800 : {
2825                 'a' : { 100 : 'a' },
2826                 'd' : { 100 : 'd' }
2827             },
2828             810 : {
2829                 'a' : { 110 : 'a' },
2830                 'd' : { 110 : 'd' }
2831             },
2832             811 : {
2833                 'a' : { 111 : 'a' },
2834                 'd' : { 111 : 'd' }
2835             },
2836             830 : {
2837                 'a' : { 130 : 'a' },
2838                 'd' : { 130 : 'd' }
2839             },
2840             600 : {
2841                 'a' : { 100 : 'a' },
2842                 'd' : { 100 : 'd' },
2843                 'q' : { 100 : 'q' },
2844                 't' : { 100 : 't' },
2845                 'v' : { 180 : 'v',
2846                     100 : 'v',
2847                     181 : 'v',
2848                     182 : 'v',
2849                     185 : 'v'
2850                 },
2851                 'x' : { 180 : 'x',
2852                     100 : 'x',
2853                     181 : 'x',
2854                     182 : 'x',
2855                     185 : 'x'
2856                 },
2857                 'y' : { 180 : 'y',
2858                     100 : 'y',
2859                     181 : 'y',
2860                     182 : 'y',
2861                     185 : 'y'
2862                 },
2863                 'z' : { 180 : 'z',
2864                     100 : 'z',
2865                     181 : 'z',
2866                     182 : 'z',
2867                     185 : 'z'
2868                 }
2869             },
2870             610 : {
2871                 'a' : { 110 : 'a' },
2872                 'd' : { 110 : 'd' },
2873                 't' : { 110 : 't' },
2874                 'v' : { 180 : 'v',
2875                     110 : 'v',
2876                     181 : 'v',
2877                     182 : 'v',
2878                     185 : 'v'
2879                 },
2880                 'x' : { 180 : 'x',
2881                     110 : 'x',
2882                     181 : 'x',
2883                     182 : 'x',
2884                     185 : 'x'
2885                 },
2886                 'y' : { 180 : 'y',
2887                     110 : 'y',
2888                     181 : 'y',
2889                     182 : 'y',
2890                     185 : 'y'
2891                 },
2892                 'z' : { 180 : 'z',
2893                     110 : 'z',
2894                     181 : 'z',
2895                     182 : 'z',
2896                     185 : 'z'
2897                 }
2898             },
2899             611 : {
2900                 'a' : { 111 : 'a' },
2901                 'd' : { 111 : 'd' },
2902                 't' : { 111 : 't' },
2903                 'v' : { 180 : 'v',
2904                     111 : 'v',
2905                     181 : 'v',
2906                     182 : 'v',
2907                     185 : 'v'
2908                 },
2909                 'x' : { 180 : 'x',
2910                     111 : 'x',
2911                     181 : 'x',
2912                     182 : 'x',
2913                     185 : 'x'
2914                 },
2915                 'y' : { 180 : 'y',
2916                     111 : 'y',
2917                     181 : 'y',
2918                     182 : 'y',
2919                     185 : 'y'
2920                 },
2921                 'z' : { 180 : 'z',
2922                     111 : 'z',
2923                     181 : 'z',
2924                     182 : 'z',
2925                     185 : 'z'
2926                 }
2927             },
2928             630 : {
2929                 'a' : { 130 : 'a' },
2930                 'd' : { 130 : 'd' }
2931             },
2932             648 : {
2933                 'a' : { 148 : 'a' },
2934                 'v' : { 148 : 'v' },
2935                 'x' : { 148 : 'x' },
2936                 'y' : { 148 : 'y' },
2937                 'z' : { 148 : 'z' }
2938             },
2939             650 : {
2940                 'a' : { 150 : 'a' },
2941                 'b' : { 150 : 'b' },
2942                 'v' : { 180 : 'v',
2943                     150 : 'v',
2944                     181 : 'v',
2945                     182 : 'v',
2946                     185 : 'v'
2947                 },
2948                 'x' : { 180 : 'x',
2949                     150 : 'x',
2950                     181 : 'x',
2951                     182 : 'x',
2952                     185 : 'x'
2953                 },
2954                 'y' : { 180 : 'y',
2955                     150 : 'y',
2956                     181 : 'y',
2957                     182 : 'y',
2958                     185 : 'y'
2959                 },
2960                 'z' : { 180 : 'z',
2961                     150 : 'z',
2962                     181 : 'z',
2963                     182 : 'z',
2964                     185 : 'z'
2965                 }
2966             },
2967             651 : {
2968                 'a' : { 151 : 'a' },
2969                 'v' : { 180 : 'v',
2970                     151 : 'v',
2971                     181 : 'v',
2972                     182 : 'v',
2973                     185 : 'v'
2974                 },
2975                 'x' : { 180 : 'x',
2976                     151 : 'x',
2977                     181 : 'x',
2978                     182 : 'x',
2979                     185 : 'x'
2980                 },
2981                 'y' : { 180 : 'y',
2982                     151 : 'y',
2983                     181 : 'y',
2984                     182 : 'y',
2985                     185 : 'y'
2986                 },
2987                 'z' : { 180 : 'z',
2988                     151 : 'z',
2989                     181 : 'z',
2990                     182 : 'z',
2991                     185 : 'z'
2992                 }
2993             },
2994             655 : {
2995                 'a' : { 155 : 'a' },
2996                 'v' : { 180 : 'v',
2997                     155 : 'v',
2998                     181 : 'v',
2999                     182 : 'v',
3000                     185 : 'v'
3001                 },
3002                 'x' : { 180 : 'x',
3003                     155 : 'x',
3004                     181 : 'x',
3005                     182 : 'x',
3006                     185 : 'x'
3007                 },
3008                 'y' : { 180 : 'y',
3009                     155 : 'y',
3010                     181 : 'y',
3011                     182 : 'y',
3012                     185 : 'y'
3013                 },
3014                 'z' : { 180 : 'z',
3015                     155 : 'z',
3016                     181 : 'z',
3017                     182 : 'z',
3018                     185 : 'z'
3019                 }
3020             }
3021         }
3022     }
3023 };
3024