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