1 /* ---------------------------------------------------------------------------
2 * Copyright (C) 2009-2015 Equinox Software, Inc.
3 * Mike Rylander <miker@esilibrary.com>
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.
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 * ---------------------------------------------------------------------------
18 // This module requires a /real/ jQuery be used with your
19 // angularjs, so as to avoid using hand-rolled AJAX.
23 Record : function(kwargs) {
24 if (!kwargs) kwargs = {};
26 this.generate008 = function () {
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;
38 if (f = this.field('008',true)[0]) {
42 /* lang code from 041a */
43 var lang = orig008.substr(35, 3);
45 if (f = this.field('041',true)[0]) {
46 if (s = f.subfield('a',true)[0]) {
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];
58 while (country.length < 3) country = country + ' ';
59 if (country.length > 3) country = country.substr(0,3);
62 var date1 = now.getUTCFullYear().toString();
63 if (f = this.field('260',true)[0]) {
64 if (s = f.subfield('c',true)[0]) {
67 tmpd = tmpd.replace(/[^0-9]/g, '');
68 if (tmpd.match(/^\d\d\d\d/)) {
69 date1 = tmpd.substr(0, 4);
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);
80 return '' + y + m + d + datetype + date1 + date2 + country + ' ' + lang + modded + catsrc;
84 this.title = function () { return this.subfield('245','a')[1] }
86 this.field = function (spec, wantarray) {
87 var list = this.fields.filter(function (f) {
88 if (f.tag.match(spec)) return true;
92 if (!wantarray && list.length == 1) return list[0];
96 this.subfield = function (spec, code) {
97 var f = this.field(spec, true)[0];
98 if (f) return f.subfield(code)
102 this.appendFields = function () {
104 Array.prototype.slice.call(arguments).forEach( function (f) { f.position = me.fields.length; me.fields.push( f ) } );
107 this.deleteField = function (f) { return this.deleteFields(f) },
109 this.insertOrderedFields = function () {
111 for (var i = 0; i < arguments.length; i++) {
112 var f = arguments[i];
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);
121 if (!done) this.appendFields(f);
125 this.insertFieldsBefore = function (target) {
126 var args = Array.prototype.slice.call(arguments);
129 for (var j = 0; j < this.fields.length; j++) {
130 if (target === this.fields[j]) {
131 args.forEach( function (f) {
133 me.fields.splice(j++,0,f);
138 for (var j = 0; j < this.fields.length; j++) {
139 this.fields[j].position = j;
143 this.insertFieldsAfter = function (target) {
144 var args = Array.prototype.slice.call(arguments);
147 for (var j = 0; j < this.fields.length; j++) {
148 if (target === this.fields[j]) {
149 args.forEach( function (f) {
151 me.fields.splice(++j,0,f);
156 for (var j = 0; j < this.fields.length; j++) {
157 this.fields[j].position = j;
161 this.deleteFields = function () {
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);
175 for (var j = 0; j < this.fields.length; j++) {
176 this.fields[j].position = j;
181 // this.clone = function () { return dojo.clone(this) } // maybe implement later...
183 this.fromXmlURL = function (url) {
185 return $.get( // This is a Promise
188 me.fromXmlDocument($('record', mxml)[0]);
189 if (me.onLoad) me.onLoad();
193 this.fromXmlString = function (mxml) {
194 this.fromXmlDocument( $( $.parseXML( mxml ) ).find('record')[0] );
197 this.fromXmlDocument = function (mxml) {
199 me.leader = $($('leader',mxml)[0]).text() || '00000cam a2200205Ka 4500';
201 $('controlfield', mxml).each(function (ind) {
206 tag : cf.attr('tag'),
212 $('datafield', mxml).each(function (ind) {
217 tag : df.attr('tag'),
218 ind1 : df.attr('ind1'),
219 ind2 : df.attr('ind2'),
220 subfields : $('subfield', df).map(
222 return [[ $(sf).attr('code'), $(sf).text(), i ]];
229 for (var j = 0; j < this.fields.length; j++) {
230 this.fields[j].position = j;
237 this.toXmlDocument = function () {
239 var doc = $.parseXML('<record xmlns="http://www.loc.gov/MARC21/slim"/>');
240 var rec_node = $('record', doc)[0];
242 var ldr = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'leader');
243 ldr.textContent = this.leader;
244 rec_node.appendChild( ldr );
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);
251 if (f.isControlfield()) {
252 if (f.data) f_node.textContent = f.data;
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);
264 rec_node.appendChild(f_node);
270 this.toXmlString = function () {
271 return (new XMLSerializer()).serializeToString( this.toXmlDocument() );
274 this.fromBreaker = function (marctxt) {
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) {
284 return (x == 'LDR' || x < '010') ? true : false;
287 var lines = marctxt.replace(/^=/gm,'').split('\n');
288 lines.forEach(function (current_line, ind) {
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';
299 tag : line_tag(current_line),
300 data : cf_line_data(current_line).replace('\\',' ','g'),
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);
308 var data = df_line_data(current_line);
309 if (!(data.substring(0,1) == me.delimiter)) data = me.delimiter + 'a' + data;
311 var sf_list = data.split(me.delimiter);
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 ];
330 for (var j = 0; j < this.fields.length; j++) {
331 this.fields[j].position = j;
338 this.toBreaker = function () {
341 var mtxt = '=LDR ' + this.leader + '\n';
343 mtxt += this.fields.map( function (f) {
344 if (f.isControlfield()) {
345 if (f.data) return '=' + f.tag + ' ' + f.data.replace(' ','\\','g');
348 return '=' + f.tag + ' ' +
349 f.indicator(1).replace(' ','\\') +
350 f.indicator(2).replace(' ','\\') +
351 f.subfields.map( function (sf) {
353 if (me.delimiter == '$') sf_data = sf_data.replace(/\$/g, '{dollar}');
354 return me.delimiter + sf[0] + sf_data;
362 this.recordType = function () {
364 var _t = this.leader.substr(MARC.Record._ff_pos.Type.ldr.BKS.start, MARC.Record._ff_pos.Type.ldr.BKS.len);
365 var _b = this.leader.substr(MARC.Record._ff_pos.BLvl.ldr.BKS.start, MARC.Record._ff_pos.BLvl.ldr.BKS.len);
367 for (var t in MARC.Record._recType) {
368 if (_t.match(MARC.Record._recType[t].Type) && _b.match(MARC.Record._recType[t].BLvl)) {
372 return 'BKS'; // default
375 this.videorecordingFormatName = function () {
376 var _7 = this.field('007').data;
378 if (_7 && _7.match(/^v/)) {
379 var _v_e = _7.substr(
380 MARC.Record._physical_characteristics.v.subfields.e.start,
381 MARC.Record._physical_characteristics.v.subfields.e.len
384 return MARC.Record._physical_characteristics.v.subfields.e.values[ _v_e ];
390 this.videorecordingFormatCode = function () {
391 var _7 = this.field('007').data;
393 if (_7 && _7.match(/^v/)) {
395 MARC.Record._physical_characteristics.v.subfields.e.start,
396 MARC.Record._physical_characteristics.v.subfields.e.len
403 this.extractFixedField = function (field, dflt) {
404 if (!MARC.Record._ff_pos[field]) return null;
406 var _l = this.leader;
407 var _8 = this.field('008').data;
408 var _6 = this.field('006').data;
410 var rtype = this.recordType();
414 if (MARC.Record._ff_pos[field].ldr && _l) {
415 if (MARC.Record._ff_pos[field].ldr[rtype]) {
417 MARC.Record._ff_pos[field].ldr[rtype].start,
418 MARC.Record._ff_pos[field].ldr[rtype].len
421 } else if (MARC.Record._ff_pos[field]._8 && _8) {
422 if (MARC.Record._ff_pos[field]._8[rtype]) {
424 MARC.Record._ff_pos[field]._8[rtype].start,
425 MARC.Record._ff_pos[field]._8[rtype].len
430 if (!val && MARC.Record._ff_pos[field]._6 && _6) {
431 if (MARC.Record._ff_pos[field]._6[rtype]) {
433 MARC.Record._ff_pos[field]._6[rtype].start,
434 MARC.Record._ff_pos[field]._6[rtype].len
443 if (MARC.Record._ff_pos[field].ldr && MARC.Record._ff_pos[field].ldr[rtype]) {
444 d = MARC.Record._ff_pos[field].ldr[rtype].def;
448 if (MARC.Record._ff_pos[field]._8 && MARC.Record._ff_pos[field]._8[rtype]) {
449 d = MARC.Record._ff_pos[field]._8[rtype].def;
453 if (!val && MARC.Record._ff_pos[field]._6 && MARC.Record._ff_pos[field]._6[rtype]) {
454 d = MARC.Record._ff_pos[field]._6[rtype].def;
459 for (var j = 0; j < MARC.Record._ff_pos[field][p][rtype].len; j++) {
470 this.setFixedField = function (field, value) {
471 if (!MARC.Record._ff_pos[field]) return null;
473 var _l = this.leader;
474 var _8 = this.field('008').data;
475 var _6 = this.field('006').data;
477 var rtype = this.recordType();
481 if (MARC.Record._ff_pos[field].ldr && _l) {
482 if (MARC.Record._ff_pos[field].ldr[rtype]) { // It's in the leader
483 val = value.substr(0, MARC.Record._ff_pos[field].ldr[rtype].len);
485 _l.substring(0, MARC.Record._ff_pos[field].ldr[rtype].start) +
488 MARC.Record._ff_pos[field].ldr[rtype].start
489 + MARC.Record._ff_pos[field].ldr[rtype].len
492 } else if (MARC.Record._ff_pos[field]._8 && _8) {
493 if (MARC.Record._ff_pos[field]._8[rtype]) { // Nope, it's in the 008
494 val = value.substr(0, MARC.Record._ff_pos[field]._8[rtype].len);
495 this.field('008').update(
496 _8.substring(0, MARC.Record._ff_pos[field]._8[rtype].start) +
499 MARC.Record._ff_pos[field]._8[rtype].start
500 + MARC.Record._ff_pos[field]._8[rtype].len
506 if (!val && MARC.Record._ff_pos[field]._6 && _6) {
507 if (MARC.Record._ff_pos[field]._6[rtype]) { // ok, maybe the 006?
508 val = value.substr(0, MARC.Record._ff_pos[field]._6[rtype].len);
509 this.field('006').update(
510 _6.substring(0, MARC.Record._ff_pos[field]._6[rtype].start) +
513 MARC.Record._ff_pos[field]._6[rtype].start
514 + MARC.Record._ff_pos[field]._6[rtype].len
525 this.delimiter = '\u2021';
526 this.leader = '00000cam a2200205Ka 4500';
528 if (kwargs.delimiter) this.delimiter = kwargs.delimiter;
529 if (kwargs.onLoad) this.onLoad = kwargs.onLoad;
532 this.fromXmlURL(kwargs.url);
533 } else if (kwargs.marcxml) {
534 this.fromXmlString(kwargs.marcxml);
535 if (this.onLoad) this.onLoad();
536 } else if (kwargs.xml) {
537 this.fromXmlDocument(kwargs.xml);
538 if (this.onLoad) this.onLoad();
539 } else if (kwargs.marcbreaker) {
540 this.fromBreaker(kwargs.marcbreaker);
541 if (this.onLoad) this.onLoad();
544 if (kwargs.rtype == 'AUT') {
545 this.setFixedField('Type','z');
550 Field : function (kwargs) {
551 if (!kwargs) kwargs = {};
553 this.subfield = function (code, wantarray) {
554 var list = this.subfields.filter( function (s) {
555 if (s[0] == code) return true; return false;
557 if (!wantarray && list.length == 1) return list[0];
561 this.addSubfields = function () {
562 for (var i = 0; i < arguments.length; i++) {
563 var code = arguments[i];
564 var value = arguments[++i];
565 this.subfields.push( [ code, value ] );
569 this.deleteExactSubfields = function () {
573 for ( var i in arguments ) {
574 var f = arguments[i];
575 for (var j = 0; j < me.subfields.length; j++) {
576 if (f === me.subfields[j]) {
577 me.subfields.splice(j,1);
582 if (done && me.subfields[j])
583 me.subfields[j][2] -= 1;
590 this.deleteSubfields = function (c) {
591 return this.deleteSubfield( { code : c } );
594 this.deleteSubfield = function (args) {
596 if (!Array.isArray( args.code )) {
597 args.code = [ args.code ];
600 if (args.pos && !Array.isArray( args.pos )) {
601 args.pos = [ args.pos ];
604 for (var i = 0; i < args.code.length; i++) {
606 for (var j = 0; j < me.subfields; j++) {
607 if (me.subfields[j][0] == args.code[i]) {
609 if (!sub_pos[args.code[i]]) sub_pos[args.code[j]] = 0;
610 else sub_pos[args.code[i]]++;
613 for (var k = 0; k < args.pos.length; k++) {
614 if (sub_pos[args.code[i]] == args.pos[k]) me.subfields.splice(j,1);
616 } else if (args.match && me.subfields[j][1].match( args.match )) {
617 me.subfields.splice(j,1);
619 me.subfields.splice(j,1);
626 this.update = function ( args ) {
627 if (this.isControlfield()) {
630 if (args.ind1) this.ind1 = args.ind1;
631 if (args.ind2) this.ind2 = args.ind2;
632 if (args.tag) this.tag = args.tag;
634 for (var i in args) {
635 if (i == 'tag' || i == 'ind1' || i == 'ind2') continue;
637 this.subfields.forEach( function (f) {
638 if (!done && f[0] == i) {
647 this.isControlfield = function () {
648 return this.tag < '010' ? true : false;
651 this.indicator = function (num, value) {
652 if (value !== undefined) {
653 if (num == 1) this.ind1 = value;
654 else if (num == 2) this.ind2 = value;
655 else { this.error = true; return null; }
657 if (num == 1) return this.ind1;
658 else if (num == 2) return this.ind2;
659 else { this.error = true; return null; }
663 this.record = null; // MARC record pointer
664 this.tag = ''; // MARC tag
665 this.ind1 = ' '; // MARC indicator 1
666 this.ind2 = ' '; // MARC indicator 2
667 this.data = ''; // MARC data for a controlfield element
668 this.subfields = []; // list of MARC subfields for a datafield element
670 this.position = kwargs.position;
671 this.record = kwargs.record;
672 this.tag = kwargs.tag;
673 this.ind1 = kwargs.ind1 || ' ';
674 this.ind2 = kwargs.ind2 || ' ';
675 this.data = kwargs.data;
677 if (kwargs.subfields) this.subfields = kwargs.subfields;
678 else this.subfields = [];
682 Batch : function(kwargs) {
684 this.parse = function () {
685 if (this.source instanceof Object ) { // assume an xml collection document
686 this.source = $('record', this.source);
688 } else if (this.source.match(/^\s*</)) { // this is xml text
689 this.source = $.parseXML( mxml ).find('record');
691 } else { // must be a marcbreaker doc. split on blank lines
692 this.source = this.source.split(/^$/);
693 this.type = 'marcbreaker';
697 this.fetchURL = function (u) {
699 $.get( u, function (mrc) {
705 this.next = function () {
706 var chunk = this.source[this.current_record++];
710 args[this.type] = chunk;
711 if (this.delimiter) args.delimiter = this.delimiter;
712 return new MARC.Record(args);
720 this.source = kwargs.source;
721 this.delimiter = kwargs.delimiter
722 this.current_record = 0;
724 if (this.source) this.ready = true;
725 if (!this.ready && kwargs.url) this.fetchURL( kwargs.url );
727 if (this.ready) this.parse();
732 MARC.Record._recType = {
733 BKS : { Type : /[at]{1}/, BLvl : /[acdm]{1}/ },
734 SER : { Type : /[a]{1}/, BLvl : /[bsi]{1}/ },
735 VIS : { Type : /[gkro]{1}/, BLvl : /[abcdmsi]{1}/ },
736 MIX : { Type : /[p]{1}/, BLvl : /[cdi]{1}/ },
737 MAP : { Type : /[ef]{1}/, BLvl : /[abcdmsi]{1}/ },
738 SCO : { Type : /[cd]{1}/, BLvl : /[abcdmsi]{1}/ },
739 REC : { Type : /[ij]{1}/, BLvl : /[abcdmsi]{1}/ },
740 COM : { Type : /[m]{1}/, BLvl : /[abcdmsi]{1}/ },
741 AUT : { Type : /[z]{1}/, BLvl : /.{1}/ },
742 MFHD : { Type : /[uvxy]{1}/, BLvl : /.{1}/ }
745 MARC.Record._ff_pos = {
748 SCO : {start: 24, len : 6, def : ' ' },
749 REC : {start: 24, len : 6, def : ' ' }
752 SCO : {start: 7, len : 6, def : ' ' },
753 REC : {start: 7, len : 6, def : ' ' }
758 SER : {start : 33, len : 1, def : ' ' }
761 SER : {start : 16, len : 1, def : ' ' }
766 BKS : {start : 22, len : 1, def : ' ' },
767 SER : {start : 22, len : 1, def : ' ' },
768 VIS : {start : 22, len : 1, def : ' ' },
769 SCO : {start : 22, len : 1, def : ' ' },
770 REC : {start : 22, len : 1, def : ' ' },
771 COM : {start : 22, len : 1, def : ' ' }
774 BKS : {start : 5, len : 1, def : ' ' },
775 SER : {start : 5, len : 1, def : ' ' },
776 VIS : {start : 5, len : 1, def : ' ' },
777 SCO : {start : 5, len : 1, def : ' ' },
778 REC : {start : 5, len : 1, def : ' ' },
779 COM : {start : 5, len : 1, def : ' ' }
784 BKS : {start : 34, len : 1, def : ' ' }
787 BKS : {start : 17, len : 1, def : ' ' }
792 BKS : {start : 7, len : 1, def : 'm' },
793 SER : {start : 7, len : 1, def : 's' },
794 VIS : {start : 7, len : 1, def : 'm' },
795 MIX : {start : 7, len : 1, def : 'c' },
796 MAP : {start : 7, len : 1, def : 'm' },
797 SCO : {start : 7, len : 1, def : 'm' },
798 REC : {start : 7, len : 1, def : 'm' },
799 COM : {start : 7, len : 1, def : 'm' }
804 SCO : {start : 18, len : 2, def : 'uu'},
805 REC : {start : 18, len : 2, def : 'uu'}
808 SCO : {start : 1, len : 2, def : 'uu'},
809 REC : {start : 1, len : 2, def : 'uu'}
814 BKS : {start : 29, len : 1, def : '0' },
815 SER : {start : 29, len : 1, def : '0' }
818 BKS : {start : 11, len : 1, def : '0' },
819 SER : {start : 11, len : 1, def : '0' }
824 BKS : {start : 24, len : 4, def : ' ' },
825 SER : {start : 25, len : 3, def : ' ' }
828 BKS : {start : 7, len : 4, def : ' ' },
829 SER : {start : 8, len : 3, def : ' ' }
834 MAP : {start: 25, len : 1, def : 'a' }
837 MAP : {start : 8, len : 1, def : 'a' }
842 BKS : {start : 8, len : 1, def : ' ' },
843 SER : {start : 8, len : 1, def : ' ' },
844 VIS : {start : 8, len : 1, def : ' ' },
845 MIX : {start : 8, len : 1, def : ' ' },
846 MAP : {start : 8, len : 1, def : ' ' },
847 SCO : {start : 8, len : 1, def : ' ' },
848 REC : {start : 8, len : 1, def : ' ' },
849 COM : {start : 8, len : 1, def : ' ' }
854 BKS : {start : 15, len : 3, def : ' ' },
855 SER : {start : 15, len : 3, def : ' ' },
856 VIS : {start : 15, len : 3, def : ' ' },
857 MIX : {start : 15, len : 3, def : ' ' },
858 MAP : {start : 15, len : 3, def : ' ' },
859 SCO : {start : 15, len : 3, def : ' ' },
860 REC : {start : 15, len : 3, def : ' ' },
861 COM : {start : 15, len : 3, def : ' ' }
866 BKS : {start : 7, len : 4, def : ' ' },
867 SER : {start : 7, len : 4, def : ' ' },
868 VIS : {start : 7, len : 4, def : ' ' },
869 MIX : {start : 7, len : 4, def : ' ' },
870 MAP : {start : 7, len : 4, def : ' ' },
871 SCO : {start : 7, len : 4, def : ' ' },
872 REC : {start : 7, len : 4, def : ' ' },
873 COM : {start : 7, len : 4, def : ' ' }
878 BKS : {start : 11, len : 4, def : ' ' },
879 SER : {start : 11, len : 4, def : '9' },
880 VIS : {start : 11, len : 4, def : ' ' },
881 MIX : {start : 11, len : 4, def : ' ' },
882 MAP : {start : 11, len : 4, def : ' ' },
883 SCO : {start : 11, len : 4, def : ' ' },
884 REC : {start : 11, len : 4, def : ' ' },
885 COM : {start : 11, len : 4, def : ' ' }
890 BKS : {start : 18, len : 1, def : ' ' },
891 SER : {start : 18, len : 1, def : ' ' },
892 VIS : {start : 18, len : 1, def : ' ' },
893 MIX : {start : 18, len : 1, def : ' ' },
894 MAP : {start : 18, len : 1, def : ' ' },
895 SCO : {start : 18, len : 1, def : ' ' },
896 REC : {start : 18, len : 1, def : ' ' },
897 COM : {start : 18, len : 1, def : ' ' }
902 BKS : {start : 6, len : 1, def : ' ' },
903 SER : {start : 6, len : 1, def : 'c' },
904 VIS : {start : 6, len : 1, def : ' ' },
905 MIX : {start : 6, len : 1, def : ' ' },
906 MAP : {start : 6, len : 1, def : ' ' },
907 SCO : {start : 6, len : 1, def : ' ' },
908 REC : {start : 6, len : 1, def : ' ' },
909 COM : {start : 6, len : 1, def : ' ' }
914 BKS : {start : 17, len : 1, def : ' ' },
915 SER : {start : 17, len : 1, def : ' ' },
916 VIS : {start : 17, len : 1, def : ' ' },
917 MIX : {start : 17, len : 1, def : ' ' },
918 MAP : {start : 17, len : 1, def : ' ' },
919 SCO : {start : 17, len : 1, def : ' ' },
920 REC : {start : 17, len : 1, def : ' ' },
921 COM : {start : 17, len : 1, def : ' ' },
922 AUT : {start : 17, len : 1, def : 'n' },
923 MFHD : {start : 17, len : 1, def : 'u' }
928 SER : {start : 24, len : 1, def : ' '}
931 SER : {start : 7, len : 1, def : ' '}
936 BKS : {start : 30, len : 1, def : '0' }
939 BKS : {start : 13, len : 1, def : '0' }
944 COM : {start: 26, len : 1, def : 'u' }
947 COM : {start: 9, len : 1, def : 'u' }
952 SCO : {start : 20, len : 1, def : 'u'},
953 REC : {start : 20, len : 1, def : 'n'}
956 SCO : {start : 3, len : 1, def : 'u'},
957 REC : {start : 3, len : 1, def : 'n'}
962 BKS : {start : 23, len : 1, def : ' ' },
963 SER : {start : 23, len : 1, def : ' ' },
964 VIS : {start : 29, len : 1, def : ' ' },
965 MIX : {start : 23, len : 1, def : ' ' },
966 MAP : {start : 29, len : 1, def : ' ' },
967 SCO : {start : 23, len : 1, def : ' ' },
968 REC : {start : 23, len : 1, def : ' ' }
971 BKS : {start : 6, len : 1, def : ' ' },
972 SER : {start : 6, len : 1, def : ' ' },
973 VIS : {start : 12, len : 1, def : ' ' },
974 MIX : {start : 6, len : 1, def : ' ' },
975 MAP : {start : 12, len : 1, def : ' ' },
976 SCO : {start : 6, len : 1, def : ' ' },
977 REC : {start : 6, len : 1, def : ' ' }
982 SER : {start : 18, len : 1, def : ' '}
985 SER : {start : 1, len : 1, def : ' '}
990 BKS : {start : 28, len : 1, def : ' ' },
991 SER : {start : 28, len : 1, def : ' ' },
992 VIS : {start : 28, len : 1, def : ' ' },
993 MAP : {start : 28, len : 1, def : ' ' },
994 COM : {start : 28, len : 1, def : ' ' }
997 BKS : {start : 11, len : 1, def : ' ' },
998 SER : {start : 11, len : 1, def : ' ' },
999 VIS : {start : 11, len : 1, def : ' ' },
1000 MAP : {start : 11, len : 1, def : ' ' },
1001 COM : {start : 11, len : 1, def : ' ' }
1006 BKS : {start : 18, len : 4, def : ' ' }
1009 BKS : {start : 1, len : 4, def : ' ' }
1014 BKS : {start : 31, len : 1, def : '0' },
1015 MAP : {start : 31, len : 1, def : '0' }
1018 BKS : {start : 14, len : 1, def : '0' },
1019 MAP : {start : 14, len : 1, def : '0' }
1024 MFHD : {start : 18, len : 1, def : 'i' }
1029 BKS : {start : 35, len : 3, def : ' ' },
1030 SER : {start : 35, len : 3, def : ' ' },
1031 VIS : {start : 35, len : 3, def : ' ' },
1032 MIX : {start : 35, len : 3, def : ' ' },
1033 MAP : {start : 35, len : 3, def : ' ' },
1034 SCO : {start : 35, len : 3, def : ' ' },
1035 REC : {start : 35, len : 3, def : ' ' },
1036 COM : {start : 35, len : 3, def : ' ' }
1041 BKS : {start : 33, len : 1, def : '0' }
1044 BKS : {start : 16, len : 1, def : '0' }
1049 SCO : {start : 30, len : 2, def : 'n'},
1050 REC : {start : 30, len : 2, def : ' '}
1053 SCO : {start : 13, len : 2, def : 'n'},
1054 REC : {start : 13, len : 2, def : ' '}
1059 BKS : {start : 38, len : 1, def : ' ' },
1060 SER : {start : 38, len : 1, def : ' ' },
1061 VIS : {start : 38, len : 1, def : ' ' },
1062 MIX : {start : 38, len : 1, def : ' ' },
1063 MAP : {start : 38, len : 1, def : ' ' },
1064 SCO : {start : 38, len : 1, def : ' ' },
1065 REC : {start : 38, len : 1, def : ' ' },
1066 COM : {start : 38, len : 1, def : ' ' }
1071 SER : {start : 22, len : 1, def : ' '}
1074 SER : {start: 5, len : 1, def: ' '}
1079 SCO : {start : 21, len : 1, def : ' '},
1080 REC : {start : 21, len : 1, def : 'n'}
1083 SCO : {start : 4, len : 1, def : ' '},
1084 REC : {start : 4, len : 1, def : 'n'}
1089 MAP : {start : 22, len : 2, def : ' ' }
1092 MAP: {start : 5, len : 2, def : ' ' }
1097 BKS : {start : 5, len : 1, def : 'n' },
1098 SER : {start : 5, len : 1, def : 'n' },
1099 VIS : {start : 5, len : 1, def : 'n' },
1100 MIX : {start : 5, len : 1, def : 'n' },
1101 MAP : {start : 5, len : 1, def : 'n' },
1102 SCO : {start : 5, len : 1, def : 'n' },
1103 REC : {start : 5, len : 1, def : 'n' },
1104 COM : {start : 5, len : 1, def : 'n' },
1105 MFHD: {start : 5, len : 1, def : 'n' },
1106 AUT : {start : 5, len : 1, def : 'n' }
1111 SER : {start : 19, len : 1, def : ' '}
1114 SER : {start : 2, len : 1, def : ' '}
1119 MAP : {start: 18, len : 4, def : ' '}
1122 MAP : {start: 1, len : 4, def : ' '}
1127 SER : {start : 34, len : 1, def : '0' }
1130 SER : {start : 17, len : 1, def : '0' }
1135 MAP : {start: 33, len : 2, def : ' ' }
1138 MAP : {start: 16, len : 2, def : ' '}
1143 BKS : {start : 39, len : 1, def : 'd' },
1144 SER : {start : 39, len : 1, def : 'd' },
1145 VIS : {start : 39, len : 1, def : 'd' },
1146 SCO : {start : 39, len : 1, def : 'd' },
1147 REC : {start : 39, len : 1, def : 'd' },
1148 COM : {start : 39, len : 1, def : 'd' },
1149 MFHD : {start : 39, len : 1, def : 'd' },
1150 "AUT" : {"start" : 39, "len" : 1, "def" : 'd' }
1155 SER : {start : 21, len : 1, def : ' '}
1158 SER : {start : 4, len : 1, def : ' '}
1163 VIS : {start : 34, len : 1, def : ' '}
1166 VIS : {start : 17, len : 1, def : ' '}
1171 VIS : {start : 18, len : 3, def : ' '}
1174 VIS : {start : 1, len : 3, def : ' '}
1179 VIS : {start : 33, len : 1, def : ' ' }
1182 VIS : {start : 16, len : 1, def : ' ' }
1187 SCO : {start : 33, len : 1, def : ' ' },
1188 REC : {start : 33, len : 1, def : 'n' }
1191 SCO : {start : 16, len : 1, def : ' ' },
1192 REC : {start : 16, len : 1, def : 'n' }
1197 BKS : {start : 6, len : 1, def : 'a' },
1198 SER : {start : 6, len : 1, def : 'a' },
1199 VIS : {start : 6, len : 1, def : 'g' },
1200 MIX : {start : 6, len : 1, def : 'p' },
1201 MAP : {start : 6, len : 1, def : 'e' },
1202 SCO : {start : 6, len : 1, def : 'c' },
1203 REC : {start : 6, len : 1, def : 'i' },
1204 COM : {start : 6, len : 1, def : 'm' },
1205 AUT : {start : 6, len : 1, def : 'z' },
1206 MFHD : {start : 6, len : 1, def : 'y' }
1211 "AUT" : {"start" : 6, "len" : 1, "def" : ' ' }
1216 "AUT" : {"start" : 7, "len" : 1, "def" : ' ' }
1221 "AUT" : {"start" : 8, "len" : 1, "def" : ' ' }
1226 "AUT" : {"start" : 9, "len" : 1, "def" : ' ' }
1231 "AUT" : {"start" : 10, "len" : 1, "def" : ' ' }
1236 "AUT" : {"start" : 11, "len" : 1, "def" : ' ' }
1241 "AUT" : {"start" : 12, "len" : 1, "def" : ' ' }
1246 "AUT" : {"start" : 13, "len" : 1, "def" : ' ' }
1251 "AUT" : {"start" : 14, "len" : 1, "def" : ' ' }
1256 "AUT" : {"start" : 15, "len" : 1, "def" : ' ' }
1261 "AUT" : {"start" : 16, "len" : 1, "def" : ' ' }
1266 "AUT" : {"start" : 17, "len" : 1, "def" : ' ' }
1271 "AUT" : {"start" : 28, "len" : 1, "def" : ' ' }
1276 "AUT" : {"start" : 29, "len" : 1, "def" : ' ' }
1281 "AUT" : {"start" : 31, "len" : 1, "def" : ' ' }
1286 "AUT" : {"start" : 32, "len" : 1, "def" : ' ' }
1291 "AUT" : {"start" : 33, "len" : 1, "def" : ' ' }
1296 "AUT" : {"start" : 38, "len" : 1, "def" : ' ' }
1301 "AUT" : {"start" : 39, "len" : 1, "def" : ' ' }
1306 MARC.Record._physical_characteristics = {
1308 label : "Electronic Resource",
1313 values: { a : "Tape Cartridge",
1314 b : "Chip cartridge",
1315 c : "Computer optical disk cartridge",
1316 f : "Tape cassette",
1318 j : "Magnetic disk",
1319 m : "Magneto-optical disk",
1329 values: { a : "One color",
1330 b : "Black-and-white",
1334 n : "Not applicable",
1341 label : "Dimensions",
1342 values: { a : "3 1/2 in.",
1344 g : "4 3/4 in. or 12 cm.",
1345 i : "1 1/8 x 2 3/8 in.",
1346 j : "3 7/8 x 2 1/2 in.",
1347 n : "Not applicable",
1357 values: { ' ' : "No sound (Silent)",
1364 label : "Image bit depth",
1365 values: { mmm : "Multiple",
1366 nnn : "Not applicable",
1372 label : "File formats",
1373 values: { a : "One file format",
1374 m : "Multiple file formats",
1380 label : "Quality assurance target(s)",
1381 values: { a : "Absent",
1382 n : "Not applicable",
1389 label : "Antecedent/Source",
1390 values: { a : "File reproduced from original",
1391 b : "File reproduced from microform",
1392 c : "File reproduced from electronic resource",
1393 d : "File reproduced from an intermediate (not microform)",
1395 n : "Not applicable",
1401 label : "Level of compression",
1402 values: { a : "Uncompressed",
1411 label : "Reformatting quality",
1412 values: { a : "Access",
1413 n : "Not applicable",
1427 values: { a : "Celestial globe",
1428 b : "Planetary or lunar globe",
1429 c : "Terrestrial globe",
1430 e : "Earth moon globe",
1438 values: { a : "One color",
1444 label : "Physical medium",
1445 values: { a : "Paper",
1459 label : "Type of reproduction",
1460 values: { f : "Facsimile",
1461 n : "Not applicable",
1474 values: { d : "Atlas",
1479 r : "Remote-sensing image",
1489 values: { a : "One color",
1495 label : "Physical medium",
1496 values: { a : "Paper",
1504 q : "Flexible base photographic medium, positive",
1505 r : "Flexible base photographic medium, negative",
1506 s : "Non-flexible base photographic medium, positive",
1507 t : "Non-flexible base photographic medium, negative",
1509 y : "Other photographic medium",
1515 label : "Type of reproduction",
1516 values: { f : "Facsimile",
1517 n : "Not applicable",
1524 label : "Production/reproduction details",
1525 values: { a : "Photocopy, blueline print",
1527 c : "Pre-production",
1535 label : "Positive/negative",
1536 values: { a : "Positive",
1539 n : "Not applicable"
1545 label : "Microform",
1550 values: { a : "Aperture card",
1551 b : "Microfilm cartridge",
1552 c : "Microfilm cassette",
1553 d : "Microfilm reel",
1555 f : "Microfiche cassette",
1563 label : "Positive/negative",
1564 values: { a : "Positive",
1572 label : "Dimensions",
1573 values: { a : "8 mm.",
1578 l : "3 x 5 in. (8 x 13 cm.)",
1579 m : "4 x 6 in. (11 x 15 cm.)",
1580 o : "6 x 9 in. (16 x 23 cm.)",
1581 p : "3 1/4 x 7 3/8 in. (9 x 19 cm.)",
1588 label : "Reduction ratio range/Reduction ratio",
1589 values: { a : "Low (1-16x)",
1590 b : "Normal (16-30x)",
1591 c : "High (31-60x)",
1592 d : "Very high (61-90x)",
1595 v : "Reduction ratio varies"
1601 values: { b : "Black-and-white",
1610 label : "Emulsion on film",
1611 values: { a : "Silver halide",
1615 n : "Not applicable",
1622 label : "Quality assurance target(s)",
1623 values: { a : "1st gen. master",
1624 b : "Printing master",
1626 m : "Mixed generation",
1632 label : "Base of film",
1633 values: { a : "Safety base, undetermined",
1634 c : "Safety base, acetate undetermined",
1635 d : "Safety base, diacetate",
1638 n : "Not applicable",
1639 p : "Safety base, polyester",
1640 r : "Safety base, mixed",
1641 t : "Safety base, triacetate",
1649 label : "Motion Picture",
1654 values: { a : "Film cartridge",
1655 f : "Film cassette",
1664 values: { b : "Black-and-white",
1674 label : "Motion picture presentation format",
1675 values: { a : "Standard sound aperture, reduced frame",
1676 b : "Nonanamorphic (wide-screen)",
1678 d : "Anamorphic (wide-screen)",
1679 e : "Other-wide screen format",
1680 f : "Standard. silent aperture, full frame",
1687 label : "Sound on medium or separate",
1688 values: { a : "Sound on medium",
1689 b : "Sound separate from medium",
1695 label : "Medium for sound",
1696 values: { a : "Optical sound track on motion picture film",
1697 b : "Magnetic sound track on motion picture film",
1698 c : "Magnetic audio tape in cartridge",
1700 e : "Magnetic audio tape on reel",
1701 f : "Magnetic audio tape in cassette",
1702 g : "Optical and magnetic sound track on film",
1711 label : "Dimensions",
1712 values: { a : "Standard 8 mm.",
1713 b : "Super 8 mm./single 8 mm.",
1725 label : "Configuration of playback channels",
1726 values: { k : "Mixed",
1728 n : "Not applicable",
1729 q : "Multichannel, surround or quadraphonic",
1737 label : "Production elements",
1738 values: { a : "Work print",
1742 e : "Mixing tracks",
1743 f : "Title bands/inter-title rolls",
1744 g : "Production rolls",
1745 n : "Not applicable",
1752 label : "Non-projected Graphic",
1757 values: { c : "Collage",
1760 f : "Photo-mechanical print",
1761 g : "Photonegative",
1765 l : "Technical drawing",
1767 o : "Flash/activity card",
1775 values: { a : "One color",
1776 b : "Black-and-white",
1786 label : "Primary support material",
1787 values: { a : "Canvas",
1788 b : "Bristol board",
1789 c : "Cardboard/illustration board",
1795 m : "Mixed collection",
1808 label : "Secondary support material",
1809 values: { a : "Canvas",
1810 b : "Bristol board",
1811 c : "Cardboard/illustration board",
1817 m : "Mixed collection",
1831 label : "Projected Graphic",
1836 values: { c : "Film cartridge",
1838 f : "Film filmstrip type",
1839 o : "Filmstrip roll",
1848 values: { b : "Black-and-white",
1852 n : "Not applicable",
1859 label : "Base of emulsion",
1860 values: { d : "Glass",
1863 k : "Film base, other than safety film",
1864 m : "Mixed collection",
1872 label : "Sound on medium or separate",
1873 values: { a : "Sound on medium",
1874 b : "Sound separate from medium",
1880 label : "Medium for sound",
1881 values: { a : "Optical sound track on motion picture film",
1882 b : "Magnetic sound track on motion picture film",
1883 c : "Magnetic audio tape in cartridge",
1885 e : "Magnetic audio tape on reel",
1886 f : "Magnetic audio tape in cassette",
1887 g : "Optical and magnetic sound track on film",
1896 label : "Dimensions",
1897 values: { a : "Standard 8 mm.",
1898 b : "Super 8 mm./single 8 mm.",
1904 j : "2 x 2 in. (5 x 5 cm.)",
1905 k : "2 1/4 x 2 1/4 in. (6 x 6 cm.)",
1906 s : "4 x 5 in. (10 x 13 cm.)",
1907 t : "5 x 7 in. (13 x 18 cm.)",
1908 v : "8 x 10 in. (21 x 26 cm.)",
1909 w : "9 x 9 in. (23 x 23 cm.)",
1910 x : "10 x 10 in. (26 x 26 cm.)",
1911 y : "7 x 7 in. (18 x 18 cm.)",
1918 label : "Secondary support material",
1919 values: { c : "Cardboard",
1923 j : "Metal and glass",
1924 k : "Synthetics and glass",
1925 m : "Mixed collection",
1933 label : "Remote-sensing Image",
1938 values: { u : "Unspecified" }
1942 label : "Altitude of sensor",
1943 values: { a : "Surface",
1946 n : "Not applicable",
1953 label : "Attitude of sensor",
1954 values: { a : "Low oblique",
1957 n : "Not applicable",
1963 label : "Cloud cover",
1964 values: { 0 : "0-09%",
1974 n : "Not applicable",
1980 label : "Platform construction type",
1981 values: { a : "Balloon",
1982 b : "Aircraft-low altitude",
1983 c : "Aircraft-medium altitude",
1984 d : "Aircraft-high altitude",
1985 e : "Manned spacecraft",
1986 f : "Unmanned spacecraft",
1987 g : "Land-based remote-sensing device",
1988 h : "Water surface-based remote-sensing device",
1989 i : "Submersible remote-sensing device",
1990 n : "Not applicable",
1997 label : "Platform use category",
1998 values: { a : "Meteorological",
1999 b : "Surface observing",
2000 c : "Space observing",
2002 n : "Not applicable",
2009 label : "Sensor type",
2010 values: { a : "Active",
2018 label : "Data type",
2019 values: { nn : "Not applicable",
2022 aa : "Visible light",
2023 da : "Near infrared",
2024 db : "Middle infrared",
2025 dc : "Far infrared",
2026 dd : "Thermal infrared",
2027 de : "Shortwave infrared (SWIR)",
2028 df : "Reflective infrared",
2029 dv : "Combinations",
2030 dz : "Other infrared data",
2031 ga : "Sidelooking airborne radar (SLAR)",
2032 gb : "Synthetic aperture radar (SAR-single frequency)",
2033 gc : "SAR-multi-frequency (multichannel)",
2034 gd : "SAR-like polarization",
2035 ge : "SAR-cross polarization",
2036 gf : "Infometric SAR",
2037 gg : "Polarmetric SAR",
2038 gu : "Passive microwave mapping",
2039 gz : "Other microwave data",
2040 ja : "Far ultraviolet",
2041 jb : "Middle ultraviolet",
2042 jc : "Near ultraviolet",
2043 jv : "Ultraviolet combinations",
2044 jz : "Other ultraviolet data",
2045 ma : "Multi-spectral, multidata",
2046 mb : "Multi-temporal",
2047 mm : "Combination of various data types",
2048 pa : "Sonar-water depth",
2049 pb : "Sonar-bottom topography images, sidescan",
2050 pc : "Sonar-bottom topography, near-surface",
2051 pd : "Sonar-bottom topography, near-bottom",
2052 pe : "Seismic surveys",
2053 pz : "Other acoustical data",
2054 ra : "Gravity anomales (general)",
2058 sa : "Magnetic field",
2059 ta : "Radiometric surveys"
2065 label : "Sound Recording",
2070 values: { d : "Sound disc",
2072 g : "Sound cartridge",
2073 i : "Sound-track film",
2075 s : "Sound cassette",
2076 t : "Sound-tape reel",
2078 w : "Wire recording",
2085 values: { a : "16 rpm",
2105 label : "Configuration of playback channels",
2106 values: { m : "Monaural",
2115 label : "Groove width or pitch",
2116 values: { m : "Microgroove/fine",
2117 n : "Not applicable",
2118 s : "Coarse/standard",
2125 label : "Dimensions",
2126 values: { a : "3 in.",
2132 g : "4 3/4 in. (12 cm.)",
2133 j : "3 7/8 x 2 1/2 in.",
2134 o : "5 1/4 x 3 7/8 in.",
2135 s : "2 3/4 x 4 in.",
2136 n : "Not applicable",
2143 label : "Tape width",
2144 values: { l : "1/8 in.",
2146 n : "Not applicable",
2155 label : "Tape configuration ",
2156 values: { a : "Full (1) track",
2157 b : "Half (2) track",
2158 c : "Quarter (4) track",
2162 n : "Not applicable",
2169 label : "Special playback",
2170 values: { a : "NAB standard",
2171 b : "CCIR standard",
2172 c : "Dolby-B encoded, standard Dolby",
2174 e : "Digital recording",
2175 f : "Dolby-A encoded",
2176 g : "Dolby-C encoded",
2178 n : "Not applicable",
2185 label : "Capture and storage",
2186 values: { a : "Acoustical capture, direct storage",
2187 b : "Direct storage, not acoustical",
2188 d : "Digital storage",
2189 e : "Analog electrical storage",
2197 label : "Tactile Material",
2202 values: { a : "Moon",
2205 d : "Tactile, with no writing system",
2212 label : "Class of braille writing",
2213 values: { a : "Literary braille",
2214 b : "Format code braille",
2215 c : "Mathematics and scientific braille",
2216 d : "Computer braille",
2217 e : "Music braille",
2218 m : "Multiple braille types",
2219 n : "Not applicable",
2226 label : "Level of contraction",
2227 values: { a : "Uncontracted",
2230 n : "Not applicable",
2237 label : "Braille music format",
2238 values: { a : "Bar over bar",
2240 c : "Line over line",
2243 f : "Section by section",
2246 i : "Spanner short form scoring",
2247 j : "Short form scoring",
2249 l : "Vertical score",
2250 n : "Not applicable",
2257 label : "Special physical characteristics",
2258 values: { a : "Print/braille",
2259 b : "Jumbo or enlarged braille",
2260 n : "Not applicable",
2268 label : "Videorecording",
2273 values: { c : "Videocartridge",
2275 f : "Videocassette",
2284 values: { b : "Black-and-white",
2287 n : "Not applicable",
2294 label : "Videorecording format",
2295 values: { a : "Beta",
2317 label : "Sound on medium or separate",
2318 values: { a : "Sound on medium",
2319 b : "Sound separate from medium",
2325 label : "Medium for sound",
2326 values: { a : "Optical sound track on motion picture film",
2327 b : "Magnetic sound track on motion picture film",
2328 c : "Magnetic audio tape in cartridge",
2330 e : "Magnetic audio tape on reel",
2331 f : "Magnetic audio tape in cassette",
2332 g : "Optical and magnetic sound track on motion picture film",
2341 label : "Dimensions",
2342 values: { a : "8 mm.",
2354 label : "Configuration of playback channel",
2355 values: { k : "Mixed",
2357 n : "Not applicable",
2358 q : "Multichannel, surround or quadraphonic",