marc-ts 0.2.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -130
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +410 -387
- package/dist/index.js.map +1 -1
- package/dist/marcjson.cjs +1 -1
- package/dist/marcjson.cjs.map +1 -1
- package/dist/marcjson.js +1 -1
- package/dist/marcjson.js.map +1 -1
- package/dist/marctxt.cjs +1 -1
- package/dist/marctxt.cjs.map +1 -1
- package/dist/marctxt.js +1 -1
- package/dist/marctxt.js.map +1 -1
- package/dist/marcxml.cjs +6 -6
- package/dist/marcxml.cjs.map +1 -1
- package/dist/marcxml.d.ts +8 -3
- package/dist/marcxml.js +188 -127
- package/dist/marcxml.js.map +1 -1
- package/dist/parser.d.ts +10 -1
- package/dist/serializer.d.ts +11 -1
- package/dist/{types-c4Mo9m9u.js → types-BMKDHD1l.js} +1 -1
- package/dist/types-BMKDHD1l.js.map +1 -0
- package/dist/{types-CJcxHJff.cjs → types-CsOhH4OF.cjs} +1 -1
- package/dist/types-CsOhH4OF.cjs.map +1 -0
- package/dist/types.d.ts +23 -1
- package/dist/warnings-6yoB06xI.cjs +3 -0
- package/dist/warnings-6yoB06xI.cjs.map +1 -0
- package/dist/warnings-Bt6wvWFe.js +13 -0
- package/dist/warnings-Bt6wvWFe.js.map +1 -0
- package/package.json +2 -2
- package/dist/types-CJcxHJff.cjs.map +0 -1
- package/dist/types-c4Mo9m9u.js.map +0 -1
package/README.md
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
## Features
|
|
9
9
|
|
|
10
10
|
- **Four formats** — ISO2709 binary, MARCXML, MARC-in-JSON, MARCBreaker/marctxt
|
|
11
|
-
- **Consistent API** — every format uses `parse*(input) → MarcRecord[]` and `serialize*(records
|
|
12
|
-
- **
|
|
13
|
-
- **Zero dependencies** —
|
|
11
|
+
- **Consistent API** — every format uses `parse*(input) → MarcRecord[]` and `serialize*(records) → output`
|
|
12
|
+
- **Functional-style** — all operations return new objects; originals are never mutated
|
|
13
|
+
- **Zero dependencies** — no runtime deps, including no XML parser. MARCXML has only 5 element types with no arbitrary nesting, so it's parsed with a lightweight hand-rolled tokenizer instead of a full DOM/SAX library. Works in Node.js and modern browsers.
|
|
14
14
|
- **Fully typed** — strict TypeScript throughout
|
|
15
15
|
|
|
16
16
|
## Installation
|
|
@@ -27,21 +27,15 @@ import { parseMarcXml, serializeMarcXml } from 'marc-ts/xml';
|
|
|
27
27
|
import { parseMarcJson, serializeMarcJsonString } from 'marc-ts/json';
|
|
28
28
|
import { parseMarcTxt, serializeMarcTxt } from 'marc-ts/txt';
|
|
29
29
|
|
|
30
|
-
// Binary (ISO2709) — splits on 0x1D, returns all records
|
|
31
30
|
const records = parseMarcBinary(buffer);
|
|
32
31
|
console.log(title(records[0]));
|
|
33
|
-
console.log(author(records[0]));
|
|
34
|
-
const binary = serializeMarcBinary(records);
|
|
35
32
|
|
|
36
|
-
// MARCXML — parses <collection> or bare <record> elements
|
|
37
33
|
const xmlRecords = parseMarcXml(xmlString);
|
|
38
34
|
const xml = serializeMarcXml(xmlRecords);
|
|
39
35
|
|
|
40
|
-
// MARC-in-JSON — accepts array, single object, or JSON string
|
|
41
36
|
const jsonRecords = parseMarcJson(jsonString);
|
|
42
37
|
const json = serializeMarcJsonString(jsonRecords);
|
|
43
38
|
|
|
44
|
-
// MARCBreaker — records separated by blank lines
|
|
45
39
|
const txtRecords = parseMarcTxt(txtString);
|
|
46
40
|
const txt = serializeMarcTxt(txtRecords);
|
|
47
41
|
```
|
|
@@ -52,41 +46,33 @@ const txt = serializeMarcTxt(txtRecords);
|
|
|
52
46
|
|
|
53
47
|
```typescript
|
|
54
48
|
import { parseMarcBinary, serializeMarcBinary } from 'marc-ts';
|
|
55
|
-
import type { ParseOptions, SerializeOptions } from 'marc-ts';
|
|
56
49
|
```
|
|
57
50
|
|
|
58
51
|
#### `parseMarcBinary(buffer, options?): MarcRecord[]`
|
|
59
52
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
```typescript
|
|
63
|
-
const records = parseMarcBinary(buffer);
|
|
64
|
-
const strict = parseMarcBinary(buffer, { strict: true });
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
**`ParseOptions`**
|
|
53
|
+
Splits on `0x1D` record terminators and parses each record. Failed records are skipped in lenient mode; `strict: true` throws on the first error.
|
|
68
54
|
|
|
69
55
|
| Option | Type | Default | Description |
|
|
70
56
|
|--------|------|---------|-------------|
|
|
71
57
|
| `strict` | `boolean` | `false` | Throw on fatal parse errors instead of skipping |
|
|
72
|
-
| `maxWarnings` | `number` | `100` | Stop collecting warnings after this many |
|
|
58
|
+
| `maxWarnings` | `number` | `100` | Stop collecting warnings after this many (per record) |
|
|
73
59
|
|
|
74
|
-
|
|
60
|
+
Leader byte 9 controls character decoding: `'a'` = UTF-8, `' '` = MARC-8. MARC-8 handles ANSEL Latin, Greek, Hebrew, Cyrillic, Arabic, and sub/superscript scripts. EACC/CJK coverage is minimal (~33 of ~16k triples) — prefer UTF-8 sources for CJK catalogs.
|
|
75
61
|
|
|
76
|
-
#### `
|
|
62
|
+
#### `parseMarcBinaryWithWarnings(buffer, options?): ParseBatchResult`
|
|
77
63
|
|
|
78
|
-
|
|
64
|
+
Same as `parseMarcBinary`, but returns per-record results with warnings. Failed records appear with `record: null`.
|
|
79
65
|
|
|
80
|
-
|
|
81
|
-
const buffer = serializeMarcBinary(records);
|
|
82
|
-
const marc8Buffer = serializeMarcBinary(records, { encoding: 'marc8' });
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
**`SerializeOptions`**
|
|
66
|
+
#### `serializeMarcBinary(records, options?): Uint8Array`
|
|
86
67
|
|
|
87
68
|
| Option | Type | Default | Description |
|
|
88
69
|
|--------|------|---------|-------------|
|
|
89
70
|
| `encoding` | `'utf8' \| 'marc8'` | `'utf8'` | Character encoding; `'marc8'` replaces unsupported Unicode with `?` |
|
|
71
|
+
| `maxWarnings` | `number` | `100` | Stop collecting warnings after this many (per record) |
|
|
72
|
+
|
|
73
|
+
#### `serializeMarcBinaryWithWarnings(records, options?): SerializeBatchResult`
|
|
74
|
+
|
|
75
|
+
Same as `serializeMarcBinary`, but returns per-record serialization warnings alongside the bytes.
|
|
90
76
|
|
|
91
77
|
---
|
|
92
78
|
|
|
@@ -98,19 +84,11 @@ import { parseMarcXml, serializeMarcXml } from 'marc-ts/xml';
|
|
|
98
84
|
|
|
99
85
|
#### `parseMarcXml(xml): MarcRecord[]`
|
|
100
86
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
```typescript
|
|
104
|
-
const records = parseMarcXml(xmlString);
|
|
105
|
-
```
|
|
87
|
+
Accepts `<collection>`, bare `<record>` elements, or namespace-prefixed variants. Returns `[]` for empty input.
|
|
106
88
|
|
|
107
89
|
#### `serializeMarcXml(records): string`
|
|
108
90
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
```typescript
|
|
112
|
-
const xml = serializeMarcXml(records);
|
|
113
|
-
```
|
|
91
|
+
Produces a full MARCXML `<collection>` document with XML declaration and MARC21 namespace.
|
|
114
92
|
|
|
115
93
|
---
|
|
116
94
|
|
|
@@ -118,52 +96,18 @@ const xml = serializeMarcXml(records);
|
|
|
118
96
|
|
|
119
97
|
```typescript
|
|
120
98
|
import { parseMarcJson, serializeMarcJson, serializeMarcJsonString } from 'marc-ts/json';
|
|
121
|
-
import type { MarcJsonObject } from 'marc-ts/json';
|
|
122
99
|
```
|
|
123
100
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
```json
|
|
127
|
-
{
|
|
128
|
-
"leader": "01142cam a2200301 a 4500",
|
|
129
|
-
"fields": [
|
|
130
|
-
{ "001": "5490" },
|
|
131
|
-
{ "245": { "subfields": [{ "a": "The Hobbit" }], "ind1": "1", "ind2": "0" } }
|
|
132
|
-
]
|
|
133
|
-
}
|
|
134
|
-
```
|
|
101
|
+
Implements the [MARC-in-JSON](https://wiki.code4lib.org/MARCJSONification) spec.
|
|
135
102
|
|
|
136
103
|
#### `parseMarcJson(json): MarcRecord[]`
|
|
137
104
|
|
|
138
|
-
|
|
139
|
-
- A JSON string whose top-level value is an array or a single object
|
|
140
|
-
- A `MarcJsonObject[]` array
|
|
141
|
-
- A single `MarcJsonObject`
|
|
142
|
-
|
|
143
|
-
Always returns `MarcRecord[]`. Throws on structural errors.
|
|
144
|
-
|
|
145
|
-
```typescript
|
|
146
|
-
const records = parseMarcJson(jsonString); // JSON string (array or single)
|
|
147
|
-
const records = parseMarcJson([obj1, obj2]); // plain object array
|
|
148
|
-
const records = parseMarcJson(singleObj); // single object → one-element array
|
|
149
|
-
```
|
|
105
|
+
Accepts a JSON string (array or single object), a `MarcJsonObject[]`, or a single `MarcJsonObject`.
|
|
150
106
|
|
|
151
107
|
#### `serializeMarcJson(records): MarcJsonObject[]`
|
|
152
108
|
|
|
153
|
-
Serialize records to an array of MARC-in-JSON plain objects.
|
|
154
|
-
|
|
155
|
-
```typescript
|
|
156
|
-
const objs = serializeMarcJson(records);
|
|
157
|
-
```
|
|
158
|
-
|
|
159
109
|
#### `serializeMarcJsonString(records): string`
|
|
160
110
|
|
|
161
|
-
Serialize records directly to a JSON string (a JSON array).
|
|
162
|
-
|
|
163
|
-
```typescript
|
|
164
|
-
const json = serializeMarcJsonString(records);
|
|
165
|
-
```
|
|
166
|
-
|
|
167
111
|
---
|
|
168
112
|
|
|
169
113
|
### MARCBreaker / marctxt (`marc-ts/txt`)
|
|
@@ -172,49 +116,18 @@ const json = serializeMarcJsonString(records);
|
|
|
172
116
|
import { parseMarcTxt, serializeMarcTxt } from 'marc-ts/txt';
|
|
173
117
|
```
|
|
174
118
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
```
|
|
178
|
-
=LDR 00706cam a2200217 a 4500
|
|
179
|
-
=001 5490
|
|
180
|
-
=003 OCoLC
|
|
181
|
-
=245 14$aThe Hobbit /$cJ.R.R. Tolkien.
|
|
182
|
-
=650 \1$aHobbits (Fictitious characters)$vFiction.
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
**Value escaping** — reserved characters in field values are escaped as follows:
|
|
186
|
-
|
|
187
|
-
| Character | Escaped form |
|
|
188
|
-
|-----------|-------------|
|
|
189
|
-
| `$` | `{dollar}` |
|
|
190
|
-
| `{` | `{lcub}` |
|
|
191
|
-
| `}` | `{rcub}` |
|
|
192
|
-
| `\` | `{bsol}` |
|
|
119
|
+
Line-oriented format: one field per line, blank lines between records, `$` for subfield delimiters, `\` for blank indicators.
|
|
193
120
|
|
|
194
|
-
|
|
121
|
+
Reserved characters are escaped: `$` → `{dollar}`, `{` → `{lcub}`, `}` → `{rcub}`, `\` → `{bsol}`.
|
|
195
122
|
|
|
196
123
|
#### `parseMarcTxt(text): MarcRecord[]`
|
|
197
124
|
|
|
198
|
-
Parse a marctxt string. Accepts `\n` and `\r\n` line endings. Records are separated by blank lines. Returns all records found.
|
|
199
|
-
|
|
200
|
-
```typescript
|
|
201
|
-
const records = parseMarcTxt(txtString);
|
|
202
|
-
```
|
|
203
|
-
|
|
204
125
|
#### `serializeMarcTxt(records): string`
|
|
205
126
|
|
|
206
|
-
Serialize records to a marctxt string, with records separated by blank lines.
|
|
207
|
-
|
|
208
|
-
```typescript
|
|
209
|
-
const txt = serializeMarcTxt(records);
|
|
210
|
-
```
|
|
211
|
-
|
|
212
127
|
---
|
|
213
128
|
|
|
214
129
|
## Convenience Accessors
|
|
215
130
|
|
|
216
|
-
Extract common bibliographic metadata from any `MarcRecord`:
|
|
217
|
-
|
|
218
131
|
```typescript
|
|
219
132
|
import { title, titleProper, author, edition, publisher, publicationDate,
|
|
220
133
|
isbn, issn, lccn, subjects, seriesStatement } from 'marc-ts';
|
|
@@ -243,46 +156,32 @@ import { getField, getFields, getSubfield, getSubfields, getAllSubfields } from
|
|
|
243
156
|
import { isControlField, isDataField } from 'marc-ts';
|
|
244
157
|
```
|
|
245
158
|
|
|
246
|
-
#### `getField(record, tag)` / `getFields(record, tag)`
|
|
247
|
-
|
|
248
159
|
```typescript
|
|
249
160
|
const field = getField(record, '245'); // first match or undefined
|
|
250
161
|
const fields = getFields(record, '650'); // all matches
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
#### `getSubfield(field, code)` / `getSubfields(field, code)`
|
|
254
162
|
|
|
255
|
-
```typescript
|
|
256
163
|
if (field && isDataField(field)) {
|
|
257
|
-
const a = getSubfield(field, 'a');
|
|
258
|
-
const xs = getSubfields(field, 'x');
|
|
164
|
+
const a = getSubfield(field, 'a');
|
|
165
|
+
const xs = getSubfields(field, 'x');
|
|
166
|
+
const all = getAllSubfields(field); // [{ code, value }, ...]
|
|
259
167
|
}
|
|
260
168
|
```
|
|
261
169
|
|
|
262
|
-
#### `getAllSubfields(field)`
|
|
263
|
-
|
|
264
|
-
```typescript
|
|
265
|
-
const all = getAllSubfields(field); // [{ code, value }, ...]
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
---
|
|
269
|
-
|
|
270
170
|
## Wildcard Querying
|
|
271
171
|
|
|
272
172
|
```typescript
|
|
273
173
|
import { getFieldsByPattern, getFirstFieldByPattern } from 'marc-ts';
|
|
274
174
|
|
|
275
175
|
const subjects = getFieldsByPattern(record, '6..'); // all 6XX fields
|
|
276
|
-
const first7xx = getFirstFieldByPattern(record, '7XX');
|
|
277
176
|
```
|
|
278
177
|
|
|
279
178
|
`.` and `X` each match any single digit.
|
|
280
179
|
|
|
281
180
|
---
|
|
282
181
|
|
|
283
|
-
## Field Operations
|
|
182
|
+
## Field Operations
|
|
284
183
|
|
|
285
|
-
All operations return
|
|
184
|
+
All operations return new objects — originals are never mutated.
|
|
286
185
|
|
|
287
186
|
```typescript
|
|
288
187
|
import {
|
|
@@ -294,11 +193,10 @@ import {
|
|
|
294
193
|
const r1 = appendField(record, newField);
|
|
295
194
|
const r2 = insertFieldBefore(record, '700', newField);
|
|
296
195
|
const r3 = insertFieldAfter(record, '245', newField);
|
|
297
|
-
const r4 = insertGroupedField(record, newField); // maintains MARC
|
|
196
|
+
const r4 = insertGroupedField(record, newField); // maintains MARC tag order
|
|
298
197
|
const r5 = removeFields(record, '650');
|
|
299
|
-
const r6 = removeField(record, specificField);
|
|
198
|
+
const r6 = removeField(record, specificField); // reference equality
|
|
300
199
|
|
|
301
|
-
// Subfield operations — return a new DataField
|
|
302
200
|
const f1 = addSubfield(field, 'b', 'Subtitle');
|
|
303
201
|
const f2 = removeSubfield(field, 'x');
|
|
304
202
|
const f3 = replaceSubfield(field, 'a', 'New value');
|
|
@@ -330,7 +228,7 @@ import type { MarcRecord, ControlField, DataField, Subfield,
|
|
|
330
228
|
|
|
331
229
|
## Development
|
|
332
230
|
|
|
333
|
-
Requires Node.js **20.19** or **22.12+** (driven by Vite 8).
|
|
231
|
+
Requires Node.js **20.19** or **22.12+** (driven by Vite 8).
|
|
334
232
|
|
|
335
233
|
```bash
|
|
336
234
|
npm test # run tests
|
package/dist/index.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("./types-CJcxHJff.cjs");var ee=27,m="�",k=new Map([[33,"Ł"],[34,"Ø"],[35,"Đ"],[36,"Þ"],[37,"Æ"],[38,"Œ"],[39,"ʹ"],[40,"·"],[41,"♭"],[42,"®"],[43,"±"],[44,"Ơ"],[45,"Ư"],[46,"ʼ"],[48,"ʻ"],[49,"ł"],[50,"ø"],[51,"đ"],[52,"þ"],[53,"æ"],[54,"œ"],[55,"ʺ"],[56,"ı"],[57,"£"],[58,"ð"],[59,"ơ"],[60,"ư"],[63,"°"]]),W=new Map([[96,"̉"],[97,"̀"],[98,"́"],[99,"̂"],[100,"̃"],[101,"̄"],[102,"̆"],[103,"̇"],[104,"̈"],[105,"̌"],[106,"̊"],[107,"︠"],[108,"︡"],[109,"̕"],[110,"̋"],[111,"̐"],[112,"̧"],[113,"̨"],[114,"̣"],[115,"̤"],[116,"̥"],[117,"̳"],[118,"̲"],[119,"̦"],[120,"̜"],[121,"̮"],[122,"︢"],[123,"︣"],[126,"̓"]]),te=new Map(Array.from(W.entries()).map(([e,t])=>[t,e+128])),ne=new Map(Array.from(k.entries()).map(([e,t])=>[t,e+128])),re=M(65,"ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ",97,"αβγδεζηθικλμνξοπρστυφχψω"),ie=M(96,"אבגדהוזחטיךכלםמןנסעףפץצקרשת"),se=M(65,"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ",97,"абвгдежзийклмнопрстуфхцчшщъыьэюя"),oe=new Map([[33,"ء"],[34,"آ"],[35,"أ"],[36,"ؤ"],[37,"إ"],[38,"ئ"],[39,"ا"],[40,"ب"],[41,"ة"],[42,"ت"],[43,"ث"],[44,"ج"],[45,"ح"],[46,"خ"],[47,"د"],[48,"ذ"],[49,"ر"],[50,"ز"],[51,"س"],[52,"ش"],[53,"ص"],[54,"ض"],[55,"ط"],[56,"ظ"],[57,"ع"],[58,"غ"],[65,"ف"],[66,"ق"],[67,"ك"],[68,"ل"],[69,"م"],[70,"ن"],[71,"ه"],[72,"و"],[73,"ى"],[74,"ي"]]),ae=new Map([[40,"₍"],[41,"₎"],[43,"₊"],[45,"₋"],[48,"₀"],[49,"₁"],[50,"₂"],[51,"₃"],[52,"₄"],[53,"₅"],[54,"₆"],[55,"₇"],[56,"₈"],[57,"₉"]]),ce=new Map([[40,"⁽"],[41,"⁾"],[43,"⁺"],[45,"⁻"],[48,"⁰"],[49,"¹"],[50,"²"],[51,"³"],[52,"⁴"],[53,"⁵"],[54,"⁶"],[55,"⁷"],[56,"⁸"],[57,"⁹"],[110,"ⁿ"]]),le=new Map([[2171169,"一"],[2171170,"丁"],[2171171,"七"],[2171172,"万"],[2171173,"丈"],[2171174,"三"],[2171175,"上"],[2171176,"下"],[2171177,"不"],[2171178,"与"],[2171179,"丐"],[2171180,"丑"],[2171181,"且"],[2171182,"世"],[2171183,"丘"],[2171184,"丙"],[2171185,"业"],[2171186,"丛"],[2171187,"东"],[2171188,"丝"],[2171189,"丞"],[2171190,"丟"],[2171191,"丠"],[2171192,"両"],[2171193,"丢"],[2171194,"两"],[2171195,"严"],[2171196,"並"],[2171197,"丧"],[2171198,"丨"],[2171199,"个"],[2171200,"丫"],[2171201,"中"],[2171202,"丰"]]),de={ascii:new Map,ansel:fe(k,W),greek:re,hebrew:ie,cyrillic:se,arabic:oe,subscript:ae,superscript:ce};function M(...e){const t=new Map;for(let n=0;n<e.length;n+=2){const r=e[n],i=e[n+1];Array.from(i).forEach((s,o)=>t.set(r+o,s))}return t}function fe(...e){const t=new Map;for(const n of e)for(const[r,i]of n)t.set(r,i);return t}function T(e){const t=e.codePointAt(0);return t>=768&&t<=879||t>=65056&&t<=65071}function I(e,t){return t?e-128:e}function ue(e,t,n){const r=I(e,n);return t==="ascii"?r>=32&&r<=126?String.fromCharCode(r):m:de[t].get(r)??m}function ge(e,t,n){if(t+2>=e.length)return{char:m,next:e.length};const r=I(e[t],n),i=I(e[t+1],n),s=I(e[t+2],n),o=r<<16|i<<8|s;return{char:le.get(o)??m,next:t+3}}function he(e,t,n){if(t+1>=e.length)return{char:m,next:e.length};const r=e[t+1];let i,s;if(r===40||r===44)i="g0",s=t+2;else if(r===41||r===45)i="g1",s=t+2;else if(r===36){const l=e[t+2];if(l===void 0)return{char:m,next:e.length};l===40||l===44?(i="g0",s=t+3):l===41||l===45?(i="g1",s=t+3):(i="g0",s=t+2)}else return{char:m,next:t+2};if(s>=e.length)return{char:m,next:e.length};let o=e[s];if(o===33){if(s++,s>=e.length)return{char:m,next:e.length};o=e[s]}const c=Ee(o);return c?{char:"",next:pe(n,i,c,s+1)}:{char:m,next:s+1}}function pe(e,t,n,r){return e[t]=n,r}function Ee(e){switch(e){case 49:return"eacc";case 50:return"hebrew";case 51:return"arabic";case 52:return"cyrillic";case 66:return"ascii";case 69:return"ansel";case 78:return"cyrillic";case 81:return"greek";case 83:return"greek";case 98:return"subscript";case 112:return"superscript";default:return}}function j(e){const t={g0:"ascii",g1:"ansel"},n=[];let r="",i=0;const s=o=>{if(o){if(T(o)){r+=o;return}n.push(o+r),r=""}};for(;i<e.length;){const o=e[i];if(o===ee){const d=he(e,i,t);s(d.char),i=d.next;continue}if(o<32){s(String.fromCharCode(o)),i++;continue}const c=o>=160,l=c?t.g1:t.g0;if(l==="eacc"){const d=ge(e,i,c);s(d.char),i=d.next;continue}s(ue(o,l,c)),i++}return r&&n.push(r),n.join("")}function we(e){return L(e).bytes}function L(e){const t=e.normalize("NFD"),n=[];let r=0,i=0;for(;i<t.length;){const s=t.codePointAt(i),o=t[i];if(T(o)){n.push(63),r++,i++;continue}let c=i+(s>65535?2:1);const l=[];for(;c<t.length&&T(t[c]);){const d=te.get(t[c]);d!==void 0?l.push(d):(l.push(63),r++),c++}if(n.push(...l),s<128)n.push(s);else{const d=ne.get(o);d!==void 0?n.push(d):(n.push(63),r++)}i=c}return{bytes:new Uint8Array(n),lossyCount:r}}var B=31,H=30,y=24,A=12,C=3,U=4,N=new TextDecoder("utf-8",{fatal:!1});function q(e){return N.decode(e)}function z(e,t=16){const n=e.slice(0,t),r=Array.from(n,i=>i.toString(16).padStart(2,"0")).join(" ");return e.length>t?`${r} … (${e.length} bytes)`:r}function O(e,t={}){const n=t.strict??!1,r=t.maxWarnings??100,i=[];if(e.length<y+1){const a=h("truncated_record",`Record too short: ${e.length} bytes`);if(n)throw new Error(a.message);return i.push(a),{record:null,warnings:i}}const s=Se(e);if(!be(s,i,n)&&(n||i.length>=r))return{record:null,warnings:i};const o=parseInt(s.substring(0,5),10);if(isNaN(o)||o>e.length){const a=h("invalid_leader",`Invalid record length in leader: ${s.substring(0,5)}`);if(n)throw new Error(a.message);i.push(a)}else if(o<e.length){const a=h("truncated_record",`Buffer is longer than the record length declared in the leader: leader says ${o}, buffer is ${e.length} bytes. Trailing bytes ignored (likely a concatenated stream — split on 0x1D first).`);if(n)throw new Error(a.message);i.push(a),e=e.slice(0,o)}const c=parseInt(s.substring(12,17),10);if(isNaN(c)){const a=h("invalid_leader",`Invalid base address in leader: ${s.substring(12,17)}`);if(n)throw new Error(a.message);return i.push(a),{record:null,warnings:i}}const l=y,d=e.indexOf(H,l);if(d===-1){const a=h("invalid_directory","Directory terminator not found");if(n)throw new Error(a.message);return i.push(a),{record:null,warnings:i}}const g=Fe(e.slice(l,d),i,n,r);if(g.length===0){const a=h("invalid_directory","No directory entries found");if(n)throw new Error(a.message);return i.push(a),{record:null,warnings:i}}const f=s[9]===" ";if(s[9]!==" "&&s[9]!=="a"){const a=h("invalid_leader",`Leader position 9 (encoding flag) is '${s[9]}'; expected 'a' (UTF-8) or ' ' (MARC-8). Defaulting to UTF-8.`);if(n)throw new Error(a.message);i.push(a)}return{record:{leader:s,fields:ye(e,g,c,f?j:a=>N.decode(a),i,n,r)},warnings:i}}var ve=29;function me(e,t){const n=[];let r=0;for(let i=0;i<e.length;i++)if(e[i]===ve){const s=e.slice(r,i+1);if(s.length>0){const o=O(s,t);o.record&&n.push(o.record)}r=i+1}if(r<e.length){const i=O(e.slice(r),t);i.record&&n.push(i.record)}return n}function Se(e){const t=e.slice(0,y);return N.decode(t)}function be(e,t,n){if(e.length!==y){const r=h("invalid_leader",`Leader length is ${e.length}, expected ${y}`);if(n)throw new Error(r.message);return t.push(r),!1}if(e[10]!=="2"){const r=h("invalid_leader",`Leader position 10 (indicator count) is '${e[10]}', expected '2'`);t.push(r)}if(e[11]!=="2"){const r=h("invalid_leader",`Leader position 11 (subfield code length) is '${e[11]}', expected '2'`);t.push(r)}return!0}function Fe(e,t,n,r){const i=[];for(let s=0;s<e.length;s+=A){if(t.length>=r){t.push(h("truncated_record",`Directory parsing halted after reaching maxWarnings limit (${r}); remaining ${e.length-s} bytes of directory not parsed.`));break}if(s+A>e.length)break;const o=e.slice(s,s+A),c=N.decode(o),l=c.substring(0,C),d=c.substring(C,C+U),g=c.substring(C+U,A),f=parseInt(d,10),a=parseInt(g,10);if(isNaN(f)||isNaN(a)){const E=h("invalid_directory",`Invalid directory entry for tag ${l}: length=${d}, position=${g}`);if(n)throw new Error(E.message);t.push(E);continue}i.push({tag:l,fieldLength:f,startingPosition:a})}return i}function ye(e,t,n,r,i,s,o){const c=[];for(const l of t){if(i.length>=o){i.push(h("truncated_record",`Field parsing halted after reaching maxWarnings limit (${o}); not all directory entries were processed.`,void 0,l.tag));break}const d=n+l.startingPosition,g=d+l.fieldLength-1;if(d>=e.length||g>e.length){const a=h("invalid_field",`Field ${l.tag} out of bounds: start=${d}, end=${g}, buffer length=${e.length}`,d,l.tag);if(s)throw new Error(a.message);i.push(a);continue}let f;if(e[g]!==H){const a=h("invalid_field",`Field ${l.tag} does not end with a field terminator at byte ${g} (found 0x${(e[g]??0).toString(16).padStart(2,"0")}); using the full declared length without stripping a terminator byte.`,d,l.tag);if(s)throw new Error(a.message);i.push(a),f=e.slice(d,d+l.fieldLength)}else f=e.slice(d,g);if(l.tag.startsWith("00")){try{const a=r(f);c.push({tag:l.tag,data:a})}catch(a){const E=h("encoding_error",`Failed to decode control field ${l.tag}: ${a instanceof Error?a.message:String(a)}. Raw bytes (hex): ${z(f)}.`,d,l.tag);if(s)throw new Error(E.message);i.push(E),c.push({tag:l.tag,data:q(f)})}continue}if(f.length<2){const a=h("invalid_field",`Data field ${l.tag} too short for indicators: ${f.length} bytes`,d,l.tag);if(s)throw new Error(a.message);i.push(a);continue}try{const a=String.fromCharCode(f[0]??0),E=String.fromCharCode(f[1]??0),$=$e(f.slice(2),r,l.tag,i,s,o);c.push({tag:l.tag,indicator1:a,indicator2:E,subfields:$})}catch(a){const E=h("invalid_field",`Failed to parse data field ${l.tag}: ${a instanceof Error?a.message:String(a)}`,d,l.tag);if(s)throw new Error(E.message);i.push(E)}}return c}function $e(e,t,n,r,i,s){const o=[];let c=0;for(;c<e.length;){if(r.length>=s){r.push(h("truncated_record",`Subfield parsing halted after reaching maxWarnings limit (${s}) in field ${n}; not all subfields were processed.`,void 0,n));break}if(e[c]!==B){const f=h("invalid_field",`Expected subfield delimiter in field ${n} at position ${c}`,void 0,n);if(i)throw new Error(f.message);r.push(f);break}if(c++,c>=e.length)break;const l=String.fromCharCode(e[c]??0);c++;const d=c;for(;c<e.length&&e[c]!==B;)c++;const g=e.slice(d,c);try{const f=t(g);o.push({code:l,value:f})}catch(f){const a=h("encoding_error",`Failed to decode subfield ${n}$${l}: ${f instanceof Error?f.message:String(f)}. Raw bytes (hex): ${z(g)}.`,void 0,n);if(i)throw new Error(a.message);r.push(a),o.push({code:l,value:q(g)})}}return o}function h(e,t,n,r){return{type:e,message:t,position:n,tag:r}}function J(e,t,n,r){return{type:e,message:t,position:n,tag:r}}var Ae=31,P=30,Ce=29,_=24,Ie=3,_e=4,Ne=5;function Re(e,t={}){return De(e,t).bytes}function De(e,t={}){Te(e);const n=[],r=t.encoding==="marc8",i=new TextEncoder,s=r?(v,S)=>{const b=L(v);return b.lossyCount>0&&n.push(J("encoding_error",`MARC-8 encoding substituted ${b.lossyCount} character(s) with '?' because they have no MARC-8 equivalent.`,void 0,S)),b.bytes}:v=>i.encode(v),o=[],c=[];let l=0;for(const v of e.fields){const S=Me(v,Q=>s(Q,v.tag)),b=S.length+1,X=v.tag.padEnd(Ie," ")+b.toString().padStart(_e,"0")+l.toString().padStart(Ne,"0");o.push(X),c.push(S),c.push(new Uint8Array([P])),l+=b}const d=i.encode(o.join("")),g=new Uint8Array(d.length+1);g.set(d),g[d.length]=P;const f=_+g.length,a=c.reduce((v,S)=>v+S.length,0),E=new Uint8Array(a);let $=0;for(const v of c)E.set(v,$),$+=v.length;const R=f+a+1,V=Le(e.leader,R,f,r),F=new Uint8Array(R);return F.set(i.encode(V),0),F.set(g,_),F.set(E,f),F[R-1]=Ce,{bytes:F,warnings:n}}function D(e){const t=e.charCodeAt(0);return t>=32&&t<=126}function Te(e){for(const t of e.fields){if(typeof t.tag!="string"||t.tag.length!==3)throw new Error(`MARC field tag must be exactly 3 characters; got ${JSON.stringify(t.tag)}`);if(!u.isControlField(t)){if(t.indicator1.length!==1)throw new Error(`Field ${t.tag} indicator1 must be exactly 1 character; got ${JSON.stringify(t.indicator1)}`);if(!D(t.indicator1))throw new Error(`Field ${t.tag} indicator1 must be an ASCII printable character (U+0020–U+007E); got ${JSON.stringify(t.indicator1)}`);if(t.indicator2.length!==1)throw new Error(`Field ${t.tag} indicator2 must be exactly 1 character; got ${JSON.stringify(t.indicator2)}`);if(!D(t.indicator2))throw new Error(`Field ${t.tag} indicator2 must be an ASCII printable character (U+0020–U+007E); got ${JSON.stringify(t.indicator2)}`);for(const n of t.subfields){if(n.code.length!==1)throw new Error(`Field ${t.tag} subfield code must be exactly 1 character; got ${JSON.stringify(n.code)}`);if(!D(n.code))throw new Error(`Field ${t.tag} subfield code must be an ASCII printable character (U+0020–U+007E); got ${JSON.stringify(n.code)}`)}}}}function Me(e,t){if(u.isControlField(e))return t(e.data);const n=[new Uint8Array([e.indicator1.charCodeAt(0),e.indicator2.charCodeAt(0)])];for(const o of e.subfields){const c=new Uint8Array([Ae,o.code.charCodeAt(0)]);n.push(c,t(o.value))}const r=n.reduce((o,c)=>o+c.length,0),i=new Uint8Array(r);let s=0;for(const o of n)i.set(o,s),s+=o.length;return i}function Le(e,t,n,r){let i=e.padEnd(_," ").substring(0,_);const s=t.toString().padStart(5,"0");if(s.length>5)throw new Error(`Record length ${t} exceeds maximum (99999)`);i=s+i.substring(5);const o=n.toString().padStart(5,"0");if(o.length>5)throw new Error(`Base address ${n} exceeds maximum (99999)`);return i=i.substring(0,12)+o+i.substring(17),i=i.substring(0,9)+(r?" ":"a")+i.substring(10),i}function xe(e,t={}){const n=e.map(o=>Re(o,t)),r=n.reduce((o,c)=>o+c.length,0),i=new Uint8Array(r);let s=0;for(const o of n)i.set(o,s),s+=o.length;return i}function w(e,t){return e.fields.find(n=>n.tag===t)}function Be(e,t){return e.fields.filter(n=>n.tag===t)}function p(e,t){return e.subfields.find(n=>n.code===t)?.value}function Ue(e,t){return e.subfields.filter(n=>n.code===t).map(n=>n.value)}function Oe(e){return e.subfields.map(t=>({code:t.code,value:t.value}))}function Pe(e){const t=w(e,"245");if(!t||!u.isDataField(t))return;const n=p(t,"a")??"",r=p(t,"b")??"";return(n+" "+r).trim()||void 0}function Ge(e){const t=w(e,"245");if(!(!t||!u.isDataField(t)))return p(t,"a")}function ke(e){const t=w(e,"100");if(t&&u.isDataField(t))return p(t,"a");const n=w(e,"110");if(n&&u.isDataField(n))return p(n,"a")}function We(e){const t=w(e,"250");if(!(!t||!u.isDataField(t)))return p(t,"a")}function je(e){const t=w(e,"264");if(t&&u.isDataField(t)){const r=p(t,"b");if(r)return r}const n=w(e,"260");if(n&&u.isDataField(n))return p(n,"b")}function He(e){const t=w(e,"264");if(t&&u.isDataField(t)){const r=p(t,"c");if(r)return r}const n=w(e,"260");if(n&&u.isDataField(n))return p(n,"c")}function qe(e){const t=[];for(const n of e.fields)if(n.tag==="020"&&u.isDataField(n)){const r=p(n,"a");r&&t.push(r)}return t}function ze(e){const t=w(e,"022");if(!(!t||!u.isDataField(t)))return p(t,"a")}function Je(e){const t=w(e,"010");if(!(!t||!u.isDataField(t)))return p(t,"a")}function Ye(e){const t=[];for(const n of e.fields)if(n.tag.startsWith("6")&&u.isDataField(n)){const r=p(n,"a");r&&t.push(r)}return t}function Ze(e){const t=w(e,"490");if(!(!t||!u.isDataField(t)))return p(t,"a")}function Y(e,t){if(e.length!==3||t.length!==3)return!1;for(let n=0;n<3;n++){const r=t[n],i=e[n];if(r==="."||r?.toUpperCase()==="X"){if(i&&!/\d/.test(i))return!1;continue}if(r!==i)return!1}return!0}function Ke(e,t){return e.fields.filter(n=>Y(n.tag,t))}function Ve(e,t){return e.fields.find(n=>Y(n.tag,t))}function x(e,t){return{...e,fields:[...e.fields,t]}}function Xe(e,t,n){const r=e.fields.findIndex(s=>s.tag===t);if(r===-1)return x(e,n);const i=Array.from(e.fields);return i.splice(r,0,n),{...e,fields:i}}function Qe(e,t,n){const r=e.fields.findIndex(s=>s.tag===t);if(r===-1)return x(e,n);const i=Array.from(e.fields);return i.splice(r+1,0,n),{...e,fields:i}}function et(e,t){const n=parseInt(t.tag,10);let r=e.fields.length;for(let s=0;s<e.fields.length;s++){const o=e.fields[s];if(o&&parseInt(o.tag,10)>n){r=s;break}}const i=Array.from(e.fields);return i.splice(r,0,t),{...e,fields:i}}function tt(e,t){return{...e,fields:e.fields.filter(n=>n.tag!==t)}}function nt(e,t){return{...e,fields:e.fields.filter(n=>n!==t)}}function Z(e,t,n){return{...e,subfields:[...e.subfields,{code:t,value:n}]}}function rt(e,t){return{...e,subfields:e.subfields.filter(n=>n.code!==t)}}function it(e,t,n){const r=e.subfields.findIndex(s=>s.code===t);if(r===-1)return Z(e,t,n);const i=[...e.subfields];return i[r]={code:t,value:n},{...e,subfields:i}}function st(e){const t=new Array(e.fields.length);for(let n=0;n<e.fields.length;n++){const r=e.fields[n];if(u.isControlField(r))t[n]={tag:r.tag,data:r.data};else{const i=new Array(r.subfields.length);for(let s=0;s<r.subfields.length;s++){const o=r.subfields[s];i[s]={code:o.code,value:o.value}}t[n]={tag:r.tag,indicator1:r.indicator1,indicator2:r.indicator2,subfields:i}}}return{leader:e.leader,fields:t}}function ot(e,t,n=!1){if(e.leader!==t.leader||e.fields.length!==t.fields.length)return!1;const r=n?[...e.fields].sort(G):e.fields,i=n?[...t.fields].sort(G):t.fields;for(let s=0;s<r.length;s++){const o=r[s],c=i[s];if(!o||!c||!K(o,c))return!1}return!0}function K(e,t){if(e.tag!==t.tag)return!1;if(u.isControlField(e)&&u.isControlField(t))return e.data===t.data;if(!u.isControlField(e)&&!u.isControlField(t)){if(e.indicator1!==t.indicator1||e.indicator2!==t.indicator2||e.subfields.length!==t.subfields.length)return!1;for(let n=0;n<e.subfields.length;n++){const r=e.subfields[n],i=t.subfields[n];if(!r||!i||r.code!==i.code||r.value!==i.value)return!1}return!0}return!1}function G(e,t){return e.tag.localeCompare(t.tag)}exports.addSubfield=Z;exports.appendField=x;exports.author=ke;exports.cloneRecord=st;exports.createWarning=J;exports.edition=We;exports.fieldsEqual=K;exports.getAllSubfields=Oe;exports.getField=w;exports.getFields=Be;exports.getFieldsByPattern=Ke;exports.getFirstFieldByPattern=Ve;exports.getSubfield=p;exports.getSubfields=Ue;exports.insertFieldAfter=Qe;exports.insertFieldBefore=Xe;exports.insertGroupedField=et;exports.isControlField=u.isControlField;exports.isDataField=u.isDataField;exports.isbn=qe;exports.issn=ze;exports.lccn=Je;exports.marc8ToUnicode=j;exports.parseMarcBinary=me;exports.publicationDate=He;exports.publisher=je;exports.recordsEqual=ot;exports.removeField=nt;exports.removeFields=tt;exports.removeSubfield=rt;exports.replaceSubfield=it;exports.serializeMarcBinary=xe;exports.seriesStatement=Ze;exports.subjects=Ye;exports.title=Pe;exports.titleProper=Ge;exports.unicodeToMarc8=we;exports.unicodeToMarc8WithStats=L;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("./types-CsOhH4OF.cjs"),G=require("./warnings-6yoB06xI.cjs");var ne=27,v="�",k=new Map([[33,"Ł"],[34,"Ø"],[35,"Đ"],[36,"Þ"],[37,"Æ"],[38,"Œ"],[39,"ʹ"],[40,"·"],[41,"♭"],[42,"®"],[43,"±"],[44,"Ơ"],[45,"Ư"],[46,"ʼ"],[48,"ʻ"],[49,"ł"],[50,"ø"],[51,"đ"],[52,"þ"],[53,"æ"],[54,"œ"],[55,"ʺ"],[56,"ı"],[57,"£"],[58,"ð"],[59,"ơ"],[60,"ư"],[63,"°"]]),q=new Map([[96,"̉"],[97,"̀"],[98,"́"],[99,"̂"],[100,"̃"],[101,"̄"],[102,"̆"],[103,"̇"],[104,"̈"],[105,"̌"],[106,"̊"],[107,"︠"],[108,"︡"],[109,"̕"],[110,"̋"],[111,"̐"],[112,"̧"],[113,"̨"],[114,"̣"],[115,"̤"],[116,"̥"],[117,"̳"],[118,"̲"],[119,"̦"],[120,"̜"],[121,"̮"],[122,"︢"],[123,"︣"],[126,"̓"]]),re=new Map(Array.from(q.entries()).map(([e,t])=>[t,e+128])),ie=new Map(Array.from(k.entries()).map(([e,t])=>[t,e+128])),se=T(65,"ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ",97,"αβγδεζηθικλμνξοπρστυφχψω"),oe=T(96,"אבגדהוזחטיךכלםמןנסעףפץצקרשת"),ae=T(65,"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ",97,"абвгдежзийклмнопрстуфхцчшщъыьэюя"),ce=new Map([[33,"ء"],[34,"آ"],[35,"أ"],[36,"ؤ"],[37,"إ"],[38,"ئ"],[39,"ا"],[40,"ب"],[41,"ة"],[42,"ت"],[43,"ث"],[44,"ج"],[45,"ح"],[46,"خ"],[47,"د"],[48,"ذ"],[49,"ر"],[50,"ز"],[51,"س"],[52,"ش"],[53,"ص"],[54,"ض"],[55,"ط"],[56,"ظ"],[57,"ع"],[58,"غ"],[65,"ف"],[66,"ق"],[67,"ك"],[68,"ل"],[69,"م"],[70,"ن"],[71,"ه"],[72,"و"],[73,"ى"],[74,"ي"]]),le=new Map([[40,"₍"],[41,"₎"],[43,"₊"],[45,"₋"],[48,"₀"],[49,"₁"],[50,"₂"],[51,"₃"],[52,"₄"],[53,"₅"],[54,"₆"],[55,"₇"],[56,"₈"],[57,"₉"]]),de=new Map([[40,"⁽"],[41,"⁾"],[43,"⁺"],[45,"⁻"],[48,"⁰"],[49,"¹"],[50,"²"],[51,"³"],[52,"⁴"],[53,"⁵"],[54,"⁶"],[55,"⁷"],[56,"⁸"],[57,"⁹"],[110,"ⁿ"]]),fe=new Map([[2171169,"一"],[2171170,"丁"],[2171171,"七"],[2171172,"万"],[2171173,"丈"],[2171174,"三"],[2171175,"上"],[2171176,"下"],[2171177,"不"],[2171178,"与"],[2171179,"丐"],[2171180,"丑"],[2171181,"且"],[2171182,"世"],[2171183,"丘"],[2171184,"丙"],[2171185,"业"],[2171186,"丛"],[2171187,"东"],[2171188,"丝"],[2171189,"丞"],[2171190,"丟"],[2171191,"丠"],[2171192,"両"],[2171193,"丢"],[2171194,"两"],[2171195,"严"],[2171196,"並"],[2171197,"丧"],[2171198,"丨"],[2171199,"个"],[2171200,"丫"],[2171201,"中"],[2171202,"丰"]]),ue={ascii:new Map,ansel:ge(k,q),greek:se,hebrew:oe,cyrillic:ae,arabic:ce,subscript:le,superscript:de};function T(...e){const t=new Map;for(let n=0;n<e.length;n+=2){const i=e[n],r=e[n+1];Array.from(r).forEach((s,o)=>t.set(i+o,s))}return t}function ge(...e){const t=new Map;for(const n of e)for(const[i,r]of n)t.set(i,r);return t}function D(e){const t=e.codePointAt(0);return t>=768&&t<=879||t>=65056&&t<=65071}function C(e,t){return t?e-128:e}function he(e,t,n){const i=C(e,n);return t==="ascii"?i>=32&&i<=126?String.fromCharCode(i):v:ue[t].get(i)??v}function pe(e,t,n){if(t+2>=e.length)return{char:v,next:e.length};const i=C(e[t],n),r=C(e[t+1],n),s=C(e[t+2],n),o=i<<16|r<<8|s;return{char:fe.get(o)??v,next:t+3}}function we(e,t,n){if(t+1>=e.length)return{char:v,next:e.length};const i=e[t+1];let r,s;if(i===40||i===44)r="g0",s=t+2;else if(i===41||i===45)r="g1",s=t+2;else if(i===36){const l=e[t+2];if(l===void 0)return{char:v,next:e.length};l===40||l===44?(r="g0",s=t+3):l===41||l===45?(r="g1",s=t+3):(r="g0",s=t+2)}else return{char:v,next:t+2};if(s>=e.length)return{char:v,next:e.length};let o=e[s];if(o===33){if(s++,s>=e.length)return{char:v,next:e.length};o=e[s]}const a=me(o);return a?{char:"",next:Ee(n,r,a,s+1)}:{char:v,next:s+1}}function Ee(e,t,n,i){return e[t]=n,i}function me(e){switch(e){case 49:return"eacc";case 50:return"hebrew";case 51:return"arabic";case 52:return"cyrillic";case 66:return"ascii";case 69:return"ansel";case 78:return"cyrillic";case 81:return"greek";case 83:return"greek";case 98:return"subscript";case 112:return"superscript";default:return}}function z(e){const t={g0:"ascii",g1:"ansel"},n=[];let i="",r=0;const s=o=>{if(o){if(D(o)){i+=o;return}n.push(o+i),i=""}};for(;r<e.length;){const o=e[r];if(o===ne){const d=we(e,r,t);s(d.char),r=d.next;continue}if(o<32){s(String.fromCharCode(o)),r++;continue}const a=o>=160,l=a?t.g1:t.g0;if(l==="eacc"){const d=pe(e,r,a);s(d.char),r=d.next;continue}s(he(o,l,a)),r++}return i&&n.push(i),n.join("")}function ve(e){return x(e).bytes}function x(e){const t=e.normalize("NFD"),n=[];let i=0,r=0;for(;r<t.length;){const s=t.codePointAt(r),o=t[r];if(D(o)){n.push(63),i++,r++;continue}let a=r+(s>65535?2:1);const l=[];for(;a<t.length&&D(t[a]);){const d=re.get(t[a]);d!==void 0?l.push(d):(l.push(63),i++),a++}if(n.push(...l),s<128)n.push(s);else{const d=ie.get(o);d!==void 0?n.push(d):(n.push(63),i++)}r=a}return{bytes:new Uint8Array(n),lossyCount:i}}var U=31,j=30,$=24,A=12,O=3,R=new TextDecoder("utf-8",{fatal:!1});function H(e){return R.decode(e)}function J(e,t=16){const n=e.slice(0,t),i=Array.from(n,r=>r.toString(16).padStart(2,"0")).join(" ");return e.length>t?`${i} … (${e.length} bytes)`:i}function I(e,t={}){const n=t.strict??!1,i=t.maxWarnings??100,r=[];if(e.length<25){const c=g("truncated_record",`Record too short: ${e.length} bytes`);if(n)throw new Error(c.message);return r.push(c),{record:null,warnings:r}}const s=Fe(e);if(!ye(s,r,n)&&(n||r.length>=i))return{record:null,warnings:r};const o=parseInt(s.substring(0,5),10);if(isNaN(o)||o>e.length){const c=g("invalid_leader",`Invalid record length in leader: ${s.substring(0,5)}`);if(n)throw new Error(c.message);r.push(c)}else if(o<e.length){const c=g("truncated_record",`Buffer is longer than the record length declared in the leader: leader says ${o}, buffer is ${e.length} bytes. Trailing bytes ignored (likely a concatenated stream — split on 0x1D first).`);if(n)throw new Error(c.message);r.push(c),e=e.slice(0,o)}const a=parseInt(s.substring(12,17),10);if(isNaN(a)){const c=g("invalid_leader",`Invalid base address in leader: ${s.substring(12,17)}`);if(n)throw new Error(c.message);return r.push(c),{record:null,warnings:r}}const l=$,d=e.indexOf(j,l);if(d===-1){const c=g("invalid_directory","Directory terminator not found");if(n)throw new Error(c.message);return r.push(c),{record:null,warnings:r}}const h=Ae(e.slice(l,d),r,n,i);if(h.length===0){const c=g("invalid_directory","No directory entries found");if(n)throw new Error(c.message);return r.push(c),{record:null,warnings:r}}const f=s[9]===" ";if(s[9]!==" "&&s[9]!=="a"){const c=g("invalid_leader",`Leader position 9 (encoding flag) is '${s[9]}'; expected 'a' (UTF-8) or ' ' (MARC-8). Defaulting to UTF-8.`);if(n)throw new Error(c.message);r.push(c)}return{record:{leader:s,fields:Ce(e,h,a,f?z:c=>R.decode(c),r,n,i)},warnings:r}}var Y=29;function Se(e,t){const n=[];let i=0;for(let r=0;r<e.length;r++)if(e[r]===Y){const s=e.slice(i,r+1);if(s.length>0){const o=I(s,t);o.record&&n.push(o.record)}i=r+1}if(i<e.length){const r=I(e.slice(i),t);r.record&&n.push(r.record)}return n}function be(e,t){const n=[];let i=0;for(let r=0;r<e.length;r++)if(e[r]===Y){const s=e.slice(i,r+1);s.length>0&&n.push(I(s,t)),i=r+1}if(i<e.length){const r=e.slice(i);n.push(I(r,t))}return{results:n}}function Fe(e){const t=e.slice(0,$);return R.decode(t)}function ye(e,t,n){if(e.length!==$){const i=g("invalid_leader",`Leader length is ${e.length}, expected ${$}`);if(n)throw new Error(i.message);return t.push(i),!1}if(e[10]!=="2"){const i=g("invalid_leader",`Leader position 10 (indicator count) is '${e[10]}', expected '2'`);t.push(i)}if(e[11]!=="2"){const i=g("invalid_leader",`Leader position 11 (subfield code length) is '${e[11]}', expected '2'`);t.push(i)}return!0}function Ae(e,t,n,i){const r=[];for(let s=0;s<e.length;s+=A){if(t.length>=i){t.push(g("truncated_record",`Directory parsing halted after reaching maxWarnings limit (${i}); remaining ${e.length-s} bytes of directory not parsed.`));break}if(s+A>e.length)break;const o=e.slice(s,s+A),a=R.decode(o),l=a.substring(0,O),d=a.substring(O,7),h=a.substring(7,A),f=parseInt(d,10),c=parseInt(h,10);if(isNaN(f)||isNaN(c)){const w=g("invalid_directory",`Invalid directory entry for tag ${l}: length=${d}, position=${h}`);if(n)throw new Error(w.message);t.push(w);continue}r.push({tag:l,fieldLength:f,startingPosition:c})}return r}function Ce(e,t,n,i,r,s,o){const a=[];for(const l of t){if(r.length>=o){r.push(g("truncated_record",`Field parsing halted after reaching maxWarnings limit (${o}); not all directory entries were processed.`,void 0,l.tag));break}const d=n+l.startingPosition,h=d+l.fieldLength-1;if(d>=e.length||h>e.length){const c=g("invalid_field",`Field ${l.tag} out of bounds: start=${d}, end=${h}, buffer length=${e.length}`,d,l.tag);if(s)throw new Error(c.message);r.push(c);continue}let f;if(e[h]!==j){const c=g("invalid_field",`Field ${l.tag} does not end with a field terminator at byte ${h} (found 0x${(e[h]??0).toString(16).padStart(2,"0")}); using the full declared length without stripping a terminator byte.`,d,l.tag);if(s)throw new Error(c.message);r.push(c),f=e.slice(d,d+l.fieldLength)}else f=e.slice(d,h);if(l.tag.startsWith("00")){try{const c=i(f);a.push({tag:l.tag,data:c})}catch(c){const w=g("encoding_error",`Failed to decode control field ${l.tag}: ${c instanceof Error?c.message:String(c)}. Raw bytes (hex): ${J(f)}.`,d,l.tag);if(s)throw new Error(w.message);r.push(w),a.push({tag:l.tag,data:H(f)})}continue}if(f.length<2){const c=g("invalid_field",`Data field ${l.tag} too short for indicators: ${f.length} bytes`,d,l.tag);if(s)throw new Error(c.message);r.push(c);continue}try{const c=String.fromCharCode(f[0]??0),w=String.fromCharCode(f[1]??0),y=$e(f.slice(2),i,l.tag,r,s,o);a.push({tag:l.tag,indicator1:c,indicator2:w,subfields:y})}catch(c){const w=g("invalid_field",`Failed to parse data field ${l.tag}: ${c instanceof Error?c.message:String(c)}`,d,l.tag);if(s)throw new Error(w.message);r.push(w)}}return a}function $e(e,t,n,i,r,s){const o=[];let a=0;for(;a<e.length;){if(i.length>=s){i.push(g("truncated_record",`Subfield parsing halted after reaching maxWarnings limit (${s}) in field ${n}; not all subfields were processed.`,void 0,n));break}if(e[a]!==U){const f=g("invalid_field",`Expected subfield delimiter in field ${n} at position ${a}`,void 0,n);if(r)throw new Error(f.message);i.push(f);break}if(a++,a>=e.length)break;const l=String.fromCharCode(e[a]??0);a++;const d=a;for(;a<e.length&&e[a]!==U;)a++;const h=e.slice(d,a);try{const f=t(h);o.push({code:l,value:f})}catch(f){const c=g("encoding_error",`Failed to decode subfield ${n}$${l}: ${f instanceof Error?f.message:String(f)}. Raw bytes (hex): ${J(h)}.`,void 0,n);if(r)throw new Error(c.message);i.push(c),o.push({code:l,value:H(h)})}}return o}function g(e,t,n,i){return{type:e,message:t,position:n,tag:i}}var Ie=31,P=30,_e=29,_=24,Re=3,Me=4,Ne=5;function De(e,t={}){return Z(e,t).bytes}function Z(e,t={}){Te(e);const n=[],i=t.maxWarnings??100,r=t.encoding==="marc8",s=new TextEncoder,o=r?(m,S)=>{const b=x(m);return b.lossyCount>0&&n.length<i&&n.push(G.createWarning("encoding_error",`MARC-8 encoding substituted ${b.lossyCount} character(s) with '?' because they have no MARC-8 equivalent.`,void 0,S)),b.bytes}:m=>s.encode(m),a=[],l=[];let d=0;for(const m of e.fields){const S=xe(m,te=>o(te,m.tag)),b=S.length+1,ee=m.tag.padEnd(Re," ")+b.toString().padStart(Me,"0")+d.toString().padStart(Ne,"0");a.push(ee),l.push(S),l.push(new Uint8Array([P])),d+=b}const h=s.encode(a.join("")),f=new Uint8Array(h.length+1);f.set(h),f[h.length]=P;const c=_+f.length,w=l.reduce((m,S)=>m+S.length,0),y=new Uint8Array(w);let B=0;for(const m of l)y.set(m,B),B+=m.length;const M=c+w+1,Q=Le(e.leader,M,c,r),F=new Uint8Array(M);return F.set(s.encode(Q),0),F.set(f,_),F.set(y,c),F[M-1]=_e,{bytes:F,warnings:n}}function N(e){const t=e.charCodeAt(0);return t>=32&&t<=126}function Te(e){for(const t of e.fields){if(typeof t.tag!="string"||t.tag.length!==3)throw new Error(`MARC field tag must be exactly 3 characters; got ${JSON.stringify(t.tag)}`);if(!u.isControlField(t)){if(t.indicator1.length!==1)throw new Error(`Field ${t.tag} indicator1 must be exactly 1 character; got ${JSON.stringify(t.indicator1)}`);if(!N(t.indicator1))throw new Error(`Field ${t.tag} indicator1 must be an ASCII printable character (U+0020–U+007E); got ${JSON.stringify(t.indicator1)}`);if(t.indicator2.length!==1)throw new Error(`Field ${t.tag} indicator2 must be exactly 1 character; got ${JSON.stringify(t.indicator2)}`);if(!N(t.indicator2))throw new Error(`Field ${t.tag} indicator2 must be an ASCII printable character (U+0020–U+007E); got ${JSON.stringify(t.indicator2)}`);for(const n of t.subfields){if(n.code.length!==1)throw new Error(`Field ${t.tag} subfield code must be exactly 1 character; got ${JSON.stringify(n.code)}`);if(!N(n.code))throw new Error(`Field ${t.tag} subfield code must be an ASCII printable character (U+0020–U+007E); got ${JSON.stringify(n.code)}`)}}}}function xe(e,t){if(u.isControlField(e))return t(e.data);const n=[new Uint8Array([e.indicator1.charCodeAt(0),e.indicator2.charCodeAt(0)])];for(const o of e.subfields){const a=new Uint8Array([Ie,o.code.charCodeAt(0)]);n.push(a,t(o.value))}const i=n.reduce((o,a)=>o+a.length,0),r=new Uint8Array(i);let s=0;for(const o of n)r.set(o,s),s+=o.length;return r}function Le(e,t,n,i){let r=e.padEnd(_," ").substring(0,_);const s=t.toString().padStart(5,"0");if(s.length>5)throw new Error(`Record length ${t} exceeds maximum (99999)`);r=s+r.substring(5);const o=n.toString().padStart(5,"0");if(o.length>5)throw new Error(`Base address ${n} exceeds maximum (99999)`);return r=r.substring(0,12)+o+r.substring(17),r=r.substring(0,9)+(i?" ":"a")+r.substring(10),r}function Be(e,t={}){const n=e.map(o=>De(o,t)),i=n.reduce((o,a)=>o+a.length,0),r=new Uint8Array(i);let s=0;for(const o of n)r.set(o,s),s+=o.length;return r}function Ue(e,t={}){const n=[],i=[];for(const a of e){const l=Z(a,t);n.push(l),i.push(l.bytes)}const r=i.reduce((a,l)=>a+l.length,0),s=new Uint8Array(r);let o=0;for(const a of i)s.set(a,o),o+=a.length;return{bytes:s,results:n}}function E(e,t){return e.fields.find(n=>n.tag===t)}function Oe(e,t){return e.fields.filter(n=>n.tag===t)}function p(e,t){return e.subfields.find(n=>n.code===t)?.value}function Pe(e,t){return e.subfields.filter(n=>n.code===t).map(n=>n.value)}function We(e){return e.subfields.map(t=>({code:t.code,value:t.value}))}function Ge(e){const t=E(e,"245");if(!t||!u.isDataField(t))return;const n=p(t,"a")??"",i=p(t,"b")??"";return(n+" "+i).trim()||void 0}function ke(e){const t=E(e,"245");if(!(!t||!u.isDataField(t)))return p(t,"a")}function qe(e){const t=E(e,"100");if(t&&u.isDataField(t))return p(t,"a");const n=E(e,"110");if(n&&u.isDataField(n))return p(n,"a")}function ze(e){const t=E(e,"250");if(!(!t||!u.isDataField(t)))return p(t,"a")}function je(e){const t=E(e,"264");if(t&&u.isDataField(t)){const i=p(t,"b");if(i)return i}const n=E(e,"260");if(n&&u.isDataField(n))return p(n,"b")}function He(e){const t=E(e,"264");if(t&&u.isDataField(t)){const i=p(t,"c");if(i)return i}const n=E(e,"260");if(n&&u.isDataField(n))return p(n,"c")}function Je(e){const t=[];for(const n of e.fields)if(n.tag==="020"&&u.isDataField(n)){const i=p(n,"a");i&&t.push(i)}return t}function Ye(e){const t=E(e,"022");if(!(!t||!u.isDataField(t)))return p(t,"a")}function Ze(e){const t=E(e,"010");if(!(!t||!u.isDataField(t)))return p(t,"a")}function Ke(e){const t=[];for(const n of e.fields)if(n.tag.startsWith("6")&&u.isDataField(n)){const i=p(n,"a");i&&t.push(i)}return t}function Ve(e){const t=E(e,"490");if(!(!t||!u.isDataField(t)))return p(t,"a")}function K(e,t){if(e.length!==3||t.length!==3)return!1;for(let n=0;n<3;n++){const i=t[n],r=e[n];if(i==="."||i?.toUpperCase()==="X"){if(r&&!/\d/.test(r))return!1;continue}if(i!==r)return!1}return!0}function Xe(e,t){return e.fields.filter(n=>K(n.tag,t))}function Qe(e,t){return e.fields.find(n=>K(n.tag,t))}function L(e,t){return{...e,fields:[...e.fields,t]}}function et(e,t,n){const i=e.fields.findIndex(s=>s.tag===t);if(i===-1)return L(e,n);const r=Array.from(e.fields);return r.splice(i,0,n),{...e,fields:r}}function tt(e,t,n){const i=e.fields.findIndex(s=>s.tag===t);if(i===-1)return L(e,n);const r=Array.from(e.fields);return r.splice(i+1,0,n),{...e,fields:r}}function nt(e,t){const n=parseInt(t.tag,10);let i=e.fields.length;for(let s=0;s<e.fields.length;s++){const o=e.fields[s];if(o&&parseInt(o.tag,10)>n){i=s;break}}const r=Array.from(e.fields);return r.splice(i,0,t),{...e,fields:r}}function rt(e,t){return{...e,fields:e.fields.filter(n=>n.tag!==t)}}function it(e,t){return{...e,fields:e.fields.filter(n=>n!==t)}}function V(e,t,n){return{...e,subfields:[...e.subfields,{code:t,value:n}]}}function st(e,t){return{...e,subfields:e.subfields.filter(n=>n.code!==t)}}function ot(e,t,n){const i=e.subfields.findIndex(s=>s.code===t);if(i===-1)return V(e,t,n);const r=[...e.subfields];return r[i]={code:t,value:n},{...e,subfields:r}}function at(e){const t=new Array(e.fields.length);for(let n=0;n<e.fields.length;n++){const i=e.fields[n];if(u.isControlField(i))t[n]={tag:i.tag,data:i.data};else{const r=new Array(i.subfields.length);for(let s=0;s<i.subfields.length;s++){const o=i.subfields[s];r[s]={code:o.code,value:o.value}}t[n]={tag:i.tag,indicator1:i.indicator1,indicator2:i.indicator2,subfields:r}}}return{leader:e.leader,fields:t}}function ct(e,t,n=!1){if(e.leader!==t.leader||e.fields.length!==t.fields.length)return!1;const i=n?[...e.fields].sort(W):e.fields,r=n?[...t.fields].sort(W):t.fields;for(let s=0;s<i.length;s++){const o=i[s],a=r[s];if(!o||!a||!X(o,a))return!1}return!0}function X(e,t){if(e.tag!==t.tag)return!1;if(u.isControlField(e)&&u.isControlField(t))return e.data===t.data;if(!u.isControlField(e)&&!u.isControlField(t)){if(e.indicator1!==t.indicator1||e.indicator2!==t.indicator2||e.subfields.length!==t.subfields.length)return!1;for(let n=0;n<e.subfields.length;n++){const i=e.subfields[n],r=t.subfields[n];if(!i||!r||i.code!==r.code||i.value!==r.value)return!1}return!0}return!1}function W(e,t){return e.tag.localeCompare(t.tag)}exports.addSubfield=V;exports.appendField=L;exports.author=qe;exports.cloneRecord=at;exports.createWarning=G.createWarning;exports.edition=ze;exports.fieldsEqual=X;exports.getAllSubfields=We;exports.getField=E;exports.getFields=Oe;exports.getFieldsByPattern=Xe;exports.getFirstFieldByPattern=Qe;exports.getSubfield=p;exports.getSubfields=Pe;exports.insertFieldAfter=tt;exports.insertFieldBefore=et;exports.insertGroupedField=nt;exports.isControlField=u.isControlField;exports.isDataField=u.isDataField;exports.isbn=Je;exports.issn=Ye;exports.lccn=Ze;exports.marc8ToUnicode=z;exports.parseMarcBinary=Se;exports.parseMarcBinaryWithWarnings=be;exports.publicationDate=He;exports.publisher=je;exports.recordsEqual=ct;exports.removeField=it;exports.removeFields=rt;exports.removeSubfield=st;exports.replaceSubfield=ot;exports.serializeMarcBinary=Be;exports.serializeMarcBinaryWithWarnings=Ue;exports.seriesStatement=Ve;exports.subjects=Ke;exports.title=Ge;exports.titleProper=ke;exports.unicodeToMarc8=ve;exports.unicodeToMarc8WithStats=x;
|
|
2
2
|
|
|
3
3
|
//# sourceMappingURL=index.cjs.map
|